]> code.delx.au - gnu-emacs-elpa/blob - packages/jgraph-mode/jgraph-mode.el
* Debbugs.wsdl: Add get_usertag specification.
[gnu-emacs-elpa] / packages / jgraph-mode / jgraph-mode.el
1 ;;; jgraph-mode.el --- Major mode for Jgraph files
2
3 ;; Copyright (C) 2006, 2011 Free Software Foundation, Inc
4
5 ;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
6 ;; Keywords: tex, wp
7
8 ;; This file is part of GNU Emacs.
9
10 ;; GNU Emacs is free software: you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation, either version 3 of the License, or
13 ;; (at your option) any later version.
14
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
22
23 ;;; Commentary:
24
25 ;; Simple editing mode for the Jgraph graph plotting tool.
26 ;; You can find more info at http://web.eecs.utk.edu/~plank/plank/jgraph/jgraph.html
27
28 ;;; Code:
29
30 (defgroup jgraph-mode ()
31 "Major mode for Jgraph files."
32 :group 'tools)
33
34 (defvar jgraph-mode-map
35 (let ((map (make-sparse-keymap)))
36 map)
37 "Keymap for `jgraph-mode'.")
38
39 ;; (easy-menu-define jgraph-mode-menu jgraph-mode-map
40 ;; "Menu for `jgraph-mode'."
41 ;; '("Jgraph"
42 ;; ["Do some stuff" jgraph-do-bar :active mark-active]
43 ;; "..."
44 ;; ["Do some other" jgraph-do-foo]
45 ;; ("Sub-jgraph"
46 ;; ["Haha" jgraph-crash])
47 ;; ...))
48
49 (defvar jgraph-mode-syntax-table
50 (let ((st (make-syntax-table)))
51 ;; tokens are made of any non-whitespace chars.
52 (map-char-table (lambda (c v) (if (not (memq (car v) '(0 2 3)))
53 (modify-syntax-entry c "_" st)))
54 st)
55 (modify-syntax-entry ?\( "_ 1n" st)
56 (modify-syntax-entry ?\) "_ 4n" st)
57 (modify-syntax-entry ?\* "_ 23" st)
58 st)
59 "Syntax table for `jgraph-mode'.")
60
61 (defun jgraph-extract-commands ()
62 (let ((sections nil)
63 (tok-cmds nil))
64 (goto-char (point-min))
65 (while (and (re-search-forward "^\\.RE" nil t)
66 (re-search-forward "^\\.B \\(.*\\)" nil t))
67 (let ((section (downcase (match-string 1)))
68 (commands nil)
69 (end (save-excursion
70 (and (re-search-forward "^\\.RE" nil t)
71 (match-beginning 0)))))
72 (setq section (replace-regexp-in-string "simple" "" section))
73 (setq section (replace-regexp-in-string "advanced" "" section))
74 (setq section (replace-regexp-in-string "editing" "" section))
75 (setq section (replace-regexp-in-string "commands" "" section))
76 (setq section (replace-regexp-in-string "\\\\" "" section))
77 (setq section (replace-regexp-in-string "\\` *" "" section))
78 (setq section (replace-regexp-in-string " *\\'" "" section))
79 (setq section (replace-regexp-in-string " " "-" section))
80 (setq section (intern section))
81 (while (re-search-forward "^\\.TP\n\\(?:\\.B \\|\\\\fB\\)\\([^ :\t\n\\]+\\)\\([ {\\fI]*token\\)?" end 'move)
82 (let ((cmd (match-string-no-properties 1)))
83 (if (match-end 2) (add-to-list 'tok-cmds cmd))
84 (add-to-list 'commands cmd)))
85 (setq commands (nreverse commands))
86 (let ((sec (assoc section sections)))
87 (if sec (nconc sec commands)
88 (push (cons section commands) sections)))))
89 (nreverse (cons (cons 'token tok-cmds) sections))))
90
91 (defconst jgraph-commands
92 ;; Obtained by running (jgraph-extract-commands) in the jgraph.1 nroff doc.
93 '((top-level-description "newgraph" "graph" "copygraph" "newpage" "X" "Y"
94 "bbox" "preamble" "epilogue")
95 (graph "xaxis" "yaxis" "newcurve" "curve" "newline" "copycurve" "title"
96 "legend" "newstring" "string" "copystring" "border" "noborder"
97 "clip" "noclip" "inherit_axes" "x_translate" "y_translate" "X" "Y")
98 (axis "linear" "log" "min" "max" "size" "log_base" "hash" "shash" "mhash"
99 "precision" "hash_format" "label" "draw_at" "nodraw" "draw"
100 "grid_lines" "no_grid_lines" "mgrid_lines" "no_mgrid_lines" "gray"
101 "color" "grid_gray" "grid_color" "mgrid_gray" "mgrid_color" "hash_at"
102 "mhash_at" "hash_label" "hash_labels" "hash_scale"
103 "draw_hash_marks_at" "draw_hash_labels_at" "auto_hash_marks"
104 "no_auto_hash_marks" "auto_hash_labels" "no_auto_hash_labels"
105 "draw_axis" "no_draw_axis" "draw_axis_label" "no_draw_axis_label"
106 "draw_hash_marks" "no_draw_hash_marks" "draw_hash_labels"
107 "no_draw_hash_labels")
108 (curve "pts" "x_epts" "y_epts" "marktype" "marksize" "mrotate" "gray"
109 "color" "fill" "cfill" "pattern" "poly" "nopoly" "pfill" "pcfill"
110 "ppattern" "gmarks" "postscript" "eps" "larrows" "rarrows"
111 "nolarrows" "norarrows" "larrow" "rarrow" "nolarrow" "norarrow"
112 "asize" "afill" "apattern" "linetype" "glines" "linethickness"
113 "bezier" "nobezier" "clip" "noclip" "label")
114 (label "x" "y" "font" "fontsize" "linesep" "hjl" "hjc" "hjr" "vjt" "vjc"
115 "vjb" "rotate" "lgray" "lcolor")
116 (legend "on" "off" "linelength" "linebreak" "midspace" "defaults" "left"
117 "top" "bottom" "x" "y" "custom")
118 (hash-label "at")
119 ;; Commands that can be followed by a token.
120 (token "apattern" "eps" "postscript" "ppattern" "pattern" "hash_format"
121 "epilogue" "preamble")))
122
123 (defconst jgraph-file-include-commands
124 '("include" "preamble" "epilogue" "postscript" "eps"))
125
126 (defvar jgraph-font-lock-keywords
127 `((,(concat "\\_<" (regexp-opt jgraph-file-include-commands)
128 "[ \t]+\\(\\sw+\\)")
129 (1 font-lock-constant-face))
130 (,(concat "^" (regexp-opt
131 (cdr (assoc 'top-level-description jgraph-commands)))
132 "\\_>")
133 . font-lock-function-name-face)
134 (,(concat "\\_<"
135 (regexp-opt (cons "include"
136 (apply 'append (mapcar 'cdr jgraph-commands))))
137 "\\_>") . font-lock-keyword-face)
138 )
139 "Keyword highlighting specification for `jgraph-mode'.")
140
141 ;; (defvar jgraph-imenu-generic-expression
142 ;; '(("Vars" "^defvar[ \t]+\\(\\(\\sw\\|\\s_\\)+\\)" 1)
143 ;; (nil "^function[ \t]+\\(\\(\\sw\\|\\s_\\)+\\)" 1)
144 ;; ...)
145 ;; "Regex patterns for the index menu of `jgraph-mode'.")
146
147 ;; (defvar jgraph-outline-regexp "(\\|;;;+"
148 ;; "Regexp for `outline-minor-mode' in `jgraph-mode'.")
149
150 ;; Abbreviations and Skeletons
151
152 ;; (define-skeleton jgraph-insert-if
153 ;; "Jgraph mode skeleton for if..then expressions."
154 ;; nil
155 ;; "if " _ \n "then " _ \n "else " _ \n "fi" \n)
156
157 ;; (define-skeleton jgraph-insert-begend
158 ;; "Jgraph mode skeleton for begin<x>...end<x> expressions."
159 ;; "Block name: "
160 ;; "begin<" str ">" \n _ \n "end<" str ">" \n)
161
162 ;; (define-abbrev-table 'jgraph-mode-abbrev-table
163 ;; '(("if" "" jgraph-insert-if nil t)
164 ;; ("cwcc" "call-with-current-continuation" nil nil t)
165 ;; ("begin" "" jgraph-insert-begend nil t)
166 ;; ))
167
168 ;;;###autoload
169 (add-to-list 'auto-mode-alist '("\\.jgr\\'" . jgraph-mode))
170
171 ;;;###autoload
172 (define-derived-mode jgraph-mode prog-mode "Jgraph"
173 "A major mode for editing Jgraph files."
174 (set (make-local-variable 'comment-start) "(* ")
175 (set (make-local-variable 'comment-start-skip) "\\_<(\\*\\_>[ \t]*")
176 (set (make-local-variable 'comment-end) " *)")
177 (set (make-local-variable 'comment-start-skip) "[ \t]*\\_<\\*)\\_>")
178 (set (make-local-variable 'font-lock-defaults)
179 '(jgraph-font-lock-keywords))
180 (set (make-local-variable 'syntax-propertize-function)
181 (syntax-propertize-rules
182 ;; FIXME: naive(broken) multiline pattern.
183 ("\\s-\\(:\\)\\s-\\(?:.*\\\\\n\\)*.*\\(\n\\)" (1 "|") (2 "|"))))
184 (set (make-local-variable 'indent-line-function) 'jgraph-indent-line)
185 ;; (set (make-local-variable 'imenu-generic-expression)
186 ;; jgraph-imenu-generic-expression)
187 ;; (set (make-local-variable 'outline-regexp) jgraph-outline-regexp)
188 )
189
190 ;;; Indentation
191
192 (defcustom jgraph-indent-offset 4
193 "Basic indentation step size in `jgraph-mode'."
194 :group 'jgraph-mode
195 :type 'integer)
196
197 (defun jgraph-indent-line ()
198 "Indent current line of Jgraph code."
199 (interactive)
200 (let* ((savep (point))
201 (indent (or (with-demoted-errors
202 (save-excursion
203 (forward-line 0)
204 (skip-chars-forward " \t")
205 (if (>= (point) savep) (setq savep nil))
206 (jgraph-indent-calculate)))
207 'noindent)))
208 (if (not (numberp indent))
209 indent
210 (setq indent (max indent 0))
211 (if savep
212 (save-excursion (indent-line-to indent))
213 (indent-line-to indent)))))
214
215 (defun jgraph-indent-calculate ()
216 "Return the column to which the current line should be indented."
217 (save-excursion
218 (skip-chars-forward " \t")
219 (or (when (looking-at (concat (regexp-opt
220 (cdr (assoc 'top-level-description
221 jgraph-commands)))
222 "\\_>"))
223 0)
224 'noindent)))
225
226 (provide 'jgraph-mode)
227 ;;; jgraph-mode.el ends here