File: mgp-mode-cd.el

package info (click to toggle)
mgp 1.13a%2Bupstream20090219-8
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 3,232 kB
  • ctags: 3,009
  • sloc: ansic: 32,357; sh: 4,295; lisp: 1,405; yacc: 944; lex: 264; makefile: 130; perl: 117; awk: 9
file content (291 lines) | stat: -rw-r--r-- 9,916 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
;; mgp-mode-cd.el - An Emacs major-mode for editing MagicPoint files.

;; Filename: mgp-mode-cd.el
;; Author:   Christoph Dalitz
;; Version:  1.6
;; License:  GNU General Public License
;; Homepage: http://lionel.kr.hsnr.de/~dalitz/data/software/mgp/mgp.html

;; Abstract:
;;
;;  This mode is called "mgp-mode-cd" in order to distinguish it from the 
;;  official "mgp-mode" that is shipped with MagicPoint. In contrast to the
;;  official "mgp-mode", which I find too complicated for the average user,
;;  this mode focuses on ease of use: all actions are accessible from a
;;  self-explanatory main menu entry. Moreover this mode supports the
;;  option to preview only the current page.

;; Installation:
;;
;;  1) Optionally, byte-compile this file
;;  2) Put this file in a directory Emacs can find
;;  3) Tell Emacs when to load this file
;;  4) Customize some variables for your system
;;
;; ad 1)
;;  Byte-compilation speeds up the load time for this mode
;;  and is therefore recommended. Just load this file into
;;  Emacs and select "Byte-compile This File" from the
;;  "Emacs-Lisp" main menu. This will create the compiled
;;  file with the extension "elc".
;;
;; ad 2)
;;  The directories that Emacs searches are given by the 
;;  load-path variable, which you can query within Emacs with
;;     ESC-x describe-variable RET load-path Ret
;;  To add a directory (eg. ~/.emacs) to load-path, add 
;;  the following code to your $HOME/.emacs file:
;;     (add-to-list 'load-path "~/elisp")
;;
;; ad 3)
;;  Add the following lines to your $HOME/.emacs file:
;;     (autoload 'mgp-mode "mgp-mode-cd" "MGP mode." t)
;;     (add-to-list 'auto-mode-alist '("\\.mgp$" . mgp-mode))
;;  The first line tells Emacs to load mgp-mode-cd.elc or
;;  mgp-mode-cd.el when the command 'mgp-mode' is called.
;;  The second line tells emacs to invoke the command 'mgp-mode'
;;  when a file with a name ending on ".mgp" is opened.
;;
;; ad 4)
;;  Some variables might need adjustment to your local system
;;  environment. You can do it in your $HOME/.emacs file with 
;;  commands like
;;     (setq mgp-command     "mgp -x vflib")
;;     (setq mgp-tmpfile     "/tmp/preview.mgp")
;;     (setq mgp-helpcommand "zcat /usr/share/doc/mgp/SYNTAX.gz | xless")
;;  You can also set these variables interactively from the
;;  entry "Options" in the "MGP" main menu that is created
;;  when mgp-mode is entered.

;; History
;;
;;   01.05.2001  first creation for GNU Emacs
;;   27.02.2002  added installation instructions
;;               added options menu for setting of mgp command line
;;               bugfix preview-file when cursor in header
;;   01.03.2002  bugfix in mark-page for last page
;;   10.05.2002  new option "Syntax Help" in MGP main menu
;;   30.05.2002  "Syntax Help" now displayed asynchronously
;;               ported to Xemacs
;;   12.06.2002  workaround for undefined builtin-face in Xemacs
;;               preview-page now also works when cursor in preamble
;;   12.12.2002  added support for ispell

;; List of functions called when mgp-mode is entered
(defcustom mgp-mode-hook '()
  "*Hook for customising `mgp-mode'."
  :type 'hook
  :group 'Mgp)

;; custom variables
(defcustom mgp-command "mgp -x vflib"
  "mgp command line.
Must be adjusted according to the compilation options,
eg. 'mgp -x vflib' when mgp is compile with vflib, but vflib 
is not installed."
  :group 'Mgp)
(defcustom mgp-tmpfile "/tmp/page.mgp"
  "Temporary file generated when only parts are previewed."
  :group 'Mgp)
(defcustom mgp-helpcommand "zcat /usr/share/doc/mgp/SYNTAX.gz | xless"
  "Command for display of MGP syntax documentation."
  :group 'Mgp)

;; shortcut key bindings
(defvar mgp-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "C-c C-b") 'mgp-preview-file)
    (define-key map (kbd "C-c C-p") 'mgp-preview-page)
    (define-key map (kbd "C-c C-c") 'mgp-comment-region)
    (define-key map (kbd "C-c C-u") 'mgp-uncomment-region)
    (define-key map (kbd "C-c C-m") 'mgp-mark-page)
    map)
  "Mode map used for `mgp-mode'.")

;; main menu entry
(easy-menu-define
 mgp-mode-menu mgp-mode-map
 "Menu for `mgp-mode'."
 '("MGP"
   ["Preview Buffer" mgp-preview-file ]
   ["Preview Page" mgp-preview-page ]
   ;; automatic menu deactivation when no region marked
   ;; only works with GNU Emacs and crashes (!) Xemacs
   ;; ["Comment Region" mgp-comment-region (region-beginning) ]
   ;; ["Uncomment Region" mgp-uncomment-region (region-beginning) ]
   ["Comment Region" mgp-comment-region ]
   ["Uncomment Region" mgp-uncomment-region ]
   ["Mark Page" mgp-mark-page ]
   ["Syntax Help" (start-process-shell-command "bla" nil mgp-helpcommand) ]
   ["-" nil ]
   ["Options" (customize-group "Mgp") ]
))

;; syntax table 
;; currently not used; see comment below font-lock-defaults
(defvar mgp-mode-syntax-table 
  (let ((table (make-syntax-table)))
    ;; comments start with # and end with newline
    (modify-syntax-entry ?\# "<" table)
    (modify-syntax-entry 10  ">" table)
    (modify-syntax-entry 12  ">" table)
    table)
  "Syntax table used in 'mgp-mode'.")

(defvar mgp-mode-font-lock-keywords nil
  "Mgp keywords used by font-lock.")
(if mgp-mode-font-lock-keywords ()
  (let ()
    (setq mgp-mode-font-lock-keywords
	  (list 
       ;; comments
	   (cons "^#.*" 'font-lock-comment-face)
	   (cons "^%%.*" 'font-lock-comment-face)
       ;; new page
	   (cons "^%page" 'font-lock-string-face)
       ;; filters
	   (cons "^%filter.*" 'font-lock-builtin-face)
	   (cons "^%endfilter.*" 'font-lock-builtin-face)
       ;; other format parameters
	   (cons "^%.*" 'font-lock-function-name-face)
	  ))
))

;; function definitions
(defun mgp-comment-region (start end)
  "Comments out the current region with '# '."
  (interactive "r")
  (goto-char end) (beginning-of-line) (setq end (point))
  (goto-char start) (beginning-of-line) (setq start (point))
  (let ()
  (save-excursion
	(save-restriction
	  (narrow-to-region start end)
	  (while (not (eobp))
		(insert "# ")
		(forward-line 1)))))
)
(defun mgp-uncomment-region (start end)
  "Remove '# ' comments from current region."
  (interactive "r")
  (goto-char end) (beginning-of-line) (setq end (point))
  (goto-char start) (beginning-of-line) (setq start (point))
  (let ((prefix-len '2))
  (save-excursion
	(save-restriction
	  (narrow-to-region start end)
	  (while (not (eobp))
		(if (string= "# "
					 (buffer-substring
					  (point) (+ (point) prefix-len)))
			(delete-char prefix-len))
		(forward-line 1)))))
)
(defun mgp-preview-file ()
  "Previews current file with mgp.
Starts at the page where the cursor currently is."
  (interactive)
  (save-buffer)
  (save-excursion
    (let ((pnum (string-to-number (how-many "^%page"))))
      ;; calculate current page number
      (goto-char (point-min))
      (setq pnum (- (string-to-number (how-many "^%page")) pnum))
	  (when (< pnum 1) (setq pnum 1))
      ;;(y-or-n-p (format "Pages %d" pnum))
      (shell-command
       (format "%s -p %d %s" mgp-command pnum
               (shell-quote-argument buffer-file-name)))
      ))
)
(defun mgp-mark-page ()
  "Marks the current page.
In mgp-mode, one page is one paragraph. Thus you can mark
a page with `mark-paragraph' as well."
  (interactive)
  (mark-paragraph)
)
(defun mgp-preview-page ()
  "Previews current page with mgp."
  (interactive)
  (save-buffer)
  ;; write preamble...
  (save-excursion
	(goto-char (point-min))
	(mgp-mark-page)
	(write-region (region-beginning) (region-end) mgp-tmpfile)
	)
  ;; ...and current page
  (save-excursion
	;; move to first page when cursor before first page
    (let ((pnum (string-to-number (how-many "^%page"))))
	  (save-excursion
		(goto-char (point-min))
		(setq pnum (- (string-to-number (how-many "^%page")) pnum)))
	  (when (< pnum 1) (re-search-forward "^%page" nil t)))
	(mgp-mark-page)
	(append-to-file (region-beginning) (region-end) mgp-tmpfile)
	(shell-command (format "%s %s" mgp-command mgp-tmpfile))
	)
)

;;;###autoload
(defun mgp-mode ()
  "Major mode for editing mgp2 source.
Comments etc. are highlighted with font-lock. There are also a 
number of commands that make editing and working with MGP files 
more convenient. These commands are available from the main menu 
`MGP' or via the following shortcuts:

\\[mgp-preview-file]	- Run mgp on the current file.
\\[mgp-comment-region]	- Comments out the current region.
\\[mgp-uncomment-region]	- Uncomments the current region.
\\[mgp-mark-page]	- Marks the current page (== paragraph).
"
  (interactive)
  (kill-all-local-variables)
  (setq major-mode 'mgp-mode)
  (setq mode-name "mgp")

  (use-local-map mgp-mode-map)

  ;; workarounds for xemacs:
  ;; - menu must be explicitly added
  ;; - xemacs uses preprocessor-face instead of builtin-face
  (easy-menu-add mgp-mode-menu mgp-mode-map)
  (if (string-match "XEmacs\\|Lucid" emacs-version)
	  (progn (make-face 'font-lock-builtin-face)
			 (copy-face 'font-lock-preprocessor-face 'font-lock-builtin-face)))

  ;; syntax table is not used (see below)
  (set-syntax-table mgp-mode-syntax-table)
  (make-local-variable 'font-lock-defaults)
  (setq font-lock-defaults '(mgp-mode-font-lock-keywords
				 t t ((?_ . "w") (?. . "w"))))
  ;;            ^^^
  ;; (otherwise syntax table wins and keywords are ignored!)

  ;; paragraph == page
  (make-local-variable 'paragraph-start)
  (setq paragraph-start "[%#]?.*%page") 

  ;; additional options

  ;;(make-local-variable 'require-final-newline)
  ;;(setq require-final-newline t)

  ;;(setq blink-matching-paren t)

  ;; TAB must insert TAB rather than Spaces
  (setq indent-tabs-mode t)

  ;; let ispell skip %-directives
  (make-local-variable 'ispell-skip-region-alists)
  (add-to-list 'ispell-skip-region-alist (list "^%.*$"))

  ;; case insensitive pattern matching
  (setq font-lock-keywords-case-fold-search t)
  (put 'mgp-mode 'font-lock-keywords-case-fold-search t)

  (run-hooks 'mgp-mode-hook)
)