EasyPG 1.07 Released
[packages] / xemacs-packages / auctex / style / mathtools.el
1 ;;; mathtools.el --- Style hook for the LaTeX package `mathtools'.
2
3 ;; Copyright (C) 2011-2012, 2014, 2016 Free Software Foundation, Inc.
4
5 ;; Author: Mads Jensen <mje@inducks.org>
6 ;; Created: 2011-02-13
7 ;; Keywords: tex
8
9 ;; This file is part of AUCTeX.
10
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)
14 ;; any later version.
15
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.
20
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
24 ;; 02110-1301, USA.
25
26 ;;; Commentary:
27
28 ;;  This file adds support for `mathtools.sty'
29
30 ;;; Comments:
31
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>
36
37 ;;; Code:
38
39 ;; Needed for auto-parsing.
40 (require 'tex)
41
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)
48     "nonrobust")
49   "Package options for the mathtools package.")
50
51 (defvar LaTeX-mathtools-key-val-options
52   '(("showonlyrefs")
53     ("mathic" ("true" "false"))
54     ("showmanualtags" ("true" "false"))
55     ;; 3.4.1 Matrices
56     ("smallmatrix-align" ("c" "l" "r"))
57     ("smallmatrix-inner-space")
58     ;; 3.4.2 The multlined environment
59     ("firstline-afterskip")
60     ("lastline-preskip")
61     ("multlined-pos" ("c" "b" "t"))
62     ("multlined-width")
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.")
80
81 ;; Setup for \newtagform
82 (TeX-auto-add-type "mathtools-newtagform" "LaTeX")
83
84 (defvar LaTeX-mathtools-newtagform-regexp
85   '("\\\\newtagform{\\([^}]+\\)}"
86     1 LaTeX-auto-mathtools-newtagform)
87   "Matches the first argument of \\newtagform from mathtools package.")
88
89 ;; Setup for \DeclarePairedDelimiter(X)?:
90 (TeX-auto-add-type "mathtools-DeclarePairedDelimiter" "LaTeX")
91
92 (defvar LaTeX-mathtools-DeclarePairedDelimiter-regexp
93   `(,(concat "\\\\DeclarePairedDelimiter\\(?:X\\|XPP\\)?"
94              "{?"
95              "\\\\\\([a-zA-Z]+\\)"
96              "}?"
97              "\\(?:\\[\\([0-9]+\\)\\]\\)?")
98     (1 2) LaTeX-auto-mathtools-DeclarePairedDelimiter)
99   "Match the arguments of \\DeclarePairedDelimiterX? from mathtools package.")
100
101 ;; Setup for \newgathered
102 (TeX-auto-add-type "mathtools-newgathered" "LaTeX")
103
104 (defvar LaTeX-mathtools-newgathered-regexp
105   '("\\\\newgathered{\\([^}]+\\)}"
106     1 LaTeX-auto-mathtools-newgathered)
107   "Matches the first argument of \\newgathered from mathtools package.")
108
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))
114
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))
120             (arg (cadr delim)))
121         (TeX-add-symbols `(,cmd [ LaTeX-mathtools-arg-mathsize-completion ]
122                                 ,(if (string= arg "")
123                                      1
124                                    (string-to-number arg)))
125                          `(,(concat cmd "*")
126                            ,(if (string= arg "")
127                                 1
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)))))))
138
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)
142
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."
146   (TeX-argument-insert
147    (completing-read
148     (TeX-argument-prompt optional nil
149                          (concat "Math style: " TeX-esc) t)
150     '("displaystyle" "textstyle"
151       "scriptstyle"  "scriptscriptstyle"))
152    optional TeX-esc))
153
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."
157   (TeX-argument-insert
158    (completing-read
159     (TeX-argument-prompt optional nil
160                          (concat "Size command: " TeX-esc) t)
161     '("big" "Big" "bigg" "Bigg"))
162    optional TeX-esc))
163
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 ]
170                             ,(if X
171                                  ;; This is no precaution, arg has to be > 0
172                                  (string-to-number arg)
173                                1))
174                      `(,(concat cmd "*")
175                        ,(if X
176                             (string-to-number arg)
177                           1)))
178     (LaTeX-add-mathtools-DeclarePairedDelimiters
179      `(,cmd ,(if X arg "")))
180     (TeX-argument-insert cmd optional TeX-esc)
181     (when arg
182       (insert (concat LaTeX-optop arg LaTeX-optcl)))))
183
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
188 brackets."
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")
193                 (mapcar
194                  (lambda (x) (concat TeX-esc (car x)))
195                  (LaTeX-length-list)))))
196     (LaTeX-insert-environment
197      env
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 ""))
204                  (string= width ""))
205             (format "[%s]" pos))
206            (;; pos empty, width not
207             (and (string= pos "")
208                  width (not (string= width "")))
209             (format "[][%s]" width))
210            (t nil)))))
211
212 (defun LaTeX-mathtools-env-cases (env)
213   "Insert various cases ENVs incl. an ampersand from mathtools package."
214   (LaTeX-insert-environment env)
215   (save-excursion
216     (insert ?&)))
217
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."
221   (end-of-line 0)
222   (just-one-space)
223   (TeX-insert-macro "\\")
224   (forward-line 1)
225   (save-excursion
226     (insert ?&)))
227
228 (TeX-add-style-hook
229  "mathtools"
230  (lambda ()
231
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)
236
237    ;; "default" is pre-defined
238    (LaTeX-add-mathtools-newtagforms "default")
239
240    ;; mathtools requires amsmath, as some bugs in amsmath are fixed
241    (TeX-run-style-hooks "amsmath")
242
243    (dolist (elt LaTeX-amsmath-package-options)
244      (add-to-list 'LaTeX-mathtools-package-options elt))
245
246    (LaTeX-add-environments
247     ;; 3.4.1 Matrices
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))" ])
255     '("psmallmatrix")
256     '("psmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
257     '("bsmallmatrix")
258     '("bsmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
259     '("Bsmallmatrix")
260     '("Bsmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
261     '("vsmallmatrix")
262     '("vsmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
263     '("Vsmallmatrix")
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)"]))
280
281    (TeX-add-symbols
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)
288     '("clap" 1)
289     '("mathmbox" 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
302     '("newtagform"
303       (TeX-arg-eval
304        (lambda ()
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")
310     '("renewtagform"
311       (TeX-arg-eval completing-read
312                     (TeX-argument-prompt nil nil "Name")
313                     (LaTeX-mathtools-newtagform-list))
314       [ "Inner format" ] "Left" "Right")
315     '("usetagform"
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)
341     '("underbrace" 1)
342     '("overbrace" 1)
343     '("LaTeXunderbrace" 1)
344     '("LaTeXoverbrace" 1)
345     ;; 3.4.2
346     '("shoveleft"  [ (TeX-arg-length "Dimension") ] 1)
347     '("shoveright" [ (TeX-arg-length "Dimension") ] 1)
348     ;; 3.4.4
349     '("MoveEqLeft" [ "Number" ])
350     ;; 3.4.5 Boxing a single line in an alignment
351     '("Aboxed" 1)
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)
374     '("delimsize" 0)
375     ;; 3.6.1 Expert use
376     '("reDeclarePairedDelimiterInnerWrapper"
377       (TeX-arg-eval
378        (lambda ()
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
384                     "star or nostar: "
385                     '("star" "nostar"))
386       t)
387     ;; 3.7.1 Left and right parentheses
388     '("lparen" TeX-arg-insert-right-brace-maybe)
389     '("rparen")
390     ;; 3.7.2 Vertically centered colon
391     "vcentcolon" "ordinarycolon" "coloneqq" "Coloneqq"
392     "coloneq" "Coloneq" "eqqcolon" "Eqqcolon" "eqcolon"
393     "Eqcolon" "colonapprox" "Colonapprox" "colonsim" "Colonsim"
394     "dblcolon"
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
402     '("newgathered"
403       (TeX-arg-eval
404        (lambda ()
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)
413            (format "%s" env))))
414       3)
415     '("renewgathered"
416       (TeX-arg-eval completing-read
417                     (TeX-argument-prompt nil nil "Name")
418                     (LaTeX-mathtools-newgathered-list))
419       3)
420     ;; 4.6 Split fractions
421     '("splitfrac" 2)
422     '("splitdfrac" 2))
423
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)
428
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))
447                  LaTeX-item-list))
448
449    (setq LaTeX-label-alist
450          (append '(("lgathered" . LaTeX-amsmath-label)
451                    ("rgathered" . LaTeX-amsmath-label)
452                    ("multlined" . LaTeX-amsmath-label))
453                  LaTeX-label-alist))
454
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))))
460        (dolist (env envs)
461          (reftex-add-label-environments `(,env)))))
462
463    ;; Fontification
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"              "{{{{"))
476                               'function)
477      (font-latex-add-keywords '(("usetagform" "{"))
478                               'variable)
479      (font-latex-add-keywords '(("refeq"   "{")
480                                 ("noeqref" "{"))
481                               'reference)))
482  LaTeX-dialect)
483
484 ;;; mathtools.el ends here