diff options
Diffstat (limited to 'macros/latex-dev/required/latex-lab/latex-lab-amsmath.dtx')
-rw-r--r-- | macros/latex-dev/required/latex-lab/latex-lab-amsmath.dtx | 971 |
1 files changed, 923 insertions, 48 deletions
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-amsmath.dtx b/macros/latex-dev/required/latex-lab/latex-lab-amsmath.dtx index 8591b39b39..3c9b8585a4 100644 --- a/macros/latex-dev/required/latex-lab/latex-lab-amsmath.dtx +++ b/macros/latex-dev/required/latex-lab/latex-lab-amsmath.dtx @@ -2,7 +2,7 @@ % %% File: latex-lab-amsmath.dtx % -% Copyright (C) 2022-2024 The LaTeX Project +% Copyright (C) 2022-2025 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -48,15 +48,16 @@ % % \section{Introduction} % -% This file implements adaptations to the \pkg{amsmath} package needed for -% the tagging project. +% This file implements adaptations to the \pkg{amsmath} package needed for +% the tagging project. % % \MaybeStop{\setlength\IndexMin{200pt} \PrintIndex } % % \section{The Implementation} % +% Better no @@ expansion here \ldots ... % \begin{macrocode} -%<@@=math> +%<@@=> % \end{macrocode} % % \begin{macrocode} @@ -66,7 +67,7 @@ % \subsection{File declaration} % \begin{macrocode} \ProvidesFile{latex-lab-amsmath.ltx} - [2024-09-18 v0.1c amsmath adaptions] + [2025-01-31 v0.1e amsmath adaptions] % \end{macrocode} % \subsection{Tagpdf support} % To make the code independent from tagging being loaded and active @@ -75,87 +76,958 @@ % \begin{macrocode} \RequirePackage{tagpdf-base} % \end{macrocode} -% +% % \begin{macrocode} \ExplSyntaxOn % \end{macrocode} % +% \subsection{Measuring} +% When measuring we neither want tagging nor the luamml processing. +% \begin{macro}{\measuring@true} +% \begin{macrocode} +\def\measuring@true{\let\ifmeasuring@\iftrue\tag_suspend:n{\measuring}\luamml_ignore:} +% \end{macrocode} +% \end{macro} +% +% \subsection{Display environments} +% \changes{0.1e}{2025-01-31}{moved redefinitions from latex-lab-math and luamml into this file} +% +% \subsubsection{Tag} +% The tag/label must be saved, so that it can be reinserted later. +% +% TODO: \cs{maketag@@@} is perhaps used in places where tagging/luamml handling +% is not wanted. This must be checked and handled. +% \begin{macro}{\maketag@@@} +% \begin{macrocode} +\def\maketag@@@#1 + {% + \ifmeasuring@ + \hbox{\m@th\normalfont#1}% + \else + \UseTaggingSocket{math/display/tag/begin} + \hbox{\m@th\normalfont#1 + \UseTaggingSocket{math/luamml/mtable/tag/save} + }% + \UseTaggingSocket{math/display/tag/end} + \fi + } +% \end{macrocode} +% \end{macro} +% \cs{eqref} uses \cs{tagform@} and so \cs{maketag@@@} but we do not want this tagging +% there. +% +% \begin{macro}{\eqref} +% \begin{macro}{\maketag@@@notog} +% \begin{macrocode} +\def\maketag@@@notag#1{\hbox{\m@th\normalfont#1}} +\DeclareRobustCommand{\eqref}[1] + {\textup{\let\maketag@@@\maketag@@@notag\tagform@{\ref{#1}}}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{align \& friends} +% +% Most display environment uses a common command for the end which contains +% the luamml socket to finalize the mtable. +% \begin{macro}{\common@align@ending} +% \begin{macrocode} +\def\common@align@ending { + \math@cr \black@\totwidth@ + \UseExpandableTaggingSocket {math/luamml/mtable/finalize} {align} + \egroup + \ifingather@ + \restorealignstate@ + \egroup + \nonumber + \ifnum0=`{\fi\iffalse}\fi + \else + $$% + \fi + \ignorespacesafterend +} +% \end{macrocode} +% \end{macro} +% Now we redefine the display alignments to use these ending. +% \begin{macrocode} +\renewenvironment{align}{% + \start@align\@ne\st@rredfalse\m@ne +}{% + \common@align@ending +} +\renewenvironment{align*}{% + \start@align\@ne\st@rredtrue\m@ne +}{% + \common@align@ending +} +\renewenvironment{alignat}{% + \start@align\z@\st@rredfalse +}{% + \common@align@ending +} +\renewenvironment{alignat*}{% + \start@align\z@\st@rredtrue +}{% + \common@align@ending +} +\renewenvironment{flalign}{% + \start@align\tw@\st@rredfalse\m@ne +}{% + \common@align@ending +} +\renewenvironment{flalign*}{% + \start@align\tw@\st@rredtrue\m@ne +}{% + \common@align@ending +} +\renewenvironment{xalignat}{% + \start@align\@ne\st@rredfalse +}{% + \common@align@ending +} +\renewenvironment{xalignat*}{% + \start@align\@ne\st@rredtrue +}{% + \common@align@ending +} +\renewenvironment{xxalignat}{% + \start@align\tw@\st@rredtrue +}{% + \common@align@ending +} +% \end{macrocode} +% +% And register these environments for the math grabbing. +% \begin{macrocode} + \math_register_halign_env:nn {align}{} + \math_register_halign_env:nn {align*}{} + \math_register_halign_env:nn {alignat}{} + \math_register_halign_env:nn {alignat*}{} + \math_register_halign_env:nn {flalign}{} + \math_register_halign_env:nn {flalign*}{} + \math_register_halign_env:nn {xalignat}{} + \math_register_halign_env:nn {xalignat*}{} + \math_register_halign_env:nn {xxalignat}{} +% \end{macrocode} +% +% The align preamble (used in \cs{align@}) needs code for luamml +% to save the cells. +% \begin{macro}{\align@preamble} +% \begin{macrocode} +\def\align@preamble{% + &\hfil + \strut@ + \setboxz@h + { + \@lign + $ + \m@th\displaystyle{##} + \ifmeasuring@ + \luamml_ignore: + \else + \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd} } + \fi + $ + }% + \ifmeasuring@ + \savefieldlength@ + \else + \UseTaggingSocket{math/luamml/mtable/finalizecol}{box} + \fi + \set@field + \tabskip\z@skip + &\setboxz@h + { + \@lign + $ + \m@th\displaystyle{{}##} + \ifmeasuring@ + \luamml_ignore: + \else + \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd} } + \fi + $ + }% + \ifmeasuring@ + \savefieldlength@ + \else + \UseTaggingSocket{math/luamml/mtable/finalizecol}{box} + \fi + \set@field + \hfil + \tabskip\alignsep@ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\math@cr@@@align} +% \begin{macrocode} +\def\math@cr@@@align{% + \ifst@rred\nonumber\fi + \if@eqnsw \global\tag@true \fi + \global\advance\row@\@ne + \add@amps\maxfields@ + \omit + \kern-\alignsep@ + \iftag@ + \setboxz@h{\@lign\strut@{\make@display@tag}}% + \place@tag + \fi + \UseTaggingSocket{math/luamml/mtable/tag/set} + \ifst@rred\else\global\@eqnswtrue\fi + \global\lineht@\z@ + \cr +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\texttt{gather} and \texttt{gather*}} +% +% \begin{macro}{\gather@} +% \begin{macrocode} +\def\gather@#1{% + \ingather@true \let\split\insplit@ + \let\tag\tag@in@align \let\label\label@in@display + \chardef\dspbrk@context\z@ + \intertext@ \displ@y@ \Let@ + \let\math@cr@@@\math@cr@@@gather + \gmeasure@{#1}% + \global\shifttag@false + \tabskip\z@skip + \global\row@\@ne + \halign to\displaywidth\bgroup + \strut@ + \setboxz@h + { + $\m@th\displaystyle{##} + \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd} } + $ + }% + \UseTaggingSocket{math/luamml/mtable/finalizecol}{box} + \calc@shift@gather + \set@gather@field + \tabskip\@centering + &\setboxz@h{\strut@{##}}% + \place@tag@gather + \UseTaggingSocket{math/luamml/mtable/tag/set} + \tabskip \iftagsleft@ \gdisplaywidth@ \else \z@skip \span\fi + \crcr + #1% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\endgather} +% \begin{macrocode} +\def\endgather{ + \math@cr + \black@ \totwidth@ + \UseExpandableTaggingSocket{math/luamml/mtable/finalize} {gather} + \egroup + $$ + \ignorespacesafterend +} +% \end{macrocode} +% \end{macro} +% +% The original definition of \texttt{gather*} uses \cs{endgather} +% but this redirection doesn't work if we alter \texttt{gather} so we use +% the real meaning and add the socket. +% \begin{environment}{gather*} +% \begin{macrocode} +\renewenvironment{gather*} + { + \start@gather\st@rredtrue + } + { + \math@cr + \black@\totwidth@ + \UseExpandableTaggingSocket{math/luamml/mtable/finalize} {gather} + \egroup + $$\ignorespacesafterend + } +% \end{macrocode} +% \end{environment} +% +% Register both environments +% \begin{macrocode} +\math_register_halign_env:nn {gather}{} +\math_register_halign_env:nn {gather*}{} +% \end{macrocode} +% +% \subsubsection{gathered, aligned and alignedat} +% These environments are not grabbed as they are inside other display +% environments but they need various sockets for luamml support. +% \begin{macro}{\start@aligned} +% \begin{macrocode} +\renewcommand{\start@aligned}[2]{ + \RIfM@ + \else + \nonmatherr@ {\begin{\@currenvir}} + \fi + \savecolumn@ % Assumption: called inside a group + \UseTaggingSocket{math/luamml/annotate/false}{}{ \alignedspace@left } + \ams@start@box {#1} \bgroup + \maxfields@ #2 \relax + \ifnum \maxfields@ > \m@ne + \multiply \maxfields@ \tw@ + \let \math@cr@@@ \math@cr@@@alignedat + \alignsep@ \z@skip + \else + \let \math@cr@@@ \math@cr@@@aligned + \alignsep@ \minalignsep + \fi + \Let@ \chardef \dspbrk@context \@ne + \default@tag + \spread@equation % no-op if already called + \global \column@ \z@ + \ialign \bgroup + & \column@plus + \hfil + \strut@ + $ + \m@th + \displaystyle + {##} + \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd} } + $ + \UseTaggingSocket{math/luamml/mtable/finalizecol}{last} + \tabskip \z@skip + & \column@plus + $ + \m@th + \displaystyle + { + {} + ## + } + \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd} } + $ + \UseTaggingSocket{math/luamml/mtable/finalizecol}{last} + \hfil + \tabskip\alignsep@ + \crcr + \ams@return@opt@arg +} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{gathered} +% \begin{macrocode} +\renewenvironment{gathered}[1][c]{% + \RIfM@\else + \nonmatherr@{\begin{gathered}}% + \fi +% \end{macrocode} +% This annotates the space +% \begin{macrocode} + \UseTaggingSocket{ math/luamml/annotate/false } {}{ \alignedspace@left } + \ams@start@box{#1}\bgroup + \Let@ \chardef\dspbrk@context\@ne \restore@math@cr + \spread@equation + \ialign\bgroup + \hfil\strut@$\m@th\displaystyle## +% \end{macrocode} +% This save the cell and then finalize it. +% \begin{macrocode} + \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd} } + $ + \UseTaggingSocket{math/luamml/mtable/finalizecol}{last} + \hfil + \crcr + \ams@return@opt@arg +}{% + \endaligned +} +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\endaligned} +% \begin{macrocode} +\def\endaligned + { + \crcr + \UseExpandableTaggingSocket{math/luamml/mtable/innertable/save} + \egroup + \restorecolumn@ + \egroup + \UseTaggingSocket{math/luamml/mtable/innertable/finalize} + } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{multline and multline*} +% +% \texttt{multline*} needs a redefinition before it is registered as it uses +% \cs{endmultline}, this must be replaced by the true code. +% +% \begin{environment}{multline*} +% \begin{macrocode} +\renewenvironment{multline*}{\start@multline\st@rredtrue} + {% + \iftagsleft@ \@xp\lendmultline@ \else \@xp\rendmultline@ \fi + \ignorespacesafterend + } +% \end{macrocode} +% \end{environment} +% +% And now we register both +% \begin{macrocode} +\math_register_halign_env:nn {multline}{} +\math_register_halign_env:nn {multline*}{} +% \end{macrocode} +% +% In the internal commands we have to add sockets for alignment attributes +% \begin{macro}{\multline@} +% \begin{macrocode} +\def\multline@#1{% + \Let@ + \@display@init{\global\advance\row@\@ne \global\dspbrk@lvl\m@ne}% + \chardef\dspbrk@context\z@ + \restore@math@cr + \let\tag\tag@in@align + \global\tag@false \global\let\raise@tag\@empty + \mmeasure@{#1}% + \let\tag\gobble@tag \let\label\@gobble + \tabskip \if@fleqn \@mathmargin \else \z@skip \fi + \totwidth@\displaywidth + \if@fleqn + \advance\totwidth@-\@mathmargin + \fi + \halign\bgroup + \hbox to\totwidth@{% + \if@fleqn + \hskip \@centering \relax + \else + \hfil + \fi + \strut@ + $\m@th\displaystyle{}##\endmultline@math + \hfil + }% + \crcr + \if@fleqn + \hskip-\@mathmargin + \def\multline@indent{\hskip\@mathmargin}% put it back + \else + \hfilneg + \def\multline@indent{\hskip\multlinegap}% + \fi + \iftagsleft@ + \iftag@ + \begingroup + \ifshifttag@ + \rlap{\vbox{% + \normalbaselines + \hbox{% + \strut@ + \make@display@tag + }% + \vbox to\lineht@{}% + \raise@tag + }}% + \multline@indent + \else + \setbox\z@\hbox{\make@display@tag}% + \dimen@\@mathmargin \advance\dimen@-\wd\z@ + \ifdim\dimen@<\multlinetaggap + \dimen@\multlinetaggap + \fi + \box\z@ \hskip\dimen@\relax + \fi + \endgroup + \else + \multline@indent + \fi + \else + \multline@indent + \fi + \ifmeasuring@ \else + \UseTaggingSocket{math/luamml/mtable/aligncol} {left} + \fi + #1% + \ifmeasuring@ \else + \UseTaggingSocket{math/luamml/mtable/aligncol} {right} + \fi +} +% \end{macrocode} +% \end{macro} +% +% Luckily, \texttt{multline} uses \cs{endmultline@math} in exactly +% the spot where we have to set the flag. +% Less luckily, \cs{endmultline@math} sometimes get overwritten for the last line. +% But that isn't much of a problem since we want special behavior there anyway. +% \begin{macro}{\endmultline@math} +% \begin{macrocode} +\def\endmultline@math + { + \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd} } + $ + \UseTaggingSocket{math/luamml/mtable/finalizecol}{last} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\rendmultline@} +% \begin{macrocode} +\def\rendmultline@{% + \iftag@ +% \end{macrocode} +% we need to surround the math token with tagging sockets. +% \begin{macrocode} + \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd} } + $ + \UseTaggingSocket{math/luamml/mtable/finalizecol}{last} + \let\endmultline@math\relax + \ifshifttag@ + \hskip\multlinegap + \llap{\vtop{% + \raise@tag + \normalbaselines + \setbox\@ne\null + \dp\@ne\lineht@ + \box\@ne + \hbox{\strut@\make@display@tag}% + }}% + \else + \hskip\multlinetaggap + \make@display@tag + \fi +% \end{macrocode} +% Here we set the tag TODO: is that sensible with multline? Where is the tag saved? +% \begin{macrocode} + \UseTaggingSocket{math/luamml/mtable/tag/set} + \else + \hskip\multlinegap + \fi + \hfilneg + \math@cr +% \end{macrocode} +% Now we finalize the mtable. +% \begin{macrocode} + \UseExpandableTaggingSocket {math/luamml/mtable/finalize} {multline} + \egroup$$% +} +% \end{macrocode} +% \end{macro} +% And something similar for the left version +% \begin{macro}{\lendmultline@} +% \begin{macrocode} +\def\lendmultline@{% + \hfilneg + \hskip\multlinegap + \math@cr + \UseExpandableTaggingSocket {math/luamml/mtable/finalize} {multline} + \egroup + $$% +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Cases} +% +% \begin{macro}{env@cases} +% \begin{macrocode} +\def\env@cases{% + \let\@ifnextchar\new@ifnextchar + \left\lbrace + \def\arraystretch{1.2}% + \array{@{}l@{\quad}l@{\luamml_ignore:}}% +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{smallmatrix} + +% \begin{environment}{smallmatrix} +% \begin{macrocode} +\renewenvironment {smallmatrix} { + \UseTaggingSocket{ math/luamml/annotate/false } {} { \null\, } + \vcenter \bgroup + \Let@ + \restore@math@cr + \default@tag + \baselineskip 6 \ex@ + \lineskip 1.5 \ex@ + \lineskiplimit \lineskip + \ialign \bgroup + \hfil + $ + \m@th + \scriptstyle + ## + % No \scriptsize here since we want to add the mstyle nodes + \UseTaggingSocket{math/luamml/save/nn}{ {} {mtd} } + $ + \UseTaggingSocket{math/luamml/mtable/finalizecol}{last} + \hfil + && + \thickspace + \hfil + $ + \m@th + \scriptstyle + ## + % No \scriptsize here since we want to add the mstyle nodes + \UseTaggingSocket{math/luamml/save/nn}{ {} {mtd} } + $ + \UseTaggingSocket{math/luamml/mtable/finalizecol}{last} + \hfil + \crcr +}{% + \crcr + \UseExpandableTaggingSocket{math/luamml/mtable/smallmatrix/save} + \egroup + \egroup + \UseTaggingSocket{math/luamml/mtable/innertable/finalize} + \UseTaggingSocket{ math/luamml/annotate/false } {}{ \, } +} +% \end{macrocode} +% \end{environment} +% +% \subsection{The split environment} +% +% The split environment is not trivial to handle as it has a rather convoluted +% implementation in amsmath: depending on in which display environment it is embedded +% it takes different branches, which makes it difficult to finalize the mtable. +% +% The following patches work with leqno and reqno if the (default) \texttt{centertags} +% are used. +% The currently fail (the structure is wrong) if the option \texttt{tbtags} is used. +% The alignment of the cells is currently not handled. +% A simple debug command until everything is sorted. +% \begin{macro}{\__math_split_debug_typeout:n} +% \begin{macrocode} +\cs_new:Npn\__math_split_debug_typeout:n#1{\use_none:n{#1}} +% \end{macrocode} +% \end{macro} +% We need to detect if \cs{gather@split} has been used or not +% \begin{macro}{\l__math_gathersplit_bool} +% \begin{macrocode} +\bool_new:N\l__math_gathersplit_bool +% \end{macrocode} +% \end{macro} +% At first a redefinition of the main environment. Here we only have to add +% the saving command for the inner table: +% \begin{environment}{split} +% \begin{macrocode} +\renewenvironment{split}{% + \__math_split_debug_typeout:n {begin~split} + \if@display + \ifinner + \@xp\@xp\@xp\split@aligned + \else + \ifst@rred \else \global\@eqnswtrue \fi + \fi + \else + \let\endsplit\@empty \@xp\collect@body\@xp\split@err + \fi + \collect@body\gather@split +}{\__math_split_debug_typeout:n{end~split}% + \crcr + \UseExpandableTaggingSocket{math/luamml/mtable/innertable/save}% + \egroup + \egroup + \iftagsleft@ \@xp\lendsplit@ \else \@xp\rendsplit@ \fi +} +% \end{macrocode} +% \end{environment} +% +% In \cs{gather@split} we have to add the finalization socket. +% We also set the boolean to true so that we can detect if +% the finalization has already happened. Perhaps this +% could be done in the luamml code instead? +% \begin{macro}{\gather@split} +% \begin{macrocode} +\def\gather@split#1#2#3{ + \__math_split_debug_typeout:n{gather@split}% + \@xp\endgroup \reset@equation % math@cr will handle equation numbering + \iftag@ + \toks@\@xp{\df@tag}% + \edef\split@tag{% + \gdef\@nx\df@tag{\the\toks@}% + \global\@nx\tag@true \@nx\nonumber + }% + \else \let\split@tag\@empty + \fi + \bool_set_true:N\l__math_gathersplit_bool + \spread@equation + \vcenter\bgroup + \gather@{\split@tag + \begin{split}#1\end{split}}% + \def\endmathdisplay@a{% + \__math_split_debug_typeout:n{endmathdisplay@a} + \__math_split_debug_typeout:n{finalize~innertable~endmathdisplay@a} + \math@cr + \black@ \totwidth@ + \egroup + \egroup + \UseExpandableTaggingSocket{math/luamml/mtable/innertable/finalize}% + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\insplit@} +% In \cs{insplit@} we have to add the sockets which store the cell content. +% \begin{macrocode} +\def\insplit@{\__math_split_debug_typeout:n{insplit@}% + \global\setbox\z@\vbox\bgroup + \Let@ \chardef\dspbrk@context\@ne \restore@math@cr + \default@tag % disallow use of \tag here + \ialign\bgroup + \hfil + \strut@ + $\m@th\displaystyle {##}% + \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd} }% + $% + \UseTaggingSocket{math/luamml/mtable/finalizecol}{last}% + &$\m@th\displaystyle {{}##}% + \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd} }% + $% + \UseTaggingSocket{math/luamml/mtable/finalizecol}{last}% + \hfill % Why not \hfil?---dmj, 1994/12/28 + \crcr +} +% \end{macrocode} +% \end{macro} +% And now the difficult part. Depending on the options leqno/reqno \cs{lendsplit@} +% or \cs{rendsplit@} are used for the typesetting and the inner table must +% be finalized here in case this hasn't happen yet. This must be tested with the +% boolean from \cs{gather@split} +% \begin{macrocode} +\def\lendsplit@{% + \global\setbox9\vtop{\unvcopy\z@}% + \ifinalign@ + \setbox\@ne\vbox{% + \unvcopy\z@ + \global\setbox8\lastbox + }% + \setbox\@ne\hbox{% + \unhcopy8% + \unskip + \setbox\tw@\lastbox + \unskip + \global\setbox\thr@@\lastbox + }% + \__math_split_debug_typeout:n{lendsplit@/aligncase} + \ifctagsplit@ + \__math_split_debug_typeout:n{lendsplit@/aligncase/centertags} + \gdef\split@{% + \hbox to\wd\thr@@{}% + &\vcenter{\vbox{\moveleft\wd\thr@@\box9}}% + \__math_split_debug_typeout:n{finalize~innertable~aligncase} + \UseTaggingSocket{math/luamml/mtable/innertable/finalize}% + }% + \else + %TODO, not correct yet. + \__math_split_debug_typeout:n{lendsplit@/aligncase/tbtags} + \gdef\split@{% + \hbox to\wd\thr@@{}% + &\vbox{\moveleft\wd\thr@@\box9}% + \__math_split_debug_typeout:n{finalize~innertable~aligncase} + \UseTaggingSocket{math/luamml/mtable/innertable/finalize}% + }% + \fi + \else +% \end{macrocode} +% If not in align we need to test for \cs{gather@split} +% \begin{macrocode} + \ifctagsplit@ + \bool_if:NTF \l__math_gathersplit_bool + { + \__math_split_debug_typeout:n{lendsplit/equationcase/centertags} + \gdef\split@% + {\UseTaggingSocket{math/luamml/annotate/false}{}{\vcenter{\box9}}} + } + { + \__math_split_debug_typeout:n {lendsplit/gathercase/centertags} + \gdef\split@{\vcenter{\box9}% + \__math_split_debug_typeout:n {finalize~innertable~gathercase} + \UseTaggingSocket{math/luamml/mtable/innertable/finalize}} + } + \else + % TODO tbtags not correct yet. + \bool_if:NTF \l__math_gathersplit_bool + { + \__math_split_debug_typeout:n {lendsplit/equationcase/tbtags} + \gdef\split@% + {\UseTaggingSocket{math/luamml/annotate/false}{}{\box9}} + } + { + \__math_split_debug_typeout:n {lendsplit/gathercase/tbtags} + \gdef\split@{ + \box9% + \__math_split_debug_typeout:n {finalize~innertable~gathercase} + \UseTaggingSocket{math/luamml/mtable/innertable/finalize}} + } + \fi + \fi + \aftergroup\split@ +} +% \end{macrocode} +% +% \begin{macro}{\rendsplit@} +% And more or less the same for the \cs{rendsplit@} environment. +% \begin{macrocode} +\def\rendsplit@{% + \ifinalign@ + \global\setbox9 \vtop{% + \unvcopy\z@ + \global\setbox8 \lastbox + \unskip + }% + \setbox\@ne\hbox{% + \unhcopy8 + \unskip + \global\setbox\tw@\lastbox + \unskip + \global\setbox\thr@@\lastbox + }% + \ifctagsplit@ + \gdef\split@{% + \hbox to\wd\thr@@{} + &\vcenter{\vbox{\moveleft\wd\thr@@\boxz@}}% + \__math_split_debug_typeout:n {rendsplit/aligncase/centertags} + \__math_split_debug_typeout:n {finalize~innertable~aligncase} + \UseTaggingSocket{math/luamml/mtable/innertable/finalize} + }% + \else + \__math_split_debug_typeout:n{rendsplit@/aligncase/tbtags} + %TODO tbtags is not correct yet + \global\setbox7 \hbox{\unhbox\tw@\unskip}% + \gdef\split@{% + \global\@tempcnta\column@ + &\setboxz@h{}% + \savetaglength@ + \global\advance\row@\@ne + \vbox{\moveleft\wd\thr@@\box9}% + \crcr + \noalign{\global\lineht@\z@}% + \add@amps\@tempcnta + \UseTaggingSocket{math/luamml/annotate/false}{}{\box\thr@@} + &\box7 + \__math_split_debug_typeout:n {finalize~innertable~aligncase} + \UseTaggingSocket{math/luamml/mtable/innertable/finalize}% + }% + \fi +% \end{macrocode} +% and again the if we are not in align we need to test for \cs{gathersplit} +% \begin{macrocode} + \else + \ifctagsplit@ + \bool_if:NTF \l__math_gathersplit_bool + { + \__math_split_debug_typeout:n {rendsplit/equationcase/centertags} + \gdef\split@% + {\UseTaggingSocket{math/luamml/annotate/false}{}{\vcenter{\boxz@}}} + } + { + \__math_split_debug_typeout:n {rendsplit/gathercase/centertags} + \gdef\split@{\vcenter{\boxz@}% + \__math_split_debug_typeout:n {finalize~innertable~gathercase} + \UseTaggingSocket{math/luamml/mtable/innertable/finalize}} + } + \else + \bool_if:NTF \l__math_gathersplit_bool + { + \__math_split_debug_typeout:n {rendsplit/equationcase/tbtags} + \gdef\split@{% + \UseTaggingSocket{math/luamml/annotate/false}{}{\boxz@}} + } + { + \__math_split_debug_typeout:n {rendsplit/gathercase/tbtags} + \gdef\split@{% + \boxz@ + \UseTaggingSocket{math/luamml/mtable/innertable/finalize}} + } + \fi + \fi + \aftergroup\split@ +} +% \end{macrocode} +% \end{macro} % \subsection{\cs{intertext}} % The \cs{intertext} command errors with active tagging as it is processed twice -% which leads to duplicated structures. +% which leads to duplicated structures. +% +% \begin{macro}{\intertext@} +% TODO: review and add sockets! % \begin{macrocode} -\AddToHook{package/amsmath/after} - { - \def\intertext@{% - \def\intertext##1{% - \ifvmode\else\\\@empty\fi - \noalign{% +\def\intertext@{% + \def\intertext##1{% + \ifvmode\else\\\@empty\fi + \noalign{% % \end{macrocode} % we have to flip the sign and use a negative \cs{belowdisplayskip} % as we flipped the sign at the outside. % \begin{macrocode} - \penalty\postdisplaypenalty\vskip-\belowdisplayskip - \vbox{ + \penalty\postdisplaypenalty\vskip-\belowdisplayskip + \vbox{ % \end{macrocode} % Stop tagging when measuring: % \begin{macrocode} - \ifmeasuring@\tag_suspend:n{\measuring}\fi - \normalbaselines - \ifdim\linewidth=\columnwidth - \else \parshape\@ne \@totalleftmargin \linewidth - \fi + \ifmeasuring@\tag_suspend:n{\measuring}\fi + \normalbaselines + \ifdim\linewidth=\columnwidth + \else \parshape\@ne \@totalleftmargin \linewidth + \fi % \end{macrocode} % End the previous mc: % \begin{macrocode} - \tag_mc_end_push: + \tag_mc_end_push: % \end{macrocode} % We are already in a par so we change now to text: % \begin{macrocode} - \tagpdfsetup{para/tag=P}% + \tagpdfsetup{para/tag=P}% % \end{macrocode} -% TODO why \cs{tagpdfparaOn} needed? +% TODO why \cs{tagpdfparaOn} needed? % \begin{macrocode} - \tagpdfparaOn - \noindent\ignorespaces##1\par + \tagpdfparaOn + \noindent\ignorespaces##1\par % \end{macrocode} % Restart the MC % \begin{macrocode} - \tag_mc_begin_pop:n{}}% - \penalty\predisplaypenalty\vskip\abovedisplayskip% - }% - }} - } + \tag_mc_begin_pop:n{}}% + \penalty\predisplaypenalty\vskip\abovedisplayskip% + }% +}} % \end{macrocode} +% \end{macro} % % \subsection{\cs{text}} -% +% % The \cs{text} command uses \cs{mathchoice} which \enquote{typesets} the argument -% four times. This makes it quite problematic for tagging. Without precautions -% structure objects would be created four times and would get MC-chunks as kids -% that doesn't really exist. amsmath contains a switch that allows to execute code +% four times. This makes it quite problematic for tagging. Without precautions +% structure objects would be created four times and would get MC-chunks as kids +% that don't really exist. amsmath contains a switch that allows to execute code % only in the first (displaymath) branch, but that isn't usable here. At first because % we don't know if the first branch creates the same structure as the one that is % actually used. At second because the engines executes some commands like \cs{label} % and \cs{pdfannot} only at shipout from the branch that really was used. So we would -% get structure data from one \cs{mathchoice}-branch and MC-labels and links from another -% one and that gets very messy. -% +% get structure data from one \cs{mathchoice}-branch and MC-labels and links from another +% one and that gets very messy. +% % We therefore have to avoid that tagging is active in unused branches. In pdflatex it % is not possible to detect the mathstyle before, so we use a label. With lualatex is % is possible to redefine \cs{text} not to use \cs{mathchoice} -% +% +% \begin{macro}{\text@} % \begin{macrocode} \AddToHook{package/amstext/after} { % \end{macrocode} % currently amsmath is loaded in a begindocument hook, so this % test is fine. If amstext is loaded earlier (in the kernel), this needs perhaps a change. +% \changes{v0.1d}{2024/12/03}{Add tagging socket for luamml support} % \begin{macrocode} \tag_if_active:T { \sys_if_engine_luatex:TF { - \def\text@#1{{% + \def\text@#1{ + \tag_socket_use:nnn {math/luamml/hbox}{} + {{% \ifcase\mathstyle \hbox{{#1}}\or \hbox{{#1}}\or @@ -168,7 +1040,7 @@ \ERROR \fi \check@mathfonts - }} + }}} } { \def\text@#1 @@ -177,39 +1049,41 @@ \tag_suspend:n{\text@} \mathchoice { - \@@_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{0} + \__math_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{0} \textdef@\displaystyle\f@size{#1} } { - \@@_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{2} + \__math_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{2} \textdef@\textstyle\f@size{\firstchoice@false #1} } { - \@@_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{4} + \__math_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{4} \textdef@\textstyle\sf@size{\firstchoice@false #1} } { - \@@_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{6} + \__math_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{6} \textdef@\textstyle \ssf@size{\firstchoice@false #1} } \check@mathfonts - }} + }} } } } % \end{macrocode} +% \end{macro} % % \subsection{\cs{pmb}} % \cs{pmb} prints its argument three times. For tagging we must mark % two of occurrences as artifact. % For luatex the attributes in the box must be reset, for this % we switch to expl3-boxes. +% \begin{macro}{\pbm@@,\pmb@} % \begin{macrocode} \AddToHook{package/amsbsy/after} { - \def\pmb@@@@#1#2#3{\leavevmode\hbox_set:Nn\l_@@_tmpa_box{xxx#3} + \def\pmb@@#1#2#3{\leavevmode\hbox_set:Nn\l_@@_tmpa_box{xxx#3} \dimen@-\box_wd:N\l_@@_tmpa_box - \kern-.5\ex@\box_use:N\l_@@_tmpa_box + \kern-.5\ex@\box_use:N\l_@@_tmpa_box \tag_mc_end:\tag_mc_begin:n{artifact} \tag_mc_reset_box:N\l_@@_tmpa_box \kern\dimen@\kern.25\ex@\raise.4\ex@\box_use:N\l_@@_tmpa_box @@ -220,7 +1094,7 @@ \setboxz@h{$\m@th#1\mkern.5mu$}\pmbraise@\wdz@ \binrel@{#2} \dimen@-\box_wd:N\l_@@_tmpa_box - \binrel@@@@{ + \binrel@@{ \mkern-.8mu\box_use:N\l_@@_tmpa_box \tag_mc_end:\tag_mc_begin:n{artifact} \tag_mc_reset_box:N\l_@@_tmpa_box @@ -231,6 +1105,7 @@ } } % \end{macrocode} +% \end{macro} % \begin{macrocode} \ExplSyntaxOff % \end{macrocode} |