1 ;;; mathtools.el --- Style hook for the LaTeX package `mathtools'.
3 ;; Copyright (C) 2011-2012, 2014, 2016 Free Software Foundation, Inc.
5 ;; Author: Mads Jensen <mje@inducks.org>
9 ;; This file is part of AUCTeX.
11 ;; AUCTeX is free software; you can redistribute it and/or modify it
12 ;; under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
16 ;; AUCTeX is distributed in the hope that it will be useful, but
17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ;; General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with AUCTeX; see the file COPYING. If not, write to the Free
23 ;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 ;; This file adds support for `mathtools.sty'
32 ;;; This package serves as a wrapper for amsmath, adding more features
33 ;;; and fixing a few bugs in amsmath. The mathstyle argument for many
34 ;;; of the macros is discussed at
35 ;;; <http://www.tug.org/TUGboat/Articles/tb22-4/tb72perlS.pdf>
39 ;; Needed for auto-parsing.
42 ;; amsmath options which can be passed directly to mathtools are
43 ;; appended in the style hook below
44 (defvar LaTeX-mathtools-package-options
45 '("fixamsmath" "donotfixamsmathbugs" "allowspaces" "disallowspaces"
46 ;; Update 2013: We now make \(\) and \[\] robust (can be disabled
47 ;; via nonrobust package option)
49 "Package options for the mathtools package.")
51 (defvar LaTeX-mathtools-key-val-options
53 ("mathic" ("true" "false"))
54 ("showmanualtags" ("true" "false"))
56 ("smallmatrix-align" ("c" "l" "r"))
57 ("smallmatrix-inner-space")
58 ;; 3.4.2 The multlined environment
59 ("firstline-afterskip")
61 ("multlined-pos" ("c" "b" "t"))
63 ;; 3.4.7 Centered \vdots
64 ("shortvdotsadjustabove")
65 ("shortvdotsadjustbelow")
66 ;; 3.5 Intertext and short intertext
67 ("original-intertext" ("true" "false"))
68 ("original-shortintertext" ("true" "false"))
69 ("above-intertext-sep")
70 ("below-intertext-sep")
71 ("above-shortintertext-sep")
72 ("below-shortintertext-sep")
73 ;; 3.7.2 Vertically centered colon
74 ("centercolon" ("true" "false"))
75 ;; 4.2 Left sub/superscripts
76 ("prescript-sub-format")
77 ("prescript-sup-format")
78 ("prescript-arg-format"))
79 "Options for the \\mathtoolsset command.")
81 ;; Setup for \newtagform
82 (TeX-auto-add-type "mathtools-newtagform" "LaTeX")
84 (defvar LaTeX-mathtools-newtagform-regexp
85 '("\\\\newtagform{\\([^}]+\\)}"
86 1 LaTeX-auto-mathtools-newtagform)
87 "Matches the first argument of \\newtagform from mathtools package.")
89 ;; Setup for \DeclarePairedDelimiter(X)?:
90 (TeX-auto-add-type "mathtools-DeclarePairedDelimiter" "LaTeX")
92 (defvar LaTeX-mathtools-DeclarePairedDelimiter-regexp
93 `(,(concat "\\\\DeclarePairedDelimiter\\(?:X\\|XPP\\)?"
97 "\\(?:\\[\\([0-9]+\\)\\]\\)?")
98 (1 2) LaTeX-auto-mathtools-DeclarePairedDelimiter)
99 "Match the arguments of \\DeclarePairedDelimiterX? from mathtools package.")
101 ;; Setup for \newgathered
102 (TeX-auto-add-type "mathtools-newgathered" "LaTeX")
104 (defvar LaTeX-mathtools-newgathered-regexp
105 '("\\\\newgathered{\\([^}]+\\)}"
106 1 LaTeX-auto-mathtools-newgathered)
107 "Matches the first argument of \\newgathered from mathtools package.")
109 (defun LaTeX-mathtools-auto-prepare ()
110 "Clear various variables for mathtools package before parsing."
111 (setq LaTeX-auto-mathtools-newtagform nil
112 LaTeX-auto-mathtools-DeclarePairedDelimiter nil
113 LaTeX-auto-mathtools-newgathered nil))
115 (defun LaTeX-mathtools-auto-cleanup ()
116 "Process the parsed elements for mathtools package."
117 (when (LaTeX-mathtools-DeclarePairedDelimiter-list)
118 (dolist (delim (LaTeX-mathtools-DeclarePairedDelimiter-list))
119 (let ((cmd (car delim))
121 (TeX-add-symbols `(,cmd [ LaTeX-mathtools-arg-mathsize-completion ]
122 ,(if (string= arg "")
124 (string-to-number arg)))
126 ,(if (string= arg "")
128 (string-to-number arg)))))))
129 (when (LaTeX-mathtools-newgathered-list)
130 (dolist (env (mapcar #'car (LaTeX-mathtools-newgathered-list)))
131 (LaTeX-add-environments env)
132 (add-to-list 'LaTeX-item-list
133 `(,env . LaTeX-item-equation) t)
134 (add-to-list 'LaTeX-label-alist
135 `(,env . LaTeX-amsmath-label) t)
136 (when (fboundp 'reftex-add-label-environments)
137 (reftex-add-label-environments `((,env ?e nil nil t)))))))
139 (add-hook 'TeX-auto-prepare-hook #'LaTeX-mathtools-auto-prepare t)
140 (add-hook 'TeX-auto-cleanup-hook #'LaTeX-mathtools-auto-cleanup t)
141 (add-hook 'TeX-update-style-hook #'TeX-auto-parse t)
143 (defun LaTeX-mathtools-arg-mathstyle-completion (optional)
144 "Query and insert mathstyle argument to various commands.
145 If OPTIONAL, insert it as optional argument in brackets."
148 (TeX-argument-prompt optional nil
149 (concat "Math style: " TeX-esc) t)
150 '("displaystyle" "textstyle"
151 "scriptstyle" "scriptscriptstyle"))
154 (defun LaTeX-mathtools-arg-mathsize-completion (optional)
155 "Query and insert math size argument to various commands.
156 If OPTIONAL, insert it as optional argument in brackets."
159 (TeX-argument-prompt optional nil
160 (concat "Size command: " TeX-esc) t)
161 '("big" "Big" "bigg" "Bigg"))
164 (defun LaTeX-mathtools-arg-declarepaireddelimiter (optional &optional X)
165 "Query and insert various \\DeclarePairedDelimiter macros from mathtools package."
166 (let ((cmd (TeX-read-string (concat "Command: " TeX-esc)))
167 (arg (when X (TeX-read-string
168 (TeX-argument-prompt t nil "Number of arguments")))))
169 (TeX-add-symbols `(,cmd [ LaTeX-mathtools-arg-mathsize-completion ]
171 ;; This is no precaution, arg has to be > 0
172 (string-to-number arg)
176 (string-to-number arg)
178 (LaTeX-add-mathtools-DeclarePairedDelimiters
179 `(,cmd ,(if X arg "")))
180 (TeX-argument-insert cmd optional TeX-esc)
182 (insert (concat LaTeX-optop arg LaTeX-optcl)))))
184 (defun LaTeX-mathtools-env-multlined (env)
185 "Query and insert two optional arguments for ENV multlined.
186 If both arguments are given, insert them in brackets. If only a
187 width is given, insert it prefixed with a pair of empty
189 (let ((pos (TeX-read-string
190 (TeX-argument-prompt t nil "Position (t, b or c (default))")))
191 (width (completing-read
192 (TeX-argument-prompt t nil "Width")
194 (lambda (x) (concat TeX-esc (car x)))
195 (LaTeX-length-list)))))
196 (LaTeX-insert-environment
198 (cond (;; both arguments
199 (and pos (not (string= pos ""))
200 width (not (string= width "")))
201 (format "[%s][%s]" pos width))
202 (;; pos not empty, width empty
203 (and pos (not (string= pos ""))
206 (;; pos empty, width not
207 (and (string= pos "")
208 width (not (string= width "")))
209 (format "[][%s]" width))
212 (defun LaTeX-mathtools-env-cases (env)
213 "Insert various cases ENVs incl. an ampersand from mathtools package."
214 (LaTeX-insert-environment env)
218 (defun LaTeX-mathtools-item-cases ()
219 "Insert contents to terminate a line in multi-line cases environment.
220 Put line break macro on the last line. Next, insert an ampersand."
223 (TeX-insert-macro "\\")
232 ;; Add mathtools to parser
233 (TeX-auto-add-regexp LaTeX-mathtools-newtagform-regexp)
234 (TeX-auto-add-regexp LaTeX-mathtools-DeclarePairedDelimiter-regexp)
235 (TeX-auto-add-regexp LaTeX-mathtools-newgathered-regexp)
237 ;; "default" is pre-defined
238 (LaTeX-add-mathtools-newtagforms "default")
240 ;; mathtools requires amsmath, as some bugs in amsmath are fixed
241 (TeX-run-style-hooks "amsmath")
243 (dolist (elt LaTeX-amsmath-package-options)
244 (add-to-list 'LaTeX-mathtools-package-options elt))
246 (LaTeX-add-environments
248 '("matrix*" [ "Vertical alignment (l, r or c (default))" ])
249 '("pmatrix*" [ "Vertical alignment (l, r or c (default))" ])
250 '("bmatrix*" [ "Vertical alignment (l, r or c (default))" ])
251 '("Bmatrix*" [ "Vertical alignment (l, r or c (default))" ])
252 '("vmatrix*" [ "Vertical alignment (l, r or c (default))" ])
253 '("Vmatrix*" [ "Vertical alignment (l, r or c (default))" ])
254 '("smallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
256 '("psmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
258 '("bsmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
260 '("Bsmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
262 '("vsmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
264 '("Vsmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
265 ;; 3.4.2 The multlined environment
266 '("multlined" LaTeX-mathtools-env-multlined)
267 ;; 3.4.3 More cases -like environments
268 '("dcases" LaTeX-mathtools-env-cases)
269 '("dcases*" LaTeX-mathtools-env-cases)
270 '("rcases" LaTeX-mathtools-env-cases)
271 '("rcases*" LaTeX-mathtools-env-cases)
272 '("drcases" LaTeX-mathtools-env-cases)
273 '("drcases*" LaTeX-mathtools-env-cases)
274 '("cases*" LaTeX-mathtools-env-cases)
275 ;; 4.4 Spreading equations
276 '("spreadlines" "Spacing between lines")
277 ;; 4.5 Gathered environments
278 '("lgathered" ["Vertical position (t or b)"])
279 '("rgathered" ["Vertical position (t or b)"]))
282 '("mathtoolsset" (TeX-arg-key-val LaTeX-mathtools-key-val-options))
283 ;; 3.1.1 A complement to \smash, \llap, and \rlap
284 '("mathllap" [ LaTeX-mathtools-arg-mathstyle-completion ] t)
285 '("mathrlap" [ LaTeX-mathtools-arg-mathstyle-completion ] t)
286 '("mathclap" [ LaTeX-mathtools-arg-mathstyle-completion ] t)
287 '("mathmakebox" [ (TeX-arg-length "Width") ] [ "Position" ] 1)
290 ;; 3.1.2 Forcing a cramped style
291 '("cramped" [ LaTeX-mathtools-arg-mathstyle-completion ] 1)
292 '("crampedllap" [ LaTeX-mathtools-arg-mathstyle-completion ] t)
293 '("crampedrlap" [ LaTeX-mathtools-arg-mathstyle-completion ] t)
294 '("crampedclap" [ LaTeX-mathtools-arg-mathstyle-completion ] t)
295 ;; 3.1.3 Smashing an operator
296 '("smashoperator" [ "Position (l, r or lr (default)" ] 1)
297 ;; 3.1.4 Adjusting the limits of operators
298 '("adjustlimits" t (TeX-arg-literal "_") nil nil (TeX-arg-literal "_") nil)
299 ;; 3.1.5 Swapping space above AMS display math environments
300 '("SwapAboveDisplaySkip" 0)
301 ;; 3.2.1 The appearance of tags
305 (let ((newtag (TeX-read-string
306 (TeX-argument-prompt nil nil "Name"))))
307 (LaTeX-add-mathtools-newtagforms newtag)
308 (format "%s" newtag))))
309 [ "Inner format" ] "Left" "Right")
311 (TeX-arg-eval completing-read
312 (TeX-argument-prompt nil nil "Name")
313 (LaTeX-mathtools-newtagform-list))
314 [ "Inner format" ] "Left" "Right")
316 (TeX-arg-eval completing-read
317 (TeX-argument-prompt nil nil "Name")
318 (LaTeX-mathtools-newtagform-list)))
319 ;; 3.2.2 Showing only referenced tags
320 '("refeq" TeX-arg-ref)
321 '("noeqref" TeX-arg-ref)
322 ;; 3.3.1 Arrow-like symbols
323 '("xleftrightarrow" ["Below"] "Above")
324 '("xLeftarrow" ["Below"] "Above")
325 '("xRightarrow" ["Below"] "Above")
326 '("xLeftrightarrow" ["Below"] "Above")
327 '("xhookleftarrow" ["Below"] "Above")
328 '("xhookrightarrow" ["Below"] "Above")
329 '("xmapsto" ["Below"] "Above")
330 '("xrightharpoondown" ["Below"] "Above")
331 '("xrightharpoonup" ["Below"] "Above")
332 '("xleftharpoondown" ["Below"] "Above")
333 '("xleftharpoonup" ["Below"] "Above")
334 '("xrightleftharpoons" ["Below"] "Above")
335 '("xleftrightharpoons" ["Below"] "Above")
336 ;; 3.3.2 Braces and brackets
337 '("underbracket" [ (TeX-arg-length "Rule thickness") ]
338 [ (TeX-arg-length "Bracket height") ] t)
339 '("overbracket" [ (TeX-arg-length "Rule thickness") ]
340 [ (TeX-arg-length "Bracket height") ] t)
343 '("LaTeXunderbrace" 1)
344 '("LaTeXoverbrace" 1)
346 '("shoveleft" [ (TeX-arg-length "Dimension") ] 1)
347 '("shoveright" [ (TeX-arg-length "Dimension") ] 1)
349 '("MoveEqLeft" [ "Number" ])
350 ;; 3.4.5 Boxing a single line in an alignment
352 ;; 3.4.6 Adding arrows between lines in an alignment
353 '("ArrowBetweenLines" [ TeX-arg-macro ] )
354 '("ArrowBetweenLines*" [ TeX-arg-macro ] )
355 ;; 3.4.7 Centered \vdots
356 '("vdotswithin" "Symbol")
357 '("shortvdotswithin" "Symbol")
358 '("shortvdotswithin*" "Symbol")
359 '("MTFlushSpaceAbove")
360 '("MTFlushSpaceBelow")
361 ;; 3.5 Intertext and short intertext
362 ;; don't understand t, but intertext in amsmath.el uses it
363 '("shortintertext" t)
364 ;; 3.6 Paired delimiters
365 '("DeclarePairedDelimiter"
366 LaTeX-mathtools-arg-declarepaireddelimiter
367 "Left delimiter" "Right delimiter")
368 '("DeclarePairedDelimiterX"
369 (LaTeX-mathtools-arg-declarepaireddelimiter t)
370 "Left delimiter" "Right delimiter" t)
371 '("DeclarePairedDelimiterXPP"
372 (LaTeX-mathtools-arg-declarepaireddelimiter t)
373 "Pre-code" "Left delimiter" "Right delimiter" 2)
376 '("reDeclarePairedDelimiterInnerWrapper"
379 (let ((cmd (completing-read
380 (concat "Command: " TeX-esc)
381 (mapcar #'car (LaTeX-mathtools-DeclarePairedDelimiter-list)))))
382 (concat TeX-esc cmd))))
383 (TeX-arg-eval completing-read
387 ;; 3.7.1 Left and right parentheses
388 '("lparen" TeX-arg-insert-right-brace-maybe)
390 ;; 3.7.2 Vertically centered colon
391 "vcentcolon" "ordinarycolon" "coloneqq" "Coloneqq"
392 "coloneq" "Coloneq" "eqqcolon" "Eqqcolon" "eqcolon"
393 "Eqcolon" "colonapprox" "Colonapprox" "colonsim" "Colonsim"
395 ;; 3.7.3 A few missing symbols
396 "nuparrow" "ndownarrow" "bigtimes"
397 ;; 4.2 Left sub/superscripts
398 '("prescript" "Below" "Above" t)
399 ;; 4.3 Declaring math sizes
400 '("DeclareMathSizes" 4)
401 ;; 4.5 Gathered environments
405 (let ((env (TeX-read-string
406 (TeX-argument-prompt nil nil "Name"))))
407 (LaTeX-add-environments env)
408 (LaTeX-add-mathtools-newgathereds env)
409 (add-to-list 'LaTeX-item-list
410 `(,env . LaTeX-item-equation) t)
411 (add-to-list 'LaTeX-label-alist
412 `(,env . LaTeX-amsmath-label) t)
416 (TeX-arg-eval completing-read
417 (TeX-argument-prompt nil nil "Name")
418 (LaTeX-mathtools-newgathered-list))
420 ;; 4.6 Split fractions
424 ;; Append delimiters to `TeX-braces-association'
425 ;; 3.7.1 Left and right parentheses
426 (make-local-variable 'TeX-braces-association)
427 (add-to-list 'TeX-braces-association '("\\lparen" . "\\rparen") t)
429 (setq LaTeX-item-list
430 (append '(("multlined" . LaTeX-item-equation)
431 ("lgathered" . LaTeX-item-equation)
432 ("rgathered" . LaTeX-item-equation)
433 ("spreadlines" . LaTeX-item-equation)
434 ("matrix*" . LaTeX-item-equation)
435 ("pmatrix*" . LaTeX-item-equation)
436 ("bmatrix*" . LaTeX-item-equation)
437 ("Bmatrix*" . LaTeX-item-equation)
438 ("vmatrix*" . LaTeX-item-equation)
439 ("Vmatrix*" . LaTeX-item-equation)
440 ("dcases" . LaTeX-mathtools-item-cases)
441 ("dcases*" . LaTeX-mathtools-item-cases)
442 ("rcases" . LaTeX-mathtools-item-cases)
443 ("rcases*" . LaTeX-mathtools-item-cases)
444 ("drcases" . LaTeX-mathtools-item-cases)
445 ("drcases*" . LaTeX-mathtools-item-cases)
446 ("cases*" . LaTeX-mathtools-item-cases))
449 (setq LaTeX-label-alist
450 (append '(("lgathered" . LaTeX-amsmath-label)
451 ("rgathered" . LaTeX-amsmath-label)
452 ("multlined" . LaTeX-amsmath-label))
455 ;; RefTeX support: Add env's with `reftex-add-label-environments'
456 (when (fboundp 'reftex-add-label-environments)
457 (let ((envs '(("lgathered" ?e nil nil t)
458 ("rgathered" ?e nil nil t)
459 ("multlined" ?e nil nil t))))
461 (reftex-add-label-environments `(,env)))))
464 (when (and (featurep 'font-latex)
465 (eq TeX-install-font-lock 'font-latex-setup))
466 (font-latex-add-keywords '(("mathtoolsset" "{")
467 ("newtagform" "{[{{")
468 ("renewtagform" "{[{{")
469 ("DeclarePairedDelimiter" "|{\\{{")
470 ("DeclarePairedDelimiterX" "|{\\[{{{")
471 ("DeclarePairedDelimiterXPP" "|{\\[{{{{{")
472 ("reDeclarePairedDelimiterInnerWrapper" "|{\\{{")
473 ("DeclareMathSizes" "{{{{")
474 ("newgathered" "{{{{")
475 ("renewgathered" "{{{{"))
477 (font-latex-add-keywords '(("usetagform" "{"))
479 (font-latex-add-keywords '(("refeq" "{")
484 ;;; mathtools.el ends here