summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/mathcommand
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/mathcommand
Initial commit
Diffstat (limited to 'macros/latex/contrib/mathcommand')
-rw-r--r--macros/latex/contrib/mathcommand/README.md36
-rw-r--r--macros/latex/contrib/mathcommand/makefile49
-rw-r--r--macros/latex/contrib/mathcommand/mathcommand.dtx1160
-rw-r--r--macros/latex/contrib/mathcommand/mathcommand.ins68
-rw-r--r--macros/latex/contrib/mathcommand/mathcommand.pdfbin0 -> 446268 bytes
5 files changed, 1313 insertions, 0 deletions
diff --git a/macros/latex/contrib/mathcommand/README.md b/macros/latex/contrib/mathcommand/README.md
new file mode 100644
index 0000000000..fe154ad579
--- /dev/null
+++ b/macros/latex/contrib/mathcommand/README.md
@@ -0,0 +1,36 @@
+%%%%%%%%
+This directory contains the package
+
+ name: mathcommand
+ license: LaTeX Project Public License version 1.2 or above
+ version: v1.02
+ date: 2019/07/03
+ author: Thomas Colcombet
+ mail: thomas.colcombet@irif.fr
+ web: -
+
+Purpose:
+ The mathcommand package provides functionalities for defining macros:
+ - that have different behaviors depending on whether in math or text mode,
+ - absorb Primes, Indices, Exponents (PIE) following LaTeX notations and
+ have them as extra parameters usable in the code.
+ The primary objective of this code is to be used together with the knowledge
+ package for a proper handling of mathematical notations.
+
+Install:
+ It is sufficient to have the file mathcommand.sty accessible by LaTeX.
+ It can be produced by `make mathcommand.sty' if necessary.
+ The documentation is in the file mathcommand.pdf.
+
+Content of the file mathcommand-ctan.zip:
+ - README.md: this file generated while compiling mathcommand.ins,
+ - mathcommand.sty: the package file (generated using knowledge.ins)
+ - mathcommand.pdf: the user documentation (generated by compiling
+ mathcommand.dtx)
+ - makefile: the makefile. Use 'make all' to generate mathcommand.sty
+ and knowledge.pdf. It can also: clean the directory, make zip
+ version of the sources, or ready for CTAN.
+ - mathcommand.ins: is the file generating mathcommand.sty and
+ README.md from mathcommand.dtx (using docstrip).
+ - mathcommand.dtx: code and documentation.
+
diff --git a/macros/latex/contrib/mathcommand/makefile b/macros/latex/contrib/mathcommand/makefile
new file mode 100644
index 0000000000..0e802f1fad
--- /dev/null
+++ b/macros/latex/contrib/mathcommand/makefile
@@ -0,0 +1,49 @@
+help:
+ @echo "This is the makefile for the mathcommand package"
+ @echo "- all: produces mathcommand.pdf mathcommand.sty mathcommand-code.pdf README.md"
+ @echo "- clean"
+ @echo "- ctan: creates the mathcommand-ctan.zip file tailored for CTAN"
+
+all: mathcommand.sty mathcommand.pdf README.md
+
+mathcommand.sty: mathcommand.dtx mathcommand.ins
+ latex mathcommand.ins
+
+README.md: mathcommand.dtx mathcommand.ins
+ latex mathcommand.ins
+
+clean:
+ rm -f *.aux *.glo *.idx *.aux *.synctex.gz *.out *.toc *.kaux *.diagnose *.log
+ rm -f *.bbl *.out *.bbl *.ind *.ilg *.idx
+ rm -f mathcommand.sty
+ rm -f mathcommand.pdf
+ rm -f mathcommand-sources-complete.zip
+ rm -f mathcommand-ctan.zip
+ rm -f README.md
+
+ctan: mathcommand-ctan.zip
+
+mathcommand.pdf: mathcommand.dtx mathcommand.sty
+ pdflatex mathcommand.dtx
+ pdflatex mathcommand.dtx
+ pdflatex mathcommand.dtx
+
+mathcommand.aux: mathcommand.dtx mathcommand.sty
+ pdflatex mathcommand.dtx
+
+sources: clean mathcommand-ctan.zip mathcommand-sources-complete.zip
+
+mathcommand-sources-complete.zip: clean
+ \rm -f mathcommand-sources-complete.zip
+ cp mathcommand-sources-complete.zip ../mathcommand-sources-complete-`date +%y-%m-%d_%H:%M`.zip
+
+mathcommand-ctan.zip: mathcommand.pdf mathcommand.sty mathcommand.ins README.md makefile
+ rm -f mathcommand-ctan.zip
+ rm -rf mathcommand
+ mkdir mathcommand
+ cp mathcommand.pdf mathcommand/
+ cp mathcommand.dtx mathcommand/
+ cp makefile mathcommand.ins README.md mathcommand/
+ zip mathcommand-ctan.zip mathcommand/*
+ rm -rf mathcommand
+
diff --git a/macros/latex/contrib/mathcommand/mathcommand.dtx b/macros/latex/contrib/mathcommand/mathcommand.dtx
new file mode 100644
index 0000000000..ca621c869d
--- /dev/null
+++ b/macros/latex/contrib/mathcommand/mathcommand.dtx
@@ -0,0 +1,1160 @@
+% \iffalse
+% !TEX encoding = UTF-8 Unicode
+% !TEX TS-program = pdflatex
+%
+%
+%
+% meta-comment
+%
+% Copyright (C) 2019-2019 by Thomas Colcombet
+% -----------------------------------
+%
+% This file may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.2
+% of this license or (at your option) any later version.
+% The latest version of this license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.2 or later is part of all distributions of LaTeX
+% version 1999/12/01 or later.
+%
+% \fi
+%
+% \iffalse
+%<head>\usepackage{expl3}
+%<head>\ProvidesExplPackage{mathcommand}{2019/07/03}{1.02}{}
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{paralist}
+\usepackage[svgnames]{xcolor}
+\usepackage{expl3}
+\usepackage{mathcommand}
+\usepackage[hidelinks]{hyperref}
+\usepackage[quotation,scope,electronic]{knowledge}
+\usepackage{enumitem}
+
+\CheckSum{0}
+\changes{1.01}{2019/05/12}{Initial version} %
+\changes{1.02}{2019/07/03}{Bug correction} %
+\GetFileInfo{mathcommand.sty} %
+\DoNotIndex{}
+\edef\mathcommandversiondate{\fileversion--\filedate}
+
+
+
+
+
+ \newcommand\smallcode[1]{\colorbox{Honeydew}{\texttt{#1}}}
+
+
+\newsavebox{\fminipagebox}
+
+\NewDocumentEnvironment{cminipage}{m O{\fboxsep}}
+ {\par\kern#2\noindent\begin{lrbox}{\fminipagebox}
+ \begin{minipage}{#1}\ignorespaces}
+ {\end{minipage}\end{lrbox}%
+ \makebox[#1]{%
+ \kern\dimexpr-\fboxsep-\fboxrule\relax
+ \colorbox{Honeydew}{\usebox{\fminipagebox}}%
+ \kern\dimexpr-\fboxsep-\fboxrule\relax}\par\kern#2}
+
+\NewDocumentEnvironment{fminipage}{m O{\fboxsep}}
+ {\par\kern#2\noindent\begin{lrbox}{\fminipagebox}
+ \begin{minipage}{#1}\ignorespaces}
+ {\end{minipage}\end{lrbox}%
+ \makebox[#1]{%
+ \kern\dimexpr-\fboxsep-\fboxrule\relax
+ \fbox{\usebox{\fminipagebox}}%
+ \kern\dimexpr-\fboxsep-\fboxrule\relax}\par\kern#2\relax}
+
+ \newenvironment{code}[1][12.4cm]
+ {\par
+ \noindent
+ \cminipage{#1}%
+ \tt
+ }{%
+ \endcminipage%
+ \par
+ }
+
+% This is a hack. Introducing Hyphenation everywhere in a sequence of token.
+% Otherwise the macro names tend to always exceed lines.
+% It should be improved in order to always require at least--say--3 symbols before
+% and after the hyphenation.
+\ExplSyntaxOn
+\cs_new:Nn\tl_fragilize:n
+ {\__tl_fragilize:N#1\q_stop}
+\cs_new:Nn\__tl_fragilize:N
+ {\token_if_eq_meaning:NNTF#1\q_stop
+ {}{#1
+ \-\__tl_fragilize:N}}
+\cs_set_eq:NN\textfragilize\tl_fragilize:n
+\cs_new:Npn\Robustdisplay#1
+ {\exp_args:Nx\textfragilize{\robustdisplay{#1}}}
+\ExplSyntaxOff
+
+\let\cs\undefined
+\knowledgenewvariant\cs
+ {namespace=cs,
+ default style={autoref link,cs},
+ unknown style=cs unknown,
+ unknown style cont=cs unknown,
+ unknown warning=false,
+ unknown diagnose=true,
+ suggestion=cs,
+ PDF string={\detokenize{#1}}}
+\knowledgestyle{cs}{wrap=\Robustdisplay,typewriter,up,md,color=NavyBlue}
+\knowledgestyle{cs unknown}{wrap=\Robustdisplay,typewriter,up,md,color=black}
+
+\knowledgenewvariant\csintro
+ {namespace=cs,
+ auto knowledge={autoref,scope=document,also now},
+ default style={autoref target,csintro},
+ unknown style=csintro unknown,
+ unknown style cont=csintro unknown,
+ unknown warning=false,
+ unknown diagnose=false,
+ PDF string = {\detokenize{#1}}}
+\knowledgestyle{csintro}{wrap=\Robustdisplay,typewriter,up,md,color=blue}
+\knowledgestyle{csintro unknown}{wrap=\Robustdisplay,typewriter,up,md,color=black}
+
+\knowledgenewvariant\csreintro
+ {namespace=cs,
+ default style=csintro,
+ unknown style=csintro unknown,
+ unknown style cont=csintro unknown,
+ PDF string = {\Robustdisplay{#1}}}
+
+
+
+
+\newenvironment{commandlist}
+ {\begin{description}[font=\normalfont,
+ nosep,
+ itemindent=-2cm,
+ leftmargin=0cm,
+ topsep=2.5mm]}
+ {\end{description}}
+
+
+
+
+
+\knowledgedirective{doc notion}
+ {autoref,style=doc notion,intro style=intro doc notion}
+\knowledgestyle{doc notion}{color=DarkBlue}
+\knowledgestyle{intro doc notion}{color=blue,emphasize}
+
+
+\knowledgedirective{package}{style=package}
+\knowledgestyle{package}{typewriter,color=black}
+
+
+
+
+\knowledge{xparse}{package,url = {https://www.ctan.org/pkg/xparse}}
+\knowledge{knowledge}{package,url = {https://www.ctan.org/pkg/knowledge}}
+\knowledge{xcolor}{package,url = {https://www.ctan.org/pkg/xcolor}}
+\knowledge{amsfonts}{package,url = {https://www.ctan.org/pkg/amsfonts}}
+\knowledge{mathcommand}{package}
+
+\knowledge{math variant}{doc notion}
+\knowledge{text variant}{doc notion}
+\knowledge{PIE}[PIEs]{doc notion}
+\knowledge{PIE command}[PIE commands]{doc notion}
+
+
+\begin{document}
+\title{The \texttt{mathcommand} package for \LaTeX\\
+ {\small[version \mathcommandversiondate]}}
+
+\author{Thomas Colcombet}
+ \maketitle
+ \begin{abstract}
+ \noindent The "mathcommand" package provides functionalities for defining macros
+ \begin{compactenum}
+ \item that have different behaviors depending on whether in math or text mode,
+ \item that absorb Primes, Indices and Exponents (PIE) as extra parameters usable in the code, and
+ \item offers some iteration facilities for defining macros with similar code.
+ \end{compactenum}
+ The primary objective of this package is to be used together with the "knowledge"
+ package for a proper handling of mathematical notations.
+ \end{abstract}
+
+ \section{History of the package}
+
+ \begin{compactdesc}
+\item[2019-05-12] First version of the package. V1.01 on CTAN,
+\item[2019-05-14] New macros \cs\IfEmptyTF, \cs\GetExponent, and \cs\GetIndex.
+\item[2019-07-03] Corrects bug of functions declaring PIE's issuing an error when already existing. Version 1.02 on CTAN.
+\end{compactdesc}
+
+
+ \section{Defining text and math commands}
+
+ The principle is that the package will maintain, for a macro \cs{\macro}, two concurrent version of the code:
+ a ""math variant"" (technically it is stored in a macro \verb|\Math macro|) and a ""text variant""
+ (technically stored in a macro \verb|\Text macro|\footnote{These cannot be used accidentally by the user since these control sequences contain a space.}).
+ The macro \cs{\macro} itself will execute one or the other depending on whether it is
+ executed in math or text mode. Note that all the macros are non-expandable for avoiding problems
+ with mathematics that would be sent, for instance, to the table of contents. The list of commands is described at the end of the section.
+
+ For instance after executing:
+ \begin{code}
+ \cs{\newmathcommand}\cs\macro[1]\{\cs\mathit\{math\}\verb.^.\cs\mathrm\{code\}\verb._.\{(\#1)\}\}\\
+ \cs{\newtextcommand}\cs\macro[1]\{text code (\#1)\}
+ \end{code}
+ \noindent when executing \cs{\macro} in math mode,
+ the math code will be executed, and in text mode similarly:
+ \newmathcommand\toto[1]{\mathit{math}^{\mathrm{code}}_{(#1)}}
+ \newtextcommand\toto[1]{text code (#1)}
+ \begin{center}
+ \smallcode{\cs\macro\{a\}} yields~`\toto{a}' \qquad while \smallcode{\$\cs\macro\{a\}\$} yields `$\toto{a}$'.
+ \end{center}
+
+ If the macro \cs{\macro} already exists, it is stored
+ under the name \cs{\LaTeXmacro}, and then everything's happen as
+ if it had already been defined both in math and text mode.
+
+ This is interesting for redefining known macros.
+ For instance \cs{\c} is a convenient way to producing cedillas in \LaTeX, as in \smallcode{\cs\c\ a}
+ which yields `\c a'. However, one may want \cs{\c} to reprensent a variable $c$ in math mode.
+ This is done using, e.g.:
+ \begin{code}[5cm]
+ \cs{\renewmathcommand}\cs\c\{c\}
+ \end{code}
+ \renewmathcommand\c{c}
+ \noindent Then, the macro \cs{\c} still works in text mode,
+ and using~\cs{\c} in math mode does display simply~`$\c$'.
+
+
+
+
+ The name of the macros offered by the "mathcommand" package are mere adaptations of the standard macros of \LaTeX\ and of the package "xparse"\footnote{The package "xparse" offers a very convenient way to define macros with complicated parameter signatures.}.
+ Their syntax is the same (in particular in terms of parameter definitions):
+ \begin{commandlist}
+ \itemAP[\csintro{\newmathcommand}] is similar to \cs{\newcommand} and creates a "math variant",
+ \itemAP[\csintro{\newtextcommand}] is similar to \cs{\newcommand} and creates a "text variant",
+ \itemAP[\csintro{\renewmathcommand}] is similar to \cs{\renewcommand} and creates a "math variant",
+ \itemAP[\csintro{\renewtextcommand}] is similar to \cs{\renewcommand} and creates a "text variant",
+ \itemAP[\csintro{\declaremathcommand}] is similar to \cs{\newcommand} but defines the macro even if it exists before; it creates a "math variant",
+ \itemAP[\csintro{\declaretextcommand}] is similar to \cs{\newcommand} but defines the macro even if it exists before; it creates a "text variant",
+ \itemAP[\csintro{\NewDocumentMathCommand}] is like \cs{\NewDocumentCommand} of the "xparse" package, but creates a "math variant",
+ \itemAP[\csintro{\NewDocumentTextCommand}] is like \cs{\NewDocumentCommand} of the "xparse" package, but creates a "text variant",
+ \itemAP[\csintro{\RenewDocumentMathCommand}] is like \cs{\RenewDocumentCommand} of the "xparse" package, but creates a "math variant",
+ \itemAP[\csintro{\RenewDocumentTextCommand}] is like \cs{\RenewDocumentCommand} of the "xparse" package, but creates a "text variant",
+ \itemAP[\csintro{\DeclareDocumentMathCommand}] is like \cs{\DeclareDocumentCommand} of the "xparse" package, but creates a "math variant",
+ \itemAP[\csintro{\DeclareDocumentTextCommand}] is like \cs{\DeclareDocumentCommand} of the "xparse" package, but creates a "text variant",
+ \itemAP[\csintro{\ProvideDocumentMathCommand}] is like \cs{\ProvideDocumentCommand} of the "xparse" package, but creates a "math variant",
+ \itemAP[\csintro{\ProvideDocumentTextCommand}] is like \cs{\ProvideDocumentCommand} of the "xparse" package, but creates a "text variant".
+ \end{commandlist}
+
+ The package offers also the following commands:
+ \begin{commandlist}
+ \itemAP[\csintro{\declarecommand}] which is similar to \cs{\newcommand} but defines the macro even if it exists before,
+ \itemAP[\csintro{\storecommand}\texttt{[optional-prefix]}\texttt{\cs\macro}] which copies the content of the macro \cs\macro\ to \verb|\optional-prefixmacro|. By default, the optional prefix is \verb|LaTeX|. (Hence, it does what is automatically made by commands such as \cs\declarecommand).
+ \end{commandlist}
+
+ \section{Defining Prime/Indices/Exponents absorbing commands (PIE commands)}
+
+ Another feature offered by the "mathcommand" package is to permit the definitions of macros that would
+ absorb the primes, subscript and superscript that follow them.
+ \AP
+ The three pieces of information are abbreviated as ""PIE"" (for ``Primes-Indices-Exponents'').
+ This terminology serves as a help for remembering the order prime-index-exponent.
+ \AP A ""PIE command"" is similar to a normal macro/command, but for the fact
+ that the "PIEs" that follow are absorbed and can be used in the macro as
+ three extra parameters. The list of macros usable for for defining "PIE commands" can be found at the end of this section.
+
+ This is best explained through an example. After writing:
+ \begin{code}
+ \cs\newcommandPIE\cs\macro[1]\{([\#1]\#3)\#2\#4\}
+ \end{code}
+ \noindent one obtains that
+ \newcommandPIE\macrob[1]{([#1]#3)#2#4}
+ \begin{center}
+ \smallcode{\$\cs\macro\{A\}\_2'\$} yields $\macrob{A}_2'$\ .
+ \end{center}
+ Indeed, in the body of the definition of \cs{macro}, \texttt{\#1} represents the normal parameter of the command, while the three following parameters (\texttt{\#2},\texttt{\#3},\texttt{\#4} in this case) contain respectively the primes (either empty or a sequence of $'$ symbols),
+ the index (either empty if there is no subscript or of the form \verb"_{index}" if there is
+ an index), and the exponent (either empty if there is no superscript or of the form
+ \verb"^{exponent}" if there is one).
+ In the case of the above definition, the index (parameter \texttt{\#3}) is written inside the parenthesis,
+ while primes and exponents are put outside.
+
+The are furthermore some helper functions:
+\begin{commandlist}
+\itemAP[\csintro\IfEmptyTF] takes a string and two codes, and expands to the first one if the string is empty, and the second otherwise,
+\itemAP[\csintro{\GetIndex}] takes a string that is an index as in "PIE commands", and expands to its content: it maps the empty string to the empty string, and strings of the form \verb|_{sthg}| to \verb|sthg|,
+\itemAP[\csintro{\GetExponent}] takes a string that is an exponent as in "PIE commands", and expands to its content: it maps the empty string to the empty string, and strings of the form \verb|^{sthg}| to \verb|sthg|.
+\end{commandlist}
+
+For instance:
+\begin{code}
+\cs\newmathcommandPIE\cs\F\{\#2F\#1\cs\IfEmptyTF\{\#3\}\{\}\{\verb.^.\{(\cs\GetExponent\{\#3\})\}\}\}
+\end{code}
+\newmathcommandPIE\F{#2F#1\IfEmptyTF{#3}{}{^{(\GetExponent{#3})}}}
+\noindent displays \verb|$\F_2^3$| as `$\F_2^3$': the index is placed before, and the exponent is surrounded by parentheses.
+
+
+\paragraph{List of macros of defining "PIE commands".} Once more,
+ appart from the specificity of "PIE commands", the syntax is as the original corresponding commands these are based on.
+ \begin{commandlist}
+ \itemAP[\csintro{\newcommandPIE}] is similar to \cs\newcommand\ (but defines a non-expandable macro)
+ \itemAP[\csintro{\renewcommandPIE}] is similar to \cs\renewcommand\ (but defines a non-expandable macro)
+ \itemAP[\csintro{\declarecommandPIE}] is similar to \cs\newcommand\ and works even if the macro already exists (and defines a non-expandable macro)
+ \itemAP[\csintro{\NewDocumentCommandPIE}] is similar to \cs\NewDocumentCommand\ of the "xparse" package,
+ \itemAP[\csintro{\RenewDocumentCommandPIE}] is similar to \cs\RenewDocumentCommand\ of the "xparse" package,
+ \itemAP[\csintro{\DeclareDocumentCommandPIE}] is similar to \cs\DeclareDocumentCommand\ of the "xparse" package,
+ \itemAP[\csintro{\ProvideDocumentCommandPIE}] is similar to \cs\ProvideDocumentCommand\ of the "xparse" package.
+ \end{commandlist}
+
+ Finally, a bunch of macros are used to define "math variants" that are "PIE commands":
+ \begin{commandlist}
+ \itemAP[\csintro{\newmathcommandPIE}] is like \cs{\newcommandPIE} and creates a "math variant",
+ \itemAP[\csintro{\renewmathcommandPIE}] is like \cs{\renewcommandPIE} and creates a "math variant",
+ \itemAP[\csintro{\declaremathcommandPIE}] is like \cs{\declarecommandPIE} and creates a "math variant",
+ \itemAP[\csintro{\NewDocumentMathCommandPIE}] is like \cs{\NewDocumentCommandPIE}, but creates a "math variant",
+ \itemAP[\csintro{\RenewDocumentMathCommandPIE}] is like \cs{\RenewDocumentCommandPIE}, but creates a "math variant",
+ \itemAP[\csintro{\DeclareDocumentMathCommandPIE}] is like \cs{\DeclareDocumentCommandPIE}, but creates a "math variant",
+ \itemAP[\csintro{\ProvideDocumentMathCommandPIE}] is like \cs{\ProvideDocumentCommandPIE}, but creates a "math variant",
+ \end{commandlist}
+
+
+ \section{Looping for defining commands}
+
+ \begin{scope}\label{LoopCommands}
+ \knowledge{list on which to iterate}{doc notion}
+ \knowledge{name 1}{doc notion}
+ \knowledge{name 2}{doc notion}
+ \knowledge{name 7}{doc notion}
+ \knowledge{code}{doc notion}
+ The "mathcommand" package offer also some capabilities for automatically defining multiple
+ similar macros. This is done using only one command:
+ \begin{center}
+ \AP\csintro{\LoopCommands}\{"list on which to iterate"\}["name 1"]["name 2"]\dots["name 7"]\{"code@@LoopCommands"\}
+ \end{center}
+ \AP The ""list on which to iterate"" is a list of letters or braced sequences of letters.
+ \AP the ""name 1"", ""name 2"" up to ""name 7"" optional parameters are expandable
+ pieces of code that are to be evaluated
+ and then converted into control sequences; they may use the extra parameter~\texttt{\#1}.
+ \AP Finally, ""code"" is the code to be executed that can
+ use the parameters~\texttt{\#1}, \texttt{\#2}, up to~\texttt{\#8}.
+
+ The result of executing this macro is that each of the letters or sequences of letters
+ in the "list on which to iterate" will be taken one after the other. For each of them, the "code" is executed,
+ taking as value of the parameter~\texttt{\#1} the element in the list, and as parameters~\texttt{\#2} to~\texttt{\#8}
+ control sequences constructed from the evaluation of "name 1" up to "name 7" (using as parameters~\texttt{\#1} the element of the sequence).
+
+ For instance, imagine one easily wants to denote vectors simply as `\cs\vx' instead of `\cs\vec~x' or `\cs\vec\{x\}',
+ it is sufficient to write:
+ \begin{code}[9cm]
+ \cs\LoopCommands\{abcdefghijklmnopqrstuvwxyz\}[v\#1]\\
+ \indent~~~~\{\cs\newcommand\#2\{\cs\vec~\#1\}\}
+ \end{code}
+ \noindent It will result in the successive execution of
+ \smallcode{\cs\newcommand\cs\va\{\cs\vec~a\}} and so on up to
+ \smallcode{\cs\newcommand\cs\vz\{\cs\vec~z\}}.
+
+ Note also that the "list on which to iterate" is automatically expanded,
+ and if a non-expandable control sequence is met, then it is replaced by its the text defining the control sequence.
+ Hence using \texttt{\{\cs\alpha\cs\beta\}} is equivalent to \texttt{\{\{alpha\}\{beta\}\}}.
+
+
+ Some extra remarks may be helpful:
+ \begin{itemize}
+ \item As usual in \TeX/\LaTeX, the "code" may have to use its own internal parameters,
+ for instance for defining macros: such parameters should use double \texttt{\#}'s, i.e., \texttt{\#\#1}, \texttt{\#\#2} up to \texttt{\#\#9}.
+
+ \LoopCommands{abcdefghijklmnopqrstuvwxyz}[o#1]
+ {\declarecommandPIE#2{\overline{#1##2}##1##3}}
+ For instance:
+ \begin{code}[10cm]
+ \cs\LoopCommands\{abcdefghijklmnopqrstuvwxyz\}[o\#1]\\
+ \indent~~~~\{\cs\declarecommandPIE\#2\{\cs\overline\{\#1\#\#2\}\#\#1\#\#3\}
+ \end{code}
+ \noindent will result in \cs\ou\ to be declared as the "PIE command"
+defined with as main body \texttt{\cs\overline\{u\#2\}\#1\#3}
+ (note the translation of parameters, which is the standard way to proceed for \TeX).
+ In our case {\tt \cs\ou\_1\verb.^.2} yields `$\ou_1^2$' (the subscript gets to be inside the bar,
+ and the superscript and primes outside), and so on...
+ \item When defining multiple commands, some may already exist. To avoid conflicts, one should use
+ the `declare' version of the defining commands. These will work independently of the
+ context. Is it also good to define only the "math variants" using the appropriate commands
+ of the package.
+ \itemAP The following strings are predefined for the user to loop on:
+ \begin{asparaitem}
+ \itemAP[\csintro\lettersUppercase] stands for \texttt{\lettersUppercase}
+ \itemAP[\csintro\lettersLowercase] stands for \texttt{\lettersLowercase}
+ \itemAP[\csintro\lettersAll] stands for \texttt{\lettersAll}.
+ \itemAP[\csintro\lettersGreekLowercase] stands for $\lettersGreekLowercase$.
+ \itemAP[\csintro\lettersGreekUppercase] stands for $\lettersGreekUppercase$.
+ \itemAP[\csintro\lettersGreekAll] stands for $\lettersGreekAll$.
+ \end{asparaitem}
+ \end{itemize}
+ \end{scope}
+
+ Hence, for instance:
+ \begin{code}[10cm]
+ \cs\LoopCommands\cs\lettersUppercase[bb\#1]\\
+ \indent~~~~~~\{\cs\newmathcommand\{\cs\mathbb \#1\}\}\\
+ \cs\LoopCommands\cs\lettersGreekLowercase[\#1][LaTeX\#1]\\
+ \indent~~~~~~\{\cs\renewmathcommand\#2\{\cs\textcolor\{blue\}\{\#3\}\}
+ \end{code}
+ \noindent configures the macros \cs\bbA, \dots, \cs\bbZ\ to display
+ the letters in blackboard bold alphabet (e.g. with the "amsfonts" package),
+ and the lowercase greek letters \cs\alpha,\dots\ to
+ be displayed in blue (with the "xcolor" package loaded). Note in the last case
+ the use of the third parameter used for accessing the macros \cs\LaTeXalpha,\dots\
+ that are automatically generated by the \cs\renewmathcommand\ macro.
+ \newpage
+
+ \DocInput{mathcommand.dtx}
+ \end{document}
+%</driver>
+% \fi
+%
+%
+%
+%%%%%%%%%%
+%
+% \section{Implementation}
+% \label{section:code}
+%
+% \subsection{README.md}
+%
+%<*readme>
+% \begin{macrocode}
+This directory contains the package
+
+ name: mathcommand
+ license: LaTeX Project Public License version 1.2 or above
+ version: v1.02
+ date: 2019/07/03
+ author: Thomas Colcombet
+ mail: thomas.colcombet@irif.fr
+ web: -
+
+Purpose:
+ The mathcommand package provides functionalities for defining macros:
+ - that have different behaviors depending on whether in math or text mode,
+ - absorb Primes, Indices, Exponents (PIE) following LaTeX notations and
+ have them as extra parameters usable in the code.
+ The primary objective of this code is to be used together with the knowledge
+ package for a proper handling of mathematical notations.
+
+Install:
+ It is sufficient to have the file mathcommand.sty accessible by LaTeX.
+ It can be produced by `make mathcommand.sty' if necessary.
+ The documentation is in the file mathcommand.pdf.
+
+Content of the file mathcommand-ctan.zip:
+ - README.md: this file generated while compiling mathcommand.ins,
+ - mathcommand.sty: the package file (generated using knowledge.ins)
+ - mathcommand.pdf: the user documentation (generated by compiling
+ mathcommand.dtx)
+ - makefile: the makefile. Use 'make all' to generate mathcommand.sty
+ and knowledge.pdf. It can also: clean the directory, make zip
+ version of the sources, or ready for CTAN.
+ - mathcommand.ins: is the file generating mathcommand.sty and
+ README.md from mathcommand.dtx (using docstrip).
+ - mathcommand.dtx: code and documentation.
+
+% \end{macrocode}
+%</readme>
+% \subsection{Code preparation}
+%<*package>
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}[1994/06/01]
+\RequirePackage{expl3}
+\RequirePackage{etoolbox}
+\RequirePackage{xparse}
+
+\ExplSyntaxOn
+\bool_if_exist:NTF\mathcommand_package_loaded_bool
+ \endinput
+ {\bool_new:N\mathcommand_package_loaded_bool
+ \bool_set_true:N\mathcommand_package_loaded_bool}
+% \end{macrocode}
+
+
+% \subsection{Absorbing primes, indices and exponents (PIE)}
+% \subsubsection{Parsing pies}
+% We start by defining the code used to absorb "PIEs" from the input stream.
+% The main function defined in this context is
+% \begin{quote}\AP
+% \csintro{\__mathcommand_absorb_PIE:nw}
+% \end{quote}
+% which takes some code as first parameter, then absorbs primes, indices and exponents,
+% and finally reinserts the code in the input stream, followed with three braces containing
+% respectively the primes, the index, and the exponent.
+%
+% \AP
+% It works by storing the code to be executed in \csintro{\__mathcommand_absorb_finished_tl},
+% preparing \csintro{\__mathcommand_primes_tl}, \csintro{\__mathcommand_index_t},
+% and \csintro{\__mathcommand_exponent_tl} to contain the "PIEs".
+% Then the core of the parsing is performed by \csintro{\__mathcommand_absorb:w}.
+% \begin{macrocode}
+\cs_new:Npn\__mathcommand_absorb_PIE:nw#1{
+ \tl_set:Nn\__mathcommand_absorb_finished_tl{#1}
+ \tl_set:Nn\__mathcommand_primes_tl{}
+ \tl_set:Nn\__mathcommand_index_tl{}
+ \tl_set:Nn\__mathcommand_exponent_tl{}
+ \__mathcommand_absorb:w
+}
+% \end{macrocode}
+% \AP
+% When the parsing is finished, \csintro{\__mathcommand_absorb_finished:} is
+% executed, which inserts the original code stored in \cs{\__mathcommand_absorb_finished_tl}
+% followed by the "PIEs" in the input stream.
+% \begin{macrocode}
+\cs_new:Nn\__mathcommand_absorb_finished:{
+ \exp_args:NV\__mathcommand_absorb_finished_:\__mathcommand_exponent_tl
+}
+\cs_new:Nn\__mathcommand_absorb_finished_:{
+ \exp_args:NV\__mathcommand_absorb_finished__:\__mathcommand_index_tl
+}
+\cs_new:Nn\__mathcommand_absorb_finished__:{
+ \exp_args:NV\__mathcommand_absorb_finished_tl\__mathcommand_primes_tl
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn\peek_subscript_remove:TFw
+ {\peek_charcode_remove:NTF _}
+\cs_new:Npn\peek_superscript_remove:TFw
+ {\peek_charcode_remove:NTF ^}
+\cs_new:Npn\peek_prime_remove:TFw
+ {\peek_charcode_remove:NTF '}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Nn\__mathcommand_absorb_add_prime:{
+ \tl_put_right:Nn\__mathcommand_primes_tl{'}
+}
+% \end{macrocode}
+% \begin{macrocode}
+\ExplSyntaxOff
+\expandafter\def\csname g_tmpa_tl\endcsname{_}
+\ExplSyntaxOn
+\cs_new:Nx\__mathcommand_absorb_add_index_after:Nn{
+ \exp_not:N\tl_set:Nn\exp_not:N\__mathcommand_index_tl
+ {\g_tmpa_tl{#2}}
+ #1
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Nn\__mathcommand_absorb_add_exponent_after:Nn{
+ \tl_set:Nn\__mathcommand_exponent_tl{^{#2}}
+ #1
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn\__mathcommand_absorb:w{
+ \peek_prime_remove:TFw
+ {\__mathcommand_absorb_add_prime:
+ \__mathcommand_absorb_p:w}
+ \__mathcommand_absorb_:w}
+\cs_new:Npn\__mathcommand_absorb_:w{
+ \peek_subscript_remove:TFw
+ {\__mathcommand_absorb_add_index_after:Nn
+ \__mathcommand_absorb_i:w}
+ \__mathcommand_absorb__:w}
+\cs_new:Npn\__mathcommand_absorb__:w{
+ \peek_superscript_remove:TFw
+ {\__mathcommand_absorb_add_exponent_after:Nn
+ \__mathcommand_absorb_e:w}
+ \__mathcommand_absorb_finished:}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn\__mathcommand_absorb_p:w{
+ \peek_prime_remove:TFw
+ {\__mathcommand_absorb_add_prime:
+ \__mathcommand_absorb_p:w}
+ \__mathcommand_absorb_p_:w}
+\cs_new:Npn\__mathcommand_absorb_p_:w{
+ \peek_subscript_remove:TFw
+ {\__mathcommand_absorb_add_index_after:Nn
+ \__mathcommand_absorb_pi:w}
+ \__mathcommand_absorb_finished:}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn\__mathcommand_absorb_pi:w{
+ \peek_prime_remove:TFw
+ {\__mathcommand_absorb_add_prime:
+ \__mathcommand_absorb_pi:w}
+ \__mathcommand_absorb_finished:}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn\__mathcommand_absorb_e:w{
+ \peek_subscript_remove:TFw
+ {\__mathcommand_absorb_add_index_after:Nn
+ \__mathcommand_absorb_finished:}
+ \__mathcommand_absorb_finished:}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn\__mathcommand_absorb_i:w{
+ \peek_prime_remove:TFw
+ {\__mathcommand_absorb_add_prime:
+ \__mathcommand_absorb_pi:w}
+ \__mathcommand_absorb_i_:w}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn\__mathcommand_absorb_i_:w{
+ \peek_superscript_remove:TFw
+ {\__mathcommand_absorb_add_exponent_after:Nn
+ \__mathcommand_absorb_finished:}
+ \__mathcommand_absorb_finished:}
+% \end{macrocode}
+%
+%\subsubsection{Definition of high level commands}
+%
+% \begin{macrocode}
+\NewDocumentCommand\newcommandPIE{ m o o m }{
+ \__xparse_check_definable:nNT {#1} \newcommandPIE
+ {
+ \cs_if_exist:NTF #1
+ {
+ \__kernel_msg_error:nnxx { mathcommand } { command-already-defined }
+ { \use:nnn \token_to_str:N #1 { } }
+ { \token_to_str:N \newcommandPIE }
+ }
+ { \__mathcommand_declarecommandPIE:Nnnn #1{#2}{#3}{#4} }
+ }
+}
+\NewDocumentCommand\renewcommandPIE{ m o o m }{
+ \__xparse_check_definable:nNT {#1} \renewcommandPIE
+ {
+ \cs_if_exist:NTF #1
+ { \__mathcommand_declarecommandPIE:Nnnn #1{#2}{#3}{#4} }
+ {
+ \__kernel_msg_error:nnxx { mathcommand } { command-not-yet-defined }
+ { \use:nnn \token_to_str:N #1 { } }
+ { \token_to_str:N \renewcommandPIE }
+ }
+ }
+}
+\NewDocumentCommand\declarecommandPIE{ m o o m }{
+ \__xparse_check_definable:nNT {#1} \declarecommandPIE
+ { \__mathcommand_declarecommandPIE:Nnnn #1{#2}{#3}{#4} }
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Nn\__mathcommand_declarecommandPIE:Nnnn{
+ \use:x{
+ \exp_not:N\__mathcommand_declarePIE_generic:Nnnn
+ \exp_not:N#1
+ {\IfNoValueTF{#2}{0}{#2}}
+ {\cs_if_exist:NTF#1
+ {\exp_not:N\renewrobustcmd}
+ {\exp_not:N\newrobustcmd}
+ \exp_not:N#1
+ \IfNoValueTF{#2}{}{[#2]}
+ \IfNoValueTF{#3}{}{[{\exp_not:n{#3}}]}}
+ {\exp_not:n{#4}}
+}}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new_protected:Npn\NewDocumentCommandPIE#1#2#3{
+ \__xparse_check_definable:nNT {#1} \NewDocumentCommandPIE
+ {
+ \cs_if_exist:NTF #1
+ {
+ \__kernel_msg_error:nnxx { mathcommand } { command-already-defined }
+ { \use:nnn \token_to_str:N #1 { } }
+ { \token_to_str:N \NewDocumentCommandPIE }
+ }
+ { \__mathcommand_DeclareDocumentCommandPIE:Nnn #1 {#2} {#3} }
+ }
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new_protected:Npn\RenewDocumentCommandPIE#1#2#3{
+ \__xparse_check_definable:nNT {#1} \RenewDocumentCommandPIE
+ {
+ \cs_if_exist:NTF #1
+ { \__mathcommand_DeclareDocumentCommandPIE:Nnn #1 {#2} {#3} }
+ {
+ \__kernel_msg_error:nnxx { xparse } { command-not-yet-defined }
+ { \use:nnn \token_to_str:N #1 { } }
+ { \token_to_str:N \RenewDocumentCommandPIE }
+ }
+ }
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new_protected:Npn\DeclareDocumentCommandPIE#1#2#3{
+ \__xparse_check_definable:nNT {#1} \DeclareDocumentCommandPIE
+ {
+ \__mathcommand_DeclareDocumentCommandPIE:Nnn #1 {#2} {#3}
+ }
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new_protected:Npn\ProvideDocumentCommandPIE#1#2#3{
+ \__xparse_check_definable:nNT {#1} \ProvideDocumentCommandPIE
+ {
+ \cs_if_exist:NTF #1{}
+ {
+ \__mathcommand_DeclareDocumentCommandPIE:Nnn #1 {#2} {#3}
+ }
+ }
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_set:Nn\__mathcommand_DeclareDocumentCommandPIE:Nnn{
+ \group_begin:
+ \DeclareDocumentCommand#1{#2}{}
+ \int_gset_eq:NN\g_tmpa_int\l__xparse_current_arg_int
+ \group_end:
+ \__mathcommand_declarePIE_generic:Nnnn
+ #1
+ {\g_tmpa_int}
+ {\DeclareDocumentCommand#1{#2}}
+ {#3}
+}
+% \end{macrocode}
+% Control token, number parameters, defining command, code
+% \begin{macrocode}
+\cs_new:Nn\__mathcommand_declarePIE_generic:Nnnn{
+ \int_compare:nNnTF{#2}>{6}
+ {\PackageError{mathcommand}
+ {At~most~6~parameters~in~PIE~commands~when~defining~`\token_to_str:N#1'}
+ {PIE~commands~(mathcommand~package)~do~not~accept~more~than~six~parameters.}}
+ {\int_case:nn{#2}
+ {{0} {\cs_set:cpn{\cs_to_str:N#1~PIE~code}##1##2##3}
+ {1} {\cs_set:cpn{\cs_to_str:N#1~PIE~code}##1##2##3##4}
+ {2} {\cs_set:cpn{\cs_to_str:N#1~PIE~code}##1##2##3##4##5}
+ {3} {\cs_set:cpn{\cs_to_str:N#1~PIE~code}##1##2##3##4##5##6}
+ {4} {\cs_set:cpn{\cs_to_str:N#1~PIE~code}##1##2##3##4##5##6##7}
+ {5} {\cs_set:cpn{\cs_to_str:N#1~PIE~code}##1##2##3##4##5##6##7##8}
+ {6} {\cs_set:cpn{\cs_to_str:N#1~PIE~code}##1##2##3##4##5##6##7##8##9}}
+ {#4}
+ \use:x{
+ \exp_not:n{#3}
+ {\exp_not:N\__mathcommand_absorb_PIE:nw
+ {\exp_not:c{\cs_to_str:N#1~PIE~code}
+ \int_case:nn{#2}
+ {{0}{}
+ {1}{\exp_not:n{{##1}}}
+ {2}{\exp_not:n{{##1}{##2}}}
+ {3}{\exp_not:n{{##1}{##2}{##3}}}
+ {4}{\exp_not:n{{##1}{##2}{##3}{##4}}}
+ {5}{\exp_not:n{{##1}{##2}{##3}{##4}{##5}}}
+ {6}{\exp_not:n{{##1}{##2}{##3}{##4}{##5}{##6}}}}}}}
+ }
+}
+% \end{macrocode}
+%
+%
+% \subsubsection{Auxiliary functions}
+%
+%
+% \begin{macrocode}
+\def\lettersUppercase{ABCDEFGHIJKLMNOPQRSTUVWXYZ}
+\def\lettersLowercase{abcdefghijklmnopqrstuvwxyz}
+\xdef\lettersAll{\lettersLowercase\lettersUppercase}
+\def\lettersGreekLowercase{\alpha\beta\gamma\delta\epsilon\varepsilon\zeta\eta\theta\vartheta\iota\kappa\lambda\mu\nu\xi\pi\varpi\rho\varrho\sigma\varsigma\tau\upsilon\phi\varphi\chi\psi\omega}
+\def\lettersGreekUppercase{\Gamma\Delta\Theta\Lambda\Xi\Pi\Sigma\Upsilon\Phi\Psi\Omega}
+\xdef\lettersGreekAll{\lettersGreekLowercase\lettersGreekUppercase}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_set_eq:NN\IfEmptyTF\tl_if_empty:nTF
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn\EmptyContent#1{
+ \tl_if_empty:nTF{#1}{{}}{
+ \__mathcommand_EmptyContent:w #1*\end_marker:
+ }
+}
+\cs_new:Npn\__mathcommand_EmptyContent:w #1#2\end_marker:{
+ #1*
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn\GetExponent#1{
+ \tl_if_empty:nTF{#1}{}{
+ \__mathcommand_GetIndexOrExponent:w #1\__end_marker__
+ }
+}
+\cs_new:Npn\GetIndex#1{
+ \tl_if_empty:nTF{#1}{}{
+ \__mathcommand_GetIndexOrExponent:w #1\__end_marker__
+ }
+}
+\cs_new:Npn\__mathcommand_GetIndexOrExponent:w #1#2#3\__end_marker__{
+ #2
+}
+% \end{macrocode}
+%
+%
+% \subsection{Separating math and text macros}
+%
+%
+% \begin{macrocode}
+\tl_const:Nn\__mathcommand_prefix_math_tl{Math~}
+\tl_const:Nn\__mathcommand_prefix_text_tl{Text~}
+\tl_const:Nn\__mathcommand_prefix_store_tl{LaTeX}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Nn\__mathcommand_to_mathtl:N{\__mathcommand_prefix_math_tl\cs_to_str:N#1}
+\cs_new:Nn\__mathcommand_to_texttl:N{\__mathcommand_prefix_text_tl\cs_to_str:N#1}
+\cs_new:Nn\__mathcommand_to_storetl:N{\__mathcommand_prefix_store_tl\cs_to_str:N#1}
+\cs_new:Nn\__mathcommand_coretl:N
+ {\expandafter\__command_coretl:w\string#1\end_mark}
+\cs_new:Npn\__command_coretl:w#1~#2\end_mark{#2}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn\__mathcommand_if_exist:NTF
+ {\cs_if_exist:NTF}
+\cs_new:Npn\__mathcommand_if_exist_math:NTF#1
+ {\cs_if_exist:cTF{\__mathcommand_to_mathtl:N#1}}
+\cs_new:Npn\__mathcommand_if_exist_text:NTF#1
+ {\cs_if_exist:cTF{\__mathcommand_to_texttl:N#1}}
+\cs_new:Npn\__mathcommand_if_exist_text_or_math:NTF#1
+ {\__mathcommand_if_exist_math:NTF#1
+ \use_i:nn{\__mathcommand_if_exist_text:NTF#1}}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Nn\__mathcommand_error_if_exist_math:NF{
+ \cs_if_exist:cTF{\__mathcommand_to_mathtl:N#1}
+ {\exp_args:Nnx\PackageError{}
+ {Command~`\token_to_str:N#1'~already~exists~in~math~mode}
+ {}
+ }{#2}
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Nn\__mathcommand_error_if_exist_text:NF{
+ \cs_if_exist:cTF{\__mathcommand_to_texttl:N#1}
+ {\exp_args:Nnx\PackageError{}
+ {Command~`\token_to_str:N#1'~already~exists~in~text~mode}
+ {}
+ }{#2}
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Nn\__mathcommand_error_if_not_exist_math:NF{
+ \cs_if_exist:cTF{\__mathcommand_to_mathtl:N#1}
+ {#2}
+ {\exp_args:Nnx\PackageError{}
+ {Command~`\token_to_str:N#1'~does~not~exist~in~math~mode}
+ {}
+ }
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Nn\__mathcommand_error_if_not_exist_text:NF{
+ \cs_if_exist:cTF{\__mathcommand_to_texttl:N#1}
+ {#2}
+ {\exp_args:Nnx\PackageError{}
+ {Command~`\token_to_str:N#1'~does~not~exist~in~text~mode}
+ {}
+ }
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Nn\__mathcommand_error_unknownmath:N{
+ \exp_args:Nnx\PackageError{}
+ {Command~`\token_to_str:c{\__mathcommand_coretl:N #1}'~does~not~exist~in~math~mode}
+ {}
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Nn\__mathcommand_error_unknowntext:N{
+ \exp_args:Nnx\PackageError{}
+ {Command~`\token_to_str:c{\__mathcommand_coretl:N #1}'~does~not~exist~in~text~mode}
+ {}
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Nn\__mathcommand_try_math:N{
+ \cs_if_exist:NTF#1#1{\__mathcommand_error_unknownmath:N#1}
+}
+\cs_new:Nn\__mathcommand_try_text:N{
+ \cs_if_exist:NTF#1#1{\__mathcommand_error_unknowntext:N#1}
+}
+% \end{macrocode}
+% \AP
+% The macro \csintro{\__mathcommand_create_fork:N} takes a control sequence,
+% and creates the forking code that executes either the math branch of the text branch.
+% If this forking code is already present, the command does nothing.
+% However, if some macro was already associated with this control sequence, then
+% it is copied to the "math variant", the "text variant" as well as the stored.
+% \begin{macrocode}
+\cs_set:Nn\__mathcommand_create_fork:N{
+ \let\__mathcommand_tmp_cs\undefined
+ \exp_args:NNx
+ \cs_new_protected:Npn\__mathcommand_tmp_cs{
+ \exp_not:N\mode_if_math:TF
+ {\exp_not:N\__mathcommand_try_math:N\exp_not:c{\__mathcommand_to_mathtl:N#1}}
+ {\exp_not:N\__mathcommand_try_text:N\exp_not:c{\__mathcommand_to_texttl:N#1}}
+ }
+ \cs_if_exist:NTF#1{
+ \cs_if_eq:NNTF#1\__mathcommand_tmp_cs
+ { }
+ { \cs_set_eq:cN{\__mathcommand_to_storetl:N#1}#1
+ \cs_set_eq:cN{\__mathcommand_to_mathtl:N#1}#1
+ \cs_set_eq:cN{\__mathcommand_to_texttl:N#1}#1
+ \cs_set_eq:NN#1\__mathcommand_tmp_cs
+ }
+ }{ \cs_set_eq:NN#1\__mathcommand_tmp_cs }
+}
+% \end{macrocode}
+% \subsection{Definition of the high level commands}
+% \begin{macrocode}
+\NewDocumentCommand\declarecommand{m}{
+ \__xparse_check_definable:nNT {#1} \declarecommand
+ {
+ \cs_if_exist:NTF#1
+ {\renewcommand#1}
+ {\newcommand#1}
+ }
+}
+\newrobustcmd\storecommand[2][\__mathcommand_prefix_store_tl]{
+ \__xparse_check_definable:nNT {#2} \storecommand
+ {
+ \cs_if_exist:NTF#2{
+ \cs_set_eq:cN{\__mathcommand_prefix_store_tl\cs_to_str:N#2}#2
+ }
+ {
+ \PackageError{mathcommand}
+ {The~command~`\token_to_str:N#2'~does~not~exist~(in~\token_to_str:N\storecommand)}
+ {}
+ }
+ }
+}
+
+\NewDocumentCommand\NewDocumentMathCommand{m}{
+ \__xparse_check_definable:nNT {#1} \NewDocumentMathCommand
+ {
+ \__mathcommand_create_fork:N#1
+ \__mathcommand_error_if_exist_math:NF#1
+ {\exp_args:Nc\DeclareDocumentCommand{\__mathcommand_to_mathtl:N#1}}
+ }
+}
+\NewDocumentCommand\NewDocumentTextCommand{m}{
+ \__xparse_check_definable:nNT {#1} \NewDocumentTextCommand
+ {
+ \__mathcommand_create_fork:N#1
+ \__mathcommand_error_if_exist_text:NF#1
+ {\exp_args:Nc\DeclareDocumentCommand{\__mathcommand_to_texttl:N#1}}
+ }
+}
+\NewDocumentCommand\newmathcommand{m}{
+ \__xparse_check_definable:nNT {#1} \newmathcommand
+ {
+ \__mathcommand_create_fork:N#1
+ \__mathcommand_error_if_exist_math:NF#1
+ {\exp_args:Nc\newcommand{\__mathcommand_to_mathtl:N#1}}
+ }
+}
+\NewDocumentCommand\newtextcommand{m}{
+ \__xparse_check_definable:nNT {#1} \newtextcommand
+ {
+ \__mathcommand_create_fork:N#1
+ \__mathcommand_error_if_exist_text:NF#1
+ {\exp_args:Nc\newcommand{\__mathcommand_to_texttl:N#1}}
+ }
+}
+\NewDocumentCommand\RenewDocumentMathCommand{m}{
+ \__xparse_check_definable:nNT {#1} \RenewDocumentMathCommand
+ {
+ \__mathcommand_create_fork:N#1
+ \__mathcommand_error_if_not_exist_math:NF#1
+ {\exp_args:Nc\DeclareDocumentCommand{\__mathcommand_to_mathtl:N#1}}
+ }
+}
+\NewDocumentCommand\RenewDocumentTextCommand{m}{
+ \__xparse_check_definable:nNT {#1} \RenewDocumentMathCommand
+ {
+ \__mathcommand_create_fork:N#1
+ \__mathcommand_error_if_not_exist_text:NF#1
+ {\exp_args:Nc\DeclareDocumentCommand{\__mathcommand_to_texttl:N#1}}
+ }
+}
+\NewDocumentCommand\renewmathcommand{m}{
+ \__xparse_check_definable:nNT {#1} \renewmathcommand
+ {
+ \__mathcommand_create_fork:N#1
+ \__mathcommand_error_if_not_exist_math:NF#1
+ {\exp_args:Nc\renewcommand{\__mathcommand_to_mathtl:N#1}}
+ }
+}
+\NewDocumentCommand\renewtextcommand{m}{
+ \__xparse_check_definable:nNT {#1} \renewtextcommand
+ {
+ \__mathcommand_create_fork:N#1
+ \__mathcommand_error_if_not_exist_text:NF#1
+ {\exp_args:Nc\renewcommand{\__mathcommand_to_texttl:N#1}}
+ }
+}
+\NewDocumentCommand\declaremathcommand{m}{
+ \__xparse_check_definable:nNT {#1} \renewmathcommand
+ {
+ \__mathcommand_create_fork:N#1
+ \exp_args:Nc\declarecommand{\__mathcommand_to_mathtl:N#1}
+ }
+}
+\NewDocumentCommand\declaretextcommand{m}{
+ \__xparse_check_definable:nNT {#1} \renewtextcommand
+ {
+ \__mathcommand_create_fork:N#1
+ \exp_args:Nc\declarecommand{\__mathcommand_to_texttl:N#1}
+ }
+}
+
+\NewDocumentCommand\DeclareDocumentMathCommand{m}{
+ \__xparse_check_definable:nNT {#1} \DeclareDocumentMathCommand
+ {
+ \__mathcommand_create_fork:N#1
+ \exp_args:Nc\DeclareDocumentCommand{\__mathcommand_to_mathtl:N#1}
+ }
+}
+\NewDocumentCommand\DeclareDocumentTextCommand{m}{
+ \__xparse_check_definable:nNT {#1} \DeclareDocumentTextCommand
+ {
+ \__mathcommand_create_fork:N#1
+ \exp_args:Nc\DeclareDocumentCommand{\__mathcommand_to_texttl:N#1}
+ }
+}
+\NewDocumentCommand\ProvideDocumentMathCommand{mmm}{
+ \__xparse_check_definable:nNT {#1} \ProvideDocumentMathCommand
+ {
+ \__mathcommand_create_fork:N#1
+ \exp_args:Nc\ProvideDocumentCommand{\__mathcommand_to_mathtl:N#1}{#2}{#3}
+ }
+}
+\NewDocumentCommand\ProvideDocumentTextCommand{m}{
+ \__xparse_check_definable:nNT {#1} \ProvideDocumentTextCommand
+ {
+ \__mathcommand_create_fork:N#1
+ \exp_args:Nc\ProvideDocumentCommand{\__mathcommand_to_texttl:N#1}
+ }
+}
+% \end{macrocode}
+%
+% \subsection{Definition of the high level combined commands}
+%
+% \begin{macrocode}
+\NewDocumentCommand\NewDocumentMathCommandPIE{m}{
+ \__xparse_check_definable:nNT {#1} \NewDocumentMathCommandPIE
+ {
+ \__mathcommand_create_fork:N#1
+ \__mathcommand_error_if_exist_math:NF#1
+ {\exp_args:Nc\DeclareDocumentCommandPIE{\__mathcommand_to_mathtl:N#1}}
+ }
+}
+\NewDocumentCommand\newmathcommandPIE{m}{
+ \__xparse_check_definable:nNT {#1} \newmathcommandPiE
+ {
+ \__mathcommand_create_fork:N#1
+ \__mathcommand_error_if_exist_math:NF#1
+ {\exp_args:Nc\newcommandPIE{\__mathcommand_to_mathtl:N#1}}
+ }
+}
+\NewDocumentCommand\RenewDocumentMathCommandPIE{m}{
+ \__xparse_check_definable:nNT {#1} \RenewDocumentMathCommandPIE
+ {
+ \__mathcommand_create_fork:N#1
+ \__mathcommand_error_if_not_exist_math:NF#1
+ {\exp_args:Nc\DeclareDocumentCommandPIE{\__mathcommand_to_mathtl:N#1}}
+ }
+}
+\NewDocumentCommand\renewmathcommandPIE{m}{
+ \__xparse_check_definable:nNT {#1} \renewmathcommandPIE
+ {
+ \__mathcommand_create_fork:N#1
+ \__mathcommand_error_if_not_exist_math:NF#1
+ {\exp_args:Nc\renewcommandPIE{\__mathcommand_to_mathtl:N#1}}
+ }
+}
+\NewDocumentCommand\DeclareDocumentMathCommandPIE{m}{
+ \__xparse_check_definable:nNT {#1} \DeclareDocumentMathCommand
+ {
+ \__mathcommand_create_fork:N#1
+ \exp_args:Nc\DeclareDocumentCommand{\__mathcommand_to_mathtl:N#1}
+ }
+}
+\NewDocumentCommand\declaremathcommandPIE{m}{
+ \__xparse_check_definable:nNT {#1} \declaremathcommandPIE
+ {
+ \__mathcommand_create_fork:N#1
+ \exp_args:Nc\declarecommandPIE{\__mathcommand_to_mathtl:N#1}
+ }
+}
+
+\NewDocumentCommand\ProvideDocumentMathCommandPIE{mmm}{
+ \__xparse_check_definable:nNT {#1} \ProvideDocumentMathCommandPIE
+ {
+ \__mathcommand_create_fork:N#1
+ \exp_args:Nc\ProvideDocumentCommandPIE{\__mathcommand_to_mathtl:N#1}{#2}{#3}
+ }
+}
+% \end{macrocode}
+%
+% \subsection{Looping for command definitions}
+%
+%
+% \begin{macrocode}
+\NewDocumentCommand\LoopCommands{ m ooooooo m }{
+ \IfNoValueTF{#2}
+ {\cs_set:Nn\__tmp_two:n{\exp_not:c{##1}}}
+ {\cs_set:Nn\__tmp_two:n{\exp_not:c{#2}}}
+ \IfNoValueTF{#3}
+ {\cs_set:Nn\__tmp_three:n{\exp_not:c{##1}}}
+ {\cs_set:Nn\__tmp_three:n{\exp_not:c{#3}}}
+ \IfNoValueTF{#4}
+ {\cs_set:Nn\__tmp_four:n{\exp_not:c{##1}}}
+ {\cs_set:Nn\__tmp_four:n{\exp_not:c{#4}}}
+ \IfNoValueTF{#5}
+ {\cs_set:Nn\__tmp_five:n{\exp_not:c{##1}}}
+ {\cs_set:Nn\__tmp_five:n{\exp_not:c{#5}}}
+ \IfNoValueTF{#6}
+ {\cs_set:Nn\__tmp_six:n{\exp_not:c{##1}}}
+ {\cs_set:Nn\__tmp_six:n{\exp_not:c{#6}}}
+ \IfNoValueTF{#7}
+ {\cs_set:Nn\__tmp_seven:n{\exp_not:c{##1}}}
+ {\cs_set:Nn\__tmp_seven:n{\exp_not:c{#7}}}
+ \IfNoValueTF{#8}
+ {\cs_set:Nn\__tmp_eight:n{\exp_not:c{##1}}}
+ {\cs_set:Nn\__tmp_eight:n{\exp_not:c{#8}}}
+ %
+ \cs_gset:Nn\g_tmpb_cs:nnnnnnnn{#9}
+ %
+ \cs_gset:Nn\g_tmpa_cs:n{
+ \tl_set:Nn\l_tmpa_tl{##1}
+ \use:x{
+ \exp_not:N\g_tmpb_cs:nnnnnnnn
+ {\l_tmpa_tl}
+ \__tmp_two:n{\l_tmpa_tl}
+ \__tmp_three:n{\l_tmpa_tl}
+ \__tmp_four:n{\l_tmpa_tl}
+ \__tmp_five:n{\l_tmpa_tl}
+ \__tmp_six:n{\l_tmpa_tl}
+ \__tmp_seven:n{\l_tmpa_tl}
+ \__tmp_eight:n{\l_tmpa_tl}}
+ }
+ \exp_args:Nx\tl_map_inline:nn{#1}
+ {\tl_if_blank:nTF{##1}
+ {}
+ {\g_tmpa_cs:n{\__mathcommand_getbasename:n{##1}}}
+ }
+}
+\cs_new:Nn\__mathcommand_getbasename:n{
+ \tl_if_single:nTF{#1}{
+ \token_if_cs:NTF#1
+ {\cs_to_str:N#1}
+ {#1}
+ }{#1}
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ExplSyntaxOff
+% \end{macrocode}
+%
+% \end{document}
+
diff --git a/macros/latex/contrib/mathcommand/mathcommand.ins b/macros/latex/contrib/mathcommand/mathcommand.ins
new file mode 100644
index 0000000000..b8104498c5
--- /dev/null
+++ b/macros/latex/contrib/mathcommand/mathcommand.ins
@@ -0,0 +1,68 @@
+%%
+%% Copyright (C) 2017 by Thomas Colcombet
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.2 of this license or (at your option) any later
+%% version. The latest version of this license is in:
+%%
+
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.2 or later is part of all distributions of
+%% LaTeX version 1999/12/01 or later.
+%%
+\input docstrip.tex
+\keepsilent
+\askforoverwritefalse
+\preamble
+
+This is a generated file. Copyright (C) 2019 by Thomas Colcombet
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either
+version 1.2 of this license or (at your option) any later
+version. The latest version of this license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.2 or later is part of all distributions of
+LaTeX version 1999/12/01 or later.
+
+\endpreamble
+
+\generate{%
+ \file{mathcommand.sty}{%
+ \from{mathcommand.dtx}{head,package}%
+ }%
+}
+
+
+
+\nopreamble\nopostamble
+\def\MetaPrefix{}
+\generate{%
+ \file{README.md}{
+ \usepreamble\empty
+ \usepostamble\empty%
+ \from{mathcommand.dtx}{readme}%
+ }}%
+
+
+
+
+\obeyspaces
+\Msg{****************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the }
+\Msg{* following file into a directory searched by TeX:}
+\Msg{*}
+\Msg{* knowledge.sty}
+\Msg{*}
+\Msg{* To produce the documentation run the file *}
+\Msg{* knowledge.dtx through LaTeX.}
+\Msg{*}
+\Msg{****************************************************}
+
+\endbatchfile
+
diff --git a/macros/latex/contrib/mathcommand/mathcommand.pdf b/macros/latex/contrib/mathcommand/mathcommand.pdf
new file mode 100644
index 0000000000..1924fc0b59
--- /dev/null
+++ b/macros/latex/contrib/mathcommand/mathcommand.pdf
Binary files differ