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