yatex
changeset 518:dfb71acdec98 dev
add yatexflt.el
author | HIROSE Yuuji <yuuji@gentei.org> |
---|---|
date | Tue, 09 Jan 2018 13:14:28 +0900 |
parents | 668632d9392e |
children | a6a80e2b6f5a |
files | yatexflt.el |
diffstat | 1 files changed, 271 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/yatexflt.el Tue Jan 09 13:14:28 2018 +0900 1.3 @@ -0,0 +1,271 @@ 1.4 +;;; yatexflt.el --- YaTeX filter command utilizer -*- coding: sjis -*- 1.5 +;;; 1.6 +;;; (c)1993-2018 by HIROSE Yuuji.[yuuji@yatex.org] 1.7 +;;; Last modified Sun Jan 7 11:38:12 2018 on firestorm 1.8 +;;; $Id$ 1.9 + 1.10 +;;; Commentary: 1.11 +;;; 1.12 +;;; This lisp enables passing inline text to some external filter 1.13 +;;; command to generate files such as graphic files. 1.14 +;;; 1.15 +;;; Typical situation is using blockdiag/dot(graphviz) command to 1.16 +;;; generate png/pdf file. 1.17 +;;; 1.18 +;;; Example: 1.19 +;;; 1.20 +;;; [[LaTeX Source]] 1.21 +;;; %#BEGIN FILTER{foo.pdf}{dot -T %t -o o} 1.22 +;;; \if0 1.23 +;;; === 1.24 +;;; digraph { 1.25 +;;; A -> B; 1.26 +;;; B -> C; 1.27 +;;; } 1.28 +;;; === 1.29 +;;; \fi 1.30 +;;; %#END 1.31 +;;; \includegraphics{foo.pdf} 1.32 +;;; 1.33 +;;; In this case above, when you type `[prefix] t e' between two 1.34 +;;; `===' lines, the content in a region are fed to dot command as 1.35 +;;; follows: 1.36 +;;; 1.37 +;;; echo TEXT | dot -T pdf -o foo.pdf 1.38 +;;; 1.39 +;;; Then foo.pdf file will be generated and the image (as PNG) will 1.40 +;;; be displayed in the next window. 1.41 + 1.42 +;;; Code: 1.43 +(defun YaTeX-filter-filter-set-conversion-flag () 1.44 + (let ((ovl (get 'YaTeX-filter-filter-sentinel 'overlay))) 1.45 + (if ovl ;; When successful conversion met, 1.46 + (progn ;; (1)Set conversion complete flag 1.47 + (add-hook ;; (2)Add hook of seim-automatic 1.48 + 'write-file-hooks ;; update of convert to write- 1.49 + 'YaTeX-filter-update-all) ;; file hook. 1.50 + (overlay-put ovl 'converted t))))) 1.51 + 1.52 +(defun YaTeX-filter-filter-unset-conversion-flag 1.53 + (ovl after beg end &optional length) 1.54 + (if after (overlay-put ovl 'converted nil))) 1.55 + 1.56 + 1.57 +(defun YaTeX-filter-pngify-sentinel (proc msg) 1.58 + (save-excursion 1.59 + (let ((b (process-buffer proc)) (selw (selected-window)) 1.60 + img) 1.61 + (set-buffer b) 1.62 + (cond 1.63 + ((eq (process-status proc) 'run) 1.64 + (put-text-property (point-min) (point-max) 'invisible t)) 1.65 + ((eq (process-status proc) 'exit) 1.66 + (set-buffer b) 1.67 + (YaTeX-popup-image 1.68 + (YaTeX-buffer-substring 1.69 + (get 'YaTeX-filter-pngify-sentinel 'start) (point-max)) 1.70 + b) 1.71 + (YaTeX-filter-filter-set-conversion-flag)) 1.72 + (t 1.73 + (set-buffer b) 1.74 + (remove-text-properties (point-min) (point-max) '(invisible t)) 1.75 + (insert "\nProcess aborted %s\n" msg)))))) 1.76 + 1.77 +(defvar YaTeX-filter-pdf2png-stdout 1.78 + (cond 1.79 + ((YaTeX-executable-find "convert") "convert -trim %s PNG:-") 1.80 + (t 1.81 + "gs -dNOPAUSE -sDEVICE=png256 -sOutputFile=- -dBATCH -q -r75 %s")) 1.82 + "Command line syntax to convert PDF file to PNG stream") 1.83 + 1.84 +(defun YaTeX-filter-modified-BEGEND-regions () 1.85 + "Return the list of overlays which contains un-converted text." 1.86 + (save-excursion 1.87 + (save-restriction 1.88 + (widen) 1.89 + (let (r pl (list (overlays-in (point-min) (point-max)))) 1.90 + (while list 1.91 + (if (and (overlay-get (car list) 'filter-input) 1.92 + (setq pl (plist-member (overlay-properties (car list)) 1.93 + 'converted)) 1.94 + (not (plist-get pl 'converted))) 1.95 + (setq r (cons (car list) r))) 1.96 + (setq list (cdr list))) 1.97 + (nconc r) 1.98 + r)))) 1.99 + 1.100 +(defun YaTeX-filter-update-all () 1.101 + "Update all destination files from built-in source text." 1.102 + (interactive) 1.103 + (let ((timeout 4) 1.104 + ans ovl (update-list (YaTeX-filter-modified-BEGEND-regions))) 1.105 + (if update-list 1.106 + (save-excursion 1.107 + (save-window-excursion 1.108 + (catch 'abort 1.109 + (while update-list 1.110 + (goto-char (overlay-start (setq ovl (car update-list)))) 1.111 + (or (pos-visible-in-window-p) 1.112 + (set-window-start nil (point))) 1.113 + (unwind-protect 1.114 + (progn 1.115 + (overlay-put ovl 'face 'YaTeX-on-the-fly-activated-face) 1.116 + (message "Non-update source found: Update here: %s " 1.117 + "Y)es N)o A)bort") 1.118 + (setq ans (read-char)) 1.119 + (cond 1.120 + ((memq ans '(?Y ?y)) 1.121 + (YaTeX-filter-BEGEND) 1.122 + (while (and (> (setq timeout (1- timeout))) 1.123 + (eq (process-status "Filter") 'run)) 1.124 + (message "Waiting for conversion process to finish") 1.125 + (sit-for 1))) 1.126 + ((memq ans '(?A ?a)) (throw 'abort t)) 1.127 + (t nil))) 1.128 + (overlay-put ovl 'face nil)) 1.129 + (setq update-list (cdr update-list))))))) 1.130 + ;; Write file hook should return nil 1.131 + nil)) 1.132 + 1.133 +(defun YaTeX-filter-filter-sentinel (proc msg) 1.134 + (put 'YaTeX-filter-pngify-sentinel 'start nil) 1.135 + (let ((b (process-buffer proc)) 1.136 + (imagefile (get 'YaTeX-filter-filter-sentinel 'outfile)) 1.137 + ovl 1.138 + (selw (selected-window))) 1.139 + (save-excursion 1.140 + (cond 1.141 + ((eq (process-status proc) 'run)) 1.142 + ((eq (process-status proc) 'exit) 1.143 + (set-buffer b) 1.144 + (remove-images (point-min) (point-max)) 1.145 + (if (and (file-regular-p imagefile) 1.146 + (file-readable-p imagefile)) 1.147 + (save-excursion 1.148 + (setq buffer-read-only nil) 1.149 + (cond 1.150 + ((string-match "\\.\\(jpg\\|png\\)" imagefile) 1.151 + (erase-buffer) 1.152 + (YaTeX-popup-image imagefile b) 1.153 + (YaTeX-filter-filter-set-conversion-flag)) 1.154 + (t ;Convert again to PNG file 1.155 + (goto-char (point-max)) 1.156 + (insert "\nConvert Again to PNG file...\n") 1.157 + (put 'YaTeX-filter-pngify-sentinel 'start (point)) 1.158 + (set-process-sentinel 1.159 + (start-process 1.160 + "Filter" b ;Safe to reuse 1.161 + shell-file-name YaTeX-shell-command-option 1.162 + (format YaTeX-filter-pdf2png-stdout imagefile)) 1.163 + 'YaTeX-filter-pngify-sentinel) 1.164 + (set-buffer-multibyte nil) 1.165 + )) 1.166 + (select-window selw))) 1.167 + (YaTeX-preview-image-mode) 1.168 + ) 1.169 + (t ;Other status might be an error 1.170 + (set-buffer b) 1.171 + (goto-char (point-max)) 1.172 + (insert (format "%s\n" (process-status proc)))))))) 1.173 + 1.174 +(defun YaTeX-filter-pass-to-filter (begend-info) 1.175 + "Pass current BEGIN FILTER environment to external command." 1.176 + (put 'YaTeX-filter-filter-sentinel 'outfile nil) 1.177 + ;; begend-info is from YaTeX-in-BEGEND-p: (BEG END ARGS) 1.178 + (let ((b (car begend-info)) (e (nth 1 begend-info)) 1.179 + (args (nth 2 begend-info)) 1.180 + (p (point)) openb closeb outfile cmdline point-if0 point-fi) 1.181 + (save-excursion 1.182 + (if (and begend-info 1.183 + (string-match "FILTER" args) ;easy test 1.184 + (goto-char (car begend-info)) 1.185 + (re-search-forward 1.186 + "FILTER\\s *{\\([^}]+\\)}" e t) 1.187 + (setq outfile (YaTeX-match-string 1)) 1.188 + (goto-char (match-end 0)) 1.189 + (prog2 ;Step into the second brace 1.190 + (skip-chars-forward "\t ") 1.191 + (looking-at "{") ;Check if 2nd brace surely exists 1.192 + (skip-chars-forward "{") 1.193 + (skip-chars-forward "\t")) 1.194 + (setq openb (point)) 1.195 + (condition-case nil 1.196 + (progn (up-list 1) t) 1.197 + (error nil)) 1.198 + (setq closeb (1- (point)) 1.199 + cmdline (YaTeX-buffer-substring openb closeb)) 1.200 + (re-search-forward "^\\\\if0\\>" p t) 1.201 + (setq point-if0 (point)) 1.202 + (re-search-forward "^\\\\fi\\>" e t) 1.203 + (setq point-fi (match-beginning 0))) 1.204 + (let*((case-fold-search t) 1.205 + (type (cond 1.206 + ((string-match "\\.png$" outfile) "png") 1.207 + ((string-match "\\.svg$" outfile) "svg") 1.208 + (t "pdf"))) 1.209 + (newcmdline (YaTeX-replace-formats 1.210 + cmdline 1.211 + (list (cons "t" type) 1.212 + (cons "o" outfile)))) 1.213 + (delim (progn (goto-char point-if0) 1.214 + (forward-line 1) 1.215 + (and (looking-at "\\(.\\)\\1\\1") ;Triple chars 1.216 + (prog1 1.217 + (YaTeX-match-string 0) 1.218 + (forward-line 1))))) 1.219 + (text-start (point)) 1.220 + (text-end (if (and delim 1.221 + (re-search-forward 1.222 + (concat "^" (regexp-quote delim)) 1.223 + point-fi t)) 1.224 + (match-beginning 0) 1.225 + point-fi)) 1.226 + (text (YaTeX-buffer-substring text-start text-end)) 1.227 + ;; 1.228 + ;; Now it's time to start filter process 1.229 + ;; 1.230 + (procbuf (YaTeX-system newcmdline "Filter" 'force)) 1.231 + (proc (get-buffer-process procbuf)) 1.232 + ;(procbuf (get-buffer-create " *Filter*")) 1.233 + (ovl (progn 1.234 + (remove-overlays text-start text-end) 1.235 + (make-overlay text-start text-end))) 1.236 + (ovlmodhook ;hook function to reset conv-success flag 1.237 + 'YaTeX-filter-filter-unset-conversion-flag)) 1.238 + (if proc 1.239 + (progn 1.240 + (overlay-put ovl 'filter-input outfile) 1.241 + (overlay-put ovl 'converted nil) 1.242 + (overlay-put ovl 'modification-hooks (list ovlmodhook)) 1.243 + (set-process-coding-system proc 'undecided 'utf-8) 1.244 + (set-process-sentinel proc 'YaTeX-filter-filter-sentinel) 1.245 + (YaTeX-showup-buffer procbuf) 1.246 + (set-buffer procbuf) 1.247 + (setq buffer-read-only nil) 1.248 + (erase-buffer) 1.249 + (insert (format "Starting process `%s'...\n" newcmdline)) 1.250 + (set-marker (process-mark proc) (point-max)) 1.251 + (process-send-string proc text) 1.252 + (process-send-string proc "\n") 1.253 + (process-send-eof proc) ;Notify stream chunk end 1.254 + (process-send-eof proc) ;Notify real EOF 1.255 + (put 'YaTeX-filter-filter-sentinel 'outfile outfile) 1.256 + (put 'YaTeX-filter-filter-sentinel 'overlay ovl)))))))) 1.257 + 1.258 +(defun YaTeX-insert-filter-special (filter list &optional region-p) 1.259 + (let ((f (YaTeX-read-string-or-skip "Output file: "))) 1.260 + (if region-p 1.261 + (if (< (point) (mark)) (exchange-point-and-mark))) 1.262 + (save-excursion (insert "===\n\\fi\n%#END\n")) 1.263 + (and region-p (exchange-point-and-mark)) 1.264 + (insert (format "%%#BEGIN FILTER{%s}{%s}\n\\if0\n===\n" 1.265 + f (or (car list) ""))) 1.266 + (save-excursion (insert (or (car (cdr list)) "\n") "\n")))) 1.267 + 1.268 +(provide 'yatexflt) 1.269 + 1.270 +; Local variables: 1.271 +; fill-prefix: ";;; " 1.272 +; paragraph-start: "^$\\|\\|;;;$" 1.273 +; paragraph-separate: "^$\\|\\|;;;$" 1.274 +; End: