root/trunk/lisp/textmodes/artist.el

Revision 4220, 188.1 kB (checked in by miyoshi, 9 months ago)

Sync up with Emacs22.2.

  • Property svn:eol-style set to LF
Line 
1 ;;; artist.el --- draw ascii graphics with your mouse
2
3 ;; Copyright (C) 2000, 2001, 2002, 2003, 2004,
4 ;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5
6 ;; Author:       Tomas Abrahamsson <tab@lysator.liu.se>
7 ;; Maintainer:   Tomas Abrahamsson <tab@lysator.liu.se>
8 ;; Keywords:     mouse
9 ;; Version:      1.2.6
10 ;; Release-date: 6-Aug-2004
11 ;; Location:     http://www.lysator.liu.se/~tab/artist/
12
13 ;; This file is part of GNU Emacs.
14
15 ;; GNU Emacs is free software; you can redistribute it and/or modify
16 ;; it under the terms of the GNU General Public License as published by
17 ;; the Free Software Foundation; either version 3, or (at your option)
18 ;; any later version.
19
20 ;; GNU Emacs is distributed in the hope that it will be useful,
21 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 ;; GNU General Public License for more details.
24
25 ;; You should have received a copy of the GNU General Public License
26 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
27 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
28 ;; Boston, MA 02110-1301, USA.
29
30 ;;; Commentary:
31
32 ;; What is artist?
33 ;; ---------------
34 ;;
35 ;; Artist is an Emacs lisp package that allows you to draw lines,
36 ;; rectangles and ellipses by using your mouse and/or keyboard.  The
37 ;; shapes are made up with the ascii characters |, -, / and \.
38 ;;
39 ;; Features are:
40 ;;
41 ;; * Intersecting: When a `|' intersects with a `-', a `+' is
42 ;;   drawn, like this:    |        \ /
43 ;;                      --+--       X
44 ;;                        |        / \
45 ;;
46 ;; * Rubber-banding: When drawing lines you can interactively see the
47 ;;   result while holding the mouse button down and moving the mouse.  If
48 ;;   your machine is not fast enough (a 386 is a bit to slow, but a
49 ;;   pentium is well enough), you can turn this feature off.  You will
50 ;;   then see 1's and 2's which mark the 1st and 2nd endpoint of the line
51 ;;   you are drawing.
52 ;;
53 ;; * Drawing operations: The following drawing operations are implemented:
54 ;;
55 ;;     lines                    straight-lines
56 ;;     rectangles               squares
57 ;;     poly-lines               straight poly-lines
58 ;;     ellipses                 circles
59 ;;     text (see-thru)          text (overwrite)
60 ;;     spray-can                setting size for spraying
61 ;;     vaporize line            vaporize lines
62 ;;     erase characters         erase rectangles
63 ;;
64 ;;   Straight lines are lines that go horizontally, vertically or
65 ;;   diagonally.  Plain lines go in any direction.  The operations in
66 ;;   the right column are accessed by holding down the shift key while
67 ;;   drawing.
68 ;;
69 ;;   It is possible to vaporize (erase) entire lines and connected lines
70 ;;   (rectangles for example) as long as the lines being vaporized are
71 ;;   straight and connected at their endpoints.  Vaporizing is inspired
72 ;;   by the drawrect package by Jari Aalto <jari.aalto@poboxes.com>.
73 ;;
74 ;; * Flood-filling: You can fill any area with a certain character by
75 ;;   flood-filling.
76 ;;
77 ;; * Cut copy and paste: You can cut, copy and paste rectangular
78 ;;   regions.  Artist also interfaces with the rect package (this can be
79 ;;   turned off if it causes you any trouble) so anything you cut in
80 ;;   artist can be yanked with C-x r y and vice versa.
81 ;;
82 ;; * Drawing with keys: Everything you can do with the mouse, you can
83 ;;   also do without the mouse.
84 ;;
85 ;; * Arrows: After having drawn a (straight) line or a (straight)
86 ;;   poly-line, you can set arrows on the line-ends by typing < or >.
87 ;;
88 ;; * Aspect-ratio: You can set the variable artist-aspect-ratio to
89 ;;   reflect the height-width ratio for the font you are using.  Squares
90 ;;   and circles are then drawn square/round.  Note, that once your
91 ;;   ascii-file is shown with font with a different height-width ratio,
92 ;;   the squares won't be square and the circles won't be round.
93 ;;
94 ;; * Picture mode compatibility: Artist is picture mode compatible (this
95 ;;   can be turned off).
96 ;;
97 ;; See the documentation for the function artist-mode for a detailed
98 ;; description on how to use artist.
99 ;;
100 ;;
101 ;; What about adding my own drawing modes?
102 ;; ---------------------------------------
103 ;;
104 ;; See the short guide at the end of this file.
105 ;; If you add a new drawing mode, send it to me, and I would gladly
106 ;; include in the next release!
107
108
109 ;;; Installation:
110
111 ;; To use artist, put this in your .emacs:
112 ;;
113 ;;    (autoload 'artist-mode "artist" "Enter artist-mode" t)
114
115
116 ;;; Requirements:
117
118 ;; Artist requires Emacs 19.28 or higher.
119 ;;
120 ;; Artist requires the `rect' package (which comes with Emacs) to be
121 ;; loadable, unless the variable `artist-interface-with-rect' is set
122 ;; to nil.
123 ;;
124 ;; Artist also requires the Picture mode (which also comes with Emacs)
125 ;; to be loadable, unless the variable `artist-picture-compatibility'
126 ;; is set to nil.
127
128 ;;; Known bugs:
129
130 ;; The shifted operations are not available when drawing with the mouse
131 ;; in Emacs 19.29 and 19.30.
132 ;;
133 ;; It is not possible to change between shifted and unshifted operation
134 ;; while drawing with the mouse. (See the comment in the function
135 ;; artist-shift-has-changed for further details.)
136
137
138 ;;; ChangeLog:
139
140 ;; 1.2.6        6-Aug-2004
141 ;; New:         Coerced with the artist.el that's in Emacs-21.3.
142 ;;              (minor editorial changes)
143 ;;
144 ;; 1.2.5        4-Aug-2004
145 ;; New:         Added tool selection via the mouse-wheel
146 ;;              Function provided by Andreas Leue <al@sphenon.de>
147 ;;
148 ;; 1.2.4        25-Oct-2001
149 ;; Bugfix:      Some operations (the edit menu) got hidden
150 ;; Bugfix:      The first arrow for poly-lines was always pointing
151 ;;              to the right
152 ;; Changed:     Updated with changes made for Emacs 21.1
153 ;;
154 ;; 1.2.3        20-Nov-2000
155 ;; Bugfix:      Autoload cookie corrected
156 ;;
157 ;; 1.2.2        19-Nov-2000
158 ;; Changed:     More documentation fixes.
159 ;; Bugfix:      The arrow characters (`artist-arrows'), which
160 ;;              got wrong in 1.1, are now corrected.
161 ;;
162 ;; 1.2.1        15-Nov-2000
163 ;; New:         Documentation fixes.
164 ;; Bugfix:      Sets next-line-add-newlines to t while in artist-mode.
165 ;;              Drawing with keys was confusing without this fix, if
166 ;;              next-line-add-newlines was set to nil.
167 ;;              Thanks to Tatsuo Furukawa <tatsuo@kobe.hp.com> for this.
168 ;;
169 ;; 1.2          22-Oct-2000
170 ;; New:         Updated to work with Emacs 21
171 ;;
172 ;; 1.1          15-Aug-2000
173 ;; Bugfix:      Cursor follows mouse pointer more closely.
174 ;; New:         Works with Emacs 20.x
175 ;; New:         Variables are customizable
176 ;;
177 ;; 1.1-beta1    21-Apr-1998
178 ;; New:         Spray-can (Utterly useless, I believe, but it was fun
179 ;;              to implement :-) after an idea by Karl-Johan Karlsson
180 ;;              <kj@lysator.liu.se>.
181 ;; New:         Freehand drawing (with pen).
182 ;; New:         Vaporizing lines.
183 ;; New:         Text-rendering using figlet.
184 ;; New:         Picture mode compatibility.
185 ;; Changed:     All Artist keys now uses the prefix C-c C-a not to conflict
186 ;;              with Picture mode.
187 ;; Bugfix:      No longer leaves traces of lines when rubberbanding
188 ;;              if the buffer auto-scrolls.
189 ;; Bugfix:      Infinite loop sometimes when rubberbanding was turned
190 ;;              off.
191 ;;
192 ;; 1.0          01-Mar-1998
193 ;; First official release.
194
195 ;;; Code:
196
197 ;; Variables
198
199 (defconst artist-version "1.2.6")
200 (defconst artist-maintainer-address "tab@lysator.liu.se")
201
202 (defvar x-pointer-crosshair)
203
204 (eval-and-compile
205  (condition-case ()
206      (require 'custom)
207    (error nil))
208  (if (and (featurep 'custom) (fboundp 'custom-declare-variable))
209      nil ;; We've got what we needed
210      ;; We have the old custom-library, hack around it!
211      (defmacro defgroup (&rest args)
212        nil)
213      (defmacro defface (var values doc &rest args)
214        `(make-face ,var))
215      (defmacro defcustom (var value doc &rest args)
216        `(defvar ,var ,value ,doc))))
217
218 ;; User options
219 ;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
220
221 (defgroup artist nil
222   "Customization of the Artist mode."
223   :group 'mouse)
224
225 (defgroup artist-text nil
226   "Customization of the text rendering."
227   :group 'artist)
228
229 (defcustom artist-rubber-banding t
230   "Interactively do rubber-banding when non-nil."
231   :group 'artist
232   :type 'boolean)
233
234 (defcustom artist-first-char ?1
235   "Character to set at first point when not rubber-banding."
236   :group 'artist
237   :type 'character)
238
239 (defcustom artist-second-char ?2
240   "Character to set at second point when not rubber-banding."
241   :group 'artist
242   :type 'character)
243
244 (defcustom artist-interface-with-rect t
245   "Whether to interface with the rect package or not.
246
247 Interfacing to the rect package means that the Copy and Paste operations
248 will use the rectangle buffer when accessing the copied area.  This means
249 that you can insert a rectangle which is copied using the artist package
250 and vice versa.
251
252 If this causes any problem for you (for example, if the implementation of
253 the rectangle package changes), you can set this variable to nil, and the
254 artist package will use its own copy buffer."
255   :group 'artist
256   :type 'boolean)
257
258 (defvar artist-arrows [ ?> nil ?v ?L ?< nil ?^ nil ]
259   ;; This is a defvar, not a defcustom, since the custom
260   ;; package shows vectors of characters as a vector of integers,
261   ;; which is confusing
262   "A vector of characters to use as arrows.
263
264 The vector is 8 elements long and contains a character for each
265 direction, or nil if there is no suitable character to use for arrow
266 in that direction.
267
268 The directions are as follows:
269
270                           5  6  7
271                            \\ | /
272                          4 - * - 0
273                            / | \\
274                           3  2  1")
275
276 (defcustom artist-aspect-ratio 1
277   "Defines the character height-to-width aspect ratio.
278 This is used when drawing squares and circles.  If the height of the"
279   :group 'artist
280   :type 'number)
281
282 (defcustom artist-trim-line-endings t
283   "Whether or not to remove white-space at end of lines.
284
285 If non-nil, line-endings are trimmed (that is, extraneous white-space
286 at the end of the line is removed) when the shape is drawn."
287   :group 'artist
288   :type 'boolean)
289
290
291 (defcustom artist-flood-fill-right-border 'window-width
292   "Right edge definition, used when flood-filling.
293
294 When flood-filling, if the area is not closed off to the right, then
295 flood-filling will fill no more to the right than specified by this
296 variable.  This limit is called the fill-border."
297   :group 'artist
298   :type '(choice (const :tag "limited to window" window-width)
299                  (const :tag "limited to value of `fill-column'" fill-column)))
300
301 (defcustom artist-flood-fill-show-incrementally t
302   "Whether or not to incrementally update display when flood-filling.
303
304 If non-nil, incrementally update display when flood-filling.
305 If set to non-nil, this currently implies discarding any input events
306 during the flood-fill."
307   :group 'artist
308   :type 'boolean)
309
310
311 (defcustom artist-ellipse-right-char ?\)
312   "Character to use at the rightmost position when drawing narrow ellipses.
313
314 In this figure, it is the right parenthesis (the ``)'' character):
315              -----
316             (     )
317              -----"
318   :group 'artist
319   :type 'character)
320
321
322 (defcustom artist-ellipse-left-char ?\(
323   "Character to use at the leftmost position when drawing narrow ellipses.
324
325 In this figure, it is the left parenthesis (the ``('' character):
326              -----
327             (     )
328              -----"
329   :group 'artist
330   :type 'character)
331
332 (defcustom artist-picture-compatibility t
333   "Whether or not picture mode compatibility is on."
334   :group 'artist
335   :type 'boolean)
336
337
338
339
340 (defcustom artist-vaporize-fuzziness 1
341   "How to vaporize lines that are cut off.
342
343 Accept this many characters cutting off a line and still treat
344 it as one line.
345 Example:
346  If `artist-vaporize-fuzziness' is 2, then those will be recognized as
347  lines from A to B (provided you start vaporizing them at the ``*''):
348                          /
349             A----*------/-----------B
350                       \\/
351             A----*----/\\------------B
352                      /  \\
353
354  but this one won't, since it is cut off by more than 2 characters:
355                       \\/ /
356             A----*----/\\/----------B
357                      / /\\
358  (in fact, only the left part (between the A and the leftmost ``/''
359  crossing the line) will be vaporized)"
360   :group 'artist
361   :type 'integer)
362
363
364 (defvar artist-pointer-shape (if (eq window-system 'x) x-pointer-crosshair nil)
365   "*If in X Windows, use this pointer shape while drawing with the mouse.")
366
367
368 (defcustom artist-text-renderer-function 'artist-figlet
369   "Function for doing text rendering."
370   :group 'artist-text
371   :type 'symbol)
372 (defvaralias 'artist-text-renderer 'artist-text-renderer-function)
373
374
375 (defcustom artist-figlet-program "figlet"
376   "Program to run for `figlet'."
377   :group 'artist-text
378   :type 'string)
379
380
381 (defcustom artist-figlet-default-font "standard"
382   "Default font for `figlet'."
383   :group 'artist-text
384   :type 'string)
385
386
387 (defcustom artist-figlet-list-fonts-command
388   ;; list files ending with *.flf in any directory printed by the
389   ;; ``figlet -I2'' command. I think this will not produce more than
390   ;; one directory, but it never hurts to be on the safe side...
391   "for dir in `figlet -I2`; do cd $dir; ls *.flf; done"
392   "Command to run to get list of available fonts."
393   :group 'artist-text
394   :type 'string)
395
396
397 (defcustom artist-spray-interval 0.2
398   "Number of seconds between repeated spraying."
399   :group 'artist
400   :type 'number)
401
402
403 (defcustom artist-spray-radius 4
404   "Size of the area for spraying."
405   :group 'artist
406   :type 'integer)
407
408
409 (defvar artist-spray-chars '(?\s ?. ?- ?+ ?m ?% ?* ?#)
410   ;; This is a defvar, not a defcustom, since the custom
411   ;; package shows lists of characters as a lists of integers,
412   ;; which is confusing
413   "*Characters (``color'') to use when spraying.
414 They should be ordered
415 from the ``lightest'' to the ``heaviest'' since spraying replaces a
416 light character with the next heavier one.")
417
418
419 (defvar artist-spray-new-char ?.
420   "*Initial character to use when spraying.
421 This character is used if spraying upon a character that is
422 not in `artist-spray-chars'.  The character defined by this variable
423 should be in `artist-spray-chars', or spraying will behave
424 strangely.")
425
426
427 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
428 ;; End of user options
429
430
431 ;; Internal variables
432 ;;
433 (defvar artist-mode nil
434   "Non-nil to enable `artist-mode' and nil to disable.")
435 (make-variable-buffer-local 'artist-mode)
436
437 (defvar artist-mode-name " Artist"
438   "Name of artist mode beginning with a space (appears in the mode-line).")
439
440 (defvar artist-curr-go 'pen-char
441   "Current selected graphics operation.")
442 (make-variable-buffer-local 'artist-curr-go)
443
444 (defvar artist-line-char-set nil
445   "Boolean to tell whether user has set some char to use when drawing lines.")
446 (make-variable-buffer-local 'artist-line-char-set)
447
448 (defvar artist-line-char nil
449   "Char to use when drawing lines.")
450 (make-variable-buffer-local 'artist-line-char)
451
452 (defvar artist-fill-char-set nil
453   "Boolean to tell whether user has set some char to use when filling.")
454 (make-variable-buffer-local 'artist-fill-char-set)
455
456 (defvar artist-fill-char nil
457   "Char to use when filling.")
458 (make-variable-buffer-local 'artist-fill-char)
459
460 (defvar artist-erase-char ?\s
461   "Char to use when erasing.")
462 (make-variable-buffer-local 'artist-erase-char)
463
464 (defvar artist-default-fill-char ?.
465   "Char to use when a fill-char is required but none is set.")
466 (make-variable-buffer-local 'artist-default-fill-char)
467
468 ; This variable is not buffer local
469 (defvar artist-copy-buffer nil
470   "Copy buffer.")
471
472 (defvar artist-draw-region-min-y 0
473   "Line-number for top-most visited line for draw operation.")
474 (make-variable-buffer-local 'artist-draw-region-min-y)
475
476 (defvar artist-draw-region-max-y 0
477   "Line-number for bottom-most visited line for draw operation.")
478 (make-variable-buffer-local 'artist-draw-region-max-y)
479
480 (defvar artist-borderless-shapes nil
481   "When non-nil, draw shapes without border.
482 The fill char is used instead, if it is set.")
483 (make-variable-buffer-local 'artist-borderless-shapes)
484
485 (defvar artist-prev-next-op-alist nil
486   "Assoc list for looking up next and/or previous draw operation.
487 The structure is as follows:  (OP . (PREV-OP . NEXT-OP))
488 where the elements are as follows:
489 * OP is an atom: the KEY-SYMBOL in the `artist-mt' structure
490 * PREV-OP and NEXT-OP are strings: the KEYWORD in the `artist-mt' structure
491
492 This variable is initialized by the artist-make-prev-next-op-alist function.")
493
494 (eval-when-compile
495   ;; Make rect available at compile-time
496   (require 'rect)                       ; for interfacing with rect
497   (require 'reporter)                   ; the bug-reporting tool
498   (require 'picture))                   ; picture mode compatibility
499
500 (if artist-interface-with-rect
501     (require 'rect))
502
503 (require 'reporter)
504
505 (if artist-picture-compatibility
506     (require 'picture))
507
508 ;; Variables that are made local in artist-mode-init
509 (defvar artist-key-is-drawing nil)
510 (defvar artist-key-endpoint1 nil)
511 (defvar artist-key-poly-point-list nil)
512 (defvar artist-key-shape nil)
513 (defvar artist-key-draw-how nil)
514 (defvar artist-popup-menu-table nil)
515 (defvar artist-key-compl-table nil)
516 (defvar artist-rb-save-data nil)
517 (defvar artist-arrow-point-1 nil)
518 (defvar artist-arrow-point-2 nil)
519
520 (defvar artist-mode-map
521   (let ((map (make-sparse-keymap)))
522     (setq artist-mode-map (make-sparse-keymap))
523     (define-key map [down-mouse-1] 'artist-down-mouse-1)
524     (define-key map [S-down-mouse-1] 'artist-down-mouse-1)
525     (define-key map [down-mouse-2] 'artist-mouse-choose-operation)
526     (define-key map [S-down-mouse-2] 'artist-mouse-choose-operation)
527     (define-key map [down-mouse-3] 'artist-down-mouse-3)
528     (define-key map [S-down-mouse-3] 'artist-down-mouse-3)
529     (define-key map [C-mouse-4] 'artist-select-prev-op-in-list)
530     (define-key map [C-mouse-5] 'artist-select-next-op-in-list)
531     (define-key map "\r" 'artist-key-set-point) ; return
532     (define-key map [up] 'artist-previous-line)
533     (define-key map "\C-p" 'artist-previous-line)
534     (define-key map [down] 'artist-next-line)
535     (define-key map "\C-n" 'artist-next-line)
536     (define-key map [left] 'artist-backward-char)
537     (define-key map "\C-b" 'artist-backward-char)
538     (define-key map [right] 'artist-forward-char)
539     (define-key map "\C-f" 'artist-forward-char)
540     (define-key map "<" 'artist-toggle-first-arrow)
541     (define-key map ">" 'artist-toggle-second-arrow)
542     (define-key map "\C-c\C-a\C-e" 'artist-select-erase-char)
543     (define-key map "\C-c\C-a\C-f" 'artist-select-fill-char)
544     (define-key map "\C-c\C-a\C-l" 'artist-select-line-char)
545     (define-key map "\C-c\C-a\C-o" 'artist-select-operation)
546     (define-key map "\C-c\C-a\C-r" 'artist-toggle-rubber-banding)
547     (define-key map "\C-c\C-a\C-t" 'artist-toggle-trim-line-endings)
548     (define-key map "\C-c\C-a\C-s" 'artist-toggle-borderless-shapes)
549     (define-key map "\C-c\C-c"     'artist-mode-off)
550     (define-key map "\C-c\C-al"    'artist-select-op-line)
551     (define-key map "\C-c\C-aL"    'artist-select-op-straight-line)
552     (define-key map "\C-c\C-ar"    'artist-select-op-rectangle)
553     (define-key map "\C-c\C-aR"    'artist-select-op-square)
554     (define-key map "\C-c\C-as"    'artist-select-op-square)
555     (define-key map "\C-c\C-ap"    'artist-select-op-poly-line)
556     (define-key map "\C-c\C-aP"    'artist-select-op-straight-poly-line)
557     (define-key map "\C-c\C-ae"    'artist-select-op-ellipse)
558     (define-key map "\C-c\C-ac"    'artist-select-op-circle)
559     (define-key map "\C-c\C-at"    'artist-select-op-text-see-thru)
560     (define-key map "\C-c\C-aT"    'artist-select-op-text-overwrite)
561     (define-key map "\C-c\C-aS"    'artist-select-op-spray-can)
562     (define-key map "\C-c\C-az"    'artist-select-op-spray-set-size)
563     (define-key map "\C-c\C-a\C-d" 'artist-select-op-erase-char)
564     (define-key map "\C-c\C-aE"    'artist-select-op-erase-rectangle)
565     (define-key map "\C-c\C-av"    'artist-select-op-vaporize-line)
566     (define-key map "\C-c\C-aV"    'artist-select-op-vaporize-lines)
567     (define-key map "\C-c\C-a\C-k" 'artist-select-op-cut-rectangle)
568     (define-key map "\C-c\C-a\M-w" 'artist-select-op-copy-rectangle)
569     (define-key map "\C-c\C-a\C-y" 'artist-select-op-paste)
570     (define-key map "\C-c\C-af"    'artist-select-op-flood-fill)
571     (define-key map "\C-c\C-a\C-b" 'artist-submit-bug-report)
572     map)
573   "Keymap for `artist-minor-mode'.")
574
575 (defvar artist-replacement-table (make-vector 256 0)
576   "Replacement table for `artist-replace-char'.")
577
578
579 ;;;
580 ;;; The table of graphic operations
581 ;;;
582 (defvar artist-mt
583   ;; Implementation note: Maybe this should be done using a structure
584   ;; in the cl package?
585   ;;
586   '(
587     (menu
588      ("Drawing"
589       ((function-call
590         ( "Undo"                do-undo         undo))
591
592        (separator )
593        (graphics-operation
594         ("Pen" (("Pen" pen-char "pen-c"
595                  artist-no-arrows nil
596                  nil nil nil
597                  artist-do-continously
598                  artist-pen
599                  (nil))
600                 ("Pen Line" pen-line "pen-l"
601                  artist-arrows artist-pen-set-arrow-points
602                  artist-pen-reset-last-xy nil nil
603                  artist-do-continously
604                  artist-pen-line
605                  (nil)))))
606
607        (graphics-operation
608         ("Line" (("line" line "line"
609                   artist-arrows artist-set-arrow-points-for-2points
610                   nil nil nil
611                   2
612                   artist-draw-line
613                   (artist-undraw-line
614                    artist-nil nil))
615                  ("straight line" s-line "sline"
616                   artist-arrows artist-set-arrow-points-for-2points
617                   nil nil nil
618                   2
619                   artist-draw-sline
620                   (artist-undraw-sline
621                    artist-nil nil)))))
622
623        (graphics-operation
624         ("Rectangle" (("rectangle" rect "rect"
625                        artist-no-arrows nil
626                        nil nil nil
627                        2
628                        artist-draw-rect
629                        (artist-undraw-rect
630                         artist-t-if-fill-char-set artist-fill-rect))
631                       ("square" square "square"
632                        artist-no-arrows nil
633                        nil nil nil
634                        2
635                        artist-draw-square
636                        (artist-undraw-square
637                         artist-t-if-fill-char-set artist-fill-square)))))
638
639        (graphics-operation
640         ("Poly-line" (("poly-line" polyline "poly"
641                        artist-arrows artist-set-arrow-points-for-poly
642                        nil nil nil
643                        artist-do-poly
644                        artist-draw-line
645                        (artist-undraw-line
646                         artist-nil nil))
647                       ("straight poly-line" spolyline "s-poly"
648                        artist-arrows artist-set-arrow-points-for-poly
649                        nil nil nil
650                        artist-do-poly
651                        artist-draw-sline
652                        (artist-undraw-sline
653                         artist-nil nil)))))
654
655        (graphics-operation
656         ("Ellipse" (("ellipse" ellipse "ellipse"
657                      artist-no-arrows nil
658                      nil nil nil
659                      2
660                      artist-draw-ellipse
661                      (artist-undraw-ellipse
662                       artist-t-if-fill-char-set artist-fill-ellipse))
663                     ("circle" circle "circle"
664                      artist-no-arrows nil
665                      nil nil nil
666                      2
667                      artist-draw-circle
668                      (artist-undraw-circle
669                       artist-t-if-fill-char-set artist-fill-circle)))))
670
671        (graphics-operation
672         ("Text" (("text see-thru" text-thru "text-thru"
673                    artist-no-arrows nil
674                    nil nil nil
675                    1
676                    artist-text-see-thru
677                    nil)
678                   ("text overwrite" text-ovwrt "text-ovwrt"
679                    artist-no-arrows nil
680                    nil nil nil
681                    1
682                    artist-text-overwrite
683                    nil))))
684
685        (graphics-operation
686         ("Spray-can" (("spray-can" spray-can "spray-can"
687                        artist-no-arrows nil
688                        nil nil nil
689                        artist-do-continously
690                        artist-spray
691                        (artist-spray-get-interval))
692                       ("spray set size" spray-get-size "spray-size"
693                        artist-no-arrows nil
694                        nil artist-spray-clear-circle artist-spray-set-radius
695                        2
696                        artist-draw-circle
697                        (artist-undraw-circle
698                         artist-nil nil)))))
699
700        (graphics-operation
701         ("Erase" (("erase char" erase-char "erase-c"
702                    artist-no-arrows nil
703                    nil nil nil
704                    artist-do-continously
705                    artist-erase-char
706                    (nil))
707                   ("erase rectangle" erase-rect "erase-r"
708                    artist-no-arrows nil
709                    nil nil nil
710                    2
711                    artist-draw-rect
712                    (artist-undraw-rect
713                     artist-t artist-erase-rect)))))
714
715        (graphics-operation
716         ("Vaporize" (("vaporize line" vaporize-line "vaporize-1"
717                    artist-no-arrows nil
718                    nil nil nil
719                    1
720                    artist-vaporize-line
721                    nil)
722                   ("vaporize lines" vaporize-lines "vaporize-n"
723                    artist-no-arrows nil
724                    nil nil nil
725                    1
726                    artist-vaporize-lines
727                    nil)))))))
728
729     (menu
730      ("Edit"
731       ((graphics-operation
732         ("Cut" (("cut rectangle" cut-r "cut-r"
733                  artist-no-arrows nil
734                  nil nil nil
735                  2
736                  artist-draw-rect
737                  (artist-undraw-rect
738                   artist-t artist-cut-rect)
739                 ("cut square" cut-s "cut-s"
740                  artist-no-arrows nil
741                  nil nil nil
742                  2
743                  artist-draw-square
744                  (artist-undraw-square
745                   artist-t artist-cut-square))))))
746
747        (graphics-operation
748         ("Copy" (("copy rectangle" copy-r "copy-r"
749                   artist-no-arrows nil
750                   nil nil nil
751                   2
752                   artist-draw-rect
753                   (artist-undraw-rect
754                    artist-t artist-copy-rect)
755                  ("copy square" copy-s "copy-s"
756                   artist-no-arrows nil
757                   nil nil nil
758                   2
759                   artist-draw-square
760                   (artist-undraw-square
761                    artist-t artist-copy-square))))))
762
763        (graphics-operation
764         ("Paste" (("paste" paste "paste"
765                    artist-no-arrows nil
766                    nil nil nil
767                    1
768                    artist-paste
769                    nil)
770                   ("paste" paste "paste"
771                    artist-no-arrows nil
772                    nil nil nil
773                    1
774                    artist-paste
775                    nil))))
776
777        (graphics-operation
778         ("Flood-fill" (("flood-fill" flood-fill "flood"
779                         artist-no-arrows nil
780                         nil nil nil
781                         1
782                         artist-flood-fill
783                         nil)
784                        ("flood-fill" flood-fill "flood"
785                         artist-no-arrows nil
786                         nil nil nil
787                         1
788                         artist-flood-fill
789                         nil)))))))
790
791     (menu
792      ("Settings"
793       ((function-call
794         ("Set Fill"     set-fill        artist-select-fill-char))
795
796        (function-call
797         ("Set Line"     set-line        artist-select-line-char))
798
799        (function-call
800         ("Set Erase"    set-erase       artist-select-erase-char))
801
802        (function-call
803         ("Rubber-banding" rubber-band   artist-toggle-rubber-banding))
804
805        (function-call
806         ("Trimming"     trimming        artist-toggle-trim-line-endings))
807
808        (function-call
809         ("Borders"      borders         artist-toggle-borderless-shapes))
810
811        (function-call
812         ("Spray-chars"  spray-chars     artist-select-spray-chars)))))
813
814   ) ;; end of list
815
816   "Master Table for `artist-mode'.
817 This table is primarily a table over the different graphics operations
818 available in artist mode, but it also holds layout information for the
819 popup menu.
820
821 The master table is a list of table elements.  The elements of this table
822 have the layout
823
824   (TAG INFO-PART)
825
826 There are three kinds of TAG:
827