diff options
author | Karl Berry <karl@freefriends.org> | 2024-11-01 21:23:08 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2024-11-01 21:23:08 +0000 |
commit | 7c1ef55261d9d318083e5bb7b51f216a2fc62eba (patch) | |
tree | 9c65da88deb765787dc89b11356b9e66b6c464fa /Master/texmf-dist/source | |
parent | 98a2515429596389ba8b1c7bff761316a53eda7c (diff) |
latex-dev (1nov24)
git-svn-id: svn://tug.org/texlive/trunk@72738 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
17 files changed, 1244 insertions, 690 deletions
diff --git a/Master/texmf-dist/source/latex-dev/amsmath/amsmath.dtx b/Master/texmf-dist/source/latex-dev/amsmath/amsmath.dtx index 41a5c64863d..9d45cc2f9df 100644 --- a/Master/texmf-dist/source/latex-dev/amsmath/amsmath.dtx +++ b/Master/texmf-dist/source/latex-dev/amsmath/amsmath.dtx @@ -81,11 +81,11 @@ Bug reports can be opened (category \texttt{#1}) at\\% % \begin{macrocode} \DeclareRelease{}{1994-06-01}{amsmath-2018-12-01.sty} \DeclareRelease{}{2018-12-01}{amsmath-2018-12-01.sty} -\DeclareCurrentRelease{}{2019-04-01} +\DeclareCurrentRelease{}{2024-10-30} % \end{macrocode} % % \begin{macrocode} -\ProvidesPackage{amsmath}[2024/08/11 v2.17r AMS math features] +\ProvidesPackage{amsmath}[2024/10/30 v2.17s AMS math features] % \end{macrocode} % % \section{Catcode defenses} @@ -1002,6 +1002,10 @@ Foreign command \@backslashchar#1;\MessageBreak \let\DOTSI\relax \let\DOTSB\relax \let\DOTSX\relax +% \end{macrocode} +% In the definitions below, special \cs{uccode}s are used to generate macros +% with arguments delimited by catcode 12 letters as returned by \cs{meaning}. +% \begin{macrocode} {\uccode`7=`\\ \uccode`8=`m \uccode`9=`a \uccode`0=`t \uccode`!=`h \uppercase{% \gdef\math@#1#2#3#4#5#6\math@{\gtest@false\ifx 7#1\ifx 8#2% @@ -1039,6 +1043,13 @@ Foreign command \@backslashchar#1;\MessageBreak } \fi % \end{macrocode} +% \changes{v2.17s}{2024/10/30}{guard against primitive if (gh/1448)} +% \begin{macrocode} +{\uccode`7=`\\ \uccode`(=`i \uccode`)=`f + \uppercase{\gdef\testif@#1#2#3#4\testif@{% + \ifx7#1\ifx(#2\ifx)#3\@tempswafalse\fi\fi\fi} +}} +% \end{macrocode} % \begin{macrocode} \newcount\classnum@ \def\getmathch@#1.#2\getmathch@{\classnum@#1 \divide\classnum@4096 @@ -1159,11 +1170,17 @@ Foreign command \@backslashchar#1;\MessageBreak % \changes{v2.15d}{2016/06/28}{Add space token to prevent runaway % argument error} % \changes{v2.17r}{2024/06/29}{Drop \cs{protect} if present (gh/1265)} -% \begin{macrocode} - \begingroup - \def\protect{\protect}% % make it a quark - \xdef\meaning@{\@xp\stripprotect@\@let@token.........\stripprotect@. .........}% - \endgroup +% \changes{v2.17s}{2024/10/30}{skip protect testif detect primitive if (gh/1448)} +% \begin{macrocode} + \xdef\meaning@{\meaning\@let@token. .........}% + \@tempswatrue + \@xp\testif@\meaning@....\testif@ + \if@tempswa + \begingroup + \def\protect{\protect}% % make it a quark + \xdef\meaning@{\@xp\stripprotect@\@let@token.........\stripprotect@. .........}% + \endgroup + \fi % \end{macrocode} % In previous versions \verb|\long| macros were not seen by the lookahead. % That was bad as this file uses \verb|\(re)newcommand| for \verb|\implies| etc. diff --git a/Master/texmf-dist/source/latex-dev/base/doc.dtx b/Master/texmf-dist/source/latex-dev/base/doc.dtx index 4cb8dd6b1cc..a6af48b88a8 100644 --- a/Master/texmf-dist/source/latex-dev/base/doc.dtx +++ b/Master/texmf-dist/source/latex-dev/base/doc.dtx @@ -34,7 +34,7 @@ %\catcode`\<=14 %<+package|shortvrb>\NeedsTeXFormat{LaTeX2e}[1994/12/01] %<+package> -% Any rollback request before 2016-02-15 we try to fulfill with the 2016 version: +% ^^A Any rollback request before 2016-02-15 we try to fulfill with the 2016 version: %<+package>\DeclareRelease{}{1994-06-01} %<+package> {doc-2016-02-15.sty} %<+package>\DeclareRelease{v2.1g}{2016-02-15} @@ -45,7 +45,7 @@ %<+package> %<+package>\ProvidesPackage{doc} %<+shortvrb>\ProvidesPackage{shortvrb} -%<+package|shortvrb> [2024/06/29 v3.0q +%<+package|shortvrb> [2024/10/23 v3.0q %<+package|shortvrb> Standard LaTeX documentation package V3 (FMi)] %\catcode`\<=12 % diff --git a/Master/texmf-dist/source/latex-dev/base/ltcmdhooks.dtx b/Master/texmf-dist/source/latex-dev/base/ltcmdhooks.dtx index e8793817df3..0d14ebfe6bb 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltcmdhooks.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltcmdhooks.dtx @@ -20,7 +20,7 @@ %<*driver> % \fi \ProvidesFile{ltcmdhooks.dtx} - [2024/07/08 v1.0j LaTeX Kernel (Command hooks)] + [2024/10/22 v1.0j LaTeX Kernel (Command hooks)] % \iffalse % \documentclass{l3doc} @@ -68,7 +68,15 @@ % supported % for all types of commands, see section~\ref{sec:look-ahead} for % the restrictions that apply and what happens if one tries to use -% this with commands for which this is not supported.} These are: +% this with commands for which this is not supported.} +% +% However, this is only true \enquote{in theory}. In practice there +% are a number of restrictions that makes it impossible to use such +% generic command hooks in a number of cases, so please read all +% of section~\ref{sec:restrictions} to understand what may prevent +% you from using them successfully. +% +% The generic command hooks are: % \begin{description} % \item[\hook{cmd/\meta{name}/before}] % @@ -152,7 +160,55 @@ % and \TeX{} doesn't have a reliable way to see that, so some guesswork % has to be employed. % -% \subsection{Patching} +% We can do this in most cases when commands are defined using +% \cs{NewDocumentCommand} or \cs{newcommand} (with a few exceptions). +% For commands defined with \tn{def} the situation is less good. +% Common cases where the command hooks will not work are: +% \begin{itemize} +% \item +% +% Commands that use special catcode settings within their +% definition. In that case it is usually not possible to augment the +% definition (see~\ref{sec:patching}). +% +% \item +% +% If a command is defined while \cs{ExplSyntaxOn} is in force +% \textbf{and} the command contains \verb=~= characters to represent +% spaces, then it can't be patched to include the command hooks. In +% fact in some very special circumstances you might even get a +% low-level error rather than the information that the command can't +% be patched (see, for example, +% \url{https://github.com/latex3/latex2e/issues/1430}. +% +% \item +% +% Commands that have arguments as far as the user is concerned +% (e.g., \cs{section} or \cs{caption}), but are defined in a way that these +% arguments are not read by the user level command but only later +% during the processing. In that case the \texttt{after} hook +% doesn't work at all. The \text{before} hook only works with +% \cs{AddToHook} but not with \cs{AddToHookWithArguments} because the +% arguments haven't been read at that point where the hook is +% patched in. See +% section~\ref{sec:look-ahead}. +% +% +% \item +% Adding a specific generic command hook is only attempted once per +% command, thus after redefining a command such hooks will no longer +% be there and will also not being re-added, see section~\ref{sec:timing}. +% +% \end{itemize} +% All this means that you have to have a good understanding of how +% commands are defined when you attempt to make use of such hooks and +% something goes wrong. +% What can help in that case is to turn on \cs{DebugHooksOn} in which +% case you get much more (low-level) details on why something fails and +% what was tried to enable the hooks. +% +% +% \subsection{Patching}\label{sec:patching} % % The code here tries to find out if a command was defined with % \tn{newcommand} or \tn{DeclareRobustCommand} or @@ -172,7 +228,7 @@ % catcode settings are not the same as the ones at the time of command's % definition, so not always adding a hook to a command will work. % -% \subsubsection{Timing} +% \subsubsection{Timing}\label{sec:timing} % % When \cs{AddToHook} (or its \pkg{expl3} equivalent) is called with % a generic |cmd| hook, say, \hook{cmd/foo/before}, for the first time @@ -211,12 +267,14 @@ % hooks attached to them. % % One good example is the \tn{section} command. You can add something -% to the \hook{cmd/section/before} hook, but if you try to add something -% to the \hook{cmd/section/after} hook, \tn{section} will no longer -% work. That happens because the \tn{section} macro takes no argument, -% but instead calls a few internal \LaTeX{} macros to look for the -% optional and mandatory arguments. By adding code to the -% \hook{cmd/section/after} hook, you get in the way of that scanning. +% to the \hook{cmd/section/before} hook (but only with \cs{AddToHook} +% not \cs{AddToHookWithArguments}), +% but if you try to add anything to the \hook{cmd/section/after} +% hook, \tn{section} will no longer work at all. That happens because the +% \tn{section} macro takes no argument, but instead calls a few +% internal \LaTeX{} macros to look for the optional and mandatory +% arguments. By adding code to the \hook{cmd/section/after} hook, you +% get in the way of that scanning. % % In such a case, where it is known that a specific generic command % hook does not work if code is added to it, the package author can diff --git a/Master/texmf-dist/source/latex-dev/base/ltcounts.dtx b/Master/texmf-dist/source/latex-dev/base/ltcounts.dtx index 9417769d733..1d3f2024898 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltcounts.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltcounts.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltcounts.dtx} - [2024/09/20 v1.1o LaTeX Kernel (Counters)] + [2024/10/26 v1.1p LaTeX Kernel (Counters)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltcounts.dtx} @@ -310,6 +310,7 @@ % \changes{v1.1n}{2023/11/07}{Do not change \cs{the...} if already defined (gh/823)} % \changes{v1.1o}{2024/09/20}{define theHfoo (used for internal links)} % \begin{macrocode} +% \changes{v1.1p}{2024/10/26}{Fully expand counter name in theHfoo commands (gh/1508)} %</2ekernel> %<latexrelease>\IncludeInRelease{2024/11/01}{\@definecounter} %<latexrelease> {provide theHfoo commands}% @@ -319,7 +320,8 @@ \global\expandafter\let\csname cl@#1\endcsname\@empty \@addtoreset{#1}{@ckpt}% \global\expandafter\let\csname p@#1\endcsname\@empty - \expandafter\gdef\csname theH#1\endcsname{\the\value{#1}}% + \expandafter\xdef\csname theH#1\endcsname{% + \noexpand\the\noexpand\value{#1}}% % \end{macrocode} % If \cs{the\#1} is undefined or \cs{relax} we define it with the % standard definition for counters, otherwise we warn. This will @@ -360,6 +362,7 @@ % % \begin{macro}{\@addtoreset} % \changes{v1.1o}{2024/09/20}{add the parent theHfoo if a counter is reset} +% \changes{v1.1p}{2024/10/26}{Fully expand counter name in theHfoo commands (gh/1508)} % If a counter is reset when a parent counter changes it no longer has an unique value % across the document. As |\theH<counter>| should be unique % this representation is changed to include also the @@ -371,7 +374,9 @@ %<latexrelease> {provide theHfoo commands}% %<*2ekernel|latexrelease> \def\@addtoreset#1#2{\expandafter\@cons\csname cl@#2\endcsname {{#1}}% - \expandafter\gdef\csname theH#1\endcsname{\csname theH#2\endcsname.\the\value{#1}}% + \expandafter\xdef\csname theH#1\endcsname{% + \expandafter\noexpand\csname theH#2\endcsname.% + \noexpand\the\noexpand\value{#1}}% } %<latexrelease>\EndIncludeInRelease %</2ekernel|latexrelease> diff --git a/Master/texmf-dist/source/latex-dev/base/lthooks.dtx b/Master/texmf-dist/source/latex-dev/base/lthooks.dtx index 9e4450d628d..0c33c022e3b 100644 --- a/Master/texmf-dist/source/latex-dev/base/lthooks.dtx +++ b/Master/texmf-dist/source/latex-dev/base/lthooks.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{lthooks.dtx} - [2024/08/09 v1.1i LaTeX Kernel (hooks)] + [2024/10/29 v1.1k LaTeX Kernel (hooks)] % \iffalse % \documentclass{l3doc} @@ -405,11 +405,17 @@ % Removes any code labeled by \meta{label} from the \meta{hook}. % When the optional argument \meta{label} is not provided, the % \meta{default label} is used (see section~\ref{sec:default-label}). +% \end{function} % % If there is no code under the \meta{label} in the \meta{hook}, % or if the \meta{hook} does not exist, a warning is issued when % you attempt to \cs{RemoveFromHook}, and the command is ignored. -% \cs{RemoveFromHook} should be used only when you know exactly what +% \cs{RemoveFromHook}\marginpar{\raggedleft\rightskip5pt\itshape +% \textbf{Important:}\break The \cs{RemoveFromHook} command should be +% only used if one has full control over the code chunk to be removed. +% In particular it should not be used to remove code chunks from other +% packages! For this the \texttt{voids} relation is provided.} +% should be used only when you know exactly what % labels are in a hook. Typically this will be when some code gets added to a hook % by a package, then later this code is removed by that same package. % If you want to prevent the execution of code from another @@ -423,16 +429,15 @@ % The \meta{hook} and \meta{label} can be specified using the % dot-syntax to denote the current package name. % See section~\ref{sec:default-label}. -% \end{function} -% -% \medskip % -% In contrast to the \texttt{voids} relationship between two labels +% In contrast to the \texttt {voids} relationship between two labels % in a \cs{DeclareHookRule} this is a destructive operation as the % labeled code is removed from the hook data structure, whereas the % relationship setting can be undone by providing a different % relationship later. % +% \medskip +% % A useful application for this declaration inside the document body % is when one wants to temporarily add code to hooks and later remove % it again, e.g., @@ -538,7 +543,6 @@ % % % -% % \subsubsection{Hook names and default labels} % \label{sec:default-label} % @@ -894,7 +898,7 @@ % some variant thereof. Generic hooks such as \hook{file} and \hook{env} hooks are % automatically declared when code is added to them. % -% \begin{function}[EXP]{\IfHookEmptyTF} +% \begin{function}[EXP]{\IfHookEmptyTF,\IfHookEmptyT,\IfHookEmptyF} % \begin{syntax} % \cs{IfHookEmptyTF} \Arg{hook} \Arg{true code} \Arg{false code} % \end{syntax} @@ -6174,6 +6178,8 @@ } % \end{macrocode} % +% \changes{v1.1k}{2024/10/29} +% {Skip mapping over undeclared \cs{g_@@_\meta{hook}_code_prop} (gh/1513)} % \begin{macrocode} \@@_if_usable:nF {#1} { \@@_log_line:x { The~hook~is~not~declared. } } @@ -6183,7 +6189,9 @@ { #2 { The~hook~is~empty } } { \@@_log_line:x { Code~chunks: } - \prop_if_empty:cTF { g_@@_#1_code_prop } + \bool_lazy_or:nnTF + { ! \prop_if_exist_p:c { g_@@_#1_code_prop } } + { \prop_if_empty_p:c { g_@@_#1_code_prop } } { \@@_log_line_indent:x { --- } } { \prop_map_inline:cn { g_@@_#1_code_prop } @@ -6445,19 +6453,24 @@ % |#2|${}={}$\meta{label_1}\verb=|=\meta{label_2}, % and |#3|${}={}$\meta{hook} (the latter may be the argument |#1| to % \cs{@@_list_rules:nn}, or \texttt{??} if it is a default rule). +% \changes{v1.1k}{2024/10/29} +% {Skip mapping over undeclared \cs{g_@@_\meta{hook}_code_prop} (gh/1513)} % \begin{macrocode} \cs_new_protected:Npn \@@_list_rules:nn #1 #2 { - \cs_set_protected:Npn \@@_tmp:w ##1 ##2 ##3 {#2} - \prop_map_inline:cn { g_@@_#1_code_prop } + \prop_if_exist:cT { g_@@_#1_code_prop } { + \cs_set_protected:Npn \@@_tmp:w ##1 ##2 ##3 {#2} \prop_map_inline:cn { g_@@_#1_code_prop } { - \@@_if_label_case:nnnnn {##1} {####1} - { \prop_map_break: } - { \@@_list_one_rule:nnn {##1} {####1} } - { \@@_list_one_rule:nnn {####1} {##1} } - {#1} + \prop_map_inline:cn { g_@@_#1_code_prop } + { + \@@_if_label_case:nnnnn {##1} {####1} + { \prop_map_break: } + { \@@_list_one_rule:nnn {##1} {####1} } + { \@@_list_one_rule:nnn {####1} {##1} } + {#1} + } } } } @@ -7764,13 +7777,16 @@ % \end{macro} % % -% \begin{macro}[EXP]{\IfHookEmptyTF} +% \begin{macro}[EXP]{\IfHookEmptyTF,\IfHookEmptyT,\IfHookEmptyF} +% \changes{v1.1j}{2024/10/21}{Define \cs{IfHookEmptyT}, \cs{IfHookEmptyF}} % Here we avoid the overhead of \pkg{xparse}, since \cs{IfHookEmptyTF} % is used in \cs{end} (that is, every \LaTeX{} environment). As a % further optimization, use \cs{let} rather than \cs{def} to avoid one % expansion step. % \begin{macrocode} \cs_new_eq:NN \IfHookEmptyTF \hook_if_empty:nTF +\cs_new_eq:NN \IfHookEmptyT \hook_if_empty:nT +\cs_new_eq:NN \IfHookEmptyF \hook_if_empty:nF % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex-dev/base/ltmarks.dtx b/Master/texmf-dist/source/latex-dev/base/ltmarks.dtx index f71bfab9b63..f769a093240 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltmarks.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltmarks.dtx @@ -17,7 +17,7 @@ %<*driver> % \fi \ProvidesFile{ltmarks.dtx} - [2024/07/08 v1.0g LaTeX Kernel (Marks)] + [2024/10/22 v1.0h LaTeX Kernel (Marks)] % \iffalse % \documentclass{l3doc} @@ -257,7 +257,7 @@ % running headers and footers and shipout out both in one % go.\footnote{As of now that scenario is not yet officially supported.} % -% \begin{function}[EXP]{\IfMarksEqualTF,\mark_if_eq:nnnnTF,\mark_if_eq:nnnnnnTF} +% \begin{function}[EXP]{\IfMarksEqualTF,\IfMarksEqualT,\IfMarksEqualF,\mark_if_eq:nnnnTF,\mark_if_eq:nnnnnnTF} % \begin{syntax} % \cs{IfMarksEqualTF} \oarg{region} \Arg{class} \Arg{pos_1} \Arg{pos_2} \Arg{true} \Arg{false} % \cs{mark_if_eq:nnnnTF} \Arg{region} \Arg{class} \Arg{pos_1} \Arg{pos_2} \Arg{true} \Arg{false} @@ -676,7 +676,8 @@ % and adds suitable \cs{mark_insert:nn} in the two token % lists. These token lists can then be executed at the right place % to reinsert the marks, e.g., directly after the box. This is, for -% example, used by \pkg{multicol} when a short balanced +% example, going to be used\footnote{Probably not before 2025, though.} +% by \pkg{multicol} when a short balanced % \env{multicols} is returned to the galley for typesetting. % % If the \meta{source} consists of a single vertical box (plus @@ -1799,8 +1800,9 @@ % % % -% \begin{macro}[EXP]{\IfMarksEqualTF} -% We only provide a CamelCase command for the case with one region +% \begin{macro}[EXP]{\IfMarksEqualTF,\IfMarksEqualT,\IfMarksEqualF} +% \changes{v1.0h}{2024/10/21}{Define \cs{IfMarksEqualT}, \cs{IfMarksEqualF}} +% We only provide CamelCase commands for the case with one region % (optional) and one class. One could think of also providing a % version for the general case with several optional arguments, but % use cases for this are most likely rare, so not done yet. @@ -1808,6 +1810,12 @@ \NewExpandableDocumentCommand \IfMarksEqualTF {O{page}mmm} { \mark_if_eq:nnnnTF {#1}{#2}{#3}{#4} } +\NewExpandableDocumentCommand \IfMarksEqualT {O{page}mmm} { + \mark_if_eq:nnnnT {#1}{#2}{#3}{#4} +} +\NewExpandableDocumentCommand \IfMarksEqualF {O{page}mmm} { + \mark_if_eq:nnnnF {#1}{#2}{#3}{#4} +} % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex-dev/base/ltproperties.dtx b/Master/texmf-dist/source/latex-dev/base/ltproperties.dtx index 23a38c43af9..77d36a43a98 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltproperties.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltproperties.dtx @@ -30,7 +30,7 @@ %<*driver> % \fi \ProvidesFile{ltproperties.dtx} - [2024/09/25 v1.0g LaTeX Kernel (Properties)] + [2024/10/21 v1.0h LaTeX Kernel (Properties)] % \iffalse % \documentclass[full]{l3doc} @@ -363,7 +363,7 @@ % has been set with the standard \cs{label} command. % \end{function} % -% \begin{function}{\IfPropertyRecordedTF} +% \begin{function}{\IfPropertyRecordedTF,\IfPropertyRecordedT,\IfPropertyRecordedF} % \begin{syntax} % \cs{IfPropertyRecordedTF} \Arg{label} \Arg{property} \Arg{true code} \Arg{false code} % \end{syntax} @@ -805,9 +805,12 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\IfPropertyRecordedTF} +% \begin{macro}{\IfPropertyRecordedTF,\IfPropertyRecordedT,\IfPropertyRecordedF} +% \changes{v1.0h}{2024-10-21}{Define \cs{IfPropertyRecordedT}, \cs{IfPropertyRecordedF}} % \begin{macrocode} -\cs_new_eq:NN \IfPropertyRecordedTF \property_if_recorded:eeTF +\cs_new_eq:NN \IfPropertyRecordedTF \property_if_recorded:eeTF +\cs_new:Npn \IfPropertyRecordedT #1#2#3 { \property_if_recorded:eeTF {#1}{#2}{#3}{} } +\cs_new:Npn \IfPropertyRecordedF #1#2#3 { \property_if_recorded:eeTF {#1}{#2}{}{#3} } % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx b/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx index 0c9113ce938..c2e70ba6d54 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx @@ -34,7 +34,7 @@ %<*driver> % \fi \ProvidesFile{ltshipout.dtx} - [2024/02/11 v1.0n LaTeX Kernel (Shipout)] + [2024/10/22 v1.0n LaTeX Kernel (Shipout)] % \iffalse % \documentclass{l3doc} @@ -469,7 +469,7 @@ % % \begin{variable}{\PreviousTotalPages} % \begin{syntax} -% \cs{thetotalpages}/\cs{PreviousTotalPages} +% \cs{PreviousTotalPages} % \end{syntax} % Command that expands to the number of total pages from the % previous run. If there was no previous run or if used in the diff --git a/Master/texmf-dist/source/latex-dev/base/ltsockets.dtx b/Master/texmf-dist/source/latex-dev/base/ltsockets.dtx index c77c74b57f2..a977f8f6aa5 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltsockets.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltsockets.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltsockets.dtx} - [2024/06/29 v0.9a LaTeX Kernel (Sockets)] + [2024/10/27 v0.9b LaTeX Kernel (Sockets)] % \iffalse % \documentclass{l3doc} @@ -371,7 +371,7 @@ % number of inputs = 2 % available plugs = noop, plug-A, plug-B % current plug = plug-B -% definition = \protected\long macro:#1#2->\begin {quote}\sffamily +% definition = \long macro:#1#2->\begin {quote}\sffamily % foo-B: #2\textsuperscript {2}\end {quote} % \end{verbatim} % \LogSocket{foo} @@ -617,6 +617,22 @@ % \end{function} % % +% \begin{function}[EXP]{\socket_use_expandable:nw,\socket_use_expandable:n} +% \begin{syntax} +% \cs{socket_use_expandable:n} \Arg{socket-name} +% \end{syntax} +% Fully expandable variant of \cs{socket_use:n}. This can be used in macro code +% to retrieve code from sockets which need to appear in an expandable context. +% +% This usually requires the plug to only contain expandable code and should therefore +% only be used for sockets which are clearly documented to be used in an expandable context. +% This command does not print any debugging info when \cs{DebugSocketsOn} is active +% and should therefore be avoided whenever possible. +% +% For performance reasons there is no explicit check that the socket was declared! +% \end{function} +% +% % \begin{function}{\ShowSocket,\LogSocket,\socket_show:n,\socket_log:n} % \begin{syntax} % \cs{ShowSocket} \Arg{socket-name} @@ -820,6 +836,7 @@ % % % \begin{macro}{\socket_new_plug:nnn,\socket_set_plug:nnn} +% \changes{v0.9b}{2024/10/27}{Make plug definition non-protected} % % Declaring a code for a socket is just making a definition, taking % the number of arguments from the saved int. @@ -834,7 +851,7 @@ { \cs_generate_from_arg_count:cNnn { @@_#1_plug_#2:w } - \cs_new_protected:Npn + \cs_new:Npn { \int_use:c { c_@@_#1_args_int } } {#3} % \end{macrocode} @@ -862,7 +879,7 @@ { \cs_generate_from_arg_count:cNnn { @@_#1_plug_#2:w } - \cs_set_protected:Npn + \cs_set:Npn { \int_use:c { c_@@_#1_args_int } } {#3} \@@_debug_term:n @@ -942,6 +959,17 @@ % \fmi{Implement?} % \end{macro} % +% \begin{macro}{\socket_use_expandable:nw,\socket_use_expandable:n} +% \changes{v0.9b}{2024/10/27}{Added \cs{socket_use_expandable:n}} +% The same as the non-expandable code, except for the missing debug output. +% \begin{macrocode} +\cs_new:Npn \socket_use_expandable:nw #1 { + \use:c { @@_#1_plug_ \str_use:c { l_@@_#1_plug_str } :w } +} +\cs_new_eq:NN \socket_use_expandable:n \socket_use_expandable:nw % socket with no inputs +% \end{macrocode} +% \end{macro} +% % % % diff --git a/Master/texmf-dist/source/latex-dev/base/lttagging.dtx b/Master/texmf-dist/source/latex-dev/base/lttagging.dtx index 74735a37626..6b68cd0e05f 100644 --- a/Master/texmf-dist/source/latex-dev/base/lttagging.dtx +++ b/Master/texmf-dist/source/latex-dev/base/lttagging.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{lttagging.dtx} - [2024/10/11 v1.0j LaTeX Kernel (tagging support)] + [2024/10/21 v1.0k LaTeX Kernel (tagging support)] % \iffalse \documentclass{l3doc} \GetFileInfo{lttagging.dtx} @@ -78,7 +78,7 @@ % \DescribeMacro\tag_suspend:n % \DescribeMacro\tag_resume:n -% +% % The are places in code where it is import top stop any tagging % activities, e.g., when we are doing trial typesetting that it is % done several times. In such a case one must tag only the final @@ -107,46 +107,51 @@ % \DescribeMacro\UseTaggingSocket % \DescribeMacro\tag_socket_use:n % \DescribeMacro\tag_socket_use:nn -% To support tagging in packages we use sockets with names starting -% with \texttt{tagsupport/}. Usually, these sockets have exactly two -% plugs defined: -% \plug{noop} (when no tagging is requested or tagging is not wanted -% for some reason) and a second plug that enables the tagging. There -% may be more, e.g., tagging with special debugging, etc., but right -% now it is usually just on or off. -% -% Given that we sometimes have to suspend tagging, it would be fairly -% inefficient to put different plugs into these sockets whenever that -% happens. We therefore offer \cs{UseTaggingSocket} which is like -% \cs{UseSocket} except that the socket name is specified without -% \texttt{tagsupport/}, i.e., +% \DescribeMacro\tag_socket_use:nnn +% Given that we sometimes have to suspend tagging, it would be fairly +% inefficient to put different plugs into these sockets whenever that +% happens. We therefore offer \cs{UseTaggingSocket} which is like +% \cs{UseSocket} except that is expects a socket starting with +% \texttt{tagsupport/} but the socket name is specified without +% this prefix, i.e., % \begin{quote} % \verb=\UseTaggingSocket{foo}= $\to$ % \verb=\UseSocket{tagsupport/foo}= -% \end{quote} -% Beside being slightly shorter, the big advantage is that this way -% we can change \cs{UseTaggingSocket} to do nothing when tagging is -% suspended with \cs{SuspendTagging} instead of changing the plugs of -% the tagging support sockets back and forth. -% -% This means that with \cs{SuspendTagging} in force all socket -% arguments are ignored (including the case when there is a single -% one), i.e., all sockets used with \cs{UseTaggingSocket} behave as -% if the \text{noop} plug is assigned. -% -% It is possible to use the tagging support sockets with -% \cs{UseSocket} instead of \cs{UseTaggingSocket}, but in this case -% the socket remains active if \cs{SuspendTagging} is in force. There -% may be reasons for doing that, but in general we expect to always -% use \cs{UseTaggingSocket}. -% -% The L3 programming layer versions \cs{tag_socket_use:n} and -% \cs{tag_socket_use:nn} are slightly more efficient than +% \end{quote}. +% +% Beside being slightly shorter, the big advantage is that this way +% we can change \cs{UseTaggingSocket} to do nothing by switching a boolean +% instead of changing the plugs of the tagging support sockets back and forth. +% +% Usually, these sockets have (beside the default plug defined for every socket) +% one additional plug defined and directly assigned. This plug is used when +% tagging is active. +% There may be more plugs, e.g., tagging with special debugging or special behaviour +% depending on the class or PDF version etc., but right now it is usually just on or off. +% +% When tagging is suspended they all have the same predefined behaviour: +% The sockets with zero arguments do nothing. The sockets with one argument +% gobble their argument. The sockets with two arguments +% will drop their first argument and pass the second unchanged. +% +% It is possible to use the tagging support sockets with +% \cs{UseSocket} directly, but in this case the socket remains active +% if \cs{SuspendTagging} is in force. There may be reasons for doing +% that but in general we expect to always use \cs{UseTaggingSocket}. +% +% \DescribeMacro\UseExpandableTaggingSocket +% \DescribeMacro\tag_socket_use_expandable:n +% For special cases like in some \cs{halign} contexts we need a fully expandable +% version of the commend. For these cases, \cs{UseExpandableTaggingSocket} can be +% used. To allow being expandable, it does not output any debugging information +% if \cs{DebugSocketsOn} is in effect and therefore should be avoided whenever possible. +% +% The L3 programming layer versions \cs{tag_socket_use_expandable:n}, +% \cs{tag_socket_use:n}, \cs{tag_socket_use:nn}, and \cs{tag_socket_use:nnn} +% are slightly more efficient than % \cs{UseTaggingSocket} because they do not have to determine how -% many arguments the socket takes when disabling it, so in code that -% is using the L3 programming layer we recommend to use them instead -% of the CamelCase command. -% +% many arguments the socket takes when disabling it. +% % % \MaybeStop{} % @@ -156,12 +161,12 @@ % % % \begin{macro}{\tag_suspend:n,\tag_resume:n,\SuspendTagging,\ResumeTagging} -% +% % In the kernel, these commands get dummy definitions so that % they can be used without harm in packages. The real definition is % used when tagging gets enabled. % \begin{macrocode} -\cs_new_eq:NN \tag_suspend:n \use_none:n +\cs_new_eq:NN \tag_suspend:n \use_none:n \cs_new_eq:NN \tag_resume:n \use_none:n \cs_new_protected:Npn \SuspendTagging #1 { \tag_suspend:n {#1} } \cs_new_protected:Npn \ResumeTagging #1 { \tag_resume:n {#1} } @@ -170,7 +175,10 @@ % % \begin{macro}{\tag_socket_use:n, % \tag_socket_use:nn, +% \tag_socket_use:nnn, +% \tag_socket_use_expandable:n, % \UseTaggingSocket, +% \UseExpandableTaggingSocket, % } % Again this is not the final definition for the kernel; it is just % a version to get going while some parts of the kernel support are @@ -187,19 +195,21 @@ % % Dummy definitions in the kernel. % These definitions will get updated in \pkg{tagpdf}. +% The default in the kernel is just to get rid of the first argument, the second is preserved if present: +% \changes{v1.0k}{2024/10/21}{Changed behavior of two argument tagging sockets when disabled.} +% \changes{v1.0k}{2024/10/21}{Added expandable variants} % \begin{macrocode} +\cs_new:Npn \tag_socket_use_expandable:n #1 { } \cs_new_protected:Npn \tag_socket_use:n #1 { } \cs_new_protected:Npn \tag_socket_use:nn #1#2 { } -% \end{macrocode} -% The default in the kernel is just to get rid of the argument: -% \begin{macrocode} +\cs_new_protected:Npn \tag_socket_use:nnn #1#2#3 { #3 } \cs_new_protected:Npn \UseTaggingSocket #1 { \int_case:nnF { \int_use:c { c__socket_tagsupport/#1_args_int } } { 0 \prg_do_nothing: 1 \use_none:n - 2 \use_none:nn + 2 \use_ii:nn % \end{macrocode} % We do not expect tagging sockets with more than one or two % arguments, so for now we only provide those. @@ -208,15 +218,28 @@ \ERRORusetaggingsocket % that should get a proper error message } % \end{macrocode} +% The same as an expandable command: +% \begin{macrocode} +\cs_new:Npn \UseExpandableTaggingSocket #1 { + \int_case:nnF + { \int_use:c { c__socket_tagsupport/#1_args_int } } + { + 0 \prg_do_nothing: + 1 \use_none:n + 2 \use_ii:nn + } + \ERRORusetaggingsocket % that should get a proper error message +} +% \end{macrocode} % % \end{macro} % % \subsection{Tagging sockets} % This collects tagging sockets that should be generally available -% so that they can also be used even if the tagging code is not loaded. -% +% so that they can also be used even if the tagging code is not loaded. +% % \subsubsection{Tagging support for paragraph setup} -% +% % Paragraphs are tagged through the code in the para/hooks. This code is sometimes % adjusted, e.g. to produce a \enquote{flattened} paragraph or to use a different tag. % Sockets related to such code parts are collected here. @@ -225,22 +248,22 @@ % The block code needs to know if they are nested blockenvs inside % a flattened environment. For this it uses a counter. Inside some contexts, % e.g. at the begin of a minipage or a footnote this counter must be reset. -% We therefore define the counter here so that we can use it in the following -% socket. +% We therefore define the counter here so that we can use it in the following +% socket. % \begin{macrocode} \int_new:N \l__tag_block_flattened_level_int % \end{macrocode} % \end{macro} -% +% % \begin{socketdecl}{tagsupport/para/restore} % This socket restores the para related settings to their default. It % should be used in places where ``normal'' paragraph tagging must be ensured, for example -% at the begin of a footnote. +% at the begin of a footnote. % \begin{macrocode} \NewSocket{tagsupport/para/restore}{0} % \end{macrocode} % \end{socketdecl} -% +% % \begin{plugdecl}{default} % \changes{v1.0i}{2024/10/10}{Restore also paratagging (tagging/723)} % \begin{macrocode} @@ -255,7 +278,7 @@ \AssignSocketPlug{tagsupport/para/restore}{default} % \end{macrocode} % \end{plugdecl} -% +% % \begin{socketdecl}{tagsupport/para/begin,tagsupport/para/end} % These sockets are currently defined in tagpdf. They overwrite % definitions in the latex-lab-block code. There is also a simpler @@ -273,22 +296,22 @@ \NewSocket{tagsupport/recordtarget}{0} % \end{macrocode} % \end{socketdecl} -% +% % \begin{plugdecl}{kernel (tagsupport/recordtarget)} % \begin{macrocode} -% +% \NewSocketPlug{tagsupport/recordtarget}{kernel} { \tl_if_blank:VF \@currentHref { - \prop_gput:Nee - \g__tag_struct_dest_num_prop + \prop_gput:Nee + \g__tag_struct_dest_num_prop {\@currentHref} - {\tag_get:n{struct_num}} + {\tag_get:n{struct_num}} } } -\AssignSocketPlug{tagsupport/recordtarget}{kernel} -\ExplSyntaxOff +\AssignSocketPlug{tagsupport/recordtarget}{kernel} +\ExplSyntaxOff % \end{macrocode} % \end{plugdecl} % \subsubsection{Tagging sockets for toc} @@ -307,28 +330,28 @@ % \begin{socketdecl}{tagsupport/toc/starttoc/before, % tagsupport/toc/starttoc/after} % Tagging sockets for the begin and end of start of \cs{@starttoc}. -% They take one argument, the extension. +% They take one argument, the extension. % \begin{macrocode} \NewSocket{tagsupport/toc/starttoc/before}{1} \NewSocket{tagsupport/toc/starttoc/after}{1} % \end{macrocode} % \end{socketdecl} -% +% % \begin{socketdecl}{tagsupport/toc/leaders/before, % tagsupport/toc/leaders/after} % Tagging sockets to make the dot leaders an artifact. -% They do not take an argument. +% They do not take an argument. % \begin{macrocode} \NewSocket{tagsupport/toc/leaders/before}{0} \NewSocket{tagsupport/toc/leaders/after}{0} % \end{macrocode} % \end{socketdecl} -% +% % \subsubsection{Tagging support for table/tabular packages} % % The code uses a number of sockets to inject the tagging % commands. These can be easily set to a noop-plug in case the -% automated tagging is not wanted. +% automated tagging is not wanted. % % \begin{socketdecl}{tagsupport/tbl/cell/begin, % tagsupport/tbl/cell/end, @@ -463,10 +486,10 @@ % \end{socketdecl} % % \subsubsection{Tagging Support for floats} -% +% % \begin{socketdecl}{tagsupport/float/hmode/begin, % tagsupport/float/hmode/end} -% These sockets are used if the float is called in +% These sockets are used if the float is called in % hmode. % \changes{v1.0h}{2024/09/13}{Sockets for floats added} % \begin{macrocode} @@ -484,38 +507,38 @@ % \end{macrocode} % \end{socketdecl} % -% +% % \begin{socketdecl}{tagsupport/caption/begin, % tagsupport/caption/end} % These sockets are used in \cs{@makecaption}. % They open and close the \texttt{Caption} structure. -% Their default plugs assume that they are used in +% Their default plugs assume that they are used in % vmode. The argument of the begin socket is % the structure number of the parent float. If it is -% empty the current structure number is used. +% empty the current structure number is used. % \begin{macrocode} \NewSocket{tagsupport/caption/begin}{1} \NewSocket{tagsupport/caption/end}{0} % \end{macrocode} % \end{socketdecl} -% +% % \begin{socketdecl}{tagsupport/caption/label/begin, % tagsupport/caption/label/end} % These sockets are used in \cs{@makecaption} around the -% label. Their default plugs ensure that -% the label is outside the paragraph and that +% label. Their default plugs ensure that +% the label is outside the paragraph and that % the rest of the caption uses flattened para mode. If the -% caption is not in a hbox, the \texttt{para/begin} -% socket should follow to properly start the paragraph. +% caption is not in a hbox, the \texttt{para/begin} +% socket should follow to properly start the paragraph. % \begin{macrocode} \NewSocket{tagsupport/caption/label/begin}{0} -\NewSocket{tagsupport/caption/label/end}{0} +\NewSocket{tagsupport/caption/label/end}{0} % \end{macrocode} % \end{socketdecl} -% +% % \section{For lttab.dtx parked here for now} % -% +% % \begin{macrocode} %<@@=tbl> \ExplSyntaxOn @@ -536,7 +559,7 @@ % \g_@@_row_int, % \g_@@_span_tl, % \g_@@_table_cols_tl} -% +% % \cs{g_@@_row_int} holds the current row number in the table. The % value \texttt{0} means we haven't yet processed the table % preamble (or in case of longtable are just in front of the next @@ -606,14 +629,14 @@ % \subsection{Tracing/debugging} % % \begin{macro}{\DebugTablesOn,\DebugTablesOff} -% +% % \begin{macrocode} \def\DebugTablesOn{ \cs_set_eq:NN \@@_trace:n \typeout -} +} \def\DebugTablesOff{ \cs_set_eq:NN \@@_trace:n \use_none:n -} +} % \end{macrocode} % % \begin{macrocode} @@ -663,7 +686,7 @@ % % % \begin{macro}{\l_@@_tmpa_seq} -% +% % \begin{macrocode} \seq_new:N \l_@@_tmpa_seq % \end{macrocode} @@ -672,7 +695,7 @@ % % % \begin{macro}{\tbl_count_missing_cells:n} -% +% % We might have the situation that some table package has not % implemented the \cs{tbl_count_table_cols:} in which case % \cs{g_@@_table_cols_tl} would always be zero and we would get an @@ -708,7 +731,7 @@ % % % \begin{macro}{\tbl_save_outer_table_cols:} -% +% % \begin{macrocode} \cs_new_protected:Npn \tbl_save_outer_table_cols: { \tl_set_eq:NN \l_@@_saved_table_cols_tl \g_@@_table_cols_tl @@ -718,7 +741,7 @@ % % % \begin{macro}{\tbl_init_cell_data_for_table:} -% +% % \begin{macrocode} \cs_new_protected:Npn \tbl_init_cell_data_for_table: { \tl_set:No \l_@@_saved_col_tl {\int_use:N \g_@@_col_int } @@ -832,14 +855,14 @@ % % % \begin{macro}{\tbl_restore_outer_cell_data:} -% +% % \begin{macrocode} \cs_new_protected:Npn \tbl_restore_outer_cell_data: { \int_gset:Nn \g_@@_col_int { \l_@@_saved_col_tl } \int_gset:Nn \g_@@_row_int { \l_@@_saved_row_tl } \tl_gset_eq:NN \g_@@_span_tl \l_@@_saved_span_tl \tl_gset_eq:NN \g_@@_table_cols_tl \l_@@_saved_table_cols_tl - \UseTaggingSocket{tbl/restore/celldata} + \UseTaggingSocket{tbl/restore/celldata} \@@_trace:n { ==>~ restored~cell~data:~ \int_use:N \g_@@_row_int, \int_use:N \g_@@_col_int, @@ -901,7 +924,7 @@ % the macro \cs{tbl_count_missing_cells:n} is executed and % then the row is finished with a final \cs{cr}. % \begin{macrocode} -\cs_new:Npn \tbl_crcr:n #1 { +\cs_new:Npn \tbl_crcr:n #1 { \int_compare:nNnT \g_@@_col_int > 0 { \tbl_count_missing_cells:n {#1} @@ -928,7 +951,7 @@ % \changes{v1.0h}{2024/09/20}{moved \cs{@kernel@refstepcounter} into ltxref} % This is needed for \pkg{longtable} because \cs{refstepcounter} is % setting up a target when \pkg{hyperref} is loaded and we don't -% want that in \pkg{longtable}.%% +% want that in \pkg{longtable}.%% % Prevent longtable patching by hyperref until hyperref does so automatically: % \begin{macrocode} \def\hyper@nopatch@longtable{} diff --git a/Master/texmf-dist/source/latex-dev/base/lttextcomp.dtx b/Master/texmf-dist/source/latex-dev/base/lttextcomp.dtx index 7f247747d6a..1ee4a18b7a9 100644 --- a/Master/texmf-dist/source/latex-dev/base/lttextcomp.dtx +++ b/Master/texmf-dist/source/latex-dev/base/lttextcomp.dtx @@ -2357,8 +2357,8 @@ % \changes{v1.1a}{2024/01/27}{Added check file for encoding subset} % \begin{macrocode} %<*TS1check> -\Providesfile{checkencodingsubset.tex} - [2024/01/27 v0.5a Figure out safe TS1 encoding subsets] +\ProvidesFile{checkencodingsubset.tex} + [2024/10/18 v0.5b Figure out safe TS1 encoding subsets] % \end{macrocode} % % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex-dev/base/ltvers.dtx b/Master/texmf-dist/source/latex-dev/base/ltvers.dtx index 50c8b9a91fe..76a16e35281 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltvers.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltvers.dtx @@ -112,10 +112,10 @@ %</2ekernel> %<latexrelease>\edef\latexreleaseversion %<*2ekernel|latexrelease> - {2024-11-01} + {2025-06-01} %</2ekernel|latexrelease> %<*2ekernel> -\def\patch@level{-4} +\def\patch@level{0} % \end{macrocode} % % \begin{macro}{\development@branch@name} diff --git a/Master/texmf-dist/source/latex-dev/firstaid/latex2e-first-aid-for-external-files.dtx b/Master/texmf-dist/source/latex-dev/firstaid/latex2e-first-aid-for-external-files.dtx index 4f473276f08..68877bc24dc 100644 --- a/Master/texmf-dist/source/latex-dev/firstaid/latex2e-first-aid-for-external-files.dtx +++ b/Master/texmf-dist/source/latex-dev/firstaid/latex2e-first-aid-for-external-files.dtx @@ -111,8 +111,8 @@ % \end{macrocode} % % \begin{macrocode} -\def\LaTeXFirstAidDate{2024/07/05} -\def\LaTeXFirstAidVersion{v1.1f} +\def\LaTeXFirstAidDate{2024/10/16} +\def\LaTeXFirstAidVersion{v1.1g} % \end{macrocode} % % \begin{macrocode} @@ -717,6 +717,34 @@ {[\@tempb][\arabic{page}][\cref@result]\thepage}{}{}{}}}% <------- five \@esphack}% } +% \end{macrocode} +% \changes{v1.1g}{2024/10/16}{update cleveref data in label hook} +% cleveref patches and redefines \cs{refstepcounter} so that a call updates its data. +% This fails if like e.g. in \pkg{longtable} the counter is stepped with +% \cs{@kernel@refstepcounter}. We therefore move the data setup into the label hook. +% As the hook is in a group we have to smuggle the data out of it. +% \url{https://tex.stackexchange.com/a/722909/2388} and issue \#1393 +% \begin{macrocode} + \newcommand\firstaid@cref@smugglelabel{\let\cref@currentlabel\cref@gcurrentlabel@temp} + \newcommand\firstaid@cref@updatelabeldata[1]{% + \cref@constructprefix{#1}{\cref@result}% + \@ifundefined{cref@#1@alias}% + {\def\@tempa{#1}}% + {\def\@tempa{\csname cref@#1@alias\endcsname}}% + \protected@xdef\cref@gcurrentlabel@temp{% + [\@tempa][\arabic{#1}][\cref@result]% + \csname p@#1\endcsname\csname the#1\endcsname}% + \aftergroup\firstaid@cref@smugglelabel + } +% \end{macrocode} +% we test if \cs{@currentcounter} is empty for unnumbered sections +% \begin{macrocode} + \AddToHook{label}[firstaid/cleveref] + {\ifx + \@currentcounter\@empty + \else + \firstaid@cref@updatelabeldata{\@currentcounter} + \fi} }% } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-firstaid.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-firstaid.dtx index 083cfcdc40b..118baccd797 100644 --- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-firstaid.dtx +++ b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-firstaid.dtx @@ -16,8 +16,8 @@ % % for those people who are interested or want to report an issue. % -\def\ltlabfirstaiddate{2024-10-04} -\def\ltlabfirstaidversion{0.85g} +\def\ltlabfirstaiddate{2024-10-16} +\def\ltlabfirstaidversion{0.85h} %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -125,6 +125,7 @@ \AddToHook{package/amsthm/after}[latex-lab-testphase-firstaid/amsthm] {\tag_if_active:T{\@@_firstaid_amsthm:}} % \end{macrocode} +% \changes{v0.85h}{2024/10/16}{moved Caption tag into \@begintheorem, tagging issue\#733} % \begin{macrocode} \cs_new_protected:Npn \@@_firstaid_amsthm: { @@ -166,17 +167,27 @@ \def\@begintheorem##1##2[##3]{% % \end{macrocode} % We use the theorem instance. +% \changes{v0.85h}{2024/10/16}{Added pre and post skips tagging/733} % \begin{macrocode} - \UseInstance{blockenv}{theorem}{} + \UseInstance{blockenv}{theorem}{beginsep=\thm@preskip} +% \end{macrocode} +% There is no working key to set the endskip, so we set the skip directly +% similar to what amsthm is doing after the \cs{trivlist}. +% \begin{macrocode} + \skip_set:Nn\l__block_topsepadd_skip { \thm@postskip } % \end{macrocode} % While create the caption/label we disable para-tagging. % \begin{macrocode} \tagpdfparaOff \mode_leave_vertical: % \end{macrocode} -% The anchor for links +% The anchor for links. amsthm allows for unnumbered theorems so we have to test +% for an empty counter. +% \changes{v0.85h}{2024/10/16}{add test if counter is empty tagging/736} % \begin{macrocode} - \MakeLinkTarget{\l__block_thm_current_counter_tl} + \tl_if_empty:NTF \l__block_thm_current_counter_tl + {\MakeLinkTarget[theorem]{}} + {\MakeLinkTarget{\l__block_thm_current_counter_tl}} \group_begin: \normalfont \the\thm@headfont \thm@indent @@ -197,7 +208,10 @@ \@ifempty{##3} {\let\thmnote\@gobble} {\def\thmnote####1{\tag_mc_begin:n{}####1\tag_mc_end:}}% - \thm@swap\swappedhead\thmhead{##1}{##2}{##3}% + \tag_struct_begin:n{tag=Caption} + \thm@swap\swappedhead\thmhead{##1}{##2}{##3}% + \tag_mc_begin:n{}\the\thm@headpunct\tag_mc_end: + \tag_struct_end: \thmheadnl % possibly a newline. \hskip\thm@headsep \group_end: @@ -215,24 +229,17 @@ % to make tagging more easier. % \begin{macrocode} \def\thmhead@plain##1##2##3{% - \tag_struct_begin:n{tag=Caption} \thmname{##1} \thmnumber{ \@ifnotempty{##1}{~}\@upn{##2} }% - \thmnote{\pdffakespace\space{\the\thm@notefont(##3)}} - %moved for easier tagging - \tag_mc_begin:n{}\the\thm@headpunct\tag_mc_end: - \tag_struct_end: + \thmnote{\pdffakespace\space{\the\thm@notefont(##3)}} } \let\thmhead\thmhead@plain \def\swappedhead##1##2##3{% - \tag_struct_begin:n{tag=Caption} \thmnumber{##2} \thmname{\@ifnotempty{##2}{\nobreakspace}##1} \thmnote{\pdffakespace\space{\the\thm@notefont(##3)}} - \tag_mc_begin:n{}\the\thm@headpunct\tag_mc_end: - \tag_struct_end: } \let\swappedhead@plain=\swappedhead % \end{macrocode} @@ -377,7 +384,9 @@ % \subsection{cleveref} % % The cleveref package redefines \cs{@makefntext} and this means that the patches in -% the new footnote code fails. We use a hook instead +% the new footnote code fails. We use a hook instead. +% \changes{v0.85h}{2024/10/16}{Remove redefinition of refstepcounter. It no longer uses +% the hook.} % \begin{macrocode} \AddToHook{package/cleveref/after} { @@ -387,16 +396,6 @@ \protected@edef\cref@currentlabel{% [footnote][\arabic{footnote}][\cref@result]% \p@footnote\@thefnmark}} -% \end{macrocode} -% The second problem is that it redefines \cs{refstepcounter} to use an argument. -% In itself this isn't a problem but as the new definition doesn't grab the arguments -% directly it fails over the generic hook inserted at the end of the definition -% \begin{macrocode} - \RenewDocumentCommand\refstepcounter{om}{% - \IfNoValueTF{#1}% - {\refstepcounter@noarg{#2}}% - {\refstepcounter@optarg[#1]{#2}}% - }% } % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-math.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-math.dtx index e8710b60a88..94d31c817b4 100644 --- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-math.dtx +++ b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-math.dtx @@ -19,13 +19,13 @@ % for those people who are interested or want to report an issue. % % -\def\ltlabmathdate{2024-10-12} -\def\ltlabmathversion{0.6h} +\def\ltlabmathdate{2024-10-25} +\def\ltlabmathversion{0.6i} % %<*driver> \documentclass{l3doc} \EnableCrossrefs -\CodelineIndex +\CodelineIndex \usepackage{todonotes} @@ -40,7 +40,7 @@ % \title{The \texttt{latex-lab-math} code\thanks{}} % \author{Frank Mittelbach, Joseph Wright, \LaTeX{} Project} % \date{v\ltlabmathversion\ \ltlabmathdate} -% +% % \maketitle % % \newcommand\NEW[1]{\marginpar{\mbox{}\hfill\fbox{New: #1}}} @@ -77,21 +77,21 @@ % \tableofcontents % % \section{Introduction} -% \car*{Todo: update all the documentation! Both here and +% \car*{Todo: update all the documentation! Both here and % (what little there is!) in the implementation section.} % % Tagging math involves a variety of tasks that require that math is captured before the % typesetting -% \begin{itemize} -% \item When typesetting the math MC-tags and structure commands must -% be inserted at the begin and the end, and perhaps also around lines -% or other subparts of the equation. +% \begin{itemize} +% \item When typesetting the math MC-tags and structure commands must +% be inserted at the begin and the end, and perhaps also around lines +% or other subparts of the equation. % \item The source and/or a mathml-representation of the source must be available % so that it can be (perhaps after some preprocessing) be used in an associated file % or in an alternate text -% \item It must be possible to measure the math for e.g. a bbox setting. +% \item It must be possible to measure the math for, e.g., a bbox setting. % \end{itemize} -% +% % This file implements capture of all math mode material at the outer % level, i.e., a formula is captured in its entirety with inner text % blocks (possibly containing further math) absorbed as part of the @@ -101,24 +101,24 @@ %\end{verbatim} % would only result in a single capture of the tokens % ``\verb*/a \in A \text{ for all $a<5$}/''. -% +% % % \section{Math capture} \label{sec:mathcapture} -% In the current setup +% In the current setup % \begin{itemize} % \item |$|, |\(...\)| and |$$| grab (through a command in \cs{everymath}/cs{everydisplay}) % if the boolean \cs{l_@@_collected_bool} is false. % If the boolean is true they behave normally and can for example contain verbatim. -% -% \item All (registered) environments grab their body +% +% \item All (registered) environments grab their body % regardless of the state of the boolean. For -% |equation|, |equation*| and |math| this is a change as they no longer can +% |equation|, |equation*| and |math| this is a change as they no longer can % contain verbatim. -% +% % \item BUG: |\[...\]| grabs if \cs{l_@@_collected_bool} is false. If it is -% true it falls back to |equation*| and then errors because this can't find the end. -% \end{itemize} -% +% true it falls back to |equation*| and then errors because this can't find the end. +% \end{itemize} +% % \subsection{Code level interfaces} % % \begin{function}{\math_register_env:n, \math_register_env:nn} @@ -163,51 +163,52 @@ % material. % \end{itemize} % \end{function} -% +% % \section{Math tagging} -% -% The tagging code has to handle +% +% \subsection{Code requirements} +% The tagging code has to handle % \begin{itemize} -% \item the embedding into the surrounding. This means -% \begin{itemize} -% \item closing and reopening MC-chunks +% \item the embedding into the surrounding. This means +% \begin{itemize} +% \item closing and reopening MC-chunks % \item closing and reopening text/P-structures % \item handling interferences of the tagging code with penalties and spacing. % \end{itemize} % \item the actual tagging which means to do some or all of the following tasks: % \begin{itemize} % \item setup content for an associated source file -% \item setup content for an associated mathml file +% \item setup content for an associated mathml file % \item setup content for the /Alt key % \item setup content for the /ActualText key % \item setup attributes -% \item add associated files +% \item add associated files % \item add a Formula structure -% \item surround subparts (e.g. lines) with Formula sub structures +% \item surround subparts (e.g., lines) with Formula sub structures % (perhaps with their own set of additional content) -% \item surround elements of the equation with mathml structure elements +% \item surround elements of the equation with mathml structure elements % (currently only luatex with luamml) % \end{itemize} % \end{itemize} -% +% % \subsection{Inline math} -% +% % The embedding code is added through -% the sockets +% the sockets % \begin{itemize} -% \item |tagsupport/math/inline/begin| +% \item |tagsupport/math/inline/begin| % \item |tagsupport/math/inline/end| -% \end{itemize} +% \end{itemize} % The sockets simply push and pop the MC currently. Without -% tagging they use the noop-plug. -% +% tagging they use the noop-plug. +% % The actual tagging is in done through the sockets % \begin{itemize} % \item |tagsupport/math/inline/formula/begin| % This socket takes the math as argument and its code -% should output it for typesetting. +% should output it for typesetting. % It is not \emph{used} as a tagging socket as the math argument should -% not be lost without tagging, so without tagging the +% not be lost without tagging, so without tagging the % socket uses the identity plug. % The |default| plug of the socket calls these three internal sockets % for the tagging support: @@ -218,62 +219,62 @@ % \item |tagsupport/math/struct/begin| This calls \cs{tag_struct_begin:n}. % It should also write the associated files if needed. % \item |tagsupport/math/substruct/begin| this handles subparts. -% TODO: does it really make sense in inline math to have that?? +% TODO: does it really make sense in inline math to have that?? % \end{itemize} % \item |tagsupport/math/inline/formula/end| % This socket ends the formula structure(s). The |default| % plug calls these internal sockets: % \begin{itemize} % \item |tagsupport/math/substruct/end| -% \item |tagsupport/math/struct/end| +% \item |tagsupport/math/struct/end| % \end{itemize} -% \end{itemize} -% +% \end{itemize} +% % \subsection{Display math} -% +% % \textit{to be written} -% +% % \subsection{Associated Files} -% +% % The current code allows the attachment of two types of associated file to the % Formula structure: -% the \LaTeX\ source and a MathML representation. +% the \LaTeX\ source and a MathML representation. % Technically both can be attached---AF is an array -% of file references---practically there can be problems with PDF consumers: -% e.g. ngpdf used both and so showed the equation twice -% (this has been corrected in the newest version) and +% of file references-----in practice there can be problems with PDF consumers: +% e.g., ngpdf used both and so showed the equation twice +% (this has been corrected in the newest version) and % Foxit seems to see only the first AF in the array (so we attach the % mathml as first file). -% -% The \LaTeX\ source can be (and is) attached automatically. +% +% The \LaTeX\ source can be (and is) attached automatically. % It can be suppressed by an option with -% \texttt{math/tex/AF=false}, see below. -% -% The MathML is attached if the files |\jobname-mathml.html| and/or -% |\jobname-luamml-mathml.html| are found -% and if they contains a suitable MathML snippet for the current formula. +% \texttt{math/tex/AF=false}, see below. +% +% The MathML is attached if the files |\jobname-mathml.html| and/or +% |\jobname-luamml-mathml.html| are found +% and if they contains a suitable MathML snippet for the current formula. % If the files contain more than one suitable snippet (as identified by the hash) -% the first one is used. +% the first one is used. % |\jobname-luamml-mathml.html| is automatically generated (see below section~\ref{sec:luamml}) % and read after |\jobname-mathml.html|. This means that |\jobname-mathml.html| can contain -% improved versions of a formula. -% +% improved versions of a formula. +% % The MathML processing can be suppressed globally by emptying the list of % mathml files with |math/mathml/sources=|. Locally for a formula |math/mathml/AF=false| -% can be used. -% -% For a MathML representation a file with such representations must be provided. -% If the equation is numbered the numbering should be part of the MathML as +% can be used. +% +% For a MathML representation a file with such representations must be provided. +% If the equation is numbered the numbering should be part of the MathML as % the |Lbl| substructure is ignored if an MathML is used (see https://github.com/foxitsoftware/PDF_UA-2). -% -% The MathML representation is given in a special format. +% +% The MathML representation is given in a special format. % It is meant to be a valid html file % that can be viewed in a browser. % For this it can start with |<!DOCTYPE html><html>| and end with |</html>| -% It should have the extension \texttt{.html}. The \meta{mathml} content +% It should have the extension \texttt{.html}. The \meta{mathml} content % is read with special catcodes, so can contain ambersands, hashes, comment chars % and unmatched braces such as |<mo>{</mo>| -% +% % The file should contain a number of representations in this format: % \begin{quote} % |<div>| \\ @@ -287,197 +288,338 @@ % \end{quote} % The keywords |<div>|, |<h2>\mml|, |<p>|, |<math|, |</math>| |</div>| are required as % they are used to delimit the arguments by the \LaTeX{} code. -% +% % \meta{key} and \meta{source} are only used for debugging, they help to identify % the equation referred by this representation. The source should be used correctly escaped % |&| and |<| so that if gives valid html! -% -% \meta{attributes} is not required either, but can e.g. contain attributes +% +% \meta{attributes} is not required either, but can, e.g., contain attributes % to improve the display in a browser: % \begin{verbatim} % <math alttext="\mathbf{G}" class="ltx_Math" display="inline"> % \end{verbatim} % It can also contain the name space declaration: |xmlns="http://www.w3.org/1998/Math/MathML"|% % \footnote{But it is probably not needed and only blows up the PDF.} -% -% -% By default the code tries at the begin of the document -% to read a file |\jobname-mathml.html| in the |html|-format. -% The file name can be changed with |mathml/setfiles={filename1,filename2}| -% (without extension, |html| is added automatically). -% If there is a list, all files are loaded. +% +% +% By default the code tries at the begin of the document +% to read a file |\jobname-mathml.html| in the |html|-format. +% The file name can be changed with |mathml/setfiles={filename1,filename2}| +% (without extension, |html| is added automatically). +% If there is a list, all files are loaded. % If a file doesn't exist it is ignored, only an info is written to the log. -% -% Currently every MathML-snippet from a file is embedded into the PDF, -% it is not checked first if it is actually used (simply writing everything to the PDF -% is a bit easier than keeping everything in memory and also means that -% the snippets are one after the other in the PDF). -% -% As mentioned above the MathML-AF can be suppressed for the equations in a group with +% +% Currently every MathML-snippet from a file is embedded into the PDF, +% it is not checked first if it is actually used (simply writing everything to the PDF +% is a bit easier than keeping everything in memory and also means that +% the snippets are one after the other in the PDF). +% +% As mentioned above the MathML-AF can be suppressed for the equations in a group with % |math/mathml/AF=false|, or -% completely by setting |math/mathml/sources=| in the preamble. -% +% completely by setting |math/mathml/sources=| in the preamble. +% % Files embedded in a PDF can be listed in the attachments panel of a PDF viewer. % This is probably not so useful for lots of small files (but one could create -% collections), but as long as PDF editors or viewers don't offer +% collections), but as long as PDF editors or viewers don't offer % proper support to access the AF it can help so have them there. The MathML are % added by default, but the \LaTeX{} source not. This can be changed with % |viewer/pane/mathsource=true| (anywhere in the document) and |viewer/pane/mathml=false| (in the -% preamble, before the external file is read). -% -% +% preamble, before the external file is read). +% +% % \subsection{Automatic mathml creation with luamml}\label{sec:luamml} -% -% If lualatex is used, if the package \texttt{unicode-math} is used -% and if the package \texttt{luamml} is found -% then it will automatically generate the file |\jobname-luamml-mathml.html| +% +% If lualatex and the package \pkg{unicode-math} is used +% the package \texttt{luamml} is loaded and +% will automatically generate the file |\jobname-luamml-mathml.html| % with mathml representations of all math formulas. -% The generation of the file can be suppressed with |math/mathml/luamml=false|. -% If \texttt{unicode-math} is not used, -% the generation of the file can be forced -% with |math/mathml/luamml=true| or |math/mathml/luamml| but be aware that -% it is then probable that various symbols are mapped to the wrong unicode code -% points. -% The package is still quite experimental and the output should be checked. -% The |\jobname-luamml-mathml.html| file may be previewed in a browser although -% you may need to add additional css or javascript declarations -% to enable browser support for all mathml constructs. -% The file is then used in subsequent compilations and works also with -% pdflatex. +% This file is then used in subsequent compilations and works also with +% pdflatex. % +% The generation of the file can be suppressed (in the preamble) +% with |math/mathml/luamml/write=false|. % -% \subsection{Options} -% -% +% If the package \pkg{unicode-math} is not used, +% the loading of \pkg{luamml} and with it the generation of the file can be forced +% with |math/mathml/luamml/load=true| or |math/mathml/luamml/write=true| +% but be aware that it is then possible that various symbols +% are mapped to the wrong Unicode code points. +% +% The package \pkg{luamml} is still quite experimental and the output should be checked. +% The |\jobname-luamml-mathml.html| file may be previewed in a browser although +% you may need to add additional css or javascript declarations +% to enable browser support for all mathml constructs. +% +% +% \subsection{Summary of math options} +% The following options exist to make math more accessible: +% \begin{description} +% \item[ActualText] An \texttt{ActualText} can be placed on structure elements, +% but can also be added in the stream on a \texttt{BDC} marker with a \texttt{Span} +% tag (normally an independant marker without an MCID number, it is not clear yet +% if it can be used on a MC-chunk). +% The content is a text string, typically one or a few Unicode characters. +% \texttt{ActualText} is meant to replaces the content +% and should only be used on small entities, +% e.g., to define the semantic or the Unicode code point of a symbol. +% \texttt{ActualText} is not supported by all PDF reader. +% It is also unknown where it should be used at best (in a structure element, +% or on an independent Span-BDC) and what happens if it is used in more than +% one place. +% \begin{description} +% \item[enabled by default?] False +% \item[how to enable/disable] No interface yet. +% \texttt{ActualText} can only be added on the Formula structure element by +% changing the \texttt{tagsupport/math/content} or some other socket. +% For a BDC marker one can, e.g., use +% \begin{verbatim} +% \pdf_string_from_unicode:nnN{utf16/hex}{€}\l_tmpa_tl +% \pdf_bdc:ee{Span}{/ActualText\l_tmpa_tl}content\pdf_emc: +% \end{verbatim} +% There should be no pagebreak in the \meta{content} and the BDC should be correctly +% nested into tagging, so, e.g., a \cs{leavevmode} should be issued before the bdc command. +% \item[Consumer support] in part and in part buggy, needs tests \ldots +% \end{description} +% +% \item[Alt] Like \texttt{ActualText} the \texttt{Alt} key can be used on +% structure elements and on \texttt{Span} in the stream. It should contain a description +% of the content and is mainly meant for images. PDF/UA-1, +% which views math formulas as illustrations, mandates the key +% also for \texttt{Formula} structure elements. +% \begin{description} +% \item[enabled by default?] false unless PDF/UA-1 is detected, +% then it is enabled in the begindocument/end hook +% (this will reconsidered when it is clear, that +% the use of \texttt{Alt} does not shadow mathml). It can be enabled for +% all engines and PDF versions. +% \item[enable/disable] \verb+\tagpdfsetup{math/alt/use}+ (local boolean, +% so can be used on individual equations) +% \item[default value] A template text (stored in \cs{l_@@_content_template_tl}) +% starting with \texttt{LaTeX formula starts}. +% \item[user value] No interface currently provided. This needs optional arguments +% or an external setup command. +% See \url{https://github.com/latex3/tagging-project/discussions/717}. +% +% \end{description} +% +% \item[source-AF] The \LaTeX{}-source of the equation can +% be attached as an associated file with mime-type +% application/Fx-tex. The \texttt{AFRelationship} is \texttt{Source}. +% The source is embedded without expansion. This means that targets of +% references and macros are not resolved. +% The files are by default not shown in the EmbeddedFiles pane, +% this can be enabled with |viewer/pane/mathsource=true|. +% If an A-standard is used, it must be one that allows embedded files, e.g., A-4f. +% +% \begin{description} +% \item[enabled by default?] true for all engines and PDF versions +% \item[enable/disable] \verb+\tagpdfsetup{math/tex/AF}+ (local boolean, so can +% be used on individual equations) +% \item[default value] source code including dollars or environment name. +% \item[consumer support] Currently only ngpdf makes +% use of it: if there is no mathml it passes the source to mathjax. +% \end{description} +% +% \item[luamml] The following options make (with lualatex) use +% of the \pkg{luamml} package. \pkg{luamml} is currently automatically +% loaded (at the end of the preamble) if \pkg{unicode-math} has been detected. +% The loading can be forced or suppressed +% with \verb+\tagpdfsetup{math/mathml/luamml/load=true/false}+. +% +% \pkg{luamml} affects all math, locally it can be stopped with |math/mathml/ignore|, +% or by using the commands described in the package. +% +% \item[mathml-AF] A mathml representation of the equation can be attached +% to the structure. The configuration possibilities are rather complex as the +% keys have to control three different tasks: +% The \emph{generation} of the file with the mathml fragments, +% the \emph{reading} and \emph{embedding} of the mathml fragments, +% and the \emph{association} of a mathml fragment to a specific equation. +% +% \begin{description} +% \item[generation] +% With pdf\LaTeX{} mathml fragments can not be generated automatically, +% but a file with dummy fragments for every equation will be written if +% \verb+\tagpdfsetup{math/mathml/write-dummy}+ is issued in the preamble. +% +% With lua\LaTeX{} a file with mathml fragments will be created automatically +% if the package \pkg{luamml} has been loaded (see above). +% +% \item[reading and embedding] +% By default the code will read and embed +% mathml from |\jobname-mathml.html| and |\jobname-luamml-mathml.html| in this order and +% the first fragment with a new hash value will be inserted.% +% The list of sources and their order can be changed with the key +% |math/mathml/sources|, setting that to an empty value suppresses +% the loading mathml associated files completely. For efficiency reasons +% it embeds math fragments directly, there is no check yet if the fragment is +% actually used. +% +% The files are by default shown in the EmbeddedFiles pane, +% this can be disabled with |viewer/pane/mathml=false|. +% +% \item[attaching] A mathml fragment is currently +% attached as an associated file to an Formula if the hash of +% the source matches the hash of the fragment. This is not a perfect test: +% equations with the same source and so the same hash +% can have different mathml representation, e.g., +% if there are references or commands or counters in the equation. This +% will change in a feature version. +% The attachment can be suppressed locally with |math/mathml/AF=false|. +% The mathml fragment will still be embedded in the PDF! +% +% % TODO: adapt test +% \end{description} +% +% \item[mathml structure elements] +% Mathml structure elements can be used in PDF~2.0 directly. +% In PDF~1.7. one could theoretically +% use them if one declares a role mapping first, +% (this can be done with \verb+\tagpdfsetup{role/mathml-tags}+) +% which maps all to \texttt{Span}. But such a role mapping currently breaks reading, +% e.g. in Adobe, and so it is not recommended. +% +% Automatic generation of structure elements is only possible with +% lualatex. It requires that the packages \pkg{luamml} and \pkg{tagpdf} +% have been loaded. +% \begin{description} +% \item[enabled by default?] false +% \item[enable/disable] \verb+\tagpdfsetup{math/mathml/structelem}+ +% (local setting, so can be used with grouping on individual equations). +% \item[consumer support] Needs more tests. +% \end{description} +% +% \end{description} +% +% +% % \section{Known current bugs, etc.} -% \car*{New Section, now with subsections.\\ -% As indicated, these lists are probably incomplete.\\ -% Some of these have been addressed in a more recent branch.} % % \subsection{Capture/grabbing problems} -% +% % \begin{enumerate} -% \item Incorrect grabbing of |$|-math when there is also -% explicit |$|-math within a \textit{text environment} +% \item Incorrect grabbing of |$|-math when there is also +% explicit |$|-math within a \textit{text environment} % that is itself within the math that should all be grabbed. % For example, % \begin{verbatim} % $a\begin{minipage}{1cm}$b$\end{minipage}$ % \end{verbatim} % would only result in the capture of the tokens -% ``\verb*/a\begin {minipage}{1cm}/''. +% ``\verb*/a\begin {minipage}{1cm}/''. % This can be avoided by an additional brace group: % \begin{verbatim} % $a{\begin{minipage}{1cm}$b$\end{minipage}}$ -% \end{verbatim} -% +% \end{verbatim} +% % \item Similar incorrect grabbing with |$$| also. -% +% % \item The grabbing, for all the display environments (and |\) \]|), needs -% to deal with nesting: \pkg{amsmath} contains code for this. -% -% \item The math can't contain verbatim and verbatim-like commands. This is +% to deal with nesting: \pkg{amsmath} contains code for this. +% +% \item The math can't contain verbatim and verbatim-like commands. This is % nothing new for the \pkg{amsmath} environments but changes |$| and |\[\]| -% and |equation*| (see e.g. tagging-project issue \#30). -% +% and |equation*| (see, e.g., tagging-project issue \#30). +% % \item Begin and end of the math or math environment can not be hidden in commands. -% For example \verb+>{$}l<{$}+ in a tabular would lead to errors. -% Defining |\[| to fall back to |equation*| doesn't work if |equation*| is +% For example \verb+>{$}l<{$}+ in a tabular would lead to errors. +% Defining |\[| to fall back to |equation*| doesn't work if |equation*| is % a grabbing environment. -% +% % \item The behaviour of |\[...\]| is faulty. See above. -% \end{enumerate} +% \end{enumerate} % % \subsection{Fake math} -% In a number of places in \LaTeX{} math commands (mainly |$|) is used -% only for technical reason, e.g. to access a math font, to setup a symbol -% or to use \cs{vcenter}. -% +% In a number of places in \LaTeX{} math commands (mainly |$|) is used +% only for technical reason, e.g., to access a math font, to setup a symbol +% or to use \cs{vcenter}. +% % The code identifies such fake math mostly by making use of the \cs{m@th} command % where two methods are used for the automatic detection: -% +% % \begin{itemize} -% \item After grabbing math content the code checks if the content contains the token +% \item After grabbing math content the code checks if the content contains the token % \cs{m@th} and if yes it doesn't call the processor before reinserting % the content and perhaps adding tagging code. % This method requires that the math can be grabbed (e.g. that the end dollar is visible) % and that the \cs{m@th} is visible. It applies for example in \cs{@iiiparbox} where the % code from |$\vcenter| to |\m@th$| is grabbed an put back. It does not work for % example for |tabular| where the dollars and the \cs{m@th} token are spread around -% over three commands. |tabular| needs therefore manual intervention. -% +% over three commands. |tabular| needs therefore manual intervention. +% % A look in the list of usages (in \texttt{usage-of-m@th.md}) justifies this approach. % All usages are either not math at all, or related to small elements that probably -% shouldn't be grabbed and processed on their own. +% shouldn't be grabbed and processed on their own. % % \item \cs{m@th} is redefined so that it sets the boolean \cs{l_@@_collected_bool} % to true. If \cs{m@th} is used inside math that has been grabbed % this doesn't change much as the boolean is set by the grabbing anyway. For usages % outside math the benefit is not so clear: The setting avoids that in \cs{LaTeXe} % the epsilon is processed as math, but it also prevents that the content of the amsmath -% command \cs{boxed} is processed as math. +% command \cs{boxed} is processed as math. % It means that if one wants to reenable math processing inside some (fake) math % one has to do it after \cs{m@th} calls. % \end{itemize} -% -% Open problems +% +% \subsubsection{Open problems} +% % \begin{enumerate} % \item The grabbing code doesn't pass the info that it detected a \cs{m@th} token. % This means that the tagging code has to do the same check (and doesn't do this % in all cases yet). -% -% \item Commands are missing to locally disable the grabbing and processing, e.g. +% +% \item Commands are missing to locally disable the grabbing and processing, e.g., % to handle |tabular|. -% +% % \item It must be checked if setting the boolean in \cs{m@th} really makes sense -% or if commands like \cs{LaTeXe} should be handled manually. -% +% or if commands like \cs{LaTeXe} should be handled manually. +% % \end{enumerate} -% +% % \subsection{Processor} -% +% % The grabbed math is at first passed to the processor. The processor is not called -% in a measuring phase (from the amsmath \cs{ifmeasuring@}) and if the \cs{m@th} -% token is detected. +% in a measuring phase (from the amsmath \cs{ifmeasuring@}) and if the \cs{m@th} +% token is detected. % It is not quite clear what purpose the processor has. As it is a public interface % it can't be used for internal code. And typesetting happens later and the processor % can't really change this. Currently it is mostly used for debugging and messages. % If the \cs{m@th} is found the \cs{l_@@_fakemath_bool} is set, so if the code % is changed this must be preserved. -% +% % \subsection{Other problems} -% -% \begin{enumerate} -% \item +% +% \begin{enumerate} +% \item % The presence of \cs{m@th} in association with \cs{ensuremath} -% does not necessarily indicate fakemath. This is because -% wanting mathsurround to be zero is very reasonable and common, +% does not necessarily indicate fakemath. This is because +% wanting mathsurround to be zero is very reasonable and common, % \emph{even when the math is genuine} (and hence needs to be collected). -% -% TODO: this claim needs some examples. -% -% \item User-defined environments can create problems; but this area, of -% new, copied and changed environments, has not yet been developed. -% +% +% TODO: this claim needs some examples. +% +% \item User-defined environments can create problems; but this area, of +% new, copied and changed environments, has not yet been developed. +% % \car*{Joseph wrote, inter alia:\\ % My thinking [regarding] \cs{RegisterMathEnvironment}\\ % - (New) Math environments should not be created-then-patched, but only -% generated by a [(future)] dedicated command (\cs{DeclareMathEnvironment}, +% generated by a [(future)] dedicated command (\cs{DeclareMathEnvironment}, % presumably)\\ % - Math environments created with \pkg{ltcmd} [commands] should not be copied, . . .\\ % - Package authors should be able to manually set up math environments with a public boolean.} -% \end{enumerate} +% \end{enumerate} % % % \subsection{Other ToDos} % % \begin{enumerate} -% \item Add (some of) the math display commands that were \enquote{lifted from +% \item Add (some of) the math display commands that were \enquote{lifted from % plain}, e.g., \cs{displaylines} \cs{eqalign}(??). % \item The breqn packages changes catcodes and that isn't yet covered % by our mechanism. % \item \cs{intertext} is not correctly taken into account by the -% code splitting multiline math into subformulas. +% code splitting multiline math into subformulas. % \end{enumerate} % % @@ -524,7 +666,7 @@ % neatly. % \begin{macrocode} \AddToHook{begindocument/before}{ \RequirePackage { amsmath } } -% \end{macrocode} +% \end{macrocode} % % % \subsection{Data structures} @@ -532,7 +674,7 @@ % \begin{variable}{\l_@@_collected_bool} % Tracks whether math mode material has been collected, which happens inside % \pkg{amsmath} environments as well as those handled directly here. -% If true following math will not grab and/or process. +% If true following math will not grab and/or process. % See \ref{sec:mathcapture} for details. % \begin{macrocode} \bool_new:N \l_@@_collected_bool @@ -541,7 +683,7 @@ % % \begin{variable}{\l_@@_fakemath_bool} % Tracks whether math mode material has been identified as fake math during -% the grabbing phase, which happens currently if the +% the grabbing phase, which happens currently if the % grabbed contents contains the \cs{m@th} token. % % \begin{macrocode} @@ -562,7 +704,7 @@ \tl_new:N \g_@@_grabbed_math_tl % \end{macrocode} % \end{variable} -% +% % \begin{variable}{\l_@@_tmpa_tl,\l_@@_tmpa_skip,\l_@@_tmpa_str} % Temporary variables % \begin{macrocode} @@ -575,8 +717,8 @@ % \begin{variable}{\l_@@_content_alt_tl, % \l_@@_content_actual_tl, % \l_@@_content_AF_tl} -% Temporary variables to hold math content that should -% be used in actual or alt text and stored as AF. +% Temporary variables to hold math content that should +% be used in actual or alt text and stored as AF. % \begin{macrocode} \tl_new:N \l_@@_content_alt_tl \tl_new:N \l_@@_content_actual_tl @@ -585,15 +727,15 @@ \tl_new:N \l_@@_content_AF_mathml_tl % \end{macrocode} % \end{variable} -% +% % \subsection{Tagging tools} -% The following commands implement small tagging code chunks. +% The following commands implement small tagging code chunks. % This should probably be collected and moved into tagpdf later. % \begin{macro}{\__tag_tool_close_P:} % This closes a P/text-chunk, both the MC and the structure and % increases the counter manually. % \begin{macrocode} -\cs_new_protected:Npn \__tag_tool_close_P: +\cs_new_protected:Npn \__tag_tool_close_P: { \tag_if_active:T { @@ -605,14 +747,14 @@ } % \end{macrocode} % \end{macro} -% -% We add also an attribute. -% \begin{macrocode} +% +% We add also an attribute. +% \begin{macrocode} \tl_new:N\l_@@_attribute_class_tl \tagpdfsetup {role/new-attribute = {inline} {/O /Layout /Placement/Inline}, role/new-attribute = {display} {/O /Layout /Placement/Block}, - } + } % \end{macrocode} % % \subsection{Code related to AF} @@ -640,7 +782,7 @@ \tl_gset:Nn\g__tag_math_luamml_tl {0} % \end{macrocode} % \end{variable} -% +% % \begin{variable}{ % \g_@@_mathml_total_int, % \g_@@_mathml_int, @@ -650,13 +792,13 @@ % } % \cs{g_@@_mml_total_int} records the mathml fragments read in. % \cs{g_@@_mml_int} records the mathml fragments read in with a different hash. -% \cs{g_@@_AF_total_int} records the number of math structures that try to -% attach a mathml AF. +% \cs{g_@@_AF_total_int} records the number of math structures that try to +% attach a mathml AF. % \cs{g_@@_AF_found_int} records the number of math structures for which a fitting -% mathml is found. +% mathml is found. % \cs{g_@@_AF_attached_int} records the number of math structures which got a mathml fragment % (if mathml-AF are not disabled locally this should be the equal to the previous number. -% +% % \begin{macrocode} \int_new:N\g_@@_mathml_total_int \int_new:N\g_@@_mathml_int @@ -668,15 +810,15 @@ % % \begin{variable}{\l__tag_math_mathml_files_clist} % A sequence to store the file list for the mathml. -% If luatex is detected with also check the luamml file. +% We also check the luamml file. % \begin{macrocode} \clist_new:N\l__tag_math_mathml_files_clist -\clist_put_right:Ne\l__tag_math_mathml_files_clist +\clist_put_right:Ne\l__tag_math_mathml_files_clist {\c_sys_jobname_str-mathml,\c_sys_jobname_str-luamml-mathml} % \end{macrocode} % \end{variable} - -% This is the internal variant of the \cs{mml} command. +% +% This is the internal variant of the \cs{mml} command. % \begin{macro}{\@@_AF_mml:nnnn} % \begin{macrocode} \cs_new_protected:Npn \@@_AF_mml:nnnn #1 #2 #3 #4 @@ -692,22 +834,22 @@ % \end{macrocode} % a simple Desc key, take care that it is a valid string! % \begin{macrocode} - \pdfdict_put:nne {l_pdffile/Filespec} {Desc}{(mathml-#1)} + \pdfdict_put:nne {l_pdffile/Filespec} {Desc}{(mathml-#1)} \pdffile_embed_stream:nnN {#4}{mathml-#1.xml}\l_@@_tmpa_tl % \end{macrocode} -% not strictly necessary but makes the files visible in the file attachment -% page +% not strictly necessary but makes the files visible in the file attachment +% page % \begin{macrocode} \bool_if:NT \l__tag_math_mathml_pane_bool {\pdfmanagement_add:nne {Catalog/Names}{EmbeddedFiles}{\l_@@_tmpa_tl}} \tl_new:c{g_@@_mathml_#3_tl} - \tl_gset_eq:cN{g_@@_mathml_#3_tl}\l_@@_tmpa_tl + \tl_gset_eq:cN{g_@@_mathml_#3_tl}\l_@@_tmpa_tl } - } + } % \end{macrocode} % \end{macro} % -% The html reader. +% The html reader. % \begin{macrocode} \cs_new_protected:Npn \@@_AF_html_reader:w#1</h2>#2<p>#3</p>#4<p>#5</p>#6<math{ \begingroup @@ -725,36 +867,36 @@ } % \end{macrocode} % -% As with luatex we write two files we define a few constants for +% As with luatex we write two files we define a few constants for % the shared texts. -% +% % \begin{macro} % {\c_@@_mathml_write_init_tl,\l_@@_mathml_write_before_tl, -% \c_@@_mathml_write_after_tl,\c_@@_mathml_write_final_tl} +% \c_@@_mathml_write_after_tl,\c_@@_mathml_write_final_tl} % \begin{macrocode} -\tl_const:Nn \c_@@_mathml_write_init_tl +\tl_const:Nn \c_@@_mathml_write_init_tl { <!DOCTYPE~html> \iow_newline: <html> \iow_newline: } -\tl_new:N \l_@@_mathml_write_before_tl -\tl_const:Nn \c_@@_mathml_write_after_tl +\tl_new:N \l_@@_mathml_write_before_tl +\tl_const:Nn \c_@@_mathml_write_after_tl { \iow_newline: </div> \iow_newline: - } -\tl_const:Nn \c_@@_mathml_write_final_tl + } +\tl_const:Nn \c_@@_mathml_write_final_tl { </html> - } + } % \end{macrocode} % \end{macro} % \begin{socketdecl}{tagsupport/math/mathml/write/prepare} -% To prepare the hash and the starting command we use a socket, so +% To prepare the hash and the starting command we use a socket, so % that both the dummy and luamml can make use of it. % \begin{macrocode} \socket_new:nn {tagsupport/math/mathml/write/prepare}{0} @@ -768,7 +910,7 @@ \str_set:NV\l_@@_tmpa_str\l_@@_content_AF_source_tl \str_replace_all:Nnn\l_@@_tmpa_str{&}{&} \str_replace_all:Nnn\l_@@_tmpa_str{<}{<} - \tl_set:Nn \l_@@_mathml_write_before_tl + \tl_set:Nn \l_@@_mathml_write_before_tl { <div> \iow_newline: @@ -778,39 +920,62 @@ \iow_newline: <p>\l_@@_content_hash_tl </p> \iow_newline: - } + } } % \end{macrocode} % \end{plugdecl} % -% With luatex we automatically generate mathml with luamml if the package -% can be loaded and unicode-math is detected. +% With luatex we automatically generate mathml with \pkg{luamml} if the package +% can be loaded and \pkg{unicode-math} is detected. % We start the process in the begindocument/end hook % so that the reading from a previous compilation can happen before! +% +% For other engines, for future name changes +% and in case luamml is not loaded we provide +% some commands % \begin{macrocode} -\sys_if_engine_luatex:T - { - \file_if_exist:nT { luamml.sty } +\cs_new_protected:Npn\@@_provide_luamml_commands: + { + \providecommand\luamml_flag_structelem:{} + \cs_if_free:NT \luamml_structelem: { - \RequirePackage { luamml } + \cs_set_eq:NN\luamml_structelem:\luamml_flag_structelem: + } + \providecommand\luamml_flag_process:{} + \cs_if_free:NT \luamml_process: + { + \cs_set_eq:NN\luamml_process:\luamml_flag_process: + } + \providecommand\luamml_flag_ignore:{} + \cs_if_free:NT \luamml_ignore: + { + \cs_set_eq:NN\luamml_ignore:\luamml_flag_ignore: + } + } +% \end{macrocode} +% \begin{macrocode} +\sys_if_engine_luatex:TF + { % \end{macrocode} -% Temporary (!) fixes for endarray +% Temporary (!) fixes for endarray % \begin{macrocode} + \cs_new_protected:Npn \@@_correct_luamml_array_patches: + { \AddToHook{package/array/after} { - \cs_set:Npn \endarray + \cs_set:Npn \endarray { \tbl_crcr:n{endarray} \__luamml_array_save_array: \egroup \UseTaggingSocket{tbl/finalize} - \tbl_restore_outer_cell_data: + \tbl_restore_outer_cell_data: \egroup \mode_if_math:T { \__luamml_array_finalize_array: } \@arrayright \gdef \@preamble {} } - \cs_set:Npn \@classz + \cs_set:Npn \@classz { \@classx \@tempcnta \count@ @@ -881,125 +1046,198 @@ \fi } \prepnext@tok - } - } -% \end{macrocode} -% -% \begin{macrocode} - \AddToHook{begindocument/end} - { - \str_case:on \g__tag_math_luamml_tl - { - { 1 } { - \@@_luamml_activate_write: - \msg_note:nnnn { tag } - { luamml-status }{ enabled }{ create } - } - {-1 } { - \msg_note:nnnn { tag } - { luamml-status }{ disabled }{ not~create } - } - { 0 } - { - \@ifpackageloaded { unicode-math } - { - \@@_luamml_activate_write: - \msg_note:nnnn { tag } - { luamml-status }{ enabled }{ create } + } + } + } +% \end{macrocode} +% +% \begin{macrocode} + \AddToHook{begindocument/before} + { + \str_case:on \g_@@_luamml_load_tl + { + { 1 } { + \RequirePackage { luamml } + \@@_correct_luamml_array_patches: + \AddToHook{begindocument/end} + { + \@@_luamml_activate_write: + } + } + {-1 } { + \AddToHook{begindocument/end} + { + \msg_note:nnnn { tag } + { luamml-status }{ disabled }{ not~create } + } + } + { 0 } + { + \@ifpackageloaded { unicode-math } + { + \RequirePackage { luamml } + \@@_correct_luamml_array_patches: + \AddToHook{begindocument/end} + { + \@@_luamml_activate_write: } - { \msg_warning:nn { tag }{ unicode-math-missing } } - } - } + } + { \msg_warning:nn { tag }{ unicode-math-missing } } + } } + \@@_provide_luamml_commands: } } -\msg_new:nnn { tag }{ luamml-status } + { + \@@_provide_luamml_commands: + } +\msg_new:nnn { tag }{ luamml-status } { luamml~has~been~#1~and~will~#2~an~MathML~file. - } - -\msg_new:nnn { tag }{ unicode-math-missing } + } + +\msg_new:nnn { tag }{ unicode-math-missing } { The~package~unicode-math~is~missing\\ luamml~will~not~create~an~MathML~file.\\ To~avoid~this~warning~load~unicode-math~\\ or~disable~luamml~with~\\ - \tl_to_str:n{\tagpdfsetup{math/mathml/luamml=false}}\\ + \tl_to_str:n{\tagpdfsetup{math/mathml/luamml/load=false}}\\ or~force~luamml~with~\\ - \tl_to_str:n{\tagpdfsetup{math/mathml/luamml=true}} - } + \tl_to_str:n{\tagpdfsetup{math/mathml/luamml/load=true}} + } \cs_new_protected:Npn \@@_luamml_activate_write: { + \bool_if:NT \g_@@_luamml_write_bool + { % \end{macrocode} % to avoid that nothing is written in the first run, we must activate the sockets: % \begin{macrocode} - \bool_gset_true:N\g__tag_math_mathml_AF_bool - \AssignSocketPlug{tagsupport/math/struct/begin}{test-mathml} - \AssignSocketPlug{tagsupport/math/struct/end}{test-mathml} - \AssignSocketPlug{tagsupport/math/substruct/begin}{single} - \AssignSocketPlug{tagsupport/math/substruct/end}{single} - \int_set:Nn \l__luamml_pretty_int { 5 } - \RegisterFamilyMapping\symsymbols{oms} - \RegisterFamilyMapping\symletters{oml} - \AssignSocketPlug{tagsupport/math/mathml/write/prepare}{On} - \iow_new:N \g_@@_luamml_iow - \iow_open:Nn \g_@@_luamml_iow {\c_sys_jobname_str-luamml-mathml.html} - \iow_now:Ne \g_@@_luamml_iow { \c_@@_mathml_write_init_tl } - \cs_new:Npn \@@_luamml_output_hook:n ##1 - { - \tl_if_empty:NF \l_@@_mathml_write_before_tl - { - \iow_now:Ne \g_@@_luamml_iow - { - \l_@@_mathml_write_before_tl - ##1 - \c_@@_mathml_write_after_tl - } - } + \bool_gset_true:N\g__tag_math_mathml_AF_bool + \AssignSocketPlug{tagsupport/math/struct/begin}{mathml-AF} + \AssignSocketPlug{tagsupport/math/struct/end}{mathml-AF} + \AssignSocketPlug{tagsupport/math/substruct/begin}{single} + \AssignSocketPlug{tagsupport/math/substruct/end}{single} + \int_set:Nn \l__luamml_pretty_int { 7 } + \RegisterFamilyMapping\symsymbols{oms} + \RegisterFamilyMapping\symletters{oml} + \AssignSocketPlug{tagsupport/math/mathml/write/prepare}{On} + \iow_new:N \g_@@_luamml_iow + \iow_open:Nn \g_@@_luamml_iow {\c_sys_jobname_str-luamml-mathml.html} + \iow_now:Ne \g_@@_luamml_iow { \c_@@_mathml_write_init_tl } + \cs_new:Npn \@@_luamml_output_hook:n ##1 + { + \tl_if_empty:NF \l_@@_mathml_write_before_tl + { + \iow_now:Ne \g_@@_luamml_iow + { + \l_@@_mathml_write_before_tl + ##1 + \c_@@_mathml_write_after_tl + } + } + } + \__luamml_register_output_hook:N \@@_luamml_output_hook:n +% \end{macrocode} +% At the end of the document we must finish and close the file: +% \begin{macrocode} + \AddToHook{enddocument/afterlastpage} + { + \iow_now:Ne \g_@@_luamml_iow + { \c_@@_mathml_write_final_tl } + \iow_close:N \g_@@_luamml_iow + } + \msg_note:nnnn { tag } + { luamml-status }{ enabled }{ create } } - \__luamml_register_output_hook:N \@@_luamml_output_hook:n + } % \end{macrocode} -% this starts the process and set flag to 3, -% not really needed, as it is the default but set here for clarity: +% And now keys to activate/deactivate luamml feature +% \begin{variable}{\g_@@_luamml_load_tl} +% This variable will be used to suppress the loading of luamml +% altogether. % \begin{macrocode} - \luamml_flag_process: +\tl_new:N \g_@@_luamml_load_tl +\tl_gset:Nn \g_@@_luamml_load_tl {0} % \end{macrocode} -% At the end of the document we must finish and close the file: +% \end{variable} +% \begin{variable}{\g_@@_luamml_write_bool} +% This variable decides if luamml writes a mathml +% altogether. % \begin{macrocode} - \AddToHook{enddocument/afterlastpage} - { - \iow_now:Ne \g_@@_luamml_iow - { \c_@@_mathml_write_final_tl } - \iow_close:N \g_@@_luamml_iow - } - } +\bool_new:N \g_@@_luamml_write_bool +\bool_gset_true:N \g_@@_luamml_write_bool % \end{macrocode} -% And now a key to deactivate luamml +% \end{variable} +% % \begin{macrocode} - +\msg_new:nnn { tag }{ PDF-2.0-recommended } + { + The~key~#1~will~not~work~properly~with~PDF~#2.\\ + Switching~to~PDF~2.0~is~recommended. + } \keys_define:nn { __tag / setup } { - math/mathml/luamml .choice: , - math/mathml/luamml/true .code:n = {\tl_gset:Nn \g__tag_math_luamml_tl{1}}, - math/mathml/luamml/false .code:n = {\tl_gset:Nn \g__tag_math_luamml_tl{-1}}, - math/mathml/luamml .default:n = true, - math/mathml/luamml .usage:n=preamble +% \end{macrocode} +% At first a key to suppress the loading altogether +% \begin{macrocode} + math/mathml/luamml/load .choice: , + math/mathml/luamml/load/true .code:n = {\tl_gset:Nn \g_@@_luamml_load_tl{1}}, + math/mathml/luamml/load/false .code:n = {\tl_gset:Nn \g_@@_luamml_load_tl{-1}}, + math/mathml/luamml/load .default:n = true, + math/mathml/luamml/load .usage:n=preamble, +% \end{macrocode} +% A key to activate math structure elements. It shouldn't +% be issued in the preamble as luamml is not yet loaded. +% \begin{macrocode} + math/mathml/structelem .code:n = + { + \pdf_version_compare:NnT < {2.0} + { + \msg_warning:nnne { tag }{ PDF-2.0-recommended } + { math/mathml/structelem }{ \pdf_version: } + } + \AddToHook{begindocument/end}{\luamml_structelem:} + }, +% \end{macrocode} +% and a key to call the ignore flag. This should only be used locally. +% \begin{macrocode} + math/mathml/ignore .code:n = {\luamml_ignore:}, +% \end{macrocode} +% \begin{macrocode} + math/mathml/luamml/write .choice:, + math/mathml/luamml/write/true .code:n = + { + \tl_gset:Nn \g_@@_luamml_load_tl{1} + \bool_gset_true:N \g_@@_luamml_write_bool + }, + math/mathml/luamml/write/false .code:n = + { + \bool_gset_false:N \g_@@_luamml_write_bool + }, + math/mathml/luamml/write .default:n = true, + math/mathml/luamml/write .usage:n=preamble, +% \end{macrocode} +% alias keys for compatibility +% \begin{macrocode} + math/mathml/luamml .bool_gset:N = \g_@@_luamml_write_bool, + math/mathml/luamml .usage:n=preamble } % \end{macrocode} % \begin{socketdecl}{tagsupport/math/mathml/write} % This writes a html-dummy with the hash and the math content. % This should be optional, so it uses a socket that can be disabled -% +% % \begin{macrocode} \socket_new:nn {tagsupport/math/mathml/write}{0} % \end{macrocode} % \end{socketdecl} -% +% % \begin{plugdecl}{On} % \begin{macrocode} \socket_new_plug:nnn{tagsupport/math/mathml/write}{On} { - \iow_now:Ne \g_@@_writedummy_iow + \iow_now:Ne \g_@@_writedummy_iow { \l_@@_mathml_write_before_tl <math></math> @@ -1013,32 +1251,32 @@ \keys_define:nn { __tag / setup } { - math/mathml/write-dummy .code:n = + math/mathml/write-dummy .code:n = { \bool_gset_true:N \g__tag_math_mathml_AF_bool - \tl_if_exist:NF\g_@@_writedummy_iow + \tl_if_exist:NF\g_@@_writedummy_iow { \iow_new:N \g_@@_writedummy_iow - \iow_open:Nn \g_@@_writedummy_iow - { + \iow_open:Nn \g_@@_writedummy_iow + { \c_sys_jobname_str-mathml-dummy.html } \iow_now:Ne \g_@@_writedummy_iow { \c_@@_mathml_write_init_tl } - \AssignSocketPlug {tagsupport/math/mathml/write/prepare}{On} + \AssignSocketPlug {tagsupport/math/mathml/write/prepare}{On} \AssignSocketPlug {tagsupport/math/mathml/write}{On} \AddToHook{enddocument/afterlastpage} { - \iow_now:Ne \g_@@_writedummy_iow + \iow_now:Ne \g_@@_writedummy_iow { \c_@@_mathml_write_final_tl } \iow_close:N \g_@@_writedummy_iow } - } + } }, - math/mathml/write-dummy .usage:n=preamble - } + math/mathml/write-dummy .usage:n=preamble + } % \end{macrocode} % % \begin{macro}{\@@_AF_process_mathml_files:} @@ -1049,9 +1287,9 @@ \hbox_set:Nn \l_@@_tmpa_box { \pdfdict_put:nnn { l_pdffile/Filespec }{AFRelationship} { /Supplement } - \pdfdict_put:nne - { l_pdffile }{Subtype} - { \pdf_name_from_unicode_e:n{application/mathml+xml} } + \pdfdict_put:nne + { l_pdffile }{Subtype} + { \pdf_name_from_unicode_e:n{application/mathml+xml} } \char_set_catcode_other:N \# \cs_set_eq:NN\mml \@@_AF_html_reader:w \clist_map_inline:Nn \l__tag_math_mathml_files_clist @@ -1065,13 +1303,13 @@ { \typeout{Info:~mathml~file~##1~does~not~exist}%info message } - } + } } \bool_if:NT\g__tag_math_mathml_AF_bool { \typeout{Info:~Activating~mathml~support} - \AssignSocketPlug{tagsupport/math/struct/begin}{test-mathml} - \AssignSocketPlug{tagsupport/math/struct/end}{test-mathml} + \AssignSocketPlug{tagsupport/math/struct/begin}{mathml-AF} + \AssignSocketPlug{tagsupport/math/struct/end}{mathml-AF} % \end{macrocode} % mathml handling doesn't like subparts, so we disable them for now: % \begin{macrocode} @@ -1081,29 +1319,29 @@ { \iow_term:n{MathML~statistic} \iow_term:n{================} - \iow_term:e{==>~\int_use:N\g_@@_mathml_total_int\c_space_tl + \iow_term:e{==>~\int_use:N\g_@@_mathml_total_int\c_space_tl MathML~fragments~read} - \iow_term:e{==>~\int_use:N\g_@@_mathml_int\c_space_tl + \iow_term:e{==>~\int_use:N\g_@@_mathml_int\c_space_tl different~MathML~fragments} - \iow_term:e{==>~\int_use:N\g_@@_math_total_int\c_space_tl + \iow_term:e{==>~\int_use:N\g_@@_math_total_int\c_space_tl math~fragments~found} - \iow_term:e{==>~\int_use:N\g_@@_mathml_AF_found_int\c_space_tl + \iow_term:e{==>~\int_use:N\g_@@_mathml_AF_found_int\c_space_tl fitting~MathML~AF~found} - \iow_term:e{==>~\int_use:N\g_@@_mathml_AF_attached_int\c_space_tl + \iow_term:e{==>~\int_use:N\g_@@_mathml_AF_attached_int\c_space_tl MathML~AF~attached} } - } + } } -\AddToHook{begindocument}{\@@_AF_process_mathml_files:} +\AddToHook{begindocument}{\@@_AF_process_mathml_files:} % \end{macrocode} % \end{macro} -% +% % \subsection{Mathstyle detection} % In some cases we need to detect the mathstyle used in a \cs{mathchoice} -% command and to disable/enable tagging in the unused branches. +% command and to disable/enable tagging in the unused branches. % This is currently only used in the amstext command \cs{text} % but is perhaps also needed in other cases, so we create a general command. -% +% %\begin{macro}{\l_@@_mathstyle_int,\g_@@_mathchoice_int,mathstyle} % \begin{macrocode} \int_new:N \l_@@_mathstyle_int @@ -1114,12 +1352,12 @@ % For now internal, but perhaps will need a public version. % The command should be used in every branch of a \cs{mathchoice} % (with the correct mathstyle number) and with an unique label (which should -% be the same in every branch). -% \cs{g_@@_mathchoice_int} can be e.g. increased before the mathchoice and +% be the same in every branch). +% \cs{g_@@_mathchoice_int} can be, e.g., increased before the mathchoice and % then used. % \begin{macro}{\@@_tag_if_mathstyle:nn} % \begin{macrocode} -\cs_new_protected:Npn \@@_tag_if_mathstyle:nn #1 #2 +\cs_new_protected:Npn \@@_tag_if_mathstyle:nn #1 #2 %#1 refers to label %#2 is a number for the mathstyle (typically 0,2,4,6) { @@ -1128,29 +1366,50 @@ \int_compare:nNnTF { \property_ref:nn {#1}{ mathstyle} } = { #2 } { \tag_resume:n{\mathchoice} }{ \tag_suspend:n{\mathchoice} } } -\cs_generate_variant:Nn \@@_tag_if_mathstyle:nn {en} +\cs_generate_variant:Nn \@@_tag_if_mathstyle:nn {en} % \end{macrocode} % \end{macro} -% +% % \subsection{Tagging options} % \begin{macrocode} \keys_define:nn { __tag / setup } { math/mathml/sources .clist_set:N = \l__tag_math_mathml_files_clist, - math/alt/use .bool_set:N = \l__tag_math_alt_bool, + math/alt/use .bool_set:N = \l__tag_math_alt_bool, viewer/pane/mathml .bool_set:N = \l__tag_math_mathml_pane_bool, viewer/pane/mathml .initial:n = true, - viewer/pane/mathsource .bool_set:N = \l__tag_math_texsource_pane_bool, + viewer/pane/mathsource .bool_set:N = \l__tag_math_texsource_pane_bool, math/mathml/AF .bool_set:N = \l__tag_math_mathml_AF_bool, math/mathml/AF .initial:n = true, math/tex/AF .bool_set:N = \l__tag_math_texsource_AF_bool, math/tex/AF .initial:n = true - } + } +% \end{macrocode} +% alt is required for pdf/UA-1. +% TODO: l3pdfmeta should support this test. +% \begin{macrocode} +\AddToHook{begindocument/end} + { + \str_if_eq:eeT + {1} + { + \exp_last_unbraced:Ne\use_i:nn + {\GetDocumentProperties{document/pdfstandard-UA}} + \c_empty_tl\c_empty_tl + } + { + \bool_if:NF \l__tag_math_alt_bool + { + \typeout{PDF/UA-1~detected.~Enabling~alt~text~on~Formula} + } + \bool_set_true:N\l__tag_math_alt_bool + } + } % \end{macrocode} % % \subsection{Sockets} % \subsubsection{Main inline math sockets} -% +% % \begin{socketdecl} % { % tagsupport/math/inline/begin, @@ -1159,11 +1418,11 @@ % tagsupport/math/inline/formula/end, % } % The first two sockets are meant to embed inline -% math into the surrounding (so to close/reopen e.g. MC-chunks). -% The other two implement the actual formula structure. +% math into the surrounding (so to close/reopen, e.g., MC-chunks). +% The other two implement the actual formula structure. % The formula sockets are despite their naming not symmetric: -% the begin socket is issued after the math has started, while -% the end socket is after the math! +% the begin socket is issued after the math has started, while +% the end socket is after the math! % \begin{macrocode} \socket_new:nn {tagsupport/math/inline/begin}{0} \socket_new:nn {tagsupport/math/inline/end}{0} @@ -1171,8 +1430,8 @@ \socket_new:nn {tagsupport/math/inline/formula/end}{0} % \end{macrocode} %\end{socketdecl} -% -% +% +% % \begin{plugdecl}{MC} % \begin{macrocode} \socket_new_plug:nnn @@ -1182,10 +1441,10 @@ \socket_new_plug:nnn {tagsupport/math/inline/end} {MC} - {\tag_mc_begin_pop:n{}} + {\tag_mc_begin_pop:n{}} % \end{macrocode} % \end{plugdecl} -% +% % We probably will want to test different tagging recipes. % \begin{plugdecl}{default} % \begin{macrocode} @@ -1195,7 +1454,7 @@ % \end{macrocode} % \changes{v0.6g}{2024-10-02}{disable paratagging, issue \#711} % \begin{macrocode} - { \tagpdfparaOff + { \tagpdfparaOff \tag_socket_use:n{math/content} \tag_socket_use:n{math/struct/begin} % \end{macrocode} @@ -1209,15 +1468,15 @@ \socket_new_plug:nnn {tagsupport/math/inline/formula/end} {default} - { + { \socket_use:n{tagsupport/math/substruct/end} \socket_use:n{tagsupport/math/struct/end} - } + } % \end{macrocode} % \end{plugdecl} -% +% % \subsubsection{Main display math sockets} -% +% % \begin{socketdecl} % { % tagsupport/math/display/begin, @@ -1226,15 +1485,15 @@ % tagsupport/math/display/formula/end, % } % The first two sockets are meant to embed display -% math into the surrounding (so to close/reopen e.g. MC-chunks and +% math into the surrounding (so to close/reopen, e.g., MC-chunks and % P-structure). -% The other two implement the actual formula structure. +% The other two implement the actual formula structure. % The formula sockets are despite their naming not symmetric: -% the begin socket is issued after the math has started, while -% the end socket is after the math! +% the begin socket is issued after the math has started, while +% the end socket is after the math! % The socket |tagsupport/math/display/formula/begin| should similar to % the inline version not be used as tagging socket so that the argument, the math, -% is not lost. +% is not lost. % \begin{macrocode} \socket_new:nn {tagsupport/math/display/begin}{0} \socket_new:nn {tagsupport/math/display/end}{0} @@ -1253,7 +1512,7 @@ {tagsupport/math/display/end} {default} { - } + } % \end{macrocode} % \end{plugdecl} @@ -1263,25 +1522,25 @@ \socket_new_plug:nnn {tagsupport/math/display/formula/begin} {default} - { + { \tag_socket_use:n{math/content} \tag_socket_use:n{math/struct/begin} \tag_socket_use:n{math/substruct/begin} - #1 + #1 \tag_socket_use:n{math/end} } \socket_new_plug:nnn {tagsupport/math/display/formula/end} {default} - { + { \socket_use:n{tagsupport/math/substruct/end} \socket_use:n{tagsupport/math/struct/end} - } + } % \end{macrocode} % \end{plugdecl} % % \subsubsection{Internal sockets} -% +% % \begin{variable}{\l_@@_content_template_tl} % The default text used as alt or actual text. % \begin{macrocode} @@ -1295,7 +1554,7 @@ \c_space_tl \exp_not:N\end{\g_@@_grabbed_env_tl} \c_space_tl LaTeX~ formula~ ends~ - } + } % \end{macrocode} % \end{variable} @@ -1305,7 +1564,7 @@ \tl_new:N\l_@@_texsource_template_tl \tl_const:Nn\c_@@_inline_env_tl {math} \tl_set:Nn \l_@@_texsource_template_tl - { + { \tl_if_eq:NNTF\g_@@_grabbed_env_tl\c_@@_inline_env_tl { $ @@ -1316,29 +1575,29 @@ \exp_not:N\begin{\g_@@_grabbed_env_tl} \exp_not:V\g_@@_grabbed_math_tl \exp_not:N\end{\g_@@_grabbed_env_tl} - } - } + } + } % \end{macrocode} % \end{variable} -% +% % \begin{socketdecl}{tagsupport/math/content} -% The math content is stored in associated files and used for +% The math content is stored in associated files and used for % actual and alternative text. As the exact text is still % unclear we use a socket to be able to test variants. % The socket should set all four tl vars above, if needed -% to identical values. It can use the two variables +% to identical values. It can use the two variables % \cs{g_@@_grabbed_env_tl} and \cs{g_@@_grabbed_math_tl} % \begin{macrocode} \socket_new:nn {tagsupport/math/content}{0} % \end{macrocode} % \end{socketdecl} -% +% % Some default sockets to set the contents. -% TODO: think about naming convention. +% TODO: think about naming convention. % TODO: think how this should organized so that one % has options to change from the outside and so that -% there are less repetitions. +% there are less repetitions. % \begin{plugdecl}{actual+source} % \begin{macrocode} \socket_new_plug:nnn @@ -1348,17 +1607,17 @@ \tl_set:Ne\l_@@_content_actual_tl { \l_@@_content_template_tl - } - \tl_set:Ne \l_@@_content_AF_source_tl + } + \tl_set:Ne \l_@@_content_AF_source_tl { \l_@@_texsource_template_tl - } + } \tl_set:Nn \l_@@_content_AF_mathml_tl {} \tl_set:Nn \l_@@_content_alt_tl {} } % \end{macrocode} -% \end{plugdecl} -% +% \end{plugdecl} +% % \begin{plugdecl}{alt+source} % \begin{macrocode} \socket_new_plug:nnn @@ -1368,26 +1627,26 @@ \tl_set:Ne\l_@@_content_alt_tl { \l_@@_content_template_tl - } - \tl_set:Ne \l_@@_content_AF_source_tl + } + \tl_set:Ne \l_@@_content_AF_source_tl { \l_@@_texsource_template_tl - } + } \tl_set:Nn \l_@@_content_AF_mathml_tl {} \tl_set:Nn \l_@@_content_actual_tl {} } % \end{macrocode} % \end{plugdecl} % \begin{macrocode} -\socket_assign_plug:nn {tagsupport/math/content}{alt+source} +\socket_assign_plug:nn {tagsupport/math/content}{alt+source} % \end{macrocode} % % \begin{socketdecl}{tagsupport/math/struct/begin, % tagsupport/math/struct/end} -% For the main structure we use a socket too. -% This allow e.g. to create a special one for luamml -% which setups additional objects. -% The begin socket can use the two variables +% For the main structure we use a socket too. +% This allows, e.g., to create a special one for luamml +% which setups additional objects. +% The begin socket can use the two variables % \cs{g_@@_grabbed_env_tl} and \cs{g_@@_grabbed_math_tl} % \begin{macrocode} \socket_new:nn {tagsupport/math/struct/begin}{0} @@ -1402,12 +1661,22 @@ {tagsupport/math/struct/begin} {default} { - \bool_if:NTF\l__tag_math_texsource_AF_bool + \bool_if:NTF\l__tag_math_texsource_AF_bool { \tl_set_eq:NN \l_@@_content_AF_source_tmpa_tl \l_@@_content_AF_source_tl } { \tl_clear:N \l_@@_content_AF_source_tmpa_tl } + \tl_if_eq:NnTF\g_@@_grabbed_env_tl {math} + { + \tl_set:Nn\l_@@_attribute_class_tl{inline} + } + { + \tl_set:Nn\l_@@_attribute_class_tl{display} + } + \bool_if:NF\l__tag_math_alt_bool + { \tl_set:Nn \l_@@_content_alt_tl{} } \tag_struct_begin:n { tag=Formula, + attribute-class=\l_@@_attribute_class_tl, texsource = \l_@@_content_AF_source_tmpa_tl, title-o = \g_@@_grabbed_env_tl, actualtext = \l_@@_content_actual_tl, @@ -1418,19 +1687,18 @@ {tagsupport/math/struct/end} {default} { \tag_struct_end: } - -\socket_assign_plug:nn {tagsupport/math/struct/begin}{default} -\socket_assign_plug:nn {tagsupport/math/struct/end}{default} -% \end{macrocode} -% \end{plugdecl} -% -% \begin{plugdecl}{test-mathml} -% This (test-)socket tries to add a mathml-AF to formula. -% It is activated if a mathml.html has been found and loaded. -% Additionally it also sets an attribute -% (this can perhaps be done by default anyway.) -% As it disturbs the reading of the AF it currently deactivates the /Alt key, -% unless it has been reenabled with |math/alt/use=true| + +\socket_assign_plug:nn {tagsupport/math/struct/begin}{default} +\socket_assign_plug:nn {tagsupport/math/struct/end}{default} +% \end{macrocode} +% \end{plugdecl} +% +% \begin{plugdecl}{mathml-AF} +% This socket tries to add a mathml-AF to formula. +% It is activated if a mathml.html has been found and loaded. +% As it disturbs the reading of the AF +% it currently deactivates the /Alt key, +% unless it has been reenabled with |math/alt/use=true| % \begin{macrocode} \cs_generate_variant:Nn \str_mdfive_hash:n {o} \tl_new:N\l_@@_content_hash_tl @@ -1443,49 +1711,52 @@ % \begin{macrocode} \socket_new_plug:nnn {tagsupport/math/struct/begin} - {test-mathml} - { - \int_gincr:N\g_@@_math_total_int - \tl_set:Ne\l_@@_content_hash_tl - {\str_mdfive_hash:o { \l_@@_content_AF_source_tl }} - \tl_set_eq:NN\l_@@_grabbed_math_tl\g_@@_grabbed_math_tl + {mathml-AF} + { + \int_gincr:N\g_@@_math_total_int + \tl_set:Ne\l_@@_content_hash_tl + {\str_mdfive_hash:o { \l_@@_content_AF_source_tl }} + \tl_set_eq:NN\l_@@_grabbed_math_tl\g_@@_grabbed_math_tl \tl_if_eq:NnTF\g_@@_grabbed_env_tl {math} { - \tl_set:Nn\l_@@_attribute_class_tl{inline} + \tl_set:Nn\l_@@_attribute_class_tl{inline} } { \tl_set:Nn\l_@@_attribute_class_tl{display} } \bool_if:NF\l__tag_math_alt_bool - { \tl_set:Nn \l_@@_content_alt_tl{} } + { \tl_set:Nn \l_@@_content_alt_tl{} } % \end{macrocode} % debugging option. TODO: hide in debug key. % \begin{macrocode} \tl_if_exist:cTF { g_@@_mathml_ \l_@@_content_hash_tl _tl } - { - \int_gincr:N\g_@@_mathml_AF_found_int - \bool_if:NTF \l__tag_math_mathml_AF_bool - { - \int_gincr:N\g_@@_mathml_AF_attached_int - \typeout {Inserting~mathml~with~Hash~\l_@@_content_hash_tl} - } - { - \typeout {Ignoring~mathml~with~Hash~\l_@@_content_hash_tl} - } - } - { - \typeout{WARNING:~mathml~missing~for~hash~\l_@@_content_hash_tl} - } - \socket_use:n {tagsupport/math/mathml/write/prepare} - \socket_use:n {tagsupport/math/mathml/write} % write hash if request - \bool_if:NTF\l__tag_math_texsource_AF_bool + { + \int_gincr:N\g_@@_mathml_AF_found_int + \bool_if:NTF \l__tag_math_mathml_AF_bool + { + \int_gincr:N\g_@@_mathml_AF_attached_int + \typeout {Inserting~mathml~with~Hash~\l_@@_content_hash_tl} + } + { + \typeout {Ignoring~mathml~with~Hash~\l_@@_content_hash_tl} + } + } + { + \bool_if:NT \l__tag_math_mathml_AF_bool + { + \typeout {WARNING:~mathml~missing~for~hash~\l_@@_content_hash_tl} + } + } + \socket_use:n {tagsupport/math/mathml/write/prepare} + \socket_use:n {tagsupport/math/mathml/write} % write hash if request + \bool_if:NTF\l__tag_math_texsource_AF_bool { \tl_set_eq:NN \l_@@_content_AF_source_tmpa_tl \l_@@_content_AF_source_tl } - { \tl_clear:N \l_@@_content_AF_source_tmpa_tl } + { \tl_clear:N \l_@@_content_AF_source_tmpa_tl } \tag_struct_begin:n { tag=Formula, attribute-class=\l_@@_attribute_class_tl, % - AFref = + AFref = \bool_if:NT\l__tag_math_mathml_AF_bool { \cs_if_exist_use:c {g_@@_mathml_ \l_@@_content_hash_tl _tl} @@ -1500,13 +1771,13 @@ % \begin{macrocode} \socket_new_plug:nnn {tagsupport/math/struct/end} - {test-mathml} + {mathml-AF} { \tag_struct_end: - } + } % \end{macrocode} % \end{plugdecl} -% +% % \begin{socketdecl}{tagsupport/math/substruct/begin, % tagsupport/math/substruct/end} % This holds the code to handle subparts of the formula. @@ -1515,7 +1786,7 @@ \socket_new:nn {tagsupport/math/substruct/end}{0} % \end{macrocode} % \end{socketdecl} -% +% % \begin{plugdecl}{default} % \begin{macrocode} \socket_new_plug:nnn @@ -1525,16 +1796,16 @@ \socket_new_plug:nnn {tagsupport/math/substruct/end} {default} - { + { \tagmcend \if@subformulas \tagstructend \fi - } -\socket_assign_plug:nn {tagsupport/math/substruct/begin}{default} -\socket_assign_plug:nn {tagsupport/math/substruct/end}{default} -% \end{macrocode} -% \end{plugdecl} + } +\socket_assign_plug:nn {tagsupport/math/substruct/begin}{default} +\socket_assign_plug:nn {tagsupport/math/substruct/end}{default} +% \end{macrocode} +% \end{plugdecl} % \begin{plugdecl}{single} % We need an option to disable subparts as it is unclear @@ -1546,7 +1817,7 @@ { \typeout{====>subpart~splitting~deactivated} \typeout{====>grabbed~math=\meaning\g_@@_grabbed_math_tl} - \tag_mc_begin:n{} + \tag_mc_begin:n{} } \socket_new_plug:nnn {tagsupport/math/substruct/end} @@ -1554,21 +1825,21 @@ { \tag_mc_end:} % \end{macrocode} % \end{plugdecl} -% +% % \begin{socketdecl}{tagsupport/math/end} % A socket used at the end of the math (before the closing dollar(s)) -% which can e.g. set a flag for luamml. +% which can, e.g., set a flag for luamml. % \begin{macrocode} \socket_new:nn {tagsupport/math/end}{0} % \end{macrocode} % \end{socketdecl} - -% + +% % \begin{macro}{\__tag_math_disable:} % Similar to the table code we collect the plugs that should be % assigned to do nothing if we don't want tagging % \begin{macrocode} -\cs_new_protected:Npn \__tag_math_disable: +\cs_new_protected:Npn \__tag_math_disable: { \socket_assign_plug:nn {tagsupport/math/inline/begin}{noop} \socket_assign_plug:nn {tagsupport/math/inline/end}{noop} @@ -1577,16 +1848,16 @@ \socket_assign_plug:nn {tagsupport/math/display/begin}{noop} \socket_assign_plug:nn {tagsupport/math/display/end}{noop} \socket_assign_plug:nn {tagsupport/math/display/formula/begin}{identity} - \socket_assign_plug:nn {tagsupport/math/display/formula/end}{noop} - } + \socket_assign_plug:nn {tagsupport/math/display/formula/end}{noop} + } % \end{macrocode} % \end{macro} -% +% % \begin{macro}{\__tag_math_enable:} % Similar to the table code we collect the default plugs that should be % assigned if we want tagging % \begin{macrocode} -\cs_new_protected:Npn \__tag_math_enable: +\cs_new_protected:Npn \__tag_math_enable: { \socket_assign_plug:nn {tagsupport/math/inline/begin}{MC} \socket_assign_plug:nn {tagsupport/math/inline/end}{MC} @@ -1596,7 +1867,7 @@ \socket_assign_plug:nn {tagsupport/math/display/end}{default} \socket_assign_plug:nn {tagsupport/math/display/formula/begin}{default} \socket_assign_plug:nn {tagsupport/math/display/formula/end}{default} - } + } % \end{macrocode} % \end{macro} % At begin document we can activate: @@ -1667,7 +1938,7 @@ % We do not want math tagging in fakemath or when measuring, % We also do not want math tagging if tagging has been suspended. % \begin{macrocode} - \bool_lazy_any:nTF + \bool_lazy_any:nTF { {\legacy_if_p:n { measuring@ }} { \l_@@_fakemath_bool } @@ -1677,7 +1948,7 @@ #1 $ % $ } { - \tag_socket_use:n {math/inline/begin} %end P-MC + \tag_socket_use:n {math/inline/begin} %end P-MC % \end{macrocode} % We do no use a tagging socket here, so that the argument (the % math) is not lost, tagging-project issue 661. @@ -1700,7 +1971,7 @@ { \@@_grab_dollar:n {#1} } % \end{macrocode} % \end{macro} -% +% % \begin{macro}{\@@_grab_dollardollar:w} % And for the classical \TeX{} display structure. % \begin{macrocode} @@ -1716,11 +1987,11 @@ $$ } % \end{macrocode} -% +% % The end code is added through a \cs{aftergroup} so we % store it inside a command. % \begin{macrocode} -\cs_new_protected:Npn \@@_tag_dollardollar_display_end: +\cs_new_protected:Npn \@@_tag_dollardollar_display_end: { % \typeout{== tag dollarldollar display end} % \ShowTagging{struct-stack} @@ -2126,7 +2397,7 @@ } { % \typeout{==>A3} - \__tag_tool_close_P: + \__tag_tool_close_P: } \socket_use:nn{tagsupport/math/display/formula/begin}{} \tagpdfparaOff @@ -2144,7 +2415,7 @@ \cs_new_protected:Npn \math_register_env:n #1 { \math_register_env:nn {#1} { } } - + \NewDocumentCommand \RegisterMathEnvironment { O{} m } { \math_register_env:nn {#2} {#1} } % \end{macrocode} @@ -2231,7 +2502,7 @@ { \cs_gset_protected:Npn \[ % \] { - \@@_grab_eqn:w + \@@_grab_eqn:w % \bool_if:NTF \l_@@_collected_bool % { \begin { equation* } } % { \@@_grab_eqn:w } @@ -2329,7 +2600,7 @@ % \end{macrocode} % % Tabulars currently contain a \$ that shouldn't trigger math -% tagging. +% tagging. % \begin{macrocode} \RequirePackage{array} \tl_if_in:NnT\@tabular{$} @@ -2338,7 +2609,7 @@ \leavevmode \UseTaggingSocket{tbl/hmode/begin}% \hbox \bgroup - \bool_set_true:N \l_@@_collected_bool + \bool_set_true:N \l_@@_collected_bool $ \bool_set_false:N \l_@@_collected_bool \col@sep\tabcolsep \let\d@llarbegin\begingroup @@ -2363,10 +2634,10 @@ } % \end{macrocode} % \end{macro} -% +% % \subsection{Disable math grabbing in the begindocument hook} % For example amsart uses math to measure text there. -% +% % \begin{macrocode} \tl_gput_right:Nn\@kernel@before@begindocument { @@ -2490,7 +2761,7 @@ \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 {alignat*}{} \math_register_halign_env:nn {flalign}{} \math_register_halign_env:nn {flalign*}{} \math_register_halign_env:nn {gather}{} @@ -2571,8 +2842,8 @@ % % \begin{macro}{\@@_split_at_nl:NN} -% This splits grabbed math at newlines. -% +% This splits grabbed math at newlines. +% % \begin{macrocode} \cs_new:Npn \@@_split_at_nl:NN #1#2 { \tl_set:Nf \l_@@_tmpa_tl { @@ -2591,14 +2862,14 @@ #2 \\ #3 \s_stop } } - + \cs_new_protected:Npn \@@_split_at_nl_aux:nnNN #1 #2 #3 #4 { \tl_gset:Nn #4 {#1} \tl_gset:Nn #3 {#2} } -\cs_new:Npn \@@_split_chk_if_begin:ww +\cs_new:Npn \@@_split_chk_if_begin:ww #1 \begin #2 #3 \s_mark #4 \\ \q_nil \\ \s_stop { \quark_if_nil:nTF {#2} @@ -2649,11 +2920,11 @@ { \exp_end: { #4 #1 } } { \@@_split_final_cleanup:w #3 \s_mark { #4 #1 #2 } } } - + \cs_new:Npn \@@_split:n #1 { \@@_split_at_nl_first:w #1 \\ \q_nil \\ \s_stop } - -% this looks unused. + +% this looks unused. %\NewDocumentCommand \splitnl { mm +m } % { % \tl_set:Nf \l_@@_tmpa_tl { \split:n {#3} } @@ -2665,12 +2936,12 @@ % % % \begin{macro}{\maybestartnewformulatag} -% +% % \begin{macrocode} \newif\if@subformulas -\tl_new:N \result - +\tl_new:N \result + \cs_new_protected:Npn\grabaformulapartandstart { \@@_split_at_nl:NN \g_@@_grabbed_math_tl \result \typeout{====>first-result=\meaning\result} @@ -2690,7 +2961,7 @@ % but we add a short text to satisfy the pdf/ua-2 validator % \begin{macrocode} % alt=\result, - alt = subformula, + alt = subformula, title-o=\resulttitle } } @@ -2728,7 +2999,7 @@ % \tl_if_empty:NF \g_@@_grabbed_math_tl { - \tagmcend + \tagmcend \tagstructend \grabaformulapartandmayberestart } @@ -2744,21 +3015,21 @@ % \typeout{===>~ in~ hook} % \math_register_halign_env:nn {dmath}{} % \math_register_halign_env:nn {dgroup*}{} -%} +%} % \end{macrocode} -% +% % \begin{macrocode} \ExplSyntaxOff % \end{macrocode} -% +% % \begin{macrocode} %<@@=> % \end{macrocode} -% +% % \begin{macrocode} %</kernel> % \end{macrocode} % % \Finale % -% +% diff --git a/Master/texmf-dist/source/latex-dev/tools/array.dtx b/Master/texmf-dist/source/latex-dev/tools/array.dtx index f141f069e3a..f4c8ab28d8d 100644 --- a/Master/texmf-dist/source/latex-dev/tools/array.dtx +++ b/Master/texmf-dist/source/latex-dev/tools/array.dtx @@ -39,7 +39,7 @@ % \begin{macrocode} %<+package>\NeedsTeXFormat{LaTeX2e}[2024/06/01] %<+package>\ProvidesPackage{array} -%<+package> [2024/10/12 v2.6g Tabular extension package (FMi)] +%<+package> [2024/10/17 v2.6g Tabular extension package (FMi)] % % \fi % @@ -259,7 +259,7 @@ % \begin{table}[!t] % \begin{center} % \setlength{\extrarowheight}{1pt} -% \begin{tabular}{|>{\tt}c|m{9cm}|} +% \begin{tabular}{|>{\ttfamily}c|m{9cm}|} % \hline % \multicolumn{2}{|c|}{Unchanged options}\\ % \hline @@ -382,6 +382,20 @@ % \end{itemize} % % +% +% \subsection{A note on the allowed content of \texttt{>\{...\}} and +% \texttt{<\{...\}}} +% +% These specifiers are meant to hold declarations, such as +% \verb=>{\itshape}=. They cannot end in commands that take arguments +% without providing these arguments as part of the \verb={...}=. It +% would be a mistaken assumption that they pick up all or parts of the +% alignment entry data if their argument is not provided. E.g., +% \verb=>{\textbf}= would not make the whole column bold nor would it +% make the first character bold (technically it would try to +% bolden \cs{ignorespaces}). Thus, it would not fail with an error, +% but effectively the output would be wrong and not as expected. +% % \subsection{The behavior of the \texttt{\string\\} command} % % In the basic \texttt{tabular} implementation of \LaTeX{} the \cs{\bslash} @@ -464,16 +478,16 @@ % "\newcolumntype{L}{>{$}l<{$}}" \\ % "\newcolumntype{R}{>{$}r<{$}}" % \end{quote} -% Then we can use \texttt{C} to get centred LR-mode in an -% \texttt{array}, or centred math-mode in a \texttt{tabular}. +% Then we can use \texttt{C} to get centered LR-mode in an +% \texttt{array}, or centered math-mode in a \texttt{tabular}. % -% The example given above for `centred decimal points' could be +% The example given above for `center decimal points' could be % assigned to a \texttt{d} specifier with the following command. % \begin{quote} % "\newcolumntype{d}{>{\centerdots}c<{\endcenterdots}}" % \end{quote} % -% The above solution always centres the dot in the +% The above solution always centers the dot in the % column. This does not look too good if the column consists of large % numbers, but to only a few decimal places. An alternative definition % of a \texttt{d} column is @@ -734,7 +748,7 @@ % user the opportunity of overriding the settings of a % "\newcolumntype" defined using these declarations. For example, % suppose in an \texttt{array} environment we use a \texttt{C} -% column defined as above. The \texttt{C} specifies a centred text +% column defined as above. The \texttt{C} specifies a centered text % column, however ">{\bfseries}C", which re-writes to % ">{\bfseries}>{$}c<{$}" would not specify a bold column as might % be expected, as the preamble would essentially expand to @@ -896,14 +910,14 @@ Bug reports can be opened (category \texttt{#1}) at\\% % % \section{A note on the updates done December 2023} % -% We introduced support for tagged PDf and at the same time we added +% We introduced support for tagged PDF and at the same time we added % code to determine row and column numbers for each cell in % preparation for supporting formatting or type specifications for individual % cells (or group of cells) from the outside, e.g., \enquote{rows 1, % 2, and 10 are header rows} (syntax to be decided). % % This new code is already written with L3 programming layer conventions -% while most of the legay code is still as it was before. This make the code +% while most of the legacy code is still as it was before. This make the code % currently somewhat clattered, unfortunately. Eventually this will all move to L3 % programming layer but this will take time. % @@ -1345,7 +1359,7 @@ Bug reports can be opened (category \texttt{#1}) at\\% % of \textsf{token} register $15$ instead of $1$ later on. % % The example above referred to an older version of =\save@decl= which -% inserted a =\relex= inside the token register. This is now moved to +% inserted a =\relax= inside the token register. This is now moved to % the places where the actual token registers are inserted (look for % =\the@toks=) because the old version would still make =@= % expressions to moving arguments since after expanding the second @@ -1386,33 +1400,112 @@ Bug reports can be opened (category \texttt{#1}) at\\% % \begin{macrocode} \UseTaggingSocket{tbl/cell/begin}% % \end{macrocode} -% Here, we assume that the \textsf{count} register +% Next we have to insert the toks register holding the content of +% \verb=>{...}=. Here, we assume that the \textsf{count} register % =\@tempcnta= has saved the value $=\count@= - 1$. % -% To keep \TeX{} happy if there is a look ahead in the tabular preamble -% which uses the Appendix~D trick (for example anything with a trailing -% optional argument defined by \pkg{ltcmd}), we wrap everything here in -% a protected version of \cs{@firstofone}.\footnote{The reason this -% works is not really clear: almost certainly there is a bug in \TeX{} -% here that we are simply avoiding, but as the master counter doesn't -% show up in a trace, a full understanding likely means working through -% the code that implements \cs{halign}!} -% \TeX{} otherwise can get +% To keep \TeX{} happy if there is a look ahead in the tabular +% preamble, i.e., starting in \verb=>{...}=, which uses the +% Appendix~D trick (for example, anything with a trailing optional +% argument defined by \pkg{ltcmd}), we wrap everything here in a +% protected version of \cs{@firstofone}. \TeX{} otherwise can get % confused about the value of the master counter, and we get some -% strange errors. (Quite possibly the underlying issue is a \TeX{} -% bug, but rather than try to fix in 2024 we accept it's there and -% work-around.) As an example, without this approach, something -% like +% strange errors. We suspected that there was an underlying issue +% is the \TeX{} engine, but it turned out to be rather hard to get +% to the bottom of it, because the master counter is not accessible +% through \TeX{}'s tracing tools. Thus, all we could do was +% producing various example documents, observing results, as well +% as staring at a printout of the \TeX{} program. As an example, +% without this approach, something like % \begin{verbatim} -%\NewDocumentCommand\foo{o}{x} -%\begin{tabular}{>{\foo}l} -% Foo -%\end{tabular} +% \NewDocumentCommand\foo{o}{x} +% \begin{tabular}{>{\foo}l} +% Foo +% \end{tabular} % \end{verbatim} -% will fail; that can be fixed by adding a \cs{relax} after the \cs{@tempcnta}, -% but that then leads to issues if you are collecting whole cells (tagging code -% or \\pkg{collcell}), where you can no longer alter the meaning of \cs{cr} -% as the master counter goes wrong. +% failed. That can be fixed by adding a \cs{relax} after the +% \cs{@tempcnta}, but that then leads to issues if you are +% collecting whole cells (tagging code or \pkg{collcell}), where +% you can no longer alter the meaning of \cs{cr} as the master +% counter goes wrong due to an obscure bug (or perhaps, say, an +% undocumented feature of \TeX{}). Eventually, we were able to pin +% down the root cause and really understand why +% \cs{@protected@firstofone} solves the problem, even though it +% looks like a nonsense addition to the code that does nothing +% useful.\footnote{So it is a \TeX{} engine bug that was in there +% from day one, or if you like, it is a hidden feature that is not +% explained; neither in the \TeX{}book nor in the program code. We +% don't really expect this to change in \TeX{} after such a long +% time, other than perhaps documenting it as a feature, so this is +% a proper solution to the problem and not just a workaround.} +% +% The problem is that \TeX{} tries to conserve stack space, and +% when the last token of an existing token list is a macro, then +% this token list is \emph{first} removed from memory (reducing the +% stack) \emph{before} the macro replacement text (as a new +% token list) is given to the parser adding a new stack level. This +% is done using the routine \texttt{end\_token\_list} in the \TeX{} +% program and ending the u-part of an \cs{halign} column with this +% routine immediately sets the \emph{master counter} used by alignments to +% zero (see chapter~22 and Appendix~D of the \TeX{}book). This +% means that technically the expansion of the last token in the u-part (if it +% is a macro) is not executed in the context of the u-part, but in +% the context of the alignment entry in the document. That normally +% doesn't make any difference whatsoever --- unless you play +% around (as we sometimes have to) with tricks like those from +% Appendix~D. +% +% To illustrate the issue we show a bit of strange low-level plain +% \TeX{} code.\footnote{If all of this looks mighty strange to you, +% don't worry. You will be unlikely to need to know about it. It is +% just there so that programmers at some point in the future do not +% have to wonder too much why there is this odd +% \cs{@protected@firstofone} that apparently does nothing +% useful. It took us several nights of head scratching to come up +% with these minimal examples and then some more time to understand +% what the heck is going on inside \TeX{}---thanks to Bruno for the +% right ideas on the latter.} Below are two very special grouping +% commands that are like \cs{bgroup} and \cs{egroup} but also +% affect the alignment master counter when expanded (see +% \TeX{}book p.385). If one of them is used as the +% last macro in the u-part of a column, then you get strange errors +% that you shouldn't get. +% \begin{verbatim} +% \def\bbgroup{{\ifnum0=`}\fi} +% \def\eegroup{\ifnum0=`{\fi}} +% +% % Fails with an error message, but there should be none: +% \halign{% +% \message{u-part^^J}% +% \bbgroup % <-- in the u-part +% \eegroup % <-- in the u-part +% #% +% \message{v-part^^J}% +% \hfill\cr +% \message{body^^J}x +% \cr +% } +% +% % Fails but should work, the v-part is never reached: +% \halign{% +% \message{u-part^^J}% +% \bbgroup % <-- in the u-part +% #% +% \message{v-part^^JJ}% +% \eegroup % <-- in the v-part +% \hfill\cr +% \message{body^^J}x +% \cr +% } +% \end{verbatim} +% +% So the trick we use now is making \cs{@protected@firstofone} the +% last macro in the u-part, i.e., before the \cs{@sharp}. That way +% its argument is always fully expanded as part of the alignment +% entry and not as part of the u-part and this way we know exactly +% what the master counter value is at this point, regardless of the content of +% \verb=>{...}=. +% % \changes{v2.6f}{2024/09/13}{Stop parsing for optional argument (gh/1468)} % \changes{v2.6g}{2024/10/12}{Further work to support optional args in preamble (gh/1468)} % \begin{macrocode} @@ -1429,7 +1522,7 @@ Bug reports can be opened (category \texttt{#1}) at\\% % afterwards; in math mode, the latter is suppressed while the % \cs{ignorespaces} makes no difference. % \changes{v2.0e}{1991/02/07}{Added \{\} around \cs{@sharp} for new ftsel} -% \changes{v2.0h}{1992/06/22}{Removed \{\} again in favour of +% \changes{v2.0h}{1992/06/22}{Removed \{\} again in favor of % \cs{d@llarbegin}} % \changes{v2.6b}{2024/04/08}{Do not \cs{unskip} if in math mode (gh/1323)} % \begin{macrocode} @@ -1920,7 +2013,7 @@ Bug reports can be opened (category \texttt{#1}) at\\% % For that reason the new implementation does the centering % manually: First we check the height of the cell and if that is % less or equal to =\ht\strutbox= we assume that this is a -% single line cell. In that case we don't do any vertical maneuvre +% single line cell. In that case we don't do any vertical maneuver % and simply output the box, i.e., make it behave like a single % line p-cell. % @@ -2363,7 +2456,7 @@ Bug reports can be opened (category \texttt{#1}) at\\% \lineskip \z@ \baselineskip \z@ % \end{macrocode} -% Don't use \cs{m@th} here as that signals to the math taggingg +% Don't use \cs{m@th} here as that signals to the math tagging % code that this is fake math that should not be tagged. % \changes{v2.6a}{2023/12/11}{Support for tagged PDF} % \begin{macrocode} @@ -2489,7 +2582,7 @@ Bug reports can be opened (category \texttt{#1}) at\\% % % We then start a special brace which I have directly % copied from the original definition. It is -% necessary, because the =\futurlet= in =\@ifnextchar= +% necessary, because the =\futurelet= in =\@ifnextchar= % might % expand a following =&= \textsf{token} in a construction like % =\\ &=. This would otherwise end the alignment template at a @@ -2502,7 +2595,7 @@ Bug reports can be opened (category \texttt{#1}) at\\% % that a =&= will not be considered belonging to the current % =\halign= while we are looking for a =*= or =[=. % For further information see -% \cite[Appendix D]{bk:knuth}. +% \cite[Appendix~D]{bk:knuth}. % \begin{macrocode} \iffalse{\fi\ifnum 0=`}\fi % \end{macrocode} @@ -2687,7 +2780,7 @@ Bug reports can be opened (category \texttt{#1}) at\\% % \section{The Environment Definitions} % % After these preparations we are able to define the environments. They -% only differ in the initialisations of =\d@llar...=, =\col@sep= +% only differ in the initializations of =\d@llar...=, =\col@sep= % and =\@halignto=. % % \begin{macro}{\@halignto} @@ -2702,7 +2795,7 @@ Bug reports can be opened (category \texttt{#1}) at\\% % able overwrite the =\@halignto= % setting of a tabular in the main text resulting in a very weird error. % \changes{v2.4d}{2016/10/06}{\cs{@halignto} set locally (pr/4488)} -% \changes{v2.0g}{1992/06/18}{`d@llarbegin defined on toplevel.} +% \changes{v2.0g}{1992/06/18}{`d@llarbegin defined on top-level.} % When the new font selection scheme is in force we have to % we surround all =\halign= entries % with braces. See remarks in TUGboat 10\#2. Actually we are going @@ -2752,7 +2845,7 @@ Bug reports can be opened (category \texttt{#1}) at\\% % \begin{macro}{\tabular} % \begin{macro}{\tabular*} % The environments \textsf{tabular} and \textsf{tabular$*$} differ -% only in the initialisation of the command =\@halignto=. Therefore +% only in the initialization of the command =\@halignto=. Therefore % we define % \changes{v2.4d}{2016/10/06}{\cs{@halignto} set locally (pr/4488)} % \begin{macrocode} @@ -3034,7 +3127,7 @@ Bug reports can be opened (category \texttt{#1}) at\\% % rewrites (in the token register "\NC@list") will look like % "\NC@do *" "\NC@do C" "\NC@do L". % So we need to define "\NC@do" as a one argument macro which -% initialises the rewriting of the specified column. Let us assume that +% initializes the rewriting of the specified column. Let us assume that % `C' is the argument. % \begin{macrocode} \def\NC@do#1{% @@ -3102,7 +3195,7 @@ Bug reports can be opened (category \texttt{#1}) at\\% % \end{macro} % % \subsection{The $*$--form} -% We view the $*$-form as a slight generalisation of the system +% We view the $*$-form as a slight generalization of the system % described in the previous subsection. The idea is to define a $*$ % column by a command of the form: % \begin{verbatim} @@ -3540,7 +3633,7 @@ Bug reports can be opened (category \texttt{#1}) at\\% % the cell content is too wide. % \changes{v2.4f}{2017/11/07}{Column type added} % \changes{v2.5a}{2020/04/06}{Use \cs{d@llarbegin} and \cs{d@llarend} so -% that cell is typeset in mathmode inside \texttt{array} (gh/297)} +% that cell is typeset in math mode inside \texttt{array} (gh/297)} % \begin{macrocode} \newcolumntype{W}[2] {>{\begin{lrbox}\ar@cellbox\d@llarbegin}% diff --git a/Master/texmf-dist/source/latex-dev/tools/longtable.dtx b/Master/texmf-dist/source/latex-dev/tools/longtable.dtx index 439542a18c9..061d7b56102 100644 --- a/Master/texmf-dist/source/latex-dev/tools/longtable.dtx +++ b/Master/texmf-dist/source/latex-dev/tools/longtable.dtx @@ -38,7 +38,7 @@ %<driver> \ProvidesFile{longtable.drv} % \fi % \ProvidesFile{longtable.dtx} - [2024-07-06 v4.21 Multi-page Table package (DPC)] + [2024-10-27 v4.22 Multi-page Table package (DPC)] % % \iffalse %<*driver> @@ -1639,15 +1639,20 @@ \LT@final@warn \fi % \end{macrocode} -% Force one more go with the \env{longtable} output routine. +% Force one more go with the \env{longtable} output routine. +% Guard the special start of page value of "\pagegoal". % \changes{v4.14}{2020/02/07} % {Rearrange vertical space tests for tools/3512 (floats on same page)} +% \changes{v4.22}{2024/10/27} +% {Keep \cs{pagegoal} below \cs{maxdimen} gh1495} % \begin{macrocode} \endgraf\penalty -\LT@end@pen \ifvoid\LT@foot\else \global\advance\vsize\ht\LT@foot \global\advance\@colroom\ht\LT@foot - \dimen@\pagegoal\advance\dimen@\ht\LT@foot\pagegoal\dimen@ + \ifdim\pagegoal<\maxdimen + \dimen@\pagegoal\advance\dimen@\ht\LT@foot\pagegoal\dimen@ + \fi \fi % \end{macrocode} % Now close the group to return to the standard routine. |