yatex

view yatexenv.el @ 298:c5052c0354f6

Removed tag yatex-1.77
author HIROSE Yuuji <yuuji@gentei.org>
date Mon, 01 Apr 2013 23:03:08 +0900
parents 5921f28ef77c
children 9cfc505ba6aa
line source
1 ;;; yatexenv.el --- YaTeX environment-specific functions
2 ;;; (c) 1994-2013 by HIROSE Yuuji.[yuuji@yatex.org]
3 ;;; Last modified Mon Apr 1 22:43:10 2013 on firestorm
4 ;;; $Id$
6 ;;; Code:
7 ;;;
8 ;; Functions for tabular environment
9 ;;;
11 ;; Showing the matching column of tabular environment.
12 (defun YaTeX-array-what-column-internal ()
13 "Return the cons of matching column and its title of array environment.
14 When calling from a program, make sure to be in array/tabular environment."
15 (let ((p (point)) beg eot bor (nlptn "\\\\\\\\") (andptn "[^\\]&")
16 (n 0) j
17 (firsterr "This line might be the first row."))
18 (save-excursion
19 (YaTeX-beginning-of-environment)
20 (search-forward "{" p) (up-list 1)
21 (search-forward "{" p) (up-list 1)
22 ;;(re-search-forward andptn p)
23 (while (progn (search-forward "&" p)
24 (equal (char-after (1- (match-beginning 0))) ?\\ )))
25 (setq beg (1- (point))) ;beg is the point of the first &
26 (or (re-search-forward nlptn p t)
27 (error firsterr))
28 (setq eot (point)) ;eot is the point of the first \\
29 (goto-char p)
30 (or (re-search-backward nlptn beg t)
31 (error firsterr))
32 (setq bor (point)) ;bor is the beginning of this row.
33 (while (< (1- (point)) p)
34 (if (equal (following-char) ?&)
35 (forward-char 1)
36 (re-search-forward andptn nil 1))
37 (setq n (1+ n))) ;Check current column number
38 (goto-char p)
39 (cond ;Start searching \multicolumn{N}
40 ((> n 1)
41 (re-search-backward andptn) ;Sure to find!
42 (while (re-search-backward "\\\\multicolumn{\\([0-9]+\\)}" bor t)
43 (setq n (+ n (string-to-int
44 (buffer-substring (match-beginning 1)
45 (match-end 1)))
46 -1)))))
47 (message "%s" n)
48 (goto-char (1- beg))
49 (beginning-of-line)
50 (setq j n)
51 (while (> j 1)
52 (or (re-search-forward andptn p nil)
53 (error "This column exceeds the limit."))
54 (setq j (1- j)))
55 (skip-chars-forward "\\s ")
56 (list n
57 (buffer-substring
58 (point)
59 (progn
60 (re-search-forward (concat andptn "\\|" nlptn) eot)
61 (goto-char (match-beginning 0))
62 (if (looking-at andptn)
63 (forward-char 1))
64 (skip-chars-backward "\\s ")
65 (point)))))))
67 (defun YaTeX-array-what-column ()
68 "Show matching column title of array environment.
69 When calling from a program, make sure to be in array/tabular environment."
70 (apply 'message
71 "This is the column(#%d) of: %s"
72 (YaTeX-array-what-column-internal)))
74 ;;;###autoload
75 (defun YaTeX-what-column ()
76 "Show which kind of column the current position is belonging to."
77 (interactive)
78 (cond
79 ((YaTeX-quick-in-environment-p '("tabular" "tabular*" "array" "array*"))
80 (YaTeX-array-what-column))
81 (t (message "Not in array/tabular environment."))))
83 (defun YaTeX-tabular-parse-format-count-cols (beg end)
84 (goto-char beg)
85 (let (elt (cols 0))
86 (while (< (point) end)
87 (setq elt (following-char))
88 (cond
89 ((string-match (char-to-string elt) "clr") ;normal indicators.
90 (setq cols (1+ cols))
91 (forward-char 1))
92 ((equal elt ?|) ;vertical
93 (forward-char 1))
94 ((string-match (char-to-string elt) "p@") ;p or @ expression
95 (setq cols (+ (if (eq elt ?p) 1 0) cols))
96 ;;(skip-chars-forward "^{" p)
97 (skip-chars-forward "^{" end)
98 (forward-list 1))
99 ((equal elt ?*) ;*{N}{EXP} -> Repeat EXP N times
100 (skip-chars-forward "^{" end)
101 (setq cols (* (string-to-int
102 (buffer-substring
103 (1+ (point))
104 (progn (forward-list 1) (1- (point)))))
105 (YaTeX-tabular-parse-format-count-cols
106 (progn (skip-chars-forward "^{" end) (1+ (point)))
107 (progn (forward-list 1) (1- (point)))))))
108 (t (forward-char 1)) ;unknown char
109 ))
110 cols))
112 (defun YaTeX-tabular-parse-format (&optional type)
113 "Parse `tabular' format.
114 Return the list of (No.ofCols PointEndofFormat)"
115 (let ((p (point)) boform eoform (cols 0))
116 (save-excursion
117 (if (null (YaTeX-beginning-of-environment t))
118 (error "Beginning of tabular not found."))
119 (skip-chars-forward "^{")
120 (forward-list 1)
121 (cond
122 ((eq type 'tabular*)
123 (skip-chars-forward "^{")
124 (forward-list 1)))
125 (skip-chars-forward "^{" p)
126 (if (/= (following-char) ?\{) (error "Tabular format not found."))
127 (setq boform (1+ (point))
128 eoform (progn (forward-list 1) (1- (point))))
129 (if (> eoform p) (error "Non-terminated tabular format."))
130 (goto-char boform)
131 (setq cols
132 (cond
133 ((eq type 'alignat)
134 (max
135 1
136 (* 2 (string-to-int
137 (buffer-substring
138 (point)
139 (progn (up-list -1) (forward-list 1) (1- (point))))))))
140 (t
141 (YaTeX-tabular-parse-format-count-cols (point) eoform))))
142 (list cols (1+ eoform)))))
144 ;; Insert &
145 (defun YaTeX-intelligent-newline-tabular (&optional type)
146 "Parse current tabular format and insert that many `&'s."
147 (let*((p (point)) (format (YaTeX-tabular-parse-format type))
148 (cols (car format)) (beg (car (cdr format)))
149 space hline)
150 (cond
151 ((search-backward "&" beg t)
152 (goto-char p)
153 (setq hline (search-backward "\\hline" beg t))
154 (setq space (if (search-backward "\t&" beg t) "\t" " "))
155 (goto-char p))
156 (t ;;(insert "\\hline\n")
157 (setq space " ")))
158 (goto-char p)
159 (while (> (1- cols) 0)
160 (insert "&" space)
161 (setq cols (1- cols)))
162 (insert "\\\\")
163 (if hline (insert " \\hline"))
164 (goto-char p)
165 (YaTeX-indent-line)))
167 (defun YaTeX-intelligent-newline-tabular* ()
168 "Parse current tabular* format and insert that many `&'s."
169 (YaTeX-intelligent-newline-tabular 'tabular*))
171 (fset 'YaTeX-intelligent-newline-array 'YaTeX-intelligent-newline-tabular)
172 (fset 'YaTeX-intelligent-newline-supertabular 'YaTeX-intelligent-newline-tabular)
174 (defun YaTeX-intelligent-newline-align ()
175 "Intelligent newline function for align.
176 Count the number of & in the first align line and insert that many &s."
177 (let*((p (point)) (amps 0))
178 (if (string-match "alignat" env)
179 (setq amps (1- (car (YaTeX-tabular-parse-format 'alignat))))
180 (save-excursion
181 (YaTeX-beginning-of-environment)
182 (catch 'done
183 (while (YaTeX-re-search-active-forward
184 "\\(&\\)\\|\\(\\\\\\\\\\)" YaTeX-comment-prefix p t)
185 (if (match-beginning 1) (setq amps (1+ amps)) (throw 'done t))))))
186 (save-excursion
187 (forward-line -1)
188 (skip-chars-forward " \t")
189 (or (prog1 (looking-at "\\\\begin{") (end-of-line))
190 (save-excursion
191 (skip-chars-backward " \t")
192 (and (= (preceding-char) ?\\) (= (char-after (- (point) 2)) ?\\)))
193 (insert "\\\\")))
194 (save-excursion
195 (while (>= (setq amps (1- amps)) 0)
196 (insert "& ")))
197 (YaTeX-indent-line)))
199 (mapcar
200 '(lambda (s)
201 (fset (intern (concat "YaTeX-intelligent-newline-"
202 (symbol-name s)))
203 'YaTeX-intelligent-newline-align))
204 '(align* flalign flalign* matrix pmatrix bmatrix Bmatrix vmatrix Vmatrix
205 cases eqnarray eqnarray* alignat alignat*))
207 ;;;
208 ;; Functions for tabbing environment
209 ;;;
210 (defun YaTeX-intelligent-newline-tabbing ()
211 "Check the number of \\= in the first line and insert that many \\>."
212 (let ((p (point)) begenv tabcount)
213 (save-excursion
214 (YaTeX-beginning-of-environment)
215 (setq begenv (point-end-of-line))
216 (if (YaTeX-search-active-forward "\\\\" YaTeX-comment-prefix p t)
217 (progn
218 (setq tabcount 0)
219 (while (> (point) begenv)
220 (if (search-backward "\\=" begenv 1)
221 (setq tabcount (1+ tabcount)))))))
222 (YaTeX-indent-line)
223 (if tabcount
224 (progn
225 (save-excursion
226 (while (> tabcount 0)
227 (insert "\\>\t")
228 (setq tabcount (1- tabcount))))
229 (forward-char 2))
230 (insert "\\= \\\\")
231 (forward-char -5))))
233 ;;;
234 ;; Functions for itemize/enumerate/list environments
235 ;;;
237 (defun YaTeX-intelligent-newline-itemize ()
238 "Insert '\\item '."
239 (insert "\\item ")
240 (YaTeX-indent-line))
242 (fset 'YaTeX-intelligent-newline-enumerate 'YaTeX-intelligent-newline-itemize)
243 (fset 'YaTeX-intelligent-newline-list 'YaTeX-intelligent-newline-itemize)
245 (defun YaTeX-intelligent-newline-description ()
246 (insert "\\item[] ")
247 (forward-char -2)
248 (YaTeX-indent-line))
250 (defun YaTeX-intelligent-newline-thebibliography ()
251 "Insert '\\bibitem '."
252 (YaTeX-indent-line)
253 (YaTeX-make-section nil nil nil "bibitem")
254 (YaTeX-indent-line))
256 ;;;
257 ;; For document environment
258 ;;;
259 (defun YaTeX-intelligent-newline-document ()
260 "New paragraph by null line or `\\par'."
261 (if (< (count-lines
262 (or (get 'YaTeX-inner-environment 'point)
263 (max 1 (- (point) 17))) ;"\begin{document}\n" == 17
264 (point))
265 2)
266 nil
267 (if (save-excursion (re-search-backward "\\\\par\\>" nil t))
268 (progn
269 (YaTeX-indent-line)
270 (insert "\\par")))
271 (newline))
272 (YaTeX-indent-line))
274 ;;;
275 ;; Intelligent newline
276 ;;;
277 ;;;###autoload
278 (defun YaTeX-intelligent-newline (arg)
279 "Insert newline and environment-specific entry.
280 `\\item' for some itemizing environment,
281 `\\> \\> \\' for tabbing environemnt,
282 `& & \\ \hline' for tabular environment."
283 (interactive "P")
284 (let*(env func)
285 (end-of-line)
286 (setq env (YaTeX-inner-environment))
287 (if arg (setq env (YaTeX-read-environment "For what environment? ")))
288 (setq func (intern-soft (concat "YaTeX-intelligent-newline-" env)))
289 (end-of-line)
290 (newline)
291 (undo-boundary)
292 (if (and env func (fboundp func))
293 (funcall func))))
295 ;;;
296 ;; Environment-specific line indenting functions
297 ;;;
298 ;;;###autoload
299 (defun YaTeX-indent-line-equation ()
300 "Indent a line in equation family."
301 (let ((p (point)) (l-r 0) right-p peol depth (mp YaTeX-environment-indent))
302 (if (save-excursion
303 (beginning-of-line)
304 (skip-chars-forward " \t")
305 (looking-at "\\\\right\\b"))
306 (progn (YaTeX-reindent
307 (save-excursion (YaTeX-goto-corresponding-leftright)
308 (- (current-column) 0))))
309 (save-excursion
310 (forward-line -1)
311 (while (and (not (bobp)) (YaTeX-on-comment-p))
312 (forward-line -1))
313 ;;(beginning-of-line) ;must be unnecessary
314 (skip-chars-forward " \t")
315 (if (eolp) (error "Math-environment can't have a null line!!"))
316 (setq depth (current-column)
317 peol (point-end-of-line))
318 (while (re-search-forward
319 "\\\\\\(\\(left\\)\\|\\(right\\)\\)\\b" peol t)
320 (setq l-r (+ l-r (if (match-beginning 2) 1 -1))))
321 (cond
322 ((progn (beginning-of-line)
323 (re-search-forward "\\\\\\\\\\s *$" (point-end-of-line) t))
324 ;;If previous line has `\\', this indentation is always normal.
325 (setq depth (+ (YaTeX-current-indentation) mp)))
326 ((> l-r 0)
327 (beginning-of-line)
328 (search-forward "\\left" peol nil l-r)
329 (goto-char (1+ (match-beginning 0)))
330 (setq depth (current-column)))
331 ((< l-r 0)
332 (goto-char (match-beginning 0)) ;should be \right
333 (YaTeX-goto-corresponding-leftright)
334 (beginning-of-line)
335 (skip-chars-forward " \t")
336 ;(setq depth (+ (current-column) mp)) ;+mp is good?
337 (setq depth (current-column)))
338 (t ;if \left - \right = 0
339 (cond
340 ((re-search-forward "\\\\\\\\\\s *$" peol t)
341 (setq depth (+ (YaTeX-current-indentation) mp)))
342 ((re-search-forward "\\\\end{" peol t)
343 nil) ;same indentation as previous line's
344 ((re-search-forward "\\\\begin{" peol t)
345 (setq depth (+ depth mp)))
346 (t
347 (or (bobp) (forward-line -1))
348 (cond
349 ((re-search-forward
350 "\\\\\\\\\\s *$\\|\\\\begin{" (point-end-of-line) t)
351 (setq depth (+ depth mp)))
352 )))))
353 (goto-char p))
354 (YaTeX-reindent depth))))
356 ;;;###autoload
357 (defun YaTeX-goto-corresponding-leftright ()
358 "Go to corresponding \left or \right."
359 (let ((YaTeX-struct-begin "\\left%1")
360 (YaTeX-struct-end "\\right%1")
361 (YaTeX-struct-name-regexp "[][(){}\\.|]")
362 (in-leftright-p t))
363 (YaTeX-goto-corresponding-environment t)))
365 ;;;
366 ;; Functions for formatting region being enclosed with environment
367 ;;;
368 ; These functions must take two argument; region-beginning, region-end.
370 (defun YaTeX-enclose-equation (beg end)
371 (goto-char beg)
372 (save-restriction
373 (let (m0 bsl)
374 (narrow-to-region beg end)
375 (while (YaTeX-re-search-active-forward
376 "\\(\\$\\)" YaTeX-comment-prefix nil t)
377 (goto-char (setq m0 (match-beginning 0)))
378 (setq bsl 0)
379 (if (and (not (bobp)) (= (char-after (1- (point))) ?\\ ))
380 (while (progn (forward-char -1) (= (char-after (point)) ?\\ ))
381 (setq bsl (1+ bsl))))
382 (goto-char m0)
383 (if (= 0 (% bsl 2))
384 (delete-char 1)
385 (forward-char 1))))))
387 (fset 'YaTeX-enclose-eqnarray 'YaTeX-enclose-equation)
388 (fset 'YaTeX-enclose-eqnarray* 'YaTeX-enclose-equation)
390 (defun YaTeX-enclose-verbatim (beg end)) ;do nothing when enclose verbatim
391 (fset 'YaTeX-enclose-verbatim* 'YaTeX-enclose-verbatim)
393 (provide 'yatexenv)