yatex

annotate yatexenv.el @ 541:7595fc6462ff

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