yatex

view yatexgen.el @ 564:71697ec66240

Auto-usepackage assumes amsart, amsbook and amsproc same as amsmath
author HIROSE Yuuji <yuuji@gentei.org>
date Thu, 24 Jan 2019 08:03:47 +0900
parents 77a2fd4fd634
children
line source
1 ;;; yatexgen.el --- YaTeX add-in function generator(rev.5)
3 ;;; (c)1991-1995,1999,2000,2017 by HIROSE Yuuji.[yuuji@yatex.org]
4 ;;; Last modified Sun Dec 21 14:04:49 2014 on firestorm
5 ;;; $Id$
7 ;;; Code:
8 (require 'yatex)
10 (defmacro YaTeX-setq (var japanese english)
11 (list 'setq var
12 (if YaTeX-japan japanese english)))
14 (put 'YaTeX-setq 'lisp-indent-hook 1)
16 (YaTeX-setq YaTeX-generate-initial-message
17 " 自動生成モードへようこそ!!
19 初めてやる人はこのバッファの例にしたがって指示通りにやって練習してね。
20 本番の時もこのバッファに出るメッセージを *よく読んで* 操作しないとう
21 まく関数が作れないよ!!
23 ではリターンキーを押して下さい。"
24 " Welcome to auto-generation mode!!
26 If this is your first trial, exercise this according to example and
27 following my messages. Then, at making actual function, operate
28 reading my messages *carefully*, or you'll fail to generate appropriate
29 function.
31 Hit return key!")
33 (YaTeX-setq YaTeX-generate-start-message
34 "さぁはじめるよ.\n1.登録したい補完をやってみて.
35 たとえば section 型補完の \\documentstyle だったら \\documentstyle{}
36 だけをいれてみてね. ちゃんと『〜型補完』を使わないとダメよ!。
37 で、おわったらりたーん!!"
38 "Let's begin completion for which you want to make add-in function.
39 If you want to make add-in function for \\documentstyle input only
40 `\\documentstyle{}' *with* completion of yatex-mode.
41 If you finish this, please press RET.")
43 (YaTeX-setq YaTeX-generate-abort-message
44 "やめた、やめた〜いめんどくせ〜"
45 "Aborted.")
47 (YaTeX-setq YaTeX-generate-same-message
48 "それじゃ、なにも変わってねぇだろーが! やめた。"
49 "I found no difference between them. So I'm quitting.")
51 (YaTeX-setq YaTeX-generate-invalid-message
52 "それは、ちと無理というものじゃ."
53 "It's impossible.")
55 (YaTeX-setq YaTeX-generate-idontknow-message
56 "う〜ん、難しくてよくわからないなぁ。ばかでごめんねェ〜"
57 "Sorry I can't tell your adding method.")
59 (YaTeX-setq YaTeX-generate-confirm-message
60 "ということは、付け足したい部分はこれでいいのね"
61 "Is it additional string of add-in function?")
63 (YaTeX-setq YaTeX-generate-output-message
64 "2.じゃ、それにくっつけたいものを *カーソルの位置に* 足してみて.
65 さっきの \\documentstyle{} の例だと \\documentstyle[12pt]{} とかにするの。
66 しつこいようだけど、今の位置からカーソル動かしちゃダメよ!!
67 で、またおわったらりたーん!!"
68 "2.Then input additional string *at CURSOR POSITION*
69 According to last example \\documentstyle{},
70 modify it \\documentstyle[12pt]{}. RET to finish.")
72 (YaTeX-setq YaTeX-generate-put-arg-message
73 "3.このうち、キーボードから読み込んで欲しい文字列を順に入れて。
74 さっきの \\documentstyle[12pt]{} だったら、付加する文字は[12pt]だけど
75 手で入れたいのは 12pt の部分だけですね。
76 で、全部入れ終ったら、りたーんだけうってね!!"
77 "3.In this string, extract string which you want to input from key
78 board with quiry afterwards. For example, though additional string is
79 \\documentstyle[12pt]{}, but you want enter only `12pt' by hand.
80 RET to finish!")
82 (YaTeX-setq YaTeX-generate-read-prompt-message
83 "4.では、あとでこれらの文字列を読み込む時に、どういうプロンプトを
84 出したいですか? 順に入れて下さい。面倒なら単にリターンを打ってね。
85 さっきの 12pt の部分だったら、『サイズは』とかがおすすめ。"
86 "4.When you use this add-in function afterwards, what message
87 do you like to be prompted with to enter these values. In last
88 example `12pt', typical prompt string may be `Size?: '.")
90 (YaTeX-setq YaTeX-generate-done-message
91 "よし! これが、君の作りたかった関数だ。~/.emacs にでも入れてせいぜい
92 楽してくれ。このバッファ(*ご案内*)を yatex-mode にしておくから
93 できた関数が本当にお望みの動作をするか確かめてみるといいかもね。
94 ところで、この関数こんなに簡単だろう? そろそろ自分で書いたらどう?
95 "
96 "OK! This is the definition of function you want to make! Add
97 this description to your ~/.emacs or so. Use this buffer(*Guide*)
98 for testing of this function please.
99 But you can see this function quite easy, can't you? You had better
100 write your most favorite add-in function yourself!
101 ")
103 (YaTeX-setq YaTeX-generate-nomatch-message
104 "こらこら、そんな文字列どこにもねーぞ!!"
105 "No such string in additional string.")
107 (YaTeX-setq YaTeX-generate-buffer
108 "*付加関数生成バッファ*"
109 "*Generate-add-in-function*")
111 (YaTeX-setq YaTeX-generate-message-buffer
112 "*ご案内*"
113 "*Guide*")
115 (YaTeX-setq YaTeX-generate-bug-message
116 "ごめ〜ん!! ちょっと、このアドイン関数つくるの失敗しちゃったみたい!!
117 作者まで連絡してくださ〜〜〜い!"
118 "Sorry I failed to make add-in function for you...
119 Send bug report to me.")
121 (YaTeX-setq YaTeX-generate-narrow-message
122 "画面がせますぎるような気がします。"
123 "Too narrow screen height.")
125 (defvar YaTeX-generate-message-height
126 10 "Window height of YaTeX-generate-message-buffer")
128 ;; Do you need learning for generated function?
129 ;; If you need, please tell me (yuuji@yatex.org)
130 ;;(defvar YaTeX-generate-variables-for-learning nil)
131 ;;(defvar YaTeX-generate-current-completion-table nil)
133 ;;;
134 ;Generate mode.
135 ;;;
136 (defun YaTeX-generate ()
137 "Genarate YaTeX add-in function with enquiry."
138 (interactive)
139 (if (< (YaTeX-screen-height) (+ YaTeX-generate-message-height 10))
140 (error YaTeX-generate-narrow-message))
141 (put 'YaTeX-generate 'disabled t)
142 (save-window-excursion
143 (unwind-protect
144 (let (input output (i 0) (beg 0) end add-in map map1 si str slist
145 (from (make-marker)) (to (make-marker)))
146 (delete-other-windows)
147 (switch-to-buffer YaTeX-generate-message-buffer)
148 (yatex-mode)
149 (erase-buffer)
150 (insert YaTeX-generate-initial-message)
151 (read-string
152 (if YaTeX-japan "リターンキーを押して下さい." "Press RETURN."))
153 (erase-buffer)
154 (insert YaTeX-generate-start-message)
155 (pop-to-buffer (get-buffer-create YaTeX-generate-buffer))
156 (enlarge-window (- (window-height) YaTeX-generate-message-height 1))
157 (erase-buffer)
158 (yatex-mode)
159 (use-local-map (setq map (copy-keymap YaTeX-mode-map)))
160 (define-key (current-local-map) "\n" 'exit-recursive-edit)
161 (define-key (current-local-map) "\r" 'exit-recursive-edit)
162 (define-key (current-local-map) "\C-g" 'abort-recursive-edit)
163 (setq map1 (copy-keymap map))
164 (YaTeX-suppress-sparse-keymap map)
165 ;;First get input form.
166 (recursive-edit)
167 (setq input (YaTeX-minibuffer-string)
168 end (1- (length input)))
169 (if (string= "" input) (error YaTeX-generate-abort-message))
170 (YaTeX-generate-move-to-add-in-position)
171 (set-marker from (1- (point))) ;;Can't write before `from'
172 (set-marker to (1+ (point))) ;;Can't write after `to'
173 ;;Second get output form.
174 (setq beg (1- (point)));;Cheat begin point!
175 (YaTeX-generate-display-message YaTeX-generate-output-message)
176 (use-local-map map1)
177 (fset 'si (symbol-function 'self-insert-command))
178 (defun self-insert-command (arg)
179 (interactive "p")
180 (if (or (not (equal (buffer-name) YaTeX-generate-buffer))
181 (and (> (point) (marker-position from))
182 (< (point) (marker-position to))))
183 (insert (this-command-keys)) (ding)))
184 (unwind-protect
185 (recursive-edit)
186 (fset 'self-insert-command (symbol-function 'si)))
187 (setq output (YaTeX-minibuffer-string))
188 (cond ((string= "" output) (error YaTeX-generate-abort-message))
189 ((string= input output) (error YaTeX-generate-same-message))
190 ((< (length output) (length input))
191 (error YaTeX-generate-invalid-message)))
192 ;;(while (and (< beg end) (= (aref input beg) (aref output i)))
193 ;; (setq beg (1+ beg) i (1+ i))) ;;for universal use.
194 (setq i (1- (length output)))
195 (while (and (>= end beg) (= (aref output i) (aref input end)))
196 (setq end (1- end) i (1- i)))
197 (setq add-in (substring output beg
198 (if (= i (1- (length output))) nil (1+ i))))
199 (erase-buffer)
200 (insert add-in)
201 (if (not (y-or-n-p YaTeX-generate-confirm-message))
202 (error YaTeX-generate-idontknow-message))
203 ;;Extract arguments.
204 (YaTeX-generate-display-message YaTeX-generate-put-arg-message)
205 (setq i 1)
206 (while (not (string=
207 "" (setq str (read-string (format "Arg %d: " i)))))
208 (if (not (string-match (regexp-quote str) add-in))
209 (progn
210 (ding)
211 (YaTeX-generate-display-message
212 YaTeX-generate-nomatch-message -1))
213 (setq slist (append slist (list (list str))) i (1+ i)))
214 );input all of arguments.
215 ;;Compare with output string.
216 (set-buffer YaTeX-generate-buffer) ;;for safety
217 (emacs-lisp-mode)
218 (if (> i 1)
219 (YaTeX-generate-parse-add-in slist add-in)
220 (erase-buffer)
221 (insert "(defun " (YaTeX-generate-function-name) " ()\n")
222 (insert "\"" (YaTeX-generate-lisp-quote add-in) "\")\n")
223 (indent-region (point-min) (point-max) nil)
224 (message (if YaTeX-japan
225 "このくらいの関数手で書け!!"
226 "You don't need me to make such easy function.")))
227 );let
228 (put 'YaTeX-generate 'disabled nil)
229 (put 'YaTeX-addin 'disabled nil)
230 ))
231 (YaTeX-generate-display-message YaTeX-generate-done-message)
232 (switch-to-buffer YaTeX-generate-buffer)
233 (condition-case error
234 (eval-current-buffer)
235 (error (insert YaTeX-generate-bug-message)))
236 (pop-to-buffer YaTeX-generate-message-buffer))
238 (defun YaTeX-generate-parse-add-in (args add-in)
239 "Parse add-in string and extract argument for it.
240 Variable add-in is referred in parent function."
241 (let ((i 1) j (case-fold-search nil) ;i holds argument number
242 (prompt (make-vector (length args) ""))
243 (used (make-vector (length add-in) nil))
244 func-name (string ""))
245 ;;Phase 1. extract argument from add-in string.
246 (mapcar
247 (function
248 (lambda (arg)
249 (let ((index 0) (match 0) beg end (carg (car arg)))
250 (YaTeX-generate-display-message
251 YaTeX-generate-read-prompt-message)
252 (aset prompt (1- i)
253 (read-string
254 (format
255 (if YaTeX-japan "%d番目(%s)を読む時?: "
256 "When reading argument #%d(%s)?: ") i (car arg))))
257 (while (string-match (regexp-quote carg) (substring add-in index))
258 (setq beg (+ index (match-beginning 0))
259 end (+ index (match-end 0)))
260 (if (aref used beg) nil
261 (setq match (1+ match))
262 (cond
263 ((= match 1)
264 ;;(setq arg (append arg (list (list beg end))))
265 (YaTeX-generate-register-match))
266 ((YaTeX-generate-ask-match-position)
267 (YaTeX-generate-register-match))))
268 (setq index end))
269 (setq i (1+ i)))))
270 args)
271 ;;Phase 2. Generate function!!
272 (setq i 0)
273 (setq func-name (YaTeX-generate-function-name))
274 (while (< i (length add-in))
275 (setq beg i j (aref used i))
276 (while (and (< i (length add-in)) (equal j (aref used i)))
277 (setq i (1+ i)))
278 (if j ;If it is argument.
279 (setq string (concat string (format " arg%d" j)))
280 (setq string
281 (concat string " \""
282 (YaTeX-generate-quote-quote (substring add-in beg i))
283 "\""))
284 ))
285 (erase-buffer)
286 (setq i 1)
287 (insert
288 "(defun " func-name " ()\n"
289 " (let (")
290 (mapcar
291 (function
292 (lambda (arg)
293 (insert (format "(arg%d (read-string \"%s: \"))\n"
294 i (aref prompt (1- i))))
295 (setq i (1+ i))))
296 args)
297 (delete-region (point) (progn (forward-line -1) (end-of-line) (point)))
298 (insert ")\n(concat " (YaTeX-generate-lisp-quote string)
299 ")))\n")
300 (indent-region (point-min) (point) nil)
301 used))
303 (defun YaTeX-generate-ask-match-position ()
304 "Ask user whether match-position is in his expectation,
305 Referencing variables in parent function YaTeX-generate-parse-add-in."
306 (pop-to-buffer YaTeX-generate-message-buffer)
307 (goto-char (point-max))
308 (insert "\n\n"
309 (format (if YaTeX-japan "%d 番目の引数 %s って"
310 "Is argument #%d's value `%s' also corresponding to")
311 i carg) "\n" add-in "\n")
312 (indent-to-column beg)
313 (let ((c beg))
314 (while (< c end) (insert "^") (setq c (1+ c))))
315 (insert "\n" (if YaTeX-japan "ここにも対応してるの?"
316 "this underlined part too?"))
317 (other-window -1)
318 (y-or-n-p (if YaTeX-japan "下線部はあってますか" "Is underline right")))
320 (defun YaTeX-generate-register-match ()
321 (nconc arg (list (list beg end)))
322 (let ((x beg))
323 (while (< x end) (aset used x i)(setq x (1+ x)))))
325 (defun YaTeX-generate-display-message (mes &optional bottom)
326 "Display message to generation buffer."
327 (pop-to-buffer YaTeX-generate-message-buffer)
328 (goto-char (point-max))
329 (insert "\n\n")
330 (if bottom (recenter (1- bottom)) (recenter 0))
331 (insert mes)
332 (other-window -1))
334 (defun YaTeX-generate-move-to-add-in-position ()
335 "Move cursor where add-in function should insert string."
336 (cond
337 ((eq YaTeX-current-completion-type 'begin)
338 (goto-char (point-min))
339 (skip-chars-forward "^{")
340 (setq YaTeX-env-name
341 (buffer-substring (1+ (point))
342 (progn (skip-chars-forward "^}") (point))))
343 (forward-char 1))
344 ((eq YaTeX-current-completion-type 'section)
345 (goto-char (point-min))
346 (skip-chars-forward "^{"))
347 ((eq YaTeX-current-completion-type 'maketitle)
348 (goto-char (point-max))
349 (if (= (preceding-char) ? )
350 (forward-char -1)))))
352 (defun YaTeX-generate-function-name ()
353 (concat
354 "YaTeX:"
355 (cond
356 ((eq YaTeX-current-completion-type 'begin) YaTeX-env-name)
357 ((eq YaTeX-current-completion-type 'section) YaTeX-section-name)
358 ((eq YaTeX-current-completion-type 'maketitle) YaTeX-single-command))))
360 (defun YaTeX-generate-lisp-quote (str)
361 (let ((len (length str))(i 0) (quote ""))
362 (while (< i len)
363 (if (= (aref str i) ?\\)
364 (setq quote (concat quote "\\")))
365 (if (= (aref str i) 127)
366 (setq quote (concat quote "\""))
367 (setq quote (concat quote (substring str i (1+ i)))))
368 (setq i (1+ i)))
369 quote))
371 (defun YaTeX-generate-quote-quote (str)
372 (let ((len (length str))(i 0) (quote ""))
373 (while (< i len)
374 (if (= (aref str i) ?\")
375 (setq quote (concat quote (char-to-string 127))))
376 (setq quote (concat quote (substring str i (1+ i))))
377 (setq i (1+ i)))
378 quote))
380 (defun YaTeX-suppress-sparse-keymap (map)
381 (let ((i ? ))
382 (while (< i 127)
383 (define-key map (char-to-string i) 'undefined)
384 (setq i (1+ i)))))
386 ;;;
387 ;; Auto-generate Function for Lispers.
388 ;;;
389 (defun YaTeX-generate-read-completion-type (nth)
390 (message
391 "Read type(%d): (S)tring (C)omplete (F)ile ([)option (P)osition co(O)rd. (q)uit" nth)
392 (let ((c (read-char)))
393 (cond
394 ((= c ?s) 'string)
395 ((= c ?c) 'completion)
396 ((= c ?f) 'file)
397 ((= c ?\[) 'option)
398 ((= c ?p) 'oneof)
399 ((= c ?o) 'coord)
400 ;;((= c ?m) 'macro)
401 (t 'quit))))
403 (defun YaTeX-generate-read-completion-table ()
404 (let ((i 1) cand (cands "(") (cb (current-buffer))
405 (buf (get-buffer-create " *Candidates*")))
406 (save-window-excursion
407 (save-excursion
408 (YaTeX-showup-buffer buf nil)
409 (set-buffer buf)
410 (erase-buffer)
411 (while (string<
412 ""
413 (setq cand (read-string (format "Item[%d](RET to exit): " i))))
414 (setq cands (concat cands (format "(\"%s\")\n" cand))
415 i (1+ i))
416 (insert cand "\n"))
417 (kill-buffer buf)))
418 ;;(set-buffer cb)
419 (setq YaTeX-generate-current-completion-table (concat cands ")"))))
421 (defun YaTeX-generate-corresponding-paren (left)
422 (cond
423 ((equal left "{") "}")
424 ((equal left "[") "]")
425 ((equal left "(") ")")
426 ((equal left "<") ">")
427 ((equal left "\\begin{") "}")
428 (t left)))
430 (defun YaTeX-generate-create-read-string (&optional nth)
431 (concat
432 "(read-string \""
433 (read-string (if nth (format "Prompt for argument#%d: " nth) "Prompt: "))
434 ": \"\n"
435 "\"" (read-string "Default: ") "\""
436 ")\n"))
438 (defun YaTeX-generate-create-completing-read (&optional nth)
439 (prog1
440 (concat
441 "(completing-read \""
442 (read-string
443 (if nth (format "Prompt for argument#%d: " nth) "Prompt: "))
444 ": \"\n"
445 (format "'%s\n" (YaTeX-generate-read-completion-table))
446 "nil "
447 (format "%s)" (y-or-n-p "Require match? ")))
448 (if nil ;;;(y-or-n-p "Do you need learning for this completion?")
449 (setq YaTeX-generate-variables-for-learning
450 (cons
451 (cons (format "YaTeX-%s-%d" command (or nth 0))
452 YaTeX-generate-current-completion-table)
453 YaTeX-generate-variables-for-learning)))))
455 (defun YaTeX-generate-create-read-file-name (&optional nth)
456 (concat
457 "(read-file-name \""
458 (read-string (if nth (format "Prompt for argument#%d: " nth) "Prompt: "))
459 ": \" "" \"\" t \"\")\n"))
461 (defun YaTeX-generate-create-read-oneof (&optional nth readpos)
462 (concat
463 (if readpos
464 "(YaTeX:read-position \""
465 "(YaTeX:read-oneof \"")
466 (read-string "Acceptable characters: " "lcr") "\")\n"))
468 (defun YaTeX-generate-option-type (command)
469 (let ((func (format "YaTeX:%s" command)) leftp
470 (buf (get-buffer-create YaTeX-generate-buffer)) type (n 1))
471 (set-buffer buf)
472 (erase-buffer)
473 (insert "(defun " func " ()\n (concat\n")
474 (catch 'done
475 (while t
476 (setq type (YaTeX-generate-read-completion-type n))
477 (insert
478 (cond
479 ;;Read string
480 ((eq type 'string)
481 (concat "\"" (setq leftp (read-string "Left parenthesis: " "("))
482 "\"\n"
483 (YaTeX-generate-create-read-string)
484 "\"" (YaTeX-generate-corresponding-paren leftp) "\"")
485 )
486 ;;Completing-read
487 ((eq type 'completion)
488 (concat "\"" (setq leftp (read-string "Left parenthesis: " "{"))
489 "\"\n"
490 (YaTeX-generate-create-completing-read)
491 "\"" (YaTeX-generate-corresponding-paren leftp) "\"")
492 )
493 ((eq type 'file)
494 (concat "\"" (setq leftp (read-string "Left parenthesis: " "("))
495 "\"\n"
496 (YaTeX-generate-create-read-file-name)
497 "\"" (YaTeX-generate-corresponding-paren leftp) "\"")
498 )
499 ((eq type 'oneof)
500 (YaTeX-generate-create-read-oneof nil t)
501 )
502 ((eq type 'option)
503 (concat "(let ((op (read-string \""
504 (read-string "Prompt: ")
505 ": \")))\n"
506 "(if (string< \"\" op)\n"
507 " (concat \"[\" op \"]\")\n"
508 " \"\"))\n")
509 )
510 ((eq type 'coord)
511 (concat "(YaTeX:read-coordinates \""
512 (read-string "Prompt for coordinates: ")
513 ": \")\n")
514 )
515 ((eq type 'macro)
516 (error "not yet supported")
517 )
518 (t (throw 'done t))))
519 (setq n (1+ n))))
520 (insert "))\n") ;close defun
521 (goto-char (point-min))
522 (while (not (eobp)) (lisp-indent-line) (forward-line 1))
523 (eval-current-buffer)
524 buf))
526 (defun YaTeX-generate-argument-type (command argc)
527 "Create an argument-type add-in function."
528 (interactive)
529 (let ((func (format "YaTeX::%s" command)) (argp 1)
530 (cb (current-buffer))
531 (buf (get-buffer-create YaTeX-generate-buffer)))
532 (set-buffer buf)
533 (erase-buffer)
534 (insert "(defun " func " (&optional argp)\n(cond\n")
535 (while (<= argp argc)
536 (insert (format "((equal argp %d)\n" argp))
537 (setq type (YaTeX-generate-read-completion-type argp))
538 (insert
539 (cond
540 ((eq type 'string)
541 (concat (YaTeX-generate-create-read-string argp)))
542 ((eq type 'completion)
543 (concat (YaTeX-generate-create-completing-read argp)))
544 ((eq type 'oneof)
545 (YaTeX-generate-create-read-oneof))
546 ((eq type 'file)
547 (concat (YaTeX-generate-create-read-file-name argp)))
548 (t ""))
549 ")\n")
550 (setq argp (1+ argp)))
551 (insert "))\n")
552 (goto-char (point-min))
553 (while (not (eobp)) (lisp-indent-line) (forward-line 1))
554 (eval-current-buffer)
555 (set-buffer cb)
556 (YaTeX-update-table
557 (if (> argc 1) (list command argc) (list command))
558 'section-table 'user-section-table 'tmp-section-table)
559 buf))
561 (defun YaTeX-generate-simple (&optional command)
562 "Simple but requiring some elisp knowledge add-in generator."
563 (interactive)
564 (setq YaTeX-generate-variables-for-learning nil)
565 (or command
566 (setq command
567 (completing-read
568 (format
569 "Making add-in function for (default %s): " YaTeX-section-name)
570 (append
571 section-table user-section-table tmp-section-table
572 env-table user-env-table tmp-env-table
573 singlecmd-table user-singlecmd-table tmp-singlecmd-table)
574 nil nil)
575 command (if (string= "" command) YaTeX-section-name command)))
576 (message
577 (cond
578 (YaTeX-japan "(o)追加型? (a)引数型? (yatexadd.docを参照のこと) :")
579 (t "(O)ption? (A)rgument?")))
580 (YaTeX-showup-buffer
581 (if (= (read-char) ?o)
582 (YaTeX-generate-option-type command)
583 (YaTeX-generate-argument-type
584 command
585 (YaTeX-str2int (read-string "How many arguments?: ")))) nil))
587 (provide 'yatexgen)