yatex

view yatexenv.el @ 243:74229d191b17

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