yatex

view yatexflt.el @ 522:ce46889a743d

Add yatexflt.el to manifest
author HIROSE Yuuji <yuuji@gentei.org>
date Sat, 13 Jan 2018 20:57:58 +0900
parents dfb71acdec98
children b1896ef49747
line source
1 ;;; yatexflt.el --- YaTeX filter command utilizer -*- coding: sjis -*-
2 ;;;
3 ;;; (c)1993-2018 by HIROSE Yuuji.[yuuji@yatex.org]
4 ;;; Last modified Tue Jan 9 13:28:56 2018 on firestorm
5 ;;; $Id$
7 ;;; Commentary:
8 ;;;
9 ;;; This lisp enables passing inline text to some external filter
10 ;;; command to generate files such as graphic files.
11 ;;;
12 ;;; Typical situation is using blockdiag/dot(graphviz) command to
13 ;;; generate png/pdf file.
14 ;;;
15 ;;; Example:
16 ;;;
17 ;;; [[LaTeX Source]]
18 ;;; %#BEGIN FILTER{foo.pdf}{dot -T %t -o o}
19 ;;; \if0
20 ;;; ===
21 ;;; digraph {
22 ;;; A -> B;
23 ;;; B -> C;
24 ;;; }
25 ;;; ===
26 ;;; \fi
27 ;;; %#END
28 ;;; \includegraphics{foo.pdf}
29 ;;;
30 ;;; In this case above, when you type `[prefix] t e' between two
31 ;;; `===' lines, the content in a region are fed to dot command as
32 ;;; follows:
33 ;;;
34 ;;; echo TEXT | dot -T pdf -o foo.pdf
35 ;;;
36 ;;; Then foo.pdf file will be generated and the image (as PNG) will
37 ;;; be displayed in the next window.
40 ;;; Code:
41 (require 'yatexlib)
42 (defvar YaTeX-filter-special-env-alist-default
43 '((".blockdiag"
44 "blockdiag -T %t -o %o -"
45 "blockdiag {
46 default_fontsize = 32;
47 A -> B;
48 }")
49 (".seqdiag" "seqdiag -T %t -o %o -"
50 "seqdiag {
51 client -> server [label = \"SYN\"];
52 client <- server [label = \"SYN/ACK\"];
53 client -> server [label = \"ACK\"];}")
54 (".actdiag" "actdiag -T %t -o %o -"
55 "actdiag {
56 sayHo -> ho -> hohoho
57 lane dj {
58 label = \"DJ\"
59 sayHo [label = \"Say Ho\"]; hohoho [label = \"Ho Ho Ho!\"]; }
60 lane mc { label = \"MC\"; ho [label = \"Hooooh!\"]}}")
61 (".nwdiag" "nwdiag -T %t -o %o -"
62 "nwdiag {
63 network ext {
64 address = \"10.1.2.0/24\"
65 router [address = \"10.1.2.1\"]
66 }
67 network int {
68 address = \"192.168.22.0/24\"
69 router [address = \"192.168.22.1\"]
70 websrv [address = \"192.168.22.80\"]
71 cli-1; cli-2
72 }
73 }")
74 (".rackdiag" "rackdiag -T %t -o %o -"
75 "rackdiag {
76 16U;
77 1: UPS [4U]; 5: Storage [3U]; 8: PC [2U]; 8: PC [2U];
78 }")
79 (".dot"
80 "dot -T %t -o %o"
81 "digraph {
82 graph [charset=\"utf-8\"]
83 }
84 bigraph {
85 graph [charset=\"utf-8\"]}"
86 )))
88 (defvar YaTeX-filter-special-env-alist-private nil)
89 (defvar YaTeX-filter-special-env-alist
90 (append YaTeX-filter-special-env-alist-private
91 YaTeX-filter-special-env-alist-default))
93 (defun YaTeX-filter-filter-set-conversion-flag ()
94 (let ((ovl (get 'YaTeX-filter-filter-sentinel 'overlay)))
95 (if ovl ;; When successful conversion met,
96 (progn ;; (1)Set conversion complete flag
97 (add-hook ;; (2)Add hook of seim-automatic
98 'write-file-hooks ;; update of convert to write-
99 'YaTeX-filter-update-all) ;; file hook.
100 (overlay-put ovl 'converted t)))))
102 (defun YaTeX-filter-filter-unset-conversion-flag
103 (ovl after beg end &optional length)
104 (if after (overlay-put ovl 'converted nil)))
107 (defun YaTeX-filter-pngify-sentinel (proc msg)
108 (save-excursion
109 (let ((b (process-buffer proc)) (selw (selected-window))
110 img)
111 (set-buffer b)
112 (cond
113 ((eq (process-status proc) 'run)
114 (put-text-property (point-min) (point-max) 'invisible t))
115 ((eq (process-status proc) 'exit)
116 (set-buffer b)
117 (YaTeX-popup-image
118 (YaTeX-buffer-substring
119 (get 'YaTeX-filter-pngify-sentinel 'start) (point-max))
120 b)
121 (YaTeX-filter-filter-set-conversion-flag))
122 (t
123 (set-buffer b)
124 (remove-text-properties (point-min) (point-max) '(invisible t))
125 (insert "\nProcess aborted %s\n" msg))))))
127 (defvar YaTeX-filter-pdf2png-stdout
128 (cond
129 ((YaTeX-executable-find "convert") "convert -trim %s PNG:-")
130 (t
131 "gs -dNOPAUSE -sDEVICE=png256 -sOutputFile=- -dBATCH -q -r75 %s"))
132 "Command line syntax to convert PDF file to PNG stream")
134 (defun YaTeX-filter-modified-BEGEND-regions ()
135 "Return the list of overlays which contains un-converted text."
136 (save-excursion
137 (save-restriction
138 (widen)
139 (let (r pl (list (overlays-in (point-min) (point-max))))
140 (while list
141 (if (and (overlay-get (car list) 'filter-input)
142 (setq pl (plist-member (overlay-properties (car list))
143 'converted))
144 (not (plist-get pl 'converted)))
145 (setq r (cons (car list) r)))
146 (setq list (cdr list)))
147 (nconc r)
148 r))))
150 (defun YaTeX-filter-update-all ()
151 "Update all destination files from built-in source text."
152 (interactive)
153 (let ((timeout 4)
154 ans ovl (update-list (YaTeX-filter-modified-BEGEND-regions)))
155 (if update-list
156 (save-excursion
157 (save-window-excursion
158 (catch 'abort
159 (while update-list
160 (goto-char (overlay-start (setq ovl (car update-list))))
161 (or (pos-visible-in-window-p)
162 (set-window-start nil (point)))
163 (unwind-protect
164 (progn
165 (overlay-put ovl 'face 'YaTeX-on-the-fly-activated-face)
166 (message "Non-update source found: Update here: %s "
167 "Y)es N)o A)bort")
168 (setq ans (read-char))
169 (cond
170 ((memq ans '(?Y ?y))
171 (YaTeX-filter-BEGEND)
172 (while (and (> (setq timeout (1- timeout)))
173 (eq (process-status "Filter") 'run))
174 (message "Waiting for conversion process to finish")
175 (sit-for 1)))
176 ((memq ans '(?A ?a)) (throw 'abort t))
177 (t nil)))
178 (overlay-put ovl 'face nil))
179 (setq update-list (cdr update-list)))))))
180 ;; Write file hook should return nil
181 nil))
183 (defun YaTeX-filter-filter-sentinel (proc msg)
184 (put 'YaTeX-filter-pngify-sentinel 'start nil)
185 (let ((b (process-buffer proc))
186 (imagefile (get 'YaTeX-filter-filter-sentinel 'outfile))
187 ovl
188 (selw (selected-window)))
189 (save-excursion
190 (cond
191 ((eq (process-status proc) 'run))
192 ((eq (process-status proc) 'exit)
193 (set-buffer b)
194 (remove-images (point-min) (point-max))
195 (if (and (file-regular-p imagefile)
196 (file-readable-p imagefile))
197 (save-excursion
198 (setq buffer-read-only nil)
199 (cond
200 ((string-match "\\.\\(jpg\\|png\\)" imagefile)
201 (erase-buffer)
202 (YaTeX-popup-image imagefile b)
203 (YaTeX-filter-filter-set-conversion-flag))
204 (t ;Convert again to PNG file
205 (goto-char (point-max))
206 (insert "\nConvert Again to PNG file...\n")
207 (put 'YaTeX-filter-pngify-sentinel 'start (point))
208 (set-process-sentinel
209 (start-process
210 "Filter" b ;Safe to reuse
211 shell-file-name YaTeX-shell-command-option
212 (format YaTeX-filter-pdf2png-stdout imagefile))
213 'YaTeX-filter-pngify-sentinel)
214 (set-buffer-multibyte nil)
215 ))
216 (select-window selw)))
217 (YaTeX-preview-image-mode)
218 )
219 (t ;Other status might be an error
220 (set-buffer b)
221 (goto-char (point-max))
222 (insert (format "%s\n" (process-status proc))))))))
224 (defun YaTeX-filter-pass-to-filter (begend-info)
225 "Pass current BEGIN FILTER environment to external command."
226 (put 'YaTeX-filter-filter-sentinel 'outfile nil)
227 ;; begend-info is from YaTeX-in-BEGEND-p: (BEG END ARGS)
228 (let ((b (car begend-info)) (e (nth 1 begend-info))
229 (args (nth 2 begend-info))
230 (p (point)) openb closeb outfile cmdline point-if0 point-fi)
231 (save-excursion
232 (if (and begend-info
233 (string-match "FILTER" args) ;easy test
234 (goto-char (car begend-info))
235 (re-search-forward
236 "FILTER\\s *{\\([^}]+\\)}" e t)
237 (setq outfile (YaTeX-match-string 1))
238 (goto-char (match-end 0))
239 (prog2 ;Step into the second brace
240 (skip-chars-forward "\t ")
241 (looking-at "{") ;Check if 2nd brace surely exists
242 (skip-chars-forward "{")
243 (skip-chars-forward "\t"))
244 (setq openb (point))
245 (condition-case nil
246 (progn (up-list 1) t)
247 (error nil))
248 (setq closeb (1- (point))
249 cmdline (YaTeX-buffer-substring openb closeb))
250 (re-search-forward "^\\\\if0\\>" p t)
251 (setq point-if0 (point))
252 (re-search-forward "^\\\\fi\\>" e t)
253 (setq point-fi (match-beginning 0)))
254 (let*((case-fold-search t)
255 (type (cond
256 ((string-match "\\.png$" outfile) "png")
257 ((string-match "\\.svg$" outfile) "svg")
258 (t "pdf")))
259 (newcmdline (YaTeX-replace-formats
260 cmdline
261 (list (cons "t" type)
262 (cons "o" outfile))))
263 (delim (progn (goto-char point-if0)
264 (forward-line 1)
265 (and (looking-at "\\(.\\)\\1\\1") ;Triple chars
266 (prog1
267 (YaTeX-match-string 0)
268 (forward-line 1)))))
269 (text-start (point))
270 (text-end (if (and delim
271 (re-search-forward
272 (concat "^" (regexp-quote delim))
273 point-fi t))
274 (match-beginning 0)
275 point-fi))
276 (text (YaTeX-buffer-substring text-start text-end))
277 ;;
278 ;; Now it's time to start filter process
279 ;;
280 (procbuf (YaTeX-system newcmdline "Filter" 'force))
281 (proc (get-buffer-process procbuf))
282 ;(procbuf (get-buffer-create " *Filter*"))
283 (ovl (progn
284 (remove-overlays text-start text-end)
285 (make-overlay text-start text-end)))
286 (ovlmodhook ;hook function to reset conv-success flag
287 'YaTeX-filter-filter-unset-conversion-flag))
288 (if proc
289 (progn
290 (overlay-put ovl 'filter-input outfile)
291 (overlay-put ovl 'converted nil)
292 (overlay-put ovl 'modification-hooks (list ovlmodhook))
293 (set-process-coding-system proc 'undecided 'utf-8)
294 (set-process-sentinel proc 'YaTeX-filter-filter-sentinel)
295 (YaTeX-showup-buffer procbuf)
296 (set-buffer procbuf)
297 (setq buffer-read-only nil)
298 (erase-buffer)
299 (insert (format "Starting process `%s'...\n" newcmdline))
300 (set-marker (process-mark proc) (point-max))
301 (process-send-string proc text)
302 (process-send-string proc "\n")
303 (process-send-eof proc) ;Notify stream chunk end
304 (process-send-eof proc) ;Notify real EOF
305 (put 'YaTeX-filter-filter-sentinel 'outfile outfile)
306 (put 'YaTeX-filter-filter-sentinel 'overlay ovl))))))))
308 (defun YaTeX-insert-filter-special (filter list &optional region-p)
309 (let ((f (YaTeX-read-string-or-skip "Output file: ")))
310 (if region-p
311 (if (< (point) (mark)) (exchange-point-and-mark)))
312 (save-excursion (insert "===\n\\fi\n%#END\n"))
313 (and region-p (exchange-point-and-mark))
314 (insert (format "%%#BEGIN FILTER{%s}{%s}\n\\if0\n===\n"
315 f (or (car list) "")))
316 (save-excursion (insert (or (car (cdr list)) "\n") "\n"))))
318 (provide 'yatexflt)
320 ; Local variables:
321 ; fill-prefix: ";;; "
322 ; paragraph-start: "^$\\| \\|;;;$"
323 ; paragraph-separate: "^$\\| \\|;;;$"
324 ; End: