emacs/code/elpa/auctex-13.1.3/style/mathtools.el

505 lines
20 KiB
EmacsLisp

;;; mathtools.el --- Style hook for the LaTeX package `mathtools'. -*- lexical-binding: t; -*-
;; Copyright (C) 2011-2020, 2022 Free Software Foundation, Inc.
;; Author: Mads Jensen <mje@inducks.org>
;; Created: 2011-02-13
;; Keywords: tex
;; This file is part of AUCTeX.
;; AUCTeX is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; AUCTeX is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with AUCTeX; see the file COPYING. If not, write to the Free
;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
;; 02110-1301, USA.
;;; Commentary:
;; This file adds support for `mathtools.sty'
;;; Comments:
;;; This package serves as a wrapper for amsmath, adding more features
;;; and fixing a few bugs in amsmath. The mathstyle argument for many
;;; of the macros is discussed at
;;; <https://www.tug.org/TUGboat/Articles/tb22-4/tb72perlS.pdf>
;;; Code:
;; Needed for auto-parsing:
(require 'tex)
(require 'latex)
;; Silence the compiler:
(declare-function font-latex-add-keywords
"font-latex"
(keywords class))
(defvar LaTeX-amsmath-package-options)
;; amsmath options which can be passed directly to mathtools are
;; appended in the style hook below
(defvar LaTeX-mathtools-package-options
'("fixamsmath" "donotfixamsmathbugs" "allowspaces" "disallowspaces"
;; Update 2013: We now make \(\) and \[\] robust (can be disabled
;; via nonrobust package option)
"nonrobust")
"Package options for the mathtools package.")
(TeX-load-style "amsmath")
(dolist (elt LaTeX-amsmath-package-options)
(add-to-list 'LaTeX-mathtools-package-options elt))
(defvar LaTeX-mathtools-key-val-options
'(("showonlyrefs")
("mathic" ("true" "false"))
("showmanualtags" ("true" "false"))
;; 3.4.1 Matrices
("smallmatrix-align" ("c" "l" "r"))
("smallmatrix-inner-space")
;; 3.4.2 The multlined environment
("firstline-afterskip")
("lastline-preskip")
("multlined-pos" ("c" "b" "t"))
("multlined-width")
;; 3.4.7 Centered \vdots
("shortvdotsadjustabove")
("shortvdotsadjustbelow")
;; 3.5 Intertext and short intertext
("original-intertext" ("true" "false"))
("original-shortintertext" ("true" "false"))
("above-intertext-sep")
("below-intertext-sep")
("above-shortintertext-sep")
("below-shortintertext-sep")
;; 3.7.2 Vertically centered colon
("centercolon" ("true" "false"))
;; 4.2 Left sub/superscripts
("prescript-sub-format")
("prescript-sup-format")
("prescript-arg-format"))
"Options for the \\mathtoolsset command.")
;; Setup for \newtagform
(TeX-auto-add-type "mathtools-newtagform" "LaTeX")
(defvar LaTeX-mathtools-newtagform-regexp
'("\\\\newtagform{\\([^}]+\\)}"
1 LaTeX-auto-mathtools-newtagform)
"Matches the first argument of \\newtagform from mathtools package.")
;; Setup for \DeclarePairedDelimiter(X)?:
(TeX-auto-add-type "mathtools-DeclarePairedDelimiter" "LaTeX")
(defvar LaTeX-mathtools-DeclarePairedDelimiter-regexp
`(,(concat "\\\\DeclarePairedDelimiter\\(?:X\\|XPP\\)?"
"{?"
"\\\\\\([a-zA-Z]+\\)"
"}?"
"\\(?:\\[\\([0-9]+\\)\\]\\)?")
(1 2) LaTeX-auto-mathtools-DeclarePairedDelimiter)
"Match the arguments of \\DeclarePairedDelimiterX? from mathtools package.")
;; Setup for \newgathered
(TeX-auto-add-type "mathtools-newgathered" "LaTeX")
(defvar LaTeX-mathtools-newgathered-regexp
'("\\\\newgathered{\\([^}]+\\)}"
1 LaTeX-auto-mathtools-newgathered)
"Matches the first argument of \\newgathered from mathtools package.")
(defun LaTeX-mathtools-auto-prepare ()
"Clear various variables for mathtools package before parsing."
(setq LaTeX-auto-mathtools-newtagform nil
LaTeX-auto-mathtools-DeclarePairedDelimiter nil
LaTeX-auto-mathtools-newgathered nil))
(defun LaTeX-mathtools-auto-cleanup ()
"Process the parsed elements for mathtools package."
(when (LaTeX-mathtools-DeclarePairedDelimiter-list)
(dolist (delim (LaTeX-mathtools-DeclarePairedDelimiter-list))
(let ((cmd (car delim))
(arg (cadr delim)))
(TeX-add-symbols `(,cmd [ LaTeX-mathtools-arg-mathsize-completion ]
,(if (string= arg "")
1
(string-to-number arg)))
`(,(concat cmd "*")
,(if (string= arg "")
1
(string-to-number arg)))))))
(when (LaTeX-mathtools-newgathered-list)
(dolist (env (mapcar #'car (LaTeX-mathtools-newgathered-list)))
(LaTeX-add-environments env)
(add-to-list 'LaTeX-item-list
`(,env . LaTeX-item-equation) t)
(add-to-list 'LaTeX-label-alist
`(,env . LaTeX-amsmath-label) t)
(when (fboundp 'reftex-add-label-environments)
(reftex-add-label-environments `((,env ?e nil nil t)))))))
(add-hook 'TeX-auto-prepare-hook #'LaTeX-mathtools-auto-prepare t)
(add-hook 'TeX-auto-cleanup-hook #'LaTeX-mathtools-auto-cleanup t)
(add-hook 'TeX-update-style-hook #'TeX-auto-parse t)
(defun LaTeX-mathtools-arg-mathstyle-completion (optional)
"Query and insert mathstyle argument to various commands.
If OPTIONAL, insert it as optional argument in brackets."
(TeX-argument-insert
(completing-read
(TeX-argument-prompt optional nil
(concat "Math style: " TeX-esc) t)
'("displaystyle" "textstyle"
"scriptstyle" "scriptscriptstyle"))
optional TeX-esc))
(defun LaTeX-mathtools-arg-mathsize-completion (optional)
"Query and insert math size argument to various commands.
If OPTIONAL, insert it as optional argument in brackets."
(TeX-argument-insert
(completing-read
(TeX-argument-prompt optional nil
(concat "Size command: " TeX-esc) t)
'("big" "Big" "bigg" "Bigg"))
optional TeX-esc))
(defun LaTeX-mathtools-arg-declarepaireddelimiter (optional &optional X)
"Query and insert various \\DeclarePairedDelimiter macros from mathtools package."
(let ((cmd (TeX-read-string (concat "Command: " TeX-esc)))
(arg (when X (TeX-read-string
(TeX-argument-prompt t nil "Number of arguments")))))
(TeX-add-symbols `(,cmd [ LaTeX-mathtools-arg-mathsize-completion ]
,(if X
;; This is no precaution, arg has to be > 0
(string-to-number arg)
1))
`(,(concat cmd "*")
,(if X
(string-to-number arg)
1)))
(LaTeX-add-mathtools-DeclarePairedDelimiters
`(,cmd ,(if X arg "")))
(TeX-argument-insert cmd optional TeX-esc)
(when arg
(insert (concat LaTeX-optop arg LaTeX-optcl)))))
(defun LaTeX-mathtools-env-multlined (env)
"Query and insert two optional arguments for ENV multlined.
If both arguments are given, insert them in brackets. If only a
width is given, insert it prefixed with a pair of empty
brackets."
(let ((pos (TeX-read-string
(TeX-argument-prompt t nil "Position (t, b or c (default))")))
(width (completing-read
(TeX-argument-prompt t nil "Width")
(mapcar
(lambda (x) (concat TeX-esc (car x)))
(LaTeX-length-list)))))
(LaTeX-insert-environment
env
(cond (;; both arguments
(and pos (not (string= pos ""))
width (not (string= width "")))
(format "[%s][%s]" pos width))
(;; pos not empty, width empty
(and pos (not (string= pos ""))
(string= width ""))
(format "[%s]" pos))
(;; pos empty, width not
(and (string= pos "")
width (not (string= width "")))
(format "[][%s]" width))
(t nil)))))
(defun LaTeX-mathtools-env-cases (env)
"Insert various cases ENVs incl. an ampersand from mathtools package."
(LaTeX-insert-environment env)
(save-excursion
(insert ?&)))
(defun LaTeX-mathtools-item-cases ()
"Insert contents to terminate a line in multi-line cases environment.
Put line break macro on the last line. Next, insert an ampersand."
(end-of-line 0)
(just-one-space)
(TeX-insert-macro "\\")
(forward-line 1)
(save-excursion
(insert ?&)))
(TeX-add-style-hook
"mathtools"
(lambda ()
;; Add mathtools to parser
(TeX-auto-add-regexp LaTeX-mathtools-newtagform-regexp)
(TeX-auto-add-regexp LaTeX-mathtools-DeclarePairedDelimiter-regexp)
(TeX-auto-add-regexp LaTeX-mathtools-newgathered-regexp)
;; "default" is pre-defined
(LaTeX-add-mathtools-newtagforms "default")
;; mathtools requires amsmath, as some bugs in amsmath are fixed
(TeX-run-style-hooks "amsmath")
(LaTeX-add-environments
;; 3.4.1 Matrices
'("matrix*" [ "Vertical alignment (l, r or c (default))" ])
'("pmatrix*" [ "Vertical alignment (l, r or c (default))" ])
'("bmatrix*" [ "Vertical alignment (l, r or c (default))" ])
'("Bmatrix*" [ "Vertical alignment (l, r or c (default))" ])
'("vmatrix*" [ "Vertical alignment (l, r or c (default))" ])
'("Vmatrix*" [ "Vertical alignment (l, r or c (default))" ])
'("smallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
'("psmallmatrix")
'("psmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
'("bsmallmatrix")
'("bsmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
'("Bsmallmatrix")
'("Bsmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
'("vsmallmatrix")
'("vsmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
'("Vsmallmatrix")
'("Vsmallmatrix*" [ "Vertical alignment (l, r or c (default))" ])
;; 3.4.2 The multlined environment
'("multlined" LaTeX-mathtools-env-multlined)
;; 3.4.3 More cases -like environments
'("dcases" LaTeX-mathtools-env-cases)
'("dcases*" LaTeX-mathtools-env-cases)
'("rcases" LaTeX-mathtools-env-cases)
'("rcases*" LaTeX-mathtools-env-cases)
'("drcases" LaTeX-mathtools-env-cases)
'("drcases*" LaTeX-mathtools-env-cases)
'("cases*" LaTeX-mathtools-env-cases)
;; 4.4 Spreading equations
'("spreadlines" "Spacing between lines")
;; 4.5 Gathered environments
'("lgathered" ["Vertical position (t or b)"])
'("rgathered" ["Vertical position (t or b)"]))
(TeX-add-symbols
'("mathtoolsset" (TeX-arg-key-val LaTeX-mathtools-key-val-options))
;; 3.1.1 A complement to \smash, \llap, and \rlap
'("mathllap" [ LaTeX-mathtools-arg-mathstyle-completion ] t)
'("mathrlap" [ LaTeX-mathtools-arg-mathstyle-completion ] t)
'("mathclap" [ LaTeX-mathtools-arg-mathstyle-completion ] t)
'("mathmakebox" [ (TeX-arg-length "Width") ] [ "Position" ] 1)
'("clap" 1)
'("mathmbox" 1)
;; 3.1.2 Forcing a cramped style
'("cramped" [ LaTeX-mathtools-arg-mathstyle-completion ] 1)
'("crampedllap" [ LaTeX-mathtools-arg-mathstyle-completion ] t)
'("crampedrlap" [ LaTeX-mathtools-arg-mathstyle-completion ] t)
'("crampedclap" [ LaTeX-mathtools-arg-mathstyle-completion ] t)
;; 3.1.3 Smashing an operator
'("smashoperator" [ "Position (l, r or lr (default)" ] 1)
;; 3.1.4 Adjusting the limits of operators
'("adjustlimits" t (TeX-arg-literal "_") nil nil (TeX-arg-literal "_") nil)
;; 3.1.5 Swapping space above AMS display math environments
'("SwapAboveDisplaySkip" 0)
;; 3.2.1 The appearance of tags
'("newtagform"
(TeX-arg-eval
(lambda ()
(let ((newtag (TeX-read-string
(TeX-argument-prompt nil nil "Name"))))
(LaTeX-add-mathtools-newtagforms newtag)
(format "%s" newtag))))
[ "Inner format" ] "Left" "Right")
'("renewtagform"
(TeX-arg-eval completing-read
(TeX-argument-prompt nil nil "Name")
(LaTeX-mathtools-newtagform-list))
[ "Inner format" ] "Left" "Right")
'("usetagform"
(TeX-arg-eval completing-read
(TeX-argument-prompt nil nil "Name")
(LaTeX-mathtools-newtagform-list)))
;; 3.2.2 Showing only referenced tags
'("refeq" TeX-arg-ref)
'("noeqref" TeX-arg-ref)
;; 3.3.1 Arrow-like symbols
'("xleftrightarrow" ["Below"] "Above")
'("xLeftarrow" ["Below"] "Above")
'("xRightarrow" ["Below"] "Above")
'("xLeftrightarrow" ["Below"] "Above")
'("xhookleftarrow" ["Below"] "Above")
'("xhookrightarrow" ["Below"] "Above")
'("xmapsto" ["Below"] "Above")
'("xrightharpoondown" ["Below"] "Above")
'("xrightharpoonup" ["Below"] "Above")
'("xleftharpoondown" ["Below"] "Above")
'("xleftharpoonup" ["Below"] "Above")
'("xrightleftharpoons" ["Below"] "Above")
'("xleftrightharpoons" ["Below"] "Above")
;; 3.3.2 Braces and brackets
'("underbracket" [ (TeX-arg-length "Rule thickness") ]
[ (TeX-arg-length "Bracket height") ] t)
'("overbracket" [ (TeX-arg-length "Rule thickness") ]
[ (TeX-arg-length "Bracket height") ] t)
'("underbrace" 1)
'("overbrace" 1)
'("LaTeXunderbrace" 1)
'("LaTeXoverbrace" 1)
;; 3.4.2
'("shoveleft" [ (TeX-arg-length "Dimension") ] 1)
'("shoveright" [ (TeX-arg-length "Dimension") ] 1)
;; 3.4.4
'("MoveEqLeft" [ "Number" ])
;; 3.4.5 Boxing a single line in an alignment
'("Aboxed" 1)
;; 3.4.6 Adding arrows between lines in an alignment
'("ArrowBetweenLines" [ TeX-arg-macro ] )
'("ArrowBetweenLines*" [ TeX-arg-macro ] )
;; 3.4.7 Centered \vdots
'("vdotswithin" "Symbol")
'("shortvdotswithin" "Symbol")
'("shortvdotswithin*" "Symbol")
'("MTFlushSpaceAbove")
'("MTFlushSpaceBelow")
;; 3.5 Intertext and short intertext
;; don't understand t, but intertext in amsmath.el uses it
'("shortintertext" t)
;; 3.6 Paired delimiters
'("DeclarePairedDelimiter"
LaTeX-mathtools-arg-declarepaireddelimiter
"Left delimiter" "Right delimiter")
'("DeclarePairedDelimiterX"
(LaTeX-mathtools-arg-declarepaireddelimiter t)
"Left delimiter" "Right delimiter" t)
'("DeclarePairedDelimiterXPP"
(LaTeX-mathtools-arg-declarepaireddelimiter t)
"Pre-code" "Left delimiter" "Right delimiter" 2)
'("delimsize" 0)
;; 3.6.1 Expert use
'("reDeclarePairedDelimiterInnerWrapper"
(TeX-arg-eval
(lambda ()
(let ((cmd (completing-read
(concat "Command: " TeX-esc)
(mapcar #'car (LaTeX-mathtools-DeclarePairedDelimiter-list)))))
(concat TeX-esc cmd))))
(TeX-arg-eval completing-read
"star or nostar: "
'("star" "nostar"))
t)
;; 3.7.1 Left and right parentheses
'("lparen" TeX-arg-insert-right-brace-maybe)
'("rparen")
;; 3.7.2 Vertically centered colon
"vcentcolon" "ordinarycolon" "coloneqq" "Coloneqq"
"coloneq" "Coloneq" "eqqcolon" "Eqqcolon" "eqcolon"
"Eqcolon" "colonapprox" "Colonapprox" "colonsim" "Colonsim"
"dblcolon"
;; 3.7.3 A few missing symbols
"nuparrow" "ndownarrow" "bigtimes"
;; 4.2 Left sub/superscripts
'("prescript" "Below" "Above" t)
;; 4.3 Declaring math sizes
'("DeclareMathSizes" 4)
;; 4.5 Gathered environments
'("newgathered"
(TeX-arg-eval
(lambda ()
(let ((env (TeX-read-string
(TeX-argument-prompt nil nil "Name"))))
(LaTeX-add-environments env)
(LaTeX-add-mathtools-newgathereds env)
(add-to-list 'LaTeX-item-list
`(,env . LaTeX-item-equation) t)
(add-to-list 'LaTeX-label-alist
`(,env . LaTeX-amsmath-label) t)
(format "%s" env))))
3)
'("renewgathered"
(TeX-arg-eval completing-read
(TeX-argument-prompt nil nil "Name")
(LaTeX-mathtools-newgathered-list))
3)
;; 4.6 Split fractions
'("splitfrac" 2)
'("splitdfrac" 2))
;; Append delimiters to `TeX-braces-association'
;; 3.7.1 Left and right parentheses
(make-local-variable 'TeX-braces-association)
(add-to-list 'TeX-braces-association '("\\lparen" . "\\rparen") t)
(setq LaTeX-item-list
(append '(("multlined" . LaTeX-item-equation)
("lgathered" . LaTeX-item-equation)
("rgathered" . LaTeX-item-equation)
;; FIXME: The entry for spreadlines seems dubious.
("spreadlines" . LaTeX-item-equation)
("matrix*" . LaTeX-item-equation)
("pmatrix*" . LaTeX-item-equation)
("bmatrix*" . LaTeX-item-equation)
("Bmatrix*" . LaTeX-item-equation)
("vmatrix*" . LaTeX-item-equation)
("Vmatrix*" . LaTeX-item-equation)
("smallmatrix*" . LaTeX-item-equation)
("psmallmatrix" . LaTeX-item-equation)
("psmallmatrix*" . LaTeX-item-equation)
("bsmallmatrix" . LaTeX-item-equation)
("bsmallmatrix*" . LaTeX-item-equation)
("Bsmallmatrix" . LaTeX-item-equation)
("Bsmallmatrix*" . LaTeX-item-equation)
("vsmallmatrix" . LaTeX-item-equation)
("vsmallmatrix*" . LaTeX-item-equation)
("Vsmallmatrix" . LaTeX-item-equation)
("Vsmallmatrix*" . LaTeX-item-equation)
("dcases" . LaTeX-mathtools-item-cases)
("dcases*" . LaTeX-mathtools-item-cases)
("rcases" . LaTeX-mathtools-item-cases)
("rcases*" . LaTeX-mathtools-item-cases)
("drcases" . LaTeX-mathtools-item-cases)
("drcases*" . LaTeX-mathtools-item-cases)
("cases*" . LaTeX-mathtools-item-cases))
LaTeX-item-list))
(setq LaTeX-label-alist
(append '(("lgathered" . LaTeX-amsmath-label)
("rgathered" . LaTeX-amsmath-label)
("multlined" . LaTeX-amsmath-label))
LaTeX-label-alist))
;; RefTeX support: Add env's with `reftex-add-label-environments'
(when (fboundp 'reftex-add-label-environments)
(let ((envs '(("lgathered" ?e nil nil t)
("rgathered" ?e nil nil t)
("multlined" ?e nil nil t))))
(dolist (env envs)
(reftex-add-label-environments `(,env)))))
;; Fontification
(when (and (featurep 'font-latex)
(eq TeX-install-font-lock 'font-latex-setup))
(font-latex-add-keywords '(("mathtoolsset" "{")
("newtagform" "{[{{")
("renewtagform" "{[{{")
("DeclarePairedDelimiter" "|{\\{{")
("DeclarePairedDelimiterX" "|{\\[{{{")
("DeclarePairedDelimiterXPP" "|{\\[{{{{{")
("reDeclarePairedDelimiterInnerWrapper" "|{\\{{")
("DeclareMathSizes" "{{{{")
("newgathered" "{{{{")
("renewgathered" "{{{{"))
'function)
(font-latex-add-keywords '(("usetagform" "{"))
'variable)
(font-latex-add-keywords '(("refeq" "{")
("noeqref" "{"))
'reference)))
TeX-dialect)
;;; mathtools.el ends here