texlive[74063] Master/texmf-dist: luamml (17feb25)

commits+karl at tug.org commits+karl at tug.org
Mon Feb 17 21:43:46 CET 2025


Revision: 74063
          https://tug.org/svn/texlive?view=revision&revision=74063
Author:   karl
Date:     2025-02-17 21:43:45 +0100 (Mon, 17 Feb 2025)
Log Message:
-----------
luamml (17feb25)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/lualatex/luamml/luamml.pdf
    trunk/Master/texmf-dist/source/lualatex/luamml/luamml.dtx
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-amsmath.lua
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-array.lua
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-convert.lua
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-demo.sty
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-amsmath.sty
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-amstext.sty
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-kernel.sty
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-lab-math.sty
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-mathtools.sty
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-pdf-demo.sty
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-pdf.sty
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-structelemwriter.lua
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-table.lua
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-tex-annotate.lua
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-xmlwriter.lua
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml.sty

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/lualatex/luamml/CHANGELOG.md

Removed Paths:
-------------
    trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-array.sty

Added: trunk/Master/texmf-dist/doc/lualatex/luamml/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/lualatex/luamml/CHANGELOG.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/lualatex/luamml/CHANGELOG.md	2025-02-17 20:43:45 UTC (rev 74063)
@@ -0,0 +1,19 @@
+# Changelog
+All notable changes to the `luamml` package since the
+2025-02-17 will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+this project uses date-based 'snapshot' version identifiers.
+## [Unreleased]
+
+## 2025-02-17
+
+### Changed
+- Ulrike Fischer, 2024-11-29
+  luamml-structelemwriter.lua: moved the actualtext for e.g. stretched braces from the structure element to the mc-chunk.
+
+- Ulrike Fischer, 2024-03-03
+  luamml.dtx: add plug for mbox socket to correctly annotate them in math.
+
+- Ulrike Fischer, 2024-11-29
+  luamml-structelemwriter.lua: use structnum instead of label when stashing. 


Property changes on: trunk/Master/texmf-dist/doc/lualatex/luamml/CHANGELOG.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/lualatex/luamml/luamml.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/lualatex/luamml/luamml.dtx
===================================================================
--- trunk/Master/texmf-dist/source/lualatex/luamml/luamml.dtx	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/source/lualatex/luamml/luamml.dtx	2025-02-17 20:43:45 UTC (rev 74063)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% Copyright (C) 2020-2024 by Marcel Krueger
+%% Copyright (C) 2020-2025 by Marcel Krueger
 %%
 %% This file may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either
@@ -37,6 +37,9 @@
 \usepackage{csquotes,luacolor}
 \MakeShortVerb{\|}
 \RecordChanges
+\ProvideDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl}
+\ProvideDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl}
+
 \begin{document}
 \tracingmathml2
 \DocInput{luamml.dtx}
@@ -93,8 +96,24 @@
 % }
 % \end{verbatim}
 % produces a |<mi>TeX</mi>| element in the output instead of trying to import \TeX~as a mathematical expression.
-% The table structure is explained in an appendix.
 %
+% It it possible to add a structure around the construct, stash that structure
+% and then to tell \cmd{luamml_annotate:en} to insert it later inside the math.
+% For this the keys \texttt{struct} (which takes a label as argument) or \texttt{structnum}
+% (which takes a structure number) can be used. For example
+% \begin{verbatim}
+% $a = b \quad
+%  \tagstructbegin{tag=mtext,stash}\tagmcbegin{}
+%  \luamml_annotate:en{nucleus=true,structnum=\tag_get:n{struct_num}}
+%  {\mbox{some~text~with~\emph{structure}}}
+%  \tagmcend\tagstructend
+% $
+% \end{verbatim}
+% Such a construction should check that the flag for structure elements has actually
+% been set to avoid orphaned structures if the stashed structure is ignored.
+%
+% More about the table structure is explained in an appendix.
+%
 % \section{Features \& Limitations}
 % Currently all mathematical expressions which purely contain Unicode encoded math mode material without embedded non-math should get converted successfully.
 % Usage with non-Unicode math (\TeX's 8-bit math fonts) is highly experimental and undocumented.
@@ -114,11 +133,11 @@
 %    \begin{macrocode}
 %<@@=luamml>
 %<*luatex>
-\ProvidesExplPackage {luamml} {2024-10-30} {0.2.0}
+\ProvidesExplPackage {luamml} {2025-02-17} {0.3.0}
   {Automatically generate presentational MathML from LuaTeX math expressions}
 %</luatex>
 %<*pdftex>
-\ProvidesExplPackage {luamml-pdf} {2024-10-30} {0.2.0}
+\ProvidesExplPackage {luamml-pdf} {2025-02-17} {0.3.0}
   {MathML generation for L̶u̶a̶pdfLaTeX}
 %</pdftex>
 %    \end{macrocode}
@@ -300,7 +319,7 @@
 %   written by a previous formula. Therefore this has to be called separately
 %   for every formula or it must expand to different values to be useful.
 %   The value is fully expanded when the file is written.
-%   
+%
 %   Only complete formulas get written into files (so formulas where
 %   \cs{luamml_process:} or \cs{luamml_structelem:} are in effect).
 %
@@ -507,11 +526,447 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \subsection{Sockets}
+% In various places luamml has to add code to kernel commands. This is done through
+% sockets which are predeclared in lttagging.
 %
+% \subsubsection{Save sockets}
+% These sockets are wrappers around the \cs{luamml_save:...} commands
+% They should be provided until 2025-06-01
+%    \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/save/nn_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/save/nn}{1}
+   \AssignSocketPlug{tagsupport/math/luamml/save/nn}{noop}
+   \NewSocket{tagsupport/math/luamml/save/nNn}{1}
+   \AssignSocketPlug{tagsupport/math/luamml/save/nNn}{noop}
+ }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\NewSocketPlug{tagsupport/math/luamml/save/nNn}{luamml}
+ {
+   \luamml_save:nNn #1
+ }
+\AssignSocketPlug{tagsupport/math/luamml/save/nNn}{luamml}
+\NewSocketPlug{tagsupport/math/luamml/save/nn}{luamml}
+ {
+   \luamml_save:nn #1
+ }
+\AssignSocketPlug{tagsupport/math/luamml/save/nn}{luamml}
+%    \end{macrocode}
+%
+% \subsubsection{sockets to annotate content}
+%
+%    \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/annotate/false_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/annotate/false}{2}
+   \NewSocketPlug{tagsupport/math/luamml/annotate/false}{default}{#2}
+   \AssignSocketPlug{tagsupport/math/luamml/annotate/false}{default}
+ }
+%<*luatex>
+\NewSocketPlug{tagsupport/math/luamml/annotate/false}{luamml}
+ {
+   \luamml_annotate:en { core = false } 
+    {
+      #2
+    }
+ }
+\AssignSocketPlug{tagsupport/math/luamml/annotate/false}{luamml} 
+%</luatex>   
+%    \end{macrocode}
+% \subsubsection{socket plugs for the array package}
+%
+% The socket declaration can go with the 2025-06-01 release
+%    \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/array/finalize_plug_str }
+  {
+     \NewSocket{tagsupport/math/luamml/array/save}{0}
+     \NewSocket{tagsupport/math/luamml/array/finalize}{0}
+     \NewSocket{tagsupport/math/luamml/array/initcol}{0}
+     \NewSocket{tagsupport/math/luamml/array/finalizecol}{1}
+     \AssignSocketPlug{tagsupport/math/luamml/array/finalizecol}{noop}
+  }
+%    \end{macrocode}
+%
+% The luamml support makes only sense with luatex.
+%    \begin{macrocode}
+%<*luatex>
+\AddToHook{package/array/after}{\lua_now:n { require'luamml-array' }}
+%    \end{macrocode}
+% \begin{plugdecl}{tagsupport/math/luamml/array/save}
+%  The socket of this plug is used in \cs{endarray}.
+%    \begin{macrocode}
+\NewSocketPlug{tagsupport/math/luamml/array/save}{luamml}
+ {
+   \__luamml_array_save_array:
+ }
+%    \end{macrocode}
+% \end{plugdecl}
+%
+% \begin{plugdecl}{tagsupport/math/luamml/array/finalize}
+%  This socket of this plug is used in \cs{endarray}.
+%    \begin{macrocode}
+\NewSocketPlug{tagsupport/math/luamml/array/finalize}{luamml}
+ {
+   \mode_if_math:T { \__luamml_array_finalize_array: }
+ }
+%    \end{macrocode}
+% \end{plugdecl}
+%
+% \begin{plugdecl}{tagsupport/math/luamml/array/initcol}
+%  The socket of this plug is used in \cs{@classz}.
+%    \begin{macrocode}
+\NewSocketPlug{tagsupport/math/luamml/array/initcol}{luamml}
+ {
+   \__luamml_array_init_col:
+ }
+%    \end{macrocode}
+% \end{plugdecl}
+%
+%
+% \begin{plugdecl}{tagsupport/math/luamml/array/finalizecol}
+%  The socket of this plug is used used in \cs{@classz}.
+%    \begin{macrocode}
+\NewSocketPlug{tagsupport/math/luamml/array/finalizecol}{luamml}
+ {
+   \__luamml_array_finalize_col:w #1~
+ }
+%    \end{macrocode}
+% \end{plugdecl}
+%    \begin{macrocode}
+\AssignSocketPlug{tagsupport/math/luamml/array/save}{luamml}
+\AssignSocketPlug{tagsupport/math/luamml/array/finalize}{luamml}
+\AssignSocketPlug{tagsupport/math/luamml/array/initcol}{luamml}
+\AssignSocketPlug{tagsupport/math/luamml/array/finalizecol}{luamml}
+%</luatex>
+%    \end{macrocode}
+% \subsubsection{amsmath alignments}
+%
+% This socket is used at the end of alignment cells and adds the content to
+% the current row.
+%
+%    \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/finalizecol_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/finalizecol}{1}
+ }
+%    \end{macrocode}
+%    \begin{macrocode}
+%<*luatex>
+\NewSocketPlug{tagsupport/math/luamml/mtable/finalizecol}{luamml}
+ {
+   \use:c{__luamml_amsmath_add_#1_to_row:}
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/finalizecol}{luamml}
+
+%</luatex>
+%    \end{macrocode}
+%
+% These sockets save an inner table
+%    \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/innertable/save_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/innertable/save}{0}
+   \NewSocket{tagsupport/math/luamml/mtable/smallmatrix/save}{0}
+   \NewSocket{tagsupport/math/luamml/mtable/innertable/finalize}{0}
+ }
+%    \end{macrocode}
+%    \begin{macrocode}
+%<*luatex>
+\NewSocketPlug{tagsupport/math/luamml/mtable/innertable/save}{luamml}
+ {
+   \__luamml_amsmath_save_inner_table:n \@currenvir
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/innertable/save}{luamml}
+\NewSocketPlug{tagsupport/math/luamml/mtable/smallmatrix/save}{luamml}
+ {
+   \__luamml_amsmath_save_smallmatrix:
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/smallmatrix/save}{luamml}
+\NewSocketPlug{tagsupport/math/luamml/mtable/innertable/finalize}{luamml}
+ {
+   \__luamml_amsmath_finalize_inner_table:
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/innertable/finalize}{luamml}
+%</luatex>
+%    \end{macrocode}
+%
+%
+% This socket finalize the \texttt{mtable} in alignments like align or gather.
+% It takes an argument, the environment.
+% It should be used normally with \cs{UseExpandableTaggingSocket}.
+%    \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/finalize_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/finalize}{1}
+   \AssignSocketPlug{tagsupport/math/luamml/mtable/finalize}{noop}
+ }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<*luatex>
+\NewSocketPlug{tagsupport/math/luamml/mtable/finalize}{luamml}
+ {
+   \__luamml_amsmath_finalize_table:n {#1}
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/finalize}{luamml}
+%</luatex>
+%    \end{macrocode}
+%
+% This socket adds attributes for the alignment in \texttt{multline}.
+% It takes an argument, the alignment.
+%    \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/aligncol_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/aligncol}{1}
+   \AssignSocketPlug{tagsupport/math/luamml/mtable/aligncol}{noop}
+ }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<*luatex>
+\NewSocketPlug{tagsupport/math/luamml/mtable/aligncol}{luamml}
+ {
+   \__luamml_amsmath_set_row_columnalign:n {#1}
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/aligncol}{luamml}
+%</luatex>
+%    \end{macrocode}
+
+%
+% \subsubsection{Tags and labels}
+% These sockets save and set tags and labels in alignments.
+%    \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/tag/save_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/tag/save}{0}
+   \NewSocket{tagsupport/math/luamml/mtable/tag/set}{0}
+ }
+%    \end{macrocode}
+%    \begin{macrocode}
+%<*luatex>
+\NewSocketPlug{tagsupport/math/luamml/mtable/tag/save}{luamml}
+ {
+   \__luamml_amsmath_save_tag:
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/tag/save}{luamml}
+\NewSocketPlug{tagsupport/math/luamml/mtable/tag/set}{luamml}
+ {
+   \__luamml_amsmath_set_tag:
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/tag/set}{luamml}
+
+%</luatex>
+%    \end{macrocode}
+%
+% If math structure elements are created the Lbl-structure of a tag
+% must be moved inside the math structure, typically as an additional column in an
+% \texttt{mtable} with an intent \texttt{:equationlabel}.
+% 
+% The luamml-code handles this by stashing the Lbl-structure, storing the
+% structure number in an array and reusing it once it creates the math structure elements.
+% 
+% This should only be done for specific environments, we define
+% a constant to test: 
+%    \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/math/display/tag/begin_plug_str }
+ {
+   \NewSocket{tagsupport/math/display/tag/begin}{0}
+   \NewSocket{tagsupport/math/display/tag/end}{0}
+ }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<*luatex>
+\clist_map_inline:nn 
+  {
+    align,
+    align*,
+    alignat,
+    alignat*,
+    xalignat,
+    xalignat*,
+%    \end{macrocode}
+%  there is never a tag/label in xxalignat, so does it make sense to add a label column? 
+%  Left out for now.
+%    \begin{macrocode}
+    %xxalignat, 
+    flalign,
+    flalign*,
+    gather,
+    gather*,
+%    \end{macrocode}
+% equation and multline have at most one tag, so we do not use a label column
+% but rely on the external Lbl for now.
+%    \begin{macrocode}
+    %multline, % NO
+    %multline*, % NO
+    %equation, % NO
+    %equation*, % NO
+%    \end{macrocode}
+%   split has never a numbering so is ignored
+%    \begin{macrocode}
+    %split, % NO
+  }
+  {\tl_const:cn { c__luamml_label_#1_tl}{}}
+%    \end{macrocode}
+% 
+% 
+%    \begin{macrocode}
+\NewSocketPlug{tagsupport/math/display/tag/begin}{luamml}
+ { 
+   \tag_mc_end: 
+   \bool_lazy_and:nnTF
+    { \tl_if_exist_p:c { c__luamml_label_ \@currenvir _tl } }
+    { \int_if_odd_p:n { \int_div_truncate:nn { \l__luamml_flag_int } { 8 } } }
+    {   
+      %\typeout{Stash~and~move~\@currenvir\c_space_tl Lbl}   
+      \tag_struct_begin:n {tag=Lbl,stash}
+      \directlua{table.insert(ltx.__tag.struct.luamml.labels,\tag_get:n{struct_num})}
+    }
+    {     
+      \tag_struct_begin:n {tag=Lbl}
+    } 
+   \tag_mc_begin:n {}
+ }
+\AssignSocketPlug{tagsupport/math/display/tag/begin}{luamml} 
+%</luatex>
+%    \end{macrocode}
+%
+%
+% \subsubsection{Horizontal boxes}
+% This socket annotates an \cs{hbox} inside box commands used in math.
+% We test for the socket until the release 2025-06-01.
+%    \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/hbox_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/hbox}{2}
+   \NewSocketPlug{tagsupport/math/luamml/hbox}{default}{#2}
+   \AssignSocketPlug{tagsupport/math/luamml/hbox}{default}
+ }
+%<*luatex>
+\NewSocketPlug{tagsupport/math/luamml/hbox}{luamml}
+ {
+   \bool_lazy_and:nnTF
+    { \mode_if_math_p: }
+    { \int_if_odd_p:n { \int_div_truncate:nn { \l__luamml_flag_int } { 8 } } }
+    {
+      \tag_struct_begin:n
+       {
+         tag=mtext,
+         stash,
+       }
+      \tag_mc_begin:n {}
+      \luamml_annotate:en
+       {
+         nucleus = true,
+         structnum=\tag_get:n{struct_num}
+       }
+       { #2 }
+      \tag_mc_end:
+      \tag_struct_end:
+    }
+    { #2 }
+  }
+\AssignSocketPlug{tagsupport/math/luamml/hbox}{luamml}
+%</luatex>
+%    \end{macrocode}
+%
+% \subsubsection{Artifact characters}
+% Unicode characters like a root sign should be marked as artifacts
+% to avoid duplication e.g. in derivation if mathml
+% structure elements are used that imply the meaning.
+% We test for the socket until the release 2025-06-01.
+%    \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/artifact_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/artifact}{0}
+ }
+%<*luatex>
+\NewSocketPlug{tagsupport/math/luamml/artifact}{luamml}
+ {
+   \int_if_odd:nT { \int_div_truncate:nn { \l__luamml_flag_int } { 8 } }
+    {
+      \tag_mc_begin:n{artifact}
+    }
+ }
+\AssignSocketPlug{tagsupport/math/luamml/artifact}{luamml}
+%</luatex>
+%    \end{macrocode}
+%
+% \subsubsection{Math phantom socket}
+% This socket is used around \cs{finph at nt}.
+% It should provided until 2025-06-01
+%    \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/finph at nt_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/finph at nt}{2}
+   \NewSocketPlug{tagsupport/math/luamml/finph at nt}{default}{#2}
+   \AssignSocketPlug{tagsupport/math/luamml/finph at nt}{default}
+ }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<*luatex>
+\NewSocketPlug{tagsupport/math/luamml/finph at nt}{luamml}
+ {
+   \luamml_annotate:nen {1}
+    {
+     nucleus = true,
+     core =
+       {
+        [0] = 'mpadded',
+        \ifh@\else
+         width = 0,
+        \fi
+        \ifv@\else
+         height = 0, depth = 0,
+        \fi
+        consume_label'mathphant',
+      }
+    }
+    { #2 }
+ }
+\AssignSocketPlug{tagsupport/math/luamml/finph at nt}{luamml}
+%</luatex>
+%    \end{macrocode}
+
+% \subsubsection{Math smash socket}
+% This socket is used around \cs{finsm at sh}.
+% It should provided until 2025-06-01
+%    \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/finsm at sh_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/finsm at sh}{2}
+   \NewSocketPlug{tagsupport/math/luamml/finsm at sh}{default}{#2}
+   \AssignSocketPlug{tagsupport/math/luamml/finsm at sh}{default}
+ }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<*luatex>
+\NewSocketPlug{tagsupport/math/luamml/finsm at sh}{luamml}
+ {
+   \luamml_annotate:nen {2}
+    {
+     nucleus = true,
+     core =
+       consume_label('mathsmash',
+           function(padded)
+             padded.height, padded.depth = 0, 0~
+           end),
+    }
+    { #2 }
+ }
+\AssignSocketPlug{tagsupport/math/luamml/finsm at sh}{luamml}
+%</luatex>
+%    \end{macrocode}
 % \subsection{Patching}
 % For some packages, we ship with patches to make them more compatible and to
 % demonstrate how other code can be patched to work with \texttt{luamml}.
-% 
+%
 % These are either loaded directly if the packages are loaded or delayed using
 % \LaTeX's hook system otherwise.
 % \begin{macro}{\__luamml_patch_package:nn, \__luamml_patch_package:n}
@@ -533,7 +988,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% We currently provide minimal patching for the kernel, \pkg{amsmath} and \pkg{array}.
+% We currently provide minimal patching for the kernel, \pkg{amsmath}.
 % Currently only the kernel code supports pdf\TeX, but it's planned to extend this.
 %    \begin{macrocode}
 \RequirePackage { luamml-patches-kernel }
@@ -541,7 +996,6 @@
 \__luamml_patch_package:n {amstext}
 \__luamml_patch_package:n {amsmath}
 \__luamml_patch_package:n {mathtools}
-\__luamml_patch_package:n {array}
 %</luatex>
 %    \end{macrocode}
 

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-amsmath.lua
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-amsmath.lua	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-amsmath.lua	2025-02-17 20:43:45 UTC (rev 74063)
@@ -3,6 +3,7 @@
 local save_result = require'luamml-tex'.save_result
 local store_column = require'luamml-table'.store_column
 local store_tag = require'luamml-table'.store_tag
+local store_notag = require'luamml-table'.store_notag
 local get_table = require'luamml-table'.get_table
 local set_row_attribute = require'luamml-table'.set_row_attribute
 local to_text = require'luamml-lr'
@@ -125,9 +126,9 @@
 token.set_lua('__luamml_amsmath_set_tag:', funcid, 'protected')
 lua.get_functions_table()[funcid] = function()
   if not last_tag then
-    texio.write_nl'WARNING: Tag extraction failed'
-    return
+    store_notag({[0] = 'mtd',''})
+  else
+    store_tag({[0] = 'mtd', last_tag})
+    last_tag = nil
   end
-  store_tag({[0] = 'mtd', last_tag})
-  last_tag = nil
 end

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-array.lua
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-array.lua	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-array.lua	2025-02-17 20:43:45 UTC (rev 74063)
@@ -54,7 +54,7 @@
 
 local saved_array
 
-funcid = luatexbase.new_luafunction'__luamml_array_finalize_array:'
+funcid = luatexbase.new_luafunction'__luamml_array_save_array:'
 token.set_lua('__luamml_array_save_array:', funcid)
 lua.get_functions_table()[funcid] = function()
   -- TODO: Error handling etc.

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-convert.lua
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-convert.lua	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-convert.lua	2025-02-17 20:43:45 UTC (rev 74063)
@@ -370,7 +370,8 @@
     elem, core = {[0] = 'msqrt', nucleus, }, nil
   elseif kind == 'uroot' then
     -- FIXME: Check that this is really a root
-    elem, core = {[0] = 'msqrt', nucleus, kernel_to_table(radical.degree, 7, text_families)}, nil
+    -- UF 2024-12-04: force use of only one return value     
+    elem, core = {[0] = 'mroot', nucleus, (kernel_to_table(radical.degree, 7, text_families))}, nil
   elseif kind == 'uunderdelimiter' then
     elem, core = {[0] = 'munder', left, nucleus}, left
   elseif kind == 'uoverdelimiter' then

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-demo.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-demo.sty	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-demo.sty	2025-02-17 20:43:45 UTC (rev 74063)
@@ -1,5 +1,5 @@
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesExplPackage{luamml-demo}{2024-10-30}{0.2.0}{Reasonable default definitions for luamml}
+\ProvidesExplPackage{luamml-demo}{2025-02-17}{0.3.0}{Reasonable default definitions for luamml}
 
 \sys_if_engine_luatex:F {
   \msg_new:nnn {luamml-demo} {pdftex-option-ignored} {Option~`#1'~is~being~ignored~in~pdfTeX~mode.}

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-amsmath.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-amsmath.sty	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-amsmath.sty	2025-02-17 20:43:45 UTC (rev 74063)
@@ -1,4 +1,4 @@
-\ProvidesExplPackage {luamml-patches-amsmath} {2024-10-30} {0.2.0}
+\ProvidesExplPackage {luamml-patches-amsmath} {2025-02-17} {0.3.0}
   {Feel free to add a description here}
 
 \lua_now:n { require'luamml-amsmath' }
@@ -7,411 +7,415 @@
 % But they are almost identical to the original and only
 % add luamml commands in appropriate places, so they would
 % mostly disappear if there were enough hooks in amsmath.
+\IfPackageAtLeastTF{latex-lab-testphase-math}{2025-01-24}
+ {}
+ {
+   \PackageInfo{luamml}{patching~\string\start at aligned}
+    % aligned and friends
+    \cs_set:Npn \start at aligned #1#2 {
+      \RIfM@
+      \else
+        \nonmatherr@ { \begin { \@currenvir } }
+      \fi
+      \savecolumn@ % Assumption: called inside a group
+        \UseTaggingSocket{ math/luamml/annotate/false } {}{ \alignedspace at left }
+      \ams at start@box {#1} \bgroup
+        \maxfields@ #2 \relax
+        \ifnum \maxfields@ > \m at ne
+          \multiply \maxfields@ \tw@
+          \let \math at cr@@@ \math at cr@@@alignedat
+          \alignsep@ \z at skip
+        \else
+          \let \math at cr@@@ \math at cr@@@aligned
+          \alignsep@ \minalignsep
+        \fi
+        \Let@ \chardef \dspbrk at context \@ne
+        \default at tag
+        \spread at equation % no-op if already called
+        \global \column@ \z@
+        \ialign \bgroup
+          & \column at plus
+            \hfil
+            \strut@
+            $
+              \m at th
+              \displaystyle
+              {##}
+              \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd}}
+            $
+            \UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
+            \tabskip \z at skip
+          & \column at plus
+            $
+              \m at th
+              \displaystyle
+              {
+                {}
+                ##
+              }
+              \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd}}
+            $
+            \UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
+            \hfil
+            \tabskip\alignsep@
+          \crcr
+          \ams at return@opt at arg
+    }
+   \PackageInfo{luamml}{patching~gathered}
+     \renewcommand \gathered [1] [c] {
+       \RIfM@
+       \else
+         \nonmatherr@ { \begin {gathered} }
+       \fi
+       \UseTaggingSocket{ math/luamml/annotate/false } {}{ \alignedspace at left }
+       \ams at start@box {#1} \bgroup
+         \Let@
+         \chardef \dspbrk at context \@ne
+         \restore at math@cr
+         \spread at equation
+         \ialign \bgroup
+             \hfil
+             \strut@
+             $
+               \m at th
+               \displaystyle
+               ##
+               \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd}}
+             $
+             \UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
+             \hfil
+           \crcr
+             \ams at return@opt at arg
+     }
+   \PackageInfo{luamml}{patching~\string\endaligned}
+   \cs_set:Npn \endaligned {
+         \crcr
+         \UseExpandableTaggingSocket{math/luamml/mtable/innertable/save}
+       \egroup
+       \restorecolumn@
+     \egroup
+     \UseTaggingSocket{math/luamml/mtable/innertable/finalize}
+   }
+   \PackageInfo{luamml}{patching~\string\gather@}
+     \cs_set:Npn \gather@ #1 {
+       \ingather at true
+       \let \split \insplit@
+       \let \tag \tag at in@align
+       \let \label \label at in@display
+       \chardef \dspbrk at context \z@
+       \intertext@ \displ at y@ \Let@
+       \let \math at cr@@@ \math at cr@@@gather
+       \gmeasure@ {#1}
+       \global \shifttag at false
+       \tabskip \z at skip
+       \global \row@ \@ne
+       \halign to \displaywidth \bgroup
+           \strut@
+           \setboxz at h {
+             $
+               \m at th
+               \displaystyle
+               {##}
+               \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd}}
+             $
+           }
+           \UseTaggingSocket{math/luamml/mtable/finalizecol}{box}
+           \calc at shift@gather
+           \set at gather@field
+           \tabskip\@centering
+         &
+           \setboxz at h {
+             \strut@
+             {##}
+           }
+           \dim_compare:nNnTF {0pt} = {
+             \box_wd:N \c_zero_int
+           }
+           { \place at tag@gather }
+           {
+             \place at tag@gather
+             \UseTaggingSocket{math/luamml/mtable/tag/set}
+           }
+           \tabskip \iftagsleft@
+             \gdisplaywidth@
+           \else
+             \z at skip
+           \span \fi
+           \crcr
+           #1
+     }
+% in latex lab, add the luamml_ignore to \measuring at true instead.
+    \PackageInfo{luamml}{patching~\string\gmeasure@}
+    \cs_new_eq:NN \__luamml_amsmath_original_gmeasure:n \gmeasure@
+    \cs_set:Npn \gmeasure@ #1 {
+      \exp_last_unbraced:Nno
+        \use_ii_i:nn
+        { \luamml_ignore: }
+        { \__luamml_amsmath_original_gmeasure:n {#1} }
+    }
 
-% aligned and friends
-\cs_set:Npn \start at aligned #1#2 {
-  \RIfM@
-  \else
-    \nonmatherr@ { \begin { \@currenvir } }
-  \fi
-  \savecolumn@ % Assumption: called inside a group
-  \luamml_annotate:en {
-    core = false
-  } {
-    \alignedspace at left
-  }
-  \ams at start@box {#1} \bgroup
-    \maxfields@ #2 \relax
-    \ifnum \maxfields@ > \m at ne
-      \multiply \maxfields@ \tw@
-      \let \math at cr@@@ \math at cr@@@alignedat
-      \alignsep@ \z at skip
-    \else
-      \let \math at cr@@@ \math at cr@@@aligned
-      \alignsep@ \minalignsep
-    \fi
-    \Let@ \chardef \dspbrk at context \@ne
-    \default at tag
-    \spread at equation % no-op if already called
-    \global \column@ \z@
-    \ialign \bgroup
-      & \column at plus
-        \hfil
-        \strut@
-        $
-          \m at th
-          \displaystyle
-          {##}
-          \luamml_save:nNn {} \displaystyle {mtd}
-        $
-        \__luamml_amsmath_add_last_to_row:
-        \tabskip \z at skip
-      & \column at plus
-        $
-          \m at th
-          \displaystyle
-          {
-            {}
-            ##
-          }
-          \luamml_save:nNn {} \displaystyle {mtd}
-        $
-        \__luamml_amsmath_add_last_to_row:
-        \hfil
-        \tabskip\alignsep@
-      \crcr
-      \ams at return@opt at arg
-}
 
-\renewcommand \gathered [1] [c] {
-  \RIfM@
-  \else
-    \nonmatherr@ { \begin {gathered} }
-  \fi
-  \luamml_annotate:en {
-    core = false
-  } {
-    \alignedspace at left
-  }
-  \ams at start@box {#1} \bgroup
-    \Let@
-    \chardef \dspbrk at context \@ne
-    \restore at math@cr
-    \spread at equation
-    \ialign \bgroup
-        \hfil
-        \strut@
-        $
-          \m at th
-          \displaystyle
-          ##
-          \luamml_save:nNn {} \displaystyle {mtd}
-        $
-        \__luamml_amsmath_add_last_to_row:
-        \hfil
-      \crcr
-        \ams at return@opt at arg
-}
+   \PackageInfo{luamml}{patching~\string\endgather}
+   \cs_set:Npn \endgather {
+         \math at cr
+         \black@ \totwidth@
+         \UseExpandableTaggingSocket{math/luamml/mtable/finalize} {gather}
+     \egroup
+     $$
+     \ignorespacesafterend
+   }
 
-\cs_set:Npn \endaligned {
-      \crcr
-      \__luamml_amsmath_save_inner_table:n \@currenvir
-    \egroup
-    \restorecolumn@
-  \egroup
-  \__luamml_amsmath_finalize_inner_table:
-}
 
-% gather
-\cs_set:Npn \gather@ #1 {
-  \ingather at true
-  \let \split \insplit@
-  \let \tag \tag at in@align
-  \let \label \label at in@display
-  \chardef \dspbrk at context \z@
-  \intertext@ \displ at y@ \Let@
-  \let \math at cr@@@ \math at cr@@@gather
-  \gmeasure@ {#1}
-  \global \shifttag at false
-  \tabskip \z at skip
-  \global \row@ \@ne
-  \halign to \displaywidth \bgroup
-      \strut@
-      \setboxz at h {
-        $
-          \m at th
-          \displaystyle
-          {##}
-          \luamml_save:nNn {} \displaystyle {mtd}
-        $
-      }
-      \__luamml_amsmath_add_box_to_row:
-      \calc at shift@gather
-      \set at gather@field
-      \tabskip\@centering
-    &
-      \setboxz at h {
-        \strut@
-        {##}
-      }
-      \dim_compare:nNnF {0pt} = {
-        \box_wd:N \c_zero_int
-      } {
-        \__luamml_amsmath_set_tag:
-      }
-      \place at tag@gather
-      \tabskip \iftagsleft@
-        \gdisplaywidth@
-      \else
-        \z at skip
-      \span \fi
-      \crcr
-      #1
-}
+% align and friends
+   \PackageInfo{luamml}{patching~\string\align at preamble}
+   \cs_set:Npn \align at preamble {
+     &
+       \hfil
+       \strut@
+       \setboxz at h {
+         \@lign
+         $
+           \m at 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 at field
+       \tabskip\z at skip
+     &
+       \setboxz at h {
+         \@lign
+         $
+         \m at 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 at field
+       \hfil
+       \tabskip\alignsep@
+   }
+   \PackageInfo{luamml}{patching~\string\math at cr@@@align}
+   \cs_set:Npn \math at cr@@@align {
+     \ifst at rred
+       \nonumber
+     \fi
+     \if at eqnsw
+       \global \tag at true
+     \fi
+     \global \advance \row@ \@ne
+     \add at amps \maxfields@
+     \omit
+     \kern -\alignsep@
+     \iftag@
+       \setboxz at h {
+         \@lign
+         \strut@
+         { \make at display@tag }
+       }
+       \place at tag
+       \UseTaggingSocket{math/luamml/mtable/tag/set}
+     \fi
+     \ifst at rred
+     \else
+       \global \@eqnswtrue
+     \fi
+     \global \lineht@ \z@
+     \cr
+   }
 
-\cs_new_eq:NN \__luamml_amsmath_original_gmeasure:n \gmeasure@
-\cs_set:Npn \gmeasure@ #1 {
-  \exp_last_unbraced:Nno
-    \use_ii_i:nn
-    { \luamml_ignore: }
-    { \__luamml_amsmath_original_gmeasure:n {#1} }
-}
-
-\cs_set:Npn \endgather {
+% This was lost anyway, as the latex-lab code overwrites
+% the definition again.
+   \PackageInfo{luamml}{patching~\string\maketag@@@}
+   \cs_set:Npn \maketag@@@ #1
+    {
+      \hbox {
+       \m at th
+       \normalfont
+       #1
+       \UseTaggingSocket{math/luamml/mtable/tag/save}
+     }
+    }
+   \PackageInfo{luamml}{patching~\string\endalign}
+% this handled in latex-lab through \common at align@ending
+    \cs_set:Npn \endalign {
       \math at cr
       \black@ \totwidth@
-      \__luamml_amsmath_finalize_table:n {gather}
-  \egroup
-  $$
-  \ignorespacesafterend
-}
-
-% align and friends
-\cs_set:Npn \align at preamble {
-  &
-    \hfil
-    \strut@
-    \setboxz at h {
-      \@lign
-      $
-        \m at th
-        \displaystyle
-        {##}
-        \ifmeasuring@
-          \luamml_ignore:
-        \else
-          \luamml_save:nNn {} \displaystyle {mtd}
-        \fi
-      $
-    }
-    \ifmeasuring@
-      \savefieldlength@
-    \else
-      \__luamml_amsmath_add_box_to_row:
-    \fi
-    \set at field
-    \tabskip\z at skip
-  &
-    \setboxz at h {
-      \@lign
-      $
-      \m at th
-      \displaystyle
-      {
-        {}
-        ##
-      }
-      \ifmeasuring@
-        \luamml_ignore:
+      \UseTaggingSocket{math/luamml/mtable/finalize} {align}
+      \egroup
+      \ifingather@
+        \restorealignstate@
+        \egroup
+        \nonumber
+        \ifnum0=`{\fi\iffalse}\fi
       \else
-        \luamml_save:nNn {} \displaystyle {mtd}
+        $$
       \fi
-      $
+      \ignorespacesafterend
     }
-    \ifmeasuring@
-      \savefieldlength@
-    \else
-      \__luamml_amsmath_add_box_to_row:
-    \fi
-    \set at field
-    \hfil
-    \tabskip\alignsep@
-}
+   
+   \PackageInfo{luamml}{patching~\string\multline@}
+   % For a more interesting one, let's consider multline:
+   \cs_new_eq:NN \__luamml_amsmath_original_multline:n \multline@
+   \cs_set:Npn \multline@ #1 {
+     \__luamml_amsmath_original_multline:n {
+       \ifmeasuring@ \else
+         \UseTaggingSocket{math/luamml/mtable/aligncol} {left}
+       \fi
+       #1
+       \ifmeasuring@ \else
+         \UseTaggingSocket{math/luamml/mtable/aligncol} {right}
+       \fi
+     }
+   }
 
-\cs_set:Npn \math at cr@@@align {
-  \ifst at rred
-    \nonumber
-  \fi
-  \if at eqnsw
-    \global \tag at true
-  \fi
-  \global \advance \row@ \@ne
-  \add at amps \maxfields@
-  \omit
-  \kern -\alignsep@
-  \iftag@
-    \setboxz at h { 
-      \@lign
-      \strut@
-      { \make at display@tag }
-    }
-    \place at tag
-    \__luamml_amsmath_set_tag:
-  \fi
-  \ifst at rred
-  \else
-    \global \@eqnswtrue
-  \fi
-  \global \lineht@ \z@
-  \cr
-}
-
-\cs_set:Npn \maketag@@@ #1 {
-  \hbox {
-    \m at th
-    \normalfont
-    #1
-    \__luamml_amsmath_save_tag:
-  }
-}
-
-\cs_set:Npn \endalign {
-  \math at cr
-  \black@ \totwidth@
-  \__luamml_amsmath_finalize_table:n {align}
-  \egroup
-  \ifingather@
-    \restorealignstate@
-    \egroup
-    \nonumber
-    \ifnum0=`{\fi\iffalse}\fi
-  \else
-    $$
-  \fi
-  \ignorespacesafterend
-}
-
-% For a more interesting one, let's consider multline:
-\cs_new_eq:NN \__luamml_amsmath_original_multline:n \multline@
-\cs_set:Npn \multline@ #1 {
-  \__luamml_amsmath_original_multline:n {
-    \ifmeasuring@ \else
-      \__luamml_amsmath_set_row_columnalign:n {left}
-    \fi
-    #1
-    \ifmeasuring@ \else
-      \__luamml_amsmath_set_row_columnalign:n {right}
-    \fi
-  }
-}
-
-\cs_new_eq:NN \__luamml_amsmath_original_mmeasure:n \mmeasure@
-\cs_set:Npn \mmeasure@ #1 {
-  \exp_last_unbraced:Nno
-    \use_ii_i:nn
-    { \luamml_ignore: }
-    { \__luamml_amsmath_original_mmeasure:n {#1} }
-}
-
+   %this is not move to latex-lab as the luamml_ignore is inserting with 
+   % \measuringtrue
+   \PackageInfo{luamml}{patching~\string\mmeasure@}
+   \cs_new_eq:NN \__luamml_amsmath_original_mmeasure:n \mmeasure@
+   \cs_set:Npn \mmeasure@ #1 {
+     \exp_last_unbraced:Nno
+       \use_ii_i:nn
+       { \luamml_ignore: }
+       { \__luamml_amsmath_original_mmeasure:n {#1} }
+   }
 % Luckily, {multline} uses \endmultline at math in exactly
 % the spot where we have to set the flag.
 % Less luckily, \endmultline at math sometimes get overwritten for the last line.
 % But that isn't a problem since we want special behavior there anyway.
-\cs_set:Npn \endmultline at math {
-  \luamml_save:nNn {} \displaystyle {mtd}
-  $
-  \__luamml_amsmath_add_last_to_row:
-}
-
-\cs_set:Npn \rendmultline@ {
-    \iftag@
-      \luamml_save:nNn {} \displaystyle {mtd}
+    \PackageInfo{luamml}{patching~\string\endmultline at math}
+    \cs_set:Npn \endmultline at math {
+      \UseTaggingSocket{math/luamml/save/nNn}{{} \displaystyle {mtd}}
       $
-      \__luamml_amsmath_add_last_to_row:
-      \let \endmultline at math \relax
-      \ifshifttag@
-        \hskip \multlinegap
-        \llap {
-          \vtop {
-            \raise at tag
-            \normalbaselines
-            \setbox \@ne \null
-            \dp \@ne \lineht@
-            \box \@ne
-            \hbox {
-              \strut@
-              \make at display@tag
+      \UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
+    }
+    \PackageInfo{luamml}{patching~\string\rendmultline@}
+    \cs_set:Npn \rendmultline@ {
+        \iftag@
+          \UseTaggingSocket{math/luamml/save/nNn}{{} \displaystyle {mtd}}
+          $
+          \UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
+          \let \endmultline at math \relax
+          \ifshifttag@
+            \hskip \multlinegap
+            \llap {
+              \vtop {
+                \raise at tag
+                \normalbaselines
+                \setbox \@ne \null
+                \dp \@ne \lineht@
+                \box \@ne
+                \hbox {
+                  \strut@
+                  \make at display@tag
+                }
+              }
             }
-          }
-        }
-      \else
-        \hskip \multlinetaggap
-        \make at display@tag
-      \fi
-      \__luamml_amsmath_set_tag:
-    \else
-      \hskip \multlinegap
-    \fi
-    \hfilneg
-    \math at cr
-    \__luamml_amsmath_finalize_table:n {multline}
-  \egroup
-  $$
-}
+          \else
+            \hskip \multlinetaggap
+            \make at display@tag
+          \fi
+          \UseTaggingSocket{math/luamml/mtable/tag/set}
+        \else
+          \hskip \multlinegap
+        \fi
+        \hfilneg
+        \math at cr
+        \UseExpandableTaggingSocket {math/luamml/mtable/finalize} {multline}
+      \egroup
+      $$
+    }
+    \PackageInfo{luamml}{patching~\string\lendmultline@}
+    \cs_set:Npn \lendmultline@ {
+        \hfilneg
+        \hskip\multlinegap
+        \math at cr
+        \UseExpandableTaggingSocket {math/luamml/mtable/finalize} {multline}
+        %\__luamml_amsmath_finalize_table:n {multline}
+      \egroup
+      $$
+    }
+   
+   \PackageInfo{luamml}{patching~smallmatrix}
+    \renewenvironment {smallmatrix} {
+      \UseTaggingSocket{ math/luamml/annotate/false } {} { \null\, }
+      \vcenter \bgroup
+        \Let@
+        \restore at math@cr
+        \default at tag
+        \baselineskip 6 \ex@
+        \lineskip 1.5 \ex@
+        \lineskiplimit \lineskip
+        \ialign \bgroup
+            \hfil
+            $
+            \m at 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 at 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} {}{ \, }
+    }
 
-\cs_set:Npn \lendmultline@ {
-    \hfilneg
-    \hskip\multlinegap
-    \math at cr
-    \__luamml_amsmath_finalize_table:n {multline}
-  \egroup
-  $$
-}
-
-% Finally some slightly different stuff.
-% While {matrix} is covered by {array}, we still have {smallmatrix}:
-\renewenvironment {smallmatrix} {
-  \luamml_annotate:en {
-    core = false
-  } {
-    \null
-    \,
-  }
-  \vcenter \bgroup
-    \Let@
-    \restore at math@cr
-    \default at tag
-    \baselineskip 6 \ex@
-    \lineskip 1.5 \ex@
-    \lineskiplimit \lineskip
-    \ialign \bgroup
-        \hfil
-        $
-        \m at th
-        \scriptstyle
-        ##
-        \luamml_save:nn {} {mtd} % No \scriptsize here since we want to add the mstyle nodes
-        $
-        \__luamml_amsmath_add_last_to_row:
-        \hfil
-      &&
-        \thickspace
-        \hfil
-        $
-        \m at th
-        \scriptstyle
-        ##
-        \luamml_save:nn {} {mtd} % No \scriptsize here since we want to add the mstyle nodes
-        $
-        \__luamml_amsmath_add_last_to_row:
-        \hfil
-      \crcr
-}{%
-      \crcr
-      \__luamml_amsmath_save_smallmatrix:
-    \egroup
-  \egroup
-  \__luamml_amsmath_finalize_inner_table:
-  \luamml_annotate:en {
-    core = false
-  } {
-    \,
-  }
-}
-
-% {cases} is defined by the kernel, but we patch the overwritten version by amsmath.
-\cs_set:Npn \env at cases {
-  \let \@ifnextchar \new at ifnextchar
-  \left \lbrace
-    \def \arraystretch {1.2}
-    \array {@{}l@{\quad \luamml_ignore:}l@{}}
-}
-
-
-\cs_set:Npn \bBigg@ #1 #2 {
-  {
-    \ensuremath {
-      \Uvextensible height~#1 \big at size axis~exact~#2
+    % {cases} is defined by the kernel, but we patch the overwritten version by amsmath.
+    \PackageInfo{luamml}{patching~\string\env at cases}
+    \cs_set:Npn \env at cases {
+      \let \@ifnextchar \new at ifnextchar
+      \left \lbrace
+        \def \arraystretch {1.2}
+        \array {@{}l@{\quad \luamml_ignore:}l@{}}
     }
-  }
-}
+   \PackageInfo{luamml}{patching~\string\bBigg@}
+   \cs_set:Npn \bBigg@ #1 #2 {
+     {
+       \ensuremath {
+         \Uvextensible height~#1 \big at size axis~exact~#2
+       }
+     }
+   }
+} %end package test

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-amstext.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-amstext.sty	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-amstext.sty	2025-02-17 20:43:45 UTC (rev 74063)
@@ -1,37 +1,29 @@
-\ProvidesExplPackage {luamml-patches-amstext} {2024-10-30} {0.2.0}
-  {Feel free to add a description here}
+\ProvidesExplPackage {luamml-patches-amstext} {2025-02-17} {0.3.0}
+  {patches of amstext commands}
 
-\int_new:N \g__luamml_amsmath_text_struct_int
-\cs_set:Npn \textdef@ #1 #2 #3 {
-  \int_if_odd:nTF { \int_div_truncate:nn { \l__luamml_flag_int } { 8 } } {
-    \int_gincr:N \g__luamml_amsmath_text_struct_int
-    \tag_struct_begin:n {
-      tag = mtext/mathml,
-      stash,
-      label = __luamml_amsmath_text_ \int_use:N \g__luamml_amsmath_text_struct_int
+% This is the same definition as in latex-lab-amsmath. It can go with the
+% 2025-06-01 release.
+\IfPackageAtLeastTF{latex-lab-testphase-math}{2025-01-24}
+ {}
+ {
+   \PackageInfo{luamml}{patching~\string\text@}    
+   \sys_if_engine_luatex:T
+    {
+      \def\text@#1{
+       \tag_socket_use:nnn {math/luamml/hbox}{}
+       {{%
+        \ifcase\mathstyle
+        \hbox{{#1}}\or
+        \hbox{{#1}}\or
+        \hbox{{#1}}\or
+        \hbox{{#1}}\or
+        \hbox{{\let\f at size\sf at size\selectfont#1}}\or
+        \hbox{{\let\f at size\sf at size\selectfont#1}}\or
+        \hbox{{\let\f at size\ssf at size\selectfont#1}}\or
+        \hbox{{\let\f at size\ssf at size\selectfont#1}}\or
+        \ERROR
+        \fi
+        \check at mathfonts
+      }}}
     }
-    \tag_mc_begin:n {
-      tag = mtext
-    }
-    \AnnotateFormula {
-      nucleus = true,
-      struct = "__luamml_amsmath_text_ \int_use:N \g__luamml_amsmath_text_struct_int"
-    }
-  } {
-    \use:n
   }
-  {
-    \hbox {
-      {
-        \everymath {#1}
-        \let \f at size #2
-        \selectfont
-        #3
-      }
-    }
-  }
-  \int_if_odd:nT { \int_div_truncate:nn { \l__luamml_flag_int } { 8 } } {
-    \tag_mc_end:
-    \tag_struct_end:
-  }
-}

Deleted: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-array.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-array.sty	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-array.sty	2025-02-17 20:43:45 UTC (rev 74063)
@@ -1,101 +0,0 @@
-\ProvidesExplPackage {luamml-patches-array} {2024-10-30} {0.2.0}
-  {Feel free to add a description here}
-
-\lua_now:n { require'luamml-array' }
-
-\cs_set:Npn \@classz {
-  \@classx
-  \@tempcnta \count@
-  \prepnext at tok
-  \@addtopreamble {
-    \ifcase \@chnum
-      \hfil
-      \hskip 1sp
-      \d at llarbegin
-      \cs_if_eq:NNTF \d at llarbegin \begingroup {
-        \insert at column
-        \d at llarend
-      } {
-        \__luamml_array_init_col:
-        \insert at column
-        \luamml_save:nn {} {mtd}
-        \d at llarend
-        \__luamml_array_finalize_col:w 0~
-      }
-      \do at row@strut
-      \hfil
-    \or
-      \hskip 1sp
-      \d at llarbegin
-      \cs_if_eq:NNTF \d at llarbegin \begingroup {
-        \insert at column
-        \d at llarend
-      } {
-        \__luamml_array_init_col:
-        \insert at column
-        \luamml_save:nn {} {mtd}
-        \d at llarend
-        \__luamml_array_finalize_col:w 1~
-      }
-      \do at row@strut
-      \hfil
-    \or
-      \hfil
-      \hskip 1sp
-      \d at llarbegin
-      \cs_if_eq:NNTF \d at llarbegin \begingroup {
-        \insert at column
-        \d at llarend
-      } {
-        \__luamml_array_init_col:
-        \insert at column
-        \luamml_save:nn {} {mtd}
-        \d at llarend
-        \__luamml_array_finalize_col:w 2~
-      }
-      \do at row@strut
-    \or
-      \setbox \ar at mcellbox \vbox \@startpbox { \@nextchar }
-        \insert at pcolumn
-      \@endpbox
-      \ar at align@mcell
-      \do at row@strut
-    \or
-      \vtop \@startpbox { \@nextchar }
-        \insert at pcolumn
-      \@endpbox
-      \do at row@strut
-    \or
-      \vbox \@startpbox { \@nextchar }
-      \insert at pcolumn
-      \@endpbox
-      \do at row@strut
-    \fi
-  }
-  \prepnext at tok
-}
-
-\IfPackageAtLeastTF {array} {2023/12/11} {
-  \cs_set:Npn \endarray {
-    \tbl_crcr:n{endarray}
-    \__luamml_array_save_array:
-    \egroup
-    \UseTaggingSocket{tbl/finalize}
-    \tbl_restore_outer_cell_data:
-    \egroup
-    \mode_if_math:T { \__luamml_array_finalize_array: }
-    \@arrayright
-    \gdef \@preamble {}
-  }
-} {
-  \cs_new_eq:NN \insert at pcolumn \insert at column
-  \cs_set:Npn \endarray {
-    \crcr
-    \__luamml_array_save_array:
-    \egroup
-    \egroup
-    \mode_if_math:T { \__luamml_array_finalize_array: }
-    \@arrayright
-    \gdef \@preamble {}
-  }
-}

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-kernel.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-kernel.sty	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-kernel.sty	2025-02-17 20:43:45 UTC (rev 74063)
@@ -1,52 +1,64 @@
-\ProvidesExplPackage {luamml-patches-kernel} {2024-10-30} {0.2.0}
+\ProvidesExplPackage {luamml-patches-kernel} {2025-02-17} {0.3.0}
   {Feel free to add a description here}
 
-\cs_set:Npn \mathsm at sh #1 #2 {
-  \setbox \z@ \hbox {
-    $
-    \m at th #1 {
-      #2
-    }
-    \luamml_save:nNn {mathsmash} #1 {mpadded}
-    \luamml_pdf_write:
-    $
-  }
-  \luamml_annotate:nen {2} {
-    nucleus = true,
-    core = consume_label('mathsmash', function(padded)
-      padded.height, padded.depth = 0, 0~
-    end),
-  } {
-    {}
-    \finsm at sh
-  }
-}
 
-\cs_set:Npn \mathph at nt #1 #2 {
-  \setbox \z@ = \hbox {
-    $
-    \m at th
-    #1
-    {#2}
-    \luamml_save:nNn {mathphant} #1 {mphantom}
-    $
-  }
-  \luamml_annotate:nen {1} {
-    nucleus = true,
-    core = {[0] = 'mpadded',
-      \ifh@\else
-        width = 0,
-      \fi
-      \ifv@\else
-        height = 0, depth = 0,
-      \fi
-      consume_label'mathphant',
-    }
-  } {
-    \finph at nt
-  }
-}
+\IfPackageAtLeastTF{latex-lab-testphase-math}{2025-01-24}
+ {}
+ {
+   \PackageInfo{luamml}{patching~\string\mathsm at sh}
+    \cs_set:Npn \mathsm at sh #1 #2 {
+     \setbox \z@ \hbox {
+       $
+       \m at th #1 {
+         #2
+       }
+       \luamml_save:nNn {mathsmash} #1 {mpadded}
+       \luamml_pdf_write:
+       $
+     }
+     \luamml_annotate:nen {2} {
+       nucleus = true,
+       core = consume_label('mathsmash', function(padded)
+         padded.height, padded.depth = 0, 0~
+       end),
+     } {
+       {}
+       \finsm at sh
+     }
+   }
 
+   \PackageInfo{luamml}{patching~\string\mathph at nt}
+   \cs_set:Npn \mathph at nt #1 #2 {
+     \setbox \z@ = \hbox {
+       $
+       \m at th
+       #1
+       {#2}
+       \luamml_save:nNn {mathphant} #1 {mphantom}
+       $
+     }
+     \luamml_annotate:nen {1} {
+       nucleus = true,
+       core = {[0] = 'mpadded',
+         \ifh@\else
+           width = 0,
+         \fi
+         \ifv@\else
+           height = 0, depth = 0,
+         \fi
+         consume_label'mathphant',
+       }
+     } {
+       \finph at nt
+     }
+   }
+   \IfFileLoadedT {latex-lab-math.ltx} {
+  \RequirePackage{luamml-patches-lab-math}
+   }
+ }
+
+% This is not moved to latex-lab for now. It doesn't work properly with structure elements
+% active: the content is outside of the math. 
 \@ifpackageloaded {unicode-math} {} {
   \cs_new:Npn \__luamml_kernel_define_character:Nnn #1#2#3 {
     \cs_set:cpx { \cs_to_str:N #1 ~ } {
@@ -70,7 +82,3 @@
   \__luamml_kernel_define_character:Nnn \longleftrightarrow {3} {27f7}
   \__luamml_kernel_define_character:Nnn \longmapsto {4} {27fc}
 }
-
-\IfFileLoadedT {latex-lab-math.ltx} {
-  \RequirePackage{luamml-patches-lab-math}
-}

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-lab-math.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-lab-math.sty	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-lab-math.sty	2025-02-17 20:43:45 UTC (rev 74063)
@@ -1,11 +1,17 @@
-\ProvidesExplPackage {luamml-patches-lab-math} {2024-10-30} {0.2.0}
+\ProvidesExplPackage {luamml-patches-lab-math} {2025-02-17} {0.3.0}
   {Feel free to add a description here}
 
-\AddToHook{begindocument} {
+% This definition is identical to the one in latex-lab-math.
+% The redefinition and the whole patch file can be removed in 2025-06-01
+\IfPackageAtLeastTF{latex-lab-testphase-math}{2025-01-24}
+ {}
+ {
+  \AddToHook{begindocument} {
+  \PackageInfo{luamml}{patching~\string\common at align@ending}
   \cs_set:Npn \common at align@ending {
     \math at cr
     \black@ \totwidth@
-    \__luamml_amsmath_finalize_table:n {align}
+    \UseExpandableTaggingSocket{math/luamml/mtable/finalize}{align}
     \egroup
     \ifingather@
       \restorealignstate@
@@ -16,5 +22,6 @@
       $$
     \fi
     \ignorespacesafterend
+   }
   }
 }

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-mathtools.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-mathtools.sty	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-patches-mathtools.sty	2025-02-17 20:43:45 UTC (rev 74063)
@@ -1,35 +1,38 @@
-\ProvidesExplPackage {luamml-patches-mathtools} {2024-10-26} {0.2.0}
+\ProvidesExplPackage {luamml-patches-mathtools} {2025-02-17} {0.3.0}
   {Feel free to add a description here}
-
-\RequirePackage{luamml-patches-amsmath}
-% see https://github.com/latex3/tagging-project/issues/734
-\renewcommand*\MT_mult_internal:n [1]{
- \MH_if_boolean:nF {outer_mult}{\alignedspace at left} %<-- requires amsmath 2016/11/05
-  \MT_next:
-  \bgroup
-    \Let@
-    \def\l_MT_multline_lastline_fint{0 }
-    \chardef\dspbrk at context\@ne \restore at math@cr
-    \MH_let:NwN \math at cr@@\MT_mult_mathcr_atat:w
-    \MH_let:NwN \shoveleft\MT_shoveleft:wn
-    \MH_let:NwN \shoveright\MT_shoveright:wn
-    \spread at equation
-    \MH_set_boolean_F:n {mult_firstline}
-    \MT_measure_mult:n {#1}
-    \MH_if_dim:w \l_MT_multwidth_dim<\l_MT_multline_measure_fdim
-      \MH_setlength:dn \l_MT_multwidth_dim{\l_MT_multline_measure_fdim}
-    \fi
-    \MH_set_boolean_T:n {mult_firstline}
-    \MH_if_num:w \l_MT_multline_lastline_fint=\@ne
-      \MH_let:NwN \math at cr@@ \MT_mult_firstandlast_mathcr:w
-    \MH_fi:
-    \ialign\bgroup
-      \hfil\strut@$\m at th\displaystyle{}##
-      \luamml_save:nNn {} \displaystyle {mtd}
-      $
-      \__luamml_amsmath_add_last_to_row:
-      \hfil
-      \crcr
-      \hfilneg
-      #1
+\IfPackageAtLeastTF{latex-lab-testphase-math}{2025-01-24}
+ {}
+ {
+    \RequirePackage{luamml-patches-amsmath}
+    % see https://github.com/latex3/tagging-project/issues/734
+    \renewcommand*\MT_mult_internal:n [1]{
+     \MH_if_boolean:nF {outer_mult}{\alignedspace at left} %<-- requires amsmath 2016/11/05
+      \MT_next:
+      \bgroup
+        \Let@
+        \def\l_MT_multline_lastline_fint{0 }
+        \chardef\dspbrk at context\@ne \restore at math@cr
+        \MH_let:NwN \math at cr@@\MT_mult_mathcr_atat:w
+        \MH_let:NwN \shoveleft\MT_shoveleft:wn
+        \MH_let:NwN \shoveright\MT_shoveright:wn
+        \spread at equation
+        \MH_set_boolean_F:n {mult_firstline}
+        \MT_measure_mult:n {#1}
+        \MH_if_dim:w \l_MT_multwidth_dim<\l_MT_multline_measure_fdim
+          \MH_setlength:dn \l_MT_multwidth_dim{\l_MT_multline_measure_fdim}
+        \fi
+        \MH_set_boolean_T:n {mult_firstline}
+        \MH_if_num:w \l_MT_multline_lastline_fint=\@ne
+          \MH_let:NwN \math at cr@@ \MT_mult_firstandlast_mathcr:w
+        \MH_fi:
+        \ialign\bgroup
+          \hfil\strut@$\m at th\displaystyle{}##
+          \UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd}}
+          $
+          \UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
+          \hfil
+          \crcr
+          \hfilneg
+          #1
+    }
 }

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-pdf-demo.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-pdf-demo.sty	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-pdf-demo.sty	2025-02-17 20:43:45 UTC (rev 74063)
@@ -1,5 +1,5 @@
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesExplPackage{luamml-pdf-demo}{2024-10-30}{0.2.0}{Reasonable default definitions for luamml-pdf}
+\ProvidesExplPackage{luamml-pdf-demo}{2025-02-17}{0.3.0}{Reasonable default definitions for luamml-pdf}
 
 \RequirePackage{luamml-pdf}% Loading luamml-pdf is pretty much the point
 % \RequirePackage{amsmath,array}% May come back if the patches get ported

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-pdf.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-pdf.sty	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-pdf.sty	2025-02-17 20:43:45 UTC (rev 74063)
@@ -20,7 +20,7 @@
 %% original source files, as listed above, are part of the
 %% same distribution. (The sources need not necessarily be
 %% in the same archive or directory.)
-%% Copyright (C) 2020-2024 by Marcel Krueger
+%% Copyright (C) 2020-2025 by Marcel Krueger
 %%
 %% This file may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either
@@ -31,7 +31,7 @@
 %%
 %% and version 1.3 or later is part of all distributions of
 %% LaTeX version 2005/12/01 or later.
-\ProvidesExplPackage {luamml-pdf} {2024-10-30} {0.2.0}
+\ProvidesExplPackage {luamml-pdf} {2025-02-17} {0.3.0}
   {MathML generation for L̶u̶a̶pdfLaTeX}
 \int_new:N \l__luamml_flag_int
 \int_new:N \l__luamml_pretty_int
@@ -189,6 +189,91 @@
     LUAMML_INSTRUCTION:REGISTER_MAPPING: \int_use:N #1 : #2
   }
 }
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/save/nn_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/save/nn}{1}
+   \AssignSocketPlug{tagsupport/math/luamml/save/nn}{noop}
+   \NewSocket{tagsupport/math/luamml/save/nNn}{1}
+   \AssignSocketPlug{tagsupport/math/luamml/save/nNn}{noop}
+ }
+\NewSocketPlug{tagsupport/math/luamml/save/nNn}{luamml}
+ {
+   \luamml_save:nNn #1
+ }
+\AssignSocketPlug{tagsupport/math/luamml/save/nNn}{luamml}
+\NewSocketPlug{tagsupport/math/luamml/save/nn}{luamml}
+ {
+   \luamml_save:nn #1
+ }
+\AssignSocketPlug{tagsupport/math/luamml/save/nn}{luamml}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/annotate/false_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/annotate/false}{2}
+   \NewSocketPlug{tagsupport/math/luamml/annotate/false}{default}{#2}
+   \AssignSocketPlug{tagsupport/math/luamml/annotate/false}{default}
+ }
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/array/finalize_plug_str }
+  {
+     \NewSocket{tagsupport/math/luamml/array/save}{0}
+     \NewSocket{tagsupport/math/luamml/array/finalize}{0}
+     \NewSocket{tagsupport/math/luamml/array/initcol}{0}
+     \NewSocket{tagsupport/math/luamml/array/finalizecol}{1}
+     \AssignSocketPlug{tagsupport/math/luamml/array/finalizecol}{noop}
+  }
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/finalizecol_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/finalizecol}{1}
+ }
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/innertable/save_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/innertable/save}{0}
+   \NewSocket{tagsupport/math/luamml/mtable/smallmatrix/save}{0}
+   \NewSocket{tagsupport/math/luamml/mtable/innertable/finalize}{0}
+ }
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/finalize_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/finalize}{1}
+   \AssignSocketPlug{tagsupport/math/luamml/mtable/finalize}{noop}
+ }
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/aligncol_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/aligncol}{1}
+   \AssignSocketPlug{tagsupport/math/luamml/mtable/aligncol}{noop}
+ }
+
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/tag/save_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/tag/save}{0}
+   \NewSocket{tagsupport/math/luamml/mtable/tag/set}{0}
+ }
+\str_if_exist:cF { l__socket_tagsupport/math/display/tag/begin_plug_str }
+ {
+   \NewSocket{tagsupport/math/display/tag/begin}{0}
+   \NewSocket{tagsupport/math/display/tag/end}{0}
+ }
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/hbox_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/hbox}{2}
+   \NewSocketPlug{tagsupport/math/luamml/hbox}{default}{#2}
+   \AssignSocketPlug{tagsupport/math/luamml/hbox}{default}
+ }
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/artifact_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/artifact}{0}
+ }
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/finph at nt_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/finph at nt}{2}
+   \NewSocketPlug{tagsupport/math/luamml/finph at nt}{default}{#2}
+   \AssignSocketPlug{tagsupport/math/luamml/finph at nt}{default}
+ }
+
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/finsm at sh_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/finsm at sh}{2}
+   \NewSocketPlug{tagsupport/math/luamml/finsm at sh}{default}{#2}
+   \AssignSocketPlug{tagsupport/math/luamml/finsm at sh}{default}
+ }
 \cs_new_protected:Npn \__luamml_patch_package:nn #1 #2 {
   \@ifpackageloaded {#1} {#2} {
     \hook_gput_code:nnn {package/#1/after} {luamml} {#2}

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-structelemwriter.lua
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-structelemwriter.lua	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-structelemwriter.lua	2025-02-17 20:43:45 UTC (rev 74063)
@@ -1,10 +1,19 @@
 local struct_begin = token.create'tag_struct_begin:n'
 local struct_use = token.create'tag_struct_use:n'
+local struct_use_num = token.create'tag_struct_use_num:n'
 local struct_end = token.create'tag_struct_end:'
 
 local mc_begin = token.create'tag_mc_begin:n'
 local mc_end = token.create'tag_mc_end:'
 
+local catlatex       = luatexbase.registernumber("catcodetable at latex")
+
+ltx = ltx or {}
+ltx.__tag = ltx.__tag or {}
+ltx.__tag.struct = ltx.__tag.struct or {}
+ltx.__tag.struct.luamml = ltx.__tag.struct.luamml or {}
+ltx.__tag.struct.luamml.labels = ltx.__tag.struct.luamml.labels or {}
+
 local function escape_name(name)
   return name
 end
@@ -43,7 +52,7 @@
   local attr_name = string.format('luamml_attr_%i', attribute_counter)
   t[k] = attr_name
   tex.runtoks(function()
-    tex.sprint(string.format('\\tagpdfsetup{newattribute={%s}{/O/NSO/NS %i 0 R',
+    tex.sprint(catlatex,string.format('\\tagpdfsetup{newattribute={%s}{/O/NSO/NS %i 0 R',
         attr_name, mathml_ns_obj or get_mathml_ns_obj()))
     -- tex.sprint(string.format('\\tagpdfsetup{newattribute={%s}{/O/MathML-3',
     --     attr_name))
@@ -65,6 +74,11 @@
       return tex.sprint(struct_use, '{', tree[':struct'], '}')
     end)
   end
+  if tree[':structnum'] then
+    return tex.runtoks(function()
+      return tex.sprint(struct_use_num, '{', tree[':structnum'], '}')
+    end)
+  end
   if not tree[0] then print('ERR', require'inspect'(tree)) end
   local i = 0
   for attr, val in next, tree do if type(attr) == 'string' and not string.find(attr, ':') and attr ~= 'xmlns' then
@@ -75,10 +89,8 @@
   table.sort(attrs)
 
   if stash then
-    stash_cnt = stash_cnt + 1
-    stash = '__luamml_stashed_' .. stash_cnt
-    tree[':struct'] = stash
-    stash = ', stash, label = ' .. stash
+    tree[':structnum'] = get_ltx().tag.get_struct_num_next()
+    stash = ', stash, '
   end
 
   local attr_flag = i ~= 0 and ', attribute=' .. attributes[table.concat(attrs)]
@@ -85,11 +97,6 @@
   tex.sprint(struct_begin, '{tag=' .. tree[0] .. '/mathml')
   if stash then tex.sprint(stash) end
   if attr_flag then tex.sprint(attr_flag) end
-  if tree[':actual'] then
-    tex.sprint(', actualtext = {')
-    tex.cprint(12, tree[':actual'])
-    tex.sprint'}'
-  end
   tex.sprint'}'
   for j = 1, i do attrs[j] = nil end
 
@@ -96,7 +103,13 @@
   if tree[':nodes'] then
     local n = tree[':nodes']
     tex.runtoks(function()
-      tex.sprint{mc_begin, string.format('{tag=%s}', tree[0])}
+      if tree[':actual'] then
+       tex.sprint(mc_begin,'{tag=Span,actualtext=')
+       tex.cprint(12,tree[':actual'])
+       tex.sprint('}')
+      else
+       tex.sprint{mc_begin, string.format('{tag=%s}', tree[0])}
+      end
       -- NOTE: This will also flush all previous sprint's... That's often annoying, but in this case actually intentional.
     end)
     local mct, mcc = tex.attribute[mc_type], tex.attribute[mc_cnt]
@@ -109,7 +122,14 @@
     end)
   end
   for _, elem in ipairs(tree) do
-    if type(elem) ~= 'string' then
+    if type(elem) ~= 'string'  and not elem['tex:ignore']  then
+      if elem['intent']==':equationlabel' and ltx.__tag.struct.luamml.labels then
+        if #ltx.__tag.struct.luamml.labels > 0 then         
+         -- print("CHECK LABEL STRUCTURE: ",table.serialize(elem), table.serialize(ltx.__tag.struct.luamml.labels))
+        local num= table.remove(ltx.__tag.struct.luamml.labels,1) 
+        elem[1][#elem+1]={[':structnum']= num}
+        end
+      end 
       write_elem(elem)
     end
   end

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-table.lua
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-table.lua	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-table.lua	2025-02-17 20:43:45 UTC (rev 74063)
@@ -63,6 +63,12 @@
   last_tag = nil
 end
 
+local function store_notag(xml)
+  local mml_row = store_get_row()
+  xml.intent = ':noequationlabel'
+  table.insert(mml_row, 1, xml)  
+end
+
 local function set_row_attribute(name, value)
   local mml_row = store_get_row()
   mml_row[name] = value
@@ -105,6 +111,7 @@
   store_column = store_column,
   store_column_xml = store_column_xml,
   store_tag = store_tag,
+  store_notag = store_notag,
   set_row_attribute = set_row_attribute,
   get_table = get_table,
 }

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-tex-annotate.lua
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-tex-annotate.lua	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-tex-annotate.lua	2025-02-17 20:43:45 UTC (rev 74063)
@@ -83,6 +83,18 @@
           end
         end
       end
+      if annotation.structnum ~= nil then
+        local saved = props.mathml_filter
+        local structnum = annotation.structnum
+        function props.mathml_filter(mml, core)
+          mml[':structnum'] = structnum
+          if saved then
+            return saved(mml, core)
+          else
+            return mml, core
+          end
+        end
+      end            
     else
       tex.error'Unable to annotate nucleus of node without nucleus'
     end

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-xmlwriter.lua
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-xmlwriter.lua	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml-xmlwriter.lua	2025-02-17 20:43:45 UTC (rev 74063)
@@ -34,6 +34,10 @@
     return out .. '/>'
   end
   out = out .. '>'
+  -- Never indent the content if it's purely text.
+  if #tree == 1 and type(tree[1]) == 'string' then
+    indent = nil
+  end
   local inner_indent = indent and indent .. '  '
   local is_string
   for _, elem in ipairs(tree) do
@@ -44,7 +48,9 @@
       out = out .. escape_text(elem)
       is_string = true
     else
-      out = out .. write_elem(elem, inner_indent)
+      if not elem['tex:ignore'] then
+        out = out .. write_elem(elem, inner_indent)
+      end
       is_string = nil
     end
   end

Modified: trunk/Master/texmf-dist/tex/lualatex/luamml/luamml.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luamml/luamml.sty	2025-02-17 20:43:29 UTC (rev 74062)
+++ trunk/Master/texmf-dist/tex/lualatex/luamml/luamml.sty	2025-02-17 20:43:45 UTC (rev 74063)
@@ -20,7 +20,7 @@
 %% original source files, as listed above, are part of the
 %% same distribution. (The sources need not necessarily be
 %% in the same archive or directory.)
-%% Copyright (C) 2020-2024 by Marcel Krueger
+%% Copyright (C) 2020-2025 by Marcel Krueger
 %%
 %% This file may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either
@@ -31,7 +31,7 @@
 %%
 %% and version 1.3 or later is part of all distributions of
 %% LaTeX version 2005/12/01 or later.
-\ProvidesExplPackage {luamml} {2024-10-30} {0.2.0}
+\ProvidesExplPackage {luamml} {2025-02-17} {0.3.0}
   {Automatically generate presentational MathML from LuaTeX math expressions}
 \int_new:N \l__luamml_flag_int
 \int_new:N \l__luamml_pretty_int
@@ -113,6 +113,265 @@
 }
 
 \cs_new_eq:NN \luamml_pdf_write: \scan_stop:
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/save/nn_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/save/nn}{1}
+   \AssignSocketPlug{tagsupport/math/luamml/save/nn}{noop}
+   \NewSocket{tagsupport/math/luamml/save/nNn}{1}
+   \AssignSocketPlug{tagsupport/math/luamml/save/nNn}{noop}
+ }
+\NewSocketPlug{tagsupport/math/luamml/save/nNn}{luamml}
+ {
+   \luamml_save:nNn #1
+ }
+\AssignSocketPlug{tagsupport/math/luamml/save/nNn}{luamml}
+\NewSocketPlug{tagsupport/math/luamml/save/nn}{luamml}
+ {
+   \luamml_save:nn #1
+ }
+\AssignSocketPlug{tagsupport/math/luamml/save/nn}{luamml}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/annotate/false_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/annotate/false}{2}
+   \NewSocketPlug{tagsupport/math/luamml/annotate/false}{default}{#2}
+   \AssignSocketPlug{tagsupport/math/luamml/annotate/false}{default}
+ }
+\NewSocketPlug{tagsupport/math/luamml/annotate/false}{luamml}
+ {
+   \luamml_annotate:en { core = false }
+    {
+      #2
+    }
+ }
+\AssignSocketPlug{tagsupport/math/luamml/annotate/false}{luamml}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/array/finalize_plug_str }
+  {
+     \NewSocket{tagsupport/math/luamml/array/save}{0}
+     \NewSocket{tagsupport/math/luamml/array/finalize}{0}
+     \NewSocket{tagsupport/math/luamml/array/initcol}{0}
+     \NewSocket{tagsupport/math/luamml/array/finalizecol}{1}
+     \AssignSocketPlug{tagsupport/math/luamml/array/finalizecol}{noop}
+  }
+\AddToHook{package/array/after}{\lua_now:n { require'luamml-array' }}
+\NewSocketPlug{tagsupport/math/luamml/array/save}{luamml}
+ {
+   \__luamml_array_save_array:
+ }
+\NewSocketPlug{tagsupport/math/luamml/array/finalize}{luamml}
+ {
+   \mode_if_math:T { \__luamml_array_finalize_array: }
+ }
+\NewSocketPlug{tagsupport/math/luamml/array/initcol}{luamml}
+ {
+   \__luamml_array_init_col:
+ }
+\NewSocketPlug{tagsupport/math/luamml/array/finalizecol}{luamml}
+ {
+   \__luamml_array_finalize_col:w #1~
+ }
+\AssignSocketPlug{tagsupport/math/luamml/array/save}{luamml}
+\AssignSocketPlug{tagsupport/math/luamml/array/finalize}{luamml}
+\AssignSocketPlug{tagsupport/math/luamml/array/initcol}{luamml}
+\AssignSocketPlug{tagsupport/math/luamml/array/finalizecol}{luamml}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/finalizecol_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/finalizecol}{1}
+ }
+\NewSocketPlug{tagsupport/math/luamml/mtable/finalizecol}{luamml}
+ {
+   \use:c{__luamml_amsmath_add_#1_to_row:}
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/finalizecol}{luamml}
+
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/innertable/save_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/innertable/save}{0}
+   \NewSocket{tagsupport/math/luamml/mtable/smallmatrix/save}{0}
+   \NewSocket{tagsupport/math/luamml/mtable/innertable/finalize}{0}
+ }
+\NewSocketPlug{tagsupport/math/luamml/mtable/innertable/save}{luamml}
+ {
+   \__luamml_amsmath_save_inner_table:n \@currenvir
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/innertable/save}{luamml}
+\NewSocketPlug{tagsupport/math/luamml/mtable/smallmatrix/save}{luamml}
+ {
+   \__luamml_amsmath_save_smallmatrix:
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/smallmatrix/save}{luamml}
+\NewSocketPlug{tagsupport/math/luamml/mtable/innertable/finalize}{luamml}
+ {
+   \__luamml_amsmath_finalize_inner_table:
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/innertable/finalize}{luamml}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/finalize_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/finalize}{1}
+   \AssignSocketPlug{tagsupport/math/luamml/mtable/finalize}{noop}
+ }
+\NewSocketPlug{tagsupport/math/luamml/mtable/finalize}{luamml}
+ {
+   \__luamml_amsmath_finalize_table:n {#1}
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/finalize}{luamml}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/aligncol_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/aligncol}{1}
+   \AssignSocketPlug{tagsupport/math/luamml/mtable/aligncol}{noop}
+ }
+\NewSocketPlug{tagsupport/math/luamml/mtable/aligncol}{luamml}
+ {
+   \__luamml_amsmath_set_row_columnalign:n {#1}
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/aligncol}{luamml}
+
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/mtable/tag/save_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/mtable/tag/save}{0}
+   \NewSocket{tagsupport/math/luamml/mtable/tag/set}{0}
+ }
+\NewSocketPlug{tagsupport/math/luamml/mtable/tag/save}{luamml}
+ {
+   \__luamml_amsmath_save_tag:
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/tag/save}{luamml}
+\NewSocketPlug{tagsupport/math/luamml/mtable/tag/set}{luamml}
+ {
+   \__luamml_amsmath_set_tag:
+ }
+\AssignSocketPlug{tagsupport/math/luamml/mtable/tag/set}{luamml}
+
+\str_if_exist:cF { l__socket_tagsupport/math/display/tag/begin_plug_str }
+ {
+   \NewSocket{tagsupport/math/display/tag/begin}{0}
+   \NewSocket{tagsupport/math/display/tag/end}{0}
+ }
+\clist_map_inline:nn
+  {
+    align,
+    align*,
+    alignat,
+    alignat*,
+    xalignat,
+    xalignat*,
+    %xxalignat,
+    flalign,
+    flalign*,
+    gather,
+    gather*,
+    %multline, % NO
+    %multline*, % NO
+    %equation, % NO
+    %equation*, % NO
+    %split, % NO
+  }
+  {\tl_const:cn { c__luamml_label_#1_tl}{}}
+\NewSocketPlug{tagsupport/math/display/tag/begin}{luamml}
+ {
+   \tag_mc_end:
+   \bool_lazy_and:nnTF
+    { \tl_if_exist_p:c { c__luamml_label_ \@currenvir _tl } }
+    { \int_if_odd_p:n { \int_div_truncate:nn { \l__luamml_flag_int } { 8 } } }
+    {
+      %\typeout{Stash~and~move~\@currenvir\c_space_tl Lbl}
+      \tag_struct_begin:n {tag=Lbl,stash}
+      \directlua{table.insert(ltx.__tag.struct.luamml.labels,\tag_get:n{struct_num})}
+    }
+    {
+      \tag_struct_begin:n {tag=Lbl}
+    }
+   \tag_mc_begin:n {}
+ }
+\AssignSocketPlug{tagsupport/math/display/tag/begin}{luamml}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/hbox_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/hbox}{2}
+   \NewSocketPlug{tagsupport/math/luamml/hbox}{default}{#2}
+   \AssignSocketPlug{tagsupport/math/luamml/hbox}{default}
+ }
+\NewSocketPlug{tagsupport/math/luamml/hbox}{luamml}
+ {
+   \bool_lazy_and:nnTF
+    { \mode_if_math_p: }
+    { \int_if_odd_p:n { \int_div_truncate:nn { \l__luamml_flag_int } { 8 } } }
+    {
+      \tag_struct_begin:n
+       {
+         tag=mtext,
+         stash,
+       }
+      \tag_mc_begin:n {}
+      \luamml_annotate:en
+       {
+         nucleus = true,
+         structnum=\tag_get:n{struct_num}
+       }
+       { #2 }
+      \tag_mc_end:
+      \tag_struct_end:
+    }
+    { #2 }
+  }
+\AssignSocketPlug{tagsupport/math/luamml/hbox}{luamml}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/artifact_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/artifact}{0}
+ }
+\NewSocketPlug{tagsupport/math/luamml/artifact}{luamml}
+ {
+   \int_if_odd:nT { \int_div_truncate:nn { \l__luamml_flag_int } { 8 } }
+    {
+      \tag_mc_begin:n{artifact}
+    }
+ }
+\AssignSocketPlug{tagsupport/math/luamml/artifact}{luamml}
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/finph at nt_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/finph at nt}{2}
+   \NewSocketPlug{tagsupport/math/luamml/finph at nt}{default}{#2}
+   \AssignSocketPlug{tagsupport/math/luamml/finph at nt}{default}
+ }
+\NewSocketPlug{tagsupport/math/luamml/finph at nt}{luamml}
+ {
+   \luamml_annotate:nen {1}
+    {
+     nucleus = true,
+     core =
+       {
+        [0] = 'mpadded',
+        \ifh@\else
+         width = 0,
+        \fi
+        \ifv@\else
+         height = 0, depth = 0,
+        \fi
+        consume_label'mathphant',
+      }
+    }
+    { #2 }
+ }
+\AssignSocketPlug{tagsupport/math/luamml/finph at nt}{luamml}
+
+\str_if_exist:cF { l__socket_tagsupport/math/luamml/finsm at sh_plug_str }
+ {
+   \NewSocket{tagsupport/math/luamml/finsm at sh}{2}
+   \NewSocketPlug{tagsupport/math/luamml/finsm at sh}{default}{#2}
+   \AssignSocketPlug{tagsupport/math/luamml/finsm at sh}{default}
+ }
+\NewSocketPlug{tagsupport/math/luamml/finsm at sh}{luamml}
+ {
+   \luamml_annotate:nen {2}
+    {
+     nucleus = true,
+     core =
+       consume_label('mathsmash',
+           function(padded)
+             padded.height, padded.depth = 0, 0~
+           end),
+    }
+    { #2 }
+ }
+\AssignSocketPlug{tagsupport/math/luamml/finsm at sh}{luamml}
 \cs_new_protected:Npn \__luamml_patch_package:nn #1 #2 {
   \@ifpackageloaded {#1} {#2} {
     \hook_gput_code:nnn {package/#1/after} {luamml} {#2}
@@ -127,7 +386,6 @@
 \__luamml_patch_package:n {amstext}
 \__luamml_patch_package:n {amsmath}
 \__luamml_patch_package:n {mathtools}
-\__luamml_patch_package:n {array}
 
 \endinput
 %%



More information about the tex-live-commits mailing list.