% \iffalse meta-comment % % Copyright 2011–2020 by Philipp Stephani, Joseph Wright, and Will Robertson % Copyright 2021, 2022 Google LLC % % 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, ngerman, american]{phst-doc} \usepackage{lualatex-math} \newcommand*{\thispackage}{\textsf{lualatex-math}\xspace} \begin{document} \DocInput{lualatex-math.dtx} \PrintChanges \PrintIndex \end{document} % % \fi % % \CheckSum{322} % % \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} % \changes{v0.3a}{2011/09/13}{Updated for changes in \pkg{l3kernel}} % \changes{v1.0}{2012/08/27}{Switched to \pkg{l3docstrip}} % % \GetFileInfo{lualatex-math.sty} % % \title{The \thispackage package\thanks{This document corresponds to % \thispackage{}~\fileversion, dated~\filedate.}} % % \author{Philipp Stephani \\ \texttt{p.stephani2@gmail.com}} % \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} packages 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 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}, % \pkg{mathtools} and \pkg{icomma} 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}\cmd{\mathstyle} primitive % 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} % % \changes{v1.4a}{2015/08/24}{Use \pkg{expl3} versions of \hologo{LuaTeX} % math primitives} % \changes{v1.4a}{2015/08/24}{Avoid \cs{RequireLuaModule}} % \changes{v1.4a}{2015/09/16}{Load \pkg{luatexbase} only if required} % \changes{v1.9}{2020/09/25}{Require 2020 version of \hologo{LaTeX2e}} % \changes{v1.9}{2020/09/25}{Use builtin \hologo{LaTeX2e} hooks if available} % % \subsection{Requirements} % % \begin{macrocode} %<*package> %<@@=lltxmath> \NeedsTeXFormat{LaTeX2e}[2020/02/02] \RequirePackage{expl3}[2018/06/18] \ProvidesExplPackage{lualatex-math}{2022/01/01}{1.12}% {Patches for mathematics typesetting with LuaLaTeX} \RequirePackage { etoolbox } [ 2007/10/08 ] \cs_if_exist:NF \newluabytecode { \RequirePackage { luatexbase } [ 2010/05/27 ] } \directlua{require("lualatex-math")} % \end{macrocode} % % \begin{macro}{\@@_restore_catcode:N} % Executing the exhaustive expansion of % \cmd{\@@_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 \@@_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 { \@@_restore_catcode:N \$ } \char_set_catcode_math_toggle: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 third 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. % \begin{macrocode} \sys_if_engine_luatex:F { \msg_error:nn { lualatex-math } { luatex-required } \endinput } % \end{macrocode} % % \subsection{Patching} % % \begin{macro}{\@@_temp:w} % A scratch macro. % \begin{macrocode} \cs_new_eq:NN \@@_temp:w \prg_do_nothing: % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_patch:NNnnn} % \begin{macro}{\@@_patch:cNnnn} % The auxiliary macro \cmd{\@@_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 \@@_patch:NNnnn #1 #2 #3 #4 #5 { \cs_if_exist:NT #1 { \token_if_macro:NTF #1 { \group_begin: #2 \@@_temp:w #3 { #4 } \cs_if_eq:NNTF #1 \@@_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 \@@_temp:w } \group_end: } } { \msg_warning:nnx { lualatex-math } { macro-expected } { \token_to_str:N #1 } } } } \cs_generate_variant:Nn \@@_patch:NNnnn { c } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\@@_set_mathchar:NN} % The macro \cmd{\@@_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}. We cannot use the % |\Umathcharnumdef| primitive here since we would then rely on the % |\Umathcodenum| primitive which is currently % broken.\footnote{\url{http://tug.org/pipermail/luatex/2012-October/003794.html}} % \changes{v0.3c}{2012/08/23}{\pkg{l3kernel} renamed \cs{lua_now:x} to % \cs{lua_now_x:n}} % \changes{v1.1}{2012/10/13}{Update reasoning why \cs{Umathcharnumdef} is not % used here} % \changes{v1.3a}{2014/06/18}{\pkg{l3kernel} has (currently) dropped % \cs{lua_now_x:n}} % \changes{v1.4a}{2015/08/24}{\cs{lua_now_x:n} is back} % \changes{v1.8}{2019/01/21}{\cs{lua_now_x:n} is now called \cs{lua_now:e}} % \changes{v1.8}{2019/01/21}{Stop using \cs{…:D} control sequences} % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_set_mathchar:NN #1 #2 { \Umathchardef #1 \lua_now:e { lualatex.math.print_class_fam_slot( \int_eval:n { `#2 } ) } \scan_stop: } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_before_package:nn} % \begin{macro}{\@@_after_package:nn} % The macro \cmd{\@@_before_package:nn}\marg{package}\marg{code} executes the % \meta{code} before the \meta{package} is loaded. Accordingly, % \cmd{\@@_after_package:nn}\marg{package}\marg{code} executes the % \meta{code} after the \meta{package} is loaded. If the \meta{package} is % already loaded, nothing happens. We prefer using native \hologo{LaTeX2e} % hooks if possible. % \changes{v1.12}{2022-01-01}{Use the new generic hook names if available} % \begin{macrocode} \@ifl@t@r \fmtversion { 2021/11/15 } { \cs_new_protected_nopar:Npn \@@_before_package:nn #1 #2 { \AddToHook { package/#1/before } { #2 } } \cs_new_protected_nopar:Npn \@@_after_package:nn #1 #2 { \AddToHook { package/#1/after } { #2 } } }{ \@ifl@t@r \fmtversion { 2020/10/01 } { \cs_new_protected_nopar:Npn \@@_before_package:nn #1 #2 { \AddToHook { package/before/#1 } { #2 } } \cs_new_protected_nopar:Npn \@@_after_package:nn #1 #2 { \AddToHook { package/after/#1 } { #2 } } } { \RequirePackage { filehook } [ 2011/03/09 ] \cs_new_protected_nopar:Npn \@@_before_package:nn #1 #2 { \AtBeginOfPackageFile { #1 } { #2 } } \cs_new_protected_nopar:Npn \@@_after_package:nn #1 #2 { \AtEndOfPackageFile { #1 } { #2 } } } } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\@@_after_package_or_now:nn} % The macro \cmd{\@@_after_package_or_now:nn}\marg{package}\marg{code} % executes the \meta{code} after the \meta{package} is loaded. If the % \meta{package} is already loaded, the \meta{code} is executed immediately. % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_after_package_or_now:nn #1 #2 { \@ifpackageloaded { #1 } { #2 } { \@@_after_package:nn { #1 } { #2 } } } % \end{macrocode} % \end{macro} % % % \subsection{\Hologo{LaTeX2e} kernel} % % \changes{v0.3}{2011/08/07}{Patched math group allocation to gain access to % all families} % \changes{v1.4}{2015/04/04}{Removed patch for math group allocation; the % kernel itself now supports all available math families} % \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}{\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. Since \cmd{\frac} is declared by % \cmd{\DeclareRobustCommand}, we must patch the macro % \cmd{\frac\textvisiblespace}. % \changes{v1.9}{2020/09/25}{Adapt to changes in \hologo{LaTeX2e} kernel} % \begin{macrocode} \AtEndPreamble { \@ifpackageloaded { amsmath } { } { \@@_patch:cNnnn { frac~ } \cs_set:Npn { #1 #2 } { { \begingroup #1 \endgroup \over #2 } } { % \end{macrocode} % To do: do we need the additional set of braces around \cmd{\Ustack}? % \changes{v1.8}{2019/01/21}{Stop using \cs{…:D} control sequences} % \begin{macrocode} { \Ustack { \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} % These problems have been fixed in version~2.17i of \pkg{amsmath}, so we don’t % attempt to patch it if that version is loaded. % % \begin{macro}{\c_@@_std_minus_mathcode_int} % \begin{macro}{\c_@@_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_@@_std_minus_mathcode_int { "2200 } \int_const:Nn \c_@@_std_equal_mathcode_int { "303D } % \end{macrocode} % \end{macro} % \end{macro} % % \changes{v1.5}{2016/03/07}{Removed unused helper macro \cs{@@_char_dim:NN}} % % \begin{macro}{\l_@@_minus_mathchar} % \begin{macro}{\l_@@_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}. % \changes{v1.2}{2013/01/13}{Replace removed macro \cs{chk_if_free_cs:N}} % \changes{v1.9}{2020/09/25}{Don’t patch newer versions of \pkg{amsmath}} % \begin{macrocode} \tl_new:N \l_@@_minus_mathchar \tl_new:N \l_@@_equal_mathchar \@@_before_package:nn { amsmath } { \@ifpackagelater { amsmath } { 2020/08/24 } { } { \@@_set_mathchar:NN \l_@@_minus_mathchar \- \@@_set_mathchar:NN \l_@@_equal_mathchar \= % \end{macrocode} % \end{macro} % \end{macro} % Now we temporarily reset the mathematical codes. % \begin{macrocode} \char_set_mathcode:nn { `\- } { \c_@@_std_minus_mathcode_int } \char_set_mathcode:nn { `\= } { \c_@@_std_equal_mathcode_int } \@@_after_package:nn { 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_@@_minus_mathchar \cs_set_eq:NN \std@equal \l_@@_equal_mathchar % \end{macrocode} % \end{macro} % \end{macro} % Finally, we restore the original mathematical codes of the two signs. % \changes{v1.8}{2019/01/21}{Stop using \cs{…:D} control sequences} % \begin{macrocode} \Umathcodenum `\- \l_@@_minus_mathchar \Umathcodenum `\= \l_@@_equal_mathchar } } } % \end{macrocode} % All of the following fixes work even if \pkg{amsmath} is already loaded. % \begin{macro}{\@begindocumenthook} % \changes{v0.3b}{2011/09/18}{Another update for a change in \pkg{l3kernel}} % \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. % \changes{v1.9}{2020/09/25}{Don’t patch newer versions of \pkg{amsmath}} % \begin{macrocode} \@@_after_package_or_now:nn { amsmath } { \@ifpackagelater { amsmath } { 2020/08/24 } { } { \tl_replace_once:Nnn \@begindocumenthook { \mathchardef \std@minus \mathcode `\- \relax \mathchardef \std@equal \mathcode `\= \relax } { \@@_set_mathchar:NN \std@minus \- \@@_set_mathchar:NN \std@equal \= } } % \end{macrocode} % \end{macro} % % \changes{v1.5}{2016/03/07}{Removed patch for \cs{Mathstrutbox@}; % \pkg{amsmath} now has a definition usable in \Hologo{LuaLaTeX}} % % \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}). % \changes{v1.8}{2019/01/21}{Stop using \cs{…:D} control sequences} % \changes{v1.9}{2020/09/25}{Don’t patch newer versions of \pkg{amsmath}} % \changes{v1.9}{2020/09/25}{Stop using \cs{…:D} control sequences} % \begin{macrocode} \@ifpackagelater { amsmath } { 2020/09/23 } { } { \@@_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@@ %<@@=lltxmath> \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 { \Umathstacknumup \scriptstyle + \Umathstackdenomdown \scriptstyle } \lineskip \Umathstackvgap \scriptstyle \lineskiplimit \lineskip \ialign \c_group_begin_token \token_if_eq_meaning:NNT c #1 { \hfil } \Ustartmath \m@th \scriptstyle \alignmark \alignmark \Ustopmath \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}. % \changes{v1.8}{2019/01/21}{Stop using \cs{…:D} control sequences} % \begin{macrocode} \@@_patch:cNnnn { frac~ } \cs_set:Npn { #1 #2 } { { %<@@=> \begingroup #1 \endgroup \@@over #2 } } { { \Ustack { \group_begin: #1 \group_end: \@@over #2 } %<@@=lltxmath> } } % \end{macrocode} % \end{macro} % % \begin{macro}{\genfrac} % Generalized fractions are typeset by the \cmd{\genfrac} command. % Since \cmd{\genfrac} is declared by \cmd{\DeclareRobustCommand}, % we have to patch the macro \cmd{\genfrac\textvisiblespace}. % \changes{v1.7}{2017/06/15}{Adapt patch to changes in \pkg{amsmath}} % \changes{v1.8}{2019/01/21}{Stop using \cs{…:D} control sequences} % \begin{macrocode} \@@_patch:cNnnn { genfrac~ } \cs_set:Npn { #1 #2 #3 #4 #5 #6 } { { \@mathstyle { #4 } \genfrac@choice o { #1 } { \begingroup #5 \endgroup %<@@=> \ifx @ #3 @ \@@over \else \@@above \fi #3 \relax #6 } \genfrac@choice c { #2 } } } { { \@mathstyle { #4 } \genfrac@choice o { #1 } { \Ustack { \group_begin: #5 \group_end: \tl_if_empty:nTF { #3 } { \@@over } { \@@above #3 \scan_stop: } %<@@=lltxmath> #6 } } \genfrac@choice c { #2 } } } } } % \end{macrocode} % \end{macro} % % % \changes{v1.1}{2012/10/13}{Add fix and unit test for \pkg{amsopn}} % \changes{v1.6}{2016/04/16}{Removed patch for \cs{newmcodes@}; % \pkg{amsmath} now has a definition usable in \Hologo{LuaLaTeX}} % % % \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. % % In newer versions of \pkg{mathtools}, this issue is fixed, in which case we % skip the patch. % \changes{v1.10}{2021/03/28}{Skip patch if \pkg{mathtools} is recent enough} % \changes{v1.11}{2021/07/05}{Adapt to March 2021 changes to \pkg{mathtools}} % % \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} \@@_after_package_or_now:nn { mathtools } { \@ifpackagelater { mathtools } { 2021/03/28 } { } { \@@_patch:NNnnn \MT_cramped_internal:Nn \cs_set_nopar:Npn { #1 #2 } { \setbox \z@ \hbox { $ \m@th #1 \kern -\nulldelimiterspace \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@ \ifvmode \leavevmode \fi { } \box\z@ } { % \end{macrocode} % \changes{v1.4}{2014/08/18}{Added \cs{ensuremath} to work around % \href{https://github.com/phst/lualatex-math/issues/11}{issue~11}} % 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. As the original command works in both text and % math mode, we use |\ensuremath| here. % \changes{v1.9}{2020/09/25}{Stop using \cs{…:D} control sequences} % \begin{macrocode} { \ensuremath { \use:c { cramped \cs_to_str:N #1 } #2 } } } } } % \end{macrocode} % \end{macro} % % % \subsection{\pkg{icomma}} % % \changes{v0.2}{2011/07/03}{Added patch for the \pkg{icomma} package} % The \pkg{icomma} package uses |\mathchardef| to save the mathematical code of % the comma character. This breaks for Unicode fonts. The incompatibility was % noticed by % \Breitfeld.\footnote{\url{https://groups.google.com/forum/\#!topic/de.comp.text.tex/Cputk-AJS5I/discussion}} % \changes{v1.10}{2021/03/28}{Use new \Hologo{LaTeX2e} hook management if % available} % % \begin{macro}{\mathcomma} % \pkg{icomma} defines the mathemathical character shorthand \cmd{\icomma} at % the beginning of the document, therefore we again patch % \cmd{\@begindocumenthook}. % \begin{macrocode} \@@_after_package_or_now:nn { icomma } { \@ifl@t@r \fmtversion { 2020/10/01 } { \hook_gput_code:nnn { begindocument } { lualatex-math } { \@@_set_mathchar:NN \mathcomma \, \mathcode `\, = "8000 ~ } \hook_gset_rule:nnnn { begindocument } { lualatex-math } { voids } { icomma } } { \tl_replace_once:Nnn \@begindocumenthook { \mathchardef \mathcomma \mathcode `\, } { \@@_set_mathchar:NN \mathcomma \, } } } % % \end{macrocode} % \end{macro} % % % \section{Implementation of the \hologo{LuaLaTeX} module} % % For the Lua module, we use the standard \pkg{luatexbase-modutils} template. % \changes{v1.3}{2013/08/03}{Stop using the deprecated \func{module} function} % \changes{v1.4a}{2015/08/24}{Load all of \pkg{luatexbase}} % \begin{macrocode} %<*lua> lualatex = lualatex or {} lualatex.math = lualatex.math or {} luatexbase.provides_module({ name = "lualatex-math", date = "2013/08/03", version = 1.3, description = "Patches for mathematics typesetting with LuaLaTeX", author = "Philipp Stephani", licence = "LPPL v1.3+" }) % \end{macrocode} % \begin{function}{unpack} % \changes{v1.3}{2013/08/03}{Integrate Philipp Gesang’s patch to make the % \func{unpack} function compatible with Lua~5.2} % The function \func{unpack} needs to be treated specially as it got moved % around in Lua~5.2. % \begin{macrocode} local unpack = unpack or table.unpack % \end{macrocode} % \end{function} % \changes{v1.4a}{2015/08/24}{Pick up new name for string catcode table % where available} % \begin{macrocode} local cctb = luatexbase.catcodetables or {string = luatexbase.registernumber("catcodetable@string")} % \end{macrocode} % % \changes{v1.5}{2016/03/07}{Removed unused Lua function \func{print_fam_slot}} % % \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 lualatex.math.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 % \end{macrocode} % \end{function} % \begin{macrocode} return lualatex.math % % \end{macrocode} % % \Finale \endinput % Local Variables: % mode: doctex % coding: utf-8-unix % TeX-engine: luatex % End: