summaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
Diffstat (limited to 'macros')
-rw-r--r--macros/latex/contrib/starray/README.md77
-rw-r--r--macros/latex/contrib/starray/doc/starray.pdfbin0 -> 206077 bytes
-rw-r--r--macros/latex/contrib/starray/doc/starray.tex566
-rw-r--r--macros/latex/contrib/starray/latex/starray.sty2073
-rw-r--r--macros/latex/contrib/unicode-math-input/DEPENDS.txt3
-rw-r--r--macros/latex/contrib/unicode-math-input/README24
-rw-r--r--macros/latex/contrib/unicode-math-input/unicode-math-input-script.py591
-rw-r--r--macros/latex/contrib/unicode-math-input/unicode-math-input-table.tex2453
-rw-r--r--macros/latex/contrib/unicode-math-input/unicode-math-input.pdfbin0 -> 98884 bytes
-rw-r--r--macros/latex/contrib/unicode-math-input/unicode-math-input.sty731
-rw-r--r--macros/latex/contrib/unicode-math-input/unicode-math-input.tex391
-rw-r--r--macros/luatex/latex/sympycalc/README.md5
-rw-r--r--macros/luatex/latex/sympycalc/doc/SympyCalc-doc.pdfbin130436 -> 145115 bytes
-rw-r--r--macros/luatex/latex/sympycalc/doc/SympyCalc-doc.tex164
-rw-r--r--macros/luatex/latex/sympycalc/tex/SympyCalc.sty110
15 files changed, 7152 insertions, 36 deletions
diff --git a/macros/latex/contrib/starray/README.md b/macros/latex/contrib/starray/README.md
new file mode 100644
index 0000000000..81c97cd931
--- /dev/null
+++ b/macros/latex/contrib/starray/README.md
@@ -0,0 +1,77 @@
+starray
+==========
+
+This is a structured (properties) array (hash) package based on expl3.
+
+For more details, see the documentation,
+[starray.pdf](http://mirrors.ctan.org/macros/latex/contrib/starray/doc/starray.pdf)
+
+--------------
+
+## Requirements
+* none besides a fairly recent LaTeX distribution as recent as 2022/06/01
+(with the new in kernel *\ProcessKeyOptions* and *\NewDocumentCommand*)
+
+## Installation
+The stable version is available at [CTAN](https://ctan.org/pkg/starray).
+
+## Usage
+### Stable version
+Just place
+```latex
+ \usepackage{starray}
+```
+
+in the preamble and compile away.
+
+
+Be aware that options might change between versions, so you have to check them manually.
+
+## More Information and documentation
+More Information can be found in the documentation; you can find a "bleeding edge" version
+at [the github page](http://github.com/alceu-frigeri/starray)
+
+## Contacting Author
+
+For bug reports and enhacement suggestions, the preferred way is to use
+[the project's issue page](https://github.com/alceu-frigeri/starray/issues).
+Please be ready to provide an example code showing the bug, if any.
+
+Please do not use the issue page for generic help on how to use the package.
+
+* git: https://github.com/alceu-frigeri/starray
+
+-------------
+Copyright 2023 by Alceu Frigeri
+
+ This work may be distributed and/or modified under the
+ conditions of
+
+ * The [LaTeX Project Public License](http://www.latex-project.org/lppl.txt), version 1.3c (or later), and/or
+ * The [GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.html), version 3 (or later)
+
+This work has the LPPL maintenance status *maintained*.
+
+The Current Maintainer of this work is Alceu Frigeri
+
+-------------
+## This work consists of the files
+
+* starray.sty
+ - The Package itself
+
+* README.md (this file)
+ - quick introduction
+
+* starray.tex
+ - package documentation
+
+* starray.pdf
+ - documentation in PDF format
+
+-------------
+
+## Changelog
+
+* Version 1.0
+ - Initial release by CTAN.
diff --git a/macros/latex/contrib/starray/doc/starray.pdf b/macros/latex/contrib/starray/doc/starray.pdf
new file mode 100644
index 0000000000..c77d198ba9
--- /dev/null
+++ b/macros/latex/contrib/starray/doc/starray.pdf
Binary files differ
diff --git a/macros/latex/contrib/starray/doc/starray.tex b/macros/latex/contrib/starray/doc/starray.tex
new file mode 100644
index 0000000000..ee260e9ed8
--- /dev/null
+++ b/macros/latex/contrib/starray/doc/starray.tex
@@ -0,0 +1,566 @@
+%%%==============================================================================
+%% Copyright 2023 by Alceu Frigeri
+%%
+%% This work may be distributed and/or modified under the conditions of
+%%
+%% * The [LaTeX Project Public License](http://www.latex-project.org/lppl.txt),
+%% version 1.3c (or later), and/or
+%% * The [GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.html),
+%% version 3 (or later)
+%%
+%% This work has the LPPL maintenance status *maintained*.
+%%
+%% The Current Maintainer of this work is Alceu Frigeri
+%%
+%% This is version 1.0 (2023/05/11)
+%%
+%% The list of files that compose this work can be found in the README.md file at
+%% https://ctan.org/pkg/starray
+%%
+%%%==============================================================================
+% !TEX program = pdflatex
+% !TEX ext = --interaction=nonstopmode --enable-etex
+% !BIB program = none
+\documentclass[10pt]{article}
+\RequirePackage[verbose,a4paper,marginparwidth=27.5mm,top=2.5cm,bottom=1.5cm,hmargin={40mm,20mm},marginparsep=2.5mm,columnsep=10mm,asymmetric]{geometry}
+%\RequirePackage[verbose,a4paper,marginparwidth=27.5mm,top=2.5cm,bottom=1.5cm,hmargin={45mm,25mm},marginparsep=2.5mm,columnsep=10mm,asymmetric]{geometry}
+\usepackage{codedescribe}
+\usepackage{codelisting}
+\usepackage{starray}
+\RequirePackage[inline]{enumitem}
+\SetEnumitemKey{miditemsep}{parsep=0ex,itemsep=0.4ex}
+
+
+\begin{document}
+\tstitle{
+ author={Alceu Frigeri\footnote{\tsverb{https://github.com/alceu-frigeri/starray}}},
+ date={2023/05/11},
+ title={The starray Package\break Version \PkgInfo{starray}{version}}
+ }
+
+\begin{typesetabstract}
+
+This package implements vector like 'structures', like in 'C' and other programming languages.
+It's based on \tsobj[pkg]{expl3} and aimed at 'package writers', and not end users. The provided 'functions' are similar the ones provided for property (or sequence, or token) lists. For most of the provided functions there is a companion 'branching version'.
+
+\end{typesetabstract}
+
+\tableofcontents
+
+\section{Introduction}
+The main idea is to have an array like syntax when setting/recovering structured information, e.g. \tsmacro{\starray_get_prop:nn} {student[2].work[3].reviewer[4] , name} where ''student'' is the starray root, ''work'' is a sub-structure (an array in itself), ''reviewer'' is a sub-structure of ''work'' and so on, \tsobj[marg]{name} being a property of ''reviewer''. Moreover one can iterate over the structure, for instance \tsmacro{\starray_get_prop:nn}{student.work.reviewer,name} is also a possible reference in which one is using ''student's'', ''work's'' and ''reviewer's'' iterators.
+
+Internally, a \tsobj[pkg]{starray} is stored as a collection of property lists. Each \tsobj[pkg]{starray} can contain a list of property pairs (key/value as in any \tsobj[pkg]{expl3} property lists) and a list of sub-structures. Each sub-structure, at it's turn, can also contain a list of property pairs and a list of sub-structures.
+
+The construction/definition of a \tsobj[pkg]{starray} can be done piecewise (a property/sub-structure a time) or with a keyval interface or both, either way, one has to first ''create a root starray'' (\tsmacro{\starray_new:n}{}), define it's elements (properties and sub-structures), then instantiate them ''as needed''. An instance of a \tsobj[pkg]{starray} (or one of it's sub-structures) is referred, in this text, as a ''term''.
+
+Finally, almost all defined functions have a branching version, as per \tsobj[pkg]{expl3}: \tsobj[code]{_p,T,F,TF}. For simplicity, in the text bellow only the \underline{\textsl{TF}} variant is described, as in \tsobj[code]{\starray_new:nTF}, keep in mind that all 4 variants do exist, e.g. \tsobj[code]{\starray_new_p:n,\starray_new:nT,\starray_new_p:nF,\starray_new_p:nTF}. As usual, the \tsobj[code]{_p} version denotes, is the predicate one (which can be used in boolena expressions).
+
+\begin{tsremark}[N.B.:]
+ Could it be implemented with a single property list? It sure could, but at a cost:
+\begin{enumerate*} \item complexity; \item access time. \end{enumerate*}
+The current implementation, albeit also complex, tries to reach a balance between inherent structure complexity, number of used/defined auxiliary property lists and access time.
+\end{tsremark}
+
+\section{Class Options}\label{pack:options}
+The package options (\tsobj[key]{key}\,=\tsobj[value]{value}) are:
+\begin{describelist}{option}
+\describe{prefix}{(default: \tsobj[value]{\detokenize{l__starray_}} ). Set the \tsobj[key]{prefix} used when declaring the property lists associated with any \tsobj[pkg]{starray}.}
+
+\describe{msg-err}{
+By default, the \tsobj[pkg]{starray} package only generates ''warnings'', with \tsobj[option]{msg-err} one can choose which cases will generate ''package error'' messages. There are 3 message classes: 1. \tsobj[value]{strict} relates to \tsmacro{\starray_new:n}{} cases (\tsobj[pkg]{starray} creation); 2. \tsobj[value]{syntax} relates to ''term syntax'' errors (student.work.reviewer in the above examples); finally 3. \tsobj[value]{reference} relates to cases whereas the syntax is correct but referring to non-existent terms/properties. }
+
+\begin{describelist*}{value}
+\describe{none}{ (default) no package message will raise an error.}
+\describe{strict}{ will raise an error on \tsobj[value]{strict} case alone.}
+\describe{syntax}{ will raise an error on \tsobj[value]{strict} and \tsobj[value]{syntax} cases.}
+\describe{reference}{ will raise an error on \tsobj[value]{strict}, \tsobj[value]{syntax} and \tsobj[value]{reference} cases.}
+\describe{all}{ will raise an error on all cases.}
+\end{describelist*}
+
+\describe{msg-suppress}{ ditto, to suppress classes of messages:}
+\begin{describelist*}{value}
+\describe{none}{ (default) no package message will be suppressed.}
+\describe{reference}{ only \tsobj[value]{reference} level messages will be suppressed.}
+\describe{syntax}{ \tsobj[value]{reference} and \tsobj[value]{syntax} level messages will be suppressed.}
+\describe{strict}{ \tsobj[value]{reference}, \tsobj[value]{syntax} and \tsobj[value]{strict} level messages will be suppressed.}
+\describe{all}{ all messages will be suppressed.}
+\end{describelist*}
+\end{describelist}
+
+\section{Creating a starray}\label{pack:new}
+\begin{codedescribe}{\starray_new:n,\starray_new:nTF}
+\begin{codesyntax}%
+\tsmacro{\starray_new:n}{starray}
+\tsmacro{\starray_new:nTF}{starray,if-true,if-false}
+\end{codesyntax}
+\end{codedescribe}
+
+Creates a new \tsobj[marg]{starray} or raises a warning if the name is already taken. The declaration (and associated property lists) is global. The given name is referred (in this text) as the \tsobj[marg]{starray-root} or just \tsobj[marg]{root}.
+\begin{tsremark}
+ A warning is raised (see \ref{pack:options}) if the name is already taken. The branching version doesn't raise any warning.
+\end{tsremark}
+
+\section{Defining and initialising a starray structure}\label{pack:def}
+
+\begin{codedescribe}{\starray_def_prop:nnn,\starray_def_prop:nnnTF}
+\begin{codesyntax}%
+\tsmacro{\starray_def_prop:nnn}{starray-ref,prop-key,initial-value}
+\tsmacro{\starray_def_prop:nnnTF}{starray-ref,prop-key,initial-value,if-true,if-false}
+\end{codesyntax}
+Adds an entry, \tsobj[marg]{prop-key}, to the \tsobj[marg]{starray-ref} (see \ref{pack:ref}) definition and set its initial value. If \tsobj[marg]{prop-key} is already present its initial value is updated. Both \tsobj[marg]{prop-key} and \tsobj[marg]{initial-value} may contain any \tsobj[marg]{balanced text}. \tsobj[marg]{prop-key} is an (\tsobj[pkg]{expl3}) property list \tsobj[marg]{key} meaning that category codes are ignored.
+
+The definition/assignment of a \tsobj[marg]{prop-key} to a \tsobj[marg]{starray-ref} is global.
+\end{codedescribe}
+
+\begin{tsremark}
+A warning is raised (see \ref{pack:options}) in case of a \tsobj[marg]{starray-ref} syntax/reference error. The branching version doesn't raise any warning.
+\end{tsremark}
+
+\begin{codedescribe}{\starray_def_structure:nn,\starray_def_structure:nnTF}
+\begin{codesyntax}%
+\tsmacro{\starray_def_struct:nn}{starray-ref,struct-name}
+\tsmacro{\starray_def_struct:nnTF}{starray-ref,struct-name,if-true,if-false}
+\end{codesyntax}
+Adds a sub-structure (a \tsobj[pkg]{starray} in itself) to \tsobj[marg]{starray-ref} (see \ref{pack:ref}). If \tsobj[marg]{struct-name} is already present nothing happens. The definition/assignment of a \tsobj[marg]{struct-name} to a \tsobj[marg]{starray-ref} is global.
+\end{codedescribe}
+
+
+\begin{tsremark}
+Do not use a dot when defining a (sub-)structure name, it might seems to work but it will breaks further down (see \ref{pack:ref}).
+\end{tsremark}
+
+
+\begin{tsremark}[Note 2:]
+A warning is raised (see \ref{pack:options}) in case of a \tsobj[marg]{starray-ref} syntax error. The branching version doesn't raise any warning.
+\end{tsremark}
+
+\begin{codedescribe}{\starray_def_from_keyval:nn,\starray_def_from_keyval:nnTF}
+\begin{codesyntax}%
+\tsmacro{\starray_def_from_keyval:nn}{starray-ref,keyval-lst}
+\tsmacro{\starray_def_from_keyval:nnTF}{starray-ref,keyval-lst,if-true,if-false}
+\end{codesyntax}
+
+Adds a set of \tsobj[marg]{keys} / \tsobj[marg]{values} and/or \tsobj[marg]{structures} to \tsobj[marg]{starray-ref} (see \ref{pack:ref}). The \tsobj[marg]{keyval-lst} is pretty straightforward,
+the construction \tsobj[key]{\tsobj[marg]{key} . struct} denotes a nested structure :
+\end{codedescribe}
+
+\begin{codestore}[keyval.demo]
+\starray_def_from_keyval:nn {root.substructure}
+ {
+ keyA = valA ,
+ keyB = valB ,
+ subZ . struct =
+ {
+ keyZA = valZA ,
+ keyZB = valZB ,
+ }
+ subY . struct =
+ {
+ keyYA = valYA ,
+ keyYB = valYB ,
+ subYYY . struct =
+ {
+ keyYYYa = valYYYa ,
+ keyYYYb = valYYYb
+ }
+ }
+ }
+\end{codestore}
+
+\tscode*[codeprefix=~]{keyval.demo}
+
+The definitions/assignments to \tsobj[marg]{starray-ref} are all global.
+
+
+The non-branching version raises a warning (see \ref{pack:options}) in case of a \tsobj[marg]{starray-ref} syntax error. The branching version doesn't raise any warning. Please note that, syntax errors on the \tsobj[marg]{keyval-lst} might raise low level (\TeX) errors.
+
+\subsection{Fixing an ill-instantiated starray}\label{pack:def-fix}
+
+When instantiating (see \ref{pack:instantiate}) a \tsobj[pkg]{starray}, the associated structured will be constructed based on it's ''current definition'' (see \ref{pack:def}). A problem that migh arise, when one extends the definition of an already instantiated \tsobj[pkg]{starray} (better said, if one adds a sub-structure), is a \textsl{quark loop} (from \tsobj[pkg]{l3quark}). To avoid a \textsl{quark loop} it is necessary to ''fix'' the structure of already instantiated terms.
+
+\begin{codedescribe}{\starray_fix_terms:n}
+\begin{codesyntax}%
+\tsmacro{\starray_fix_terms:n}{starray-ref}
+\end{codesyntax}
+\end{codedescribe}
+The sole purpose of this function is to ''fix'' the already instantiated terms of a \tsobj[pkg]{starray}. Note, this can be an expensive operation depending on the number of terms (it has to craw over all the terms of an instantiated \tsobj[pkg]{starray} adding any missing sub-structure references), but one doesn't need to run it ''right away'' it is possible to add a bunch of sub-structures and than run this just once.
+
+
+\section{Instantiating starray terms}\label{pack:instantiate}
+
+\begin{codedescribe}{\starray_new_term:n,\starray_new_term:nn,\starray_new_term:nTF,\starray_new_term:nnTF}
+\begin{codesyntax}%
+\tsmacro{\starray_new_term:n}{starray-ref}
+\tsmacro{\starray_new_term:nn}{starray-ref,hash}
+\tsmacro{\starray_new_term:nTF}{starray-ref,if-true,if-false}
+\tsmacro{\starray_new_term:nnTF}{starray-ref,hash,if-true,if-false}
+\end{codesyntax}
+\end{codedescribe}
+This create a new \textsl{term} (in fact a property list) of the (sub-)struture referenced by \tsobj[marg]{starray-ref}. Note that the newly created \textsl{term} will have all properties (key/values) as defined by the associated \tsmacro{\starray_prop_def:nn}{starray-ref}, with the respective ''initial values''. For instance, given the following
+
+\begin{codestore}[store-env=keyval.demo2]
+\starray_new:n {st-root}
+
+\starray_def_from_keyval:nn {st-root}
+ {
+ keyA = valA ,
+ keyB = valB ,
+ subZ . struct =
+ {
+ keyZA = valZA ,
+ keyZB = valZB ,
+ }
+ subY . struct =
+ {
+ keyYA = valYA ,
+ keyYB = valYB ,
+ subYYY . struct =
+ {
+ keyYYYa = valYYYa ,
+ keyYYYb = valYYYb
+ }
+ }
+ }
+
+\starray_new_term:n {st-root}
+\starray_new_term:n {st-root.subZ}
+\starray_new_term:n {st-root.subZ}
+\starray_new_term:n {st-root.subY}
+\starray_new_term:nn {st-root}{hash-A}
+\starray_new_term:n {st-root.subZ}
+\end{codestore}
+
+\tscode*[codeprefix=~]{keyval.demo2}
+
+One will have created 6 \textsl{terms}:
+\begin{enumerate}[miditemsep]
+\item 2 \tsobj[marg]{st-root} \textsl{terms}
+ \begin{enumerate}[miditemsep]
+ \item the first one with index 1 and
+ \begin{enumerate}[miditemsep]
+ \item 2 sub-structures \tsobj[marg]{subZ} (indexes 1 and 2)
+ \item 1 sub-structure \tsobj[marg]{subY} (index 1)
+ \end{enumerate}
+ \item the second one with indexes 2 and ''hash-A'' and
+ \begin{enumerate}[miditemsep]
+ \item 1 sub-structure \tsobj[marg]{subZ} (index 1)
+ \end{enumerate}
+ \end{enumerate}
+\end{enumerate}
+
+Note that, in the above example, it was used the ''implicit'' indexing (aka. iterator, see \ref{pack:ref}). Also note that no \textsl{term} of kind \tsobj[marg]{subYYY} was created.
+
+A warning is raised (see \ref{pack:options}) in case of a \tsobj[marg]{starray-ref} syntax error. The branching version doesn't raise any warning.
+
+
+\subsection{referencing terms}\label{pack:ref}
+
+When typing a \tsobj[marg]{starray-ref} there are 3 cases to consider:
+\begin{enumerate}[miditemsep]
+ \item structure definition
+ \item term instantiation
+ \item getting/setting a property
+\end{enumerate}
+
+The first case is the simplest one, in which, one (starting by \tsobj[marg]{starray-root} will use a construct like \tsobj[marg]{starray-root}.\tsobj[marg]{sub-struct}.\tsobj[marg]{sub-struct}\ldots
+For example, an equivalent construct to the one shown in \ref{pack:instantiate} :
+
+\begin{codestore}[store-env=demo3]
+\starray_new:n {st-root}
+
+\starray_def_struct:nn {st-root}{subZ}
+
+\starray_def_prop:nnn {st-root}{keyA}{valA}
+\starray_def_prop:nnn {st-root}{keyB}{valB}
+
+\starray_def_prop:nnn {st-root.subZ}{keyZA}{valZA}
+\starray_def_prop:nnn {st-root.subZ}{keyZB}{valZB}
+
+\starray_def_struct:nn {st-root}{subY}
+\starray_def_prop:nnn {st-root.subY}{keyYA}{valYA}
+\starray_def_prop:nnn {st-root.subY}{keyYB}{valYB}
+
+\starray_def_struct:nn {st-root.subY}{subYYY}
+\starray_def_prop:nnn {st-root.subY.subYYY}{keyYYYA}{valYYYA}
+\starray_def_prop:nnn {st-root.subY.subYYY}{keyYYYB}{valYYYB}
+
+\end{codestore}
+
+\tscode*[codeprefix=~]{demo3}
+
+Note that, all it's needed in order to be able to use \tsobj[marg]{starray-root}.\tsobj[marg]{sub-A} is that \tsobj[marg]{sub-A} is an already declared sub-structure of \tsobj[marg]{starray-root}. The property definitions can be made in any order.
+
+In all other cases, term instantiation, getting/setting a property, one has to address/reference a specific instance/term, implicitly (using iterators) or explicitly using indexes.
+The general form, of a \tsobj[marg]{starray-ref}, is: \par
+\tsobj[marg]{starray-root}\tsobj[oarg]{idx}.\tsobj[marg]{sub-A}\tsobj[oarg]{idxA}.\tsobj[marg]{sub-B}\tsobj[oarg]{idxB} \par
+In the case of term instantiation the last \tsobj[marg]{sub-} cannot be indexed, after all one is creating a new term/index. Moreover, all \tsobj[oarg]{idx} are optional like:\par
+\tsobj[marg]{starray-root}.\tsobj[marg]{sub-A}\tsobj[oarg]{idxA}.\tsobj[marg]{sub-B} \par
+in which case, one is using the ''iterator'' of \tsobj[marg]{starray-root} and \tsobj[marg]{sub-B} (more later, but keep in mind the \tsobj[marg]{sub-B} iterator is the \tsobj[marg]{sub-B} associated with the \tsobj[marg]{sub-A}\tsobj[oarg]{idxA}).
+
+Since one has to explicitly instantiate all (sub)terms of a starray, one can end with a highly asymmetric structure. Starting at the \tsobj[marg]{starray-root} one has a first counter (representing, indexing the root structure terms), then for all sub-strutures of \tsobj[marg]{starray-root} one will have an additional counter for every term of \tsobj[marg]{starray-root} !
+
+So, for example:
+\begin{codestore}[store-env=demo4]
+\starray_new:n {st-root}
+\starray_def_struct:nn {st-root}{subZ}
+\starray_def_struct:nn {st-root}{subY}
+\starray_def_struct:nn {st-root.subY}{subYYY}
+
+\starray_new_term:n {st-root}
+\starray_new_term:n {st-root.subZ}
+\starray_new_term:n {st-root.subZ}
+\starray_new_term:n {st-root.subY}
+\starray_new_term:n {st-root.subY}
+\starray_new_term:n {st-root.subY.subYYY}
+\starray_new_term:n {st-root.subY}
+
+\starray_new_term:n {st-root}
+\starray_new_term:n {st-root.subZ}
+\starray_new_term:n {st-root.subZ}
+\starray_new_term:n {st-root.subY}
+\end{codestore}
+
+\tscode*[codeprefix=~]{demo4}
+
+One has a single \tsobj[marg]{st-root} iterator (pointing to one of the 3 \tsobj[marg]{st-root} terms), then 3 ''\tsobj[marg]{subZ} iterators'', in fact, one \tsobj[marg]{subZ} iterator for each \tsobj[marg]{st-root} term.
+Likewise there are 3 ''\tsobj[marg]{subY} iterators'' and 4 (four) ''\tsobj[marg]{subYYY} iterators'' one for each instance of \tsobj[marg]{subY}.
+
+Every time a new term is created/instantiated, the corresponding iterator will points to it, which allows the notation used in this last example, keep in mind that one could instead, using explicit indexes:
+
+\begin{codestore}[store-env=demo5]
+\starray_new:n {st-root}
+\starray_def_struct:nn {st-root}{subZ}
+\starray_def_struct:nn {st-root}{subY}
+\starray_def_struct:nn {st-root.subY}{subYYY}
+
+\starray_new_term:n {st-root}
+\starray_new_term:n {st-root[1].subZ}
+\starray_new_term:n {st-root[1].subZ}
+\starray_new_term:n {st-root[1].subY}
+\starray_new_term:n {st-root[1].subY}
+\starray_new_term:n {st-root[1].subY[2].subYYY}
+\starray_new_term:n {st-root[1].subY}
+
+\starray_new_term:n {st-root}
+\starray_new_term:n {st-root[2].subZ}
+\starray_new_term:n {st-root[2].subZ}
+\starray_new_term:n {st-root[2].subY}
+\end{codestore}
+
+\tscode*[codeprefix=~]{demo5}
+
+Finally, observe that, when creating a new term, one has the option to assign a ''hash'' to it, in which case that term can be referred to using an iterator, the explicit index or the hash:
+
+\begin{codestore}[store-env=demo6]
+\starray_new:n {st-root}
+\starray_def_struct:nn {st-root}{subZ}
+\starray_def_struct:nn {st-root}{subY}
+\starray_def_struct:nn {st-root.subY}{subYYY}
+
+\starray_new_term:nn {st-root}{hash-A}
+\starray_new_term:n {st-root.subZ}
+\starray_new_term:n {st-root[1].subZ}
+\starray_new_term:n {st-root[hash-A].subZ}
+\end{codestore}
+\tscode*[codeprefix=~]{demo6}
+
+Will create 3 \tsobj[marg]{subZ} terms associated with the first (index = 1) \tsobj[marg]{st-root}.
+
+
+\subsection{iterators}\label{pack:iter}
+
+\begin{codedescribe}{\starray_set_iter:nn,\starray_set_iter:nnTF,\starray_reset_iter:nn,\starray_reset_iter:nnTF,\starray_next_iter:nn,\starray_next_iter:nnTF}
+\begin{codesyntax}%
+\tsmacro{\starray_set_iter:nn}{starray-ref,int-val}
+\tsmacro{\starray_set_iter:nTF}{starray-ref,int-val,if-true,if-false}
+\tsmacro{\starray_reset_iter:nn}{starray-ref}
+\tsmacro{\starray_reset_iter:nTF}{starray-ref,if-true,if-false}
+\tsmacro{\starray_next_iter:nn}{starray-ref}
+\tsmacro{\starray_next_iter:nTF}{starray-ref,if-true,if-false}
+\end{codesyntax}
+\end{codedescribe}
+Those functions allows to \tsmacro{set}{} an iterator to a given \tsobj[marg]{int-val}, \tsmacro{reset}{} it (i.e. assign 1 to the iterator), or increase the iterator by one. An iterator might have a value between 1 and the number of instantiated terms (if the given (sub-)structure was already instantiated). If the (sub-)structure hasn't been instantiated yet, the iterator will always end being set to 0. The branching versions allows to catch those cases, like trying to set a value past its maximum, or a value smaller than one.
+
+\begin{tsremark}[Important:]
+Please observe that, when setting/resetting/incrementing the iterator of a (sub-)structure, all ''descending'' iterators will be also be reset.
+\end{tsremark}
+\begin{tsremark}
+A warning is raised (see \ref{pack:options}) in case of a \tsobj[marg]{starray-ref} syntax error. The branching version doesn't raise any warning.
+\end{tsremark}
+
+
+\begin{codestore}[store-env=demo7]
+\starray_new:n {st-root}
+\starray_def_struct:nn {st-root}{subZ}
+\starray_def_struct:nn {st-root}{subY}
+\starray_def_struct:nn {st-root.subY}{subYYY}
+
+\starray_new_term:n {st-root}
+\starray_new_term:n {st-root.subZ}
+\starray_new_term:n {st-root.subZ}
+\starray_new_term:n {st-root.subY}
+\starray_new_term:n {st-root.subY.subYYY}
+\starray_new_term:n {st-root.subY.subYYY}
+\starray_new_term:n {st-root.subY}
+\starray_new_term:n {st-root.subY.subYYY}
+\starray_new_term:n {st-root.subY.subYYY}
+\starray_new_term:n {st-root}
+\starray_new_term:n {st-root.subZ}
+\starray_new_term:n {st-root.subZ}
+\starray_new_term:n {st-root.subY}
+\starray_new_term:n {st-root.subY.subYYY}
+\starray_new_term:n {st-root.subY.subYYY}
+\starray_new_term:n {st-root.subY}
+\starray_new_term:n {st-root.subY.subYYY}
+\starray_new_term:n {st-root.subY.subYYY}
+
+\starray_set_prop:nnn {st-root.subY.subYYY}{key}{val}
+\starray_set_prop:nnn {st-root[2].subY[2].subYYY[2]}{key}{val}
+
+\starray_reset_iter:n {st-root[2].subY}
+
+\starray_set_prop:nnn {st-root.subY.subYYY}{key}{val}
+\starray_set_prop:nnn {st-root[2].subY[1].subYYY[1]}{key}{val}
+\end{codestore}
+
+\tscode*[codeprefix=~]{demo7}
+
+Before the reset \tsobj[marg]{st-root.subY.subYYY} was equivalent to \tsobj[marg]{st-root[2].subY[2]. subYYY[2]}, given that each iterator was pointing to the ''last term'', since the reset was of the \tsobj[marg]{subY} iterator, only it and the descending ones (in this example just \tsobj[marg]{subYYY}) where reseted, and therefore \tsobj[marg]{st-root.subY.subYYY} was then equivalent to \tsobj[marg]{st-root[2].subY[1].subYYY[1]}
+
+
+
+\begin{codedescribe}{\starray_get_iter:n,\starray_get_iter:nN,\starray_get_iter:nNTF}
+\begin{codesyntax}%
+\tsmacro{\starray_get_iter:n}{starray-ref}
+\tsmacro{\starray_get_iter:nN}{starray-ref,int-var}
+\tsmacro{\starray_get_iter:nNTF}{starray-ref,int-var,if-true,if-false}
+\end{codesyntax}
+\end{codedescribe}
+\tsmacro{\starray_get_iter:n}{starray-ref} will type in the current value of a given iterator, whilst the other two functions will save it's value in a integer variable (\tsobj[pkg]{expl3}).
+\begin{tsremark}
+A warning is raised (see \ref{pack:options}) in case of a \tsobj[marg]{starray-ref} syntax error. The branching version doesn't raise any warning.
+\end{tsremark}
+
+\begin{codedescribe}{\starray_get_cnt:n,\starray_get_cnt:nN,\starray_get_cnt:nNTF}
+\begin{codesyntax}%
+\tsmacro{\starray_get_cnt:n}{starray-ref}
+\tsmacro{\starray_get_cnt:nN}{starray-ref,integer}
+\tsmacro{\starray_get_cnt:nNTF}{starray-ref,integer,if-true,if-false}
+\end{codesyntax}
+\end{codedescribe}
+\tsmacro{\starray_get_cnt:n}{starray-ref} will type in the current number of terms of a given (sub-)structure, whilst the other two functions will save it's value in a integer variable (\tsobj[pkg]{expl3}).
+\begin{tsremark}
+A warning is raised (see \ref{pack:options}) in case of a \tsobj[marg]{starray-ref} syntax error. The branching version doesn't raise any warning.
+\end{tsremark}
+
+\section{Changing and recovering starray properties}\label{pack:get/set}
+
+\begin{codedescribe}{\starray_set_prop:nnn,\starray_set_prop:nnV,\starray_set_prop:nnnTF,\starray_set_prop:nnVTF,\starray_gset_prop:nnn,\starray_gset_prop:nnV,\starray_gset_prop:nnnTF,\starray_gset_prop:nnVTF}
+\begin{codesyntax}%
+\tsmacro{\starray_set_prop:nnn}{starray-ref,prop-key,value}
+\tsmacro{\starray_set_prop:nnV}{starray-ref,prop-key,value}
+\tsmacro{\starray_set_prop:nnnTF}{starray-ref,prop-key,value,if-true,if-false}
+\tsmacro{\starray_set_prop:nnVTF}{starray-ref,prop-key,value,if-true,if-false}
+\tsmacro{\starray_gset_prop:nnn}{starray-ref,prop-key,value}
+\tsmacro{\starray_gset_prop:nnV}{starray-ref,prop-key,value}
+\tsmacro{\starray_gset_prop:nnnTF}{starray-ref,prop-key,value,if-true,if-false}
+\tsmacro{\starray_gset_prop:nnVTF}{starray-ref,prop-key,value,if-true,if-false}
+\end{codesyntax}
+\end{codedescribe}
+Those are the functions that allow to (g)set (change) the value of a term's property. If the \tsobj[marg]{prop-key} isn't already present it will be added just for that term \tsobj[marg]{starray-ref}. The \tsobj[parg]{nnV} variants allow to save any variable like a token list, property list, etc...
+\begin{tsremark}
+A warning is raised (see \ref{pack:options}) in case of a \tsobj[marg]{starray-ref} syntax error. The branching version doesn't raise any warning.
+\end{tsremark}
+
+\begin{codedescribe}{\starray_set_from_keyval:nn,\starray_set_from_keyval:nnTF,\starray_gset_from_keyval:nn,\starray_gset_from_keyval:nnTF}
+\begin{codesyntax}%
+\tsmacro{\starray_set_from_keyval:nnn}{starray-ref,keyval-lst}
+\tsmacro{\starray_set_from_keyval:nnnTF}{starray-ref,keyval-lst,if-true,if-false}
+\tsmacro{\starray_gset_from_keyval:nnn}{starray-ref,keyval-lst}
+\tsmacro{\starray_gset_from_keyval:nnnTF}{starray-ref,keyval-lst,if-true,if-false}
+\end{codesyntax}
+\end{codedescribe}
+
+it is possible to set a collection of properties using a key/val syntax, similar to the one used to define a \tsobj[pkg]{starray} from keyvals (see \ref{pack:def}), with a few distinctions:
+\begin{enumerate}
+ \item when referring a (sub-)structure one can either explicitly use an index, or
+ \item implicitly use it's iterator
+ \item if a given key isn't already presented it will be added only to the given term
+\end{enumerate}
+
+ Note that, in the following example, TWO iterators are being used, the one for \tsobj[marg]{st-root} and then \tsobj[marg]{subY}.
+
+\begin{codestore}[store-env=keyval.demo8]
+\starray_set_from_keyval:nn {st-root}
+ {
+ keyA = valA ,
+ keyB = valB ,
+ subZ[2] =
+ {
+ keyZA = valZA ,
+ keyZB = valZB ,
+ }
+ subY =
+ {
+ keyYA = valYA ,
+ keyYB = valYB ,
+ subYYY[1] =
+ {
+ keyYYYa = valYYYa ,
+ keyYYYb = valYYYb
+ }
+ }
+ }
+\end{codestore}
+
+\tscode*[codeprefix=~]{keyval.demo8}
+
+Also note that the above example is fully equivalent to:
+
+\begin{codestore}[store-env=keyval.demo9]
+\starray_set_prop:nnn {st-root} {keyA} {valA}
+\starray_set_prop:nnn {st-root} {keyB} {valB}
+\starray_set_prop:nnn {st-root.subZ[2]} {keyZA} {valZA}
+\starray_set_prop:nnn {st-root.subZ[2]} {keyZB} {valZB}
+\starray_set_prop:nnn {st-root.subY} {keyYA} {valYA}
+\starray_set_prop:nnn {st-root.subY} {keyYB} {valYB}
+\starray_set_prop:nnn {st-root.subY.subYYY[1} {keyYYYa} {valYYYa}
+\starray_set_prop:nnn {st-root.subY.subYYY[1} {keyYYYb} {valYYYb}
+\end{codestore}
+
+\tscode*[codeprefix=~]{keyval.demo9}
+
+
+\section{Additional Conditionals}\label{pack:extra}
+
+\begin{codedescribe}{\starray_if_in:nnTF,\starray_term_syntax:nTF}
+\begin{codesyntax}%
+\tsmacro{\starray_if_in:nnTF}{starray-ref,key,if-true,if-false}
+\tsmacro{\starray_term_syntax:nTF}{starray-ref,if-true,if-false}
+\end{codesyntax}
+\end{codedescribe}
+The \tsmacro{\starray_if_in:nnTF}{starray-ref,key,\ldots,\ldots} tests if a given \tsobj[marg]{key} is present, whilst \tsmacro{\starray_term_syntax:nTF}{starray-ref,\ldots,\ldots} just verifies if the \tsobj[marg]{starray-ref} syntax is valid or not, branching accordly.
+
+
+\section{Showing (debugging) starrays }\label{pack:show}
+
+\begin{codedescribe}{\starray_show_def:n,\starray_show_def_in_text:n}
+\begin{codesyntax}%
+\tsmacro{\starray_show_def:n}{starray-ref}
+\tsmacro{\starray_show_def_in_text:n}{starray-ref}
+\end{codesyntax}
+\end{codedescribe}
+Displays the \tsobj[marg]{starray} structure definition and initial property values in the terminal or directly in text.
+
+\begin{codedescribe}{\starray_show_terms:n,\starray_show_terms_in_text:n}
+\begin{codesyntax}%
+\tsmacro{\starray_show_terms:n}{starray-ref}
+\tsmacro{\starray_show_terms_in_text:n}{starray-ref}
+\end{codesyntax}
+\end{codedescribe}
+Displays the \tsobj[marg]{starray} instantiated terms and current property values in the terminal or directly in text.
+
+
+
+\end{document}
diff --git a/macros/latex/contrib/starray/latex/starray.sty b/macros/latex/contrib/starray/latex/starray.sty
new file mode 100644
index 0000000000..332118809f
--- /dev/null
+++ b/macros/latex/contrib/starray/latex/starray.sty
@@ -0,0 +1,2073 @@
+%%%==============================================================================
+%% Copyright 2023 by Alceu Frigeri
+%%
+%% This work may be distributed and/or modified under the conditions of
+%%
+%% * The [LaTeX Project Public License](http://www.latex-project.org/lppl.txt),
+%% version 1.3c (or later), and/or
+%% * The [GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.html),
+%% version 3 (or later)
+%%
+%% This work has the LPPL maintenance status *maintained*.
+%%
+%% The Current Maintainer of this work is Alceu Frigeri
+%%
+%% This is version 1.0 (2023/05/11)
+%%
+%% The list of files that compose this work can be found in the README.md file at
+%% https://ctan.org/pkg/starray
+%%
+%%%==============================================================================
+\NeedsTeXFormat{LaTeX2e}[2022/06/01]
+\RequirePackage{ expl3 }
+\ProvidesExplPackage
+ {starray}
+ {2023/05/11}
+ {1.0}
+ {A structured array/hash of properties}
+
+\prop_if_exist:NTF \g__codedesc_pkg_prop
+ {}
+ { \prop_new:N \g__codedesc_pkg_prop }
+
+\prop_put_from_keyval:Nn \g__codedesc_pkg_prop
+ {
+ starray . name = starrayr ,
+ starray . prefix = starray ,
+ starray . date = 2023/05/01 ,
+ starray . version = 1.0 ,
+ starray . description = A structured array/hash of properties
+ }
+
+\cs_gset:Npn \__codedesc_pkg_info:nn #1#2
+ {
+ \prop_item:Nn \g__codedesc_pkg_prop {#1.#2}
+ }
+
+\cs_if_exist:NTF \PkgInfo
+ {}
+ {
+ \NewDocumentCommand \PkgInfo {mm} { \prop_item:Nn \g__codedesc_pkg_prop {#1.#2} }
+ }
+
+
+%%%%%%%%%%%%%%%%%%%
+%%%%
+%%%% New package
+%%%%
+%%%%%%%%%%%%%%%%%%%
+
+\tl_new:N \l__starray_prefix_tl
+%\tl_gset:Nn \l__starray_prefix_tl {l__starray_}
+
+
+\keys_define:nn { starray }
+{
+ prefix .tl_set:N = \l__starray_prefix_tl ,
+ prefix .value_required:n = true ,
+ prefix .initial:n = l__starray_ ,
+ prefix .usage:n = load ,
+
+ msg-err .choice: ,
+ msg-err / none .code:n = {
+ % \msg_redirect_module:nnn { starray } { warning } { none }
+ },
+ msg-err / default .code:n = {} ,
+ msg-err / strict .code:n = {
+ \msg_redirect_module:nnn { starray / strict } { warning } { error }
+ },
+ msg-err / syntax .code:n = {
+ \msg_redirect_module:nnn { starray / strict } { warning } { error }
+ \msg_redirect_module:nnn { starray / syntax } { warning } { error }
+ } ,
+ msg-err / reference .code:n = {
+ \msg_redirect_module:nnn { starray / strict } { warning } { error }
+ \msg_redirect_module:nnn { starray / syntax } { warning } { error }
+ \msg_redirect_module:nnn { starray / reference } { warning } { error }
+ } ,
+ msg-err / all .code:n = \msg_redirect_module:nnn { starray } { warning } { error } ,
+ msg-err . usage:n = load ,
+
+ msg-supress .choice: ,
+ msg-supress / none .code:n = {} ,
+ msg-supress / reference .code:n = {
+ \msg_redirect_module:nnn { starray / reference } { warning } { none }
+ },
+ msg-supress / syntax .code:n = {
+ \msg_redirect_module:nnn { starray / strict } { warning } { none }
+ \msg_redirect_module:nnn { starray / syntax } { warning } { none }
+ } ,
+ msg-supress / strict .code:n = {
+ \msg_redirect_module:nnn { starray / strict } { warning } { none }
+ \msg_redirect_module:nnn { starray / syntax } { warning } { none }
+ \msg_redirect_module:nnn { starray / reference } { warning } { none }
+ } ,
+ msg-supress / all .code:n = \msg_redirect_module:nnn { starray } { warning } { none } ,
+ msg-supress . usage:n = load ,
+
+
+}
+
+\ProcessKeyOptions [ starray ]
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% New variants of core expl3 primitives
+%%%% expansion handling
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+\cs_generate_variant:Nn \prop_item:Nn { ce , Ne }
+\cs_generate_variant:Nn \tl_put_right:Nn {Ne}
+\cs_generate_variant:Nn \tl_gput_right:Nn {Ne}
+\cs_generate_variant:Nn \tl_set:Nn {Ne , ce}
+\cs_generate_variant:Nn \tl_gset:Nn {Ne , ce}
+
+\cs_generate_variant:Nn \seq_put_right:Nn {ce}
+\cs_generate_variant:Nn \seq_gput_right:Nn {ce}
+
+\cs_generate_variant:Nn \int_to_Alph:n {e}
+
+\cs_generate_variant:Nn \prop_put:Nnn {Nee , cee}
+\cs_generate_variant:Nn \prop_gput:Nnn {Nee , cee}
+
+\cs_generate_variant:Nn \prop_get:NnN {Nnc , cnc , Nec , cec}
+
+\prg_generate_conditional_variant:Nnn \prop_get:NnN {Nnc , cnc , Nec , cec} { F , T , TF}
+
+\prg_generate_conditional_variant:Nnn \seq_if_in:Nn {ce} {TF}
+\prg_generate_conditional_variant:Nnn \prop_if_in:Nn {ce} {TF}
+
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% Package error/warning messages
+%%%% #1 'ID' (code identifier)
+%%%% #2 / #3 / #4 further fields (as needed)
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+\msg_new:nnnn {starray} {strict / (re)define}
+ {
+ (ID:#1)~'#2'~already~defined!
+ }
+ {
+ You~tried~to~(re)define~'#2'.
+ ~Error~Code~ ID:<#1>.
+ }
+
+
+\msg_new:nnnn {starray} {syntax / ref-syntax-err}
+ {
+ (ID:#1)~term~reference~'#2'~--~'#3'.
+ }
+ {
+ Your~term~'#2'~contains~a~syntax~error:~'#3'.
+ ~Error~ Code~ ID:<#1>.
+ }
+
+\msg_new:nnnn {starray} {syntax / keyval-term}
+ {
+ (ID:#1)~term~reference~'#2'~error~'#3'.
+ }
+ {
+ Your~term~'#2'~contains~a~syntax~error:~'#3'.
+ ~Error~ Code~ ID:<#1>.
+ }
+
+\msg_new:nnnn {starray} {syntax / term}
+ {
+ (ID:#1)~'#2'~isn't~a~valid~term~ref.
+ }
+ {
+ Invalid~term~reference:~'#2'.
+ ~Error~ Code~ ID:<#1>.
+ }
+
+\msg_new:nnnn {starray} {syntax / structure-ref}
+ {
+ (ID:#1)~'#3'~isn't~a~sub-structure~of~'#2'.
+ }
+ {
+ '#2' ~doesn't~have~a~sub-structure~named:~'#3'.
+ ~Error~ Code~ ID:<#1>.
+ }
+
+\msg_new:nnnn {starray} {syntax / iter}
+ {
+ (ID:#1)~cannot~set~iter. ~invalid~'#2'.
+ }
+ {
+ cannot~set~iter.~ invalid '#2'.
+ ~Error~ Code~ ID:<#1>.
+ }
+
+
+\msg_new:nnnn {starray} {syntax / prop}
+ {
+ (ID:#1)~cannot~get/set~property~from~'#2'.
+ }
+ {
+ You~have~referenced~an~invalid~structur~'#2'.
+ ~Error~ Code~ ID:<#1>.
+ }
+
+
+\msg_new:nnnn {starray} {reference / invalid-starray} %%%$$
+ {
+ (ID:#1)~'#2'~invalid~starray.
+ \tl_if_blank:nTF {#3}
+ {~#3}
+ {}
+ }
+ {
+ '#2'~isn't~a~starray.
+ \tl_if_blank:nTF {#3}
+ {~#3}
+ {}
+ ~Error~ Code~ ID:<#1>.
+ }
+
+\msg_new:nnnn {starray} {reference / iter}
+ {
+ (ID:#1)~invalid~iter~(#3)~from~'#2'
+ \str_if_empty:nTF {#4}
+ {}
+ {#4}
+ .
+ }
+ {
+ Invalid~iter~(#3)~from~ '#2'.~You~might~have~tried~to~use/set/reset~an~iter~of
+ ~an~ill~instantiated~structured.
+ ~Error~ Code~ ID:<#1>.
+ }
+
+\msg_new:nnnn {starray} {reference / prop} %%%$$
+ {
+ (ID:#1)~cannot~get/set~property~'#3'~from~'#2'.
+ }
+ {
+ '#3'~isn't~a~property~of~'#2'.
+ ~Error~ Code~ ID:<#1>.
+ }
+
+\msg_new:nnnn {starray} {info / show}
+ {
+ \iow_newline:(ID:#1)\iow_newline:~ #2 \iow_newline:
+
+ #3
+
+ \iow_newline:
+ definition's~end.
+ }
+ {
+ \iow_newline:(ID:#1)\iow_newline:~ #2 \iow_newline:
+
+ #3
+
+ \iow_newline:
+ definition's~end.
+ }
+
+
+
+
+
+\cs_new:Npn \__starray_msg:nnnnn #1#2#3#4#5
+ {
+ \bool_gset_false:N \l__starray_rtn_bool
+
+ \seq_gput_right:Nn \l__starray_msg_seq
+ {
+ \msg_warning:nnnnnn
+ {starray}{ #1 } { #2 }{ #3 }{ #4 }{ #5 }
+ }
+ }
+
+\cs_generate_variant:Nn \__starray_msg:nnnnn { nneee , neeee }
+
+\cs_new:Npn \__starray_msg_dispatch:
+ {
+ \seq_map_tokens:Nn \l__starray_msg_seq { }
+ \seq_clear:N \l__starray_msg_seq
+ }
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% Package Variables declaration
+%%%%
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+% TODO variables declaration
+
+\prop_new:N \l__starray_tmpA_prop
+
+%%%%
+%%%% 'general' (internal) returning bool
+%%%%
+\bool_new:N \l__starray_rtn_bool
+
+%%%%
+%%%% sequence of 'error mensages' (stacked).
+%%%%
+\seq_new:N \l__starray_msg_seq
+
+%%%%
+%%%% recursive/reentrant aware tmp variables.
+%%%%
+
+\int_set:Nn \l_tmpa_int {7}
+\tl_clear:N \l_tmpa_tl
+\int_do_while:nNnn {\l_tmpa_int} > {0}
+ {
+ \tl_put_left:Nn \l_tmpa_tl {A}
+ \prop_new:c { l__starray_tmp \l_tmpa_tl _hash_prop }
+ \prop_new:c { l__starray_tmp \l_tmpa_tl _def_prop }
+ \prop_new:c { l__starray_tmp \l_tmpa_tl _idx_prop }
+ \int_new:c { l__starray_tmp \l_tmpa_tl _int }
+ \seq_new:c { l__starray_tmp \l_tmpa_tl _seq }
+ \tl_new:c { l__starray_tmp \l_tmpa_tl _tl }
+ \tl_new:c { l__starray_tmp \l_tmpa_tl :A_tl }
+ \tl_new:c { l__starray_tmp \l_tmpa_tl :B_tl }
+ \tl_new:c { l__starray_tmp \l_tmpa_tl _idx_tl }
+
+ \int_decr:N \l_tmpa_int
+ }
+
+\tl_new:N \l__starray_tmpa_tl
+\tl_new:N \l__starray_tmpb_tl
+
+\tl_new:N \l__starray_showcmd_tl
+
+%%%%
+%%%% (sub)structure returning tl.
+%%%%
+\tl_new:N \l__starray_tmpST_tl
+
+
+%%%%
+%%%% parser related ones
+%%%%
+\bool_const:Nn \c__starray_no_idx_ending_bool \c_true_bool
+\bool_const:Nn \c__starray_idx_ending_bool \c_false_bool
+
+
+%%%%
+%%%% parser returning variables
+%%%%
+\tl_new:N \l__starray_parsed_tl
+\tl_new:N \l__starray_parsed_ref_tl
+\tl_new:N \l__starray_parsed_base_ref_tl
+\tl_new:N \l__starray_parsed_root_ref_tl
+
+\tl_new:N \l__starray_parsing_term_tl
+
+%%%%
+%%%% parser 'internal' variables
+%%%%
+\bool_new:N \l__starray_parser_no_idx_ending_bool
+
+\tl_new:N \l__starray_parsed_term_tl
+\tl_new:N \l__starray_parsed_idx_tl
+
+\tl_new:N \l__starray_parser_aux_tl %% when constructing parser ref, 1st <nothing> then dot .
+
+\bool_new:N \l__starray_parser_OK_bool
+
+
+%% big one, (g)put !!
+%%%%
+%%%% (g)put :: IF the effect shall be local or global
+%%%%
+\tl_new:N \l__starray_put_tl
+
+
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% Package conditionals
+%%%%
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+\prg_new_conditional:Npnn \__starray_if_free:n #1 {p, T, F, TF}
+ {
+ \prop_if_exist:cTF {#1}
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+
+\prg_generate_conditional_variant:Nnn \__starray_if_free:n {e} {p, T, F, TF}
+
+\prg_new_conditional:Npnn \__starray_if_valid:n #1 {p, T, F, TF}
+ {
+ \bool_lazy_and:nnTF {\prop_if_exist_p:c {#1}} {\prop_item:cn {#1} {is_starray}}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\prg_generate_conditional_variant:Nnn \__starray_if_valid:n {e} {p, T, F, TF}
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% starray \...._new declarations
+%%%%
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+
+\cs_new:Npn \__starray_base_new:nn #1#2
+ {
+ \int_new:c
+ { \l__starray_prefix_tl #2 _cnt_int }
+ \int_gzero:c
+ { \l__starray_prefix_tl #2 _cnt_int }
+
+ \int_new:c
+ { \l__starray_prefix_tl #2 _iter_int }
+ \int_gzero:c
+ { \l__starray_prefix_tl #2 _iter_int }
+
+ \prop_new:c { \l__starray_prefix_tl #2 _base_prop }
+
+ \prop_gset_from_keyval:cn
+ { \l__starray_prefix_tl #2 _base_prop }
+ {
+ def_ref = #1 ,
+ is_starray = \c_true_bool ,
+ }
+
+ \prop_gput:cno
+ { \l__starray_prefix_tl #2 _base_prop }
+ { cnt }
+ { \use:c { \l__starray_prefix_tl #2 _cnt_int } }
+
+ \prop_gput:cno
+ { \l__starray_prefix_tl #2 _base_prop }
+ { iter }
+ { \use:c {\l__starray_prefix_tl #2 _iter_int} }
+
+ \prop_gput:cnV
+ { \l__starray_prefix_tl #2 _base_prop }
+ { idx_hash }
+ \c_empty_prop
+ }
+
+\cs_generate_variant:Nn \__starray_base_new:nn { ee }
+
+
+\cs_new:Npn \__starray_sub_base_new:nnn #1#2#3
+ { \__starray_base_new:ee {#1.#3}{#2.#3} }
+
+
+\cs_new:Npn \__starray_new:n #1
+ {
+ \prop_new:c
+ { \l__starray_prefix_tl #1 _def_prop }
+
+ \prop_gset_from_keyval:cn
+ { \l__starray_prefix_tl #1 _def_prop }
+ {
+ is_starray = \c_true_bool ,
+ def_ref = #1
+ }
+
+ \prop_clear:N \l_tmpa_prop
+
+ \prop_gput:cnV { \l__starray_prefix_tl #1 _def_prop } {@st_seq} \c_empty_seq
+
+ \prop_gput:cnV
+ { \l__starray_prefix_tl #1 _def_prop} {def} \l_tmpa_prop
+
+ }
+
+\cs_generate_variant:Nn \__starray_new:n { e }
+
+
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \starray_new
+%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \starray_new:n #1
+ {
+ \__starray_if_free:nTF {\l__starray_prefix_tl #1 _def_prop}
+ {
+ \__starray_new:e {#1 }
+ \__starray_base_new:ee {#1}{#1} % TODO: might be incomplete !!!
+ }
+ {
+ \msg_warning:nnnn {starray} {strict / (re)define} {new:1} {#1}
+ }
+ }
+
+
+\prg_new_conditional:Npnn \starray_new:n #1 {p, T, F, TF}
+ {
+ \__starray_if_free:nTF {\l__starray_prefix_tl #1 _def_prop}
+ {
+ \__starray_new:e {#1 }
+ \__starray_base_new:ee {#1}{#1} % TODO: might be incomplete !!!
+ \prg_return_true:
+ }
+ { \prg_return_false: }
+ }
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% starray ref parser
+%%%%
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% get root reference (first term) assuming called as
+%%%% <st-ref> . \q_nil \q_stop
+%%%% so that even if {ref} (has no dot, no idx) it will return 'the root ref'
+%%%%
+%%%% e.g.: \tl_set:Ne \l__tmpb_tl {\__starray_get_root:w \l__starray_tmpa_tl . \q_nil \q_stop}
+%%%%
+%%%% It will return the 'root ref' assuming that the ref is of form root.name.name (no [idx])
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \__starray_get_root:w #1 . #2 \q_stop { #1 }
+
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% adding property #3 (#4 being it's initial/default value)
+%%%% #1 prefix
+%%%% #2 starray
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+
+\cs_new:Npn \__starray_def_prop:nnn #1#2#3
+ {
+ \prop_get:cnN {\l__starray_prefix_tl #1 _def_prop} {def} \l_tmpa_prop
+ \prop_put:Nnn \l_tmpa_prop {#2} {#3}
+ \prop_gput:cnV {\l__starray_prefix_tl #1 _def_prop} {def} \l_tmpa_prop
+ }
+
+
+
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \starray_def_prop
+%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \starray_def_prop:nnn #1#2#3
+ {
+ \__starray_if_valid:nTF {\l__starray_prefix_tl #1 _def_prop}
+ { \__starray_def_prop:nnn {#1} {#2} {#3} }
+ {
+ \msg_warning:nnxxx {starray}{reference / invalid-starray}
+ {addprop:1} {#1} {cannot~add~property:#2}
+ }
+ }
+
+
+\prg_new_conditional:Npnn \starray_def_prop:nnn #1#2#3 {p, T, F, TF}
+ {
+ \__starray_if_valid:nTF {\l__starray_prefix_tl #1 _def_prop}
+ {
+ \__starray_def_prop:nnn {#1} {#2} {#3}
+ \prg_return_true:
+ }
+ { \prg_return_false: }
+ }
+
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% adding struct array #2 to a starray
+%%%%
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \__starray_def_struct:nn #1#2
+ {
+ \prop_get:cnN {\l__starray_prefix_tl #1 _def_prop} {@st_seq} \l_tmpa_seq
+ \seq_if_in:NnF \l_tmpa_seq {#2}
+ {
+ \seq_put_right:Nn \l_tmpa_seq {#2}
+
+ \prop_gput:cnV {\l__starray_prefix_tl #1 _def_prop} {@st_seq} \l_tmpa_seq
+
+ \__starray_new:e { #1 . #2}
+ }
+ }
+
+\cs_generate_variant:Nn \__starray_def_struct:nn {ne}
+
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% fixing struct _base for already instantiated terms
+%%%%
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%TODO: recurse over 'terms' to fix a 'late addtion' (after being instantiated?)
+
+\cs_new:Npn \__starray_fix_terms_seq_aux:nnnn #1#2#3#4
+ {
+ \__starray_if_valid:eTF {\l__starray_prefix_tl #2 _ #3 . #4 _base_prop}
+ {
+ \__starray_fix_terms:nn {#1.#4}{#2_#3.#4}
+ }
+ {
+ \__starray_base_new:ee {#1.#4}{#2_#3.#4}
+ }
+ }
+
+\cs_new:Npn \__starray_fix_terms_seq:nnnn #1#2#3#4
+ {
+ \prop_get:cnN
+ {\l__starray_prefix_tl #2 _base_prop}
+ {def_ref}
+ \l_tmpa_tl
+ \prop_get:cec
+ {\l__starray_prefix_tl \l_tmpa_tl _def_prop}
+ {@st_seq}
+ {l__starray_tmp A_seq}
+ \seq_map_tokens:cn
+ {l__starray_tmp A_seq}
+ {\__starray_fix_terms_seq_aux:nnnn {#1}{#2}{#4}}
+
+ }
+
+\cs_new:Npn \__starray_fix_terms:nn #1#2
+ {
+ \group_begin:
+ \prop_get:cnc
+ {\l__starray_prefix_tl #2 _base_prop}
+ {idx_hash}
+ {l__starray_tmp A_prop}
+ \prop_if_empty:cF {l__starray_tmp A_prop}
+ {
+ \prop_map_tokens:cn
+ {l__starray_tmp A_prop}
+ {\__starray_fix_terms_seq:nnnn {#1}{#2}}
+ }
+ \group_end:
+ }
+
+\cs_generate_variant:Nn \__starray_fix_terms:nn {ee}
+
+
+
+\cs_new:Npn \starray_fix_terms:n #1
+ {
+ \tl_set:Ne \l_tmpb_tl {\__starray_get_root:w #1 . \q_nil \q_stop}
+
+ \__starray_if_valid:nTF { \l__starray_prefix_tl \l_tmpb_tl _def_prop}
+ {
+ \__starray_fix_terms:ee {\l_tmpb_tl}{\l_tmpb_tl}
+ }
+ {
+ \msg_warning:nnxxx {starray}{reference / invalid-starray}
+ {fixterms:1} {#1} {}
+ }
+ }
+
+
+
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \starray_def_struct
+%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \starray_def_struct:nn #1#2
+ {
+ \__starray_if_valid:nTF { \l__starray_prefix_tl #1 _def_prop}
+ {
+ \__starray_def_struct:nn {#1} {#2}
+ }
+ {
+ \msg_warning:nnxxx {starray}{reference / invalid-starray}
+ {addstruct:1} {#1} {cannot~add~structure:#2}
+ }
+ }
+
+\prg_new_conditional:Npnn \starray_def_struct:nn #1#2 {p, T, F, TF}
+ {
+ \__starray_if_valid:nTF { \l__starray_prefix_tl #1 _def_prop}
+ {
+ \__starray_def_struct:nn {#1} {#2}
+ \prg_return_true:
+ }
+ { \prg_return_false: }
+ }
+
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% adding prop/struct from keyval
+%%%%
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+
+\prg_new_conditional:Npnn \__starray_def_from_keyval_testdot_aux:w #1 . \q_nil { p, TF}
+ {
+ \str_compare:nNnTF {#1} = {struct}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+
+\prg_new_conditional:Npnn \__starray_def_from_keyval_testdot:w #1 . #2 \q_stop { TF}
+ {
+ \quark_if_nil:nTF {#2}
+ {
+ \prg_return_false:
+ } % no dot, OK
+ {
+ \__starray_def_from_keyval_testdot_aux:wTF #2
+ {
+ \tl_set:Ne \l__starray_tmpST_tl { #1 }
+ \prg_return_true:
+ } % dot struct, OK
+ {
+% \bool_gset_false:N \l__starray_rtn_bool
+ \prg_return_false:
+ } %% possible syntax ERR (dot, but no struct!)
+ }
+ }
+
+
+\cs_new:Npn \__starray_def_from_keyval_parse:nnn #1#2#3
+ {
+ \group_begin:
+ \__starray_def_from_keyval_testdot:wTF #2 . \q_nil \q_stop
+ {
+ \tl_set:ce {l__starray_tmp A _tl} {#1 . \l__starray_tmpST_tl}
+ \__starray_def_struct:ne {#1} {\l__starray_tmpST_tl}
+ \keyval_parse:nnn
+ {\__starray_def_from_keyval_parse:en {\tl_use:c {l__starray_tmp A _tl}}}
+ {\__starray_def_from_keyval_parse:enn {\tl_use:c {l__starray_tmp A _tl}}}
+ {#3}
+ }
+ {
+ \__starray_def_prop:nnn {#1} {#2} {#3}
+ }
+ \group_end:
+ }
+
+\cs_generate_variant:Nn \__starray_def_from_keyval_parse:nnn {enn}
+
+
+\cs_new:Npn \__starray_def_from_keyval_parse:nn #1#2
+ {
+ \__starray_def_prop:nnn {#1} {#2} {}
+ }
+
+\cs_generate_variant:Nn \__starray_def_from_keyval_parse:nn {en}
+
+
+
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \starray_def_from_keyval
+%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \starray_def_from_keyval:nn #1#2
+ {
+% \bool_set_true:N \l__starray_rtn_bool
+ \__starray_if_valid:nTF { \l__starray_prefix_tl #1 _def_prop}
+ {
+ \keyval_parse:nnn
+ {\__starray_def_from_keyval_parse:en {#1}}
+ {\__starray_def_from_keyval_parse:enn {#1}}
+ { #2 }
+ }
+ {
+ \msg_warning:nnxxx {starray}{reference / invalid-starray}
+ {addkeyval:1} {#1} {cannot~add:#2}
+ }
+ }
+
+\cs_generate_variant:Nn \starray_def_from_keyval:nn {ne , ee}
+
+
+\prg_new_conditional:Npnn \starray_def_from_keyval:nn #1#2 {p, T, F, TF}
+ {
+ \__starray_if_valid:nTF { \l__starray_prefix_tl #1 _def_prop}
+ {
+ \keyval_parse:nnn
+ {\__starray_def_from_keyval_parse:en {#1}}
+ {\__starray_def_from_keyval_parse:enn {#1}}
+ { #2 }
+ \prg_return_true:
+ }
+ { \prg_return_false: }
+ }
+
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% adding terms
+%%%%
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \__starray_new_term:nn #1#2
+ {
+ \int_gincr:N
+ {\prop_item:cn {\l__starray_prefix_tl #1 _base_prop} {cnt} }
+
+ \int_gset_eq:NN
+ {\prop_item:cn {\l__starray_prefix_tl #1 _base_prop} {iter} }
+ {\prop_item:cn {\l__starray_prefix_tl #1 _base_prop} {cnt} }
+
+
+ % idx_hash Update.
+ \prop_get:cnN {\l__starray_prefix_tl #1 _base_prop} {idx_hash} \l_tmpa_prop
+
+ \prop_put:Nee \l_tmpa_prop
+ { \int_use:N \prop_item:cn {\l__starray_prefix_tl #1 _base_prop} {cnt} }
+ { \int_to_Alph:e { \prop_item:cn {\l__starray_prefix_tl #1 _base_prop} {cnt} } }
+
+ \tl_if_blank:nF {#2}
+ {
+ \prop_put:Nee \l_tmpa_prop
+ { #2 }
+ { \int_to_Alph:e { \prop_item:cn {\l__starray_prefix_tl #1 _base_prop} {cnt} } }
+ }
+
+ \prop_gput:cnV {\l__starray_prefix_tl #1 _base_prop} {idx_hash} \l_tmpa_prop
+
+ % creating the 'new property list' (aka. term)
+ \tl_set:Ne \l_tmpa_tl
+ { \int_to_Alph:e { \prop_item:cn {\l__starray_prefix_tl #1 _base_prop} {cnt} } }
+
+ \prop_new:c
+ { \l__starray_prefix_tl #1 _ \l_tmpa_tl _term_prop }
+
+ \prop_get:cnN {\l__starray_prefix_tl #1 _base_prop} {def_ref} \l_tmpb_tl
+
+ \prop_get:cnN {\l__starray_prefix_tl \l_tmpb_tl _def_prop} {def} \l_tmpa_prop
+
+ \prop_gset_eq:cN { \l__starray_prefix_tl #1 _ \l_tmpa_tl _term_prop } \l_tmpa_prop
+
+ \prop_get:cnN {\l__starray_prefix_tl \l_tmpb_tl _def_prop} {@st_seq} \l_tmpa_seq
+
+% map over 'all sub-starrays parts of def_ref -> st_seq (those starting with a dot, @st_seq)
+ \seq_map_tokens:Nn
+ \l_tmpa_seq
+ {
+ \__starray_sub_base_new:nnn
+ { \l_tmpb_tl }{ #1 _ \l_tmpa_tl }
+ }
+ }
+
+
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \starray_new_term
+%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \starray_new_term:nn #1#2
+ {
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \__starray_new_term:nn
+ {\l__starray_parsed_ref_tl }
+ {#2}
+ }
+ {
+ \__starray_msg_dispatch:
+ \msg_warning:nnnn {starray}{syntax / term}{addterm:2}{#1}
+ }
+ }
+
+\prg_new_conditional:Npnn \starray_new_term:nn #1#2 {p, T, F, TF}
+ {
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \__starray_new_term:nn
+ {\l__starray_parsed_ref_tl }
+ {#2}
+ \prg_return_true:
+ }
+ { \prg_return_false: }
+ }
+
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% changing iterator value (recursing sub-structures)
+%%%%
+%%%% NOTE: since iterator change 'can' be just local, 'temp vars' are recursive aware.
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \__starray_incr_iter:n #1
+ {
+ \int_compare:nNnTF
+ {\prop_item:cn {\l__starray_prefix_tl #1 _base_prop} {iter}} <
+ {\prop_item:cn {\l__starray_prefix_tl #1 _base_prop} {cnt}}
+ {
+ \int_gincr:N { \prop_item:cn {\l__starray_prefix_tl #1 _base_prop} {iter} }
+ }
+ {
+ % TODO: should it be a potential 'warning' ???
+ \bool_set_false:N \l__starray_rtn_bool
+ }
+ }
+
+\prg_new_conditional:Npnn \__starray_set_iter:nn #1#2 {p , T , F , TF}
+ {
+ \int_compare:nNnTF {#1} > {\prop_item:cn {\l__starray_prefix_tl #2 _base_prop} {cnt}}
+ {
+ \int_gset_eq:NN
+ { \prop_item:cn {\l__starray_prefix_tl #2 _base_prop} {iter} }
+ { \prop_item:cn {\l__starray_prefix_tl #2 _base_prop} {cnt} }
+ \prg_return_false:
+ }
+ {
+ \int_gset:Nn
+ { \prop_item:cn {\l__starray_prefix_tl #2 _base_prop} {iter} }
+ { #1 }
+ \prg_return_true:
+ }
+ }
+
+\prg_generate_conditional_variant:Nnn \__starray_set_iter:nn {ne} {p , T , F , TF}
+
+\cs_new:Npn \__starray_set_sub_iter:nnn #1#2#3
+ {
+ \prop_get:cnN {\l__starray_prefix_tl #2#3 _base_prop} {idx_hash} \l_tmpa_prop
+
+ \prop_get:NecT \l_tmpa_prop
+ { \int_use:N \prop_item:cn {\l__starray_prefix_tl #2#3 _base_prop} {iter} }
+ { l__starray_tmp #1 A_tl }
+ {
+ \prop_get:cnN
+ {\l__starray_prefix_tl #2#3 _base_prop}
+ {def_ref}
+ \l_tmpa_tl
+
+ \prop_get:cnc
+ { \l__starray_prefix_tl \l_tmpa_tl _def_prop }
+ { @st_seq }
+ {l__starray_tmp #1 A_seq }
+
+ \seq_if_empty:cF {l__starray_tmp #1 A_seq }
+ {
+ \seq_map_variable:cNn
+ { l__starray_tmp #1 A_seq }
+ \l_tmpb_tl
+ {
+ \__starray_set_iter:neTF
+ { 1 }
+ { #2#3 _ \tl_use:c {l__starray_tmp #1 A_tl} . \l_tmpb_tl }
+ {}
+ {}
+
+ \__starray_set_sub_iter:nne
+ { #1 A }
+ { #2#3 _ \tl_use:c {l__starray_tmp #1 A_tl} . }
+ { \l_tmpb_tl }
+ }
+ }
+ }
+ }
+
+\cs_generate_variant:Nn \__starray_set_sub_iter:nnn {nne}
+
+
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \starray_set_iter
+%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \starray_set_iter:nn #1#2
+ {
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \int_compare:nNnTF {#2} < {1}
+ {
+ \__starray_set_iter:nnTF {1}{\l__starray_parsed_ref_tl}
+ {} {}
+ }
+ {
+ \__starray_set_iter:nnTF {#2}{\l__starray_parsed_ref_tl}
+ {} {}
+ }
+ \__starray_set_sub_iter:nnn {}{\l__starray_parsed_ref_tl}{}
+ }
+ {
+ \__starray_msg_dispatch:
+ \msg_warning:nnnn {starray} {syntax / iter} {iter:1} {#1}
+ } % returns nothing by default
+ }
+
+
+
+\prg_new_conditional:Npnn \starray_set_iter:nn #1#2 {p, T, F, TF}
+ {
+ \bool_set_true:N \l__starray_rtn_bool
+
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \int_compare:nNnTF {#2} < {1}
+ {
+ \bool_set_false:N \l__starray_rtn_bool
+ \__starray_set_iter:nnTF {1}{\l__starray_parsed_ref_tl}
+ {}
+ {}
+ }
+ {
+ \__starray_set_iter:nnTF {#2}{\l__starray_parsed_ref_tl}
+ {}
+ {\bool_set_false:N \l__starray_rtn_bool}
+ }
+ \__starray_set_sub_iter:nnn {}{\l__starray_parsed_ref_tl}{}
+ \bool_if:NTF \l__starray_rtn_bool
+ {\prg_return_true:}
+ {\prg_return_false:}
+ }
+ {
+ \seq_clear:N \l__starray_msg_seq
+ \prg_return_false:
+ }
+ }
+
+
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \starray_reset_iter
+%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \starray_reset_iter:n #1
+ {
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \__starray_set_iter:nnTF {1}{\l__starray_parsed_ref_tl} {}{}
+ \__starray_set_sub_iter:nnn {}{\l__starray_parsed_ref_tl}{}
+ }
+ {
+ \__starray_msg_dispatch:
+ \msg_warning:nnnn {starray} {syntax / iter} {iter:4} {#1}
+ } % returns nothing by default
+ }
+
+
+\prg_new_conditional:Npnn \starray_reset_iter:n #1 {p, T, F, TF}
+ {
+ \bool_set_true:N \l__starray_rtn_bool
+
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \__starray_set_iter:nnTF {1}{\l__starray_parsed_ref_tl} {}{\bool_set_false:N \l__starray_rtn_bool} %% TODO: verify logic !@!!
+ \__starray_set_sub_iter:nnn {}{\l__starray_parsed_ref_tl}{}
+ \bool_if:NTF \l__starray_rtn_bool
+ {\prg_return_true:}
+ {\prg_return_false:}
+ }
+ {
+ \seq_clear:N \l__starray_msg_seq
+ \prg_return_false:
+ }
+ }
+
+
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \starray_next_iter
+%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \starray_next_iter:n #1
+ {
+% \bool_set_true:N \l__starray_rtn_bool
+ \seq_clear:N \l__starray_msg_seq
+
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \__starray_incr_iter:n {\l__starray_parsed_ref_tl}
+ \__starray_set_sub_iter:nnn {}{\l__starray_parsed_ref_tl}{}
+ }
+ {
+ \__starray_msg_dispatch:
+% \bool_set_false:N \l__starray_rtn_bool
+ \msg_warning:nnnn {starray} {syntax / iter} {iter:5} {#1}
+ } % returns nothing by default
+ }
+
+
+
+\prg_new_conditional:Npnn \starray_next_iter:n #1 {p, T, F, TF}
+ {
+ \bool_set_true:N \l__starray_rtn_bool
+ \seq_clear:N \l__starray_msg_seq
+
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \__starray_incr_iter:n {\l__starray_parsed_ref_tl}
+ \__starray_set_sub_iter:nnn {}{\l__starray_parsed_ref_tl}{}
+ \bool_if:NTF \l__starray_rtn_bool
+ {\prg_return_true:}
+ {\prg_return_false:}
+ }
+ { \prg_return_false: }
+ }
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% set/get properties
+%%%%
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+
+\cs_new:Npn \__starray_get_prop:nn #1#2
+ {
+ \prop_item:cn {\l__starray_prefix_tl #1 _term_prop}{#2}
+ }
+
+\cs_generate_variant:Nn \__starray_get_prop:nn {ee}
+
+
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \starray_get_prop
+%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \starray_get_prop:nn #1#2
+ {
+ \__starray_parser:nnTF {\c__starray_idx_ending_bool}{#1}
+ {
+ \__starray_get_prop:ee {\l__starray_parsed_ref_tl}{#2}
+ }
+ {
+ \__starray_msg_dispatch:
+ \msg_warning:nnnn {starray} {syntax / prop} {get:1} {#1}
+ } % returns nothing by default
+ }
+
+\cs_new:Npn \starray_get_prop:nnN #1#2#3
+ {
+ \__starray_parser:nnTF {\c__starray_idx_ending_bool}{#1}
+ {
+ \prop_get:cnNF
+ {\l__starray_prefix_tl \l__starray_parsed_ref_tl _term_prop} {#2} #3
+ { \tl_set:Nn #3 {} }
+ }
+ {
+ \tl_set:Nn #3 {}
+ \__starray_msg_dispatch:
+ \msg_warning:nnnn {starray} {syntax / prop}
+ {get:1} {#1}
+ } % returns nothing by default
+ }
+
+
+\prg_new_conditional:Npnn \starray_get_prop:nnN #1#2#3 {p, T, F, TF}
+ {
+ \__starray_parser:nnTF {\c__starray_idx_ending_bool}{#1}
+ {
+ \prop_get:cnNTF
+ {\l__starray_prefix_tl \l__starray_parsed_ref_tl _term_prop} {#2} #3
+ {
+ \prg_return_true:
+ }
+ {
+ \tl_set:Nn #3 {}
+ \prg_return_false:
+ }
+ }
+ {
+ \tl_set:Nn #3 {}
+ \seq_clear:N \l__starray_msg_seq
+ \prg_return_false:
+ } % returns nothing by default
+ }
+
+
+\prg_new_conditional:Npnn \starray_if_in:nn #1#2 {p, T, F, TF}
+ {
+ \__starray_parser:nnTF {\c__starray_idx_ending_bool}{#1}
+ {
+ \prop_if_in:cnTF
+ {\l__starray_prefix_tl \l__starray_parsed_ref_tl _term_prop} {#2}
+ {
+ \prg_return_true:
+ }
+ {
+ \prg_return_false:
+ }
+ }
+ {
+ \seq_clear:N \l__starray_msg_seq
+ \prg_return_false:
+ } % returns nothing by default
+ }
+
+
+\cs_new:Npn \starray_get_cnt:n #1
+ {
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \int_use:N
+ \prop_item:cn { \l__starray_prefix_tl \l__starray_parsed_ref_tl _base_prop } {cnt}
+ }
+ {
+ \__starray_msg_dispatch:
+ \msg_warning:nnnn {starray} {syntax / prop} {get:XX} {#1}
+ } % returns nothing by default
+ }
+
+\cs_new:Npn \starray_get_cnt:nN #1#2
+ {
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \int_set_eq:NN
+ #2
+ \prop_item:cn { \l__starray_prefix_tl \l__starray_parsed_ref_tl _base_prop } {cnt}
+ }
+ {
+ \__starray_msg_dispatch:
+ \msg_warning:nnnn {starray} {syntax / prop}
+ {get:XX} {#1}
+ } % returns nothing by default
+ }
+
+\prg_new_conditional:Npnn \starray_get_cnt:nN #1#2 {p, T, F, TF}
+ {
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \int_set_eq:NN
+ #2
+ \prop_item:cn { \l__starray_prefix_tl \l__starray_parsed_ref_tl _base_prop } {cnt}
+ \prg_return_true:
+ }
+ {
+ \seq_clear:N \l__starray_msg_seq
+ \prg_return_false:
+ } % returns nothing by default
+ }
+
+\cs_new:Npn \starray_get_iter:n #1
+ {
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \int_use:N
+ \prop_item:cn { \l__starray_prefix_tl \l__starray_parsed_ref_tl _base_prop } {iter}
+ }
+ {
+ \__starray_msg_dispatch:
+ \msg_warning:nnnn {starray} {syntax / prop}
+ {get:XX} {#1}
+ } % returns nothing by default
+ }
+
+
+\cs_new:Npn \starray_get_iter:nN #1#2
+ {
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \int_set_eq:NN
+ #2
+ \prop_item:cn { \l__starray_prefix_tl \l__starray_parsed_ref_tl _base_prop } {iter}
+ }
+ {
+ \__starray_msg_dispatch:
+ \msg_warning:nnnn {starray} {syntax / prop}
+ {get:XX} {#1}
+ } % returns nothing by default
+ }
+
+\prg_new_conditional:Npnn \starray_get_iter:nN #1#2 {p, T, F, TF}
+ {
+ \__starray_parser:nnTF {\c__starray_no_idx_ending_bool}{#1}
+ {
+ \int_set_eq:NN
+ #2
+ \prop_item:cn { \l__starray_prefix_tl \l__starray_parsed_ref_tl _base_prop } {iter}
+ \prg_return_true:
+ }
+ {
+ \seq_clear:N \l__starray_msg_seq
+ \prg_return_false:
+ } % returns nothing by default
+ }
+
+
+
+
+
+\cs_new:Npn \__starray_set_prop:nnn #1#2#3
+ {
+ \l__starray_put_tl {\l__starray_prefix_tl #1 _term_prop}{#2}{#3}
+ }
+
+
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \starray_set_prop
+%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \starray_set_prop:nnn #1#2#3
+ {
+ \tl_set:Nn \l__starray_put_tl \prop_put:cnn
+ \__starray_parser:nnTF {\c__starray_idx_ending_bool}{#1}
+ {
+ \__starray_set_prop:nnn {\l__starray_parsed_ref_tl}{#2}{#3}
+ }
+ {
+ \__starray_msg_dispatch:
+ \msg_warning:nnnn {starray} {syntax / prop}
+ {set:1} {#1}
+ } % returns nothing by default
+ }
+
+\cs_generate_variant:Nn \starray_set_prop:nnn {nnV}
+
+\cs_new:Npn \starray_gset_prop:nnn #1#2#3
+ {
+ \tl_set:Nn \l__starray_put_tl \prop_gput:cnn
+ \__starray_parser:nnTF {\c__starray_idx_ending_bool}{#1}
+ {
+ \__starray_set_prop:nnn {\l__starray_parsed_ref_tl}{#2}{#3}
+ }
+ {
+ \__starray_msg_dispatch:
+ \msg_warning:nnnn {starray} {syntax / prop}
+ {set:1} {#1}
+ } % returns nothing by default
+ }
+
+\cs_generate_variant:Nn \starray_gset_prop:nnn {nnV}
+
+
+\prg_new_conditional:Npnn \starray_set_prop:nnn #1#2#3 {p, T, F, TF}
+ {
+ \tl_set:Nn \l__starray_put_tl \prop_put:cnn
+ \__starray_parser:nnTF {\c__starray_idx_ending_bool}{#1}
+ {
+ \__starray_set_prop:nnn {\l__starray_parsed_ref_tl}{#2}{#3}
+ \prg_return_true:
+ }
+ {
+ \seq_clear:N \l__starray_msg_seq
+ \prg_return_false:
+ }
+ }
+
+\prg_generate_conditional_variant:Nnn \starray_set_prop:nnn { nnV } { p , T, F , TF }
+
+\prg_new_conditional:Npnn \starray_gset_prop:nnn #1#2#3 {p, T, F, TF}
+ {
+ \tl_set:Nn \l__starray_put_tl \prop_gput:cnn
+ \__starray_parser:nnTF {\c__starray_idx_ending_bool}{#1}
+ {
+ \__starray_set_prop:nnn {\l__starray_parsed_ref_tl}{#2}{#3}
+ \prg_return_true:
+ }
+ {
+ \seq_clear:N \l__starray_msg_seq
+ \prg_return_false:
+ }
+ }
+
+
+\prg_generate_conditional_variant:Nnn \starray_gset_prop:nnn { nnV } { p , T, F , TF }
+
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% set/get properties (keyval)
+%%%%
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+
+\prg_new_conditional:Npnn \__starray_set_parse_end:w #1#2 ] #3 \q_stop { TF}
+ {
+ \quark_if_nil:nTF {#3}
+ { \prg_return_false: } %% syntax ERR
+ {
+ \tl_set:cn {l__starray_tmp #1 :A_tl} {#2}
+ \prg_return_true:
+ }
+ }
+
+
+\prg_new_conditional:Npnn \__starray_set_parse_aux:w #1#2 [ \q_nil \q_stop { TF}
+ {
+ \__starray_set_parse_end:wTF {#1}#2 ] \q_nil\q_stop
+ {\prg_return_true:}
+ {\prg_return_false:}
+ }
+
+
+\prg_new_conditional:Npnn \__starray_set_parse_begin:w #1#2 [ #3 \q_stop { TF}
+ {
+ \quark_if_nil:nTF {#3}
+ { % no 'term' ref, just array_name (current/iter term)
+ \tl_clear:c {l__starray_tmp #1 :A_tl}
+ \prg_return_true:
+ }
+ {
+ \tl_set:cn {l__starray_tmp #1 :B_tl}{#2}
+ \__starray_set_parse_aux:wTF {#1}#3 \q_stop
+ {\prg_return_true:}
+ {\prg_return_false:}
+ }
+ }
+
+
+
+\cs_new:Npn \__starray_set_from_keyval_parse:nnnn #1#2#3#4
+ {
+ \__starray_set_prop:nnn {#3}{#4}{}
+ }
+
+\cs_generate_variant:Nn \__starray_set_from_keyval_parse:nnnn {nnen}
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% set from keyval
+%%%%
+%%%% NOTE: tmp variables are recursive aware.
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+
+\cs_new:Npn \__starray_set_from_keyval_parse:nnnnn #1#2#3#4#5
+ {
+ \tl_clear:c {l__starray_tmp #1 _tl}
+ \__starray_set_parse_begin:wTF {#1}#4 [ \q_nil \q_stop
+ {
+ \tl_if_blank:eTF {\tl_use:c{l__starray_tmp #1 :A_tl}}
+ {
+ \prop_get:cnc
+ {\l__starray_prefix_tl #2 _def_prop}
+ {@st_seq}
+ {l__starray_tmp #1 _seq}
+
+ \seq_if_in:cnTF {l__starray_tmp #1 _seq}{#4}
+ {
+ \prop_get:cnc
+ { \l__starray_prefix_tl #3 .#4 _base_prop }
+ { idx_hash }
+ { l__starray_tmp #1 _hash_prop }
+ \prop_get:cnc
+ { \l__starray_prefix_tl #3 .#4 _base_prop }
+ { iter }
+ { l__starray_tmp #1 _int }
+ \int_compare:nNnTF {\int_use:c {l__starray_tmp #1 _int}} < {1}
+ {
+ \__starray_msg:nnnnn {reference / iter}
+ {setkeyval:2}{#2.#4}{-0-}{~(not~instantiated)}
+ % invalid iter / not instantiated
+ }
+ {
+ \tl_set:ce
+ { l__starray_tmp #1 _tl }
+ { #3.#4 _ \int_to_Alph:e {\int_use:c {l__starray_tmp #1 _int}} }
+ \keyval_parse:nnn
+ {
+ \__starray_set_from_keyval_parse:nnen
+ { #1 A }
+ { #2.#4 }
+ { \tl_use:c { l__starray_tmp #1 _tl } }
+ }
+ {
+ \__starray_set_from_keyval_parse:nnenn
+ { #1 A }
+ { #2.#4 }
+ { \tl_use:c { l__starray_tmp #1 _tl } }
+ }
+ { #5 }
+
+ }
+ }
+ {
+ \__starray_set_prop:nnn {#3}{#4}{#5}
+ }
+ }
+ {
+ \prop_get:cnc
+ { \l__starray_prefix_tl #2 _def_prop }
+ { @st_seq }
+ { l__starray_tmp #1 _seq }
+
+ \seq_if_in:ceTF
+ { l__starray_tmp #1 _seq } { \tl_use:c{l__starray_tmp #1 :B_tl} }
+ {
+ \prop_get:cnc
+ { \l__starray_prefix_tl #3. \tl_use:c{l__starray_tmp #1 :B_tl} _base_prop }
+ { idx_hash }
+ { l__starray_tmp #1 _hash_prop }
+ \tl_set:ce
+ { l__starray_tmp #1 _idx_tl }
+ {
+ #3 . \tl_use:c{l__starray_tmp #1 :B_tl} _
+ \prop_item:ce
+ { l__starray_tmp #1 _hash_prop }
+ { \tl_use:c{ l__starray_tmp #1 :A_tl } }
+ }
+ \tl_put_left:cn { l__starray_tmp #1 :B_tl } { #2 . }
+ \prop_if_in:ceTF
+ { l__starray_tmp #1 _hash_prop }
+ { \tl_use:c{l__starray_tmp #1 :A_tl}}
+ {
+ \keyval_parse:nnn
+ {
+ \__starray_set_from_keyval_parse:nnen
+ { #1 A }
+ { \tl_use:c{l__starray_tmp #1 :B_tl} }
+ { \tl_use:c { l__starray_tmp #1 _idx_tl } }
+ }
+ {
+ \__starray_set_from_keyval_parse:nnenn
+ { #1 A }
+ { \tl_use:c{l__starray_tmp #1 :B_tl} }
+ { \tl_use:c { l__starray_tmp #1 _idx_tl } }
+ }
+ { #5 }
+
+ }
+ {
+ \__starray_msg:nneee {reference / iter}
+ {setkeyval:3} {#2.#4} {\tl_use:c{l__starray_tmp #1 :A_tl}} {}
+ % invalid hash
+ }
+ }
+ {
+ \__starray_msg:nneee {syntax / structure-ref}
+ {setkeyval:4} {#2.#4} {\tl_use:c{l__starray_tmp #1 :B_tl}} {}
+ % invalid ref / not a substructure
+ }
+ }
+ }
+ {
+ \__starray_msg:nnnnn {syntax / term}
+ {setkeyval:5}{#4}{}{}
+ % invalid ref/syntax
+ }
+ }
+
+\cs_generate_variant:Nn \__starray_set_from_keyval_parse:nnnnn {nnenn}
+
+
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \starray_set_from_keyval
+%%%%
+%%%%%%%%%%%%%%%
+
+
+\cs_new:Npn \__starray_set_from_keyval:nn #1#2
+ {
+ \bool_set_true:N \l__starray_rtn_bool
+ \__starray_parser:nnTF {\c__starray_idx_ending_bool}{#1}
+ {
+ \keyval_parse:nnn
+ {\__starray_set_from_keyval_parse:nnen {A}{#1}{\l__starray_parsed_ref_tl}}
+ {\__starray_set_from_keyval_parse:nnenn {A}{#1}{\l__starray_parsed_ref_tl}}
+ { #2 }
+ \bool_if:NF \l__starray_rtn_bool
+ { \__starray_msg_dispatch: }
+ }
+ {
+ \__starray_msg_dispatch:
+ \msg_warning:nnnn {starray} {syntax / prop}
+ {setkeyval:1} {#1}
+ } % returns nothing by default
+ }
+
+
+\cs_new:Npn \starray_set_from_keyval:nn #1#2
+ {
+ \tl_set:Nn \l__starray_put_tl \prop_put:cnn
+ \__starray_set_from_keyval:nn {#1}{#2}
+ }
+
+\cs_new:Npn \starray_gset_from_keyval:nn #1#2
+ {
+ \tl_set:Nn \l__starray_put_tl \prop_gput:cnn
+ \__starray_set_from_keyval:nn {#1}{#2}
+ }
+
+
+\cs_new:Npn \__starray_set_from_keyvalTF:nn #1#2
+ {
+ \bool_set_true:N \l__starray_rtn_bool
+ \__starray_parser:nnTF {\c__starray_idx_ending_bool}{#1}
+ {
+ \keyval_parse:nnn
+ {\__starray_set_from_keyval_parse:nnen {A}{#1}{\l__starray_parsed_ref_tl}}
+ {\__starray_set_from_keyval_parse:nnenn {A}{#1}{\l__starray_parsed_ref_tl}}
+ { #2 }
+ \bool_if:NTF \l__starray_rtn_bool
+ {\prg_return_true:}
+ {\prg_return_false:}
+ }
+ { \prg_return_false: }
+ }
+
+\prg_new_conditional:Npnn \starray_set_from_keyval:nn #1#2 {p, T, F, TF}
+ {
+ \tl_set:Nn \l__starray_put_tl \prop_put:cnn
+ \__starray_set_from_keyvalTF:nn {#1}{#2}
+ }
+
+\prg_new_conditional:Npnn \starray_gset_from_keyval:nn #1#2 {p, T, F, TF}
+ {
+ \tl_set:Nn \l__starray_put_tl \prop_gput:cnn
+ \__starray_set_from_keyvalTF:nn {#1}{#2}
+ }
+
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% starray ref/address parser using quarks
+%%%% could be done with seq_split and regex but
+%%%% would have been even more cumbersome
+%%%%
+%%%% <starray_ref> := <array_ref> [ . <starray_ref> ]
+%%%% <array_ref> := <array_name> [ <term_ref> ]
+%%%% <term_ref> := \[ <number/hash> \]
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+\prg_new_conditional:Npnn \__starray_term_parse_end:w #1 ] #2 \q_stop { TF}
+ {
+ \quark_if_nil:nTF {#2}
+ { \prg_return_false: } %% syntax ERR
+ {
+ \tl_set:Nn \l__starray_parsed_idx_tl {#1}
+ \prg_return_true:
+ }
+ }
+
+
+\prg_new_conditional:Npnn \__starray_term_parse_aux:w #1 [ \q_nil \q_stop { TF}
+ {
+ \__starray_term_parse_end:wTF #1 ] \q_nil\q_stop
+ {\prg_return_true:}
+ {\prg_return_false:}
+ }
+
+
+\prg_new_conditional:Npnn \__starray_term_parse_begin:w #1 [ #2 \q_stop { TF}
+ {
+ \tl_set:Nn \l__starray_parsed_term_tl {#1}
+
+ \quark_if_nil:nTF {#2}
+ { % no 'term' ref, just array_name (current/iter term)
+ \tl_clear:N \l__starray_parsed_idx_tl
+ \prg_return_true:
+ }
+ {
+ \__starray_term_parse_aux:wTF #2 \q_stop
+ {\prg_return_true:}
+ {\prg_return_false:}
+ }
+ }
+
+
+% verify #2 before going for #1 . . .
+% if #2 isn't empty test for it return true/false
+% if #2 is empty, test if #1 is valid, return true/false
+\prg_new_conditional:Npnn \__starray_if_valid_idx:nn #1#2 {p, T, F, TF}
+ {
+ \prop_get:cnN {\l__starray_prefix_tl \l__starray_parsed_ref_tl _base_prop} {idx_hash} \l_tmpa_prop
+
+ \tl_if_blank:nTF {#2}
+ {
+ \tl_put_right:Ne \l__starray_parsed_ref_tl
+ { _ \prop_item:Ne \l_tmpa_prop {#1} }
+ }
+ {
+ \tl_put_right:Ne \l__starray_parsed_ref_tl
+ { _ \prop_item:Ne \l_tmpa_prop {#2} }
+ }
+
+ \prop_if_exist:cTF { \l__starray_prefix_tl \l__starray_parsed_ref_tl _term_prop }
+ {\prg_return_true:}
+ {\prg_return_false:}
+ }
+
+\prg_generate_conditional_variant:Nnn \__starray_if_valid_idx:nn {ee} {p, T, F, TF}
+
+\cs_new:Npn \__starray_ref_parse:w #1 . #2 \q_stop
+ {
+ \tl_put_right:Ne \l__starray_parsed_tl {#1}
+
+ \__starray_term_parse_begin:wTF #1 [ \q_nil \q_stop
+ { % syntax ok so far.
+ % TODO: verify instance validity hash/index
+ % vars: \l__starray_parsed_term_tl
+ % \l__starray_parsed_idx_tl
+ \tl_put_right:Ne \l__starray_parsed_ref_tl
+ { \l__starray_parser_aux_tl \l__starray_parsed_term_tl }
+ \tl_put_right:Ne \l__starray_parsed_base_ref_tl
+ { \l__starray_parser_aux_tl \l__starray_parsed_term_tl }
+ \tl_set:Nn \l__starray_parser_aux_tl { . }
+
+ \__starray_if_valid:eTF
+ {\l__starray_prefix_tl \l__starray_parsed_ref_tl _base_prop}
+ {
+ \quark_if_nil:nTF {#2}
+ { % this is the last one
+ \bool_if:NTF \l__starray_parser_no_idx_ending_bool
+ { % assuming it is to add a term...
+ \tl_if_empty:NTF \l__starray_parsed_idx_tl
+ { } % done. correct
+ {
+ \bool_set_false:N \l__starray_parser_OK_bool
+ \__starray_msg:nneee {syntax / ref-syntax-err} {parser:1}
+ {\l__starray_parsing_term_tl}
+ {invalid~index~\l__starray_parsed_idx_tl~(at~the~end)}
+ {}
+ } % err !
+ }
+ { % assuming it is to set/get a property
+ \__starray_if_valid_idx:eeTF
+ {
+ \int_use:N
+ \prop_item:cn
+ {\l__starray_prefix_tl \l__starray_parsed_ref_tl _base_prop}
+ {iter}
+ }
+ {
+ \l__starray_parsed_idx_tl
+ }
+ { } % done, finish, ok
+ {
+ \bool_set_false:N \l__starray_parser_OK_bool
+ \__starray_msg:nneee {syntax / ref-syntax-err} {parser:2}
+ {\l__starray_parsing_term_tl}
+ {invalid~index~\l__starray_parsed_idx_tl}
+ {}
+ }
+ }
+ }
+ {
+ \__starray_if_valid_idx:eeTF
+ {
+ \int_use:N
+ \prop_item:cn
+ {\l__starray_prefix_tl \l__starray_parsed_ref_tl _base_prop}
+ {iter}
+ }
+ {
+ \l__starray_parsed_idx_tl
+ }
+ {
+ \__starray_ref_parse:w #2 \q_stop
+ } % recurse next term
+ {
+ \bool_set_false:N \l__starray_parser_OK_bool
+ \__starray_msg:nneee {syntax / ref-syntax-err} {parser:3}
+ {\l__starray_parsing_term_tl}
+ {invalid~index~\l__starray_parsed_idx_tl}
+ {}
+ }
+ }
+ }
+ {
+ \bool_set_false:N \l__starray_parser_OK_bool
+ \__starray_msg:nneee {syntax / ref-syntax-err} {parser:4}
+ {\l__starray_parsing_term_tl}
+ {invalid~struct~\l__starray_parsed_ref_tl}
+ {}
+ } % invalid/ref err.
+ }
+ {
+ \bool_set_false:N \l__starray_parser_OK_bool
+ \__starray_msg:nneee {syntax / ref-syntax-err} {parser:5}
+ {\l__starray_parsing_term_tl}
+ {invalid~struct~#1~at~\l__starray_parsed_tl}
+ {}
+ } % syntax/ref err.
+ }
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% parser 'true' returns:
+%%%% \l__starray_parsed_ref_tl
+%%%% \l__starray_parsed_base_ref_tl
+%%%% \l__starray_parsed_root_ref_tl
+%%%% parser 'false' returns:
+%%%%
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+\prg_new_conditional:Npnn \__starray_parser:nn #1#2 {p, T, F, TF}
+ {
+ \bool_set_eq:NN \l__starray_parser_no_idx_ending_bool #1
+ \bool_set_true:N \l__starray_parser_OK_bool
+
+ \tl_clear:N \l__starray_parsed_tl
+ \tl_clear:N \l__starray_parsed_ref_tl
+ \tl_clear:N \l__starray_parsed_base_ref_tl
+ \tl_clear:N \l__starray_parsed_root_ref_tl
+
+ \tl_set:Nn \l__starray_parser_aux_tl {}
+
+ \tl_set:Nn \l__starray_parsing_term_tl {#2}
+
+ \__starray_ref_parse:w #2 .\q_nil\q_stop
+
+ \bool_if:NTF \l__starray_parser_OK_bool
+ {
+ \tl_set:Ne \l__starray_parsed_root_ref_tl
+ { \__starray_get_root:w \l__starray_parsed_base_ref_tl .\q_nil\q_stop }
+ \prg_return_true:
+ }
+ {
+ \prg_return_false:
+ }
+ }
+
+
+\prg_new_conditional:Npnn \starray_term_syntax:n #1 {p, T, F, TF}
+ {
+ \__starray_parser:nnTF {\c__starray_idx_ending_bool}{#1}
+ {\prg_return_true:}
+ {
+ \seq_clear:N \l__starray_msg_seq
+ \prg_return_false:
+ }
+ }
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \..show_def commands
+%%%%
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% Note to self:
+%%%% \l__starray_showcmd_tl could be an extra param as well
+%%%% (more tokens jungling around...)
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+
+\cs_new:Npn \__starray_show_def_item:nnn #1#2#3
+ {
+ \tl_gput_right:Nn \l__starray_tmpa_tl
+ {
+ \l__starray_showcmd_tl > #1 \use:nnn { ~ } { ~ } { ~ }
+ \tl_to_str:n { {#2} }
+ \use:nn { ~ } { ~ } => \use:nn { ~ } { ~ }
+ \tl_to_str:n { {#3} }
+ }
+ }
+
+\cs_new:Npn \__starray_show_def:nnn #1#2#3
+ {
+ \group_begin:
+ \tl_gput_right:Nn \l__starray_tmpa_tl
+ {
+ \l__starray_showcmd_tl > #1
+ \tl_to_str:n {{#3} ~ struct}
+ \use:nn { ~ } { ~ } =>
+ }
+
+ \prop_get:cnc
+ {\l__starray_prefix_tl #2#3 _def_prop}
+ {def}
+ {l__starray_tmp A _def_prop}
+
+ \prop_get:cnc
+ { \l__starray_prefix_tl #2#3 _def_prop }
+ { @st_seq }
+ {l__starray_tmp A _seq }
+
+ \prop_map_tokens:cn
+ {l__starray_tmp A _def_prop}
+ {\__starray_show_def_item:nnn {#1}}
+
+ \seq_if_empty:cF { l__starray_tmp A _seq }
+ {
+ \seq_map_tokens:cn
+ { l__starray_tmp A _seq }
+ { \__starray_show_def:nnn { #1 \use:nnn { ~ } { ~ } { ~ }} { #2#3. } }
+ }
+ \group_end:
+ }
+
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \starray_show_def
+%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \starray_show_def:n #1
+ {
+ \tl_clear:N \l__starray_tmpa_tl
+ \tl_set:Nn \l__starray_showcmd_tl \iow_newline:
+ \__starray_show_def:nnn {}{}{#1}
+
+ \msg_show:nnxxx {starray}{info / show}
+ { show~def }
+ { The~ starray~ <#1> ~is~defined~as~follow: }
+ { \tl_use:N \l__starray_tmpa_tl }
+ }
+
+\cs_new:Npn \starray_show_def_in_text:n #1
+ {
+ \tl_clear:N \l__starray_tmpa_tl
+ \tl_set:Nn \l__starray_showcmd_tl \par
+ \__starray_show_def:nnn {}{}{#1}
+
+ \tl_use:N \l__starray_tmpa_tl
+ }
+
+
+
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \..show_terms commands
+%%%%
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+%%%%
+%%%% Note to self:
+%%%% \l__starray_showcmd_tl could be an extra param as well
+%%%% (more tokens jungling around...)
+%%%%
+%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%
+
+
+\cs_new:Npn \__starray_show_term_item:nnnnn #1#2#3#4#5
+ {
+ \group_begin:
+ \tl_gput_right:Nn \l__starray_tmpa_tl
+ {
+ \l__starray_showcmd_tl > #1
+ \tl_to_str:n { {#3[#4]} ~ (idx: ~ #5)}
+ \use:nn { ~ } { ~ } =>
+ }
+
+ \prop_map_tokens:cn
+ {\l__starray_prefix_tl #2 #3 _ #5 _term_prop}
+ {\__starray_show_def_item:nnn {#1 }}
+
+ \prop_get:cnN
+ { \l__starray_prefix_tl #2 #3 _base_prop }
+ { def_ref }
+ \l_tmpa_tl
+
+ \prop_get:cnc
+ { \l__starray_prefix_tl \l_tmpa_tl _def_prop }
+ { @st_seq }
+ {l__starray_tmp A _seq }
+
+ \seq_if_empty:cTF { l__starray_tmp A _seq }
+ {}
+ {
+ \seq_map_tokens:cn
+ { l__starray_tmp A _seq }
+ { \__starray_show_terms:nen { #1 \use:nnn { ~ } { ~ } { ~ }} { #2 #3_#5. } }
+ }
+ \group_end:
+ }
+
+
+
+\cs_new:Npn \__starray_show_terms:nnn #1#2#3
+ {
+ \group_begin:
+ \prop_get:cnc
+ {\l__starray_prefix_tl #2 #3 _base_prop}
+ {idx_hash}
+ {l__starray_tmp A _idx_prop}
+
+ \prop_map_tokens:cn
+ {l__starray_tmp A _idx_prop}
+ {\__starray_show_term_item:nnnnn {#1}{#2}{#3}}
+ \group_end:
+ }
+
+\cs_generate_variant:Nn \__starray_show_terms:nnn {nen}
+
+%%%%%%%%%%%%%%%
+%%%%
+%%%% \starray_show_terms
+%%%%
+%%%%%%%%%%%%%%%
+
+\cs_new:Npn \starray_show_terms:n #1
+ {
+ \tl_clear:N \l__starray_tmpa_tl
+ \tl_set:Nn \l__starray_showcmd_tl \iow_newline:
+ \__starray_show_terms:nnn {}{}{#1}
+
+ \msg_show:nnxxx {starray}{info / show}
+ { show~terms }
+ { The~ starray~ <#1> ~has~the~following~terms: }
+ { \tl_use:N \l__starray_tmpa_tl }
+ }
+
+\cs_new:Npn \starray_show_terms_in_text:n #1
+ {
+ \tl_clear:N \l__starray_tmpa_tl
+ \tl_set:Nn \l__starray_showcmd_tl \par
+ \__starray_show_terms:nnn {}{}{#1}
+
+ \tl_use:N \l__starray_tmpa_tl
+ }
+
+
diff --git a/macros/latex/contrib/unicode-math-input/DEPENDS.txt b/macros/latex/contrib/unicode-math-input/DEPENDS.txt
new file mode 100644
index 0000000000..030077db7c
--- /dev/null
+++ b/macros/latex/contrib/unicode-math-input/DEPENDS.txt
@@ -0,0 +1,3 @@
+expl3
+iftex
+l3keys2e
diff --git a/macros/latex/contrib/unicode-math-input/README b/macros/latex/contrib/unicode-math-input/README
new file mode 100644
index 0000000000..5533cf6261
--- /dev/null
+++ b/macros/latex/contrib/unicode-math-input/README
@@ -0,0 +1,24 @@
+unicode-math-input -- Allow entering Unicode symbols in math formulas
+Allow entering Unicode symbols in math formulas.
+
+Released under the LaTeX Project Public License v1.3c or later
+See http://www.latex-project.org/lppl.txt
+
+Report bugs at https://github.com/user202729/TeXlib
+
+========
+
+Copyright 2022-2023 user202729
+
+This work may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this license or
+(at your option) any later version. The latest version of this license is in
+the file:
+
+ http://www.latex-project.org/lppl.txt
+
+This work has the LPPL maintenance status `maintained'.
+
+The Current Maintainer of this work is user202729.
+
+This work consists of the files unicode-math-input.sty, unicode-math-input-script.py, unicode-math-input-table.tex.
diff --git a/macros/latex/contrib/unicode-math-input/unicode-math-input-script.py b/macros/latex/contrib/unicode-math-input/unicode-math-input-script.py
new file mode 100644
index 0000000000..a3dbbb4625
--- /dev/null
+++ b/macros/latex/contrib/unicode-math-input/unicode-math-input-script.py
@@ -0,0 +1,591 @@
+#!/bin/python3
+# This file is not used while TeX is running. It's for generating unicode-math-input-table.tex file only.
+# This requires pythonimmediate (not sure which version is compatible but commit 63f94476a5cb11e33db1215a9bf7c17657d9773d on Python 3.10.10 is)
+
+from __future__ import annotations
+
+from pythonimmediate.engine import ChildProcessEngine
+from pythonimmediate.engine import default_engine
+from pythonimmediate import*
+import pythonimmediate
+from collections import defaultdict
+import os
+import json
+import subprocess
+import re
+import sys
+import unicodedata
+import functools
+from dataclasses import dataclass
+
+# ========
+
+print(r'% This file is automatically generated from unicode-math-input-script.py.')
+
+
+
+# ======== start a luatex engine
+engine=ChildProcessEngine("luatex", env={**os.environ, "hash_extra": "0"})
+# https://tex.stackexchange.com/questions/574607/tex-hashtokens-incomplete
+default_engine.set_engine(engine)
+
+Catcode.active("a").meaning_str()
+
+
+"""
+from the TeXbook:
+
+(INITEX starts out with
+\mathcode x = x for all characters x that are neither letters nor digits. The ten digits
+have \mathcode x = x+"7000; the 52 letters have \mathcode x = x+"7100.)
+"""
+# ======== reset all mathcode to 0
+TokenList([r"\directlua", TokenList.fstr(
+r"""
+for i=0, 0x10ffff do
+ tex.setmathcode(i, {0, 0, 0})
+end
+"""
+)]).execute()
+
+# ======== load unicode-math
+execute(r'''
+\documentclass{article}
+\usepackage{unicode-math}
+\begin{document}
+''')
+
+# ======== print changed mathcodes (we aim to support all of these)
+changed_mathcodes = TokenList([r"\directlua", TokenList.fstr(
+r"""
+for i=0, 0x10ffff do
+ local cls, family, pos=table.unpack(tex.getmathcode(i))
+ if not (
+ --(cls==0 and family==0 and pos==i) or (cls==7 and family==1 and pos==i)
+ (cls==0 and family==0 and pos==0)
+ ) then
+ tex.print(-2, i .. ":"..utf8.char(i)..":" .. cls..' '..family..' '..pos .. "\n")
+ end
+end
+"""
+)]).expand_x().str()
+
+changed_chars: set[str] = set()
+for line in changed_mathcodes.splitlines():
+ match = re.fullmatch(r'(\d+):(.):(\d+) (\d+) (\d+)', line)
+ assert match
+ unicode_char = match[2]
+ assert match[2]==chr(int(match[1])), match
+ if match[3]=="8" and match[4]=="0" and match[5]=="0":
+ code = Umathcode.active
+ else:
+ code = Umathcode(int(match[4]), MathClass.lookup(int(match[3])), int(match[5]))
+ changed_chars.add(unicode_char)
+
+# ======== parse the unicode math table
+
+path = subprocess.run(["kpsewhich", "unicode-math-table.tex"], stdout=subprocess.PIPE).stdout
+lines = Path(path.decode('u8').strip('\n')).read_text().splitlines()
+lines = [line for line in lines if line and not line.startswith("%")]
+unicode_math_table_=defaultdict(list)
+for line in lines:
+ match = re.fullmatch(r'\\UnicodeMathSymbol{"(.*)}{\\(.*?) *}{\\math(.*)}{(.*)}%', line)
+ assert match
+ unicode_char=chr(int(match[1], 16))
+ csname=match[2]
+ #unicode_math_table_.append(Item(unicode_char=unicode_char, csname=csname))
+ unicode_math_table_[unicode_char].append(csname)
+unicode_math_table={unicode_char: tuple(csnames) for unicode_char, csnames in unicode_math_table_.items()}
+
+# ======== check how much of the table is valid on unicode-math/luatex
+
+def getdelcode(x: str)->tuple[int, int, int, int]:
+ return tuple(map(int, TokenList([r"\directlua", TokenList.fstr( # type: ignore
+ r"""
+ for _, v in ipairs(tex.getdelcode(""" + str(ord(x)) + r""")) do tex.sprint(v..",") end
+ """
+ )]).expand_x().str().rstrip(",").split(",")))
+
+@functools.lru_cache(maxsize=None)
+def meaning(csname: str)->str:
+ return T[csname].meaning_str()
+
+@functools.lru_cache(maxsize=None)
+def good_delimiter(meaning: str, ch: str)->bool:
+ math = umathcode[ch]
+ o = ord(ch)
+ if math.family!=0 or math.position!=o: return False
+ a, b, c, d = getdelcode(ch)
+ if a!=0 or b!=o or c!=0 or d!=0: return False
+ other = f'\\protected macro:->\\Udelimiter {math.cls.value}\\symoperators "{o:05X}\\scan_stop: '
+ return meaning==other
+
+specially_handled = {
+ match[1] for match in
+ re.finditer(r'\\__umi_special_handle{(.)}', Path("unicode-math-input.sty").read_text())
+ }
+
+not_handled = {*"⎴⎵⏜⏝⏞⏟⟌\u03a2\U0001d455"}
+
+math_alphabet_translate = {
+ "mup" : None,
+ "mbf" : "umiMathbf",
+ "mit" : "umiMathit",
+ "mbfit" : "umiMathbfit", # https://tex.stackexchange.com/questions/14395/bold-italic-vectors
+ "mscr" : "umiMathscr",
+ "mbfscr" : "umiMathbfscr", # https://tex.stackexchange.com/questions/23455/latex-calligraphic-script-bold
+ "mfrak" : "umiMathfrak",
+ "Bbb" : "umiMathbb",
+ "mitBbb" : "umiMathbbit", # https://tex.stackexchange.com/questions/16645/blackboard-italic-font
+ "mbffrak" : "umiMathbffrak", # https://tex.stackexchange.com/questions/610696/may-i-have-bold-mathfraktur
+ "msans" : "umiMathsf",
+ "mbfsans" : "umiMathsfbf", # https://tex.stackexchange.com/questions/340097/bold-sans-serif-math-font
+ "mitsans" : "umiMathsfit",
+ "mbfitsans": "umiMathsfbfit",
+ "mtt" : "umiMathtt",
+ }
+math_alphabet_translate = dict(sorted(math_alphabet_translate.items(), key=lambda x: -len(x[0]))) # match against longest prefix first
+math_alphabet_csname_translation = {
+ "alpha": r"\alpha",
+ "Alpha": r"\Alpha",
+ "beta": r"\beta",
+ "Beta": r"\Beta",
+ "chi": r"\chi",
+ "Chi": r"\Chi",
+ "delta": r"\delta",
+ "Delta": r"\Delta",
+ "digamma": r"\digamma",
+ "Digamma": r"\Digamma",
+ "epsilon": r"\epsilon",
+ "Epsilon": r"\Epsilon",
+ "eta": r"\eta",
+ "Eta": r"\Eta",
+ "gamma": r"\gamma",
+ "Gamma": r"\Gamma",
+ "iota": r"\iota",
+ "Iota": r"\Iota",
+ "kappa": r"\kappa",
+ "Kappa": r"\Kappa",
+ "lambda": r"\lambda",
+ "Lambda": r"\Lambda",
+ "mu": r"\mu",
+ "Mu": r"\Mu",
+ "nabla": r"\nabla",
+ "nu": r"\nu",
+ "Nu": r"\Nu",
+ "omega": r"\omega",
+ "Omega": r"\Omega",
+ "omicron": r"\omicron",
+ "Omicron": r"\Omicron",
+ "partial": r"\partial",
+ "phi": r"\phi",
+ "Phi": r"\Phi",
+ "pi": r"\pi",
+ "Pi": r"\Pi",
+ "psi": r"\psi",
+ "Psi": r"\Psi",
+ "rho": r"\rho",
+ "Rho": r"\Rho",
+ "sigma": r"\sigma",
+ "Sigma": r"\Sigma",
+ "sum": r"\sum",
+ "tau": r"\tau",
+ "Tau": r"\Tau",
+ "theta": r"\theta",
+ "Theta": r"\Theta",
+ "upsilon": r"\upsilon",
+ "Upsilon": r"\Upsilon",
+ "varepsilon": r"\varepsilon",
+ "varkappa": r"\varkappa",
+ "varphi": r"\varphi",
+ "varpi": r"\varpi",
+ "varrho": r"\varrho",
+ "varsigma": r"\varsigma",
+ "vartheta": r"\vartheta",
+ "varTheta": r"\varTheta",
+ "xi": r"\xi",
+ "Xi": r"\Xi",
+ "zeta": r"\zeta",
+ "Zeta": r"\Zeta",
+ "a": "a",
+ "A": "A",
+ "b": "b",
+ "B": "B",
+ "c": "c",
+ "C": "C",
+ "d": "d",
+ "D": "D",
+ "e": "e",
+ "E": "E",
+ "f": "f",
+ "F": "F",
+ "g": "g",
+ "G": "G",
+ "h": "h",
+ "H": "H",
+ "i": "i",
+ "I": "I",
+ "j": "j",
+ "J": "J",
+ "k": "k",
+ "K": "K",
+ "l": "l",
+ "L": "L",
+ "m": "m",
+ "M": "M",
+ "n": "n",
+ "N": "N",
+ "o": "o",
+ "O": "O",
+ "p": "p",
+ "P": "P",
+ "q": "q",
+ "Q": "Q",
+ "r": "r",
+ "R": "R",
+ "s": "s",
+ "S": "S",
+ "t": "t",
+ "T": "T",
+ "u": "u",
+ "U": "U",
+ "v": "v",
+ "V": "V",
+ "w": "w",
+ "W": "W",
+ "x": "x",
+ "X": "X",
+ "y": "y",
+ "Y": "Y",
+ "z": "z",
+ "Z": "Z",
+ "zero" : "0",
+ "one" : "1",
+ "two" : "2",
+ "three": "3",
+ "four" : "4",
+ "five" : "5",
+ "six" : "6",
+ "seven": "7",
+ "eight": "8",
+ "nine" : "9",
+ }
+
+math_alphabet_redundant_greek = {
+ r"\Alpha" : "A",
+ r"\Beta" : "B",
+ r"\Chi" : "X",
+ r"\Digamma": "F",
+ r"\Epsilon": "E",
+ r"\Eta" : "H",
+ r"\Iota" : "I",
+ r"\Kappa" : "K",
+ r"\Mu" : "M",
+ r"\Nu" : "N",
+ r"\omicron": "o",
+ r"\Omicron": "O",
+ r"\Rho" : "P",
+ r"\Tau" : "T",
+ r"\Zeta" : "Z",
+ }
+
+extra_synonyms = {v: u for u in
+ [
+ ["adots", "iddots"]
+ ]
+ for v in u}
+
+##
+
+remaining_chars = changed_chars - {*unicode_math_table} - specially_handled - not_handled
+remaining_chars = {x for x in remaining_chars if ord(x) >= 0x80}
+
+for i in range(ord("!"), ord("~")+1):
+ fullch=chr(0xff00+i-0x20)
+ assert unicodedata.name(fullch) == "FULLWIDTH " + unicodedata.name(chr(i))
+ if fullch in remaining_chars: remaining_chars.remove(fullch)
+ print(r'\__umi_define_char{' + fullch + r'}{\char'+str(i)+' }')
+
+defined_csnames = {x for l in unicode_math_table.values() for x in l}
+
+
+pdf_engine=ChildProcessEngine("pdftex")
+execute(r"""
+\documentclass{article}
+\usepackage{amsmath}
+\usepackage{amssymb}
+\usepackage{amsfonts}
+\usepackage{mathrsfs}
+\begin{document}
+""", engine=pdf_engine)
+
+for unicode_char, csnames_ in unicode_math_table.items():
+ csnames = [*csnames_]
+ if unicodedata.combining(unicode_char) != 0:
+ if 0:
+ print(
+ repr(unicode_char),
+ f"U+{ord(unicode_char):04X}",
+ unicodedata.name(unicode_char),
+ "mathcode: ", umathcode[unicode_char],
+ {csname: meaning(csname) for csname in csnames},
+ f" -- good: {good}" if good else ""
+ )
+ for csname in csnames:
+ assert "Umathaccent" in meaning(csname), (unicode_char, unicodedata.name(unicode_char), csname, meaning(csname))
+ continue # don't support combining characters
+
+ is_combining2="COMBINING" in unicodedata.name(unicode_char).split()
+ if is_combining2:
+ for csname in csnames:
+ assert csname in "enclosecircle enclosesquare enclosediamond enclosetriangle".split(), (unicode_char, csname)
+ assert len(csnames)==1
+
+ optional_space=" " if is_combining2 else ""
+
+ if ord(unicode_char) <= 0x7f: continue
+ if unicode_char in specially_handled or unicode_char in not_handled: continue
+ #
+ bad_or_delimiter = [csname for csname in csnames if meaning(csname) != "the character " + unicode_char]
+ delimiter = [csname for csname in bad_or_delimiter if good_delimiter(meaning(csname), unicode_char)]
+ bad = [*{*bad_or_delimiter} - {*delimiter}]
+ is_delimiter = delimiter or getdelcode(unicode_char)!=(-1, 0, 0, 0)
+ # in unicode-math:
+ # the situation with ⟨/langle and ↑/uparrow is different
+ # in both cases the character gets assigned mathcode and delcode so \left⟨ and \left↑ both work
+ # in langle case the macro is defined to be \protected macro:->\Udelimiter 4\symoperators "027E8\scan_stop:
+ # this is because of @@_set_math_open logic which sets the macro like that
+ # (I don't know why it doesn't just do the thing below)
+ # in uparrow case the macro is defined to be "the character ↑"
+ # then delcode is assigned in @@_assign_delcode manually
+ if bad:
+ good = [*set(csnames) - set(bad)]
+ print(
+ repr(unicode_char),
+ f"U+{ord(unicode_char):04X}",
+ unicodedata.name(unicode_char),
+ "mathcode: ", umathcode[unicode_char],
+ "bad: ", {csname: meaning(csname) for csname in bad},
+ f" -- good: {good}" if good else ""
+ )
+ assert False, "please specially handle this"
+ else:
+ csnames = [*csnames_]
+ for csname in [*csnames]:
+ if csname in extra_synonyms:
+ csnames+=extra_synonyms[csname]
+ csnames=[*set(csnames)]
+
+ items1=[]
+ for csname in csnames:
+ if not is_delimiter:
+ assert "delimiter" not in T[csname].meaning_str(engine=pdf_engine), (unicode_char, csname)
+ # that is the symbol is not a delimiter in pdf_engine either (check is not particularly reliable but okay)
+
+ for prefix, replacement in math_alphabet_translate.items():
+ if csname.startswith(prefix):
+ cs = math_alphabet_csname_translation[csname.removeprefix(prefix)]
+ def wrap_in_alphabet_selector(cs: str)->str:
+ if replacement is None: return cs
+ return "\\" + replacement + "{" + cs + "}"
+
+ if cs in math_alphabet_redundant_greek:
+ items1.append(wrap_in_alphabet_selector(
+ "\\__umi_alternatives_iisafe" + cs + ("" if math_alphabet_redundant_greek[cs].startswith("\\") else " ") + math_alphabet_redundant_greek[cs]
+ ))
+ else:
+ items1.append(wrap_in_alphabet_selector(cs))
+ break
+ else:
+ items1.append("\\" + csname)
+
+ if len(items1)==1:
+ a = items1[0]
+ if a.startswith(r"\not") and a.removeprefix(r"\not") in defined_csnames:
+ assert not is_delimiter
+ b='\\' + a.removeprefix(r"\not")
+ print(f"\\__umi_define_char{{{optional_space}{unicode_char}}}{{\__umi_alternatives_not{a}{b}}}")
+ a.removeprefix(r"\not")
+ elif a.startswith(r"\n") and a.removeprefix(r"\n") in defined_csnames:
+ assert not is_delimiter
+ b='\\' + a.removeprefix(r"\n")
+ print(f"\\__umi_define_char{{{optional_space}{unicode_char}}}{{\__umi_alternatives_not{a}{b}}}")
+ a.removeprefix(r"\n")
+ else:
+ if is_delimiter:
+ print(f"\\__umi_define_char_maybe_delimiter{{{optional_space}{unicode_char}}}{{{a}}}")
+ else:
+ print(f"\\__umi_define_char{{{optional_space}{unicode_char}}}{{{a}}}")
+ else:
+ assert not is_delimiter, (unicode_char, delimiter)
+ assert len(items1)==2, items1
+ assert re.fullmatch(r'\\[a-zA-Z]+', items1[0]), items1
+ assert re.fullmatch(r'\\[a-zA-Z]+', items1[1]), items1
+ print(f"\\__umi_define_char{{{optional_space}{unicode_char}}}{{\\__umi_alternatives{items1[0]}{items1[1]}}}")
+
+##
+
+# ========
+
+sys.exit()
+
+# ======== part below are draft.
+
+T.longdivisionsign.meaning_str()
+
+
+
+T.mathexclam.meaning_str()
+
+T.symoperators.meaning_str()
+
+T.perp.meaning_str()
+
+umathcode[" ̅"[1]]
+
+BalancedTokenList(r'\the\Udelcode `̅').expand_o().int()
+
+x = BalancedTokenList(r'\the\Udelcode `!').expand_o().int()
+print(hex(x))
+
+hex(BalancedTokenList(r'\the\delcode `!').expand_o().int())
+
+
+
+
+
+if 0:
+
+ data = TokenList([r"\directlua", TokenList.fstr(
+ r"""
+ for k, v in pairs(tex.hashtokens()) do
+ tex.print(-2, v .. "\0")
+ end
+ """
+ )]).expand_x().str()
+ control_sequences = data.split("\x00")
+ assert control_sequences[-1]==""
+ del control_sequences[-1]
+
+
+Path("/tmp/control_sequences.json").write_text(json.dumps(control_sequences)) # type: ignore
+control_sequences = json.loads(Path("/tmp/control_sequences.json").read_text()) # type: ignore
+
+
+Path("/tmp/control_sequences_unicode_math.json").write_text(json.dumps(control_sequences))
+control_sequences = json.loads(Path("/tmp/control_sequences_unicode_math.json").read_text())
+assert "mitrho" in control_sequences
+
+if 0:
+ # try some other random things
+
+ control_sequences = data.split("\x00")
+ assert control_sequences[-1]==""
+ del control_sequences[-1]
+
+
+
+ BalancedTokenList(r'\the\Umathcode `′').expand_o().int() == 0x1000000
+
+
+control_sequences
+
+BalancedTokenList(r'\the\mathcode`⨁').expand_o().int()
+
+Catcode.active("⨁").meaning_str(engine=engine)
+
+Catcode.active("′").meaning_str(engine=engine)
+
+T.bigoplus_sym.meaning_str()
+
+T.bigoplusop.meaning_str()
+
+T.bigoplus.meaning_str()
+
+
+
+T.rho.meaning_str()
+
+T.mitrho.meaning_str()
+
+T.bigoplus.meaning_str()
+
+engine._stdout_lines[-100:] + [bytes(engine._stdout_buffer)]
+
+
+
+T.mscrA.meaning_str()
+
+
+
+
+
+
+@functools.lru_cache(maxsize=None)
+def is_defined(csname: str)->bool:
+ return T[csname].meaning_str()!="undefined"
+
+
+# show distinct items with math alphabet
+a_=defaultdict(list)
+for l in unicode_math_table.values():
+ for csname in l:
+ if csname.startswith(tuple(math_alphabet_translate)):
+ t = csname
+ for prefix in sorted(math_alphabet_translate, key=len, reverse=True):
+ if t.startswith(prefix):
+ t=t.removeprefix(prefix)
+ break
+ a_[t].append(csname)
+a_
+
+a_.keys()
+
+for v in math_alphabet_csname_translation.values():
+ if v.startswith("\\") and not is_defined(v[1:]):
+ print(v)
+
+
+
+
+
+
+def is_okay(csname: str)->bool:
+ if is_defined(csname): return True
+ if csname.startswith(tuple(math_alphabet_translate)): return True
+ return False
+#
+# print bad ones
+for unicode_char, csnames_ in unicode_math_table.items():
+ if ord(unicode_char) >= 0x80 and all( not is_okay(csname) for csname in csnames_ ):
+ print(unicode_char, csnames_)
+
+
+# print okay ones
+for unicode_char, csnames_ in unicode_math_table.items():
+ valid_csnames = [ csname for csname in csnames_ if T[csname].meaning_str()!="undefined" ]
+ if ord(unicode_char) >= 0x80 and valid_csnames:
+ print(unicode_char, valid_csnames)
+
+T.lsime.meaning_str()
+
+"ℝ".encode('u8')
+
+BalancedTokenList([T.meaning, Catcode.active("\xe2")]).expand_x(engine=pdf_engine)
+
+T["UTFviii@three@octets"].meaning_str(engine=pdf_engine)
+
+T["UTFviii@three@octets@combine"].meaning_str(engine=pdf_engine)
+
+T["UTF@three@octets@noexpand"].meaning_str(engine=pdf_engine)
+
+BalancedTokenList([T.meaning, Catcode.active("\xe2")]).expand_x()
+
+test_engine=ChildProcessEngine("pdftex")
+BalancedTokenList(r"\def\aa{bb}").execute(engine=test_engine)
+BalancedTokenList(r"\csname\noexpand\aa\endcsname").expand_o(engine=test_engine) # give error
+BalancedTokenList(r"\csname\string\aa\endcsname").expand_o(engine=test_engine) # \[\aa] as expected
+
+T.iddots.meaning_str(engine=engine)
+
+T.adots.meaning_str(engine=engine)
diff --git a/macros/latex/contrib/unicode-math-input/unicode-math-input-table.tex b/macros/latex/contrib/unicode-math-input/unicode-math-input-table.tex
new file mode 100644
index 0000000000..7ab364cedd
--- /dev/null
+++ b/macros/latex/contrib/unicode-math-input/unicode-math-input-table.tex
@@ -0,0 +1,2453 @@
+% This file is automatically generated from unicode-math-input-script.py.
+\__umi_define_char{!}{\char33 }
+\__umi_define_char{"}{\char34 }
+\__umi_define_char{#}{\char35 }
+\__umi_define_char{$}{\char36 }
+\__umi_define_char{%}{\char37 }
+\__umi_define_char{&}{\char38 }
+\__umi_define_char{'}{\char39 }
+\__umi_define_char{(}{\char40 }
+\__umi_define_char{)}{\char41 }
+\__umi_define_char{*}{\char42 }
+\__umi_define_char{+}{\char43 }
+\__umi_define_char{,}{\char44 }
+\__umi_define_char{-}{\char45 }
+\__umi_define_char{.}{\char46 }
+\__umi_define_char{/}{\char47 }
+\__umi_define_char{0}{\char48 }
+\__umi_define_char{1}{\char49 }
+\__umi_define_char{2}{\char50 }
+\__umi_define_char{3}{\char51 }
+\__umi_define_char{4}{\char52 }
+\__umi_define_char{5}{\char53 }
+\__umi_define_char{6}{\char54 }
+\__umi_define_char{7}{\char55 }
+\__umi_define_char{8}{\char56 }
+\__umi_define_char{9}{\char57 }
+\__umi_define_char{:}{\char58 }
+\__umi_define_char{;}{\char59 }
+\__umi_define_char{<}{\char60 }
+\__umi_define_char{=}{\char61 }
+\__umi_define_char{>}{\char62 }
+\__umi_define_char{?}{\char63 }
+\__umi_define_char{@}{\char64 }
+\__umi_define_char{A}{\char65 }
+\__umi_define_char{B}{\char66 }
+\__umi_define_char{C}{\char67 }
+\__umi_define_char{D}{\char68 }
+\__umi_define_char{E}{\char69 }
+\__umi_define_char{F}{\char70 }
+\__umi_define_char{G}{\char71 }
+\__umi_define_char{H}{\char72 }
+\__umi_define_char{I}{\char73 }
+\__umi_define_char{J}{\char74 }
+\__umi_define_char{K}{\char75 }
+\__umi_define_char{L}{\char76 }
+\__umi_define_char{M}{\char77 }
+\__umi_define_char{N}{\char78 }
+\__umi_define_char{O}{\char79 }
+\__umi_define_char{P}{\char80 }
+\__umi_define_char{Q}{\char81 }
+\__umi_define_char{R}{\char82 }
+\__umi_define_char{S}{\char83 }
+\__umi_define_char{T}{\char84 }
+\__umi_define_char{U}{\char85 }
+\__umi_define_char{V}{\char86 }
+\__umi_define_char{W}{\char87 }
+\__umi_define_char{X}{\char88 }
+\__umi_define_char{Y}{\char89 }
+\__umi_define_char{Z}{\char90 }
+\__umi_define_char{[}{\char91 }
+\__umi_define_char{\}{\char92 }
+\__umi_define_char{]}{\char93 }
+\__umi_define_char{^}{\char94 }
+\__umi_define_char{_}{\char95 }
+\__umi_define_char{`}{\char96 }
+\__umi_define_char{a}{\char97 }
+\__umi_define_char{b}{\char98 }
+\__umi_define_char{c}{\char99 }
+\__umi_define_char{d}{\char100 }
+\__umi_define_char{e}{\char101 }
+\__umi_define_char{f}{\char102 }
+\__umi_define_char{g}{\char103 }
+\__umi_define_char{h}{\char104 }
+\__umi_define_char{i}{\char105 }
+\__umi_define_char{j}{\char106 }
+\__umi_define_char{k}{\char107 }
+\__umi_define_char{l}{\char108 }
+\__umi_define_char{m}{\char109 }
+\__umi_define_char{n}{\char110 }
+\__umi_define_char{o}{\char111 }
+\__umi_define_char{p}{\char112 }
+\__umi_define_char{q}{\char113 }
+\__umi_define_char{r}{\char114 }
+\__umi_define_char{s}{\char115 }
+\__umi_define_char{t}{\char116 }
+\__umi_define_char{u}{\char117 }
+\__umi_define_char{v}{\char118 }
+\__umi_define_char{w}{\char119 }
+\__umi_define_char{x}{\char120 }
+\__umi_define_char{y}{\char121 }
+\__umi_define_char{z}{\char122 }
+\__umi_define_char{{}{\char123 }
+\__umi_define_char{|}{\char124 }
+\__umi_define_char{}}{\char125 }
+\__umi_define_char{~}{\char126 }
+\__umi_define_char{£}{\mathsterling}
+\__umi_define_char{¥}{\mathyen}
+\__umi_define_char{§}{\mathsection}
+\__umi_define_char{¬}{\neg}
+\__umi_define_char{±}{\pm}
+\__umi_define_char{¶}{\mathparagraph}
+\__umi_define_char{·}{\cdotp}
+\__umi_define_char{×}{\times}
+\__umi_define_char{ð}{\matheth}
+\__umi_define_char{÷}{\div}
+\__umi_define_char{Ƶ}{\Zbar}
+\__umi_define_char{Α}{\__umi_alternatives_iisafe\Alpha A}
+\__umi_define_char{Β}{\__umi_alternatives_iisafe\Beta B}
+\__umi_define_char{Γ}{\Gamma}
+\__umi_define_char{Δ}{\Delta}
+\__umi_define_char{Ε}{\__umi_alternatives_iisafe\Epsilon E}
+\__umi_define_char{Ζ}{\__umi_alternatives_iisafe\Zeta Z}
+\__umi_define_char{Η}{\__umi_alternatives_iisafe\Eta H}
+\__umi_define_char{Θ}{\Theta}
+\__umi_define_char{Ι}{\__umi_alternatives_iisafe\Iota I}
+\__umi_define_char{Κ}{\__umi_alternatives_iisafe\Kappa K}
+\__umi_define_char{Λ}{\Lambda}
+\__umi_define_char{Μ}{\__umi_alternatives_iisafe\Mu M}
+\__umi_define_char{Ν}{\__umi_alternatives_iisafe\Nu N}
+\__umi_define_char{Ξ}{\Xi}
+\__umi_define_char{Ο}{\__umi_alternatives_iisafe\Omicron O}
+\__umi_define_char{Π}{\Pi}
+\__umi_define_char{Ρ}{\__umi_alternatives_iisafe\Rho P}
+\__umi_define_char{Σ}{\Sigma}
+\__umi_define_char{Τ}{\__umi_alternatives_iisafe\Tau T}
+\__umi_define_char{Υ}{\Upsilon}
+\__umi_define_char{Φ}{\Phi}
+\__umi_define_char{Χ}{\__umi_alternatives_iisafe\Chi X}
+\__umi_define_char{Ψ}{\Psi}
+\__umi_define_char{Ω}{\Omega}
+\__umi_define_char{α}{\alpha}
+\__umi_define_char{β}{\beta}
+\__umi_define_char{γ}{\gamma}
+\__umi_define_char{δ}{\delta}
+\__umi_define_char{ε}{\varepsilon}
+\__umi_define_char{ζ}{\zeta}
+\__umi_define_char{η}{\eta}
+\__umi_define_char{θ}{\theta}
+\__umi_define_char{ι}{\iota}
+\__umi_define_char{κ}{\kappa}
+\__umi_define_char{λ}{\lambda}
+\__umi_define_char{μ}{\mu}
+\__umi_define_char{ν}{\nu}
+\__umi_define_char{ξ}{\xi}
+\__umi_define_char{ο}{\__umi_alternatives_iisafe\omicron o}
+\__umi_define_char{π}{\pi}
+\__umi_define_char{ρ}{\rho}
+\__umi_define_char{ς}{\varsigma}
+\__umi_define_char{σ}{\sigma}
+\__umi_define_char{τ}{\tau}
+\__umi_define_char{υ}{\upsilon}
+\__umi_define_char{φ}{\varphi}
+\__umi_define_char{χ}{\chi}
+\__umi_define_char{ψ}{\psi}
+\__umi_define_char{ω}{\omega}
+\__umi_define_char{ϑ}{\vartheta}
+\__umi_define_char{ϕ}{\phi}
+\__umi_define_char{ϖ}{\varpi}
+\__umi_define_char{Ϝ}{\upDigamma}
+\__umi_define_char{ϝ}{\updigamma}
+\__umi_define_char{ϰ}{\varkappa}
+\__umi_define_char{ϱ}{\varrho}
+\__umi_define_char{ϴ}{\varTheta}
+\__umi_define_char{ϵ}{\epsilon}
+\__umi_define_char{϶}{\upbackepsilon}
+\__umi_define_char{‐}{\mathhyphen}
+\__umi_define_char{―}{\horizbar}
+\__umi_define_char_maybe_delimiter{‖}{\Vert}
+\__umi_define_char{‗}{\twolowline}
+\__umi_define_char{†}{\dagger}
+\__umi_define_char{‡}{\ddagger}
+\__umi_define_char{•}{\smblkcircle}
+\__umi_define_char{‥}{\enleadertwodots}
+\__umi_define_char{…}{\unicodeellipsis}
+\__umi_define_char{‸}{\caretinsert}
+\__umi_define_char{‼}{\Exclam}
+\__umi_define_char{⁀}{\tieconcat}
+\__umi_define_char{⁃}{\hyphenbullet}
+\__umi_define_char_maybe_delimiter{⁄}{\fracslash}
+\__umi_define_char{⁇}{\Question}
+\__umi_define_char{⁐}{\closure}
+\__umi_define_char{€}{\euro}
+\__umi_define_char{ ⃝}{\enclosecircle}
+\__umi_define_char{ ⃞}{\enclosesquare}
+\__umi_define_char{ ⃟}{\enclosediamond}
+\__umi_define_char{ ⃤}{\enclosetriangle}
+\__umi_define_char{ℂ}{\umiMathbb{C}}
+\__umi_define_char{ℇ}{\Eulerconst}
+\__umi_define_char{ℊ}{\umiMathscr{g}}
+\__umi_define_char{ℋ}{\umiMathscr{H}}
+\__umi_define_char{ℌ}{\umiMathfrak{H}}
+\__umi_define_char{ℍ}{\umiMathbb{H}}
+\__umi_define_char{ℎ}{\Planckconst}
+\__umi_define_char{ℏ}{\hslash}
+\__umi_define_char{ℐ}{\umiMathscr{I}}
+\__umi_define_char{ℑ}{\Im}
+\__umi_define_char{ℒ}{\umiMathscr{L}}
+\__umi_define_char{ℓ}{\ell}
+\__umi_define_char{ℕ}{\umiMathbb{N}}
+\__umi_define_char{℘}{\wp}
+\__umi_define_char{ℙ}{\umiMathbb{P}}
+\__umi_define_char{ℚ}{\umiMathbb{Q}}
+\__umi_define_char{ℛ}{\umiMathscr{R}}
+\__umi_define_char{ℜ}{\Re}
+\__umi_define_char{ℝ}{\umiMathbb{R}}
+\__umi_define_char{ℤ}{\umiMathbb{Z}}
+\__umi_define_char{℧}{\mho}
+\__umi_define_char{ℨ}{\umiMathfrak{Z}}
+\__umi_define_char{℩}{\turnediota}
+\__umi_define_char{Å}{\Angstrom}
+\__umi_define_char{ℬ}{\umiMathscr{B}}
+\__umi_define_char{ℭ}{\umiMathfrak{C}}
+\__umi_define_char{ℯ}{\umiMathscr{e}}
+\__umi_define_char{ℰ}{\umiMathscr{E}}
+\__umi_define_char{ℱ}{\umiMathscr{F}}
+\__umi_define_char{Ⅎ}{\Finv}
+\__umi_define_char{ℳ}{\umiMathscr{M}}
+\__umi_define_char{ℴ}{\umiMathscr{o}}
+\__umi_define_char{ℵ}{\aleph}
+\__umi_define_char{ℶ}{\beth}
+\__umi_define_char{ℷ}{\gimel}
+\__umi_define_char{ℸ}{\daleth}
+\__umi_define_char{ℼ}{\umiMathbb{\pi}}
+\__umi_define_char{ℽ}{\umiMathbb{\gamma}}
+\__umi_define_char{ℾ}{\umiMathbb{\Gamma}}
+\__umi_define_char{ℿ}{\umiMathbb{\Pi}}
+\__umi_define_char{⅀}{\umiMathbb{\sum}}
+\__umi_define_char{⅁}{\Game}
+\__umi_define_char{⅂}{\sansLturned}
+\__umi_define_char{⅃}{\sansLmirrored}
+\__umi_define_char{⅄}{\Yup}
+\__umi_define_char{ⅅ}{\umiMathbbit{D}}
+\__umi_define_char{ⅆ}{\umiMathbbit{d}}
+\__umi_define_char{ⅇ}{\umiMathbbit{e}}
+\__umi_define_char{ⅈ}{\umiMathbbit{i}}
+\__umi_define_char{ⅉ}{\umiMathbbit{j}}
+\__umi_define_char{⅊}{\PropertyLine}
+\__umi_define_char{⅋}{\upand}
+\__umi_define_char{←}{\leftarrow}
+\__umi_define_char_maybe_delimiter{↑}{\uparrow}
+\__umi_define_char{→}{\rightarrow}
+\__umi_define_char_maybe_delimiter{↓}{\downarrow}
+\__umi_define_char{↔}{\leftrightarrow}
+\__umi_define_char_maybe_delimiter{↕}{\updownarrow}
+\__umi_define_char{↖}{\nwarrow}
+\__umi_define_char{↗}{\nearrow}
+\__umi_define_char{↘}{\searrow}
+\__umi_define_char{↙}{\swarrow}
+\__umi_define_char{↚}{\__umi_alternatives_not\nleftarrow\leftarrow}
+\__umi_define_char{↛}{\__umi_alternatives_not\nrightarrow\rightarrow}
+\__umi_define_char{↜}{\leftwavearrow}
+\__umi_define_char{↝}{\rightwavearrow}
+\__umi_define_char{↞}{\twoheadleftarrow}
+\__umi_define_char_maybe_delimiter{↟}{\twoheaduparrow}
+\__umi_define_char{↠}{\twoheadrightarrow}
+\__umi_define_char_maybe_delimiter{↡}{\twoheaddownarrow}
+\__umi_define_char{↢}{\leftarrowtail}
+\__umi_define_char{↣}{\rightarrowtail}
+\__umi_define_char{↤}{\mapsfrom}
+\__umi_define_char_maybe_delimiter{↥}{\mapsup}
+\__umi_define_char{↦}{\mapsto}
+\__umi_define_char_maybe_delimiter{↧}{\mapsdown}
+\__umi_define_char_maybe_delimiter{↨}{\updownarrowbar}
+\__umi_define_char{↩}{\hookleftarrow}
+\__umi_define_char{↪}{\hookrightarrow}
+\__umi_define_char{↫}{\looparrowleft}
+\__umi_define_char{↬}{\looparrowright}
+\__umi_define_char{↭}{\leftrightsquigarrow}
+\__umi_define_char{↮}{\__umi_alternatives_not\nleftrightarrow\leftrightarrow}
+\__umi_define_char{↯}{\downzigzagarrow}
+\__umi_define_char{↰}{\Lsh}
+\__umi_define_char{↱}{\Rsh}
+\__umi_define_char{↲}{\Ldsh}
+\__umi_define_char{↳}{\Rdsh}
+\__umi_define_char{↴}{\linefeed}
+\__umi_define_char{↵}{\carriagereturn}
+\__umi_define_char{↶}{\curvearrowleft}
+\__umi_define_char{↷}{\curvearrowright}
+\__umi_define_char{↸}{\barovernorthwestarrow}
+\__umi_define_char{↹}{\barleftarrowrightarrowbar}
+\__umi_define_char{↺}{\acwopencirclearrow}
+\__umi_define_char{↻}{\cwopencirclearrow}
+\__umi_define_char{↼}{\leftharpoonup}
+\__umi_define_char{↽}{\leftharpoondown}
+\__umi_define_char_maybe_delimiter{↾}{\upharpoonright}
+\__umi_define_char_maybe_delimiter{↿}{\upharpoonleft}
+\__umi_define_char{⇀}{\rightharpoonup}
+\__umi_define_char{⇁}{\rightharpoondown}
+\__umi_define_char_maybe_delimiter{⇂}{\downharpoonright}
+\__umi_define_char_maybe_delimiter{⇃}{\downharpoonleft}
+\__umi_define_char{⇄}{\rightleftarrows}
+\__umi_define_char_maybe_delimiter{⇅}{\updownarrows}
+\__umi_define_char{⇆}{\leftrightarrows}
+\__umi_define_char{⇇}{\leftleftarrows}
+\__umi_define_char_maybe_delimiter{⇈}{\upuparrows}
+\__umi_define_char{⇉}{\rightrightarrows}
+\__umi_define_char_maybe_delimiter{⇊}{\downdownarrows}
+\__umi_define_char{⇋}{\leftrightharpoons}
+\__umi_define_char{⇌}{\rightleftharpoons}
+\__umi_define_char{⇍}{\__umi_alternatives_not\nLeftarrow\Leftarrow}
+\__umi_define_char{⇎}{\__umi_alternatives_not\nLeftrightarrow\Leftrightarrow}
+\__umi_define_char{⇏}{\__umi_alternatives_not\nRightarrow\Rightarrow}
+\__umi_define_char{⇐}{\Leftarrow}
+\__umi_define_char_maybe_delimiter{⇑}{\Uparrow}
+\__umi_define_char{⇒}{\Rightarrow}
+\__umi_define_char_maybe_delimiter{⇓}{\Downarrow}
+\__umi_define_char{⇔}{\Leftrightarrow}
+\__umi_define_char_maybe_delimiter{⇕}{\Updownarrow}
+\__umi_define_char{⇖}{\Nwarrow}
+\__umi_define_char{⇗}{\Nearrow}
+\__umi_define_char{⇘}{\Searrow}
+\__umi_define_char{⇙}{\Swarrow}
+\__umi_define_char{⇚}{\Lleftarrow}
+\__umi_define_char{⇛}{\Rrightarrow}
+\__umi_define_char{⇜}{\leftsquigarrow}
+\__umi_define_char{⇝}{\rightsquigarrow}
+\__umi_define_char_maybe_delimiter{⇞}{\nHuparrow}
+\__umi_define_char_maybe_delimiter{⇟}{\nHdownarrow}
+\__umi_define_char{⇠}{\leftdasharrow}
+\__umi_define_char_maybe_delimiter{⇡}{\updasharrow}
+\__umi_define_char{⇢}{\rightdasharrow}
+\__umi_define_char_maybe_delimiter{⇣}{\downdasharrow}
+\__umi_define_char{⇤}{\barleftarrow}
+\__umi_define_char{⇥}{\rightarrowbar}
+\__umi_define_char{⇦}{\leftwhitearrow}
+\__umi_define_char_maybe_delimiter{⇧}{\upwhitearrow}
+\__umi_define_char{⇨}{\rightwhitearrow}
+\__umi_define_char_maybe_delimiter{⇩}{\downwhitearrow}
+\__umi_define_char_maybe_delimiter{⇪}{\whitearrowupfrombar}
+\__umi_define_char{⇴}{\circleonrightarrow}
+\__umi_define_char_maybe_delimiter{⇵}{\downuparrows}
+\__umi_define_char{⇶}{\rightthreearrows}
+\__umi_define_char{⇷}{\nvleftarrow}
+\__umi_define_char{⇸}{\nvrightarrow}
+\__umi_define_char{⇹}{\nvleftrightarrow}
+\__umi_define_char{⇺}{\nVleftarrow}
+\__umi_define_char{⇻}{\nVrightarrow}
+\__umi_define_char{⇼}{\nVleftrightarrow}
+\__umi_define_char{⇽}{\leftarrowtriangle}
+\__umi_define_char{⇾}{\rightarrowtriangle}
+\__umi_define_char{⇿}{\leftrightarrowtriangle}
+\__umi_define_char{∀}{\forall}
+\__umi_define_char{∁}{\complement}
+\__umi_define_char{∂}{\partial}
+\__umi_define_char{∃}{\exists}
+\__umi_define_char{∄}{\__umi_alternatives_not\nexists\exists}
+\__umi_define_char{∅}{\varnothing}
+\__umi_define_char{∆}{\increment}
+\__umi_define_char{∇}{\nabla}
+\__umi_define_char{∈}{\in}
+\__umi_define_char{∉}{\__umi_alternatives_not\notin\in}
+\__umi_define_char{∊}{\smallin}
+\__umi_define_char{∋}{\ni}
+\__umi_define_char{∌}{\__umi_alternatives_not\nni\ni}
+\__umi_define_char{∍}{\smallni}
+\__umi_define_char{∎}{\QED}
+\__umi_define_char{∏}{\prod}
+\__umi_define_char{∐}{\coprod}
+\__umi_define_char{∑}{\sum}
+\__umi_define_char{−}{\minus}
+\__umi_define_char{∓}{\mp}
+\__umi_define_char{∔}{\dotplus}
+\__umi_define_char_maybe_delimiter{∕}{\divslash}
+\__umi_define_char{∖}{\smallsetminus}
+\__umi_define_char{∗}{\ast}
+\__umi_define_char{∘}{\vysmwhtcircle}
+\__umi_define_char{∙}{\vysmblkcircle}
+\__umi_define_char{∝}{\propto}
+\__umi_define_char{∞}{\infty}
+\__umi_define_char{∟}{\rightangle}
+\__umi_define_char{∠}{\angle}
+\__umi_define_char{∡}{\measuredangle}
+\__umi_define_char{∢}{\sphericalangle}
+\__umi_define_char{∣}{\mid}
+\__umi_define_char{∤}{\__umi_alternatives_not\nmid\mid}
+\__umi_define_char{∥}{\parallel}
+\__umi_define_char{∦}{\__umi_alternatives_not\nparallel\parallel}
+\__umi_define_char{∧}{\wedge}
+\__umi_define_char{∨}{\vee}
+\__umi_define_char{∩}{\cap}
+\__umi_define_char{∪}{\cup}
+\__umi_define_char{∫}{\int}
+\__umi_define_char{∬}{\iint}
+\__umi_define_char{∭}{\iiint}
+\__umi_define_char{∮}{\oint}
+\__umi_define_char{∯}{\oiint}
+\__umi_define_char{∰}{\oiiint}
+\__umi_define_char{∱}{\intclockwise}
+\__umi_define_char{∲}{\varointclockwise}
+\__umi_define_char{∳}{\ointctrclockwise}
+\__umi_define_char{∴}{\therefore}
+\__umi_define_char{∵}{\because}
+\__umi_define_char{∶}{\mathratio}
+\__umi_define_char{∷}{\Colon}
+\__umi_define_char{∸}{\dotminus}
+\__umi_define_char{∹}{\dashcolon}
+\__umi_define_char{∺}{\dotsminusdots}
+\__umi_define_char{∻}{\kernelcontraction}
+\__umi_define_char{∼}{\sim}
+\__umi_define_char{∽}{\backsim}
+\__umi_define_char{∾}{\invlazys}
+\__umi_define_char{∿}{\sinewave}
+\__umi_define_char{≀}{\wr}
+\__umi_define_char{≁}{\__umi_alternatives_not\nsim\sim}
+\__umi_define_char{≂}{\eqsim}
+\__umi_define_char{≃}{\__umi_alternatives\simeq\sime}
+\__umi_define_char{≄}{\__umi_alternatives\nsimeq\nsime}
+\__umi_define_char{≅}{\cong}
+\__umi_define_char{≆}{\simneqq}
+\__umi_define_char{≇}{\__umi_alternatives_not\ncong\cong}
+\__umi_define_char{≈}{\approx}
+\__umi_define_char{≉}{\__umi_alternatives_not\napprox\approx}
+\__umi_define_char{≊}{\approxeq}
+\__umi_define_char{≋}{\approxident}
+\__umi_define_char{≌}{\backcong}
+\__umi_define_char{≍}{\asymp}
+\__umi_define_char{≎}{\Bumpeq}
+\__umi_define_char{≏}{\bumpeq}
+\__umi_define_char{≐}{\doteq}
+\__umi_define_char{≑}{\Doteq}
+\__umi_define_char{≒}{\fallingdotseq}
+\__umi_define_char{≓}{\risingdotseq}
+\__umi_define_char{≔}{\coloneq}
+\__umi_define_char{≕}{\eqcolon}
+\__umi_define_char{≖}{\eqcirc}
+\__umi_define_char{≗}{\circeq}
+\__umi_define_char{≘}{\arceq}
+\__umi_define_char{≙}{\wedgeq}
+\__umi_define_char{≚}{\veeeq}
+\__umi_define_char{≛}{\stareq}
+\__umi_define_char{≜}{\triangleq}
+\__umi_define_char{≝}{\eqdef}
+\__umi_define_char{≞}{\measeq}
+\__umi_define_char{≟}{\questeq}
+\__umi_define_char{≠}{\ne}
+\__umi_define_char{≡}{\equiv}
+\__umi_define_char{≢}{\__umi_alternatives_not\nequiv\equiv}
+\__umi_define_char{≣}{\Equiv}
+\__umi_define_char{≤}{\leq}
+\__umi_define_char{≥}{\geq}
+\__umi_define_char{≦}{\leqq}
+\__umi_define_char{≧}{\geqq}
+\__umi_define_char{≨}{\lneqq}
+\__umi_define_char{≩}{\gneqq}
+\__umi_define_char{≪}{\ll}
+\__umi_define_char{≫}{\gg}
+\__umi_define_char{≬}{\between}
+\__umi_define_char{≭}{\__umi_alternatives_not\nasymp\asymp}
+\__umi_define_char{≮}{\__umi_alternatives_not\nless\less}
+\__umi_define_char{≯}{\ngtr}
+\__umi_define_char{≰}{\__umi_alternatives_not\nleq\leq}
+\__umi_define_char{≱}{\__umi_alternatives_not\ngeq\geq}
+\__umi_define_char{≲}{\lesssim}
+\__umi_define_char{≳}{\gtrsim}
+\__umi_define_char{≴}{\__umi_alternatives_not\nlesssim\lesssim}
+\__umi_define_char{≵}{\__umi_alternatives_not\ngtrsim\gtrsim}
+\__umi_define_char{≶}{\lessgtr}
+\__umi_define_char{≷}{\gtrless}
+\__umi_define_char{≸}{\__umi_alternatives_not\nlessgtr\lessgtr}
+\__umi_define_char{≹}{\__umi_alternatives_not\ngtrless\gtrless}
+\__umi_define_char{≺}{\prec}
+\__umi_define_char{≻}{\succ}
+\__umi_define_char{≼}{\preccurlyeq}
+\__umi_define_char{≽}{\succcurlyeq}
+\__umi_define_char{≾}{\precsim}
+\__umi_define_char{≿}{\succsim}
+\__umi_define_char{⊀}{\__umi_alternatives_not\nprec\prec}
+\__umi_define_char{⊁}{\__umi_alternatives_not\nsucc\succ}
+\__umi_define_char{⊂}{\subset}
+\__umi_define_char{⊃}{\supset}
+\__umi_define_char{⊄}{\__umi_alternatives_not\nsubset\subset}
+\__umi_define_char{⊅}{\__umi_alternatives_not\nsupset\supset}
+\__umi_define_char{⊆}{\subseteq}
+\__umi_define_char{⊇}{\supseteq}
+\__umi_define_char{⊈}{\__umi_alternatives_not\nsubseteq\subseteq}
+\__umi_define_char{⊉}{\__umi_alternatives_not\nsupseteq\supseteq}
+\__umi_define_char{⊊}{\subsetneq}
+\__umi_define_char{⊋}{\supsetneq}
+\__umi_define_char{⊌}{\cupleftarrow}
+\__umi_define_char{⊍}{\cupdot}
+\__umi_define_char{⊎}{\uplus}
+\__umi_define_char{⊏}{\sqsubset}
+\__umi_define_char{⊐}{\sqsupset}
+\__umi_define_char{⊑}{\sqsubseteq}
+\__umi_define_char{⊒}{\sqsupseteq}
+\__umi_define_char{⊓}{\sqcap}
+\__umi_define_char{⊔}{\sqcup}
+\__umi_define_char{⊕}{\oplus}
+\__umi_define_char{⊖}{\ominus}
+\__umi_define_char{⊗}{\otimes}
+\__umi_define_char{⊘}{\oslash}
+\__umi_define_char{⊙}{\odot}
+\__umi_define_char{⊚}{\circledcirc}
+\__umi_define_char{⊛}{\circledast}
+\__umi_define_char{⊜}{\circledequal}
+\__umi_define_char{⊝}{\circleddash}
+\__umi_define_char{⊞}{\boxplus}
+\__umi_define_char{⊟}{\boxminus}
+\__umi_define_char{⊠}{\boxtimes}
+\__umi_define_char{⊡}{\boxdot}
+\__umi_define_char{⊢}{\vdash}
+\__umi_define_char{⊣}{\dashv}
+\__umi_define_char{⊤}{\top}
+\__umi_define_char{⊥}{\bot}
+\__umi_define_char{⊦}{\assert}
+\__umi_define_char{⊧}{\models}
+\__umi_define_char{⊨}{\vDash}
+\__umi_define_char{⊩}{\Vdash}
+\__umi_define_char{⊪}{\Vvdash}
+\__umi_define_char{⊫}{\VDash}
+\__umi_define_char{⊬}{\__umi_alternatives_not\nvdash\vdash}
+\__umi_define_char{⊭}{\__umi_alternatives_not\nvDash\vDash}
+\__umi_define_char{⊮}{\__umi_alternatives_not\nVdash\Vdash}
+\__umi_define_char{⊯}{\__umi_alternatives_not\nVDash\VDash}
+\__umi_define_char{⊰}{\prurel}
+\__umi_define_char{⊱}{\scurel}
+\__umi_define_char{⊲}{\vartriangleleft}
+\__umi_define_char{⊳}{\vartriangleright}
+\__umi_define_char{⊴}{\trianglelefteq}
+\__umi_define_char{⊵}{\trianglerighteq}
+\__umi_define_char{⊶}{\origof}
+\__umi_define_char{⊷}{\imageof}
+\__umi_define_char{⊸}{\multimap}
+\__umi_define_char{⊹}{\hermitmatrix}
+\__umi_define_char{⊺}{\intercal}
+\__umi_define_char{⊻}{\veebar}
+\__umi_define_char{⊼}{\barwedge}
+\__umi_define_char{⊽}{\barvee}
+\__umi_define_char{⊾}{\measuredrightangle}
+\__umi_define_char{⊿}{\varlrtriangle}
+\__umi_define_char{⋀}{\bigwedge}
+\__umi_define_char{⋁}{\bigvee}
+\__umi_define_char{⋂}{\bigcap}
+\__umi_define_char{⋃}{\bigcup}
+\__umi_define_char{⋄}{\smwhtdiamond}
+\__umi_define_char{⋅}{\cdot}
+\__umi_define_char{⋆}{\star}
+\__umi_define_char{⋇}{\divideontimes}
+\__umi_define_char{⋈}{\bowtie}
+\__umi_define_char{⋉}{\ltimes}
+\__umi_define_char{⋊}{\rtimes}
+\__umi_define_char{⋋}{\leftthreetimes}
+\__umi_define_char{⋌}{\rightthreetimes}
+\__umi_define_char{⋍}{\backsimeq}
+\__umi_define_char{⋎}{\curlyvee}
+\__umi_define_char{⋏}{\curlywedge}
+\__umi_define_char{⋐}{\Subset}
+\__umi_define_char{⋑}{\Supset}
+\__umi_define_char{⋒}{\Cap}
+\__umi_define_char{⋓}{\Cup}
+\__umi_define_char{⋔}{\pitchfork}
+\__umi_define_char{⋕}{\equalparallel}
+\__umi_define_char{⋖}{\lessdot}
+\__umi_define_char{⋗}{\gtrdot}
+\__umi_define_char{⋘}{\lll}
+\__umi_define_char{⋙}{\ggg}
+\__umi_define_char{⋚}{\lesseqgtr}
+\__umi_define_char{⋛}{\gtreqless}
+\__umi_define_char{⋜}{\eqless}
+\__umi_define_char{⋝}{\eqgtr}
+\__umi_define_char{⋞}{\curlyeqprec}
+\__umi_define_char{⋟}{\curlyeqsucc}
+\__umi_define_char{⋠}{\__umi_alternatives_not\npreccurlyeq\preccurlyeq}
+\__umi_define_char{⋡}{\__umi_alternatives_not\nsucccurlyeq\succcurlyeq}
+\__umi_define_char{⋢}{\__umi_alternatives_not\nsqsubseteq\sqsubseteq}
+\__umi_define_char{⋣}{\__umi_alternatives_not\nsqsupseteq\sqsupseteq}
+\__umi_define_char{⋤}{\sqsubsetneq}
+\__umi_define_char{⋥}{\sqsupsetneq}
+\__umi_define_char{⋦}{\lnsim}
+\__umi_define_char{⋧}{\gnsim}
+\__umi_define_char{⋨}{\precnsim}
+\__umi_define_char{⋩}{\succnsim}
+\__umi_define_char{⋪}{\__umi_alternatives_not\nvartriangleleft\vartriangleleft}
+\__umi_define_char{⋫}{\__umi_alternatives_not\nvartriangleright\vartriangleright}
+\__umi_define_char{⋬}{\__umi_alternatives_not\ntrianglelefteq\trianglelefteq}
+\__umi_define_char{⋭}{\__umi_alternatives_not\ntrianglerighteq\trianglerighteq}
+\__umi_define_char{⋮}{\vdots}
+\__umi_define_char{⋯}{\unicodecdots}
+\__umi_define_char{⋰}{\__umi_alternatives\iddots\adots}
+\__umi_define_char{⋱}{\ddots}
+\__umi_define_char{⋲}{\disin}
+\__umi_define_char{⋳}{\varisins}
+\__umi_define_char{⋴}{\isins}
+\__umi_define_char{⋵}{\isindot}
+\__umi_define_char{⋶}{\varisinobar}
+\__umi_define_char{⋷}{\isinobar}
+\__umi_define_char{⋸}{\isinvb}
+\__umi_define_char{⋹}{\isinE}
+\__umi_define_char{⋺}{\nisd}
+\__umi_define_char{⋻}{\varnis}
+\__umi_define_char{⋼}{\nis}
+\__umi_define_char{⋽}{\varniobar}
+\__umi_define_char{⋾}{\niobar}
+\__umi_define_char{⋿}{\bagmember}
+\__umi_define_char{⌀}{\diameter}
+\__umi_define_char{⌂}{\house}
+\__umi_define_char{⌅}{\varbarwedge}
+\__umi_define_char{⌆}{\vardoublebarwedge}
+\__umi_define_char_maybe_delimiter{⌈}{\lceil}
+\__umi_define_char_maybe_delimiter{⌉}{\rceil}
+\__umi_define_char_maybe_delimiter{⌊}{\lfloor}
+\__umi_define_char_maybe_delimiter{⌋}{\rfloor}
+\__umi_define_char{⌐}{\invnot}
+\__umi_define_char{⌑}{\sqlozenge}
+\__umi_define_char{⌒}{\profline}
+\__umi_define_char{⌓}{\profsurf}
+\__umi_define_char{⌗}{\viewdata}
+\__umi_define_char{⌙}{\turnednot}
+\__umi_define_char_maybe_delimiter{⌜}{\ulcorner}
+\__umi_define_char_maybe_delimiter{⌝}{\urcorner}
+\__umi_define_char_maybe_delimiter{⌞}{\llcorner}
+\__umi_define_char_maybe_delimiter{⌟}{\lrcorner}
+\__umi_define_char{⌠}{\inttop}
+\__umi_define_char{⌡}{\intbottom}
+\__umi_define_char{⌢}{\frown}
+\__umi_define_char{⌣}{\smile}
+\__umi_define_char{⌬}{\varhexagonlrbonds}
+\__umi_define_char{⌲}{\conictaper}
+\__umi_define_char{⌶}{\topbot}
+\__umi_define_char{⌽}{\obar}
+\__umi_define_char{⌿}{\APLnotslash}
+\__umi_define_char{⍀}{\APLnotbackslash}
+\__umi_define_char{⍓}{\APLboxupcaret}
+\__umi_define_char{⍰}{\APLboxquestion}
+\__umi_define_char{⍼}{\rangledownzigzagarrow}
+\__umi_define_char{⎔}{\hexagon}
+\__umi_define_char{⎛}{\lparenuend}
+\__umi_define_char{⎜}{\lparenextender}
+\__umi_define_char{⎝}{\lparenlend}
+\__umi_define_char{⎞}{\rparenuend}
+\__umi_define_char{⎟}{\rparenextender}
+\__umi_define_char{⎠}{\rparenlend}
+\__umi_define_char{⎡}{\lbrackuend}
+\__umi_define_char{⎢}{\lbrackextender}
+\__umi_define_char{⎣}{\lbracklend}
+\__umi_define_char{⎤}{\rbrackuend}
+\__umi_define_char{⎥}{\rbrackextender}
+\__umi_define_char{⎦}{\rbracklend}
+\__umi_define_char{⎧}{\lbraceuend}
+\__umi_define_char{⎨}{\lbracemid}
+\__umi_define_char{⎩}{\lbracelend}
+\__umi_define_char{⎪}{\vbraceextender}
+\__umi_define_char{⎫}{\rbraceuend}
+\__umi_define_char{⎬}{\rbracemid}
+\__umi_define_char{⎭}{\rbracelend}
+\__umi_define_char{⎮}{\intextender}
+\__umi_define_char{⎯}{\harrowextender}
+\__umi_define_char_maybe_delimiter{⎰}{\lmoustache}
+\__umi_define_char_maybe_delimiter{⎱}{\rmoustache}
+\__umi_define_char{⎲}{\sumtop}
+\__umi_define_char{⎳}{\sumbottom}
+\__umi_define_char{⎶}{\bbrktbrk}
+\__umi_define_char{⎷}{\sqrtbottom}
+\__umi_define_char{⎸}{\lvboxline}
+\__umi_define_char{⎹}{\rvboxline}
+\__umi_define_char{⏎}{\varcarriagereturn}
+\__umi_define_char{⏠}{\obrbrak}
+\__umi_define_char{⏡}{\ubrbrak}
+\__umi_define_char{⏢}{\trapezium}
+\__umi_define_char{⏣}{\benzenr}
+\__umi_define_char{⏤}{\strns}
+\__umi_define_char{⏥}{\fltns}
+\__umi_define_char{⏦}{\accurrent}
+\__umi_define_char{⏧}{\elinters}
+\__umi_define_char{␢}{\blanksymbol}
+\__umi_define_char{␣}{\mathvisiblespace}
+\__umi_define_char{┆}{\bdtriplevdash}
+\__umi_define_char{▀}{\blockuphalf}
+\__umi_define_char{▄}{\blocklowhalf}
+\__umi_define_char{█}{\blockfull}
+\__umi_define_char{▌}{\blocklefthalf}
+\__umi_define_char{▐}{\blockrighthalf}
+\__umi_define_char{░}{\blockqtrshaded}
+\__umi_define_char{▒}{\blockhalfshaded}
+\__umi_define_char{▓}{\blockthreeqtrshaded}
+\__umi_define_char{■}{\mdlgblksquare}
+\__umi_define_char{□}{\mdlgwhtsquare}
+\__umi_define_char{▢}{\squoval}
+\__umi_define_char{▣}{\blackinwhitesquare}
+\__umi_define_char{▤}{\squarehfill}
+\__umi_define_char{▥}{\squarevfill}
+\__umi_define_char{▦}{\squarehvfill}
+\__umi_define_char{▧}{\squarenwsefill}
+\__umi_define_char{▨}{\squareneswfill}
+\__umi_define_char{▩}{\squarecrossfill}
+\__umi_define_char{▪}{\smblksquare}
+\__umi_define_char{▫}{\smwhtsquare}
+\__umi_define_char{▬}{\hrectangleblack}
+\__umi_define_char{▭}{\hrectangle}
+\__umi_define_char{▮}{\vrectangleblack}
+\__umi_define_char{▯}{\vrectangle}
+\__umi_define_char{▰}{\parallelogramblack}
+\__umi_define_char{▱}{\parallelogram}
+\__umi_define_char{▲}{\bigblacktriangleup}
+\__umi_define_char{△}{\bigtriangleup}
+\__umi_define_char{▴}{\blacktriangle}
+\__umi_define_char{▵}{\vartriangle}
+\__umi_define_char{▶}{\blacktriangleright}
+\__umi_define_char{▷}{\triangleright}
+\__umi_define_char{▸}{\smallblacktriangleright}
+\__umi_define_char{▹}{\smalltriangleright}
+\__umi_define_char{►}{\blackpointerright}
+\__umi_define_char{▻}{\whitepointerright}
+\__umi_define_char{▼}{\bigblacktriangledown}
+\__umi_define_char{▽}{\bigtriangledown}
+\__umi_define_char{▾}{\blacktriangledown}
+\__umi_define_char{▿}{\triangledown}
+\__umi_define_char{◀}{\blacktriangleleft}
+\__umi_define_char{◁}{\triangleleft}
+\__umi_define_char{◂}{\smallblacktriangleleft}
+\__umi_define_char{◃}{\smalltriangleleft}
+\__umi_define_char{◄}{\blackpointerleft}
+\__umi_define_char{◅}{\whitepointerleft}
+\__umi_define_char{◆}{\mdlgblkdiamond}
+\__umi_define_char{◇}{\mdlgwhtdiamond}
+\__umi_define_char{◈}{\blackinwhitediamond}
+\__umi_define_char{◉}{\fisheye}
+\__umi_define_char{◊}{\mdlgwhtlozenge}
+\__umi_define_char{○}{\mdlgwhtcircle}
+\__umi_define_char{◌}{\dottedcircle}
+\__umi_define_char{◍}{\circlevertfill}
+\__umi_define_char{◎}{\bullseye}
+\__umi_define_char{●}{\mdlgblkcircle}
+\__umi_define_char{◐}{\circlelefthalfblack}
+\__umi_define_char{◑}{\circlerighthalfblack}
+\__umi_define_char{◒}{\circlebottomhalfblack}
+\__umi_define_char{◓}{\circletophalfblack}
+\__umi_define_char{◔}{\circleurquadblack}
+\__umi_define_char{◕}{\blackcircleulquadwhite}
+\__umi_define_char{◖}{\blacklefthalfcircle}
+\__umi_define_char{◗}{\blackrighthalfcircle}
+\__umi_define_char{◘}{\inversebullet}
+\__umi_define_char{◙}{\inversewhitecircle}
+\__umi_define_char{◚}{\invwhiteupperhalfcircle}
+\__umi_define_char{◛}{\invwhitelowerhalfcircle}
+\__umi_define_char{◜}{\ularc}
+\__umi_define_char{◝}{\urarc}
+\__umi_define_char{◞}{\lrarc}
+\__umi_define_char{◟}{\llarc}
+\__umi_define_char{◠}{\topsemicircle}
+\__umi_define_char{◡}{\botsemicircle}
+\__umi_define_char{◢}{\lrblacktriangle}
+\__umi_define_char{◣}{\llblacktriangle}
+\__umi_define_char{◤}{\ulblacktriangle}
+\__umi_define_char{◥}{\urblacktriangle}
+\__umi_define_char{◦}{\smwhtcircle}
+\__umi_define_char{◧}{\squareleftblack}
+\__umi_define_char{◨}{\squarerightblack}
+\__umi_define_char{◩}{\squareulblack}
+\__umi_define_char{◪}{\squarelrblack}
+\__umi_define_char{◫}{\boxbar}
+\__umi_define_char{◬}{\trianglecdot}
+\__umi_define_char{◭}{\triangleleftblack}
+\__umi_define_char{◮}{\trianglerightblack}
+\__umi_define_char{◯}{\lgwhtcircle}
+\__umi_define_char{◰}{\squareulquad}
+\__umi_define_char{◱}{\squarellquad}
+\__umi_define_char{◲}{\squarelrquad}
+\__umi_define_char{◳}{\squareurquad}
+\__umi_define_char{◴}{\circleulquad}
+\__umi_define_char{◵}{\circlellquad}
+\__umi_define_char{◶}{\circlelrquad}
+\__umi_define_char{◷}{\circleurquad}
+\__umi_define_char{◸}{\ultriangle}
+\__umi_define_char{◹}{\urtriangle}
+\__umi_define_char{◺}{\lltriangle}
+\__umi_define_char{◻}{\mdwhtsquare}
+\__umi_define_char{◼}{\mdblksquare}
+\__umi_define_char{◽}{\mdsmwhtsquare}
+\__umi_define_char{◾}{\mdsmblksquare}
+\__umi_define_char{◿}{\lrtriangle}
+\__umi_define_char{★}{\bigstar}
+\__umi_define_char{☆}{\bigwhitestar}
+\__umi_define_char{☉}{\astrosun}
+\__umi_define_char{☡}{\danger}
+\__umi_define_char{☻}{\blacksmiley}
+\__umi_define_char{☼}{\sun}
+\__umi_define_char{☽}{\rightmoon}
+\__umi_define_char{☾}{\leftmoon}
+\__umi_define_char{♀}{\female}
+\__umi_define_char{♂}{\male}
+\__umi_define_char{♠}{\spadesuit}
+\__umi_define_char{♡}{\heartsuit}
+\__umi_define_char{♢}{\diamondsuit}
+\__umi_define_char{♣}{\clubsuit}
+\__umi_define_char{♤}{\varspadesuit}
+\__umi_define_char{♥}{\varheartsuit}
+\__umi_define_char{♦}{\vardiamondsuit}
+\__umi_define_char{♧}{\varclubsuit}
+\__umi_define_char{♩}{\quarternote}
+\__umi_define_char{♪}{\eighthnote}
+\__umi_define_char{♫}{\twonotes}
+\__umi_define_char{♭}{\flat}
+\__umi_define_char{♮}{\natural}
+\__umi_define_char{♯}{\sharp}
+\__umi_define_char{♾}{\acidfree}
+\__umi_define_char{⚀}{\dicei}
+\__umi_define_char{⚁}{\diceii}
+\__umi_define_char{⚂}{\diceiii}
+\__umi_define_char{⚃}{\diceiv}
+\__umi_define_char{⚄}{\dicev}
+\__umi_define_char{⚅}{\dicevi}
+\__umi_define_char{⚆}{\circledrightdot}
+\__umi_define_char{⚇}{\circledtwodots}
+\__umi_define_char{⚈}{\blackcircledrightdot}
+\__umi_define_char{⚉}{\blackcircledtwodots}
+\__umi_define_char{⚥}{\Hermaphrodite}
+\__umi_define_char{⚪}{\mdwhtcircle}
+\__umi_define_char{⚫}{\mdblkcircle}
+\__umi_define_char{⚬}{\mdsmwhtcircle}
+\__umi_define_char{⚲}{\neuter}
+\__umi_define_char{✓}{\checkmark}
+\__umi_define_char{✠}{\maltese}
+\__umi_define_char{✪}{\circledstar}
+\__umi_define_char{✶}{\varstar}
+\__umi_define_char{✽}{\dingasterisk}
+\__umi_define_char_maybe_delimiter{❲}{\lbrbrak}
+\__umi_define_char_maybe_delimiter{❳}{\rbrbrak}
+\__umi_define_char{➛}{\draftingarrow}
+\__umi_define_char{⟀}{\threedangle}
+\__umi_define_char{⟁}{\whiteinwhitetriangle}
+\__umi_define_char{⟂}{\perp}
+\__umi_define_char{⟃}{\subsetcirc}
+\__umi_define_char{⟄}{\supsetcirc}
+\__umi_define_char_maybe_delimiter{⟅}{\lbag}
+\__umi_define_char_maybe_delimiter{⟆}{\rbag}
+\__umi_define_char{⟇}{\veedot}
+\__umi_define_char{⟈}{\bsolhsub}
+\__umi_define_char{⟉}{\suphsol}
+\__umi_define_char{⟐}{\diamondcdot}
+\__umi_define_char{⟑}{\wedgedot}
+\__umi_define_char{⟒}{\upin}
+\__umi_define_char{⟓}{\pullback}
+\__umi_define_char{⟔}{\pushout}
+\__umi_define_char{⟕}{\leftouterjoin}
+\__umi_define_char{⟖}{\rightouterjoin}
+\__umi_define_char{⟗}{\fullouterjoin}
+\__umi_define_char{⟘}{\bigbot}
+\__umi_define_char{⟙}{\bigtop}
+\__umi_define_char{⟚}{\DashVDash}
+\__umi_define_char{⟛}{\dashVdash}
+\__umi_define_char{⟜}{\multimapinv}
+\__umi_define_char{⟝}{\vlongdash}
+\__umi_define_char{⟞}{\longdashv}
+\__umi_define_char{⟟}{\cirbot}
+\__umi_define_char{⟠}{\lozengeminus}
+\__umi_define_char{⟡}{\concavediamond}
+\__umi_define_char{⟢}{\concavediamondtickleft}
+\__umi_define_char{⟣}{\concavediamondtickright}
+\__umi_define_char{⟤}{\whitesquaretickleft}
+\__umi_define_char{⟥}{\whitesquaretickright}
+\__umi_define_char_maybe_delimiter{⟦}{\lBrack}
+\__umi_define_char_maybe_delimiter{⟧}{\rBrack}
+\__umi_define_char_maybe_delimiter{⟨}{\langle}
+\__umi_define_char_maybe_delimiter{⟩}{\rangle}
+\__umi_define_char_maybe_delimiter{⟪}{\lAngle}
+\__umi_define_char_maybe_delimiter{⟫}{\rAngle}
+\__umi_define_char_maybe_delimiter{⟬}{\Lbrbrak}
+\__umi_define_char_maybe_delimiter{⟭}{\Rbrbrak}
+\__umi_define_char_maybe_delimiter{⟮}{\lgroup}
+\__umi_define_char_maybe_delimiter{⟯}{\rgroup}
+\__umi_define_char{⟰}{\UUparrow}
+\__umi_define_char{⟱}{\DDownarrow}
+\__umi_define_char{⟲}{\acwgapcirclearrow}
+\__umi_define_char{⟳}{\cwgapcirclearrow}
+\__umi_define_char{⟴}{\rightarrowonoplus}
+\__umi_define_char{⟵}{\longleftarrow}
+\__umi_define_char{⟶}{\longrightarrow}
+\__umi_define_char{⟷}{\longleftrightarrow}
+\__umi_define_char{⟸}{\Longleftarrow}
+\__umi_define_char{⟹}{\Longrightarrow}
+\__umi_define_char{⟺}{\Longleftrightarrow}
+\__umi_define_char{⟻}{\longmapsfrom}
+\__umi_define_char{⟼}{\longmapsto}
+\__umi_define_char{⟽}{\Longmapsfrom}
+\__umi_define_char{⟾}{\Longmapsto}
+\__umi_define_char{⟿}{\longrightsquigarrow}
+\__umi_define_char{⤀}{\nvtwoheadrightarrow}
+\__umi_define_char{⤁}{\nVtwoheadrightarrow}
+\__umi_define_char{⤂}{\nvLeftarrow}
+\__umi_define_char{⤃}{\nvRightarrow}
+\__umi_define_char{⤄}{\nvLeftrightarrow}
+\__umi_define_char{⤅}{\twoheadmapsto}
+\__umi_define_char{⤆}{\Mapsfrom}
+\__umi_define_char{⤇}{\Mapsto}
+\__umi_define_char{⤈}{\downarrowbarred}
+\__umi_define_char{⤉}{\uparrowbarred}
+\__umi_define_char{⤊}{\Uuparrow}
+\__umi_define_char{⤋}{\Ddownarrow}
+\__umi_define_char{⤌}{\leftbkarrow}
+\__umi_define_char{⤍}{\rightbkarrow}
+\__umi_define_char{⤎}{\leftdbkarrow}
+\__umi_define_char{⤏}{\dbkarrow}
+\__umi_define_char{⤐}{\drbkarrow}
+\__umi_define_char{⤑}{\rightdotarrow}
+\__umi_define_char{⤒}{\baruparrow}
+\__umi_define_char{⤓}{\downarrowbar}
+\__umi_define_char{⤔}{\nvrightarrowtail}
+\__umi_define_char{⤕}{\nVrightarrowtail}
+\__umi_define_char{⤖}{\twoheadrightarrowtail}
+\__umi_define_char{⤗}{\nvtwoheadrightarrowtail}
+\__umi_define_char{⤘}{\nVtwoheadrightarrowtail}
+\__umi_define_char{⤙}{\lefttail}
+\__umi_define_char{⤚}{\righttail}
+\__umi_define_char{⤛}{\leftdbltail}
+\__umi_define_char{⤜}{\rightdbltail}
+\__umi_define_char{⤝}{\diamondleftarrow}
+\__umi_define_char{⤞}{\rightarrowdiamond}
+\__umi_define_char{⤟}{\diamondleftarrowbar}
+\__umi_define_char{⤠}{\barrightarrowdiamond}
+\__umi_define_char{⤡}{\nwsearrow}
+\__umi_define_char{⤢}{\neswarrow}
+\__umi_define_char{⤣}{\hknwarrow}
+\__umi_define_char{⤤}{\hknearrow}
+\__umi_define_char{⤥}{\hksearrow}
+\__umi_define_char{⤦}{\hkswarrow}
+\__umi_define_char{⤧}{\tona}
+\__umi_define_char{⤨}{\toea}
+\__umi_define_char{⤩}{\tosa}
+\__umi_define_char{⤪}{\towa}
+\__umi_define_char{⤫}{\rdiagovfdiag}
+\__umi_define_char{⤬}{\fdiagovrdiag}
+\__umi_define_char{⤭}{\seovnearrow}
+\__umi_define_char{⤮}{\neovsearrow}
+\__umi_define_char{⤯}{\fdiagovnearrow}
+\__umi_define_char{⤰}{\rdiagovsearrow}
+\__umi_define_char{⤱}{\neovnwarrow}
+\__umi_define_char{⤲}{\nwovnearrow}
+\__umi_define_char{⤳}{\rightcurvedarrow}
+\__umi_define_char{⤴}{\uprightcurvearrow}
+\__umi_define_char{⤵}{\downrightcurvedarrow}
+\__umi_define_char{⤶}{\leftdowncurvedarrow}
+\__umi_define_char{⤷}{\rightdowncurvedarrow}
+\__umi_define_char{⤸}{\cwrightarcarrow}
+\__umi_define_char{⤹}{\acwleftarcarrow}
+\__umi_define_char{⤺}{\acwoverarcarrow}
+\__umi_define_char{⤻}{\acwunderarcarrow}
+\__umi_define_char{⤼}{\curvearrowrightminus}
+\__umi_define_char{⤽}{\curvearrowleftplus}
+\__umi_define_char{⤾}{\cwundercurvearrow}
+\__umi_define_char{⤿}{\ccwundercurvearrow}
+\__umi_define_char{⥀}{\acwcirclearrow}
+\__umi_define_char{⥁}{\cwcirclearrow}
+\__umi_define_char{⥂}{\rightarrowshortleftarrow}
+\__umi_define_char{⥃}{\leftarrowshortrightarrow}
+\__umi_define_char{⥄}{\shortrightarrowleftarrow}
+\__umi_define_char{⥅}{\rightarrowplus}
+\__umi_define_char{⥆}{\leftarrowplus}
+\__umi_define_char{⥇}{\rightarrowx}
+\__umi_define_char{⥈}{\leftrightarrowcircle}
+\__umi_define_char{⥉}{\twoheaduparrowcircle}
+\__umi_define_char{⥊}{\leftrightharpoonupdown}
+\__umi_define_char{⥋}{\leftrightharpoondownup}
+\__umi_define_char{⥌}{\updownharpoonrightleft}
+\__umi_define_char{⥍}{\updownharpoonleftright}
+\__umi_define_char{⥎}{\leftrightharpoonupup}
+\__umi_define_char{⥏}{\updownharpoonrightright}
+\__umi_define_char{⥐}{\leftrightharpoondowndown}
+\__umi_define_char{⥑}{\updownharpoonleftleft}
+\__umi_define_char{⥒}{\barleftharpoonup}
+\__umi_define_char{⥓}{\rightharpoonupbar}
+\__umi_define_char{⥔}{\barupharpoonright}
+\__umi_define_char{⥕}{\downharpoonrightbar}
+\__umi_define_char{⥖}{\barleftharpoondown}
+\__umi_define_char{⥗}{\rightharpoondownbar}
+\__umi_define_char{⥘}{\barupharpoonleft}
+\__umi_define_char{⥙}{\downharpoonleftbar}
+\__umi_define_char{⥚}{\leftharpoonupbar}
+\__umi_define_char{⥛}{\barrightharpoonup}
+\__umi_define_char{⥜}{\upharpoonrightbar}
+\__umi_define_char{⥝}{\bardownharpoonright}
+\__umi_define_char{⥞}{\leftharpoondownbar}
+\__umi_define_char{⥟}{\barrightharpoondown}
+\__umi_define_char{⥠}{\upharpoonleftbar}
+\__umi_define_char{⥡}{\bardownharpoonleft}
+\__umi_define_char{⥢}{\leftharpoonsupdown}
+\__umi_define_char{⥣}{\upharpoonsleftright}
+\__umi_define_char{⥤}{\rightharpoonsupdown}
+\__umi_define_char{⥥}{\downharpoonsleftright}
+\__umi_define_char{⥦}{\leftrightharpoonsup}
+\__umi_define_char{⥧}{\leftrightharpoonsdown}
+\__umi_define_char{⥨}{\rightleftharpoonsup}
+\__umi_define_char{⥩}{\rightleftharpoonsdown}
+\__umi_define_char{⥪}{\leftharpoonupdash}
+\__umi_define_char{⥫}{\dashleftharpoondown}
+\__umi_define_char{⥬}{\rightharpoonupdash}
+\__umi_define_char{⥭}{\dashrightharpoondown}
+\__umi_define_char{⥮}{\updownharpoonsleftright}
+\__umi_define_char{⥯}{\downupharpoonsleftright}
+\__umi_define_char{⥰}{\rightimply}
+\__umi_define_char{⥱}{\equalrightarrow}
+\__umi_define_char{⥲}{\similarrightarrow}
+\__umi_define_char{⥳}{\leftarrowsimilar}
+\__umi_define_char{⥴}{\rightarrowsimilar}
+\__umi_define_char{⥵}{\rightarrowapprox}
+\__umi_define_char{⥶}{\ltlarr}
+\__umi_define_char{⥷}{\leftarrowless}
+\__umi_define_char{⥸}{\gtrarr}
+\__umi_define_char{⥹}{\subrarr}
+\__umi_define_char{⥺}{\leftarrowsubset}
+\__umi_define_char{⥻}{\suplarr}
+\__umi_define_char{⥼}{\leftfishtail}
+\__umi_define_char{⥽}{\rightfishtail}
+\__umi_define_char{⥾}{\upfishtail}
+\__umi_define_char{⥿}{\downfishtail}
+\__umi_define_char_maybe_delimiter{⦀}{\Vvert}
+\__umi_define_char{⦁}{\mdsmblkcircle}
+\__umi_define_char{⦂}{\typecolon}
+\__umi_define_char_maybe_delimiter{⦃}{\lBrace}
+\__umi_define_char_maybe_delimiter{⦄}{\rBrace}
+\__umi_define_char_maybe_delimiter{⦅}{\lParen}
+\__umi_define_char_maybe_delimiter{⦆}{\rParen}
+\__umi_define_char_maybe_delimiter{⦇}{\llparenthesis}
+\__umi_define_char_maybe_delimiter{⦈}{\rrparenthesis}
+\__umi_define_char_maybe_delimiter{⦉}{\llangle}
+\__umi_define_char_maybe_delimiter{⦊}{\rrangle}
+\__umi_define_char_maybe_delimiter{⦋}{\lbrackubar}
+\__umi_define_char_maybe_delimiter{⦌}{\rbrackubar}
+\__umi_define_char_maybe_delimiter{⦍}{\lbrackultick}
+\__umi_define_char_maybe_delimiter{⦎}{\rbracklrtick}
+\__umi_define_char_maybe_delimiter{⦏}{\lbracklltick}
+\__umi_define_char_maybe_delimiter{⦐}{\rbrackurtick}
+\__umi_define_char_maybe_delimiter{⦑}{\langledot}
+\__umi_define_char_maybe_delimiter{⦒}{\rangledot}
+\__umi_define_char_maybe_delimiter{⦓}{\lparenless}
+\__umi_define_char_maybe_delimiter{⦔}{\rparengtr}
+\__umi_define_char_maybe_delimiter{⦕}{\Lparengtr}
+\__umi_define_char_maybe_delimiter{⦖}{\Rparenless}
+\__umi_define_char_maybe_delimiter{⦗}{\lblkbrbrak}
+\__umi_define_char_maybe_delimiter{⦘}{\rblkbrbrak}
+\__umi_define_char{⦙}{\fourvdots}
+\__umi_define_char{⦚}{\vzigzag}
+\__umi_define_char{⦛}{\measuredangleleft}
+\__umi_define_char{⦜}{\rightanglesqr}
+\__umi_define_char{⦝}{\rightanglemdot}
+\__umi_define_char{⦞}{\angles}
+\__umi_define_char{⦟}{\angdnr}
+\__umi_define_char{⦠}{\gtlpar}
+\__umi_define_char{⦡}{\sphericalangleup}
+\__umi_define_char{⦢}{\turnangle}
+\__umi_define_char{⦣}{\revangle}
+\__umi_define_char{⦤}{\angleubar}
+\__umi_define_char{⦥}{\revangleubar}
+\__umi_define_char{⦦}{\wideangledown}
+\__umi_define_char{⦧}{\wideangleup}
+\__umi_define_char{⦨}{\measanglerutone}
+\__umi_define_char{⦩}{\measanglelutonw}
+\__umi_define_char{⦪}{\measanglerdtose}
+\__umi_define_char{⦫}{\measangleldtosw}
+\__umi_define_char{⦬}{\measangleurtone}
+\__umi_define_char{⦭}{\measangleultonw}
+\__umi_define_char{⦮}{\measangledrtose}
+\__umi_define_char{⦯}{\measangledltosw}
+\__umi_define_char{⦰}{\revemptyset}
+\__umi_define_char{⦱}{\emptysetobar}
+\__umi_define_char{⦲}{\emptysetocirc}
+\__umi_define_char{⦳}{\emptysetoarr}
+\__umi_define_char{⦴}{\emptysetoarrl}
+\__umi_define_char{⦵}{\circlehbar}
+\__umi_define_char{⦶}{\circledvert}
+\__umi_define_char{⦷}{\circledparallel}
+\__umi_define_char{⦸}{\obslash}
+\__umi_define_char{⦹}{\operp}
+\__umi_define_char{⦺}{\obot}
+\__umi_define_char{⦻}{\olcross}
+\__umi_define_char{⦼}{\odotslashdot}
+\__umi_define_char{⦽}{\uparrowoncircle}
+\__umi_define_char{⦾}{\circledwhitebullet}
+\__umi_define_char{⦿}{\circledbullet}
+\__umi_define_char{⧀}{\olessthan}
+\__umi_define_char{⧁}{\ogreaterthan}
+\__umi_define_char{⧂}{\cirscir}
+\__umi_define_char{⧃}{\cirE}
+\__umi_define_char{⧄}{\boxdiag}
+\__umi_define_char{⧅}{\boxbslash}
+\__umi_define_char{⧆}{\boxast}
+\__umi_define_char{⧇}{\boxcircle}
+\__umi_define_char{⧈}{\boxbox}
+\__umi_define_char{⧉}{\boxonbox}
+\__umi_define_char{⧊}{\triangleodot}
+\__umi_define_char{⧋}{\triangleubar}
+\__umi_define_char{⧌}{\triangles}
+\__umi_define_char{⧍}{\triangleserifs}
+\__umi_define_char{⧎}{\rtriltri}
+\__umi_define_char{⧏}{\ltrivb}
+\__umi_define_char{⧐}{\vbrtri}
+\__umi_define_char{⧑}{\lfbowtie}
+\__umi_define_char{⧒}{\rfbowtie}
+\__umi_define_char{⧓}{\fbowtie}
+\__umi_define_char{⧔}{\lftimes}
+\__umi_define_char{⧕}{\rftimes}
+\__umi_define_char{⧖}{\hourglass}
+\__umi_define_char{⧗}{\blackhourglass}
+\__umi_define_char_maybe_delimiter{⧘}{\lvzigzag}
+\__umi_define_char_maybe_delimiter{⧙}{\rvzigzag}
+\__umi_define_char_maybe_delimiter{⧚}{\Lvzigzag}
+\__umi_define_char_maybe_delimiter{⧛}{\Rvzigzag}
+\__umi_define_char{⧜}{\iinfin}
+\__umi_define_char{⧝}{\tieinfty}
+\__umi_define_char{⧞}{\nvinfty}
+\__umi_define_char{⧟}{\dualmap}
+\__umi_define_char{⧠}{\laplac}
+\__umi_define_char{⧡}{\lrtriangleeq}
+\__umi_define_char{⧢}{\shuffle}
+\__umi_define_char{⧣}{\eparsl}
+\__umi_define_char{⧤}{\smeparsl}
+\__umi_define_char{⧥}{\eqvparsl}
+\__umi_define_char{⧦}{\gleichstark}
+\__umi_define_char{⧧}{\thermod}
+\__umi_define_char{⧨}{\downtriangleleftblack}
+\__umi_define_char{⧩}{\downtrianglerightblack}
+\__umi_define_char{⧪}{\blackdiamonddownarrow}
+\__umi_define_char{⧫}{\mdlgblklozenge}
+\__umi_define_char{⧬}{\circledownarrow}
+\__umi_define_char{⧭}{\blackcircledownarrow}
+\__umi_define_char{⧮}{\errbarsquare}
+\__umi_define_char{⧯}{\errbarblacksquare}
+\__umi_define_char{⧰}{\errbardiamond}
+\__umi_define_char{⧱}{\errbarblackdiamond}
+\__umi_define_char{⧲}{\errbarcircle}
+\__umi_define_char{⧳}{\errbarblackcircle}
+\__umi_define_char{⧴}{\ruledelayed}
+\__umi_define_char{⧵}{\setminus}
+\__umi_define_char{⧶}{\dsol}
+\__umi_define_char{⧷}{\rsolbar}
+\__umi_define_char{⧸}{\xsol}
+\__umi_define_char{⧹}{\xbsol}
+\__umi_define_char{⧺}{\doubleplus}
+\__umi_define_char{⧻}{\tripleplus}
+\__umi_define_char_maybe_delimiter{⧼}{\lcurvyangle}
+\__umi_define_char_maybe_delimiter{⧽}{\rcurvyangle}
+\__umi_define_char{⧾}{\tplus}
+\__umi_define_char{⧿}{\tminus}
+\__umi_define_char{⨀}{\bigodot}
+\__umi_define_char{⨁}{\bigoplus}
+\__umi_define_char{⨂}{\bigotimes}
+\__umi_define_char{⨃}{\bigcupdot}
+\__umi_define_char{⨄}{\biguplus}
+\__umi_define_char{⨅}{\bigsqcap}
+\__umi_define_char{⨆}{\bigsqcup}
+\__umi_define_char{⨇}{\conjquant}
+\__umi_define_char{⨈}{\disjquant}
+\__umi_define_char{⨉}{\bigtimes}
+\__umi_define_char{⨊}{\modtwosum}
+\__umi_define_char{⨋}{\sumint}
+\__umi_define_char{⨌}{\iiiint}
+\__umi_define_char{⨍}{\intbar}
+\__umi_define_char{⨎}{\intBar}
+\__umi_define_char{⨏}{\fint}
+\__umi_define_char{⨐}{\cirfnint}
+\__umi_define_char{⨑}{\awint}
+\__umi_define_char{⨒}{\rppolint}
+\__umi_define_char{⨓}{\scpolint}
+\__umi_define_char{⨔}{\npolint}
+\__umi_define_char{⨕}{\pointint}
+\__umi_define_char{⨖}{\sqint}
+\__umi_define_char{⨗}{\intlarhk}
+\__umi_define_char{⨘}{\intx}
+\__umi_define_char{⨙}{\intcap}
+\__umi_define_char{⨚}{\intcup}
+\__umi_define_char{⨛}{\upint}
+\__umi_define_char{⨜}{\lowint}
+\__umi_define_char{⨝}{\Join}
+\__umi_define_char{⨞}{\bigtriangleleft}
+\__umi_define_char{⨟}{\zcmp}
+\__umi_define_char{⨠}{\zpipe}
+\__umi_define_char{⨡}{\zproject}
+\__umi_define_char{⨢}{\ringplus}
+\__umi_define_char{⨣}{\plushat}
+\__umi_define_char{⨤}{\simplus}
+\__umi_define_char{⨥}{\plusdot}
+\__umi_define_char{⨦}{\plussim}
+\__umi_define_char{⨧}{\plussubtwo}
+\__umi_define_char{⨨}{\plustrif}
+\__umi_define_char{⨩}{\commaminus}
+\__umi_define_char{⨪}{\minusdot}
+\__umi_define_char{⨫}{\minusfdots}
+\__umi_define_char{⨬}{\minusrdots}
+\__umi_define_char{⨭}{\opluslhrim}
+\__umi_define_char{⨮}{\oplusrhrim}
+\__umi_define_char{⨯}{\vectimes}
+\__umi_define_char{⨰}{\dottimes}
+\__umi_define_char{⨱}{\timesbar}
+\__umi_define_char{⨲}{\btimes}
+\__umi_define_char{⨳}{\smashtimes}
+\__umi_define_char{⨴}{\otimeslhrim}
+\__umi_define_char{⨵}{\otimesrhrim}
+\__umi_define_char{⨶}{\otimeshat}
+\__umi_define_char{⨷}{\Otimes}
+\__umi_define_char{⨸}{\odiv}
+\__umi_define_char{⨹}{\triangleplus}
+\__umi_define_char{⨺}{\triangleminus}
+\__umi_define_char{⨻}{\triangletimes}
+\__umi_define_char{⨼}{\intprod}
+\__umi_define_char{⨽}{\intprodr}
+\__umi_define_char{⨾}{\fcmp}
+\__umi_define_char{⨿}{\amalg}
+\__umi_define_char{⩀}{\capdot}
+\__umi_define_char{⩁}{\uminus}
+\__umi_define_char{⩂}{\barcup}
+\__umi_define_char{⩃}{\barcap}
+\__umi_define_char{⩄}{\capwedge}
+\__umi_define_char{⩅}{\cupvee}
+\__umi_define_char{⩆}{\cupovercap}
+\__umi_define_char{⩇}{\capovercup}
+\__umi_define_char{⩈}{\cupbarcap}
+\__umi_define_char{⩉}{\capbarcup}
+\__umi_define_char{⩊}{\twocups}
+\__umi_define_char{⩋}{\twocaps}
+\__umi_define_char{⩌}{\closedvarcup}
+\__umi_define_char{⩍}{\closedvarcap}
+\__umi_define_char{⩎}{\Sqcap}
+\__umi_define_char{⩏}{\Sqcup}
+\__umi_define_char{⩐}{\closedvarcupsmashprod}
+\__umi_define_char{⩑}{\wedgeodot}
+\__umi_define_char{⩒}{\veeodot}
+\__umi_define_char{⩓}{\Wedge}
+\__umi_define_char{⩔}{\Vee}
+\__umi_define_char{⩕}{\wedgeonwedge}
+\__umi_define_char{⩖}{\veeonvee}
+\__umi_define_char{⩗}{\bigslopedvee}
+\__umi_define_char{⩘}{\bigslopedwedge}
+\__umi_define_char{⩙}{\veeonwedge}
+\__umi_define_char{⩚}{\wedgemidvert}
+\__umi_define_char{⩛}{\veemidvert}
+\__umi_define_char{⩜}{\midbarwedge}
+\__umi_define_char{⩝}{\midbarvee}
+\__umi_define_char{⩞}{\doublebarwedge}
+\__umi_define_char{⩟}{\wedgebar}
+\__umi_define_char{⩠}{\wedgedoublebar}
+\__umi_define_char{⩡}{\varveebar}
+\__umi_define_char{⩢}{\doublebarvee}
+\__umi_define_char{⩣}{\veedoublebar}
+\__umi_define_char{⩤}{\dsub}
+\__umi_define_char{⩥}{\rsub}
+\__umi_define_char{⩦}{\eqdot}
+\__umi_define_char{⩧}{\dotequiv}
+\__umi_define_char{⩨}{\equivVert}
+\__umi_define_char{⩩}{\equivVvert}
+\__umi_define_char{⩪}{\dotsim}
+\__umi_define_char{⩫}{\simrdots}
+\__umi_define_char{⩬}{\simminussim}
+\__umi_define_char{⩭}{\congdot}
+\__umi_define_char{⩮}{\asteq}
+\__umi_define_char{⩯}{\hatapprox}
+\__umi_define_char{⩰}{\approxeqq}
+\__umi_define_char{⩱}{\eqqplus}
+\__umi_define_char{⩲}{\pluseqq}
+\__umi_define_char{⩳}{\eqqsim}
+\__umi_define_char{⩴}{\Coloneq}
+\__umi_define_char{⩵}{\eqeq}
+\__umi_define_char{⩶}{\eqeqeq}
+\__umi_define_char{⩷}{\ddotseq}
+\__umi_define_char{⩸}{\equivDD}
+\__umi_define_char{⩹}{\ltcir}
+\__umi_define_char{⩺}{\gtcir}
+\__umi_define_char{⩻}{\ltquest}
+\__umi_define_char{⩼}{\gtquest}
+\__umi_define_char{⩽}{\leqslant}
+\__umi_define_char{⩾}{\geqslant}
+\__umi_define_char{⩿}{\lesdot}
+\__umi_define_char{⪀}{\gesdot}
+\__umi_define_char{⪁}{\lesdoto}
+\__umi_define_char{⪂}{\gesdoto}
+\__umi_define_char{⪃}{\lesdotor}
+\__umi_define_char{⪄}{\gesdotol}
+\__umi_define_char{⪅}{\lessapprox}
+\__umi_define_char{⪆}{\gtrapprox}
+\__umi_define_char{⪇}{\lneq}
+\__umi_define_char{⪈}{\gneq}
+\__umi_define_char{⪉}{\lnapprox}
+\__umi_define_char{⪊}{\gnapprox}
+\__umi_define_char{⪋}{\lesseqqgtr}
+\__umi_define_char{⪌}{\gtreqqless}
+\__umi_define_char{⪍}{\lsime}
+\__umi_define_char{⪎}{\gsime}
+\__umi_define_char{⪏}{\lsimg}
+\__umi_define_char{⪐}{\gsiml}
+\__umi_define_char{⪑}{\lgE}
+\__umi_define_char{⪒}{\glE}
+\__umi_define_char{⪓}{\lesges}
+\__umi_define_char{⪔}{\gesles}
+\__umi_define_char{⪕}{\eqslantless}
+\__umi_define_char{⪖}{\eqslantgtr}
+\__umi_define_char{⪗}{\elsdot}
+\__umi_define_char{⪘}{\egsdot}
+\__umi_define_char{⪙}{\eqqless}
+\__umi_define_char{⪚}{\eqqgtr}
+\__umi_define_char{⪛}{\eqqslantless}
+\__umi_define_char{⪜}{\eqqslantgtr}
+\__umi_define_char{⪝}{\simless}
+\__umi_define_char{⪞}{\simgtr}
+\__umi_define_char{⪟}{\simlE}
+\__umi_define_char{⪠}{\simgE}
+\__umi_define_char{⪡}{\Lt}
+\__umi_define_char{⪢}{\Gt}
+\__umi_define_char{⪣}{\partialmeetcontraction}
+\__umi_define_char{⪤}{\glj}
+\__umi_define_char{⪥}{\gla}
+\__umi_define_char{⪦}{\ltcc}
+\__umi_define_char{⪧}{\gtcc}
+\__umi_define_char{⪨}{\lescc}
+\__umi_define_char{⪩}{\gescc}
+\__umi_define_char{⪪}{\smt}
+\__umi_define_char{⪫}{\lat}
+\__umi_define_char{⪬}{\smte}
+\__umi_define_char{⪭}{\late}
+\__umi_define_char{⪮}{\bumpeqq}
+\__umi_define_char{⪯}{\preceq}
+\__umi_define_char{⪰}{\succeq}
+\__umi_define_char{⪱}{\precneq}
+\__umi_define_char{⪲}{\succneq}
+\__umi_define_char{⪳}{\preceqq}
+\__umi_define_char{⪴}{\succeqq}
+\__umi_define_char{⪵}{\precneqq}
+\__umi_define_char{⪶}{\succneqq}
+\__umi_define_char{⪷}{\precapprox}
+\__umi_define_char{⪸}{\succapprox}
+\__umi_define_char{⪹}{\precnapprox}
+\__umi_define_char{⪺}{\succnapprox}
+\__umi_define_char{⪻}{\Prec}
+\__umi_define_char{⪼}{\Succ}
+\__umi_define_char{⪽}{\subsetdot}
+\__umi_define_char{⪾}{\supsetdot}
+\__umi_define_char{⪿}{\subsetplus}
+\__umi_define_char{⫀}{\supsetplus}
+\__umi_define_char{⫁}{\submult}
+\__umi_define_char{⫂}{\supmult}
+\__umi_define_char{⫃}{\subedot}
+\__umi_define_char{⫄}{\supedot}
+\__umi_define_char{⫅}{\subseteqq}
+\__umi_define_char{⫆}{\supseteqq}
+\__umi_define_char{⫇}{\subsim}
+\__umi_define_char{⫈}{\supsim}
+\__umi_define_char{⫉}{\subsetapprox}
+\__umi_define_char{⫊}{\supsetapprox}
+\__umi_define_char{⫋}{\subsetneqq}
+\__umi_define_char{⫌}{\supsetneqq}
+\__umi_define_char{⫍}{\lsqhook}
+\__umi_define_char{⫎}{\rsqhook}
+\__umi_define_char{⫏}{\csub}
+\__umi_define_char{⫐}{\csup}
+\__umi_define_char{⫑}{\csube}
+\__umi_define_char{⫒}{\csupe}
+\__umi_define_char{⫓}{\subsup}
+\__umi_define_char{⫔}{\supsub}
+\__umi_define_char{⫕}{\subsub}
+\__umi_define_char{⫖}{\supsup}
+\__umi_define_char{⫗}{\suphsub}
+\__umi_define_char{⫘}{\supdsub}
+\__umi_define_char{⫙}{\forkv}
+\__umi_define_char{⫚}{\topfork}
+\__umi_define_char{⫛}{\mlcp}
+\__umi_define_char{⫝̸}{\forks}
+\__umi_define_char{⫝}{\forksnot}
+\__umi_define_char{⫞}{\shortlefttack}
+\__umi_define_char{⫟}{\shortdowntack}
+\__umi_define_char{⫠}{\shortuptack}
+\__umi_define_char{⫡}{\perps}
+\__umi_define_char{⫢}{\vDdash}
+\__umi_define_char{⫣}{\dashV}
+\__umi_define_char{⫤}{\Dashv}
+\__umi_define_char{⫥}{\DashV}
+\__umi_define_char{⫦}{\varVdash}
+\__umi_define_char{⫧}{\Barv}
+\__umi_define_char{⫨}{\vBar}
+\__umi_define_char{⫩}{\vBarv}
+\__umi_define_char{⫪}{\barV}
+\__umi_define_char{⫫}{\Vbar}
+\__umi_define_char{⫬}{\Not}
+\__umi_define_char{⫭}{\bNot}
+\__umi_define_char{⫮}{\revnmid}
+\__umi_define_char{⫯}{\cirmid}
+\__umi_define_char{⫰}{\midcir}
+\__umi_define_char{⫱}{\topcir}
+\__umi_define_char{⫲}{\nhpar}
+\__umi_define_char{⫳}{\parsim}
+\__umi_define_char{⫴}{\interleave}
+\__umi_define_char{⫵}{\nhVvert}
+\__umi_define_char{⫶}{\threedotcolon}
+\__umi_define_char{⫷}{\lllnest}
+\__umi_define_char{⫸}{\gggnest}
+\__umi_define_char{⫹}{\leqqslant}
+\__umi_define_char{⫺}{\geqqslant}
+\__umi_define_char{⫻}{\trslash}
+\__umi_define_char{⫼}{\biginterleave}
+\__umi_define_char{⫽}{\sslash}
+\__umi_define_char{⫾}{\talloblong}
+\__umi_define_char{⫿}{\bigtalloblong}
+\__umi_define_char{⬒}{\squaretopblack}
+\__umi_define_char{⬓}{\squarebotblack}
+\__umi_define_char{⬔}{\squareurblack}
+\__umi_define_char{⬕}{\squarellblack}
+\__umi_define_char{⬖}{\diamondleftblack}
+\__umi_define_char{⬗}{\diamondrightblack}
+\__umi_define_char{⬘}{\diamondtopblack}
+\__umi_define_char{⬙}{\diamondbotblack}
+\__umi_define_char{⬚}{\dottedsquare}
+\__umi_define_char{⬛}{\lgblksquare}
+\__umi_define_char{⬜}{\lgwhtsquare}
+\__umi_define_char{⬝}{\vysmblksquare}
+\__umi_define_char{⬞}{\vysmwhtsquare}
+\__umi_define_char{⬟}{\pentagonblack}
+\__umi_define_char{⬠}{\pentagon}
+\__umi_define_char{⬡}{\varhexagon}
+\__umi_define_char{⬢}{\varhexagonblack}
+\__umi_define_char{⬣}{\hexagonblack}
+\__umi_define_char{⬤}{\lgblkcircle}
+\__umi_define_char{⬥}{\mdblkdiamond}
+\__umi_define_char{⬦}{\mdwhtdiamond}
+\__umi_define_char{⬧}{\mdblklozenge}
+\__umi_define_char{⬨}{\mdwhtlozenge}
+\__umi_define_char{⬩}{\smblkdiamond}
+\__umi_define_char{⬪}{\smblklozenge}
+\__umi_define_char{⬫}{\smwhtlozenge}
+\__umi_define_char{⬬}{\blkhorzoval}
+\__umi_define_char{⬭}{\whthorzoval}
+\__umi_define_char{⬮}{\blkvertoval}
+\__umi_define_char{⬯}{\whtvertoval}
+\__umi_define_char{⬰}{\circleonleftarrow}
+\__umi_define_char{⬱}{\leftthreearrows}
+\__umi_define_char{⬲}{\leftarrowonoplus}
+\__umi_define_char{⬳}{\longleftsquigarrow}
+\__umi_define_char{⬴}{\nvtwoheadleftarrow}
+\__umi_define_char{⬵}{\nVtwoheadleftarrow}
+\__umi_define_char{⬶}{\twoheadmapsfrom}
+\__umi_define_char{⬷}{\twoheadleftdbkarrow}
+\__umi_define_char{⬸}{\leftdotarrow}
+\__umi_define_char{⬹}{\nvleftarrowtail}
+\__umi_define_char{⬺}{\nVleftarrowtail}
+\__umi_define_char{⬻}{\twoheadleftarrowtail}
+\__umi_define_char{⬼}{\nvtwoheadleftarrowtail}
+\__umi_define_char{⬽}{\nVtwoheadleftarrowtail}
+\__umi_define_char{⬾}{\leftarrowx}
+\__umi_define_char{⬿}{\leftcurvedarrow}
+\__umi_define_char{⭀}{\equalleftarrow}
+\__umi_define_char{⭁}{\bsimilarleftarrow}
+\__umi_define_char{⭂}{\leftarrowbackapprox}
+\__umi_define_char{⭃}{\rightarrowgtr}
+\__umi_define_char{⭄}{\rightarrowsupset}
+\__umi_define_char{⭅}{\LLeftarrow}
+\__umi_define_char{⭆}{\RRightarrow}
+\__umi_define_char{⭇}{\bsimilarrightarrow}
+\__umi_define_char{⭈}{\rightarrowbackapprox}
+\__umi_define_char{⭉}{\similarleftarrow}
+\__umi_define_char{⭊}{\leftarrowapprox}
+\__umi_define_char{⭋}{\leftarrowbsimilar}
+\__umi_define_char{⭌}{\rightarrowbsimilar}
+\__umi_define_char{⭐}{\medwhitestar}
+\__umi_define_char{⭑}{\medblackstar}
+\__umi_define_char{⭒}{\smwhitestar}
+\__umi_define_char{⭓}{\rightpentagonblack}
+\__umi_define_char{⭔}{\rightpentagon}
+\__umi_define_char{〒}{\postalmark}
+\__umi_define_char{〰}{\hzigzag}
+\__umi_define_char{𝐀}{\umiMathbf{A}}
+\__umi_define_char{𝐁}{\umiMathbf{B}}
+\__umi_define_char{𝐂}{\umiMathbf{C}}
+\__umi_define_char{𝐃}{\umiMathbf{D}}
+\__umi_define_char{𝐄}{\umiMathbf{E}}
+\__umi_define_char{𝐅}{\umiMathbf{F}}
+\__umi_define_char{𝐆}{\umiMathbf{G}}
+\__umi_define_char{𝐇}{\umiMathbf{H}}
+\__umi_define_char{𝐈}{\umiMathbf{I}}
+\__umi_define_char{𝐉}{\umiMathbf{J}}
+\__umi_define_char{𝐊}{\umiMathbf{K}}
+\__umi_define_char{𝐋}{\umiMathbf{L}}
+\__umi_define_char{𝐌}{\umiMathbf{M}}
+\__umi_define_char{𝐍}{\umiMathbf{N}}
+\__umi_define_char{𝐎}{\umiMathbf{O}}
+\__umi_define_char{𝐏}{\umiMathbf{P}}
+\__umi_define_char{𝐐}{\umiMathbf{Q}}
+\__umi_define_char{𝐑}{\umiMathbf{R}}
+\__umi_define_char{𝐒}{\umiMathbf{S}}
+\__umi_define_char{𝐓}{\umiMathbf{T}}
+\__umi_define_char{𝐔}{\umiMathbf{U}}
+\__umi_define_char{𝐕}{\umiMathbf{V}}
+\__umi_define_char{𝐖}{\umiMathbf{W}}
+\__umi_define_char{𝐗}{\umiMathbf{X}}
+\__umi_define_char{𝐘}{\umiMathbf{Y}}
+\__umi_define_char{𝐙}{\umiMathbf{Z}}
+\__umi_define_char{𝐚}{\umiMathbf{a}}
+\__umi_define_char{𝐛}{\umiMathbf{b}}
+\__umi_define_char{𝐜}{\umiMathbf{c}}
+\__umi_define_char{𝐝}{\umiMathbf{d}}
+\__umi_define_char{𝐞}{\umiMathbf{e}}
+\__umi_define_char{𝐟}{\umiMathbf{f}}
+\__umi_define_char{𝐠}{\umiMathbf{g}}
+\__umi_define_char{𝐡}{\umiMathbf{h}}
+\__umi_define_char{𝐢}{\umiMathbf{i}}
+\__umi_define_char{𝐣}{\umiMathbf{j}}
+\__umi_define_char{𝐤}{\umiMathbf{k}}
+\__umi_define_char{𝐥}{\umiMathbf{l}}
+\__umi_define_char{𝐦}{\umiMathbf{m}}
+\__umi_define_char{𝐧}{\umiMathbf{n}}
+\__umi_define_char{𝐨}{\umiMathbf{o}}
+\__umi_define_char{𝐩}{\umiMathbf{p}}
+\__umi_define_char{𝐪}{\umiMathbf{q}}
+\__umi_define_char{𝐫}{\umiMathbf{r}}
+\__umi_define_char{𝐬}{\umiMathbf{s}}
+\__umi_define_char{𝐭}{\umiMathbf{t}}
+\__umi_define_char{𝐮}{\umiMathbf{u}}
+\__umi_define_char{𝐯}{\umiMathbf{v}}
+\__umi_define_char{𝐰}{\umiMathbf{w}}
+\__umi_define_char{𝐱}{\umiMathbf{x}}
+\__umi_define_char{𝐲}{\umiMathbf{y}}
+\__umi_define_char{𝐳}{\umiMathbf{z}}
+\__umi_define_char{𝐴}{\umiMathit{A}}
+\__umi_define_char{𝐵}{\umiMathit{B}}
+\__umi_define_char{𝐶}{\umiMathit{C}}
+\__umi_define_char{𝐷}{\umiMathit{D}}
+\__umi_define_char{𝐸}{\umiMathit{E}}
+\__umi_define_char{𝐹}{\umiMathit{F}}
+\__umi_define_char{𝐺}{\umiMathit{G}}
+\__umi_define_char{𝐻}{\umiMathit{H}}
+\__umi_define_char{𝐼}{\umiMathit{I}}
+\__umi_define_char{𝐽}{\umiMathit{J}}
+\__umi_define_char{𝐾}{\umiMathit{K}}
+\__umi_define_char{𝐿}{\umiMathit{L}}
+\__umi_define_char{𝑀}{\umiMathit{M}}
+\__umi_define_char{𝑁}{\umiMathit{N}}
+\__umi_define_char{𝑂}{\umiMathit{O}}
+\__umi_define_char{𝑃}{\umiMathit{P}}
+\__umi_define_char{𝑄}{\umiMathit{Q}}
+\__umi_define_char{𝑅}{\umiMathit{R}}
+\__umi_define_char{𝑆}{\umiMathit{S}}
+\__umi_define_char{𝑇}{\umiMathit{T}}
+\__umi_define_char{𝑈}{\umiMathit{U}}
+\__umi_define_char{𝑉}{\umiMathit{V}}
+\__umi_define_char{𝑊}{\umiMathit{W}}
+\__umi_define_char{𝑋}{\umiMathit{X}}
+\__umi_define_char{𝑌}{\umiMathit{Y}}
+\__umi_define_char{𝑍}{\umiMathit{Z}}
+\__umi_define_char{𝑎}{\umiMathit{a}}
+\__umi_define_char{𝑏}{\umiMathit{b}}
+\__umi_define_char{𝑐}{\umiMathit{c}}
+\__umi_define_char{𝑑}{\umiMathit{d}}
+\__umi_define_char{𝑒}{\umiMathit{e}}
+\__umi_define_char{𝑓}{\umiMathit{f}}
+\__umi_define_char{𝑔}{\umiMathit{g}}
+\__umi_define_char{𝑖}{\umiMathit{i}}
+\__umi_define_char{𝑗}{\umiMathit{j}}
+\__umi_define_char{𝑘}{\umiMathit{k}}
+\__umi_define_char{𝑙}{\umiMathit{l}}
+\__umi_define_char{𝑚}{\umiMathit{m}}
+\__umi_define_char{𝑛}{\umiMathit{n}}
+\__umi_define_char{𝑜}{\umiMathit{o}}
+\__umi_define_char{𝑝}{\umiMathit{p}}
+\__umi_define_char{𝑞}{\umiMathit{q}}
+\__umi_define_char{𝑟}{\umiMathit{r}}
+\__umi_define_char{𝑠}{\umiMathit{s}}
+\__umi_define_char{𝑡}{\umiMathit{t}}
+\__umi_define_char{𝑢}{\umiMathit{u}}
+\__umi_define_char{𝑣}{\umiMathit{v}}
+\__umi_define_char{𝑤}{\umiMathit{w}}
+\__umi_define_char{𝑥}{\umiMathit{x}}
+\__umi_define_char{𝑦}{\umiMathit{y}}
+\__umi_define_char{𝑧}{\umiMathit{z}}
+\__umi_define_char{𝑨}{\umiMathbfit{A}}
+\__umi_define_char{𝑩}{\umiMathbfit{B}}
+\__umi_define_char{𝑪}{\umiMathbfit{C}}
+\__umi_define_char{𝑫}{\umiMathbfit{D}}
+\__umi_define_char{𝑬}{\umiMathbfit{E}}
+\__umi_define_char{𝑭}{\umiMathbfit{F}}
+\__umi_define_char{𝑮}{\umiMathbfit{G}}
+\__umi_define_char{𝑯}{\umiMathbfit{H}}
+\__umi_define_char{𝑰}{\umiMathbfit{I}}
+\__umi_define_char{𝑱}{\umiMathbfit{J}}
+\__umi_define_char{𝑲}{\umiMathbfit{K}}
+\__umi_define_char{𝑳}{\umiMathbfit{L}}
+\__umi_define_char{𝑴}{\umiMathbfit{M}}
+\__umi_define_char{𝑵}{\umiMathbfit{N}}
+\__umi_define_char{𝑶}{\umiMathbfit{O}}
+\__umi_define_char{𝑷}{\umiMathbfit{P}}
+\__umi_define_char{𝑸}{\umiMathbfit{Q}}
+\__umi_define_char{𝑹}{\umiMathbfit{R}}
+\__umi_define_char{𝑺}{\umiMathbfit{S}}
+\__umi_define_char{𝑻}{\umiMathbfit{T}}
+\__umi_define_char{𝑼}{\umiMathbfit{U}}
+\__umi_define_char{𝑽}{\umiMathbfit{V}}
+\__umi_define_char{𝑾}{\umiMathbfit{W}}
+\__umi_define_char{𝑿}{\umiMathbfit{X}}
+\__umi_define_char{𝒀}{\umiMathbfit{Y}}
+\__umi_define_char{𝒁}{\umiMathbfit{Z}}
+\__umi_define_char{𝒂}{\umiMathbfit{a}}
+\__umi_define_char{𝒃}{\umiMathbfit{b}}
+\__umi_define_char{𝒄}{\umiMathbfit{c}}
+\__umi_define_char{𝒅}{\umiMathbfit{d}}
+\__umi_define_char{𝒆}{\umiMathbfit{e}}
+\__umi_define_char{𝒇}{\umiMathbfit{f}}
+\__umi_define_char{𝒈}{\umiMathbfit{g}}
+\__umi_define_char{𝒉}{\umiMathbfit{h}}
+\__umi_define_char{𝒊}{\umiMathbfit{i}}
+\__umi_define_char{𝒋}{\umiMathbfit{j}}
+\__umi_define_char{𝒌}{\umiMathbfit{k}}
+\__umi_define_char{𝒍}{\umiMathbfit{l}}
+\__umi_define_char{𝒎}{\umiMathbfit{m}}
+\__umi_define_char{𝒏}{\umiMathbfit{n}}
+\__umi_define_char{𝒐}{\umiMathbfit{o}}
+\__umi_define_char{𝒑}{\umiMathbfit{p}}
+\__umi_define_char{𝒒}{\umiMathbfit{q}}
+\__umi_define_char{𝒓}{\umiMathbfit{r}}
+\__umi_define_char{𝒔}{\umiMathbfit{s}}
+\__umi_define_char{𝒕}{\umiMathbfit{t}}
+\__umi_define_char{𝒖}{\umiMathbfit{u}}
+\__umi_define_char{𝒗}{\umiMathbfit{v}}
+\__umi_define_char{𝒘}{\umiMathbfit{w}}
+\__umi_define_char{𝒙}{\umiMathbfit{x}}
+\__umi_define_char{𝒚}{\umiMathbfit{y}}
+\__umi_define_char{𝒛}{\umiMathbfit{z}}
+\__umi_define_char{𝒜}{\umiMathscr{A}}
+\__umi_define_char{𝒞}{\umiMathscr{C}}
+\__umi_define_char{𝒟}{\umiMathscr{D}}
+\__umi_define_char{𝒢}{\umiMathscr{G}}
+\__umi_define_char{𝒥}{\umiMathscr{J}}
+\__umi_define_char{𝒦}{\umiMathscr{K}}
+\__umi_define_char{𝒩}{\umiMathscr{N}}
+\__umi_define_char{𝒪}{\umiMathscr{O}}
+\__umi_define_char{𝒫}{\umiMathscr{P}}
+\__umi_define_char{𝒬}{\umiMathscr{Q}}
+\__umi_define_char{𝒮}{\umiMathscr{S}}
+\__umi_define_char{𝒯}{\umiMathscr{T}}
+\__umi_define_char{𝒰}{\umiMathscr{U}}
+\__umi_define_char{𝒱}{\umiMathscr{V}}
+\__umi_define_char{𝒲}{\umiMathscr{W}}
+\__umi_define_char{𝒳}{\umiMathscr{X}}
+\__umi_define_char{𝒴}{\umiMathscr{Y}}
+\__umi_define_char{𝒵}{\umiMathscr{Z}}
+\__umi_define_char{𝒶}{\umiMathscr{a}}
+\__umi_define_char{𝒷}{\umiMathscr{b}}
+\__umi_define_char{𝒸}{\umiMathscr{c}}
+\__umi_define_char{𝒹}{\umiMathscr{d}}
+\__umi_define_char{𝒻}{\umiMathscr{f}}
+\__umi_define_char{𝒽}{\umiMathscr{h}}
+\__umi_define_char{𝒾}{\umiMathscr{i}}
+\__umi_define_char{𝒿}{\umiMathscr{j}}
+\__umi_define_char{𝓀}{\umiMathscr{k}}
+\__umi_define_char{𝓁}{\umiMathscr{l}}
+\__umi_define_char{𝓂}{\umiMathscr{m}}
+\__umi_define_char{𝓃}{\umiMathscr{n}}
+\__umi_define_char{𝓅}{\umiMathscr{p}}
+\__umi_define_char{𝓆}{\umiMathscr{q}}
+\__umi_define_char{𝓇}{\umiMathscr{r}}
+\__umi_define_char{𝓈}{\umiMathscr{s}}
+\__umi_define_char{𝓉}{\umiMathscr{t}}
+\__umi_define_char{𝓊}{\umiMathscr{u}}
+\__umi_define_char{𝓋}{\umiMathscr{v}}
+\__umi_define_char{𝓌}{\umiMathscr{w}}
+\__umi_define_char{𝓍}{\umiMathscr{x}}
+\__umi_define_char{𝓎}{\umiMathscr{y}}
+\__umi_define_char{𝓏}{\umiMathscr{z}}
+\__umi_define_char{𝓐}{\umiMathbfscr{A}}
+\__umi_define_char{𝓑}{\umiMathbfscr{B}}
+\__umi_define_char{𝓒}{\umiMathbfscr{C}}
+\__umi_define_char{𝓓}{\umiMathbfscr{D}}
+\__umi_define_char{𝓔}{\umiMathbfscr{E}}
+\__umi_define_char{𝓕}{\umiMathbfscr{F}}
+\__umi_define_char{𝓖}{\umiMathbfscr{G}}
+\__umi_define_char{𝓗}{\umiMathbfscr{H}}
+\__umi_define_char{𝓘}{\umiMathbfscr{I}}
+\__umi_define_char{𝓙}{\umiMathbfscr{J}}
+\__umi_define_char{𝓚}{\umiMathbfscr{K}}
+\__umi_define_char{𝓛}{\umiMathbfscr{L}}
+\__umi_define_char{𝓜}{\umiMathbfscr{M}}
+\__umi_define_char{𝓝}{\umiMathbfscr{N}}
+\__umi_define_char{𝓞}{\umiMathbfscr{O}}
+\__umi_define_char{𝓟}{\umiMathbfscr{P}}
+\__umi_define_char{𝓠}{\umiMathbfscr{Q}}
+\__umi_define_char{𝓡}{\umiMathbfscr{R}}
+\__umi_define_char{𝓢}{\umiMathbfscr{S}}
+\__umi_define_char{𝓣}{\umiMathbfscr{T}}
+\__umi_define_char{𝓤}{\umiMathbfscr{U}}
+\__umi_define_char{𝓥}{\umiMathbfscr{V}}
+\__umi_define_char{𝓦}{\umiMathbfscr{W}}
+\__umi_define_char{𝓧}{\umiMathbfscr{X}}
+\__umi_define_char{𝓨}{\umiMathbfscr{Y}}
+\__umi_define_char{𝓩}{\umiMathbfscr{Z}}
+\__umi_define_char{𝓪}{\umiMathbfscr{a}}
+\__umi_define_char{𝓫}{\umiMathbfscr{b}}
+\__umi_define_char{𝓬}{\umiMathbfscr{c}}
+\__umi_define_char{𝓭}{\umiMathbfscr{d}}
+\__umi_define_char{𝓮}{\umiMathbfscr{e}}
+\__umi_define_char{𝓯}{\umiMathbfscr{f}}
+\__umi_define_char{𝓰}{\umiMathbfscr{g}}
+\__umi_define_char{𝓱}{\umiMathbfscr{h}}
+\__umi_define_char{𝓲}{\umiMathbfscr{i}}
+\__umi_define_char{𝓳}{\umiMathbfscr{j}}
+\__umi_define_char{𝓴}{\umiMathbfscr{k}}
+\__umi_define_char{𝓵}{\umiMathbfscr{l}}
+\__umi_define_char{𝓶}{\umiMathbfscr{m}}
+\__umi_define_char{𝓷}{\umiMathbfscr{n}}
+\__umi_define_char{𝓸}{\umiMathbfscr{o}}
+\__umi_define_char{𝓹}{\umiMathbfscr{p}}
+\__umi_define_char{𝓺}{\umiMathbfscr{q}}
+\__umi_define_char{𝓻}{\umiMathbfscr{r}}
+\__umi_define_char{𝓼}{\umiMathbfscr{s}}
+\__umi_define_char{𝓽}{\umiMathbfscr{t}}
+\__umi_define_char{𝓾}{\umiMathbfscr{u}}
+\__umi_define_char{𝓿}{\umiMathbfscr{v}}
+\__umi_define_char{𝔀}{\umiMathbfscr{w}}
+\__umi_define_char{𝔁}{\umiMathbfscr{x}}
+\__umi_define_char{𝔂}{\umiMathbfscr{y}}
+\__umi_define_char{𝔃}{\umiMathbfscr{z}}
+\__umi_define_char{𝔄}{\umiMathfrak{A}}
+\__umi_define_char{𝔅}{\umiMathfrak{B}}
+\__umi_define_char{𝔇}{\umiMathfrak{D}}
+\__umi_define_char{𝔈}{\umiMathfrak{E}}
+\__umi_define_char{𝔉}{\umiMathfrak{F}}
+\__umi_define_char{𝔊}{\umiMathfrak{G}}
+\__umi_define_char{𝔍}{\umiMathfrak{J}}
+\__umi_define_char{𝔎}{\umiMathfrak{K}}
+\__umi_define_char{𝔏}{\umiMathfrak{L}}
+\__umi_define_char{𝔐}{\umiMathfrak{M}}
+\__umi_define_char{𝔑}{\umiMathfrak{N}}
+\__umi_define_char{𝔒}{\umiMathfrak{O}}
+\__umi_define_char{𝔓}{\umiMathfrak{P}}
+\__umi_define_char{𝔔}{\umiMathfrak{Q}}
+\__umi_define_char{𝔖}{\umiMathfrak{S}}
+\__umi_define_char{𝔗}{\umiMathfrak{T}}
+\__umi_define_char{𝔘}{\umiMathfrak{U}}
+\__umi_define_char{𝔙}{\umiMathfrak{V}}
+\__umi_define_char{𝔚}{\umiMathfrak{W}}
+\__umi_define_char{𝔛}{\umiMathfrak{X}}
+\__umi_define_char{𝔜}{\umiMathfrak{Y}}
+\__umi_define_char{𝔞}{\umiMathfrak{a}}
+\__umi_define_char{𝔟}{\umiMathfrak{b}}
+\__umi_define_char{𝔠}{\umiMathfrak{c}}
+\__umi_define_char{𝔡}{\umiMathfrak{d}}
+\__umi_define_char{𝔢}{\umiMathfrak{e}}
+\__umi_define_char{𝔣}{\umiMathfrak{f}}
+\__umi_define_char{𝔤}{\umiMathfrak{g}}
+\__umi_define_char{𝔥}{\umiMathfrak{h}}
+\__umi_define_char{𝔦}{\umiMathfrak{i}}
+\__umi_define_char{𝔧}{\umiMathfrak{j}}
+\__umi_define_char{𝔨}{\umiMathfrak{k}}
+\__umi_define_char{𝔩}{\umiMathfrak{l}}
+\__umi_define_char{𝔪}{\umiMathfrak{m}}
+\__umi_define_char{𝔫}{\umiMathfrak{n}}
+\__umi_define_char{𝔬}{\umiMathfrak{o}}
+\__umi_define_char{𝔭}{\umiMathfrak{p}}
+\__umi_define_char{𝔮}{\umiMathfrak{q}}
+\__umi_define_char{𝔯}{\umiMathfrak{r}}
+\__umi_define_char{𝔰}{\umiMathfrak{s}}
+\__umi_define_char{𝔱}{\umiMathfrak{t}}
+\__umi_define_char{𝔲}{\umiMathfrak{u}}
+\__umi_define_char{𝔳}{\umiMathfrak{v}}
+\__umi_define_char{𝔴}{\umiMathfrak{w}}
+\__umi_define_char{𝔵}{\umiMathfrak{x}}
+\__umi_define_char{𝔶}{\umiMathfrak{y}}
+\__umi_define_char{𝔷}{\umiMathfrak{z}}
+\__umi_define_char{𝔸}{\umiMathbb{A}}
+\__umi_define_char{𝔹}{\umiMathbb{B}}
+\__umi_define_char{𝔻}{\umiMathbb{D}}
+\__umi_define_char{𝔼}{\umiMathbb{E}}
+\__umi_define_char{𝔽}{\umiMathbb{F}}
+\__umi_define_char{𝔾}{\umiMathbb{G}}
+\__umi_define_char{𝕀}{\umiMathbb{I}}
+\__umi_define_char{𝕁}{\umiMathbb{J}}
+\__umi_define_char{𝕂}{\umiMathbb{K}}
+\__umi_define_char{𝕃}{\umiMathbb{L}}
+\__umi_define_char{𝕄}{\umiMathbb{M}}
+\__umi_define_char{𝕆}{\umiMathbb{O}}
+\__umi_define_char{𝕊}{\umiMathbb{S}}
+\__umi_define_char{𝕋}{\umiMathbb{T}}
+\__umi_define_char{𝕌}{\umiMathbb{U}}
+\__umi_define_char{𝕍}{\umiMathbb{V}}
+\__umi_define_char{𝕎}{\umiMathbb{W}}
+\__umi_define_char{𝕏}{\umiMathbb{X}}
+\__umi_define_char{𝕐}{\umiMathbb{Y}}
+\__umi_define_char{𝕒}{\umiMathbb{a}}
+\__umi_define_char{𝕓}{\umiMathbb{b}}
+\__umi_define_char{𝕔}{\umiMathbb{c}}
+\__umi_define_char{𝕕}{\umiMathbb{d}}
+\__umi_define_char{𝕖}{\umiMathbb{e}}
+\__umi_define_char{𝕗}{\umiMathbb{f}}
+\__umi_define_char{𝕘}{\umiMathbb{g}}
+\__umi_define_char{𝕙}{\umiMathbb{h}}
+\__umi_define_char{𝕚}{\umiMathbb{i}}
+\__umi_define_char{𝕛}{\umiMathbb{j}}
+\__umi_define_char{𝕜}{\umiMathbb{k}}
+\__umi_define_char{𝕝}{\umiMathbb{l}}
+\__umi_define_char{𝕞}{\umiMathbb{m}}
+\__umi_define_char{𝕟}{\umiMathbb{n}}
+\__umi_define_char{𝕠}{\umiMathbb{o}}
+\__umi_define_char{𝕡}{\umiMathbb{p}}
+\__umi_define_char{𝕢}{\umiMathbb{q}}
+\__umi_define_char{𝕣}{\umiMathbb{r}}
+\__umi_define_char{𝕤}{\umiMathbb{s}}
+\__umi_define_char{𝕥}{\umiMathbb{t}}
+\__umi_define_char{𝕦}{\umiMathbb{u}}
+\__umi_define_char{𝕧}{\umiMathbb{v}}
+\__umi_define_char{𝕨}{\umiMathbb{w}}
+\__umi_define_char{𝕩}{\umiMathbb{x}}
+\__umi_define_char{𝕪}{\umiMathbb{y}}
+\__umi_define_char{𝕫}{\umiMathbb{z}}
+\__umi_define_char{𝕬}{\umiMathbffrak{A}}
+\__umi_define_char{𝕭}{\umiMathbffrak{B}}
+\__umi_define_char{𝕮}{\umiMathbffrak{C}}
+\__umi_define_char{𝕯}{\umiMathbffrak{D}}
+\__umi_define_char{𝕰}{\umiMathbffrak{E}}
+\__umi_define_char{𝕱}{\umiMathbffrak{F}}
+\__umi_define_char{𝕲}{\umiMathbffrak{G}}
+\__umi_define_char{𝕳}{\umiMathbffrak{H}}
+\__umi_define_char{𝕴}{\umiMathbffrak{I}}
+\__umi_define_char{𝕵}{\umiMathbffrak{J}}
+\__umi_define_char{𝕶}{\umiMathbffrak{K}}
+\__umi_define_char{𝕷}{\umiMathbffrak{L}}
+\__umi_define_char{𝕸}{\umiMathbffrak{M}}
+\__umi_define_char{𝕹}{\umiMathbffrak{N}}
+\__umi_define_char{𝕺}{\umiMathbffrak{O}}
+\__umi_define_char{𝕻}{\umiMathbffrak{P}}
+\__umi_define_char{𝕼}{\umiMathbffrak{Q}}
+\__umi_define_char{𝕽}{\umiMathbffrak{R}}
+\__umi_define_char{𝕾}{\umiMathbffrak{S}}
+\__umi_define_char{𝕿}{\umiMathbffrak{T}}
+\__umi_define_char{𝖀}{\umiMathbffrak{U}}
+\__umi_define_char{𝖁}{\umiMathbffrak{V}}
+\__umi_define_char{𝖂}{\umiMathbffrak{W}}
+\__umi_define_char{𝖃}{\umiMathbffrak{X}}
+\__umi_define_char{𝖄}{\umiMathbffrak{Y}}
+\__umi_define_char{𝖅}{\umiMathbffrak{Z}}
+\__umi_define_char{𝖆}{\umiMathbffrak{a}}
+\__umi_define_char{𝖇}{\umiMathbffrak{b}}
+\__umi_define_char{𝖈}{\umiMathbffrak{c}}
+\__umi_define_char{𝖉}{\umiMathbffrak{d}}
+\__umi_define_char{𝖊}{\umiMathbffrak{e}}
+\__umi_define_char{𝖋}{\umiMathbffrak{f}}
+\__umi_define_char{𝖌}{\umiMathbffrak{g}}
+\__umi_define_char{𝖍}{\umiMathbffrak{h}}
+\__umi_define_char{𝖎}{\umiMathbffrak{i}}
+\__umi_define_char{𝖏}{\umiMathbffrak{j}}
+\__umi_define_char{𝖐}{\umiMathbffrak{k}}
+\__umi_define_char{𝖑}{\umiMathbffrak{l}}
+\__umi_define_char{𝖒}{\umiMathbffrak{m}}
+\__umi_define_char{𝖓}{\umiMathbffrak{n}}
+\__umi_define_char{𝖔}{\umiMathbffrak{o}}
+\__umi_define_char{𝖕}{\umiMathbffrak{p}}
+\__umi_define_char{𝖖}{\umiMathbffrak{q}}
+\__umi_define_char{𝖗}{\umiMathbffrak{r}}
+\__umi_define_char{𝖘}{\umiMathbffrak{s}}
+\__umi_define_char{𝖙}{\umiMathbffrak{t}}
+\__umi_define_char{𝖚}{\umiMathbffrak{u}}
+\__umi_define_char{𝖛}{\umiMathbffrak{v}}
+\__umi_define_char{𝖜}{\umiMathbffrak{w}}
+\__umi_define_char{𝖝}{\umiMathbffrak{x}}
+\__umi_define_char{𝖞}{\umiMathbffrak{y}}
+\__umi_define_char{𝖟}{\umiMathbffrak{z}}
+\__umi_define_char{𝖠}{\umiMathsf{A}}
+\__umi_define_char{𝖡}{\umiMathsf{B}}
+\__umi_define_char{𝖢}{\umiMathsf{C}}
+\__umi_define_char{𝖣}{\umiMathsf{D}}
+\__umi_define_char{𝖤}{\umiMathsf{E}}
+\__umi_define_char{𝖥}{\umiMathsf{F}}
+\__umi_define_char{𝖦}{\umiMathsf{G}}
+\__umi_define_char{𝖧}{\umiMathsf{H}}
+\__umi_define_char{𝖨}{\umiMathsf{I}}
+\__umi_define_char{𝖩}{\umiMathsf{J}}
+\__umi_define_char{𝖪}{\umiMathsf{K}}
+\__umi_define_char{𝖫}{\umiMathsf{L}}
+\__umi_define_char{𝖬}{\umiMathsf{M}}
+\__umi_define_char{𝖭}{\umiMathsf{N}}
+\__umi_define_char{𝖮}{\umiMathsf{O}}
+\__umi_define_char{𝖯}{\umiMathsf{P}}
+\__umi_define_char{𝖰}{\umiMathsf{Q}}
+\__umi_define_char{𝖱}{\umiMathsf{R}}
+\__umi_define_char{𝖲}{\umiMathsf{S}}
+\__umi_define_char{𝖳}{\umiMathsf{T}}
+\__umi_define_char{𝖴}{\umiMathsf{U}}
+\__umi_define_char{𝖵}{\umiMathsf{V}}
+\__umi_define_char{𝖶}{\umiMathsf{W}}
+\__umi_define_char{𝖷}{\umiMathsf{X}}
+\__umi_define_char{𝖸}{\umiMathsf{Y}}
+\__umi_define_char{𝖹}{\umiMathsf{Z}}
+\__umi_define_char{𝖺}{\umiMathsf{a}}
+\__umi_define_char{𝖻}{\umiMathsf{b}}
+\__umi_define_char{𝖼}{\umiMathsf{c}}
+\__umi_define_char{𝖽}{\umiMathsf{d}}
+\__umi_define_char{𝖾}{\umiMathsf{e}}
+\__umi_define_char{𝖿}{\umiMathsf{f}}
+\__umi_define_char{𝗀}{\umiMathsf{g}}
+\__umi_define_char{𝗁}{\umiMathsf{h}}
+\__umi_define_char{𝗂}{\umiMathsf{i}}
+\__umi_define_char{𝗃}{\umiMathsf{j}}
+\__umi_define_char{𝗄}{\umiMathsf{k}}
+\__umi_define_char{𝗅}{\umiMathsf{l}}
+\__umi_define_char{𝗆}{\umiMathsf{m}}
+\__umi_define_char{𝗇}{\umiMathsf{n}}
+\__umi_define_char{𝗈}{\umiMathsf{o}}
+\__umi_define_char{𝗉}{\umiMathsf{p}}
+\__umi_define_char{𝗊}{\umiMathsf{q}}
+\__umi_define_char{𝗋}{\umiMathsf{r}}
+\__umi_define_char{𝗌}{\umiMathsf{s}}
+\__umi_define_char{𝗍}{\umiMathsf{t}}
+\__umi_define_char{𝗎}{\umiMathsf{u}}
+\__umi_define_char{𝗏}{\umiMathsf{v}}
+\__umi_define_char{𝗐}{\umiMathsf{w}}
+\__umi_define_char{𝗑}{\umiMathsf{x}}
+\__umi_define_char{𝗒}{\umiMathsf{y}}
+\__umi_define_char{𝗓}{\umiMathsf{z}}
+\__umi_define_char{𝗔}{\umiMathsfbf{A}}
+\__umi_define_char{𝗕}{\umiMathsfbf{B}}
+\__umi_define_char{𝗖}{\umiMathsfbf{C}}
+\__umi_define_char{𝗗}{\umiMathsfbf{D}}
+\__umi_define_char{𝗘}{\umiMathsfbf{E}}
+\__umi_define_char{𝗙}{\umiMathsfbf{F}}
+\__umi_define_char{𝗚}{\umiMathsfbf{G}}
+\__umi_define_char{𝗛}{\umiMathsfbf{H}}
+\__umi_define_char{𝗜}{\umiMathsfbf{I}}
+\__umi_define_char{𝗝}{\umiMathsfbf{J}}
+\__umi_define_char{𝗞}{\umiMathsfbf{K}}
+\__umi_define_char{𝗟}{\umiMathsfbf{L}}
+\__umi_define_char{𝗠}{\umiMathsfbf{M}}
+\__umi_define_char{𝗡}{\umiMathsfbf{N}}
+\__umi_define_char{𝗢}{\umiMathsfbf{O}}
+\__umi_define_char{𝗣}{\umiMathsfbf{P}}
+\__umi_define_char{𝗤}{\umiMathsfbf{Q}}
+\__umi_define_char{𝗥}{\umiMathsfbf{R}}
+\__umi_define_char{𝗦}{\umiMathsfbf{S}}
+\__umi_define_char{𝗧}{\umiMathsfbf{T}}
+\__umi_define_char{𝗨}{\umiMathsfbf{U}}
+\__umi_define_char{𝗩}{\umiMathsfbf{V}}
+\__umi_define_char{𝗪}{\umiMathsfbf{W}}
+\__umi_define_char{𝗫}{\umiMathsfbf{X}}
+\__umi_define_char{𝗬}{\umiMathsfbf{Y}}
+\__umi_define_char{𝗭}{\umiMathsfbf{Z}}
+\__umi_define_char{𝗮}{\umiMathsfbf{a}}
+\__umi_define_char{𝗯}{\umiMathsfbf{b}}
+\__umi_define_char{𝗰}{\umiMathsfbf{c}}
+\__umi_define_char{𝗱}{\umiMathsfbf{d}}
+\__umi_define_char{𝗲}{\umiMathsfbf{e}}
+\__umi_define_char{𝗳}{\umiMathsfbf{f}}
+\__umi_define_char{𝗴}{\umiMathsfbf{g}}
+\__umi_define_char{𝗵}{\umiMathsfbf{h}}
+\__umi_define_char{𝗶}{\umiMathsfbf{i}}
+\__umi_define_char{𝗷}{\umiMathsfbf{j}}
+\__umi_define_char{𝗸}{\umiMathsfbf{k}}
+\__umi_define_char{𝗹}{\umiMathsfbf{l}}
+\__umi_define_char{𝗺}{\umiMathsfbf{m}}
+\__umi_define_char{𝗻}{\umiMathsfbf{n}}
+\__umi_define_char{𝗼}{\umiMathsfbf{o}}
+\__umi_define_char{𝗽}{\umiMathsfbf{p}}
+\__umi_define_char{𝗾}{\umiMathsfbf{q}}
+\__umi_define_char{𝗿}{\umiMathsfbf{r}}
+\__umi_define_char{𝘀}{\umiMathsfbf{s}}
+\__umi_define_char{𝘁}{\umiMathsfbf{t}}
+\__umi_define_char{𝘂}{\umiMathsfbf{u}}
+\__umi_define_char{𝘃}{\umiMathsfbf{v}}
+\__umi_define_char{𝘄}{\umiMathsfbf{w}}
+\__umi_define_char{𝘅}{\umiMathsfbf{x}}
+\__umi_define_char{𝘆}{\umiMathsfbf{y}}
+\__umi_define_char{𝘇}{\umiMathsfbf{z}}
+\__umi_define_char{𝘈}{\umiMathsfit{A}}
+\__umi_define_char{𝘉}{\umiMathsfit{B}}
+\__umi_define_char{𝘊}{\umiMathsfit{C}}
+\__umi_define_char{𝘋}{\umiMathsfit{D}}
+\__umi_define_char{𝘌}{\umiMathsfit{E}}
+\__umi_define_char{𝘍}{\umiMathsfit{F}}
+\__umi_define_char{𝘎}{\umiMathsfit{G}}
+\__umi_define_char{𝘏}{\umiMathsfit{H}}
+\__umi_define_char{𝘐}{\umiMathsfit{I}}
+\__umi_define_char{𝘑}{\umiMathsfit{J}}
+\__umi_define_char{𝘒}{\umiMathsfit{K}}
+\__umi_define_char{𝘓}{\umiMathsfit{L}}
+\__umi_define_char{𝘔}{\umiMathsfit{M}}
+\__umi_define_char{𝘕}{\umiMathsfit{N}}
+\__umi_define_char{𝘖}{\umiMathsfit{O}}
+\__umi_define_char{𝘗}{\umiMathsfit{P}}
+\__umi_define_char{𝘘}{\umiMathsfit{Q}}
+\__umi_define_char{𝘙}{\umiMathsfit{R}}
+\__umi_define_char{𝘚}{\umiMathsfit{S}}
+\__umi_define_char{𝘛}{\umiMathsfit{T}}
+\__umi_define_char{𝘜}{\umiMathsfit{U}}
+\__umi_define_char{𝘝}{\umiMathsfit{V}}
+\__umi_define_char{𝘞}{\umiMathsfit{W}}
+\__umi_define_char{𝘟}{\umiMathsfit{X}}
+\__umi_define_char{𝘠}{\umiMathsfit{Y}}
+\__umi_define_char{𝘡}{\umiMathsfit{Z}}
+\__umi_define_char{𝘢}{\umiMathsfit{a}}
+\__umi_define_char{𝘣}{\umiMathsfit{b}}
+\__umi_define_char{𝘤}{\umiMathsfit{c}}
+\__umi_define_char{𝘥}{\umiMathsfit{d}}
+\__umi_define_char{𝘦}{\umiMathsfit{e}}
+\__umi_define_char{𝘧}{\umiMathsfit{f}}
+\__umi_define_char{𝘨}{\umiMathsfit{g}}
+\__umi_define_char{𝘩}{\umiMathsfit{h}}
+\__umi_define_char{𝘪}{\umiMathsfit{i}}
+\__umi_define_char{𝘫}{\umiMathsfit{j}}
+\__umi_define_char{𝘬}{\umiMathsfit{k}}
+\__umi_define_char{𝘭}{\umiMathsfit{l}}
+\__umi_define_char{𝘮}{\umiMathsfit{m}}
+\__umi_define_char{𝘯}{\umiMathsfit{n}}
+\__umi_define_char{𝘰}{\umiMathsfit{o}}
+\__umi_define_char{𝘱}{\umiMathsfit{p}}
+\__umi_define_char{𝘲}{\umiMathsfit{q}}
+\__umi_define_char{𝘳}{\umiMathsfit{r}}
+\__umi_define_char{𝘴}{\umiMathsfit{s}}
+\__umi_define_char{𝘵}{\umiMathsfit{t}}
+\__umi_define_char{𝘶}{\umiMathsfit{u}}
+\__umi_define_char{𝘷}{\umiMathsfit{v}}
+\__umi_define_char{𝘸}{\umiMathsfit{w}}
+\__umi_define_char{𝘹}{\umiMathsfit{x}}
+\__umi_define_char{𝘺}{\umiMathsfit{y}}
+\__umi_define_char{𝘻}{\umiMathsfit{z}}
+\__umi_define_char{𝘼}{\umiMathsfbfit{A}}
+\__umi_define_char{𝘽}{\umiMathsfbfit{B}}
+\__umi_define_char{𝘾}{\umiMathsfbfit{C}}
+\__umi_define_char{𝘿}{\umiMathsfbfit{D}}
+\__umi_define_char{𝙀}{\umiMathsfbfit{E}}
+\__umi_define_char{𝙁}{\umiMathsfbfit{F}}
+\__umi_define_char{𝙂}{\umiMathsfbfit{G}}
+\__umi_define_char{𝙃}{\umiMathsfbfit{H}}
+\__umi_define_char{𝙄}{\umiMathsfbfit{I}}
+\__umi_define_char{𝙅}{\umiMathsfbfit{J}}
+\__umi_define_char{𝙆}{\umiMathsfbfit{K}}
+\__umi_define_char{𝙇}{\umiMathsfbfit{L}}
+\__umi_define_char{𝙈}{\umiMathsfbfit{M}}
+\__umi_define_char{𝙉}{\umiMathsfbfit{N}}
+\__umi_define_char{𝙊}{\umiMathsfbfit{O}}
+\__umi_define_char{𝙋}{\umiMathsfbfit{P}}
+\__umi_define_char{𝙌}{\umiMathsfbfit{Q}}
+\__umi_define_char{𝙍}{\umiMathsfbfit{R}}
+\__umi_define_char{𝙎}{\umiMathsfbfit{S}}
+\__umi_define_char{𝙏}{\umiMathsfbfit{T}}
+\__umi_define_char{𝙐}{\umiMathsfbfit{U}}
+\__umi_define_char{𝙑}{\umiMathsfbfit{V}}
+\__umi_define_char{𝙒}{\umiMathsfbfit{W}}
+\__umi_define_char{𝙓}{\umiMathsfbfit{X}}
+\__umi_define_char{𝙔}{\umiMathsfbfit{Y}}
+\__umi_define_char{𝙕}{\umiMathsfbfit{Z}}
+\__umi_define_char{𝙖}{\umiMathsfbfit{a}}
+\__umi_define_char{𝙗}{\umiMathsfbfit{b}}
+\__umi_define_char{𝙘}{\umiMathsfbfit{c}}
+\__umi_define_char{𝙙}{\umiMathsfbfit{d}}
+\__umi_define_char{𝙚}{\umiMathsfbfit{e}}
+\__umi_define_char{𝙛}{\umiMathsfbfit{f}}
+\__umi_define_char{𝙜}{\umiMathsfbfit{g}}
+\__umi_define_char{𝙝}{\umiMathsfbfit{h}}
+\__umi_define_char{𝙞}{\umiMathsfbfit{i}}
+\__umi_define_char{𝙟}{\umiMathsfbfit{j}}
+\__umi_define_char{𝙠}{\umiMathsfbfit{k}}
+\__umi_define_char{𝙡}{\umiMathsfbfit{l}}
+\__umi_define_char{𝙢}{\umiMathsfbfit{m}}
+\__umi_define_char{𝙣}{\umiMathsfbfit{n}}
+\__umi_define_char{𝙤}{\umiMathsfbfit{o}}
+\__umi_define_char{𝙥}{\umiMathsfbfit{p}}
+\__umi_define_char{𝙦}{\umiMathsfbfit{q}}
+\__umi_define_char{𝙧}{\umiMathsfbfit{r}}
+\__umi_define_char{𝙨}{\umiMathsfbfit{s}}
+\__umi_define_char{𝙩}{\umiMathsfbfit{t}}
+\__umi_define_char{𝙪}{\umiMathsfbfit{u}}
+\__umi_define_char{𝙫}{\umiMathsfbfit{v}}
+\__umi_define_char{𝙬}{\umiMathsfbfit{w}}
+\__umi_define_char{𝙭}{\umiMathsfbfit{x}}
+\__umi_define_char{𝙮}{\umiMathsfbfit{y}}
+\__umi_define_char{𝙯}{\umiMathsfbfit{z}}
+\__umi_define_char{𝙰}{\umiMathtt{A}}
+\__umi_define_char{𝙱}{\umiMathtt{B}}
+\__umi_define_char{𝙲}{\umiMathtt{C}}
+\__umi_define_char{𝙳}{\umiMathtt{D}}
+\__umi_define_char{𝙴}{\umiMathtt{E}}
+\__umi_define_char{𝙵}{\umiMathtt{F}}
+\__umi_define_char{𝙶}{\umiMathtt{G}}
+\__umi_define_char{𝙷}{\umiMathtt{H}}
+\__umi_define_char{𝙸}{\umiMathtt{I}}
+\__umi_define_char{𝙹}{\umiMathtt{J}}
+\__umi_define_char{𝙺}{\umiMathtt{K}}
+\__umi_define_char{𝙻}{\umiMathtt{L}}
+\__umi_define_char{𝙼}{\umiMathtt{M}}
+\__umi_define_char{𝙽}{\umiMathtt{N}}
+\__umi_define_char{𝙾}{\umiMathtt{O}}
+\__umi_define_char{𝙿}{\umiMathtt{P}}
+\__umi_define_char{𝚀}{\umiMathtt{Q}}
+\__umi_define_char{𝚁}{\umiMathtt{R}}
+\__umi_define_char{𝚂}{\umiMathtt{S}}
+\__umi_define_char{𝚃}{\umiMathtt{T}}
+\__umi_define_char{𝚄}{\umiMathtt{U}}
+\__umi_define_char{𝚅}{\umiMathtt{V}}
+\__umi_define_char{𝚆}{\umiMathtt{W}}
+\__umi_define_char{𝚇}{\umiMathtt{X}}
+\__umi_define_char{𝚈}{\umiMathtt{Y}}
+\__umi_define_char{𝚉}{\umiMathtt{Z}}
+\__umi_define_char{𝚊}{\umiMathtt{a}}
+\__umi_define_char{𝚋}{\umiMathtt{b}}
+\__umi_define_char{𝚌}{\umiMathtt{c}}
+\__umi_define_char{𝚍}{\umiMathtt{d}}
+\__umi_define_char{𝚎}{\umiMathtt{e}}
+\__umi_define_char{𝚏}{\umiMathtt{f}}
+\__umi_define_char{𝚐}{\umiMathtt{g}}
+\__umi_define_char{𝚑}{\umiMathtt{h}}
+\__umi_define_char{𝚒}{\umiMathtt{i}}
+\__umi_define_char{𝚓}{\umiMathtt{j}}
+\__umi_define_char{𝚔}{\umiMathtt{k}}
+\__umi_define_char{𝚕}{\umiMathtt{l}}
+\__umi_define_char{𝚖}{\umiMathtt{m}}
+\__umi_define_char{𝚗}{\umiMathtt{n}}
+\__umi_define_char{𝚘}{\umiMathtt{o}}
+\__umi_define_char{𝚙}{\umiMathtt{p}}
+\__umi_define_char{𝚚}{\umiMathtt{q}}
+\__umi_define_char{𝚛}{\umiMathtt{r}}
+\__umi_define_char{𝚜}{\umiMathtt{s}}
+\__umi_define_char{𝚝}{\umiMathtt{t}}
+\__umi_define_char{𝚞}{\umiMathtt{u}}
+\__umi_define_char{𝚟}{\umiMathtt{v}}
+\__umi_define_char{𝚠}{\umiMathtt{w}}
+\__umi_define_char{𝚡}{\umiMathtt{x}}
+\__umi_define_char{𝚢}{\umiMathtt{y}}
+\__umi_define_char{𝚣}{\umiMathtt{z}}
+\__umi_define_char{𝚤}{\imath}
+\__umi_define_char{𝚥}{\jmath}
+\__umi_define_char{𝚨}{\umiMathbf{\__umi_alternatives_iisafe\Alpha A}}
+\__umi_define_char{𝚩}{\umiMathbf{\__umi_alternatives_iisafe\Beta B}}
+\__umi_define_char{𝚪}{\umiMathbf{\Gamma}}
+\__umi_define_char{𝚫}{\umiMathbf{\Delta}}
+\__umi_define_char{𝚬}{\umiMathbf{\__umi_alternatives_iisafe\Epsilon E}}
+\__umi_define_char{𝚭}{\umiMathbf{\__umi_alternatives_iisafe\Zeta Z}}
+\__umi_define_char{𝚮}{\umiMathbf{\__umi_alternatives_iisafe\Eta H}}
+\__umi_define_char{𝚯}{\umiMathbf{\Theta}}
+\__umi_define_char{𝚰}{\umiMathbf{\__umi_alternatives_iisafe\Iota I}}
+\__umi_define_char{𝚱}{\umiMathbf{\__umi_alternatives_iisafe\Kappa K}}
+\__umi_define_char{𝚲}{\umiMathbf{\Lambda}}
+\__umi_define_char{𝚳}{\umiMathbf{\__umi_alternatives_iisafe\Mu M}}
+\__umi_define_char{𝚴}{\umiMathbf{\__umi_alternatives_iisafe\Nu N}}
+\__umi_define_char{𝚵}{\umiMathbf{\Xi}}
+\__umi_define_char{𝚶}{\umiMathbf{\__umi_alternatives_iisafe\Omicron O}}
+\__umi_define_char{𝚷}{\umiMathbf{\Pi}}
+\__umi_define_char{𝚸}{\umiMathbf{\__umi_alternatives_iisafe\Rho P}}
+\__umi_define_char{𝚹}{\umiMathbf{\varTheta}}
+\__umi_define_char{𝚺}{\umiMathbf{\Sigma}}
+\__umi_define_char{𝚻}{\umiMathbf{\__umi_alternatives_iisafe\Tau T}}
+\__umi_define_char{𝚼}{\umiMathbf{\Upsilon}}
+\__umi_define_char{𝚽}{\umiMathbf{\Phi}}
+\__umi_define_char{𝚾}{\umiMathbf{\__umi_alternatives_iisafe\Chi X}}
+\__umi_define_char{𝚿}{\umiMathbf{\Psi}}
+\__umi_define_char{𝛀}{\umiMathbf{\Omega}}
+\__umi_define_char{𝛁}{\umiMathbf{\nabla}}
+\__umi_define_char{𝛂}{\umiMathbf{\alpha}}
+\__umi_define_char{𝛃}{\umiMathbf{\beta}}
+\__umi_define_char{𝛄}{\umiMathbf{\gamma}}
+\__umi_define_char{𝛅}{\umiMathbf{\delta}}
+\__umi_define_char{𝛆}{\umiMathbf{\varepsilon}}
+\__umi_define_char{𝛇}{\umiMathbf{\zeta}}
+\__umi_define_char{𝛈}{\umiMathbf{\eta}}
+\__umi_define_char{𝛉}{\umiMathbf{\theta}}
+\__umi_define_char{𝛊}{\umiMathbf{\iota}}
+\__umi_define_char{𝛋}{\umiMathbf{\kappa}}
+\__umi_define_char{𝛌}{\umiMathbf{\lambda}}
+\__umi_define_char{𝛍}{\umiMathbf{\mu}}
+\__umi_define_char{𝛎}{\umiMathbf{\nu}}
+\__umi_define_char{𝛏}{\umiMathbf{\xi}}
+\__umi_define_char{𝛐}{\umiMathbf{\__umi_alternatives_iisafe\omicron o}}
+\__umi_define_char{𝛑}{\umiMathbf{\pi}}
+\__umi_define_char{𝛒}{\umiMathbf{\rho}}
+\__umi_define_char{𝛓}{\umiMathbf{\varsigma}}
+\__umi_define_char{𝛔}{\umiMathbf{\sigma}}
+\__umi_define_char{𝛕}{\umiMathbf{\tau}}
+\__umi_define_char{𝛖}{\umiMathbf{\upsilon}}
+\__umi_define_char{𝛗}{\umiMathbf{\varphi}}
+\__umi_define_char{𝛘}{\umiMathbf{\chi}}
+\__umi_define_char{𝛙}{\umiMathbf{\psi}}
+\__umi_define_char{𝛚}{\umiMathbf{\omega}}
+\__umi_define_char{𝛛}{\umiMathbf{\partial}}
+\__umi_define_char{𝛜}{\umiMathbf{\epsilon}}
+\__umi_define_char{𝛝}{\umiMathbf{\vartheta}}
+\__umi_define_char{𝛞}{\umiMathbf{\varkappa}}
+\__umi_define_char{𝛟}{\umiMathbf{\phi}}
+\__umi_define_char{𝛠}{\umiMathbf{\varrho}}
+\__umi_define_char{𝛡}{\umiMathbf{\varpi}}
+\__umi_define_char{𝛢}{\umiMathit{\__umi_alternatives_iisafe\Alpha A}}
+\__umi_define_char{𝛣}{\umiMathit{\__umi_alternatives_iisafe\Beta B}}
+\__umi_define_char{𝛤}{\umiMathit{\Gamma}}
+\__umi_define_char{𝛥}{\umiMathit{\Delta}}
+\__umi_define_char{𝛦}{\umiMathit{\__umi_alternatives_iisafe\Epsilon E}}
+\__umi_define_char{𝛧}{\umiMathit{\__umi_alternatives_iisafe\Zeta Z}}
+\__umi_define_char{𝛨}{\umiMathit{\__umi_alternatives_iisafe\Eta H}}
+\__umi_define_char{𝛩}{\umiMathit{\Theta}}
+\__umi_define_char{𝛪}{\umiMathit{\__umi_alternatives_iisafe\Iota I}}
+\__umi_define_char{𝛫}{\umiMathit{\__umi_alternatives_iisafe\Kappa K}}
+\__umi_define_char{𝛬}{\umiMathit{\Lambda}}
+\__umi_define_char{𝛭}{\umiMathit{\__umi_alternatives_iisafe\Mu M}}
+\__umi_define_char{𝛮}{\umiMathit{\__umi_alternatives_iisafe\Nu N}}
+\__umi_define_char{𝛯}{\umiMathit{\Xi}}
+\__umi_define_char{𝛰}{\umiMathit{\__umi_alternatives_iisafe\Omicron O}}
+\__umi_define_char{𝛱}{\umiMathit{\Pi}}
+\__umi_define_char{𝛲}{\umiMathit{\__umi_alternatives_iisafe\Rho P}}
+\__umi_define_char{𝛳}{\umiMathit{\varTheta}}
+\__umi_define_char{𝛴}{\umiMathit{\Sigma}}
+\__umi_define_char{𝛵}{\umiMathit{\__umi_alternatives_iisafe\Tau T}}
+\__umi_define_char{𝛶}{\umiMathit{\Upsilon}}
+\__umi_define_char{𝛷}{\umiMathit{\Phi}}
+\__umi_define_char{𝛸}{\umiMathit{\__umi_alternatives_iisafe\Chi X}}
+\__umi_define_char{𝛹}{\umiMathit{\Psi}}
+\__umi_define_char{𝛺}{\umiMathit{\Omega}}
+\__umi_define_char{𝛻}{\umiMathit{\nabla}}
+\__umi_define_char{𝛼}{\umiMathit{\alpha}}
+\__umi_define_char{𝛽}{\umiMathit{\beta}}
+\__umi_define_char{𝛾}{\umiMathit{\gamma}}
+\__umi_define_char{𝛿}{\umiMathit{\delta}}
+\__umi_define_char{𝜀}{\umiMathit{\varepsilon}}
+\__umi_define_char{𝜁}{\umiMathit{\zeta}}
+\__umi_define_char{𝜂}{\umiMathit{\eta}}
+\__umi_define_char{𝜃}{\umiMathit{\theta}}
+\__umi_define_char{𝜄}{\umiMathit{\iota}}
+\__umi_define_char{𝜅}{\umiMathit{\kappa}}
+\__umi_define_char{𝜆}{\umiMathit{\lambda}}
+\__umi_define_char{𝜇}{\umiMathit{\mu}}
+\__umi_define_char{𝜈}{\umiMathit{\nu}}
+\__umi_define_char{𝜉}{\umiMathit{\xi}}
+\__umi_define_char{𝜊}{\umiMathit{\__umi_alternatives_iisafe\omicron o}}
+\__umi_define_char{𝜋}{\umiMathit{\pi}}
+\__umi_define_char{𝜌}{\umiMathit{\rho}}
+\__umi_define_char{𝜍}{\umiMathit{\varsigma}}
+\__umi_define_char{𝜎}{\umiMathit{\sigma}}
+\__umi_define_char{𝜏}{\umiMathit{\tau}}
+\__umi_define_char{𝜐}{\umiMathit{\upsilon}}
+\__umi_define_char{𝜑}{\umiMathit{\varphi}}
+\__umi_define_char{𝜒}{\umiMathit{\chi}}
+\__umi_define_char{𝜓}{\umiMathit{\psi}}
+\__umi_define_char{𝜔}{\umiMathit{\omega}}
+\__umi_define_char{𝜕}{\umiMathit{\partial}}
+\__umi_define_char{𝜖}{\umiMathit{\epsilon}}
+\__umi_define_char{𝜗}{\umiMathit{\vartheta}}
+\__umi_define_char{𝜘}{\umiMathit{\varkappa}}
+\__umi_define_char{𝜙}{\umiMathit{\phi}}
+\__umi_define_char{𝜚}{\umiMathit{\varrho}}
+\__umi_define_char{𝜛}{\umiMathit{\varpi}}
+\__umi_define_char{𝜜}{\umiMathbfit{\__umi_alternatives_iisafe\Alpha A}}
+\__umi_define_char{𝜝}{\umiMathbfit{\__umi_alternatives_iisafe\Beta B}}
+\__umi_define_char{𝜞}{\umiMathbfit{\Gamma}}
+\__umi_define_char{𝜟}{\umiMathbfit{\Delta}}
+\__umi_define_char{𝜠}{\umiMathbfit{\__umi_alternatives_iisafe\Epsilon E}}
+\__umi_define_char{𝜡}{\umiMathbfit{\__umi_alternatives_iisafe\Zeta Z}}
+\__umi_define_char{𝜢}{\umiMathbfit{\__umi_alternatives_iisafe\Eta H}}
+\__umi_define_char{𝜣}{\umiMathbfit{\Theta}}
+\__umi_define_char{𝜤}{\umiMathbfit{\__umi_alternatives_iisafe\Iota I}}
+\__umi_define_char{𝜥}{\umiMathbfit{\__umi_alternatives_iisafe\Kappa K}}
+\__umi_define_char{𝜦}{\umiMathbfit{\Lambda}}
+\__umi_define_char{𝜧}{\umiMathbfit{\__umi_alternatives_iisafe\Mu M}}
+\__umi_define_char{𝜨}{\umiMathbfit{\__umi_alternatives_iisafe\Nu N}}
+\__umi_define_char{𝜩}{\umiMathbfit{\Xi}}
+\__umi_define_char{𝜪}{\umiMathbfit{\__umi_alternatives_iisafe\Omicron O}}
+\__umi_define_char{𝜫}{\umiMathbfit{\Pi}}
+\__umi_define_char{𝜬}{\umiMathbfit{\__umi_alternatives_iisafe\Rho P}}
+\__umi_define_char{𝜭}{\umiMathbfit{\varTheta}}
+\__umi_define_char{𝜮}{\umiMathbfit{\Sigma}}
+\__umi_define_char{𝜯}{\umiMathbfit{\__umi_alternatives_iisafe\Tau T}}
+\__umi_define_char{𝜰}{\umiMathbfit{\Upsilon}}
+\__umi_define_char{𝜱}{\umiMathbfit{\Phi}}
+\__umi_define_char{𝜲}{\umiMathbfit{\__umi_alternatives_iisafe\Chi X}}
+\__umi_define_char{𝜳}{\umiMathbfit{\Psi}}
+\__umi_define_char{𝜴}{\umiMathbfit{\Omega}}
+\__umi_define_char{𝜵}{\umiMathbfit{\nabla}}
+\__umi_define_char{𝜶}{\umiMathbfit{\alpha}}
+\__umi_define_char{𝜷}{\umiMathbfit{\beta}}
+\__umi_define_char{𝜸}{\umiMathbfit{\gamma}}
+\__umi_define_char{𝜹}{\umiMathbfit{\delta}}
+\__umi_define_char{𝜺}{\umiMathbfit{\varepsilon}}
+\__umi_define_char{𝜻}{\umiMathbfit{\zeta}}
+\__umi_define_char{𝜼}{\umiMathbfit{\eta}}
+\__umi_define_char{𝜽}{\umiMathbfit{\theta}}
+\__umi_define_char{𝜾}{\umiMathbfit{\iota}}
+\__umi_define_char{𝜿}{\umiMathbfit{\kappa}}
+\__umi_define_char{𝝀}{\umiMathbfit{\lambda}}
+\__umi_define_char{𝝁}{\umiMathbfit{\mu}}
+\__umi_define_char{𝝂}{\umiMathbfit{\nu}}
+\__umi_define_char{𝝃}{\umiMathbfit{\xi}}
+\__umi_define_char{𝝄}{\umiMathbfit{\__umi_alternatives_iisafe\omicron o}}
+\__umi_define_char{𝝅}{\umiMathbfit{\pi}}
+\__umi_define_char{𝝆}{\umiMathbfit{\rho}}
+\__umi_define_char{𝝇}{\umiMathbfit{\varsigma}}
+\__umi_define_char{𝝈}{\umiMathbfit{\sigma}}
+\__umi_define_char{𝝉}{\umiMathbfit{\tau}}
+\__umi_define_char{𝝊}{\umiMathbfit{\upsilon}}
+\__umi_define_char{𝝋}{\umiMathbfit{\varphi}}
+\__umi_define_char{𝝌}{\umiMathbfit{\chi}}
+\__umi_define_char{𝝍}{\umiMathbfit{\psi}}
+\__umi_define_char{𝝎}{\umiMathbfit{\omega}}
+\__umi_define_char{𝝏}{\umiMathbfit{\partial}}
+\__umi_define_char{𝝐}{\umiMathbfit{\epsilon}}
+\__umi_define_char{𝝑}{\umiMathbfit{\vartheta}}
+\__umi_define_char{𝝒}{\umiMathbfit{\varkappa}}
+\__umi_define_char{𝝓}{\umiMathbfit{\phi}}
+\__umi_define_char{𝝔}{\umiMathbfit{\varrho}}
+\__umi_define_char{𝝕}{\umiMathbfit{\varpi}}
+\__umi_define_char{𝝖}{\umiMathsfbf{\__umi_alternatives_iisafe\Alpha A}}
+\__umi_define_char{𝝗}{\umiMathsfbf{\__umi_alternatives_iisafe\Beta B}}
+\__umi_define_char{𝝘}{\umiMathsfbf{\Gamma}}
+\__umi_define_char{𝝙}{\umiMathsfbf{\Delta}}
+\__umi_define_char{𝝚}{\umiMathsfbf{\__umi_alternatives_iisafe\Epsilon E}}
+\__umi_define_char{𝝛}{\umiMathsfbf{\__umi_alternatives_iisafe\Zeta Z}}
+\__umi_define_char{𝝜}{\umiMathsfbf{\__umi_alternatives_iisafe\Eta H}}
+\__umi_define_char{𝝝}{\umiMathsfbf{\Theta}}
+\__umi_define_char{𝝞}{\umiMathsfbf{\__umi_alternatives_iisafe\Iota I}}
+\__umi_define_char{𝝟}{\umiMathsfbf{\__umi_alternatives_iisafe\Kappa K}}
+\__umi_define_char{𝝠}{\umiMathsfbf{\Lambda}}
+\__umi_define_char{𝝡}{\umiMathsfbf{\__umi_alternatives_iisafe\Mu M}}
+\__umi_define_char{𝝢}{\umiMathsfbf{\__umi_alternatives_iisafe\Nu N}}
+\__umi_define_char{𝝣}{\umiMathsfbf{\Xi}}
+\__umi_define_char{𝝤}{\umiMathsfbf{\__umi_alternatives_iisafe\Omicron O}}
+\__umi_define_char{𝝥}{\umiMathsfbf{\Pi}}
+\__umi_define_char{𝝦}{\umiMathsfbf{\__umi_alternatives_iisafe\Rho P}}
+\__umi_define_char{𝝧}{\umiMathsfbf{\varTheta}}
+\__umi_define_char{𝝨}{\umiMathsfbf{\Sigma}}
+\__umi_define_char{𝝩}{\umiMathsfbf{\__umi_alternatives_iisafe\Tau T}}
+\__umi_define_char{𝝪}{\umiMathsfbf{\Upsilon}}
+\__umi_define_char{𝝫}{\umiMathsfbf{\Phi}}
+\__umi_define_char{𝝬}{\umiMathsfbf{\__umi_alternatives_iisafe\Chi X}}
+\__umi_define_char{𝝭}{\umiMathsfbf{\Psi}}
+\__umi_define_char{𝝮}{\umiMathsfbf{\Omega}}
+\__umi_define_char{𝝯}{\umiMathsfbf{\nabla}}
+\__umi_define_char{𝝰}{\umiMathsfbf{\alpha}}
+\__umi_define_char{𝝱}{\umiMathsfbf{\beta}}
+\__umi_define_char{𝝲}{\umiMathsfbf{\gamma}}
+\__umi_define_char{𝝳}{\umiMathsfbf{\delta}}
+\__umi_define_char{𝝴}{\umiMathsfbf{\varepsilon}}
+\__umi_define_char{𝝵}{\umiMathsfbf{\zeta}}
+\__umi_define_char{𝝶}{\umiMathsfbf{\eta}}
+\__umi_define_char{𝝷}{\umiMathsfbf{\theta}}
+\__umi_define_char{𝝸}{\umiMathsfbf{\iota}}
+\__umi_define_char{𝝹}{\umiMathsfbf{\kappa}}
+\__umi_define_char{𝝺}{\umiMathsfbf{\lambda}}
+\__umi_define_char{𝝻}{\umiMathsfbf{\mu}}
+\__umi_define_char{𝝼}{\umiMathsfbf{\nu}}
+\__umi_define_char{𝝽}{\umiMathsfbf{\xi}}
+\__umi_define_char{𝝾}{\umiMathsfbf{\__umi_alternatives_iisafe\omicron o}}
+\__umi_define_char{𝝿}{\umiMathsfbf{\pi}}
+\__umi_define_char{𝞀}{\umiMathsfbf{\rho}}
+\__umi_define_char{𝞁}{\umiMathsfbf{\varsigma}}
+\__umi_define_char{𝞂}{\umiMathsfbf{\sigma}}
+\__umi_define_char{𝞃}{\umiMathsfbf{\tau}}
+\__umi_define_char{𝞄}{\umiMathsfbf{\upsilon}}
+\__umi_define_char{𝞅}{\umiMathsfbf{\varphi}}
+\__umi_define_char{𝞆}{\umiMathsfbf{\chi}}
+\__umi_define_char{𝞇}{\umiMathsfbf{\psi}}
+\__umi_define_char{𝞈}{\umiMathsfbf{\omega}}
+\__umi_define_char{𝞉}{\umiMathsfbf{\partial}}
+\__umi_define_char{𝞊}{\umiMathsfbf{\epsilon}}
+\__umi_define_char{𝞋}{\umiMathsfbf{\vartheta}}
+\__umi_define_char{𝞌}{\umiMathsfbf{\varkappa}}
+\__umi_define_char{𝞍}{\umiMathsfbf{\phi}}
+\__umi_define_char{𝞎}{\umiMathsfbf{\varrho}}
+\__umi_define_char{𝞏}{\umiMathsfbf{\varpi}}
+\__umi_define_char{𝞐}{\umiMathsfbfit{\__umi_alternatives_iisafe\Alpha A}}
+\__umi_define_char{𝞑}{\umiMathsfbfit{\__umi_alternatives_iisafe\Beta B}}
+\__umi_define_char{𝞒}{\umiMathsfbfit{\Gamma}}
+\__umi_define_char{𝞓}{\umiMathsfbfit{\Delta}}
+\__umi_define_char{𝞔}{\umiMathsfbfit{\__umi_alternatives_iisafe\Epsilon E}}
+\__umi_define_char{𝞕}{\umiMathsfbfit{\__umi_alternatives_iisafe\Zeta Z}}
+\__umi_define_char{𝞖}{\umiMathsfbfit{\__umi_alternatives_iisafe\Eta H}}
+\__umi_define_char{𝞗}{\umiMathsfbfit{\Theta}}
+\__umi_define_char{𝞘}{\umiMathsfbfit{\__umi_alternatives_iisafe\Iota I}}
+\__umi_define_char{𝞙}{\umiMathsfbfit{\__umi_alternatives_iisafe\Kappa K}}
+\__umi_define_char{𝞚}{\umiMathsfbfit{\Lambda}}
+\__umi_define_char{𝞛}{\umiMathsfbfit{\__umi_alternatives_iisafe\Mu M}}
+\__umi_define_char{𝞜}{\umiMathsfbfit{\__umi_alternatives_iisafe\Nu N}}
+\__umi_define_char{𝞝}{\umiMathsfbfit{\Xi}}
+\__umi_define_char{𝞞}{\umiMathsfbfit{\__umi_alternatives_iisafe\Omicron O}}
+\__umi_define_char{𝞟}{\umiMathsfbfit{\Pi}}
+\__umi_define_char{𝞠}{\umiMathsfbfit{\__umi_alternatives_iisafe\Rho P}}
+\__umi_define_char{𝞡}{\umiMathsfbfit{\varTheta}}
+\__umi_define_char{𝞢}{\umiMathsfbfit{\Sigma}}
+\__umi_define_char{𝞣}{\umiMathsfbfit{\__umi_alternatives_iisafe\Tau T}}
+\__umi_define_char{𝞤}{\umiMathsfbfit{\Upsilon}}
+\__umi_define_char{𝞥}{\umiMathsfbfit{\Phi}}
+\__umi_define_char{𝞦}{\umiMathsfbfit{\__umi_alternatives_iisafe\Chi X}}
+\__umi_define_char{𝞧}{\umiMathsfbfit{\Psi}}
+\__umi_define_char{𝞨}{\umiMathsfbfit{\Omega}}
+\__umi_define_char{𝞩}{\umiMathsfbfit{\nabla}}
+\__umi_define_char{𝞪}{\umiMathsfbfit{\alpha}}
+\__umi_define_char{𝞫}{\umiMathsfbfit{\beta}}
+\__umi_define_char{𝞬}{\umiMathsfbfit{\gamma}}
+\__umi_define_char{𝞭}{\umiMathsfbfit{\delta}}
+\__umi_define_char{𝞮}{\umiMathsfbfit{\varepsilon}}
+\__umi_define_char{𝞯}{\umiMathsfbfit{\zeta}}
+\__umi_define_char{𝞰}{\umiMathsfbfit{\eta}}
+\__umi_define_char{𝞱}{\umiMathsfbfit{\theta}}
+\__umi_define_char{𝞲}{\umiMathsfbfit{\iota}}
+\__umi_define_char{𝞳}{\umiMathsfbfit{\kappa}}
+\__umi_define_char{𝞴}{\umiMathsfbfit{\lambda}}
+\__umi_define_char{𝞵}{\umiMathsfbfit{\mu}}
+\__umi_define_char{𝞶}{\umiMathsfbfit{\nu}}
+\__umi_define_char{𝞷}{\umiMathsfbfit{\xi}}
+\__umi_define_char{𝞸}{\umiMathsfbfit{\__umi_alternatives_iisafe\omicron o}}
+\__umi_define_char{𝞹}{\umiMathsfbfit{\pi}}
+\__umi_define_char{𝞺}{\umiMathsfbfit{\rho}}
+\__umi_define_char{𝞻}{\umiMathsfbfit{\varsigma}}
+\__umi_define_char{𝞼}{\umiMathsfbfit{\sigma}}
+\__umi_define_char{𝞽}{\umiMathsfbfit{\tau}}
+\__umi_define_char{𝞾}{\umiMathsfbfit{\upsilon}}
+\__umi_define_char{𝞿}{\umiMathsfbfit{\varphi}}
+\__umi_define_char{𝟀}{\umiMathsfbfit{\chi}}
+\__umi_define_char{𝟁}{\umiMathsfbfit{\psi}}
+\__umi_define_char{𝟂}{\umiMathsfbfit{\omega}}
+\__umi_define_char{𝟃}{\umiMathsfbfit{\partial}}
+\__umi_define_char{𝟄}{\umiMathsfbfit{\epsilon}}
+\__umi_define_char{𝟅}{\umiMathsfbfit{\vartheta}}
+\__umi_define_char{𝟆}{\umiMathsfbfit{\varkappa}}
+\__umi_define_char{𝟇}{\umiMathsfbfit{\phi}}
+\__umi_define_char{𝟈}{\umiMathsfbfit{\varrho}}
+\__umi_define_char{𝟉}{\umiMathsfbfit{\varpi}}
+\__umi_define_char{𝟊}{\umiMathbf{\__umi_alternatives_iisafe\Digamma F}}
+\__umi_define_char{𝟋}{\umiMathbf{\digamma}}
+\__umi_define_char{𝟎}{\umiMathbf{0}}
+\__umi_define_char{𝟏}{\umiMathbf{1}}
+\__umi_define_char{𝟐}{\umiMathbf{2}}
+\__umi_define_char{𝟑}{\umiMathbf{3}}
+\__umi_define_char{𝟒}{\umiMathbf{4}}
+\__umi_define_char{𝟓}{\umiMathbf{5}}
+\__umi_define_char{𝟔}{\umiMathbf{6}}
+\__umi_define_char{𝟕}{\umiMathbf{7}}
+\__umi_define_char{𝟖}{\umiMathbf{8}}
+\__umi_define_char{𝟗}{\umiMathbf{9}}
+\__umi_define_char{𝟘}{\umiMathbb{0}}
+\__umi_define_char{𝟙}{\umiMathbb{1}}
+\__umi_define_char{𝟚}{\umiMathbb{2}}
+\__umi_define_char{𝟛}{\umiMathbb{3}}
+\__umi_define_char{𝟜}{\umiMathbb{4}}
+\__umi_define_char{𝟝}{\umiMathbb{5}}
+\__umi_define_char{𝟞}{\umiMathbb{6}}
+\__umi_define_char{𝟟}{\umiMathbb{7}}
+\__umi_define_char{𝟠}{\umiMathbb{8}}
+\__umi_define_char{𝟡}{\umiMathbb{9}}
+\__umi_define_char{𝟢}{\umiMathsf{0}}
+\__umi_define_char{𝟣}{\umiMathsf{1}}
+\__umi_define_char{𝟤}{\umiMathsf{2}}
+\__umi_define_char{𝟥}{\umiMathsf{3}}
+\__umi_define_char{𝟦}{\umiMathsf{4}}
+\__umi_define_char{𝟧}{\umiMathsf{5}}
+\__umi_define_char{𝟨}{\umiMathsf{6}}
+\__umi_define_char{𝟩}{\umiMathsf{7}}
+\__umi_define_char{𝟪}{\umiMathsf{8}}
+\__umi_define_char{𝟫}{\umiMathsf{9}}
+\__umi_define_char{𝟬}{\umiMathsfbf{0}}
+\__umi_define_char{𝟭}{\umiMathsfbf{1}}
+\__umi_define_char{𝟮}{\umiMathsfbf{2}}
+\__umi_define_char{𝟯}{\umiMathsfbf{3}}
+\__umi_define_char{𝟰}{\umiMathsfbf{4}}
+\__umi_define_char{𝟱}{\umiMathsfbf{5}}
+\__umi_define_char{𝟲}{\umiMathsfbf{6}}
+\__umi_define_char{𝟳}{\umiMathsfbf{7}}
+\__umi_define_char{𝟴}{\umiMathsfbf{8}}
+\__umi_define_char{𝟵}{\umiMathsfbf{9}}
+\__umi_define_char{𝟶}{\umiMathtt{0}}
+\__umi_define_char{𝟷}{\umiMathtt{1}}
+\__umi_define_char{𝟸}{\umiMathtt{2}}
+\__umi_define_char{𝟹}{\umiMathtt{3}}
+\__umi_define_char{𝟺}{\umiMathtt{4}}
+\__umi_define_char{𝟻}{\umiMathtt{5}}
+\__umi_define_char{𝟼}{\umiMathtt{6}}
+\__umi_define_char{𝟽}{\umiMathtt{7}}
+\__umi_define_char{𝟾}{\umiMathtt{8}}
+\__umi_define_char{𝟿}{\umiMathtt{9}}
+\__umi_define_char{𞻰}{\arabicmaj}
+\__umi_define_char{𞻱}{\arabichad}
diff --git a/macros/latex/contrib/unicode-math-input/unicode-math-input.pdf b/macros/latex/contrib/unicode-math-input/unicode-math-input.pdf
new file mode 100644
index 0000000000..80d94c1908
--- /dev/null
+++ b/macros/latex/contrib/unicode-math-input/unicode-math-input.pdf
Binary files differ
diff --git a/macros/latex/contrib/unicode-math-input/unicode-math-input.sty b/macros/latex/contrib/unicode-math-input/unicode-math-input.sty
new file mode 100644
index 0000000000..dcb72f6a30
--- /dev/null
+++ b/macros/latex/contrib/unicode-math-input/unicode-math-input.sty
@@ -0,0 +1,731 @@
+% File: unicode-math-input.sty
+% Copyright 2022-2023 user202729
+%
+% This work may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this license or
+% (at your option) any later version. The latest version of this license is in
+% the file:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is user202729.
+
+\RequirePackage{expl3}
+\RequirePackage{iftex}
+\ProvidesExplPackage{unicode-math-input}{2023-05-12}{0.0.0}{Allow entering Unicode symbols in math formulas}
+
+\makeatletter
+\AtBeginDocument{
+ \@ifpackageloaded{unicode-math}{
+ \msg_new:nnn {unicode-math-input} {unicode-math-clash} {
+ You~don't~need~this~package~if~you~use~unicode-math~package!
+ }
+ \msg_error:nn {unicode-math-input} {unicode-math-clash}
+ }{}
+}
+\makeatother
+
+\RequirePackage{l3keys2e}
+\keys_define:nn{unicode-math-input}{
+ ignore-refresh-delimiter-list .bool_set:N=\__umi_ignore_refresh_delimiter_list,
+ ignore-patch-delimiter-commands .bool_set:N=\__umi_ignore_patch_delimiter_commands,
+ ignore-patch-prime .bool_set:N=\__umi_ignore_patch_prime,
+}
+\ProcessKeysOptions{unicode-math-input}
+
+\cs_new_protected:Npn \umiMathbf {\__umi_check_math_alphabet \mathbf \umiMathbf }
+\cs_new_protected:Npn \umiMathit {\__umi_check_math_alphabet \mathit \umiMathit }
+\cs_new_protected:Npn \umiMathbfit {\__umi_check_math_alphabet \bm \umiMathbfit }
+\cs_new_protected:Npn \umiMathscr {\__umi_check_math_alphabet \mathscr \umiMathscr }
+\cs_new_protected:Npn \umiMathbfscr {\__umi_check_math_alphabet \mathbfscr \umiMathbfscr }
+\cs_new_protected:Npn \umiMathfrak {\__umi_check_math_alphabet \mathfrak \umiMathfrak }
+\cs_new_protected:Npn \umiMathbb {\__umi_check_math_alphabet \mathbb \umiMathbb }
+\cs_new_protected:Npn \umiMathbbit {\__umi_check_math_alphabet \mathbbit \umiMathbbit }
+\cs_new_protected:Npn \umiMathbffrak{\__umi_check_math_alphabet \mathbffrak \umiMathbffrak }
+\cs_new_protected:Npn \umiMathsf {\__umi_check_math_alphabet \mathsf \umiMathsf }
+\cs_new_protected:Npn \umiMathsfbf {\__umi_check_math_alphabet \mathsfbf \umiMathsfbf }
+\cs_new_protected:Npn \umiMathsfit {\__umi_check_math_alphabet \mathsfit \umiMathsfit }
+\cs_new_protected:Npn \umiMathsfbfit{\__umi_check_math_alphabet \mathsfbfit \umiMathsfbfit }
+\cs_new_protected:Npn \umiMathtt {\__umi_check_math_alphabet \mathtt \umiMathtt }
+
+\msg_new:nnn {unicode-math-input} {define-math-alphabet} {
+ Please~load~a~package~that~defines~#1,~or~manually~define~#2.
+}
+\cs_new_protected:Npn \__umi_check_math_alphabet#1#2{
+ \ifdefined#1
+ \expandafter#1
+ \else
+ \msg_error:nnnn {unicode-math-input} {define-math-alphabet} #1 #2
+ \fi
+}
+
+\msg_new:nnn {unicode-math-input} {internal-error} {
+ Internal~error!
+}
+\cs_new_protected:Npn \__umi_internal_error {
+ \msg_error:nn {unicode-math-input} {internal-error}
+}
+
+\msg_new:nnn {unicode-math-input} {undefined-cs} {
+ Please~load~a~package~that~defines~any~of~#1~to~use~this~Unicode~symbol.
+}
+% take 2 control sequences, return the first one that is defined. They must not peek ahead
+\cs_new_protected:Npn \__umi_alternatives #1 #2 {
+ \ifdefined #1
+ #1
+ \else
+ \ifdefined #2
+ #2
+ \else
+ \msg_error:nnn {unicode-math-input} {undefined-cs} {#1#2}
+ \fi
+ \fi
+}
+
+% #1 is control sequence, #2 is anything (must not peek ahead!)
+\cs_new_protected:Npn \__umi_alternatives_iisafe #1 #2 {
+ \ifdefined #1
+ \expandafter#1
+ \else
+ #2
+ \fi
+}
+
+% e.g. '\__umi_alternatives_not \nexists \exists' → \nexists or \not\exists
+% both must be control sequences
+\cs_new_protected:Npn \__umi_alternatives_not #1 #2 {
+ \ifdefined #1
+ #1
+ \else
+ \ifdefined #2
+ \not#2
+ \else
+ \msg_error:nnn {unicode-math-input} {undefined-cs} {#1#2}
+ \fi
+ \fi
+}
+
+% ======== \__umi_require_math
+\msg_new:nnn {unicode-math-input} {not-math-mode} {
+ This~symbol~can~only~be~used~in~math~mode!
+}
+\cs_new_protected:Npn \__umi_require_math {
+ \ifmmode\else \msg_error:nn {unicode-math-input} {not-math-mode} \fi
+}
+
+% ======== \__umi_define_char
+
+\msg_new:nnn {unicode-math-input} {not-single-character} {
+ Argument~must~be~a~single~character.
+}
+
+\msg_new:nnn {unicode-math-input} {not-correct-catcode} {
+ Redefining~this~special~character~in~math~mode~is~not~supported.
+}
+
+\cs_new_protected:Npn \__umi_check_before_define_char_single #1 {
+ \ifnum \str_count:n{#1}=\c_one_int
+ \int_case:nnF{\catcode `#1}{
+ {11}{} % letter
+ {12}{} % other
+ {13}{} % active
+ }{
+ % otherwise the character won't be active in math mode...
+ \msg_error:nn {unicode-math-input} {not-correct-catcode}
+ }
+ \else
+ \msg_error:nn {unicode-math-input} {not-single-character}
+ \fi
+}
+
+\int_const:Nn \__umi_active_mathcode_input {"8000} % equal to \__umi_active_mathcode unless on lualatex where the former is "1000000
+
+\cs_gset_protected:Npn \__umi_gtmp #1 {
+ \cs_new_protected:Npn \__umi_define_char_single ##1 ##2{ % this function is \__umi_define_char if simply redefining the character and setting the mathcode to "8000 suffices
+ \__umi_check_before_define_char_single{##1}
+ \global\mathcode `##1=\__umi_active_mathcode_input
+ \begingroup \lccode 0=`##1 \lowercase{\endgroup \cs_gset_protected:Npx #1} {\unexpanded{##2}} % #1 = ⟨active character with code 0⟩
+ % the code above executes '\cs_gset_protected:Npn ⟨active character with charcode ##1⟩ {##2}'
+ }
+}
+\expandafter \expandafter \expandafter \__umi_gtmp \char_generate:nn {0} {13}
+
+\ifTUTeX
+ \cs_new_eq:NN \__umi_if_engine_unicode \use_i:nn
+\else
+ \cs_new_eq:NN \__umi_if_engine_unicode \use_ii:nn
+\fi
+
+\cs_generate_variant:Nn \str_if_eq:nnTF {x}
+
+\__umi_if_engine_unicode {
+ \cs_new_eq:NN \__umi_define_char \__umi_define_char_single
+
+ % as documented in the documentation, for Unicode engines we need to handle the delimiters specially.
+ \cs_new_protected:Npn \__umi_define_char_maybe_delimiter #1 #2 {
+ \ifnum \tl_count:n {#2}=1 \else \__umi_internal_error \fi
+ \tl_if_head_is_N_type:nF {#2} {\__umi_internal_error}
+
+ \__umi_define_char #1 #2
+ \tl_build_put_right:Nn \__umi_delimiter_list {\__umi_check_delimiter #1 #2}
+ }
+
+ \msg_new:nnn {unicode-math-input} {not-delimiter} {
+ The~Unicode~character~#1~is~mapped~to~#2,~but~the~latter~is~not~determined~to~be~a~delimiter.
+ }
+
+ \cs_generate_variant:Nn \str_range:nnn {V}
+ \cs_generate_variant:Nn \cs_replacement_spec:N {c}
+
+ % e.g. \__umi_check_delimiter_aux ⟨ \langle
+ % #2 must be a single token
+ % on successful, just set (globally)
+ % on unsuccessful (if #2 is undefined) call \__umi_check_delimiter_undefined #1 #2
+ % on unsuccessful (if #2 is defined but not a delimiter) call \__umi_check_delimiter_defined_not_delimiter #1 #2
+ % caller of this function should set these 2 functions in advance
+ \cs_new_protected:Npn \__umi_check_delimiter_aux #1 #2 {
+ \begingroup
+ \escapechar=`\/~
+
+ \str_gset:Nx \g_tmpb_str {\cs_replacement_spec:N #2}
+
+ % some introspection is needed to determine what it is...
+ % e.g. 'macro:->/protect /langle ' → 'macro:->/delimiter "426830A ' (for old LaTeX versions)
+ \str_if_eq:VnT \g_tmpb_str {/protect~#2~} {
+ \str_gset:Nx \g_tmpb_str {\cs_replacement_spec:c {\cs_to_str:N #2 ~}}
+ }
+ \endgroup
+
+ \str_if_eq:VnTF \g_tmpb_str {/scan_stop:~} {
+ \__umi_check_delimiter_undefined #1 #2
+ } {
+ % e.g. '/delimiter "426830A '
+ \str_if_eq:xnTF {\str_range:Vnn \g_tmpb_str {1} {11}} {/delimiter~} {
+ %\typeout{setting delcode #1 to \int_to_hex:n {\int_mod:nn {\str_range:Vnn \g_tmpb_str {12} {-1}} {"1000000}} }
+ \global\delcode `#1 = \int_mod:nn {\str_range:Vnn \g_tmpb_str {12} {-1}} {"1000000} \relax
+ } {
+ %\typeout{>> |\g_tmpb_str|}
+ \__umi_check_delimiter_defined_not_delimiter #1 #2
+ }
+ }
+ }
+
+
+ \cs_new_eq:NN \umiDefineMathChar \__umi_define_char_single
+ \cs_new_protected:Npn \umiDefineMathDelimiter #1 #2 {
+ \cs_new_protected:Npn \__umi_check_delimiter_defined_not_delimiter ##1 ##2 {
+ \msg_error:nnnn {unicode-math-input} {not-delimiter} {##1} {##2}
+ }
+ \cs_new_eq:NN \__umi_check_delimiter_undefined \__umi_check_delimiter_defined_not_delimiter
+ \ifnum \str_count:n{#1}=1 \else \__umi_internal_error \fi
+ \ifnum \tl_count:n {#2}=1 \else \__umi_internal_error \fi
+ \tl_if_head_is_N_type:nF {#2} {\__umi_internal_error}
+ \__umi_define_char #1 #2
+ \__umi_check_delimiter_aux #1 #2
+ }
+
+} {
+ \cs_new:Npn \__umi_take_IeC \IeC #1 \__umi_delimiter { \unexpanded{#1} }
+
+ % internal procedure
+ % e.g.
+ % \str_set:Nn \l_tmpa_str {u8:×} \__umi_define_char_math_only {\times}
+ % the character #1 is already defined in LaTeX, check if it's LaTeX default definition (\IeC{\texttimes})
+ % if it is then change it to do a switch-case on text/math mode, otherwise raise an error
+ \cs_new_protected:Npn \__umi_define_char_math_only #1 {
+ \begingroup
+ \escapechar=`\/~
+ \str_gset:Nx \g_tmpb_str { \expandafter\meaning\csname \l_tmpa_str\endcsname }
+ \endgroup
+ \str_if_eq:xnTF { \str_range:Nnn \g_tmpb_str {1} {13} } {macro:->/IeC~} {
+ % it probably is, tack on the math definition
+ \cs_gset_protected:cpx {\l_tmpa_str} {
+ \noexpand\mode_if_math:TF {
+ \unexpanded{#1}
+ } {
+ \expandafter\expandafter\expandafter \__umi_take_IeC \csname \l_tmpa_str\endcsname \__umi_delimiter
+ }
+ } % this is already protected, no need protected@empty
+
+ % in summary if the existing definition is
+ % \u8:×:
+ % macro:->\IeC {\texttimes }
+ % then the new definition is
+ % \protected macro:->\mode_if_math:TF {\times} {\texttimes}
+ % as expected.
+ % we use \mode_if_math:TF just in case the thing inside peeks ahead.
+ } {
+ % ... cannot redefine...?
+ \__umi_internal_error
+ }
+ }
+
+ \cs_new_protected:Npn \__umi_define_char #1 #2{
+ \ifnum \str_count:n{#1}=1
+ \__umi_define_char_single #1 {#2}
+ \else
+ \str_set:Nn \l_tmpa_str{u8:#1}
+ \ifcsname \l_tmpa_str\endcsname
+ \__umi_define_char_math_only {#2}
+ \else
+ % the character is not defined, just define it
+ \cs_gset_protected:cpx {\l_tmpa_str} {\unexpanded{\__umi_require_math #2}}
+ \fi
+ \fi
+ }
+
+ \cs_new_eq:NN \__umi_define_char_maybe_delimiter \__umi_define_char
+
+ \cs_new_protected:Npn \umiDefineMathChar #1 #2{
+ \ifnum \str_count:n{#1}=1
+ \__umi_define_char_single #1 {#2}
+ \else
+ \cs_gset_protected:cpx {u8:\detokenize{#1}} {\unexpanded{\__umi_require_math #2}}
+ \fi
+ }
+ \cs_new_eq:NN \umiDefineMathDelimiter \umiDefineMathChar
+}
+
+\__umi_if_engine_unicode {
+ \tl_build_begin:N \__umi_delimiter_list
+} {}
+% we temporarily turn off the check for extra performance.
+\cs_gset_eq:NN \__umi_check_before_define_char_single_backup \__umi_check_before_define_char_single
+\cs_gset_eq:NN \__umi_check_before_define_char_single \use_none:n
+\input unicode-math-input-table.tex
+\cs_gset_eq:NN \__umi_check_before_define_char_single \__umi_check_before_define_char_single_backup
+\__umi_if_engine_unicode {
+ \tl_build_end:N \__umi_delimiter_list
+ \cs_new_protected:Npn \umiRefreshDelimiterList{
+ \cs_new_eq:NN \__umi_check_delimiter_undefined \use_none:nn
+ \cs_new_protected:Npn \__umi_check_delimiter_defined_not_delimiter ##1 ##2 {
+ \msg_warning:nnnn {unicode-math-input} {not-delimiter} {##1} {##2}
+ }
+ \cs_new_eq:NN \__umi_check_delimiter \__umi_check_delimiter_aux
+ \__umi_delimiter_list
+ }
+ \bool_if:NF\__umi_ignore_refresh_delimiter_list{
+ \AtBeginDocument{\umiRefreshDelimiterList}
+ }
+} {
+ \cs_new_eq:NN \umiRefreshDelimiterList \relax
+}
+
+\cs_new_eq:NN \__umi_special_handle \__umi_define_char
+
+\cs_new_eq:NN \umiFrac \frac
+
+% ======== after the superscript collection, \umiPrime\umiPrime... should be replaced with \dprime etc. smartly
+\cs_new_protected:Npn \umiPrime{ \__umi_prime } % indirection layer for fast meaning-equality checking
+\cs_new_eq:NN \umiPrimeNormalDefinition \umiPrime
+\cs_new_protected:Npn \__umi_prime {
+ \peek_meaning_collect_inline:Nn \umiPrime {
+ % note that ##1 misses one \prime as expands to this current function
+ \int_case:nnF { \tl_count:n {##1} } {
+ 1 {\__umi_alternatives_iisafe \dprime {\prime\prime}}
+ 2 {\__umi_alternatives_iisafe \trprime{\prime\prime\prime}}
+ 3 {\__umi_alternatives_iisafe \qprime {\prime\prime\prime\prime}}
+ } {
+ % complicated way to repeat '\prime' <count #1> times
+ \cs_gset_eq:NN \umiPrime \prime
+ \prime ##1
+ \cs_gset_eq:NN \umiPrime \umiPrimeNormalDefinition
+ }
+ }
+}
+
+% similar for backprime
+\cs_new_protected:Npn \umiBackprime{ \__umi_backprime }
+\cs_new_eq:NN \umiBackprimeNormalDefinition \umiBackprime
+\cs_new_protected:Npn \__umi_backprime {
+ \peek_meaning_collect_inline:Nn \umiBackprime {
+ \int_case:nnF { \tl_count:n {##1} } {
+ 1 {\__umi_alternatives_iisafe \backdprime {\backprime\backprime}}
+ 2 {\__umi_alternatives_iisafe \backtrprime {\backprime\backprime\backprime}}
+ } {
+ \cs_gset_eq:NN \umiBackprime \backprime
+ \backprime ##1
+ \cs_gset_eq:NN \umiBackprime \umiBackprimeNormalDefinition
+ }
+ }
+}
+
+\__umi_special_handle{ı}{\imath}
+\__umi_special_handle{ȷ}{\jmath}
+
+\__umi_special_handle{↉}{\umiFrac{0}{3} }
+\__umi_special_handle{⅒}{\umiFrac{1}{10}}
+\__umi_special_handle{⅑}{\umiFrac{1}{9} }
+\__umi_special_handle{⅛}{\umiFrac{1}{8} }
+\__umi_special_handle{⅐}{\umiFrac{1}{7} }
+\__umi_special_handle{⅙}{\umiFrac{1}{6} }
+\__umi_special_handle{⅕}{\umiFrac{1}{5} }
+\__umi_special_handle{¼}{\umiFrac{1}{4} }
+\__umi_special_handle{⅓}{\umiFrac{1}{3} }
+\__umi_special_handle{⅜}{\umiFrac{3}{8} }
+\__umi_special_handle{⅖}{\umiFrac{2}{5} }
+\__umi_special_handle{½}{\umiFrac{1}{2} }
+\__umi_special_handle{⅗}{\umiFrac{3}{5} }
+\__umi_special_handle{⅝}{\umiFrac{5}{8} }
+\__umi_special_handle{⅔}{\umiFrac{2}{3} }
+\__umi_special_handle{¾}{\umiFrac{3}{4} }
+\__umi_special_handle{⅘}{\umiFrac{4}{5} }
+\__umi_special_handle{⅚}{\umiFrac{5}{6} }
+\__umi_special_handle{⅞}{\umiFrac{7}{8} }
+\__umi_special_handle{√}{\sqrt}
+\__umi_special_handle{∛}{\sqrt[3]}
+\__umi_special_handle{∜}{\sqrt[4]}
+
+
+% ======== the following routine handles both superscript and subscript collection.
+
+% like this:
+% \__umi_superscript {12} ≡ ^{12}
+% \__umi_superscript {12}^{34} ≡ ^{1234}
+% \__umi_superscript {12}^{34}^{56} ≡ ^{123456} (unintended but okay no problem)
+% \__umi_superscript {12}' ≡ ^{12\prime} (something like this)
+% \__umi_superscript {12} \__umi_superscript {34} ≡ ^{1234}
+% \__umi_superscript {12} \__umi_superscript {34} ^{56} ≡ ^{123456}
+% we will not deal with ^\bgroup...\egroup
+
+\cs_new_protected:Npn \__umi_superscript {
+ \cs_gset_eq:NN \__umi_superscript ^
+ \cs_gset_eq:NN \__umi_script_cat ^
+ \cs_gset:Npn \__umi_script_collect_done {\cs_gset_eq:NN \__umi_superscript \__umi_superscript_normal}
+ \__umi_script
+}
+\cs_new_protected:Npn \__umi_subscript {
+ \cs_gset_eq:NN \__umi_subscript \sb
+ \cs_gset_eq:NN \__umi_script_cat \sb
+ \cs_gset:Npn \__umi_script_collect_done {\cs_gset_eq:NN \__umi_subscript \__umi_subscript_normal}
+ \__umi_script
+}
+\cs_new_eq:NN \__umi_superscript_normal \__umi_superscript
+\cs_new_eq:NN \__umi_subscript_normal \__umi_subscript
+
+% in order to use the function below the caller should (do as what \__umi_superscript does above...)
+
+\cs_new_protected:Npn \__umi_script #1 {
+ % * store the argument
+ \tl_set:Nn \l_tmpa_tl {#1}
+ % * f-expand following stuff exclude the \__umi_*script token itself which has been set to ^ or _
+ % by the code above
+ \expandafter \__umi_continue_script_aux \exp:w\exp_end_continue_f:w
+}
+
+\cs_new_protected:Npn \__umi_continue_script_aux {
+ \peek_catcode_remove:NTF \__umi_script_cat {
+ % * in this case following is either \__umi_script token or ^{something} as usual, we handle both the same way
+ \__umi_continue_script_auxii
+ } {
+ % * following may be some other-catcode token
+ \peek_catcode:NTF ? {
+ \__umi_replace_other_active
+ } {
+ \__umi_script_collect_done
+ \__umi_script_cat{\l_tmpa_tl}
+ }
+ }
+}
+
+\cs_new_protected:Npn \__umi_continue_script_auxii #1 {
+ \tl_put_right:Nn \l_tmpa_tl {#1}
+ \expandafter \__umi_continue_script_aux \exp:w\exp_end_continue_f:w
+}
+
+% the active mathcode value.
+\int_const:Nn \__umi_active_mathcode {\mathcode `'}
+
+\use:x{
+ \cs_new:Npn \noexpand\__umi_gobble_the_character \detokenize{the~character~} {`}
+}
+% effectively the result will be that
+% \int_eval:n {\__umi_gobble_the_character 'the character a'} = 65
+
+\cs_new_protected:Npn \__umi_replace_other_active #1 {
+ % * if following is some other-catcode and the mathcode is active, replace it with the active token and retry
+ % (we ignore the case of letter-catcode)
+ \int_compare:nNnTF {\mathcode \expandafter \__umi_gobble_the_character \meaning #1} = {\__umi_active_mathcode} {
+ \expandafter \__umi_continue_script_aux \exp:w\exp_end_continue_f:w
+ \char_generate:nn {\expandafter \__umi_gobble_the_character \meaning #1} {13}
+ } {
+ \cs_gset_eq:NN \__umi_script \__umi_put_script_normal
+ ^{\l_tmpa_tl} #1
+ }
+}
+
+% ======== patch \big etc.
+
+
+\__umi_if_engine_unicode {
+ \cs_new_eq:NN \umiPatchCmdUnicodeArg \use_none:n
+ \cs_new_eq:NN \umiPatchCmdUnicodeArgExtraGroup \use_none:n
+ \cs_new_eq:NN \umiPatchCmdUnicodeTwoArgs \use_none:n
+ \cs_new_eq:NN \umiUnpatchCmdUnicodeArg \use_none:n
+} {
+
+ % usage:
+ % \umiBraceNext {abc...} xyz... ≡ abc... xyz...
+ % \umiBraceNext {abc...} αyz... ≡ abc... {α}yz...
+ \cs_new_protected:Npn \umiBraceNext #1 {
+ \tl_set:Nn \l_tmpa_tl {#1}
+ \peek_N_type:TF {
+ \__umi_brace_next_aux
+ } {
+ \l_tmpa_tl
+ }
+ }
+
+ \cs_new_protected:Npn \__umi_brace_next_aux #1 {
+ \begingroup
+ \escapechar=`\\~ % just in case there's \⟨single byte⟩ ...
+ \int_compare:nNnTF {\str_count:n {#1}} = {1} {
+ \endgroup
+ \csname __umi_brace_handle_\string#1 \endcsname
+ } {
+ \endgroup
+ \l_tmpa_tl
+ }
+ #1
+ }
+
+ \def \__umi_brace_error {\__umi_internal_error \l_tmpa_tl}
+ \def \__umi_brace_two #1 #2 {\l_tmpa_tl {#1 #2}}
+ \def \__umi_brace_three #1 #2 #3 {\l_tmpa_tl {#1 #2 #3}}
+ \def \__umi_brace_four #1 #2 #3 #4 {\l_tmpa_tl {#1 #2 #3 #4}}
+
+ \int_step_inline:nnn {"00} {"7F} {
+ \expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \relax
+ }
+ \int_step_inline:nnn {"80} {"BF} {
+ \expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \__umi_brace_error
+ }
+ \int_step_inline:nnn {"C0} {"DF} {
+ \expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \__umi_brace_two
+ }
+ \int_step_inline:nnn {"E0} {"EF} {
+ \expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \__umi_brace_three
+ }
+ \int_step_inline:nnn {"F0} {"F7} {
+ \expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \__umi_brace_four
+ }
+ \int_step_inline:nnn {"F8} {"FF} {
+ \expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \__umi_brace_error
+ }
+
+ \cs_new_protected:Npn \umiPatchCmdUnicodeArg #1 { % #1 = \big
+ \exp_args:NNc \__umi_patch_cmd_aux #1 {umi-before-patch~\cs_to_str:N #1}
+ }
+ \cs_new_protected:Npn \__umi_patch_cmd_aux #1 #2 { % #1 = \big, #2 = \umi-before-patch␣big
+ \cs_new_eq:NN #2 #1 % error if #2 already defined i.e. already patched
+ \cs_gset_protected:Npn #1 {\umiBraceNext #2}
+ }
+
+ % the situation for \big / \bigl is a bit complicated -- \bigl = \mathopen \big,
+ % and \mathopen expect implicit {...} right after it without any assignment
+ % while it's possible to patch the source code of \big in a more sophisticated way to keep the implicit group
+ % it's simpler to just pile on another implicit group...
+ % consequently, \Bigl etc. does not need patching
+ \cs_new_protected:Npn \umiPatchCmdUnicodeArgExtraGroup #1 { % #1 = \big
+ \exp_args:NNc \__umi_patch_cmd_extra_group_aux #1 {umi-before-patch~\cs_to_str:N #1}
+ }
+ \cs_new_protected:Npn \__umi_patch_cmd_extra_group_aux #1 #2 { % #1 = \big, #2 = \umi-before-patch␣big
+ \cs_new_eq:NN #2 #1 % error if #2 already defined i.e. already patched
+ \cs_gset_protected:Npn #1 {\bgroup \umiBraceNext {\__umi_patch_cmd_extra_group_auxii #2}}
+ }
+ \cs_new_protected:Npn \__umi_patch_cmd_extra_group_auxii #1 #2 { #1 {#2} \egroup }
+
+ \cs_new_protected:Npn \umiPatchCmdUnicodeTwoArgs #1 {
+ \exp_args:NNc \__umi_patch_cmd_two_aux #1 {umi-before-patch~\cs_to_str:N #1}
+ }
+ \cs_new_protected:Npn \__umi_patch_cmd_two_aux #1 #2 { % #1 = \frac, #2 = \umi-before-patch␣frac
+ \cs_new_eq:NN #2 #1
+ \cs_gset_protected:Npn #1 {
+ \umiBraceNext {\__umi_patch_cmd_two_auxii #2}
+ }
+ }
+ \cs_new_protected:Npn \__umi_patch_cmd_two_auxii #1 #2 { % #1 = \umi-before-patch␣frac, #2 = {α}
+ \umiBraceNext {
+ #1 {#2}
+ }
+ }
+
+ \msg_new:nnn {unicode-math-input} {unpatch-without-patch} {
+ #1 was~not~patched!
+ }
+ \cs_new_protected:Npn \umiUnpatchCmdUnicodeArg #1 {
+ \bgroup \exp_args:NNc \egroup \__umi_unpatch_cmd {umi-before-patch~\cs_to_str:N #1} #1
+ }
+ \cs_new_protected:Npn \__umi_unpatch_cmd #1 #2 {
+ \ifdefined #1 \else \msg_error:nnn {unicode-math-input} {unpatch-without-patch} {#2} \fi
+ \cs_gset_eq:NN #2 #1
+ \cs_undefine:N #1
+ }
+
+ \bool_if:NF\__umi_ignore_patch_delimiter_commands{
+ \AtBeginDocument{
+ \umiPatchCmdUnicodeArgExtraGroup \big
+ \umiPatchCmdUnicodeArgExtraGroup \Big
+ \umiPatchCmdUnicodeArgExtraGroup \bigg
+ \umiPatchCmdUnicodeArgExtraGroup \Bigg
+ }
+ }
+
+}
+
+
+% ======== definitions.
+
+\msg_new:nnn {unicode-math-input} {prime-already-patched} {
+ The~'~symbol~is~already~patched,~call~umiUnpatchPrime~first.
+}
+\msg_new:nnn {unicode-math-input} {prime-not-patched} {
+ The~'~symbol~is~not~patched,~call~umiPatchPrime~first.
+}
+
+\cs_new_protected:Npn \umiPatchPrime {
+ \ifdefined \__umi_prime_backup
+ \msg_error:nn {unicode-math-input} {prime-already-patched}
+ \else
+ \__umi_backup_prime_definition
+ \__umi_special_handle{'}{\__umi_superscript \umiPrime}
+ \fi
+}
+
+\cs_new_protected:Npn \umiUnpatchPrime {
+ \ifdefined \__umi_prime_backup
+ \__umi_restore_prime_definition
+ \cs_undefine:N \__umi_prime_backup
+ \else
+ \msg_error:nn {unicode-math-input} {prime-not-patched}
+ \fi
+}
+
+
+\cs_gset_protected:Npn \__umi_gtmp #1 { % auxiliary to define the following commands where #1 is \cA\'
+ \cs_new_protected:Npn \__umi_backup_prime_definition {
+ \cs_gset_eq:NN \__umi_prime_backup #1
+ }
+ \cs_new_protected:Npn \__umi_restore_prime_definition {
+ \cs_gset_eq:NN #1 \__umi_prime_backup
+ }
+}
+\expandafter \expandafter \expandafter \__umi_gtmp \char_generate:nn {`'} {13}
+
+\bool_if:NF\__umi_ignore_patch_prime{
+ \AtBeginDocument{\umiPatchPrime}
+}
+
+\__umi_special_handle{′}{\__umi_superscript \umiPrime}
+\__umi_special_handle{″}{\__umi_superscript{\umiPrime\umiPrime}}
+\__umi_special_handle{‴}{\__umi_superscript{\umiPrime\umiPrime\umiPrime}}
+\__umi_special_handle{⁗}{\__umi_superscript{\umiPrime\umiPrime\umiPrime\umiPrime}}
+\__umi_special_handle{‵}{\__umi_superscript \umiBackprime}
+\__umi_special_handle{‶}{\__umi_superscript{\umiBackprime\umiBackprime}}
+\__umi_special_handle{‷}{\__umi_superscript{\umiBackprime\umiBackprime\umiBackprime}}
+
+\__umi_special_handle{⁰}{\__umi_superscript 0}
+\__umi_special_handle{¹}{\__umi_superscript 1}
+\__umi_special_handle{²}{\__umi_superscript 2}
+\__umi_special_handle{³}{\__umi_superscript 3}
+\__umi_special_handle{⁴}{\__umi_superscript 4}
+\__umi_special_handle{⁵}{\__umi_superscript 5}
+\__umi_special_handle{⁶}{\__umi_superscript 6}
+\__umi_special_handle{⁷}{\__umi_superscript 7}
+\__umi_special_handle{⁸}{\__umi_superscript 8}
+\__umi_special_handle{⁹}{\__umi_superscript 9}
+\__umi_special_handle{⁺}{\__umi_superscript +}
+\__umi_special_handle{⁻}{\__umi_superscript -}
+\__umi_special_handle{⁼}{\__umi_superscript =}
+\__umi_special_handle{⁽}{\__umi_superscript (}
+\__umi_special_handle{⁾}{\__umi_superscript )}
+\__umi_special_handle{ᴬ}{\__umi_superscript A}
+\__umi_special_handle{ᴮ}{\__umi_superscript B}
+\__umi_special_handle{ᴰ}{\__umi_superscript D}
+\__umi_special_handle{ᴱ}{\__umi_superscript E}
+\__umi_special_handle{ᴳ}{\__umi_superscript G}
+\__umi_special_handle{ᴴ}{\__umi_superscript H}
+\__umi_special_handle{ᴵ}{\__umi_superscript I}
+\__umi_special_handle{ᴶ}{\__umi_superscript J}
+\__umi_special_handle{ᴷ}{\__umi_superscript K}
+\__umi_special_handle{ᴸ}{\__umi_superscript L}
+\__umi_special_handle{ᴹ}{\__umi_superscript M}
+\__umi_special_handle{ᴺ}{\__umi_superscript N}
+\__umi_special_handle{ᴼ}{\__umi_superscript O}
+\__umi_special_handle{ᴾ}{\__umi_superscript P}
+\__umi_special_handle{ᴿ}{\__umi_superscript R}
+\__umi_special_handle{ᵀ}{\__umi_superscript T}
+\__umi_special_handle{ᵁ}{\__umi_superscript U}
+\__umi_special_handle{ⱽ}{\__umi_superscript V}
+\__umi_special_handle{ᵂ}{\__umi_superscript W}
+\__umi_special_handle{ᵃ}{\__umi_superscript a}
+\__umi_special_handle{ᵇ}{\__umi_superscript b}
+\__umi_special_handle{ᶜ}{\__umi_superscript c}
+\__umi_special_handle{ᵈ}{\__umi_superscript d}
+\__umi_special_handle{ᵉ}{\__umi_superscript e}
+\__umi_special_handle{ᶠ}{\__umi_superscript f}
+\__umi_special_handle{ᵍ}{\__umi_superscript g}
+\__umi_special_handle{ʰ}{\__umi_superscript h}
+\__umi_special_handle{ⁱ}{\__umi_superscript i}
+\__umi_special_handle{ʲ}{\__umi_superscript j}
+\__umi_special_handle{ᵏ}{\__umi_superscript k}
+\__umi_special_handle{ˡ}{\__umi_superscript l}
+\__umi_special_handle{ᵐ}{\__umi_superscript m}
+\__umi_special_handle{ⁿ}{\__umi_superscript n}
+\__umi_special_handle{ᵒ}{\__umi_superscript o}
+\__umi_special_handle{ᵖ}{\__umi_superscript p}
+\__umi_special_handle{ʳ}{\__umi_superscript r}
+\__umi_special_handle{ˢ}{\__umi_superscript s}
+\__umi_special_handle{ᵗ}{\__umi_superscript t}
+\__umi_special_handle{ᵘ}{\__umi_superscript u}
+\__umi_special_handle{ᵛ}{\__umi_superscript v}
+\__umi_special_handle{ʷ}{\__umi_superscript w}
+\__umi_special_handle{ˣ}{\__umi_superscript x}
+\__umi_special_handle{ʸ}{\__umi_superscript y}
+\__umi_special_handle{ᶻ}{\__umi_superscript z}
+\__umi_special_handle{ᵝ}{\__umi_superscript \beta}
+\__umi_special_handle{ᵞ}{\__umi_superscript \gamma}
+\__umi_special_handle{ᵟ}{\__umi_superscript \delta}
+\__umi_special_handle{ᵠ}{\__umi_superscript \phi}
+\__umi_special_handle{ᵡ}{\__umi_superscript \chi}
+\__umi_special_handle{ᶿ}{\__umi_superscript \theta}
+
+\__umi_special_handle{₀}{\__umi_subscript 0}
+\__umi_special_handle{₁}{\__umi_subscript 1}
+\__umi_special_handle{₂}{\__umi_subscript 2}
+\__umi_special_handle{₃}{\__umi_subscript 3}
+\__umi_special_handle{₄}{\__umi_subscript 4}
+\__umi_special_handle{₅}{\__umi_subscript 5}
+\__umi_special_handle{₆}{\__umi_subscript 6}
+\__umi_special_handle{₇}{\__umi_subscript 7}
+\__umi_special_handle{₈}{\__umi_subscript 8}
+\__umi_special_handle{₉}{\__umi_subscript 9}
+\__umi_special_handle{₊}{\__umi_subscript +}
+\__umi_special_handle{₋}{\__umi_subscript -}
+\__umi_special_handle{₌}{\__umi_subscript =}
+\__umi_special_handle{₍}{\__umi_subscript (}
+\__umi_special_handle{₎}{\__umi_subscript )}
+\__umi_special_handle{ₐ}{\__umi_subscript a}
+\__umi_special_handle{ₑ}{\__umi_subscript e}
+\__umi_special_handle{ₕ}{\__umi_subscript h}
+\__umi_special_handle{ᵢ}{\__umi_subscript i}
+\__umi_special_handle{ⱼ}{\__umi_subscript j}
+\__umi_special_handle{ₖ}{\__umi_subscript k}
+\__umi_special_handle{ₗ}{\__umi_subscript l}
+\__umi_special_handle{ₘ}{\__umi_subscript m}
+\__umi_special_handle{ₙ}{\__umi_subscript n}
+\__umi_special_handle{ₒ}{\__umi_subscript o}
+\__umi_special_handle{ₚ}{\__umi_subscript p}
+\__umi_special_handle{ᵣ}{\__umi_subscript r}
+\__umi_special_handle{ₛ}{\__umi_subscript s}
+\__umi_special_handle{ₜ}{\__umi_subscript t}
+\__umi_special_handle{ᵤ}{\__umi_subscript u}
+\__umi_special_handle{ᵥ}{\__umi_subscript v}
+\__umi_special_handle{ₓ}{\__umi_subscript x}
+\__umi_special_handle{ᵦ}{\__umi_subscript \beta}
+\__umi_special_handle{ᵧ}{\__umi_subscript \gamma}
+\__umi_special_handle{ᵨ}{\__umi_subscript \rho}
+\__umi_special_handle{ᵩ}{\__umi_subscript \phi}
+\__umi_special_handle{ᵪ}{\__umi_subscript \chi}
diff --git a/macros/latex/contrib/unicode-math-input/unicode-math-input.tex b/macros/latex/contrib/unicode-math-input/unicode-math-input.tex
new file mode 100644
index 0000000000..7b385c34cc
--- /dev/null
+++ b/macros/latex/contrib/unicode-math-input/unicode-math-input.tex
@@ -0,0 +1,391 @@
+%! TEX program = lualatex
+\ProvidesFile{unicode-math-input.tex} [2023/05/12 v0.0.0 ]
+\RequirePackage{fvextra}
+\documentclass{l3doc}
+\usepackage[svgnames]{xcolor}
+\EnableCrossrefs
+\CodelineIndex
+\fvset{breaklines=true,gobble=0,tabsize=4,frame=single,numbers=left,numbersep=3pt}
+\AtBeginDocument{\DeleteShortVerb\"}
+\MakeOuterQuote{"}
+\usepackage{cleveref}
+\usepackage{fontspec}
+\setmonofont{DejaVu Sans Mono}[Scale=0.8]
+\usepackage[bold-style=ISO]{unicode-math}
+\tracinglostchars=3
+\newcommand\csref[1]{\texttt{\hyperref[doc/function//#1]{\textbackslash #1}}}
+\newcommand\varref[1]{\texttt{\hyperref[doc/function//#1]{#1}}}
+\begin{document}
+\hfuzz=1pt
+\GetFileInfo{\jobname.tex}
+
+\title{\pkg{unicode-math-input} --- Allow entering Unicode symbols in math formulas\thanks{This file
+ describes version \fileversion, last revised \filedate.}
+}
+\author{user202729%
+%\thanks{E-mail: (not set)}
+}
+\date{Released \filedate}
+
+\maketitle
+
+\begin{abstract}
+Allow entering Unicode symbols in math formulas.
+\end{abstract}
+
+\section{Introduction}
+
+This package allows entering Unicode symbols in math formulas.
+
+\subsection{Existing packages}
+
+There are several existing packages, but other than |unicode-math| (which also changes the output encoding)
+they does not cover a lot of characters and/or does not handle several issues well.
+
+We compare the situation with several existing packages:
+
+\begin{itemize}
+ \item \pkg{unixode}:
+ \begin{itemize}
+ \item defines |′| to be |\prime| which is big and not usable, it should be |^{\prime}|
+ similar to |'|'s definition.
+ \item defines |–| (en dash) to be nothing, which breaks the character even in text mode.
+ \item does not define |×| or |±| (they're already valid in text mode in \LaTeX, but will be
+ silently omitted in math mode)
+ \item does not handle consecutive superscript/subscript characters.
+ \item you need to manually patch the source code a bit in order to make it work with PDF\LaTeX. And even after that it will raise lots of warnings about redefining Unicode characters.
+ \end{itemize}
+ \item \pkg{utf8x}:
+ \begin{itemize}
+ \item incompatible with lots of packages.
+ \item does not define $\bigoplus$ (|\bigoplus|)
+ \item also does not handle consecutive superscript/subscript characters.
+ \end{itemize}
+\end{itemize}
+
+See also \url{https://tex.stackexchange.com/a/628285}.
+
+\subsection{Features}
+
+\LaTeX's implementation of input encoding and font encoding is \emph{very} complicated, necessitated by the fact that non-Unicode \TeX\ engines handles each UTF-8 character as multiple tokens and enc\TeX\ extension is not enabled in \LaTeX.%
+\footnote{Refer to \url{https://tex.stackexchange.com/a/266282/250119} for a way to force-enable enc\TeX\ extension in
+\LaTeX\ if you're interested.}
+
+There's a few other issues that we don't really need to deal with, because they are in the next layer:
+
+\begin{itemize}
+ \item \href{https://tex.stackexchange.com/q/31640/250119}{What is the use of the command \texttt{\textbackslash IeC}?}
+ \item \url{https://tex.stackexchange.com/a/239575/250119}
+
+\end{itemize}
+
+We don't need to deal with |\IeC| as since \TeX\ Live 2019, the mechanism is no longer used and the Unicode character itself
+is written to auxiliary files.
+%\immediate\openout 5=a.tex
+%\makeatletter
+%\let \protect \@unexpandable@protect
+%\immediate\write 5{a á b}
+
+We need to get the following things correct:
+
+\begin{itemize}
+ \item |\left⟨|
+
+ In Lua\LaTeX\ in order to implement this we need to hard code the |\Udelcode| of the character,
+ so if |\langle| is redefined, the change will not follow.
+
+ An alternative is to overwrite the definition of |\left| built-in, but this is not used.
+
+ \item |\big⟨| (in \pkg{amsmath} package or outside)
+
+ In PDF\LaTeX\ there's an issue of argument-grabbing (|\big| etc. is a macro so they will
+ only grab the first octet of the |⟨| character), so the macro must be patched.
+
+ Furthermore, the patching is done |\AtBeginDocument| in case |amsmath| etc. is loaded after this package.
+
+ We handle |\big \Big \bigg \Bigg| and the |\bigl|, |\bigr| variants etc.
+
+ Pass the option \varref{ignore-patch-delimiter-commands} to disable the behavior in case of package clash.
+
+ \item in \pkg{unicode-math}, |a`| renders as |a^{\backprime}| i.e. $a^{\backprime}$.
+ We will not modify the default behavior i.e. $a\text{`}$ in this package.
+
+ \item |\section{$1 × 2$}| (for writing to auxiliary file in table of contents) -- as mentioned above,
+ since \TeX\ Live 2019 this is correct by default.
+ \item Some characters such as |×| or |½| in PDF\LaTeX\ are already
+ usable outside math mode, we try to not break the compatibility.
+ \item The symbol should work correctly when appear at the start of an alignment entry,
+ e.g., the start of an |align*| cell.
+ \item |$2³⁴$| (consecutive Unicode characters for superscript/subscript, refer to \url{https://tex.stackexchange.com/q/344160/250119}.) Also need to handle |'| similarly.
+
+ \item This packages does modify the default definition of |'| to allow |G'²| to work however.
+ Pass the option \varref{ignore-patch-prime} to disable the behavior in case of package clash.
+
+ \item The original implementation of |'| is somewhat interesting that it allows sequences such as |G'^\bgroup 123\egroup| to work,
+ we will not emulate it here.
+
+ \item Also need to handle Unicode prime symbols |′|, |″| etc.
+
+ \item To minimize errors, we make |≢| default to |\nequiv|, but fallback to |\not\equiv|
+ if the former is not available.
+
+ We should also take care of aliases -- for example, |≰| should check |\nle| and |\nleq| before fallback to |\not\le| or |\not\leq|.
+
+ Note that by default (or with \pkg{amsmath} or \pkg{amssymb}),
+ |\not| does not smartly check the following symbol,
+ however with some packages such as \pkg{unicode-math},
+ \pkg{txfonts} the |\not| does do that -- in particular, it checks for the presence of control sequences named
+ |\notXXX| and |\nXXX| where |XXX| stands for the original control sequence/character.
+
+ It would be beneficial for \pkg{amssymb}
+ to make |\not| smart, as for example |\not\exists| looks worse than |\nexists|,
+ however the package does not touch |\not|.
+
+ \item Similarly, |''| default to |^{\dprime}| if available, else fallback to |^{\prime\prime}|.
+
+ \item Whenever possible, we do not make the symbols have active catcode, only change the mathcode,
+ that way usage of the symbols in places such as |fancyvrb| environment is minimally affected. (see test files for an example)
+ \item We try to make minimum assumptions about the internal implementation details of \LaTeX\ packages; nevertheless this is not always possible.
+
+ \item Combining modifiers (such as |U+00305 COMBINING OVERLINE| in |a̅|, which corresponds to |\overbar|) are difficult to support
+ (although with whole-file scanning + \pkg{rescansync} or Lua\TeX's |process_input_buffer| callback
+ it's not impossible; an alternative is to use Lua\TeX\ callback to modify the math list
+ after it's constructed, see \url{https://github.com/wspr/unicode-math/issues/555#issuecomment-1045207378}
+ for an example),
+ plus |unicode-math| does not support them anyway,
+ so they will not be supported.
+
+ They're difficult to support because normally the modifier appear after the character that it modifies
+ but \TeX\ requires the command (e.g. |\overbar|) to appear \emph{before} the character that it modifies.
+
+ As a special case, the 4 commands |\enclosecircle| |\enclosesquare| |\enclosediamond| and |\enclosetriangle|
+ are supported (simply because the \TeX\ command can appear after the character it modifies)
+
+ \item The fraction slash |U+2044 FRACTION SLASH|, as in |1|⁄|2| rendering $\frac{1}{2}$, is also not implemented
+ because of similar difficulty as above.
+ \item Symbols such as |√| or |∛| will be equivalent to |\sqrt| command (taking an argument to draw a square root)
+ instead of |\surd| (the symbol itself), unlike \pkg{unicode-math}.
+
+ While sequences such as |⁵√{67}| may feasibly be supported without breaking too many things,
+ implementation is difficult and we don't see much use for it.
+ \item Similarly, one might expect that $⏟$ |U+23DF BOTTOM CURLY BRACKET| get mapped to |\underbrace|,
+ but the behavior of such command would be a bit unexpected (you need to
+ write $⏟$|{123}_{456}| to get $\smash{\underbrace{123}_{456}}$), so this will not be the default.
+
+ \item the Unicode character is mapped indirectly to the control sequence,
+ so that when the user/some package redefines a control sequence such as |\pi|, the
+ corresponding Unicode character (|π|) will also change. This will incur a small loss in efficiency however.
+
+ (modulo the issue with |\Udelcode| mentioned above)
+\end{itemize}
+
+There are some issues however:
+\begin{itemize}
+ \item \textsf{\rlap{0}\kern 1.2pt\relax 0} |U+1D7D8 MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO|
+gets translated to |\mathbb{0}|, but this is incorrect by default
+unless the blackboard bold font happens to have such a character.
+
+(nevertheless, it's difficult to change math font in the middle of the document anyway.
+Refer to \url{https://tex.stackexchange.com/q/30049/250119}.)
+
+\item In the \pkg{unicode-math} source code there's this remark:
+
+ \begin{quote}
+ The catcode setting is to work around (strange?) behaviour in Lua\TeX\ in
+which catcode 11 characters don't have italic correction for maths. We don't adjust
+ascii chars, however, because certain punctuation should not have their catcodes
+changed.
+\end{quote}
+
+This feature is currently unimplemented.
+
+\item At the moment, following a Unicode superscript character, double superscript will not be defined --
+ that is, |G²^3^4| will just display as |G^{234}| --
+ while this is fixable, we don't see much point in detecting this error.
+\end{itemize}
+
+\section{Usage}
+
+Simply include the package.
+
+\begin{verbatim}
+\usepackage{unicode-math-input}
+\end{verbatim}
+
+Because by default the \pkg{unicode-math} package will already allow entering Unicode symbols in math formulas, this package will raise an error if the other package is already loaded.
+
+\section{Advanced commands and options}
+
+\begin{function}{
+ \umiMathbf,\umiMathit,\umiMathbfit,\umiMathscr,\umiMathbfscr,\umiMathfrak,\umiMathbb,\umiMathbbit,\umiMathbffrak,\umiMathsf,\umiMathsfbf,\umiMathsfit,\umiMathsfbfit,\umiMathtt
+ }
+ \begin{syntax}
+ |\umiMathbf {...}|
+ |\umiMathit {...}|
+ \end{syntax}
+ These functions are not to be used directly. But you can redefine them to customized behavior of bold/italic/etc. Unicode characters.
+
+ For example you can |\renewcommand\umiMathbf[1]{\mathbf{#1}}| which is the default behavior.
+
+ More usefully, you may want to |\renewcommand\umiMathbf{\bm}| to make entered characters such as
+ $𝐚$ appear bold italic in the output, remember to load package \pkg{bm} if you want to do so (which is |unicode-math| behavior
+ with |[bold-style=ISO]| package option).
+\end{function}
+
+\begin{function}{\umiFrac}
+ \begin{syntax}
+ |\umiFrac {1} {2}|
+ \end{syntax}
+ Not to be used directly, but you can redefine it such as
+ |\let\umiFrac\tfrac| (or more clearly, |\renewcommand\umiFrac[2]{\tfrac{#1}{#2}}|)
+ to customize the appearance of Unicode characters like |½|.
+
+ If you want to customize the appearance of individual symbols, consider using \csref{umiDefineMathChar}.
+\end{function}
+
+\begin{function}{\umiDefineMathChar}
+ \begin{syntax}
+ |\umiDefineMathChar {α} {\alpha}|
+ \end{syntax}
+ Does what it says.
+
+ Note that the Unicode character must be braced.
+
+ (You may choose to call \csref{umiPatchCmdUnicodeArg}| \umiDefineMathChar|
+ beforehand so bracing is not necessary, but this is not really recommended)
+
+ This might or might not destroy the existing text-mode definition. For now,
+ one way to preserve it is |\umiDefineMathChar {²} {\TextOrMath{\texttwosuperior}{^2}}|.
+\end{function}
+
+\begin{function}{\umiDefineMathDelimiter}
+ \begin{syntax}
+ |\umiDefineMathDelimiter {⟨} \langle|
+ \end{syntax}
+ You must use this in order to use the Unicode character with |\left|, |\big|, |\bigl| etc.
+ (because of the internal detail being that in Xe\LaTeX\ and Lua\LaTeX,
+ as this package does not change the character catcode to be active,
+ it's necessary to set the |delcode| as mentioned before)
+
+ In that case the second argument must be a single token.
+
+ Unfortunately, the command does not always work.
+\end{function}
+
+\begin{function}{\umiRefreshDelimiterList}
+ \begin{syntax}
+ |\umiRefreshDelimiterList|
+ \end{syntax}
+ You should normally not need this command.
+
+ As mentioned before, in Lua\LaTeX\ once a command is redefined, the Unicode character does not automatically update.
+
+ This command will check all the normal delimiter Unicode characters. In PDF\LaTeX\ this command does nothing.
+
+ Another way is to use \csref{umiDefineMathDelimiter} to manually refresh individual Unicode characters,
+ this is also useful if you define an Unicode character that is not "normally" a delimiter.
+\end{function}
+
+\begin{variable}{ignore-refresh-delimiter-list}
+ Package option.
+
+ \csref{umiRefreshDelimiterList} will be run |\AtBeginDocument|. Pass this to disable it running.
+
+ Only needed if there's some package clash or if there's spurious warning on "not determined to be a delimiter" etc.
+\end{variable}
+
+\begin{function}{\umiPatchCmdUnicodeArg,\umiUnpatchCmdUnicodeArg}
+ \begin{syntax}
+ |\umiPatchCmdUnicodeArg \sqrt|
+ |\umiUnpatchCmdUnicodeArg \sqrt|
+ \end{syntax}
+ After executing this command, the command specified in the argument (|\sqrt| in this example)
+ can be called with one argument being an Unicode character without needing a brace.
+
+ (i.e. you can write |\sqrt α| instead of |\sqrt{α}|.)
+
+ Because of implementation detail,
+ \begin{itemize}
+ \item |\sqrtα| (without the space between |\sqrt| and |α|) works in PDF\LaTeX\ but not Lua\LaTeX. (so this form is not recommended.)
+ \item |\sqrt α| works in Lua\LaTeX\ without needing the patch. In other words, the patch does nothing in Unicode engines.
+ \end{itemize}
+
+ The command being patched must take at least one mandatory argument as the first argument, and it only affect that first argument.
+ In other words, |\sqrt[3]α| cannot be patched this way unless you do e.g. |\newcommand\cbrt[1]{\sqrt[3]{#1}}| then |\umiPatchCmdUnicodeArg\cbrt|,
+ then |\cbrt α| works (but |\sqrt[3]α| still doesn't).
+\end{function}
+
+\begin{function}{\umiPatchCmdUnicodeTwoArgs}
+ \begin{syntax}
+ |\umiPatchCmdUnicodeTwoArgs \frac|
+ |\umiUnpatchCmdUnicodeArg \frac|
+ \end{syntax}
+ Similar to above, but for commands with (at least) two mandatory arguments.
+
+ Only affects these 2 mandatory arguments.
+\end{function}
+
+\begin{function}{\umiPatchCmdUnicodeArgExtraGroup}
+ \begin{syntax}
+ |\umiPatchCmdUnicodeArgExtraGroup \Big|
+ \end{syntax}
+ Don't use this command unless you know exactly what you're doing.
+
+ Similar to |\umiPatchCmdUnicodeArg|, but open an implicit group before executing anything and close the group after.
+
+ The command being patched must take exactly one argument.
+
+ This is useful because some \TeX\ primitives such as |^| or |\mathopen|
+ requires either a single "character" or a group braced with |{...}| / |\bgroup...\egroup|.
+\end{function}
+
+\begin{variable}{ignore-patch-delimiter-commands}
+ Package option. Pass this to avoid patching |\Big| etc. with the command above (only needed if there's some package clash).
+\end{variable}
+
+\begin{function}{\umiBraceNext}
+ \begin{syntax}
+ |\umiBraceNext {abc...} αxyz...|
+ \end{syntax}
+ In the example above, after some steps of execution of \TeX, the state will be
+ |abc... {α}xyz...|.
+
+ Formally: if the character following the first argument to |\umiBraceNext| is not representable in a single byte
+ and the engine is not Unicode, the character will be braced, otherwise nothing happens. Then the argument
+ is put back in the input stream.
+
+ This is an internal command mainly useful for defining the command above, for example after
+\begin{verbatim}
+\let\oldbig\big
+\def\big{\umiBraceNext{\oldbig}}
+\end{verbatim}
+then |\big⟨| will eventually execute |\oldbig{⟨}| which is the desired behavior (that |\oldbig| expects one braced argument).
+\end{function}
+
+\begin{variable}{ignore-patch-prime}
+ Do not patch the default definition of |'| in math mode.
+
+ By default it's patched to allow |G'²| and |G²'| to work. Only use this when there's some package clash.
+\end{variable}
+
+\begin{function}{\umiPatchPrime,\umiUnpatchPrime}
+ \begin{syntax}
+ |\umiPatchPrime|
+ |\umiUnpatchPrime|
+ \end{syntax}
+ As mentioned above, by default |\umiPatchPrime| is run |\AtBeginDocument|. But it can be patched
+ and unpatched manually.
+
+ Note that it's undefined behavior if some package modifies the definition of active |'|
+ while it's patched. To resolve conflict, unpatch |'|, load the package, then patch again.
+\end{function}
+
+\section{Compatibility}
+
+This package should have tested with various \TeX\ distribution versions on Overleaf.
+
+\PrintChanges
+\PrintIndex
+\Finale
+
+\end{document}
diff --git a/macros/luatex/latex/sympycalc/README.md b/macros/luatex/latex/sympycalc/README.md
index 7b34198db4..aa918b9a9a 100644
--- a/macros/luatex/latex/sympycalc/README.md
+++ b/macros/luatex/latex/sympycalc/README.md
@@ -1,7 +1,8 @@
-SympyCalc is a package to work with Sympy with TeX printing.
+SympyCalc is a package to work with Sympy (Python) with TeX printing.
-----------------------------------------------------------------------------
SympyCalc un package pour travailler avec le module Sympy et sa sortie LaTeX.
-----------------------------------------------------------------------------
Author : Cédric Pierquet
email : cpierquet@outlook.fr
-Licence : Released under the LaTeX Project Public License v1.3c or later, see http://www.latex-project.org/lppl.txt \ No newline at end of file
+Licence : Released under the LaTeX Project Public License v1.3c or later, see http://www.latex-project.org/lppl.txt
+Note : SymPy is a Python library for symbolic math (sympy.org). \ No newline at end of file
diff --git a/macros/luatex/latex/sympycalc/doc/SympyCalc-doc.pdf b/macros/luatex/latex/sympycalc/doc/SympyCalc-doc.pdf
index 20964a4b68..f2e9838bee 100644
--- a/macros/luatex/latex/sympycalc/doc/SympyCalc-doc.pdf
+++ b/macros/luatex/latex/sympycalc/doc/SympyCalc-doc.pdf
Binary files differ
diff --git a/macros/luatex/latex/sympycalc/doc/SympyCalc-doc.tex b/macros/luatex/latex/sympycalc/doc/SympyCalc-doc.tex
index b294eb56f6..418bccc652 100644
--- a/macros/luatex/latex/sympycalc/doc/SympyCalc-doc.tex
+++ b/macros/luatex/latex/sympycalc/doc/SympyCalc-doc.tex
@@ -3,8 +3,8 @@
% arara: lualatex: {shell: yes, synctex: no, interaction: batchmode} if found('log', '(undefined references|Please rerun|Rerun to get)')
\documentclass[french,a4paper,11pt]{article}
-\def\SCversion{0.1.0}
-\def\SCdate{5 mai 2023}
+\def\SCversion{0.1.1}
+\def\SCdate{8 mai 2023}
\usepackage[executable=python.exe]{pyluatex}
\usepackage[svgnames]{xcolor}
\usepackage{siunitx}
@@ -68,13 +68,13 @@
commentstyle={\itshape\color{violet}},
keywordstyle={\bfseries\color{DodgerBlue}},%
classoffset=0,%
- keywords={frac,dfrac,int,sqrt},%
+ keywords={frac,dfrac,int,sqrt,mathcal},%
keywordstyle={\bfseries\color{DodgerBlue}},%
classoffset=1,%
- morekeywords={sympycalc,dsympycalc,sympydev,dsympydev,sympyfact,dsympyfact,sympyderiv,dsympyderiv,sympyprim,dsympyprim,sympyintegr,dsympyintegr,sympylim,dsympylim,sympyfexpo,dsympyfexpo,sympyresol,dsympyresol,sympyresolC,dsympyresolC},%
+ morekeywords={sympycalc,dsympycalc,sympydev,dsympydev,sympyfact,dsympyfact,sympyderiv,dsympyderiv,sympyprim,dsympyprim,sympyintegr,dsympyintegr,sympylim,dsympylim,sympyfexpo,dsympyfexpo,sympyresol,dsympyresol,sympyresolC,dsympyresolC,sympynbderiv,dsympynbderiv,sympyimage,dsympyimage,pythonq},%
keywordstyle={\bfseries\color{purple}},%
classoffset=2,%
- morekeywords={solve},%
+ morekeywords={solve,radsimp,cancel},%
keywordstyle={\bfseries\color{ForestGreen}},%
classoffset=3,%
morekeywords={NoSimplif,Simplif},%
@@ -148,6 +148,18 @@
\end{tabular}
\end{center}
+\begin{center}
+ \begin{minipage}{0.5\linewidth}
+ \begin{tcolorbox}[colframe=DarkBlue!50,colback=DarkBlue!5]
+ \begin{center}
+ \textsf{SymPy} est un module \textsf{Python} qui permet de faire du calcul symbolique.
+
+ \texttt{\url{https://www.sympy.org/}}
+ \end{center}
+ \end{tcolorbox}
+ \end{minipage}
+\end{center}
+
\vspace{0.25cm}
{$\blacktriangleright$~~Compilation en \hologo{LuaLaTeX}, avec un accès \textsf{--shell-escape}, en \textit{partenariat} avec \textsf{pyluatex}.}
@@ -319,7 +331,7 @@ Autant que peut se faire, les commandes sont assez explicites sur leur fonctionn
\item \texttt{\textbackslash \textcolor{purple}{sympy...}} : commande qui simplifie (par défaut), avec règles typographiques \texttt{[fr]} \textsf{romain} ;
\item \texttt{\textbackslash \textcolor{purple}{dsympy...}} : commande qui simplifie (par défaut), avec règles typographiques \texttt{[fr]} \textsf{romain}, et affichage en \texttt{\textbackslash displaystyle} ;
\item \texttt{\textbackslash \textcolor{purple}{sympy...*}} : commande qui simplifie (par défaut), avec règles typographiques \texttt{[fr]} \textsf{italique} ;
- \item \texttt{\textbackslash \textcolor{purple}{dsympy...*}} : commande qui simplifie (par défaut), avec règles typographiques \texttt{[fr]} \textsf{romain}, et affichage en \texttt{\textbackslash displaystyle}.
+ \item \texttt{\textbackslash \textcolor{purple}{dsympy...*}} : commande qui simplifie (par défaut), avec règles typographiques \texttt{[fr]} \textsf{italique}, et affichage en \texttt{\textbackslash displaystyle}.
\end{itemize}
Dans certains cas la \textit{simplification} ne propose pas une sortie \textit{classique}, et il est possible d'empêcher la simplification grâce à l'argument optionnel \texttt{<\textcolor{OliveDrab}{NoSimplif}>}.
@@ -337,9 +349,11 @@ La variable est par défaut \texttt{x}, mais peut-être modifiée grâce à l'ar
\dsympycalc(*)<NoSimplif>{commande sympy}
%commandes spécifiques, sortie standard, détaillées plus loin
+\sympyimage(*)<NoSimplif>{fonction sympy}[variable]{point}
\sympydev(*)<NoSimplif>{expr sympy}[variable]
\sympyfact(*)<NoSimplif>{expr sympy}
\sympyderiv(*)<NoSimplif>{expr sympy}[variable]
+\sympynbderiv(*)<NoSimplif>{expr sympy}[variable]{point}[côté]
\sympyprim(*)<NoSimplif>{expr sympy}[variable]
\sympyintegr(*)<NoSimplif>{expr sympy}[variable]{borne inf}{borne sup}
\sympylim(*)<NoSimplif>{expr sympy}[variable]{point}[côté]
@@ -349,8 +363,10 @@ La variable est par défaut \texttt{x}, mais peut-être modifiée grâce à l'ar
%commandes spécifiques, sortie displaystyle, détaillées plus loin
\dsympydev(*)<NoSimplif>{expr sympy}[variable]
+\dsympyimage(*)<NoSimplif>{fonction sympy}[variable]{point}
\dsympyfact(*)<NoSimplif>{expr sympy}
\dsympyderiv(*)<NoSimplif>{expr sympy}[variable]
+\dsympynbderiv(*)<NoSimplif>{expr sympy}[variable]{point}[côté]
\dsympyprim(*)<NoSimplif>{expr sympy}[variable]
\dsympyintegr(*)<NoSimplif>{expr sympy}[variable]{borne inf}{borne sup}
\dsympylim(*)<NoSimplif>{expr sympy}[variable]{point}[côté]
@@ -371,8 +387,6 @@ L'\og infini \fg{} est disponible en \textsf{sympy}, grâce à \texttt{+oo} ou \
Un petit \textit{guide} pour \textsf{sympy} est disponible à : \url{https://hashdork.com/fr/sympy-library-guide/}.
\end{tipblock}
-\newpage
-
\section{Limitations}
\begin{warningblock}
@@ -460,6 +474,45 @@ $x_2 = \dsympycalc{solve(1/3*x**2+9*x+4,x)[1]}$
\section{Quelques commandes spécifiques}
+\subsection{Images}
+
+\begin{cautionblock}
+\cmaj{0.1.1} La commande pour calculer une image via \textsf{sympy} est \texttt{\textbackslash \textcolor{purple}{sympyimage}} ou \texttt{\textbackslash \textcolor{purple}{dsympyimage}}.
+
+Il vaut mieux vérifier si le résultat formaté est conforme aux attentes, et sinon utiliser la commande générique.
+\end{cautionblock}
+
+\begin{bloctext}[listing only]
+%commandes pour cacluler une image
+\sympyimage(*)<NoSimplif>{fonction sympy}[variable]{point}
+\dsympyimage(*)<NoSimplif>{fonction sympy}[variable]{point}
+\end{bloctext}
+
+\begin{tipblock}
+Concernant son fonctionnement :
+
+\begin{itemize}
+ \item la version \Cle{*} permet de ne pas formater le \texttt{e} et le \texttt{i} en \textsf{romain} ;
+ \item le premier argument, optionnel et pouvant valoir \texttt{<\textcolor{OliveDrab}{NoSimplif}>} permet d'\textit{annuler} la simplification (attention au comportement de la \textit{simplification} par \textsf{sympy}\ldots)
+ \item le deuxième argument, obligatoire et entre \texttt{\{...\}} est quant à lui la fonction, en langage \textsf{sympy} à passer en \textsf{python} ;
+ \item les derniers arguments, optionnel entre \texttt{[...]} et obligatoire et entre \texttt{\{...\}} correspondent à la variable et le point.
+\end{itemize}
+\vspace*{-\baselineskip}\leavevmode
+\end{tipblock}
+
+\begin{bloctext}
+$f(x)=\dfrac{2+\e^x}{3+4\e^{2x}}$ avec $a=5$ : $f(5)=\dsympyimage{(2+exp(x))/(3+4*exp(2*x))}{5}$
+\end{bloctext}
+
+\begin{bloctext}
+$g(t)=\sqrt{1+\ln(t)}$ avec $a=13$ : $g(13)=\sympyimage{sqrt(1+log(t))}[t]{13}$
+\end{bloctext}
+
+\begin{bloctext}
+$h(x)=2x^2+2,5x+7$ en $a=\sqrt{2}$ :
+$h\left(\sqrt{2}\right)=\dsympyimage{2*x**2+5/2*x+7}{sqrt(2)}$
+\end{bloctext}
+
\subsection{Développement}
\begin{cautionblock}
@@ -599,10 +652,57 @@ Les solutions de $x^3-2,5x+16x=40$ sont $\mathcal{S}=\dsympyresolC{x**3-5/2*x**2
Les solutions de $10\,\e^{4x+5}=2$ sont $\mathcal{S}=\dsympyresol{10*exp(4*x+5)=2}$
\end{bloctext}
-\subsection{Dérivation}
+\subsection{Dérivation locale}
\begin{cautionblock}
-La commande pour dériver, grâce à \textsf{sympy} est \texttt{\textbackslash \textcolor{purple}{sympyderiv}} ou \texttt{\textbackslash \textcolor{purple}{dsympyderv}}.
+\cmaj{0.1.1} La commande pour dériver localement, grâce à \textsf{sympy} est \texttt{\textbackslash \textcolor{purple}{sympynbderiv}} ou \texttt{\textbackslash \textcolor{purple}{dsympynbderiv}}.
+
+Il vaut mieux vérifier si le résultat formaté est conforme aux attentes, et sinon utiliser la commande générique.
+\end{cautionblock}
+
+\begin{bloctext}[listing only]
+%commandes pour dériver localement
+\sympynbderiv(*)<NoSimplif>{expression sympy}[variable]{point}[côté]
+\dsympynbderiv(*)<NoSimplif>{expression sympy}[variable]{point}[côté]
+\end{bloctext}
+
+\begin{tipblock}
+Concernant son fonctionnement :
+
+\begin{itemize}
+ \item la version \Cle{*} permet de ne pas formater le \texttt{e} et le \texttt{i} en \textsf{romain} ;
+ \item le premier argument, optionnel et pouvant valoir \texttt{<\textcolor{OliveDrab}{NoSimplif}>} permet d'\textit{annuler} la simplification (attention au comportement de la \textit{simplification} par \textsf{sympy}\ldots)
+ \item le deuxième argument, obligatoire et entre \texttt{\{...\}} est quant à lui l'expression en langage \textsf{sympy} à passer en \textsf{python} ;
+ \item le troisième argument, optionnel et entre \texttt{[...]} est la variable ;
+ \item les derniers arguments, obligatoire et entre \texttt{\{...\}} et optionnel entre \texttt{[...]} correspondent à la valeur (et la position \texttt{[g]} ou \texttt{[d]}) en laquelle on souhaite travailler.
+\end{itemize}
+\vspace*{-\baselineskip}\leavevmode
+\end{tipblock}
+
+\begin{bloctext}
+Si $f(x)=(x+3)\,\e^{2x}$, alors on peut montrer que $f'(2) = \sympynbderiv{(x+3)*exp(2*x)}{2}$
+\end{bloctext}
+
+\begin{bloctext}
+Le nombre dérivé de la fonction $x \mapsto \sqrt{x}$ en $a=2$ vaut
+$\lim\limits_{x \to 2} \frac{\sqrt{x}-\sqrt{2}}{x-2} = \sympynbderiv{sqrt(x)}{2}$.
+
+Le nombre dérivé de la fonction $x \mapsto \sqrt{x}$ en $a=2$ vaut
+$\lim\limits_{x \to 2} \dfrac{\sqrt{x}-\sqrt{2}}{x-2} = \dsympynbderiv{sqrt(x)}{2}$.
+\end{bloctext}
+
+\begin{bloctext}
+Le nombre dérivé de $\varphi(x) = 1+\dfrac{1}{(x+2)^2}$ en $a=-5$ vaut
+$\lim\limits_{x \to -3} \frac{\varphi(x)-\varphi(-5)}{x-(-5)} = \sympynbderiv{1+1/(x+2)**2}{-5}$.
+
+Le nombre dérivé de $\varphi(x) = 1+\dfrac{1}{(x+2)^2}$ en $a=-5$ vaut
+$\lim\limits_{x \to -3} \dfrac{\varphi(x)-\varphi(-5)}{x-(-5)} = \dsympynbderiv{1+1/(x+2)**2}{-5}$.
+\end{bloctext}
+
+\subsection{Dérivation globale}
+
+\begin{cautionblock}
+La commande pour dériver, grâce à \textsf{sympy} est \texttt{\textbackslash \textcolor{purple}{sympyderiv}} ou \texttt{\textbackslash \textcolor{purple}{dsympyderiv}}.
Il vaut mieux vérifier si le résultat formaté est conforme aux attentes, et sinon utiliser la commande générique.
\end{cautionblock}
@@ -771,43 +871,43 @@ On a $\dfrac{-\sqrt{2}}{1+\i} = \dsympyfexpo{(-sqrt(2))/(1+I)}$
\section{Évolutions}
\begin{tipblock}
-L'utilisateur du package pourra utiliser ses propres fonctions ou commandes \textsf{sympy}, qui pourront être déclarés grâce à l'environnement \texttt{python}.
+L'utilisateur du package pourra utiliser ses propres fonctions ou commandes \textsf{sympy}, qui pourront être déclarés grâce à l'environnement \texttt{pythonq}.
\end{tipblock}
\begin{bloctext}[listing only]
-\begin{python}
-def tangente(expr,var,a) :
- f = lambdify(x, expr)
- deriveef = diff(expr,x)
- derf = lambdify(x, deriveef)
- pente = simplify(derf(a))
- ordonnee = simplify(f(a))
- tgte = simplify(pente*(x-a) + ordonnee)
+\begin{pythonq}
+def tangente_exacte(expr,var,a) :
+ fdea = expr.subs(var,a)
+ fprimedea = limit((expr-fdea)/(var-a),var,a)
+ tgte = expand(fprimedea*(x-a) + fdea)
return tgte
-\end{python}
+\end{pythonq}
\end{bloctext}
-\begin{python}
-def tangente(expr,var,a) :
- f = lambdify(x, expr)
- deriveef = diff(expr,x)
- derf = lambdify(x, deriveef)
- pente = simplify(derf(a))
- ordonnee = simplify(f(a))
- tgte = simplify(pente*(x-a) + ordonnee)
+\begin{pythonq}
+def tangente_exacte(expr,var,a) :
+ fdea = expr.subs(var,a)
+ fprimedea = limit((expr-fdea)/(var-a),var,a)
+ tgte = expand(fprimedea*(x-a) + fdea)
return tgte
-
-\end{python}
+
+\end{pythonq}
\begin{bloctext}
-La tangente à la courbe de la fonction $f(x)=\e^{2x}+3$ en $a=1$ a pour équation (appochée) :
+La tangente à la courbe de la fonction $f(x)=\e^{2x}+3$ en $a=1$ a pour équation :\\
+$y = \sympycalc{tangente_exacte(exp(2*x)+3,x,1)}$.
+\end{bloctext}
-$y \approx \sympycalc{tangente(exp(2*x)+3,x,1)}$.
+\begin{bloctext}
+La tangente à la courbe de la fonction $g(t)=\ln(x+3)$ en $a=4$ a pour équation :\\
+$y = \dsympycalc{tangente_exacte(log(t+3),t,4)}$.
\end{bloctext}
\section{Historique}
+\verb|v0.1.1|~:~~~~Commandes pour les nombres dérivés + images.
+
\verb|v0.1.0|~:~~~~Version initiale.
diff --git a/macros/luatex/latex/sympycalc/tex/SympyCalc.sty b/macros/luatex/latex/sympycalc/tex/SympyCalc.sty
index 736da2c084..ec7da67390 100644
--- a/macros/luatex/latex/sympycalc/tex/SympyCalc.sty
+++ b/macros/luatex/latex/sympycalc/tex/SympyCalc.sty
@@ -2,7 +2,8 @@
% licence : Released under the LaTeX Project Public License v1.3c or later, see http://www.latex-project.org/lppl.txtf
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{SympyCalc}[2023/05/05 v0.1.0 Sympy commands with TeX printing]
+\ProvidesPackage{SympyCalc}[2023/05/08 v0.1.1 Sympy commands with TeX printing]
+% 0.1.1 Ajout du nombre dérivé + calcul image
% 0.1 Version initiale
%------Packages utiles
@@ -10,10 +11,12 @@
%------Scripts python
\begin{python}
+#initialisations
from sympy import *
init_printing()
x, y, z, t = symbols('x y z t')
+#commandes génériques
def latex_fr(expr) :
return latex(expr,imaginary_unit='ri',ln_notation=True,decimal_separator='comma').replace("e^","\\text{e}^")
@@ -26,6 +29,7 @@ def latex_fr_simpl(expr) :
def latex_frit_simpl(expr) :
return latex(simplify(expr),ln_notation=True,decimal_separator='comma')
+#commandes de résolutions
def latex_fr_resol(expr,var) :
if '=' in expr :
expr = expr.replace('=','-(') + ')'
@@ -74,15 +78,52 @@ def latex_frit_resolC(expr,var) :
res = res.replace("]","\\}")
return res
+#commandes de nombres dérivés
+def latex_fr_nbderiv(expr,var,pta,pos) :
+ tmpf = Lambda(var,expr)
+ res = (tmpf(var)-tmpf(pta))/(var-pta)
+ res = limit(res,var,pta,pos)
+ res = latex(res,ln_notation=True,decimal_separator='comma')
+ res = res.replace("e^","\\text{e}^")
+ return res
+
+def latex_frit_nbderiv(expr,var,pta,pos) :
+ tmpf = Lambda(var,expr)
+ res = (tmpf(var)-tmpf(pta))/(var-pta)
+ res = limit(res,var,pta,pos)
+ res = latex(res,ln_notation=True,decimal_separator='comma')
+ return res
+
+def latex_fr_nbderiv_simpl(expr,var,pta,pos) :
+ tmpf = Lambda(var,expr)
+ res = (tmpf(var)-tmpf(pta))/(var-pta)
+ res = simplify(limit(res,var,pta,pos))
+ res = latex(res,ln_notation=True,decimal_separator='comma')
+ res = res.replace("e^","\\text{e}^")
+ return res
+
+def latex_frit_nbderiv_simpl(expr,var,pta,pos) :
+ tmpf = Lambda(var,expr)
+ res = (tmpf(var)-tmpf(pta))/(var-pta)
+ res = simplify(limit(res,var,pta,pos))
+ res = latex(res,ln_notation=True,decimal_separator='comma')
+ return res
+
+#Patch pour +oo
def patch_oo(res) :
if res == '\\infty' :
return '+\\infty'
else :
return res
+#Commande de forme exponentielle
def forme_expo(z) :
return abs(z)*exp(I*arg(z))
+#Commande de calcul d'image
+def imagefct(expr,var,pta) :
+ return expr.subs(var,pta)
+
\end{python}
%------Commandes de base
@@ -114,6 +155,35 @@ def forme_expo(z) :
{\displaystyle\sympycalc<#2>{#3}}%
}
+%------Image
+\NewDocumentCommand\sympyimage{ s D<>{Simplif} m O{x} m }{%
+ \StrSubstitute{#3}{/}{*S.One/}[\argtmp]%
+ \IfBooleanTF{#1}%*=frit, no*=fr
+ {%
+ \IfStrEq{#2}{Simplif}%
+ {%
+ \py{latex_frit_simpl(imagefct(\argtmp,#4,#5))}%
+ }%
+ {%
+ \py{latex_frit(imagefct(\argtmp,#4,#5))}%
+ }%
+ }%
+ {%
+ \IfStrEq{#2}{Simplif}%
+ {%
+ \py{latex_fr_simpl(imagefct(\argtmp,#4,#5))}%
+ }%
+ {%
+ \py{latex_fr(imagefct(\argtmp,#4,#5))}%
+ }%
+ }%
+}
+\NewDocumentCommand\dsympyimage{ s D<>{Simplif} m O{x} m }{%
+ \IfBooleanTF{#1}%
+ {\displaystyle\sympyimage*<#2>{#3}[#4]{#5}}%
+ {\displaystyle\sympyimage<#2>{#3}[#4]{#5}}%
+}
+
%------Développer
\NewDocumentCommand\sympydev{ s D<>{Simplif} m O{x} }{%
\StrSubstitute{#3}{/}{*S.One/}[\argtmp]%
@@ -172,6 +242,8 @@ def forme_expo(z) :
{\displaystyle\sympyfact<#2>{#3}}%
}
+%------Image
+
%------Dériver
\NewDocumentCommand\sympyderiv{ s D<>{Simplif} m O{x} }{%
\StrSubstitute{#3}{/}{*S.One/}[\argtmp]%
@@ -262,7 +334,7 @@ def forme_expo(z) :
%------Limite
\NewDocumentCommand\sympylim{ s D<>{Simplif} m O{x} m O{} }{%
\StrSubstitute{#3}{/}{*S.One/}[\argtmp]%
- \def\poslim{}
+ \def\poslim{'+-'}
\IfStrEq{#6}{g}%
{\def\poslim{'-'}}{}
\IfStrEq{#6}{d}%
@@ -293,6 +365,40 @@ def forme_expo(z) :
{\displaystyle\sympylim<#2>{#3}[#4]{#5}[#6]}%
}
+%------Nb deriv
+\NewDocumentCommand\sympynbderiv{ s D<>{Simplif} m O{x} m O{} }{%
+ \StrSubstitute{#3}{/}{*S.One/}[\argtmp]%
+ \def\poslim{'+-'}
+ \IfStrEq{#6}{g}%
+ {\def\poslim{'-'}}{}
+ \IfStrEq{#6}{d}%
+ {\def\poslim{'+'}}{}
+ \IfBooleanTF{#1}%*=frit, no*=fr
+ {%
+ \IfStrEq{#2}{Simplif}%
+ {%
+ \py{patch_oo(latex_fr_nbderiv_simpl(\argtmp,#4,#5,\poslim))}%
+ }%
+ {%
+ \py{patch_oo(latex_frit_nbderiv_simpl(\argtmp,#4,#5,\poslim))}%
+ }%
+ }%
+ {%
+ \IfStrEq{#2}{Simplif}%
+ {%
+ \py{patch_oo(latex_fr_nbderiv(\argtmp,#4,#5,\poslim))}%
+ }%
+ {%
+ \py{patch_oo(latex_frit_nbderiv(\argtmp,#4,#5,\poslim))}%
+ }%
+ }%
+}
+\NewDocumentCommand\dsympynbderiv{ s D<>{Simplif} m O{x} m O{} }{%
+ \IfBooleanTF{#1}%
+ {\displaystyle\sympynbderiv*<#2>{#3}[#4]{#5}[#6]}%
+ {\displaystyle\sympynbderiv<#2>{#3}[#4]{#5}[#6]}%
+}
+
%------FormeExpo
\NewDocumentCommand\sympyfexpo{ s D<>{NoSimplif} m }{%
%\StrSubstitute{#3}{/}{*S.One/}[\argtmp]%