summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/lualatex/lualatex-math
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/lualatex/lualatex-math')
-rw-r--r--Master/texmf-dist/source/lualatex/lualatex-math/lualatex-math.dtx1218
-rw-r--r--Master/texmf-dist/source/lualatex/lualatex-math/lualatex-math.ins90
2 files changed, 1308 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/lualatex/lualatex-math/lualatex-math.dtx b/Master/texmf-dist/source/lualatex/lualatex-math/lualatex-math.dtx
new file mode 100644
index 00000000000..12bf9cbd2f8
--- /dev/null
+++ b/Master/texmf-dist/source/lualatex/lualatex-math/lualatex-math.dtx
@@ -0,0 +1,1218 @@
+% \iffalse meta-comment
+%
+% Copyright 2011 by Philipp Stephani
+%
+% This file may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either
+% version 1.3c of this license or (at your option) any later
+% version. The latest version of this license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3c or later is part of all distributions of
+% LaTeX version 2009/09/24 or later.
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\documentclass[a4paper, 10pt]{phst-doc}
+
+\usepackage{lualatex-math}
+\newcommand*{\thispackage}{\textsf{lualatex-math}\xspace}
+
+\begin{document}
+
+\DocInput{lualatex-math.dtx}
+\PrintChanges
+\PrintIndex
+
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{721}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+% \changes{v0.1}{2011/04/22}{Initial version}
+%
+% \GetFileInfo{lualatex-math.sty}
+%
+% \title{The \thispackage package\thanks{This document corresponds to \thispackage{}~\fileversion, dated~\filedate.}}
+% \author{Philipp Stephani \\ \texttt{st\_philipp@yahoo.de}}
+% \date{\filedate}
+%
+%
+% \maketitle
+% \tableofcontents
+%
+%
+% \section{Introduction}
+%
+% \Hologo{LuaTeX} brings major improvements to all areas of \hologo{TeX}
+% typesetting and programming. They are made available through new primitives
+% or the embedded Lua interpreter, and combining them with existing
+% \hologo{LaTeX2e} package is not a task the average \hologo{LaTeX} user should
+% have to care about. Therefore a multitude of \hologo{LaTeX2e} packages have
+% been written to bridge the gap between documents and the new features. The
+% \thispackage package focuses on the additional possibilities for mathematical
+% typesetting. The most eminent of the new features is the ability to use
+% Unicode and OpenType fonts, as provided by \Robertson’s \pkg{unicode-math}
+% package. However, there is a smaller group of changes unrelated to Unicode:
+% these are to be dealt with in this package. While in principle most
+% \hologo{TeX} documents written for traditional engines should work just fine
+% with \hologo{LuaTeX}, there is a small number of breaking changes that
+% require the attention of package authors. The \thispackage package tries to
+% fix some of the issues encountered while porting traditional macro packages
+% to \hologo{LuaLaTeX}.
+%
+% The decision to write patches for existing macro packages should not be made
+% lightly: monkey patching done by somebody different from the original package
+% author ties the patching package to the implementation details of the patched
+% functionality and breaks all rules of encapsulation. However, due to the
+% lack of alternatives, it has become an accepted way of providing new
+% functionality in \hologo{LaTeX}. To keep the negative impact as small as
+% possible, the \thispackage package patches only the \hologo{LaTeX2e} kernel
+% and a small number of popular packages. In general, this package should be
+% regarded as a temporary kludge that should be removed once the math-related
+% packages are updated to be usable with \hologo{LuaTeX}. By its very nature,
+% the package is likely to cause problems; in such cases, please refer to the
+% issue tracker\footnote{\url{https://github.com/phst/lualatex-math/issues}}.
+%
+%
+% \section{Interface}
+%
+% The \thispackage package can be loaded with \cmd{\usepackage} or
+% \cmd{\RequirePackage}, as usual. It has no options and no public interface;
+% the patching is always done when the package is loaded and cannot be
+% controlled. As a matter of course, the \thispackage package needs
+% \hologo{LuaLaTeX} to function; it will produce error messages and refuse to
+% load under other engines and formats. The package depends on the \pkg{expl3}
+% bundle, the \pkg{etoolbox} package, the \pkg{luatexbase} bundle and the
+% \pkg{filehook} package. The \thispackage package is independent of the
+% \pkg{unicode-math} package; the fixes provided here are valid for both
+% Unicode and legacy math typesetting.
+%
+% Currently patches for the \hologo{LaTeX2e} kernel and the \pkg{amsmath} and
+% \pkg{mathtools} packages are provided. It is not relevant whether you load
+% these packages before or after \thispackage. They should work as expected
+% (and ideally you shouldn’t notice anything), but if you load other packages
+% that by themselves overwrite commands patched by this package, bad things may
+% happen, as it is usual with \hologo{LaTeX}.
+%
+% One user-visible change is that the new
+% \DescribeMacros{\mathstyle\luatexmathstyle}\cmd{\mathstyle} primitive
+% (usually called \cmd{\luatexmathstyle} in \hologo{LuaLaTeX}) should work in
+% all cases after the \thispackage package has been loaded, provided you use
+% the high-level macros \DescribeMacros{\frac\binom\genfrac}\cmd{\frac},
+% \cmd{\binom}, and \cmd{\genfrac}. The fraction-like \hologo{TeX} primitives
+% like \cmd{\over} or \cmd{\atopwithdelims} and the \hologo{plainTeX} leftovers
+% like \cmd{\brack} or \cmd{\choose} cannot be patched, and you shouldn’t use
+% them.
+%
+% \StopEventually{}
+%
+%
+% \section{Implementation of the \hologo{LaTeX2e} package}
+%
+% \subsection{Requirements}
+%
+% \begin{macrocode}
+%<*package>
+\NeedsTeXFormat{LaTeX2e}[2009/09/24]
+\RequirePackage{expl3}[2011/02/17]
+\ProvidesExplPackage{lualatex-math}{2011/05/05}{0.1}%
+ {Patches for mathematics typesetting with LuaLaTeX}
+\RequirePackage { etoolbox } [ 2007/10/08 ]
+\RequirePackage { luatexbase } [ 2010/05/27 ]
+\RequirePackage { filehook } [ 2011/03/09 ]
+\RequireLuaModule { lualatex-math } [ 2011/05/05 ]
+% \end{macrocode}
+%
+% \begin{macro}{\lltxmath_restore_catcode:N}
+% Executing the exhaustive expansion of
+% \cmd{\lltxmath_restore_catcode:N}\meta{character token} restores the
+% category code of the \meta{character token} to its current value.
+% \begin{macrocode}
+\cs_new_nopar:Npn \lltxmath_restore_catcode:N #1 {
+ \char_set_catcode:nn { \int_eval:n { `#1 } }
+ { \char_value_catcode:n { `#1 } }
+}
+% \end{macrocode}
+% \end{macro}
+% We use the macro defined above to restore the category code of the dollar
+% sign. There are packages that make the dollar sign active; hopefully they
+% get loaded after the packages we are trying to patch.
+% \begin{macrocode}
+\exp_args:Nx \AtEndOfPackage {
+ \lltxmath_restore_catcode:N \$
+}
+\char_make_math_shift:N \$
+% \end{macrocode}
+%
+%
+% \subsection{Messages}
+%
+% \begin{l3message}{luatex-required}
+% Issued when not running under \hologo{LuaTeX}.
+% \begin{macrocode}
+\msg_new:nnn { lualatex-math } { luatex-required } {
+ The~ lualatex-math~ package~ requires~ LuaTeX. \\
+ I~ will~ stop~ loading~ now.
+}
+% \end{macrocode}
+% \end{l3message}
+%
+% \begin{l3message}{macro-expected}
+% Issued when trying to patch a non-macro. The first argument must be the
+% detokenized macro name.
+% \begin{macrocode}
+\msg_new:nnn { lualatex-math } { macro-expected } {
+ I've~ expected~ that~ #1~ is~ a~ macro,~ but~ it~ isn't.
+}
+% \end{macrocode}
+% \end{l3message}
+%
+% \begin{l3message}{wrong-meaning}
+% Issued when trying to patch a macro with an unexpected meaning. The first
+% argument must be the detokenized macro name; the second argument must be
+% the actual detokenized meaning; and the thied argument must be the expected
+% detokenized meaning.
+% \begin{macrocode}
+\msg_new:nnn { lualatex-math } { wrong-meaning } {
+ I've~ expected~ #1~ to~ have~ the~ meaning \\
+ #3, \\
+ but~ it~ has~ the~ meaning \\
+ #2.
+}
+% \end{macrocode}
+% \end{l3message}
+%
+% \begin{l3message}{patch-macro}
+% Issued when a macro is patched. The first argument must be the detokenized
+% macro name.
+% \begin{macrocode}
+\msg_new:nnn { lualatex-math } { patch-macro } {
+ I'm~ going~ to~ patch~ macro~ #1.
+}
+% \end{macrocode}
+% \end{l3message}
+%
+%
+% \subsection{Initialization}
+%
+% Unless we are running under \hologo{LuaTeX}, we issue an error and quit
+% immediately. Loading the \pkg{luatexbase} module will already have produced
+% an error, but we issue another one for clarity.
+% \begin{macrocode}
+\luatex_if_engine:F {
+ \msg_error:nn { lualatex-math } { luatex-required }
+ \endinput
+}
+% \end{macrocode}
+%
+%
+% \subsection{Patching}
+%
+% \begin{macro}{\lltxmath_temp:w}
+% A scratch macro.
+% \begin{macrocode}
+\chk_if_free_cs:N \lltxmath_temp:w
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\lltxmath_patch:NNnnn}
+% \begin{macro}{\lltxmath_patch:cNnnn}
+% The macro \cmd{\lltxmath_patch:NNnnn}\meta{command}\meta{factory
+% command}\marg{parameter text}\marg{expected replacement text}\marg{new
+% replacement text} tries to patch \meta{command}. If \meta{command} is
+% undefined, do nothing. Otherwise it must be a macro with the given
+% \meta{parameter text} and \meta{expected replacement text}, created by the
+% given \meta{factory command} or equivalent. In this case it will be
+% overwritten using the \meta{parameter text} and the \meta{new replacement
+% text}. Otherwise issue a warning and don’t overwrite.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \lltxmath_patch:NNnnn #1 #2 #3 #4 #5 {
+ \cs_if_exist:NT #1 {
+ \token_if_macro:NTF #1 {
+ \group_begin:
+ #2 \lltxmath_temp:w #3 { #4 }
+ \cs_if_eq:NNTF #1 \lltxmath_temp:w {
+ \msg_info:nnx { lualatex-math } { patch-macro }
+ { \token_to_str:N #1 }
+ \group_end:
+ #2 #1 #3 { #5 }
+ } {
+ \msg_warning:nnxxx { lualatex-math } { wrong-meaning }
+ { \token_to_str:N #1 } { \token_to_meaning:N #1 }
+ { \token_to_meaning:N \lltxmath_temp:w }
+ \group_end:
+ }
+ } {
+ \msg_warning:nnx { lualatex-math } { macro-expected }
+ { \token_to_str:N #1 }
+ }
+ }
+}
+\cs_generate_variant:Nn \lltxmath_patch:NNnnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{\Hologo{LaTeX2e} kernel}
+%
+% \Hologo{LuaTeX} enables access to the current mathematical style via the
+% \cmd{\mathstyle} primitive. For this to work, fraction-like constructs (\eg,
+% \meta{numerator} \cmd{\over} \meta{denominator}) have to be enclosed in a
+% \cmd{\Ustack} group. \cmd{\frac} can be patched to do this, but the
+% \hologo{plainTeX} remnants \cmd{\choose}, \cmd{\brack} and \cmd{\brace}
+% should be discouraged.
+%
+% \begin{macro}{\luatexUstack}
+% First we make sure that we can use the \cmd{\Ustack} primitive (under the
+% name \cmd{\luatexUstack}).
+% \begin{macrocode}
+\luatexbase@ensure@primitive { Ustack }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\frac}
+% Here we assume that nobody except \pkg{amsmath} redefines \cmd{\frac}.
+% This is obviously not the case, but we ignore other packages (\eg,
+% \pkg{nath}) for the moment. We only patch the \hologo{LaTeX2e} kernel
+% definition if the \pkg{amsmath} package is not loaded; the corresponding
+% patch for \pkg{amsmath} follows below.
+% \begin{macrocode}
+\AtEndPreamble {
+ \@ifpackageloaded { amsmath } { } {
+ \lltxmath_patch:NNnnn \frac \cs_set_nopar:Npn { #1 #2 } {
+ {
+ \begingroup #1 \endgroup \over #2
+ }
+ } {
+% \end{macrocode}
+% To do: do we need the additional set of braces around \cmd{\Ustack}?
+% \begin{macrocode}
+ {
+ \luatexUstack { \group_begin: #1 \group_end: \over #2 }
+ }
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{\pkg{amsmath}}
+%
+% The popular \pkg{amsmath} package is subject to three \hologo{LuaTeX}-related problems:
+% \begin{itemize}
+% \item The \cmd{\mathcode} primitive is used several times, which fails for
+% Unicode math characters. \cmd{\Umathcode} should be used instead.
+% \item Legacy font dimensions are used for constructing stacks in the
+% \cmd{\substack} command and the \env{subarray} environment. This doesn’t
+% work if a Unicode math font is selected.
+% \item The fraction commands \cmd{\frac} and \cmd{\genfrac} don’t use the
+% \cmd{\Ustack} primitive.
+% \end{itemize}
+%
+% \begin{macro}{\luatexUmathcodenum}
+% \begin{macro}{\luatexUmathchardef}
+% We need the extended versions of \cmd{\mathcode} and \cmd{\mathchardef}.
+% \begin{macrocode}
+\luatexbase@ensure@primitive { Umathcodenum }
+\luatexbase@ensure@primitive { Umathchardef }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\luatexalignmark}
+% \begin{macro}{\luatexUstartmath}
+% \begin{macro}{\luatexUstopmath}
+% We use the primitives corresponding to the alignment mark (\verb+#+) and to
+% the inline math switches; this is more semantical and might lead to better
+% error messages.
+% \begin{macrocode}
+\luatexbase@ensure@primitive { alignmark }
+\luatexbase@ensure@primitive { Ustartmath }
+\luatexbase@ensure@primitive { Ustopmath }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\luatexUmathstacknumup}
+% \begin{macro}{\luatexUmathstackdenomdown}
+% \begin{macro}{\luatexUmathstackvgap}
+% Now we require the font parameters we will use.
+% \begin{macrocode}
+\luatexbase@ensure@primitive { Umathstacknumup }
+\luatexbase@ensure@primitive { Umathstackdenomdown }
+\luatexbase@ensure@primitive { Umathstackvgap }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\c_lltxmath_std_minus_mathcode_int}
+% \begin{macro}{\c_lltxmath_std_equal_mathcode_int}
+% These constants contain the standard \hologo{TeX} mathematical codes for
+% the minus and the equal signs. We temporarily set the math codes to these
+% constants before loading the \pkg{amsmath} package so that it can request
+% the legacy math code without error.
+% \begin{macrocode}
+\int_const:Nn \c_lltxmath_std_minus_mathcode_int { "2200 }
+\int_const:Nn \c_lltxmath_std_equal_mathcode_int { "303D }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\lltxmath_set_mathchar:NN}
+% The macro \cmd{\lltxmath_set_mathchar:NN}\meta{control
+% sequence}\meta{token} defines the \meta{control sequence} as an extended
+% mathematical character shorthand whose mathematical code is given by the
+% mathematical code of the character \texttt{\textasciigrave}\meta{token}.
+% Since there is no \cmd{\Umathcharnumdef} primitive, we have to extract the
+% class, family, and slot numbers separately.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \lltxmath_set_mathchar:NN #1 #2 {
+ \luatexUmathchardef #1
+ \lua_now:x {
+ lualatex.math.print_class_fam_slot( \int_eval:n { `#2 } )
+ }
+ \scan_stop:
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\lltxmath_char_dim:NN}
+% The macro \cmd{\lltxmath_char_dim:NN}\meta{primitive}\meta{token} expands
+% to a \meta{dimen} whose value is the metric of the mathematical character
+% corresponding to the character \texttt{\textasciigrave}\meta{token}
+% specified by \meta{primitive}, which must be one of \cmd{\fontcharwd},
+% \cmd{\fontcharht} or \cmd{\fontchardp}, in the currently selected text
+% style font.
+% \begin{macrocode}
+\cs_new_nopar:Npn \lltxmath_char_dim:NN #1 #2 {
+ #1 \textfont
+ \lua_now:x {
+ lualatex.math.print_fam_slot( \int_eval:n { `#2 } )
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_lltxmath_minus_mathchar}
+% \begin{macro}{\l_lltxmath_equal_mathchar}
+% These mathematical characters are saved before \pkg{amsmath} is loaded so
+% that we can temporarily assign the \hologo{TeX} values to the mathematical
+% codes of the minus and equals signs. The \pkg{amsmath} package queries
+% these codes, and if they represent Unicode characters, the package loading
+% will fail. If \pkg{amsmath} has already been loaded, there is nothing we
+% can do, therefore we use the non-starred version of
+% \cmd{\AtBeginOfPackageFile}.
+% \begin{macrocode}
+\chk_if_free_cs:N \l_lltxmath_minus_mathchar
+\chk_if_free_cs:N \l_lltxmath_equal_mathchar
+\AtBeginOfPackageFile { amsmath } {
+ \lltxmath_set_mathchar:NN \l_lltxmath_minus_mathchar \-
+ \lltxmath_set_mathchar:NN \l_lltxmath_equal_mathchar \=
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% Now we temporarily reset the mathematical codes.
+% \begin{macrocode}
+ \char_set_mathcode:nn { `\- } { \c_lltxmath_std_minus_mathcode_int }
+ \char_set_mathcode:nn { `\= } { \c_lltxmath_std_equal_mathcode_int }
+ \AtEndOfPackageFile { amsmath } {
+% \end{macrocode}
+% \begin{macro}{\std@minus}
+% \begin{macro}{\std@equals}
+% The \pkg{amsmath} package defines the control sequences \cmd{\std@minus}
+% and \cmd{\std@equal} as mathematical character shorthands while loading,
+% but uses our restored mathematical codes, which must be fixed.
+% \begin{macrocode}
+ \cs_set_eq:NN \std@minus \l_lltxmath_minus_mathchar
+ \cs_set_eq:NN \std@equal \l_lltxmath_equal_mathchar
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% Finally, we restore the original mathematical codes of the two signs.
+% \begin{macrocode}
+ \luatexUmathcodenum `\- \l_lltxmath_minus_mathchar
+ \luatexUmathcodenum `\= \l_lltxmath_equal_mathchar
+ }
+}
+% \end{macrocode}
+% All of the following fixes work even if \pkg{amsmath} is already loaded.
+% \begin{macro}{\@begindocumenthook}
+% \pkg{amsmath} repeats the definiton of \cmd{\std@minus} and
+% \cmd{\std@equal} at the beginning of the document, so we also have to patch
+% the internal kernel macro \cmd{\@begindocumenthook} which contains the hook
+% code.
+% \begin{macrocode}
+\AtEndOfPackageFile * { amsmath } {
+ \tl_replace_in:Nnn \@begindocumenthook {
+ \mathchardef \std@minus \mathcode `\- \relax
+ \mathchardef \std@equal \mathcode `\= \relax
+ } {
+ \lltxmath_set_mathchar:NN \std@minus \-
+ \lltxmath_set_mathchar:NN \std@equal \=
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\resetMathstrut@}
+% \pkg{amsmath} uses the box \cmd{\Mathstrutbox@} for struts in mathematical
+% mode. This box is defined to have the height and depth of the opening
+% parenthesis taken from the current text font. The command
+% \cmd{\resetMathstrut@} is executed whenever the mathematical fonts are
+% changed and has to restore the correct dimensions. The original definition
+% uses a temporary mathematical character shorthand definition whose meaning
+% is queried to extract the family and slot. We can do this in Lua;
+% furthermore we can avoid a temporary box because \hologo{eTeX} allows us to
+% query glyph metrics directly.
+% \begin{macrocode}
+ \lltxmath_patch:NNnnn \resetMathstrut@ \cs_set_nopar:Npn { } {
+ \setbox \z@ \hbox {
+ \mathchardef \@tempa \mathcode `\( \relax % \)
+ \def \@tempb ##1 "##2 ##3 { \the \textfont "##3 \char" }
+ \expandafter \@tempb \meaning \@tempa \relax
+ }
+ \ht \Mathstrutbox@ \ht \z@
+ \dp \Mathstrutbox@ \dp \z@
+ } {
+ \box_set_ht:Nn \Mathstrutbox@ {
+ \lltxmath_char_dim:NN \fontcharht \( % \)
+ }
+ \box_set_dp:Nn \Mathstrutbox@ {
+ \lltxmath_char_dim:NN \fontchardp \)
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{subarray}
+% The \env{subarray} environment uses legacy font dimensions. We simply
+% patch it to use \hologo{LuaTeX} font parameters (and \hologo{LaTeX3}
+% expressions instead of \hologo{TeX} arithmetic). Since subscript arrays
+% are conceptually vertical stacks, we use the sum of top and bottom shift
+% for the default vertical baseline distance (\cmd{\baselineskip}) and the
+% minimum vertical gap for stack for the minimum baseline distance
+% (\cmd{\lineskip}).
+% \begin{macrocode}
+ \lltxmath_patch:NNnnn \subarray \cs_set:Npn { #1 } {
+ \vcenter
+ \bgroup
+ \Let@
+ \restore@math@cr
+ \default@tag
+ \baselineskip \fontdimen 10~ \scriptfont \tw@
+ \advance \baselineskip \fontdimen 12~ \scriptfont \tw@
+ \lineskip \thr@@ \fontdimen 8~ \scriptfont \thr@@
+ \lineskiplimit \lineskip
+ \ialign
+ \bgroup
+ \ifx c #1 \hfil \fi
+ $ \m@th \scriptstyle ## $
+ \hfil
+ \crcr
+ } {
+ \vcenter
+ \c_group_begin_token
+ \Let@
+ \restore@math@cr
+ \default@tag
+ \skip_set:Nn \baselineskip {
+ \luatexUmathstacknumup \scriptstyle
+ + \luatexUmathstackdenomdown \scriptstyle
+ }
+ \lineskip \luatexUmathstackvgap \scriptstyle
+ \lineskiplimit \lineskip
+ \ialign
+ \c_group_begin_token
+ \token_if_eq_meaning:NNT c #1 { \hfil }
+ \luatexUstartmath
+ \m@th
+ \scriptstyle
+ \luatexalignmark \luatexalignmark
+ \luatexUstopmath
+ \hfil
+ \crcr
+ }
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\frac}
+% Since \cmd{\frac} is declared by \cmd{\DeclareRobustCommand}, we must patch
+% the macro \cmd{\frac\textvisiblespace}.
+% \begin{macrocode}
+ \lltxmath_patch:cNnnn { frac~ } \cs_set:Npn { #1 #2 } {
+ {
+ \begingroup #1 \endgroup \@@over #2
+ }
+ } {
+ {
+ \luatexUstack { \group_begin: #1 \group_end: \@@over #2 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@genfrac}
+% Generalized fractions are typeset by the internal \cmd{\@genfrac} command.
+% \begin{macrocode}
+ \lltxmath_patch:NNnnn \@genfrac \cs_set_nopar:Npn {
+ #1 #2 #3 #4 #5
+ } {
+ {
+ #1 { \begingroup #4 \endgroup #2 #3 \relax #5 }
+ }
+ } {
+ {
+ #1 {
+ \luatexUstack {
+ \group_begin: #4 \group_end: #2 #3 \scan_stop: #5
+ }
+ }
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{\pkg{mathtools}}
+%
+% \pkg{mathtools}’ \cmd{\cramped} command and others that make use of its
+% internal version use a hack involving a null radical. \Hologo{LuaTeX} has
+% primitives for setting material in cramped mode, so we make use of them.
+%
+% \begin{macro}{\luatexcrampeddisplaystyle}
+% \begin{macro}{\luatexcrampedtextstyle}
+% \begin{macro}{\luatexcrampedscriptstyle}
+% \begin{macro}{\luatexcrampedscriptscriptstyle}
+% First we make sure that the needed primitives for cramped styles are
+% available.
+% \begin{macrocode}
+\luatexbase@ensure@primitive { crampeddisplaystyle }
+\luatexbase@ensure@primitive { crampedtextstyle }
+\luatexbase@ensure@primitive { crampedscriptstyle }
+\luatexbase@ensure@primitive { crampedscriptscriptstyle }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\MT_cramped_internal:Nn}
+% The macro \cmd{\MT_cramped_internal:Nn}\meta{style}\marg{expression}
+% typesets the \meta{expression} in the cramped style corresponding to the
+% given \meta{style} (\cmd{\displaystyle} etc.); all we have to do in
+% \hologo{LuaTeX} is to select the correct primitive. Rewriting the
+% user-level \cmd{\cramped} command and employing \cmd{\mathstyle} would be
+% possible as well, but we avoid this way since we want to patch only a
+% single command.
+% \begin{macrocode}
+\AtEndOfPackageFile * { mathtools } {
+ \lltxmath_patch:NNnnn \MT_cramped_internal:Nn
+ \cs_set_nopar:Npn { #1 #2 } {
+ \sbox \z@ {
+ $
+ \m@th
+ #1
+ \nulldelimiterspace = \z@
+ \radical \z@ { #2 }
+ $
+ }
+ \ifx #1 \displaystyle
+ \dimen@ = \fontdimen 8 \textfont 3
+ \advance \dimen@ .25 \fontdimen 5 \textfont 2
+ \else
+ \dimen@ = 1.25 \fontdimen 8
+ \ifx #1 \textstyle
+ \textfont
+ \else
+ \ifx #1 \scriptstyle
+ \scriptfont
+ \else
+ \scriptscriptfont
+ \fi
+ \fi
+ 3
+ \fi
+ \advance \dimen@ -\ht\z@
+ \ht\z@ = -\dimen@
+ \box\z@
+ } {
+% \end{macrocode}
+% Here the additional set of braces is absolutely necessary, otherwise the
+% changed mathematical style would be applied to the material after the
+% \cmd{\mathchoice} construct.
+% \begin{macrocode}
+ {
+ \use:c { luatexcramped \cs_to_str:N #1 } #2
+ }
+ }
+}
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \section{Implementation of the \hologo{LuaLaTeX} module}
+%
+% For the Lua module, we use the standard \pkg{luatexbase-modutils} template
+% and the \func{module} function.
+% \begin{macrocode}
+%<*lua>
+require("luatexbase.modutils")
+require("luatexbase.cctb")
+local err, warn, info, log = luatexbase.provides_module({
+ name = "lualatex-math",
+ date = "2011/05/05",
+ version = 0.1,
+ description = "Patches for mathematics typesetting with LuaLaTeX",
+ author = "Philipp Stephani",
+ licence = "LPPL v1.3+"
+})
+local unpack = unpack
+local string = string
+local tex = tex
+local cctb = luatexbase.catcodetables
+module("lualatex.math")
+% \end{macrocode}
+%
+% \begin{function}{print_fam_slot}
+% The function \func{print_fam_slot} takes one argument which must be a
+% number. It interprets the argument as a Unicode code point whose
+% mathematical code is printed in the form
+% \meta{family}\texttt{\textvisiblespace}\meta{slot}, suitable for the
+% right-hand side of \eg \verb|\fontcharht\textfont|.
+% \begin{macrocode}
+function print_fam_slot(char)
+ local code = tex.getmathcode(char)
+ local class, family, slot = unpack(code)
+ local result = string.format("%i %i ", family, slot)
+ tex.sprint(cctb.string, result)
+end
+% \end{macrocode}
+% \end{function}
+%
+% \begin{function}{print_class_fam_slot}
+% The function \func{print_class_fam_slot} takes one argument which must be a
+% number. It interprets the argument as a Unicode code point whose
+% mathematical code is printed in the form
+% \meta{class}\texttt{\textvisiblespace}\meta{family}\texttt{\textvisiblespace}\meta{slot},
+% suitable for the right-hand side of \cmd{\Umathchardef}.
+% \begin{macrocode}
+function print_class_fam_slot(char)
+ local code = tex.getmathcode(char)
+ local class, family, slot = unpack(code)
+ local result = string.format("%i %i %i ", class, family, slot)
+ tex.sprint(cctb.string, result)
+end
+%</lua>
+% \end{macrocode}
+% \end{function}
+%
+%
+% \section{Test files}
+%
+% Finally two small test files—but not a real test suite.
+%
+%
+% \subsection{Common definitions}
+%
+% \begin{macrocode}
+%<*test>
+\documentclass[pagesize=auto]{scrartcl}
+% \end{macrocode}
+% Only \pkg{xparse} starting with 2008/08/03 has \cmd{\NewDocumentCommand}.
+% \begin{macrocode}
+\usepackage{xparse}[2008/08/03]
+\ExplSyntaxOn
+% \end{macrocode}
+%
+% \begin{l3message}{pass}
+% This message is issued when a test passed.
+% \begin{macrocode}
+\msg_new:nnn { test } { pass } { #1 }
+% \end{macrocode}
+% \end{l3message}
+%
+% \begin{macro}{\test_pass:x}
+% The macro \cmd{\test_pass:x}\marg{text} issues the \msg{pass} message with
+% description \meta{text}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \test_pass:x #1 {
+ \msg_info:nnx { test } { pass } { #1 }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{l3message}{fail}
+% This message is issued when a test failed.
+% \begin{macrocode}
+\msg_new:nnn { test } { fail } { #1 }
+% \end{macrocode}
+% \end{l3message}
+%
+% \begin{macro}{\test_fail:x}
+% The macro \cmd{\test_fail:x}\marg{text} issues the \msg{fail} message with
+% description \meta{text}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \test_fail:x #1 {
+ \msg_error:nnx { test } { fail } { #1 }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_const:Nx}
+% We need expanding constants.
+% \begin{macrocode}
+\cs_generate_variant:Nn \tl_const:Nn { Nx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c_test_equal_tl}
+% \begin{macro}{\c_test_not_equal_tl}
+% Two shorthands for pretty-printing test results.
+% \begin{macrocode}
+\tl_const:Nx \c_test_equal_tl { \c_space_tl == \c_space_tl }
+\tl_const:Nx \c_test_not_equal_tl { \c_space_tl != \c_space_tl }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\test_equal_pass:nxnx}
+% The macro \cmd{\test_equal_pass:nxnx}\marg{first expression}\marg{first
+% value}\marg{second expression}\marg{second value} is called when the two
+% values arising from the two expressions are equal.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \test_equal_pass:nxnx #1 #2 #3 #4 {
+ \test_pass:x {
+ \exp_not:n { #1 }
+ \c_test_equal_tl
+ #2
+ \c_test_equal_tl
+ #4
+ \c_test_equal_tl
+ \exp_not:n { #3 }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\test_equal_fail:nxnx}
+% The macro \cmd{\test_equal_pass:nxnx}\marg{first expression}\marg{first
+% value}\marg{second expression}\marg{second value} is called when the two
+% values arising from the two expressions are not equal.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \test_equal_fail:nxnx #1 #2 #3 #4 {
+ \test_fail:x {
+ \exp_not:n { #1 }
+ \c_test_equal_tl
+ #2
+ \c_test_not_equal_tl
+ #4
+ \c_test_equal_tl
+ \exp_not:n { #3 }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\test_assert_equal:NNNNNnn}
+% \begin{macro}{\test_assert_equal:cccccnn}
+% The macro \cmd{\test_assert_equal:NNNNNnn}\meta{set command}\meta{use
+% command}\meta{compare command}\meta{first temporary command}\meta{second
+% temporary command}\marg{first expression}\marg{second expression} asserts
+% that the two expressions are equal. The \meta{set command} must have the
+% argument specification \texttt{Nn}, the \meta{use command} \texttt{N}, and
+% the \meta{compare command} \texttt{nNnTF}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn
+\test_assert_equal:NNNNNnn #1 #2 #3 #4 #5 #6 #7 {
+ #1 #4 { #6 }
+ #1 #5 { #7 }
+ #3 { #4 } = { #5 } {
+ \test_equal_pass:nxnx { #6 } { #2 #4 } { #7 } { #2 #5 }
+ } {
+ \test_equal_fail:nxnx { #6 } { #2 #4 } { #7 } { #2 #5 }
+ }
+}
+\cs_generate_variant:Nn \test_assert_equal:NNNNNnn { ccccc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\test_assert_equal:nnn}
+% The macro \cmd{\test_assert_equal:nnn}\marg{data type}\marg{first
+% expression}\marg{second expression} is a simplified version of
+% \cmd{\test_assert_equal:NNNNNnn} for data types following the
+% \hologo{LaTeX3} naming conventions; \meta{data type} must be \texttt{int},
+% \texttt{dim}, \etc
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \test_assert_equal:nnn #1 #2 #3 {
+ \test_assert_equal:cccccnn
+ { #1 _set:Nn } { #1 _use:N } { #1 _compare:nNnTF }
+ { l_test_tmpa_ #1 } { l_test_tmpb_ #1 } { #2 } { #3 }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_test_tmpa_int}
+% \begin{macro}{\l_test_tmpb_int}
+% Scratch registers for numbers.
+% \begin{macrocode}
+\int_new:N \l_test_tmpa_int
+\int_new:N \l_test_tmpb_int
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\AssertIntEqual}
+% The command \cmd{\AssertIntEqual}\marg{first expression}\marg{second
+% expression} asserts that the two integral expressions are equal.
+% \begin{macrocode}
+\NewDocumentCommand \AssertIntEqual { m m } {
+ \test_assert_equal:nnn { int } { #1 } { #2 }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_test_tmpa_int}
+% \begin{macro}{\l_test_tmpb_int}
+% Scratch registers for dimensions.
+% \begin{macrocode}
+\dim_new:N \l_test_tmpa_dim
+\dim_new:N \l_test_tmpb_dim
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\AssertIntEqual}
+% The command \cmd{\AssertDimEqual}\marg{first expression}\marg{second
+% expression} asserts that the two dimension expressions are equal.
+% \begin{macrocode}
+\NewDocumentCommand \AssertDimEqual { m m } {
+ \test_assert_equal:nnn { dim } { #1 } { #2 }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\AssertMathStyle}
+% The command \cmd{\AssertMathStyle}\marg{expression} asserts that the
+% current mathematical style is equal to the value of the integral
+% \meta{expression}.
+% \begin{macrocode}
+\NewDocumentCommand \AssertMathStyle { m } {
+ \AssertIntEqual { \luatexmathstyle } { #1 }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\test_assert_cramped:Nx}
+% The macro \cmd{\test_assert_cramped:Nn}\meta{predicate}\marg{name} asserts
+% that we are in math mode and that the current style fulfills the
+% \meta{predicate} (identified by the \meta{name}) which must have the
+% argument specification \texttt{n}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \test_assert_cramped:Nx #1 #2 {
+ \int_set:Nn \l_test_tmpa_int { \luatexmathstyle }
+ \bool_if:nTF {
+ \int_compare_p:nNn { \l_test_tmpa_int } > { \c_minus_one }
+ &&
+ #1 { \l_test_tmpa_int }
+ } {
+ \test_pass:x {
+ \exp_not:N \luatexmathstyle
+ \c_test_equal_tl
+ \int_use:N \l_test_tmpa_int
+ \c_space_tl
+ is~ a~ #2~ style
+ }
+ } {
+ \test_fail:x {
+ \exp_not:N \luatexmathstyle
+ \c_test_equal_tl
+ \int_use:N \l_test_tmpa_int
+ \c_space_tl
+ is~ not~ a~ #2~ style
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\AssertNoncrampedStyle}
+% The command \cmd{\AssertNoncrampedStyle} asserts that the current
+% mathematical style is one of the non-cramped styles.
+% \begin{macrocode}
+\NewDocumentCommand \AssertNoncrampedStyle { } {
+ \test_assert_cramped:Nx \int_if_even_p:n { non-cramped }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\AssertCrampedStyle}
+% The command \cmd{\AssertCrampedStyle} asserts that the current mathematical
+% style is one of the cramped styles.
+% \begin{macrocode}
+\NewDocumentCommand \AssertCrampedStyle { } {
+ \test_assert_cramped:Nx \int_if_odd_p:n { cramped }
+}
+\ExplSyntaxOff
+%</test>
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{\Hologo{LaTeX2e} kernel}
+%
+% Here we only check whether different fractions and other style-changing
+% commands result in the correct mathematical style.
+% \begin{macrocode}
+%<*test-kernel>
+\usepackage{lualatex-math}
+\begin{document}
+\begin{displaymath}
+ \AssertMathStyle{0} \sqrt{\AssertMathStyle{1}}
+ \frac{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ a^{\frac{\AssertMathStyle{6}}{\AssertMathStyle{7}}}
+ \sqrt{\frac{\AssertMathStyle{3}}{\AssertMathStyle{3}}}
+ \displaystyle
+ \frac{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ \luatexcrampeddisplaystyle
+ \frac{\AssertMathStyle{3}}{\AssertMathStyle{3}}
+ \textstyle
+ \frac{\AssertMathStyle{4}}{\AssertMathStyle{5}}
+ \luatexcrampedtextstyle
+ \frac{\AssertMathStyle{5}}{\AssertMathStyle{5}}
+ \scriptstyle
+ \frac{\AssertMathStyle{6}}{\AssertMathStyle{7}}
+ \luatexcrampedscriptstyle
+ \frac{\AssertMathStyle{7}}{\AssertMathStyle{7}}
+\end{displaymath}
+\begin{math}
+ \AssertMathStyle{2} \sqrt{\AssertMathStyle{3}}
+ \frac{\AssertMathStyle{4}}{\AssertMathStyle{5}}
+ a^{\frac{\AssertMathStyle{6}}{\AssertMathStyle{7}}}
+ \sqrt{\frac{\AssertMathStyle{5}}{\AssertMathStyle{5}}}
+ \displaystyle
+ \frac{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ \luatexcrampeddisplaystyle
+ \frac{\AssertMathStyle{3}}{\AssertMathStyle{3}}
+ \textstyle
+ \frac{\AssertMathStyle{4}}{\AssertMathStyle{5}}
+ \luatexcrampedtextstyle
+ \frac{\AssertMathStyle{5}}{\AssertMathStyle{5}}
+ \scriptstyle
+ \frac{\AssertMathStyle{6}}{\AssertMathStyle{7}}
+ \luatexcrampedscriptstyle
+ \frac{\AssertMathStyle{7}}{\AssertMathStyle{7}}
+\end{math}
+\end{document}
+%</test-kernel>
+% \end{macrocode}
+%
+%
+% \subsection{\pkg{amsmath} and \pkg{mathtools}}
+%
+% Since \pkg{mathtools} loads \pkg{amsmath} anyway, we test both in one file.
+% \begin{macro}{\testbox}
+% First a scratch box register.
+% \begin{macrocode}
+%<*test-amsmath>
+\usepackage{lualatex-math}
+\newsavebox{\testbox}
+% \end{macrocode}
+% \end{macro}
+% We set the mathematical code for the minus sign to some arbitrary Unicode
+% value to test whether the load-time patch works.
+% \begin{macrocode}
+\luatexUmathcode`\-="2 "33 "44444 \relax
+\usepackage{amsmath}
+\AssertIntEqual{\luatexUmathcode`\-}{"33444444}
+\makeatletter
+\AssertIntEqual{\std@minus}{"33444444}
+\makeatother
+\usepackage{mathtools}
+% \end{macrocode}
+% The same for the document begin hook.
+% \begin{macrocode}
+\luatexUmathcode`\="5 "66 "77777 \relax
+\begin{document}
+\AssertIntEqual{\luatexUmathcode`\=}{"66A77777}
+\makeatletter
+\AssertIntEqual{\std@equal}{"66A77777}
+\makeatother
+% \end{macrocode}
+% Here we test whether the strut box has the correct height and depth.
+% \begin{macrocode}
+\sbox{\testbox}{$($} % )
+\makeatletter
+\AssertDimEqual{\ht\Mathstrutbox@}{\ht\testbox}
+\AssertDimEqual{\dp\Mathstrutbox@}{\dp\testbox}
+\makeatother
+% \end{macrocode}
+% Here we test for the various \pkg{amsmath} features that have to be patched:
+% sub-arrays and various kind of fraction-like objects. The \cmd{\substack}
+% command and \env{subarray} environment aren’t really tested since it is hard
+% to check whether the outcome looks right in an automated way. All tests are
+% done in both inline and display mode.
+% \begin{macrocode}
+\begin{equation*}
+ \AssertMathStyle{0} \sqrt{\AssertMathStyle{1}}
+ \sum_{
+ \substack{\frac12 \\ \frac34 \\ \frac56}
+ }
+ \sum_{
+ \begin{subarray}{l} \frac12 \\ \frac34 \\ \frac56 \end{subarray}
+ }
+ \frac{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ a^{\frac{\AssertMathStyle{6}}{\AssertMathStyle{7}}}
+ \dfrac{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ \tfrac{\AssertMathStyle{4}}{\AssertMathStyle{5}}
+ \binom{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ a^{\binom{\AssertMathStyle{6}}{\AssertMathStyle{7}}}
+ \dbinom{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ \tbinom{\AssertMathStyle{4}}{\AssertMathStyle{5}}
+ \genfrac{}{}{}{}{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ \genfrac{<}{/}{0pt}{0}{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ \genfrac{}{}{}{1}{\AssertMathStyle{4}}{\AssertMathStyle{5}}
+ \genfrac{|}{]}{4pt}{2}{\AssertMathStyle{6}}{\AssertMathStyle{7}}
+ \genfrac{}{}{}{3}{\AssertMathStyle{6}}{\AssertMathStyle{7}}
+\end{equation*}
+\begin{math}
+ \AssertMathStyle{2} \sqrt{\AssertMathStyle{3}}
+ \sum_{
+ \substack{\frac12 \\ \frac34 \\ \frac56}
+ }
+ \sum_{
+ \begin{subarray}{l} \frac12 \\ \frac34 \\ \frac56 \end{subarray}
+ }
+ \frac{\AssertMathStyle{4}}{\AssertMathStyle{5}}
+ a^{\frac{\AssertMathStyle{6}}{\AssertMathStyle{7}}}
+ \dfrac{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ \tfrac{\AssertMathStyle{4}}{\AssertMathStyle{5}}
+ \binom{\AssertMathStyle{4}}{\AssertMathStyle{5}}
+ a^{\binom{\AssertMathStyle{6}}{\AssertMathStyle{7}}}
+ \dbinom{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ \tbinom{\AssertMathStyle{4}}{\AssertMathStyle{5}}
+ \genfrac{}{}{}{}{\AssertMathStyle{4}}{\AssertMathStyle{5}}
+ \genfrac{<}{/}{0pt}{0}{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ \genfrac{}{}{}{1}{\AssertMathStyle{4}}{\AssertMathStyle{5}}
+ \genfrac{|}{]}{4pt}{2}{\AssertMathStyle{6}}{\AssertMathStyle{7}}
+ \genfrac{}{}{}{3}{\AssertMathStyle{6}}{\AssertMathStyle{7}}
+\end{math}
+% \end{macrocode}
+% Since \pkg{mathtools}’ \cmd{\cramped} command uses \cmd{\mathchoice}, we
+% cannot test for a single mathematical style since all of them are executed;
+% instead, we just verify that all styles encountered are cramped.
+% \begin{macrocode}
+\begin{equation*}
+ \AssertMathStyle{0}
+ a^{\AssertMathStyle{4} a}
+ \cramped{\AssertCrampedStyle a^{\AssertCrampedStyle a}}
+ a^{
+ \AssertMathStyle{4}
+ a^a
+ \cramped{\AssertCrampedStyle a^{\AssertCrampedStyle a}}
+ a^a
+ \AssertMathStyle{4}
+ }
+ a^{
+ a^{
+ \AssertMathStyle{6}
+ a^a
+ \cramped{\AssertCrampedStyle a^{\AssertCrampedStyle a}}
+ a^a
+ \AssertMathStyle{6}
+ }
+ }
+ a^{\AssertMathStyle{4} a}
+ \AssertMathStyle{0}
+\end{equation*}
+\begin{math}
+ \AssertMathStyle{2}
+ a^{\AssertMathStyle{4} a}
+ \cramped{\AssertCrampedStyle a^{\AssertCrampedStyle a}}
+ a^{
+ \AssertMathStyle{4}
+ a^a
+ \cramped{\AssertCrampedStyle a^{\AssertCrampedStyle a}}
+ a^a
+ \AssertMathStyle{4}
+ }
+ a^{
+ a^{
+ \AssertMathStyle{6}
+ a^a
+ \cramped{\AssertCrampedStyle a^{\AssertCrampedStyle a}}
+ a^a
+ \AssertMathStyle{6}
+ }
+ }
+ a^{\AssertMathStyle{4} a}
+ \AssertMathStyle{2}
+\end{math}
+\end{document}
+%</test-amsmath>
+% \end{macrocode}
+%
+%
+% \subsection{\pkg{unicode-math}}
+%
+% This test file loads both \pkg{amsmath} and \pkg{unicode-math}. The latter
+% package contains fixes that somewhat overlap with ours. We have to take care
+% in all packages that no attempt is made to patch a sinlge macro twice.
+% Therefore we treat warnings (that occur when trying to patch a macro with an
+% unknown meaning) as errors here.
+%
+% \begin{macrocode}
+%<*test-unicode>
+\ExplSyntaxOn
+\msg_redirect_class:nn { warning } { error }
+\ExplSyntaxOff
+\usepackage{amsmath}
+\usepackage{unicode-math}[2011/05/05]
+\setmathfont{XITS Math}
+\usepackage{lualatex-math}
+\begin{document}
+\begin{equation*}
+ \AssertMathStyle{0} \sqrt{\AssertMathStyle{1}}
+ \frac{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ a^{\frac{\AssertMathStyle{6}}{\AssertMathStyle{7}}}
+ \dfrac{\AssertMathStyle{2}}{\AssertMathStyle{3}}
+ \tfrac{\AssertMathStyle{4}}{\AssertMathStyle{5}}
+\end{equation*}
+\end{document}
+%</test-unicode>
+% \end{macrocode}
+%
+% \Finale
+\endinput
+
+% Local Variables:
+% mode: doctex
+% coding: utf-8-unix
+% TeX-engine: luatex
+% End:
diff --git a/Master/texmf-dist/source/lualatex/lualatex-math/lualatex-math.ins b/Master/texmf-dist/source/lualatex/lualatex-math/lualatex-math.ins
new file mode 100644
index 00000000000..c21c33cdf16
--- /dev/null
+++ b/Master/texmf-dist/source/lualatex/lualatex-math/lualatex-math.ins
@@ -0,0 +1,90 @@
+% lualatex-math.ins
+% Copyright 2011 Philipp Stephani
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either
+% version 1.3c of this license or (at your option) any later
+% version. The latest version of this license is in
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3c or later is part of all distributions of
+% LaTeX version 2009/09/24 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+% The Current Maintainer of this work is Philipp Stephani.
+% This work consists of all files listed in MANIFEST.
+
+\input docstrip.tex
+
+\keepsilent
+\askforoverwritefalse
+
+\usedir{tex/lualatex/lualatex-math}
+
+\preamble
+
+This is a generated file.
+
+Copyright 2011 by Philipp Stephani
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either
+version 1.3c of this license or (at your option) any later
+version. The latest version of this license is in
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of
+LaTeX version 2009/09/24 or later.
+
+\endpreamble
+
+\generate{
+ \file{lualatex-math.sty}{\from{lualatex-math.dtx}{package}}
+ \file{test-kernel.tex}{\from{lualatex-math.dtx}{test,test-kernel}}
+ \file{test-amsmath.tex}{\from{lualatex-math.dtx}{test,test-amsmath}}
+ \file{test-unicode.tex}{\from{lualatex-math.dtx}{test,test-unicode}}
+}
+
+\def\MetaPrefix{--}
+\preamble
+
+This is a generated file.
+
+Copyright 2011 by Philipp Stephani
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either
+version 1.3c of this license or (at your option) any later
+version. The latest version of this license is in
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of
+LaTeX version 2009/09/24 or later.
+
+\endpreamble
+\nopostamble
+
+\generate{
+ \file{lualatex-math.lua}{\from{lualatex-math.dtx}{lua}}
+}
+
+\obeyspaces
+\Msg{*****************************************************}
+\Msg{* *}
+\Msg{* To finish the installation you have to move the *}
+\Msg{* following files into a directory searched by TeX: *}
+\Msg{* *}
+\Msg{* lualatex-math.sty *}
+\Msg{* lualatex-math.lua *}
+\Msg{* *}
+\Msg{* To produce the documentation run the file *}
+\Msg{* lualatex-math.dtx through LaTeX. *}
+\Msg{* *}
+\Msg{* Happy TeXing! *}
+\Msg{* *}
+\Msg{*****************************************************}
+
+\endbatchfile