From a776d572cfd8fa24365dbc0cc22bbd856fbbe97b Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 1 Nov 2023 20:13:49 +0000 Subject: latex2e (1nov23) git-svn-id: svn://tug.org/texlive/trunk@68720 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/latex/base/docstrip.dtx | 25 +- Master/texmf-dist/source/latex/base/format.ins | 2 + .../texmf-dist/source/latex/base/latexrelease.ins | 2 + Master/texmf-dist/source/latex/base/ltboxes.dtx | 95 +- Master/texmf-dist/source/latex/base/ltcmd.dtx | 153 +- Master/texmf-dist/source/latex/base/ltexpl.dtx | 25 +- Master/texmf-dist/source/latex/base/ltfilehook.dtx | 3 +- Master/texmf-dist/source/latex/base/ltfiles.dtx | 2 +- Master/texmf-dist/source/latex/base/ltfssaxes.dtx | 6 +- Master/texmf-dist/source/latex/base/ltfssbas.dtx | 4 +- Master/texmf-dist/source/latex/base/lthooks.dtx | 32 +- Master/texmf-dist/source/latex/base/ltluatex.dtx | 12 +- Master/texmf-dist/source/latex/base/ltmiscen.dtx | 245 +- Master/texmf-dist/source/latex/base/ltplain.dtx | 4 +- .../texmf-dist/source/latex/base/ltproperties.dtx | 966 +++++ Master/texmf-dist/source/latex/base/ltsockets.dtx | 1069 +++++ Master/texmf-dist/source/latex/base/ltspace.dtx | 44 +- Master/texmf-dist/source/latex/base/ltvers.dtx | 4 +- .../texmf-dist/source/latex/firstaid/firstaid.ins | 8 +- .../latex2e-first-aid-for-external-files.dtx | 155 +- Master/texmf-dist/source/latex/l3build/l3build.dtx | 14 +- .../latex/latex-lab/documentmetadata-support.dtx | 65 +- .../source/latex/latex-lab/latex-lab-bib.dtx | 11 +- .../latex/latex-lab/latex-lab-block-tagging.dtx | 4055 ------------------- .../source/latex/latex-lab/latex-lab-block.dtx | 4101 ++++++++++++++++++++ .../source/latex/latex-lab/latex-lab-firstaid.dtx | 62 +- .../source/latex/latex-lab/latex-lab-float.dtx | 60 +- .../source/latex/latex-lab/latex-lab-footnotes.dtx | 999 +++-- .../source/latex/latex-lab/latex-lab-graphic.dtx | 103 +- .../source/latex/latex-lab/latex-lab-math.dtx | 1313 +++++++ .../latex/latex-lab/latex-lab-mathtagging.dtx | 1280 ------ .../source/latex/latex-lab/latex-lab-minipage.dtx | 86 +- .../source/latex/latex-lab/latex-lab-namespace.dtx | 100 + .../source/latex/latex-lab/latex-lab-new-or-1.dtx | 57 +- .../source/latex/latex-lab/latex-lab-new-or-2.dtx | 341 +- .../source/latex/latex-lab/latex-lab-sec.dtx | 89 +- .../source/latex/latex-lab/latex-lab-table.dtx | 1975 ++++++++++ .../source/latex/latex-lab/latex-lab-testphase.dtx | 46 +- .../source/latex/latex-lab/latex-lab-text.dtx | 12 +- .../latex-lab/latex-lab-toc-hyperref-changes.dtx | 4 +- .../latex-lab/latex-lab-toc-kernel-changes.dtx | 48 +- .../latex-lab/latex-lab-toc-tagging-functions.dtx | 365 -- .../source/latex/latex-lab/latex-lab-toc.dtx | 403 ++ .../source/latex/latex-lab/latex-lab.ins | 115 +- Master/texmf-dist/source/latex/tools/afterpage.dtx | 12 +- Master/texmf-dist/source/latex/tools/array.dtx | 4 +- Master/texmf-dist/source/latex/tools/bm.dtx | 63 +- Master/texmf-dist/source/latex/tools/calc.dtx | 26 +- Master/texmf-dist/source/latex/tools/dcolumn.dtx | 22 +- Master/texmf-dist/source/latex/tools/enumerate.dtx | 10 +- Master/texmf-dist/source/latex/tools/ftnright.dtx | 18 +- .../texmf-dist/source/latex/tools/indentfirst.dtx | 4 +- Master/texmf-dist/source/latex/tools/layout.dtx | 42 +- Master/texmf-dist/source/latex/tools/longtable.dtx | 36 +- Master/texmf-dist/source/latex/tools/shellesc.dtx | 18 +- Master/texmf-dist/source/latex/tools/showkeys.dtx | 20 +- Master/texmf-dist/source/latex/tools/tabularx.dtx | 38 +- Master/texmf-dist/source/latex/tools/theorem.dtx | 12 +- Master/texmf-dist/source/latex/tools/verbatim.dtx | 24 +- Master/texmf-dist/source/latex/tools/xr.dtx | 4 +- 60 files changed, 11918 insertions(+), 6995 deletions(-) create mode 100644 Master/texmf-dist/source/latex/base/ltproperties.dtx create mode 100644 Master/texmf-dist/source/latex/base/ltsockets.dtx delete mode 100644 Master/texmf-dist/source/latex/latex-lab/latex-lab-block-tagging.dtx create mode 100644 Master/texmf-dist/source/latex/latex-lab/latex-lab-block.dtx create mode 100644 Master/texmf-dist/source/latex/latex-lab/latex-lab-math.dtx delete mode 100644 Master/texmf-dist/source/latex/latex-lab/latex-lab-mathtagging.dtx create mode 100644 Master/texmf-dist/source/latex/latex-lab/latex-lab-namespace.dtx create mode 100644 Master/texmf-dist/source/latex/latex-lab/latex-lab-table.dtx delete mode 100644 Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-tagging-functions.dtx create mode 100644 Master/texmf-dist/source/latex/latex-lab/latex-lab-toc.dtx (limited to 'Master/texmf-dist/source') diff --git a/Master/texmf-dist/source/latex/base/docstrip.dtx b/Master/texmf-dist/source/latex/base/docstrip.dtx index be373499e6b..776d0e68d7d 100644 --- a/Master/texmf-dist/source/latex/base/docstrip.dtx +++ b/Master/texmf-dist/source/latex/base/docstrip.dtx @@ -31,7 +31,7 @@ \def\filename{docstrip.dtx} \def\fileversion{v2.6b} \def\filedate{2022-09-03} -\def\docdate {2022-09-03} +\def\docdate {2023-10-10} %% % %\iffalse @@ -838,6 +838,29 @@ % suppressed by giving an empty module name, namely using the % syntax \texttt{\%<@@=>}. % +% The exact steps that are carried out by this replacement +% algorithm are the following: +% \begin{enumerate} +% \item First, deal with \texttt{@@@@} as a special case (by using a +% temporary disguise). +% +% \item Then change all |__@@| to |__|\meta{module}. +% +% \item Then change all remaining |_@@| to +% |__|\meta{module}. +% +% \item Then change all remaining \texttt{@@} to +% |__|\meta{module}. +% +% \item Finally, tidy up by changing each ``disguised +% \texttt{@@@@}'' to \texttt{@@}. +% \end{enumerate} +% Thus, replacement means that \texttt{@@} is replaced by the +% \meta{module} name and that 0, 1, or 2 underscores in front of +% \texttt{@@} are replaced by exactly 2 underscores (whilst any +% larger number of underscores is preserved). +% +% % \section{Those other languages} % Since \TeX\ is an open system some of \TeX\ packages include % non-\TeX\ files. Some authors use \ds\ to generate PostScript diff --git a/Master/texmf-dist/source/latex/base/format.ins b/Master/texmf-dist/source/latex/base/format.ins index 74cd78ff4a8..ba0965004d1 100644 --- a/Master/texmf-dist/source/latex/base/format.ins +++ b/Master/texmf-dist/source/latex/base/format.ins @@ -169,6 +169,7 @@ the system are in the document `cfgguide.tex'. \from{ltcmd.dtx}{2ekernel} % L3 layer module (used to be xparse) \from{lthooks.dtx}{2ekernel} % L3 layer module \from{ltcmdhooks.dtx}{2ekernel} % L3 layer module + \from{ltsockets.dtx}{2ekernel} % L3 layer module \from{ltalloc.dtx}{2ekernel} \from{ltcntrl.dtx}{2ekernel} \from{lterror.dtx}{2ekernel} @@ -191,6 +192,7 @@ the system are in the document `cfgguide.tex'. \from{lttextcomp.dtx}{2ekernel} \from{ltpageno.dtx}{2ekernel} \from{ltxref.dtx}{2ekernel} + \from{ltproperties.dtx}{2ekernel} \from{ltmiscen.dtx}{2ekernel} \from{ltmath.dtx}{2ekernel} \from{ltlists.dtx}{2ekernel} diff --git a/Master/texmf-dist/source/latex/base/latexrelease.ins b/Master/texmf-dist/source/latex/base/latexrelease.ins index 61315f8e078..93739630e3e 100644 --- a/Master/texmf-dist/source/latex/base/latexrelease.ins +++ b/Master/texmf-dist/source/latex/base/latexrelease.ins @@ -96,6 +96,7 @@ extension .ins) which are part of the distribution. \from{ltcmd.dtx} {latexrelease}% L3 layer module \from{lthooks.dtx} {latexrelease}% L3 layer module \from{ltcmdhooks.dtx} {latexrelease}% L3 layer module + \from{ltsockets.dtx} {latexrelease}% L3 layer module \from{ltalloc.dtx} {latexrelease}% empty \from{ltcntrl.dtx} {latexrelease}% empty \from{lterror.dtx} {latexrelease}% empty @@ -118,6 +119,7 @@ extension .ins) which are part of the distribution. \from{lttextcomp.dtx} {latexrelease}% \from{ltpageno.dtx} {latexrelease}% empty \from{ltxref.dtx} {latexrelease}% empty + \from{ltproperties.dtx}{latexrelease}% \from{ltmiscen.dtx} {latexrelease}% \from{ltmath.dtx} {latexrelease}% \from{ltlists.dtx} {latexrelease}% empty diff --git a/Master/texmf-dist/source/latex/base/ltboxes.dtx b/Master/texmf-dist/source/latex/base/ltboxes.dtx index ff1717caa97..d84158c161b 100644 --- a/Master/texmf-dist/source/latex/base/ltboxes.dtx +++ b/Master/texmf-dist/source/latex/base/ltboxes.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltboxes.dtx} - [2022/09/07 v1.4d LaTeX Kernel (Box Commands)] + [2023/10/26 v1.4e LaTeX Kernel (Box Commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltboxes.dtx} @@ -342,13 +342,36 @@ % \begin{macro}{\@imakebox} % \changes{v0.1a}{1993/12/03} % {macro modified} +% \changes{v1.4e}{2023/10/26} +% {Guard against unknown alignment gh/1072} % Internal form of |\makebox|. % \begin{macrocode} +% +%\IncludeInRelease{2023/11/01}% +% {\@imakebox}{Unknown alignment warning}% +%<*2ekernel|latexrelease> \long\def\@imakebox[#1][#2]#3{% \@begin@tempboxa\hbox{#3}% \setlength\@tempdima{#1}% support calc - \hb@xt@\@tempdima{\csname bm@#2\endcsname}% + \hb@xt@\@tempdima{% + \expandafter\ifx\csname bm@#2\endcsname\relax + \bm@c + \@latex@warning{Unexpected alignment #2}% + \else + \csname bm@#2\endcsname + \fi}% \@end@tempboxa} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@imakebox}{Unknown alignment warning}% +%\long\def\@imakebox[#1][#2]#3{% +% \@begin@tempboxa\hbox{#3}% +% \setlength\@tempdima{#1}% support calc +% \hb@xt@\@tempdima{\csname bm@#2\endcsname}% +% \@end@tempboxa} +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -748,19 +771,46 @@ % {\cs{leavevmode} moved to \cs{@frameb@x}} % \changes{v1.0s}{1995/04/27} % {Move \cs{leavevmode} for graphics/1512} +% \changes{v1.4e}{2023/10/26} +% {Guard against unknown alignment gh/1072} % In order to set the whole box, including the frame to the % specified dimension, we first determine that dimension % from the natural size of the text, |#3|. % calculated width. % \begin{macrocode} +% +%\IncludeInRelease{2023/11/01}% +% {\@iframebox}{Unknown alignment warning}% +%<*2ekernel|latexrelease> \long\def\@iframebox[#1][#2]#3{% \leavevmode \@begin@tempboxa\hbox{#3}% \setlength\@tempdima{#1}% \setbox\@tempboxa\hb@xt@\@tempdima - {\kern\fboxsep\csname bm@#2\endcsname\kern\fboxsep}% + {\kern\fboxsep + \expandafter\ifx\csname bm@#2\endcsname\relax + \bm@c + \@latex@warning{Unexpected alignment #2}% + \else + \csname bm@#2\endcsname + \fi + \kern\fboxsep}% \@frameb@x{\kern-\fboxrule}% \@end@tempboxa} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@iframebox}{Unknown alignment warning}% +%\long\def\@iframebox[#1][#2]#3{% +% \leavevmode +% \@begin@tempboxa\hbox{#3}% +% \setlength\@tempdima{#1}% +% \setbox\@tempboxa\hb@xt@\@tempdima +% {\kern\fboxsep\csname bm@#2\endcsname\kern\fboxsep}% +% \@frameb@x{\kern-\fboxrule}% +% \@end@tempboxa} +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -881,9 +931,17 @@ % \changes{v1.1g}{2006/05/18} % {Ensure \cs{@parboxto} holds the value of \cs{@tempdimb} not the % register itself (pr/3867)} +% \changes{v1.4e}{2023/10/26} +% {Guard against unknown alignment gh/1072} % The internal version of |\parbox|. % \begin{macrocode} \let\@parboxto\@empty +% \end{macrocode} +% \begin{macrocode} +% +%\IncludeInRelease{2023/11/01}% +% {\@iiiparbox}{Unknown alignment warning}% +%<*2ekernel|latexrelease> \long\def\@iiiparbox#1#2[#3]#4#5{% \leavevmode \@pboxswfalse @@ -899,9 +957,38 @@ \else\@pboxswtrue $\vcenter \fi\fi\fi \@parboxto{\let\hss\vss\let\unhbox\unvbox - \csname bm@#3\endcsname}% + \expandafter\ifx\csname bm@#3\endcsname\relax + \bm@c + \@latex@warning{Unexpected alignment #3}% + \else + \csname bm@#3\endcsname + \fi}% \if@pboxsw \m@th$\fi \@end@tempboxa} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@iiiparbox}{Unknown alignment warning}% +%\long\def\@iiiparbox#1#2[#3]#4#5{% +% \leavevmode +% \@pboxswfalse +% \setlength\@tempdima{#4}% +% \@begin@tempboxa\vbox{\hsize\@tempdima\@parboxrestore#5\@@par}% +% \ifx\relax#2\else +% \setlength\@tempdimb{#2}% +% \edef\@parboxto{to\the\@tempdimb}% +% \fi +% \if#1b\vbox +% \else\if #1t\vtop +% \else\ifmmode\vcenter +% \else\@pboxswtrue $\vcenter +% \fi\fi\fi +% \@parboxto{\let\hss\vss\let\unhbox\unvbox +% \csname bm@#3\endcsname}% +% \if@pboxsw \m@th$\fi +% \@end@tempboxa} +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % \end{macro} diff --git a/Master/texmf-dist/source/latex/base/ltcmd.dtx b/Master/texmf-dist/source/latex/base/ltcmd.dtx index d6322ff3ee8..dcb85a1ae8d 100644 --- a/Master/texmf-dist/source/latex/base/ltcmd.dtx +++ b/Master/texmf-dist/source/latex/base/ltcmd.dtx @@ -34,8 +34,8 @@ %%% From File: ltcmd.dtx % % \begin{macrocode} -\def\ltcmdversion{v1.1e} -\def\ltcmddate{2023-05-26} +\def\ltcmdversion{v1.2a} +\def\ltcmddate{2023-08-19} % \end{macrocode} % %<*driver> @@ -59,6 +59,8 @@ % \section{Creating document commands} % % \changes{v1.0a}{2020/11/20}{Initial version derived from \texttt{xparse.dtx}} +% \changes{v1.2a}{2023/08/19}{Removed commands that should have remained +% only in \texttt{xparse.dtx}} % % Document commands should be created using the tools provided by this module: % \cs{NewDocumentCommand}, etc.\@, in almost all cases. This allows clean @@ -4263,116 +4265,6 @@ % \end{macro} % \end{macro} % -% \subsection{Access to the argument specification} -% -% \begin{macro}{\@@_get_arg_spec_error:N, \@@_get_arg_spec_error:n} -% \begin{macro}{\@@_get_arg_spec_error_aux:n} -% Provide an informative error when trying to get the argument -% specification of a non-\pkg{xparse} command or environment. -% \begin{macrocode} -\cs_new_protected:Npn \@@_get_arg_spec_error:N #1 - { - \bool_set_false:N \l_@@_environment_bool - \tl_set:Nn \l_@@_fn_tl {#1} - \@@_get_arg_spec_error_aux:n { \cs_if_exist:NTF #1 } - } -\cs_new_protected:Npn \@@_get_arg_spec_error:n #1 - { - \bool_set_true:N \l_@@_environment_bool - \str_set:Nx \l_@@_environment_str {#1} - \@@_get_arg_spec_error_aux:n - { \cs_if_exist:cTF { \l_@@_environment_str } } - } -\cs_new_protected:Npn \@@_get_arg_spec_error_aux:n #1 - { - #1 - { - \msg_error:nnx { cmd } { non-xparse } - { \@@_environment_or_command: } - } - { - \msg_error:nnx { cmd } { unknown } - { \@@_environment_or_command: } - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_get_arg_spec:NTF} -% If the command is not an \pkg{xparse} command, complain. If it is, -% its second \enquote{item} is the argument specification. -% \begin{macrocode} -\cs_new_protected:Npn \@@_get_arg_spec:NTF #1#2#3 - { - \__kernel_cmd_if_xparse:NTF #1 - { - \tl_set:Nx \ArgumentSpecification { \tl_item:Nn #1 { 2 } } - #2 - } - {#3} - } -% \end{macrocode} -% \end{macro} -% -% Rolling forward from 2020-10-01 is tricky because the entire |ltcmd| -% module is new, but the user-level commands have the same name, so only -% these will clash. To work around that, in |latexrelease| mode we will -% (temporarily) disable \cs{__kernel_chk_if_free_cs:N} for this final -% part of the code, then restore at the end. -% \begin{macrocode} -%\cs_new_eq:NN \@@_chk_if_free_cs:N \__kernel_chk_if_free_cs:N -%\cs_gset_eq:NN \__kernel_chk_if_free_cs:N \use_none:n -% \end{macrocode} -% -% \begin{variable}{\ArgumentSpecification} -% \begin{macrocode} -\tl_new:N \ArgumentSpecification -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\@@_get_arg_spec:N} -% \begin{macro}{\@@_get_arg_spec:n} -% Recovering the argument specification is now trivial. -% \begin{macrocode} -\cs_new_protected:Npn \@@_get_arg_spec:N #1 - { - \@@_get_arg_spec:NTF #1 { } - { \@@_get_arg_spec_error:N #1 } - } -\cs_new_protected:Npn \@@_get_arg_spec:n #1 - { - \exp_args:Nc \@@_get_arg_spec:NTF - { environment~ \tl_to_str:n {#1} } - { } - { \@@_get_arg_spec_error:n {#1} } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_show_arg_spec:N} -% \begin{macro}{\@@_show_arg_spec:n} -% Showing the argument specification simply means finding it and then -% calling the \cs{tl_show:N} function. -% \begin{macrocode} -\cs_new_protected:Npn \@@_show_arg_spec:N #1 - { - \@@_get_arg_spec:NTF #1 - { \tl_show:N \ArgumentSpecification } - { \@@_get_arg_spec_error:N #1 } - } -\cs_new_protected:Npn \@@_show_arg_spec:n #1 - { - \exp_args:Nc \@@_get_arg_spec:NTF - { environment~ \tl_to_str:n {#1} } - { \tl_show:N \ArgumentSpecification } - { \@@_get_arg_spec_error:n {#1} } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% % \subsection{Utilities} % % \begin{macro}{\@@_check_definable:nNT, \@@_check_definable_aux:nN} @@ -4817,12 +4709,6 @@ LaTeX~did~not~find~this~argument~and~will~insert~a~default~value~ for~further~processing. } -\msg_new:nnnn { cmd } { non-xparse } - { \str_uppercase:n #1~not~defined~using~xparse. } - { - You~have~asked~for~the~argument~specification~for~the~#1,~ - but~this~was~not~defined~using~xparse. - } \msg_new:nnnn { cmd } { arg-split } { Too~many~'#1'~separators~in~argument. } { @@ -4830,12 +4716,6 @@ at~each~occurrence~of~the~separator~'#1'~into~#2~parts.~ Too~many~separators~were~found. } -\msg_new:nnnn { cmd } { unknown } - { Unknown~document~#1. } - { - You~have~asked~for~the~argument~specification~for~the~#1,~ - but~it~is~not~defined. - } \msg_new:nnnn { cmd } { verbatim-nl } { Verbatim-like~#1~ended~by~end~of~line. } { @@ -5153,31 +5033,6 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\GetDocumentCommandArgSpec} -% \begin{macro}{\GetDocumentEnvironmentArgSpec} -% \begin{macro}{\ShowDocumentCommandArgSpec} -% \begin{macro}{\ShowDocumentEnvironmentArgSpec} -% More simple mappings, with a check that the argument is a single -% control sequence or active character. -% \begin{macrocode} -\cs_new_protected:Npn \GetDocumentCommandArgSpec #1 - { - \@@_check_definable:nNT {#1} \GetDocumentCommandArgSpec - { \@@_get_arg_spec:N #1 } - } -\cs_new_eq:NN \GetDocumentEnvironmentArgSpec \@@_get_arg_spec:n -\cs_new_protected:Npn \ShowDocumentCommandArgSpec #1 - { - \@@_check_definable:nNT {#1} \ShowDocumentCommandArgSpec - { \@@_show_arg_spec:N #1 } - } -\cs_new_eq:NN \ShowDocumentEnvironmentArgSpec \@@_show_arg_spec:n -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% % Finally as promised, restore \cs{__kernel_chk_if_free_cs:N}: % \begin{macrocode} %\cs_gset_eq:NN \__kernel_chk_if_free_cs:N \@@_chk_if_free_cs:N diff --git a/Master/texmf-dist/source/latex/base/ltexpl.dtx b/Master/texmf-dist/source/latex/base/ltexpl.dtx index 92e6de52cb6..4e5eba550b0 100644 --- a/Master/texmf-dist/source/latex/base/ltexpl.dtx +++ b/Master/texmf-dist/source/latex/base/ltexpl.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltexpl.dtx} - [2022/02/28 v1.3f LaTeX Kernel (expl3-dependent code)] + [2023/10/13 v1.3g LaTeX Kernel (expl3-dependent code)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltexpl.dtx} @@ -516,4 +516,27 @@ %\EndIncludeInRelease % \end{macrocode} % +% \DescribeMacro\IfExplAtLeastTF +% A pretty simple wrapper. +% +% \begin{macro}{\IfExplAtLeastTF} +% \changes{v1.3g}{2023/10/13}{Provide a test for \pkg{expl3} date (gh/1004)} +% \begin{macrocode} +%<*2ekernel|latexrelease> +%\IncludeInRelease{2023/11/01}% +% {\IfExplAtLeastTF}{Test for expl3 date}% +\def\IfExplAtLeastTF{\@ifl@t@r\ExplLoaderFileDate} +% \end{macrocode} +% \end{macro} +% We make sure the command is always available. +% \begin{macrocode} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\IfExplAtLeastTF}{Test for expl3 date}% +% +%\def\IfExplAtLeastTF{\@ifl@t@r\ExplLoaderFileDate} +%\EndIncludeInRelease +% \end{macrocode} +% % \Finale diff --git a/Master/texmf-dist/source/latex/base/ltfilehook.dtx b/Master/texmf-dist/source/latex/base/ltfilehook.dtx index e10a5416e58..ae183bfeb47 100644 --- a/Master/texmf-dist/source/latex/base/ltfilehook.dtx +++ b/Master/texmf-dist/source/latex/base/ltfilehook.dtx @@ -32,7 +32,7 @@ % % \begin{macrocode} \providecommand\ltfilehookversion{v1.0o} -\providecommand\ltfilehookdate{2023/04/02} +\providecommand\ltfilehookdate{2023/07/10} % \end{macrocode} % %<*driver> @@ -1043,7 +1043,6 @@ % % \begin{macrocode} %<@@=> -\ExplSyntaxOff % \end{macrocode} % % \subsection{Selecting a file (\cs{set@curr@file})} diff --git a/Master/texmf-dist/source/latex/base/ltfiles.dtx b/Master/texmf-dist/source/latex/base/ltfiles.dtx index 9b028241979..f079c2cf5b1 100644 --- a/Master/texmf-dist/source/latex/base/ltfiles.dtx +++ b/Master/texmf-dist/source/latex/base/ltfiles.dtx @@ -1225,7 +1225,7 @@ % \begin{macrocode} % %<*2ekernel|latexrelease> -%\IncludeInRelease{2023/05/01}% +%\IncludeInRelease{2023/06/01}% % {\IfFileExists@}{IfFileExists} \long\def \IfFileExists@#1#2#3{% \edef\@filef@und{\IfFileExists@@{#1}}% diff --git a/Master/texmf-dist/source/latex/base/ltfssaxes.dtx b/Master/texmf-dist/source/latex/base/ltfssaxes.dtx index 9e68b38654e..a0746bd08c0 100644 --- a/Master/texmf-dist/source/latex/base/ltfssaxes.dtx +++ b/Master/texmf-dist/source/latex/base/ltfssaxes.dtx @@ -35,7 +35,7 @@ % % \ProvidesFile{ltfssaxes.dtx} - [2021/03/18 v1.0i LaTeX Kernel (NFSS Axes handing)] + [2023/10/30 v1.0i LaTeX Kernel (NFSS Axes handing)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -1240,9 +1240,9 @@ % The next rule might be a bit surprising and rightly so. Correct % would be that \texttt{sc} is not affected by \texttt{up}, i.e., % remains \texttt{sc} as showed in the commented out rule. However, -% for nearly three decades commands such as \upshape{sc} or +% for nearly three decades commands such as \cs{sc} or % \cs{textup} changed small caps back to the ``normal'' shape. So -% for backward compatibility we keep hat behavior. +% for backward compatibility we keep that behavior. % % As a result you are currently typesetting in \texttt{scit} or % \texttt{scsl} using \cs{upshape} twice will return you to the diff --git a/Master/texmf-dist/source/latex/base/ltfssbas.dtx b/Master/texmf-dist/source/latex/base/ltfssbas.dtx index fda3d1ca4b0..fa82bd73bb6 100644 --- a/Master/texmf-dist/source/latex/base/ltfssbas.dtx +++ b/Master/texmf-dist/source/latex/base/ltfssbas.dtx @@ -35,7 +35,7 @@ % % \ProvidesFile{ltfssbas.dtx} - [2023/04/01 v3.2l LaTeX Kernel (NFSS Basic Macros)] + [2023/10/21 v3.2l LaTeX Kernel (NFSS Basic Macros)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -279,7 +279,7 @@ % For this we compare the given value \verb=#3= with one where we % may have dropped an ``m''. If nothing has changes, % fine. Otherwise there was a wrong value which is now corrected in -% \cs{reservedb} so we use that and also issue a warning. +% \cs{reserved@b} so we use that and also issue a warning. % \changes{v3.2j}{2021/06/09}{Improve information message} % \begin{macrocode} \edef\reserved@a{#3}% diff --git a/Master/texmf-dist/source/latex/base/lthooks.dtx b/Master/texmf-dist/source/latex/base/lthooks.dtx index 8f78ecd0c6a..20d48730c48 100644 --- a/Master/texmf-dist/source/latex/base/lthooks.dtx +++ b/Master/texmf-dist/source/latex/base/lthooks.dtx @@ -32,7 +32,7 @@ % % \begin{macrocode} \def\lthooksversion{v1.1f} -\def\lthooksdate{2023/06/16} +\def\lthooksdate{2023/10/02} % \end{macrocode} % %<*driver> @@ -298,10 +298,6 @@ % consumed and any further attempt to add to it will result in % executing the code to be added immediately. % -% The \meta{hook} \emph{cannot} be specified using the dot-syntax. -% A leading |.| is treated literally. See -% section~\ref{sec:default-label} for details. -% % Using \cs{UseOneTimeHook} several times with the same % \Arg{hook} means that it only executes the first time it is used. % For example, if it is used in a command that can be called several times @@ -311,6 +307,11 @@ % Mixing \cs{UseHook} and \cs{UseOneTimeHook} for the same % \Arg{hook} should be avoided, but if this is done then neither will execute % after the first \cs{UseOneTimeHook}. +% +% The \meta{hook} \emph{cannot} be specified using the dot-syntax. +% A leading |.| is treated literally. See +% section~\ref{sec:default-label} for details. +% % \end{function} % % \begin{function}{\UseOneTimeHookWithArguments} @@ -327,6 +328,11 @@ % longer possible to use \cs{AddToHookWithArguments} or similar with % that hook. \cs{AddToHook} continues to work as normal. % Section~\ref{sec:hook-args} explains hooks with arguments. +% +% The \meta{hook} \emph{cannot} be specified using the dot-syntax. +% A leading |.| is treated literally. See +% section~\ref{sec:default-label} for details. +% % \end{function} % % @@ -607,7 +613,10 @@ % \meta{hook} arguments, both in the \LaTeXe{} interface, and the \LaTeX3 % interface described in section~\ref{sec:l3hook-interface}. % -% Note, however, that the replacement of |.| by the \meta{default label} +% Note,\marginpar{\raggedleft\rightskip5pt\itshape \textbf{Important:}\break The dot-syntax +% is \textbf{not} available with +% \cs{UseHook} and some other commands that are typically used within code!} +% however, that the replacement of |.| by the \meta{default label} % takes place when the hook command is executed, so actions that are % somehow executed after the package ends will have the wrong % \meta{default label} if the dot-syntax is used. For that reason, @@ -786,7 +795,7 @@ % \end{itemize} % There can only be a single relation between two labels for a % given hook, -% i.e., a later \cs{DeclareHookrule} overwrites any previous +% i.e., a later \cs{DeclareHookRule} overwrites any previous % declaration. % % The \meta{hook} and \meta{label} can be specified using the @@ -1557,8 +1566,8 @@ % % Generic hooks defined in this way are always normal hooks (i.e., % you can't implement reversed hooks this way). This is a -% deliberate limitation, because it speeds up the processessing -% conciderably. +% deliberate limitation, because it speeds up the processing +% considerably. % % % \subsection{Hooks with arguments} @@ -1997,8 +2006,9 @@ % % \item[\hook{begindocument}] % -% This hook is added to when using \cs{AtBeginDocument} and it is -% executed after the \texttt{.aux} file as be read in and most +% This hook is added to by using \cs{AddToHook}\texttt{\{begindocument\}} +% or by using \cs{AtBeginDocument} and it is +% executed after the \texttt{.aux} file has been read and most % initialization are done, so they can be altered and inspected by % the hook code. It is followed by a small number of further % initializations that shouldn't be altered and are therefore diff --git a/Master/texmf-dist/source/latex/base/ltluatex.dtx b/Master/texmf-dist/source/latex/base/ltluatex.dtx index 135cb630096..6d274ed5c33 100644 --- a/Master/texmf-dist/source/latex/base/ltluatex.dtx +++ b/Master/texmf-dist/source/latex/base/ltluatex.dtx @@ -28,7 +28,7 @@ \ProvidesFile{ltluatex.dtx} % %<*tex> -[2023/01/19 v1.2b +[2023/08/03 v1.2c % % LuaTeX support for plain TeX (core) %<*tex> @@ -1284,6 +1284,7 @@ luatexbase.new_chunkname = new_chunkname % % \begin{macro}{new_luafunction} % \changes{v1.1i}{2018/10/21}{Function added} +% \changes{v1.2c}{2023/07/02}{Ensure existing table entries not overwritten gh/1100} % Much the same as for attribute allocation in Lua. % The optional \meta{name} argument is used in the log if given. % \begin{macrocode} @@ -1291,7 +1292,11 @@ local luafunction_count_name = luafunction_count_name or "e@alloc@luafunction@count" local function new_luafunction(name) tex_setcount("global", luafunction_count_name, - tex_count[luafunction_count_name] + 1) + math.max( + #(lua.get_functions_table()), + tex_count[luafunction_count_name]) + + 1) + lua.get_functions_table()[tex_count[luafunction_count_name]] = false if tex_count[luafunction_count_name] > 65534 then luatexbase_error("No room for a new luafunction register") end @@ -2147,12 +2152,13 @@ luatexbase.uninstall = uninstall % \begin{macro}{mlist_to_hlist} % \changes{v1.1l}{2020/02/02}{|pre/post_mlist_to_hlist| added} % \changes{v1.1y}{2022/08/13}{Use shared\_callback system for pre/post/mlist_to_hlist} +% \changes{v1.2c}{2023/08/03}{Fix callback type of post_mlist_to_hlist_callback} % To emulate these callbacks, the ``real'' |mlist_to_hlist| is replaced by a % wrapper calling the wrappers before and after. % \begin{macrocode} create_callback('pre_mlist_to_hlist_filter', 'list') create_callback('mlist_to_hlist', 'exclusive', node.mlist_to_hlist) -create_callback('post_mlist_to_hlist_filter', 'list') +create_callback('post_mlist_to_hlist_filter', 'reverselist') function shared_callbacks.mlist_to_hlist.handler(head, display_type, need_penalties) local current = call_callback("pre_mlist_to_hlist_filter", head, display_type, need_penalties) if current == false then diff --git a/Master/texmf-dist/source/latex/base/ltmiscen.dtx b/Master/texmf-dist/source/latex/base/ltmiscen.dtx index 801d1e68627..74a9685f1fb 100644 --- a/Master/texmf-dist/source/latex/base/ltmiscen.dtx +++ b/Master/texmf-dist/source/latex/base/ltmiscen.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltmiscen.dtx} - [2022/11/06 v1.2a LaTeX Kernel (Misc. Environments)] + [2023/09/13 v1.2c LaTeX Kernel (Misc. Environments)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltmiscen.dtx} @@ -194,8 +194,8 @@ % \begin{macrocode} % %<*2ekernel|latexrelease> -%\IncludeInRelease{2020/10/01}% -% {\enddocument}{Use Hooks}% +%\IncludeInRelease{2023/11/01}% +% {\enddocument}{check property labels}% \def\enddocument{% % \end{macrocode} % The |\end{document}| hook is executed first. If necessary it can @@ -230,6 +230,10 @@ \let\@setckpt\@gobbletwo \let\@newl@bel\@testdef % \end{macrocode} +% \changes{v1.2b}{2023/09/06}{Test changes of values in \cs{new@label@record}} +% \begin{macrocode} + \let\new@label@record\@kernel@new@label@record@testdef +% \end{macrocode} % \changes{v1.0z}{1995/07/13}{Shorten redefinition of \cs{bibcite} and % \cs{newlabel}} % The previous line is equiv to setting @@ -357,6 +361,67 @@ % \begin{macrocode} % %\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}% +% {\enddocument}{Use Hooks}% +%\def\enddocument{% +% \@kernel@before@enddocument +% \UseOneTimeHook{enddocument}% +% \@kernel@after@enddocument +% \@checkend{document}% +% \clearpage +% \UseOneTimeHook{enddocument/afterlastpage}% +% \@kernel@after@enddocument@afterlastpage +% \begingroup +% \if@filesw +% \immediate\closeout\@mainaux +% \let\@setckpt\@gobbletwo +% \let\@newl@bel\@testdef +% \@tempswafalse +% \makeatletter \@@input\jobname.aux +% \fi +% \UseOneTimeHook{enddocument/afteraux}% +% \UseOneTimeHook{enddocument/info}% +% \endgroup +% \UseOneTimeHook{enddocument/end}% +% \deadcycles\z@\@@end} +%\NewHook{enddocument} +%\NewHook{enddocument/afterlastpage} +%\NewHook{enddocument/afteraux} +%\NewHook{enddocument/info} +%\NewHook{enddocument/end} +%\AddToHook{enddocument/info}[kernel/filelist]{\@dofilelist} +%\AddToHook{enddocument/info}[kernel/warnings]{\@enddocument@kernel@warnings} +%\AddToHook{enddocument/info}[kernel/release]{% +% \let\show@release@info\wlog +% \show@release@info{ ***********}% +% \the\LaTeXReleaseInfo +% \show@release@info{ ***********}} +% +%\DeclareHookRule{enddocument/info}{kernel/release}{before}{kernel/filelist} +%\DeclareHookRule{enddocument/info}{kernel/filelist}{before}{kernel/warnings} +%\def\@enddocument@kernel@warnings{% +% \ifdim \font@submax >\fontsubfuzz\relax +% \@font@warning{Size substitutions with differences\MessageBreak +% up to \font@submax\space have occurred.\@gobbletwo}% +% \fi +% \@defaultsubs +% \@refundefined +% \if@filesw +% \ifx \@multiplelabels \relax +% \if@tempswa +% \@latex@warning@no@line{Label(s) may have changed. +% Rerun to get cross-references right}% +% \fi +% \else +% \@multiplelabels +% \fi +% \ifx \@extra@page@added \relax +% \@latex@warning@no@line{Temporary extra page added at the end. +% Rerun to get it removed}% +% \fi +% \fi +%} +%\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% % {\enddocument}{Use Hooks}% % @@ -496,8 +561,7 @@ \protected\def\protected@file@percent{} % \end{macrocode} % \end{macro} - - +% % \begin{macro}{\add@percent@to@temptokena} % Helper function which is used to inspect a sequence of tokens % (the second argument of \cs{@writefile} and it the last token is @@ -1189,11 +1253,33 @@ % print as the \TeX{}book's space character instead of as blank spaces. % % \begin{macro}{\@vobeyspaces} +% \changes{v1.2b}{2023/06/15}{Support tabs} +% \begin{macro}{\@vobeytabs} +% \changes{v1.2b}{2023/06/14}{Macro added} +% \changes{v1.2c}{2023/09/01}{Provide global definition for active tab} % \begin{macrocode} +% +%\IncludeInRelease{2023/11/01}% +% {\@vobeytabs}{Obeyed tabs}% +%<*2ekernel|latexrelease> {\catcode`\ =\active% -\gdef\@vobeyspaces{\catcode`\ \active\let \@xobeysp}} +\gdef\@vobeyspaces{\catcode`\ \active\let \@xobeysp\@vobeytabs}} +{\catcode`\^^I=\active +\gdef\@vobeytabs{\catcode`\^^I\active\let^^I\@xobeytab}% +\global\let^^I=\space +} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@vobeytabs}{Obeyed tabs}% +%{\catcode`\ =\active% +%\gdef\@vobeyspaces{\catcode`\ \active\let \@xobeysp}} +%\let\@vobeytabs\@undefined +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}{\@xobeysp} % \changes{v1.0z}{1995/07/13}{Use \cs{nobreak}} @@ -1368,44 +1454,8 @@ % \end{macro} % % - -% \begin{macro}{\@setupverbvisiblespace} -% -% In pdf\TeX{} a catcode 12 space will produce the character in -% slot 32 which is assumed to be a visible space character (in a -% typewriter font in OT1 or T1 encoding). In Xe\TeX{} or Lua\TeX{} a -% font in TU encoding is normally used and that has a real space in -% this slot. So what we do in this case is this: we check the -% definition of -% |\verbvisiblespace| and if it is |\asciispace| we assume that the -% char32 can be used (e.g., in pdf\TeX{}). We then redefine -% |\@xobeysp| so that after running |\@vobeyspaces| we get -% characters from slot 32 for each active space. -% -% \changes{v1.1o}{2018/10/11} -% {Provide visible space in \cs{verb*} also for XeTeX and LuaTeX (github/69)} -% \begin{macrocode} -\def\@setupverbvisiblespace{% - \ifx\verbvisiblespace\asciispace - \let\@xobeysp\asciispace - \else -% \end{macrocode} Otherwise we measure the width of a character in -% the mon-spaced current font and place a -% |\verbvisiblespace| into a box of the right width which we are then -% using as the character for a space. By default this will be the space -% character from OT1 cmtt but by changing -% |\verbvisiblespace| one could use, for example, the |\textvisiblespace| -% of the current typewriter font. -% \begin{macrocode} - \setbox\z@\hbox{x}% - \setbox\@verbvisiblespacebox\hbox to\wd\z@{\hss\verbvisiblespace\hss}% - \def\@xobeysp{\leavevmode\copy\@verbvisiblespacebox}% - \fi -} -% \end{macrocode} -% \end{macro} +% ^^A \@setupverbvisiblespace was here % - % \begin{macro}{\@verbvisiblespacebox} % The box to hold the visible space character if it isn't in slot % 32 in the current typewriter font. @@ -1426,6 +1476,8 @@ % check if space is already active---it shouldn't be. % \changes{v1.1o}{2018/10/11} % {Provide visible space in \cs{verb*} also for XeTeX and LuaTeX (github/69)} +% \changes{v1.2b}{2023/06/14} +% {Support visible tabs in \cs{verb*}} % \begin{macrocode} \@namedef{verbatim*}{\@verbatim \@setupverbvisiblespace @@ -1434,8 +1486,6 @@ % \end{macrocode} % \end{environment} % -% -% % \begin{macrocode} % %\EndIncludeInRelease @@ -1452,7 +1502,88 @@ %<*2ekernel> % \end{macrocode} % +% \begin{macro}{\@setupverbvisiblespace} % +% In pdf\TeX{} a catcode 12 space will produce the character in +% slot 32 which is assumed to be a visible space character (in a +% typewriter font in OT1 or T1 encoding). In Xe\TeX{} or Lua\TeX{} a +% font in TU encoding is normally used and that has a real space in +% this slot. So what we do in this case is this: we check the +% definition of +% |\verbvisiblespace| and if it is |\asciispace| we assume that the +% char32 can be used (e.g., in pdf\TeX{}). We then redefine +% |\@xobeysp| so that after running |\@vobeyspaces| we get +% characters from slot 32 for each active space. +% +% \changes{v1.1o}{2018/10/11} +% {Provide visible space in \cs{verb*} also for XeTeX and LuaTeX (github/69)} +% \changes{v1.2b}{2023/06/15} +% {Support visible tabs} +% \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2023/11/01}% +% {\@setupverbvisiblespace}{Setup visible tab for \verb}% +\def\@setupverbvisiblespace{% + \ifx\verbvisiblespace\asciispace + \let\@xobeysp\asciispace + \else +% \end{macrocode} +% Otherwise we measure the width of a character in +% the mono-spaced current font and place a +% |\verbvisiblespace| into a box of the right width which we are then +% using as the character for a space. By default this will be the space +% character from OT1 cmtt but by changing +% |\verbvisiblespace| one could use, for example, the |\textvisiblespace| +% of the current typewriter font. +% \begin{macrocode} + \setbox\z@\hbox{x}% + \setbox\@verbvisiblespacebox\hbox to\wd\z@{\hss\verbvisiblespace\hss}% + \def\@xobeysp{\leavevmode\copy\@verbvisiblespacebox}% + \fi + \@setupverbvisibletab +} +% +%\EndIncludeInRelease +%\IncludeInRelease{2018/12/01}% +% {\@setupverbvisiblespace}{Setup visible space for \verb}% +%\def\@setupverbvisiblespace{% +% \ifx\verbvisiblespace\asciispace +% \let\@xobeysp\asciispace +% \else +% \setbox\z@\hbox{x}% +% \setbox\@verbvisiblespacebox\hbox to\wd\z@{\hss\verbvisiblespace\hss}% +% \def\@xobeysp{\leavevmode\copy\@verbvisiblespacebox}% +% \fi +%} +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@setupverbvisiblespace}{Setup visible space for \verb}% +%\let\@setupverbvisiblespace\@undefined +%\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@setupverbvisibletab} +% \changes{v1.2q}{2023/06/15} +% {Provide visible tab in \cs{verb*}} +% A redirection: just a simple wrapper. +% \begin{macrocode} +% +%\IncludeInRelease{2023/11/01}% +% {\@setupverbvisibletab}{Setup visible tab for \verb}% +%<*2ekernel|latexrelease> +\def\@setupverbvisibletab{\let\@xobeytab\@xobeysp} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@setupverbvisibletab}{Setup visible tab for \verb}% +%\let\@setupverbvisibletab\@undefined +%\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} % % \begin{macro}{\@sverb} % \begin{macro}{\@@sverb} @@ -1464,8 +1595,8 @@ % \begin{macrocode} % %<*2ekernel|latexrelease> -%\IncludeInRelease{2020/10/01}% -% {\@sverb}{Drop spaces before \verb delimiter}% +%\IncludeInRelease{2023/11/01}% +% {\@sverb}{Support visible tabs}% % \end{macrocode} % % If the users types \verb=\verb !~! foo= then surprisingly we would @@ -1496,8 +1627,13 @@ % it the definition for the active space character. % \changes{v1.1o}{2018/10/11} % {Provide visible space in \cs{verb*} also for XeTeX and LuaTeX (github/69)} +% \changes{v1.2b}{2023/06/15} +% {Support visible tabs} % \begin{macrocode} - \ifnum\catcode`\ =\active + \ifnum0% + \ifnum\catcode`\ =\active\else 1\fi + \ifnum\catcode`\^^I=\active\else 1\fi + =0 % \else \@setupverbvisiblespace \@vobeyspaces \fi } % \end{macrocode} @@ -1505,6 +1641,19 @@ % \begin{macrocode} % %\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}% +% {\@sverb}{Drop spaces before \verb delimiter}% +%\def\@@sverb#1{% +% \catcode`#1\active +% \lccode`\~`#1% +% \gdef\verb@balance@group{\verb@egroup +% \@latex@error{\noexpand\verb illegal in argument}\@ehc}% +% \aftergroup\verb@balance@group +% \lowercase{\let~\verb@egroup}% +% \ifnum\catcode`\ =\active +% \else \@setupverbvisiblespace \@vobeyspaces \fi +%} +%\EndIncludeInRelease %\IncludeInRelease{2018/12/01}% % {\@sverb}{Setup visible space for \verb}% % diff --git a/Master/texmf-dist/source/latex/base/ltplain.dtx b/Master/texmf-dist/source/latex/base/ltplain.dtx index 89e5017300f..b41810373d0 100644 --- a/Master/texmf-dist/source/latex/base/ltplain.dtx +++ b/Master/texmf-dist/source/latex/base/ltplain.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltplain.dtx} - [2023/04/15 v2.3i LaTeX Kernel (Plain TeX)] + [2023/10/21 v2.3i LaTeX Kernel (Plain TeX)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltplain.dtx} @@ -1281,7 +1281,7 @@ % \cs{par} with whatever definition \cs{par} has when it is % executed. It can, however, be % redefined (before calling \cs{obeylines}!) to achieve some -% special effects. If you want to alter is definition when already +% special effects. If you want to alter this definition when already % in the scope of \cs{obeylines}, it has no effect (because % \cs{let} is used above). % In that case simply make another call to \cs{obeylines} diff --git a/Master/texmf-dist/source/latex/base/ltproperties.dtx b/Master/texmf-dist/source/latex/base/ltproperties.dtx new file mode 100644 index 00000000000..40c50cd20a2 --- /dev/null +++ b/Master/texmf-dist/source/latex/base/ltproperties.dtx @@ -0,0 +1,966 @@ +% \iffalse meta-comment +% +%% File: ltproperties.dtx +% +% Copyright (C) 2021-2023 The LaTeX Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% http://www.latex-project.org/lppl.txt +% +% This file is part of the LaTeX base system. (The Work in LPPL) +% and all files in that bundle must be distributed together. +% +% ----------------------------------------------------------------------- +% +% The development version of the bundle can be found at +% +% https://github.com/latex3/latex2e +% +% for those people who are interested. +% \begin{macrocode} +\def\ltpropertiesversion{1.0c} +\def\ltpropertiesdate{2023-10-15} +% \end{macrocode} + +%<*driver> +\documentclass[full]{l3doc} +\EnableCrossrefs +\CodelineIndex +\begin{document} + \DocInput{ltproperties.dtx} +\end{document} +% +% \fi +% +% \title{^^A +% Recording and cross-referencing document properties^^A +% \thanks{This module has version +% \ltpropertiesversion\ dated \ltpropertiesdate, \copyright\ The \LaTeX\ +% Project.} +% } +% +% \author{^^A +% The \LaTeX\ Project\thanks +% {^^A +% E-mail: +% \href{mailto:latex-team@latex-project.org} +% {latex-team@latex-project.org}^^A +% }^^A +% } +% +% \maketitle +% +% \begin{documentation} +% \begin{abstract} +% This code implements command to record and (expandably) reference +% document properties. It extends the standard \cs{label}/\cs{ref}/\cs{pageref} +% commands. +% \end{abstract} +% +% \tableofcontents +% +% \section{Introduction} +% +% The module allows to record the \enquote{current state} of various +% document properties (typically the content of macros and values of counters) +% and to access them in other places through a label. +% The list of properties that can be recorded and retrieved +% are not fix and can be extended by the user. The values of the properties +% are recorded in the \texttt{.aux} file and can be retrieved at the second compilation. +% +% +% The module uses the ideas of properties and labels. A label is +% a document reference point: a name for the user. An property is something +% that \LaTeX{} can track, such as a page number, section number or name. +% The names of labels and properties may be arbitrary. Note that there is +% a single namespace for each. +% +% \section{Design discussion} +% +% The design here largely follows ideas from \pkg{zref}. In particular, there +% are two independent concepts: properties that can be recorded between runs, +% and labels which consist of lists of these properties. The reason for the +% split is that individual labels will want to record some but not all +% properties. For examples, a label concerned with position would track +% the $x$ and $y$ co-ordinates of the current point, but not for example +% the page number. +% +% In the current implementation, properties share a single namespace. This +% allows multiple lists to re-use the same properties, for example page number, +% absolute page number, etc. This does mean that \emph{changing} a standard +% property is an issue. However, some properties have complex definitions +% (again, see \pkg{zref} at present): having them in a single shared space +% avoids the need to copy code. +% +% Labels could be implemented as |prop| data. That is not done at present as +% there is no obvious need to map to or copy the data. As such, faster +% performance is available using a hash table approach as in a \enquote{classical} +% set up. Data written to the |.aux| file uses simple paired \emph{balanced +% text} not keyvals: this avoids any restrictions on names and again offers +% increased performance. +% +% The \pkg{expl3} versions of the label command do not +% use \cs{@bsphack}/\cs{@esphack} to avoid double spaces, +% but the \LaTeXe{} command does as it lives at the document command level. +% +% The reference commands are expandable. +% +% Currently the code has nearly no impact on the main \cs{label} and \cs{ref} commands as +% too many external packages rely on the concrete implementation. +% There is one exception: +% the label names share the same namespace. That means that if both |\label{ABC}| and +% |\RecordProperties{ABC}{page}| are used there is a warning +% \texttt{Label `ABC' multiply defined}. +% +% \section{Handling unknown labels and properties} +% With the standard \cs{label}/\cs{ref} commands the requested label is +% either in the |.aux|-file (and so known) or not. +% In the first case the stored value can be used, +% in the second case the reference commands print two question marks. +% +% With flexible property lists a reference commands asks for the +% value of a specific property stored under a label name +% and we have to consider more variants: +% \begin{itemize} +% \item If the requested property is unknown (not declared) the system +% is not correctly set up and an error is issued. +% \item If the label is unknown, the default of the property is used. +% \item If the label is known, but doesn't provide a value for the +% property then again the default of the property is used. +% \item The command |\property_ref:nnn| allows to give a local default +% which is used instead of the property default in the two cases before. +% \end{itemize} +% +% \section{Rerun messages} +% +% As the reference commands are expandable they can neither issue a message that +% the label or the label-property combination is unknown, nor can they trigger the +% rerun message at the end of the \LaTeX{} run. +% +% Where needed such messages must therefore be triggered manually. For this two commands +% are provided: \cs{property_ref_undefined_warn:} and \cs{property_ref_undefined_warn:nn}. +% See below for a description. +% +% \section{Open points} +% +% \begin{itemize} +% \item The \texttt{xpos} and \texttt{ypos} properties require that the position is +% stored first but there is no (public) engine independent interface yet. Code must +% use \cs{tex_savepos:D}. +% \end{itemize} +% +% \section{Code interfaces} +% +% \begin{function}{\property_new:nnnn,\property_gset:nnnn} +% \begin{syntax} +% \cs{property_new:nnnn} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code} +% \cs{property_gset:nnnn} \Arg{property}\Arg{setpoint} \Arg{default} \Arg{code} +% \end{syntax} +% \LaTeXe-interface: see \cs{NewProperty}, \cs{SetProperty}.\\ +% Sets the \meta{property} to have the \meta{default} specified, and at the +% \meta{setpoint} (either |now| or |shipout|) to write the result of the +% \meta{code} as part of a label. The \meta{code} should be expandable. The expansion +% of \meta{code} (the value of the property) is written to the |.aux| file and read +% back from there at the next compilation. Values should assume that the +% standard \LaTeX{} catcode régime with |@| a letter is active then. +% +% If the property is declared within a package it is suggested +% that its name is build from letters, hyphens and slashes, +% and is always structured as follows:\\ +% \meta{package-name}\texttt{/}\meta{property-name}. +% \end{function} +% +% \begin{function} +% { +% \property_record:nN, +% \property_record:nn, \property_record:nV, \property_record:ee +% } +% \begin{syntax} +% \cs{property_record:nN} \Arg{label} \Arg{clist var} +% \cs{property_record:nn} \Arg{label} \Arg{clist} +% \end{syntax} +% \LaTeXe{}-interface: see \cs{RecordProperties}.\\ +% Writes the list of properties given by the \meta{clist} to the |.aux| +% file with the \meta{label} specified. +% \end{function} +% +% \begin{function}[EXP]{\property_ref:nn,\property_ref:ee} +% \begin{syntax} +% \cs{property_ref:nn} \Arg{label} \Arg{property} +% \end{syntax} +% \LaTeXe{}-interface: see \cs{RefProperty}.\\ +% Expands to the value of the \meta{property} for the \meta{label}, if +% available, and the default value of the property otherwise. +% If \meta{property} has not been declared with |\property_new:nnnn| +% an error is issued. The command raises an internal, expandable, local flag +% if the reference can not be resolved. +% \end{function} +% +% \begin{function}[EXP]{\property_ref:nnn,\property_ref:een} +% \begin{syntax} +% \cs{property_ref:nnn} \Arg{label} \Arg{property} \Arg{local default} +% \end{syntax} +% \LaTeXe{}-interface: see \cs{RefProperty}.\\ +% Expands to the value of the \meta{property} for the \meta{label}, if +% available, and to \meta{local default} otherwise. +% If \meta{property} has not been declared with |\property_new:nnnn| +% an error is issued. The command raises an internal, expandable local flag +% if the reference can not be resolved. +% \end{function} +% +% \begin{function}{\property_ref_undefined_warn:} +% \begin{syntax} +% \cs{property_ref_undefined_warn:} +% \end{syntax} +% \LaTeXe{}-interface: not provided.\\ +% The commands triggers the standard warning +% \\ +% \hspace*{1em}\texttt{LaTeX Warning: There were undefined references.} +% \\ +% at the end of the document if there was a recent +% \cs{property_ref:nn} or \cs{property_ref:nnn} which couldn't be resolved +% and so raised the flag. \enquote{Recent} means in the same group +% or in some outer group! +% \end{function} +% +% \begin{function}{\property_ref_undefined_warn:n,\property_ref_undefined_warn:e} +% \begin{syntax} +% \cs{property_ref_undefined_warn:n} \Arg{label} +% \end{syntax} +% \LaTeXe{}-interface: not provided.\\ +% The commands triggers the standard warning\\ +% \hspace*{1em}\texttt{LaTeX Warning: There were undefined references.} +% \\ +% at the end of the document if \meta{label} is not known. +% At the point where it is called it also issues the warning\\ +% \hspace*{1em}% +% \texttt{Reference~`\meta{label}'~on~page~\meta{page}\space undefined}. +% \end{function} +% +% \begin{function}{\property_ref_undefined_warn:nn,\property_ref_undefined_warn:ee} +% \begin{syntax} +% \cs{property_ref_undefined_warn:nn} \Arg{label} \Arg{property} +% \end{syntax} +% \LaTeXe{}-interface: see \cs{RefUndefinedWarn}.\\ +% The commands triggers the standard warning\\ +% \hspace*{1em}% +% \texttt{LaTeX Warning: There were undefined references.}\\ +% at the end of the document if the reference can not be resolved. +% At the point where it is called it also issues the warning\\ +% \hspace*{1em}% +% \texttt{Reference~`\meta{label}'~on~page~\meta{page}\space undefined}\\ +% if the label +% is unknown, or the more specific\\ +% \hspace*{1em}% +% \texttt{Property `\meta{property}' undefined for reference +% `\meta{label}' on page \meta{page}}\\ +% if the label is known but doesn't provide a value for the requested property. +% \end{function} +% +% \begin{function}[pTF]{\property_if_exist:n,\property_if_exist:e} +% \begin{syntax} +% \cs{property_if_exist_p:n} \Arg{property} +% \cs{property_if_exist:nTF} \Arg{property} \Arg{true code} \Arg{false code} +% \end{syntax} +% \LaTeXe{}-interface: \cs{IfPropertyExistTF}.\\ +% Tests if the \meta{property} has been declared. +% \end{function} +% +% \begin{function}[pTF]{\property_if_recorded:n,\property_if_recorded:e} +% \begin{syntax} +% \cs{property_if_recorded_p:n} \Arg{label} +% \cs{property_if_recorded:nTF} \Arg{label} \Arg{true code} \Arg{false code} +% \end{syntax} +% \LaTeXe{}-interface: \cs{IfLabelExistTF}\\ +% Tests if the \meta{label} is known. This is also true if the label has been +% set with the standard \cs{label} command. +% \end{function} +% +% \begin{function}[pTF]{\property_if_recorded:nn,\property_if_recorded:ee} +% \begin{syntax} +% \cs{property_if_recorded_p:nn} \Arg{label} \Arg{property} +% \cs{property_if_recorded:nnTF} \Arg{label} \Arg{property} \Arg{true code} \Arg{false code} +% \end{syntax} +% \LaTeXe{}-interface: \cs{IfPropertyRecordedTF}.\\ +% Tests if the label \meta{label} is known and if it provides a value of the \meta{property}. +% \end{function} +% +% \section{Auxiliary file interfaces} +% +% \begin{function}{\new@label@record} +% \begin{syntax} +% \cs{new@label@record} \Arg{label} \Arg{data} +% \end{syntax} +% This is a command only for use in the |.aux| file. It loads the key--value +% list of \meta{data} to be available for the \meta{label}. +% \end{function} +% +% \section{\LaTeXe{} interface} +% +% The LaTeXe{} interfaces always expand label and property arguments. +% This means that one must be careful when using active chars or commands in the +% names. UTF8-chars are protected and should be safe, similar most babel shorthands. +% +% \begin{function}{\NewProperty,\SetProperty} +% \begin{syntax} +% \cs{NewProperty} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code} +% \cs{SetProperty} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code} +% \end{syntax} +% Sets the \meta{property} to have the \meta{default} specified, and at the +% \meta{setpoint} (either |now| or |shipout|) to write the result of the +% \meta{code} as part of a label. The \meta{code} should be expandable. The expansion +% of \meta{code} (the value of the property) is written to the |.aux| file and read +% back from there at the next compilation (at which point normally +% the standard \LaTeX{} catcode régime with |@| a letter is active). +% +% \end{function} +% +% \begin{function}{\RecordProperties} +% \begin{syntax} +% \cs{RecordProperties} \Arg{label} \Arg{clist} +% \end{syntax} +% Writes the list of properties given by the \meta{clist} to the |.aux| +% file with the \meta{label} specified. Similar to the standard \cs{label} command +% the arguments are expanded. So \meta{clist} can be a macro containing a list +% of properties. Also similar to the standard \cs{label} command, the command is surrounded +% by an \cs{@bsphack}/\cs{@esphack} pair to preserve spacing. +% \end{function} + +% \begin{function}[EXP]{\RefProperty} +% \begin{syntax} +% \cs{RefProperty} \oarg{local default} \Arg{label} \Arg{property} +% \end{syntax} +% Expands to the value of the \meta{property} for the \meta{label}, if +% available, and the default value of the property or -- if given -- +% to \meta{local default} otherwise. +% If \Arg{property} has not been declared an error is issued. +% \end{function} +% +% \begin{function}{\IfPropertyExistTF} +% \begin{syntax} +% \cs{IfPropertyExistTF} \Arg{property} \Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if the \meta{property} has been declared. +% \end{function} +% +% \begin{function}{\IfLabelExistTF} +% \begin{syntax} +% \cs{IfLabelExistTF} \Arg{label} \Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if the \meta{label} has been recorded. This is also true if a label +% has been set with the standard \cs{label} command. +% \end{function} +% +% \begin{function}{\IfPropertyRecordedTF} +% \begin{syntax} +% \cs{IfPropertyRecordedTF} \Arg{label} \Arg{property} \Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if the label and a value of the \meta{property} for the \meta{label} are both known. +% \end{function} + +% \begin{function}{\RefUndefinedWarn} +% \begin{syntax} +% \cs{RefUndefinedWarn} \Arg{label} \Arg{property} +% \end{syntax} +% This commands triggers the standard warning\\ +% \hspace*{1em}% +% \texttt{LaTeX Warning: There were undefined references.}\\ +% at the end of the document if the reference for \meta{label} and \meta{property} +% can not be resolved. +% At the point where it is called it also issues the warning\\ +% \hspace*{1em}% +% \texttt{Reference `\meta{label}' on page \meta{page} undefined}\\ +% if the label is unknown, or the more specific\\ +% \hspace*{1em}% +% \texttt{Property `\meta{property}' undefined for reference +% `\meta{label}' on page \meta{page}} +% if the label is known but doesn't provide a value for the requested property. +% \end{function} +% +% \section{Pre-declared properties} +% +% \begin{variable}{abspage} +% (shipout) The absolute value of the current page: starts at $1$ and increases +% monotonically at each shipout. +% \end{variable} +% +% \begin{variable}{page} +% (shipout) The current page as given by \cs{thepage}: this may or may not +% be a numerical value, depending on the current style. Contrast with +% \cs{abspage}. You get this value also with the standard \cs{label}/\cs{pageref}. +% \end{variable} +% +% \begin{variable}{pagenum} +% (shipout) The current page as arabic number. This is suitable for integer operations and +% comparisions. +% \end{variable} +% +% \begin{variable}{label} +% (now) The content of \cs{@currentlabel}. This is the value that +% you get also with the standard \cs{label}/\cs{ref}. +% \end{variable} +% +% \begin{variable}{title} +% (now) The content of \cs{@currentlabelname}. +% This command is filled beside others by the \pkg{nameref} package and some +% classes (e.g.~\pkg{memoir}). +% \end{variable} +% +% \begin{variable}{target} +% (now) The content of \cs{@currentHref}. +% This command is normally filled by for example +% \pkg{hyperref} and gives the name of the last destination it created. +% \end{variable} +% +% \begin{variable}{pagetarget} +% (shipout) The content of \cs{@currentHpage}. +% This command is filled for example by a recent version of +% \pkg{hyperref} and then gives the name of the last page +% destination it created. +% \end{variable} +% +% \begin{variable}{counter} +% (now) The content of \cs{@currentcounter}. +% This command contains after a \cs{refstepcounter} the name of the counter. +% \end{variable} +% +% \begin{variable}{xpos,ypos} +% (shipout) This stores the $x$~and $y$ coordinates of a point previously +% stored with \cs{pdfsavepos}/\cs{savepos}. +% E.g.~(if bidi is used it can be necessary to save the position +% before and after the label): +% \begin{verbatim} +% \tex_savepos:D +% \property_record:nn{myposition}{xpos,ypos} +% \tex_savepos:D +% \end{verbatim} +% \end{variable} +% \end{documentation} +% +% \begin{implementation} +% +% \section{The Implementation} +% +% \begin{macrocode} +%<*2ekernel|latexrelease> +% \end{macrocode} +% \begin{macrocode} +\ExplSyntaxOn +% \end{macrocode} +% +% \begin{macrocode} +%<@@=property> +% \end{macrocode} +% +% \begin{macrocode} +%\NewModuleRelease{2023/11/01}{ltproperties} +% {Cross-referencing~properties} +% \end{macrocode} +% +% The approach here is based closely on that from \pkg{zref}; separate out +% lists of properties and the properties themselves, so the latter can be +% used multiple times and in varying combinations. +% However, not everything is a straight copy. Firstly, +% we treat lists of properties as simple comma lists: that allows us to have +% either saved or dynamic lists and to avoid another data structure. The cost +% is that errors are detected at point-of-use, but in any real case that should +% be true anyway (and is true for \tn{zref@labelbyprop} already). Secondly, +% we allow properties to have +% arbitrary names, as the code does not require them to tokenize as control +% sequences. +% +% \begin{macro}{\property_new:nnnn, \property_gset:nnnn, \@@_gset:nnnn} +% As properties can be reset, they are not constants. But they also have +% various pieces of required data. So we use the same approach as color and +% make them declarations. Data-wise, we need the detail of the implementation, +% the default and a flag to show if the code works now or at shipout. This +% last entry is done using text so needs a check. We could use a set of +% |prop| here, but as we never need to map or copy the lists, we can gain +% performance using the hash table approach. +% \begin{macrocode} +\cs_new_protected:Npn \property_new:nnnn #1#2#3#4 + { + \cs_if_free:cTF { @@_code_ #1 : } + { + \exp_args:Nx \@@_gset:nnnn { \tl_to_str:n {#1} } + {#2} {#3} {#4} + } + { + \msg_error:nn { property }{ exists }{#1} + } + } +\cs_new_protected:Npn \property_gset:nnnn #1#2#3#4 + { + \@@_gset:ennn { \tl_to_str:n {#1} } + {#2} {#3} {#4} + } +\cs_new_protected:Npn \@@_gset:nnnn #1#2#3#4 + { + \cs_gset:cpn { @@_code_ #1 : } {#4} + \tl_gclear_new:c { g_@@_default_ #1 _tl } + \tl_gset:cn { g_@@_default_ #1 _tl } {#3} + \bool_if_exist:cF { g_@@_shipout_ #1 _tl } + { \bool_new:c { g_@@_shipout_ #1 _tl } } + \str_case:nnF {#2} + { + { now } { { \bool_gset_false:c { g_@@_shipout_ #1 _tl } } } + { shipout } + { \bool_gset_true:c { g_@@_shipout_ #1 _tl } } + } + { \msg_error:nnnn { property } { unknown-setpoint } {#1} {#2} } + } +\cs_generate_variant:Nn \@@_gset:nnnn {ennn} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\NewProperty,\SetProperty} +% For consistency we expand the property name, but this doesn't warant a +% variant of the L3-commands. +% \changes{v1.0c}{2023-09-20}{use \cs{protected@edef}} +% \begin{macrocode} +\cs_new_protected:Npn \NewProperty #1#2#3#4 + { + \protected@edef\reserved@a{#1} + \exp_args:No \property_new:nnnn {\reserved@a} {#2}{#3}{#4} + } +\cs_new_protected:Npn \SetProperty #1#2#3#4 + { + \protected@edef\reserved@a{#1} + \exp_args:No \property_gset:nnnn {\reserved@a} {#2}{#3}{#4} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\property_record:nN} +% \begin{macro} +% { +% \property_record:nn, +% \property_record:nV, +% \property_record:ee, +% \property_record:oo, +% \@@_record:nn, +% \@@_record:en +% } +% \begin{macro}[EXP] +% {\@@_record_value:n, \@@_record_value_aux:n, \@@_record_value_aux:e} +% Writing data when it is labelled means expanding at this stage and possibly +% later too. That is all pretty easy using \pkg{expl3}: we accept a stray +% comma at the end of the list as that is easier to deal with than trying +% to tidy up, and there is no real downside. +% \begin{macrocode} +\cs_new_protected:Npn \property_record:nN #1#2 + { \property_record:nV {#1} #2 } +\cs_new_protected:Npn \property_record:nn #1#2 + { \@@_record:en { \tl_to_str:n {#1} } {#2} } +\cs_generate_variant:Nn \property_record:nn { nV , ee, oo } +\cs_new_protected:Npn \@@_record:nn #1#2 + { + \legacy_if:nT { @filesw } + { + \iow_shipout_x:Nx \@auxout + { + \token_to_str:N \new@label@record + {#1} + { \clist_map_function:nN {#2} \@@_record_value:n } + } + } + } +\cs_generate_variant:Nn \@@_record:nn { e } +\cs_new:Npn \@@_record_value:n #1 + { \@@_record_value_aux:e { \tl_to_str:n {#1} } } +\cs_new:Npn \@@_record_value_aux:n #1 + { + \cs_if_exist:cTF { @@_code_ #1 : } + { + {#1} + { + \bool_if:cTF { g_@@_shipout_ #1 _tl } + { \exp_not:c } + { \use:c } + { @@_code_ #1 : } + } + } + { \msg_expandable_error:nnn { property } { not-declared } {#1} } + } +\cs_generate_variant:Nn \@@_record_value_aux:n { e } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\RecordProperties} +% \changes{v1.0c}{2023-09-20}{use \cs{protected@edef} for safer handling of active chars.} % +% \begin{macrocode} +\NewDocumentCommand\RecordProperties { m m } + { + \@bsphack + \protected@edef\reserved@a{#1} + \protected@edef\reserved@b{#2} + \property_record:oo {\reserved@a}{\reserved@b} + \@esphack + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Reference commands} +% +% \begin{variable}{ l_@@_ref_flag } +% A flag that is set if a reference couldn't be resolved. +% \begin{macrocode} +\flag_new:n { l_@@_ref_flag } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[EXP]{\property_ref:nn,\property_ref:ee} +% Search for the label/property combination, and if not found fall back +% to the default of the property. +% \begin{macrocode} +\cs_new:Npn \property_ref:nn #1#2 + { + \@@_ref:een + { \tl_to_str:n {#1} } + { \tl_to_str:n {#2} } + { \tl_use:c { g_@@_default_ #2 _tl } } + } +\cs_generate_variant:Nn \property_ref:nn {ee} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP]{\property_ref:nnn,\property_ref:een, \@@_ref:nnn, \@@_ref:een} +% This allows to set a local default value which overrides the default value +% of the property. +% \begin{macrocode} +\cs_new:Npn \property_ref:nnn #1#2#3 + { + \@@_ref:een + { \tl_to_str:n {#1} } + { \tl_to_str:n {#2} } + {#3} + } +\cs_new:Npn \@@_ref:nnn #1#2#3 + { + \tl_if_exist:cTF { g_@@_label_ #1 _ #2 _tl } + { \tl_use:c { g_@@_label_ #1 _ #2 _tl } } + { + \flag_if_raised:nF + { l_@@_ref_flag } { \flag_raise:n { l_@@_ref_flag } } +% \end{macrocode} +% We test for the default of the property only to check if the property has +% been declared. +% \begin{macrocode} + \tl_if_exist:cTF { g_@@_default_ #2 _tl } + { #3 } + { \msg_expandable_error:nnn { property } { not-declared } {#2} } + } + } +\cs_generate_variant:Nn \@@_ref:nnn { ee } +\cs_generate_variant:Nn \property_ref:nnn {een} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP]{\RefProperty} +% Search for the label/property combination, and if not found fall back +% to the default of the property or the given default. +% \begin{macrocode} +\NewExpandableDocumentCommand \RefProperty { o m m } + { + \IfNoValueTF {#1} + { + \property_ref:ee {#2}{#3} + } + { + \property_ref:een {#2}{#3}{#1} + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\new@label@record} +% \begin{macro}{\@@_data:nnn} +% A standard recursion loop. +% \begin{macrocode} +\cs_new_protected:Npn \new@label@record #1#2 + { + \tl_if_exist:cTF { r@#1 } + { + \gdef \@multiplelabels + { \@latex@warning@no@line { There~were~multiply-defined~labels } } + \@latex@warning@no@line { Label~`#1'~multiply~defined } + } + { + \tl_new:c { r@#1 } + \tl_gset:cn { r@#1 }{#2} + } + \@@_data:nnn {#1} #2 { \q_recursion_tail } { ? } \q_recursion_stop + } +\cs_new_protected:Npn \@@_data:nnn #1#2#3 + { + \quark_if_recursion_tail_stop:n {#2} + \tl_gclear_new:c { g_@@_label_ \tl_to_str:n {#1} _ \tl_to_str:n {#2} _tl } + \tl_gset:cn { g_@@_label_ \tl_to_str:n {#1} _ \tl_to_str:n {#2} _tl } {#3} + \@@_data:nnn {#1} + } +% \end{macrocode} +% +% This command is used in \cs{enddocument} to test if some label values have changed. +% \begin{macrocode} +\cs_new_protected:Npn \@kernel@new@label@record@testdef #1 #2 + { + \tl_if_eq:cnF { r@#1 } {#2} + { \@tempswatrue } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Tests and warnings} +% +% \begin{macro}[pTF]{\property_if_exist:n} +% Tests if property has been declared. +% \begin{macrocode} +\prg_new_conditional:Npnn \property_if_exist:n #1 { p , T , F, TF } + % #1 property + { + \cs_if_exist:cTF { @@_code_ #1 : } + { + \prg_return_true: + } + { + \prg_return_false: + } + } +\prg_generate_conditional_variant:Nnn \property_if_exist:n {e} {TF} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{IfPropertyExistTF} +% \begin{macrocode} +\cs_new_eq:NN \IfPropertyExistTF \property_if_exist:eTF +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[pTF]{\property_if_recorded:n} +% Tests if the label has been set. +% This can then be used to setup e.g.~rerun messages. +% \begin{macrocode} +\prg_new_conditional:Npnn \property_if_recorded:n #1 { p , T , F, TF } + % #1 label + { + \tl_if_exist:cTF { r@#1 } + { + \prg_return_true: + } + { + \prg_return_false: + } + } +\prg_generate_conditional_variant:Nnn \property_if_recorded:n {e} {TF} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IfLabelExistTF} +% \begin{macrocode} +\cs_new_eq:NN \IfLabelExistTF \property_if_recorded:eTF +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[pTF]{\property_if_recorded:nn} +% tests if the label/property combination has been set +% This can then be used to setup e.g.~rerun messages. +% \begin{macrocode} +\prg_new_conditional:Npnn \property_if_recorded:nn #1#2 { p , T , F, TF } + % #1 label #2 property + { + \tl_if_exist:cTF { g_@@_label_ \tl_to_str:n {#1} _ \tl_to_str:n {#2} _tl } + { + \prg_return_true: + } + { + \prg_return_false: + } + } +\prg_generate_conditional_variant:Nnn \property_if_recorded:nn {ee} {TF} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IfPropertyRecordedTF} +% \begin{macrocode} +\cs_new_eq:NN \IfPropertyRecordedTF \property_if_recorded:eeTF +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\property_ref_undefined_warn:} +% \cs{G@refundefinedtrue} is defined in \texttt{ltxref} and redefines a warning message. +% \begin{macrocode} +\cs_new_protected:Npn \property_ref_undefined_warn: + { + \flag_if_raised:nT { l_@@_ref_flag } + { + \G@refundefinedtrue + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\property_ref_undefined_warn:n} +% \begin{macrocode} +\cs_new_protected:Npn \property_ref_undefined_warn:n #1 %#1 label + { + \property_if_recorded:nF {#1} + { + \G@refundefinedtrue + \@latex@warning{Reference~`#1'~on~page~\thepage\space undefined}% + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\property_ref_undefined_warn:nn, +% \property_ref_undefined_warn:ee, +% \RefUndefinedWarn} +% \begin{macrocode} +\cs_new_protected:Npn \property_ref_undefined_warn:nn #1#2 %#1 label, #2 property + { + \property_if_recorded:nTF {#1} + { + \property_if_recorded:nnF {#1}{#2} + { + \G@refundefinedtrue + \@latex@warning + { Property~`#2'~undefined~for~reference~`#1'~on~page~\thepage } + } + } + { + \G@refundefinedtrue + \@latex@warning { Reference~`#1'~on~page~\thepage\space undefined }% + } + } +\cs_generate_variant:Nn \property_ref_undefined_warn:nn {ee} +\cs_set_eq:NN \RefUndefinedWarn \property_ref_undefined_warn:ee +% \end{macrocode} +% \end{macro} +% +% \subsection{Predeclared properties} +% +% \begin{variable}{abspage} +% \begin{macrocode} +\property_new:nnnn { abspage } { shipout } + { 0 } { \int_use:N \g_shipout_readonly_int } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{page} +% \begin{macrocode} +\property_new:nnnn { page } { shipout } { 0 } { \thepage } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{pagenum} +% \begin{macrocode} +\property_new:nnnn { pagenum } { shipout } { 0 } { \the \value { page } } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{label} +% \begin{macrocode} +\property_new:nnnn { label } { now } { ?? } { \@currentlabel } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{title} +% \begin{macrocode} +\property_new:nnnn { title } { now } + { \exp_not:n { \textbf { ?? } } } { \@currentlabelname } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{target} +% \begin{macrocode} +\property_new:nnnn { target } { now } { } { \@currentHref } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{target} +% \begin{macrocode} +\newcommand\@currentHpage{} +\property_new:nnnn { pagetarget } { shipout } { } { \@currentHpage } +% \end{macrocode} +% \end{variable} + +% \begin{variable}{counter} +% \begin{macrocode} +\property_new:nnnn { counter } { now } { } { \@currentcounter } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{xpos,ypos} +% \begin{macrocode} +\property_new:nnnn { xpos } { shipout } { 0} { \int_use:N \tex_lastxpos:D } +\property_new:nnnn { ypos } { shipout } { 0} { \int_use:N \tex_lastypos:D } +% \end{macrocode} +% \end{variable} +% +% \subsection{Messages} +% \begin{macrocode} +\msg_new:nnnn { property } { exists } + { Property~'#1'~ has~ already~ been~ declared. } + { There~ already~ exists~ a~ property~ declaration~ with~ this~ + name.\\ + Please~ use~ a~ different~ name~ for~ your~ property.} + +\msg_new:nnnn { property } { not-declared } + { Property~'#1'~not~declared. } + { + LaTeX~has~been~asked~to~use~property~'#1',~but~this~ + name~has~not~been~declared. + } +\msg_new:nnnn { property } { unknown-setpoint } + { Unknown~keyword~'#2'~for~setting~property~'#1'. } + { + LaTeX~has~been~asked~to~set~the~property~'#1',~but~the~keyword~ + '#2'~is~not~one~of~the~two~known~values:~'now'~or~'shipout'. + } +% \end{macrocode} +% +% \begin{macrocode} +% +%\IncludeInRelease{0000/00/00}{ltproperties} +% {cross-referencing~properties~(undo)}% +% +%\let \NewProperty \@undefined +%\let \SetProperty \@undefined +% +%\let \RecordProperties \@undefined +%\let \RefProperty \@undefined +%\let \RefUndefinedWarn \@undefined +% +%\let \IfPropertyExistTF \@undefined +%\let \IfLabelExistTF \@undefined +%\let \IfPropertyRecordedTF \@undefined +% +%\let\new@label@record \@undefined +%\let\@kernel@new@label@record@testdef\@undefined +%\EndModuleRelease +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% \begin{macrocode} +% +% \end{macrocode} +% +% Reset module prefix: +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% +% \end{implementation} +% +% \Finale diff --git a/Master/texmf-dist/source/latex/base/ltsockets.dtx b/Master/texmf-dist/source/latex/base/ltsockets.dtx new file mode 100644 index 00000000000..7d2940f454b --- /dev/null +++ b/Master/texmf-dist/source/latex/base/ltsockets.dtx @@ -0,0 +1,1069 @@ +% \iffalse meta-comment +% +% Copyright (C) 2023 +% Frank Mittelbach, The LaTeX Project +% +% This file is part of the LaTeX base system. +% ------------------------------------------- +% +% It may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3c +% of this license or (at your option) any later version. +% The latest version of this license is in +% https://www.latex-project.org/lppl.txt +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008 or later. +% +% This file has the LPPL maintenance status "maintained". +% +% The list of all files belonging to the LaTeX base distribution is +% given in the file `manifest.txt'. See also `legal.txt' for additional +% information. +% +% The list of derived (unpacked) files belonging to the distribution +% and covered by LPPL is defined by the unpacking scripts (with +% extension .ins) which are part of the distribution. +% +% \fi +% +% \iffalse +% +%%% From File: ltsockets.dtx +% +% \begin{macrocode} +\def\ltsocketsversion{0.9a} +\def\ltsocketsdate{2023-08-21} +% \end{macrocode} +% +%<*driver> +\documentclass{l3doc} + + +\providecommand\InternalDetectionOff{} +\providecommand\InternalDetectionOn{} + +\EnableCrossrefs +\CodelineIndex +\begin{document} + \DocInput{ltsockets.dtx} +\end{document} +% +% +% \fi +% +% +% +% +% \title{\LaTeX{}'s socket management\thanks{This module has version +% \ltsocketsversion\ dated \ltsocketsdate, \copyright\ \LaTeX\ +% Project.}} +% +% \author{Frank Mittelbach} +% +% \maketitle +% +% ^^A this needs some cleanup: +% \long\def\fmi#1{\begin{quote} TODO: \itshape #1\end{quote}} +% +% \providecommand\pkg[1]{\texttt{#1}} +% \providecommand\hook[1]{\texttt{#1}} +% \providecommand\env[1]{\texttt{#1}} +% \providecommand\plug[1]{\texttt{#1}} +% \providecommand\socket[1]{\texttt{#1}} +% +% +% \begin{abstract} +% This code implements sockets which are places in the code into +% which predeclared chunks of code (plugs) can be placed. Both the sockets +% and the plugs are \enquote{named} and each socket is +% assigned exactly one plug at any given time. +% \end{abstract} +% +% \tableofcontents +% +% \section{Introduction} +% +% A \LaTeX{} source file is transformed into a typeset document by +% executing code for each command or environment in the document +% source. Through various steps this code transforms the input and +% eventually generates typeset output appearing in a \enquote{galley} +% from which individual pages are cut off in an asyncronous way. This +% page generating process is normally not directly associated with +% commands in the input\footnote{Excepts for directives such as +% \cs{newpage}.} but is triggered whenever the galley has received +% enough material to form another page (giving current settings). +% +% As part of this transformation input data may get stored in some form +% and later reused, for example, as part of the output routine +% processing. +% +% \section{Configuration of the transformation process} +% +% There are three different major methods offered by \LaTeX{} to +% configure the transformation process: +% \begin{itemize} +% \item through the template mechanism, +% \item through the hook mechanism, or +% \item through sockets and plugs. +% \end{itemize} +% They offer different possibilities (with different features and +% limitations) and are intended for specific use cases, though it is +% possible to combine them. +% +% \subsection{The template mechanism} +% +% The template mechanism is intended for more complex document-level +% elements (e.g., headings such as \verb=\section= or environments like +% \env{itemize}). The template code implements the overall processing +% logic for such an element and offers a set of parameters to influence +% the final result. +% +% The document element is then implemented by (a) selecting a suitable +% template (there may be more than one available for the kind of +% document element) and (b) by setting its parameters to desired +% values. This then forms a so-called instance which is executed when +% the document element is found in the source. +% +% By altering the parameter values (in a document class or in the +% document preamble) or, if more drastic layout changes are desired, by +% selecting a different template and then adjusting its parameters, a +% wide variety of layouts can be realized through simple configuration +% setups without the need to develop new code. +% +% The target audience of this method are therefore document class +% developers or users who wish to alter an existing layout (implemented +% by a document class) in certain (minor) ways. +% +% The template mechanism is currently documented as part of the +% \pkg{xtemplate} package and one more elaborate implementation can be +% found as part of the \texttt{latex-lab} code for lists (to be +% documented further). +% +% \subsection{The hook mechanism} +% +% Hooks are places in the kernel code (or in packages) that offer +% packages the possibility to inject additional code at specific +% points in the processing in a controlled way without the need to +% replace the existing code block (and thereby overwriting +% modifications/extensions made by other packages). The target +% audience is therefore mainly package developers, even though some +% hooks can be useful for document authors. +% +% Obviously, what can reasonably be added into a hook depends on the +% individual hook (hopefully documented as part of the hook +% documentation), but in general the idea behind hooks is that more +% than one package could add code into the hook at the same +% time. Perhaps the most famous hook (that \LaTeX{} had for a very +% long time) is \hook{begindocument} into which many packages add code +% to through \cs{AtBeginDocument}\marg{code} (which is nowadays +% implemented as a shorthand for +% \cs{AddToHook}\texttt{\{\hook{begindocument}\}}\marg{code}). To +% resolve possible conflicts between injections by different packages +% there is a rule mechanism by which code chunks in a hook can be +% ordered in a certain way and by which incompatible packages can be +% detected if a resolution is impossible. +% +% In contrast to template code, there is no standard configuration +% method through parameters for hooks, i.e., the code added to a hook +% \enquote{is} the configuration. If it wants to provide for +% configuration through parameters it has to also provide its own +% method to set such parameters in some way. However, in that case it +% is likely that using a hook is not the right approach and the +% developer better calls a template instance instead which then offers +% configuration through a key/value interface. +% +% In most cases, hooks do not take any arguments as input. Instead, the data +% that they can (and are allowed to) access depends on the surrounding +% context. +% +% For example, the various hooks available during the page shipout +% process in \LaTeX's output routine can (and have to) access the +% accumulated page material stored in a box named +% \verb=\ShipoutBox=. This way, code added to, say, the +% \hook{shipout/before} hook could access the page content, alter it, +% and then write it back into \verb=\ShipoutBox= and any other code +% added to this hook could then operate on the modified content. Of +% course, for such a scheme to work the code prior to executing the hook +% would need to setup up data in appropriate places and the hook +% documentation would need to document what kind of storage can be +% accessed (and possibly altered) by the hook. +% +% There are also hooks that take arguments (typically portions of +% document data) and in that case the hook code can access these +% arguments through \verb=#1=, \verb=#2=, etc. +% +% The hook mechanism is documented in \texttt{lthooks-doc.pdf}. +% +% +% +% \subsection{The socket mechanism} +% +% In some cases there is code that implements a certain programming +% logic (for example, combining footnotes, floats, and the text for the +% current page to be shipped out) and if this logic should change (e.g., +% footnotes to be placed above bottom floats instead of below) then this +% whole code block needs to be replaced with different code. +% +% In theory, this could be implemented with templates, i.e., the code +% simply calls some instance that implements the logic and that instance +% is altered by selecting a different templates and/or adjusting their +% parameters. However, in many cases customization through parameters is +% overkill in such a case (or otherwise awkward, because paramerization +% is better done on a higher level instead of individually for small +% blocks of code) and using the template mechanism just to replace one +% block of code with a different one results in a fairly high +% performance hit. It is therefore usually not a good choice. +% +% In theory, it would also be possible to use a hook, but again that is +% basically a misuse of the concept, because in this use case there should +% never be more than one block of code inside the hook; thus, to alter +% the processing logic one would need to set up rules that replace code +% rather than (as intended) execute all code added to the hook. +% +% +% +% For this reason \LaTeX{} now offers a third mechanism: +% \enquote{sockets} into which one can place exactly one code block +% --- a \enquote{plug}. +% +% In a nutshell: instead of having a fixed code block somewhere as part +% of the code, implementing a certain programming logic there is a +% reference to a named socket at this point. +% This is done by first declaring the named socket with: +% \begin{quote} +% \cs{NewSocket}\marg{socket-name}\marg{number-of-inputs} +% \end{quote} +% This is then referenced at the point where the replaceable code block +% should be executed with: +% \begin{quote} +% \cs{UseSocket}\marg{socket-name} +% \end{quote} +% or, if the socket should take a number of inputs (additional +% arguments beside the name) with +% \begin{quote} +% \cs{UseSocket}\marg{socket-name}\marg{arg\textsubscript{1}}\ldots +% \marg{arg\textsubscript{\meta{number-of-inputs}}} +% \end{quote} +% +% In addition, several code blocks (a.k.a.\ plugs) implementing different logic for this +% socket are set up, each with a declaration of the form: +% \begin{quote} +% \cs{NewSocketPlug}\marg{socket-name}\marg{socket-plug-name}\marg{code} +% \end{quote} +% Finally, +% one of them is assigned to the socket: +% \begin{quote} +% \cs{AssignSocketPlug}\marg{socket-name}\marg{socket-plug-name} +% \end{quote} +% If the programming logic should change, then all that is necessary is +% to make a new assignment with \cs{AssignSocketPlug} to a different +% \marg{socket-plug-name}. This assignment obeys scope so that an +% environment can alter a socket without the need to restore the +% previous setting manually. +% +% If the socket takes inputs, then those need to be provided to +% \cs{UseSocket} and in that case they can be referenced in the \meta{code} +% argument of \cs{NewSocketPlug} with \verb=#1=, \verb=#2=, etc. +% +% In most cases a named socket is used only in a single place, but there +% is, of course, nothing wrong with using it in several places, as long +% as the code in all places is supposed to change in the same way. +% +% +% +% +% +% \subsubsection{Examples} +% +% +% We start by declaring a new socket named \socket{foo} that expects +% two inputs: +%\begin{verbatim} +% \NewSocket{foo}{2} +%\end{verbatim} +% \NewSocket{foo}{2} +% +% Such a declaration has do be unique across the whole \LaTeX{} +% run. Thus, if another package attempts to use the same name +% (regardless of the number of inputs) it will generate an error: +%\begin{verbatim} +% \NewSocket{foo}{2} +% \NewSocket{foo}{1} +% \end{verbatim} +% Both declarations would therefore produce: +% \begin{verbatim} +% ! LaTeX socket Error: Socket 'foo' already declared! +%\end{verbatim} +% +% You also get an error if you attempt to declare some socket plug and +% the socket name is not yet declared, e.g., +%\begin{verbatim} +% \NewSocketPlug{baz}{undeclared}{some code} +%\end{verbatim} +% generates +%\begin{verbatim} +% ! LaTeX socket Error: Socket 'baz' undeclared! +%\end{verbatim} +% +% +% Setting up plugs for the socket is done like this: +%\begin{verbatim} +% \NewSocketPlug{foo}{plug-A} +% {\begin{quote}\itshape foo-A: #1!#2\end{quote}} +% \NewSocketPlug{foo}{plug-B} +% {\begin{quote}\sffamily foo-B: #2\textsuperscript{2}\end{quote}} +%\end{verbatim} +% This will set up the plugs \texttt{plug-A} and \texttt{plug-B} for +% this socket. +% +%\NewSocketPlug{foo}{plug-A}{\begin{quote}\itshape foo-A: #1!#2\end{quote}} +%\NewSocketPlug{foo}{plug-B}{\begin{quote}\sffamily foo-B: #2\textsuperscript{2}\end{quote}} +% +% We still have to assign one or the other to the socket, thus without +% doing that the line +% \begin{verbatim} +% \UseSocket{foo}{hello}{world} +% \end{verbatim} +% produces nothing because the default plug for sockets with 2 inputs +% is \plug{noop} (which grabs the additional arguments and throws them +% away).\footnote{If socket \socket{foo} would have been a socket with one +% input, then the default plug would be \plug{identity}, in which case +% the socket input would remain without braces and gets typeset!} +% +% \UseSocket{foo}{hello}{world} ^^A nothing happens +% +% So let's do the assignment +% \begin{verbatim} +% \AssignSocketPlug{foo}{plug-A} +% \end{verbatim} +% and then +% \begin{verbatim} +% \UseSocket{foo}{hello}{world} +% \end{verbatim} +% will properly typeset +% \AssignSocketPlug{foo}{plug-A}\UseSocket{foo}{hello}{world} +% and after +% \begin{verbatim} +% \AssignSocketPlug{foo}{plug-B} +% \end{verbatim} +% and another call to +% \begin{verbatim} +% \UseSocket{foo}{hello}{world} +% \end{verbatim} +% we get +% \AssignSocketPlug{foo}{plug-B}\UseSocket{foo}{hello}{world} +% +% If we attempt to assign a plug that was not defined, e.g., +% \begin{verbatim} +% \AssignSocketPlug{foo}{plug-C} +% \end{verbatim} +% then we get an error during the assignment +% \begin{verbatim} +% ! LaTeX socket Error: Plug 'plug-C' for socket 'foo' undeclared! +% \end{verbatim} +% and the previous assignment remains in place. +% +% To see what is known about a socket and its plugs you can use +% \cs{ShowSocket} or \cs{LogSocket} which displays information similar +% to this on the terminal or in the transcript file: +% \begin{verbatim} +% Socket foo: +% number of inputs = 2 +% available plugs = noop, plug-A, plug-B +% current plug = plug-B +% definition = \protected\long macro:#1#2->\begin {quote}\sffamily +% foo-B: #2\textsuperscript {2}\end {quote} +% \end{verbatim} +% \LogSocket{foo} +% +% +% \subsubsection{Details and semantics} +% +% In this section we collect some normative statements. +% +% \begin{itemize} +% +% \item +% From a functional point of view sockets are like simple \TeX{} macros, +% i.e., they expect 0 to 9 mandatory arguments (the socket inputs) and get replaced by +% their \enquote{expansion} +% +% \item +% A socket is \enquote{named} and the name consists of ASCII letters +% \texttt{[a-z]}, +% \texttt{[A-Z]}, \texttt{[0-9]}, \texttt{[-/@]} only +% +% \item +% Socket names have to be unique, i.e., there can be only one socket +% named \meta{name}. This is ensured by declaring each socket with +% \cs{NewSocket}. +% +% However, there is no requirement that sockets and +% hook names have to be different. In fact, if a certain action that +% could overwise be specified as hook code has to be executed always +% last (or first) one could ensure this by placing a socket (single +% action) after a hook (or vice versa) and using the same name to +% indicate the relationship, e.g., +%\begin{verbatim} +% \UseHook{foo} % different package can add code here +% \UseSocket{foo} % only one package can assign a plug +%\end{verbatim} +% This avoids the need to order the hook code to ensure that +% something is always last. +% +% \item +% Best practice naming conventions are \ldots\ \emph{to be documented} +% +% \item +% A socket has documented inputs which are +% +% \begin{itemize} +% \item +% the positional arguments (if any) with a description of what +% they contain when used +% +% \item +% implicit data (registers and other 2e/expl3 data stores) that +% the socket is allowed to make use of, with a documented description +% of what they contain (if relevant for the task at hand---no need to +% describe the whole \LaTeX{} universe) +% +% \item +% information about the state of the \TeX{} engine (again when +% relevant), e.g. is called in mmode or vmode or in the output routine or \ldots +% +% \item +% \ldots\ \empty{anything missing?} +% \end{itemize} +% +% +% \item +% A socket has documented results/outputs which can be +% +% \begin{itemize} +% \item +% what kind of data it should write to the current list (if that +% is part of its task) +% +% \item +% what kind of registers and other 2e/expl3 data stores it should +% modify and in what way +% +% \item +% what kind of state changes it should do (if any) +% +% \item +% \emph{\ldots\ anything else?} +% \end{itemize} +% +% \item +% +% At any time a socket has one block of code (a plug \iffalse(\fi:-)\,) +% associated with it. Such code is itself named and the association +% is done by linking the socket name to the code name (putting a +% plug into the socket). +% +% \item +% +% The name of a plug consists of ASCII letters \texttt{[a-z]}, +% \texttt{[A-Z]}, \texttt{[0-9]}, \texttt{[-/@]} only. +% +% \item +% Socket plug names have to be unique within on a per socket basis, +% but it is perfectly allowed (and sensible in some cases) to use +% the same plug name with different sockets (where based on the +% sockets' purposes, different actions may be associated with the plug +% name). For example \plug{noop} is a plug name declared for every +% socket, yet it action \enquote{grab the socket inputs and throw +% them away} obviously differs depending on how many inputs the +% socket has. +% +% \item +% +% When declaring a plug it is stated for which socket it is meant +% (i.e., its code can only be used with that socket). This means +% that the same plug name can be used with different sockets +% referring to different code in each case. +% +% \item +% Configuration of a socket can only be done by +% linking different code to it. Nevertheless the code linked to it can +% provide its own means of configuration (but this is outside of the +% spec). +% +% \item +% Technically execution of a socket (\cs{UseSocket}) involves +% +% \begin{itemize} +% \item +% doing any house keeping (like writing debugging info, \ldots); +% +% \item +% looking up the current code association (what plug is in the socket); +% +% \item +% executing this code which will pick up the mandatory arguments +% (happens at this point, not +% before), i.e., it is like calling a csname defined with +% \begin{verbatim} +% \def\foo#1#2...{...#1...#2...} +% \end{verbatim} +% +% \item +% do some further house keeping (if needed). +% \end{itemize} +% +% \item +% A socket is typically only used in one place in code, but this is not +% a requirement, i.e., if the same operation with the same inputs need +% to be carried out in several places the same named socket can be used. +% +% \end{itemize} +% +% +% +% +% +% \subsubsection{Command syntax} +% +% We give both the \LaTeXe{} and the L3 programming layer command names. +% +% \begin{function}{\NewSocket,\socket_new:nn} +% \begin{syntax} +% \cs{NewSocket} \Arg{socket-name}\Arg{number-of-inputs} +% \cs{socket_new:nn}\Arg{socket-name}\Arg{number-of-inputs} +% \end{syntax} +% Declares a new socket with name \meta{socket-name} having +% \meta{number-of-inputs} inputs. There is automatically a +% plug \plug{noop} declared for it, which does nothing, i.e., it gobbles +% the socket inputs (if any). This is made the default plug except for +% sockets with one input which additionally define the plug +% \plug{identity} and assign that as their default. +% +% This \plug{identity} plug simply returns the socket input without +% its outer braces. +% The use case for this plug are situations like this: +% \begin{quote} +% \cs{UseSocket}\verb={tagsupport/footnote}=\Arg{code} +% \end{quote} +% If tagging is not active and the socket contains the plug \plug{identity} +% then this returns \meta{code} without the outer braces and to +% activate tagging all that is necessary is to change the plug to +% say \plug{tagpdf} so +% that it surrounds \meta{code} by some tagging magic. +% This is the most common use case for sockets with one input, which +% is why they have this special default. +% +% The socket documentation should describe its purpose, its inputs and the +% expected results as discussed above. +% +% The declaration is only allowed at top-level, i.e., not inside a group. +% \end{function} +% +% +% \begin{function}{\NewSocketPlug,\socket_new_plug:nnn,\socket_set_plug:nnn} +% \begin{syntax} +% \cs{NewSocketPlug} \Arg{socket-name}\Arg{socket-plug-name}\Arg{code} +% \cs{socket_new_plug:nnn}\Arg{socket-name}\Arg{socket-plug-name}\Arg{code} +% \cs{socket_set_plug:nnn}\Arg{socket-name}\Arg{socket-plug-name}\Arg{code} +% \end{syntax} +% Declares a new plug for socket \meta{socket-name} that runs +% \meta{code} when executing. It complains if the plug was already +% declared previously. +% +% The form \cs{socket_set_plug:nnn} changes an existing plug. As +% this should normally not be necessary, we currently have only an L3 +% layer name for the few cases it might be useful. +% +% The declarations can be made inside a group and obey scope, i.e., +% they vanish if the group ends. +% \end{function} +% +% +% \begin{function}{\AssignSocketPlug,\socket_assign_plug:nn} +% \begin{syntax} +% \cs{AssignSocketPlug} \Arg{socket-name}\Arg{socket-plug-name} +% \cs{socket_assign_plug:nn}\Arg{socket-name}\Arg{socket-plug-name} +% \end{syntax} +% Assigns the plug \meta{socket-plug-name} to the socket +% \meta{socket-name}. It errors if either socket or plug is not +% defined. +% +% The assignment is local, i.e., it obeys scope. +% \end{function} +% +% +% \begin{function}{\UseSocket,\socket_use:nw,\socket_use:n,\socket_use:nn,\socket_use:nnn,\socket_use:nnnn} +% \begin{syntax} +% \cs{UseSocket} \Arg{socket-name} +% \cs{socket_use:nnn}\Arg{socket-name} \Arg{socket-arg\textsubscript{1}} \Arg{socket-arg\textsubscript{2}} +% \end{syntax} +% Executes the socket \meta{socket-name} by retrieving the +% \meta{code} of the current plug assigned to the socket. This is +% the only command that would appear inside macro code in packages. +% +% For performance reasons there is no explicit check that the socket +% was declared! +% +% The different L3 programming layer commands are really doing the +% same thing: they grab as many arguments as defined as inputs for the socket +% and then pass them to the plug. The different names are only there +% to make the code more readable, i.e., to indicate how many +% arguments are grabbed in total (note that no runtime check is made to +% verify that this is actually true). We only provide them for +% sockets with up to 3 inputs (most likely those with zero or one input would +% have been sufficient). If you happen to have a socket with more +% inputs, use \cs{socket_use:nw}. +% \end{function} +% +% +% \begin{function}{\ShowSocket,\LogSocket,\socket_show:n,\socket_log:n} +% \begin{syntax} +% \cs{ShowSocket} \Arg{socket-name} +% \cs{socket_show:n}\Arg{socket-name} +% \end{syntax} +% Displays information about the socket \meta{socket-name} and its +% state then stops and waits for further instructions --- at the +% moment some what rudimentary. +% +% \cs{LogSocket} and \cs{socket_log:n} only differ in that they don't stop. +% \end{function} +% +% +% \begin{function}{\DebugSocketsOn,\DebugSocketsOff, +% \socket_debug_on:,\socket_debug_off:} +% \begin{syntax} +% \cs{DebugSocketsOn} \ldots\ \cs{DebugSocketsOff} +% \end{syntax} +% Turns debugging of sockets on or off. +% \end{function} +% +% \subsubsection{Rationale for error handling} +% +% The errors during the declarations are produced to help with +% typos---after all, such declarations might be part of a document +% preamble (not that likely, but possible). However, \cs{UseSocket} is +% not doing much checking, e.g., +% \begin{verbatim} +% \UseSocket{mispelled-socket}{hello}{world} +% \end{verbatim} +% will generate a rather low-level error and then typesets +% ``{hello}{world}'' because there is no dedicated runtime check if +% \texttt{mispelled-socket} is a known socket. +% +% The reason is that if the misspelling is in the code, then this is a +% programming error in the package and for speed reasons \LaTeX{} does +% not repeately make runtime checks for coding errors unless they can or +% are likely to be user introduced. +% +% +% \MaybeStop{\setlength\IndexMin{200pt} \PrintIndex } +% +% +% \section{The Implementation} +% +% The implementation of the socket mechanism should be (partially) +% redone and we should probably store the different code chunks in +% a property list so that we can have a decent \cs{ShowSocket} +% command that shows the available alternatives.\fmi{implement?} +% +% \begin{macrocode} +%<*2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOn +% \end{macrocode} +% +% \begin{macrocode} +%<@@=socket> +% \end{macrocode} +% +% \begin{macrocode} +%\NewModuleRelease{2023/11/01}{ltsockets} +% {The~socket~management~system} +% \end{macrocode} +% +% +% +% \subsection{Debugging the socket structures} +% +% Code and commands in this section are not final, it needs more +% experimentation to see what kind of tracing information is going to +% be useful in practice. For now the tracing is mainly meant to be used +% for code testing and not so much for application testing. +% +% It is quite likely that the +% commands and the behavior of the tracing might change in the +% future once we gained some experience with it. +% +% \begin{macro}{\g_@@_debug_bool} +% Holds the current debugging state. +% \begin{macrocode} +\bool_new:N \g_@@_debug_bool +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\socket_debug_on:,\socket_debug_off:} +% \begin{macro}{\@@_debug:n, \@@_debug_term:n} +% \begin{macro}{\@@_debug_gset:} +% Turns debugging on and off by redefining \cs{@@_debug:n} and +% \cs{@@_debug_term:n}. By default they do nothing. +% \begin{macrocode} +\cs_new_eq:NN \@@_debug:n \use_none:n +\cs_new_eq:NN \@@_debug_term:n \use_none:n +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \socket_debug_on: + { + \bool_gset_true:N \g_@@_debug_bool + \@@_debug_gset: + } +\cs_new_protected:Npn \socket_debug_off: + { + \bool_gset_false:N \g_@@_debug_bool + \@@_debug_gset: + } +\cs_new_protected:Npn \@@_debug_gset: + { + \cs_gset_protected:Npx \@@_debug:n ##1 + { \bool_if:NT \g_@@_debug_bool {##1} } + \cs_gset_protected:Npx \@@_debug_term:n ##1 + { \bool_if:NT \g_@@_debug_bool + { \iow_term:x { ^^J [Sockets]~ ==>~ ##1} } } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsection{The L3 layer commands} +% +% \begin{macro}{\socket_new:nn} +% +% Declaring a socket creates a str to hold the name (a pointer) to the +% code that should be used when the socket is executed, and an integer to +% hold the number of inputs of that socket. Initially, an +% ``empty'' code chunk is created and assigned so the socket +% does nothing by default other than swallowing its inputs (if any). +% \begin{macrocode} +\cs_new_protected:Npn \socket_new:nn #1 #2 { + \str_if_exist:cTF { l_@@_#1_plug_str } + { + \msg_error:nnn { socket } { already-declared } {#1} + } + { +% \end{macrocode} +% We only support declarations on top-level. +% \begin{macrocode} + \int_if_zero:nTF \tex_currentgrouplevel:D + { + \str_new:c { l_@@_#1_plug_str } + \seq_new:c { l_@@_#1_plugs_seq } + \int_const:cn { c_@@_#1_args_int } {#2} + \socket_new_plug:nnn {#1} { noop } {} + \int_compare:nNnTF {#2} = 1 + { + \socket_new_plug:nnn {#1} { identity } {##1} + \socket_assign_plug:nn {#1} { identity } + } + { \socket_assign_plug:nn {#1} { noop } } + \@@_debug_term:n + { Socket~ '#1'~ declared~ with~ #2~ input(s) } + } + { + \msg_error:nn { socket } { not-top-level } + } + } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\socket_log:n,\socket_show:n} +% Show the current state of the socket --- for now this is just a +% quick draft and should be redone and extended. +% \begin{macrocode} +\cs_new_protected:Npn \socket_log:n #1 { + \typeout{ Socket~ #1:} + \str_if_exist:cTF { l_@@_#1_plug_str } + { + \typeout{ \@spaces number~ of~ inputs~ =~ + \int_use:c { c_@@_#1_args_int } } + \typeout{ \@spaces available~plugs~ =~ + \seq_use:cnnn { l_@@_#1_plugs_seq }{,~}{,~}{,~} } + \typeout{ \@spaces current~ plug~ =~ + \str_use:c { l_@@_#1_plug_str } } + \typeout{ \@spaces definition~ =~ + \cs_meaning:c + { @@_#1_plug_ \str_use:c { l_@@_#1_plug_str } :w } } + \typeout{} + } + { +% \end{macrocode} +% If we are showing a socket it is not an error if it doesn't exist. +% \begin{macrocode} + \typeout { Socket~ is~ not~ declared! } + } +} +% \end{macrocode} +% And here the version that stops: +% \begin{macrocode} +\cs_new_protected:Npn \socket_show:n #1 {\socket_log:n {#1} \errmessage{}} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \begin{macro}{\socket_new_plug:nnn,\socket_set_plug:nnn} +% +% Declaring a code for a socket is just making a definition, taking +% the number of arguments from the saved int. +% \begin{macrocode} +\cs_new_protected:Npn \socket_new_plug:nnn #1#2#3 { + \str_if_exist:cTF { l_@@_#1_plug_str } + { + \cs_if_exist:cTF { @@_#1_plug_#2:w } + { + \msg_error:nnnn { socket } { plug-already-declared } {#1} {#2} + } + { + \cs_generate_from_arg_count:cNnn + { @@_#1_plug_#2:w } + \cs_new_protected:Npn + { \int_use:c { c_@@_#1_args_int } } + {#3} +% \end{macrocode} +% This is a new declaration so we add the name to a seq for the +% debugging info. +% \begin{macrocode} + \seq_put_right:cn { l_@@_#1_plugs_seq } {#2} + \@@_debug_term:n + { Plug~ '#2'~ for~ socket~ '#1'~ declared. } + } + } + { + \msg_error:nnn { socket } { undeclared } {#1} + } +} +% \end{macrocode} +% Changing the plug of an existing socket is rather similar, except +% that we don't have to deal with adding it to the debugging +% sequence. +% \begin{macrocode} +\cs_new_protected:Npn \socket_set_plug:nnn #1#2#3 { + \str_if_exist:cTF { l_@@_#1_plug_str } + { + \cs_if_exist:cTF { @@_#1_plug_#2:w } + { + \cs_generate_from_arg_count:cNnn + { @@_#1_plug_#2:w } + \cs_set_protected:Npn + { \int_use:c { c_@@_#1_args_int } } + {#3} + \@@_debug_term:n + { Plug~ '#2'~ for~ socket~ '#1'~ changed. } + } + { + \msg_error:nnnn { socket } { plug-undeclared } {#1} {#2} + } + } + { + \msg_error:nnn { socket } { undeclared } {#1} + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\socket_assign_plug:nn} +% +% Assigning a plug to a socket just changes the name in +% the socket string. The assignment is local to the current group. +% \begin{macrocode} +\cs_new_protected:Npn \socket_assign_plug:nn #1 #2 { + \str_if_exist:cTF { l_@@_#1_plug_str } + { + \cs_if_exist:cTF { @@_#1_plug_#2:w } + { + \@@_debug_term:n + { Replacing~ plug~ '\str_use:c { l_@@_#1_plug_str }'~ + with~ '#2'~ in~ socket~ '#1'. } + \str_set:cn { l_@@_#1_plug_str } {#2} + } + { + \msg_error:nnnn { socket } { plug-undeclared } {#1} {#2} + } + } + { \msg_error:nnn { socket } { undeclared } {#1} } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\socket_use:nw,\socket_use:n,\socket_use:nn,\socket_use:nnn,\socket_use:nnnn} +% +% And using it is more or less a \cs{use:c} so very lightweight. We do not +% add a runtime check for speed reasons! +% +% This command is named +% \cs{socket_use:nw} because we don't know how many inputs the +% socket has until we have looked at the socket name (in argument \verb=#1=). +% But, of course, the developer knows so we also offer a few aliases +% \cs{socket_use:nn}, etc.\ so that one can indicate the correct number of +% arguments (socket inputs plus one) in the L3 layer code. +% +% \begin{macrocode} +\cs_new_protected:Npn \socket_use:nw #1 { + \@@_debug_term:n + { Socket~ '#1'~ containing~ plug~ + '\str_use:c { l_@@_#1_plug_str }'~ used. } + \use:c { @@_#1_plug_ \str_use:c { l_@@_#1_plug_str } :w } +} +% \end{macrocode} +% To make code a bit more readable we also define functions that +% indicate how many arguments are picked up. However, this is just for +% code documentation: internally they all do the same and the number +% of arguments isn't checked by default. +% \begin{macrocode} +\cs_new_eq:NN \socket_use:n \socket_use:nw % socket with no inputs +\cs_new_eq:NN \socket_use:nn \socket_use:nw % socket with one input +\cs_new_eq:NN \socket_use:nnn \socket_use:nw % socket with two inputs +\cs_new_eq:NN \socket_use:nnnn \socket_use:nw % socket with three inputs +% \end{macrocode} +% The above commands could be changed to check how many inputs +% the socket is declared with (for example, when checking is in +% force). +% \fmi{Implement?} +% \end{macro} +% +% +% +% +% +% +% +% \subsection{Error messages} +% + +% +% \begin{macrocode} +\msg_new:nnnn { socket } { already-declared } + { Socket~ '#1'~ already~ declared! } + { A~ socket~ can~ only~ be~ declared~ once.~ The~ name~ '#1'~ is~ + already~ taken.~ Use~ \ShowSocket{#1}~ to~ see~ its~ definition. } + +\msg_new:nnnn { socket } { undeclared } + { Socket~ '#1'~ undeclared! } + { You~ tried~ to~ use~ a~ socket~ that~ was~ not~ declared~ before. } + +\msg_new:nnnn { socket } { not-top-level } + { Sockets~ can~ only~ be~ declared~ at~ top-level! } + { It~ is~ not~ allowed~ to~ declare~ sockets~ inside~ a~ + group.~ Move~ the~ declaration~ to~ the~ top-level. } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnnn { socket } { plug-already-declared } + { Plug~ '#2'~ for~ socket~ '#1'~ already~ declared! } + { You~ can't~ change~ an~ existing~ plug~ with~ \NewSocketPlug~ and~ it~ + is~ normally~ not~ sensible~ to~ do~ so.~ Use~ the~ L3~ programming~ + layer~ function~ \socket_set_plug:nnn~ if~ you~ really~ have~ to. } + +\msg_new:nnnn { socket } { plug-undeclared } + { Plug~ '#2'~ for~ socket~ '#1'~ undeclared! } + { The~ plug~ name~ is~ unknown.~ Is~ the~ name~ misspelled~ or~ did~ you~ + intend~ to~ assign~ it~ to~ a~ different~ socket? } +% \end{macrocode} +% +% \begin{macrocode} +\prop_gput:Nnn \g_msg_module_type_prop { socket } { LaTeX } +% \end{macrocode} +% +% +% +% +% \subsection{The \LaTeXe{} interface commands} +% +% \begin{macro}{\NewSocket,\NewSocketPlug, +% \ShowSocket,\LogSocket, +% \AssignSocketPlug,\UseSocket, +% \DebugSocketsOn,\DebugSocketsOff} +% As we expect that there are existing \LaTeXe{} packages that may +% want to make use of the socket mechanism, we provide 2e names for +% most of the commands. +% \begin{macrocode} +\cs_new_eq:NN \NewSocket \socket_new:nn +\cs_new_eq:NN \ShowSocket \socket_show:n +\cs_new_eq:NN \LogSocket \socket_log:n +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN \NewSocketPlug \socket_new_plug:nnn +\cs_new_eq:NN \AssignSocketPlug \socket_assign_plug:nn +\cs_new_eq:NN \UseSocket \socket_use:nw +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN \DebugSocketsOn \socket_debug_on: +\cs_new_eq:NN \DebugSocketsOff \socket_debug_off: +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macrocode} +% +%\IncludeInRelease{0000/00/00}{ltsockets} +% {The~socket~management~(undo)}% +% +%\let \NewSocket \@undefined +%\let \ShowSocket \@undefined +%\let \LogSocket \@undefined +% +%\let \NewSocketPlug \@undefined +%\let \AssignSocketPlug \@undefined +%\let \UseSocket \@undefined +% +%\let \DebugSocketsOn \@undefined +%\let \DebugSocketsOff \@undefined +% +%\EndModuleRelease +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% \begin{macrocode} +% +% \end{macrocode} +% +% Reset module prefix: +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% +% \Finale +% +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endinput + + + +^^A Needed for emacs +^^A +^^A Local Variables: +^^A mode: latex +^^A coding: utf-8-unix +^^A End: + + + diff --git a/Master/texmf-dist/source/latex/base/ltspace.dtx b/Master/texmf-dist/source/latex/base/ltspace.dtx index a77314b1bd1..03b34450474 100644 --- a/Master/texmf-dist/source/latex/base/ltspace.dtx +++ b/Master/texmf-dist/source/latex/base/ltspace.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltspace.dtx} - [2023/05/26 v1.3p LaTeX Kernel (spacing)] + [2023/10/26 v1.3r LaTeX Kernel (spacing)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltspace.dtx} @@ -742,7 +742,7 @@ % true (as |\@esphack| used to do previously). % This is currently used only for floats and similar environments. % \changes{v1.2s}{1996/08/02}{Remove \cs{global} before \cs{@ignore...}} -% \changes{v1.3d}{2015/01/11}{Allow hyphenation (Donald Arseneau pr/3498) (latexrelease)}w +% \changes{v1.3d}{2015/01/11}{Allow hyphenation (Donald Arseneau pr/3498) (latexrelease)} % \begin{macrocode} % %\IncludeInRelease{2015/01/01}% @@ -1195,6 +1195,7 @@ % % \begin{macro}{\nobreakspace} % \changes{v1.2k}{1995/12/04}{(Macro added} +% \changes{v1.3r}{2023/10/26}{Protected definition for tilde} % \begin{macro}{\@xobeysp} % \changes{v1.2t}{1996/09/28}{Moved from ltmiscen.dtx and redefined to % use \cs{nobreakspace }} @@ -1213,19 +1214,54 @@ % We need to keep \cs{@xobeysp} as it is widely used; so here it is % let to the non-robust command \cs{nobreakspace }. % +% The fragile version of |~| needs a brace group after \cs{nobreakspace} +% to prevent loss of spaces if it occurs in an expansion context. That's +% not an issue with the updated \cs{protected} definition, so we keep the +% code shorter and avoid that. % \begin{macrocode} \DeclareRobustCommand{\nobreakspace}{% \leavevmode\nobreak\ } \catcode `\~=13 -\def~{\nobreakspace{}} +% +%\IncludeInRelease{2023/11/01}% +% {\tilde}{Protected tilde}% +%<*2ekernel|latexrelease> +\protected\edef~{% + \noexpand\ifincsname\noexpand\expandafter\string~% + \noexpand\else + \noexpand\expandafter\noexpand\nobreakspace + \noexpand\fi +} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\tilde}{Protected tilde}% +%\def~{\nobreakspace{}} +%\EndIncludeInRelease +%<*2ekernel> \expandafter\let\expandafter\@xobeysp\csname nobreakspace \endcsname % \end{macrocode} % \end{macro} % \end{macro} % +% \begin{macro}{\@xobeytab} +% \changes{v1.3q}{2023/06/14}{Macro added} +% Equivalent to the space case with the default settings. % \begin{macrocode} +% +%\IncludeInRelease{2023/11/01}% +% {\@xobeytab}{Obeyed tabs}% +%<*2ekernel|latexrelease> +\let\@xobeytab\@xobeysp +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@xobeytab}{Obeyed tabs}% +%\let\@xobeytab\@undefined +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} -% +% \end{macro} % % % \begin{macro}{\@} diff --git a/Master/texmf-dist/source/latex/base/ltvers.dtx b/Master/texmf-dist/source/latex/base/ltvers.dtx index b324a38020b..b2198bbbbc6 100644 --- a/Master/texmf-dist/source/latex/base/ltvers.dtx +++ b/Master/texmf-dist/source/latex/base/ltvers.dtx @@ -112,10 +112,10 @@ % %\edef\latexreleaseversion %<*2ekernel|latexrelease> - {2023-06-01} + {2023-11-01} % %<*2ekernel> -\def\patch@level{1} +\def\patch@level{0} % \end{macrocode} % % \begin{macro}{\development@branch@name} diff --git a/Master/texmf-dist/source/latex/firstaid/firstaid.ins b/Master/texmf-dist/source/latex/firstaid/firstaid.ins index cd5ea2006db..22067390cd1 100644 --- a/Master/texmf-dist/source/latex/firstaid/firstaid.ins +++ b/Master/texmf-dist/source/latex/firstaid/firstaid.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 2020-2021 +%% Copyright (C) 2020-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -44,7 +44,7 @@ reports for it can be opened at https://latex-project.org/bugs/ (but please observe conditions on bug reports sent to that address!) -Copyright (C) 2020-2021 +Copyright (C) 2020-2023 The LaTeX Project and any individual authors listed elsewhere in this file. @@ -72,7 +72,7 @@ without such generated files. \generate{\file{filehook-ltx.sty} {\from{latex2e-first-aid-for-external-files.dtx}{filehook-ltx}}} -\generate{\file{everysel-ltx.sty} - {\from{latex2e-first-aid-for-external-files.dtx}{everysel-ltx}}} +\generate{\file{underscore-ltx.sty} + {\from{latex2e-first-aid-for-external-files.dtx}{underscore-ltx}}} \endbatchfile diff --git a/Master/texmf-dist/source/latex/firstaid/latex2e-first-aid-for-external-files.dtx b/Master/texmf-dist/source/latex/firstaid/latex2e-first-aid-for-external-files.dtx index 90958ed7776..ed6c898d658 100644 --- a/Master/texmf-dist/source/latex/firstaid/latex2e-first-aid-for-external-files.dtx +++ b/Master/texmf-dist/source/latex/firstaid/latex2e-first-aid-for-external-files.dtx @@ -111,8 +111,8 @@ % \end{macrocode} % % \begin{macrocode} -\def\LaTeXFirstAidDate{2023/05/20} -\def\LaTeXFirstAidVersion{v1.0z} +\def\LaTeXFirstAidDate{2023/09/20} +\def\LaTeXFirstAidVersion{v1.1b} % \end{macrocode} % % \begin{macrocode} @@ -285,62 +285,10 @@ % % \end{macrocode} % -% -% -% -% \subsection{The \pkg{bidi} package first aid} -% -% The \pkg{bidi} package adds a lot of hooks in various places and -% those added to \cs{document} and \cs{enddocument} are now no -% longer necessary as the kernel already provides the right hooks -% there. -% -% However, we aren't trying to change that but instead only make -% sure that the existing patches still work by adding some first -% aid after \pkg{biditools} has been loaded. -% -% If the package gets updated one can easily take that out simply -% through -%\begin{verbatim} -% \RemoveFromHook{file/biditools.sty/after}[firstaid] -%\end{verbatim} -% This makes it easy to test new bidi code while the first aid code -% is still in the kernel. -% % \begin{macrocode} %<*kernel> % \end{macrocode} % -% Bidi is now ar a new version: patches are no longer needed. -% \begin{macrocode} -%\AddToHook{file/biditools.sty/after}[firstaid]{% -% \FirstAidNeededT{biditools}{sty}% -% {2020/05/13 v2 Programming tools for bidi package}% -% {% -% \end{macrocode} -% \pkg{bidi} adds some code to the beginning of \cs{document} which -% contains \cs{endgroup} and \cs{begingroup} which is no longer -% correct. -% -% Patching \cs{document} using \cs{bidi@patchcmd} doesn't work so -% we take the extra groups out by hand: -% \begin{macrocode} -% \def\firstaid@bidi@document@patch -% \endgroup#1\begingroup#2\firstaid@bidi@document@patch -% {\unexpanded{#1#2}}% -% \edef\document{\expandafter\firstaid@bidi@document@patch\document -% \firstaid@bidi@document@patch}% -% \end{macrocode} -% There are also some patches into \cs{enddocument}, some continue -% to go in but one fails, so we add that now into the right place. -% \begin{macrocode} -% \AddToHook{enddocument/info}% -% {\let\bidi@AfterEndDocumentCheckLabelsRerun\@firstofone -% \bidi@afterenddocumentchecklabelsrerunhook}% -% }% -%} -% \end{macrocode} -% % \subsection{The \pkg{dinbrief} class first aid} % % Again a case of a no longer correct \cs{endgroup} in document. @@ -482,46 +430,6 @@ % % \end{macrocode} % -% \subsection{The \pkg{everysel} package first aid} -% -% -% The \cs{selectfont} command got a hook (with the 2021/05 release) which -% was originally provided by the \pkg{everysel} -% package. Now that it is in the kernel this package is no longer -% needed (or only in a simplified manner). -% -% If it is requested we replace it with a simplified package -% (until) it gets updated at which point this line can be removed. -% \changes{v2.2k}{2020/12/04}{Emulate everysel package} -% \begin{macrocode} -%<*kernel> -% this has been updated -%\declare@file@substitution{everysel.sty}{everysel-ltx.sty} -% -% \end{macrocode} -% -% -% -% \begin{macrocode} -%<*everysel-ltx> -\ProvidesPackage{everysel-ltx} - [2020/12/04 v1.0a - Emulation of the original everysel^^Jpackage with kernel methods] -% \end{macrocode} -% -% \begin{macrocode} -\newcommand*{\EverySelectfont}[1] - {\AddToHook{selectfont}{#1}} -\newcommand*{\AtNextSelectfont}[1] - {\AddToHookNext{selectfont}{#1}} -% \end{macrocode} -% -% -% \begin{macrocode} -% -% \end{macrocode} -% -% % % \begin{macrocode} %<*kernel> @@ -652,32 +560,45 @@ } % \end{macrocode} % -% -% \subsection{First aid for \pkg{memoir}} -% -% The introduction of \cs{stockheight} and \cs{stockwidth} into the -% kernel requires some first aid. This has to go in \emph{before} -% loading the class, so we cannot check the version string here. % \begin{macrocode} -\AddToHook{file/memoir.cls/before}[firstaid]{% - \expandafter\def\expandafter\@tempa\string\dimen{}% - \edef\kernel@stockheight{\expandafter\@tempa\meaning\stockheight}% - \edef\kernel@stockwidth{\expandafter\@tempa\meaning\stockwidth}% - \let\stockheight\@undefined - \let\stockwidth\@undefined -} -\AddToHook{file/memoir.cls/after}[firstaid]{% - \dimen\kernel@stockheight=\stockheight - \dimen\kernel@stockwidth=\stockwidth - \dimendef\stockheight=\kernel@stockheight - \dimendef\stockwidth=\kernel@stockwidth -} +% +% \end{macrocode} +% \subsection{The \pkg{underscore} first aid} +% +% The \pkg{underscore} package makes the underscore active. This means that the +% underscore can not be used in label and references unless the package option \texttt{strings} is used +% (which patches a selection of problematic commands like \cs{label} and \cs{ref}) +% or \pkg{babel} is used which redefines\footnote{unless the recommended option \texttt{safe=none} is used} +% a selection of problematic commands like \cs{@testdef} or \cs{@newl@bel}. +% +% With the new property commands the work-around do not work. We therefore make the +% underscore protected and use \cs{ifincsname} to allow its use in csnames. +% +% \begin{macrocode} +%<*underscore-ltx> +\ProvidesPackage{underscore-ltx}[2023/09/20 LaTeX firstaid to make underscore protected ] +\begingroup + \catcode`\_=\active + \protected\gdef _{% + \ifincsname % + \string_% + \else + \ifx\protect\@typeset@protect + \ifmmode \sb \else \BreakableUnderscore \fi + \else + \ifx\protect\@unexpandable@protect \noexpand_% + \else \protect_% + \fi\fi + \fi + } + \global\let\ActiveUnderscore=_ +\endgroup +% % \end{macrocode} -% -% -% -% % \begin{macrocode} +%<*kernel> +\AddToHook{file/underscore.sty/after}[firstaid]{% + \FirstAidNeededT{underscore}{sty}{2006/09/13}{\RequirePackage{underscore-ltx}}} % % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3build/l3build.dtx b/Master/texmf-dist/source/latex/l3build/l3build.dtx index b6787a1044f..e425786e03e 100644 --- a/Master/texmf-dist/source/latex/l3build/l3build.dtx +++ b/Master/texmf-dist/source/latex/l3build/l3build.dtx @@ -251,7 +251,7 @@ % }^^A % } % -% \date{Released 2023-09-13} +% \date{Released 2023-11-01} % % \maketitle % \tableofcontents @@ -529,7 +529,7 @@ % If the compilation is successful the |.pdf| is moved back into the main directory. % % The documentation compilation is performed with the \var{typesetexe} binary (default \texttt{pdflatex}), with options \var{typesetopts}. -% Additional \TeX{} material defined in \var{typesetcmds} is passed to the document (e.g., for writing |\\PassOptionsToClass{l3doc}{letterpaper}|, and so on---note that backslashes need to be escaped in Lua strings). +% Additional \TeX{} material defined in \var{typesetcmds} is passed to the document (e.g., for writing |\PassOptionsToClass{l3doc}{letterpaper}|, and so on---note that backslashes need to be escaped in Lua strings). % % Files that match |typesetsuppfiles| in the |support| directory (|supportdir|) are copied into the |build/doc| directory (|typesetdir|) for the typesetting compilation process. % Additional dependencies listed in the \var{typesetdeps} variable (empty by default) will also be installed. @@ -1819,7 +1819,7 @@ % |normalize_path(|\meta{path}|)| % \end{syntax} % When called on Windows, returns a string comprising the \meta{path} with -% |/| characters replaced by |\\|. In other cases returns the path unchanged. +% |/| characters replaced by |\|. In other cases returns the path unchanged. % \end{function} % % \subsection{System-dependent strings} @@ -2141,6 +2141,14 @@ % Full descriptions of their usage and arguments can be found within the |l3build-manifest-setup.lua| % code itself. % +% \section{Known limitations} +% +% \subsection{Non-\textsc{ascii} filenames} +% +% On Windows, support for non-\textsc{ascii} filenames is limited by the way +% that Lua handles system calls. While calling \TeX{} engines should work with +% any name, general file operations will only success if the filename falls +% within the codepage currently in use by the operating system. % % \end{documentation} % diff --git a/Master/texmf-dist/source/latex/latex-lab/documentmetadata-support.dtx b/Master/texmf-dist/source/latex/latex-lab/documentmetadata-support.dtx index 0dccdd87cb5..b37ae6c9d79 100644 --- a/Master/texmf-dist/source/latex/latex-lab/documentmetadata-support.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/documentmetadata-support.dtx @@ -18,8 +18,8 @@ % for those people who are interested or want to report an issue. % % \begin{macrocode} -\def\documentmetadatasupportversion{1.0d} -\def\documentmetadatasupportdate{2023-06-07} +\def\documentmetadatasupportversion{1.0f} +\def\documentmetadatasupportdate{2023-09-01} % \end{macrocode} % % @@ -139,7 +139,7 @@ % |pdfstandard| can be used more than once to set overlapping standards, e.g:\\ % |pdfstandard=A-2b,pdfstandard=X-4,pdfstandard=UA-1| % -% If XMP-metadata are added (see the following key \texttt{xmp} +% If XMP-metadata are added (see the following key \texttt{xmp}) % the needed conformance marker for the standards are set. % % More information can be found in the documentation @@ -151,9 +151,13 @@ % \item[\texttt{colorprofiles}] This allows to load icc-colorprofiles. Details % are described in the documentation of \pkg{l3pdfmeta}. % -% \item[\texttt{testphase}] This key is used to load testphase code. The values it accepts -% and their effect will change over time, when testphase packages are added or -% removed or when the code is moved into the kernel. +% \item[\texttt{testphase}] This key is used to load testphase code. +% The |testphase| key can only be used in the first \cs{DocumentMetadata}. +% The values it accepts and their effect will change over time, when testphase packages are added or +% removed or when the code is moved into the kernel. The key accepts a list of values +% and it can be used more than once. +% +% The \texttt{phase} key bundle testphase modules. They also all activate tagging. % \begin{description} % \item[\texttt{phase-I}] % This value loads code implementing the first phase of the project~\cite{blueprint}, i.e., it @@ -172,7 +176,13 @@ % table of contents and similar lists, graphics, minipages and floats. % As it redefines many internals it is currently restricted to the use of % standard classes (article, report, and book) -% and it supports only a limited number of add-on packages. +% and it supports only a limited number of add-on packages. +% \end{description} +% +% The various testphase modules can also be loaded individually (and least in theory, +% there can be hidden dependencies). If loaded like this, the tagpdf package is not +% loaded and tagging is not activated! The list of modules will change over time. +% \begin{description} % \item[\texttt{new-or-1}] This patches a few commands related % to the output routine. The patches are needed for the tagging % of paragraphs, for the tagging of header and footer and @@ -183,8 +193,32 @@ % \item[\texttt{new-or}] This loads more changes to the output routine required for the % tagging. It is not compatible with every class! The code is also loaded by the % \texttt{phase-II} value. +% \item[\texttt{sec}] This adapts commands related to sectioning to make them tagging aware. +% The \texttt{sec} module is loaded by \texttt{phase-III}. +% \item[\texttt{toc}] This adapts commands related to the table of contents and +% similar list to make them tagging aware. The \texttt{toc} module is loaded by \texttt{phase-III}. +% \item[\texttt{graphic}] This enables tagging support for +% the \cs{includegraphics} command and the \texttt{picture} environment. +% This code is also loaded by the \texttt{phase-III} key. +% \item[\texttt{block}] This reimplements lists and blocks environments and +% add tagging support. +% This code is also loaded by the \texttt{phase-III} key. +% \item[\texttt{minipage}] This adds tagging support to \texttt{minipage} +% and \cs{parbox}. +% This code is also loaded by the \texttt{phase-III} key. +% \item[\texttt{float}] This adds tagging support to floats. +% This code is also loaded by the \texttt{phase-III} key. +% \item[\texttt{bib}] This adds tagging support to citations and bibliographies. +% This code is also loaded by the \texttt{phase-III} key. +% \item[\texttt{text}] This module adds tagging support to the \LaTeX{} logo and +% to the \cs{emph} command. +% This code is also loaded by the \texttt{phase-III} key. +% \item[\texttt{math}] This adapts math for tagging. This is only a prototype. +% The module is currently not loaded by any \texttt{phase} key. +% \item[\texttt{firstaid}] This contains small adjustments to external packages. +% The module is currently not loaded by any \texttt{phase} key. % \end{description} -% The |testphase| key can only be used in the first \cs{DocumentMetadata}. +% % % \item[\texttt{debug}] This key activates some debug options. It takes a list of key-values % as value. Currently the following keys are known: @@ -200,7 +234,10 @@ % \item[\texttt{xmp-export}] This will export the XMP-metadata to a file \verb+\jobname.xmpi+. % with \texttt{debug=\{xmp-export=filename\}} the file name can be changed. % More information can be found in the documentation of \pkg{l3pdfmeta} of the \pkg{pdfmanagement-testphase} -% bundle. +% bundle. +% \item[\texttt{tagpdf}] This loads the package tagpdf-debug which enhances +% various commands from tagpdf with additional debugging options. This can slow down +% the compilation! % \end{description} % \end{description} % @@ -426,6 +463,16 @@ \tagpdfsetup{log=#1} } } + ,debug / tagpdf .code:n = + { + \AddToHook + { + package/tagpdf/after + } + { + \RequirePackage{tagpdf-debug} + } + } ,debug / uncompress .code:n = { \pdf_uncompress: diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-bib.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-bib.dtx index 9a5ee81720d..a467bf31582 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-bib.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-bib.dtx @@ -16,6 +16,8 @@ % % for those people who are interested or want to report an issue. % +\def\ltlabbibdate{2023-07-20} +\def\ltlabbibversion{0.81a} %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -31,7 +33,7 @@ % Changes and additions to the kernel related to tagging and links in citations and % bibliography entries} % \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} -% \date{Version 0.81 2023-06-07} +% \date{v\ltlabbibversion\ \ltlabbibdate} % % \maketitle % @@ -129,12 +131,12 @@ %<@@=tag> % \end{macrocode} % \begin{macrocode} -\ProvidesExplPackage {latex-lab-testphase-bib} {2023-05-18} {0.8} +\ProvidesExplPackage {latex-lab-testphase-bib} {\ltlabbibdate} {\ltlabbibversion} {Code related to the tagging of bibliography and cite command} % \end{macrocode} % We need at least the block tagging code. % \begin{macrocode} -\RequirePackage{latex-lab-testphase-block-tagging} +\RequirePackage{latex-lab-testphase-block} % \end{macrocode} % % At first we suppress the patches from hyperref. This will only work with the next @@ -398,7 +400,8 @@ % \begin{macrocode} %<*latex-lab> \ProvidesFile{bib-latex-lab-testphase.ltx} - [2023-05-18 v0.8 code related to the tagging of bib and citations] + [\ltlabbibdate\space v\ltlabbibversion\space + latex-lab wrapper bib] \RequirePackage{latex-lab-testphase-bib} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-block-tagging.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-block-tagging.dtx deleted file mode 100644 index 63145d929e9..00000000000 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-block-tagging.dtx +++ /dev/null @@ -1,4055 +0,0 @@ -% \iffalse meta-comment -% -%% File: latex-lab-block-tagging.dtx (C) Copyright 2021-2023 LaTeX Project -% -% It may be distributed and/or modified under the conditions of the -% LaTeX Project Public License (LPPL), either version 1.3c of this -% license or (at your option) any later version. The latest version -% of this license is in the file -% -% https://www.latex-project.org/lppl.txt -% -% -%<*driver> -\documentclass{l3doc} -\usepackage{amstext} -\EnableCrossrefs -\CodelineIndex - -\usepackage{todonotes} - -\begin{document} - \DocInput{latex-lab-block-tagging.dtx} -\end{document} -% -% -% \fi -% - -\def\ltblocksversion{v0.8d} -\def\ltblocksdate{2023/06/07} - -% -% \title{Prototype reimplementation of \LaTeXe{}'s block environments using templates} -% \author{\LaTeX{} Project\thanks{Initial reimplementation of lists done by Bruno -% Le Floch, generalized second version with tagging support by Frank Mittelbach.}} -% \date{\ltblocksversion\ \ltblocksdate} -% -% \maketitle -% -% -% \newcommand{\xt}[1]{\textsl{\textsf{#1}}} -% \newcommand{\TODO}[1]{\textbf{[TODO:} #1\textbf{]}} -% \newcommand{\docclass}{document class \marginpar{\raggedright document class -% customizations}} -% -% \providecommand\hook[1]{\texttt{#1}} -% \providecommand\struct[1]{\texttt{<#1>}} -% -% \NewDocElement[envlike, idxtype=objecttype, idxgroup=object types, -% printtype=\textit{objecttype}] {ObjectType}{objecttype} -% -% \NewDocElement[envlike, idxtype=template, idxgroup=templates, -% printtype=\textit{templ.}] {Template}{template} -% -% \NewDocElement[envlike, idxtype=instance, idxgroup=instances, -% printtype=\textit{inst.}] {Instance}{instance} -% -% -% \newcommand\valuefrom[1]{\textrm{value from }\texttt{#1}} -% \newcommand\key[1]{\texttt{#1}} -% -% -% \NewDocumentCommand\fmi{sO{}m} -% {\IfBooleanTF{#1}{\todo[inline,#2]{#3}}^^A -% {\todo[#2]{#3}}} -% -% \NewDocumentCommand\ufi{sO{}m} -% {\IfBooleanTF{#1}{\todo[inline,#2]{UFi:#3}}^^A -% {\todo[#2]{UFi:#3}}} -% \makeatletter -% \renewenvironment{TemplateInterfaceDescription}[1] -% { -% \subsubsection{The~object~type~`#1'} -% \begingroup -% \@beginparpenalty\@M -% \description -% \def\TemplateArgument##1##2{\item[Arg:~##1]##2\par} -% \def\TemplateSemantics -% { -% \enddescription\endgroup -% \subsubsection*{Semantics:} -% } -% } -% { -% \par\bigskip -% } -% \renewenvironment{TemplateDescription}[2] -% {\subsubsection{The \texttt{#1} template `#2'}^^A -% \paragraph*{Attributes:}^^A -% \begingroup -% \@beginparpenalty\@M -% \description -% \def\TemplateKey##1##2##3##4{^^A -% \item[\texttt{##1}~(\textit{\mdseries##2})]##3^^A -% \ifx\TemplateKey##4\TemplateKey\else -% \hfill\penalty500\hbox{}\hfill Default:~\texttt{##4}^^A -% \nobreak\hskip-\parfillskip\hskip0pt\relax -% \fi -% \par -% }^^A -% \def\TemplateSemantics{^^A -% \enddescription\endgroup -% \paragraph*{Semantics~\&~Comments:}^^A -% }^^A -% } -% { \par \bigskip } -% \makeatother -% -% -% \begin{abstract} -% \end{abstract} -% -% -% \tableofcontents -% \medskip -% -% -% \begin{documentation} -% -% -% -% \section{Introduction} -% -% The list implementation in \LaTeXe{} serves a dual purpose: it -% implements real lists such as \env{itemize} or \env{enumerate}, -% but it is also used as the basis for vertical blocks, i.e., to specify -% the vertical spacing and paragraph handling after such block, e.g., -% in environments like \env{center}, \env{quote}, \env{verbatim}, or in -% the theorem environments. They are all implemented as -% \enquote{trivial} lists with a single (hidden) item. -% -% While this was convenient to get a consistent layout using a single -% implementation it is not adequate if it comes to interpreting the -% structure of a document, because environments based on \env{trivlist} -% should not advertise themselves as being a \enquote{list} --- after all, -% from a semantic point of view they aren't lists. -% -% The approach taking here is therefore to offer separate object -% types: \xt{block} (horizontally or vertically oriented data that -% needs some handling at the start and the end), \xt{para} (that deals -% with different paragraph layouts), \xt{list} (that handles list -% related parameters, and \xt{item} (for item layouts and handling), to address -% the independent aspects and also offer the object type \xt{blockenv} -% that ties them together as necessary. -% -% For example, a \env{quote} environment would make use of a (display) -% \xt{block} and some \xt{para} handling while an standard -% \env{enumerate} would make use of a display \xt{block}, a \xt{list}, -% and an \xt{item} and \xt{para} instance. -% An inline list (like \env{enumerate*} from the \pkg{enumitem} -% package) would be using the same \xt{list} instance but a different -% (horizontally oriented) \xt{block}. -% -% -% \section{Object types and templates for blocks and lists} -% -% \subsection{Object types} -% -% \begin{TemplateInterfaceDescription}{block} -% \TemplateArgument{1}{key/value list to alter the default block parameters} -% \TemplateSemantics -% Handle the layout aspects of a block of data. In case of a -% \enquote{display} block (i.e., vertically oriented) the spacing -% and page breaking as well as the handling if the block starts a -% paragraph or ends one, that is, if text is immediately following -% the block without being separated by an empty line, then this -% text is considered to be in the same paragraph as the block. -% -% In case of a horizontally oriented block it covers any special -% handling at the start and end of the block, e.g, extra spacing, -% prohibitying or encuraging line breaks, and so forth. -% \end{TemplateInterfaceDescription} -% -% \begin{TemplateInterfaceDescription}{para} -% \TemplateArgument{1}{key/value list to alter the default item parameters} -% \TemplateSemantics -% Sets up paragraph-specific parameters for H\&J, e.g., to -% implement justification variations, the behavior of \verb=\\= -% etc. The instances are used in higher-level templates, e.g., in a -% \xt{block}. -% \end{TemplateInterfaceDescription} -% -% \begin{TemplateInterfaceDescription}{list} -% \TemplateArgument{1}{key/value list to alter the default item parameters} -% \TemplateSemantics -% Handle the aspects related to list design, e.g., the use and -% formatting of counters, etc. -% -% Note that this does not cover block-related aspects, i.e., a list -% instance could be used both for a display list or for an inline line. -% \end{TemplateInterfaceDescription} -% -% \begin{TemplateInterfaceDescription}{item} -% \TemplateArgument{1}{key/value list to alter the default item parameters} -% \TemplateSemantics -% A sub-type used as part of \xt{list} to easily cover alternative layout -% for list items. -% \end{TemplateInterfaceDescription} -% -% -% \begin{TemplateInterfaceDescription}{blockenv} -% \TemplateArgument{1}{key/value list to alter the default item parameters} -% \TemplateSemantics -% This object type is used to implement document-level -% environments. It defines a \xt{block} instance to handle the -% layout at the \enquote{edge} of the environment data, possibly -% some paragraph setup through a \xt{para} instance, potentially an -% \enquote{inner} instance for more complicated environments (such -% as lists), and possibly some additional setup code for certain -% environments. -% -% It also defines how the \xt{blockenv} behaves with respect to -% nesting, e.g., does it change when nested and if so how many -% levels of nesting are supported, etc. -% -% Finally, the object type defines how it appears in a tagged PDF -% document, what tag names are used, how they are rolemapped and -% whether it adds additional attributes, etc. -% \end{TemplateInterfaceDescription} -% -% -% -% \subsection{Templates} -% -% -% \begin{TemplateDescription}{blockenv}{display} -% -% \TemplateKey{env-name}{tokenlist} -% {Name of the environment used only in tracing}{} -% \TemplateKey{tag-name}{tokenlist} -% {Name of the tag in the PDF. If not explicitly given -% the name is defined by the \key{tagging-recipe}}{} -% \TemplateKey{tag-class}{tokenlist} -% {An explicit tag class attribute}{} -% \TemplateKey{tagging-recipe}{tokenlist} -% {Defines the way tagging is done. Currently the values -% \texttt{basic}, \texttt{standard}, and \texttt{list} -% are supported}{standard} -% \TemplateKey{level-increase}{boolean}{Does this \xt{blockenv} -% increase the block level if it is nested in an outer block?}{true} -% \TemplateKey{setup-code}{tokenlist} -% {Initial setup code. This is -% executed after legacy defaults (from \cs{@listi}, -% \cs{@listii}, etc.) are used but before the block instance is called}{} -% \TemplateKey{block-instance}{tokenlist}{Part of the name of the -% \xt{block} instance that is called. The full name has -% a \texttt{-}\meta{level} appended}{displayblock} -% \TemplateKey{para-instance}{tokenlist}{}{} -% \TemplateKey{inner-level-counter}{tokenlist}{Name of an existing (!) counter -% that is incremented and used to determine final name -% of the \key{inner-instance} or empty if always the -% same inner instance should be used}{} -% \TemplateKey{max-inner-levels}{tokenlist}{Maximum number of nested -% environments of this kind. Only relevant if there is a -% \key{inner-level-counter} specified}{4} -% \TemplateKey{inner-instance-type}{tokenlist}{Opject type of the -% inner instance}{list} -% \TemplateKey{inner-instance}{tokenlist}{Name of the inner instance -% (if any).}{} -% \TemplateKey{para-flattened}{boolean}{\emph{describe}}{false} -% \TemplateKey{final-code}{tokenlist}{Final setup code}{\cs{ignorespaces}} -% -% \TemplateSemantics -% -% This \xt{blockenv} template supports the legacy list setting that -% are found in many document classes in the macros \cs{@listi}, -% \cs{@listii}, up to \cs{@listvi}. It also uses the counter -% \cs{@listdepth} to track nesting of block, again mainly to -% support legacy setups (internally it gives it a more appropriate -% name but it remains accessible through the \LaTeXe{} name). -% -% -% It first checks that nothing is too deeply nested. -% If the level should increase then the increments the -% \cs{@listdepth} counter and -% calls the corresponding \cs{@list...} macro to update the legacy -% defaults. If \key{level-increase} is set to false this is bypassed. -% -% It then sets up the -% tagging via the \key{tagging-recipe} setting and executes any -% code in \key{setup-code}. -% -% Afterwards it calls the appropriate \xt{block} instance based on -% \key{block-instance} and current level, e.g., -% \texttt{displayblock-1}. Then it sets up paragraph parameters if -% a \key{para-instance} was specified (otherwise they stay as -% they are). -% -% If a \key{inner-instance} was specified this is called next, -% or more precisely: if no \key{inner-level-counter} was -% specified the instance \key{inner-instance} is -% called. -% -% Otherwise, the \key{inner-level-counter} is incremented and the -% instance with the name -% \key{inner-instance}\texttt{-}\key{inner-level-counter} is -% called. -% -% Finally, the \key{final-code} is executed (by default -% \cs{ignorespaces}). -% -% -% \end{TemplateDescription} -% -% The maximum number of \xt{blockenv}s that can be nested into each -% other is is restricted by the \LaTeX{} counter -% \texttt{maxblocklevels} with a default value of \texttt{6}. If this -% value is increased then it is necessary to provide additional -% instances, e.g., \texttt{displayblock-7}, etc. Decreasing is, of -% course, always possible, then some of the instances defined are not -% used and instead the user gets an error that there is too much -% nesting going on. -% -% If the key \key{level-increase} is set to \texttt{false} then such -% an environment doesn't alter the nesting level and therefore you can -% nest those environments as often as you like (a typical example -% would be \env{flushleft} anywhere in the nesting hierarchy, that -% would have no effect on hitting the boundary). -% -% -% \begin{TemplateDescription}{block}{display} -% -% \TemplateKey{heading}{tokenlist}{\emph{not really used yet}}{} -% \TemplateKey{beginsep}{skip}{}{\cs{topsep}} -% \TemplateKey{begin-par-skip}{skip}{}{\cs{partopsep}} -% \TemplateKey{par-skip}{skip}{}{\cs{parsep}} -% \TemplateKey{end-skip}{skip}{}{\valuefrom{beginsep}} -% \TemplateKey{end-par-skip}{skip}{}{\valuefrom{begin-par-skip}} -% \TemplateKey{beginpenalty}{integer}{}{\cs{@beginparpenalty}} -% \TemplateKey{endpenalty}{integer}{}{\cs{@endparpenalty}} -% \TemplateKey{leftmargin}{length}{}{\cs{leftmargin}} -% \TemplateKey{rightmargin}{length}{}{\cs{rightmargin}} -% \TemplateKey{parindent}{length}{}{\cs{listparindent}} -% -% \TemplateSemantics -% -% The idea of a \key{heading} key needs some further -% thoughts. Maybe instead the object type should accept a second -% argument and receive input for such a headding from the document -% level instead. -% -% The names of the keys need further thoughts and some -% decision. Right now it is a mixture of those with hyphens and -% those that match legacy register names (the way \pkg{enumitem} -% did its keys). -% -% Also \key{parindent} conflicts with \key{indent-width}! -% -% \end{TemplateDescription} -% -% -% \begin{TemplateDescription}{para}{std} -% -% \TemplateKey{indent-width}{length}{}{\cs{parindent}} -% \TemplateKey{start-skip}{skip}{}{0pt} -% \TemplateKey{left-skip}{skip}{}{0pt} -% \TemplateKey{right-skip}{skip}{}{0pt} -% \TemplateKey{end-skip}{skip}{}{\cs{@flushglue}} -% \TemplateKey{fixed-word-spaces}{boolean}{}{false} -% \TemplateKey{final-hyphen-demerits}{integer}{}{5000} -% \TemplateKey{cr-cmd}{tokenlist}{}{\cs{@normalcr}} -% \TemplateKey{para-class}{tokenlist}{}{justify} -% -% \TemplateSemantics -% -% -% \end{TemplateDescription} -% -% -% -% \begin{TemplateDescription}{list}{std} -% -% \TemplateKey{counter}{tokenlist} -% {Counter name to be used in a numbered list or empty, -% if the list is unnumbered}{} -% \TemplateKey{item-label}{tokenlist} -% {Label \enquote{string} for a fixed label or as -% generated from the current \key{counter} value}{} -% \TemplateKey{start}{integer} -% {Start value for the counter if the list is numbered, -% otherwise irrelevant}{1} -% \TemplateKey{resume}{boolean} -% {Should a numbered list be resumed from the last instance?}{false} -% \TemplateKey{item-instance}{instance} -% {Instance of type \texttt{item} to be used to format -% the label string}{basic} -% \TemplateKey{item-skip}{skip}{The space in front of an item in the -% list.\fmi{May need to be on a different template level}}{\cs{itemsep}} -% \TemplateKey{item-indent}{length}{Horizontal displacement of the item.}{0pt} -% \TemplateKey{item-penalty}{integer} -% {Penalty for breaking before an -% item (except the first)}{\cs{@itempenalty}} -% \TemplateKey{label-width}{length} -% {Width reserved for the formatted item label}{\cs{labelwidth}} -% \TemplateKey{label-sep}{length} -% {Horizontal separation between label and following text}{\cs{labelsep}} -% \TemplateKey{legacy-support}{boolean} -% {Is formatting the label via \cs{makelabel} supported?}{false} -% -% \TemplateSemantics -% -% -% \end{TemplateDescription} -% -% -% \begin{TemplateDescription}{item}{std} -% -% \TemplateKey{counter-label}{function{1}}{\emph{unused}}{\cs{arabic}\{\#1\}} -% \TemplateKey{counter-ref}{function{1}}{\emph{unused}}{\valuefrom{counter-label}} -% \TemplateKey{label-ref}{function{1}}{\emph{unused}}{\#1} -% \TemplateKey{label-autoref}{function{1}}{\emph{unused}}{item~\#1} -% \TemplateKey{label-format}{function{1}} -% {Formatting of the label, questionable the way it is used}{\#1} -% \TemplateKey{label-strut}{boolean}{Add a \cs{strut} to the label?}{false} -% \TemplateKey{label-align}{choice} -% {Supported values \texttt{left},\texttt{center}, -% \texttt{right}, and \texttt{parleft}. \emph{Only partly implemented}}{right} -% \TemplateKey{label-boxed}{boolean} -% {Should the label be boxed?}{true} -% \TemplateKey{next-line}{boolean}{}{false} -% \TemplateKey{text-font}{tokenlist}{\emph{unused}}{} -% \TemplateKey{compatibility}{boolean}{}{true} -% -% \TemplateSemantics -% -% This template is only rudimentary implemented at the moment. It -% probably needs other keys and the existing ones need a proper -% implementation. -% -% \end{TemplateDescription} -% -% -% \section{Tagging support} -% -% \subsection{Paragraph tags} -% -% Paragraphs in \LaTeX{} can be nested, e.g., you can have a paragraph -% containing a display quote, which in turn consists of more than one -% (sub)paragraph, followed by some more text which all belongs to the -% same outer paragraph. -% -% In the PDF model and in the HTML model that is not supported --- a -% limitation that conflicts with real live, given that such -% constructs are quite normal in spoken and written language. -% -% The approach we take to resolve this is to model such \enquote{big} -% paragraphs with a structure named \struct{text-unit} and use \struct{text} (rollmapped to \struct{P}) -% only for (portions of) the actual paragraph text in a way that the -% \struct{text}s are not nested. As a result we have for a simple -% paragraph the structures -% \begin{tabbing} -% \hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\= \kill -% \> \struct{text-unit}\\ -% \>\> \struct{text}\\ -% \>\>\> The paragraph text \ldots\\ -% \>\> \struct{/text}\\ -% \> \struct{/text-unit} -% \end{tabbing} -% The \struct{text-unit} structure is rollmapped to \struct{Part} or possibly to -% \struct{Div} so we get a valid PDF, but processors who care can identify -% the complete paragraphs by looking for \struct{text-unit} tags. -% -% In the case of an element, such as a display quote or a display list -% inside the paragraph, we then have -% \begin{tabbing} -% \hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\= \kill -% \> \struct{text-unit}\\ -% \>\> \struct{text}\\ -% \>\>\> The paragraph text before the display element \ldots\\ -% \>\> \struct{/text}\\ -% \>\> \struct{display element structure}\\ -% \>\>\> Content of the display structure possiblly involving inner \struct{text-unit} tags\\ -% \>\> \struct{/display element structure}\\ -% \>\> \struct{text}\\ -% \>\>\> \ldots{} continuing the outer paragraph text\\ -% \>\> \struct{/text}\\ -% \> \struct{/text-unit} -% \end{tabbing} -% In other words such a display block is always embedded in a -% \struct{text-unit} structure, possibly preceded by a \struct{text}\ldots\struct{/text} block -% and possibly followed by one, though both such blocks are optional. -% -% Thus an \env{itemize} environment that has some introductory text -% but no text immediately following the list -% would be tagged as follows: -% \begin{tabbing} -% \hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\= \kill -% \> \struct{text-unit}\\ -% \>\> \struct{text}\\ -% \>\>\> The intro text for the \env{itemize} environment \ldots\\ -% \>\> \struct{/text}\\ -% \>\> \struct{itemize}\\ -% \>\>\> \struct{LI}\\ -% \>\>\>\> \struct{Lbl} label \struct{/Lbl}\\ -% \>\>\>\> \struct{LBody}\\ -% \>\>\>\>\> The text of the first item involving \struct{text-unit} as necessary \ldots\\ -% \>\>\>\> \struct{/LBody}\\ -% \>\>\> \struct{/LI}\\ -% \>\>\> \struct{LI}\\ -% \>\>\>\> The second item \ldots{}\\ -% \>\>\> \struct{/LI}\\ -% \>\>\> \ldots{} further items \ldots\\ -% \>\> \struct{/itemize}\\ -% \> \struct{/text-unit} -% \end{tabbing} -% The \struct{itemize} is rollmapped to \struct{L}. -% -% For some display blocks, such as centered text, we use a simpler -% strategy. Such blocks still ensure that they are inside a \struct{text-unit} -% structure but their body uses simple \struct{text} blocks and not -% \struct{text-unit}\struct{text} inside, e.g., the input -% \begin{verbatim} -% This is a paragraph with some -% \begin{center} -% centered lines -% -% with a paragraph break between them -% \end{center} -% followed by some more text. -% \end{verbatim} -% will be tagged as follows: -% \begin{tabbing} -% \hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\= \kill -% \> \struct{text-unit}\\ -% \>\> \struct{text}\\ -% \>\>\> This is a paragraph with some\\ -% \>\> \struct{/text}\\ -% \>\> \struct{text /O /Layout /TextAlign/Center}\\ -% \>\>\> centered lines\\ -% \>\> \struct{/text}\\ -% \>\> \struct{text /O /Layout /TextAlign/Center}\\ -% \>\>\> with a paragraph break between them\\ -% \>\> \struct{/text}\\ -% \>\> \struct{text}\\ -% \>\>\> followed by some more text.\\ -% \> \struct{/text-unit} -% \end{tabbing} -% -% -% \subsection{Tagging recipes} -% -% There are a number of different tagging recipes that implement -% different tagging approaches. They are selected through the -% \key{tagging-recipe} of the \xt{blockenv} template. Currently the -% following values are implemented: -% \begin{description} -% \item[\texttt{basic}] -% This recipe does the following: -% \begin{itemize} -% \item -% Ensure that the \xt{blockenv} is inside a \struct{text-unit} -% structure, if necessary, start one. -% \item -% If inside a \struct{text-unit}\struct{text}, then close the \struct{/text} but -% leave the \struct{text-unit} open. -% -% \item -% Text inside the body of the environment starts with -% \struct{text-unit}\struct{text} if \key{para-flattened} is set to \texttt{false}, -% otherwise just with \struct{text}. -% -% \item -% At the end of the environment close \struct{/text} and possibly an -% inner \struct{/text-unit} if open. -% -% \item -% Then look if the environment is followed by an empty line -% (\cs{par}). If so, close the outer \struct{/text-unit} and start any -% following text with \struct{text-unit}\struct{text}. Otherwise, -% don't and following text restarts with a just a \struct{text} (and no -% paragraph indentation) -% \end{itemize} -% -% -% \item[\texttt{standard}] -% This recipe is like the \texttt{basic} one as far as handling -% \struct{text-unit} and \struct{text} is concerned. In addition -% \begin{itemize} -% \item -% it starts an inner tagging structure (i.e., which is therefore a -% child of the outer \struct{text-unit}). -% \item -% By default this structure is a \struct{Figure} unless overwritten -% by the key \key{tag-name}. If that key is used, a suitable -% rollmap needs to be provided for the name given. -% \item -% At the end of the environment that inner structure is closed -% again so that we are back on the \struct{text-unit} level from the outside. -% \item -% Then the lookahead for an empty line is done as described previously. -% \end{itemize} -% -% -% -% \item[\texttt{list}] -% This recipe is like the \texttt{standard} one except that -% \begin{itemize} -% \item -% the inner structure is a list (\struct{L}). -% \item -% Furthermore everything is set up so that we have list items -% (\struct{LI}) with suitable substructures (\struct{Lbl} for the item -% labels and \struct{LBody} for the item bodies). -% \item -% If the key \key{tag-name} is specified, this is used as the tag -% name for the whole list instead of \struct{L}. Of course, it -% should then have a suitable rollmap. -% \item -% If the key \key{tag-class} is specified then this is used as the -% class attribute. Again, this requires a suitable setup on the outside. -% \item -% At the end of the environment the \struct{/LBody}, \struct{/LI}, and -% \struct{/L} (or the tag name used) are closed. -% \item -% Then the lookahead for an empty line is done as described previously. -% \end{itemize} -% -% -% \end{description} -% -% -% -% -% -% -% \end{documentation} -% -% \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } -% -% -% -% \begin{implementation} -% -% \section{The Implementation} -% -% -% \begin{macrocode} -%<*package> -%<@@=block> -% \end{macrocode} -% -% -% \begin{macrocode} -\ProvidesPackage {latex-lab-testphase-block-tagging} - [\ltblocksdate\space \ltblocksversion\space - blockenv implementation] -% \end{macrocode} -% -% We make use of templates: -% \begin{macrocode} -\RequirePackage{xtemplate} -% \end{macrocode} -% Generell kernel changes, also loaded by the sec and toc code. -% \begin{macrocode} -\RequirePackage{latex-lab-kernel-changes} -% \end{macrocode} -% \begin{macrocode} -\ExplSyntaxOn -% \end{macrocode} -% -% \ufi{this variable(s) must be declared:} -% \begin{macrocode} -\tl_new:N \l_@@_item_align_tl -\tl_new:N\l_@@_legacy_env_params_tl -% \end{macrocode} - -% \subsection{Handling \cs{par} after the end of the list} -% -% An empty line (or a \cs{par}) after a list has semantic meaning as -% it defines whether then following text is logically within the same -% paragraph as the list (no empty line) or whether it starts a new -% paragraph and the paragraph containing the list ends at the end of -% the list (empty line after the list). -% This is handled by \LaTeX{} using a legacy flag called -% \texttt{@endpe} and set of commands inside the -% generic \cs{end} (calling \cs{@doendpe}) and as part of the list -% environments identifying themselves as \enquote{paragraph ending -% environments} (by setting this flag). -% -% For the reimplementation of the list environments including support -% of tagging we need to augment that mechanism slightly and add some -% kernel hook(s) to add the tagging code if needed. -% -% -% -% -% \begin{macro}{\@doendpe} -% The original \LaTeXe{} command is augmented to allow for tagging. -% \begin{macrocode} -\def\@doendpe{\@endpetrue - \def\par - { - \@restorepar - \clubpenalty\@clubpenalty -% \end{macrocode} -% At this point we add the tagging code that closes an open -% \struct{text-unit}, \struct{text} tag combination, -% if necessary: -% \begin{macrocode} - \__kernel_displayblock_doendpe: -% \end{macrocode} -% -% The standard \cs{par} command (\cs{par_end:}) acts on -% \texttt{@endpe} and attempts to close a still open \texttt{text-unit} -% and this would be wrong if it was already closed above. So we -% have to reset the switch to false first. -% \begin{macrocode} - \@endpefalse - \everypar{} - \par - } - \everypar{{\setbox\z@\lastbox} - \everypar{} - \@endpefalse - } -} -% \end{macrocode} -% -% By default we don't do any tagging: -% \begin{macrocode} -\cs_new_eq:NN \__kernel_displayblock_doendpe: \prg_do_nothing: -% \end{macrocode} -% The flag itself should be set globally not locally.\fmi{verify -% that this claim is actually correct!} -% \begin{macrocode} -\def\@endpetrue {\global\let\if@endpe\iftrue} -\def\@endpefalse{\global\let\if@endpe\iffalse} -% \end{macrocode} -% \end{macro} -% -% -% -% \subsection{Object and template interfaces} -% -% -% \begin{objecttype}{blockenv, block, para, list, item} -% All object types expect a single -% key--value argument used to tweak template parameters specific to a -% given use in the document. This section is devoted to template -% interfaces, and the template code is covered later. -% \begin{macrocode} -\DeclareObjectType{blockenv}{1} -\DeclareObjectType{block}{1} -\DeclareObjectType{para}{1} -\DeclareObjectType{list}{1} -\DeclareObjectType{item}{1} -% \end{macrocode} -% \end{objecttype} -% -% -% -% \begin{template}{blockenv display} -% -% \begin{macrocode} -\DeclareTemplateInterface{blockenv}{display}{1} -{ - env-name : tokenlist , - tag-name : tokenlist , - tag-class : tokenlist , - tagging-recipe : tokenlist = standard, - level-increase : boolean = true , - setup-code : tokenlist , - block-instance : tokenlist = displayblock , - para-instance : tokenlist , - inner-level-counter : tokenlist, - max-inner-levels : tokenlist = 4, - inner-instance-type : tokenlist = list , - inner-instance : tokenlist , - para-flattened : boolean = false , - final-code : tokenlist = \ignorespaces , -} -% \end{macrocode} -% \end{template} -% -% -% \begin{template}{block display} -% -% \begin{macrocode} -\DeclareTemplateInterface{block}{display}{1} -{ - heading : tokenlist = , %?? - beginsep : skip = \topsep , - begin-par-skip : skip = \partopsep , - par-skip : skip = \parsep , - end-skip : skip = \KeyValue{beginsep} , % conflict with name below - end-par-skip : skip = \KeyValue{begin-par-skip} , - beginpenalty : integer = \UseName{@beginparpenalty} , - endpenalty : integer = \UseName{@endparpenalty} , - leftmargin : length = \leftmargin , - rightmargin : length = \rightmargin , - parindent : length = \listparindent , -% font : tokenlist % maybe add? (or more general for fonts and color) -} -% \end{macrocode} -% \end{template} -% -% -% \begin{template}{para std} -% -% \begin{macrocode} -\DeclareTemplateInterface{para}{std}{1} -{ - indent-width : length = \parindent , - start-skip : skip = 0pt , - left-skip : skip = 0pt , - right-skip : skip = 0pt , - end-skip : skip = \@flushglue , - fixed-word-spaces : boolean = false , - final-hyphen-demerits : integer = 5000 , - cr-cmd : tokenlist = \@normalcr , - para-class : tokenlist = justify , -} -% \end{macrocode} -% \end{template} -% -% -% \begin{template}{list std} -% -% \begin{macrocode} -\DeclareTemplateInterface{list}{std}{1} % optional -{ - counter : tokenlist = , - item-label : tokenlist = , - start : integer = 1 , - resume : boolean = false , - item-instance : instance{item} = basic , - item-skip : skip = \itemsep , - item-penalty : integer = \UseName{@itempenalty} , - item-indent : length = 0pt , % was \itemindent - label-width : length = \labelwidth , - label-sep : length = \labelsep , - legacy-support : boolean = false , -} -% \end{macrocode} -% \end{template} -% -% -% \begin{template}{item std} -% -% \begin{macrocode} -\DeclareTemplateInterface{item}{std}{1} - { - counter-label : function{1} = \arabic{#1} , - counter-ref : function{1} = \KeyValue{counter-label} , - label-ref : function{1} = #1 , - label-autoref : function{1} = item~#1 , - label-format : function{1} = #1 , - label-strut : boolean = false , - label-align : choice {left,center,right,parleft} = right , - label-boxed : boolean = true , - next-line : boolean = false , - text-font : tokenlist , - compatibility : boolean = true , - } -% \end{macrocode} -% \end{template} -% -% -% -% -% -% -% \subsection{Useful helper commands} -% -% This section collects \pkg{expl3} commands that will be useful. -% -% \begin{macro}{\@@_skip_set_to_last:N,\@@_skip_remove_last:} -% Set a skiip register to the value of an immediately preceding -% skip or zero if there was none -% \begin{macrocode} -\cs_new_protected:Npn \@@_skip_set_to_last:N #1 { - \skip_set:Nn #1 { \tex_lastskip:D } -} -% \end{macrocode} -% Remove a skip previous skip if it is directly in front (not -% allowed in unrestricted vertical mode). -% \begin{macrocode} -\cs_new_eq:NN \@@_skip_remove_last: \tex_unskip:D -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\tl_if_novalue:nTF} -% -% \begin{macrocode} -\cs_generate_variant:Nn \tl_if_novalue:nTF { o } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\tag_if_active:T} -% If tagging support is not loaded then we shouldn't try to execute -% any tagging related commands. Eventually this can go once the -% basic support is available in the kernel. -% \fmi{can vanish one day} -% \begin{macrocode} -\cs_if_exist:NF \tag_if_active:T - { \cs_new_eq:NN \tag_if_active:T \use_none:n } -% \end{macrocode} -% \end{macro} -% -% \subsubsection{Debugging} -% -% -% \begin{variable}{\g_@@_debug_bool} -% -% \begin{macrocode} -\bool_new:N \g_@@_debug_bool -% \end{macrocode} -% \end{variable} -% -% -% \begin{macro}{\@@_debug:n,\@@_debug_typeout:n} -% -% \begin{macrocode} -\cs_new_eq:NN \@@_debug:n \use_none:n -\cs_new_eq:NN \@@_debug_typeout:n \use_none:n -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\block_debug_on:,\block_debug_off:, -% \@@_debug_gset:} -% \begin{macrocode} -\cs_new_protected:Npn \block_debug_on: - { - \bool_gset_true:N \g_@@_debug_bool - \@@_debug_gset: - } -% \end{macrocode} -% -% \begin{macrocode} -\cs_new_protected:Npn \block_debug_off: - { - \bool_gset_false:N \g_@@_debug_bool - \@@_debug_gset: - } -% \end{macrocode} -% -% \begin{macrocode} -\cs_new_protected:Npn \@@_debug_gset: - { - \cs_gset_protected:Npx \@@_debug:n ##1 - { \bool_if:NT \g_@@_debug_bool {##1} } - \cs_gset_protected:Npx \@@_debug_typeout:n ##1 - { \bool_if:NT \g_@@_debug_bool { \typeout{==>~ ##1} } } - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\DebugBlocksOn,\DebugBlocksOff} -% -% \begin{macrocode} -\cs_new_protected:Npn \DebugBlocksOn { \block_debug_on: } -\cs_new_protected:Npn \DebugBlocksOff { \block_debug_off: } -% \end{macrocode} -% -% \begin{macrocode} -\DebugBlocksOff -% \end{macrocode} -% \end{macro} -% -% -% -% \subsection{Implementation of the document-level block environments} -% -% Most such environments are pretty simple: they take an option -% argument and call a \texttt{blockenv} instance to do the work. At -% the end of environment we call \cs{endblockenv} to finish. -% -% -% \subsubsection{Displayblock environments} -% -% -% There are two basic block environment which are similar to -% \LaTeXe{}'s \env{trivlist} except that there aren't degenerated -% lists and thus have no hidden \cs{item} inside. -% -% -% \begin{environment}{displayblock} -% -% \begin{macrocode} -\NewDocumentEnvironment{displayblock}{ !O{} } - { \UseInstance{blockenv}{displayblock} {#1} } - { \endblockenv } -% \end{macrocode} -% \end{environment} -% -% -% -% -% \begin{environment}{displayblockflattened} -% -% \begin{macrocode} -\NewDocumentEnvironment{displayblockflattened}{ !O{} } - { \UseInstance{blockenv}{displayblockflattened} {#1} } - { \endblockenv } -% \end{macrocode} -% \end{environment} -% -% -% -% -% -% -% -% -% \begin{environment}{center,flushleft,flushright} -% -% \begin{macrocode} -\AddToHook{begindocument/before}{ - \RenewDocumentEnvironment{center} { !O{} } - { \UseInstance{blockenv}{center}{#1} } - { \endblockenv } -% \end{macrocode} -% -% \begin{macrocode} - \RenewDocumentEnvironment{flushright} { !O{} } - { \UseInstance{blockenv}{flushright}{#1} } - { \endblockenv } -% \end{macrocode} -% -% \begin{macrocode} - \RenewDocumentEnvironment{flushleft} { !O{} } - { \UseInstance{blockenv}{flushleft}{#1} } - { \endblockenv } -} -% \end{macrocode} -% -% -% \end{environment} -% -% -% -% -% \subsubsection{Display quote environments} -% -% -% \begin{environment}{quote,quotation} -% -% \begin{macrocode} -\AddToHook{begindocument/before}{ - \RenewDocumentEnvironment{quote}{ !O{} } - { \UseInstance{blockenv}{quote} {#1} } - { \endblockenv } -% \end{macrocode} -% -% \begin{macrocode} - \RenewDocumentEnvironment{quotation}{ !O{} } - { \UseInstance{blockenv}{quotation} {#1} } - { \endblockenv } -} -% \end{macrocode} -% \end{environment} -% -% -% -% -% -% -% \subsubsection{Verbatim environments} -% -% -% \begin{environment}{verbatim,verbatim*} -% -% \begin{macrocode} -\AddToHook{begindocument/before}{ - \RenewDocumentEnvironment{verbatim}{ !O{} } - { \UseInstance{blockenv}{verbatim} {#1} -% \end{macrocode} -% This is the part of the code where \env{verbatim} -% and\env{verbatim*} differ. -% \begin{macrocode} - \@setupverbinvisiblespace\frenchspacing\@vobeyspaces - \@xverbatim - } - { \endblockenv } -% \end{macrocode} -% -% \begin{macrocode} - \RenewDocumentEnvironment{verbatim*}{ !O{} } - { \UseInstance{blockenv}{verbatim} {#1} - \@setupverbvisiblespace\frenchspacing\@vobeyspaces - \@sxverbatim - } - { \endblockenv } -} -% \end{macrocode} -% \end{environment} -% -% -% -% \paragraph{Helper commands for verbatim} -% -% -% \begin{macro}{\legacyverbatimsetup} -% -% This code resembles the \LaTeXe{} verbatim implementation with a -% slight twist: in \LaTeXe{} each code line was a paragraph using -% \cs{leftskip}=\cs{@totalleftmargin}. This was possible because -% the whole environment was implemented as a trivlist. As this is -% no longer the case setting \cs{leftskip} would alter the layout -% of a surrounding list. So instead we need to make sure that the -% paragraph end is executed in a group so that any parshape setup -% is preserved. -% \begin{macrocode} -%<@@=> -\def\legacyverbatimsetup{% - \language\l@nohyphenation - \@tempswafalse - \def\par{% - \if@tempswa - \leavevmode \null {\@@par}\penalty\interlinepenalty - \else - \@tempswatrue - \ifhmode{\@@par}\penalty\interlinepenalty\fi - \fi}% - \let\do\@makeother \dospecials - \obeylines \verbatim@font \@noligs - \everypar \expandafter{\the\everypar \unpenalty}% -% \end{macrocode} -% -% \begin{macrocode} - \tl_set:Nn \l__tag_para_main_tag_tl {codeline} - \tagtool{paratag=Code}% oder faster: \tl_set:Nn\l__tag_para_tag_tl{Code} -} -%<@@=block> -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@setupverbinvisiblespace} -% In the \pdfTeX{} engine we need to use \cs{pdffakespace} chars -% for the invisible spaces. -% \begin{macrocode} -\newcommand\@setupverbinvisiblespace{} -\tag_if_active:T { - \bool_if:NF\g__tag_mode_lua_bool - { - \renewcommand\@setupverbinvisiblespace{\def\@xobeysp{\nobreakspace\pdffakespace}} - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% \subsubsection{Standard list environments} -% -% -% \begin{environment}{itemize,enumerate,description} -% -% For the standard lists everything is managed by the blockenv instance. -% \begin{macrocode} -\AddToHook{begindocument/before}{ - \RenewDocumentEnvironment{itemize}{!O{}} - { \UseInstance{blockenv}{itemize} {#1} } - { \endblockenv } -% \end{macrocode} -% -% \begin{macrocode} - \RenewDocumentEnvironment{enumerate}{!O{}} - { \UseInstance{blockenv}{enumerate} {#1} } - { \endblockenv } -% \end{macrocode} -% -% \begin{macrocode} - \RenewDocumentEnvironment{description}{!O{}} - { \UseInstance{blockenv}{description} {#1} } - { \endblockenv } -} -% \end{macrocode} -% \end{environment} -% -% -% -% -% -% -% \begin{environment}{list} -% -% The legacy 2e list environment is more complicated as we have to get the -% extra arguments accounted for. -% \begin{macrocode} -\AddToHook{begindocument/before}{ - \RenewDocumentEnvironment{list}{O{} m m } - { -% \end{macrocode} -% We do this by storing them away and then call the list -% instance. Inside this instance the \texttt{setup-code} key -% contains \cs{legacylistsetupcode}, which makes use of the stored values. -% \begin{macrocode} - \tl_set:Nn \@itemlabel {#2} - \tl_set:Nn \l_@@_legacy_env_params_tl {#3} -% \end{macrocode} -% -% \begin{macrocode} - \UseInstance{blockenv}{list} {#1} - } - { \endblockenv } -} -% \end{macrocode} -% -% Again something that should probably elsewhere: the rolemapping. -% \begin{macrocode} -\tag_if_active:T { - \tagpdfsetup{add-new-tag={tag=list,role=L}} -} -% \end{macrocode} -% \end{environment} -% -% -% -% \begin{variable}{\l_@@_env_params_tl} -% Declare the variable for the parameter argument; \cs{@itemlabel} -% is already declared in \LaTeXe{}. -% \begin{macrocode} -\tl_new:N \l_@@_env_params_tl -% \end{macrocode} -% \end{variable} -% -% -% \begin{macro}{\legacylistsetupcode} -% -% And here is the extra code for use in the list instance setup -% inside the key \texttt{setup-code}. -% \begin{macrocode} -\cs_new:Npn \legacylistsetupcode { -% \end{macrocode} -% Reset values to defaults: -% \begin{macrocode} - \dim_zero:N \listparindent - \dim_zero:N \rightmargin - \dim_zero:N \itemindent -% \end{macrocode} -% -% By default a \env{list} environment is not numbered: -% \begin{macrocode} - \tl_set:Nn \@listctr {} - \legacy_if_set_false:n { @nmbrlist } % needed if lists are nested -% \end{macrocode} -% By default there is a simple definition for \cs{makelabel}. It can be -% overwritten in the second mandatory argument to the list -% environment (stored in \cs{l_@@_legacy_env_params_tl}) and -% is used if the instance sets the compatibility key to true. -% \begin{macrocode} - \let\makelabel\@mklab % TODO: customize -% \end{macrocode} -% Now we use the argument with parameter settings to update some or -% all of the above defaults: -% \begin{macrocode} - \l_@@_legacy_env_params_tl -% \end{macrocode} -% As we don't know much about this list we can only make a guess about -% the nature of the list and the setting of the tag name (default -% \texttt{list} rolemapped to \texttt{L}) and any tag attributes -% may have to be overwritten in the optional key/value argument. But we do have some hints to play with. -% \begin{macrocode} - \legacy_if:nTF { @nmbrlist } - { \tl_set:Nn \l__tag_L_attr_class_tl {enumerate} } % numbered list - { \tl_if_empty:NTF \@itemlabel - { \tl_set:Nn \l__tag_L_attr_class_tl {list} } % no label - { \tl_set:Nn \l__tag_L_attr_class_tl {itemize} } % unnumbered, unordered - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% \begin{environment}{trivlist} -% -% \begin{macrocode} -\AddToHook{begindocument/before}{ - \RenewDocumentEnvironment{trivlist}{ !O{} } - { \list[#1]{} - { - \dim_zero:N \leftmargin - \dim_zero:N \labelwidth - \cs_set_eq:NN \makelabel \use:n - } - } - { \endblockenv } -} -% \end{macrocode} -% \end{environment} -% -% -% \subsubsection{Theorem-like environments} -% -% Theorem-like environments are defined in \LaTeX{} with the help of -% \cs{newtheorem} declarations. Internally they used a list with a -% single item. Using lists was convenient back then, but in a tagged -% document you end up with a strange structure. We therefore alter the -% mechanism. -% -% -% \begin{macro}{\newtheorem} -% This is a slightly streamlined version of \cs{newtheorem}, but it -% still uses a lot of the 2e code for now. Eventually this will change. -% \begin{macrocode} -\RenewDocumentCommand \newtheorem { m O{#1} m o } -{ - \expandafter\@ifdefinable\csname #1\endcsname - { - \str_if_eq:nnTF{#1}{#2} - { - \@definecounter {#2} - \IfNoValueTF {#4} - { % @ynthm - \tl_gset:cx { the #2 } - { - \@thmcounter{#2} - } - } - { % @xnthm - \@newctr{#1}[#4] - \tl_gset:cx { the #2 } - { - \expandafter\noexpand\csname the#4\endcsname - \@thmcountersep - \@thmcounter{#2} - } - } - } - { % @othm - \@ifundefined{c@#2} - { \@nocounterr{#2} } - { - \tl_gset:cn { the #1 } - { \UseName { the #2 } } - } - } - \global\@namedef{#1} { \@thm{#2}{#3} } - \global\@namedef{end#1}{ \@endtheorem } - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@begintheorem,\@opargbegintheorem} -% -% The \cs{@thm} command expands to either \cs{@beginthorem} or -% \cs{@opargbegintheorem}. For the moment we stick with this as it -% will help with the transion. But instead of using a -% \env{trivlist} we use a blockenv and some tagging for the title -% (as a Caption). -% We do not want potential tagging from \cs{textbf} here, -% so we use \cs{bfseries} to set the font. -% \begin{macrocode} -\def\@begintheorem#1#2{ - \UseInstance{blockenv}{theorem}{} - \tagpdfparaOff - \mode_leave_vertical: - \tag_struct_begin:n{tag=Caption} - \group_begin: - \bfseries - \tag_mc_begin:n {} - #1\ - \tag_mc_end: - \tag_struct_begin:n{tag=Lbl} - \tag_mc_begin:n {} - #2 - \tag_mc_end: - \tag_struct_end: - \group_end: - \tag_struct_end: - \tagpdfparaOn -% \end{macrocode} -% -% \begin{macrocode} - \@@_start_para_structure_unconditionally:n { \PARALABEL } -% \end{macrocode} -% -% \begin{macrocode} - \itshape - \hskip\labelsep - \ignorespaces -} -\def\@opargbegintheorem#1#2#3{ - \UseInstance{blockenv}{theorem}{} - \tagpdfparaOff - \mode_leave_vertical: - \tag_struct_begin:n{tag=Caption} - \group_begin: - \bfseries - \tag_mc_begin:n {} - #1\ - \tag_mc_end: - \tag_struct_begin:n{tag=Lbl} - \tag_mc_begin:n {} - #2 - \tag_mc_end: - \tag_struct_end: - \tag_mc_begin:n {} - \ (#3) - \tag_mc_end: - \group_end: - \tag_struct_end: - \tagpdfparaOn -% \end{macrocode} -% -% \begin{macrocode} - \@@_start_para_structure_unconditionally:n { \PARALABEL } -% \end{macrocode} -% -% \begin{macrocode} - \itshape - \hskip\labelsep - \ignorespaces -} -% \end{macrocode} -% -% \begin{macrocode} -\def\@endtheorem{\endblockenv} -% \end{macrocode} -% \end{macro} -% -% -% -% -% -% -% \subsection{Implementation of templates} -% -% -% \subsubsection{Implementation of blockenv templates \ldots} -% -% -% -% \begin{macro}{\g_block_nesting_depth_int} -% \LaTeXe{} already has a counter to record the nesting depth of -% blocks, but we want our own name because it isn't really tied to -% \enquote{lists} any more. However, \cs{@listdepth} is really part -% of the legacy interface (for example \env{minipage} alters it to -% point to a different counter) so that we are stuck with using at -% least indirectly for now and the following line makes this look -% like an L3 integer variable but internally expands to \cs{@listdepth}: -% \begin{macrocode} -\cs_new:Npn \g_block_nesting_depth_int { \@listdepth } % a fake int - % for now -% \end{macrocode} -% \end{macro} -% -% -% \begin{template}{blockenv display} -% -% \begin{macrocode} -\DeclareTemplateCode{blockenv}{display}{1} -{ - env-name = \l_@@_env_name_tl , - tag-name = \l_@@_tag_name_tl , - tag-class = \l_@@_tag_class_tl , - tagging-recipe = \l_@@_tagging_recipe_tl , - level-increase = \l_@@_level_incr_bool , - setup-code = \l_@@_setup_code_tl , - block-instance = \l_@@_block_instance_tl , - para-instance = \l_@@_para_instance_tl , - inner-level-counter = \l_@@_inner_level_counter_tl , - max-inner-levels = \l_@@_max_inner_levels_tl , - inner-instance-type = \l_@@_inner_instance_type_tl , - inner-instance = \l_@@_inner_instance_tl , - para-flattened = \l__tag_para_flattened_bool , - final-code = \l_@@_final_code_tl , -} -{ - \@@_debug_typeout:n{\l_@@_env_name_tl -env-start} -% - \tl_if_empty:nF {#1} { \SetTemplateKeys{blockenv}{display}{#1} } -% -% \end{macrocode} -% We need to know later if we haved nested blockenvs inside -% a flattened environment. Whenever we start a new blockenv we -% increment \cs{\l_@@_flattened_level_int} if it is already -% different from zero. If it is zero we increment it if flattening -% is requested. -% Thus a value of \texttt{0} means no flattening requested so far -% and \texttt{1} means this is the first blockenv requesting -% flattening. In either case we have to make sure that the blockenv -% is surrounded by a \texttt{text-unit} tag, while for any value above -% \texttt{1} we have to omit the \texttt{text-unit}. - % \begin{macrocode} - \int_compare:nNnTF \l_@@_flattened_level_int > 0 - { - \int_incr:N \l_@@_flattened_level_int - } - { - \bool_if:NT \l__tag_para_flattened_bool - { - \int_incr:N \l_@@_flattened_level_int - } - } -% - \tl_if_empty:NF \l_@@_inner_level_counter_tl - { - \int_compare:nNnTF \l_@@_inner_level_counter_tl > - { \l_@@_max_inner_levels_tl - 1 } - { \@toodeep } - { \int_incr:N \l_@@_inner_level_counter_tl } % not clean "o"? - } -% \end{macrocode} -% Legacy defaults are only roped in if the list level changes. For -% display blocks that remain on the same level the current values -% are kept. -% \begin{macrocode} - \bool_if:NT \l_@@_level_incr_bool - { - \int_compare:nNnTF \g_block_nesting_depth_int > - { \c@maxblocklevels - 1 } - { \@toodeep } - { - \int_gincr:N \g_block_nesting_depth_int -% \end{macrocode} -% If there are no legacy defaults for that level then the next line -% does nothing, i.e., the current values (from the last level -% become the defaults for the next. -% \begin{macrocode} - \use:c { @list \int_to_roman:n { \g_block_nesting_depth_int } } - } - } -% \end{macrocode} -% If we are doing tagging we load one of the available recipes for -% tagging, which alters various kernel hooks to add appropriate -% tagging structures. -% \begin{macrocode} - \tag_if_active:T { \use:c { @@_recipe_ \l_@@_tagging_recipe_tl : } } -% \end{macrocode} -% Then run the setup code if any is given in the instance. -% \begin{macrocode} - \l_@@_setup_code_tl -% \end{macrocode} -% Next call a block instance at the appropriate level passing it -% any key/value list provided in the optional argument (keys that -% are not recognized are ignored---currently with an -% error). -% \begin{macrocode} - \@@_debug_typeout:n{use~ instance:~ - \l_@@_block_instance_tl - \int_use:N \g_block_nesting_depth_int } - \UseInstance{block} - { \l_@@_block_instance_tl - \int_use:N - \g_block_nesting_depth_int } - {#1} -% \end{macrocode} -% After the block instance call the para and then inner (list) -% instance if either or both are -% specified (which may not be the case). -% \begin{macrocode} - \tl_if_empty:NF \l_@@_para_instance_tl - { - \@@_debug_typeout:n{use~ para~ instance:~ \l_@@_para_instance_tl } -% \end{macrocode} -% For now we don't offer to alter instance parameters here so we -% pass an empty argument. -% \begin{macrocode} - \UseInstance{para}{ \l_@@_para_instance_tl } {} - } -% \end{macrocode} -% In the inner instance may have its own levels or none depending -% on which the instance name differs. Again we pass it the optional -% key/value list. -% \begin{macrocode} - \tl_if_empty:NF \l_@@_inner_instance_tl - { - \@@_debug_typeout:n{use~ instance:~ \l_@@_inner_instance_tl - \tl_if_empty:NF \l_@@_inner_level_counter_tl - { - \int_use:N \l_@@_inner_level_counter_tl }} - \UseInstance{ \l_@@_inner_instance_type_tl } - { \l_@@_inner_instance_tl - \tl_if_empty:NF \l_@@_inner_level_counter_tl - { - \int_use:N \l_@@_inner_level_counter_tl } % not clean - % use "o"? - } - {#1} - } -% \end{macrocode} -% We finish off with \cs{l_@@_final_code_tl} which defaults to -% \cs{ignorespaces} so that spaces between \verb=\begin{...}= and -% the start of the text are ignored. -% \begin{macrocode} - \l_@@_final_code_tl -} -% \end{macrocode} -% \end{template} -% -% -% \begin{macro}{\l_@@_flattened_level_int} -% Count the levels of nested blockenvs starting with the first that -% is \enquote{flattened}. -% \begin{macrocode} -\int_new:N \l_@@_flattened_level_int -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\c@maxblocklevels} -% A counter to increase or decrease the number of supported -% level. If increased, one needs to suply additional level instances. -% \begin{macrocode} -\newcounter{maxblocklevels} -\setcounter{maxblocklevels}{6} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\endblockenv} -% The code executed when a blockenv ends is 99\% the same for all -% blockenvs (at least up to now). Small differences exist, though. They -% are accounted for first in the conditionals. -% -% We make this a public command so that new block environments can -% be set up without the need to resort to L3 layer -% programming.\fmi{name is bad} -% \begin{macrocode} -\cs_new:Npn \endblockenv { - \@@_debug_typeout:n{blockenv~ common~ ending \on@line} -% \end{macrocode} -% If this block was incrementing the level we have to decrement it -% now again: -% \begin{macrocode} - \bool_if:NT \l_@@_level_incr_bool - { \int_gdecr:N \g_block_nesting_depth_int } -% \end{macrocode} -% If this block was a list and there are still \cs{item} labels to -% be placed we move to horizontal mode to get them typeset. -% \begin{macrocode} - \legacy_if:nT { @inlabel } - { - \mode_leave_vertical: - \legacy_if_gset_false:n { @inlabel } - } -% \end{macrocode} -% In a pure ``displayblock'' scenario \texttt{@newlist} will be -% always false and the code bypassed, but we may have an outer list -% followed immediately by a displayblock (with the \cs{item} missing) -% \begin{macrocode} - \legacy_if:nT { @newlist } - { - \@noitemerr - \legacy_if_gset_false:n { @newlist } - } - \mode_if_horizontal:TF - { \@@_skip_remove_last: \@@_skip_remove_last: \par } - { \@inmatherr{\end{\@currenvir}} } -% \end{macrocode} -% Once we are back in vertical mode we can add the appropriate -% closing tagging structure(s), if we are doing tagging. -% \begin{macrocode} - \__kernel_displayblock_end: -% \end{macrocode} -% What to do in terms of vertical spacing in different situations -% is still somewhat open to debate, right now this is more or less -% implementing what \LaTeXe{} list environment have been -% doing.\fmi{some redesign/extensions here?} -% \begin{macrocode} -% \@@_debug_typeout:n{@noparlist = -% \legacy_if:nTF { @noparlist }{true}{false}} - \legacy_if:nF { @noparlist } - { - \@@_skip_set_to_last:N \l_tmpa_skip - \dim_compare:nNnT \l_tmpa_skip > \c_zero_dim - { - \skip_vertical:n { - \l_tmpa_skip } - \skip_vertical:n { \l_tmpa_skip + \parskip - \@outerparskip } - } - \addpenalty \@endparpenalty - \addvspace \l_@@_topsepadd_skip -% \end{macrocode} -% \LaTeXe{} triggered the paragraph handling after a list at this -% point here, i.e., only if the list didn't start a paragraph. One -% can make a case for that, but it can be somewhat surprising to -% the user and there is a good argument that even such a list could -% be followed expanatory text that is part of the same paragraph -% and doesn't start a new one.\fmi{decide which logic we want to -% use! If the old logic is used we need to close the text-unit -% ourselves in the true branch} -% \begin{macrocode} -% \legacy_if_gset_true:n { @endpe } - } -% \end{macrocode} -% So this is for now always done. Probably \cs{l_@@_topsepadd_skip} above -% should be added only if the paragraph ends here and not if it -% continues, so this need some further cleanup.\fmi{decide} - % \begin{macrocode} - \bool_if:NTF \l_@@_standalone_bool -% \end{macrocode} -% It is possible that \texttt{@endpe} is true because a -% displayblock has just ended before we end the standalone -% displayblock and in that casevthere is no outer -% \struct{text-unit} so we have to explicitly set \texttt{@endpe} -% back to false to prevent it from closing a structure later that -% isn't there. -% \begin{macrocode} - { \legacy_if_gset_false:n { @endpe } } - { \legacy_if_gset_true:n { @endpe } } -} -% \end{macrocode} -% -% \end{macro} -% -% -% \begin{macro}{\__kernel_displayblock_end:} -% The kernel hook for tagging at the end of the block. -% \begin{macrocode} -\cs_new:Npn \__kernel_displayblock_end: { - \@@_debug_typeout:n{\detokenize{__kernel_displayblock_end:}} -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\l_@@_standalone_bool} -% -% \begin{macrocode} -\bool_new:N \l_@@_standalone_bool -\bool_set_false:N \l_@@_standalone_bool -% \end{macrocode} -% \end{macro} -% -% -% -% -% -% \subsubsection{Implementation of para templates \ldots} -% -% \begin{template}{para std} -% -% \begin{macrocode} -\DeclareTemplateCode{para}{std}{1} -{ - indent-width = \parindent , - start-skip = \l__par_start_skip , % name?? - left-skip = \leftskip , - right-skip = \rightskip , - end-skip = \parfillskip , - fixed-word-spaces = \l__par_fixed_word_spaces_bool , % name?? - final-hyphen-demerits = \finalhyphendemerits , - cr-cmd = \\ , - para-class = \l_tag_para_attr_class_tl , -} -{ - \tl_if_empty:nF {#1} { \SetTemplateKeys{para}{std}{#1} } - \skip_set:Nn \@rightskip \rightskip -} -% \end{macrocode} -% \end{template} -% -% -% -% -% -% \subsubsection{Implementation of block templates \ldots} -% -% -% -% -% -% \begin{template}{block display} -% -% \begin{macrocode} -\DeclareTemplateCode{block}{display}{1} -{ - heading = \l_@@_heading_tl , - beginsep = \topsep , - begin-par-skip = \partopsep , - par-skip = \parsep , - end-skip = \l_@@_botsep_skip , - end-par-skip = \l_@@_parbotsep_skip , - beginpenalty = \@beginparpenalty , - endpenalty = \@endparpenalty , - rightmargin = \rightmargin , - leftmargin = \leftmargin , - parindent = \listparindent , -} -{ - \tl_if_empty:nF {#1} { \SetTemplateKeys{block}{display}{#1} } -% \end{macrocode} -% \fmi{generalize heading usage (or drop?)} -% \begin{macrocode} - \tl_if_blank:oF \l_@@_heading_tl - { \mode_leave_vertical: \textbf{\l_@@_heading_tl} } % TODO customize -% \end{macrocode} -% The code largely follows the logic of \LaTeXe{}'s \env{trivlist} -% implementation as far as it applicable for the \enquote{display -% block} but coded using the L3 programming layer. However, we keep -% all the legacy variables (e.g., \texttt{@noskipsec}) if there is -% some chance that they are set in classes or packages. -% \begin{macrocode} - \legacy_if:nT { @noskipsec } { \mode_leave_vertical: } - \skip_set:Nn \l_@@_topsepadd_skip { \topsep } - \mode_if_vertical:TF - { - \skip_add:Nn \l_@@_topsepadd_skip { \partopsep } -% \end{macrocode} -% At this point it is safe to add tagging structure(s) so we have -% a kernel-owned hook here for tagging. This is used to possibly -% start a paragraph structure (to surround the block, for example, -% in case of lists) and possibly do some other preparation for -% tagging the block. -% \begin{macrocode} - \__kernel_displayblock_beginpar_vmode: - } - { -% \end{macrocode} -% If we are in horizontal mode then the displayblock has to return -% to vertical mode now (after removing any immediately preceding -% skip or kern. But before we actually issue the\cs{par} we execute -% a kernel hook in which we can add tagging code. This hook is -% \enquote{weird} because by default it does nothing, but if -% tagging is wanted it takes an argument and grabs the following -% \cs{par} in order to put tagging code before and after the \cs{par}. -% \begin{macrocode} - \@@_skip_remove_last: \@@_skip_remove_last: - \__kernel_displayblock_beginpar_hmode:w \par - } -% \end{macrocode} -% Now we are back to legacy list implementation \ldots -% \begin{macrocode} - \legacy_if:nTF { @inlabel } - { - \legacy_if_set_true:n { @noparitem } - \legacy_if_set_true:n { @noparlist } - } - { - \legacy_if:nT { @newlist } { \@noitemerr } - \legacy_if_set_false:n { @noparlist } - \skip_set_eq:NN \l_@@_effective_top_skip \l_@@_topsepadd_skip - } - \skip_add:Nn \l_@@_effective_top_skip { \parskip } -% \end{macrocode} -% Next lines set some paragraph defaults, this may get overwritten -% if there is a \key{para-instance} specified on the \xt{blockenv}. -% \begin{macrocode} - \skip_zero:N \leftskip - \skip_set_eq:NN \rightskip \@rightskip - \skip_set_eq:NN \parfillskip \@flushglue -% \end{macrocode} -% The next lines establish a parshape which is retained across -% paragraphs be executing \cs{para_end:} within a group and thus -% reestablishing the parshape for the next paragraph again. In case -% a list got started \cs{par} is ignored until we have seen an -% \cs{item} (or we have executed \cs{par} one thousand times. -% \begin{macrocode} - \int_zero:N \par@deathcycles - \@setpar - { - \legacy_if:nTF { @newlist } - { - \int_incr:N \par@deathcycles - \int_compare:nNnTF \par@deathcycles > { 1000 } - { \@noitemerr - { \para_end: } - } - } - { - { \para_end: } - } - } - \skip_set_eq:NN \@outerparskip \parskip - \skip_set_eq:NN \parskip \parsep - \dim_set_eq:NN \parindent \listparindent - \dim_add:Nn \linewidth { - \rightmargin - \leftmargin } - \dim_add:Nn \@totalleftmargin { \leftmargin } - \tex_parshape:D 1 ~ \@totalleftmargin \linewidth -% \end{macrocode} -% This is the point where we are ready to add the tagging structure -% for the block, e.g., an \verb==, a \verb=
= or some -% other structure. -% \begin{macrocode} - \__kernel_displayblock_begin: -% \end{macrocode} -% Finally, we have to output the vertical separation and penalty at -% the start of the block and make corrections for a change in -% \cs{parskip} and some other housekeeping, unless this block is inside a list and the list -% \cs{item} has not yet placed. In that case the vertical -% space and penalty us suppressed. This -% is controled through the legacy switches \texttt{@noparitem}, -% \texttt{minipage}, and \texttt{@nobreak}. -% \begin{macrocode} - \legacy_if:nTF { @noparitem } - { - \legacy_if_set_false:n { @noparitem } - \hbox_gset:Nn \g_@@_labels_box - { - \skip_horizontal:n { - \leftmargin } - \hbox_unpack_drop:N \g_@@_labels_box - \skip_horizontal:n { \leftmargin } - } -% \end{macrocode} -% \fmi{document 2e logic used here} -% \begin{macrocode} - \legacy_if:nF { @minipage } % Why this chunk of code? - { - \@@_skip_set_to_last:N \l_@@_tmpa_skip - \skip_vertical:n { - \l_@@_tmpa_skip } - \skip_vertical:n { \l_@@_tmpa_skip + \@outerparskip - \parskip } - } - } - { - \legacy_if:nTF { @nobreak } - { \addvspace{\skip_eval:n{\@outerparskip-\parskip}} } - { - \addpenalty \@beginparpenalty - \addvspace \l_@@_effective_top_skip - \addvspace{-\parskip} - } - } -} -% \end{macrocode} -% -% -% Extra keys to support enumitem conventions: -% \begin{macrocode} -\keys_define:nn { template/block/display } -{ - ,topsep .skip_set:N = \topsep - ,partopsep .skip_set:N = \partopsep - ,listparindent .skip_set:N = \listparindent -} -% \end{macrocode} -% \end{template} -% -% -% -% \begin{macro}{\__kernel_displayblock_begin:, -% \__kernel_displayblock_beginpar_hmode:w, -% \__kernel_displayblock_beginpar_vmode:} -% The internal kernel hooks for tagging. -% \begin{macrocode} -\cs_new:Npn \__kernel_displayblock_begin: { - \@@_debug_typeout:n{\detokenize{__kernel_displayblock_begin:}} -} -% \end{macrocode} -% -% \begin{macrocode} -\cs_new:Npn \__kernel_displayblock_beginpar_hmode:w { - \@@_debug_typeout:n{\detokenize{__kernel_displayblock_beginpar_hmode:w}} -} -% \end{macrocode} -% -% \begin{macrocode} -\cs_new:Npn \__kernel_displayblock_beginpar_vmode: { - \@@_debug_typeout:n{\detokenize{__kernel_displayblock_beginpar_vmode:}} -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% \subsubsection{Implementation of list templates \ldots} -% -% -% -% \begin{macro}{\@itemlabel,\@listctr} -% Both \cs{@itemlabel} and \cs{@listctr} from the \LaTeXe{} list -% implementation are used (or set) by various packages. We -% therefore use them too, so that these packages have a fighting -% chance to work with the new tagging-aware implementation for -% \env{list}. -% \begin{macrocode} -\tl_new:N \@itemlabel % should have a top-level definition -\tl_new:N \@listctr % should have a top-level definition -% \end{macrocode} -% \end{macro} -% -% -% -% -% -% \begin{template}{list std} -% -% This template implements numbered and unnumbered lists and can -% be combined with display blocks or with inline blocks. -% \begin{macrocode} -\DeclareTemplateCode{list}{std}{1} -{ - counter = \l_@@_counter_tl, - item-label = \l_@@_item_label_tl, - start = \l_@@_counter_start_int , - resume = \l_@@_resume_bool , - item-instance = \@@_item_instance:n , - item-skip = \itemsep , -% item-par-skip = \parsep , - item-penalty = \@itempenalty , - item-indent = \itemindent , - label-width = \labelwidth , - label-sep = \labelsep , - legacy-support = \l_@@_legacy_support_bool , % FMi questionable -} -{ - \@@_debug_typeout:n{template:list:std} -% - \tl_if_empty:nF {#1} { \SetTemplateKeys{list}{std}{#1} } -% \end{macrocode} -% Has this list a counter name defined in the instance? -% \begin{macrocode} - \tl_if_empty:NTF \l_@@_counter_tl - { -% \end{macrocode} -% If not we check if \cs{@listctr} has a non-empty value to be used -% for the list counter. -% -% We better test for blank not empty in case somebody had defined -% \cs{@listctr} using \cs{renewcommand} or \cs{cs_set:Npn}. -% \begin{macrocode} - \tl_if_blank:oF \@listctr - { -% \end{macrocode} -% In that case \texttt{@nmbrlist} should have been set too, for -% example, through \cs{usecounter}, so we do not set it -% explicitly. However, we check if we should resume a previous list. -% \begin{macrocode} - \bool_if:NF \l_@@_resume_bool - { - \int_gset:cn{ c@ \@listctr } - { \l_@@_counter_start_int - 1 } - } - } -% \end{macrocode} -% If \cs{@listctr} is not set then we have definitely an unnumbered list. -% \begin{macrocode} - { \@nmbrlistfalse } - } -% \end{macrocode} -% If a counter is set in the list instance we use that -% one. This should be the name of a \LaTeX{} counter that is -% already allocated externally---no runtime check is made for this: -% if it is not declared one will get \enquote{no such counter} -% error when the list is used. -% \begin{macrocode} - { - \@nmbrlisttrue - \tl_set_eq:NN \@listctr \l_@@_counter_tl - \bool_if:NF \l_@@_resume_bool - { - \int_gset:cn{ c@ \@listctr } - { \l_@@_counter_start_int - 1 } - } - } -% \end{macrocode} -% Does the current instance has an item label representation? This -% would be possible whether or not we have a numbered list. If yes, -% then we use this for \cs{@itemlabel}, otherwise we expect that -% \cs{@itemlabel} is provided from the outside, e.g., as part of -% the \env{list} environment argument. -% \begin{macrocode} - \tl_if_empty:NF \l_@@_item_label_tl - { - \tl_set_eq:NN \@itemlabel \l_@@_item_label_tl - } -% \end{macrocode} -% finally, we signal that we are at the start of a new list (which -% effects how the first \cs{item} is handled and how \cs{par} -% commands are interpreted. -% \begin{macrocode} - \legacy_if_gset_true:n { @newlist } -% \end{macrocode} -% -% \begin{macrocode} - \@@_debug_typeout:n{template:list:std~end} -} -% \end{macrocode} -% -% -% Extra keys to support enumitem conventions: -% \begin{macrocode} -\keys_define:nn { template/list/std } -{ - ,nosep .code:n = - \dim_zero:N \itemsep - \dim_zero:N \parsep - \dim_zero:N \topsep - \dim_zero:N \l_@@_botsep_skip - \dim_zero:N \l_@@_parbotsep_skip - ,midsep .skip_set:N = \topsep -} -% \end{macrocode} -% -% \end{template} -% -% -% \subsubsection{Implementation of \cs{item} template(s)} -% -% -% -% \begin{template}{item std} -% The item template has one hidden key \texttt{label} which is not available on the -% template for setting because it is only used to receive any -% optional data passed to the \cs{item} command. We therefore -% declare it with \cs{keys_define:nn} and ensure that the optional -% argument data to \cs{item} (if it is not a key/value list -% already) is passed to this \texttt{label} key. -% \begin{macrocode} -\keys_define:nn { template/item/std } - { label .tl_set:N = \l_@@_label_given_tl } -% \end{macrocode} -% -% \fmi{alignment is mostly wrong (test short medium and multiline -% labels)} -% \begin{macrocode} -\DeclareTemplateCode{item}{std}{1} - { - counter-label = \@@_counter_label:n , - counter-ref = \@@_counter_ref:n , -% \end{macrocode} -% \fmi{next set of key not yet used} -% \begin{macrocode} - label-ref = \@@_label_ref:n , - label-autoref = \@@_label_autoref:n , - label-format = \@@_label_format:n , - label-strut = \l_@@_label_strut_bool , - label-boxed = \l_@@_label_boxed_bool , - next-line = \l_@@_next_line_bool , - text-font = \l_@@_text_font_tl , - compatibility = \l_@@_item_compatibility_bool , -% \end{macrocode} -% This probably needs a different implementation (and needs completing)\fmi{complete} -% \begin{macrocode} - label-align = { - left = \tl_set:Nn \l_@@_item_align_tl { \relax \hss } , - center = \tl_set:Nn \l_@@_item_align_tl { \hss \hss } , - right = \tl_set:Nn \l_@@_item_align_tl { \hss \relax } , - parleft = \NOT_IMPLEMENTED , - } , - } -% \end{macrocode} -% Then typeset the label at its natural width by applying -% \cs{@@_make_label_box:n} to the label given or to a label constructed -% from the counter. If it is boxed and reasonably short, add padding to -% make it at least of size \tn{labelwidth}, then add another layer of -% box. This way, when we unpack it in \cs{g_@@_labels_box} it correctly -% remains boxed in those cases. Afterwards, in the \texttt{nextline} -% case add \tn{newline} if the label did not fit in the allotted space. -% \begin{macrocode} - { - \@@_debug_typeout:n{template:item:std} -% \end{macrocode} -% -% First deal with the key--value input, which in particular may -% provide a value for the label (the usual optional argument of -% \cs{item}). For this we set \cs{l_@@_label_given_tl} to -% \cs{c_novalue_tl} so that we can identify if an optional argument -% was given. -% \begin{macrocode} - \tl_set_eq:NN \l_@@_label_given_tl \c_novalue_tl - \tl_if_empty:nF{#1}{ \SetTemplateKeys{item}{std}{#1} } -% \end{macrocode} -% If no optional argument was given then \cs{l_@@_label_given_tl} -% is still equal to \cs{c_novalue_tl} and so we can distinuish -% that from \verb=\item[]=. -% -% \begin{macrocode} - \tl_if_novalue:oTF \l_@@_label_given_tl - { -% \end{macrocode} -% The rest of the code for this template needs work and is both -% incomplete and partly wrong.\fmi{fix} -% \begin{macrocode} - \tl_if_blank:oF \@listctr { \@kernel@refstepcounter \@listctr } - \bool_if:NTF \l_@@_item_compatibility_bool % not sure that conditional - % makes sense - { \@@_make_label_box:n { \MakeLinkTarget[\@listctr]{}\@itemlabel } } % TODO ? - { \@@_make_label_box:n { \MakeLinkTarget[\@listctr]{}\@@_counter_label:n { \@listctr } } } - } - { - \@@_debug_typeout:n{item~ with~ optional} - \@@_make_label_box:n { \l_@@_label_given_tl } } - \bool_if:nT - { - \l_@@_label_boxed_bool - && \dim_compare_p:n { \box_wd:N \l_@@_one_label_box <= \linewidth } % TODO: is \linewidth correct? - } - { - \dim_compare:nNnT - { \box_wd:N \l_@@_one_label_box } < \labelwidth - { - \hbox_set_to_wd:Nnn \l_@@_one_label_box { \labelwidth } - { - \exp_after:wN \use_i:nn \l_@@_item_align_tl -% \end{macrocode} -% FMi: \LaTeXe{} keeps the label boxed inside (not unboxed). This -% means that the content stays rigid and does not vary based on -% glue setting in the line with the label. -% There are cases where we do want the unboxed version (I think -% enumitem offers that in some cases too) but it should probably -% not the default. -% \begin{macrocode} -% \hbox_unpack_drop:N \l_@@_one_label_box %TODO: customize? - \box_use_drop:N \l_@@_one_label_box -% \end{macrocode} -% -% \begin{macrocode} - \exp_after:wN \use_ii:nn \l_@@_item_align_tl - } - } - \hbox_set:Nn \l_@@_one_label_box - { \box_use_drop:N \l_@@_one_label_box } - } - \dim_compare:nNnTF { \box_wd:N \l_@@_one_label_box } > \labelwidth - { \bool_set_true:N \l_@@_long_label_bool } - { \bool_set_false:N \l_@@_long_label_bool } - \hbox_gset:Nn \g_@@_labels_box - { - \hbox_unpack_drop:N \g_@@_labels_box - \skip_horizontal:n { \itemindent - \labelsep - \labelwidth } - \hbox_unpack_drop:N \l_@@_one_label_box - \skip_horizontal:n { \labelsep } - \bool_if:NT \l_@@_next_line_bool - { \bool_if:NT \l_@@_long_label_bool { \nobreak \hfil \break } } - % version of \newline inside an hbox that will be unpacked - } - % \skip_set_eq:NN \parsep \l_@@_item_parsep_skip TODO??? FMi - % what's that? - \dim_set_eq:NN \parindent \listparindent -% \end{macrocode} -% Placing the list label(s) is done when the paragraph for the -% \cs{item} is started, which executes \cs{@@_item_everypar:} -% inside \hook{para/begin}. By default this command does nothing, now we -% change it to attach the pending label or labels. -% \begin{macrocode} - \cs_set_eq:NN \@@_item_everypar: \@@_item_everypar_std: - } -% \end{macrocode} -% \end{template} -% -% -% -% -% \begin{variable}{\l_@@_one_label_box, \g_@@_labels_box} -% Each label is typeset in \cs{l_@@_one_label_box} to be measured. -% Once this is ready, it is put (boxed or unboxed) in -% \cs{g_@@_labels_box}, together with any pending labels (for the case -% where a list begins just after \tn{item}). This is an analogue of -% \LaTeXe{}'s \tn{@labels}, but it is always unboxed before use, to -% support both boxed and unboxed labels. -% \begin{macrocode} -\box_new:N \l_@@_one_label_box -\box_new:N \g_@@_labels_box -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_@@_long_label_bool} -% Track whether the \cs{l_@@_one_label_box} is larger than -% \tn{labelwidth}. -% \begin{macrocode} -\bool_new:N \l_@@_long_label_bool -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\@@_make_label_box:n, \@@_label_format:x} -% Make one label, wrapped in \cs{@@_label_format:n}, with an -% appropriate \tn{strut} and possibly \tn{makelabel} in compatibility -% mode (used for the \env{list} environment). -% \begin{macrocode} -\cs_new_protected:Npn \@@_make_label_box:n #1 - { - \hbox_set:Nn \l_@@_one_label_box - { -% \end{macrocode} -% If we do tagging then the contents of this box may need to be -% wrapped into a structure, e.g., \verb==. -% \begin{macrocode} - \__kernel_list_label_begin: -% \end{macrocode} -% -% \begin{macrocode} - \@@_label_format:n - { - \bool_if:NT \l_@@_label_strut_bool { \strut } - \bool_if:NTF \l_@@_legacy_support_bool - \makelabel - \use:n - {#1} - } -% \end{macrocode} -% And what gets opened also needs closing: -% \begin{macrocode} - \__kernel_list_label_end: - } - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\__kernel_list_label_begin:, -% \__kernel_list_label_end:} -% If we aren't doing tagging the kernel hooks do nothing. -% \begin{macrocode} -\cs_new_eq:NN \__kernel_list_label_begin: \prg_do_nothing: -\cs_new_eq:NN \__kernel_list_label_end: \prg_do_nothing: -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\@@_item_everypar:, \@@_item_everypar_std:} -% The \cs{@@_item_everypar:} command is executed as part of \hook{para/begin} -% but most of the time does nothing, i.e., it has the following -% default definition. -% \begin{macrocode} -\cs_new_eq:NN \@@_item_everypar: \prg_do_nothing: -% \end{macrocode} -% -% \begin{macrocode} -\AddToHook{para/begin}[lists]{\@@_item_everypar:} -% \end{macrocode} -% -% Note that we have to make sure that the above code is executed -% after the hook chunk from \texttt{tagpdf} because the latter uses -% \texttt{@inlabel} to make a decision. -% -% By the end of the day both should probably move into the kernel -% hook instead! -% \begin{macrocode} -\DeclareHookRule{para/begin}{lists}{after}{tagpdf} -% \end{macrocode} -% -% -% What follows is the version that resets various legacy booleans and puts -% the label box in the right place and finally resets itself to do -% nothing next time. \cs{@@_item_everypar:} is set to this by the -% item template so that the next paragraph start runs the code below. -% \begin{macrocode} -\cs_new_protected:Npn \@@_item_everypar_std: { - \@@_debug_typeout:n{item~ everypar \on@line } - \legacy_if_set_false:n { @minipage } - \legacy_if_gset_false:n { @newlist } - \legacy_if:nT { @inlabel } - { - \legacy_if_gset_false:n { @inlabel } -% \end{macrocode} -% -% \begin{macrocode} - \box_if_empty:NT \g_para_indent_box { \kern - \itemindent } - \para_omit_indent: -% \end{macrocode} -% -% \begin{macrocode} - \box_use_drop:N \g_@@_labels_box -% \end{macrocode} -% After the labels are placed we start a paragraph structure (if -% appropriate). This is handled in the following kernel hook: -% \begin{macrocode} - \__kernel_list_label_after: -% \end{macrocode} -% -% \begin{macrocode} - \penalty \c_zero_int - } - \legacy_if:nTF { @nobreak } - { - \legacy_if_gset_false:n { @nobreak } - \int_set:Nn \clubpenalty { 10000 } - } - { - \int_set_eq:NN \clubpenalty \@clubpenalty -% \end{macrocode} -% Once the label(s) are typeset and we are past any special -% \texttt{@nobreak} handling we reset \cs{@@_item_everypar:} to do -% nothing. -% \begin{macrocode} - \cs_set_eq:NN \@@_item_everypar: \prg_do_nothing: - } -} -% \end{macrocode} -% -% \end{macro} -% -% -% \begin{macro}{\__kernel_list_label_after:} -% -% \begin{macrocode} -\cs_new_eq:NN \__kernel_list_label_after: \prg_do_nothing: -% \end{macrocode} -% \end{macro} -% -% \begin{variable}{\l_@@_tmpa_skip} -% \begin{macrocode} -\skip_new:N \l_@@_tmpa_skip -% \end{macrocode} -% \end{variable} -% -% -% -% -% -% -% -% \begin{variable}{\l_@@_topsepadd_skip, \l_@@_effective_top_skip} -% Variables equivalent to \LaTeXe{}'s \tn{@topsepadd} and \tn{@topsep}. -% Roughly equal to a mixture of \texttt{topsep}, \texttt{partopsep}, -% and various \texttt{parskip} at different nesting levels in lists. -% The code is really elaborate when \texttt{@inlabel} is true. -% \begin{macrocode} -\skip_new:N \l_@@_topsepadd_skip -\skip_new:N \l_@@_effective_top_skip -% \end{macrocode} -% \end{variable} -% -% -% -% -% -% -% -% -% -% -% -% \begin{macro}{\item} -% Here we already have all the building blocks. Complain in math -% mode. Distingusih between first item (do necessary tagging) and -% later items \cs{@@_inter_item:} to -% cleanly close what's before, then call \cs{@@_item_instance:n} (which -% calls \cs{UseInstance}\{item\}\marg{instance}) to prepare the -% upcoming item: it will be actually inserted only once some later -% material triggers \tn{everypar}. -% \begin{macrocode} -\AddToHook{begindocument/before}{ - \RenewDocumentCommand{\item}{ ={label}o } - { - \@inmatherr \item -% \end{macrocode} -% TODO: Test for being outside of a list needs updating! -% \begin{macrocode} - \tl_if_empty:oTF \@@_item_instance:n %%FMi? - { \msg_error:nnn { @@ } { item-in-nonlist } { \item[{#1}] } } - { - \legacy_if:nTF { @newlist } - { \__kernel_list_item_begin: } - { \@@_inter_item: } -% \end{macrocode} -% To avoid unnecessary key/val processing we make a quick check if -% there was an optional argument. -% \begin{macrocode} - \tl_if_novalue:nTF {#1} % avoids reparsing label={} - { \@@_item_instance:n { } } - { \@@_item_instance:n {#1} } -% \end{macrocode} -% Set the legacy switch that signals that we have a pending item label: -% \begin{macrocode} - \legacy_if_gset_true:n { @inlabel } - \ignorespaces - } - } -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@@_inter_item:} -% Between items. If the previous item had no content then we need to -% trigger \tn{everypar}. Otherwise we simply close the previous item -% with \tn{par} after removing some horizontal space. Between items, -% there is a penalty and some space. -% \begin{macrocode} -\cs_new_protected:Npn \@@_inter_item: { - \legacy_if:nT { @inlabel } - { \indent \par } % case of \item\item -% \end{macrocode} -% \cs{par} may have a strange definition and may not get us back to -% vertical mode in one go, so we better do not treat the next line -% as an else case to the above conditional (for now). -% \begin{macrocode} - \mode_if_horizontal:T { \@@_skip_remove_last: - \@@_skip_remove_last: \par } -% \end{macrocode} -% End any LI-tag, then start the next LI-tag (if doing tagging): -% \begin{macrocode} - \__kernel_list_item_end: - \__kernel_list_item_begin: -% \end{macrocode} -% -% \begin{macrocode} - \addpenalty \@itempenalty - \addvspace \itemsep -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\__kernel_list_item_begin:, -% \__kernel_list_item_end:} -% -% \begin{macrocode} -\cs_new_eq:NN \__kernel_list_item_begin: \prg_do_nothing: -\cs_new_eq:NN \__kernel_list_item_end: \prg_do_nothing: -% \end{macrocode} -% \end{macro} -% -% -% -% -% -% -% -% -% \subsection{Tagging recipes} -% -% \begin{macro}{\@@_recipe_basic:} -% The \texttt{basic} recipe simply ensures that the block is inside -% a \texttt{text-unit} structure and if necessary starts one. When the -% block ends and is followed by a blank line the \texttt{text-unit} -% structure is closed too, otherwise it remains open and further -% text starts with just a \struct{text} structure. -% -% There is otherwise no inner structure so -% \cs{__kernel_displayblock_begin:} and -% \cs{__kernel_displayblock_end:} do nothing---blockenvs with inner -% structure use the \texttt{standard} or \texttt{list} recipe instead. -% \begin{macrocode} -\cs_new:Npn \@@_recipe_basic: { - \cs_set_eq:NN \__kernel_displayblock_beginpar_hmode:w - \@@_beginpar_hmode:N - \cs_set_eq:NN \__kernel_displayblock_beginpar_vmode: - \@@_beginpar_vmode: - \let \__kernel_displayblock_begin: \prg_do_nothing: - \let \__kernel_displayblock_end: \prg_do_nothing: -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_recipe_standalone:} -% -% The \texttt{standalone} recipe produces a block that ensures that -% a previous \texttt{text-unit} ends and that after the block a new -% \texttt{text-unit} starts. -% \begin{macrocode} -\cs_new:Npn \@@_recipe_standalone: { - \cs_set_eq:NN \__kernel_displayblock_beginpar_hmode:w - \prg_do_nothing: - \cs_set_eq:NN \__kernel_displayblock_beginpar_vmode: - \prg_do_nothing: - \cs_set_eq:NN \__kernel_displayblock_begin: \@@_inner_begin: - \cs_set_eq:NN \__kernel_displayblock_end: \@@_inner_end: -% \end{macrocode} -% -% \begin{macrocode} - \bool_set_true:N \l_@@_standalone_bool -% \end{macrocode} -% -% \begin{macrocode} - \tl_if_empty:NTF \l_@@_tag_name_tl - { \tl_set:Nn \l_@@_tag_inner_tag_tl {Sect} } - { \tl_set_eq:NN \l_@@_tag_inner_tag_tl \l_@@_tag_name_tl } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_recipe_standard:} -% The \texttt{standard} recipe does the following: -% \begin{itemize} -% \item surround the block with a \texttt{text-unit}-structure if not already in a -% a \texttt{text-unit}. In the latter case end the -% MC and the \struct{text} but leave the \texttt{text-unit} open. -% -% If we are producing flattened paragraphs, just close any -% \struct{text} but do not open a \texttt{text-unit}. -% -% \item Then open an new (inner) structure (by default -% \texttt{Figure} but typically the one specified on the instance). -% \item At the end of the block close the the inner structure -% (\texttt{Figure} or explicit one) -% but leave the \texttt{text-unit} open to be either continued or closed due to a -% following \cs{par}. -% \end{itemize} -% \begin{macrocode} -\cs_new:Npn \@@_recipe_standard: -{ - \cs_set_eq:NN \__kernel_displayblock_beginpar_hmode:w - \@@_beginpar_hmode:N - \cs_set_eq:NN \__kernel_displayblock_beginpar_vmode: - \@@_beginpar_vmode: - \cs_set_eq:NN \__kernel_displayblock_begin: \@@_inner_begin: - \cs_set_eq:NN \__kernel_displayblock_end: \@@_inner_end: -% \end{macrocode} -% -% \begin{macrocode} - \tl_if_empty:NTF \l_@@_tag_name_tl - { \tl_set:Nn \l_@@_tag_inner_tag_tl {Figure} } - { \tl_set_eq:NN \l_@@_tag_inner_tag_tl \l_@@_tag_name_tl } -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\l_@@_tag_inner_tag_tl} -% \begin{macrocode} -\tl_new:N \l_@@_tag_inner_tag_tl -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\@@_recipe_list:} -% The \texttt{list} recipe does the following. -% \begin{itemize} -% \item It opens a \struct{text-unit}-structure or keeps the current one open (only -% closing the MC). -% \item It then starts a new structure rollmapped to L-structure -% and arranges for handling list items, e.g., Li, Lbl and LBody -% structures. -% \item At the end it closes open list structures as needed but -% keeps the \struct{text-unit}-structure open to continue the paragraph after the -% list, if necessary. -% \end{itemize} -% \begin{macrocode} -\cs_new:Npn \@@_recipe_list: -{ - \cs_set_eq:NN \__kernel_displayblock_beginpar_hmode:w - \@@_beginpar_hmode:N - \cs_set_eq:NN \__kernel_displayblock_beginpar_vmode: - \@@_beginpar_vmode: - \cs_set_eq:NN \__kernel_displayblock_begin: \@@_list_begin: - \cs_set_eq:NN \__kernel_displayblock_end: \@@_list_end: -% \end{macrocode} -% The next two lines could be done globally, because they are only -% called if we do have \cs{item}s, i.e., if we are in a list. It is -% therefore also not necessary to reset them in other recipes -% (right now---this may change if we get more templates (like -% inline lists)). -% \begin{macrocode} - \cs_set_eq:NN \__kernel_list_item_begin: \@@_list_item_begin: - \cs_set_eq:NN \__kernel_list_item_end: \@@_list_item_end: -% \end{macrocode} -% Handle the tag name and attribute classess using the key values -% from the current list instance. -% \begin{macrocode} - \tl_if_empty:NTF \l_@@_tag_name_tl - { \tl_set:Nn \l__tag_L_tag_tl {L} } - { \tl_set_eq:NN \l__tag_L_tag_tl \l_@@_tag_name_tl } - \tl_if_empty:NTF \l_@@_tag_class_tl - { \tl_set:Nn \l__tag_L_attr_class_tl {} } - { \tl_set_eq:NN \l__tag_L_attr_class_tl \l_@@_tag_class_tl } -} -% \end{macrocode} -% \end{macro} - - - -% \subsection{Blockenv instances} -% -% -% \subsubsection{Basic instances} -% -% \begin{instance}{blockenv displayblock} -% -% \begin{macrocode} -\DeclareInstance{blockenv}{displayblock}{display} -{ - env-name = displayblock, - tag-name = , - tag-class = , - tagging-recipe = standard, - inner-level-counter = , - level-increase = false, - setup-code = , - block-instance = displayblock , - inner-instance = , -} -% \end{macrocode} -% \end{instance} -% -% -% -% \begin{instance}{blockenv displayblockflattened} -% -% \begin{macrocode} -\DeclareInstance{blockenv}{displayblockflattened}{display} -{ - env-name = displayblockflattened, - tag-name = , - tag-class = , - tagging-recipe = basic, - inner-level-counter = , - level-increase = false, - setup-code = , - block-instance = displayblock , - para-flattened = true , - inner-instance = , -} -% \end{macrocode} -% \end{instance} -% -% -% -% \begin{instance}{blockenv center} -% -% \begin{macrocode} -\DeclareInstance{blockenv}{center}{display} -{ - env-name = center, - tag-name = , - tag-class = , - tagging-recipe = basic, - inner-level-counter = , - level-increase = false, - setup-code = , - block-instance = displayblock , - para-flattened = true , - para-instance = center , - inner-instance = , -} -% \end{macrocode} -% \end{instance} -% -% -% \begin{instance}{blockenv flushleft} -% -% \begin{macrocode} -\DeclareInstance{blockenv}{flushleft}{display} -{ - env-name = flushleft, - tag-name = , - tag-class = , - tagging-recipe = basic, - inner-level-counter = , - level-increase = false, - setup-code = , - block-instance = displayblock , - para-flattened = true , - para-instance = raggedright , - inner-instance = , -} -% \end{macrocode} -% \end{instance} -% -% -% -% \begin{instance}{blockenv flushright} -% -% \begin{macrocode} -\DeclareInstance{blockenv}{flushright}{display} -{ - env-name = flushleft, - tag-name = , - tag-class = , - tagging-recipe = basic, - inner-level-counter = , - level-increase = false, - setup-code = , - block-instance = displayblock , - para-flattened = true , - para-instance = raggedleft , - inner-instance = , -} -% \end{macrocode} -% \end{instance} -% -% -% -% \subsubsection{Blockquote instances} -% -% \begin{instance}{blockenv quotation} -% -% \begin{macrocode} -\tag_if_active:T { - \tagpdfsetup{add-new-tag={tag=quote,role=BlockQuote}} - \tagpdfsetup{add-new-tag={tag=quotation,role=BlockQuote}} -} -% \end{macrocode} -% -% \begin{macrocode} -\DeclareInstance{blockenv}{quotation}{display} -{ - env-name = quotation, - tag-name = quotation, - tag-class = , - tagging-recipe = standard, - inner-level-counter = , - level-increase = true, - setup-code = , - block-instance = quotationblock , - inner-instance = , -} -% \end{macrocode} -% \end{instance} -% -% -% -% \begin{instance}{blockenv quote} -% -% \begin{macrocode} -\DeclareInstance{blockenv}{quote}{display} -{ - env-name = quote, - tag-name = quote, - tag-class = , - tagging-recipe = standard, - inner-level-counter = , - level-increase = true, - setup-code = , - block-instance = quoteblock , - inner-instance = , -} -% \end{macrocode} -% \end{instance} -% -% An alternative setup for quotations, using the displayblock instance and -% just overwrite a bit in the setup code.\fmi{I guess the setup -% code is still executed too early, have to check.} -% This would be less flexible but would ensure visual consistency, -% because the displayblock settings are used throughout. -% \begin{macrocode} -% \DeclareInstance{blockenv}{quotation}{display} -% { -% env-name = quotation, -% tag-name = , -% tag-class = , -% tagging-recipe = blockquote, -% inner-level-counter = , -% level-increase = true, -% setup-code = \setlength\rightmargin{\leftmargin} -% \setlength\parsep{1.5em} , -% block-instance = displayblock , -% inner-instance = , -% } -% \end{macrocode} -% -% \begin{macrocode} -% \DeclareInstance{blockenv}{quote}{display} -% { -% env-name = quote, -% tag-name = , -% tag-class = , -% tagging-recipe = blockquote, -% inner-level-counter = , -% level-increase = true, -% setup-code = \setlength\rightmargin{\leftmargin} , -% block-instance = displayblock , -% inner-instance = , -% } -% \end{macrocode} -% - -% -% \begin{macrocode} -\DeclareInstance{blockenv}{theorem}{display} -{ - env-name = theorem-like, - tag-name = theorem-like, - tag-class = , - tagging-recipe = standalone, - inner-level-counter = , - level-increase = false, - setup-code = , - block-instance = displayblock , -% inner-instance-type = innerblock , -% inner-instance = theorem, -} -% \end{macrocode} -% -% We use \struct{theorem-like} as the structure name and rollmap it -% to a \struct{Sect} because that can hold a \struct{Caption}. -% \begin{macrocode} -\tag_if_active:T { - \tagpdfsetup{add-new-tag={tag=theorem-like,role=Sect}} -} -% \end{macrocode} -% -% -% -% -% \subsubsection{Verbatim instances} -% -% \begin{instance}{blockenv verbatim} -% -% \begin{macrocode} -\tag_if_active:T { - \tagpdfsetup{add-new-tag={tag=verbatim,role=P}} - \tagpdfsetup{add-new-tag={tag=codeline,role=Sub}} -% \end{macrocode} -% Possible alternative for PDF 1.7: -% \begin{macrocode} -% \tagpdfsetup{add-new-tag={tag=verbatim,role=Div}} -% \tagpdfsetup{add-new-tag={tag=codeline,role=P}} -} -% \end{macrocode} -% -% \begin{macrocode} -\DeclareInstance{blockenv}{verbatim}{display} -{ - env-name = verbatim, - tag-name = verbatim, - tag-class = , - tagging-recipe = standard, - inner-level-counter = , - level-increase = false, - setup-code = , - block-instance = verbatimblock , - inner-instance = , - final-code = \legacyverbatimsetup , -} -% \end{macrocode} -% \end{instance} -% -% -% \subsubsection{Standard list instances} -% -% \begin{instance}{blockenv itemize} -% -% \begin{macrocode} -\DeclareInstance{blockenv}{itemize}{display} -{ - env-name = itemize, - tag-name = itemize, - tag-class = itemize, - tagging-recipe = list, - inner-level-counter = \@itemdepth, - level-increase = true, - max-inner-levels = 4, - setup-code = , - block-instance = list , - inner-instance = itemize , -} -% \end{macrocode} -% \end{instance} -% -% -% \begin{instance}{blockenv enumerate} -% -% \begin{macrocode} -\DeclareInstance{blockenv}{enumerate}{display} -{ - env-name = enumerate, - tag-name = enumerate, - tag-class = enumerate, - tagging-recipe = list, - level-increase = true, - setup-code = , - block-instance = list , - inner-level-counter = \@enumdepth, - max-inner-levels = 4, - inner-instance = enum , -} -% \end{macrocode} -% \end{instance} -% -% -% \begin{instance}{blockenv description} -% -% \begin{macrocode} - -\DeclareInstance{blockenv}{description}{display} -{ - env-name = description, - tag-name = description, - tag-class = description, - tagging-recipe = list, - inner-level-counter = , - level-increase = true, - setup-code = , - block-instance = list , - inner-instance = description , -} -% \end{macrocode} -% \end{instance} -% -% -% \begin{instance}{blockenv list} -% The general (legacy) \env{list} environment does some of its -% setup in the \texttt{setup-code} key. -% \begin{macrocode} -\DeclareInstance{blockenv}{list}{display} -{ - env-name = list, - tag-name = list, - tag-class = , - tagging-recipe = list, - level-increase = true, - setup-code = \legacylistsetupcode , - block-instance = list , - inner-level-counter = , - inner-instance = legacy , -} -% \end{macrocode} -% \end{instance} -% -% -% -% -% \subsection{Block instances} -% -% \subsubsection{Displayblock instances} -% -% We provide 6 nesting levels (as in \LaTeXe{}). If you want to -% provide more you need to change the \texttt{maxblocklevels} -% counter, offer further \texttt{displayblock-xx} instances but -% also define further (legacy) \cs{list\meta{romannumeral}} commands -% for the defaults. If not, then the settings from the previous -% level are reused automatically---which may or may not be good enough). -% \begin{macrocode} -\setcounter{maxblocklevels}{6} -% \end{macrocode} -% -% \begin{instance}{block displayblock-0, -% block displayblock-1, -% block displayblock-2, -% block displayblock-3, -% block displayblock-4, -% block displayblock-5, -% block displayblock-6 } -% -% Here we need level zero as well in case a flattened displayblock -% (like the center env) it is used on top-level. -% \begin{macrocode} -\DeclareInstance{block}{displayblock-0}{display} - { - leftmargin = 0pt , - parindent = 0pt , - } -% \end{macrocode} -% -% \begin{macrocode} -\DeclareInstanceCopy{block}{displayblock-1}{displayblock-0} -\DeclareInstanceCopy{block}{displayblock-2}{displayblock-0} -\DeclareInstanceCopy{block}{displayblock-3}{displayblock-0} -\DeclareInstanceCopy{block}{displayblock-4}{displayblock-0} -\DeclareInstanceCopy{block}{displayblock-5}{displayblock-0} -\DeclareInstanceCopy{block}{displayblock-6}{displayblock-0} -% \end{macrocode} -% \end{instance} -% -% -% -% \subsubsection{Verbatim instances} -% -% Verbatim instances have there own levels so that one can specify -% specific indentations or vertical separations between line. -% -% \begin{instance}{block verbatimblock-0, -% block verbatimblock-1, -% block verbatimblock-2, -% block verbatimblock-3, -% block verbatimblock-4, -% block verbatimblock-5, -% block verbatimblock-6 } -% -% \begin{macrocode} -\DeclareInstance{block}{verbatimblock-0}{display} - { - leftmargin = 0pt , - parindent = 0pt , - par-skip = 0pt , - } -% \end{macrocode} -% -% \begin{macrocode} -\DeclareInstanceCopy{block}{verbatimblock-1}{verbatimblock-0} -\DeclareInstanceCopy{block}{verbatimblock-2}{verbatimblock-0} -\DeclareInstanceCopy{block}{verbatimblock-3}{verbatimblock-0} -\DeclareInstanceCopy{block}{verbatimblock-4}{verbatimblock-0} -\DeclareInstanceCopy{block}{verbatimblock-5}{verbatimblock-0} -\DeclareInstanceCopy{block}{verbatimblock-6}{verbatimblock-0} -% \end{macrocode} -% \end{instance} -% -% -% -% -% \subsubsection{Quote/quotationblock instances} -% -% Quote and quotation are not flattened, i.e., they change levels, -% thus they start with level 1 not 0. -% -% \begin{instance}{block quoteblock-1, -% block quoteblock-2, -% block quoteblock-3, -% block quoteblock-4, -% block quoteblock-5, -% block quoteblock-6 } -% Default layout is to indent equaly from both side. -% \begin{macrocode} -\DeclareInstance{block}{quoteblock-1}{display} - { rightmargin = \KeyValue{leftmargin} } -% \end{macrocode} -% -% \begin{macrocode} -\DeclareInstanceCopy{block}{quoteblock-2}{quoteblock-1} -\DeclareInstanceCopy{block}{quoteblock-3}{quoteblock-1} -\DeclareInstanceCopy{block}{quoteblock-4}{quoteblock-1} -\DeclareInstanceCopy{block}{quoteblock-5}{quoteblock-1} -\DeclareInstanceCopy{block}{quoteblock-6}{quoteblock-1} -% \end{macrocode} -% \end{instance} -% -% -% -% \begin{instance}{block quotationblock-1, -% block quotationblock-2, -% block quotationblock-3, -% block quotationblock-4, -% block quotationblock-5, -% block quotationblock-6 } -% Quotation additionally changes the parindent. -% \begin{macrocode} -\DeclareInstance{block}{quotationblock-1}{display} - { parindent = 1.5em , rightmargin = \KeyValue{leftmargin} } -% \end{macrocode} -% -% \begin{macrocode} -\DeclareInstanceCopy{block}{quotationblock-2}{quotationblock-1} -\DeclareInstanceCopy{block}{quotationblock-3}{quotationblock-1} -\DeclareInstanceCopy{block}{quotationblock-4}{quotationblock-1} -\DeclareInstanceCopy{block}{quotationblock-5}{quotationblock-1} -\DeclareInstanceCopy{block}{quotationblock-6}{quotationblock-1} -% \end{macrocode} -% \end{instance} -% -% -% \subsubsection{Block instances for the standard lists} -% -% \begin{instance}{block list-1, -% block list-2, -% block list-3, -% block list-4, -% block list-5, -% block list-6 } -% The block instances for the various list environments use the -% same underlying instance (well by default) and nothing nothing -% needs to be set up specifically (because that is already done in -% the legacy \cs{list\meta{romannumeral}} unless a -% different layout is wanted. -% \begin{macrocode} -\DeclareInstance{block}{list-1}{display}{ -% heading = , -% beginsep = \topsep , -% begin-par-skip = \partopsep , -% par-skip = \parsep , -% end-skip = \KeyValue{beginsep} , -% end-par-skip = \KeyValue{begin-par-skip} , -% beginpenalty = \UseName{@beginparpenalty} , -% endpenalty = \UseName{@endparpenalty} , -% leftmargin = \leftmargin , -% rightmargin = \rightmargin , -% parindent = \listparindent , -} -\DeclareInstance{block}{list-2}{display}{} -\DeclareInstance{block}{list-3}{display}{} -\DeclareInstance{block}{list-4}{display}{} -\DeclareInstance{block}{list-5}{display}{} -\DeclareInstance{block}{list-6}{display}{} -% \end{macrocode} -% \end{instance} -% -% -% -% \subsection{List instances for the standard lists} -% -% For all list instances we have to say what kind of label we want -% (\texttt{label-instance}) and how it should beformatted. -% -% \begin{instance}{list itemize-1, -% list itemize-2, -% list itemize-3, -% list itemize-4} -% For \env{itemize} environments this is all we need to do and we -% refer back to the external definitions rather than defining the -% \texttt{item-label} code in the instance to ensure that old -% documents still work. -% -% \begin{macrocode} -\DeclareInstance{list}{itemize-1}{std}{ item-label = \labelitemi } -\DeclareInstance{list}{itemize-2}{std}{ item-label = \labelitemii } -\DeclareInstance{list}{itemize-3}{std}{ item-label = \labelitemiii } -\DeclareInstance{list}{itemize-4}{std}{ item-label = \labelitemiv } -% \end{macrocode} -% \end{instance} -% -% -% -% \begin{instance}{list enumerate-1, -% list enumerate-2, -% list enumerate-3, -% list enumerate-4} -% \env{enumerate} environments are similar, except that we also -% have to say which counter to use on every level. -% \begin{macrocode} -\DeclareInstance{list}{enum-1}{std} - { item-label = \labelenumi , counter = enumi } -\DeclareInstance{list}{enum-2}{std} - { item-label = \labelenumii , counter = enumii } -\DeclareInstance{list}{enum-3}{std} - { item-label = \labelenumiii , counter = enumiii } -\DeclareInstance{list}{enum-4}{std} - { item-label = \labelenumiv , counter = enumiv } -% \end{macrocode} -% \end{instance} -% -% -% -% \begin{instance}{list legacy} -% For the legacy \env{list} environment there is only one instance -% which is reused on all levels. This is done this way one because -% the legacy \env{list} environment sets all its -% parameters through its arguments. So this instances shouldn't -% really be touched. It sets the \texttt{legacy-support} key to -% true, which means that the list code uses \cs{makelabel} for -% formatting the label -% \begin{macrocode} -\DeclareInstance{list}{legacy}{std} { - item-instance = basic , - legacy-support = true , -} -% \end{macrocode} -% \end{instance} -% -% -% \begin{instance}{list description} -% The \env{description} lists also use only a single list instance -% with only one key not using the default: -% \begin{macrocode} -\DeclareInstance{list}{description}{std} { item-instance = description } -% \end{macrocode} -% \end{instance} -% -% -% \subsection{Item instances} -% -% -% \begin{instance}{item basic, item description} -% There two item instances set up: \texttt{description} for use -% with the \env{description} environment and \texttt{basic} for use -% with all other lists (up to now). -% \begin{macrocode} -\DeclareInstance{item}{basic}{std} - { - label-align = right , - } -% \end{macrocode} -% -% \begin{macrocode} -\DeclareInstance{item}{description}{std} - { - label-format = \normalfont\bfseries #1 , - } -% \end{macrocode} -% \end{instance} -% -% -% -% \subsection{Para instances} -% -% \begin{macrocode} -\tag_if_active:T -{ - \tagpdfsetup - { - newattribute = {justify} {/O /Layout /TextAlign/Justify}, - newattribute = {center} {/O /Layout /TextAlign/Center}, - newattribute = {raggedright}{/O /Layout /TextAlign/Start}, - newattribute = {raggedleft} {/O /Layout /TextAlign/End}, - } -} -% \end{macrocode} -% -% \begin{instance}{para center} -% \begin{macrocode} -\DeclareInstance{para}{center}{std} -{ - indent-width = 0pt , - start-skip = 0pt , - left-skip = \@flushglue , - right-skip = \@flushglue , - end-skip = \z@skip , - final-hyphen-demerits = 0 , - cr-cmd = \@centercr , - para-class = center , -} -% \end{macrocode} -% -% \begin{macrocode} -\DeclareInstance{para}{raggedright}{std} -{ - indent-width = 0pt , - start-skip = 0pt , - left-skip = \z@skip , - right-skip = \@flushglue , - end-skip = \z@skip , - final-hyphen-demerits = 0 , - cr-cmd = \@centercr , - para-class = raggedright , -} -% \end{macrocode} -% -% \begin{macrocode} -\DeclareInstance{para}{raggedleft}{std} -{ - indent-width = 0pt , - start-skip = 0pt , - left-skip = \@flushglue , - right-skip = \z@skip , - end-skip = \z@skip , - final-hyphen-demerits = 0 , - cr-cmd = \@centercr , - para-class = raggedleft , -} -% \end{macrocode} -% -% \begin{macrocode} -\DeclareInstance{para}{justify}{std} -{ -% indent-width = 0pt , - start-skip = 0pt , - left-skip = \z@skip , - right-skip = \z@skip , - end-skip = \@flushglue , - final-hyphen-demerits = 5000 , - cr-cmd = \@normalcr , - para-class = justify , -} -% \end{macrocode} -% \end{instance} -% -% -% -% -% \begin{macrocode} -\DeclareRobustCommand\centering {\UseInstance{para}{center}{}} -\DeclareRobustCommand\raggedleft {\UseInstance{para}{raggedleft}{}} -\DeclareRobustCommand\raggedright{\UseInstance{para}{raggedright}{}} -\DeclareRobustCommand\justifying {\UseInstance{para}{justify}{}} - -\justifying -% \end{macrocode} -% -% -% -% -% -% \subsection{Tagging support} -% -% In this section we provide code to the various kernel hooks to support -% the tagging of the different displayblock environments. -% -% -% -% All of the following definitions should only be made if tagging -% is active! -% \begin{macrocode} -\tag_if_active:T { -% \end{macrocode} -% -% \begin{macro}{\@@_beginpar_vmode:} -% When a block starts out in vertical mode, i.e., is not yet part of -% a paragraph, we have to start a paragraph -% structure. However, this is not the case if we are already -% flattening paragraphs, thus in this case we do nothing. -% We also do nothing if \texttt{@endpe} is currently true, because -% that means we are right now just after the end of a -% \texttt{blockenv} and in the process of looking if we have to end -% the current \texttt{text-unit}, i.e., it is already open. -% \begin{macrocode} - \cs_set:Npn \@@_beginpar_vmode: { - \@@_debug_typeout:n - { @endpe = \legacy_if:nTF { @endpe }{true}{false} - \on@line } - \legacy_if:nTF { @endpe } - { - \legacy_if_gset_false:n { @endpe } - } -% \end{macrocode} -% We test for \texttt{<2} because the first flattened environment -% has to surround itself with a \texttt{text-unit}. Only any inner ones -% then have to avoid adding another \texttt{text-unit}. -% \begin{macrocode} - { - \int_compare:nNnT \l_@@_flattened_level_int < 2 - { - \int_gincr:N \g__tag_para_main_begin_int - \tagstructbegin{tag=\l__tag_para_main_tag_tl} - } - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_beginpar_hmode:N} -% If the block is already part of a part of a paragraph, i.e., when it has -% some text directly in front, then the first thing to -% do is to return to vertical mode. However, that should be done -% without inserting a paragraph end tag, so before calling \cs{par} -% to do its normal work, we disable paragraph tagging and -% restarting afterwards again. The argument to this config point -% simply gobbles the \cs{par} following it in the code above (which -% is used when there is no tagging going on. -% \begin{macrocode} - \cs_set:Npn \@@_beginpar_hmode:N #1 - { - \tag_mc_end: - \int_gincr:N \g__tag_para_end_int - \@@_debug_typeout:n{increment~ /P \on@line } - \bool_if:NT \l__tag_para_show_bool - { \tag_mc_begin:n{artifact} - \rlap{\color_select:n{red}\tiny\ \int_use:N\g__tag_para_end_int} - \tag_mc_end: - } - \tag_struct_end: - \tagpdfparaOff \par \tagpdfparaOn - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\__kernel_displayblock_doendpe:} -% If a display block ends and is followed by a blank line we have to end the -% enclosing paragraph tagging structure. -% \begin{macrocode} -\cs_set:Npn \__kernel_displayblock_doendpe: { - \bool_if:NT \l__tag_para_bool - { -% \end{macrocode} -% Given that restoring \cs{par} through the legacy \LaTeXe{} method -% can take a few iterations (for example, in case of nested lists, -% e.g., \verb=...\end{itemize} \item ...\par= it can happen that -% \cs{__kernel_displayblock_doendpe:} is called while -% \texttt{@endpe} is already handled and then we should not attempt -% to close a \texttt{text-unit} structure. So we need to check for this. -% \begin{macrocode} - \legacy_if:nT { @endpe } - { -% \end{macrocode} -% If the display block currently ending was \enquote{flattened} -% (i.e., uses simplified paragraphs that are not tagged by a -% combination of \texttt{text-unit} followed by \struct{text}, but simply -% with a \struct{text}, -% then we don't have to do anything, because the \struct{text} is already closed. -% \begin{macrocode} - \@@_debug_typeout:n - { flattened= \bool_if:NTF - \l__tag_para_flattened_bool {true}{false} - \on@line } - \bool_if:NF \l__tag_para_flattened_bool - { - \@@_debug_typeout:n{Structure-end~ - \l__tag_para_main_tag_tl\space after~ displayblock \on@line } - \int_gincr:N \g__tag_para_main_end_int - \tag_struct_end: %text-unit - } - } - } -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{para/begin} -% -% Paragraph tagging is mainly done using the paragraph hooks (will -% get moved eventually). The default hook setting is not good -% enough when lists get suppported: we need to delay starting the -% paragraph tagging if we still have to place the list label. -% We therefore remove the existing hook data and replace it with an -% augmented version (this will get combined eventually). -% \begin{macrocode} -\RemoveFromHook{para/begin}[tagpdf] -% \end{macrocode} -% -% \begin{macrocode} -\AddToHook{para/begin}[tagpdf]{ - \bool_if:NT \l__tag_para_bool { -% \end{macrocode} -% if we are still waiting to typeset the list label we do nothing -% (the paragraph tagging then happens when the list is finally -% typeset). -% \begin{macrocode} - \legacy_if:nF { @inlabel } - { -% \end{macrocode} -% Otherwise, we start a \struct{text} tag structure but only if we are not -% starting a paragraph immediately \emph{after} a list, in which -% case we only start a new MC (because the \struct{text} tag is still open from -% before the list --- one of the reasons why lists are always put -% \enquote{inside} paragraphs. -% -% We do this in a separate command, because it is needed elsewhere too. -% \begin{macrocode} - \@@_start_para_structure:n { \PARALABEL } - } - } -} -% \end{macrocode} -% -% -% \begin{macro}{\@@_start_para_structure:n} -% -% \begin{macrocode} -\cs_new_protected:Npn \@@_start_para_structure:n #1 { - \@@_debug_typeout:n - { @endpe = \legacy_if:nTF { @endpe }{true}{false} - \on@line } - \legacy_if:nF { @endpe } - { - \bool_if:NF \l__tag_para_flattened_bool - { - \int_gincr:N \g__tag_para_main_begin_int - \tag_struct_begin:n{tag=\l__tag_para_main_tag_tl} - } - } - \int_gincr:N \g__tag_para_begin_int - \@@_debug_typeout:n{increment~ P \on@line } - \tag_struct_begin:n - { - tag=\l__tag_para_tag_tl - ,attribute-class=\l_tag_para_attr_class_tl - } - \__tag_check_para_begin_show:nn {green}{#1} - \tag_mc_begin:n {} -} -% \end{macrocode} -% The same code, but without testing \texttt{@endpe}. This is not -% needed in the standalong e case and wrong inside lists. -% \begin{macrocode} -\cs_new_protected:Npn \@@_start_para_structure_unconditionally:n #1 { - \bool_if:NF \l__tag_para_flattened_bool - { - \int_gincr:N \g__tag_para_main_begin_int - \tag_struct_begin:n{tag=\l__tag_para_main_tag_tl} - } - \int_gincr:N \g__tag_para_begin_int - \@@_debug_typeout:n{increment~ P \on@line } - \tag_struct_begin:n - { - tag=\l__tag_para_tag_tl - ,attribute-class=\l_tag_para_attr_class_tl - } - \__tag_check_para_begin_show:nn {green}{#1} - \tag_mc_begin:n {} -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macrocode} -\tag_if_active:T { -% \tagpdfsetup{add-new-tag={tag=text-unit,role=Part}} -} -% \end{macrocode} -% -% \begin{macrocode} -\RemoveFromHook{para/end}[tagpdf] -\AddToHook{para/end} - { - \bool_if:NT \l__tag_para_bool - { - \int_gincr:N \g__tag_para_end_int - \@@_debug_typeout:n{increment~ /P \on@line } - \tag_mc_end: - \__tag_check_para_end_show:nn {red}{} - \tag_struct_end: - \bool_if:NF \l__tag_para_flattened_bool - { - \int_gincr:N \g__tag_para_main_end_int - \tag_struct_end: - } - } - } -% \end{macrocode} -% -% \begin{macrocode} -\def\PARALABEL{NP-} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\para_end:} -% If we see a \cs{par} in vmode and a \texttt{text-unit} is still open -% we need to close that. For this we check if a request for -% \text{@endpe} was made (but the \cs{par} redefinition got lost -% due to (bad?) coding). -% \begin{macrocode} -\cs_set_protected:Npn \para_end: { - \scan_stop: - \mode_if_horizontal:TF { - \mode_if_inner:F { - \tex_unskip:D - \hook_use:n{para/end} - \@kernel@after@para@end - \mode_if_horizontal:TF { - \if_int_compare:w 11 = \tex_lastnodetype:D - \tex_hskip:D \c_zero_dim - \fi: - \tex_par:D - \hook_use:n{para/after} - \@kernel@after@para@after - } - { \msg_error:nnnn { hooks }{ para-mode }{end}{horizontal} } - } - } - { - \__kernel_endpe_vmode: % should do nothing if no tagging - \tex_par:D - } -} -\cs_set_eq:NN \par \para_end: -\cs_set_eq:NN \@@par \para_end: -\cs_set_eq:NN \endgraf \para_end: -% \end{macrocode} -% -% \begin{macrocode} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\begin} -% We need to do a little more than canceling \texttt{@endpe} now. -% \begin{macrocode} -\DeclareRobustCommand*\begin[1]{% - \UseHook{env/#1/before}% - \@ifundefined{#1}% - {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% - {\def\reserved@a{\def\@currenvir{#1}% - \edef\@currenvline{\on@line}% - \@execute@begin@hook{#1}% - \csname #1\endcsname}}% - \@ignorefalse - \begingroup - \__kernel_endpe_vmode: - \reserved@a} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\__kernel_endpe_vmode:} -% Close an open \texttt{text-unit} if \texttt{@endpe} is true and we -% are in vmode. Used in \cs{para_end:} and \cs{begin}. -% \begin{macrocode} -\cs_new:Npn \__kernel_endpe_vmode: { - \if@endpe \ifvmode - \bool_if:NT \l__tag_para_bool - { - \bool_if:NF \l__tag_para_flattened_bool - { - \int_gincr:N \g__tag_para_main_end_int - \tag_struct_end: - } - \@endpefalse - } - \fi \fi -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\__kernel_list_label_after:} -% If starting the text-unit/text tags got delayed because of a pending label we -% have to do it after the label got typeset -% \begin{macrocode} -\cs_set:Npn \__kernel_list_label_after: { - \bool_if:NT \l__tag_para_bool - { - \@@_start_para_structure_unconditionally:n { LI- } - } -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@@_inner_begin:} -% Start a block that has an inner structure if it isn't also a list. -% \begin{macrocode} -\cs_new:Npn \@@_inner_begin: { - \tagstructbegin{tag=\l_@@_tag_inner_tag_tl} -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@@_inner_end:} -% End a block (which isn't also a list). -% \begin{macrocode} -\cs_new:Npn \@@_inner_end: { - \@@_debug_typeout:n{block-end \on@line} - \legacy_if:nT { @endpe } - { - \int_gincr:N \g__tag_para_main_end_int - \@@_debug_typeout:n{close~ /text-unit \on@line} - \tagstructend - } - \tagstructend % end inner structure -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% -% -% \subsubsection{List tags} -% -% -% \begin{macrocode} -\tl_new:N \l__tag_L_tag_tl -\tl_set:Nn \l__tag_L_tag_tl {L} - -\tl_new:N\l__tag_L_attr_class_tl -\tl_set:Nn \l__tag_L_attr_class_tl {list} -% \end{macrocode} -% -% \begin{macrocode} -\tag_if_active:T -{ - \tagpdfsetup - { - % default if unknown - newattribute = {list}{/O /List /ListNumbering/None}, - newattribute = {itemize}{/O /List /ListNumbering/Unordered}, - newattribute = {enumerate}{/O /List /ListNumbering/Ordered}, - newattribute = {description}{/O /List /ListNumbering/Description}, - } -} -% \end{macrocode} -% -% \begin{macrocode} -\def\LItag{LI} -% \end{macrocode} -% -% \begin{macro}{\@@_list_begin:} -% Start a list \ldots -% \begin{macrocode} -\cs_set:Npn \@@_list_begin: { - \tagstructbegin - { - tag=\l__tag_L_tag_tl - ,attribute-class=\l__tag_L_attr_class_tl - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_list_item_begin:} -% Start tagging a list item. -% \begin{macrocode} -\cs_set:Npn \@@_list_item_begin: { \tagstructbegin{tag=\LItag} } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\__kernel_list_label_begin:} -% A list label needs a \texttt{Lbl} structure tag and an MC. -% \begin{macrocode} -\cs_set:Npn \__kernel_list_label_begin: { -% -% FMi: this needs a different logic to decide when to make the label -% an artifact (after cleaning up the the \item code ), therefore -% disabled for now -% \tl_if_empty:oTF \@itemlabel -% { -% \tag_mc_begin:n {artifact} -% } -% { - \tagstructbegin{tag=Lbl} - \tagmcbegin{tag=Lbl} -% } -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\__kernel_list_label_end:} -% And when we are done with the label we have to close the MC and -% the \texttt{Lbl} structure. We then start the \texttt{LBody}. The -% material inside will be \enquote{paragraph} text and the tagging -% for that is handled by the normal para tagging. -% \begin{macrocode} -\cs_set:Npn \__kernel_list_label_end: { - \tagmcend % end mc-Lbl or artifact -% FMi: unconditionally for now -% \tl_if_empty:oF \@itemlabel - \tagstructend % end Lbl - \tagstructbegin{tag=\LBody} -} -\def\LBody{LBody} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\@@_list_item_end:} -% When a list item ends we have to close \texttt{LBody} and -% \texttt{LI} but also a \struct{text} in the special case that the -% item material ends in a list (identifiable via \texttt{@endpe}). -% \begin{macrocode} -\cs_set:Npn \@@_list_item_end: { - \legacy_if:nT { @endpe } - { - \int_gincr:N \g__tag_para_main_end_int - \tagstructend % text-unit -% \@@_debug_typeout:n{Structure-end~ P~ at~ item-end \on@line } - } - \tagstructend \tagstructend % end LBody, LI -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\@@_list_end:} -% Finally, at the list end we have to close the open -% \texttt{LBody}, \texttt{LI}, \texttt{L}, and possibly a -% \struct{text} if the last item ends with a list. -% \begin{macrocode} -\cs_set:Npn \@@_list_end: { - \legacy_if:nT { @endpe } - { - \int_gincr:N \g__tag_para_main_end_int - \tagstructend % text-unit - \@@_debug_typeout:n{Structure-end~ P~ at~ list-end \on@line } - } - \tagstructend\tagstructend % end LBody, LI - \tagstructend % end L -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% -% -% End of tagging related declarations. -% \begin{macrocode} -} -% \end{macrocode} -% -% -% -% -% -% -% -% -% -% \begin{macrocode} -% -% \end{macrocode} -% -% -% -% \begin{macrocode} -%<*latex-lab> -\ProvidesFile{block-tagging-latex-lab-testphase.ltx} - [\ltblocksdate\space \ltblocksversion\space - blockenv implementation] -\RequirePackage{latex-lab-testphase-block-tagging} -% -% \end{macrocode} -% -% \end{implementation} -% -% -% \section{Documentation from first prototype implementations} -% -% -% \subsection{Open questions} -% \begin{itemize} -% \item Existing questions --- moved to issues --- -% \end{itemize} -% -% \subsection{Code cleanup} -% \begin{itemize} -% \item Actually implement what's announced. -% -% \item Encapsulate most uses of \cs[no-index]{legacy_if\dots} into -% commands with \texttt{expl3} syntax: we cannot rename these booleans -% for compatibility reasons but we can make the code cleaner -% nevertheless. --- made issue --- -% -% \item The \tn{topsep} and \tn{partopsep} business is tricky to -% reproduce exactly (see \tn{@topsepadd} and \tn{@topsep}) because of -% how it accumulates when lists are nested immediately. -% -% \end{itemize} -% -% -% -% \subsection{Tasks} -% \begin{itemize} -% -% \item Change author to LaTeX Team once it's nice enough to deserve -% that label. -% -% \item Reproducing exactly the standard layouts and examples in the -% \pkg{enumitem} documentation. -% -% \item Hooks, but do not duplicate those that already exist as -% environment hooks. Hence, mostly around items. -% -% \item Customization and interaction with LDB: -% \begin{itemize} -% \item Allow arbitrary nesting depth with automatically defined -% styles for labels, counters etc. -% \item Adapt everything to font size! (e.g. footnotes). -% \item How to model the inheritance from trivlist to list to -% enumerate? -% \end{itemize} -% -% \item Add key--value settings mimicking \pkg{enumitem}'s ability to -% set any four of five horizontal parameters and deduce the fifth by -% $\cs{leftmargin} + \cs{itemindent} = \cs{labelindent} + -% \cs{labelwidth} + \cs{labelsep}$. -% -% \item Provide good ways to customize how overlong labels are dealt with. -% -% \item Use the \texttt{.aux} file. -% \begin{itemize} -% \item Implement the \tn{ref} styles that \pkg{enumitem} provides. -% \item Reverse enumerations, important in publication lists and the -% like. Somehow avoid needing 3 compilations for references to -% reverse enumerations to settle? -% \item Ability to calculate \tn{labelwidth} from the label contents. -% Share calculated parameters between multiple environments (cf.\ -% \texttt{resume} option). -% \end{itemize} -% -% \item Related to grabbing the whole list environment, and input syntax -% variations: -% \begin{itemize} -% \item Other layouts: tabular (see \pkg{listliketab} vs -% \pkg{typed-checklist}), multicolumn and horizontally numbered (see -% \pkg{tasks}), inline lists, runin lists in the easy case where -% there is no intervening \tn{par}. -% \item Formatting the item text in a -% box or similar (requires grabbing the whole list). -% \item Filtering which items to show: hide certain items according to -% criteria (useful together with list reuse), see -% \pkg{typed-checklist}. -% \item Shorthands \tn{iitem} for automatic nested lists, or \cs{1}, -% \cs{2} etc from \pkg{outlines}. -% \item Support markdown input like \pkg{asciilist}. -% \end{itemize} -% -% \item Check interaction with \texttt{babel} options such as -% \texttt{french} or \texttt{accadian} (see FrenchItemizeSpacing) -% -% \item RTL and vertical typesetting. -% \end{itemize} -% -% \section{Plan of attack of first prototype} -% -% Typesetting list environments involves a rather large number of -% parameters. They can be affected by the context such as the total -% list nesting level, the nesting level of the given type of list, and -% the font size. An environment like \texttt{enumerate} has two main -% aspects. -% \begin{itemize} -% \item It has a certain layout in the page, with vertical and -% horizontal spacing around it. This type of layout is shared with -% environments such as \texttt{quote}, \texttt{flushright}, or -% \texttt{tabbing}. This common layout is implemented in \LaTeXe{} -% through \cs{trivlist} (or \cs{list}). -% \item It defines how each \cs{item} should be typeset: how to -% construct the label, in particular the \texttt{counter} name, and -% how to format the content of the item. -% \end{itemize} -% -% This suggests defining two object types, \xt{block} and \xt{item} -% covering these two aspects.\footnote{Possibly also \xt{endblock} to -% deal with decorations at the end?} While the \xt{item} type will -% perhaps have a single template, one could typeset a \xt{block} object -% in several ways, for instance the standard \LaTeXe{} way or a fancy -% colored box. -% -% The \xt{general} \xt{block} template should receive the following -% parameters. The \xt{plain} \xt{block} template is a restricted -% template that freezes all item-related parameters to dummy values -% (\texttt{counter}, \texttt{start}, \texttt{resume}, -% \texttt{label-width}, \texttt{label-sep} and all \texttt{item-*}). -% The \xt{list} \xt{block} template is a restricted template\footnote{A -% better approach could be to have a notion of inheritance for object -% types, so that we end up with two different \emph{object types}. Then -% we can implement other template for the list object type: \xt{table} -% for lists typeset as rows/columns of a table, \xt{inline} for lists -% typeset in horizontal mode within a paragraph, and \xt{runin} for -% run-in lists.} that omits the \texttt{heading} parameter and whose -% default for \texttt{item-instance} is non-empty. -% \begin{itemize} -% \item Structural parameters: the \texttt{heading} to place before, -% \texttt{counter} name, \texttt{start} value, whether to -% \texttt{resume} a previous list, and the \texttt{item-instance} (an -% \xt{item} instance) to use when typesetting items. -% \item Vertical spacing and penalties: \texttt{beginpenalty}, -% \texttt{beginsep}, \texttt{begin-par-skip}, \texttt{item-penalty}, -% \texttt{item-skip}, \texttt{item-par-skip}, \texttt{endpenalty}, -% \texttt{end-skip}, \texttt{end-par-skip}. -% \item Horizontal spacing: \texttt{rightmargin}, \texttt{leftmargin}, -% \texttt{parindent}, \texttt{item-indent}, \texttt{label-width}, -% \texttt{label-sep}. -% \end{itemize} -% A \docclass should edit these templates (or define restricted -% templates) to set up default values that depend on \tn{g_block_nesting_depth_int}, -% namely how many lists are nested overall.\footnote{Does -% \pkg{xtemplate} provide a way to specify default values that are only -% evaluated once an instance is used?} The document class should then -% set up an instance of these templates for each environment, with -% appropriate settings such as a \texttt{heading}, a suitable -% \texttt{item-instance}, or making \texttt{margin-right} equal to -% \texttt{margin-left} in a \texttt{quote} environment. -% -% The \xt{inline-list} \xt{block} template receives many fewer -% parameters. Note that \texttt{beginsep}, \texttt{item-skip}, -% \texttt{end-skip} are now \emph{horizontal} skips. -% \begin{itemize} -% \item Structural parameters: \texttt{counter}, \texttt{start}, -% \texttt{resume}, \texttt{item-instance}. -% \item Spacing and penalties: \texttt{beginpenalty}, -% \texttt{beginsep}, \texttt{item-penalty}, \texttt{item-skip}, -% \texttt{endpenalty}, \texttt{end-skip}. -% \item Horizontal spacing: \texttt{label-width}, \texttt{label-sep}. -% \end{itemize} -% -% The \xt{std} \xt{item} template should receive the following -% parameters. They depend on the type of list and its nesting level -% among lists of such type, but typically not on the total nesting -% level. -% \begin{itemize} -% \item Counter name (\texttt{counter}), shared with the parent -% \xt{list} \xt{block} template, but needed for incrementing. -% \item Label construction: a function \texttt{counter-label} that -% produces the label from the counter name, used if \tn{item} is given -% without argument. -% \item References: a function \texttt{counter-ref} for how the label -% should be referred to when it is constructed from the counter, -% \texttt{label-ref} and \texttt{label-autoref} used when \tn{item} -% has an optional argument. -% \item Label formatting: \texttt{label-format} function, -% \texttt{label-strut} boolean. -% \item Label alignment (\texttt{label-align}, \texttt{label-boxed}, -% \texttt{next-line}). -% \item Content parameters: \texttt{text-font}. -% \item A \texttt{compatibility} boolean that controls for instance -% whether \tn{makelabel} is used. -% \end{itemize} -% The \docclass should set up an instance such as \xt{enumiii} for each -% environment and nesting level.\footnote{This should be made easily -% extendible to deeper levels.} -% -% A given environment will adjust some nesting levels, then call the -% \xt{block} instance appropriate to the environment type, passing it -% the \xt{item} instance appropriate to the environment and depth. -% Additional context-dependence could be provided by \pkg{l3ldb}, but -% the main context-dependence should not rely on it for simplicity -% reasons and incidentally because \pkg{l3ldb} is not yet available. -% -% -% \Finale -% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\endinput diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-block.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-block.dtx new file mode 100644 index 00000000000..e0a723ca87c --- /dev/null +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-block.dtx @@ -0,0 +1,4101 @@ +% \iffalse meta-comment +% +%% File: latex-lab-block.dtx (C) Copyright 2021-2023 LaTeX Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +\def\ltlabblockdate{2023-09-01} +\def\ltlabblockversion{0.8h} +%<*driver> +\documentclass{l3doc} +\usepackage{amstext} +\EnableCrossrefs +\CodelineIndex + +\usepackage{todonotes} + +\begin{document} + \DocInput{latex-lab-block.dtx} +\end{document} +% +% +% \fi +% +% \providecommand\hook[1]{\texttt{#1\DescribeHook[noprint]{#1}}} +% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}} +% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}} +% +% \NewDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl} +% \NewDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl} +% \NewDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl} +% +% +% \title{Prototype reimplementation of \LaTeXe{}'s block environments using templates} +% \author{\LaTeX{} Project\thanks{Initial reimplementation of lists done by Bruno +% Le Floch, generalized second version with tagging support by Frank Mittelbach.}} +% \date{v\ltlabblockversion\ \ltlabblockdate} +% +% \maketitle +% +% +% \newcommand{\xt}[1]{\textsl{\textsf{#1}}} +% \newcommand{\TODO}[1]{\textbf{[TODO:} #1\textbf{]}} +% \newcommand{\docclass}{document class \marginpar{\raggedright document class +% customizations}} +% +% \providecommand\hook[1]{\texttt{#1}} +% \providecommand\struct[1]{\texttt{<#1>}} +% +% \NewDocElement[envlike, idxtype=objecttype, idxgroup=object types, +% printtype=\textit{objecttype}] {ObjectType}{objecttype} +% +% \NewDocElement[envlike, idxtype=template, idxgroup=templates, +% printtype=\textit{templ.}] {Template}{template} +% +% \NewDocElement[envlike, idxtype=instance, idxgroup=instances, +% printtype=\textit{inst.}] {Instance}{instance} +% +% +% \newcommand\valuefrom[1]{\textrm{value from }\texttt{#1}} +% \newcommand\key[1]{\texttt{#1}} +% +% +% \NewDocumentCommand\fmi{sO{}m} +% {\IfBooleanTF{#1}{\todo[inline,#2]{#3}}^^A +% {\todo[#2]{#3}}} +% +% \NewDocumentCommand\ufi{sO{}m} +% {\IfBooleanTF{#1}{\todo[inline,#2]{UFi:#3}}^^A +% {\todo[#2]{UFi:#3}}} +% \makeatletter +% \renewenvironment{TemplateInterfaceDescription}[1] +% { +% \subsubsection{The~object~type~`#1'} +% \begingroup +% \@beginparpenalty\@M +% \description +% \def\TemplateArgument##1##2{\item[Arg:~##1]##2\par} +% \def\TemplateSemantics +% { +% \enddescription\endgroup +% \subsubsection*{Semantics:} +% } +% } +% { +% \par\bigskip +% } +% \renewenvironment{TemplateDescription}[2] +% {\subsubsection{The \texttt{#1} template `#2'}^^A +% \paragraph*{Attributes:}^^A +% \begingroup +% \@beginparpenalty\@M +% \description +% \def\TemplateKey##1##2##3##4{^^A +% \item[\texttt{##1}~(\textit{\mdseries##2})]##3^^A +% \ifx\TemplateKey##4\TemplateKey\else +% \hfill\penalty500\hbox{}\hfill Default:~\texttt{##4}^^A +% \nobreak\hskip-\parfillskip\hskip0pt\relax +% \fi +% \par +% }^^A +% \def\TemplateSemantics{^^A +% \enddescription\endgroup +% \paragraph*{Semantics~\&~Comments:}^^A +% }^^A +% } +% { \par \bigskip } +% \makeatother +% +% +% \begin{abstract} +% \end{abstract} +% +% +% \tableofcontents +% \medskip +% +% +% \begin{documentation} +% +% +% +% \section{Introduction} +% +% The list implementation in \LaTeXe{} serves a dual purpose: it +% implements real lists such as \env{itemize} or \env{enumerate}, +% but it is also used as the basis for vertical blocks, i.e., to specify +% the vertical spacing and paragraph handling after such block, e.g., +% in environments like \env{center}, \env{quote}, \env{verbatim}, or in +% the theorem environments. They are all implemented as +% \enquote{trivial} lists with a single (hidden) item. +% +% While this was convenient to get a consistent layout using a single +% implementation it is not adequate if it comes to interpreting the +% structure of a document, because environments based on \env{trivlist} +% should not advertise themselves as being a \enquote{list} --- after all, +% from a semantic point of view they aren't lists. +% +% The approach taking here is therefore to offer separate object +% types: \xt{block} (horizontally or vertically oriented data that +% needs some handling at the start and the end), \xt{para} (that deals +% with different paragraph layouts), \xt{list} (that handles list +% related parameters, and \xt{item} (for item layouts and handling), to address +% the independent aspects and also offer the object type \xt{blockenv} +% that ties them together as necessary. +% +% For example, a \env{quote} environment would make use of a (display) +% \xt{block} and some \xt{para} handling while an standard +% \env{enumerate} would make use of a display \xt{block}, a \xt{list}, +% and an \xt{item} and \xt{para} instance. +% An inline list (like \env{enumerate*} from the \pkg{enumitem} +% package) would be using the same \xt{list} instance but a different +% (horizontally oriented) \xt{block}. +% +% +% \section{Object types and templates for blocks and lists} +% +% \subsection{Object types} +% +% \begin{TemplateInterfaceDescription}{block} +% \TemplateArgument{1}{key/value list to alter the default block parameters} +% \TemplateSemantics +% Handle the layout aspects of a block of data. In case of a +% \enquote{display} block (i.e., vertically oriented) the spacing +% and page breaking as well as the handling if the block starts a +% paragraph or ends one, that is, if text is immediately following +% the block without being separated by an empty line, then this +% text is considered to be in the same paragraph as the block. +% +% In case of a horizontally oriented block it covers any special +% handling at the start and end of the block, e.g, extra spacing, +% prohibitying or encuraging line breaks, and so forth. +% \end{TemplateInterfaceDescription} +% +% \begin{TemplateInterfaceDescription}{para} +% \TemplateArgument{1}{key/value list to alter the default item parameters} +% \TemplateSemantics +% Sets up paragraph-specific parameters for H\&J, e.g., to +% implement justification variations, the behavior of \verb=\\= +% etc. The instances are used in higher-level templates, e.g., in a +% \xt{block}. +% \end{TemplateInterfaceDescription} +% +% \begin{TemplateInterfaceDescription}{list} +% \TemplateArgument{1}{key/value list to alter the default item parameters} +% \TemplateSemantics +% Handle the aspects related to list design, e.g., the use and +% formatting of counters, etc. +% +% Note that this does not cover block-related aspects, i.e., a list +% instance could be used both for a display list or for an inline line. +% \end{TemplateInterfaceDescription} +% +% \begin{TemplateInterfaceDescription}{item} +% \TemplateArgument{1}{key/value list to alter the default item parameters} +% \TemplateSemantics +% A sub-type used as part of \xt{list} to easily cover alternative layout +% for list items. +% \end{TemplateInterfaceDescription} +% +% +% \begin{TemplateInterfaceDescription}{blockenv} +% \TemplateArgument{1}{key/value list to alter the default item parameters} +% \TemplateSemantics +% This object type is used to implement document-level +% environments. It defines a \xt{block} instance to handle the +% layout at the \enquote{edge} of the environment data, possibly +% some paragraph setup through a \xt{para} instance, potentially an +% \enquote{inner} instance for more complicated environments (such +% as lists), and possibly some additional setup code for certain +% environments. +% +% It also defines how the \xt{blockenv} behaves with respect to +% nesting, e.g., does it change when nested and if so how many +% levels of nesting are supported, etc. +% +% Finally, the object type defines how it appears in a tagged PDF +% document, what tag names are used, how they are rolemapped and +% whether it adds additional attributes, etc. +% \end{TemplateInterfaceDescription} +% +% +% +% \subsection{Templates} +% +% +% \begin{TemplateDescription}{blockenv}{display} +% +% \TemplateKey{env-name}{tokenlist} +% {Name of the environment used only in tracing}{} +% \TemplateKey{tag-name}{tokenlist} +% {Name of the tag in the PDF. If not explicitly given +% the name is defined by the \key{tagging-recipe}}{} +% \TemplateKey{tag-class}{tokenlist} +% {An explicit tag class attribute}{} +% \TemplateKey{tagging-recipe}{tokenlist} +% {Defines the way tagging is done. Currently the values +% \texttt{basic}, \texttt{standard}, and \texttt{list} +% are supported}{standard} +% \TemplateKey{level-increase}{boolean}{Does this \xt{blockenv} +% increase the block level if it is nested in an outer block?}{true} +% \TemplateKey{setup-code}{tokenlist} +% {Initial setup code. This is +% executed after legacy defaults (from \cs{@listi}, +% \cs{@listii}, etc.) are used but before the block instance is called}{} +% \TemplateKey{block-instance}{tokenlist}{Part of the name of the +% \xt{block} instance that is called. The full name has +% a \texttt{-}\meta{level} appended}{displayblock} +% \TemplateKey{para-instance}{tokenlist}{}{} +% \TemplateKey{inner-level-counter}{tokenlist}{Name of an existing (!) counter +% that is incremented and used to determine final name +% of the \key{inner-instance} or empty if always the +% same inner instance should be used}{} +% \TemplateKey{max-inner-levels}{tokenlist}{Maximum number of nested +% environments of this kind. Only relevant if there is a +% \key{inner-level-counter} specified}{4} +% \TemplateKey{inner-instance-type}{tokenlist}{Object type of the +% inner instance}{list} +% \TemplateKey{inner-instance}{tokenlist}{Name of the inner instance +% (if any).}{} +% \TemplateKey{para-flattened}{boolean}{\emph{describe}}{false} +% \TemplateKey{final-code}{tokenlist}{Final setup code}{\cs{ignorespaces}} +% +% \TemplateSemantics +% +% This \xt{blockenv} template supports the legacy list setting that +% are found in many document classes in the macros \cs{@listi}, +% \cs{@listii}, up to \cs{@listvi}. It also uses the counter +% \cs{@listdepth} to track nesting of block, again mainly to +% support legacy setups (internally it gives it a more appropriate +% name but it remains accessible through the \LaTeXe{} name). +% +% +% It first checks that nothing is too deeply nested. +% If the level should increase then the increments the +% \cs{@listdepth} counter and +% calls the corresponding \cs{@list...} macro to update the legacy +% defaults. If \key{level-increase} is set to false this is bypassed. +% +% It then sets up the +% tagging via the \key{tagging-recipe} setting and executes any +% code in \key{setup-code}. +% +% Afterwards it calls the appropriate \xt{block} instance based on +% \key{block-instance} and current level, e.g., +% \texttt{displayblock-1}. Then it sets up paragraph parameters if +% a \key{para-instance} was specified (otherwise they stay as +% they are). +% +% If a \key{inner-instance} was specified this is called next, +% or more precisely: if no \key{inner-level-counter} was +% specified the instance \key{inner-instance} is +% called. +% +% Otherwise, the \key{inner-level-counter} is incremented and the +% instance with the name +% \key{inner-instance}\texttt{-}\key{inner-level-counter} is +% called. +% +% Finally, the \key{final-code} is executed (by default +% \cs{ignorespaces}). +% +% +% \end{TemplateDescription} +% +% The maximum number of \xt{blockenv}s that can be nested into each +% other is is restricted by the \LaTeX{} counter +% \texttt{maxblocklevels} with a default value of \texttt{6}. If this +% value is increased then it is necessary to provide additional +% instances, e.g., \texttt{displayblock-7}, etc. Decreasing is, of +% course, always possible, then some of the instances defined are not +% used and instead the user gets an error that there is too much +% nesting going on. +% +% If the key \key{level-increase} is set to \texttt{false} then such +% an environment doesn't alter the nesting level and therefore you can +% nest those environments as often as you like (a typical example +% would be \env{flushleft} anywhere in the nesting hierarchy, that +% would have no effect on hitting the boundary). +% +% +% \begin{TemplateDescription}{block}{display} +% +% \TemplateKey{heading}{tokenlist}{\emph{not really used yet}}{} +% \TemplateKey{beginsep}{skip}{}{\cs{topsep}} +% \TemplateKey{begin-par-skip}{skip}{}{\cs{partopsep}} +% \TemplateKey{par-skip}{skip}{}{\cs{parsep}} +% \TemplateKey{end-skip}{skip}{}{\valuefrom{beginsep}} +% \TemplateKey{end-par-skip}{skip}{}{\valuefrom{begin-par-skip}} +% \TemplateKey{beginpenalty}{integer}{}{\cs{@beginparpenalty}} +% \TemplateKey{endpenalty}{integer}{}{\cs{@endparpenalty}} +% \TemplateKey{leftmargin}{length}{}{\cs{leftmargin}} +% \TemplateKey{rightmargin}{length}{}{\cs{rightmargin}} +% \TemplateKey{parindent}{length}{}{\cs{listparindent}} +% +% \TemplateSemantics +% +% The idea of a \key{heading} key needs some further +% thoughts. Maybe instead the object type should accept a second +% argument and receive input for such a headding from the document +% level instead. +% +% The names of the keys need further thoughts and some +% decision. Right now it is a mixture of those with hyphens and +% those that match legacy register names (the way \pkg{enumitem} +% did its keys). +% +% Also \key{parindent} conflicts with \key{indent-width}! +% +% \end{TemplateDescription} +% +% +% \begin{TemplateDescription}{para}{std} +% +% \TemplateKey{indent-width}{length}{}{\cs{parindent}} +% \TemplateKey{start-skip}{skip}{}{0pt} +% \TemplateKey{left-skip}{skip}{}{0pt} +% \TemplateKey{right-skip}{skip}{}{0pt} +% \TemplateKey{end-skip}{skip}{}{\cs{@flushglue}} +% \TemplateKey{fixed-word-spaces}{boolean}{}{false} +% \TemplateKey{final-hyphen-demerits}{integer}{}{5000} +% \TemplateKey{cr-cmd}{tokenlist}{}{\cs{@normalcr}} +% \TemplateKey{para-class}{tokenlist}{}{justify} +% +% \TemplateSemantics +% +% +% \end{TemplateDescription} +% +% +% +% \begin{TemplateDescription}{list}{std} +% +% \TemplateKey{counter}{tokenlist} +% {Counter name to be used in a numbered list or empty, +% if the list is unnumbered}{} +% \TemplateKey{item-label}{tokenlist} +% {Label \enquote{string} for a fixed label or as +% generated from the current \key{counter} value}{} +% \TemplateKey{start}{integer} +% {Start value for the counter if the list is numbered, +% otherwise irrelevant}{1} +% \TemplateKey{resume}{boolean} +% {Should a numbered list be resumed from the last instance?}{false} +% \TemplateKey{item-instance}{instance} +% {Instance of type \texttt{item} to be used to format +% the label string}{basic} +% \TemplateKey{item-skip}{skip}{The space in front of an item in the +% list.\fmi{May need to be on a different template level}}{\cs{itemsep}} +% \TemplateKey{item-indent}{length}{Horizontal displacement of the item.}{0pt} +% \TemplateKey{item-penalty}{integer} +% {Penalty for breaking before an +% item (except the first)}{\cs{@itempenalty}} +% \TemplateKey{label-width}{length} +% {Width reserved for the formatted item label}{\cs{labelwidth}} +% \TemplateKey{label-sep}{length} +% {Horizontal separation between label and following text}{\cs{labelsep}} +% \TemplateKey{legacy-support}{boolean} +% {Is formatting the label via \cs{makelabel} supported?}{false} +% +% \TemplateSemantics +% +% +% \end{TemplateDescription} +% +% +% \begin{TemplateDescription}{item}{std} +% +% \TemplateKey{counter-label}{function{1}}{\emph{unused}}{\cs{arabic}\{\#1\}} +% \TemplateKey{counter-ref}{function{1}}{\emph{unused}}{\valuefrom{counter-label}} +% \TemplateKey{label-ref}{function{1}}{\emph{unused}}{\#1} +% \TemplateKey{label-autoref}{function{1}}{\emph{unused}}{item~\#1} +% \TemplateKey{label-format}{function{1}} +% {Formatting of the label, questionable the way it is used}{\#1} +% \TemplateKey{label-strut}{boolean}{Add a \cs{strut} to the label?}{false} +% \TemplateKey{label-align}{choice} +% {Supported values \texttt{left},\texttt{center}, +% \texttt{right}, and \texttt{parleft}. \emph{Only partly implemented}}{right} +% \TemplateKey{label-boxed}{boolean} +% {Should the label be boxed?}{true} +% \TemplateKey{next-line}{boolean}{}{false} +% \TemplateKey{text-font}{tokenlist}{\emph{unused}}{} +% \TemplateKey{compatibility}{boolean}{}{true} +% +% \TemplateSemantics +% +% This template is only rudimentary implemented at the moment. It +% probably needs other keys and the existing ones need a proper +% implementation. +% +% \end{TemplateDescription} +% +% +% \section{Tagging support} +% +% \subsection{Paragraph tags} +% +% Paragraphs in \LaTeX{} can be nested, e.g., you can have a paragraph +% containing a display quote, which in turn consists of more than one +% (sub)paragraph, followed by some more text which all belongs to the +% same outer paragraph. +% +% In the PDF model and in the HTML model that is not supported --- a +% limitation that conflicts with real live, given that such +% constructs are quite normal in spoken and written language. +% +% The approach we take to resolve this is to model such \enquote{big} +% paragraphs with a structure named \struct{text-unit} and use \struct{text} (rollmapped to \struct{P}) +% only for (portions of) the actual paragraph text in a way that the +% \struct{text}s are not nested. As a result we have for a simple +% paragraph the structures +% \begin{tabbing} +% \hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\= \kill +% \> \struct{text-unit}\\ +% \>\> \struct{text}\\ +% \>\>\> The paragraph text \ldots\\ +% \>\> \struct{/text}\\ +% \> \struct{/text-unit} +% \end{tabbing} +% The \struct{text-unit} structure is rollmapped to \struct{Part} or possibly to +% \struct{Div} so we get a valid PDF, but processors who care can identify +% the complete paragraphs by looking for \struct{text-unit} tags. +% +% In the case of an element, such as a display quote or a display list +% inside the paragraph, we then have +% \begin{tabbing} +% \hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\= \kill +% \> \struct{text-unit}\\ +% \>\> \struct{text}\\ +% \>\>\> The paragraph text before the display element \ldots\\ +% \>\> \struct{/text}\\ +% \>\> \struct{display element structure}\\ +% \>\>\> Content of the display structure possiblly involving inner \struct{text-unit} tags\\ +% \>\> \struct{/display element structure}\\ +% \>\> \struct{text}\\ +% \>\>\> \ldots{} continuing the outer paragraph text\\ +% \>\> \struct{/text}\\ +% \> \struct{/text-unit} +% \end{tabbing} +% In other words such a display block is always embedded in a +% \struct{text-unit} structure, possibly preceded by a \struct{text}\ldots\struct{/text} block +% and possibly followed by one, though both such blocks are optional. +% +% Thus an \env{itemize} environment that has some introductory text +% but no text immediately following the list +% would be tagged as follows: +% \begin{tabbing} +% \hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\= \kill +% \> \struct{text-unit}\\ +% \>\> \struct{text}\\ +% \>\>\> The intro text for the \env{itemize} environment \ldots\\ +% \>\> \struct{/text}\\ +% \>\> \struct{itemize}\\ +% \>\>\> \struct{LI}\\ +% \>\>\>\> \struct{Lbl} label \struct{/Lbl}\\ +% \>\>\>\> \struct{LBody}\\ +% \>\>\>\>\> The text of the first item involving \struct{text-unit} as necessary \ldots\\ +% \>\>\>\> \struct{/LBody}\\ +% \>\>\> \struct{/LI}\\ +% \>\>\> \struct{LI}\\ +% \>\>\>\> The second item \ldots{}\\ +% \>\>\> \struct{/LI}\\ +% \>\>\> \ldots{} further items \ldots\\ +% \>\> \struct{/itemize}\\ +% \> \struct{/text-unit} +% \end{tabbing} +% The \struct{itemize} is rollmapped to \struct{L}. +% +% For some display blocks, such as centered text, we use a simpler +% strategy. Such blocks still ensure that they are inside a \struct{text-unit} +% structure but their body uses simple \struct{text} blocks and not +% \struct{text-unit}\struct{text} inside, e.g., the input +% \begin{verbatim} +% This is a paragraph with some +% \begin{center} +% centered lines +% +% with a paragraph break between them +% \end{center} +% followed by some more text. +% \end{verbatim} +% will be tagged as follows: +% \begin{tabbing} +% \hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\=\hspace*{1em}\= \kill +% \> \struct{text-unit}\\ +% \>\> \struct{text}\\ +% \>\>\> This is a paragraph with some\\ +% \>\> \struct{/text}\\ +% \>\> \struct{text /O /Layout /TextAlign/Center}\\ +% \>\>\> centered lines\\ +% \>\> \struct{/text}\\ +% \>\> \struct{text /O /Layout /TextAlign/Center}\\ +% \>\>\> with a paragraph break between them\\ +% \>\> \struct{/text}\\ +% \>\> \struct{text}\\ +% \>\>\> followed by some more text.\\ +% \> \struct{/text-unit} +% \end{tabbing} +% +% +% \subsection{Tagging recipes} +% +% There are a number of different tagging recipes that implement +% different tagging approaches. They are selected through the +% \key{tagging-recipe} of the \xt{blockenv} template. Currently the +% following values are implemented: +% \begin{description} +% \item[\texttt{standalone}] +% This recipe does the following: +% \begin{itemize} +% \item +% Ensure that the \xt{blockenv} is not inside a \struct{text-unit} +% structure. If necessary, close the open one (and any open +% \struct{text} structure). +% +% \item +% Text inside the body of the environment start with +% \struct{text-unit}\struct{text} unless the key +% \key{para-flattened} is set to \texttt{true} +% (which is most likely the wrong thing to do because we then get just +% \struct{text} as the structure). +% +% \item +% At the end of the environment close \struct{/text} and possibly an +% inner \struct{/text-unit} if open. +% +% \item +% Finally, ensure that after the environment a new +% \struct{text-unit} is started, if appropriate, e.g., if text is following. +% \end{itemize} +% +% \item[\texttt{basic}] +% This recipe does the following: +% \begin{itemize} +% \item +% Ensure that the \xt{blockenv} is inside a \struct{text-unit} +% structure, if necessary, start one. +% \item +% If inside a \struct{text-unit}\struct{text}, then close the \struct{/text} but +% leave the \struct{text-unit} open. +% +% \item +% Text inside the body of the environment start with +% \struct{text-unit}\struct{text} if \key{para-flattened} is set to \texttt{false}, +% otherwise just with \struct{text}. +% +% \item +% At the end of the environment close \struct{/text} and possibly an +% inner \struct{/text-unit} if open. +% +% \item +% Then look if the environment is followed by an empty line +% (\cs{par}). If so, close the outer \struct{/text-unit} and start any +% following text with \struct{text-unit}\struct{text}. Otherwise, +% don't and following text restarts with a just a \struct{text} (and no +% paragraph indentation) +% \end{itemize} +% +% \item[\texttt{standard}] +% This recipe is like the \texttt{basic} one as far as handling +% \struct{text-unit} and \struct{text} is concerned. In addition +% \begin{itemize} +% \item +% it starts an inner tagging structure (i.e., which is therefore a +% child of the outer \struct{text-unit}). +% \item +% By default this structure is a \struct{Figure} unless overwritten +% by the key \key{tag-name}. If that key is used, a suitable +% rollmap needs to be provided for the name given. +% \item +% At the end of the environment that inner structure is closed +% again so that we are back on the \struct{text-unit} level from the outside. +% \item +% Then the lookahead for an empty line is done as described previously. +% \end{itemize} +% +% +% +% \item[\texttt{list}] +% This recipe is like the \texttt{standard} one except that +% \begin{itemize} +% \item +% the inner structure is a list (\struct{L}). +% \item +% Furthermore everything is set up so that we have list items +% (\struct{LI}) with suitable substructures (\struct{Lbl} for the item +% labels and \struct{LBody} for the item bodies). +% \item +% If the key \key{tag-name} is specified, this is used as the tag +% name for the whole list instead of \struct{L}. Of course, it +% should then have a suitable rollmap. +% \item +% If the key \key{tag-class} is specified then this is used as the +% class attribute. Again, this requires a suitable setup on the outside. +% \item +% At the end of the environment the \struct{/LBody}, \struct{/LI}, and +% \struct{/L} (or the tag name used) are closed. +% \item +% Then the lookahead for an empty line is done as described previously. +% \end{itemize} +% +% +% \end{description} +% +% +% +% +% +% +% \end{documentation} +% +% \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } +% +% +% +% \begin{implementation} +% +% \section{The Implementation} +% +% +% \begin{macrocode} +%<*package> +%<@@=block> +% \end{macrocode} +% +% +% \begin{macrocode} +\ProvidesPackage {latex-lab-testphase-block} + [\ltlabblockdate\space v\ltlabblockversion\space + blockenv implementation] +% \end{macrocode} +% +% We make use of templates: +% \begin{macrocode} +\RequirePackage{xtemplate} +% \end{macrocode} +% Generell kernel changes, also loaded by the sec and toc code. +% \begin{macrocode} +\RequirePackage{latex-lab-kernel-changes} +% \end{macrocode} +% \begin{macrocode} +\ExplSyntaxOn +% \end{macrocode} +% +% \ufi{this variable(s) must be declared:} +% \begin{macrocode} +\tl_new:N \l_@@_item_align_tl +\tl_new:N\l_@@_legacy_env_params_tl +% \end{macrocode} + +% \subsection{Handling \cs{par} after the end of the list} +% +% An empty line (or a \cs{par}) after a list has semantic meaning as +% it defines whether then following text is logically within the same +% paragraph as the list (no empty line) or whether it starts a new +% paragraph and the paragraph containing the list ends at the end of +% the list (empty line after the list). +% This is handled by \LaTeX{} using a legacy flag called +% \texttt{@endpe} and set of commands inside the +% generic \cs{end} (calling \cs{@doendpe}) and as part of the list +% environments identifying themselves as \enquote{paragraph ending +% environments} (by setting this flag). +% +% For the reimplementation of the list environments including support +% of tagging we need to augment that mechanism slightly and add some +% kernel hook(s) to add the tagging code if needed. +% +% +% +% +% \begin{macro}{\@doendpe} +% The original \LaTeXe{} command is augmented to allow for tagging. +% \begin{macrocode} +\def\@doendpe{\@endpetrue + \def\par + { + \@restorepar + \clubpenalty\@clubpenalty +% \end{macrocode} +% At this point we add the tagging code that closes an open +% \struct{text-unit}, \struct{text} tag combination, +% if necessary: +% \begin{macrocode} + \__kernel_displayblock_doendpe: +% \end{macrocode} +% +% The standard \cs{par} command (\cs{par_end:}) acts on +% \texttt{@endpe} and attempts to close a still open \texttt{text-unit} +% and this would be wrong if it was already closed above. So we +% have to reset the switch to false first. +% \begin{macrocode} + \@endpefalse + \everypar{} + \par + } + \everypar{{\setbox\z@\lastbox} + \everypar{} + \@endpefalse + } +} +% \end{macrocode} +% +% By default we don't do any tagging: +% \begin{macrocode} +\cs_new_eq:NN \__kernel_displayblock_doendpe: \prg_do_nothing: +% \end{macrocode} +% The flag itself should be set globally not locally.\fmi{verify +% that this claim is actually correct!} +% \begin{macrocode} +\def\@endpetrue {\global\let\if@endpe\iftrue} +\def\@endpefalse{\global\let\if@endpe\iffalse} +% \end{macrocode} +% \end{macro} +% +% +% +% \subsection{Object and template interfaces} +% +% +% \begin{objecttype}{blockenv, block, para, list, item} +% All object types expect a single +% key--value argument used to tweak template parameters specific to a +% given use in the document. This section is devoted to template +% interfaces, and the template code is covered later. +% \begin{macrocode} +\DeclareObjectType{blockenv}{1} +\DeclareObjectType{block}{1} +\DeclareObjectType{para}{1} +\DeclareObjectType{list}{1} +\DeclareObjectType{item}{1} +% \end{macrocode} +% \end{objecttype} +% +% +% +% \begin{template}{blockenv display} +% +% \begin{macrocode} +\DeclareTemplateInterface{blockenv}{display}{1} +{ + env-name : tokenlist , + tag-name : tokenlist , + tag-class : tokenlist , + tagging-recipe : tokenlist = standard, + level-increase : boolean = true , + setup-code : tokenlist , + block-instance : tokenlist = displayblock , + para-instance : tokenlist , + inner-level-counter : tokenlist, + max-inner-levels : tokenlist = 4, + inner-instance-type : tokenlist = list , + inner-instance : tokenlist , + para-flattened : boolean = false , + final-code : tokenlist = \ignorespaces , +} +% \end{macrocode} +% \end{template} +% +% +% \begin{template}{block display} +% +% \begin{macrocode} +\DeclareTemplateInterface{block}{display}{1} +{ + heading : tokenlist = , %?? + beginsep : skip = \topsep , + begin-par-skip : skip = \partopsep , + par-skip : skip = \parsep , + end-skip : skip = \KeyValue{beginsep} , % conflict with name below + end-par-skip : skip = \KeyValue{begin-par-skip} , + beginpenalty : integer = \UseName{@beginparpenalty} , + endpenalty : integer = \UseName{@endparpenalty} , + leftmargin : length = \leftmargin , + rightmargin : length = \rightmargin , + parindent : length = \listparindent , +% font : tokenlist % maybe add? (or more general for fonts and color) +} +% \end{macrocode} +% \end{template} +% +% +% \begin{template}{para std} +% +% \begin{macrocode} +\DeclareTemplateInterface{para}{std}{1} +{ + indent-width : length = \parindent , + start-skip : skip = 0pt , + left-skip : skip = 0pt , + right-skip : skip = 0pt , + end-skip : skip = \@flushglue , + fixed-word-spaces : boolean = false , + final-hyphen-demerits : integer = 5000 , + cr-cmd : tokenlist = \@normalcr , + para-class : tokenlist = justify , +} +% \end{macrocode} +% \end{template} +% +% +% \begin{template}{list std} +% +% \begin{macrocode} +\DeclareTemplateInterface{list}{std}{1} % optional +{ + counter : tokenlist = , + item-label : tokenlist = , + start : integer = 1 , + resume : boolean = false , + item-instance : instance{item} = basic , + item-skip : skip = \itemsep , + item-penalty : integer = \UseName{@itempenalty} , + item-indent : length = 0pt , % was \itemindent + label-width : length = \labelwidth , + label-sep : length = \labelsep , + legacy-support : boolean = false , +} +% \end{macrocode} +% \end{template} +% +% +% \begin{template}{item std} +% +% \begin{macrocode} +\DeclareTemplateInterface{item}{std}{1} + { + counter-label : function{1} = \arabic{#1} , + counter-ref : function{1} = \KeyValue{counter-label} , + label-ref : function{1} = #1 , + label-autoref : function{1} = item~#1 , + label-format : function{1} = #1 , + label-strut : boolean = false , + label-align : choice {left,center,right,parleft} = right , + label-boxed : boolean = true , + next-line : boolean = false , + text-font : tokenlist , + compatibility : boolean = true , + } +% \end{macrocode} +% \end{template} +% +% +% +% +% +% +% \subsection{Useful helper commands} +% +% This section collects \pkg{expl3} commands that will be useful. +% +% \begin{macro}{\@@_skip_set_to_last:N,\@@_skip_remove_last:} +% Set a skiip register to the value of an immediately preceding +% skip or zero if there was none +% \begin{macrocode} +\cs_new_protected:Npn \@@_skip_set_to_last:N #1 { + \skip_set:Nn #1 { \tex_lastskip:D } +} +% \end{macrocode} +% Remove a skip previous skip if it is directly in front (not +% allowed in unrestricted vertical mode). +% \begin{macrocode} +\cs_new_eq:NN \@@_skip_remove_last: \tex_unskip:D +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tl_if_novalue:nTF} +% +% \begin{macrocode} +\cs_generate_variant:Nn \tl_if_novalue:nTF { o } +% \end{macrocode} +% \end{macro} +% +% +% \subsubsection{Debugging} +% +% +% \begin{variable}{\g_@@_debug_bool} +% +% \begin{macrocode} +\bool_new:N \g_@@_debug_bool +% \end{macrocode} +% \end{variable} +% +% +% \begin{macro}{\@@_debug:n,\@@_debug_typeout:n} +% +% \begin{macrocode} +\cs_new_eq:NN \@@_debug:n \use_none:n +\cs_new_eq:NN \@@_debug_typeout:n \use_none:n +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\block_debug_on:,\block_debug_off:, +% \@@_debug_gset:} +% \begin{macrocode} +\cs_new_protected:Npn \block_debug_on: + { + \bool_gset_true:N \g_@@_debug_bool + \@@_debug_gset: + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \block_debug_off: + { + \bool_gset_false:N \g_@@_debug_bool + \@@_debug_gset: + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_debug_gset: + { + \cs_gset_protected:Npx \@@_debug:n ##1 + { \bool_if:NT \g_@@_debug_bool {##1} } + \cs_gset_protected:Npx \@@_debug_typeout:n ##1 + { \bool_if:NT \g_@@_debug_bool { \typeout{==>~ ##1} } } + } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\DebugBlocksOn,\DebugBlocksOff} +% +% \begin{macrocode} +\cs_new_protected:Npn \DebugBlocksOn { \block_debug_on: } +\cs_new_protected:Npn \DebugBlocksOff { \block_debug_off: } +% \end{macrocode} +% +% \begin{macrocode} +\DebugBlocksOff +% \end{macrocode} +% \end{macro} +% +% +% +% \subsection{Implementation of the document-level block environments} +% +% Most such environments are pretty simple: they take an option +% argument and call a \texttt{blockenv} instance to do the work. At +% the end of environment we call \cs{endblockenv} to finish. +% +% +% \subsubsection{Displayblock environments} +% +% +% There are two basic block environment which are similar to +% \LaTeXe{}'s \env{trivlist} except that there aren't degenerated +% lists and thus have no hidden \cs{item} inside. +% +% +% \begin{environment}{displayblock} +% +% \begin{macrocode} +\NewDocumentEnvironment{displayblock}{ !O{} } + { \UseInstance{blockenv}{displayblock} {#1} } + { \endblockenv } +% \end{macrocode} +% \end{environment} +% +% +% +% +% \begin{environment}{displayblockflattened} +% +% \begin{macrocode} +\NewDocumentEnvironment{displayblockflattened}{ !O{} } + { \UseInstance{blockenv}{displayblockflattened} {#1} } + { \endblockenv } +% \end{macrocode} +% \end{environment} +% +% +% +% +% +% +% +% +% \begin{environment}{center,flushleft,flushright} +% +% \begin{macrocode} +\AddToHook{begindocument/before}{ + \RenewDocumentEnvironment{center} { !O{} } + { \UseInstance{blockenv}{center}{#1} } + { \endblockenv } +% \end{macrocode} +% +% \begin{macrocode} + \RenewDocumentEnvironment{flushright} { !O{} } + { \UseInstance{blockenv}{flushright}{#1} } + { \endblockenv } +% \end{macrocode} +% +% \begin{macrocode} + \RenewDocumentEnvironment{flushleft} { !O{} } + { \UseInstance{blockenv}{flushleft}{#1} } + { \endblockenv } +} +% \end{macrocode} +% +% +% \end{environment} +% +% +% +% +% \subsubsection{Display quote environments} +% +% +% \begin{environment}{quote,quotation} +% +% \begin{macrocode} +\AddToHook{begindocument/before}{ + \RenewDocumentEnvironment{quote}{ !O{} } + { \UseInstance{blockenv}{quote} {#1} } + { \endblockenv } +% \end{macrocode} +% +% \begin{macrocode} + \RenewDocumentEnvironment{quotation}{ !O{} } + { \UseInstance{blockenv}{quotation} {#1} } + { \endblockenv } +} +% \end{macrocode} +% \end{environment} +% +% +% +% +% +% +% \subsubsection{Verbatim environments} +% +% +% \begin{environment}{verbatim,verbatim*} +% +% \begin{macrocode} +\AddToHook{begindocument/before}{ + \RenewDocumentEnvironment{verbatim}{ !O{} } + { \UseInstance{blockenv}{verbatim} {#1} +% \end{macrocode} +% This is the part of the code where \env{verbatim} +% and\env{verbatim*} differ. +% \begin{macrocode} + \@setupverbinvisiblespace\frenchspacing\@vobeyspaces + \@xverbatim + } + { \endblockenv } +% \end{macrocode} +% +% \begin{macrocode} + \RenewDocumentEnvironment{verbatim*}{ !O{} } + { \UseInstance{blockenv}{verbatim} {#1} + \@setupverbvisiblespace\frenchspacing\@vobeyspaces + \@sxverbatim + } + { \endblockenv } +} +% \end{macrocode} +% \end{environment} +% +% +% +% \paragraph{Helper commands for verbatim} +% +% +% \begin{macro}{\legacyverbatimsetup} +% +% This code resembles the \LaTeXe{} verbatim implementation with a +% slight twist: in \LaTeXe{} each code line was a paragraph using +% \cs{leftskip}=\cs{@totalleftmargin}. This was possible because +% the whole environment was implemented as a trivlist. As this is +% no longer the case setting \cs{leftskip} would alter the layout +% of a surrounding list. So instead we need to make sure that the +% paragraph end is executed in a group so that any parshape setup +% is preserved. +% \begin{macrocode} +%<@@=> +\def\legacyverbatimsetup{% + \language\l@nohyphenation + \@tempswafalse + \def\par{% + \if@tempswa + \leavevmode \null {\@@par}\penalty\interlinepenalty + \else + \@tempswatrue + \ifhmode{\@@par}\penalty\interlinepenalty\fi + \fi}% + \let\do\@makeother \dospecials + \obeylines \verbatim@font \@noligs + \everypar \expandafter{\the\everypar \unpenalty}% +% \end{macrocode} +% +% \begin{macrocode} + \tl_set:Nn \l__tag_para_main_tag_tl {codeline} + \tagtool{paratag=Code}% oder faster: \tl_set:Nn\l__tag_para_tag_tl{Code} +} +%<@@=block> +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@setupverbinvisiblespace} +% In the \pdfTeX{} engine we need to use \cs{pdffakespace} chars +% for the invisible spaces. +% \begin{macrocode} +\newcommand\@setupverbinvisiblespace{} +\tag_if_active:T { + \bool_if:NF\g__tag_mode_lua_bool + { + \renewcommand\@setupverbinvisiblespace{\def\@xobeysp{\nobreakspace\pdffakespace}} + } +} +% \end{macrocode} +% \end{macro} +% +% +% \subsubsection{Standard list environments} +% +% +% \begin{environment}{itemize,enumerate,description} +% +% For the standard lists everything is managed by the blockenv instance. +% \begin{macrocode} +\AddToHook{begindocument/before}{ + \RenewDocumentEnvironment{itemize}{!O{}} + { \UseInstance{blockenv}{itemize} {#1} } + { \endblockenv } +% \end{macrocode} +% +% \begin{macrocode} + \RenewDocumentEnvironment{enumerate}{!O{}} + { \UseInstance{blockenv}{enumerate} {#1} } + { \endblockenv } +% \end{macrocode} +% +% \begin{macrocode} + \RenewDocumentEnvironment{description}{!O{}} + { \UseInstance{blockenv}{description} {#1} } + { \endblockenv } +} +% \end{macrocode} +% \end{environment} +% +% +% \subsubsection{verse environment} +% +% \begin{environment}{verse} +% The verse environment has not special tagging currently. It is +% defined as a simple standard list and takes the tagging from there. +% But it must be redefined so that \cs{itemindent} is correctly set. +% \begin{macrocode} +\AddToHook{begindocument/before}{ + \RenewDocumentEnvironment{verse}{ !O{} } + { + \let\\\@centercr + \UseInstance{blockenv}{list} + { + item-indent=-1.5em, + parindent=-1.5em, + item-skip=0pt, + rightmargin=\leftmargin, + leftmargin=\leftmargin+1.5em, + #1 + } + \item\relax + } + { \endblockenv } + } +% \end{macrocode} +% \end{environment} +% +% +% \begin{environment}{list} +% +% The legacy 2e list environment is more complicated as we have to get the +% extra arguments accounted for. +% \begin{macrocode} +\AddToHook{begindocument/before}{ + \RenewDocumentEnvironment{list}{O{} m m } + { +% \end{macrocode} +% We do this by storing them away and then call the list +% instance. Inside this instance the \texttt{setup-code} key +% contains \cs{legacylistsetupcode}, which makes use of the stored values. +% \begin{macrocode} + \tl_set:Nn \@itemlabel {#2} + \tl_set:Nn \l_@@_legacy_env_params_tl {#3} +% \end{macrocode} +% +% \begin{macrocode} + \UseInstance{blockenv}{list} {#1} + } + { \endblockenv } +} +% \end{macrocode} +% +% \end{environment} +% +% +% +% \begin{variable}{\l_@@_env_params_tl} +% Declare the variable for the parameter argument; \cs{@itemlabel} +% is already declared in \LaTeXe{}. +% \begin{macrocode} +\tl_new:N \l_@@_env_params_tl +% \end{macrocode} +% \end{variable} +% +% +% \begin{macro}{\legacylistsetupcode} +% +% And here is the extra code for use in the list instance setup +% inside the key \texttt{setup-code}. +% \begin{macrocode} +\cs_new:Npn \legacylistsetupcode { +% \end{macrocode} +% Reset values to defaults: +% \begin{macrocode} + \dim_zero:N \listparindent + \dim_zero:N \rightmargin + \dim_zero:N \itemindent +% \end{macrocode} +% +% By default a \env{list} environment is not numbered: +% \begin{macrocode} + \tl_set:Nn \@listctr {} + \legacy_if_set_false:n { @nmbrlist } % needed if lists are nested +% \end{macrocode} +% By default there is a simple definition for \cs{makelabel}. It can be +% overwritten in the second mandatory argument to the list +% environment (stored in \cs{l_@@_legacy_env_params_tl}) and +% is used if the instance sets the compatibility key to true. +% \begin{macrocode} + \let\makelabel\@mklab % TODO: customize +% \end{macrocode} +% Now we use the argument with parameter settings to update some or +% all of the above defaults: +% \begin{macrocode} + \l_@@_legacy_env_params_tl +% \end{macrocode} +% As we don't know much about this list we can only make a guess about +% the nature of the list and the setting of the tag name (default +% \texttt{list} rolemapped to \texttt{L}) and any tag attributes +% may have to be overwritten in the optional key/value argument. But we do have some hints to play with. +% \begin{macrocode} + \legacy_if:nTF { @nmbrlist } + { \tl_set:Nn \l__tag_L_attr_class_tl {enumerate} } % numbered list + { \tl_if_empty:NTF \@itemlabel + { \tl_set:Nn \l__tag_L_attr_class_tl {list} } % no label + { \tl_set:Nn \l__tag_L_attr_class_tl {itemize} } % unnumbered, unordered + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{environment}{trivlist} +% +% \begin{macrocode} +\AddToHook{begindocument/before}{ + \RenewDocumentEnvironment{trivlist}{ !O{} } + { \list[#1]{} + { + \dim_zero:N \leftmargin + \dim_zero:N \labelwidth + \cs_set_eq:NN \makelabel \use:n + } + } + { \endblockenv } +} +% \end{macrocode} +% \end{environment} +% +% +% \subsubsection{Theorem-like environments} +% +% Theorem-like environments are defined in \LaTeX{} with the help of +% \cs{newtheorem} declarations. Internally they used a list with a +% single item. Using lists was convenient back then, but in a tagged +% document you end up with a strange structure. We therefore alter the +% mechanism. +% +% +% \begin{macro}{\newtheorem} +% This is a slightly streamlined version of \cs{newtheorem}, but it +% still uses a lot of the 2e code for now. Eventually this will change. +% \begin{macrocode} +\RenewDocumentCommand \newtheorem { m O{#1} m o } +{ + \expandafter\@ifdefinable\csname #1\endcsname + { + \str_if_eq:nnTF{#1}{#2} + { + \@definecounter {#2} + \IfNoValueTF {#4} + { % @ynthm + \tl_gset:cx { the #2 } + { + \@thmcounter{#2} + } + } + { % @xnthm + \@newctr{#1}[#4] + \tl_gset:cx { the #2 } + { + \expandafter\noexpand\csname the#4\endcsname + \@thmcountersep + \@thmcounter{#2} + } + } + } + { % @othm + \@ifundefined{c@#2} + { \@nocounterr{#2} } + { + \tl_gset:cn { the #1 } + { \UseName { the #2 } } + } + } + \global\@namedef{#1} { \@thm{#2}{#3} } + \global\@namedef{end#1}{ \@endtheorem } + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@thm} +% \cs{@thm} executes \cs{refstepcounter} too early for hyperref +% and structure destinations: the generated target is outside the structure +% and can be separated from the theorem by a page break. We therefore move +% the anchor setting into \cs{@begintheorem}. \cs{@begintheorem} doesn't +% currently get the name of the counter as argument, so we store it in variable +% for now, to be able to pass it along. +% \begin{macrocode} +\tl_new:N \l_@@_thm_current_counter_tl +\def\@thm#1#2{% + \@kernel@refstepcounter{#1} + \tl_set:Nn \l_@@_thm_current_counter_tl{#1} + \@ifnextchar[{\@ythm{#1}{#2}}{\@xthm{#1}{#2}}} +% \end{macrocode} +% To avoid that hyperref overwrites the definition again we must its patch: +% \begin{macrocode} +\def\hyper@nopatch@thm{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@begintheorem,\@opargbegintheorem} +% +% The \cs{@thm} command expands to either \cs{@beginthorem} or +% \cs{@opargbegintheorem}. For the moment we stick with this as it +% will help with the transition. But instead of using a +% \env{trivlist} we use a blockenv and some tagging for the title +% (as a Caption). +% We do not want potential tagging from \cs{textbf} here, +% so we use \cs{bfseries} to set the font. The commands set also the link targets +% which should be inside the main structure. +% \begin{macrocode} +\def\@begintheorem#1#2{ + \UseInstance{blockenv}{theorem}{} + \tagpdfparaOff + \mode_leave_vertical: + \MakeLinkTarget{\l_@@_thm_current_counter_tl} + \tag_struct_begin:n{tag=Caption} + \group_begin: + \bfseries + \tag_mc_begin:n {} + #1\ + \tag_mc_end: + \tag_struct_begin:n{tag=Lbl} + \tag_mc_begin:n {} + #2 + \tag_mc_end: + \tag_struct_end: + \group_end: + \tag_struct_end: + \tagpdfparaOn +% \end{macrocode} +% +% \begin{macrocode} + \@@_start_para_structure_unconditionally:n { \PARALABEL } +% \end{macrocode} +% +% \begin{macrocode} + \itshape + \hskip\labelsep + \ignorespaces +} +\def\@opargbegintheorem#1#2#3{ + \UseInstance{blockenv}{theorem}{} + \tagpdfparaOff + \mode_leave_vertical: + \MakeLinkTarget{\l_@@_thm_current_counter_tl} + \tag_struct_begin:n{tag=Caption} + \group_begin: + \bfseries + \tag_mc_begin:n {} + #1\ + \tag_mc_end: + \tag_struct_begin:n{tag=Lbl} + \tag_mc_begin:n {} + #2 + \tag_mc_end: + \tag_struct_end: + \tag_mc_begin:n {} + \ (#3) + \tag_mc_end: + \group_end: + \tag_struct_end: + \tagpdfparaOn +% \end{macrocode} +% +% \begin{macrocode} + \@@_start_para_structure_unconditionally:n { \PARALABEL } +% \end{macrocode} +% +% \begin{macrocode} + \itshape + \hskip\labelsep + \ignorespaces +} +% \end{macrocode} +% +% \begin{macrocode} +\def\@endtheorem{\endblockenv} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \subsection{Implementation of templates} +% +% +% \subsubsection{Implementation of blockenv templates \ldots} +% +% +% +% \begin{macro}{\g_block_nesting_depth_int} +% \LaTeXe{} already has a counter to record the nesting depth of +% blocks, but we want our own name because it isn't really tied to +% \enquote{lists} any more. However, \cs{@listdepth} is really part +% of the legacy interface (for example \env{minipage} alters it to +% point to a different counter) so that we are stuck with using at +% least indirectly for now and the following line makes this look +% like an L3 integer variable but internally expands to \cs{@listdepth}: +% \begin{macrocode} +\cs_new:Npn \g_block_nesting_depth_int { \@listdepth } % a fake int + % for now +% \end{macrocode} +% \end{macro} +% +% +% \begin{template}{blockenv display} +% +% \begin{macrocode} +\DeclareTemplateCode{blockenv}{display}{1} +{ + env-name = \l_@@_env_name_tl , + tag-name = \l_@@_tag_name_tl , + tag-class = \l_@@_tag_class_tl , + tagging-recipe = \l_@@_tagging_recipe_tl , + level-increase = \l_@@_level_incr_bool , + setup-code = \l_@@_setup_code_tl , + block-instance = \l_@@_block_instance_tl , + para-instance = \l_@@_para_instance_tl , + inner-level-counter = \l_@@_inner_level_counter_tl , + max-inner-levels = \l_@@_max_inner_levels_tl , + inner-instance-type = \l_@@_inner_instance_type_tl , + inner-instance = \l_@@_inner_instance_tl , + para-flattened = \l__tag_para_flattened_bool , + final-code = \l_@@_final_code_tl , +} +{ + \@@_debug_typeout:n{\l_@@_env_name_tl -env-start} +% + \tl_if_empty:nF {#1} { \SetTemplateKeys{blockenv}{display}{#1} } +% +% \end{macrocode} +% We need to know later if we have nested blockenvs inside +% a flattened environment. Whenever we start a new blockenv we +% increment \cs{\l_@@_flattened_level_int} if it is already +% different from zero. If it is zero we increment it if flattening +% is requested. +% Thus a value of \texttt{0} means no flattening requested so far +% and \texttt{1} means this is the first blockenv requesting +% flattening. In either case we have to make sure that the blockenv +% is surrounded by a \texttt{text-unit} tag, while for any value above +% \texttt{1} we have to omit the \texttt{text-unit}. + % \begin{macrocode} + \int_compare:nNnTF \l_@@_flattened_level_int > 0 + { + \int_incr:N \l_@@_flattened_level_int + } + { + \bool_if:NT \l__tag_para_flattened_bool + { + \int_incr:N \l_@@_flattened_level_int + } + } +% + \tl_if_empty:NF \l_@@_inner_level_counter_tl + { + \int_compare:nNnTF \l_@@_inner_level_counter_tl > + { \l_@@_max_inner_levels_tl - 1 } + { \@toodeep } + { \int_incr:N \l_@@_inner_level_counter_tl } % not clean "o"? + } +% \end{macrocode} +% Legacy defaults are only roped in if the list level changes. For +% display blocks that remain on the same level the current values +% are kept. +% \begin{macrocode} + \bool_if:NT \l_@@_level_incr_bool + { + \int_compare:nNnTF \g_block_nesting_depth_int > + { \c@maxblocklevels - 1 } + { \@toodeep } + { + \int_gincr:N \g_block_nesting_depth_int +% \end{macrocode} +% If there are no legacy defaults for that level then the next line +% does nothing, i.e., the current values (from the last level +% become the defaults for the next. +% \begin{macrocode} + \use:c { @list \int_to_roman:n { \g_block_nesting_depth_int } } + } + } +% \end{macrocode} +% If we are doing tagging we load one of the available recipes for +% tagging, which alters various kernel hooks to add appropriate +% tagging structures. +% \begin{macrocode} + \tag_if_active:T { \use:c { @@_recipe_ \l_@@_tagging_recipe_tl : } } +% \end{macrocode} +% Then run the setup code if any is given in the instance. +% \begin{macrocode} + \l_@@_setup_code_tl +% \end{macrocode} +% Next call a block instance at the appropriate level passing it +% any key/value list provided in the optional argument (keys that +% are not recognized are ignored---currently with an +% error). +% \begin{macrocode} + \@@_debug_typeout:n{use~ instance:~ + \l_@@_block_instance_tl - \int_use:N \g_block_nesting_depth_int } + \UseInstance{block} + { \l_@@_block_instance_tl - \int_use:N + \g_block_nesting_depth_int } + {#1} +% \end{macrocode} +% After the block instance call the para and then inner (list) +% instance if either or both are +% specified (which may not be the case). +% \begin{macrocode} + \tl_if_empty:NF \l_@@_para_instance_tl + { + \@@_debug_typeout:n{use~ para~ instance:~ \l_@@_para_instance_tl } +% \end{macrocode} +% For now we don't offer to alter instance parameters here so we +% pass an empty argument. +% \begin{macrocode} + \UseInstance{para}{ \l_@@_para_instance_tl } {} + } +% \end{macrocode} +% The inner instance may have its own levels or none depending +% on which the instance name differs. Again we pass it the optional +% key/value list. +% \begin{macrocode} + \tl_if_empty:NF \l_@@_inner_instance_tl + { + \@@_debug_typeout:n{use~ instance:~ \l_@@_inner_instance_tl + \tl_if_empty:NF \l_@@_inner_level_counter_tl + { - \int_use:N \l_@@_inner_level_counter_tl }} + \UseInstance{ \l_@@_inner_instance_type_tl } + { \l_@@_inner_instance_tl + \tl_if_empty:NF \l_@@_inner_level_counter_tl + { - \int_use:N \l_@@_inner_level_counter_tl } % not clean + % use "o"? + } + {#1} + } +% \end{macrocode} +% We finish off with \cs{l_@@_final_code_tl} which defaults to +% \cs{ignorespaces} so that spaces between \verb=\begin{...}= and +% the start of the text are ignored. +% \begin{macrocode} + \l_@@_final_code_tl +} +% \end{macrocode} +% \end{template} +% +% +% \begin{macro}{\l_@@_flattened_level_int} +% Count the levels of nested blockenvs starting with the first that +% is \enquote{flattened}. +% \begin{macrocode} +\int_new:N \l_@@_flattened_level_int +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\c@maxblocklevels} +% A counter to increase or decrease the number of supported +% level. If increased, one needs to supply additional level instances. +% \begin{macrocode} +\newcounter{maxblocklevels} +\setcounter{maxblocklevels}{6} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\endblockenv} +% The code executed when a blockenv ends is 99\% the same for all +% blockenvs (at least up to now). Small differences exist, though. They +% are accounted for first in the conditionals. +% +% We make this a public command so that new block environments can +% be set up without the need to resort to L3 layer +% programming.\fmi{name is bad} +% \begin{macrocode} +\cs_new:Npn \endblockenv { + \@@_debug_typeout:n{blockenv~ common~ ending \on@line} +% \end{macrocode} +% If this block was incrementing the level we have to decrement it +% now again: +% \begin{macrocode} + \bool_if:NT \l_@@_level_incr_bool + { \int_gdecr:N \g_block_nesting_depth_int } +% \end{macrocode} +% If this block was a list and there are still \cs{item} labels to +% be placed we move to horizontal mode to get them typeset. +% \begin{macrocode} + \legacy_if:nT { @inlabel } + { + \mode_leave_vertical: + \legacy_if_gset_false:n { @inlabel } + } +% \end{macrocode} +% In a pure ``displayblock'' scenario \texttt{@newlist} will be +% always false and the code bypassed, but we may have an outer list +% followed immediately by a displayblock (with the \cs{item} missing) +% \begin{macrocode} + \legacy_if:nT { @newlist } + { + \@noitemerr + \legacy_if_gset_false:n { @newlist } + } + \mode_if_horizontal:TF + { \@@_skip_remove_last: \@@_skip_remove_last: \par } + { \@inmatherr{\end{\@currenvir}} } +% \end{macrocode} +% Once we are back in vertical mode we can add the appropriate +% closing tagging structure(s), if we are doing tagging. +% \begin{macrocode} + \__kernel_displayblock_end: +% \end{macrocode} +% What to do in terms of vertical spacing in different situations +% is still somewhat open to debate, right now this is more or less +% implementing what \LaTeXe{} list environment have been +% doing.\fmi{some redesign/extensions here?} +% \begin{macrocode} +% \@@_debug_typeout:n{@noparlist = +% \legacy_if:nTF { @noparlist }{true}{false}} + \legacy_if:nF { @noparlist } + { + \@@_skip_set_to_last:N \l_tmpa_skip + \dim_compare:nNnT \l_tmpa_skip > \c_zero_dim + { + \skip_vertical:n { - \l_tmpa_skip } + \skip_vertical:n { \l_tmpa_skip + \parskip - \@outerparskip } + } + \addpenalty \@endparpenalty + \addvspace \l_@@_topsepadd_skip +% \end{macrocode} +% \LaTeXe{} triggered the paragraph handling after a list at this +% point here, i.e., only if the list didn't start a paragraph. One +% can make a case for that, but it can be somewhat surprising to +% the user and there is a good argument that even such a list could +% be followed explanatory text that is part of the same paragraph +% and doesn't start a new one.\fmi{decide which logic we want to +% use! If the old logic is used we need to close the text-unit +% ourselves in the true branch} +% \begin{macrocode} +% \legacy_if_gset_true:n { @endpe } + } +% \end{macrocode} +% So this is for now always done. Probably \cs{l_@@_topsepadd_skip} above +% should be added only if the paragraph ends here and not if it +% continues, so this need some further cleanup.\fmi{decide} +% +% Finally, we have a socket that handles the \cs{par} handling +% after the block. Normally, we use it with the \plug{on} plug (check for a +% following \cs{par}) but in the case of standalone environments we +% assign it the \plug{off} plug. +% \begin{macrocode} + \socket_use:n {tagsupport/block-endpe} +} +% \end{macrocode} +% +% \end{macro} +% +% +% \begin{macro}{\__kernel_displayblock_end:} +% The kernel hook for tagging at the end of the block. +% \begin{macrocode} +\cs_new:Npn \__kernel_displayblock_end: { + \@@_debug_typeout:n{\detokenize{__kernel_displayblock_end:}} +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{socketdecl}{tagsupport/block-endpe} +% This socket is responsible for the end environment \cs{par} +% handling. We define two plugs for it (\plug{on} and \plug{off}). +% \begin{macrocode} +\socket_new:nn {tagsupport/block-endpe}{0} +% \end{macrocode} +% \end{socketdecl} +% +% \begin{plugdecl}{on,off} +% The plugs set the legacy \texttt{@endpe} switch. This must always +% happen because block environments with different settings can be nested +% and should not inherit the setting from the outer environment. +% \begin{macrocode} +\socket_new_plug:nnn{tagsupport/block-endpe}{on} + { \legacy_if_gset_true:n { @endpe } } +\socket_new_plug:nnn{tagsupport/block-endpe}{off} + { \legacy_if_gset_false:n { @endpe } } +% \end{macrocode} +% +% \begin{macrocode} +\socket_assign_plug:nn{tagsupport/block-endpe}{on} +% \end{macrocode} +% \end{plugdecl} +% +% +% +% +% +% \subsubsection{Implementation of para templates \ldots} +% +% \begin{template}{para std} +% +% \begin{macrocode} +\DeclareTemplateCode{para}{std}{1} +{ + indent-width = \parindent , + start-skip = \l__par_start_skip , % name?? + left-skip = \leftskip , + right-skip = \rightskip , + end-skip = \parfillskip , + fixed-word-spaces = \l__par_fixed_word_spaces_bool , % name?? + final-hyphen-demerits = \finalhyphendemerits , + cr-cmd = \\ , + para-class = \l_tag_para_attr_class_tl , +} +{ + \tl_if_empty:nF {#1} { \SetTemplateKeys{para}{std}{#1} } + \skip_set:Nn \@rightskip \rightskip +} +% \end{macrocode} +% \end{template} +% +% +% +% +% +% \subsubsection{Implementation of block templates \ldots} +% +% +% +% +% +% \begin{template}{block display} +% +% \begin{macrocode} +\DeclareTemplateCode{block}{display}{1} +{ + heading = \l_@@_heading_tl , + beginsep = \topsep , + begin-par-skip = \partopsep , + par-skip = \parsep , + end-skip = \l_@@_botsep_skip , + end-par-skip = \l_@@_parbotsep_skip , + beginpenalty = \@beginparpenalty , + endpenalty = \@endparpenalty , + rightmargin = \rightmargin , + leftmargin = \leftmargin , + parindent = \listparindent , +} +{ + \tl_if_empty:nF {#1} { \SetTemplateKeys{block}{display}{#1} } +% \end{macrocode} +% \fmi{generalize heading usage (or drop?)} +% \begin{macrocode} + \tl_if_blank:oF \l_@@_heading_tl + { \mode_leave_vertical: \textbf{\l_@@_heading_tl} } % TODO customize +% \end{macrocode} +% The code largely follows the logic of \LaTeXe{}'s \env{trivlist} +% implementation as far as it applicable for the \enquote{display +% block} but coded using the L3 programming layer. However, we keep +% all the legacy variables (e.g., \texttt{@noskipsec}) if there is +% some chance that they are set in classes or packages. +% \begin{macrocode} + \legacy_if:nT { @noskipsec } { \mode_leave_vertical: } + \skip_set:Nn \l_@@_topsepadd_skip { \topsep } + \mode_if_vertical:TF + { + \skip_add:Nn \l_@@_topsepadd_skip { \partopsep } +% \end{macrocode} +% At this point it is safe to add tagging structure(s) so we have +% a kernel-owned hook here for tagging. This is used to possibly +% start a paragraph structure (to surround the block, for example, +% in case of lists) and possibly do some other preparation for +% tagging the block. +% \begin{macrocode} + \__kernel_displayblock_beginpar_vmode: + } + { +% \end{macrocode} +% If we are in horizontal mode then the displayblock has to return +% to vertical mode now (after removing any immediately preceding +% skip or kern. But before we actually issue the\cs{par} we execute +% a kernel hook in which we can add tagging code. This hook is +% \enquote{weird} because by default it does nothing, but if +% tagging is wanted it takes an argument and grabs the following +% \cs{par} in order to put tagging code before and after the \cs{par}. +% \begin{macrocode} + \@@_skip_remove_last: \@@_skip_remove_last: + \__kernel_displayblock_beginpar_hmode:w \par + } +% \end{macrocode} +% Now we are back to legacy list implementation \ldots +% \begin{macrocode} + \legacy_if:nTF { @inlabel } + { + \legacy_if_set_true:n { @noparitem } + \legacy_if_set_true:n { @noparlist } + } + { + \legacy_if:nT { @newlist } { \@noitemerr } + \legacy_if_set_false:n { @noparlist } + \skip_set_eq:NN \l_@@_effective_top_skip \l_@@_topsepadd_skip + } + \skip_add:Nn \l_@@_effective_top_skip { \parskip } +% \end{macrocode} +% Next lines set some paragraph defaults, this may get overwritten +% if there is a \key{para-instance} specified on the \xt{blockenv}. +% \begin{macrocode} + \skip_zero:N \leftskip + \skip_set_eq:NN \rightskip \@rightskip + \skip_set_eq:NN \parfillskip \@flushglue +% \end{macrocode} +% The next lines establish a parshape which is retained across +% paragraphs be executing \cs{para_end:} within a group and thus +% reestablishing the parshape for the next paragraph again. In case +% a list got started \cs{par} is ignored until we have seen an +% \cs{item} (or we have executed \cs{par} one thousand times. +% \begin{macrocode} + \int_zero:N \par@deathcycles + \@setpar + { + \legacy_if:nTF { @newlist } + { + \int_incr:N \par@deathcycles + \int_compare:nNnTF \par@deathcycles > { 1000 } + { \@noitemerr + { \para_end: } + } + } + { + { \para_end: } + } + } + \skip_set_eq:NN \@outerparskip \parskip + \skip_set_eq:NN \parskip \parsep + \dim_set_eq:NN \parindent \listparindent + \dim_add:Nn \linewidth { - \rightmargin - \leftmargin } + \dim_add:Nn \@totalleftmargin { \leftmargin } + \tex_parshape:D 1 ~ \@totalleftmargin \linewidth +% \end{macrocode} +% This is the point where we are ready to add the tagging structure +% for the block, e.g., an \verb==, a \verb=
= or some +% other structure. +% \begin{macrocode} + \__kernel_displayblock_begin: +% \end{macrocode} +% Finally, we have to output the vertical separation and penalty at +% the start of the block and make corrections for a change in +% \cs{parskip} and some other housekeeping, unless this block is inside a list and the list +% \cs{item} has not yet placed. In that case the vertical +% space and penalty us suppressed. This +% is controled through the legacy switches \texttt{@noparitem}, +% \texttt{minipage}, and \texttt{@nobreak}. +% \begin{macrocode} + \legacy_if:nTF { @noparitem } + { + \legacy_if_set_false:n { @noparitem } + \hbox_gset:Nn \g_@@_labels_box + { + \skip_horizontal:n { - \leftmargin } + \hbox_unpack_drop:N \g_@@_labels_box + \skip_horizontal:n { \leftmargin } + } +% \end{macrocode} +% \fmi{document 2e logic used here} +% \begin{macrocode} + \legacy_if:nF { @minipage } % Why this chunk of code? + { + \@@_skip_set_to_last:N \l_@@_tmpa_skip + \skip_vertical:n { - \l_@@_tmpa_skip } + \skip_vertical:n { \l_@@_tmpa_skip + \@outerparskip - \parskip } + } + } + { + \legacy_if:nTF { @nobreak } + { \addvspace{\skip_eval:n{\@outerparskip-\parskip}} } + { + \addpenalty \@beginparpenalty + \addvspace \l_@@_effective_top_skip + \addvspace{-\parskip} + } + } +} +% \end{macrocode} +% +% +% Extra keys to support enumitem conventions: +% \begin{macrocode} +\keys_define:nn { template/block/display } +{ + ,topsep .skip_set:N = \topsep + ,partopsep .skip_set:N = \partopsep + ,listparindent .skip_set:N = \listparindent +} +% \end{macrocode} +% \end{template} +% +% +% +% \begin{macro}{\__kernel_displayblock_begin:, +% \__kernel_displayblock_beginpar_hmode:w, +% \__kernel_displayblock_beginpar_vmode:} +% The internal kernel hooks for tagging. +% \begin{macrocode} +\cs_new:Npn \__kernel_displayblock_begin: { + \@@_debug_typeout:n{\detokenize{__kernel_displayblock_begin:}} +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \__kernel_displayblock_beginpar_hmode:w { + \@@_debug_typeout:n{\detokenize{__kernel_displayblock_beginpar_hmode:w}} +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \__kernel_displayblock_beginpar_vmode: { + \@@_debug_typeout:n{\detokenize{__kernel_displayblock_beginpar_vmode:}} +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \subsubsection{Implementation of list templates \ldots} +% +% +% +% \begin{macro}{\@itemlabel,\@listctr} +% Both \cs{@itemlabel} and \cs{@listctr} from the \LaTeXe{} list +% implementation are used (or set) by various packages. We +% therefore use them too, so that these packages have a fighting +% chance to work with the new tagging-aware implementation for +% \env{list}. +% \begin{macrocode} +\tl_new:N \@itemlabel % should have a top-level definition +\tl_new:N \@listctr % should have a top-level definition +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \begin{template}{list std} +% +% This template implements numbered and unnumbered lists and can +% be combined with display blocks or with inline blocks. +% \begin{macrocode} +\DeclareTemplateCode{list}{std}{1} +{ + counter = \l_@@_counter_tl, + item-label = \l_@@_item_label_tl, + start = \l_@@_counter_start_int , + resume = \l_@@_resume_bool , + item-instance = \@@_item_instance:n , + item-skip = \itemsep , +% item-par-skip = \parsep , + item-penalty = \@itempenalty , + item-indent = \itemindent , + label-width = \labelwidth , + label-sep = \labelsep , + legacy-support = \l_@@_legacy_support_bool , % FMi questionable +} +{ + \@@_debug_typeout:n{template:list:std} +% + \tl_if_empty:nF {#1} { \SetTemplateKeys{list}{std}{#1} } +% \end{macrocode} +% Has this list a counter name defined in the instance? +% \begin{macrocode} + \tl_if_empty:NTF \l_@@_counter_tl + { +% \end{macrocode} +% If not we check if \cs{@listctr} has a non-empty value to be used +% for the list counter. +% +% We better test for blank not empty in case somebody had defined +% \cs{@listctr} using \cs{renewcommand} or \cs{cs_set:Npn}. +% \begin{macrocode} + \tl_if_blank:oF \@listctr + { +% \end{macrocode} +% In that case \texttt{@nmbrlist} should have been set too, for +% example, through \cs{usecounter}, so we do not set it +% explicitly. However, we check if we should resume a previous list. +% \begin{macrocode} + \bool_if:NF \l_@@_resume_bool + { + \int_gset:cn{ c@ \@listctr } + { \l_@@_counter_start_int - 1 } + } + } +% \end{macrocode} +% If \cs{@listctr} is not set then we have definitely an unnumbered list. +% \begin{macrocode} + { \@nmbrlistfalse } + } +% \end{macrocode} +% If a counter is set in the list instance we use that +% one. This should be the name of a \LaTeX{} counter that is +% already allocated externally---no runtime check is made for this: +% if it is not declared one will get \enquote{no such counter} +% error when the list is used. +% \begin{macrocode} + { + \@nmbrlisttrue + \tl_set_eq:NN \@listctr \l_@@_counter_tl + \bool_if:NF \l_@@_resume_bool + { + \int_gset:cn{ c@ \@listctr } + { \l_@@_counter_start_int - 1 } + } + } +% \end{macrocode} +% Does the current instance has an item label representation? This +% would be possible whether or not we have a numbered list. If yes, +% then we use this for \cs{@itemlabel}, otherwise we expect that +% \cs{@itemlabel} is provided from the outside, e.g., as part of +% the \env{list} environment argument. +% \begin{macrocode} + \tl_if_empty:NF \l_@@_item_label_tl + { + \tl_set_eq:NN \@itemlabel \l_@@_item_label_tl + } +% \end{macrocode} +% finally, we signal that we are at the start of a new list (which +% effects how the first \cs{item} is handled and how \cs{par} +% commands are interpreted. +% \begin{macrocode} + \legacy_if_gset_true:n { @newlist } +% \end{macrocode} +% +% \begin{macrocode} + \@@_debug_typeout:n{template:list:std~end} +} +% \end{macrocode} +% +% +% Extra keys to support enumitem conventions: +% \begin{macrocode} +\keys_define:nn { template/list/std } +{ + ,nosep .code:n = + \dim_zero:N \itemsep + \dim_zero:N \parsep + \dim_zero:N \topsep + \dim_zero:N \l_@@_botsep_skip + \dim_zero:N \l_@@_parbotsep_skip + ,midsep .skip_set:N = \topsep +} +% \end{macrocode} +% +% \end{template} +% +% +% \subsubsection{Implementation of \cs{item} template(s)} +% +% +% +% \begin{template}{item std} +% The item template has one hidden key \texttt{label} which is not available on the +% template for setting because it is only used to receive any +% optional data passed to the \cs{item} command. We therefore +% declare it with \cs{keys_define:nn} and ensure that the optional +% argument data to \cs{item} (if it is not a key/value list +% already) is passed to this \texttt{label} key. +% \begin{macrocode} +\keys_define:nn { template/item/std } + { label .tl_set:N = \l_@@_label_given_tl } +% \end{macrocode} +% +% \fmi{alignment is mostly wrong (test short medium and multiline +% labels)} +% \begin{macrocode} +\DeclareTemplateCode{item}{std}{1} + { + counter-label = \@@_counter_label:n , + counter-ref = \@@_counter_ref:n , +% \end{macrocode} +% \fmi{next set of key not yet used} +% \begin{macrocode} + label-ref = \@@_label_ref:n , + label-autoref = \@@_label_autoref:n , + label-format = \@@_label_format:n , + label-strut = \l_@@_label_strut_bool , + label-boxed = \l_@@_label_boxed_bool , + next-line = \l_@@_next_line_bool , + text-font = \l_@@_text_font_tl , + compatibility = \l_@@_item_compatibility_bool , +% \end{macrocode} +% This probably needs a different implementation (and needs completing)\fmi{complete} +% \begin{macrocode} + label-align = { + left = \tl_set:Nn \l_@@_item_align_tl { \relax \hss } , + center = \tl_set:Nn \l_@@_item_align_tl { \hss \hss } , + right = \tl_set:Nn \l_@@_item_align_tl { \hss \relax } , + parleft = \NOT_IMPLEMENTED , + } , + } +% \end{macrocode} +% Then typeset the label at its natural width by applying +% \cs{@@_make_label_box:n} to the label given or to a label constructed +% from the counter. If it is boxed and reasonably short, add padding to +% make it at least of size \tn{labelwidth}, then add another layer of +% box. This way, when we unpack it in \cs{g_@@_labels_box} it correctly +% remains boxed in those cases. Afterwards, in the \texttt{nextline} +% case add \tn{newline} if the label did not fit in the allotted space. +% \begin{macrocode} + { + \@@_debug_typeout:n{template:item:std} +% \end{macrocode} +% +% First deal with the key--value input, which in particular may +% provide a value for the label (the usual optional argument of +% \cs{item}). For this we set \cs{l_@@_label_given_tl} to +% \cs{c_novalue_tl} so that we can identify if an optional argument +% was given. +% \begin{macrocode} + \tl_set_eq:NN \l_@@_label_given_tl \c_novalue_tl + \tl_if_empty:nF{#1}{ \SetTemplateKeys{item}{std}{#1} } +% \end{macrocode} +% If no optional argument was given then \cs{l_@@_label_given_tl} +% is still equal to \cs{c_novalue_tl} and so we can distinuish +% that from \verb=\item[]=. +% +% \begin{macrocode} + \tl_if_novalue:oTF \l_@@_label_given_tl + { +% \end{macrocode} +% The rest of the code for this template needs work and is both +% incomplete and partly wrong.\fmi{fix} +% \begin{macrocode} + \tl_if_blank:oF \@listctr { \@kernel@refstepcounter \@listctr } + \bool_if:NTF \l_@@_item_compatibility_bool % not sure that conditional + % makes sense + { \@@_make_label_box:n { \MakeLinkTarget[\@listctr]{}\@itemlabel } } % TODO ? + { \@@_make_label_box:n { \MakeLinkTarget[\@listctr]{}\@@_counter_label:n { \@listctr } } } + } + { + \@@_debug_typeout:n{item~ with~ optional} + \@@_make_label_box:n { \l_@@_label_given_tl } } + \bool_if:nT + { + \l_@@_label_boxed_bool + && \dim_compare_p:n { \box_wd:N \l_@@_one_label_box <= \linewidth } % TODO: is \linewidth correct? + } + { + \dim_compare:nNnT + { \box_wd:N \l_@@_one_label_box } < \labelwidth + { + \hbox_set_to_wd:Nnn \l_@@_one_label_box { \labelwidth } + { + \exp_after:wN \use_i:nn \l_@@_item_align_tl +% \end{macrocode} +% FMi: \LaTeXe{} keeps the label boxed inside (not unboxed). This +% means that the content stays rigid and does not vary based on +% glue setting in the line with the label. +% There are cases where we do want the unboxed version (I think +% enumitem offers that in some cases too) but it should probably +% not the default. +% \begin{macrocode} +% \hbox_unpack_drop:N \l_@@_one_label_box %TODO: customize? + \box_use_drop:N \l_@@_one_label_box +% \end{macrocode} +% +% \begin{macrocode} + \exp_after:wN \use_ii:nn \l_@@_item_align_tl + } + } + \hbox_set:Nn \l_@@_one_label_box + { \box_use_drop:N \l_@@_one_label_box } + } + \dim_compare:nNnTF { \box_wd:N \l_@@_one_label_box } > \labelwidth + { \bool_set_true:N \l_@@_long_label_bool } + { \bool_set_false:N \l_@@_long_label_bool } + \hbox_gset:Nn \g_@@_labels_box + { + \hbox_unpack_drop:N \g_@@_labels_box + \skip_horizontal:n { \itemindent - \labelsep - \labelwidth } + \hbox_unpack_drop:N \l_@@_one_label_box + \skip_horizontal:n { \labelsep } + \bool_if:NT \l_@@_next_line_bool + { \bool_if:NT \l_@@_long_label_bool { \nobreak \hfil \break } } + % version of \newline inside an hbox that will be unpacked + } + % \skip_set_eq:NN \parsep \l_@@_item_parsep_skip TODO??? FMi + % what's that? + \dim_set_eq:NN \parindent \listparindent +% \end{macrocode} +% Placing the list label(s) is done when the paragraph for the +% \cs{item} is started, which executes \cs{@@_item_everypar:} +% inside \hook{para/begin}. By default this command does nothing, now we +% change it to attach the pending label or labels. +% \begin{macrocode} + \cs_set_eq:NN \@@_item_everypar: \@@_item_everypar_std: + } +% \end{macrocode} +% \end{template} +% +% +% +% +% \begin{variable}{\l_@@_one_label_box, \g_@@_labels_box} +% Each label is typeset in \cs{l_@@_one_label_box} to be measured. +% Once this is ready, it is put (boxed or unboxed) in +% \cs{g_@@_labels_box}, together with any pending labels (for the case +% where a list begins just after \tn{item}). This is an analogue of +% \LaTeXe{}'s \tn{@labels}, but it is always unboxed before use, to +% support both boxed and unboxed labels. +% \begin{macrocode} +\box_new:N \l_@@_one_label_box +\box_new:N \g_@@_labels_box +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_long_label_bool} +% Track whether the \cs{l_@@_one_label_box} is larger than +% \tn{labelwidth}. +% \begin{macrocode} +\bool_new:N \l_@@_long_label_bool +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_make_label_box:n, \@@_label_format:e} +% Make one label, wrapped in \cs{@@_label_format:n}, with an +% appropriate \tn{strut} and possibly \tn{makelabel} in compatibility +% mode (used for the \env{list} environment). +% \begin{macrocode} +\cs_new_protected:Npn \@@_make_label_box:n #1 + { + \hbox_set:Nn \l_@@_one_label_box + { +% \end{macrocode} +% If we do tagging then the contents of this box may need to be +% wrapped into a structure, e.g., \verb==. +% \begin{macrocode} + \__kernel_list_label_begin: +% \end{macrocode} +% +% \begin{macrocode} + \@@_label_format:n + { + \bool_if:NT \l_@@_label_strut_bool { \strut } + \bool_if:NTF \l_@@_legacy_support_bool + \makelabel + \use:n + {#1} + } +% \end{macrocode} +% And what gets opened also needs closing: +% \begin{macrocode} + \__kernel_list_label_end: + } + } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\__kernel_list_label_begin:, +% \__kernel_list_label_end:} +% If we aren't doing tagging the kernel hooks do nothing. +% \begin{macrocode} +\cs_new_eq:NN \__kernel_list_label_begin: \prg_do_nothing: +\cs_new_eq:NN \__kernel_list_label_end: \prg_do_nothing: +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_item_everypar:, \@@_item_everypar_std:} +% The \cs{@@_item_everypar:} command is executed as part of \hook{para/begin} +% but most of the time does nothing, i.e., it has the following +% default definition. +% \begin{macrocode} +\cs_new_eq:NN \@@_item_everypar: \prg_do_nothing: +% \end{macrocode} +% +% \begin{macrocode} +\AddToHook{para/begin}[lists]{\@@_item_everypar:} +% \end{macrocode} +% +% Note that we have to make sure that the above code is executed +% after the hook chunk from \texttt{tagpdf} because the latter uses +% \texttt{@inlabel} to make a decision. +% +% By the end of the day both should probably move into the kernel +% hook instead! +% \begin{macrocode} +\DeclareHookRule{para/begin}{lists}{after}{tagpdf} +% \end{macrocode} +% +% +% What follows is the version that resets various legacy booleans and puts +% the label box in the right place and finally resets itself to do +% nothing next time. \cs{@@_item_everypar:} is set to this by the +% item template so that the next paragraph start runs the code below. +% \begin{macrocode} +\cs_new_protected:Npn \@@_item_everypar_std: { + \@@_debug_typeout:n{item~ everypar \on@line } + \legacy_if_set_false:n { @minipage } + \legacy_if_gset_false:n { @newlist } + \legacy_if:nT { @inlabel } + { + \legacy_if_gset_false:n { @inlabel } +% \end{macrocode} +% +% \begin{macrocode} + \box_if_empty:NT \g_para_indent_box { \kern - \itemindent } + \para_omit_indent: +% \end{macrocode} +% +% \begin{macrocode} + \box_use_drop:N \g_@@_labels_box +% \end{macrocode} +% After the labels are placed we start a paragraph structure (if +% appropriate). This is handled in the following kernel hook: +% \begin{macrocode} + \__kernel_list_label_after: +% \end{macrocode} +% +% \begin{macrocode} + \penalty \c_zero_int + } + \legacy_if:nTF { @nobreak } + { + \legacy_if_gset_false:n { @nobreak } + \int_set:Nn \clubpenalty { 10000 } + } + { + \int_set_eq:NN \clubpenalty \@clubpenalty +% \end{macrocode} +% Once the label(s) are typeset and we are past any special +% \texttt{@nobreak} handling we reset \cs{@@_item_everypar:} to do +% nothing. +% \begin{macrocode} + \cs_set_eq:NN \@@_item_everypar: \prg_do_nothing: + } +} +% \end{macrocode} +% +% \end{macro} +% +% +% \begin{macro}{\__kernel_list_label_after:} +% +% \begin{macrocode} +\cs_new_eq:NN \__kernel_list_label_after: \prg_do_nothing: +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\l_@@_tmpa_skip} +% \begin{macrocode} +\skip_new:N \l_@@_tmpa_skip +% \end{macrocode} +% \end{variable} +% +% +% +% +% +% +% +% \begin{variable}{\l_@@_topsepadd_skip, \l_@@_effective_top_skip} +% Variables equivalent to \LaTeXe{}'s \tn{@topsepadd} and \tn{@topsep}. +% Roughly equal to a mixture of \texttt{topsep}, \texttt{partopsep}, +% and various \texttt{parskip} at different nesting levels in lists. +% The code is really elaborate when \texttt{@inlabel} is true. +% \begin{macrocode} +\skip_new:N \l_@@_topsepadd_skip +\skip_new:N \l_@@_effective_top_skip +% \end{macrocode} +% \end{variable} +% +% +% +% +% +% +% +% +% +% +% +% \begin{macro}{\item} +% Here we already have all the building blocks. Complain in math +% mode. Distingusih between first item (do necessary tagging) and +% later items \cs{@@_inter_item:} to +% cleanly close what's before, then call \cs{@@_item_instance:n} (which +% calls \cs{UseInstance}\{item\}\marg{instance}) to prepare the +% upcoming item: it will be actually inserted only once some later +% material triggers \tn{everypar}. +% \begin{macrocode} +\AddToHook{begindocument/before}{ + \RenewDocumentCommand{\item}{ ={label}o } + { + \@inmatherr \item +% \end{macrocode} +% TODO: Test for being outside of a list needs updating! +% \begin{macrocode} + \tl_if_empty:oTF \@@_item_instance:n %%FMi? + { \msg_error:nnn { @@ } { item-in-nonlist } { \item[{#1}] } } + { + \legacy_if:nTF { @newlist } + { \__kernel_list_item_begin: } + { \@@_inter_item: } +% \end{macrocode} +% To avoid unnecessary key/val processing we make a quick check if +% there was an optional argument. +% \begin{macrocode} + \tl_if_novalue:nTF {#1} % avoids reparsing label={} + { \@@_item_instance:n { } } + { \@@_item_instance:n {#1} } +% \end{macrocode} +% Set the legacy switch that signals that we have a pending item label: +% \begin{macrocode} + \legacy_if_gset_true:n { @inlabel } + \ignorespaces + } + } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@_inter_item:} +% Between items. If the previous item had no content then we need to +% trigger \tn{everypar}. Otherwise we simply close the previous item +% with \tn{par} after removing some horizontal space. Between items, +% there is a penalty and some space. +% \begin{macrocode} +\cs_new_protected:Npn \@@_inter_item: { + \legacy_if:nT { @inlabel } + { \indent \par } % case of \item\item +% \end{macrocode} +% \cs{par} may have a strange definition and may not get us back to +% vertical mode in one go, so we better do not treat the next line +% as an else case to the above conditional (for now). +% \begin{macrocode} + \mode_if_horizontal:T { \@@_skip_remove_last: + \@@_skip_remove_last: \par } +% \end{macrocode} +% End any LI-tag, then start the next LI-tag (if doing tagging): +% \begin{macrocode} + \__kernel_list_item_end: + \__kernel_list_item_begin: +% \end{macrocode} +% +% \begin{macrocode} + \addpenalty \@itempenalty + \addvspace \itemsep +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\__kernel_list_item_begin:, +% \__kernel_list_item_end:} +% +% \begin{macrocode} +\cs_new_eq:NN \__kernel_list_item_begin: \prg_do_nothing: +\cs_new_eq:NN \__kernel_list_item_end: \prg_do_nothing: +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% +% +% \subsection{Tagging recipes} +% +% \begin{macro}{\@@_recipe_basic:} +% The \texttt{basic} recipe simply ensures that the block is inside +% a \texttt{text-unit} structure and if necessary starts one. When the +% block ends and is followed by a blank line the \texttt{text-unit} +% structure is closed too, otherwise it remains open and further +% text starts with just a \struct{text} structure. +% +% There is otherwise no inner structure so +% \cs{__kernel_displayblock_begin:} and +% \cs{__kernel_displayblock_end:} do nothing---blockenvs with inner +% structure use the \texttt{standard} or \texttt{list} recipe instead. +% \begin{macrocode} +\cs_new:Npn \@@_recipe_basic: { + \cs_set_eq:NN \__kernel_displayblock_beginpar_hmode:w + \@@_beginpar_hmode:N + \cs_set_eq:NN \__kernel_displayblock_beginpar_vmode: + \@@_beginpar_vmode: + \let \__kernel_displayblock_begin: \prg_do_nothing: + \let \__kernel_displayblock_end: \prg_do_nothing: +% \end{macrocode} +% End environment \cs{par} handling: +% \begin{macrocode} + \socket_assign_plug:nn{tagsupport/block-endpe}{on} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_recipe_standalone:} +% +% The \texttt{standalone} recipe produces a block that ensures that +% a previous \texttt{text-unit} ends and that after the block a new +% \texttt{text-unit} starts. +% \begin{macrocode} +\cs_new:Npn \@@_recipe_standalone: { + \cs_set_eq:NN \__kernel_displayblock_beginpar_hmode:w + \prg_do_nothing: + \cs_set_eq:NN \__kernel_displayblock_beginpar_vmode: + \prg_do_nothing: + \cs_set_eq:NN \__kernel_displayblock_begin: \@@_inner_begin: + \cs_set_eq:NN \__kernel_displayblock_end: \@@_inner_end: +% \end{macrocode} +% End environment \cs{par} handling: +% \begin{macrocode} + \socket_assign_plug:nn{tagsupport/block-endpe}{off} +% \end{macrocode} +% +% \begin{macrocode} + \tl_if_empty:NTF \l_@@_tag_name_tl + { \tl_set:Nn \l_@@_tag_inner_tag_tl {Sect} } + { \tl_set_eq:NN \l_@@_tag_inner_tag_tl \l_@@_tag_name_tl } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_recipe_standard:} +% The \texttt{standard} recipe does the following: +% \begin{itemize} +% \item surround the block with a \texttt{text-unit}-structure if not already in a +% a \texttt{text-unit}. In the latter case end the +% MC and the \struct{text} but leave the \texttt{text-unit} open. +% +% If we are producing flattened paragraphs, just close any +% \struct{text} but do not open a \texttt{text-unit}. +% +% \item Then open an new (inner) structure (by default +% \texttt{Figure} but typically the one specified on the instance). +% \item At the end of the block close the the inner structure +% (\texttt{Figure} or explicit one) +% but leave the \texttt{text-unit} open to be either continued or closed due to a +% following \cs{par}. +% \end{itemize} +% \begin{macrocode} +\cs_new:Npn \@@_recipe_standard: +{ + \cs_set_eq:NN \__kernel_displayblock_beginpar_hmode:w + \@@_beginpar_hmode:N + \cs_set_eq:NN \__kernel_displayblock_beginpar_vmode: + \@@_beginpar_vmode: + \cs_set_eq:NN \__kernel_displayblock_begin: \@@_inner_begin: + \cs_set_eq:NN \__kernel_displayblock_end: \@@_inner_end: +% \end{macrocode} +% End environment \cs{par} handling: +% \begin{macrocode} + \socket_assign_plug:nn{tagsupport/block-endpe}{on} +% \end{macrocode} +% +% \begin{macrocode} + \tl_if_empty:NTF \l_@@_tag_name_tl + { \tl_set:Nn \l_@@_tag_inner_tag_tl {Figure} } + { \tl_set_eq:NN \l_@@_tag_inner_tag_tl \l_@@_tag_name_tl } +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\l_@@_tag_inner_tag_tl} +% \begin{macrocode} +\tl_new:N \l_@@_tag_inner_tag_tl +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_recipe_list:} +% The \texttt{list} recipe does the following. +% \begin{itemize} +% \item It opens a \struct{text-unit}-structure or keeps the current one open (only +% closing the MC). +% \item It then starts a new structure rolemapped to L-structure +% and arranges for handling list items, e.g., Li, Lbl and LBody +% structures. +% \item At the end it closes open list structures as needed but +% keeps the \struct{text-unit}-structure open to continue the paragraph after the +% list, if necessary. +% \end{itemize} +% \begin{macrocode} +\cs_new:Npn \@@_recipe_list: +{ + \cs_set_eq:NN \__kernel_displayblock_beginpar_hmode:w + \@@_beginpar_hmode:N + \cs_set_eq:NN \__kernel_displayblock_beginpar_vmode: + \@@_beginpar_vmode: + \cs_set_eq:NN \__kernel_displayblock_begin: \@@_list_begin: + \cs_set_eq:NN \__kernel_displayblock_end: \@@_list_end: +% \end{macrocode} +% The next two lines could be done globally, because they are only +% called if we do have \cs{item}s, i.e., if we are in a list. It is +% therefore also not necessary to reset them in other recipes +% (right now---this may change if we get more templates (like +% inline lists)). +% \begin{macrocode} + \cs_set_eq:NN \__kernel_list_item_begin: \@@_list_item_begin: + \cs_set_eq:NN \__kernel_list_item_end: \@@_list_item_end: +% \end{macrocode} +% End environment \cs{par} handling: +% \begin{macrocode} + \socket_assign_plug:nn{tagsupport/block-endpe}{on} +% \end{macrocode} +% +% Handle the tag name and attribute classess using the key values +% from the current list instance. +% \begin{macrocode} + \tl_if_empty:NTF \l_@@_tag_name_tl + { \tl_set:Nn \l__tag_L_tag_tl {L} } + { \tl_set_eq:NN \l__tag_L_tag_tl \l_@@_tag_name_tl } + \tl_if_empty:NTF \l_@@_tag_class_tl + { \tl_set:Nn \l__tag_L_attr_class_tl {} } + { \tl_set_eq:NN \l__tag_L_attr_class_tl \l_@@_tag_class_tl } +} +% \end{macrocode} +% \end{macro} + + + +% \subsection{Blockenv instances} +% +% +% \subsubsection{Basic instances} +% +% \begin{instance}{blockenv displayblock} +% +% \begin{macrocode} +\DeclareInstance{blockenv}{displayblock}{display} +{ + env-name = displayblock, + tag-name = , + tag-class = , + tagging-recipe = standard, + inner-level-counter = , + level-increase = false, + setup-code = , + block-instance = displayblock , + inner-instance = , +} +% \end{macrocode} +% \end{instance} +% +% +% +% \begin{instance}{blockenv displayblockflattened} +% +% \begin{macrocode} +\DeclareInstance{blockenv}{displayblockflattened}{display} +{ + env-name = displayblockflattened, + tag-name = , + tag-class = , + tagging-recipe = basic, + inner-level-counter = , + level-increase = false, + setup-code = , + block-instance = displayblock , + para-flattened = true , + inner-instance = , +} +% \end{macrocode} +% \end{instance} +% +% +% +% \begin{instance}{blockenv center} +% +% \begin{macrocode} +\DeclareInstance{blockenv}{center}{display} +{ + env-name = center, + tag-name = , + tag-class = , + tagging-recipe = basic, + inner-level-counter = , + level-increase = false, + setup-code = , + block-instance = displayblock , + para-flattened = true , + para-instance = center , + inner-instance = , +} +% \end{macrocode} +% \end{instance} +% +% +% \begin{instance}{blockenv flushleft} +% +% \begin{macrocode} +\DeclareInstance{blockenv}{flushleft}{display} +{ + env-name = flushleft, + tag-name = , + tag-class = , + tagging-recipe = basic, + inner-level-counter = , + level-increase = false, + setup-code = , + block-instance = displayblock , + para-flattened = true , + para-instance = raggedright , + inner-instance = , +} +% \end{macrocode} +% \end{instance} +% +% +% +% \begin{instance}{blockenv flushright} +% +% \begin{macrocode} +\DeclareInstance{blockenv}{flushright}{display} +{ + env-name = flushleft, + tag-name = , + tag-class = , + tagging-recipe = basic, + inner-level-counter = , + level-increase = false, + setup-code = , + block-instance = displayblock , + para-flattened = true , + para-instance = raggedleft , + inner-instance = , +} +% \end{macrocode} +% \end{instance} +% +% +% +% \subsubsection{Blockquote instances} +% +% \begin{instance}{blockenv quotation} + % +% \begin{macrocode} +\DeclareInstance{blockenv}{quotation}{display} +{ + env-name = quotation, + tag-name = quotation, + tag-class = , + tagging-recipe = standard, + inner-level-counter = , + level-increase = true, + setup-code = , + block-instance = quotationblock , + inner-instance = , +} +% \end{macrocode} +% \end{instance} +% +% +% +% \begin{instance}{blockenv quote} +% +% \begin{macrocode} +\DeclareInstance{blockenv}{quote}{display} +{ + env-name = quote, + tag-name = quote, + tag-class = , + tagging-recipe = standard, + inner-level-counter = , + level-increase = true, + setup-code = , + block-instance = quoteblock , + inner-instance = , +} +% \end{macrocode} +% \end{instance} +% +% An alternative setup for quotations, using the displayblock instance and +% just overwrite a bit in the setup code.\fmi{I guess the setup +% code is still executed too early, have to check.} +% This would be less flexible but would ensure visual consistency, +% because the displayblock settings are used throughout. +% \begin{macrocode} +% \DeclareInstance{blockenv}{quotation}{display} +% { +% env-name = quotation, +% tag-name = , +% tag-class = , +% tagging-recipe = blockquote, +% inner-level-counter = , +% level-increase = true, +% setup-code = \setlength\rightmargin{\leftmargin} +% \setlength\parsep{1.5em} , +% block-instance = displayblock , +% inner-instance = , +% } +% \end{macrocode} +% +% \begin{macrocode} +% \DeclareInstance{blockenv}{quote}{display} +% { +% env-name = quote, +% tag-name = , +% tag-class = , +% tagging-recipe = blockquote, +% inner-level-counter = , +% level-increase = true, +% setup-code = \setlength\rightmargin{\leftmargin} , +% block-instance = displayblock , +% inner-instance = , +% } +% \end{macrocode} +% + +% +% \begin{macrocode} +\DeclareInstance{blockenv}{theorem}{display} +{ + env-name = theorem-like, + tag-name = theorem-like, + tag-class = , + tagging-recipe = standalone, + inner-level-counter = , + level-increase = false, + setup-code = , + block-instance = displayblock , +% inner-instance-type = innerblock , +% inner-instance = theorem, +} +% \end{macrocode} +% +% We use \struct{theorem-like} as the structure name and rolemap it +% to a \struct{Sect} because that can hold a \struct{Caption}. +% +% \subsubsection{Verbatim instances} +% +% \begin{instance}{blockenv verbatim} +% +% The rolemapping is current verbatim to P and codeline to Sub (which is role mapped +% to Span in pdf 1.7. Alternatives for PDF 1.7: Div and P. +% +% \begin{macrocode} +\DeclareInstance{blockenv}{verbatim}{display} +{ + env-name = verbatim, + tag-name = verbatim, + tag-class = , + tagging-recipe = standard, + inner-level-counter = , + level-increase = false, + setup-code = , + block-instance = verbatimblock , + inner-instance = , + final-code = \legacyverbatimsetup , +} +% \end{macrocode} +% \end{instance} +% +% +% \subsubsection{Standard list instances} +% +% \begin{instance}{blockenv itemize} +% +% \begin{macrocode} +\DeclareInstance{blockenv}{itemize}{display} +{ + env-name = itemize, + tag-name = itemize, + tag-class = itemize, + tagging-recipe = list, + inner-level-counter = \@itemdepth, + level-increase = true, + max-inner-levels = 4, + setup-code = , + block-instance = list , + inner-instance = itemize , +} +% \end{macrocode} +% \end{instance} +% +% +% \begin{instance}{blockenv enumerate} +% +% \begin{macrocode} +\DeclareInstance{blockenv}{enumerate}{display} +{ + env-name = enumerate, + tag-name = enumerate, + tag-class = enumerate, + tagging-recipe = list, + level-increase = true, + setup-code = , + block-instance = list , + inner-level-counter = \@enumdepth, + max-inner-levels = 4, + inner-instance = enum , +} +% \end{macrocode} +% \end{instance} +% +% +% \begin{instance}{blockenv description} +% +% \begin{macrocode} + +\DeclareInstance{blockenv}{description}{display} +{ + env-name = description, + tag-name = description, + tag-class = description, + tagging-recipe = list, + inner-level-counter = , + level-increase = true, + setup-code = , + block-instance = list , + inner-instance = description , +} +% \end{macrocode} +% \end{instance} +% +% +% \begin{instance}{blockenv list} +% The general (legacy) \env{list} environment does some of its +% setup in the \texttt{setup-code} key. +% \begin{macrocode} +\DeclareInstance{blockenv}{list}{display} +{ + env-name = list, + tag-name = list, + tag-class = , + tagging-recipe = list, + level-increase = true, + setup-code = \legacylistsetupcode , + block-instance = list , + inner-level-counter = , + inner-instance = legacy , +} +% \end{macrocode} +% \end{instance} +% +% +% +% +% \subsection{Block instances} +% +% \subsubsection{Displayblock instances} +% +% We provide 6 nesting levels (as in \LaTeXe{}). If you want to +% provide more you need to change the \texttt{maxblocklevels} +% counter, offer further \texttt{displayblock-xx} instances but +% also define further (legacy) \cs{list\meta{romannumeral}} commands +% for the defaults. If not, then the settings from the previous +% level are reused automatically---which may or may not be good enough). +% \begin{macrocode} +\setcounter{maxblocklevels}{6} +% \end{macrocode} +% +% \begin{instance}{block displayblock-0, +% block displayblock-1, +% block displayblock-2, +% block displayblock-3, +% block displayblock-4, +% block displayblock-5, +% block displayblock-6 } +% +% Here we need level zero as well in case a flattened displayblock +% (like the center env) it is used on top-level. +% \begin{macrocode} +\DeclareInstance{block}{displayblock-0}{display} + { + leftmargin = 0pt , + parindent = 0pt , + } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareInstanceCopy{block}{displayblock-1}{displayblock-0} +\DeclareInstanceCopy{block}{displayblock-2}{displayblock-0} +\DeclareInstanceCopy{block}{displayblock-3}{displayblock-0} +\DeclareInstanceCopy{block}{displayblock-4}{displayblock-0} +\DeclareInstanceCopy{block}{displayblock-5}{displayblock-0} +\DeclareInstanceCopy{block}{displayblock-6}{displayblock-0} +% \end{macrocode} +% \end{instance} +% +% +% +% \subsubsection{Verbatim instances} +% +% Verbatim instances have there own levels so that one can specify +% specific indentations or vertical separations between line. +% +% \begin{instance}{block verbatimblock-0, +% block verbatimblock-1, +% block verbatimblock-2, +% block verbatimblock-3, +% block verbatimblock-4, +% block verbatimblock-5, +% block verbatimblock-6 } +% +% \begin{macrocode} +\DeclareInstance{block}{verbatimblock-0}{display} + { + leftmargin = 0pt , + parindent = 0pt , + par-skip = 0pt , + } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareInstanceCopy{block}{verbatimblock-1}{verbatimblock-0} +\DeclareInstanceCopy{block}{verbatimblock-2}{verbatimblock-0} +\DeclareInstanceCopy{block}{verbatimblock-3}{verbatimblock-0} +\DeclareInstanceCopy{block}{verbatimblock-4}{verbatimblock-0} +\DeclareInstanceCopy{block}{verbatimblock-5}{verbatimblock-0} +\DeclareInstanceCopy{block}{verbatimblock-6}{verbatimblock-0} +% \end{macrocode} +% \end{instance} +% +% +% +% +% \subsubsection{Quote/quotationblock instances} +% +% Quote and quotation are not flattened, i.e., they change levels, +% thus they start with level 1 not 0. +% +% \begin{instance}{block quoteblock-1, +% block quoteblock-2, +% block quoteblock-3, +% block quoteblock-4, +% block quoteblock-5, +% block quoteblock-6 } +% Default layout is to indent equaly from both side. +% \begin{macrocode} +\DeclareInstance{block}{quoteblock-1}{display} + { rightmargin = \KeyValue{leftmargin} } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareInstanceCopy{block}{quoteblock-2}{quoteblock-1} +\DeclareInstanceCopy{block}{quoteblock-3}{quoteblock-1} +\DeclareInstanceCopy{block}{quoteblock-4}{quoteblock-1} +\DeclareInstanceCopy{block}{quoteblock-5}{quoteblock-1} +\DeclareInstanceCopy{block}{quoteblock-6}{quoteblock-1} +% \end{macrocode} +% \end{instance} +% +% +% +% \begin{instance}{block quotationblock-1, +% block quotationblock-2, +% block quotationblock-3, +% block quotationblock-4, +% block quotationblock-5, +% block quotationblock-6 } +% Quotation additionally changes the parindent. +% \begin{macrocode} +\DeclareInstance{block}{quotationblock-1}{display} + { parindent = 1.5em , rightmargin = \KeyValue{leftmargin} } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareInstanceCopy{block}{quotationblock-2}{quotationblock-1} +\DeclareInstanceCopy{block}{quotationblock-3}{quotationblock-1} +\DeclareInstanceCopy{block}{quotationblock-4}{quotationblock-1} +\DeclareInstanceCopy{block}{quotationblock-5}{quotationblock-1} +\DeclareInstanceCopy{block}{quotationblock-6}{quotationblock-1} +% \end{macrocode} +% \end{instance} +% +% +% \subsubsection{Block instances for the standard lists} +% +% \begin{instance}{block list-1, +% block list-2, +% block list-3, +% block list-4, +% block list-5, +% block list-6 } +% The block instances for the various list environments use the +% same underlying instance (well by default) and nothing +% needs to be set up specifically (because that is already done in +% the legacy \cs{list\meta{romannumeral}} unless a +% different layout is wanted. +% \begin{macrocode} +\DeclareInstance{block}{list-1}{display}{ +% heading = , +% beginsep = \topsep , +% begin-par-skip = \partopsep , +% par-skip = \parsep , +% end-skip = \KeyValue{beginsep} , +% end-par-skip = \KeyValue{begin-par-skip} , +% beginpenalty = \UseName{@beginparpenalty} , +% endpenalty = \UseName{@endparpenalty} , +% leftmargin = \leftmargin , +% rightmargin = \rightmargin , +% parindent = \listparindent , +} +\DeclareInstance{block}{list-2}{display}{} +\DeclareInstance{block}{list-3}{display}{} +\DeclareInstance{block}{list-4}{display}{} +\DeclareInstance{block}{list-5}{display}{} +\DeclareInstance{block}{list-6}{display}{} +% \end{macrocode} +% \end{instance} +% +% +% +% \subsection{List instances for the standard lists} +% +% For all list instances we have to say what kind of label we want +% (\texttt{label-instance}) and how it should be formatted. +% +% \begin{instance}{list itemize-1, +% list itemize-2, +% list itemize-3, +% list itemize-4} +% For \env{itemize} environments this is all we need to do and we +% refer back to the external definitions rather than defining the +% \texttt{item-label} code in the instance to ensure that old +% documents still work. +% +% \begin{macrocode} +\DeclareInstance{list}{itemize-1}{std}{ item-label = \labelitemi } +\DeclareInstance{list}{itemize-2}{std}{ item-label = \labelitemii } +\DeclareInstance{list}{itemize-3}{std}{ item-label = \labelitemiii } +\DeclareInstance{list}{itemize-4}{std}{ item-label = \labelitemiv } +% \end{macrocode} +% \end{instance} +% +% +% +% \begin{instance}{list enumerate-1, +% list enumerate-2, +% list enumerate-3, +% list enumerate-4} +% \env{enumerate} environments are similar, except that we also +% have to say which counter to use on every level. +% \begin{macrocode} +\DeclareInstance{list}{enum-1}{std} + { item-label = \labelenumi , counter = enumi } +\DeclareInstance{list}{enum-2}{std} + { item-label = \labelenumii , counter = enumii } +\DeclareInstance{list}{enum-3}{std} + { item-label = \labelenumiii , counter = enumiii } +\DeclareInstance{list}{enum-4}{std} + { item-label = \labelenumiv , counter = enumiv } +% \end{macrocode} +% \end{instance} +% +% +% +% \begin{instance}{list legacy} +% For the legacy \env{list} environment there is only one instance +% which is reused on all levels. This is done this way one because +% the legacy \env{list} environment sets all its +% parameters through its arguments. So this instances shouldn't +% really be touched. It sets the \texttt{legacy-support} key to +% true, which means that the list code uses \cs{makelabel} for +% formatting the label +% \begin{macrocode} +\DeclareInstance{list}{legacy}{std} { + item-instance = basic , + legacy-support = true , +} +% \end{macrocode} +% \end{instance} +% +% +% \begin{instance}{list description} +% The \env{description} lists also use only a single list instance +% with only one key not using the default: +% \begin{macrocode} +\DeclareInstance{list}{description}{std} { item-instance = description } +% \end{macrocode} +% \end{instance} +% +% +% \subsection{Item instances} +% +% +% \begin{instance}{item basic, item description} +% There two item instances set up: \texttt{description} for use +% with the \env{description} environment and \texttt{basic} for use +% with all other lists (up to now). +% \begin{macrocode} +\DeclareInstance{item}{basic}{std} + { + label-align = right , + } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareInstance{item}{description}{std} + { + label-format = \normalfont\bfseries #1 , + } +% \end{macrocode} +% \end{instance} +% +% +% +% \subsection{Para instances} +% +% \begin{macrocode} +\tag_if_active:T +{ + \tagpdfsetup + { + newattribute = {justify} {/O /Layout /TextAlign/Justify}, + newattribute = {center} {/O /Layout /TextAlign/Center}, + newattribute = {raggedright}{/O /Layout /TextAlign/Start}, + newattribute = {raggedleft} {/O /Layout /TextAlign/End}, + } +} +% \end{macrocode} +% +% \begin{instance}{para center} +% \begin{macrocode} +\DeclareInstance{para}{center}{std} +{ + indent-width = 0pt , + start-skip = 0pt , + left-skip = \@flushglue , + right-skip = \@flushglue , + end-skip = \z@skip , + final-hyphen-demerits = 0 , + cr-cmd = \@centercr , + para-class = center , +} +% \end{macrocode} +% +% \begin{macrocode} +\DeclareInstance{para}{raggedright}{std} +{ + indent-width = 0pt , + start-skip = 0pt , + left-skip = \z@skip , + right-skip = \@flushglue , + end-skip = \z@skip , + final-hyphen-demerits = 0 , + cr-cmd = \@centercr , + para-class = raggedright , +} +% \end{macrocode} +% +% \begin{macrocode} +\DeclareInstance{para}{raggedleft}{std} +{ + indent-width = 0pt , + start-skip = 0pt , + left-skip = \@flushglue , + right-skip = \z@skip , + end-skip = \z@skip , + final-hyphen-demerits = 0 , + cr-cmd = \@centercr , + para-class = raggedleft , +} +% \end{macrocode} +% +% \begin{macrocode} +\DeclareInstance{para}{justify}{std} +{ +% indent-width = 0pt , + start-skip = 0pt , + left-skip = \z@skip , + right-skip = \z@skip , + end-skip = \@flushglue , + final-hyphen-demerits = 5000 , + cr-cmd = \@normalcr , + para-class = justify , +} +% \end{macrocode} +% \end{instance} +% +% +% +% +% \begin{macrocode} +\DeclareRobustCommand\centering {\UseInstance{para}{center}{}} +\DeclareRobustCommand\raggedleft {\UseInstance{para}{raggedleft}{}} +\DeclareRobustCommand\raggedright{\UseInstance{para}{raggedright}{}} +\DeclareRobustCommand\justifying {\UseInstance{para}{justify}{}} + +\justifying +% \end{macrocode} +% +% +% +% +% +% \subsection{Tagging support} +% +% In this section we provide code to the various kernel hooks to support +% the tagging of the different displayblock environments. +% +% +% +% All of the following definitions should only be made if tagging +% is active! +% \begin{macrocode} +\tag_if_active:TF { +% \end{macrocode} +% +% \begin{macro}{\@@_beginpar_vmode:} +% When a block starts out in vertical mode, i.e., is not yet part of +% a paragraph, we have to start a paragraph +% structure. However, this is not the case if we are already +% flattening paragraphs, thus in this case we do nothing. +% We also do nothing if \texttt{@endpe} is currently true, because +% that means we are right now just after the end of a +% \texttt{blockenv} and in the process of looking if we have to end +% the current \texttt{text-unit}, i.e., it is already open. +% \begin{macrocode} + \cs_set:Npn \@@_beginpar_vmode: { + \@@_debug_typeout:n + { @endpe = \legacy_if:nTF { @endpe }{true}{false} + \on@line } + \legacy_if:nTF { @endpe } + { + \legacy_if_gset_false:n { @endpe } + } +% \end{macrocode} +% We test for \texttt{<2} because the first flattened environment +% has to surround itself with a \texttt{text-unit}. Only any inner ones +% then have to avoid adding another \texttt{text-unit}. +% \begin{macrocode} + { + \int_compare:nNnT \l_@@_flattened_level_int < 2 + { + \int_gincr:N \g__tag_para_main_begin_int + \tagstructbegin{tag=\l__tag_para_main_tag_tl} + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_beginpar_hmode:N} +% If the block is already part of a part of a paragraph, i.e., when it has +% some text directly in front, then the first thing to +% do is to return to vertical mode. However, that should be done +% without inserting a paragraph end tag, so before calling \cs{par} +% to do its normal work, we disable paragraph tagging and +% restarting afterwards again. The argument to this config point +% simply gobbles the \cs{par} following it in the code above (which +% is used when there is no tagging going on. +% \begin{macrocode} + \cs_set:Npn \@@_beginpar_hmode:N #1 + { + \tag_mc_end: + \int_gincr:N \g__tag_para_end_int + \@@_debug_typeout:n{increment~ /P \on@line } + \bool_if:NT \l__tag_para_show_bool + { \tag_mc_begin:n{artifact} + \rlap{\color_select:n{red}\tiny\ \int_use:N\g__tag_para_end_int} + \tag_mc_end: + } + \tag_struct_end: + \tagpdfparaOff \par \tagpdfparaOn + } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\__kernel_displayblock_doendpe:} +% If a display block ends and is followed by a blank line we have to end the +% enclosing paragraph tagging structure. +% \begin{macrocode} +\cs_set:Npn \__kernel_displayblock_doendpe: { + \bool_if:NT \l__tag_para_bool + { +% \end{macrocode} +% Given that restoring \cs{par} through the legacy \LaTeXe{} method +% can take a few iterations (for example, in case of nested lists, +% e.g., \verb=...\end{itemize} \item ...\par= it can happen that +% \cs{__kernel_displayblock_doendpe:} is called while +% \texttt{@endpe} is already handled and then we should not attempt +% to close a \texttt{text-unit} structure). So we need to check for this. +% \begin{macrocode} + \legacy_if:nT { @endpe } + { +% \end{macrocode} +% If the display block currently ending was \enquote{flattened} +% (i.e., uses simplified paragraphs that are not tagged by a +% combination of \texttt{text-unit} followed by \struct{text}, but simply +% with a \struct{text}), +% then we don't have to do anything, because the \struct{text} is already closed. +% \begin{macrocode} + \@@_debug_typeout:n + { flattened= \bool_if:NTF + \l__tag_para_flattened_bool {true}{false} + \on@line } + \bool_if:NF \l__tag_para_flattened_bool + { + \@@_debug_typeout:n{Structure-end~ + \l__tag_para_main_tag_tl\space after~ displayblock \on@line } + \int_gincr:N \g__tag_para_main_end_int + \tag_struct_end: %text-unit + } + } + } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{para/begin} +% +% Paragraph tagging is mainly done using the paragraph hooks (will +% get moved eventually). The default hook setting is not good +% enough when lists get supported: we need to delay starting the +% paragraph tagging if we still have to place the list label. +% We therefore remove the existing hook data and replace it with an +% augmented version (this will get combined eventually). +% \begin{macrocode} +\RemoveFromHook{para/begin}[tagpdf] +% \end{macrocode} +% +% \begin{macrocode} +\AddToHook{para/begin}[tagpdf]{ + \bool_if:NT \l__tag_para_bool { +% \end{macrocode} +% if we are still waiting to typeset the list label we do nothing +% (the paragraph tagging then happens when the list is finally +% typeset). +% \begin{macrocode} + \legacy_if:nF { @inlabel } + { +% \end{macrocode} +% Otherwise, we start a \struct{text} tag structure but only if we are not +% starting a paragraph immediately \emph{after} a list, in which +% case we only start a new MC (because the \struct{text} tag is still open from +% before the list --- one of the reasons why lists are always put +% \enquote{inside} paragraphs. +% +% We do this in a separate command, because it is needed elsewhere too. +% \begin{macrocode} + \@@_start_para_structure:n { \PARALABEL } + } + } +} +% \end{macrocode} +% +% +% \begin{macro}{\@@_start_para_structure:n} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_start_para_structure:n #1 { + \@@_debug_typeout:n + { @endpe = \legacy_if:nTF { @endpe }{true}{false} + \on@line } + \legacy_if:nF { @endpe } + { + \bool_if:NF \l__tag_para_flattened_bool + { + \int_gincr:N \g__tag_para_main_begin_int + \tag_struct_begin:n{tag=\l__tag_para_main_tag_tl} + } + } + \int_gincr:N \g__tag_para_begin_int + \@@_debug_typeout:n{increment~ P \on@line } + \tag_struct_begin:n + { + tag=\l__tag_para_tag_tl + ,attribute-class=\l_tag_para_attr_class_tl + } + \__tag_check_para_begin_show:nn {green}{#1} + \tag_mc_begin:n {} +} +% \end{macrocode} +% The same code, but without testing \texttt{@endpe}. This is not +% needed in the standalone case and wrong inside lists. +% \begin{macrocode} +\cs_new_protected:Npn \@@_start_para_structure_unconditionally:n #1 { + \bool_if:NF \l__tag_para_flattened_bool + { + \int_gincr:N \g__tag_para_main_begin_int + \tag_struct_begin:n{tag=\l__tag_para_main_tag_tl} + } + \int_gincr:N \g__tag_para_begin_int + \@@_debug_typeout:n{increment~ P \on@line } + \tag_struct_begin:n + { + tag=\l__tag_para_tag_tl + ,attribute-class=\l_tag_para_attr_class_tl + } + \__tag_check_para_begin_show:nn {green}{#1} + \tag_mc_begin:n {} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\RemoveFromHook{para/end}[tagpdf] +\AddToHook{para/end} + { + \bool_if:NT \l__tag_para_bool + { + \int_gincr:N \g__tag_para_end_int + \@@_debug_typeout:n{increment~ /P \on@line } + \tag_mc_end: + \__tag_check_para_end_show:nn {red}{} + \tag_struct_end: + \bool_if:NF \l__tag_para_flattened_bool + { + \int_gincr:N \g__tag_para_main_end_int + \tag_struct_end: + } + } + } +% \end{macrocode} +% +% \begin{macrocode} +\def\PARALABEL{NP-} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\para_end:} +% If we see a \cs{par} in vmode and a \texttt{text-unit} is still open +% we need to close that. For this we check if a request for +% \text{@endpe} was made (but the \cs{par} redefinition got lost +% due to (bad?) coding). +% \begin{macrocode} +\cs_set_protected:Npn \para_end: { + \scan_stop: + \mode_if_horizontal:TF { + \mode_if_inner:F { + \tex_unskip:D + \hook_use:n{para/end} + \@kernel@after@para@end + \mode_if_horizontal:TF { + \if_int_compare:w 11 = \tex_lastnodetype:D + \tex_hskip:D \c_zero_dim + \fi: + \tex_par:D + \hook_use:n{para/after} + \@kernel@after@para@after + } + { \msg_error:nnnn { hooks }{ para-mode }{end}{horizontal} } + } + } + { + \__kernel_endpe_vmode: % should do nothing if no tagging + \tex_par:D + } +} +\cs_set_eq:NN \par \para_end: +\cs_set_eq:NN \@@par \para_end: +\cs_set_eq:NN \endgraf \para_end: +% \end{macrocode} +% +% \end{macro} +% +% +% \begin{macro}{\begin} +% We need to do a little more than canceling \texttt{@endpe} now. +% \begin{macrocode} +\DeclareRobustCommand*\begin[1]{% + \UseHook{env/#1/before}% + \@ifundefined{#1}% + {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% + {\def\reserved@a{\def\@currenvir{#1}% + \edef\@currenvline{\on@line}% + \@execute@begin@hook{#1}% + \csname #1\endcsname}}% + \@ignorefalse + \begingroup + \__kernel_endpe_vmode: + \reserved@a} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\__kernel_endpe_vmode:} +% Close an open \texttt{text-unit} if \texttt{@endpe} is true and we +% are in vmode. Used in \cs{para_end:} and \cs{begin}. +% \begin{macrocode} +\cs_new:Npn \__kernel_endpe_vmode: { + \if@endpe \ifvmode + \bool_if:NT \l__tag_para_bool + { + \bool_if:NF \l__tag_para_flattened_bool + { + \int_gincr:N \g__tag_para_main_end_int + \tag_struct_end: + } + \@endpefalse + } + \fi \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\__kernel_list_label_after:} +% If starting the text-unit/text tags got delayed because of a pending label we +% have to do it after the label got typeset +% \begin{macrocode} +\cs_set:Npn \__kernel_list_label_after: { + \bool_if:NT \l__tag_para_bool + { + \@@_start_para_structure_unconditionally:n { LI- } + } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@_inner_begin:} +% Start a block that has an inner structure if it isn't also a list. +% \begin{macrocode} +\cs_new:Npn \@@_inner_begin: { + \tagstructbegin{tag=\l_@@_tag_inner_tag_tl} +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@_inner_end:} +% End a block (which isn't also a list). +% \begin{macrocode} +\cs_new:Npn \@@_inner_end: { + \@@_debug_typeout:n{block-end \on@line} + \legacy_if:nT { @endpe } + { + \int_gincr:N \g__tag_para_main_end_int + \@@_debug_typeout:n{close~ /text-unit \on@line} + \tagstructend + } + \tagstructend % end inner structure +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \subsubsection{List tags} +% +% +% \begin{macrocode} +\tl_new:N \l__tag_L_tag_tl +\tl_set:Nn \l__tag_L_tag_tl {L} + +\tl_new:N\l__tag_L_attr_class_tl +\tl_set:Nn \l__tag_L_attr_class_tl {list} +% \end{macrocode} +% +% \begin{macrocode} +\tag_if_active:T +{ + \tagpdfsetup + { + % default if unknown + newattribute = {list}{/O /List /ListNumbering/None}, + newattribute = {itemize}{/O /List /ListNumbering/Unordered}, + newattribute = {enumerate}{/O /List /ListNumbering/Ordered}, + newattribute = {description}{/O /List /ListNumbering/Description}, + } +} +% \end{macrocode} +% +% \begin{macrocode} +\def\LItag{LI} +% \end{macrocode} +% +% \begin{macro}{\@@_list_begin:} +% Start a list \ldots +% \begin{macrocode} +\cs_set:Npn \@@_list_begin: { + \tagstructbegin + { + tag=\l__tag_L_tag_tl + ,attribute-class=\l__tag_L_attr_class_tl + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_list_item_begin:} +% Start tagging a list item. +% \begin{macrocode} +\cs_set:Npn \@@_list_item_begin: { \tagstructbegin{tag=\LItag} } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\__kernel_list_label_begin:} +% A list label needs a \texttt{Lbl} structure tag and an MC. +% \begin{macrocode} +\cs_set:Npn \__kernel_list_label_begin: { +% +% FMi: this needs a different logic to decide when to make the label +% an artifact (after cleaning up the the \item code ), therefore +% disabled for now +% \tl_if_empty:oTF \@itemlabel +% { +% \tag_mc_begin:n {artifact} +% } +% { + \tagstructbegin{tag=Lbl} + \tagmcbegin{tag=Lbl} +% } +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\__kernel_list_label_end:} +% And when we are done with the label we have to close the MC and +% the \texttt{Lbl} structure. We then start the \texttt{LBody}. The +% material inside will be \enquote{paragraph} text and the tagging +% for that is handled by the normal para tagging. +% \begin{macrocode} +\cs_set:Npn \__kernel_list_label_end: { + \tagmcend % end mc-Lbl or artifact +% FMi: unconditionally for now +% \tl_if_empty:oF \@itemlabel + \tagstructend % end Lbl + \tagstructbegin{tag=\LBody} +} +\def\LBody{LBody} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_list_item_end:} +% When a list item ends we have to close \texttt{LBody} and +% \texttt{LI} but also a \struct{text} in the special case that the +% item material ends in a list (identifiable via \texttt{@endpe}). +% \begin{macrocode} +\cs_set:Npn \@@_list_item_end: { + \legacy_if:nT { @endpe } + { + \int_gincr:N \g__tag_para_main_end_int + \tagstructend % text-unit +% \@@_debug_typeout:n{Structure-end~ P~ at~ item-end \on@line } + } + \tagstructend \tagstructend % end LBody, LI +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_list_end:} +% Finally, at the list end we have to close the open +% \texttt{LBody}, \texttt{LI}, \texttt{L}, and possibly a +% \struct{text} if the last item ends with a list. +% \begin{macrocode} +\cs_set:Npn \@@_list_end: { + \legacy_if:nT { @endpe } + { + \int_gincr:N \g__tag_para_main_end_int + \tagstructend % text-unit + \@@_debug_typeout:n{Structure-end~ P~ at~ list-end \on@line } + } + \tagstructend\tagstructend % end LBody, LI + \tagstructend % end L +} +% \end{macrocode} +% \end{macro} +% End of tagging related declarations. +% \begin{macrocode} +} +% \end{macrocode} +% These command should have a dummy declaration if tagging is not active +% \begin{macrocode} +{ + \cs_new:Npn \@@_start_para_structure_unconditionally:n #1 {} +} +% \end{macrocode} +% +% +% +% +% +% +% +% +% +% \begin{macrocode} +% +% \end{macrocode} +% +% +% +% \begin{macrocode} +%<*latex-lab> +\ProvidesFile{block-latex-lab-testphase.ltx} + [\ltlabblockdate\space v\ltlabblockversion\space + blockenv implementation] +\RequirePackage{latex-lab-testphase-block} +% +% \end{macrocode} +% +% \end{implementation} +% +% +% \section{Documentation from first prototype implementations} +% +% +% \subsection{Open questions} +% \begin{itemize} +% \item Existing questions --- moved to issues --- +% \end{itemize} +% +% \subsection{Code cleanup} +% \begin{itemize} +% \item Actually implement what's announced. +% +% \item Encapsulate most uses of \cs[no-index]{legacy_if\dots} into +% commands with \texttt{expl3} syntax: we cannot rename these booleans +% for compatibility reasons but we can make the code cleaner +% nevertheless. --- made issue --- +% +% \item The \tn{topsep} and \tn{partopsep} business is tricky to +% reproduce exactly (see \tn{@topsepadd} and \tn{@topsep}) because of +% how it accumulates when lists are nested immediately. +% +% \end{itemize} +% +% +% +% \subsection{Tasks} +% \begin{itemize} +% +% \item Change author to LaTeX Team once it's nice enough to deserve +% that label. +% +% \item Reproducing exactly the standard layouts and examples in the +% \pkg{enumitem} documentation. +% +% \item Hooks, but do not duplicate those that already exist as +% environment hooks. Hence, mostly around items. +% +% \item Customization and interaction with LDB: +% \begin{itemize} +% \item Allow arbitrary nesting depth with automatically defined +% styles for labels, counters etc. +% \item Adapt everything to font size! (e.g. footnotes). +% \item How to model the inheritance from trivlist to list to +% enumerate? +% \end{itemize} +% +% \item Add key--value settings mimicking \pkg{enumitem}'s ability to +% set any four of five horizontal parameters and deduce the fifth by +% $\cs{leftmargin} + \cs{itemindent} = \cs{labelindent} + +% \cs{labelwidth} + \cs{labelsep}$. +% +% \item Provide good ways to customize how overlong labels are dealt with. +% +% \item Use the \texttt{.aux} file. +% \begin{itemize} +% \item Implement the \tn{ref} styles that \pkg{enumitem} provides. +% \item Reverse enumerations, important in publication lists and the +% like. Somehow avoid needing 3 compilations for references to +% reverse enumerations to settle? +% \item Ability to calculate \tn{labelwidth} from the label contents. +% Share calculated parameters between multiple environments (cf.\ +% \texttt{resume} option). +% \end{itemize} +% +% \item Related to grabbing the whole list environment, and input syntax +% variations: +% \begin{itemize} +% \item Other layouts: tabular (see \pkg{listliketab} vs +% \pkg{typed-checklist}), multicolumn and horizontally numbered (see +% \pkg{tasks}), inline lists, runin lists in the easy case where +% there is no intervening \tn{par}. +% \item Formatting the item text in a +% box or similar (requires grabbing the whole list). +% \item Filtering which items to show: hide certain items according to +% criteria (useful together with list reuse), see +% \pkg{typed-checklist}. +% \item Shorthands \tn{iitem} for automatic nested lists, or \cs{1}, +% \cs{2} etc from \pkg{outlines}. +% \item Support markdown input like \pkg{asciilist}. +% \end{itemize} +% +% \item Check interaction with \texttt{babel} options such as +% \texttt{french} or \texttt{accadian} (see FrenchItemizeSpacing) +% +% \item RTL and vertical typesetting. +% \end{itemize} +% +% \section{Plan of attack of first prototype} +% +% Typesetting list environments involves a rather large number of +% parameters. They can be affected by the context such as the total +% list nesting level, the nesting level of the given type of list, and +% the font size. An environment like \texttt{enumerate} has two main +% aspects. +% \begin{itemize} +% \item It has a certain layout in the page, with vertical and +% horizontal spacing around it. This type of layout is shared with +% environments such as \texttt{quote}, \texttt{flushright}, or +% \texttt{tabbing}. This common layout is implemented in \LaTeXe{} +% through \cs{trivlist} (or \cs{list}). +% \item It defines how each \cs{item} should be typeset: how to +% construct the label, in particular the \texttt{counter} name, and +% how to format the content of the item. +% \end{itemize} +% +% This suggests defining two object types, \xt{block} and \xt{item} +% covering these two aspects.\footnote{Possibly also \xt{endblock} to +% deal with decorations at the end?} While the \xt{item} type will +% perhaps have a single template, one could typeset a \xt{block} object +% in several ways, for instance the standard \LaTeXe{} way or a fancy +% colored box. +% +% The \xt{general} \xt{block} template should receive the following +% parameters. The \xt{plain} \xt{block} template is a restricted +% template that freezes all item-related parameters to dummy values +% (\texttt{counter}, \texttt{start}, \texttt{resume}, +% \texttt{label-width}, \texttt{label-sep} and all \texttt{item-*}). +% The \xt{list} \xt{block} template is a restricted template\footnote{A +% better approach could be to have a notion of inheritance for object +% types, so that we end up with two different \emph{object types}. Then +% we can implement other template for the list object type: \xt{table} +% for lists typeset as rows/columns of a table, \xt{inline} for lists +% typeset in horizontal mode within a paragraph, and \xt{runin} for +% run-in lists.} that omits the \texttt{heading} parameter and whose +% default for \texttt{item-instance} is non-empty. +% \begin{itemize} +% \item Structural parameters: the \texttt{heading} to place before, +% \texttt{counter} name, \texttt{start} value, whether to +% \texttt{resume} a previous list, and the \texttt{item-instance} (an +% \xt{item} instance) to use when typesetting items. +% \item Vertical spacing and penalties: \texttt{beginpenalty}, +% \texttt{beginsep}, \texttt{begin-par-skip}, \texttt{item-penalty}, +% \texttt{item-skip}, \texttt{item-par-skip}, \texttt{endpenalty}, +% \texttt{end-skip}, \texttt{end-par-skip}. +% \item Horizontal spacing: \texttt{rightmargin}, \texttt{leftmargin}, +% \texttt{parindent}, \texttt{item-indent}, \texttt{label-width}, +% \texttt{label-sep}. +% \end{itemize} +% A \docclass should edit these templates (or define restricted +% templates) to set up default values that depend on \tn{g_block_nesting_depth_int}, +% namely how many lists are nested overall.\footnote{Does +% \pkg{xtemplate} provide a way to specify default values that are only +% evaluated once an instance is used?} The document class should then +% set up an instance of these templates for each environment, with +% appropriate settings such as a \texttt{heading}, a suitable +% \texttt{item-instance}, or making \texttt{margin-right} equal to +% \texttt{margin-left} in a \texttt{quote} environment. +% +% The \xt{inline-list} \xt{block} template receives many fewer +% parameters. Note that \texttt{beginsep}, \texttt{item-skip}, +% \texttt{end-skip} are now \emph{horizontal} skips. +% \begin{itemize} +% \item Structural parameters: \texttt{counter}, \texttt{start}, +% \texttt{resume}, \texttt{item-instance}. +% \item Spacing and penalties: \texttt{beginpenalty}, +% \texttt{beginsep}, \texttt{item-penalty}, \texttt{item-skip}, +% \texttt{endpenalty}, \texttt{end-skip}. +% \item Horizontal spacing: \texttt{label-width}, \texttt{label-sep}. +% \end{itemize} +% +% The \xt{std} \xt{item} template should receive the following +% parameters. They depend on the type of list and its nesting level +% among lists of such type, but typically not on the total nesting +% level. +% \begin{itemize} +% \item Counter name (\texttt{counter}), shared with the parent +% \xt{list} \xt{block} template, but needed for incrementing. +% \item Label construction: a function \texttt{counter-label} that +% produces the label from the counter name, used if \tn{item} is given +% without argument. +% \item References: a function \texttt{counter-ref} for how the label +% should be referred to when it is constructed from the counter, +% \texttt{label-ref} and \texttt{label-autoref} used when \tn{item} +% has an optional argument. +% \item Label formatting: \texttt{label-format} function, +% \texttt{label-strut} boolean. +% \item Label alignment (\texttt{label-align}, \texttt{label-boxed}, +% \texttt{next-line}). +% \item Content parameters: \texttt{text-font}. +% \item A \texttt{compatibility} boolean that controls for instance +% whether \tn{makelabel} is used. +% \end{itemize} +% The \docclass should set up an instance such as \xt{enumiii} for each +% environment and nesting level.\footnote{This should be made easily +% extendible to deeper levels.} +% +% A given environment will adjust some nesting levels, then call the +% \xt{block} instance appropriate to the environment type, passing it +% the \xt{item} instance appropriate to the environment and depth. +% Additional context-dependence could be provided by \pkg{l3ldb}, but +% the main context-dependence should not rely on it for simplicity +% reasons and incidentally because \pkg{l3ldb} is not yet available. +% +% +% \Finale +% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endinput diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-firstaid.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-firstaid.dtx index 8f474e6b121..e2ee78b2fff 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-firstaid.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-firstaid.dtx @@ -16,6 +16,8 @@ % % for those people who are interested or want to report an issue. % +\def\ltlabfirstaiddate{2023-07-20} +\def\ltlabfirstaidversion{0.85a} %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -28,9 +30,9 @@ % \fi % % \title{The \textsf{latex-lab-firstaid} package\\ -% Temporary patches to external packages} +% Temporary patches to external packages needed for the tagging project} % \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} -% \date{Version 0.80 2023-06-04} +% \date{v\ltlabfirstaidversion\ \ltlabfirstaiddate} % % \maketitle % @@ -58,8 +60,9 @@ %<@@=tag> % \end{macrocode} % \begin{macrocode} -\ProvidesPackage {latex-lab-testphase-firstaid} [2023-06-04 v0.8 - Temporary patches to external packages need for the tagging project] +\ProvidesPackage {latex-lab-testphase-firstaid} [% + \ltlabfirstaiddate\space v\ltlabfirstaiddate\space + Temporary patches to external packages needed for the tagging project] % \end{macrocode} % \subsection{blindtext} @@ -103,43 +106,38 @@ }% } % \end{macrocode} -% \subsection{ltugboat} -% ltugboat need only a redefinition of \cs{l@section} to add the hooks +% \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 % \begin{macrocode} -\AddToHook{file/ltugboat.cls/after} +\AddToHook{package/cleveref/after} { - \def\l@section#1#2{\addpenalty{\@secpenalty}% - \addvspace{\TBtocsectionspace}% - \@tempdima 1.5em - \begingroup - \parindent\z@ \rightskip\z@ % article style makes \rightskip > 0 - \parfillskip\z@ - \TBtocsectionfont - \leavevmode\advance\leftskip\@tempdima\hskip-\leftskip - \UseHookWithArguments{contentsline/text/before}{4} - {\toclevel@part}{#1}{#2}{\@contentsline@destination}% - \csname contentsline@text@1@format\endcsname{#1}% - \UseHookWithArguments{contentsline/text/after}{4} - {\toclevel@part}{#1}{#2}{\@contentsline@destination}% - \nobreak\hfil - \nobreak\hb@xt@\@pnumwidth{\hss - \UseHookWithArguments{contentsline/page/before}{4} - {\toclevel@part}{#1}{#2}{\@contentsline@destination}% - #2% - \UseHookWithArguments{contentsline/page/after}{4} - {\toclevel@part}{#1}{#2}{\@contentsline@destination}% - }\par - \endgroup} - } + \let\@makefntext\cref@old@makefntext + \AddToHook{cmd/@makefntext/before}{% + \cref@constructprefix{footnote}{\cref@result}% + \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} - % \begin{macrocode} % % \end{macrocode} % \begin{macrocode} %<*latex-lab> \ProvidesFile{firstaid-latex-lab-testphase.ltx} - [2023-06-04 v0.8 Temporary patches to external packages need for the tagging project] + [\ltlabfirstaiddate\space v\ltlabfirstaidversion\space + latex-lab wrapper firstaid] \RequirePackage{latex-lab-testphase-firstaid} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx index 430b2aec96c..3bd34836008 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx @@ -16,6 +16,8 @@ % % for those people who are interested or want to report an issue. % +\def\ltlabfloatdate{2023-07-20} +\def\ltlabfloatversion{0.81a} %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -31,7 +33,7 @@ % \title{The \textsf{latex-lab-floats} package\\ % Tagging of floats } % \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} -% \date{v0.81 2023-06-07} +% \date{v\ltlabfloatversion\ \ltlabfloatdate} % % \maketitle % @@ -128,17 +130,11 @@ % \begin{implementation} % \section{Implementation} % \begin{macrocode} -\ProvidesExplPackage {latex-lab-testphase-float} {2023-04-28} {0.8} +\ProvidesExplPackage {latex-lab-testphase-float} {\ltlabfloatdate} {\ltlabfloatversion} {Code related to the tagging of floats} % \end{macrocode} % \subsection{Variables} -% We rolemap to Aside, and float sections to Sect -% -% \begin{macrocode} -\tagpdfsetup{add-new-tag=float/Aside} -\tagpdfsetup{add-new-tag=figures/Sect} -\tagpdfsetup{add-new-tag=tables/Sect} -% \end{macrocode} +% We rolemap to float to Aside, and float sections to Sect. % % \begin{variable}{ % \g_@@_float_sect_prop, @@ -408,6 +404,32 @@ \fi \fi } +% \end{macrocode} +% and similar for double floats: +% \begin{macrocode} +\def\end@dblfloat{% + \if@twocolumn + \@endfloatbox + \@nameuse{@@_float_end:}% + \ifnum\@floatpenalty <\z@ + \@largefloatcheck + \global\dp\@currbox1sp % + \@cons\@currlist\@currbox + \ifnum\@floatpenalty <-\@Mii + \penalty -\@Miv + \@tempdima\prevdepth + \vbox{}% + \prevdepth\@tempdima + \penalty\@floatpenalty + \else + \vadjust{\penalty -\@Miv \vbox{}\penalty\@floatpenalty}\@Esphack + \@nameuse{@@_float_start_par:} %restart P safe here?? + \fi + \fi + \else + \end@float + \fi +}% \ExplSyntaxOn % \end{macrocode} % @@ -417,6 +439,22 @@ % \begin{macrocode} \def\hyper@nopatch@caption{} % \end{macrocode} +% +% With hyperref that means that the \cs{refstepcounter} now can affect spacing so we +% change that to the kernel refstepcounter: +% \begin{macrocode} +\let\@kernel@refstepcounter\refstepcounter %as long it is not in the kernel +\def\caption{% + \ifx\@captype\@undefined + \@latex@error{\noexpand\caption outside float}\@ehd + \expandafter\@gobble + \else + \@kernel@refstepcounter\@captype + \expandafter\@firstofone + \fi + {\@dblarg{\@caption\@captype}}% +} +% \end{macrocode} % As we will use the structure number in the target, we need to provide a % theH-representation. (Once the kernel will create % theH-representation generally this will be provided automatically, as tagpdf uses @@ -471,7 +509,7 @@ \tag_mc_end: \tag_struct_end: \tag_mc_begin:n{} - #2\par + #2 \tag_mc_end:\hfil}% \fi \tag_struct_end: %caption @@ -487,7 +525,7 @@ % \begin{macrocode} %<*latex-lab> \ProvidesFile{float-latex-lab-testphase.ltx} - [2023-04-30 v0.8 code related to the tagging of floats] + [\ltlabfloatdate\space v\ltlabfloatversion\space latex-lab wrapper float] \RequirePackage{latex-lab-testphase-float} % % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-footnotes.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-footnotes.dtx index 4c8c9b73a61..2389906c5ac 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-footnotes.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-footnotes.dtx @@ -17,6 +17,9 @@ % % for those people who are interested or want to report an issue. % +\def\ltlabfootnotedate{2023-09-04} +\def\ltlabfootnoteversion{0.8c} + %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -38,7 +41,14 @@ % \newcommand\NEW[1]{\marginpar{\mbox{}\hfill\fbox{New: #1}}} % \providecommand\class[1]{\texttt{#1.cls}} % \providecommand\pkg[1]{\texttt{#1}} -% \providecommand\hook[1]{\texttt{#1}} +% +% \providecommand\hook[1]{\texttt{#1\DescribeHook[noprint]{#1}}} +% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}} +% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}} +% +% \NewDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl} +% \NewDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl} +% \NewDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl} % % \begin{abstract} % \emph{to be written} @@ -56,7 +66,7 @@ % some adjustments are mutually exclusive). This is achieved by % providing a larger number of hooks (for areas where different % packages/classes can easily coexist with their adjustments) and a -% number of configuration points to which only one class or package +% number of sockets to which only one class or package % can write to successfully (in case of multiple changes the % last one wins). The latter are for special functionality, e.g., % if footnote text is typeset as a single paragraph, it can't be configured @@ -67,7 +77,7 @@ % for this to work, all packages altering the footnote setup should % use the interfaces provided here and not do it through the % legacy methods (though there is some support for the latter as -% well, but if will not work in a cases). +% well, but it will not work in all cases). % % \subsection{Configuration methods} % @@ -103,11 +113,14 @@ % % % -% \section{Hooks and configuration points} +% \section{Sockets and hooks} +% +% We use sockets for those parts that can be controlled only by one +% package or by the kernel and hooks for places where it may be +% possible that several packages or the document class adds code +% (typically declarations such as font changes, etc.). % -% Note: the configuration points do not have an interface mechanism -% yet and all their names are temporary right now. -% Also note that configuration points are of interest only to very +% Note that sockets are of interest only to very % few specialized packages, mainly \pkg{footmisc}, and packages % providing similar functionality---the current documentation is % therefore fairly sketchy. @@ -124,7 +137,7 @@ % in the same place, etc. % % -% \subsubsection{Configuration points} +% \subsubsection{Sockets} % % None: everything is implemented through a single definition for % \cs{@footnotemark} that offers a number of hooks that can be used @@ -132,12 +145,14 @@ % formatting of marks. % % -% \subsubsection{Hooks} +% \subsubsection{Hooks for formatting the footnote mark in text} % % The hooks to customize the marks in the text are the following: % \begin{description} % \item[\hook{fnmark/before}] % +% \DescribeHook[noprint]{fnmark/before} +% % Executed at the very beginning of \cs{footnotemark}. Currently % there are two packages (\pkg{bibarts} and \pkg{chextras}) that % prepend material at this point (not necessarily correctly, e.g., @@ -147,6 +162,8 @@ % % \item[\hook{fnmark}] % +% \DescribeHook[noprint]{fnmark} +% % Executed in horizontal mode and after the current space factor % has been saved away for reuse. This is where currently code for multiple % marks does its preparation (as done by \pkg{footmisc} and @@ -156,12 +173,14 @@ % generated in math --- maybe that means the multiple handling % should happen later? % -% After the hook \cs{nobreak} is executed, so any +% After the hook a \cs{nobreak} is executed, so any % ``material'' added in the hook is tied to the following mark % unless it contains its own permissible penalty. % % \item[\hook{fnmark/begin}] % +% \DescribeHook[noprint]{fnmark/begin} +% % This hook is executed directly in front of the typeset mark. % This is the place where \pkg{hyperref} would have added % part of its code, i.e., after the \cs{nobreak} mentioned above. @@ -170,6 +189,8 @@ % % \item[\hook{fnmark/end}] % +% \DescribeHook[noprint]{fnmark/end} +% % This hook is executed directly after the typeset mark. It is % used by \pkg{memhfixc}, \pkg{scrlttr2}, and % \pkg{footmisc}. Used, for example, to implement support for @@ -180,6 +201,8 @@ % % \item[\hook{fnmark/after}] % +% \DescribeHook[noprint]{fnmark/after} +% % This hook is executed at the very end of the \cs{footnotemark} command. % % It is a reversed hook to pair with \hook{fnmark/before} @@ -201,78 +224,114 @@ % appears at the bottom of the page (default case), or possibly % elsewhere, e.g. in the margin. % -% \subsubsection{Configuration points} +% \subsubsection{Sockets} % % To cater for different layout configurations there are four -% configuration points which can be set only by one package or -% class, if two packages/classes set them they are mutually -% incompatible. +% sockets that can be set by a package or +% class but there should be only one per document setting them, i.e., if two packages/classes set them they are mutually +% incompatible (or rather the last one wins most likely). % These are: % \begin{description} -% \item[\cs{@footnotetext@cfgpoint} (1 argument)] +% \item[\socket{fntext/process} (1 argument)] +% +% \DescribeSocket[noprint]{fntext/process} +% +% This socket receives all material that is to be processed (or +% stored) including color protection code and what have you. +% The \plug{default} executes \cs{insert}\cs{footins}. +% +% Available plugs are \plug{default}, \plug{side} (side notes), and \plug{mp} (minipage). +% +% +% \item[\socket{fntext/make} (1 argument)] % -% This receives all material that is to be processed (or stored) -% including color protection code and what have you. The default -% definition is to run \cs{insert}\cs{footins}. +% \DescribeSocket[noprint]{fntext/make} % -% \item[\cs{@footnotetext@cfgpointii} (1 argument)] +% This socket receives the \meta{text} as given in \cs{footnote} +% or \cs{footnotetext} in the document and adds formatting +% instructions to it. % -% The default definition runs \cs{@makefntext} which contains +% The \plug{default} plug runs \cs{@makefntext} which contains % various hooks for customization. For most scenarios this is % sufficient. However, when running all footnotes as a single % paragraph at the bottom, then each footnote needs to be -% prepared prior to storing in the insert and this configuration -% point allows running extra code to do that. +% prepared prior to storing it with \cs{insert} and this socket +% allows running extra code to do that. % -% \item[\cs{@footnotetext@cfgpointiii} (no argument)] +% Available plugs are \plug{default} and \plug{para}. % -% By default this configuration point adds a strut to the -% footnote material so that consecutive footnotes are properly -% spaced vertically. In some use cases this is not appropriate -% (e.g., when running all footnotes as a single paragraph) and so -% this configuration point can cancel the action or do something -% else instead. +% \item[\socket{fntext/begin} (no argument)] % -% The configuration point is executed near the start of the -% argument for the configuration point -% \cs{@footnotetext@cfgpointii}. +% \DescribeSocket[noprint]{fntext/begin} % -% \item[\cs{@footnotetext@cfgpointiv} (no argument)] +% The socket is executed near the start of the +% argument for the \socket{fntext/make} socket. +% By \plug{default} it adds a strut to the footnote +% material so that consecutive footnotes are properly spaced +% vertically. In some use cases this is not appropriate (e.g., +% when running all footnotes as a single paragraph) and so with +% this socket one can cancel the action or do something else +% instead. % -% This configuration point is executed at the very end of the -% argument passed to \cs{@footnotetext@cfgpointii}. -% By default it adds a final strut as long as we are still in -% horizontal mode (i.e., processing the footnote text paragraph. -% When running several footnotes in one paragraph some additional -% material (some horizontal glue) needs adding at this point. +% Available plugs are \plug{default} and \plug{noop}. % +% +% \item[\socket{fntext/end} (no argument)] +% +% \DescribeSocket[noprint]{fntext/end} +% +% This socket is executed at the very end of the argument passed +% to socket \socket{fntext/make}. By \plug{default} it +% adds a final strut as long as we are still in horizontal mode +% (i.e., processing the footnote text paragraph). When running +% several footnotes in one paragraph some additional material +% (some horizontal glue) needs adding at this point which is done +% with the plug \plug{para}. +% +% Available plugs are \plug{default}, \plug{para}, and +% \plug{noop}. % \end{description} -% The configuration point \cs{@footnotetext@cfgpointii} runs +% +% +% All standard plugs for the socket \socket{fntext/make} run % \cs{@makefntext} and this command contains two further -% configuration points (and a few hooks): +% sockets (unless it is overwritten by a legacy class): % \begin{description} -% \item[\cs{@makefntext@cfgpoint} (1 argument)] +% \item[\socket{fntext/mark} (0 arguments)] +% +% \DescribeSocket[noprint]{fntext/mark} % -% This configuration point receives the material to typeset the -% footnote mark. By default, all it does is running \cs{indent} -% to get a paragraph indentation (if one is set up---in most -% layouts it is 0~points) and then typesets the mark, but in -% some designs it executes more elaborate code. +% This socket has no input arguments but uses \cs{@makefnmark} to +% typeset the mark in front of the footnote text. Its +% \plug{default} uses code that examines the value of +% \cs{footnotemargin} and based on its setting typeset the mark +% in different ways: +% \begin{itemize} +% \item positive: typeset the mark in a box of that size +% \item zero: use \cs{llap} around the mark +% \item negative: use \cs{llap} but with a box of the given size +% negated inside +% \item \texttt{-}\cs{maxdimen}: just use \cs{@makefnmark} +% \end{itemize} +% For most cases this would be flexible enough, but if not then a +% class can define its own plug to specify the placement of the mark. % -% If tagging is produced this configuration point is also -% responsible for surrounding the mark with the appropriate tags -% marking the mark as an Lbl. It does this using the command -% \cs{tag@FENoteLbl}. +% Available plugs are \plug{default} and \plug{noop} (no mark is produced). % -% \item[\cs{@makefntext@cfgpointii} (1 argument)] % -% This configuration point manages the formatting of the footnote -% text once the mark has been typeset. +% \item[\socket{fntext/text} (1 argument)] % -% If tagging is produced this configuration point is also -% responsible for surrounding the mark with the appropriate tags -% marking the mark as an MC of type FENote. It does this using -% the command \cs{tag@FENotetext}. +% \DescribeSocket[noprint]{fntext/text} +% +% This socket manages the formatting of the footnote text +% (presented as an argument) once the mark has been typeset. In +% all cases we can think of this formatting is better configured +% via the available hooks described below, so the \plug{default} +% just grabs the argument and processes it without any other +% action. It is really only there to allow for some fancy stuff +% that some design comes up with. +% +% Available plugs are \plug{identity} (default) and \plug{noop}. % % \end{description} % @@ -284,19 +343,23 @@ % % % -% \subsubsection{Hooks} +% \subsubsection{Hooks for formatting the footnote text} % % \begin{description} % \item[\hook{fntext/before}] % +% \DescribeHook[noprint]{fntext/before} +% % Executed at the very beginning of \cs{footnotetext}. Currently -% there is on package (\pkg{linguex}) that +% there is one package (\pkg{linguex}) that % prepends material at this point. % % This hook is paired with hook \hook{fnmark/after}. % % \item[\hook{fntext}] % +% \DescribeHook[noprint]{fntext} +% % Executed at the beginning of the material passed to the first % configuration point. Typically used to set any baseline % stretch for the footnote text, e.g., by \pkg{setspace}, @@ -308,32 +371,42 @@ % % \item[\hook{fntext/para}] % -% After the font is set default paragraph parameters are set up +% \DescribeHook[noprint]{fntext/para} +% +% After the font is set (after the previous hook), some default +% paragraph parameters +% are set up % including \cs{interlinepenalty}, \cs{hsize}, \cs{parindent} and % a number of others, as some of them depend on the font -% size. Then the \hook{fntext/para} is run. If one wants to +% size. Then the \hook{fntext/para} is run which can overwrite +% the default. If one wants to % change the font size, it is probably necessary to reset these % other parameters too, e.g., \cs{parindent}, which can be done % here. % -% The configuration point \cs{@footnotetext@cfgpointii} normally +% Note: the socket \socket{fntext/make} normally % runs the command \cs{@makefntext} or some code that eventually -% runs this command, and this then produces the footnote mark (in -% front of the footnote text) and the formatted footnote text. In +% runs this command, and this then produces the footnote mark in +% front of the formatted footnote text. In % front of both the mark and the footnote text some classes have % placed paragraph parameter adjustments in their redefinition of % \cs{@makefntext}. However, there is no need to place it there % it could equally well go into the \hook{fntext/para} hook. We -% therefore do not provide another hook at this point. +% therefore do not provide another hook at this other point. % % \item[\hook{fntext/begin} \& \hook{fntext/end}] % +% \DescribeHook[noprint]{fntext/begin} +% \DescribeHook[noprint]{fntext/end} +% % The footnote text itself is surrounded by the hooks % \hook{fntext/begin} and \hook{fntext/end}. The two hooks are % not paired as they are typically used independently. % % \item[\hook{fntext/after}] % +% \DescribeHook[noprint]{fntext/after} +% % At the very end of \cs{footnotetext} we execute the hook % \hook{fntext/after} which is a reversed hook paired with % \hook{fntext/before}. Some packages, e.g., \pkg{linguex}, have @@ -384,6 +457,8 @@ % % \section{Tagging and hyperlinking support} % +% \fmi{this section needs work (and probably csname changes)} +% % Footnotes consist of a \emph{footnotemark} (short: mark) that is typically placed in the text % as a superscript number like this\footnotemark[1], and a \emph{footnotetext} % (short: note) that is placed at the bottom of the page. @@ -407,6 +482,38 @@ % % \subsection{Technical details for the tagging} % +% The following sockets are set up for kernel use, when doing tagging: +% \begin{description} +% \item[\socket{tagsupport/fnmark} (1 argument)] +% +% \DescribeSocket[noprint]{tagsupport/fnmark} +% +% \fmi{describe and decide on names} +% +% +% \item[\socket{tagsupport/fntext/begin} (no argument)] +% +% \DescribeSocket[noprint]{tagsupport/fntext/begin} +% +% +% \item[\socket{tagsupport/fntext/end} (no argument)] +% +% \DescribeSocket[noprint]{tagsupport/fntext/end} +% +% +% \item[\socket{tagsupport/fntext/mark} (1 argument)] +% +% \DescribeSocket[noprint]{tagsupport/fntext/mark} +% +% +% \item[\socket{tagsupport/fntext/text} (1 argument)] +% +% \DescribeSocket[noprint]{tagsupport/fntext/text} +% +% +% \end{description} +% +% % The \emph{footnotemark} should create a \texttt{/Lbl} structure\footnote{to make it easier % to identify the role we use \texttt{/footnotemark} which we rolemap to \texttt{/Lbl}} that should contain a \texttt{/Ref} entry pointing % to the structure of the \emph{footnotetext}. @@ -475,36 +582,36 @@ % as long as nothing unusual is done to \cs{@thefnmark}. % It also works if a document uses more than one footnote series as long as they have distinct numbering % systems, but in case a distinction is needed it is possible to define -% a new data structure and to switch locally to use this -% container. The following three commands are used for this. +% a new class with its own data structure and to switch locally to use this +% class. The following three commands are used for this. % -% The default property uses the name \texttt{default} +% The default class uses the name \texttt{default} % -% \begin{function}{\fnote_new:nn} +% \begin{function}{\fnote_class_new:nn} % \begin{syntax} -% \cs{fnote_new:nn}\Arg{name}\Arg{key/value option} +% \cs{fnote_class_new:nn}\Arg{name}\Arg{key/value option} % \end{syntax} -% -% This commands set up the needed data structure. Currently this only -% consists of a property which is used to store and manage the mark values. -% There are no options yet. +% This declaration sets up the needed data structure. Currently this only +% consists of a property list which is used to store and manage the mark values. +% There are no options yet. % \end{function} % % \begin{function}{\fnote_mark_gput:nn,\fnote_mark_gput:no,\fnote_mark_gput:oo} % \begin{syntax} -% \cs{fnote_mark_gput:nn}\Arg{mark}\Arg{footnote type name} +% \cs{fnote_mark_gput:nn}\Arg{mark}\Arg{class name} % \end{syntax} -% This command stores the current structure number as key and the \meta{mark} as -% value in the property associated with the \meta{footnote type name} +% This command stores the current structure number as key and the \meta{mark} as +% value in the property list associated with the \meta{class name}. % \end{function} % -% \begin{function}{\fnote_mark_gpop:nnN} +% \begin{function}{\fnote_mark_gpop_all:nnN} % \begin{syntax} -% \cs{fnote_mark_gpop:nnN}\Arg{mark}\Arg{footnote type name}\meta{sequence} +% \cs{fnote_mark_gpop_all:nnN}\Arg{mark}\Arg{class name}\meta{sequence} % \end{syntax} -% This command stores the keys/structure numbers whose value are \meta{mark} in the -% property associated with \meta{footnote type name} in the \meta{sequence} -% and then remove them from the property. The content of the sequence can then be +% This command stores all the keys/structure numbers whose value in the +% property list for \meta{class name} are equal to \meta{mark} +% into the sequence \meta{sequence} and then removes them from the property list. +% The content of the sequence can then be % used to create link targets and references. % \end{function} % @@ -516,7 +623,7 @@ % above, as it contains a reference command it can't be used to match a note, also \cs{footref} can % be used after the note has already been set. \cs{footref} disables therefore the automatic detection. % -% Instead the \cs{label} command is (currently with the help of a hook from the \texttt{nameref} package) +% Instead the \cs{label} command is % extended in the \cs{footnotetext} command to also store the structure number and \cs{footref} retrieves this % number to setup the reference and the link. % @@ -560,28 +667,33 @@ % by the mark commands) and one for the structure number of the footnotetest itself % (used as target by \cs{footref}s commands). % -% \subsection{Implementation details} +% \subsection{Implementation details regarding tagging} % % \subsection{Handling the mark} % -% The mark in the text is handled by redefining the kernel configuration point -% \cs{@kernel@process@makefnmark} to \cs{tag@FEMark}. -% It takes one argument, \cs{@makefnmark}, the command which formats the -% mark, and surrounds it by link and tagging commands. -% At the point where \cs{@kernel@process@makefnmark} is issued \cs{@thefnmark} has already been -% defined and can be used to setup the reference detections. +% The mark in the text is handled by assigning an appropriate +% plug to the socket \socket{tagsupport/fnmark}. +% It takes one argument, \cs{@makefnmark}, the +% command which formats the mark, and surrounds it by link and tagging +% commands. At the point where the socket is +% executed, \cs{@thefnmark} has already been defined and can be used to +% setup the reference detections. % % % \subsection{Handling the footnotetext} % -% The main part is done by redefining \cs{@kernel@process@footnotetext}. This configuration point takes two arguments, \cs{@footnotetext@cfgpoint} (by default \verb+\insert\footins+) and as second argument lots of code related to typesetting the notemark and the footnote text with the actual content of the footnote text somewhere in the middle. +% The main part is done by assigning a different plug to socket \socket{tagsupport/fntext/begin} +% and \socket{tagsupport/fntext/end} +% surrounding the footnote text. +% These sockets are used to start and end the structure and +% attempt to detect to which mark the note is related. % -% The redefinition of \cs{@kernel@process@footnotetext} surrounds the content with the structure command -% and tries to detect to which mark the note is related. -% -% The actual typesetting of the note text is done -% by \cs{@makefntext}/\cs{fnote_makefntext:n}. In the new implementation this contains two configuration -% points, \cs{@makefntext@cfgpoint} and \cs{@makefntext@cfgpointii}. These are redefined to add the tagging commands around note mark and note text. +% The actual typesetting of the note text is done by +% \cs{fnote_makefntext:n} (or its \LaTeXe{} name \cs{@makefntext}). In +% the new implementation this contains two further kernel sockets for tagging: +% \socket{tagsupport/fntext/mark} and +% \socket{tagsupport/fntext/text}. They get plugs assigned that add the +% tagging commands around note mark and note text. % % \subsection{Footnotes in minipages} % @@ -603,13 +715,6 @@ % % \begin{itemize} % -% \item tagging destroys footnotes directly following the text with pdflatex. -% -% \item there is a dependency on nameref as it provides the hook in \cs{label} -% used by the \cs{footref} code. -% -% \item there is a dependency to etoolbox as we patch \cs{\@iiiminipage} -% % \item Special formatting of footnote marks in the text, e.g. if ranges or commas are % used require special care as they should normally mark up such text as artifacts and % perhaps have to insert empty structures to represent an invisible mark. This must be coordinated @@ -617,9 +722,6 @@ % % \item manyfoot doesn't work correctly and must be analyzed. % -% \item Check if additional kernel configuration points are needed/possible -% to avoid the redefinitions of \cs{@makefntext@cfgpoint} and \cs{@makefntext@cfgpointii}. -% % \item \pkg{memoir} is not supported at all and errors when the code tries to patch % \cs{@makefntext}. % \end{itemize} @@ -644,7 +746,8 @@ % \subsection{File declaration} % \begin{macrocode} \ProvidesFile{latex-lab-footnotes.ltx} - [2023-02-04 v0.7 changes to the footnote interfaces] + [\ltlabfootnotedate\space v\ltlabfootnoteversion\space + changes to the footnote interfaces] % \end{macrocode} % % \subsection{code not fully handled yet} @@ -796,9 +899,6 @@ % \subsection{Variants} % % \begin{macrocode} -\cs_generate_variant:Nn \ref_label:nn { Vn } -\cs_generate_variant:Nn \ref_value:nn { Vn } -\cs_generate_variant:Nn \prop_gput:Nnn {cxn} \cs_generate_variant:Nn \hook_gput_code:nnn{nne} \cs_generate_variant:Nn \tag_struct_use:n {e} % \end{macrocode} @@ -852,14 +952,22 @@ % % \subsection{Hooks} % -% Hooks in the footnotemark command. +% \begin{hookdecl}{fnmark/before,fnmark/after, +% fnmark, +% fnmark/begin,fnmark/end} +% Hooks in the footnotemark command. % \begin{macrocode} \NewMirroredHookPair{fnmark/before}{fnmark/after} \NewHook{fnmark} \NewHook{fnmark/begin} \NewHook{fnmark/end} % \end{macrocode} -% Hooks in the footnotetext command +% \end{hookdecl} +% +% \begin{hookdecl}{fntext/before,fntext/after, +% fntext, +% fntext/begin,fntext/end,fntext/para} +% Hooks in the footnotetext command: % \begin{macrocode} \NewMirroredHookPair{fntext/before}{fntext/after} \NewHook{fntext} @@ -867,6 +975,7 @@ \NewHook{fntext/begin} \NewHook{fntext/end} % \end{macrocode} +% \end{hookdecl} % % \subsection{Debugging code} % the debugging code is just temporary @@ -882,11 +991,11 @@ { \bool_if:NT \g_fnote_debug_bool { - \LogHook{fnmark/before} - \LogHook{fnmark} - \LogHook{fnmark/begin} - \LogHook{fnmark/end} - \LogHook{fnmark/after} + \hook_log:n {fnmark/before} + \hook_log:n {fnmark} + \hook_log:n {fnmark/begin} + \hook_log:n {fnmark/end} + \hook_log:n {fnmark/after} \cs_gset_eq:NN \@@_debug_footnotemark: \prg_do_nothing: } } @@ -897,18 +1006,32 @@ { \bool_if:NT \g_fnote_debug_bool { - \cs_log:N\@footnotetext@cfgpoint - \cs_log:N\@footnotetext@cfgpointii - \cs_log:N\@footnotetext@cfgpointiii - \cs_log:N\@footnotetext@cfgpointiv - \cs_log:N\@makefntext@cfgpoint - \cs_log:N\@makefntext@cfgpointii - \LogHook{fntext/before} - \LogHook{fntext} - \LogHook{fntext/para} - \LogHook{fntext/begin} - \LogHook{fntext/end} - \LogHook{fntext/after} + \socket_log:n {fntext/process} + \socket_log:n {fntext/make} + \socket_log:n {fntext/begin} + \socket_log:n {fntext/end} +% \end{macrocode} +% +% \begin{macrocode} + \socket_log:n {fntext/mark} + \socket_log:n {fntext/text} +% \end{macrocode} +% +% \begin{macrocode} + \socket_log:n {tagsupport/fnmark} + \socket_log:n {tagsupport/fntext/begin} + \socket_log:n {tagsupport/fntext/end} + \socket_log:n {tagsupport/fntext/mark} + \socket_log:n {tagsupport/fntext/text} +% \end{macrocode} +% +% \begin{macrocode} + \hook_log:n {fntext/before} + \hook_log:n {fntext} + \hook_log:n {fntext/para} + \hook_log:n {fntext/begin} + \hook_log:n {fntext/end} + \hook_log:n {fntext/after} % \end{macrocode} % Show the info only once (if at all). % \begin{macrocode} @@ -926,7 +1049,7 @@ %------- % bibarts % chextras --- actually in the wrong place does an \unskip - \UseHook{fnmark/before} + \hook_use:n {fnmark/before} %------- \leavevmode \ifhmode @@ -936,21 +1059,24 @@ % (a bit less efficient) % memhfixc.sty % footmisc.sty - \UseHook{fnmark} + \hook_use:n {fnmark} %------- \nobreak \fi %------- % hyperref.sty - \UseHook{fnmark/begin} + \hook_use:n {fnmark/begin} %------- - \@kernel@process@makefnmark - \@makefnmark +% \end{macrocode} +% The kernel socket for tagging. It picks up \cs{@makefnmark} as its +% argument and if tagging is not active it contains the \plug{identity} plug. +% \begin{macrocode} + \socket_use:nn {tagsupport/fnmark} \@makefnmark %------- % \end{macrocode} % If a footnote mark is placed by its own then it should finish by -% executing \hook{fnmark/end}, resetting the space factor, and -% finishing with \hook{fnmark/after}. However, in a complete +% executing the hook \hook{fnmark/end}, resetting the space factor, and +% finishing with the hook \hook{fnmark/after}. However, in a complete % footnote these actions have to happen only after we have handled % the footnote text (e.g., by placing it into an \cs{insert}). In % such a situation \cs{_@@_footmark_finish:} below does nothing @@ -961,9 +1087,10 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_finish:,\@@_footnotemark_finish:} +% \begin{macro}{\@@_footnotemark_default_finish:,\@@_footnotemark_finish:} +% The default definition for \cs{@@_footnotemark_finish:} is called \cs{@@_footnotemark_default_finish:} % \begin{macrocode} -\cs_new_protected:Npn \@@_finish: { +\cs_new_protected:Npn \@@_footnotemark_default_finish: { % hyperref.sty % memhfixc.sty --- could move fnmark/after % scrlttr2.cls --- could vanish if footmisc uses a hook @@ -978,20 +1105,24 @@ \UseHook{fnmark/after} %------- } - -\cs_new_eq:NN \@@_footnotemark_finish: \@@_finish: % \end{macrocode} -% \end{macro} % -% \begin{macro}{\@kernel@process@makefnmark} -% Not a public config point but the kernel hook to add tagging % \begin{macrocode} -\def \@kernel@process@makefnmark { } +\cs_new_eq:NN \@@_footnotemark_finish: \@@_footnotemark_default_finish: % \end{macrocode} % \end{macro} % +% \begin{socketdecl}{tagsupport/fnmark} +% Not a public socket but reserved for tagging. By +% default it contains \plug{identity} and is reassigned if tagging is active. +% \begin{macrocode} +\NewSocket{tagsupport/fnmark}{1} +% \end{macrocode} +% \end{socketdecl} +% % \begin{macro}{\@footnotemark} -% At last provide the name \LaTeXe{} is used to. +% Here we provide the traditional \LaTeXe{} name in case it is directly used +% in some legacy class. % \begin{macrocode} \cs_set_eq:NN \@footnotemark \fnote_footnotemark: % \end{macrocode} @@ -1007,16 +1138,23 @@ \@@_debug_footnotetext: %------- % ./linguex/linguex.sty - \UseHook{fntext/before} + \hook_use:n {fntext/before} %------- - \@kernel@process@footnotetext - \@footnotetext@cfgpoint { % config point +% \end{macrocode} +% Execute a kernel socket for tagging. +% \begin{macrocode} + \socket_use:n {tagsupport/fntext/begin} +% \end{macrocode} +% +% \begin{macrocode} + \socket_use:nn {fntext/process} + { %------- % resetting baselinestretch ... (could be done further down) % ./uafthesis/uafthesis.cls % ./setspace/setspace.sty % ./footmisc/footmisc.sty (normal) - \UseHook{fntext} + \hook_use:n {fntext} %------- \reset@font \footnotesize @@ -1046,84 +1184,144 @@ % and \cs{@currentlabel} is that is necessary. % % ./resphilosophica/resphilosophica.cls - \UseHook{fntext/para} + \hook_use:n {fntext/para} %------- \color@begingroup %------- -% fnpara wants to replace \@makefntext{...} and para and side option of footmisc etc too ... -% so we make this a config point +% fnpara wants to replace \@makefntext{...} and para and side +% option of footmisc etc too ... +% so we make this a socket, because only one action can be active: %------- - \@footnotetext@cfgpointii % config point + \socket_use:nn {fntext/make} { %------- % ./resphilosophica/resphilosophica.cls %------- - \@footnotetext@cfgpointiii % config point + \socket_use:n {fntext/begin}% %------- % bibarts % fnbreak.sty - \UseHook{fntext/begin} + \hook_use:n {fntext/begin} %------- \ignorespaces #1 %------- % bibarts % fnbreak.sty - \UseHook{fntext/end} + \hook_use:n {fntext/end} %------- - \@footnotetext@cfgpointiv % config point +% \end{macrocode} +% The socket code (by default adding a strut) has to come +% \emph{after} everything added into the hook above. +% \begin{macrocode} + \socket_use:n {fntext/end} } \par \color@endgroup } %------- +% \end{macrocode} +% The corresponding kernel hook that ends the tagging structure if +% tagging is active. +% \begin{macrocode} + \socket_use:n{tagsupport/fntext/end} +%------- % ./linguex/linguex.sty - \UseHook{fntext/after} + \hook_use:n {fntext/after} %------- } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@footnotetext@cfgpoint} -% default for config point (1 arg) +% \begin{socketdecl}{fntext/process} +% % \begin{macrocode} -\cs_new_protected:Npn \@footnotetext@cfgpoint { \insert\footins } +\NewSocket {fntext/process}{1} +\NewSocketPlug{fntext/process}{default}{ \insert\footins {#1} } +\NewSocketPlug{fntext/process}{side} { \marginpar {#1} } % \end{macrocode} -% \end{macro} +% +% \begin{macrocode} +\AssignSocketPlug{fntext/process}{default} +% \end{macrocode} +% \end{socketdecl} % % -% \begin{macro}{\@footnotetext@cfgpointii} -% default for config point (1 arg) +% +% \begin{socketdecl}{fntext/make} +% This socket receives the \meta{text} from the \cs{footnote} or +% \cs{footnotetext} and formats it. % \begin{macrocode} -\cs_new_protected:Npn \@footnotetext@cfgpointii { \@makefntext } +\NewSocket {fntext/make}{1} +\NewSocketPlug{fntext/make}{default}{ \@makefntext {#1} } +% \end{macrocode} +% When running several footnotes together as a paragraph some +% additional work is necessary to unbox the individual footnotes +% recursively (see \TeX{}book algorithm in appendix~D). +% \begin{macrocode} +\NewSocketPlug{fntext/make}{para} +{ + \setbox\FN@tempboxa\hbox{\@makefntext{#1}}% + \dp\FN@tempboxa\z@ + \ht\FN@tempboxa + \dimexpr\wd\FN@tempboxa *% + \footnotebaselineskip /\columnwidth\relax + \box\FN@tempboxa +} % \end{macrocode} -% \end{macro} % -% \begin{macro}{\@footnotetext@cfgpointiii} -% default for config point (0 args) % \begin{macrocode} -\cs_new_protected:Npn \@footnotetext@cfgpointiii { \rule\z@\footnotesep } +\AssignSocketPlug{fntext/make}{default} % \end{macrocode} -% \end{macro} +% \end{socketdecl} % -% \begin{macro}{\@footnotetext@cfgpointiv} -% default for config point (0 args) +% \begin{socketdecl}{fntext/begin} +% By default adds a strut at the start of the footnote text. % \begin{macrocode} -\cs_new_protected:Npn \@footnotetext@cfgpointiv { \@finalstrut\strutbox } +\NewSocket {fntext/begin}{0} +\NewSocketPlug{fntext/begin}{default}{ \rule\z@\footnotesep } % \end{macrocode} -% \end{macro} % -% \begin{macro}{\@kernel@process@footnotetext} -% kernel hook for tagging (2 args) % \begin{macrocode} -\cs_new_protected:Npn \@kernel@process@footnotetext {} +\AssignSocketPlug{fntext/begin}{default} % \end{macrocode} -% \end{macro} +% \end{socketdecl} +% +% \begin{socketdecl}{fntext/end} +% By default adds a strut at the end of the footnote text unless we +% are no longer in hmode. +% \begin{macrocode} +\NewSocket {fntext/end}{0} +\NewSocketPlug{fntext/end}{default}{ \@finalstrut\strutbox } +% \end{macrocode} +% When running several footnotes together as a paragraph some +% additional glue has to be added between them. +% \begin{macrocode} +\NewSocketPlug{fntext/end}{para} + {% + \strut + \penalty-10\relax + \hskip\footglue + } +% \end{macrocode} +% +% \begin{macrocode} +\AssignSocketPlug{fntext/end}{default} +% \end{macrocode} +% \end{socketdecl} +% +% \begin{socketdecl}{tagsupport/fntext/begin,tagsupport/fntext/end} +% Kernel sockets for tagging. +% \begin{macrocode} +\NewSocket{tagsupport/fntext/begin}{0} +\NewSocket{tagsupport/fntext/end}{0} +% \end{macrocode} +% \end{socketdecl} % % Provide the name \LaTeXe{} is used to and do this unconditionally -% (no patching of class code if any). This means that if a class provides it own -% definition that gets lost and if necessary needs to be handled -% with firstaid (or updating of the class). +% (no patching of class code if any). This means that if a class +% provides it own definition that gets lost and if necessary needs to +% be handled with firstaid (or updating of the class). % \begin{macrocode} \AddToHook{begindocument} { @@ -1131,6 +1329,9 @@ } % \end{macrocode} % +% +% +% % \subsection{The new \cs{@makefntext} command} % % \cs{footnotemargin} is the logic implemented by footmisc. Perhaps we @@ -1147,57 +1348,85 @@ \fi } % \end{macrocode} - +% +% +% +% % \begin{macro}{\fnote_makefntext:n} % \begin{macrocode} \cs_new_protected:Npn \fnote_makefntext:n #1 { % \end{macrocode} % Some classes in their redefinition for \cs{@makefntext} have -% places some paragraph parameters at this point, but those can +% placed some paragraph parameters at this point, but those can % equally well go into the hook \hook{fntext/para}. We therefore do % not provide a further hook at this point. % \begin{macrocode} - \@makefntext@cfgpoint - { - \ifdim\footnotemargin>\z@ - \hb@xt@ \footnotemargin{\hss\@makefnmark} - \else - \ifdim\footnotemargin=\z@ - \llap{\@makefnmark} - \else - \ifdim\footnotemargin=-\maxdimen - \@makefnmark - \else - \llap{\hb@xt@ -\footnotemargin{\@makefnmark\hss}} - \fi - \fi - \fi - } - \@makefntext@cfgpointii - { #1 } + \noindent +% \end{macrocode} +% +% \begin{macrocode} + \socket_use:nn {tagsupport/fntext/mark} { \socket_use:n {fntext/mark} } + \socket_use:nn {tagsupport/fntext/text} { \socket_use:nn {fntext/text}{#1} } } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@makefntext@cfgpoint} -% default for config point (1 arg) +% \begin{socketdecl}{fntext/mark} +% A socket to typeset the mark at the start of a footnote. +% \begin{macrocode} +\NewSocket {fntext/mark}{0} +% \end{macrocode} +% The \plug{default} plug implements the logic introduced with the +% \pkg{footmisc} package. +% \begin{macrocode} +\NewSocketPlug{fntext/mark}{default}{ + \ifdim\footnotemargin>\z@ + \hb@xt@ \footnotemargin{\hss\@makefnmark} + \else + \ifdim\footnotemargin=\z@ + \llap{\@makefnmark} + \else + \ifdim\footnotemargin=-\maxdimen + \@makefnmark + \else + \llap{\hb@xt@ -\footnotemargin{\@makefnmark\hss}} + \fi + \fi + \fi +} +% \end{macrocode} +% % \begin{macrocode} -\cs_new_protected:Npn \@makefntext@cfgpoint { \noindent } +\AssignSocketPlug{fntext/mark}{default} % \end{macrocode} -% \end{macro} +% \end{socketdecl} % -% \begin{macro}{\@makefntext@cfgpointii} -% default for config point (1 arg) +% \begin{socketdecl}{fntext/text} +% By default this socket does nothing special and simply processes +% its argument as provided. % \begin{macrocode} -\cs_new_protected:Npn \@makefntext@cfgpointii #1 { #1 } +\NewSocket {fntext/text}{1} % \end{macrocode} -% \end{macro} +% \end{socketdecl} +% +% +% +% \begin{socketdecl}{tagsupport/fntext/mark,tagsupport/fntext/text} +% Not a public socket but reserved for tagging. By +% default it contains \plug{identity} and is reassigned if tagging is active. +% \begin{macrocode} +\NewSocket{tagsupport/fntext/mark}{1} +\NewSocket{tagsupport/fntext/text}{1} +% \end{macrocode} +% \end{socketdecl} +% +% % % \subsubsection{Making documents use the new \cs{@makefntext}} % % If the definition for \cs{@makefntext} is that of the standard % classes then replace it with \cs{fnote_makefntext:n}, otherwise -% try to patch the definition. +% try to patch the definition used in the class. % % Here is the definition the way it is in % \texttt{classes.dtx}. Notice that (for saving space) there is no @@ -1217,22 +1446,24 @@ % % Here is the messy code for patching. Note that this is only there % to help classes along that aren't updated yet so it does some -% minimal patching to hopefully add configuration points in the -% right place. +% minimal patching to hopefully add kernel configuration hooks in the +% right place while otherwise leaving the legacy code alone. An +% updated class would not redefine \cs{@makefntext} but simply add +% appropriate code to the provided hooks. % % What it does is roughly the -% following: It look for a definition of \cs{@makefntext} of the form +% following: It looks for a definition of \cs{@makefntext} of the form %\begin{verbatim} % {AAA \hbox BBB { CCC } DDD #1 EEE } %\end{verbatim} % where ``BBB'' is something like \texttt{to 1em} or similar. It then % replaces that with %\begin{verbatim} -% {AAA \@makefntext@cfgpoint{\hbox BBB { CCC }} DDD -% \@makefntext@cfgpointii{#1} EEE } +% {AAA \UseSocket{tagsupport/fntext/mark}{\hbox BBB { CCC }} DDD +% \UseSocket{tagsupport/fntext/text}{#1} EEE } %\end{verbatim} % The patching is not very careful, i.e., it assumes there is only -% one \verb=#1= in the replacement text and that a \cs{hbox} found +% one \verb=#1= in the replacement text and that the first \cs{hbox} found % is the right one to patch. But that is enough to cater for all % definitions of \cs{@makefntext} out there in the TL distribution. % @@ -1247,7 +1478,7 @@ \cs_new_protected:Npn \@@_patch: { - \tl_set:No \l_@@_patch_tl { \@makefntext { \@makefntext@cfgpointii{##1} } } + \tl_set:No \l_@@_patch_tl { \@makefntext { \UseSocket{tagsupport/fntext/text}{##1} } } \tl_if_in:NnTF \l_@@_patch_tl { \hbox } { \cs_set_eq:NN \@@_tmp:w \@@_patch_hbox:w } { @@ -1268,7 +1499,7 @@ % \end{macrocode} % % If \cs{@makefntext} contains \cs{hbox} then grab ``AAA'' as -% \verb=#1= and ``BBB'' (up to the open \verb={=) and return it as +% \verb=#1= and ``BBB'' (up to the open \texttt{\{}) and return it as %\begin{verbatim} % AAA \@makefntext@processX { \hbox BBB } %\end{verbatim} @@ -1291,12 +1522,13 @@ % not a patch person, so this is the simple way out for now: % % \begin{macrocode} -\cs_new:Npn \@makefntext@processX #1#2{\@makefntext@cfgpoint{#1{#2}}} +\cs_new:Npn \@makefntext@processX #1#2{\UseSocket{tagsupport/fntext/mark}{#1{#2}}} % \end{macrocode} % % At \verb=\begin{document}= check if the current definition is % that of the standard classes and if so replace it by % \cs{fnote_makefntext:n} otherwise try and patch the definition +% made by some class or package % using the approach above. % \begin{macrocode} @@ -1340,7 +1572,7 @@ \fnote_step_fnmark:nn {#1} \@mpfn \cs_set_eq:NN \@@_footnotemark_finish: \prg_do_nothing: \@footnotemark - \cs_set_eq:NN \@@_footnotemark_finish: \@@_finish: + \cs_set_eq:NN \@@_footnotemark_finish: \@@_footnotemark_default_finish: \@footnotetext {#2} \@@_footnotemark_finish: } @@ -1362,7 +1594,7 @@ % \cs{footref} used the starred \cs{ref} in \cs{@thefnmark} % as the linking is handled by the tagging code inside % the \cs{@footnotemark}. -% \cs{footref} should not try to link to its related related +% \cs{footref} should not try to link to its related % note automatically but should instead use the label. % This is passed to \cs{@footnotemark} through % \cs{l__fnote_currentlabel_tl}. @@ -1388,9 +1620,8 @@ % Tagging of footnotes in minipages require a change in the minipage commands % We define at first a local configuration command for minipage footnotes. % -% TODO remove the dependency to etoolbox, and need for the patch. % \begin{macrocode} -\cs_new_protected:Npn \@mpfootnotetext@cfgpoint #1 +\NewSocketPlug{fntext/process}{mp} { \global\setbox\@mpfootins\vbox{% \unvbox\@mpfootins @@ -1398,16 +1629,6 @@ } } % \end{macrocode} -% Then we patch \cs{@iiiminipage} -% \begin{macrocode} -\RequirePackage{etoolbox} -\ExplSyntaxOff -\patchcmd\@iiiminipage - {\let\@footnotetext\@mpfootnotetext} - {\let\@footnotetext@cfgpoint\@mpfootnotetext@cfgpoint} - {}{\ERROR} -\ExplSyntaxOn -% \end{macrocode} % % \subsubsection{\pkg{memoir}} % The \pkg{memoir} class redefines various internal commands to inject its @@ -1484,35 +1705,28 @@ % For \cs{footref} and (perhaps later for labeled footnotes) % we must extend the label system. % Beside the normal values we also need the structure number of the note. -% We use the \pkg{nameref} hook until latex provides a hook for its label. +% We use the inbuild label hook % At first we define a suitable attribute, it uses as value the structure % number of the note as stored in \cs{l__fnote_currentstruct_tl} % \begin{macrocode} -\ref_attribute_gset:nnnn {fnote/struct}{1}{now}{\l_@@_currentstruct_tl} +\property_new:nnnn {fnote/struct}{now}{1}{\l_@@_currentstruct_tl} % \end{macrocode} % -% We add a hook to the \pkg{nameref} hook. By default it does nothing -% \begin{macro}{\@@_label_hook:} +% We add a hook to the label hook. By default it does nothing +% \begin{macro}{\@@_label_hook:e} % \begin{macrocode} -\cs_new_protected:Npn \@@_label_hook: {} -\AddToHook{begindocument/before} - { - \RequirePackage{nameref} - \g@addto@macro\label@hook - { - \@@_label_hook: - } - } +\cs_new_protected:Npn \@@_label_hook:e #1 {} +\AddToHookWithArguments{label}{ \@@_label_hook:e{#1}} % \end{macrocode} % \end{macro} % Inside a footnotetext we change the hook to store the structure number too. -% nameref provides the name of label in \cs{label@name}. +% The name of label is provided as argument in the label hook. % \begin{macrocode} \AddToHook{fntext/begin} { - \cs_set_protected:Npn \@@_label_hook: + \cs_set_protected:Npn \@@_label_hook:e #1 { - \ref_label:Vn \label@name {fnote/struct} + \property_record:ee {@@/#1} {fnote/struct} } } % \end{macrocode} @@ -1526,7 +1740,7 @@ % tabular notes, other footnote series) to make use of this. % % -% \begin{macro}{\fnote_new:nn} +% \begin{macro}{\fnote_class_new:nn} % This sets up a new footnote type, the first argument % is the name, the second is meant for options. Currently % it does nothing at all. @@ -1534,23 +1748,23 @@ % command as its own type! % % \begin{macrocode} -\cs_new_protected:Npn \fnote_new:nn #1 #2 % #1 name, #2 options +\cs_new_protected:Npn \fnote_class_new:nn #1 #2 % #1 name, #2 options { \prop_new:c { g_@@_currentmarks_ #1 _prop } } -\fnote_new:nn {default}{} +\fnote_class_new:nn {default}{} % \end{macrocode} % \end{macro} % % % \begin{macro}{\fnote_mark_gput:nn} -% This commands takes as argument the representation of the mark -% (e.g. \cs{@thefnmark} and the type (typically default should work) +% This commands takes as argument the representation of the mark, +% e.g., \cs{@thefnmark} and the type (typically default should work). % \begin{macrocode} \cs_new_protected:Npn \fnote_mark_gput:nn #1 #2 % #1 the representation of the mark, #2 type { - \prop_gput:cxn { g_@@_currentmarks_ #2 _prop } + \prop_gput:cen { g_@@_currentmarks_ #2 _prop } { \tag_get:n{struct_num} } { #1 } } @@ -1559,13 +1773,13 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\fnote_mark_gpop:nnN} +% \begin{macro}{\fnote_mark_gpop_all:nnN} % This commands takes as argument the representation of the mark -% (e.g. the content of\cs{@thefnmark}), the series (typically default should work) +% (e.g. the content of\cs{@thefnmark}), the class (typically |default| should work) % and a sequence into which every structure number in the property -% is stored that has the same value as the mark +% is stored that has the same value as the mark. The sequence is cleared first. % \begin{macrocode} -\cs_new_protected:Npn \fnote_mark_gpop:nnN #1 #2 #3 +\cs_new_protected:Npn \fnote_mark_gpop_all:nnN #1 #2 #3 { \seq_clear:N #3 \prop_set_eq:Nc \l_@@_tmpa_prop { g_@@_currentmarks_ #2 _prop } @@ -1584,20 +1798,28 @@ } } } -\cs_generate_variant:Nn\fnote_mark_gpop:nnN {ooN} +\cs_generate_variant:Nn\fnote_mark_gpop_all:nnN {ooN} % \end{macrocode} % \end{macro} - - +% +% +% +% % \subsubsection{Enabling tagging and links for the mark command} -% To handle the mark in the text, we define a special command -% which will surround \cs{@makefntext}. -% At this time \cs{@thefnmark} is already set. +% +% +% \begin{plugdecl}{FEMark} +% +% To handle the mark in the text, we define a special plug for +% the socket \socket{tagsupport/fnmark} that receives +% \cs{@makefntext} as its argument. At this time \cs{@thefnmark} +% is already set. +% % \begin{macrocode} -\cs_new_protected:Npn \tag@FEMark #1 %#1 content +\NewSocketPlug{tagsupport/fnmark}{FEMark} { % \end{macrocode} -% end an open mc and start the structure. +% End an open mc and start the structure. % \begin{macrocode} \tag_mc_end_push: \tag_struct_begin:n { tag=footnotemark } @@ -1615,7 +1837,7 @@ % which means the name of the prop shouldn't be fix. % \begin{macrocode} \fnote_mark_gput:oo {\@thefnmark}{\l_fnote_type_tl} - \tl_set:Nx \l_@@_linktarget_tl {footnote*.\tag_get:n{struct_num}} + \tl_set:Ne \l_@@_linktarget_tl {footnote*.\tag_get:n{struct_num}} } % \end{macrocode} % If there is no autodetecting we need some id, @@ -1630,13 +1852,13 @@ { \exp_not:N\fnote_gput_refs:ee { \tag_get:n{struct_num} } - { \ref_value:Vn\l_@@_currentlabel_tl {fnote/struct} } + { \property_ref:ee{ @@/\l_@@_currentlabel_tl } {fnote/struct} } } % \end{macrocode} % in this case we set the name of the linktarget in the note % to the structure number of the text mark. % \begin{macrocode} - \tl_set:Nx \l_@@_linktarget_tl {footnote*.\ref_value:Vn\l_@@_currentlabel_tl {fnote/struct}} + \tl_set:Ne \l_@@_linktarget_tl {footnote*.\property_ref:ee {@@/\l_@@_currentlabel_tl} {fnote/struct}} } % \end{macrocode} % And now the actual content @@ -1658,11 +1880,15 @@ \tag_mc_begin_pop:n{} } % \end{macrocode} -% At last set the kernel command to this one +% At last assign the plug: % \begin{macrocode} -\cs_set_eq:NN \@kernel@process@makefnmark \tag@FEMark +\AssignSocketPlug{tagsupport/fnmark}{FEMark} % \end{macrocode} - +% \end{plugdecl} +% +% +% +% % \subsubsection{The footnote text} % We need a public command to append values to the Ref keys @@ -1688,11 +1914,13 @@ \tl_new:N \l_@@_dflt_struct_tl \tl_set:Nn \l_@@_dflt_struct_tl {1} % \end{macrocode} -% kernel hook for tagging (2 args) +% kernel hooks for taggin % this sets the structure around the whole text % +% +% \begin{plugdecl}{FENote} % \begin{macrocode} -\cs_new_protected:Npn \tag@FENote #1#2 % #1 config point, \insert\footins #2 content +\NewSocketPlug{tagsupport/fntext/begin}{FENote} { \tag_mc_end_push: % \end{macrocode} @@ -1708,7 +1936,7 @@ % \end{macrocode} % Store the current structure number for labels. % \begin{macrocode} - \tl_set:Nx \l_@@_currentstruct_tl { \tag_get:n{struct_num} } + \tl_set:Ne \l_@@_currentstruct_tl { \tag_get:n{struct_num} } % \end{macrocode} % We want to move the label structure here. So we provide a container % It number is |\l__fnote_currentstruct_tl| plus 1. @@ -1724,7 +1952,7 @@ % \end{macrocode} % find open marks with identical \cs{@thefnmark} % \begin{macrocode} - \fnote_mark_gpop:ooN { \@thefnmark }{ \l_fnote_type_tl } \l_@@_currentrefs_seq + \fnote_mark_gpop_all:ooN { \@thefnmark }{ \l_fnote_type_tl } \l_@@_currentrefs_seq % \end{macrocode} % Then we store the object numbers of the marks in the /Ref of the FENote structure: % and the number of the FEnote into the marks structure: @@ -1744,57 +1972,62 @@ {%no auto } + } % \end{macrocode} % This finish the setup of the tagging structure. +% \end{plugdecl} + + + % Now we process the text. The destinations for the links are set with the label % so that we can be sure that we are in hmode. % \begin{macrocode} - #1 {#2} +\NewSocketPlug{tagsupport/fntext/end}{FENote} + { \tag_struct_end: \tag_mc_begin_pop:n{} } % \end{macrocode} -% At last set the kernel command to this one +% At last assign the plugs: % \begin{macrocode} -\cs_set_eq:NN \@kernel@process@footnotetext \tag@FENote +\AssignSocketPlug{tagsupport/fntext/begin}{FENote} +\AssignSocketPlug{tagsupport/fntext/end}{FENote} % \end{macrocode} % -% \cs{@makefntext@cfgpoint} is the configuration point responsible for -% typesetting the mark in the note. We use it to surround +% The kernel socket \socket{tagsupport/fntext/mark} is responsible for +% tagging the mark in the note. We use it to surround % the mark with the needed tagging commands. % -% TODO check if this should/can be kernel configuration points -% or if an additional kernel configuration points are needed. +% TODO check if additional kernel configuration points are needed. % If yes, what about the paragraph start and the paratagging?? % -% \begin{macrocode} -\cs_set_protected:Npn \@makefntext@cfgpoint #1 %#1 code that typesets the mark. - { - \noindent - \tag_mc_end_push: - \tag@FENoteLbl { #1 } - \tag_mc_begin_pop:n{} - } -% \end{macrocode} -% \cs{tag@FENoteLbl} creates the label in the note on the bottom. -% It also adds link targets for the hyperlinking. % -% \begin{macro}{\tag@FENoteLbl} +% +%^^A If tagging is produced this configuration point is also +%^^A responsible for surrounding the mark with the appropriate tags +%^^A marking the mark as an Lbl. It does this using the +%^^A \socket{tagsupport/fntext/mark} socket. +% +% \begin{plugdecl}{FENoteLbl} +% This plug creates the label in the note on the bottom. +% It also adds link targets for the hyperlinking. % \begin{macrocode} -\cs_new_protected:Npn \tag@FENoteLbl #1 +\NewSocketPlug{tagsupport/fntext/mark}{FENoteLbl} { + \tag_mc_end_push: % \end{macrocode} -% We create a link target for every related mark. The name is footnote* + structure number -% of the mark. We also add a link target for the current structure (for footref) +% We create a link target for every related mark. The name is +% \texttt{footnote*} \meta{structure number of the mark}. We also add a link +% target for the current structure (for \cs{footref}). % \begin{macrocode} %\seq_show:N\l_@@_currentrefs_seq \seq_map_inline:Nn\l_@@_currentrefs_seq {\MakeLinkTarget*{footnote*.##1}} \MakeLinkTarget*{footnote*.\l_@@_currentstruct_tl} % \end{macrocode} -% now we add the tagging commands. We move the structure of the label to -% to the container at the begin of the note. +% Now we add the tagging commands. We move the structure of the label to +% to the container at the begin of the note. % \begin{NOTE}{UF} -% check if the NonStruct is really needed. Perhaps we can simply move the mc. +% Check if the NonStruct is really needed. Perhaps we can simply move the mc. % \end{NOTE} % \begin{macrocode} \tag_struct_begin:n { tag=NonStruct,parent=\l_@@_currentstruct_tl +1 } @@ -1802,37 +2035,43 @@ #1 \tag_mc_end: \tag_struct_end: + \tag_mc_begin_pop:n{} } % \end{macrocode} -% \end{macro} -% -% -% \cs{@makefntext@cfgpointii} is the -% configuration point around the actual note text. % -% TODO check if this should/can be kernel configuration points % \begin{macrocode} -\cs_set_protected:Npn \@makefntext@cfgpointii #1 - { - \tag_mc_end_push: - \tag@FENotetext { #1 } - \tag_mc_begin_pop:n{} - } +\AssignSocketPlug{tagsupport/fntext/mark}{FENoteLbl} % \end{macrocode} -% \begin{macro}{\tag@FENotetext} +% \end{plugdecl} +% +% +%^^A If tagging is produced this configuration point is also +%^^A responsible for surrounding the mark with the appropriate tags +%^^A marking the mark as an MC of type FENote. It does this using +%^^A the socket \socket{tagsupport/fntext/text}. % -% This command currently only adds an MC chunk, +% \begin{plugdecl}{FENotetext} +% +% This plug is for the kernel socket \socket{tagsupport/fntext/text} +% around the actual note text when doing tagging. +% Currently it only adds an MC chunk. % % TODO Should it set a mc or could it rely on the content? % \begin{macrocode} -\cs_new_protected:Npn \tag@FENotetext #1 +\NewSocketPlug{tagsupport/fntext/text}{FENotetext} { + \tag_mc_end_push: \tag_mc_begin:n{} #1 \tag_mc_end: + \tag_mc_begin_pop:n{} } % \end{macrocode} -% \end{macro} +% +% \begin{macrocode} +\AssignSocketPlug{tagsupport/fntext/text}{FENotetext} +% \end{macrocode} +% \end{plugdecl} %------------------------------------- % \begin{macrocode} @@ -1849,7 +2088,7 @@ %<*footmisc> %% %% Copyright (c) 1995-2011 Robin Fairbairns -%% Copyright (c) 2018-2022 Robin Fairbairns, Frank Mittelbach +%% Copyright (c) 2018-2023 Robin Fairbairns, Frank Mittelbach %% %% This file is part of the `latex-lab Bundle'. %% -------------------------------------------- @@ -1864,9 +2103,6 @@ %% %% This work has the LPPL maintenance status 'maintained'. %% -%% -%% File: footmisc.dtx (C) Copyright 1995-2011 Robin Fairbairns -%% (C) Copyright 2018-2022 Frank Mittelbach \NeedsTeXFormat{LaTeX2e} \providecommand\DeclareRelease[3]{} \providecommand\DeclareCurrentRelease[2]{} @@ -1916,14 +2152,14 @@ option "para"}% {I shall ignore "\CurrentOption"}% \else - \def\@footnotetext@cfgpoint {\marginpar} \AddToHook{fntext/para}{% \hsize\marginparwidth % correct the default \hsize \footnotesep\z@ % don't add a default separation } - \def\@footnotetext@cfgpointii {\@makefntext} - \def\@footnotetext@cfgpointiii {} - \def\@footnotetext@cfgpointiv {} + \AssignSocketPlug{fntext/process}{side} +% \AssignSocketPlug{fntext/make}{default} + \AssignSocketPlug{fntext/begin}{noop} + \AssignSocketPlug{fntext/end}{noop} \fi } \let\footnotelayout\@empty @@ -1992,25 +2228,16 @@ \DeclareOption{multiple}{\FN@multiplefootnotetrue} \ProcessOptions % \end{macrocode} -% This version of \pkg{footmisc} can assume that the new OR code is -% already available, thus nothing needs loading at this -% point. However, as long as we use this code also in a package -% version that can be loaded by other package while we are in a -% transition phase it is not clear whether not the kernel code is -% already available for other packages. -% \begin{macrocode} -%\@ifundefined{@kernel@before@cclv} -% {\input{latex-lab-new-or.ltx}}{} -% \end{macrocode} % % Footnote box layout for para footnotes; % this would also be the hook to support dblfootnotes (from the % \texttt{dblfnote} package if we integrate that). % \begin{macrocode} \ifFN@para - \def\@makecol@cfgpointii {% + \NewSocketPlug{@makecol/footnotes}{para}{% \global\setbox\footins\vbox{\FN@makefootnoteparagraph}% } + \AssignSocketPlug{@makecol/footnotes}{para} \fi % \end{macrocode} % @@ -2038,64 +2265,29 @@ % \end{macrocode} % % -% % \begin{macrocode} \ifcase \FN@bottomcases\relax -\ERROR -\or + \ERROR +\or %1 \ifFN@abovefloats - \def\@makecol@cfgpoint {% - \@if@footnotes@TF - {\@outputbox@append{\vfill}}% - {\@if@bfloats@TF{\@outputbox@append{\vfill}}% - {\@outputbox@reinsertbskip}}% - \@outputbox@appendfootnotes - \@outputbox@attachfloats - } + \AssignSocketPlug {@makecol/outputbox}{space-footnotes-floats} \else - \def\@makecol@cfgpoint {% - \@outputbox@attachfloats - \@if@footnotes@TF - {\@outputbox@append{\vfill}}% - {\@outputbox@reinsertbskip}% - \@outputbox@appendfootnotes - } + \AssignSocketPlug {@makecol/outputbox}{floats-footnotes-space} \fi -\or +\or %2 \ifFN@abovefloats - \def\@makecol@cfgpoint {% - \@outputbox@appendfootnotes - \@if@bfloats@TF - {\@outputbox@append{\vfill}}% - {\@outputbox@reinsertbskip}% - \@outputbox@attachfloats - } + \AssignSocketPlug {@makecol/outputbox}{footnotes-space-floats} \else - \def\@makecol@cfgpoint {% - \@if@footnotes@TF - {\@outputbox@append{\vfill}}% - {\@if@bfloats@TF{\@outputbox@append{\vfill}}% - {\@outputbox@reinsertbskip}}% - \@outputbox@attachfloats - \@outputbox@appendfootnotes - } + \AssignSocketPlug {@makecol/outputbox}{space-floats-footnotes} \fi -\or +\or %3 \ifFN@abovefloats - \def\@makecol@cfgpoint {% - \@outputbox@appendfootnotes - \@outputbox@attachfloats - \@outputbox@reinsertbskip - } + \AssignSocketPlug {@makecol/outputbox}{footnotes-floats} \else - \def\@makecol@cfgpoint {% - \@outputbox@attachfloats - \@outputbox@appendfootnotes - \@outputbox@reinsertbskip -} + \AssignSocketPlug {@makecol/outputbox}{floats-footnotes} \fi \else -\ERROR + \ERROR \fi % next can be dropped when cleaned up @@ -2120,24 +2312,12 @@ \ifFN@para - \def\@footnotetext@cfgpoint {\insert\footins} - \long\def\@footnotetext@cfgpointii #1{% - \setbox\FN@tempboxa\hbox{\@makefntext{#1}}% - \dp\FN@tempboxa\z@ - \ht\FN@tempboxa - \dimexpr\wd\FN@tempboxa *% - \footnotebaselineskip /\columnwidth\relax - \box\FN@tempboxa - } - - - \def\@footnotetext@cfgpointiii {} - \def\@footnotetext@cfgpointiv {% config point - \strut - \penalty-10\relax - \hskip\footglue - } +% \AssignSocketPlug{fntext/process}{default} + \AssignSocketPlug{fntext/make}{para} + \AssignSocketPlug{fntext/begin}{noop} + \AssignSocketPlug{fntext/end}{para} + \fi @@ -2211,7 +2391,7 @@ % perpage is loaded this results in updating counters on the reset % list to 1 (or to a higher starting value if \cs{MakePerPage} is % used with an optional argument, which is precisely the problem -% here. By subtracting 1 in that case we set it back to 1 lower +% here). By subtracting 1 in that case we set it back to 1 lower % than the starting value. % % But to make this fully work we also need to update a support @@ -2236,10 +2416,7 @@ %} -\AddToHook{fntext/begin}{\nobreak \hspace{.2em}} - - - + \AddToHook{fntext/begin}{\nobreak \hspace{.2em}} \else @@ -2296,7 +2473,11 @@ \ifFN@multiplefootnote \providecommand*{\multiplefootnotemarker}{3sp} -% we tag the separator as artifact +% \end{macrocode} +% +% We tag the separator as artifact +% \fmi{why is this done with \cs{providecommand}?} +% \begin{macrocode} \ExplSyntaxOn \providecommand*{\multfootsep}{\tag_mc_end_push:\tag_mc_begin:n{artifact},\tag_mc_end:\tag_mc_begin_pop:n{}} \ExplSyntaxOff @@ -2526,7 +2707,7 @@ {\mathparagraph\mathparagraph\mathparagraph}% } \newcommand\mpfootnotemark{% - \@ifnextchar[% + \@ifnextchar[%] \@xmpfootnotemark {% \stepcounter\@mpfn diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-graphic.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-graphic.dtx index f9457e0524f..158b0d2a9c4 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-graphic.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-graphic.dtx @@ -15,6 +15,8 @@ % https://github.com/latex3/latex2e/required/latex-lab % % for those people who are interested or want to report an issue. +\def\ltlabgraphicdate{2023-10-13} +\def\ltlabgraphicversion{0.80b} % %<*driver> \documentclass{l3doc} @@ -31,7 +33,7 @@ % \title{The \textsf{latex-lab-graphic} package\\ % Tagging of included graphics } % \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} -% \date{v0.8 2023-04-07} +% \date{v\ltlabgraphicversion\ \ltlabgraphicdate} % % \maketitle % @@ -174,7 +176,7 @@ % \begin{implementation} % \section{Implementation} % \begin{macrocode} -\ProvidesExplPackage {latex-lab-testphase-graphic} {2023-04-07} {0.8} +\ProvidesExplPackage {latex-lab-testphase-graphic} {\ltlabgraphicdate} {\ltlabgraphicversion} {Code related to the tagging of graphics} % \end{macrocode} % We load l3opacity for the debug code @@ -182,25 +184,16 @@ \RequirePackage{l3opacity} % \end{macrocode} % -%\subsection{Saving the position} -% We need a replacement for zref-savepos. This uses l3ref which loaded -% by the pdfmanagement/tagpdf. % -% TODO: this is perhaps needed in other places too and should be moved to -% l3ref!! -% \begin{macrocode} -\ref_attribute_gset:nnnn{xpos}{0}{shipout}{\int_use:N\tex_lastxpos:D} -\ref_attribute_gset:nnnn{ypos}{0}{shipout}{\int_use:N\tex_lastypos:D} -% \end{macrocode} - % \begin{macro}{\@@_graphic_savepos:n} -% this is the command which stores the position. It uses -% two savepos in case bidi needs it (see zref-savepos). +% this is the command which stores the position. Similar to +% zref-savepos it uses two savepos commands +% for the case that bidi changes the processing order. % \begin{macrocode} \cs_new_protected:Npn\@@_graphic_savepos:n #1 { \tex_savepos:D - \ref_label:nn{#1}{xpos,ypos,abspage} + \property_record:nn{#1}{xpos,ypos,abspage} \tex_savepos:D } \cs_generate_variant:Nn \@@_graphic_savepos:n {e} @@ -308,8 +301,7 @@ \fp_new:N\l_@@_graphic_lx_fp \fp_new:N\l_@@_graphic_uy_fp % \end{macrocode} -% this holds the scale value. Currently this only the one from -% \cs{Gin@scalex} +% this holds the scale value. Either \cs{Gin@scalex} or (if that is !) \cs{Gin@scaley} % \begin{macrocode} \fp_new:N\l_@@_graphic_scale_fp % \end{macrocode} @@ -351,8 +343,8 @@ { \tl_if_empty:NT\l_@@_graphic_alt_tl { - \msg_warning:nnx{tag}{alt-text-missing}{\l_@@_graphic_alt_dflt_tl} - \tl_set:Nx\l_@@_graphic_alt_tl {\l_@@_graphic_alt_dflt_tl} + \msg_warning:nne{tag}{alt-text-missing}{\l_@@_graphic_alt_dflt_tl} + \tl_set:Ne\l_@@_graphic_alt_tl {\l_@@_graphic_alt_dflt_tl} } \tag_struct_begin:n { @@ -468,7 +460,7 @@ % \begin{macrocode} \AddToHook{package/graphicx/after}[latex-lab] { - \define@key{Gin}{alt} {\tl_set:Nx\l_@@_graphic_alt_tl{\text_purify:n{#1}}} + \define@key{Gin}{alt} {\tl_set:Ne\l_@@_graphic_alt_tl{\text_purify:n{#1}}} \define@key{Gin}{artifact}[] { \bool_set_true:N \l_@@_graphic_artifact_bool @@ -476,7 +468,7 @@ } \define@key{Gin}{actualtext} { - \tl_set:Nx\l_@@_graphic_actual_tl{\text_purify:n{#1}} + \tl_set:Ne\l_@@_graphic_actual_tl{\text_purify:n{#1}} \bool_set_false:N \l_@@_graphic_BBox_bool } \define@key{Gin}{correct-BBox} @@ -507,7 +499,7 @@ \keys_define:nn{tag/picture} { ,alt .code:n = - {\tl_set:Nx\l_@@_graphic_alt_tl{\text_purify:n{#1}}} + {\tl_set:Ne\l_@@_graphic_alt_tl{\text_purify:n{#1}}} ,artifact .code:n = { \bool_set_true:N \l_@@_graphic_artifact_bool @@ -515,7 +507,7 @@ } ,actualtext .code:n = { - \tl_set:Nx\l_@@_graphic_actual_tl{\text_purify:n{#1}} + \tl_set:Ne\l_@@_graphic_actual_tl{\text_purify:n{#1}} \bool_set_false:N \l_@@_graphic_BBox_bool } ,correct-BBox .code:n = @@ -579,7 +571,12 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_graphic_get_scale: { - \fp_set:Nn \l_@@_graphic_scale_fp { \Gin@scalex } + \fp_set:Nn \l_@@_graphic_scale_fp + { + \str_if_eq:eeTF {\Gin@scalex} { ! } + { \Gin@scaley } + { \Gin@scalex } + } } % \end{macrocode} % \end{macro} @@ -634,7 +631,7 @@ (\l_@@_graphic_uy_fp-\l_@@_graphic_ly_fp-\l_@@_graphic_trim_ly_fp) * (-\l_@@_graphic_sin_fp) } - \tl_gset:Nx\g_@@_graphic_lx_tl + \tl_gset:Ne\g_@@_graphic_lx_tl { \fp_eval:n { @@ -649,7 +646,7 @@ +\l_@@_graphic_trim_lx_fp } } - \tl_gset:Nx\g_@@_graphic_ux_tl + \tl_gset:Ne\g_@@_graphic_ux_tl { \fp_eval:n { @@ -693,7 +690,7 @@ (\l_@@_graphic_uy_fp-\l_@@_graphic_ly_fp-\l_@@_graphic_trim_ly_fp) * \l_@@_graphic_cos_fp } - \tl_gset:Nx\g_@@_graphic_ly_tl + \tl_gset:Ne\g_@@_graphic_ly_tl { \fp_eval:n { @@ -707,7 +704,7 @@ + \l_@@_graphic_ly_fp + \l_@@_graphic_trim_ly_fp } } - \tl_gset:Nx\g_@@_graphic_uy_tl + \tl_gset:Ne\g_@@_graphic_uy_tl { \fp_eval:n { @@ -733,7 +730,7 @@ { \bool_if:NT\l_@@_graphic_bboxcorr_bool { - \tl_set:Nx #1 + \tl_set:Ne #1 { \fp_eval:n { @@ -742,7 +739,7 @@ \dim_to_decimal_in_bp:n {\seq_item:Nn \l_@@_graphic_bboxcorr_seq {1} } } } - \tl_set:Nx #2 + \tl_set:Ne #2 { \fp_eval:n { @@ -751,7 +748,7 @@ \dim_to_decimal_in_bp:n {\seq_item:Nn \l_@@_graphic_bboxcorr_seq {2} } } } - \tl_set:Nx #3 + \tl_set:Ne #3 { \fp_eval:n { @@ -760,7 +757,7 @@ \dim_to_decimal_in_bp:n {\seq_item:Nn \l_@@_graphic_bboxcorr_seq {3} } } } - \tl_set:Nx #4 + \tl_set:Ne #4 { \fp_eval:n { @@ -789,22 +786,22 @@ {\l_@@_graphic_BBox_bool} } { - \fp_set:Nn \l_@@_graphic_scale_fp { \Gin@scalex } + \__tag_graphic_get_scale: \@@_graphic_get_trim: \int_gincr:N\g_@@_graphic_int - \tl_set:Nx\l_@@_graphic_currentlabel_tl {_@@_graphic_\int_use:N \g_@@_graphic_int} + \tl_set:Ne\l_@@_graphic_currentlabel_tl {_@@_graphic_\int_use:N \g_@@_graphic_int} \@@_graphic_savepos:e { \l_@@_graphic_currentlabel_tl } - \tl_gset:Nx\g_@@_graphic_lx_tl + \tl_gset:Ne\g_@@_graphic_lx_tl { \dim_to_decimal_in_bp:n - { \@@_ref_value:enn {\l_@@_graphic_currentlabel_tl}{xpos}{0}sp } + { \property_ref:een {\l_@@_graphic_currentlabel_tl}{xpos}{0}sp } } - \tl_gset:Nx\g_@@_graphic_ly_tl + \tl_gset:Ne\g_@@_graphic_ly_tl { \dim_to_decimal_in_bp:n - { \@@_ref_value:enn {\l_@@_graphic_currentlabel_tl}{ypos}{0}sp } + { \property_ref:een {\l_@@_graphic_currentlabel_tl}{ypos}{0}sp } } - \tl_gset:Nx\g_@@_graphic_ux_tl + \tl_gset:Ne\g_@@_graphic_ux_tl { \fp_eval:n { @@ -813,7 +810,7 @@ \dim_to_decimal_in_bp:n { \Gin@req@width } } } - \tl_gset:Nx\g_@@_graphic_uy_tl + \tl_gset:Ne\g_@@_graphic_uy_tl { \fp_eval:n { @@ -827,7 +824,7 @@ % \begin{macrocode} \legacy_if:nF {Gin@clip} { - \tl_gset:Nx\g_@@_graphic_ux_tl + \tl_gset:Ne\g_@@_graphic_ux_tl { \fp_eval:n { @@ -836,7 +833,7 @@ \l_@@_graphic_trim_ux_fp } } - \tl_gset:Nx\g_@@_graphic_lx_tl + \tl_gset:Ne\g_@@_graphic_lx_tl { \fp_eval:n { @@ -845,7 +842,7 @@ \l_@@_graphic_trim_lx_fp } } - \tl_gset:Nx\g_@@_graphic_uy_tl + \tl_gset:Ne\g_@@_graphic_uy_tl { \fp_eval:n { @@ -854,7 +851,7 @@ \l_@@_graphic_trim_uy_fp } } - \tl_gset:Nx\g_@@_graphic_ly_tl + \tl_gset:Ne\g_@@_graphic_ly_tl { \fp_eval:n { @@ -932,26 +929,26 @@ } { \int_gincr:N\g_@@_graphic_int - \tl_set:Nx\l_@@_graphic_currentlabel_tl {_@@_graphic_\int_use:N \g_@@_graphic_int} + \tl_set:Ne\l_@@_graphic_currentlabel_tl {_@@_graphic_\int_use:N \g_@@_graphic_int} \@@_graphic_savepos:e { \l_@@_graphic_currentlabel_tl } - \tl_gset:Nx \g_@@_graphic_lx_tl + \tl_gset:Ne \g_@@_graphic_lx_tl { \dim_to_decimal_in_bp:n - { \@@_ref_value:enn {\l_@@_graphic_currentlabel_tl}{xpos}{0}sp } + { \property_ref:een {\l_@@_graphic_currentlabel_tl}{xpos}{0}sp } } - \tl_gset:Nx \g_@@_graphic_ly_tl + \tl_gset:Ne \g_@@_graphic_ly_tl { \dim_to_decimal_in_bp:n - { \@@_ref_value:enn {\l_@@_graphic_currentlabel_tl}{ypos}{0}sp - \dp\@picbox } + { \property_ref:een {\l_@@_graphic_currentlabel_tl}{ypos}{0}sp - \dp\@picbox } } - \tl_gset:Nx \g_@@_graphic_ux_tl + \tl_gset:Ne \g_@@_graphic_ux_tl { \dim_to_decimal_in_bp:n { \g_@@_graphic_lx_tl bp + \wd\@picbox } } - \tl_gset:Nx \g_@@_graphic_uy_tl + \tl_gset:Ne \g_@@_graphic_uy_tl { \dim_to_decimal_in_bp:n { @@ -1042,7 +1039,7 @@ \int_compare:nNnT {\g_shipout_readonly_int} = - {\@@_ref_value:enn{_@@_graphic_#6}{abspage}{0}} + {\property_ref:een{_@@_graphic_#6}{abspage}{0}} { \put (#1 bp,\dim_eval:n{-\paperheight + \dim_eval:n{#2 bp}}) @@ -1066,7 +1063,7 @@ % \begin{macrocode} %<*latex-lab> \ProvidesFile{graphic-latex-lab-testphase.ltx} - [2023-04-07 v0.8 code related to the tagging included graphics] + [\ltlabgraphicdate\space v\ltlabgraphicversion\space latex-lab wrapper graphic] \RequirePackage{latex-lab-testphase-graphic} % % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-math.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-math.dtx new file mode 100644 index 00000000000..285471addc3 --- /dev/null +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-math.dtx @@ -0,0 +1,1313 @@ +% \iffalse meta-comment +% +%% File: latex-lab-math.dtx +% +% Copyright (C) 2022-2023 The LaTeX Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% +% The development version of the bundle can be found below +% +% https://github.com/latex3/latex2e/required/latex-lab +% +% for those people who are interested or want to report an issue. +% +% +\def\ltlabmathdate{2023-09-11} +\def\ltlabmathversion{0.5c} +% +%<*driver> +\documentclass{l3doc} +\EnableCrossrefs +\CodelineIndex + +\usepackage{todonotes} + +\begin{document} + \DocInput{latex-lab-math.dtx} +\end{document} +% +% +% \fi +% +% +% \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}}} +% \providecommand\class[1]{\texttt{#1.cls}} +% \providecommand\pkg[1]{\texttt{#1}} +% \providecommand\hook[1]{\texttt{#1}} +% +% ^^A \car {...} for marginal comments +% ^^A \car*{...} for longer inline comments +% +% \NewDocumentCommand\car{sO{}m} +% {\IfBooleanTF{#1}{\todo[inline,color=blue!10,#2]{#3}}^^A +% {\todo[color=blue!10,#2]{#3}}} +% +% \NewDocumentCommand\fmi{sO{}m} +% {\IfBooleanTF{#1}{\todo[inline,#2]{#3}}^^A +% {\todo[#2]{#3}}} +% +% +% +% \begin{abstract} +% This is an experimental prototype. It captures math material +% (basically okay, but the interfaces for packages aren't yet +% there) and tags the material (which is not yet anywhere near the +% final state). That part is provided for experimentation and to +% gather feedback, etc. +% \end{abstract} +% +% \tableofcontents +% +% \section{Introduction} +% \car*{Todo: update all the documentation! Both here and +% (what little there is!) in the implementation section.} +% +% 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 +% formula. For example, +%\begin{verbatim} +% \[ a \in A \text{ for all $a<5$} \] +%\end{verbatim} +% would only result in a single capture of the tokens +% ``\verb*/a \in A \text{ for all $a<5$}/''. +% +% \subsection{Code level interfaces} +% +% \begin{function}{\math_register_env:n, \math_register_env:nn} +% \begin{syntax} +% \cs{math_register_env:n} \Arg{env} +% \cs{math_register_env:nn} \Arg{env} \Arg{options} +% \end{syntax} +% Registers the \meta{env} as a math environment which should be captured +% and made available. This is necessary for all top-level math mode +% environments: low-level errors may result if these are not correct +% set up. One or more key--value \meta{options} may also be given: +% \begin{itemize} +% \item[\texttt{arg-spec}] The argument specification taken by the +% beginning of the environment; this is used to remove non-mathematical +% material. +% \end{itemize} +% \end{function} +% +% \begin{function}{\math_processor:n} +% \begin{syntax} +% \cs{math_processor:n} \Arg{tokens} +% \end{syntax} +% Declares that the captured math content should be passed to the +% \meta{tokens}, which will receive the environment type as |#1| and +% the content as |#2|. +% \end{function} +% +% \subsection{Document level interfaces} +% +% \begin{function}{\RegisterMathEnvironment} +% \begin{syntax} +% \cs{RegisterMathEnvironment} \oarg{options} \Arg{env} +% \end{syntax} +% Registers the \meta{env} as a math environment which should be captured +% and made available. This is necessary for all top-level math mode +% environments: low-level errors may result if these are not correct +% set up. One or more key--value \meta{options} may also be given: +% \begin{itemize} +% \item[\texttt{arg-spec}] The argument specification taken by the +% beginning of the environment; this is used to remove non-mathematical +% material. +% \end{itemize} +% \end{function} +% +% \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} +% that is itself within the math that should all be grabbed. +% \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 +% \end{enumerate} +% +% \subsection{Other problems} +% +% \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, +% \emph{even when the math is genuine} (and hence needs to be collected). +% \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{DeclareMathEnviornment}, +% 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} +% +% +% \subsection{Other ToDos} +% +% \begin{enumerate} +% \item Add (some of) the math display commands that were \enquote{lifted from +% plain}, e.g., \cs{displaylines} \cs{eqalign}(??). +% \item +% \end{enumerate} +% +% +% \car*{\cs{MaybeStop} (temporarily) not executed, as it is unknown on Chris' system.} +% \iffalse +% \MaybeStop{\setlength\IndexMin{200pt} \PrintIndex } +% \else +% \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } +% \fi +% +% \section{The Implementation} +% +% \begin{macrocode} +%<@@=math> +% \end{macrocode} +% +% \begin{macrocode} +%<*kernel> +% \end{macrocode} +% +% \subsection{File declaration} +% +% \car{Change description here?} +% \begin{macrocode} +\ProvidesFile{latex-lab-math.ltx} + [\ltlabmathdate\space + v\ltlabmathversion\space + Grab all the math(s) and tag it (experiments)] +% \end{macrocode} +% +% Temp loading \ldots +% \begin{macrocode} +\AddToHook{begindocument/before}{\RequirePackage{latex-lab-testphase-block}} +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOn +% \end{macrocode} +% +% \subsection{Setup} +% +% Loading \pkg{amsmath} is an absolute requirement: this avoids needing to +% have conditional definitions and deals with how to define \cs{[}/\cs{]} +% neatly. +% \begin{macrocode} +\tl_gput_right:Nn \@kernel@before@begindocument + { \RequirePackage { amsmath } } +% \end{macrocode} +% +% +% \subsection{Data structures} +% +% +% +% \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. +% +% +% \begin{macrocode} +\bool_new:N \l_@@_collected_bool +% \end{macrocode} +% \end{variable} +% +% \car{Change first tl name below: `env' $=>$ `info'?\\ +% Or do we need an extra storage tl?} +% +% \begin{variable}{\g_@@_grabbed_env_tl, \g_@@_grabbed_math_tl} +% \cs{g_@@_grabbed_env_tl} contains the name of the math environment (\texttt{math} in the case +% of inline math, \cs{g_@@_grabbed_math_tl} the math content. +% \begin{macrocode} +\tl_new:N \g_@@_grabbed_env_tl +\tl_new:N \g_@@_grabbed_math_tl +% \end{macrocode} +% \end{variable} +% +% \subsection{Interface commands} +% +% \begin{macro} +% {\@@_process:nn, \@@_process:Vn, \@@_process_auxi:nn, \@@_process_auxii:nn} +% A no-op place-holder; the internal wrapper means that it does not need to +% be concerned with internals. +% \begin{macrocode} +\cs_new_protected:Npn \@@_process:nn #1#2 + { + \legacy_if:nF { measuring@ } + { + \tl_if_in:nnF {#2} { \m@th } + { \tl_trim_spaces_apply:nN {#2} \@@_process_auxi:nn {#1} } + } + } +\cs_generate_variant:Nn \@@_process:nn { V } +\cs_new_protected:Npn \@@_process_auxi:nn #1#2 + { + \tl_gset:Nn \g_@@_grabbed_env_tl {#2} + \tl_gset:Nn \g_@@_grabbed_math_tl {#1} + \@@_process_auxii:nn {#2} {#1} + } +\cs_new_protected:Npn \@@_process_auxii:nn #1#2 { } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\math_processor:n} +% A simple installer +% \begin{macrocode} +\cs_new_protected:Npn \math_processor:n #1 + { \cs_set_protected:Npn \@@_process_auxii:nn ##1##2 {#1} } +% \end{macrocode} +% \end{macro} +% +% \subsection{Content grabbing} +% +% \begin{macro}{\@@_grab_dollar:w} +% Grab up to a single |$|, for inline math mode, suppressing +% any processing if the first token is \tn{m@th}. +% +% \fmi{what's that test doing?} +% +% \car{It is some kind of fix, to avoid the remote +% possibility that the math is empty, making the code +% produce an unwanted \texttt{\$\$}.} +% +%\car{cf.~the code for this in \cs{@ensuredmath}} +% +%\car{It is harmless but unnecessary in the dollardollar grabbing below.} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_dollar:w % $ + #1 $ + { +% \end{macrocode} +% \fmi{what's that test doing?} +% \begin{macrocode} + \tl_if_blank:nF {#1} + { + \@@_process:nn { math } {#1} % $ +% fairly simple this one +% \end{macrocode} +% We do not want math tagging in fakemath or when measuring, +% so we imitate the test inside \cs{@@_process:nn} for now, +% see https://github.com/latex3/tagging-project/issues/5 +% TODO: use socket to get more control about typesetting variants (tagged, drop etc)? +% \begin{macrocode} + \legacy_if:nTF { measuring@ } + { #1 $ } + { + \tl_if_in:nnTF {#1} { \m@th } + { #1 $ } + { + \tagmcend %end P-chunk, in code: \tag_mc_end_push: + \@kernel@math@begin + #1 $ + \@kernel@math@end + \tagmcbegin{} % restart P-chunk (whatsits in pdftex) + } + } + } + } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@@_grab_dollardollar:w} +% And for the classical \TeX{} display structure. +% \begin{macrocode} + +\skip_new:N \l_@@_tmpa_skip + +\cs_new_protected:Npn \@@_grab_dollardollar:w % $$ + #1 $$ + { + \tl_if_blank:nF {#1} + { + \@@_tag_dollardollar_display:nn { equation* }{#1} + #1 + $$ + } + } +% \end{macrocode} +% To allow to use the code without tagging we guard. But probably tagpdf should +% provide some tools for such manual para-ends. +% \begin{macrocode} +\cs_new_protected:Npn \@kernel@close@P { + \tag_if_active:T + { + \tagmcend %end P-chunk, should perhaps be \tag_mc_end_push: ... + \int_gincr:N \g__tag_para_end_int + \bool_if:NT \l__tag_para_show_bool + { \tag_mc_begin:n{artifact} + \rlap{\color_select:n{red}\tiny\ \int_use:N\g__tag_para_end_int} + \tag_mc_end: + } + \tag_struct_end: + } +} + + + +\cs_new_protected:Npn \@@_tag_dollardollar_display:nn #1#2 { + \@@_process:nn {#1} {#2} + \@kernel@close@P + \@kernel@math@begin +% \skip_set:Nn \belowdisplayskip {-\belowdisplayskip} +% \skip_set:Nn \belowdisplayshortskip {-\belowdisplayshortskip} +% \int_set:Nn \postdisplaypenalty {10000} +%% +% \group_insert_after:N \@@_tag_dollardollar_display_end: +} + +\cs_new_protected:Npn \@@_tag_dollardollar_display_end: { +% \typeout{== tag dollarldollar display end} +% \ShowTagging{struct-stack} + \tagpdfparaOff + \para_raw_end: + \tagpdfparaOn + \l_@@_tmpa_skip \lastskip + \@kernel@math@end + \penalty \postdisplaypenalty +% \end{macrocode} +% This reinserts the below display skips. It must be doubled to +% get the right amount: +% \begin{macrocode} + \skip_vertical:n { -\l_@@_tmpa_skip * 2 } +% + \@doendpe % this has no \end{...} to take care of it +} + +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@_grab_inline:w} +% Collect inline math content and deal with the need to move to math mode. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_inline:w % \( + #1 \) + { + \tl_if_blank:nF {#1} + { + \@@_process:nn { math } {#1} + $ #1 $ + } + \bool_set_false:N \l_@@_collected_bool + } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@@_grab_eqn:w} +% For the most common use of \cs{[}/\cs{]}: turn into an environment. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_eqn:w % \[ + #1 \] + { +% \typeout{collected? = \bool_if:NTF \l_@@_collected_bool {true}{false}} + \begin { equation* } #1 \end { equation* } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Marking math environments} +% +% A general mechanism for math mode environments that do not grab their +% content (\emph{cf.}~most \pkg{amsmath} environments). +% +% \begin{variable}{\l_@@_env_name_tl} +% To allow us to carry out \enquote{special effects} +% \begin{macrocode} +\tl_new:N \l_@@_env_name_tl +% \end{macrocode} +% \end{variable} +% +% Here we set up specialised handling of environments. The idea for the +% \texttt{arg-spec} key is that if an environment takes arguments, we +% don't worry during the main grabbing. Rather, we remove the arguments +% from the grabbed content and forward only the payload. That is done by +% (ab)using \pkg{ltcmd}. +% \begin{macrocode} +\keys_define:nn { @@ } + { + arg-spec .code:n = + { + \ExpandArgs { c } \DeclareDocumentCommand + { @@_env \l_@@_env_name_tl _aux: } + {#1} + { \@@_env_forward:w } + } + } +% \end{macrocode} +% +% \begin{macro}{\math_register_env:nn} +% \begin{macro}{\math_register_env:n} +% \begin{macro}{\RegisterMathEnvironment} +% Set up to capture environment content and make available. +% +% \begin{macrocode} +\cs_new_protected:Npn \math_register_env:nn #1#2 + { + \tl_set:Nn \l_@@_env_name_tl {#1} + \keys_set:nn { @@ } {#2} + \cs_gset_eq:cc { @@_env_ #1 _begin: } {#1} + \cs_gset_eq:cc { @@_env_ #1 _end: } { end #1 } +% + \ExpandArgs { nnx } \RenewDocumentEnvironment {#1} { b } + { +% \bool_set_true:N \exp_not:N \l_@@_collected_bool +% \cs_if_exist:cTF { @@_env #1 _aux: } +% { +% \exp_not:c { @@_env #1 _aux: } +% ####1 \exp_not:N \@@_env_end: {#1} +% } +% { \exp_not:N \@@_process:nn {#1} {####1} } + \exp_not:N \bool_if:NTF \exp_not:N \l_@@_collected_bool + { +% \typeout{===>B1} + } + { +% \typeout{===>B2} + \cs_if_exist:cTF { @@_env #1 _aux: } + { + \exp_not:c { @@_env #1 _aux: } + ####1 \exp_not:N \@@_env_end: {#1} + } + { \exp_not:N \@@_process:nn {#1} {####1} } + \exp_not:n { \@kernel@math@registered@begin } + \bool_set_true:N \exp_not:N \l_@@_collected_bool + } +% \exp_not:N \tracingall + \exp_not:c { @@_env_ #1 _begin: } + ####1 + \exp_not:c { @@_env_ #1 _end: } +% \exp_not:c { @@_env_ #1 _end: } +% \exp_not:N \tracingnone +% \exp_not:n { \@kernel@math@registered@end } + } + { + } + } + +\cs_set_protected:Npn \__cs_tmp:w #1 + { + \group_begin: + \exp_args:No \__cs_generate_internal_variant:n + { \tl_to_str:n {#1} } + \group_end: + } +\__cs_tmp:w { nnxx } + + +\cs_new_protected:Npn \math_register_halign_env:nn #1#2 + { + \tl_set:Nn \l_@@_env_name_tl {#1} + \keys_set:nn { @@ } {#2} + \cs_gset_eq:cc { @@_env_ #1 _begin: } {#1} + \cs_gset_eq:cc { @@_env_ #1 _end: } { end #1 } +% + \ExpandArgs { nnxx } \RenewDocumentEnvironment {#1} { b } + { +% \bool_set_true:N \exp_not:N \l_@@_collected_bool +% \cs_if_exist:cTF { @@_env #1 _aux: } +% { +% \exp_not:c { @@_env #1 _aux: } +% ####1 \exp_not:N \@@_env_end: {#1} +% } +% { \exp_not:N \@@_process:nn {#1} {####1} } + \exp_not:N \bool_if:NTF \exp_not:N \l_@@_collected_bool + { +% \typeout{===>B1} + } + { +% \typeout{===>B2} + \cs_if_exist:cTF { @@_env #1 _aux: } + { + \exp_not:c { @@_env #1 _aux: } + ####1 \exp_not:N \@@_env_end: {#1} + } + { \exp_not:N \@@_process:nn {#1} {####1} } + \exp_not:n { \@kernel@math@registered@begin } + \bool_set_true:N \exp_not:N \l_@@_collected_bool + } +% \exp_not:N \tracingall + \exp_not:c { @@_env_ #1 _begin: } + ####1 +% \exp_not:c { @@_env_ #1 _end: } +% \exp_not:N \tracingnone + } + { + \exp_not:c { @@_env_ #1 _end: } + } + } + +\cs_new_protected:Npn \math_register_odd_env:nn #1#2 + { + \tl_set:Nn \l_@@_env_name_tl {#1} + \keys_set:nn { @@ } {#2} + \cs_gset_eq:cc { @@_env_ #1 _begin: } {#1} + \cs_gset_eq:cc { @@_env_ #1 _end: } { end #1 } +% + \ExpandArgs { nnxx } \RenewDocumentEnvironment {#1} { b } + { + \exp_not:N \bool_if:NTF \exp_not:N \l_@@_collected_bool + { +% \typeout{===>B1} + } + { +% \typeout{===>B2} + \cs_if_exist:cTF { @@_env #1 _aux: } + { + \exp_not:c { @@_env #1 _aux: } + ####1 \exp_not:N \@@_env_end: {#1} + } + { \exp_not:N \@@_process:nn {#1} {####1} } + \exp_not:n { \@kernel@math@registered@begin } + \bool_set_true:N \exp_not:N \l_@@_collected_bool + } +% \exp_not:N \tracingall + \exp_not:c { @@_env_ #1 _begin: } + ####1 + } + { + \exp_not:c { @@_env_ #1 _end: } +% needed if we don't have $$...$$ +% \exp_not:n { \typeout{---> @kernel@math@registered@end }} + \exp_not:n { \@kernel@math@registered@end } + } + } + + +% FMi: compare with block change! +% +% \DeclareRobustCommand*\begin[1]{% +% \UseHook{env/#1/before}% +% \@ifundefined{#1}% +% {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% +% {\def\reserved@a{\def\@currenvir{#1}% +% \edef\@currenvline{\on@line}% +% \@execute@begin@hook{#1}% +% \csname #1\endcsname}}% +% \@ignorefalse +% \begingroup +% \@endpefalse % tmp!!! is it ok to drop this here? +% \reserved@a} + + +\cs_new:Npn \@kernel@math@registered@begin { +% \ShowTagging{struct-stack} +%\typeout{==>A1}\ShowTagging{struct-stack,mc-current} + \mode_if_vertical:TF + { +% \legacy_if:nTF { @endpe } +% { \legacy_if_set_false:n { @endpe } } +% { \__block_list_beginpar_vmode: } +% +% \typeout{==>~ at:~ \g__tag_struct_tag_tl} +% + \exp_args:Noo\str_if_eq:nnF \g__tag_struct_tag_tl { \l__tag_para_main_tag_tl } % needs correction! + { +% \typeout{==>A2} + \__block_beginpar_vmode: + } % needs correction! + } + { +% \typeout{==>A3} + \@kernel@close@P +% \tagmcend % needs correction! + } + \@kernel@math@begin + \tagpdfparaOff +% \typeout{==>MC1}\ShowTagging{mc-current} +} + +\cs_new:Npn \@kernel@math@registered@end { +% \typeout{==>MC2}\ShowTagging{mc-current} + \para_raw_end: + \tagpdfparaOn + \@kernel@math@end +% \typeout{==>MC3}\ShowTagging{mc-current} + \@endpetrue +} + +\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} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_env_forward:w} +% \begin{macrocode} +\cs_new_protected:Npn \@@_env_forward:w #1 \@@_env_end: #2 + { \@@_process:nn {#2} {#1} } +% \end{macrocode} +% \end{macro} +% +% \subsection{Document commands} +% +% \car*{Add one more here: \texttt{displaymath}, which +% is equivalent to \cs{[} , \cs{]}\\ +% and hence to the basic \texttt{equation*}.\\ +% Added in more recent branch.} +% +% \begin{macro} +% {\equation, \@@_equation_begin:, \equation*, \@@_equation_star_begin:} +% \begin{macro} +% {\endequation, \@@_equation_end:, \endequation*, \@@_equation_star_end:} +% These environments are not set up by \pkg{amsmath} to collect their body, +% so we do that here. This has to be done \emph{after} we can be sure +% \pkg{amsmath} is loaded. +% +% \car*{Note that with \pkg{amsmath} loaded, \texttt{equation*} and \texttt{equation}\\ +% are the two basics: they are used to define the other single-row\\ +% display environments, etc.} +% +% \begin{macrocode} +\tl_gput_right:Nn \@kernel@before@begindocument + { + \math_register_env:n { equation } + \math_register_env:n { equation* } +% at the moment register_env can only do display math +% \math_register_env:n { math } + \RenewDocumentEnvironment{math} {b}{$#1$}{} +% and this one doesn't work either +% \math_register_env:n { displaymath } + \RenewDocumentEnvironment{displaymath} {b}{\[#1\]}{} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\(, \)} +% If math mode has not been collected, we need to do that; otherwise, worry +% about whether we are in math mode or not. The closing command here can only +% occur inside a collected math block: otherwise it will be simply used as +% a delimiter. +% \begin{macrocode} +\cs_gset_protected:Npn \( % \) + { + \bool_if:NTF \l_@@_collected_bool + { + \mode_if_math:TF + { \@badmath } + { $ } + } + { + \@@_grab_inline:w + } + } % \( +\cs_gset_protected:Npn \) + { + \mode_if_math:TF + { $ } + { \@badmath } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\[, \]} +% Again, we need to watch for when \pkg{amsmath} is loaded after this code. +% The flag usage here is to cover the case where \cs{[}/\cs{]} is hidden +% inside another environment. In this case the grabbing happens on +% the outer level and should not be repeated. +% \begin{macrocode} +\tl_gput_right:Nn \@kernel@before@begindocument + { + \cs_gset_protected:Npn \[ % \] + { + \bool_if:NTF \l_@@_collected_bool + { \begin { equation* } } + { \@@_grab_eqn:w } + } % \[ + \cs_gset_protected:Npn \] + { + \bool_if:NTF \l_@@_collected_bool + { \end{ equation* } } + { \@badmath } + } + } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\ensuremath} +% A bit of nesting fun to make sure we collect only if required. +% \fmi{why does ensuremath need handling at all?} +% +% \car{Indeed! Currently, this is setup to process the math that +% it has anyways already captured as its argument; thus it is more +% efficient than leaving the capture to be repeated by the \cs{everymath}} +% +% \begin{macrocode} +%\cs_gset_protected:Npn \ensuremath #1 +% { +% \mode_if_math:TF +% {#1} +% { +% \bool_if:NTF \l_@@_collected_bool +% { \@ensuredmath {#1} } +% { +% \bool_set_true:N \l_@@_collected_bool +% \@@_process:nn { math } {#1} +% \@ensuredmath {#1} +% \bool_set_false:N \l_@@_collected_bool +% } +% } +% } +% \end{macrocode} +% \end{macro} +% +% \subsection{\cs{everymath} and \cs{everydisplay}} +% +% The business end for grabbing inline math and \enquote{raw} \TeX{} +% display. Most display math mode is actually handled elsewhere, as we +% have macro control. +% \begin{macrocode} + +\tl_new:N\tmpmathcontent + + +\def\@kernel@math@begin { +% \typeout{==>~math~begin} +% needs different handling if we support nesting + \tl_gset:Nx\tmpmathcontent + { + LaTeX~ formula~ starts~ + \exp_not:N\begin{\g_@@_grabbed_env_tl} + \space + \exp_not:V\g_@@_grabbed_math_tl + \space + \exp_not:N\end{\g_@@_grabbed_env_tl} + \space LaTeX~ formula~ ends~ + } + \tagstructbegin{tag=Formula, + AFinline-o=\tmpmathcontent, + title-o=\g_@@_grabbed_env_tl, + actualtext=\tmpmathcontent +% alt=\tmpmathcontent + } +% inner formula if multiple parts (not really implemented yet) + \grabaformulapartandstart +% the above does: +% \tagstructbegin{tag=Formula}\tagmcbegin{} +% or just +% \tagmcbegin{} +} +\def\@kernel@math@end { +% \typeout{==>~math~end} +% \ShowTagging{struct-stack} + \tagmcend + \if@subformulas + \tagstructend + \else + \fi + \tagstructend +% \ShowTagging{struct-stack} +} + +\exp_args:No \tex_everymath:D + { + \tex_the:D \tex_everymath:D + \bool_if:NF \l_@@_collected_bool + { + \bool_set_true:N \l_@@_collected_bool + \@@_grab_dollar:w + } + } + +\exp_args:No \tex_everydisplay:D + { + \tex_the:D \tex_everydisplay:D + \iftrue % this may have to be a settable flag! +% { +% \typeout{==>~ in~ everydisplay} +% \end{macrocode} +% flipping the \cs{belowdisplay} values is done so that we get (assumption) +% a negative skip and not make the page bigger then we take that out, +% then we add the tagging code (in \cs{@@_tag_dollardollar_display_end} ) and +% then we put a real \cs{postdisplaypenalty} in and +% the right skip (of which we don't know if it is short or a +% normal \cs{belowdisplayskip}). This might need some refinement if that skip +% is actually negative from the start +% (not sure it ever is and is worth bothering about) +% \begin{macrocode} + \skip_set:Nn \belowdisplayskip {-\belowdisplayskip} + \skip_set:Nn \belowdisplayshortskip {-\belowdisplayshortskip} + \int_set:Nn \postdisplaypenalty {10000} +% + \group_insert_after:N \@@_tag_dollardollar_display_end: +% } + \fi + \bool_if:NF \l_@@_collected_bool + { + \bool_set_true:N \l_@@_collected_bool + \@@_grab_dollardollar:w + } + } +% \end{macrocode} +% +% \subsection{Modifying kernel environments} +% +% We need to cover this even though it is, of course, not encouraged. +% \begin{macrocode} +\math_register_env:n { eqnarray } +\math_register_env:n { eqnarray* } +% \end{macrocode} +% +% Places where math mode is (ab)used. +% \begin{macrocode} +\clist_map_inline:nn + { tabular } + { + \AddToHook{ env / #1 / begin } + { \bool_set_true:N \l_@@_collected_bool } + } +% \end{macrocode} +% +% \begin{macro}{\@@_m@th:, \m@th} +% Handle non-math use of math mode. At present nesting isn't supported as +% \cs{m@th} pops up in a few places that \emph{are} math mode! +% \begin{macrocode} +\cs_new_eq:NN \@@_m@th: \m@th +\cs_gset_protected:Npn \m@th + { + \bool_set_true:N \l_@@_collected_bool + \@@_m@th: + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Modifying \pkg{amsmath}} +% +% \begin{macro}{\@@_amsmath_align@:nn} +% \begin{macro} +% { +% \@@_amsmath_gather@:n , +% \@@_amsmath_multline@:n +% } +% \begin{macro}{\align@} +% \begin{macro}{\gather@, \multline@} +% Mark up all of the display environments as the content is captured anyway. +% We then use an internal macro in each environment type to insert the +% processing code. Each of these is slightly different, so we cannot use a +% simple loop here. The test for \cs{split@tag} is required as the +% \texttt{split} environment internally uses \texttt{gather} \emph{when not +% within an \pkg{amsmath}} environment, for example inside \texttt{equation}. +% Without the precaution, we'd get two copies of the grabbed math, the second +% of which would start with \cs{split@tag}. +% \begin{macrocode} + + + +\tl_gput_right:Nn \@kernel@before@begindocument { +% +\renewenvironment{gather*}{% + \start@gather\st@rredtrue +} +{% +% this redirection doesn't work if we alter "gather"! + % \endgather +% so replace it with its real meaning + \math@cr \black@\totwidth@ \egroup + $$\ignorespacesafterend +} +% \end{macrocode} +% +% \begin{macrocode} +\def\common@align@ending { + \math@cr \black@\totwidth@ + \egroup + \ifingather@ + \restorealignstate@ + \egroup + \nonumber + \ifnum0=`{\fi\iffalse}\fi + \else + $$% + \fi + \ignorespacesafterend +} +\renewenvironment{alignat}{% + \start@align\z@\st@rredfalse +}{% + \common@align@ending +} +\renewenvironment{alignat*}{% + \start@align\z@\st@rredtrue +}{% + \common@align@ending +} +\renewenvironment{xalignat}{% + \start@align\@ne\st@rredfalse +}{% + \common@align@ending +} +\renewenvironment{xalignat*}{% + \start@align\@ne\st@rredtrue +}{% + \common@align@ending +} +\renewenvironment{xxalignat}{% + \start@align\tw@\st@rredtrue +}{% + \common@align@ending +} +\renewenvironment{align}{% + \start@align\@ne\st@rredfalse\m@ne +}{% + \common@align@ending +} +\renewenvironment{align*}{% + \start@align\@ne\st@rredtrue\m@ne +}{% + \common@align@ending +} +\renewenvironment{flalign}{% + \start@align\tw@\st@rredfalse\m@ne +}{% + \common@align@ending +} +\renewenvironment{flalign*}{% + \start@align\tw@\st@rredtrue\m@ne +}{% + \common@align@ending +} +% +\renewenvironment{multline*}{\start@multline\st@rredtrue} +{% + \iftagsleft@ \@xp\lendmultline@ \else \@xp\rendmultline@ \fi + \ignorespacesafterend +} +% \end{macrocode} +% Also for "false?" +% \begin{macrocode} +\def\measuring@true{\let\ifmeasuring@\iftrue\tag_stop:} +% \end{macrocode} +% +% \begin{macrocode} +% + \math_register_halign_env:nn {align}{} + \math_register_halign_env:nn {align*}{} + \math_register_halign_env:nn {flalign}{} + \math_register_halign_env:nn {flalign*}{} + \math_register_halign_env:nn {gather}{} + \math_register_halign_env:nn {gather*}{} + \math_register_halign_env:nn {multline}{} + \math_register_halign_env:nn {multline*}{} + \math_register_halign_env:nn {xalignat}{} + \math_register_halign_env:nn {xalignat*}{} + \math_register_halign_env:nn {xxalignat}{} + % + \@namedef{maketag @ @ @} #1{% +% \typeout{--->maketag @ @ @} + \ifmeasuring@ + \hbox{\m@th\normalfont#1}% + \else + \tagmcend \tagstructbegin{tag=Lbl}% + \tagmcbegin{tag=Lbl}% + \hbox{\m@th\normalfont#1}% + \tagmcend \tagstructend \tagmcbegin{}% + \fi + } +% \end{macrocode} +% +% \begin{macrocode} + \def\intertext@{% + \def\intertext##1{% + \ifvmode\else\\\@empty\fi + \noalign{% +% we have to flip the sign on the skip because we flipped it on the outside + \penalty\postdisplaypenalty\vskip-\belowdisplayskip + \vbox{ +% \end{macrocode} +% Stop tagging when measuring: +% \begin{macrocode} + \ifmeasuring@\tag_stop:\fi + \normalbaselines + \ifdim\linewidth=\columnwidth + \else \parshape\@ne \@totalleftmargin \linewidth + \fi +% \end{macrocode} +% End the previous mc:\fmi{if we use 2 levels of formulas this would +% need changing} +% \begin{macrocode} + \tag_mc_end_push: +% \end{macrocode} +% We are already in a par so we change now to Span:\fmi{not true any longer} +% \begin{macrocode} + \tagpdfsetup{paratag=P}% + \tagpdfparaOn + \noindent\ignorespaces##1\par +% \end{macrocode} +% Restart the MC +% \begin{macrocode} + \tag_mc_begin_pop:n{}}% + \penalty\predisplaypenalty\vskip\abovedisplayskip% + }% + } + } +% \end{macrocode} +% +% \begin{macrocode} +\@namedef{math@cr @ @ @ gather}{% + \ifst@rred\nonumber\fi + &\relax + \make@display@tag +% + \maybestartnewformulatag +% + \ifst@rred\else\global\@eqnswtrue\fi + \global\advance\row@\@ne + \cr +} +% \end{macrocode} +% +% \begin{macrocode} +\@namedef{math@cr @ @ @ align}{% + \ifst@rred\nonumber\fi + \if@eqnsw \global\tag@true \fi + \global\advance\row@\@ne + \add@amps\maxfields@ + \omit + \kern-\alignsep@ + \iftag@ + \setboxz@h{\@lign\strut@{\make@display@tag}}% + \place@tag + \fi +% + \maybestartnewformulatag +% + \ifst@rred\else\global\@eqnswtrue\fi + \global\lineht@\z@ + \cr +} +% \end{macrocode} +% +% \begin{macrocode} +\def\restore@math@cr{\@namedef{math@cr @ @ @}{ +% + \maybestartnewformulatag +% + \cr}} +\restore@math@cr +% \end{macrocode} +% +% \begin{macrocode} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% + +% \begin{macro}{} +% +% \begin{macrocode} +\cs_new:Npn \@@_split_at_nl_first:w #1 \\ #2 \\ #3 \s_stop + { + \quark_if_nil:nTF {#2} + { {#1} { } } + { + \@@_split_chk_if_begin:ww #1 \begin \q_nil \s_mark + #2 \\ #3 \s_stop + } + } +\cs_new:Npn \@@_split_chk_if_begin:ww #1 \begin #2 #3 \s_mark + #4 \\ \q_nil \\ \s_stop + { + \quark_if_nil:nTF {#2} + { {#1} {#4} } + { + \exp_after:wN \@@_split_collect_one_end:w + \@@_split_cleanup_begin_q_nil:w #1 \begin{#2} #3 \\ #4 \s_stop + { } { 1 } + } + } +\cs_new:Npn \@@_split_cleanup_begin_q_nil:w #1 \begin \q_nil {#1} +\cs_new:Npn \@@_split_collect_one_end:w #1 \end #2 #3 \s_stop #4 #5 + { + \exp_args:Nf \@@_split_check_count_begins:nnnn + { \@@_split_count_begins:n { #4 #1 } } {#5} + { #4 #1 \end{#2} } {#3} + } +\cs_new:Npn \@@_split_count_begins:n #1 + { \int_eval:n { 0 \@@_split_count_begins:w #1 \begin \q_nil } } +\cs_new:Npn \@@_split_count_begins:w #1 \begin #2 + { \quark_if_nil:nF {#2} { +1 \@@_split_count_begins:w } } +\cs_new:Npn \@@_split_check_count_begins:nnnn #1 #2 #3 #4 + { + \int_compare:nNnTF {#1} = {#2} + { + \exp_last_unbraced:Nf \@@_split_final_cleanup:nn + { \split:n { \@@_split_guard:n {#3} #4 } } + } + { + \exp_args:No \use_ii_i:nn + { \exp_after:wN { \int_value:w \int_eval:n { #2 + 1 } } } + { \@@_split_collect_one_end:w #4 \s_stop {#3} } + } + } +\cs_new:Npn \@@_split_final_cleanup:nn #1 #2 + { + \exp:w \@@_split_final_cleanup:w #1 + \@@_split_guard:n \q_nil \s_mark { } + {#2} + } +\cs_new:Npn \@@_split_final_cleanup:w #1 \@@_split_guard:n #2 #3 \s_mark #4 + { + \quark_if_nil:nTF {#2} + { \exp_end: { #4 #1 } } + { \@@_split_final_cleanup:w #3 \s_mark { #4 #1 #2 } } + } +\NewDocumentCommand \splitnl { mm +m } + { + \tl_set:Nf \l_tmpa_tl { \split:n {#3} } + \show \l_tmpa_tl + \exp_after:wN \__splitnl_aux:nnNN \l_tmpa_tl #1 #2 + } + + +\cs_new:Npn \split:n #1 { + \@@_split_at_nl_first:w #1 \\ \q_nil \\ \s_stop } + +\cs_new:Npn \@@_split_at_nl:NN #1#2 { + \tl_set:Nf \l_tmpa_tl { + \exp_after:wN \@@_split_at_nl_first:w #1 \\ \q_nil \\ \s_stop } + \exp_after:wN \@@_split_at_nl_aux:nnNN \l_tmpa_tl #1 #2 +} + +\cs_new_protected:Npn \@@_split_at_nl_aux:nnNN #1 #2 #3 #4 + { + \tl_gset:Nn #4 {#1} + \tl_gset:Nn #3 {#2} +} + +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\maybestartnewformulatag} +% +% \begin{macrocode} + +\newif\if@subformulas +\tl_new:N \result + +\cs_new_protected:Npn\grabaformulapartandstart { + \@@_split_at_nl:NN \g_@@_grabbed_math_tl \result + \typeout{====>first-result=\meaning\result} + \typeout{====>first-tmpmathcontent=\meaning\g_@@_grabbed_math_tl} + \tl_if_empty:NTF \g_@@_grabbed_math_tl + { + \typeout{====>formula~ has~ no~ subparts} + \global\@subformulasfalse + } + { + \typeout{====>formula~ has~ subparts} + \global\@subformulastrue + \edef\resulttitle{\g_@@_grabbed_env_tl\space (part)} + \tagstructbegin{tag=Formula, +% \end{macrocode} +% For now we don't put anything in /alt or /ActualText on subformulas +% \begin{macrocode} +% alt=\result, + title-o=\resulttitle + } + } + \tagmcbegin{} +} + +\cs_new_protected:Npn\grabaformulapartandmayberestart { + \@@_split_at_nl:NN \g_@@_grabbed_math_tl \result + \typeout{====>result=\meaning\result} + \typeout{====>tmpmathcontent=\meaning\g_@@_grabbed_math_tl} +% \tl_if_empty:NTF \g_@@_grabbed_math_tl +% { +% \typeout{====>tmpmathcontent=empty} +% } +% { +% \typeout{====>tmpmathcontent=not-empty} + \edef\resulttitle{\g_@@_grabbed_env_tl\space (part)} + \tagstructbegin{tag=Formula, + alt=\result, + title-o=\resulttitle + } +% } + \tagmcbegin{} +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macrocode} +\def\maybestartnewformulatag { +\if@subformulas + \ifmeasuring@\else +% + \tl_if_empty:NF \g_@@_grabbed_math_tl + { + \tagmcend + \tagstructend + \grabaformulapartandmayberestart + } + \fi +\fi +} +% \end{macrocode} +% +% The breqn packages changes catcodes and that isn't yet covered +% by our mechanism. +% \begin{macrocode} +%\AddToHook{package/breqn/after}{ +% \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} +% +% \end{macrocode} +% +% \begin{macrocode} +% +% \end{macrocode} +% +% \Finale +% +% diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathtagging.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathtagging.dtx deleted file mode 100644 index 923001f5596..00000000000 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathtagging.dtx +++ /dev/null @@ -1,1280 +0,0 @@ -% \iffalse meta-comment -% -%% File: latex-lab-mathtagging.dtx -% -% Copyright (C) 2022-2023 The LaTeX Project -% -% It may be distributed and/or modified under the conditions of the -% LaTeX Project Public License (LPPL), either version 1.3c of this -% license or (at your option) any later version. The latest version -% of this license is in the file -% -% https://www.latex-project.org/lppl.txt -% -% -% The development version of the bundle can be found below -% -% https://github.com/latex3/latex2e/required/latex-lab -% -% for those people who are interested or want to report an issue. -% -% -\def\ltmathtaggingdate{2023-03-08} -\def\ltmathtaggingversion{v0.5a} -% -%<*driver> -\documentclass{l3doc} -\EnableCrossrefs -\CodelineIndex - -\usepackage{todonotes} - -\begin{document} - \DocInput{latex-lab-mathtagging.dtx} -\end{document} -% -% -% \fi -% -% -% \title{The \texttt{latex-lab-mathtagging} code\thanks{}} -% \author{Frank Mittelbach, Joseph Wright, \LaTeX{} Project} -% -% \maketitle -% -% \newcommand\NEW[1]{\marginpar{\mbox{}\hfill\fbox{New: #1}}} -% \providecommand\class[1]{\texttt{#1.cls}} -% \providecommand\pkg[1]{\texttt{#1}} -% \providecommand\hook[1]{\texttt{#1}} -% -% ^^A \car {...} for marginal comments -% ^^A \car*{...} for longer inline comments -% -% \NewDocumentCommand\car{sO{}m} -% {\IfBooleanTF{#1}{\todo[inline,color=blue!10,#2]{#3}}^^A -% {\todo[color=blue!10,#2]{#3}}} -% -% \NewDocumentCommand\fmi{sO{}m} -% {\IfBooleanTF{#1}{\todo[inline,#2]{#3}}^^A -% {\todo[#2]{#3}}} -% -% -% -% \begin{abstract} -% This is an experimental prototype. It captures math material -% (basically okay, but the interfaces for packages aren't yet -% there) and tags the material (which is not yet anywhere near the -% final state). That part is provided for experimentation and to -% gather feedback, etc. -% \end{abstract} -% -% \tableofcontents -% -% \section{Introduction} -% \car*{Todo: update all the documentation! Both here and -% (what little there is!) in the implementation section.} -% -% 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 -% formula. For example, -%\begin{verbatim} -% \[ a \in A \text{ for all $a<5$} \] -%\end{verbatim} -% would only result in a single capture of the tokens -% ``\verb*/a \in A \text{ for all $a<5$}/''. -% -% \subsection{Code level interfaces} -% -% \begin{function}{\math_register_env:n, \math_register_env:nn} -% \begin{syntax} -% \cs{math_register_env:n} \Arg{env} -% \cs{math_register_env:nn} \Arg{env} \Arg{options} -% \end{syntax} -% Registers the \meta{env} as a math environment which should be captured -% and made available. This is necessary for all top-level math mode -% environments: low-level errors may result if these are not correct -% set up. One or more key--value \meta{options} may also be given: -% \begin{itemize} -% \item[\texttt{arg-spec}] The argument specification taken by the -% beginning of the environment; this is used to remove non-mathematical -% material. -% \end{itemize} -% \end{function} -% -% \begin{function}{\math_processor:n} -% \begin{syntax} -% \cs{math_processor:n} \Arg{tokens} -% \end{syntax} -% Declares that the captured math content should be passed to the -% \meta{tokens}, which will receive the environment type as |#1| and -% the content as |#2|. -% \end{function} -% -% \subsection{Document level interfaces} -% -% \begin{function}{\RegisterMathEnvironment} -% \begin{syntax} -% \cs{RegisterMathEnvironment} \oarg{options} \Arg{env} -% \end{syntax} -% Registers the \meta{env} as a math environment which should be captured -% and made available. This is necessary for all top-level math mode -% environments: low-level errors may result if these are not correct -% set up. One or more key--value \meta{options} may also be given: -% \begin{itemize} -% \item[\texttt{arg-spec}] The argument specification taken by the -% beginning of the environment; this is used to remove non-mathematical -% material. -% \end{itemize} -% \end{function} -% -% \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} -% that is itself within the math that should all be grabbed. -% \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 -% \end{enumerate} -% -% \subsection{Other problems} -% -% \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, -% \emph{even when the math is genuine} (and hence needs to be collected). -% \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{DeclareMathEnviornment}, -% 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.} -% -% \item -% \end{enumerate} -% -% -% \subsection{Other ToDos} -% -% \begin{enumerate} -% \item Add (some of) the math display commands that were \enquote{lifted from -% plain}, e.g., \cs{displaylines} \cs{eqalign}(??). -% \item -% \end{enumerate} -% -% -% \car*{\cs{MaybeStop} (temporarily) not executed, as it is unknown on Chris' system.} -% \iffalse -% \MaybeStop{\setlength\IndexMin{200pt} \PrintIndex } -% \else -% \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } -% \fi -% -% \section{The Implementation} -% -% \begin{macrocode} -%<@@=math> -% \end{macrocode} -% -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% -% \subsection{File declaration} -% -% \car{Change description here?} -% \begin{macrocode} -\ProvidesFile{latex-lab-mathtagging.ltx} - [\ltmathtaggingdate\space - \ltmathtaggingversion\space - Grab all the math(s) and tag it (experiments)] -% \end{macrocode} -% -% Temp loading \ldots -% \begin{macrocode} -\AddToHook{begindocument/before}{\RequirePackage{latex-lab-testphase-block-tagging}} -% \end{macrocode} -% -% \begin{macrocode} -\ExplSyntaxOn -% \end{macrocode} -% -% \subsection{Setup} -% -% Loading \pkg{amsmath} is an absolute requirement: this avoids needing to -% have conditional definitions and deals with how to define \cs{[}/\cs{]} -% neatly. -% \begin{macrocode} -\tl_gput_right:Nn \@kernel@before@begindocument - { \RequirePackage { amsmath } } -% \end{macrocode} -% -% -% \subsection{Data structures} -% -% -% -% \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. -% -% -% \begin{macrocode} -\bool_new:N \l_@@_collected_bool -% \end{macrocode} -% \end{variable} -% -% \car{Change first tl name below: `env' $=>$ `info'?\\ -% Or do we need an extra storage tl?} -% -% \begin{variable}{\g_@@_grabbed_env_tl, \g_@@_grabbed_math_tl} -% \begin{macrocode} -\tl_new:N \g_@@_grabbed_env_tl -\tl_new:N \g_@@_grabbed_math_tl -% \end{macrocode} -% \end{variable} -% -% \subsection{Interface commands} -% -% \begin{macro} -% {\@@_process:nn, \@@_process:Vn, \@@_process_auxi:nn, \@@_process_auxii:nn} -% A no-op place-holder; the internal wrapper means that it does not need to -% be concerned with internals. -% \begin{macrocode} -\cs_new_protected:Npn \@@_process:nn #1#2 - { - \legacy_if:nF { measuring@ } - { - \tl_if_in:nnF {#2} { \m@th } - { \tl_trim_spaces_apply:nN {#2} \@@_process_auxi:nn {#1} } - } - } -\cs_generate_variant:Nn \@@_process:nn { V } -\cs_new_protected:Npn \@@_process_auxi:nn #1#2 - { - \tl_gset:Nn \g_@@_grabbed_env_tl {#2} - \tl_gset:Nn \g_@@_grabbed_math_tl {#1} - \@@_process_auxii:nn {#2} {#1} - } -\cs_new_protected:Npn \@@_process_auxii:nn #1#2 { } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\math_processor:n} -% A simple installer -% \begin{macrocode} -\cs_new_protected:Npn \math_processor:n #1 - { \cs_set_protected:Npn \@@_process_auxii:nn ##1##2 {#1} } -% \end{macrocode} -% \end{macro} -% -% \subsection{Content grabbing} -% -% \begin{macro}{\@@_grab_dollar:w} -% Grab up to a single |$|, for inline math mode, suppressing -% any processing if the first token is \tn{m@th}. -% -% \fmi{what's that test doing?} -% -% \car{It is some kind of fix, to avoid the remote -% possibility that the math is empty, making the code -% produce an unwanted \texttt{\$\$}.} -% -%\car{cf.~the code for this in \cs{@ensuredmath}} -% -%\car{It is harmless but unnecessary in the dollardollar grabbing below.} -% -% \begin{macrocode} -\cs_new_protected:Npn \@@_grab_dollar:w % $ - #1 $ - { -% \end{macrocode} -% \fmi{what's that test doing?} -% \begin{macrocode} - \tl_if_blank:nF {#1} - { - \@@_process:nn { math } {#1} % $ -% fairly simple this one - \tagmcend %end P-chunk, in code: \tag_mc_end_push: - \@kernel@math@begin - #1 $ - \@kernel@math@end - \tagmcbegin{} % restart P-chunk (whatsits in pdftex) - } - } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\@@_grab_dollardollar:w} -% And for the classical \TeX{} display structure. -% \begin{macrocode} - -\skip_new:N \l_@@_tmpa_skip - -\cs_new_protected:Npn \@@_grab_dollardollar:w % $$ - #1 $$ - { - \tl_if_blank:nF {#1} - { - \@@_tag_dollardollar_display:nn { equation* }{#1} - #1 - $$ - } - } - -\cs_new_protected:Npn \@kernel@close@P { - \tagmcend %end P-chunk, in code: \tag_mc_end_push: - \int_gincr:N \g__tag_para_end_int - \bool_if:NT \l__tag_para_show_bool - { \tag_mc_begin:n{artifact} - \rlap{\color_select:n{red}\tiny\ \int_use:N\g__tag_para_end_int} - \tag_mc_end: - } - \tag_struct_end: -} - - - -\cs_new_protected:Npn \@@_tag_dollardollar_display:nn #1#2 { - \@@_process:nn {#1} {#2} - \@kernel@close@P - \@kernel@math@begin -% \skip_set:Nn \belowdisplayskip {-\belowdisplayskip} -% \skip_set:Nn \belowdisplayshortskip {-\belowdisplayshortskip} -% \int_set:Nn \postdisplaypenalty {10000} -%% -% \group_insert_after:N \@@_tag_dollardollar_display_end: -} - -\cs_new_protected:Npn \@@_tag_dollardollar_display_end: { -% \typeout{== tag dollarldollar display end} -% \ShowTagging{struct-stack} - \tagpdfparaOff - \para_raw_end: - \tagpdfparaOn - \l_@@_tmpa_skip \lastskip - \@kernel@math@end - \penalty \postdisplaypenalty - \skip_vertical:n { -\l_@@_tmpa_skip } -% - \@doendpe % this has no \end{...} to take care of it -} - - -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@@_grab_inline:w} -% Collect inline math content and deal with the need to move to math mode. -% \begin{macrocode} -\cs_new_protected:Npn \@@_grab_inline:w % \( - #1 \) - { - \tl_if_blank:nF {#1} - { - \@@_process:nn { math } {#1} - $ #1 $ - } - \bool_set_false:N \l_@@_collected_bool - } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\@@_grab_eqn:w} -% For the most common use of \cs{[}/\cs{]}: turn into an environment. -% \begin{macrocode} -\cs_new_protected:Npn \@@_grab_eqn:w % \[ - #1 \] - { -% \typeout{collected? = \bool_if:NTF \l_@@_collected_bool {true}{false}} - \begin { equation* } #1 \end { equation* } - } -% \end{macrocode} -% \end{macro} -% -% \subsection{Marking math environments} -% -% A general mechanism for math mode environments that do not grab their -% content (\emph{cf.}~most \pkg{amsmath} environments). -% -% \begin{variable}{\l_@@_env_name_tl} -% To allow us to carry out \enquote{special effects} -% \begin{macrocode} -\tl_new:N \l_@@_env_name_tl -% \end{macrocode} -% \end{variable} -% -% Here we set up specialised handling of environments. The idea for the -% \texttt{arg-spec} key is that if an environment takes arguments, we -% don't worry during the main grabbing. Rather, we remove the arguments -% from the grabbed content and forward only the payload. That is done by -% (ab)using \pkg{ltcmd}. -% \begin{macrocode} -\keys_define:nn { @@ } - { - arg-spec .code:n = - { - \ExpandArgs { c } \DeclareDocumentCommand - { @@_env \l_@@_env_name_tl _aux: } - {#1} - { \@@_env_forward:w } - } - } -% \end{macrocode} -% -% \begin{macro}{\math_register_env:nn} -% \begin{macro}{\math_register_env:n} -% \begin{macro}{\RegisterMathEnvironment} -% Set up to capture environment content and make available. -% -% \begin{macrocode} -\cs_new_protected:Npn \math_register_env:nn #1#2 - { - \tl_set:Nn \l_@@_env_name_tl {#1} - \keys_set:nn { @@ } {#2} - \cs_gset_eq:cc { @@_env_ #1 _begin: } {#1} - \cs_gset_eq:cc { @@_env_ #1 _end: } { end #1 } -% - \ExpandArgs { nnx } \RenewDocumentEnvironment {#1} { b } - { -% \bool_set_true:N \exp_not:N \l_@@_collected_bool -% \cs_if_exist:cTF { @@_env #1 _aux: } -% { -% \exp_not:c { @@_env #1 _aux: } -% ####1 \exp_not:N \@@_env_end: {#1} -% } -% { \exp_not:N \@@_process:nn {#1} {####1} } - \exp_not:N \bool_if:NTF \exp_not:N \l_@@_collected_bool - { -% \typeout{===>B1} - } - { -% \typeout{===>B2} - \cs_if_exist:cTF { @@_env #1 _aux: } - { - \exp_not:c { @@_env #1 _aux: } - ####1 \exp_not:N \@@_env_end: {#1} - } - { \exp_not:N \@@_process:nn {#1} {####1} } - \exp_not:n { \@kernel@math@registered@begin } - \bool_set_true:N \exp_not:N \l_@@_collected_bool - } -% \exp_not:N \tracingall - \exp_not:c { @@_env_ #1 _begin: } - ####1 - \exp_not:c { @@_env_ #1 _end: } -% \exp_not:c { @@_env_ #1 _end: } -% \exp_not:N \tracingnone -% \exp_not:n { \@kernel@math@registered@end } - } - { - } - } - -\cs_set_protected:Npn \__cs_tmp:w #1 - { - \group_begin: - \exp_args:No \__cs_generate_internal_variant:n - { \tl_to_str:n {#1} } - \group_end: - } -\__cs_tmp:w { nnxx } - - -\cs_new_protected:Npn \math_register_halign_env:nn #1#2 - { - \tl_set:Nn \l_@@_env_name_tl {#1} - \keys_set:nn { @@ } {#2} - \cs_gset_eq:cc { @@_env_ #1 _begin: } {#1} - \cs_gset_eq:cc { @@_env_ #1 _end: } { end #1 } -% - \ExpandArgs { nnxx } \RenewDocumentEnvironment {#1} { b } - { -% \bool_set_true:N \exp_not:N \l_@@_collected_bool -% \cs_if_exist:cTF { @@_env #1 _aux: } -% { -% \exp_not:c { @@_env #1 _aux: } -% ####1 \exp_not:N \@@_env_end: {#1} -% } -% { \exp_not:N \@@_process:nn {#1} {####1} } - \exp_not:N \bool_if:NTF \exp_not:N \l_@@_collected_bool - { -% \typeout{===>B1} - } - { -% \typeout{===>B2} - \cs_if_exist:cTF { @@_env #1 _aux: } - { - \exp_not:c { @@_env #1 _aux: } - ####1 \exp_not:N \@@_env_end: {#1} - } - { \exp_not:N \@@_process:nn {#1} {####1} } - \exp_not:n { \@kernel@math@registered@begin } - \bool_set_true:N \exp_not:N \l_@@_collected_bool - } -% \exp_not:N \tracingall - \exp_not:c { @@_env_ #1 _begin: } - ####1 -% \exp_not:c { @@_env_ #1 _end: } -% \exp_not:N \tracingnone - } - { - \exp_not:c { @@_env_ #1 _end: } - } - } - -\cs_new_protected:Npn \math_register_odd_env:nn #1#2 - { - \tl_set:Nn \l_@@_env_name_tl {#1} - \keys_set:nn { @@ } {#2} - \cs_gset_eq:cc { @@_env_ #1 _begin: } {#1} - \cs_gset_eq:cc { @@_env_ #1 _end: } { end #1 } -% - \ExpandArgs { nnxx } \RenewDocumentEnvironment {#1} { b } - { - \exp_not:N \bool_if:NTF \exp_not:N \l_@@_collected_bool - { -% \typeout{===>B1} - } - { -% \typeout{===>B2} - \cs_if_exist:cTF { @@_env #1 _aux: } - { - \exp_not:c { @@_env #1 _aux: } - ####1 \exp_not:N \@@_env_end: {#1} - } - { \exp_not:N \@@_process:nn {#1} {####1} } - \exp_not:n { \@kernel@math@registered@begin } - \bool_set_true:N \exp_not:N \l_@@_collected_bool - } -% \exp_not:N \tracingall - \exp_not:c { @@_env_ #1 _begin: } - ####1 - } - { - \exp_not:c { @@_env_ #1 _end: } -% needed if we don't have $$...$$ -% \exp_not:n { \typeout{---> @kernel@math@registered@end }} - \exp_not:n { \@kernel@math@registered@end } - } - } - - -% FMi: compare with block change! -% -% \DeclareRobustCommand*\begin[1]{% -% \UseHook{env/#1/before}% -% \@ifundefined{#1}% -% {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% -% {\def\reserved@a{\def\@currenvir{#1}% -% \edef\@currenvline{\on@line}% -% \@execute@begin@hook{#1}% -% \csname #1\endcsname}}% -% \@ignorefalse -% \begingroup -% \@endpefalse % tmp!!! is it ok to drop this here? -% \reserved@a} - - -\cs_new:Npn \@kernel@math@registered@begin { -% \ShowTagging{struct-stack} -%\typeout{==>A1}\ShowTagging{struct-stack,mc-current} - \mode_if_vertical:TF - { -% \legacy_if:nTF { @endpe } -% { \legacy_if_set_false:n { @endpe } } -% { \__block_list_beginpar_vmode: } -% -% \typeout{==>~ at:~ \g__tag_struct_tag_tl} -% - \exp_args:Noo\str_if_eq:nnF \g__tag_struct_tag_tl { \l__tag_para_main_tag_tl } % needs correction! - { -% \typeout{==>A2} - \__block_beginpar_vmode: - } % needs correction! - } - { -% \typeout{==>A3} - \@kernel@close@P -% \tagmcend % needs correction! - } - \@kernel@math@begin - \tagpdfparaOff -% \typeout{==>MC1}\ShowTagging{mc-current} -} - -\cs_new:Npn \@kernel@math@registered@end { -% \typeout{==>MC2}\ShowTagging{mc-current} - \para_raw_end: - \tagpdfparaOn - \@kernel@math@end -% \typeout{==>MC3}\ShowTagging{mc-current} - \@endpetrue -} - -\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} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_env_forward:w} -% \begin{macrocode} -\cs_new_protected:Npn \@@_env_forward:w #1 \@@_env_end: #2 - { \@@_process:nn {#2} {#1} } -% \end{macrocode} -% \end{macro} -% -% \subsection{Document commands} -% -% \car*{Add one more here: \texttt{displaymath}, which -% is equivalent to \cs{[} , \cs{]}\\ -% and hence to the basic \texttt{equation*}.\\ -% Added in more recent branch.} -% -% \begin{macro} -% {\equation, \@@_equation_begin:, \equation*, \@@_equation_star_begin:} -% \begin{macro} -% {\endequation, \@@_equation_end:, \endequation*, \@@_equation_star_end:} -% These environments are not set up by \pkg{amsmath} to collect their body, -% so we do that here. This has to be done \emph{after} we can be sure -% \pkg{amsmath} is loaded. -% -% \car*{Note that with \pkg{amsmath} loaded, \texttt{equation*} and \texttt{equation}\\ -% are the two basics: they are used to define the other single-row\\ -% display environments, etc.} -% -% \begin{macrocode} -\tl_gput_right:Nn \@kernel@before@begindocument - { - \math_register_env:n { equation } - \math_register_env:n { equation* } -% at the moment register_env can only do display math -% \math_register_env:n { math } - \RenewDocumentEnvironment{math} {b}{$#1$}{} -% and this one doesn't work either -% \math_register_env:n { displaymath } - \RenewDocumentEnvironment{displaymath} {b}{\[#1\]}{} - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\(, \)} -% If math mode has not been collected, we need to do that; otherwise, worry -% about whether we are in math mode or not. The closing command here can only -% occur inside a collected math block: otherwise it will be simply used as -% a delimiter. -% \begin{macrocode} -\cs_gset_protected:Npn \( % \) - { - \bool_if:NTF \l_@@_collected_bool - { - \mode_if_math:TF - { \@badmath } - { $ } - } - { - \bool_set_true:N \l_@@_collected_bool - \@@_grab_inline:w - } - } % \( -\cs_gset_protected:Npn \) - { - \mode_if_math:TF - { $ } - { \@badmath } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\[, \]} -% Again, we need to watch for when \pkg{amsmath} is loaded after this code. -% The flag usage here is to cover the case where \cs{[}/\cs{]} is hidden -% inside another environment. In this case the grabbing happens on -% the outer level and should not be repeated. -% \begin{macrocode} -\tl_gput_right:Nn \@kernel@before@begindocument - { - \cs_gset_protected:Npn \[ % \] - { - \bool_if:NTF \l_@@_collected_bool - { \begin { equation* } } - { \@@_grab_eqn:w } - } % \[ - \cs_gset_protected:Npn \] - { - \bool_if:NTF \l_@@_collected_bool - { \end{ equation* } } - { \@badmath } - } - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\ensuremath} -% A bit of nesting fun to make sure we collect only if required. -% \fmi{why does ensuremath need handling at all?} -% -% \car{Indeed! Currently, this is setup to process the math that -% it has anyways already captured as its argument; thus it is more -% efficient than leaving the capture to be repeated by the \cs{everymath}} -% -% \begin{macrocode} -%\cs_gset_protected:Npn \ensuremath #1 -% { -% \mode_if_math:TF -% {#1} -% { -% \bool_if:NTF \l_@@_collected_bool -% { \@ensuredmath {#1} } -% { -% \bool_set_true:N \l_@@_collected_bool -% \@@_process:nn { math } {#1} -% \@ensuredmath {#1} -% \bool_set_false:N \l_@@_collected_bool -% } -% } -% } -% \end{macrocode} -% \end{macro} -% -% \subsection{\cs{everymath} and \cs{everydisplay}} -% -% The business end for grabbing inline math and \enquote{raw} \TeX{} -% display. Most display math mode is actually handled elsewhere, as we -% have macro control. -% \begin{macrocode} - -\tl_new:N\tmpmathcontent - - -\def\@kernel@math@begin { -% \typeout{==>~math~begin} -% needs different handling if we support nesting - \tl_gset:Nx\tmpmathcontent - { - LaTeX~ formula~ starts~ - \exp_not:N\begin{\g__math_grabbed_env_tl} - \space - \exp_not:V\g__math_grabbed_math_tl - \space - \exp_not:N\end{\g__math_grabbed_env_tl} - \space LaTeX~ formula~ ends~ - } - \tagstructbegin{tag=Formula, - AFinline-o=\tmpmathcontent, - title-o=\g__math_grabbed_env_tl, - actualtext=\tmpmathcontent -% alt=\tmpmathcontent - } -% inner formula if multiple parts (not really implemented yet) - \grabaformulapartandstart -% the above does: -% \tagstructbegin{tag=Formula}\tagmcbegin{} -% or just -% \tagmcbegin{} -} -\def\@kernel@math@end { -% \typeout{==>~math~end} -% \ShowTagging{struct-stack} - \tagmcend - \if@subformulas - \tagstructend - \else - \fi - \tagstructend -% \ShowTagging{struct-stack} -} - -\exp_args:No \tex_everymath:D - { - \tex_the:D \tex_everymath:D - \bool_if:NF \l_@@_collected_bool - { - \bool_set_true:N \l_@@_collected_bool - \@@_grab_dollar:w - } - } -\exp_args:No \tex_everydisplay:D - { - \tex_the:D \tex_everydisplay:D - \iftrue % this may have to be a settable flag! -% { -% \typeout{==>~ in~ everydisplay} - \skip_set:Nn \belowdisplayskip {-\belowdisplayskip} - \skip_set:Nn \belowdisplayshortskip {-\belowdisplayshortskip} - \int_set:Nn \postdisplaypenalty {10000} -% - \group_insert_after:N \@@_tag_dollardollar_display_end: -% } - \fi - \bool_if:NF \l_@@_collected_bool - { - \bool_set_true:N \l_@@_collected_bool - \@@_grab_dollardollar:w - } - } -% \end{macrocode} -% -% \subsection{Modifying kernel environments} -% -% We need to cover this even though it is, of course, not encouraged. -% \begin{macrocode} -\math_register_env:n { eqnarray } -\math_register_env:n { eqnarray* } -% \end{macrocode} -% -% Places where math mode is (ab)used. -% \begin{macrocode} -\clist_map_inline:nn - { tabular } - { - \AddToHook{ env / #1 / begin } - { \bool_set_true:N \l_@@_collected_bool } - } -% \end{macrocode} -% -% \begin{macro}{\@@_m@th:, \m@th} -% Handle non-math use of math mode. At present nesting isn't supported as -% \cs{m@th} pops up in a few places that \emph{are} math mode! -% \begin{macrocode} -\cs_new_eq:NN \@@_m@th: \m@th -\cs_gset_protected:Npn \m@th - { - \bool_set_true:N \l_@@_collected_bool - \@@_m@th: - } -% \end{macrocode} -% \end{macro} -% -% \subsection{Modifying \pkg{amsmath}} -% -% \begin{macro}{\@@_amsmath_align@:nn} -% \begin{macro} -% { -% \@@_amsmath_gather@:n , -% \@@_amsmath_multline@:n -% } -% \begin{macro}{\align@} -% \begin{macro}{\gather@, \multline@} -% Mark up all of the display environments as the content is captured anyway. -% We then use an internal macro in each environment type to insert the -% processing code. Each of these is slightly different, so we cannot use a -% simple loop here. The test for \cs{split@tag} is required as the -% \texttt{split} environment internally uses \texttt{gather} \emph{when not -% within an \pkg{amsmath}} environment, for example inside \texttt{equation}. -% Without the precaution, we'd get two copies of the grabbed math, the second -% of which would start with \cs{split@tag}. -% \begin{macrocode} - - - -\tl_gput_right:Nn \@kernel@before@begindocument { -% -\renewenvironment{gather*}{% - \start@gather\st@rredtrue -} -{% -% this redirection doesn't work if we alter "gather"! - % \endgather -% so replace it with its real meaning - \math@cr \black@\totwidth@ \egroup - $$\ignorespacesafterend -} -% \end{macrocode} -% -% \begin{macrocode} -\def\common@align@ending { - \math@cr \black@\totwidth@ - \egroup - \ifingather@ - \restorealignstate@ - \egroup - \nonumber - \ifnum0=`{\fi\iffalse}\fi - \else - $$% - \fi - \ignorespacesafterend -} -\renewenvironment{alignat}{% - \start@align\z@\st@rredfalse -}{% - \common@align@ending -} -\renewenvironment{alignat*}{% - \start@align\z@\st@rredtrue -}{% - \common@align@ending -} -\renewenvironment{xalignat}{% - \start@align\@ne\st@rredfalse -}{% - \common@align@ending -} -\renewenvironment{xalignat*}{% - \start@align\@ne\st@rredtrue -}{% - \common@align@ending -} -\renewenvironment{xxalignat}{% - \start@align\tw@\st@rredtrue -}{% - \common@align@ending -} -\renewenvironment{align}{% - \start@align\@ne\st@rredfalse\m@ne -}{% - \common@align@ending -} -\renewenvironment{align*}{% - \start@align\@ne\st@rredtrue\m@ne -}{% - \common@align@ending -} -\renewenvironment{flalign}{% - \start@align\tw@\st@rredfalse\m@ne -}{% - \common@align@ending -} -\renewenvironment{flalign*}{% - \start@align\tw@\st@rredtrue\m@ne -}{% - \common@align@ending -} -% -\renewenvironment{multline*}{\start@multline\st@rredtrue} -{% - \iftagsleft@ \@xp\lendmultline@ \else \@xp\rendmultline@ \fi - \ignorespacesafterend -} -% \end{macrocode} -% Also for "false?" -% \begin{macrocode} -\def\measuring@true{\let\ifmeasuring@\iftrue\tag_stop:} -% \end{macrocode} -% -% \begin{macrocode} -% - \math_register_halign_env:nn {align}{} - \math_register_halign_env:nn {align*}{} - \math_register_halign_env:nn {flalign}{} - \math_register_halign_env:nn {flalign*}{} - \math_register_halign_env:nn {gather}{} - \math_register_halign_env:nn {gather*}{} - \math_register_halign_env:nn {multline}{} - \math_register_halign_env:nn {multline*}{} - \math_register_halign_env:nn {xalignat}{} - \math_register_halign_env:nn {xalignat*}{} - \math_register_halign_env:nn {xxalignat}{} - % - \@namedef{maketag @ @ @} #1{% -% \typeout{--->maketag @ @ @} - \ifmeasuring@ - \hbox{\m@th\normalfont#1}% - \else - \tagmcend \tagstructbegin{tag=Lbl}% - \tagmcbegin{tag=Lbl}% - \hbox{\m@th\normalfont#1}% - \tagmcend \tagstructend \tagmcbegin{}% - \fi - } -% \end{macrocode} -% -% \begin{macrocode} - \def\intertext@{% - \def\intertext##1{% - \ifvmode\else\\\@empty\fi - \noalign{% -% we have to flip the sign on the skip because we flipped it on the outside - \penalty\postdisplaypenalty\vskip-\belowdisplayskip - \vbox{ -% \end{macrocode} -% Stop tagging when measuring: -% \begin{macrocode} - \ifmeasuring@\tag_stop:\fi - \normalbaselines - \ifdim\linewidth=\columnwidth - \else \parshape\@ne \@totalleftmargin \linewidth - \fi -% \end{macrocode} -% End the previous mc:\fmi{if we use 2 levels of formulas this would -% need changing} -% \begin{macrocode} - \tag_mc_end_push: -% \end{macrocode} -% We are already in a par so we change now to Span:\fmi{not true any longer} -% \begin{macrocode} - \tagpdfsetup{paratag=P}% - \tagpdfparaOn - \noindent\ignorespaces##1\par -% \end{macrocode} -% Restart the MC -% \begin{macrocode} - \tag_mc_begin_pop:n{}}% - \penalty\predisplaypenalty\vskip\abovedisplayskip% - }% - } - } -% \end{macrocode} -% -% \begin{macrocode} -\@namedef{math@cr @ @ @ gather}{% - \ifst@rred\nonumber\fi - &\relax - \make@display@tag -% - \maybestartnewformulatag -% - \ifst@rred\else\global\@eqnswtrue\fi - \global\advance\row@\@ne - \cr -} -% \end{macrocode} -% -% \begin{macrocode} -\@namedef{math@cr @ @ @ align}{% - \ifst@rred\nonumber\fi - \if@eqnsw \global\tag@true \fi - \global\advance\row@\@ne - \add@amps\maxfields@ - \omit - \kern-\alignsep@ - \iftag@ - \setboxz@h{\@lign\strut@{\make@display@tag}}% - \place@tag - \fi -% - \maybestartnewformulatag -% - \ifst@rred\else\global\@eqnswtrue\fi - \global\lineht@\z@ - \cr -} -% \end{macrocode} -% -% \begin{macrocode} -\def\restore@math@cr{\@namedef{math@cr @ @ @}{ -% - \maybestartnewformulatag -% - \cr}} -\restore@math@cr -% \end{macrocode} -% -% \begin{macrocode} -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% - -% \begin{macro}{} -% -% \begin{macrocode} -\cs_new:Npn \@@_split_at_nl_first:w #1 \\ #2 \\ #3 \s_stop - { - \quark_if_nil:nTF {#2} - { {#1} { } } - { - \@@_split_chk_if_begin:ww #1 \begin \q_nil \s_mark - #2 \\ #3 \s_stop - } - } -\cs_new:Npn \@@_split_chk_if_begin:ww #1 \begin #2 #3 \s_mark - #4 \\ \q_nil \\ \s_stop - { - \quark_if_nil:nTF {#2} - { {#1} {#4} } - { - \exp_after:wN \@@_split_collect_one_end:w - \@@_split_cleanup_begin_q_nil:w #1 \begin{#2} #3 \\ #4 \s_stop - { } { 1 } - } - } -\cs_new:Npn \@@_split_cleanup_begin_q_nil:w #1 \begin \q_nil {#1} -\cs_new:Npn \@@_split_collect_one_end:w #1 \end #2 #3 \s_stop #4 #5 - { - \exp_args:Nf \@@_split_check_count_begins:nnnn - { \@@_split_count_begins:n { #4 #1 } } {#5} - { #4 #1 \end{#2} } {#3} - } -\cs_new:Npn \@@_split_count_begins:n #1 - { \int_eval:n { 0 \@@_split_count_begins:w #1 \begin \q_nil } } -\cs_new:Npn \@@_split_count_begins:w #1 \begin #2 - { \quark_if_nil:nF {#2} { +1 \@@_split_count_begins:w } } -\cs_new:Npn \@@_split_check_count_begins:nnnn #1 #2 #3 #4 - { - \int_compare:nNnTF {#1} = {#2} - { - \exp_last_unbraced:Nf \@@_split_final_cleanup:nn - { \split:n { \@@_split_guard:n {#3} #4 } } - } - { - \exp_args:No \use_ii_i:nn - { \exp_after:wN { \int_value:w \int_eval:n { #2 + 1 } } } - { \@@_split_collect_one_end:w #4 \s_stop {#3} } - } - } -\cs_new:Npn \@@_split_final_cleanup:nn #1 #2 - { - \exp:w \@@_split_final_cleanup:w #1 - \@@_split_guard:n \q_nil \s_mark { } - {#2} - } -\cs_new:Npn \@@_split_final_cleanup:w #1 \@@_split_guard:n #2 #3 \s_mark #4 - { - \quark_if_nil:nTF {#2} - { \exp_end: { #4 #1 } } - { \@@_split_final_cleanup:w #3 \s_mark { #4 #1 #2 } } - } -\NewDocumentCommand \splitnl { mm +m } - { - \tl_set:Nf \l_tmpa_tl { \split:n {#3} } - \show \l_tmpa_tl - \exp_after:wN \__splitnl_aux:nnNN \l_tmpa_tl #1 #2 - } - - -\cs_new:Npn \split:n #1 { - \@@_split_at_nl_first:w #1 \\ \q_nil \\ \s_stop } - -\cs_new:Npn \@@_split_at_nl:NN #1#2 { - \tl_set:Nf \l_tmpa_tl { - \exp_after:wN \@@_split_at_nl_first:w #1 \\ \q_nil \\ \s_stop } - \exp_after:wN \@@_split_at_nl_aux:nnNN \l_tmpa_tl #1 #2 -} - -\cs_new_protected:Npn \@@_split_at_nl_aux:nnNN #1 #2 #3 #4 - { - \tl_gset:Nn #4 {#1} - \tl_gset:Nn #3 {#2} -} - -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\maybestartnewformulatag} -% -% \begin{macrocode} - -\newif\if@subformulas -\tl_new:N \result - -\cs_new_protected:Npn\grabaformulapartandstart { - \@@_split_at_nl:NN \g__math_grabbed_math_tl \result - \typeout{====>first-result=\meaning\result} - \typeout{====>first-tmpmathcontent=\meaning\g__math_grabbed_math_tl} - \tl_if_empty:NTF \g__math_grabbed_math_tl - { - \typeout{====>formula~ has~ no~ subparts} - \global\@subformulasfalse - } - { - \typeout{====>formula~ has~ subparts} - \global\@subformulastrue - \edef\resulttitle{\g__math_grabbed_env_tl\space (part)} - \tagstructbegin{tag=Formula, -% \end{macrocode} -% For now we don't put anything in /alt or /ActualText on subformulas -% \begin{macrocode} -% alt=\result, - title-o=\resulttitle - } - } - \tagmcbegin{} -} - -\cs_new_protected:Npn\grabaformulapartandmayberestart { - \@@_split_at_nl:NN \g__math_grabbed_math_tl \result - \typeout{====>result=\meaning\result} - \typeout{====>tmpmathcontent=\meaning\g__math_grabbed_math_tl} -% \tl_if_empty:NTF \g__math_grabbed_math_tl -% { -% \typeout{====>tmpmathcontent=empty} -% } -% { -% \typeout{====>tmpmathcontent=not-empty} - \edef\resulttitle{\g__math_grabbed_env_tl\space (part)} - \tagstructbegin{tag=Formula, - alt=\result, - title-o=\resulttitle - } -% } - \tagmcbegin{} -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% \begin{macrocode} -\def\maybestartnewformulatag { -\if@subformulas - \ifmeasuring@\else -% - \tl_if_empty:NF \g__math_grabbed_math_tl - { - \tagmcend - \tagstructend - \grabaformulapartandmayberestart - } - \fi -\fi -} -% \end{macrocode} -% -% The breqn packages changes catcodes and that isn't yet covered -% by our mechanism. -% \begin{macrocode} -%\AddToHook{package/breqn/after}{ -% \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} -% -% \end{macrocode} -% -% \begin{macrocode} -% -% \end{macrocode} -% -% \Finale -% -% - diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-minipage.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-minipage.dtx index 00b1d649a14..1d3ee828aa4 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-minipage.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-minipage.dtx @@ -16,6 +16,8 @@ % % for those people who are interested or want to report an issue. % +\def\ltlabminipagedate{2023-10-30} +\def\ltlabminipageversion{0.81c} %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -27,15 +29,11 @@ % % \fi % - -\def\ltlistsversion{v0.81} -\def\ltlistsdate{2023/05/10} - % % \title{The \textsf{latex-lab-minipage} package\\ % Changes related to the tagging of minipage and parbox} % \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} -% \date{\ltlistsversion\ \ltlistsdate} +% \date{v\ltlabminipageversion\ \ltlabminipagedate} % % \maketitle % @@ -51,12 +49,21 @@ % % \section{Introduction} % -% How to tag minipages and parboxes is still under discussion. +% How to best tag minipages and parboxes is still under discussion. % But as they start and contain paragraphs it is clear that -% hooks are needed to interrupt and restart the tagging. +% some sockets are needed to interrupt and restart the tagging. +% +% The tagging added is currently quite simple-minded. See the +% todo-testfiles and the code comments for some open points. % -% The tagging added is currently quite simple minded. See the todo-testfiles and the -% code comments for some open points. +% One of the main problems is how to properly embed them in the +% surrounding. When used in normal text (in a paragraph) they +% typically should close the \texttt{text} structure and reopen one +% at the end. But when used inside low-level \cs{vbox} or \cs{hbox} +% this is often wrong. The code uses now there two sockets +% \texttt{tagsupport/parbox/before} and +% \texttt{tagsupport/parbox/after} which can be set to noop, if +% necessary. % % \begin{macrocode} %<*package> @@ -64,9 +71,15 @@ % % \section{Implementation} % \begin{macrocode} -\ProvidesExplPackage {latex-lab-testphase-minipage} {2023-05-10} {0.81} +\ProvidesExplPackage {latex-lab-testphase-minipage} + {\ltlabminipagedate} {\ltlabminipageversion} {Code related to the tagging of minipages and parboxes} % \end{macrocode} +% As minipage uses a socket from the footnote code we must load the OR-code: +% \begin{macrocode} +\RequirePackage{latex-lab-testphase-new-or-1} +\RequirePackage{latex-lab-testphase-new-or-2} +% \end{macrocode} % % \subsection{Provide the kernel hooks} @@ -78,12 +91,13 @@ \def\@kernel@init@minipage{} \def\@kernel@init@parbox{} % \end{macrocode} -% We need a few hooks. +% We use sockets for the tag support code, as there will be cases where we want +% to exchange the content or disable it. % \begin{macrocode} -\def\@kernel@before@minipage{} -\def\@kernel@after@minipage{} -\def\@kernel@before@parbox{} -\def\@kernel@after@parbox{} +\socket_new:nn {tagsupport/minipage/before}{0} +\socket_new:nn {tagsupport/minipage/after} {0} +\socket_new:nn {tagsupport/parbox/before} {0} +\socket_new:nn {tagsupport/parbox/after}{0} % \end{macrocode} % % \subsection{Patch minipage} @@ -102,16 +116,16 @@ \setlength\@tempdima{#4}% \def\@mpargs{{#1}{#2}[#3]{#4}}% % \end{macrocode} -% insert the hook +% insert the socket % \begin{macrocode} - \@kernel@before@minipage% new + \socket_use:n{tagsupport/minipage/before}% new \setbox\@tempboxa\vbox\bgroup \color@begingroup \hsize\@tempdima \textwidth\hsize \columnwidth\hsize \@parboxrestore \def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@ - \let\@footnotetext\@mpfootnotetext + \socket_assign_plug:nn{fntext/process}{mp}% \let\@listdepth\@mplistdepth \@mplistdepth\z@ \@minipagerestore \@setminipage} @@ -131,13 +145,13 @@ \color@endgroup \egroup % \end{macrocode} -% as the parbox command is called, we must prevent that it adds its additional -% tagging commands: +% As the parbox command is called, we must prevent that it adds its +% additional tagging commands: % \begin{macrocode} \tag_stop:n{minipage} \expandafter\@iiiparbox\@mpargs{\unvbox\@tempboxa}% \tag_start:n{minipage} - \@kernel@after@minipage%new end ... + \socket_use:n{tagsupport/minipage/after} %new end ... } % \end{macrocode} % @@ -148,7 +162,7 @@ \leavevmode \@pboxswfalse \setlength\@tempdima{#4}% - \@kernel@before@parbox% new + \socket_use:n{tagsupport/parbox/before} \@begin@tempboxa\vbox{\hsize\@tempdima\@parboxrestore#5\@@par}% \ifx\relax#2\else \setlength\@tempdimb{#2}% @@ -163,7 +177,7 @@ \csname bm@#3\endcsname}% \if@pboxsw \m@th$\fi \@end@tempboxa% - \@kernel@after@parbox%new end + \socket_use:n{tagsupport/parbox/after} } % \end{macrocode} % @@ -172,7 +186,7 @@ % \begin{macrocode} \tl_new:N \l__ltboxes_tag_tl \tl_set:Nn \l__ltboxes_tag_tl {Div} -\cs_set_protected:Npn\@kernel@before@minipage +\socket_new_plug:nnn{tagsupport/minipage/before}{tag/dflt} { % \end{macrocode} % As there was a \cs{leavevmode} before that is a P/text open that we have to close. @@ -181,14 +195,27 @@ % \end{macrocode} % TODO: the P can be further up, we need a proper method to test and handle this. % \begin{macrocode} - \tag_struct_begin:n{tag=\l__ltboxes_tag_tl}} -\cs_set_protected:Npn\@kernel@after@minipage + \tag_struct_begin:n{tag=\l__ltboxes_tag_tl} + } +% \end{macrocode} +% similar for the other sockets: +% \begin{macrocode} +\socket_new_plug:nnn{tagsupport/minipage/after}{tag/dflt} {\tag_struct_end:\tag_struct_begin:n{tag=\l__tag_para_tag_tl}\tag_mc_begin_pop:n{}} -\cs_set_protected:Npn\@kernel@before@parbox + +\socket_new_plug:nnn{tagsupport/parbox/before}{tag/dflt} {\tag_mc_end_push:\tag_struct_end:\tag_struct_begin:n{tag=\l__ltboxes_tag_tl}} -\cs_set_protected:Npn\@kernel@after@parbox + +\socket_new_plug:nnn{tagsupport/parbox/after}{tag/dflt} {\tag_struct_end:\tag_struct_begin:n{tag=\l__tag_para_tag_tl}\tag_mc_begin_pop:n{}} % \end{macrocode} +% Activate the default tagging plug +% \begin{macrocode} +\socket_assign_plug:nn{tagsupport/minipage/before}{tag/dflt} +\socket_assign_plug:nn{tagsupport/minipage/after} {tag/dflt} +\socket_assign_plug:nn{tagsupport/parbox/before} {tag/dflt} +\socket_assign_plug:nn{tagsupport/parbox/after} {tag/dflt} +% \end{macrocode} % \begin{macrocode} % % \end{macrocode} @@ -196,7 +223,8 @@ % \begin{macrocode} %<*latex-lab> \ProvidesFile{minipage-latex-lab-testphase.ltx} - [2022-10-26 v0.8 code related to the tagging of sectioning commands] + [\ltlabminipagedate\space v\ltlabminipageversion + code related to the tagging of minipage and parbox] \RequirePackage{latex-lab-testphase-minipage} % % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-namespace.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-namespace.dtx new file mode 100644 index 00000000000..2ec9b0584bf --- /dev/null +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-namespace.dtx @@ -0,0 +1,100 @@ +% \iffalse meta-comment +% +%% File: latex-lab-namespace.dtx (C) Copyright 2023 LaTeX Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +%<*driver> +\documentclass{l3doc} +\usepackage{amstext} +\EnableCrossrefs +\CodelineIndex + +\usepackage{todonotes} + +\begin{document} + \DocInput{latex-lab-namespace.dtx} +\end{document} +% +% \fi +% \title{Prototype reimplementation of \LaTeXe{}'s role mapping} +% \author{\LaTeX{} Project, initial implementation Ulrike Fischer} +% \date{v0.8 2023-09-04} +% +% \maketitle +% +% \begin{documentation} +% +% +% +% \section{Introduction} +% +% This short file collects tag names from the \LaTeX{} namespace and their role mapping used +% in the latex-lab files. The names and the roles are not necessarly the final ones! +% +% Later settings of the same tag overwrite previous settings. +% The syntax of a line is a list of three strings ending with commas: +% \begin{verbatim} +% latex-tag, PDF-tag, name space, +% \end{verbatim} +% +% The name space is normally pdf2 with the exception of the following PDF-tags +% which are only in pdf namespace: +% Art, BlockQuote, TOC, TOCI, Index, Private, Quote, Note, +% Reference, BibEntry, Code. +% +% \end{documentation} +% \begin{implementation} +% \begin{macrocode} +%<*ns-latex-lab> +%% \ProvidesExplFile {tagpdf-ns-latex-lab.def} {2023-09-04} {0.8} +%% {latex} {https://www.latex-project.org/ns/lab/2022}{} +% \end{macrocode} +% \subsection{Role from tagpdf} +% The following tags are already set by tagpdf, so deleting here will not remove them. +% \begin{macrocode} +title, Title, pdf2, +part, Title, pdf2, +section, H1, pdf2, +subsection, H2, pdf2, +subsubsection,H3, pdf2, +paragraph, H4, pdf2, +subparagraph, H5, pdf2, +list, L, pdf2, +itemize, L, pdf2, +enumerate, L, pdf2, +description, L, pdf2, +quote, BlockQuote,pdf, +quotation, BlockQuote,pdf, +verbatim, Div, pdf2, +item, LI, pdf2, +itemlabel, Lbl, pdf2, +itembody, LBody, pdf2, +footnote, FENote, pdf2, +footnotemark, Lbl, pdf2, +footnotelabel,Lbl, pdf2, +text-unit, Part, pdf2, +text, P, pdf2, +% \end{macrocode} +% \subsection{From block code} +% \begin{macrocode} +theorem-like, Sect, pdf2, +verbatim, P, pdf2, +codeline, Sub, pdf2, +% \end{macrocode} +% \subsection{From float code} +% \begin{macrocode} +float, Aside, pdf2, +figures, Sect, pdf2, +tables, Sect, pdf2, +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \end{implementation} +\endinput diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-1.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-1.dtx index ef799e813c4..cc60f50de01 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-1.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-1.dtx @@ -9,6 +9,8 @@ % % https://www.latex-project.org/lppl.txt % +\def\ltlabneworIdate{2023-07-20} +\def\ltlabneworIversion{0.85a} %<*driver> \documentclass{l3doc} @@ -27,7 +29,8 @@ % % \title{Temporary output patches for tagging and better link support} % \author{Frank Mittelbach \and Ulrike Fischer} -% +% \date{v\ltlabneworIversion\ \ltlabneworIdate} +% % \maketitle % % \section{Introduction} @@ -47,12 +50,13 @@ % % \section{The Implementation} % \begin{macrocode} -%<*code> +%<*package> % \end{macrocode} % % \begin{macrocode} \ProvidesPackage{latex-lab-testphase-new-or-1} - [2022-11-94 v0.1a Temporary output patches for tagging and better link support] + [\ltlabneworIdate\space v\ltlabneworIversion\space + Temporary output patches for tagging and better link support] \RequirePackage{etoolbox} % \end{macrocode} % @@ -94,18 +98,36 @@ % % We patch \cs{@makecol}, if new-or-2 is loaded too it will overwrite that again. % \begin{macrocode} - \providecommand\@kernel@before@footins{} - \providecommand\@kernel@before@cclv{} +\providecommand\@kernel@before@footins{} +\providecommand\@kernel@tagsupport@@makecol{} - \patchcmd\@makecol - {\vskip\skip\footins} - {\vskip\skip\footins\@kernel@before@footins} - {\typeout{Patching \string\@makecol\space for tagging}}{\PATCHerror } +\patchcmd\@makecol + {\vskip\skip\footins} + {\vskip\skip\footins\@kernel@before@footins} + {\typeout{Patching \string\@makecol\space for tagging}}{\PATCHerror } -%for some reason patching with etoolbox only works in this order ... +\patchcmd\@makecol + {\let\@elt\relax} + {\@kernel@tagsupport@@makecol\let\@elt\relax} + {\typeout{Patching \string\@makecol\space for tagging}}{\PATCHerror } - \pretocmd\@makecol{\@kernel@before@cclv} - {\typeout{Patching \string\@makecol\space for tagging}}{\PATCHerror } +\AddToHook{package/footmisc/after} + {% + \def\@makecol{% + \setbox\@outputbox \box\@cclv + \@outputbox@removebskip + \@kernel@tagsupport@@makecol + \let\@elt\relax + \xdef\@freelist{\@freelist\@midlist}% + \global \let \@midlist \@empty + \@makecol@appendblocks + \ifvbox\@kludgeins + \@makespecialcolbox + \else + \@makenormalcolbox + \fi + \global \maxdepth \@maxdepth} +} % \end{macrocode} % \end{macro} % @@ -150,9 +172,16 @@ \def\@kernel@after@foot {\pdfannot_link_on:} \ExplSyntaxOff % \end{macrocode} -% % \begin{macrocode} -% +% +% \end{macrocode} +% \begin{macrocode} +%<*latex-lab> +\ProvidesFile{new-or-1-latex-lab-testphase.ltx} + [\ltlabneworIdate\space v\ltlabneworIversion\space + latex-lab wrapper new-or-1] +\RequirePackage{latex-lab-testphase-new-or-1} +% % \end{macrocode} % % \Finale diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-2.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-2.dtx index 74d56d687f6..d2011256b1a 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-2.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-2.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % %% File: latex-lab-new-or-2.dtx -% Copyright (C) 2022 The LaTeX Project +% Copyright (C) 2022-2023 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,6 +17,9 @@ % % for those people who are interested or want to report an issue. % +\def\ltlabneworIIdate{2023-09-04} +\def\ltlabneworIIversion{0.85c} + %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -31,41 +34,58 @@ % % \title{The \texttt{latex-lab-testphase-new-or-2} code\thanks{}} % \author{Frank Mittelbach, \LaTeX{} Project} -% +% % \date{v\ltlabneworIIversion\ \ltlabneworIIdate} % \maketitle % % \newcommand\fmi[1]{\begin{quote} TODO: \itshape #1\end{quote}} % \newcommand\NEW[1]{\marginpar{\mbox{}\hfill\fbox{New: #1}}} % \providecommand\pkg[1]{\texttt{#1}} % +% \providecommand\hook[1]{\texttt{#1\DescribeHook[noprint]{#1}}} +% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}} +% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}} +% +% \NewDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl} +% \NewDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl} +% \NewDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl} +% +% % \begin{abstract} +% This code implements changes to the output routine intended to be +% moved in the \LaTeX{} kernel at some point in the future. % \end{abstract} % -% \section{Introduction} -% -% This code implements changes to the output routine. % % % +% \section{Introduction} % -% \section{Hooks and configuration points} % -% Note: the configuration points do not have an interface mechanism -% yet and all their names are temporary right now. +% \section{Hooks and replaceable code blocks} % % -% \subsubsection{Configuration points} +% \subsubsection{Replaceable code blocks (sockets)} % % To cater for different layouts with respect to text, footnotes, -% and bottom-floats placements there are two configuration points for +% and bottom-floats placements there are two sockets for % now. % \begin{description} -% \item[\cs{@makecol@cfgpoint} (0 arguments)] +% \item[\socket{@makecol/outputbox} (0 arguments)] % -% In this configuration point the \cs{@outputbox} (holding the +% In code for this socket the \cs{@outputbox} (holding the % galley text for the current column or page) is augmented by % attaching floats and footnote areas together with appropriate -% spacing. Before the code is run any existing glue at the bottom +% spacing. +% +% Prior to calling the socket the output routine has already +% decided which floats go into which area and which get deferred. +% Therefore, the assumption is that the code in the socket attaches all +% areas that contain floats. If this is not done, then the order +% of floats is likely to be screwed up unless unused floats +% are moved to the defer list in an appropriate way (for now we +% don't offer any interface for that scenario). +% +% Before the code in the socket is run, any existing glue at the bottom % of the \cs{@outputbox} is removed and stored in a safe % place. If needed, it can be reinserted with one of the helper % commands. @@ -74,17 +94,25 @@ % \begin{description} % \item[\cs{@outputbox@append} (1 argument)] % +% \DescribeMacro[noprint]{@outputbox@append} +% % This general purpose command alters the \cs{@outputbox} box by % appending material to it. % % \item[\cs{@outputbox@appendfootnotes} (0 arguments)] % +% \DescribeMacro[noprint]{@outputbox@appendfootnotes} +% % This command appends the footnotes to the \cs{@outputbox} (if % there are any). If not, then it does nothing. % % \item[\cs{@outputbox@attachfloats} (0 arguments)] % \item[\cs{@outputbox@attachtopfloats} (0 arguments)] % \item[\cs{@outputbox@attachbottomfloats} (0 arguments)] +% +% \DescribeMacro[noprint]{@outputbox@attachfloats} +% \DescribeMacro[noprint]{@outputbox@attachtopfloats} +% \DescribeMacro[noprint]{@outputbox@attachbottomfloats} % % Attaching top and bottom floats can usually be done in one % go, but for special layouts we might want more control so we @@ -92,11 +120,16 @@ % % \item[\cs{@outputbox@reinsertbskip} (0 arguments)] % +% \DescribeMacro[noprint]{@outputbox@reinsertbskip} +% % Reinsert the bottom skip of the \cs{@outputbox} that was % saved before. % % \item[Testing for existence of material] % +% \DescribeMacro[noprint]{@if@footnotes@TF} +% \DescribeMacro[noprint]{@if@bfloats@TF} +% % There are a number of helpers to run conditional code % depending on whether or not there are footnotes or bottom % floats. They are \cs{@if@footnotes@TF} and @@ -104,16 +137,67 @@ % (names are likely to change). % % \end{description} -% This configuration point needs an appropriate definition; a -% default is already given in the kernel. % -% \item[\cs{@makecol@cfgpointii} (0 arguments)] +% \fmi{Decide on names for these helper commands. We could keep +% them similar to the above (because they are only supposed to be +% used by a few packages). However, we could alternatively use +% CamelCase names, under the assumption that classes may also +% directly define a plug for the socket, instead of loading a +% support package such as \pkg{footmisc} (or in addition +% to). --- decide} +% +% This socket cannot be empty but needs appropriate code; a set +% of suitable plugs for it are already given in the kernel. These +% are +% \begin{description} +% \item[\plug{space-footnotes-floats}] +% +% After the galley text there is a vertical \cs{vfill} +% followed by any footnotes followed by the bottom floats, if any. +% +% \item[\plug{floats-footnotes-space}] +% +% As before but the \cs{vfill} is at the bottom (page is +% ragged bottom). +% +% \item[\plug{footnotes-space-floats}] +% +% As before but the \cs{vfill} is between footnotes and floats. % -% This configuration point is used to manipulate the footnote +% \item[\plug{space-floats-footnotes}] +% +% Here the footnotes come last.\footnote{There are two more +% permutations, but neither of them has ever been requested so +% they aren't set up by default --- doing that in a class +% would be trivial though.} +% +% \item[\plug{floats-footnotes}] +% +% All excess space has to be distributed across the existing +% glue on the page, e.g., within the text galley, the +% separation between blocks, etc. +% The order is text, floats, footnotes. +% +% \item[\plug{footnotes-floats}] +% +% As the previous one but floats and footnotes are +% swapped. This is the \LaTeX{} default, i.e., this plug is +% assigned to the socket. +% +% \end{description} +% +%----------------------- +% +% \item[\socket{@makecol/footnotes} (0 arguments)] +% +% This socket is used to manipulate the footnote % material inside \cs{box}\cs{footins}. It if contains code, it % is supposed to do some processing of that box and then write % the result back into it (and nothing else!). By default it -% does nothing. +% does nothing, i.e., has the \plug{noop} assigned. +% +% If (short) footnotes are run as a paragraph this socket gets +% the plug \plug{para} assigned which is defined elsewhere. % % \end{description} % @@ -123,28 +207,32 @@ % \section{The Implementation} % % \begin{macrocode} -%<*code> +%<*package> % \end{macrocode} % % \subsection{File declaration} % \begin{macrocode} \ProvidesPackage{latex-lab-testphase-new-or-2} - [2022-11-04 v0.1c changes to the output routine] + [\ltlabneworIIdate\space v\ltlabneworIIversion\space + Changes to the output routine] % \end{macrocode} +% % \subsection{\cs{@makecol} reimplementation} % % In order for other packages to prepend or append code to -% \cs{@makecol}, they can use the generic command hooks -% \texttt{cmd/@makecol/before} and \texttt{cmd/@makecol/after}, so -% there is nothing we need to do here. +% \cs{@makecol} the generic command hooks +% \texttt{cmd/@makecol/before} and \texttt{cmd/@makecol/after} can +% be used, so for now there is nothing we need to do for this. % % % \begin{macro}{\@makecol} % \cs{@makecol} is shortened a lot, basically all the hardwired -% code in the middle has moved into a configuration point. +% code in the middle has moved into a socket. % \begin{macrocode} \def \@makecol {% - \@kernel@before@cclv +% \end{macrocode} +% Save away box 255 as \cs{@outputbox} to make it available for further adjustments. +% \begin{macrocode} \setbox\@outputbox \box\@cclv % \end{macrocode} % The only real addition is the next command which either does @@ -153,25 +241,31 @@ % \begin{macrocode} \@outputbox@removebskip % \end{macrocode} -% Any ``here'' floats in the \cs{@outputbox} are now handled so we +% Now a kernel hook for tagging. +% \fmi{The name is likely to change and it probably will eventually +% be replaced with a socket.} +% \begin{macrocode} + \@kernel@tagsupport@@makecol +% \end{macrocode} +% When this code is run any ``here'' floats in the \cs{@outputbox} are already handled, so we % recycle their registers and put them back to the \cs{@freelist}. % \begin{macrocode} \let\@elt\relax \xdef\@freelist{\@freelist\@midlist}% \global \let \@midlist \@empty % \end{macrocode} -% Here we have the configurable part. -% \fmi{Interface to configuration points will change in the future} +% Here we have the configurable part. This socket is supposed to add floats, +% footnotes and stretchable vertical space as appropriate to the \cs{@outputbox}. % \begin{macrocode} - \@makecol@cfgpoint + \UseSocket{@makecol/outputbox}% % \end{macrocode} -% The we deal with any \cs{enlargethispage} or run the normal code +% Then we deal with any \cs{enlargethispage} or run the normal code % to build a column. % \begin{macrocode} \ifvbox\@kludgeins - \@makespecialcolbox + \@make@specialcolbox \else - \@makenormalcolbox + \@make@normalcolbox \fi \global \maxdepth \@maxdepth } @@ -188,10 +282,10 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@makenormalcolbox} +% \begin{macro}{\@make@normalcolbox} % Taken out of \cs{@makecol} for readability. % \begin{macrocode} -\def \@makenormalcolbox {% +\def \@make@normalcolbox {% \setbox\@outputbox \vbox to\@colht {% \@texttop \@outputbox@depth \dp\@outputbox @@ -204,10 +298,10 @@ % \end{macro} % % -% \begin{macro}{\@makespecialcolbox} +% \begin{macro}{\@make@specialcolbox} % Make the colbox when \cs{enlargethispage} was used. % \begin{macrocode} -\def \@makespecialcolbox {% +\def \@make@specialcolbox {% \@outputbox@append {\vskip-\@outputbox@depth}% \@tempdima \@colht \ifdim \wd\@kludgeins>\z@ @@ -235,7 +329,7 @@ % \begin{macro}{\@outputbox@removebskip} % % This is really a bug fix for the kernel but one we only -% automatically make in new documents using \cs{DocumentMetadata}. +% automatically make in new documents that are using \cs{DocumentMetadata}. % \fmi{may make optional for legacy docs} % If % \cs{raggedbottom} is in force, footnotes get attached to the main @@ -248,7 +342,7 @@ % short, but the footnotes are not pushed to the bottom. % % In \pkg{footmisc} \cs{@outputbox@removebskip} is only applied when -% \pkg{footmisc} is called with with an option specifying the +% \pkg{footmisc} is called with an option specifying the % footnote placement, i.e., not in the default case. % In new documents we apply it always. % \begin{macrocode} @@ -270,6 +364,7 @@ \ifnum \gluestretchorder\@tempskipa>\z@ \vskip-\@tempskipa % \end{macrocode} +% % \begin{macro}{\@outputbox@reinsertbskip} % We also record the value so that it can be reinserted % elsewhere. As we have to do this globally, we also need to @@ -295,25 +390,28 @@ % % % -% \begin{macro}{\@kernel@before@cclv} -% \begin{macro}{\@kernel@before@footins} +% \begin{macro}{\@kernel@before@cclv, +% \@kernel@before@footins} % These two commands are internal kernel hooks intended for tagging -% support in case that is active. By default they do nothing (and +% support in case that is active. They should not be altered by package code! +% By default they do nothing (and % may have been defined already by \cs{DocumentMetadata}). +% \fmi{The names might change and perhaps each of them is turned +% into a socket named something like \socket{tagsupport/before/cclv} +% or similar.} % \begin{macrocode} \providecommand\@kernel@before@cclv{} \providecommand\@kernel@before@footins{} % \end{macrocode} % \end{macro} -% \end{macro} % % % % % \subsection{The output routine configuration components} % -% Here we provide the components that are used to define -% \cs{@makecol@cfgpoint}. +% Here we provide the components that are used to define code for the +% \socket{@makecol/outputbox} socket. % % % \begin{macro}{\@outputbox@append} @@ -346,7 +444,7 @@ % \begin{macro}{\@outputbox@appendfootnotes} % % This command appends the footnotes to the \cs{@outputbox} (if -% there are any). If not then it does nothing. +% there are any). If not, then it does nothing. % \begin{macrocode} \def\@outputbox@appendfootnotes {% \ifvoid\footins \else @@ -354,22 +452,34 @@ % First come two configuration points: what to do if we are in a split % footnote situation and a second one that does some manipulation % of the \cs{footins} box before it gets appended. -% \fmi{this code will get revised as part of CP handling in the future} +% \fmi{The code for handling split footnotes will get revised as part of socket handling in the future} % \begin{macrocode} \@makecol@handlesplitfootnotes - \@makecol@cfgpointii +% \end{macrocode} +% +% \begin{macrocode} + \UseSocket{@makecol/footnotes}% % \end{macrocode} % Then the footnotes are appended: % \begin{macrocode} \@outputbox@append{% \vskip \skip\footins +% \end{macrocode} +% This is a kernel hook for tagging. +% \fmi{The name is likely to change and it probably will eventually +% be replaced with a socket.} +% \begin{macrocode} \@kernel@before@footins +% \end{macrocode} +% +% \begin{macrocode} \color@begingroup \normalcolor \footnoterule % \end{macrocode} % Support for \pkg{pdfcolfoot}, eventually this can go once color -% is properly supported. +% is properly supported. The csname is constructed in case it +% doesn't exist. % \begin{macrocode} \csname pdfcolfoot@current\endcsname \unvbox \footins @@ -435,17 +545,16 @@ % % % -% \begin{macro}{\@makecol@cfgpointii} +% \begin{socketdecl}{@makecol/footnote} % -% Configuration point to support manipulation of footins box -% (result needs to be moved back in there). Used by the -% \texttt{para} option. -% \fmi{Interface will change in the future} +% The socket allowing the manipulation of \cs{footins} box +% (result needs to be moved back in there). Used when footnotes are +% reformatted into a single paragraph by the +% \texttt{para} option of \pkg{footmisc}. By default it does nothing. % \begin{macrocode} -\let \@makecol@cfgpointii \@empty +\NewSocket{@makecol/footnotes}{0} % \end{macrocode} -% -% \end{macro} +% \end{socketdecl} % % % @@ -497,27 +606,124 @@ % \subsection{The \cs{@makecol} configuration} % % -% \begin{macro}{\@makecol@cfgpoint} +% \begin{socketdecl}{@makecol/outputbox} +% We have one socket that is supposed to augment the \cs{@outputbox} +% by attaching floats and footnotes with appropriate spacing. +% +% \begin{macrocode} +\NewSocket{@makecol/outputbox}{0} +% \end{macrocode} +% \end{socketdecl} +% +% The following plugs are available for +% this socket: +% +% \begin{plugdecl}{space-footnotes-floats} +% After the galley text there is a vertical \cs{vfill} followed by +% any footnotes followed by the bottom floats, if any. +% \begin{macrocode} +\NewSocketPlug {@makecol/outputbox}{space-footnotes-floats} {% + \@if@footnotes@TF + {\@outputbox@append{\vfill}}% + {\@if@bfloats@TF + {\@outputbox@append{\vfill}}% + {\@outputbox@reinsertbskip}% + }% + \@outputbox@appendfootnotes + \@outputbox@attachfloats +} +% \end{macrocode} +% \end{plugdecl} % -% Here is only the configuration for the default case for now, -% others are provided by \pkg{footmisc}. +% \begin{plugdecl}{floats-footnotes-space} +% As before but the \cs{vfill} is at the bottom (page is ragged +% bottom). +% \begin{macrocode} +\NewSocketPlug {@makecol/outputbox}{floats-footnotes-space} {% + \@outputbox@attachfloats + \@if@footnotes@TF + {\@outputbox@append{\vfill}}% + {\@outputbox@reinsertbskip}% + \@outputbox@appendfootnotes +} +% \end{macrocode} +% \end{plugdecl} % +% \begin{plugdecl}{footnotes-space-floats} +% As before but the \cs{vfill} is between footnotes and floats. % \begin{macrocode} - \def\@makecol@cfgpoint {% - \@outputbox@appendfootnotes - \@outputbox@attachfloats +\NewSocketPlug {@makecol/outputbox}{footnotes-space-floats} {% + \@outputbox@appendfootnotes + \@if@bfloats@TF + {\@outputbox@append{\vfill}}% + {\@outputbox@reinsertbskip}% + \@outputbox@attachfloats +} % \end{macrocode} -% We do, however, reinsert the bottom skip from \cs{newpage} if it +% \end{plugdecl} +% +% \begin{plugdecl}{space-floats-footnotes} +% Here the footnotes come last.\footnote{There are two more +% permutations, but neither of them has ever been requested so +% they aren't set up by default --- doing that in a class +% would be trivial though.} +% \begin{macrocode} +\NewSocketPlug {@makecol/outputbox}{space-floats-footnotes} {% + \@if@footnotes@TF + {\@outputbox@append{\vfill}}% + {\@if@bfloats@TF + {\@outputbox@append{\vfill}}% + {\@outputbox@reinsertbskip}}% + \@outputbox@attachfloats + \@outputbox@appendfootnotes +} +% \end{macrocode} +% \end{plugdecl} +% +% +% +% \begin{plugdecl}{floats-footnotes} +% All excess space has to be distributed across the existing +% glue on the page, e.g., within the text galley, the +% separation between blocks, etc. +% The order is text, floats, footnotes. +% \begin{macrocode} +\NewSocketPlug {@makecol/outputbox}{floats-footnotes} {% + \@outputbox@attachfloats + \@outputbox@appendfootnotes +% \end{macrocode} +% We do reinsert the bottom skip from \cs{newpage} if it % was taken out earlier. This is, strictly speaking, not necessary % in most cases, but it is a \cs{vfil} while \cs{raggedbottom} is % only generating \verb=\vspace{0pt plus .0001fil}=, so if you have % several \cs{vfil} on the page before the \cs{newpage} you would % alter the space distribution if one is taken out. % \begin{macrocode} - \@outputbox@reinsertbskip - } + \@outputbox@reinsertbskip +} % \end{macrocode} -% \end{macro} +% +% \end{plugdecl} +% +% \begin{plugdecl}{footnotes-floats} +% \begin{macrocode} +\NewSocketPlug {@makecol/outputbox}{footnotes-floats} {% + \@outputbox@appendfootnotes + \@outputbox@attachfloats + \@outputbox@reinsertbskip +} +% \end{macrocode} +% The \texttt{footnote-floats} plug is the default used by +% \LaTeX{}; it can be overwritten either through \pkg{footmisc} or +% by assigning any of the other plugs (or by coding yet another +% plug for the socket). +% \begin{macrocode} +\AssignSocketPlug {@makecol/outputbox}{footnotes-floats} +% \end{macrocode} +% \end{plugdecl} +% +% +% % % % \section {Replacement for the \pkg{footmisc} package} @@ -532,13 +738,14 @@ % % \section {Temp stuff that is related but should go to the kernel} % +% This is the code from \texttt{latex-lab-footnotes.dtx}. % \begin{macrocode} \input{latex-lab-footnotes.ltx} % \end{macrocode} % % % \begin{macrocode} -% +% % \end{macrocode} % % \Finale diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-sec.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-sec.dtx index 5df3803b548..ae7a0b85c30 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-sec.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-sec.dtx @@ -16,6 +16,8 @@ % % for those people who are interested or want to report an issue. % +\def\ltlabsecdate{2023-10-16} +\def\ltlabsecversion{0.84b} %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -31,7 +33,7 @@ % \title{The \textsf{latex-lab-sec} package\\ % Changes related to the tagging of sectioning commands} % \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} -% \date{v0.83 2023-06-07} +% \date{v\ltlabsecversion\ \ltlabsecdate} % % \maketitle % @@ -147,7 +149,7 @@ % % \section{Implementation} % \begin{macrocode} -\ProvidesExplPackage {latex-lab-testphase-sec} {2023-05-20} {0.81} +\ProvidesExplPackage {latex-lab-testphase-sec} {\ltlabsecdate} {\ltlabsecversion} {Code related to the tagging of sectioning commands} % \end{macrocode} % @@ -177,10 +179,12 @@ % \begin{macrocode} %<*kernelchange> \ifdefined\directlua - \pdfvariable gentounicode =1 - \protected\def\pdfglyphtounicode {\pdfextension glyphtounicode } - \protected\edef\pdfgentounicode {\pdfvariable gentounicode} - \input{glyphtounicode} + \ifnum\outputmode > 0 + \pdfvariable gentounicode =1 + \protected\def\pdfglyphtounicode {\pdfextension glyphtounicode } + \protected\edef\pdfgentounicode {\pdfvariable gentounicode} + \input{glyphtounicode} + \fi \fi \ifdefined\pdfglyphtounicode \input{glyphtounicode-cmex} @@ -437,45 +441,48 @@ % \end{macrocode} % This redefines \cs{part} in article class. % \begin{macrocode} - \RenewDocumentCommand\part{ s O{#3} m } + \@ifundefined{part}{} { - \if@noskipsec \leavevmode \fi - \par - \addvspace{4ex}% - \@afterindentfalse + \RenewDocumentCommand\part{ s O{#3} m } + { + \if@noskipsec \leavevmode \fi + \par + \addvspace{4ex}% + \@afterindentfalse % \end{macrocode} % This are the tagging commands needed at the begin. They open a Part structure % and the structure for the title of the heading. % \begin{macrocode} % tagging start commands - \tag_tool:n {sec-start-part=#2} + \tag_tool:n {sec-start-part=#2} % end tagging start commands % \end{macrocode} % This adds a manual target if the part is unnumbered or starred. % It replaces the hyperref patches. % \begin{macrocode} - \bool_lazy_any:nT - { - { #1 } - { - \int_compare_p:nNn {\c@secnumdepth}<{-1} - } - } - { - \MakeLinkTarget[part]{} - } + \bool_lazy_any:nT + { + { #1 } + { + \int_compare_p:nNn {\c@secnumdepth}<{-1} + } + } + { + \MakeLinkTarget[part]{} + } % \end{macrocode} % The main call to the underlying commands. % \begin{macrocode} - \IfBooleanTF - {#1} - { \@spart {#3} } - { \@part [#2]{#3} } + \IfBooleanTF + {#1} + { \@spart {#3} } + { \@part [#2]{#3} } % \end{macrocode} % and now the closing command for the tagging of the title. % \begin{macrocode} - \tag_tool:n {sec-stop-part} - } + \tag_tool:n {sec-stop-part} + } + } } % \end{macrocode} % Redefinitions for book and report @@ -510,12 +517,10 @@ } } { +% \end{macrocode} +% The relation target-struct is stored internally by the MakeLinkTarget commands +% \begin{macrocode} \MakeLinkTarget[chapter]{} - %todo public function for this update! - \tl_if_blank:VF \@currentHref - { - \prop_gput:Nxx \g__tag_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}} - } } % \end{macrocode} % The main call to the underlying commands. @@ -571,10 +576,6 @@ } { \MakeLinkTarget[part]{} - \tl_if_blank:VF \@currentHref - { - \prop_gput:Nxx \g__tag_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}} - } } % \end{macrocode} % The main call to the underlying commands. @@ -626,18 +627,14 @@ % probably need something slightly different based on \cs{MakeLinkTarget}. % \begin{macrocode} \cs_new_protected:Npn \@hyp@section@target@nnn #1 #2 #3 %#1 optarg #2 name/counter, #3 indent - { - \makebox[0pt][l] + { + \makebox[0pt][l] { \skip_set:Nn \@tempskipa {#3} \dim_compare:nNnF {\@tempskipa}<{0pt}{\kern-\@tempskipa} \MakeLinkTarget#1{#2} } - \tl_if_blank:VF \@currentHref - { - \prop_gput:Nxx \g__tag_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}} - } - } + } % \end{macrocode} % \end{macro} % @@ -812,8 +809,8 @@ % \begin{macrocode} %<*latex-lab> -\ProvidesFile{sec-tagging-latex-lab-testphase.ltx} - [2023-05-20 v0.82 code related to the tagging of sectioning commands] +\ProvidesFile{sec-latex-lab-testphase.ltx} + [\ltlabsecdate\space v\ltlabsecversion\space latex-lab wrapper sec] \RequirePackage{latex-lab-testphase-sec} % % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-table.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-table.dtx new file mode 100644 index 00000000000..700d4ce6c17 --- /dev/null +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-table.dtx @@ -0,0 +1,1975 @@ +% \iffalse meta-comment +% +%% File: latex-lab-table.dtx (C) Copyright 2023 LaTeX Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% +% The development version of the bundle can be found below +% +% https://github.com/latex3/latex2e/required/latex-lab +% +% for those people who are interested or want to report an issue. +% +\def\ltlabtbldate{2023-10-30} +\def\ltlabtblversion{0.85d} +%<*driver> +\documentclass{l3doc} +\EnableCrossrefs +\CodelineIndex +\begin{document} + \DocInput{latex-lab-table.dtx} +\end{document} +% +% +% \fi +% +% \providecommand\hook[1]{\texttt{#1\DescribeHook[noprint]{#1}}} +% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}} +% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}} +% +% \NewDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl} +% \NewDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl} +% \NewDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl} +% +% +% +% +% \title{The \textsf{latex-lab-table} package\\ +% Changes related to the tagging of tables} +% \author{Frank \& Ulrike, \LaTeX{} Project\thanks{Initial implementation done by Frank Mittelbach}} +% \date{v\ltlabtblversion\ \ltlabtbldate} +% +% \maketitle +% +% \newcommand{\xt}[1]{\textsl{\textsf{#1}}} +% \newcommand{\TODO}[1]{\textbf{[TODO:} #1\textbf{]}} +% \newcommand{\docclass}{document class \marginpar{\raggedright document class +% customizations}} +% +% +% \begin{abstract} +% The following code implements a first draft for the tagging of +% tables. It still has a large number of limitations and restrictions! +% \end{abstract} +% +% \tableofcontents +% +% \section{Documentation} +% +% In \LaTeX{} the word \texttt{table} is used as the name of the float environment that can contain +% a data table\footnote{But it does not really have to, you can put +% other material into such environments.} along with a caption and some additional text. The environments for +% actual data tables have various names like \texttt{tabular}, \texttt{tabular*}, +% \texttt{tabularx} and \texttt{longtable}---the last should not be used inside a float +% and supports its own caption command. +% +% In this documentation \enquote{table} always means such data tables and not the float +% environment. +% +% Tagging of tables is on one side doesn't look very difficult: one only has to +% surround rows and cells by TR and TH or TD structures. +% But there are difficulties: +% \begin{itemize} +% \item +% One is that over the years various packages related to tables have +% been written that all change some of the internals. Inserting the +% tagging commands and testing all the variants and various nestings +% is not trivial. +% +% \item +% The other difficulty is that most of the existing environments to +% create tables do not know the concept of headers as a semantic +% structures. +% +% \item +% Headers are only produced through visual formatting, e.g., by +% making them bold or by underlying some color. But accessible +% tables need headers (and the PDF/UA standards requires them) and +% this means that additional syntax to declare headers (when they +% can't be guessed) must be developed. This is still an area for +% research. +% \end{itemize} +% +% Right now, this module therefore does implement only some basic +% support for the tagging of tables. A list of the known limitations +% is shown below. +% +% The module is not loaded automatically (i.e., not yet integrated +% into any \texttt{phase-XX}) and by itself it doesn't activate +% tagging. For experimenting with table tagging it is therefore best +% to load it in combination +% with phase-III in \cs{DocumentMetadata}, i.e.: +% +% \begin{verbatim} +% \DocumentMetadata{testphase={phase-III,table}} +% \end{verbatim} +% +% It will then automatically tag all table environments it already supports with +% the exception of tables in the header and footer of the page (where tagging is disabled). +% Such tables can be nested. +% +% If a table should not be tagged as table, for example because it is merely used +% to produce a layout or because it is a not yet (fully) supported table structure, +% the tagging can be disabled with +% \verb|\tagpdfsetup{table-tagging=false}|. +% +% Inside cells the automatic tagging of paragraphs is disabled with the exception of +% p/m/b-type cells. +% +% Rows do not need to contain a full number of \&, missing cells are automatically +% added with an empty TD-structure. +% +% There is some basic support\footnote{This is not meant to be the +% final interface, though.} for headers. With +% \begin{quote} +% \verb|\tagpdfsetup{table-header-rows={|\meta{list of row numbers}\verb|}| +% \end{quote} +% you can +% declare which (absolute) row numbers should be tagged as header rows. +% It applies to all tables until it is changed to a different list of row numbers or undone by setting +% the key to \meta{empty}. +% A row number can be +% negative, then the counting starts from the end of the table. There is no support +% for header columns yet. In a \env{longtable} the code will currently use the \cs{endhead} or +% \cs{endfirsthead} rows as header if one of these commands has been +% used and in that case the code +% ignores a \texttt{table-header-rows} setting. +% +% You should not insert meaningful text with \verb+!{...}+ or \verb+@{...}+ or \cs{noalign} +% between the rows or columns of the table. +% With pdflatex such text will be unmarked, with lualatex it will be marked as artifact. +% Either case means that it will be currently ignored in the +% structure.\footnote{While it is theoretically possible +% to collect such text and move it into a structure it would require manual markup +% from the author to clarify where this text belongs too.} +% +% As mentioned below the \pkg{colortbl} doesn't yet work properly with the tagging, +% but once it does, then colors inside the table will probably be +% simply ignored (at least initially). If such a color +% has a semantic meaning (like \enquote{important value}) this meaning will be lost. +% +% Feedback and problems with the code can be reported at +% \url{https://github.com/latex3/tagging-project} either in form of +% explicit issues or as a \enquote{discussion topic}, whatever works best. +% +% +% \section{Limitations} +% +% \begin{itemize} +% \item The code loads the \pkg{array} package and so does not work without it (that is +% not really a limitation, but can affect existing tables). +% +% \item It supports only a restricted number of tables types. Currently +% \env{tabular}, \env{tabular*}, \env{tabularx}, and \env{longtable}. +% +% \item the \env{array} environment is assumed to be part of math and tagging as a table is disabled for +% it. +% +% \item Row spans are not yet supported (and the \pkg{multirow} package is untested). +% +% \item The \pkg{colortbl} package breaks tagging if there are nested tables. It also breaks +% the filling up of incomplete rows. +% +% \item The \pkg{tabularray} package use a completed different +% method to create tables and will not be supported by this code. +% +% \item The \pkg{nicematrix} package is currently incompatible. +% +% \item Most other packages related to tables in \LaTeX{} are not yet tested, +% that includes packages that change rules like \pkg{booktabs}, \pkg{hhline}, +% \pkg{arydshln}, \pkg{hvdashln}. +% +% \item \env{longtable} currently only works with lualatex. +% With other engines it breaks as its output +% routine clashes with the code which closes open MC-chunks at pagebreaks and +% if this is resolved there will probably be problems with the head and foot boxes +% (but this can't be tested currently). +% +% \item Not every table should be tagged as a Table structure, often they are +% only used as layout help, e.g. to align authors in a title pages. In such uses +% the tagging of the table must be deactivated with \verb|\tagpdfsetup{table-tagging=false}|. +% +% \item Only simple header rows are currently supported. Columns and complex headers with +% subheaders will be handled later as that needs some syntax changes. Tables +% with more than one header row are probably not pdf/UA as the headers array in +% the cells is missing. +% +% \item A \pkg{longtable} \cs{caption} is currently simply formatted as a multicolumn and +% not tagged as a \texttt{Caption} structure. +% +% \item The \pkg{caption} package will quite probably break the \pkg{longtable} caption. +% +% \item The setup for \pkg{longtable} requires lots of patches to internal \pkg{longtable} +% commands and so can easily break if other packages try to patch \pkg{longtable} too. +% +% \item The \env{longtable} environment supports footnotes in p-type columns, but it hasn't been +% tested yet if this works also with the tagging code. +% +% \item The code is quite noisy and fills the log with lots of +% messages.\footnote{Helpful for us at this stage.} +% \end{itemize} +% +% +% +% \section{Introduction} +% +% +% \section{Technical details and problems} +% +% The implementation has to take care of various details. +% +% \subsection{TODOs} +% +% \begin{itemize} +% \item +% Test \texttt{array-006-longtable.lvt} and +% \texttt{array-007-longtable.lvt} have errors with pdftex (para +% tagging) +% +% \item +% Instead of before/after hooks we should add sockets directly +% into the code. +% +% \item Debugging code and messages must be improved. +% +% \item Cells need an \texttt{Headers} array. +% +% \item Row spans should be supported (but perhaps need syntax support) +% +% \item Longtable captions should be properly supported. +% +% \item Handle p-cells better. para-tagging should probably be enabled, +% but Part can't be a child of TD, so this should probably be changed to Div here. +% Also there is a stray MC somewhere. +% +% \item More packages must be tested. +% \end{itemize} +% +% +% \section{Implementation} +% \begin{macrocode} +%<@@=tbl> +%<*package> +% \end{macrocode} +% \begin{macrocode} +\ProvidesExplPackage {latex-lab-testphase-table} {\ltlabtbldate} {\ltlabtblversion} + {Code related to the tagging of tables} +% \end{macrocode} +% This builds on \pkg{array} so we load it by default: +% \begin{macrocode} +\RequirePackage{array} +% \end{macrocode} +% +% +% \subsection{Variables} +% \begin{macro} +% { +% \l_@@_celltag_tl +% ,\l_@@_rowtag_tl +% ,\l_@@_cellattribute_tl +% ,\l_@@_rowattribute_tl +% ,\g_@@_missingcells_int +% ,\l_@@_tmpa_clist +% ,\l_@@_tmpa_seq +% ,\l_@@_tmpa_tl +% } +% This is for the celltag, e.g. TD or TH: +% \begin{macrocode} +\tl_new:N \l_@@_celltag_tl +\tl_set:Nn \l_@@_celltag_tl {TD} +% \end{macrocode} +% For the rowtag, probably always TR: +% \begin{macrocode} +\tl_new:N \l_@@_rowtag_tl +\tl_set:Nn \l_@@_rowtag_tl {TR} +% \end{macrocode} +% And here cell and row attributes: +% \begin{macrocode} +\tl_new:N \l_@@_cellattribute_tl +\tl_set:Nn \l_@@_cellattribute_tl {} +\tl_new:N \l_@@_rowattribute_tl +\tl_set:Nn \l_@@_rowattribute_tl {} +% \end{macrocode} +% This will contain the number of missing cells used: +% \begin{macrocode} +\int_new:N \g_@@_missing_cells_int +% \end{macrocode} +% Temp variables +% \begin{macrocode} +\clist_new:N \l_@@_tmpa_clist +\seq_new:N \l_@@_tmpa_seq +\tl_new:N \l_@@_tmpa_tl +% \end{macrocode} +% \end{macro} +% +% \subsection{Sockets} +% +% 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 At first sockets for the begin and +% end of cells and rows +% +% \begin{socketdecl}{tagsupport/tblcell/begin, +% tagsupport/tblcell/end, +% tagsupport/tblrow/begin, +% tagsupport/tblrow/end, +% } +% \begin{macrocode} +\NewSocket{tagsupport/tblcell/begin}{0} +\NewSocket{tagsupport/tblcell/end}{0} +\NewSocket{tagsupport/tblrow/begin}{0} +\NewSocket{tagsupport/tblrow/end}{0} +% \end{macrocode} +% \end{socketdecl} +% +% \begin{socketdecl}{tagsupport/tbl/init} +% This socket should be at the begin of the table, inside a group. +% It is meant for settings like disabling paratagging. This socket +% can perhaps be merged later into the begin-sockets when they are +% no longer added as hooks but in the environment definitions. +% \begin{macrocode} +\NewSocket{tagsupport/tbl/init}{0} +% \end{macrocode} +% \end{socketdecl} +% +% +% \begin{socketdecl}{tagsupport/tbl/finalize} +% To fine tune the structure (change cells to header cells, remove +% unwanted structures, move a foot to the end, etc.) we also need a +% socket that is executed at the end of the table but \emph{before} +% all the variables are restored to the outer or default values. +% The code in the socket can make assignments, but probably +% shouldn't do typesetting and not write whatsits. +% \begin{macrocode} +\NewSocket{tagsupport/tbl/finalize}{0} +% \end{macrocode} +% \end{socketdecl} +% +% \begin{socketdecl}{tagsupport/tbl/finalize/longtable} +% \env{longtable} needs its own socket to fine tune the structure. +% Simply switching the plug in the previous socket interferes with +% enabling/disabling the tagging. +% \begin{macrocode} +\NewSocket{tagsupport/tbl/finalize/longtable}{0} +% \end{macrocode} +% \end{socketdecl} +% +% \begin{socketdecl}{tagsupport/tblhmode/begin, +% tagsupport/tblhmode/end, +% tagsupport/tblvmode/begin, +% tagsupport/tblvmode/end +% } +% +% These sockets are used in the begin and end code of environments, +% to allow a fast enabling and disabling of the tagging. We +% distinguish between tables that can be used inside paragraphs and +% standalone tables like longtable. +% \begin{macrocode} +\NewSocket{tagsupport/tblhmode/begin}{0} +\NewSocket{tagsupport/tblhmode/end}{0} +\NewSocket{tagsupport/tblvmode/begin}{0} +\NewSocket{tagsupport/tblvmode/end}{0} +% \end{macrocode} +% \end{socketdecl} +% +% This are the standard plugs for tagging of cells and rows. +% +% \begin{plugdecl}{TD} +% \begin{macrocode} +\NewSocketPlug{tagsupport/tblcell/begin}{TD} + { + \tag_struct_begin:n + { + tag =\l_@@_celltag_tl, + attribute-class =\l_@@_cellattribute_tl + } + \seq_gput_right:Ne \g_@@_struct_cur_seq { \tag_get:n {struct_num} } +% \end{macrocode} +% we store the cells of multicolumns as negative number. This allow to skip them +% or to use them as needed. +% \begin{macrocode} + \int_step_inline:nn { \g_@@_span_tl - 1 } + { + \seq_gput_right:Ne \g_@@_struct_cur_seq { -\tag_get:n {struct_num} } + } + \tag_mc_begin:n{} + } +% \end{macrocode} +% \end{plugdecl} +% +% \begin{plugdecl}{TD} +% \begin{macrocode} +\NewSocketPlug{tagsupport/tblcell/end}{TD} + { + \tag_mc_end: + \tag_struct_end: + } +% \end{macrocode} +% \end{plugdecl} +% +% In p-columns we need a slightly different plug which reactivates the +% paragraph tagging. +% tagging +% \begin{plugdecl}{TD} +% \begin{macrocode} +\NewSocketPlug{tagsupport/tblcell/begin}{TDpbox} + { + \tag_struct_begin:n + { + tag =\l__tbl_celltag_tl, + attribute-class =\l__tbl_cellattribute_tl + } + \seq_gput_right:Ne \g__tbl_struct_cur_seq { \tag_get:n {struct_num} } + \int_step_inline:nn { \g__tbl_span_tl - 1 } + { + \seq_gput_right:Ne \g__tbl_struct_cur_seq { -\tag_get:n {struct_num} } + } + \tagpdfparaOn + \tl_set:Nn \l__tag_para_main_tag_tl {Div} + } +% \end{macrocode} +% \end{plugdecl} +% +% \begin{plugdecl}{TD} +% \begin{macrocode} +\NewSocketPlug{tagsupport/tblcell/end}{TDpbox} + { + \tag_struct_end: + } +% \end{macrocode} +% \end{plugdecl} +% +% \begin{plugdecl}{TR} +% \begin{macrocode} +\NewSocketPlug{tagsupport/tblrow/begin}{TR} + { + \seq_gclear:N \g_@@_struct_cur_seq + \tag_struct_begin:n + { + tag =\l_@@_rowtag_tl, + attribute-class=\l_@@_rowattribute_tl + } + \seq_gput_right:Ne \g_@@_struct_rows_seq { \tag_get:n {struct_num} } + } +% \end{macrocode} +% \end{plugdecl} +% +% \begin{plugdecl}{TR} +% \begin{macrocode} +\NewSocketPlug{tagsupport/tblrow/end}{TR} + { + \__tag_tbl_add_missing_cells:n { \g_@@_missing_cells_int } + \seq_gput_right:Ne \g_@@_struct_cells_seq + { + \seq_use:Nn \g_@@_struct_cur_seq {,} + } + \int_compare:nNnTF { \g_@@_row_int } = { \seq_count:N\g_@@_struct_cells_seq } + { + \typeout + {==>~ + stucture~stored~for~row~\int_use:N\g_@@_row_int :~ + \seq_use:Nn \g_@@_struct_cur_seq {,} + } + } + { \ERROR } % should not happen ... + \tag_struct_end: + } +% \end{macrocode} +% \end{plugdecl} +% +% And the plugs for the table as whole. The code can be different for +% normal tables which can also be used inline and nested and +% \enquote{vmode} tables like longtable. +% +% \begin{plugdecl}{Table} +% Inside a table we currently only disable paratagging. We assume +% that these sockets are in an environment group, so there is no +% need to reenable paratagging. +% \begin{macrocode} +\NewSocketPlug{tagsupport/tbl/init}{Table} + { + \tag_if_active:T + { + \bool_set_false:N \l__tag_para_bool + } + } +% \end{macrocode} +% \end{plugdecl} +% +% +% \begin{plugdecl}{Table} +% This plug will fine tune the structure. +% \begin{macrocode} +\NewSocketPlug{tagsupport/tbl/finalize}{Table} + { + \@@_set_header_rows: + } +% \end{macrocode} +% \end{plugdecl} +% +% \begin{plugdecl}{Table} +% This plug will fine tune the structure of longtable. +% \begin{macrocode} +\NewSocketPlug{tagsupport/tbl/finalize/longtable}{Table} + { +% \end{macrocode} +% If neither \cs{endhead} nor \cs{endfirsthead} has been used +% we use the standard header command: +% \begin{macrocode} + \bool_lazy_and:nnTF + { \seq_if_empty_p:N \g_@@_LT@head_rows_seq } + { \seq_if_empty_p:N \g_@@_LT@firsthead_rows_seq } + { \@@_set_header_rows: } +% \end{macrocode} +% Otherwise, if firsthead has not been used we use head. For this +% we simple retrieve the row numbers and then call the header +% command. +% \begin{macrocode} + { + \seq_if_empty:NTF \g_@@_LT@firsthead_rows_seq + { + \clist_set:Ne \l_@@_header_rows_clist + {\seq_use:Nn \g_@@_LT@head_rows_seq {,}} + \@@_set_header_rows: + } +% \end{macrocode} +% In the other case we use firsthead. +% \begin{macrocode} + { + \clist_set:Ne \l_@@_header_rows_clist + { \seq_use:Nn \g_@@_LT@firsthead_rows_seq {,} } + \@@_set_header_rows: +% \end{macrocode} +% Additionally we have to remove the head to avoid duplication. The +% one option here is to remove the rows from the kid sequence of +% the table (which will lead to orphaned structure elements), the +% other to make them artifact. For now we use the first option for +% pdf 1.7 and the second for pdf 2.0. +% \begin{macrocode} + \pdf_version_compare:NnTF < {2.0} + { + \seq_map_inline:Nn \g_@@_LT@head_rows_seq + { + \seq_gset_item:cnn + {g__tag_struct_kids_ \g_@@_struct_table_tl _seq} + { ##1 } + {} +% \end{macrocode} +% Not sure if needed, but if needed we can remove also the P tag. +% This is currently disabled as it produce warnings. TODO: This +% needs also a tagpdf command which takes care of debug code. +% \begin{macrocode} + \tl_set:Ne \l_@@_tmpa_tl + { \seq_item:Nn\g_@@_struct_rows_seq {##1} } + \prop_if_exist:cT + { g__tag_struct_ \l_@@_tmpa_tl _prop } + { + %\prop_gremove:cn {g__tag_struct_ \l_@@_tmpa_tl _prop} {P} + } + } + } + { + \seq_map_inline:Nn \g_@@_LT@head_rows_seq + { + \tl_set:Ne \l_@@_tmpa_tl + { \seq_item:Nn\g_@@_struct_rows_seq {##1} } + \prop_if_exist:cT + { g__tag_struct_ \l_@@_tmpa_tl _prop } + { + \@@_struct_prop_gput:Vnn \l_@@_tmpa_tl {S}{/Artifact} + } + } + } + } + } +% \end{macrocode} +% The foot is handled similar, the difference is +% that we have to move it to the end one of them +% is not empty, but do nothing if they aren't there. +% \begin{macrocode} + \bool_lazy_and:nnF + { \seq_if_empty_p:N \g_@@_LT@foot_rows_seq } + { \seq_if_empty_p:N \g_@@_LT@lastfoot_rows_seq } + { +% \end{macrocode} +% If lastfoot is empty move foot to the end. +% \begin{macrocode} + \seq_if_empty:NTF \g_@@_LT@lastfoot_rows_seq + { + \seq_map_inline:Nn \g_@@_LT@foot_rows_seq + { + \tl_set:Ne \l_@@_tmpa_tl + { + \seq_item:cn + {g__tag_struct_kids_ \g_@@_struct_table_tl _seq} + {##1} + } + \seq_gset_item:cnn + {g__tag_struct_kids_ \g_@@_struct_table_tl _seq} + { ##1 } + {} + \seq_gput_right:cV + {g__tag_struct_kids_ \g_@@_struct_table_tl _seq} + \l_@@_tmpa_tl + } + } +% \end{macrocode} +% If lastfoot is not empty we move that. +% \begin{macrocode} + { + \seq_map_inline:Nn \g_@@_LT@lastfoot_rows_seq + { + \tl_set:Ne \l_@@_tmpa_tl + { + \seq_item:cn + {g__tag_struct_kids_ \g_@@_struct_table_tl _seq} + {##1} + } + \seq_gset_item:cnn + {g__tag_struct_kids_ \g_@@_struct_table_tl _seq} + { ##1 } + {} + \seq_gput_right:cV + {g__tag_struct_kids_ \g_@@_struct_table_tl _seq} + \l_@@_tmpa_tl + } +% \end{macrocode} +% and we hide foot +% \begin{macrocode} + \pdf_version_compare:NnTF < {2.0} + { + \seq_map_inline:Nn \g_@@_LT@foot_rows_seq + { + \seq_gset_item:cnn + {g__tag_struct_kids_ \g_@@_struct_table_tl _seq} + { ##1 } + {} +% \end{macrocode} +% Not sure if needed, but if needed we can remove also the P tag. +% This is currently disabled as it produce warnings. +% TODO: This needs also +% a tagpdf command which takes care of debug code. +% \begin{macrocode} + \tl_set:Ne \l_@@_tmpa_tl + { \seq_item:Nn\g_@@_struct_rows_seq {##1} } + \prop_if_exist:cT + { g__tag_struct_ \l_@@_tmpa_tl _prop } + { + %\prop_gremove:cn {g__tag_struct_ \l_@@_tmpa_tl _prop} {P} + } + } + } + { + \seq_map_inline:Nn \g_@@_LT@foot_rows_seq + { + \tl_set:Ne \l_@@_tmpa_tl + { \seq_item:Nn\g_@@_struct_rows_seq {##1} } + \prop_if_exist:cT + { g__tag_struct_ \l_@@_tmpa_tl _prop } + { + \@@_struct_prop_gput:Vnn \l_@@_tmpa_tl {S}{/Artifact} + } + } + } + } + } + } +% \end{macrocode} +% \end{plugdecl} +% +% \begin{plugdecl}{Table} +% \begin{macrocode} +\NewSocketPlug{tagsupport/tblhmode/begin}{Table} + { + \mode_leave_vertical: + \tag_mc_end_push: +% \end{macrocode} +% Close the P-chunk. This assumes that para-tagging is active. +% For nested tables that is not necessarly true, so we test for it. +% \begin{macrocode} + \bool_lazy_and:nnT + { \bool_if_exist_p:N \l__tag_para_bool } { \l__tag_para_bool } + { \tag_struct_end:n { text } } + \tag_struct_begin:n {tag=Table} + \tl_gset:Ne \g_@@_struct_table_tl { \tag_get:n {struct_num} } + } +% \end{macrocode} +% \end{plugdecl} +% +% \begin{plugdecl}{Table} +% \begin{macrocode} +\NewSocketPlug{tagsupport/tblhmode/end}{Table} + { + \tag_struct_end: +% \end{macrocode} +% reopen the P-chunk. This assumes that para-tagging is active. +% For nested tables that is not necessarly true, so we test for it. +% \begin{macrocode} + \bool_lazy_and:nnT + { \bool_if_exist_p:N \l__tag_para_bool } { \l__tag_para_bool } + { \tag_struct_begin:n { tag=\l__tag_para_tag_tl } } + \tag_mc_begin_pop:n{} + } +% \end{macrocode} +% \end{plugdecl} +% +% \begin{plugdecl}{Table} +% \begin{macrocode} +\NewSocketPlug{tagsupport/tblvmode/begin}{Table} + { + \tag_struct_begin:n {tag=Table} + \tl_gset:Ne \g_@@_struct_table_tl { \tag_get:n {struct_num} } + } +% \end{macrocode} +% \end{plugdecl} +% +% \begin{plugdecl}{Table} +% \begin{macrocode} +\NewSocketPlug{tagsupport/tblvmode/end}{Table} + { + \tag_struct_end: + \par + } +% \end{macrocode} +% \end{plugdecl} +% +% +% +% +% +%\subsection{Environments} +% +% Currently only tabular, tabular*, tabularx and longtable. +% We must use the \texttt{before} and \texttt{after} hooks as the \texttt{end} +% hook is executed before the end of the last row and then MC are messed up. +% This means that this sockets should only contain code that doesn't needs to be +% grouped! +% \begin{macrocode} +\AddToHook{env/tabular/before} {\UseSocket{tagsupport/tblhmode/begin}} +\AddToHook{env/tabular/after} {\UseSocket{tagsupport/tblhmode/end}} +\AddToHook{env/tabular*/before} {\UseSocket{tagsupport/tblhmode/begin}} +\AddToHook{env/tabular*/after} {\UseSocket{tagsupport/tblhmode/end}} +\AddToHook{env/tabularx/before} {\UseSocket{tagsupport/tblhmode/begin}} +\AddToHook{env/tabularx/after} {\UseSocket{tagsupport/tblhmode/end}} +\AddToHook{env/longtable/before}{\UseSocket{tagsupport/tblvmode/begin}} +\AddToHook{env/longtable/after} {\UseSocket{tagsupport/tblvmode/end}} +% \end{macrocode} +% +% The \env{array} environment is math. So we disable table tagging for now. +% \begin{macrocode} +\AddToHook{env/array/begin} {\__tag_tbl_disable:} +% \end{macrocode} +% +% +% \subsection{Interfaces to tagging} +% +% \subsubsection{Tagging helper commands} +% +% \begin{macro}{\@@_set_colspan:n} +% This commands takes a number, checks if is larger than one, +% checks if the colspan attribute exists (we can't predefine an +% arbitrary number), and updates \cs{l_@@_cellattribute_tl}. +% \begin{macrocode} +\tag_if_active:T + { \cs_generate_variant:Nn \__tag_attr_new_entry:nn {ee} } +\cs_new_protected:Npn \@@_set_colspan:n #1 + { + \tag_if_active:T + { + \int_compare:nNnT {#1}>{1} + { + \prop_get:NeNF \g__tag_attr_entries_prop + {colspan-\int_eval:n{#1}} + \l_@@_tmpa_tl + { + \__tag_attr_new_entry:ee + {colspan-\int_eval:n{#1}} + {/O /Table /ColSpan~\int_eval:n{#1}} + } + \tl_set:Ne \l_@@_cellattribute_tl + {colspan-\int_eval:n{#1}} + } + } + } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Disabling/enabling} +% +% For now we have only the option true/false but this will probably be extended +% to allow different setups like first row header etc. + +% \begin{macro}{\__tag_tbl_disable:} +% +% \begin{macrocode} +\cs_new_protected:Npn \__tag_tbl_disable: + { + \AssignSocketPlug{tagsupport/tblcell/begin}{noop} + \AssignSocketPlug{tagsupport/tblcell/end}{noop} + \AssignSocketPlug{tagsupport/tblrow/begin}{noop} + \AssignSocketPlug{tagsupport/tblrow/end}{noop} + \AssignSocketPlug{tagsupport/tbl/init}{noop} + \AssignSocketPlug{tagsupport/tbl/finalize}{noop} + \AssignSocketPlug{tagsupport/tbl/finalize/longtable}{noop} + \AssignSocketPlug{tagsupport/tblhmode/begin}{noop} + \AssignSocketPlug{tagsupport/tblhmode/end}{noop} + \AssignSocketPlug{tagsupport/tblvmode/begin}{noop} + \AssignSocketPlug{tagsupport/tblvmode/end}{noop} + } +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\__tag_tbl_enable:} +% +% \begin{macrocode} +\cs_new_protected:Npn \__tag_tbl_enable: + { + \AssignSocketPlug{tagsupport/tblcell/begin}{TD} + \AssignSocketPlug{tagsupport/tblcell/end}{TD} + \AssignSocketPlug{tagsupport/tblrow/begin}{TR} + \AssignSocketPlug{tagsupport/tblrow/end}{TR} + \AssignSocketPlug{tagsupport/tbl/init}{Table} + \AssignSocketPlug{tagsupport/tbl/finalize}{Table} + \AssignSocketPlug{tagsupport/tbl/finalize/longtable}{Table} + \AssignSocketPlug{tagsupport/tblhmode/begin}{Table} + \AssignSocketPlug{tagsupport/tblhmode/end}{Table} + \AssignSocketPlug{tagsupport/tblvmode/begin}{Table} + \AssignSocketPlug{tagsupport/tblvmode/end}{Table} + } +% \end{macrocode} +% \end{macro} + +% \begin{macrocode} +% TODO decide about key name +\keys_define:nn { __tag / setup } + { + table-tagging .choices:nn = { true, on } + { \__tag_tbl_enable: }, + table-tagging .choices:nn = { false, off } + { \__tag_tbl_disable: }, + table-tagging .default:n = true, + table-tagging .initial:n = true + } +% \end{macrocode} +% +% Table tagging should be disabled in the head and foot. +% \begin{macrocode} +\AddToHook{begindocument} + { + \cs_if_exist:NT \@kernel@before@head + { + \tl_put_right:Nn \@kernel@before@head {\__tag_tbl_disable:} + \tl_put_right:Nn \@kernel@before@foot {\__tag_tbl_disable:} + } + } +% \end{macrocode} +% +% \subsubsection{Header support} +% +% Accessible table must have header cells declaring the meaning of the +% data in a row or column. To allow a data cell to find it header cell(s) +% a number of things must be done: +% \begin{itemize} +% \item every cell meant as a header should use the tag \texttt{TH}. +% +% \item header cells should have a \texttt{Scope} attribute with the +% value \texttt{Column}, \texttt{Row} or \texttt{Both}. This is not +% needed in the first row or column of a table. +% +% \item For more complex cases both \texttt{TD} and \texttt{TH} cell +% can contain a \texttt{Headers} attribute, that is an array of +% \texttt{ID}s of \texttt{TH} cell. +% \end{itemize} +% +% For now we support only header rows. +% +% At first we define attributes for the three standard cases: +% We delay to begin document +% as we can't know if tagpdf is already loaded. +% \begin{macrocode} +\AddToHook{begindocument} + { + \tag_if_active:T + { + \tagpdfsetup + { + newattribute = + {TH-col}{/O /Table /Scope /Column}, + newattribute = + {TH-row}{/O /Table /Scope /Row}, + newattribute = + {TH-both}{/O /Table /Scope /Both}, + } +% \end{macrocode} +% +% And we put all three into the class map (perhaps the next tagpdf +% should do that directly with newattribute): +% +% \begin{macrocode} + \seq_gput_left:Ne\g__tag_attr_class_used_seq + {\pdf_name_from_unicode_e:n{TH-col}} + \seq_gput_left:Ne\g__tag_attr_class_used_seq + {\pdf_name_from_unicode_e:n{TH-row}} + \seq_gput_left:Ne\g__tag_attr_class_used_seq + {\pdf_name_from_unicode_e:n{TH-both}} + } + } + +% \end{macrocode} +% +% \begin{variable}{\l_@@_header_rows_clist} +% This holds the numbers of the header rows. Negative numbers are +% possible and count from the back. +% \begin{macrocode} +\clist_new:N \l_@@_header_rows_clist +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_set_header_rows:} +% TEMP: Next tagpdf will have the right command which also updates +% the debug info. +% For now a temporary command: +% \begin{macrocode} +\cs_if_free:NTF \__tag_struct_prop_gput:nnn + { + \cs_new_protected:Npn \@@_struct_prop_gput:nnn #1#2#3 + { \prop_gput:cnn { g__tag_struct_#1_prop }{#2}{#3} } + } + { \cs_new_protected:Npn \@@_struct_prop_gput:nnn #1#2#3 + { \__tag_struct_prop_gput:nnn {#1}{#2}{#3} } + } +\cs_generate_variant:Nn \@@_struct_prop_gput:nnn {nne,Vnn} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_set_header_rows: + { + \clist_map_inline:Nn \l_@@_header_rows_clist + { + \clist_set:Ne\l_@@_tmpa_clist + { + \seq_item:Nn \g_@@_struct_cells_seq {##1} + } + \clist_map_inline:Nn \l_@@_tmpa_clist + { +% \end{macrocode} +% We can have negative numbers in the list from the multicolumn. +% \begin{macrocode} + \prop_if_exist:cT { g__tag_struct_####1_prop } + { + \@@_struct_prop_gput:nnn{ ####1 }{S}{/TH} +% \end{macrocode} +% This need refinement once row headers (and perhaps other attributes) +% are used too, but for now it should be ok. +% \begin{macrocode} + \prop_get:cnNTF + { g__tag_struct_####1_prop } + { C } + \l_@@_tmpa_tl + {\@@_struct_prop_gput:nne{ ####1 }{C}{[/TH-col~\l_@@_tmpa_tl]} } + {\@@_struct_prop_gput:nnn{ ####1 }{C}{/TH-col}} + } + } + } + } +% \end{macrocode} +% \end{macro} +% +% And some key support: +% \begin{macrocode} +% TODO decide about key name +\keys_define:nn { __tag / setup } + { + table-header-rows .clist_set:N = \l_@@_header_rows_clist + } +% \end{macrocode} +% +% \subsection{Changes to \pkg{array} commands} +% +% +% +% \begin{macro}{\@@_show_curr_cell_data:} +% Show the row/column index and span count for current table cell +% for debugging. +% \begin{macrocode} +\cs_new_protected:Npn \@@_show_curr_cell_data: { + \typeout { ==>~ current~cell~data:~ + \int_use:N \g_@@_row_int , + \int_use:N \g_@@_col_int , + \g_@@_span_tl + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\insert@column} +% \cs{insert@column} is defined in \pkg{array}, here only the two +% sockets are inserted. +% \begin{macrocode} +\def\insert@column{% + \@@_show_curr_cell_data: + \UseSocket{tagsupport/tblcell/begin}% + \the@toks \the \@tempcnta + \ignorespaces \@sharp \unskip + \the@toks \the \count@ \relax + \UseSocket{tagsupport/tblcell/end}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@classz} +% \begin{macrocode} +\def\@classz{\@classx + \@tempcnta \count@ + \prepnext@tok + \@addtopreamble{\ifcase \@chnum + \hfil + \hskip1sp% + \d@llarbegin + \insert@column + \d@llarend \do@row@strut \hfil \or + \hskip1sp\d@llarbegin \insert@column \d@llarend \do@row@strut \hfil \or + \hfil\hskip1sp\d@llarbegin \insert@column \d@llarend \do@row@strut \or + \setbox\ar@mcellbox\vbox + \@startpbox{\@nextchar} + \AssignSocketPlug{tagsupport/tblcell/begin}{TDpbox} + \AssignSocketPlug{tagsupport/tblcell/end}{TDpbox} + \insert@column \@endpbox + \ar@align@mcell + \do@row@strut \or + \vtop \@startpbox{\@nextchar} + \AssignSocketPlug{tagsupport/tblcell/begin}{TDpbox} + \AssignSocketPlug{tagsupport/tblcell/end}{TDpbox} + \insert@column \@endpbox\do@row@strut \or + \vbox \@startpbox{\@nextchar} + \AssignSocketPlug{tagsupport/tblcell/begin}{TDpbox} + \AssignSocketPlug{tagsupport/tblcell/end}{TDpbox} + \insert@column \@endpbox\do@row@strut + \fi}\prepnext@tok} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@array,\@@@@array} +% We modificate the \cs{@array} from \pkg{array}. +% \begin{macrocode} +\def\@array[#1]#2{% + \@tempdima \ht \strutbox + \advance \@tempdima by\extrarowheight + \setbox \@arstrutbox \hbox{\vrule + \@height \arraystretch \@tempdima + \@depth \arraystretch \dp \strutbox + \@width \z@}% +% \end{macrocode} +% The total number of table columns of the current table is +% determined in \cs{@@_determine_table_cols:} but this is called in +% a group, so local settings do not survive. Thus, to save away the +% outer value of \cs{g_@@_table_cols_tl} we do it before the group. +% \begin{macrocode} + \tl_set_eq:NN \l_@@_saved_table_cols_tl \g_@@_table_cols_tl +% \end{macrocode} +% +% \begin{macrocode} + \begingroup + \@mkpream{#2} +% \end{macrocode} +% Next call has to happen immediately after \cs{@mkpream} because +% it uses implementation details from that. +% \begin{macrocode} + \@@_determine_table_cols: +% \end{macrocode} +% +% \begin{macrocode} + \xdef\@preamble{% + \noexpand +% \end{macrocode} +% \cs{ialign} in the original definition is replaced by +% \cs{ar@ialign} defined below. +% \begin{macrocode} + \ar@ialign + \@halignto + \bgroup \@arstrut +% \end{macrocode} +% A socket is inserted +% \begin{macrocode} + \UseSocket{tagsupport/tblrow/begin}% +% \end{macrocode} +% At the start of the preamble for the first column we set +% \cs{g_@@_col_int} to \texttt{1} as we are no longer "at" but "in" +% the first column. This is done in \cs{@@_init_cell_data:}. In +% later columns this data is updated via \cs{@@_update_cell_data:}. +% \begin{macrocode} + \@@_init_cell_data: + \@preamble + \tabskip \z@ \cr}% + \endgroup + \@arrayleft +% \end{macrocode} +% Another socket for tagging. TODO: what about \cs{arrayleft}? +% \begin{macrocode} + \UseSocket{tagsupport/tbl/init} + \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi \fi + \bgroup + \let \@sharp ##\let \protect \relax + \lineskip \z@ + \baselineskip \z@ + \m@th + \let\\\@arraycr \let\tabularnewline\\\let\par\@empty +%\show\@preamble + \@preamble} +% \end{macrocode} +% Finally, also set \cs{@@@@array} to the new definition: +% \begin{macrocode} +\let\@@@@array\@array +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@_init_cell_data:} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_init_cell_data: { + \int_gset:Nn \g_@@_col_int {1} + \tl_gset:Nn \g_@@_span_tl {1} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_update_cell_data:} +% Updating cell data in columns after the first means we have to +% increment the \cs{g_@@_col_int} by the span count of the previous +% cell (in case it was a \cs{multicolumn} and then reset the +% \cs{g_@@_span_tl} to one (as the default). +% \begin{macrocode} +\cs_new_protected:Npn \@@_update_cell_data: { + \int_gadd:Nn \g_@@_col_int { \g_@@_span_tl } + \tl_gset:Nn \g_@@_span_tl {1} +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_determine_table_cols:} +% Current implementation of \cs{@mkpream} uses the scratch counter +% \cs{count@} to keep track of the number of toks registers it needs +% (2 per column), but this can't be used as it counts also +% insertings made with \verb+!{}+ and \verb+@{}+. +% So similar as does longtable for \cs{LT@cols} we count the +% numbers of ambersands instead. +% \begin{macrocode} +\cs_new:Npn \@@_determine_table_cols: { + \seq_set_split:NnV\l_@@_tmpa_seq {&}\@preamble + \tl_gset:Ne \g_@@_table_cols_tl { \seq_count:N \l_@@_tmpa_seq } + \typeout{ ==>~ Table~ has~ \g_@@_table_cols_tl \space columns } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@arraycr} +% Add code that figures out if the current table row is incomplete +% (not enough \verb=&=s). It can then do extra actions, such as +% inserting missing cell tags. +% \begin{macrocode} +\protected\def\@arraycr{ + \relax + \@@_store_missing_cells:n{@arraycr} + % + \iffalse{\fi\ifnum 0=`}\fi + \@ifstar \@xarraycr \@xarraycr} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_store_missing_cells:n, +% \__tag_tbl_add_missing_cells:n} +% The storing and use of the number of missing cells +% must happen at different places as the testing happens at +% the end of the last cell of a row, but +% still inside that cell, so we use two commands. The second is used in +% the endrow socket. +% \begin{macrocode} +\cs_new:Npn \@@_store_missing_cells:n #1 { + \int_compare:nNnT \g_@@_col_int > 0 + { + \int_gset:Nn \g_@@_missing_cells_int + { + \g_@@_table_cols_tl + - \g_@@_col_int + - \g_@@_span_tl + + 1 + } + \int_compare:nNnT \g_@@_missing_cells_int < 0 \ERROR % should not happen + \typeout{==>~ + (#1)~ + This~ row~ needs~ + \int_use:N \g_@@_missing_cells_int \space + additional~ cell(s) + } + } +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \__tag_tbl_add_missing_cells:n #1 + { +% \end{macrocode} +% The TD-socket messages are issued after the message about the end-row socket, +% but the structure is ok, so better issue a message for now to avoid confusion: +% \begin{macrocode} + \int_compare:nNnT {#1}>{0} + { + \typeout{==>~ + ~Inserting~\int_eval:n{#1}~additional~cell(s)~into~previous~row:} + } + \int_step_inline:nn { #1 } + { + \UseSocket{tagsupport/tblcell/begin} + \UseSocket{tagsupport/tblcell/end} + } + } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\endarray} +% If tables are nested into another then it is necessary to +% restore information about the cell the inner table started +% in. Otherwise, \cs{g_@@_row_int}, \cs{g_@@_col_int}, and +% \cs{g_@@_span_tl} reflect the status in the outer table as they +% are globally manipulated. We restore in all cases even if we are +% not in a nesting situation as that makes the code simpler (and +% probably faster). +% +% \cs{endtabular} and \cs{endtabular*} inherit from \cs{endarray} +% so we only need to change that. \texttt{tabularx} is handled +% below. +% \begin{macrocode} +\def\endarray{ + \@@_store_missing_cells:n{endarray} + \crcr \egroup + \UseSocket{tagsupport/tbl/finalize} + \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 + \tl_gset_eq:NN \g_@@_struct_table_tl \l_@@_saved_struct_table_tl + \seq_gset_eq:NN \g_@@_struct_rows_seq \l_@@_saved_struct_rows_seq + \seq_gset_eq:NN \g_@@_struct_cells_seq\l_@@_saved_struct_cells_seq + \seq_gset_eq:NN \g_@@_struct_cur_seq \l_@@_saved_struct_cur_seq + \typeout{==>~ restored~cell~data:~ + \int_use:N \g_@@_row_int, + \int_use:N \g_@@_col_int, + \l_@@_saved_span_tl \space + ( + \int_compare:nNnTF \g_@@_table_cols_tl = 0 + { outer~ level } + { max:~ \g_@@_table_cols_tl } + ) + } + \egroup + \@arrayright \gdef\@preamble{}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@addamp} +% If we are after the first column we have to insert a \verb=&= and +% also update the cell data. +% \begin{macrocode} +\def\@addamp { + \if@firstamp + \@firstampfalse + \else + \edef\@preamble{\@preamble & + \@@_update_cell_data: + } + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{ +% \g_@@_col_int, +% \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. It +% is incremented by every \cs{cr} including the one ending the +% table preamble. +% +% \cs{g_@@_col_int} holds the current column number. The value +% \texttt{0} means we have not yet started the table or just finished a table row +% (with \verb=\\= typically); any other positive value means we +% are currently typesetting a cell in that column in some row +% (denoted by the \cs{g_@@_row_int}. +% +% In a \cs{multicolumn} it holds the column number of the first +% spanned column and \cs{g_@@_span_tl} the info how many cells are +% spanned. +% +% \cs{g_@@_span_tl} is normally \texttt{1} except in a +% \cs{multicolumn} cell. +% \begin{macrocode} +\int_new:N \g_@@_col_int +\int_new:N \g_@@_row_int +\tl_new:N \g_@@_span_tl +\tl_new:N \g_@@_table_cols_tl + +\tl_gset:Nn \g_@@_span_tl {1} +\tl_gset:Nn \g_@@_table_cols_tl {0} % indicates outer level +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\l_@@_saved_col_tl,\l_@@_saved_row_tl, +% \l_@@_saved_span_tl,\l_@@_saved_table_cols_tl} +% +% Saving the outer values if we are nesting tables is necessary (as +% the above variables are globally altered. For this we use always +% token lists because they don't change and we do not need to blow +% additional integer registers. +% \begin{macrocode} +\tl_new:N \l_@@_saved_col_tl +\tl_new:N \l_@@_saved_row_tl +\tl_new:N \l_@@_saved_span_tl +\tl_new:N \l_@@_saved_table_cols_tl + +\tl_set:Nn \l_@@_saved_col_tl{0} +\tl_set:Nn \l_@@_saved_row_tl{0} +\tl_set:Nn \l_@@_saved_span_tl{1} +\tl_set:Nn \l_@@_saved_table_cols_tl{0} % indicates outer level +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \g_@@_struct_table_tl, \l_@@_saved_struct_table_tl, +% \g_@@_struct_rows_seq,\l_@@_saved_struct_rows_seq, +% \g_@@_struct_cells_seq,\l_@@_saved_struct_cells_seq, +% \g_@@_struct_cur_seq,\l_@@_saved_struct_cur_seq +% } +% We need to store the structure numbers for the fine tuning in the +% finalize socket. For now we use a rather simple system: A +% sequence that hold the numbers for the row structures, and one +% that holds comma lists for the cells. +% +% \cs{g_@@_struct_table_tl} will hold the structure number of the +% table, \cs{g_@@_struct_rows_seq} will hold at index i the +% structure number of row i, \cs{g_@@_struct_cells_seq} will hold +% at index i a comma list of the cell structure numbers of row i. +% \cs{g_@@_struct_cur_seq} is used as a temporary store for the +% cell structures of the current row. We need also local version +% to store and restore the values. +% +% \begin{macrocode} +\tl_new:N \g_@@_struct_table_tl +\tl_new:N \l_@@_saved_struct_table_tl +\seq_new:N \g_@@_struct_rows_seq +\seq_new:N \l_@@_saved_struct_rows_seq +\seq_new:N \g_@@_struct_cells_seq +\seq_new:N \l_@@_saved_struct_cells_seq +\seq_new:N \g_@@_struct_cur_seq +\seq_new:N \l_@@_saved_struct_cur_seq +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ar@ialign} +% A new command that replaces \cs{ialign} above. \cs{everycr} is +% also applied to the \cs{cr} ending the preamble so we have to +% program around that. +% \begin{macrocode} +\def\ar@ialign{% +% \end{macrocode} +% Before starting a table we locally stored the information related +% to the current cell (if any) so that we can restore it once the +% table is finished. +% \begin{macrocode} + \tl_set:No \l_@@_saved_col_tl {\int_use:N \g_@@_col_int } + \tl_set:No \l_@@_saved_row_tl {\int_use:N \g_@@_row_int } + \tl_set_eq:NN \l_@@_saved_span_tl \g_@@_span_tl + \tl_set_eq:NN \l_@@_saved_struct_table_tl \g_@@_struct_table_tl + \seq_set_eq:NN \l_@@_saved_struct_rows_seq \g_@@_struct_rows_seq + \seq_set_eq:NN \l_@@_saved_struct_cells_seq \g_@@_struct_cells_seq + \seq_set_eq:NN \l_@@_saved_struct_cur_seq \g_@@_struct_cur_seq +% + \typeout{==>~ saved~cell~data:~ + \l_@@_saved_row_tl, + \l_@@_saved_col_tl, + \l_@@_saved_span_tl \space + ( + \int_compare:nNnTF \l_@@_saved_table_cols_tl = 0 + { outer~ level } + { max:~ \l_@@_saved_table_cols_tl } + ) + } +% \end{macrocode} +% These are the initial values when starting a table: +% \begin{macrocode} + \int_gzero:N \g_@@_row_int + \int_gzero:N \g_@@_col_int + \tl_gset:Nn \g_@@_span_tl {1} + \seq_gclear:N\g_@@_struct_rows_seq + \seq_gclear:N\g_@@_struct_cells_seq + \seq_gclear:N\g_@@_struct_cur_seq +% \end{macrocode} +% +% \begin{macrocode} + \everycr{% + \noalign{% +% \end{macrocode} +% We use \cs{g_@@_col_int} equal zero to indicate that we are just +% after a TR (or at the very beginning of the table). Using the row +% count is not so good as longtable may split the table in chunks. +% \begin{macrocode} + \int_compare:nNnT \g_@@_col_int > 0 + { \UseSocket{tagsupport/tblrow/end} } + \int_gincr:N \g_@@_row_int % this row about to start + \int_gzero:N \g_@@_col_int % we are before first col + }% + }% + \tabskip\z@skip\halign} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\multicolumn} +% +% \cs{multicolumn} is also defined in \pkg{array}. The redefinition +% has to solve two problems: it must handle the row begin if it is +% used there, and it must save the numbers of cells it spans so +% that we can add a suitable ColSpan attribute.\footnote{FMi: This can +% now perhaps cleaned up somewhat} +% \begin{macrocode} +\long\def\multicolumn#1#2#3{% + % alternative: determine first col with vmode test ... + % \ifvmode + % \multispan{#1}\typeout{A==> vmode}% + % \else + % \multispan{#1}\typeout{A==> not vmode} + % \fi + % but this makes the \crcr handling really complicated which would + % then need to become something like + % \ifvmode \expandafter \@gobble + % \else \expandafter \@iden \fi {\cr\noalign{do something}}% + % so not used. + % Instead: + \multispan{#1}\begingroup +% \end{macrocode} +% Insert rowbegin socket only if this multicolumn +% replaces the preamble of the first column. In that case we have +% to set \cs{g_@@_col_int} to 1 since this is no longer done in the +% preamble for the cell. +% \begin{macrocode} + \int_compare:nNnTF \g_@@_col_int = 0 + { + \UseSocket{tagsupport/tblrow/begin} + \int_gset:Nn \g_@@_col_int {1} + } +% \end{macrocode} +% If we are in a later column we use \cs{g_@@_span_tl} from the +% previous column to update. +% \begin{macrocode} + { + \int_gadd:Nn \g_@@_col_int { \g_@@_span_tl } + } +% \end{macrocode} +% Then we set the span value so that it can be use in the next column. +% \begin{macrocode} + \tl_gset:Nn \g_@@_span_tl {#1} +% \end{macrocode} +% +% \begin{macrocode} + \def\@addamp{\if@firstamp\@firstampfalse \else + \@preamerr 5\fi}% + \@mkpream{#2}\@addtopreamble\@empty + \endgroup +% \end{macrocode} +% Now we update the colspan attribute. This needs setting after +% the group as it is hidden inside the plug in \cs{insert@column}. +% \begin{macrocode} + \@@_set_colspan:n {#1} +% \end{macrocode} +% \begin{macrocode} + \def\@sharp{#3}% + \@arstrut \@preamble + \null + \ignorespaces} +% \end{macrocode} +% \end{macro} +% +% \subsection{longtable} +% +% Longtable is complicated. When at the begin the \cs{endhead}, +% \cs{endfirsthead}, \cs{endfoot} and \cs{endlastfoot} are used to +% setup head and foot they create each a structure subtree with one or +% more rows. From this structures we want to keep at most two (head +% and foot) and move the foot to the end of the table. When the head +% and foot boxes are (re)inserted on following pages we want to mark +% them up as artifact with the exception of the head at the begin and +% the foot box at the end. +% +% TODO: When a line is killed the structure subtree is there already +% too and must be removed. +% +% Hyperref patches longtable. This must be disabled and replace with +% genuine code +% \begin{macrocode} +\let\@kernel@refstepcounter\refstepcounter +\def\hyper@nopatch@longtable{} +% \end{macrocode} +% \begin{macrocode} +\def\@@_patch_LT@array[#1]#2{% +% \end{macrocode} +% \cs{LT@array} is executed in a group, so we can disable para-tagging here. +% \begin{macrocode} + \UseSocket{tagsupport/tbl/init}% + \@kernel@refstepcounter{table}\stepcounter{LT@tables}% +% \end{macrocode} +% The target is created rather late and a \cs{label} can come earlier, +% so we have to define \cs{@currentHref} explicitly. We can't currently +% assume that \cs{theHtable} is defined always. +% \begin{macrocode} + \tl_gset:Ne \@currentHref {table.\cs_if_exist_use:N\theHtable} + \int_gzero:N \g_@@_row_int + \seq_gclear:N\g_@@_struct_rows_seq + \seq_gclear:N\g_@@_struct_cells_seq + \seq_gclear:N\g_@@_struct_cur_seq + \seq_gclear:N\g_@@_LT@firsthead_rows_seq + \seq_gclear:N\g_@@_LT@head_rows_seq + \seq_gclear:N\g_@@_LT@lastfoot_rows_seq + \seq_gclear:N\g_@@_LT@foot_rows_seq + \if l#1% + \LTleft\z@ \LTright\fill + \else\if r#1% + \LTleft\fill \LTright\z@ + \else\if c#1% + \LTleft\fill \LTright\fill + \fi\fi\fi + \let\LT@mcol\multicolumn + \let\LT@@@@tabarray\@tabarray + \let\LT@@@@hl\hline + \def\@tabarray{% + \let\hline\LT@@@@hl + \LT@@@@tabarray}% + \let\\\LT@tabularcr + \let\tabularnewline\\% + \def\newpage{\noalign{\break}}% + \def\pagebreak{\noalign{\ifnum`}=0\fi\@testopt{\LT@no@pgbk-}4}% + \def\nopagebreak{\noalign{\ifnum`}=0\fi\@testopt\LT@no@pgbk4}% + \let\hline\LT@hline \let\kill\LT@kill\let\caption\LT@caption + \@tempdima\ht\strutbox + \let\@endpbox\LT@endpbox + \ifx\extrarowheight\@undefined + \let\@acol\@tabacol + \let\@classz\@tabclassz \let\@classiv\@tabclassiv + \def\@startpbox{\vtop\LT@startpbox}% + \let\@@@@startpbox\@startpbox + \let\@@@@endpbox\@endpbox + \let\LT@LL@FM@cr\@tabularcr + \else + \advance\@tempdima\extrarowheight + \col@sep\tabcolsep + \let\@startpbox\LT@startpbox\let\LT@LL@FM@cr\@arraycr + \fi + \setbox\@arstrutbox\hbox{\vrule + \@height \arraystretch \@tempdima + \@depth \arraystretch \dp \strutbox + \@width \z@}% + \let\@sharp##\let\protect\relax + \begingroup + \@mkpream{#2}% + \@@_determine_table_cols: + \xdef\LT@bchunk{% +% \end{macrocode} +% At the start of a chunk we set \cs{g_@@_col_int} to zero to make +% sure that we aren't generating /TR with the \cs{cr} ending the +% chunk preamble. +% \begin{macrocode} + \int_gzero:N \g_@@_col_int + \global\advance\c@LT@chunks\@ne + \global\LT@rows\z@\setbox\z@\vbox\bgroup + \LT@setprevdepth + \tabskip\LTleft \noexpand\halign to\hsize\bgroup + \tabskip\z@ \@arstrut +% \end{macrocode} +% Insert the socket and the setting of the conditional +% \begin{macrocode} + \UseSocket{tagsupport/tblrow/begin}% + \@@_init_cell_data: +% \end{macrocode} +% \begin{macrocode} + \@preamble \tabskip\LTright \cr}% + \endgroup + \expandafter\LT@nofcols\LT@bchunk&\LT@nofcols + \LT@make@row + \m@th\let\par\@empty +% \end{macrocode} +% Socket and conditional +% \begin{macrocode} + \everycr{% + \noalign{% +% \end{macrocode} +% In \pkg{longtable} we have a bunch of extra \cs{cr}s that are +% executed whenever a chunk ends. In that case they should not +% increment the main row counter, sigh. +% \begin{macrocode} + \typeout{--longtable-->~chunk~row:~ \the\LT@rows \space + row:~ \the\g_@@_row_int \space + column:~ \the\g_@@_col_int + } + \int_compare:nNnT \g_@@_col_int > 0 + { + \UseSocket{tagsupport/tblrow/end} + } +% \end{macrocode} +% This prevents any of the additional \cs{cr}s at the end of the +% chunk to add another /TR. Then once we really start a new chunk +% it gets incremented so\ldots +% \begin{macrocode} + \int_gzero:N \g_@@_col_int % before first col +% \end{macrocode} +% And for the same reason such \cs{cr}s should not increment the +% main row counter (but it has to be incremented after the preamble +% of a chunk), so here we test against \cs{LT@rows} which is +% \cs{LTchunksize} at the end of a chunk. +% \begin{macrocode} + \int_compare:nNnT \LT@rows < \LTchunksize + { \int_gincr:N \g_@@_row_int } % this row about to start + }% + }% +% \end{macrocode} +% \begin{macrocode} + \lineskip\z@\baselineskip\z@ + \LT@bchunk} +% \end{macrocode} +% The end code most stop to insert the endrow too. +% \begin{macrocode} +\def\@@_patch_endlongtable{% + \@@_store_missing_cells:n{endlongtable} + \crcr + \noalign{% + \UseSocket{tagsupport/tbl/finalize/longtable} + \int_gzero:N \g_@@_row_int % this prevents considering the next + % \crcr as another row end. + \let\LT@entry\LT@entry@chop + \xdef\LT@save@row{\LT@save@row}}% + \LT@echunk + \LT@start + \unvbox\z@ + \LT@get@widths + \if@filesw + {\let\LT@entry\LT@entry@write\immediate\write\@auxout{% + \gdef\expandafter\noexpand + \csname LT@\romannumeral\c@LT@tables\endcsname + {\LT@save@row}}}% + \fi + \ifx\LT@save@row\LT@@@@save@row + \else + \LT@warn{Column~\@width s~have~changed\MessageBreak + in~table~\thetable}% + \LT@final@warn + \fi + \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@ + \fi + \endgroup + \global\@mparbottom\z@ + \endgraf\penalty\z@\addvspace\LTpost + \ifvoid\footins\else\insert\footins{}\fi} +% \end{macrocode} +% +% +% +% \begin{macro}{\@@_patch_LT@t@bularcr} +% +% \begin{macrocode} +\def\@@_patch_LT@t@bularcr{% + \global\advance\LT@rows\@ne + \ifnum\LT@rows=\LTchunksize +% \end{macrocode} +% At the end of the chunk \verb=\\= is doing something special and +% so we loose \cs{@@_store_missing_cells:n}. Below is about the +% right place to add it do this code branch. +% \begin{macrocode} + \@@_store_missing_cells:n{echunk} + \gdef\LT@setprevdepth{% + \prevdepth\z@ + \global\let\LT@setprevdepth\relax}% + \expandafter\LT@xtabularcr + \else + \ifnum0=`{}\fi + \expandafter\LT@LL@FM@cr + \fi} + +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_patch_LT@end@hd@ft} +% This command is used to store the head and foot boxes. +% We need to retrieve and store the row so that we can clean +% up the structure in the finalize code. +% \begin{macrocode} +\def\@@_patch_LT@end@hd@ft#1{% +% \end{macrocode} +% To handle missing columns in the header we need this: +% \begin{macrocode} + \__tbl_store_missing_cells:n{head/foot} + \int_step_inline:nn + { \LT@rows + 1 } + { + \seq_gput_left:ce + {g_@@_\cs_to_str:N #1 _rows_seq } + { \int_eval:n {\g_@@_row_int + 1 - ##1 } } + } +% \end{macrocode} +% We also have to set the chunk rows to its max value before +% calling \cs{LTechunk} so that we don't get extra increments of +% the main row counter due to \cs{everycr}. +% \begin{macrocode} + \int_gset:Nn \LT@rows { \LTchunksize } + \LT@echunk + \ifx\LT@start\endgraf + \LT@err + {Longtable head or foot not at start of table}% + {Increase LTchunksize}% + \fi + \setbox#1\box\z@ + \LT@get@widths + \LT@bchunk} +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\@@_patch_LT@start} +% \begin{macrocode} +\def\@@_patch_LT@start{% + \let\LT@start\endgraf + \endgraf\penalty\z@\vskip\LTpre\endgraf + \ifdim \pagetotal<\pagegoal \else + \dimen@=\pageshrink + \advance \dimen@ 1sp % + \kern\dimen@\penalty 9999\endgraf \kern-\dimen@ + \fi + \dimen@\pagetotal + \advance\dimen@ \ht\ifvoid\LT@firsthead\LT@head\else\LT@firsthead\fi + \advance\dimen@ \dp\ifvoid\LT@firsthead\LT@head\else\LT@firsthead\fi + \advance\dimen@ \ht\LT@foot + \edef\LT@reset@vfuzz{\vfuzz\the\vfuzz\vbadness\the\vbadness\relax}% + \vfuzz\maxdimen + \vbadness\@M + \setbox\tw@\copy\z@ + \setbox\tw@\vsplit\tw@ to \ht\@arstrutbox + \setbox\tw@\vbox{\unvbox\tw@}% + \LT@reset@vfuzz + \advance\dimen@ \ht + \ifdim\ht\@arstrutbox>\ht\tw@\@arstrutbox\else\tw@\fi + \advance\dimen@\dp + \ifdim\dp\@arstrutbox>\dp\tw@\@arstrutbox\else\tw@\fi + \advance\dimen@ -\pagegoal + \ifdim \dimen@>\z@ + \vfil\break + \else + \ifdim\pageshrink>\z@\pageshrink\z@\fi + \fi + \global\@colroom\@colht + \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@ + \maxdepth\z@ + \fi + \MakeLinkTarget{table} + \ifvoid\LT@firsthead\copy\LT@head\else\box\LT@firsthead\fi\nobreak +% \end{macrocode} +% Avoid that following uses of the box add content: +% \begin{macrocode} + \tagmcbegin{artifact} + \tag_mc_reset_box:N\LT@head + \tagmcend + \output{\LT@output}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@_patch_LT@output} +% We must also avoid that the reuse of the foot box leads to +% duplicated content: +% \begin{macrocode} +\def\@@_patch_LT@output{% + \ifnum\outputpenalty <-\@Mi + \ifnum\outputpenalty > -\LT@end@pen + \LT@err{floats and marginpars not allowed in a longtable}\@ehc + \else + \setbox\z@\vbox{\unvbox\@cclv}% + \ifdim \ht\LT@lastfoot>\ht\LT@foot + \dimen@\pagegoal + \advance\dimen@\ht\LT@foot + \advance\dimen@-\ht\LT@lastfoot + \ifdim\dimen@<\ht\z@ + \setbox\@cclv\vbox{\unvbox\z@\copy\LT@foot\vss}% + \@makecol + \@outputpage + \global\vsize\@colroom + \setbox\z@\vbox{\box\LT@head}% + \fi + \fi + \unvbox\z@\box\ifvoid\LT@lastfoot\LT@foot\else\LT@lastfoot\fi +% \end{macrocode} +% Reset attribute of foot box: +% \begin{macrocode} + \tagmcbegin{artifact} + \tag_mc_reset_box:N \LT@foot + \tagmcend + \fi + \else + \setbox\@cclv\vbox{\unvbox\@cclv\copy\LT@foot\vss}% +% \end{macrocode} +% Reset attribute of foot box: +% \begin{macrocode} + \tagmcbegin{artifact} + \tag_mc_reset_box:N \LT@foot + \tagmcend + \@makecol + \@outputpage + \global\vsize\@colroom + \copy\LT@head\nobreak + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_patch_\LT@makecaption} +% This patch is quite similar to the one for LaTeX's \cs{@makecaption} +% we also have to change the parbox sockets. +% \begin{macrocode} +\def\@@_patch_LT@makecaption#1#2#3{% + \LT@mcol\LT@cols c{% + % test can go after merge + \str_if_exist:cT { l__socket_tagsupport/parbox/before_plug_str } + { + \AssignSocketPlug{tagsupport/parbox/before}{noop} + \AssignSocketPlug{tagsupport/parbox/after}{noop} + } + \hbox to\z@{\hss\parbox[t]\LTcapwidth{% + \reset@font + \tag_stop:n{caption} + \sbox\@tempboxa{#1{#2:~}#3}% + \tag_start:n{caption} + \ifdim\wd\@tempboxa>\hsize + #1{#2:~}#3% + \else + \hbox to\hsize{\hfil#1{#2:~}#3\hfil}% + \fi + \endgraf\vskip\baselineskip}% + \hss}}} +% \end{macrocode} +% \end{macro} +% +% +% +% Overwrite the longtable definition. That will probably break somewhere as +% they are various package which patch too. +% \begin{macrocode} +\AddToHook{package/longtable/after} + { + \seq_new:N \g_@@_LT@firsthead_rows_seq + \seq_new:N \g_@@_LT@head_rows_seq + \seq_new:N \g_@@_LT@lastfoot_rows_seq + \seq_new:N \g_@@_LT@foot_rows_seq + \cs_set_eq:NN \LT@array\@@_patch_LT@array + \cs_set_eq:NN \endlongtable\@@_patch_endlongtable + \cs_set_eq:NN \LT@start\@@_patch_LT@start + \cs_set_eq:NN \LT@output\@@_patch_LT@output + \cs_set_eq:NN \LT@t@bularcr\@@_patch_LT@t@bularcr + \cs_set_eq:NN \LT@end@hd@ft\@@_patch_LT@end@hd@ft + \cs_set_eq:NN \LT@makecaption\@@_patch_LT@makecaption + } +% \end{macrocode} + + + + + +% \subsection{tabularx} +% +% In tabularx we mainly need to ensure that no tagging is done during +% the trial. +% +% \begin{macrocode} +\def\@@_patch_TX@endtabularx{% + \expandafter\expandafter\expandafter + \TX@find@endtabularxa\csname end\TX@\endcsname + \endtabularx\TX@\endtabularx\TX@find@endtabularxa + \expandafter\TX@newcol\expandafter{\tabularxcolumn{\TX@col@width}}% + \let\verb\TX@verb + \def\@elt##1{\global\value{##1}\the\value{##1}\relax}% + \edef\TX@ckpt{\cl@@@@ckpt}% + \let\@elt\relax + \TX@old@table\maxdimen + \TX@col@width\TX@target + \global\TX@cols\@ne + \TX@typeout@ + {\@spaces Table Width\@spaces Column Width\@spaces X Columns}% +% \end{macrocode} +% Here we stop tagging: +% \begin{macrocode} + \tag_stop:n{tabularx} + \TX@trial{\def\NC@rewrite@X{% + \global\advance\TX@cols\@ne\NC@find p{\TX@col@width}}}% + \loop + \TX@arith + \ifTX@ + \TX@trial{}% + \repeat +% \end{macrocode} +% And now we restart it again. +% \begin{macrocode} + \tag_start:n{tabularx} + {\let\@footnotetext\TX@ftntext\let\@xfootnotenext\TX@xftntext + \csname tabular*\expandafter\endcsname\expandafter\TX@target + \the\toks@ + \csname endtabular*\endcsname}% + \global\TX@ftn\expandafter{\expandafter}\the\TX@ftn + \ifnum0=`{\fi}% + \expandafter\expandafter\expandafter + \TX@find@endtabularxbb + \expandafter\end\expandafter{\TX@}% + \endtabularx\TX@\endtabularx\TX@find@endtabularxb +} + +\AddToHook{package/tabularx/after} + {\cs_set_eq:NN \TX@endtabularx\@@_patch_TX@endtabularx } +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% +% +% \begin{macrocode} +%<*latex-lab> +\ProvidesFile{table-latex-lab-testphase.ltx} + [\ltlabtbldate\space v\ltlabtblversion\space latex-lab wrapper table] +\RequirePackage{latex-lab-testphase-table} +% +% \end{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-testphase.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-testphase.dtx index ce882030e8f..b2ed5ecf8a4 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-testphase.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-testphase.dtx @@ -41,11 +41,14 @@ % \section{Introduction} % % This code implements small files which can be loaded with the |testphase| -% key of \cs{DocumentMetadata}. This will be extended to allow user to load +% key of \cs{DocumentMetadata} and which bundle various testphase modules. +% This will be extended to allow user to load % well defined parts of the tagged PDF project. -% Currently the values |phase-I|, |phase-II| and |new-or| are provided. -% |tagpdf| is an undocumented alias for |phase-II| which is kept for compability. % +% Currently the values |phase-I|, |phase-II|, |phase-III| and |new-or| (bundles |new-or-1| +% and |new-or-2|) are provided. +% |tagpdf| is an undocumented alias for |phase-II| which is kept for compability. +% The value |math| combines various math related files. % % \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } % @@ -53,17 +56,12 @@ % \section{The Implementation} % new-or-1 contains the code for header and footer (tagging and % suppressing links) and is always loaded -% \begin{macrocode} -%<*new-or-1> -\ProvidesFile{new-or-1-latex-lab-testphase.ltx} - [2022-11-04 v0.1a latex-lab wrapper new-or-1] -% -% \end{macrocode} + % new-or combines all new-or parts (currently 1+2) % \begin{macrocode} %<*new-or> \ProvidesFile{new-or-latex-lab-testphase.ltx} - [2022-11-04 v0.1a latex-lab wrapper new-or] + [2023-06-15 v0.1b latex-lab wrapper new-or] % % \end{macrocode} % \begin{macrocode} @@ -75,17 +73,17 @@ % \begin{macrocode} %<*phase-II> \ProvidesFile{phase-II-latex-lab-testphase.ltx} - [2022-11-04 v0.1a latex-lab wrapper phase-II] + [2023-06-15 v0.1b latex-lab wrapper phase-II] % % \end{macrocode} % \begin{macrocode} %<*phase-III> \ProvidesFile{phase-III-latex-lab-testphase.ltx} - [2023-03-06 v0.1a latex-lab wrapper phase-III] + [2023-07-20 v0.1b latex-lab wrapper phase-III] \input{phase-II-latex-lab-testphase.ltx} \IfFormatAtLeastTF{2023-06-01} { - \RequirePackage{latex-lab-testphase-block-tagging} + \RequirePackage{latex-lab-testphase-block} \RequirePackage{latex-lab-testphase-sec} \RequirePackage{latex-lab-testphase-toc} \RequirePackage{latex-lab-testphase-minipage} @@ -106,11 +104,11 @@ % % \end{macrocode} % \begin{macrocode} -%<*tagpdf|phase-I|phase-II|new-or|new-or-1> +%<*tagpdf|phase-I|phase-II|new-or> \RequirePackage{latex-lab-testphase-new-or-1} -% +% % \end{macrocode} -% New output routine code is loaded in phase-II and new-or: +% Support for the new output routine code are loaded in phase-II and new-or: % \begin{macrocode} %<*tagpdf|phase-II|new-or> \RequirePackage{latex-lab-testphase-new-or-2} @@ -135,23 +133,23 @@ % \begin{macrocode} % % \end{macrocode} -% Wrapper files for math tagging: +% testphase wrapper files for math: % \begin{macrocode} -%<*math-lab> +%<*math> \ProvidesFile{math-latex-lab-testphase.ltx} - [2023-01-07 v0.8 code related to the math tagging] + [2023-07-20 v0.8a latex-lab wrapper math] \RequirePackage{latex-lab-testphase-math} -% +% % \end{macrocode} % \begin{macrocode} -%<*math-sty> +%<*math-package> \ProvidesPackage{latex-lab-testphase-math} - [2023-01-07 v0.8 code related to the math tagging] -\input{latex-lab-mathtagging.ltx} + [2023-07-20 v0.8a code related to the math tagging] +\input{latex-lab-math.ltx} \input{latex-lab-amsmath.ltx} \input{latex-lab-mathtools.ltx} \input{latex-lab-mathpkg.ltx} -% +% % \end{macrocode} % \Finale % diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-text.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-text.dtx index 0f31c45969e..4041336ecbf 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-text.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-text.dtx @@ -16,6 +16,9 @@ % % for those people who are interested or want to report an issue. % +\def\ltlabtextdate{2023-07-20} +\def\ltlabtextversion{0.85a} + %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -30,7 +33,7 @@ % \title{The \textsf{latex-lab-text} package\\ % Changes and additions to the kernel related to the tagging of various small text commands} % \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} -% \date{Version 0.80 2023-05-28} +% \date{v\ltlabtextversion\ \ltlabtextdate} % % \maketitle % @@ -61,8 +64,8 @@ %<@@=tag> % \end{macrocode} % \begin{macrocode} -\ProvidesExplPackage {latex-lab-testphase-text} {2023-05-28} {0.8} - {Code related to the tagging of inline text commands} +\ProvidesExplPackage {latex-lab-testphase-text} {\ltlabtextdate} {\ltlabtextversion} + {Code related to the tagging of various small text commands} % \end{macrocode} % \subsection{The \LaTeX\ and \TeX\ logo} @@ -124,7 +127,8 @@ % \begin{macrocode} %<*latex-lab> \ProvidesFile{text-latex-lab-testphase.ltx} - [2023-05-28 v0.8 code related to the tagging of bib and citations] + [\ltlabtextdate\space v\ltlabtextversion\space + code related to the tagging of various small text commands] \RequirePackage{latex-lab-testphase-text} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-hyperref-changes.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-hyperref-changes.dtx index 186f388a190..2f00b83c059 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-hyperref-changes.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-hyperref-changes.dtx @@ -16,6 +16,8 @@ % % for those people who are interested or want to report an issue. % +\def\ltlabtochyperdate{2023-07-20} +\def\ltlabtochyperversion{0.85a} %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -29,7 +31,7 @@ % \title{The \textsf{latex-lab-toc-hyperref-changes} package\\ % Changes and additions to hyperref related to toc entries} % \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} -% \date{Version 0.83 2023-06-07} +% \date{v\ltlabtochyperversion\ \ltlabtochyperdate} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-kernel-changes.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-kernel-changes.dtx index 1c1ce7f44e1..81c9edfe4dc 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-kernel-changes.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-kernel-changes.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: latex-lab-toc-kernel-functions.dtx (C) Copyright 2022-2023 LaTeX Project +%% File: latex-lab-toc-kernel-changes.dtx (C) Copyright 2022-2023 LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -16,6 +16,9 @@ % % for those people who are interested or want to report an issue. % +% dates for latex-lab-kernel-changes.sty (pulled from various sources, see ins) +\def\ltlabkerneldate{2023-10-16} +\def\ltlabkernelversion{0.85b} %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -56,6 +59,14 @@ % They are marked as [class]. They are inserted with hooks here: this will break % if a non-standard class is used. % +% \subsection{Package declaration} +% \begin{macrocode} +%<*kernelchange> +\ProvidesPackage{latex-lab-kernel-changes} + [\ltlabkerneldate\space v\ltlabkernelversion\space + General kernel and class changes] +% \end{macrocode} +% % \subsection{Providing the counter representation \cs{theHxx} generally} % [kernel?] % @@ -67,7 +78,6 @@ % % At first we suppress the patches from hyperref: % \begin{macrocode} -%<*kernelchange> \def\hyper@nopatch@counter{} % \end{macrocode} % @@ -142,8 +152,32 @@ \def\toclevel@subparagraph{5} \def\toclevel@figure{1} \def\toclevel@table{1} +% \end{macrocode} +% +%\subsection{Storing the relation between target names and structure numbers} +% To be able to add a /Ref key to structures the tagging makes use of target names +% and stores the relationship in a property. We add a hook to \cs{MakeLinkTarget} to +% catch as much as possible, see also tagging issue \#20. This should work also +% without hyperref. The property is defined in tagpdf-base, so the code would +% work also without tagging but we add a test anyway, this is probably faster. +% \begin{macrocode} +\ExplSyntaxOn +\AddToHookWithArguments{cmd/MakeLinkTarget/after} + { + \tag_if_active:T + { + \tl_if_blank:VF \@currentHref + { + \prop_gput:Nee \g__tag_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}} + } + } + } +\ExplSyntaxOff +% \end{macrocode} +% \begin{macrocode} % % \end{macrocode} +% % \subsection{load kernel changes} % \begin{macrocode} %<*package> @@ -461,13 +495,3 @@ % \begin{macrocode} % % \end{macrocode} - -% \begin{macrocode} -%<*latex-lab> -\ProvidesFile{toc-tagging-latex-lab-testphase.ltx} - [2023-05-20 v0.81 code related to the tagging of toc and similar lists] - -\RequirePackage{latex-lab-testphase-toc} - -% -% \end{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-tagging-functions.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-tagging-functions.dtx deleted file mode 100644 index a39ace44e5b..00000000000 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-tagging-functions.dtx +++ /dev/null @@ -1,365 +0,0 @@ -% \iffalse meta-comment -% -%% File: latex-lab-toc-tagging-functions.dtx (C) Copyright 2022-2023 LaTeX Project -% -% It may be distributed and/or modified under the conditions of the -% LaTeX Project Public License (LPPL), either version 1.3c of this -% license or (at your option) any later version. The latest version -% of this license is in the file -% -% https://www.latex-project.org/lppl.txt -% -% -% The development version of the bundle can be found below -% -% https://github.com/latex3/latex2e/required/latex-lab -% -% for those people who are interested or want to report an issue. -% -%<*driver> -\documentclass{l3doc} -\EnableCrossrefs -\CodelineIndex -\begin{document} - \DocInput{latex-lab-toc-tagging-functions.dtx} -\end{document} -% -% -% \fi -% -% -% \title{The \textsf{latex-lab-toc-tagging-functions} package\\ -% Tagpdf functions related to the tagging of toc and similar lists} -% \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} -% \date{Version 0.82 2023-05-20} -% -% \maketitle -% -% \newcommand{\xt}[1]{\textsl{\textsf{#1}}} -% \newcommand{\TODO}[1]{\textbf{[TODO:} #1\textbf{]}} -% \newcommand{\docclass}{document class \marginpar{\raggedright document class -% customizations}} -% -% \providecommand\hook[1]{\texttt{#1}} -% -% \begin{abstract} -% \end{abstract} -% -% Header for the testphase package -% \begin{macrocode} -%<*header> -\ProvidesExplPackage {latex-lab-testphase-toc} {2023-05-20} {0.82} - { commands related to the tagging of toc-like lists} -% -% \end{macrocode} -% -% \section{Introduction} -% -% The followings contains various functions related to the tagging of the -% table of contents and similar list. The functions will at some time -% be moved inside the tagpdf code. -% \begin{macrocode} -%<*package> -%<@@=tag> -% \end{macrocode} -% \section{Temporary variables} -% \begin{macro}{\l_@@_toc_tmpa_tl} -% \begin{macrocode} -\tl_new:N \l_@@_toc_tmpa_tl -% \end{macrocode} -% \end{macro} -% -% \section{General struct commands} -% The following variables and commands are not restricted to toc, but -% probably will be need in other places too. -% \begin{variable}{\g_@@_struct_dest_num_prop} -% This variable records for (some or all, not clear yet) -% destination names the related structure number to allow -% to reference them in a Ref. The key is the destination. -% Moved into tagpdf! -% \end{variable} -% -% We use \cs{refstepcounter} to store the relation between -% destination names/\cs{@currentHref} and structure numbers -% -% TODO: the functions should be moved into tagpdf so that one -% doesn't has to test if the prop exists or not. -% \begin{macrocode} -\AddToHook{cmd/refstepcounter/after} - { - \tl_if_blank:VF \@currentHref - { - \prop_if_exist:NT \g_@@_struct_dest_num_prop - { - \prop_gput:Nxx \g_@@_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}} - } - } - } -\AddToHook{cmd/H@refstepcounter/after} - { - \tl_if_blank:VF \@currentHref - { - \prop_if_exist:NT \g_@@_struct_dest_num_prop - { - \prop_gput:Nxx \g_@@_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}} - } - } - } -% \end{macrocode} -% \begin{variable}{\g_@@_struct_ref_by_dest_prop} -% This variable contains structures whose Ref key should be updated -% at the end to point to structured related with this destination. -% As this is probably need in other places too, it is not only a toc-variable. -% Moved into tagpdf! -% \end{variable} -% -% \begin{macro}{\g_@@_struct_ref_by_dest:} -% This command is executed and update the Ref keys -% of the structures listed in |\g_@@_struct_ref_by_dest_prop|. -% It is currently only relevant for the |TOCI|. But other structures -% could need that later too. -% The command is executed in the |tagpdf/finish/before| hook. -% \begin{macrocode} -\msg_new:nnn { tag } {struct-dest-unknown} - { - Destination~#1~has~no~related~structure.\\ - /Ref~for~structure~#2~not~updated - } - -\cs_new_protected:Npn \g_@@_struct_ref_by_dest: - { - \prop_map_inline:Nn\g_@@_struct_ref_by_dest_prop - { - \prop_get:NnNTF \g_@@_struct_dest_num_prop {##2} \l_@@_tmpa_tl - { - \@@_struct_gput_data_ref:ee - { ##1 } - { \tag_struct_object_ref:e{ \l_@@_tmpa_tl }} - } - { - \msg_warning:nnnn {tag}{struct-dest-unknown}{##2}{ ##1} - } - } - } -\hook_gput_code:nnn {tagpdf/finish/before}{tagpdf/struct/Ref}{\g_@@_struct_ref_by_dest:} -% \end{macrocode} -% \end{macro} -% -% \section{Toc code} -% \begin{variable}{\g_@@_toc_level_int,\g_@@_toc_stack_seq} -% |\g_@@_toc_level_int| records in a toc the current absolute level. -% We must close open structures at the end of the toc, for this -% we maintain a stack |\g_@@_toc_stack_seq|. -% \begin{macrocode} -\int_new:N \g_@@_toc_level_int -\seq_new:N \g_@@_toc_stack_seq -% \end{macrocode} -% \end{variable} - -% \begin{macro}{\_tag_toc_starttoc_init:n} -% The init code clears the stack, and set the level to -100 -% and start to TOC structure. We also disable paratagging. -% The |/Title| is currently simply the type, but this could be done nicer. -% \begin{macrocode} -\cs_new_protected:Npn \@@_toc_starttoc_init:n #1 - { - \bool_set_false:N \l_@@_para_bool - \seq_gclear:N \g_@@_toc_stack_seq - \int_gset:Nn \g_@@_toc_level_int {-100} - \tag_struct_begin:n{tag=TOC,title=#1} - } -% \end{macrocode} -% Now map it into the config point: -% \begin{macrocode} -\cs_set_protected:Npn\@starttoc@cfgpoint@before#1 - { - \@@_toc_starttoc_init:n{#1} - } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\@@_toc_starttoc_finalize:} -% \begin{macrocode} -\cs_new_protected:Npn \@@_toc_starttoc_finalize: - { - \int_step_inline:nn - {\seq_count:N \g_@@_toc_stack_seq } - {\tag_struct_end:} - \tag_struct_end: - \seq_gclear:N \g_@@_toc_stack_seq - } -% \end{macrocode} -% Now map it into the config point: -% \begin{macrocode} -\cs_set_protected:Npn\@starttoc@cfgpoint@after#1 - { - \@@_toc_starttoc_finalize: - } -% \end{macrocode} -% \end{macro} - -% \begin{macro}{\@@_toc_end:n} -% This commands ends all TOC on the stack with a level higher than the argument -% \begin{macrocode} -\cs_new_protected:Npn \@@_toc_end:n #1 - { - \seq_get:NNT\g_@@_toc_stack_seq \l_@@_toc_tmpa_tl - { - \bool_lazy_and:nnT - { - \str_if_eq_p:ee{\tl_head:N\l_@@_toc_tmpa_tl}{TOC} - } - { - \int_compare_p:nNn {#1}<{\tl_tail:N \l_@@_toc_tmpa_tl} - } - { - \seq_gpop:NN\g_@@_toc_stack_seq \l_@@_toc_tmpa_tl - \tag_struct_end: - \@@_toc_end:n{#1} - } - } - } -\cs_generate_variant:Nn \@@_toc_end:n {e} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_toc_contentsline_begin:nnn} -% This is main command executed at the begin of a |\contentsline|. -% \begin{macrocode} -\cs_new_protected:Npn \@@_toc_contentsline_begin:nnn #1 #2 #3 %#1 level, #2 content, #3 destination - { - \tag_if_active:T - { -% \end{macrocode} -% We detect the intended level by checking the value of |toclevel@...| -% (currently only provided by hyperref, but should be there always). -% To be on the safe side we set it to 1 if not defined. -% \begin{macrocode} - \ExpandArgs{c}\providecommand { toclevel@#1 }{ 1 } % just in case ... - \int_compare:nNnF { \use:c{toclevel@#1} } > {\use:c{c@tocdepth}} - { -% \end{macrocode} -% if level goes up, start new sub TOC unless we are at the begin -% \begin{macrocode} - \bool_lazy_and:nnT - { \int_compare_p:nNn { \g_@@_toc_level_int } > {-100} } - { \int_compare_p:nNn { \use:c{toclevel@#1} } > { \g_@@_toc_level_int } } - { - \seq_gpush:Nx \g_@@_toc_stack_seq {{TOC}\use:c{toclevel@#1}} - \tag_struct_begin:n{tag=TOC} - } -% \end{macrocode} -% if level goes down close all TOC's with a higher level -% \begin{macrocode} - \int_compare:nNnT - { \use:c{toclevel@#1} } < { \g_@@_toc_level_int } - { - \@@_toc_end:e { \use:c{toclevel@#1} } - } -% \end{macrocode} -%if same level do nothing -% update toclevel to the current level. -% \begin{macrocode} - \int_gset:Nn \g_@@_toc_level_int { \use:c{toclevel@#1} } -% \end{macrocode} -% now open the TOCI, the tagging of the -% inner structure is left to the |\l@xxx| commands. -% setting the title is not strictly necessary but looks nicer -% but we have to remove the |\numberline| -% \begin{NOTE}{UF} -% perhaps keep the number? How to insert a space then -% \end{NOTE} -% \begin{macrocode} - \group_begin: - \text_declare_expand_equivalent:Nn \numberline \use_none:n - \exp_args:Nx \tag_struct_begin:n{tag=TOCI,title={\text_purify:n {#2}}} -% \end{macrocode} -% The TOCI structure should get a /Ref, so we put a request with its destination -% name into the prop. -% \begin{NOTE}{UF} -% This only works with hyperref currently. Without hyperref we -% need to store fake names. -% \end{NOTE} -% \begin{macrocode} - \prop_gput:Nxx \g_@@_struct_ref_by_dest_prop - { \tag_get:n {struct_num} }{#3} - \seq_gpush:Nx \g_@@_toc_stack_seq {{TOCI}\use:c{toclevel@#1}} - \group_end: - } - } - } -% \end{macrocode} -% Now map it into the config point: -% \begin{macrocode} -\cs_set_protected:Npn\@contentsline@cfgpoint@before#1#2#3#4 - { - \@@_toc_contentsline_begin:nnn {#1}{#2}{#4} - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_toc_contentsline_end:n} -% This is the closing code of a |\contentsline|. -% If the contentsline was actually printed, the code has to -% close the TOCI structure and to update the stack. -% \begin{macrocode} -\msg_new:nnn {tag}{toc-no-TOCI}{Missing~TOCI~structure~on~toc~stack} - -\cs_new_protected:Npn \@@_toc_contentsline_end:n #1 %#1 level name - { - \int_compare:nNnF { \use:c{toclevel@#1} } > {\use:c{c@tocdepth}} - { - \seq_gpop:NNT \g_@@_toc_stack_seq\l_@@_tmpa_tl - { - \str_if_eq:eeTF{\tl_head:N\l_@@_tmpa_tl}{TOCI} - { - \tag_struct_end: - } - { - \msg_warning:nn{tag}{toc-no-TOCI} - } - } - } - } -% \end{macrocode} -% Now we map it to the config point -% \begin{macrocode} -\cs_set_protected:Npn \@contentsline@cfgpoint@after #1#2#3#4 - { - \@@_toc_contentsline_end:n {#1} - } -% \end{macrocode} -% \end{macro} -% -% \subsection{Tagging of the content} -% This need discussion. -% -% \begin{macrocode} -\AddToHook{contentsline/text/before}[tagpdf]{% - \tag_struct_begin:n{tag=Reference}% - \tag_mc_begin:n{tag=Reference}} -\AddToHook{contentsline/text/after}[tagpdf]{% - \tag_mc_end:} -\AddToHook{contentsline/page/before}[tagpdf]{% - \tag_mc_begin:n{tag=Reference}} -\AddToHook{contentsline/page/after}[tagpdf]{% - \tag_mc_end: - \tag_struct_end:} %Reference -\AddToHook{contentsline/number/before}[tagpdf]{% - \tag_mc_end: - \tag_struct_begin:n{tag=Lbl}% - \tag_mc_begin:n{tag=Lbl}} -\AddToHook{contentsline/number/after}[tagpdf]{% - \tag_mc_end: - \tag_struct_end: - \tag_mc_begin:n{tag=Reference}} -% \end{macrocode} -% -% \begin{macrocode} -\def\@dottedtocline@cfgpoint@leaders#1{% - \tag_mc_begin:n{artifact}\tag_stop:n{leaders}\nobreak#1\nobreak\tag_start:n{leaders}\tag_mc_end:} -% \end{macrocode} - -% -% \begin{macrocode} -% -% \end{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc.dtx new file mode 100644 index 00000000000..6def505e113 --- /dev/null +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc.dtx @@ -0,0 +1,403 @@ +% \iffalse meta-comment +% +%% File: latex-lab-toc.dtx (C) Copyright 2022-2023 LaTeX Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% +% The development version of the bundle can be found below +% +% https://github.com/latex3/latex2e/required/latex-lab +% +% for those people who are interested or want to report an issue. +% +\def\ltlabtocdate{2023-10-16} +\def\ltlabtocversion{0.85b} +%<*driver> +\documentclass{l3doc} +\EnableCrossrefs +\CodelineIndex +\begin{document} + \DocInput{latex-lab-toc.dtx} +\end{document} +% +% +% \fi +% +% +% \title{The \textsf{latex-lab-toc} package\\ +% Changes related to the tagging of toc and similar lists} +% \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} +% \date{v\ltlabtocdate\ \ltlabtocversion} +% +% \maketitle +% +% \newcommand{\xt}[1]{\textsl{\textsf{#1}}} +% \newcommand{\TODO}[1]{\textbf{[TODO:} #1\textbf{]}} +% \newcommand{\docclass}{document class \marginpar{\raggedright document class +% customizations}} +% +% \providecommand\hook[1]{\texttt{#1}} +% +% \begin{abstract} +% \end{abstract} +% +% Header for the testphase package +% \begin{macrocode} +%<*header> +\ProvidesExplPackage {latex-lab-testphase-toc} {\ltlabtocdate} {\ltlabtocversion} + { Code related to the tagging of toc-like lists} +% +% \end{macrocode} +% \begin{documentation} +% \section{Introduction} +% +% The followings contains various functions related to the tagging of the +% table of contents and similar list. +% +% The structure of tocs consist of nested TOC and TOCI structures. +% The code uses the first argument of the \cs{contentsline} command to detect the +% level and to decided if a structure should be closed. The structure that +% should be used in \texttt{/Ref} key to link to the heading is detected from the +% target name in the fourth argument -- because of this with this code such a target +% name is created and stored also if hyperref is not loaded. +% +% \subsection{Manual toc additions} +% As the \texttt{/Ref} key relies on the target name, +% manual \cs{addcontentsline} commands must ensure that they reference the right +% structure. If an unnumbered heading command is used before this is normally the case, +% so the following should work fine: +% +% \begin{verbatim} +% \chapter*{Unnumbered} +% \addcontentsline{toc}{chapter}{Unnumbered} +% \end{verbatim} +% +% If there is no heading command a target name must be created manually \emph{inside the +% right structure} with \cs{MakeLinkTarget}: +% +% \begin{verbatim} +% \noindent % start e.g. P-structure +% \MakeLinkTarget*{unnumbered}% target inside the P-structure +% Unnumbered +% \addcontentsline{toc}{chapter}{Unnumbered} +% \end{verbatim} +% +% \end{documentation} +% \begin{implementation} +% \begin{macrocode} +%<*package> +%<@@=tag> +% \end{macrocode} +% \section{Temporary variables} +% \begin{macro}{\l_@@_toc_tmpa_tl} +% \begin{macrocode} +\tl_new:N \l_@@_toc_tmpa_tl +% \end{macrocode} +% \end{macro} +% +% \section{General struct commands} +% The following variables and commands are not restricted to toc, but +% probably will be need in other places too. +% \begin{variable}{\g_@@_struct_dest_num_prop} +% This variable records for (some or all, not clear yet) +% destination names the related structure number to allow +% to reference them in a Ref. The key is the destination. +% Defined by tagpdf. +% \end{variable} +% +% \cs{refstepcounter} doesn't use \cs{MakeLinkTarget} (yet) so +% we have to patch it too to store the relation between +% destination names/\cs{@currentHref} and structure numbers +% +% The property is set up in tagpdf-test so that one +% doesn't has to check if the prop exists or not. +% \begin{macrocode} +\AddToHook{cmd/refstepcounter/after} + { + \tl_if_blank:VF \@currentHref + { + \prop_gput:Nee \g_@@_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}} + } + } +\AddToHook{cmd/H@refstepcounter/after} + { + \tl_if_blank:VF \@currentHref + { + \prop_gput:Nee \g_@@_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}} + } + } +% \end{macrocode} +% \begin{variable}{\g_@@_struct_ref_by_dest_prop} +% This variable contains structures whose Ref key should be updated +% at the end to point to structured related with this destination. +% As this is probably need in other places too, it is not only a toc-variable. +% Moved into tagpdf! +% \end{variable} +% +% \begin{macro}{\g_@@_struct_ref_by_dest:} +% This command is executed and update the Ref keys +% of the structures listed in |\g_@@_struct_ref_by_dest_prop|. +% It is currently only relevant for the |TOCI|. But other structures +% could need that later too. +% The command is executed in the |tagpdf/finish/before| hook. +% \begin{macrocode} +\msg_new:nnn { tag } {struct-dest-unknown} + { + Destination~#1~has~no~related~structure.\\ + /Ref~for~structure~#2~not~updated + } + +\cs_new_protected:Npn \g_@@_struct_ref_by_dest: + { + \prop_map_inline:Nn\g_@@_struct_ref_by_dest_prop + { + \prop_get:NnNTF \g_@@_struct_dest_num_prop {##2} \l_@@_tmpa_tl + { + \@@_struct_gput_data_ref:ee + { ##1 } + { \tag_struct_object_ref:e{ \l_@@_tmpa_tl }} + } + { + \msg_warning:nnnn {tag}{struct-dest-unknown}{##2}{ ##1} + } + } + } +\hook_gput_code:nnn {tagpdf/finish/before}{tagpdf/struct/Ref}{\g_@@_struct_ref_by_dest:} +% \end{macrocode} +% \end{macro} +% +% \section{Toc code} +% \begin{variable}{\g_@@_toc_level_int,\g_@@_toc_stack_seq} +% |\g_@@_toc_level_int| records in a toc the current absolute level. +% We must close open structures at the end of the toc, for this +% we maintain a stack |\g_@@_toc_stack_seq|. +% \begin{macrocode} +\int_new:N \g_@@_toc_level_int +\seq_new:N \g_@@_toc_stack_seq +% \end{macrocode} +% \end{variable} + +% \begin{macro}{\_tag_toc_starttoc_init:n} +% The init code clears the stack, and set the level to -100 +% and start to TOC structure. We also disable paratagging. +% The |/Title| is currently simply the type, but this could be done nicer. +% \begin{macrocode} +\cs_new_protected:Npn \@@_toc_starttoc_init:n #1 + { + \bool_set_false:N \l_@@_para_bool + \seq_gclear:N \g_@@_toc_stack_seq + \int_gset:Nn \g_@@_toc_level_int {-100} + \tag_struct_begin:n{tag=TOC,title=#1} + } +% \end{macrocode} +% Now map it into the config point: +% \begin{macrocode} +\cs_set_protected:Npn\@starttoc@cfgpoint@before#1 + { + \@@_toc_starttoc_init:n{#1} + } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@@_toc_starttoc_finalize:} +% \begin{macrocode} +\cs_new_protected:Npn \@@_toc_starttoc_finalize: + { + \int_step_inline:nn + {\seq_count:N \g_@@_toc_stack_seq } + {\tag_struct_end:} + \tag_struct_end: + \seq_gclear:N \g_@@_toc_stack_seq + } +% \end{macrocode} +% Now map it into the config point: +% \begin{macrocode} +\cs_set_protected:Npn\@starttoc@cfgpoint@after#1 + { + \@@_toc_starttoc_finalize: + } +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\@@_toc_end:n} +% This commands ends all TOC on the stack with a level higher than the argument +% \begin{macrocode} +\cs_new_protected:Npn \@@_toc_end:n #1 + { + \seq_get:NNT\g_@@_toc_stack_seq \l_@@_toc_tmpa_tl + { + \bool_lazy_and:nnT + { + \str_if_eq_p:ee{\tl_head:N\l_@@_toc_tmpa_tl}{TOC} + } + { + \int_compare_p:nNn {#1}<{\tl_tail:N \l_@@_toc_tmpa_tl} + } + { + \seq_gpop:NN\g_@@_toc_stack_seq \l_@@_toc_tmpa_tl + \tag_struct_end: + \@@_toc_end:n{#1} + } + } + } +\cs_generate_variant:Nn \@@_toc_end:n {e} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_toc_contentsline_begin:nnn} +% This is main command executed at the begin of a |\contentsline|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_toc_contentsline_begin:nnn #1 #2 #3 %#1 level, #2 content, #3 destination + { + \tag_if_active:T + { +% \end{macrocode} +% We detect the intended level by checking the value of |toclevel@...| +% (currently only provided by hyperref, but should be there always). +% To be on the safe side we set it to 1 if not defined. +% \begin{macrocode} + \ExpandArgs{c}\providecommand { toclevel@#1 }{ 1 } % just in case ... + \int_compare:nNnF { \use:c{toclevel@#1} } > {\use:c{c@tocdepth}} + { +% \end{macrocode} +% if level goes up, start new sub TOC unless we are at the begin +% \begin{macrocode} + \bool_lazy_and:nnT + { \int_compare_p:nNn { \g_@@_toc_level_int } > {-100} } + { \int_compare_p:nNn { \use:c{toclevel@#1} } > { \g_@@_toc_level_int } } + { + \seq_gpush:Nx \g_@@_toc_stack_seq {{TOC}\use:c{toclevel@#1}} + \tag_struct_begin:n{tag=TOC} + } +% \end{macrocode} +% if level goes down close all TOC's with a higher level +% \begin{macrocode} + \int_compare:nNnT + { \use:c{toclevel@#1} } < { \g_@@_toc_level_int } + { + \@@_toc_end:e { \use:c{toclevel@#1} } + } +% \end{macrocode} +%if same level do nothing +% update toclevel to the current level. +% \begin{macrocode} + \int_gset:Nn \g_@@_toc_level_int { \use:c{toclevel@#1} } +% \end{macrocode} +% now open the TOCI, the tagging of the +% inner structure is left to the |\l@xxx| commands. +% setting the title is not strictly necessary but looks nicer +% but we have to remove the |\numberline| +% \begin{NOTE}{UF} +% perhaps keep the number? How to insert a space then +% \end{NOTE} +% \begin{macrocode} + \group_begin: + \text_declare_expand_equivalent:Nn \numberline \use_none:n + \exp_args:Nx \tag_struct_begin:n{tag=TOCI,title={\text_purify:n {#2}}} +% \end{macrocode} +% The TOCI structure should get a /Ref, so we put a request with its destination +% name into the prop. +% \begin{NOTE}{UF} +% This only works with hyperref currently. Without hyperref we +% need to store fake names. +% \end{NOTE} +% \begin{macrocode} + \prop_gput:Nxx \g_@@_struct_ref_by_dest_prop + { \tag_get:n {struct_num} }{#3} + \seq_gpush:Nx \g_@@_toc_stack_seq {{TOCI}\use:c{toclevel@#1}} + \group_end: + } + } + } +% \end{macrocode} +% Now map it into the config point: +% \begin{macrocode} +\cs_set_protected:Npn\@contentsline@cfgpoint@before#1#2#3#4 + { + \@@_toc_contentsline_begin:nnn {#1}{#2}{#4} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_toc_contentsline_end:n} +% This is the closing code of a |\contentsline|. +% If the contentsline was actually printed, the code has to +% close the TOCI structure and to update the stack. +% \begin{macrocode} +\msg_new:nnn {tag}{toc-no-TOCI}{Missing~TOCI~structure~on~toc~stack} + +\cs_new_protected:Npn \@@_toc_contentsline_end:n #1 %#1 level name + { + \int_compare:nNnF { \use:c{toclevel@#1} } > {\use:c{c@tocdepth}} + { + \seq_gpop:NNT \g_@@_toc_stack_seq\l_@@_tmpa_tl + { + \str_if_eq:eeTF{\tl_head:N\l_@@_tmpa_tl}{TOCI} + { + \tag_struct_end: + } + { + \msg_warning:nn{tag}{toc-no-TOCI} + } + } + } + } +% \end{macrocode} +% Now we map it to the config point +% \begin{macrocode} +\cs_set_protected:Npn \@contentsline@cfgpoint@after #1#2#3#4 + { + \@@_toc_contentsline_end:n {#1} + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Tagging of the content} +% This need discussion. +% +% \begin{macrocode} +\AddToHook{contentsline/text/before}[tagpdf]{% + \tag_struct_begin:n{tag=Reference}% + \tag_mc_begin:n{tag=Reference}} +\AddToHook{contentsline/text/after}[tagpdf]{% + \tag_mc_end:} +\AddToHook{contentsline/page/before}[tagpdf]{% + \tag_mc_begin:n{tag=Reference}} +\AddToHook{contentsline/page/after}[tagpdf]{% + \tag_mc_end: + \tag_struct_end:} %Reference +\AddToHook{contentsline/number/before}[tagpdf]{% + \tag_mc_end: + \tag_struct_begin:n{tag=Lbl}% + \tag_mc_begin:n{tag=Lbl}} +\AddToHook{contentsline/number/after}[tagpdf]{% + \tag_mc_end: + \tag_struct_end: + \tag_mc_begin:n{tag=Reference}} +% \end{macrocode} +% +% \begin{macrocode} +\def\@dottedtocline@cfgpoint@leaders#1{% + \tag_mc_begin:n{artifact}\tag_stop:n{leaders}\nobreak#1\nobreak\tag_start:n{leaders}\tag_mc_end:} +% \end{macrocode} + +% +% \begin{macrocode} +% +% \end{macrocode} +% Wrapper for the testphase key. +% \begin{macrocode} +%<*latex-lab> +\ProvidesFile{toc-latex-lab-testphase.ltx} + [\ltlabtocdate\space v\ltlabtocversion latex-lab wrapper toc] + +\RequirePackage{latex-lab-testphase-toc} + +% +% \end{macrocode} +% \end{implementation} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab.ins b/Master/texmf-dist/source/latex/latex-lab/latex-lab.ins index 1989ddcfa34..548f18a6fa7 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab.ins +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab.ins @@ -66,87 +66,104 @@ where one can also log issues in case there are any. % files that should be loadable with the testphase key should use the naming scheme % #1-latex-lab-testphase.ltx + +%%% phases and bundles %%% +% phases \generate{\file{phase-I-latex-lab-testphase.ltx}{\from{latex-lab-testphase.dtx}{phase-I}}} \generate{\file{phase-II-latex-lab-testphase.ltx}{\from{latex-lab-testphase.dtx}{phase-II}}} \generate{\file{phase-III-latex-lab-testphase.ltx}{\from{latex-lab-testphase.dtx}{phase-III}}} - +% obsolete \generate{\file{tagpdf-latex-lab-testphase.ltx}{\from{latex-lab-testphase.dtx}{tagpdf}}} + +%new-or (no style, only wrapper, private and not documentated) \generate{\file{new-or-latex-lab-testphase.ltx}{\from{latex-lab-testphase.dtx}{new-or}}} -\generate{\file{new-or-1-latex-lab-testphase.ltx}{\from{latex-lab-testphase.dtx}{new-or-1}}} -\generate{\file{math-latex-lab-testphase.ltx}{\from{latex-lab-testphase.dtx}{math-lab}}} -\generate{\file{latex-lab-testphase-math.sty}{\from{latex-lab-testphase.dtx}{math-sty}}} +% math +\generate{\file{math-latex-lab-testphase.ltx}{\from{latex-lab-testphase.dtx}{math}}} +\generate{\file{latex-lab-testphase-math.sty}{\from{latex-lab-testphase.dtx}{math-package}}} -% support files (the new-or code is a private package to make life easier) -\generate{\file{latex-lab-testphase-new-or-2.sty}{\from{latex-lab-new-or-2.dtx}{code}}} -\generate{\file{latex-lab-testphase-new-or-1.sty}{\from{latex-lab-new-or-1.dtx}{code}}} +%%% support files loaded by phases and testphase modules %%% +%footnotes \generate{\file{latex-lab-footmisc.ltx}{\from{latex-lab-footnotes.dtx}{footmisc}}} \generate{\file{latex-lab-footnotes.ltx}{\from{latex-lab-footnotes.dtx}{kernel}}} -\generate{\file{latex-lab-mathtagging.ltx}{\from{latex-lab-mathtagging.dtx}{kernel}}} +%new-or-2 +\generate{\file{latex-lab-testphase-new-or-2.sty}{\from{latex-lab-new-or-2.dtx}{package}}} + +%math +\generate{\file{latex-lab-math.ltx}{\from{latex-lab-math.dtx}{kernel}}} \generate{\file{latex-lab-amsmath.ltx}{\from{latex-lab-amsmath.dtx}{kernel}}} \generate{\file{latex-lab-mathtools.ltx}{\from{latex-lab-mathtools.dtx}{kernel}}} \generate{\file{latex-lab-mathpkg.ltx}{\from{latex-lab-mathpkg.dtx}{kernel}}} -\generate{\file{latex-lab-testphase-sec.sty}{\from{latex-lab-sec.dtx}{package}}} -\generate{\file{sec-tagging-latex-lab-testphase.ltx}{\from{latex-lab-sec.dtx}{latex-lab}}} - - -\generate{\file{latex-lab-testphase-toc.sty}{% - \from{latex-lab-toc-tagging-functions.dtx}{header} - \from{latex-lab-toc-kernel-changes.dtx}{package} - \from{latex-lab-toc-tagging-functions.dtx}{package} - \from{latex-lab-toc-hyperref-changes.dtx}{package}}} - -\generate{\file{toc-tagging-latex-lab-testphase.ltx}{% - \from{latex-lab-toc-kernel-changes.dtx}{latex-lab}}} - +% kernel changes need by more than one module \generate{\file{latex-lab-kernel-changes.sty} {\from{latex-lab-toc-kernel-changes.dtx}{kernelchange} \from{latex-lab-sec.dtx}{kernelchange} }} -\generate{\file{latex-lab-testphase-graphic.sty}{% - \from{latex-lab-graphic.dtx}{package}}} +%%% single modules %%% +%new-or-1 +\generate{\file{new-or-1-latex-lab-testphase.ltx}{\from{latex-lab-new-or-1.dtx}{latex-lab}}} +\generate{\file{latex-lab-testphase-new-or-1.sty}{\from{latex-lab-new-or-1.dtx}{package}}} -\generate{\file{graphic-latex-lab-testphase.ltx}{% - \from{latex-lab-graphic.dtx}{latex-lab}}} +%sec +\generate{\file{sec-latex-lab-testphase.ltx}{\from{latex-lab-sec.dtx}{latex-lab}}} +\generate{\file{latex-lab-testphase-sec.sty}{\from{latex-lab-sec.dtx}{package}}} -\generate{\file{latex-lab-testphase-block-tagging.sty}{\from{latex-lab-block-tagging.dtx}{package}}} -\generate{\file{block-tagging-latex-lab-testphase.ltx}{\from{latex-lab-block-tagging.dtx}{latex-lab}}} -\generate{\file{latex-lab-testphase-minipage.sty}{% - \from{latex-lab-minipage.dtx}{package}}} +%toc +\generate{\file{toc-latex-lab-testphase.ltx}{\from{latex-lab-toc.dtx}{latex-lab}}} -\generate{\file{minipage-latex-lab-testphase.ltx}{% - \from{latex-lab-minipage.dtx}{latex-lab}}} - - \generate{\file{latex-lab-testphase-float.sty}{% - \from{latex-lab-float.dtx}{package}}} +\generate{\file{latex-lab-testphase-toc.sty}{% + \from{latex-lab-toc.dtx}{header} + \from{latex-lab-toc-kernel-changes.dtx}{package} + \from{latex-lab-toc.dtx}{package} + \from{latex-lab-toc-hyperref-changes.dtx}{package}}} -\generate{\file{float-latex-lab-testphase.ltx}{% - \from{latex-lab-float.dtx}{latex-lab}}} - -\generate{\file{latex-lab-testphase-bib.sty}{% - \from{latex-lab-bib.dtx}{package}}} +%graphic +\generate{\file{graphic-latex-lab-testphase.ltx}{\from{latex-lab-graphic.dtx}{latex-lab}}} +\generate{\file{latex-lab-testphase-graphic.sty}{\from{latex-lab-graphic.dtx}{package}}} + +% block +\generate{\file{latex-lab-testphase-block.sty}{\from{latex-lab-block.dtx}{package}}} +\generate{\file{block-latex-lab-testphase.ltx}{\from{latex-lab-block.dtx}{latex-lab}}} -\generate{\file{bib-latex-lab-testphase.ltx}{% - \from{latex-lab-bib.dtx}{latex-lab}}} +% minipage +\generate{\file{minipage-latex-lab-testphase.ltx}{\from{latex-lab-minipage.dtx}{latex-lab}}} +\generate{\file{latex-lab-testphase-minipage.sty}{\from{latex-lab-minipage.dtx}{package}}} -\generate{\file{latex-lab-testphase-text.sty}{% - \from{latex-lab-text.dtx}{package}}} +%float +\generate{\file{float-latex-lab-testphase.ltx}{\from{latex-lab-float.dtx}{latex-lab}}} +\generate{\file{latex-lab-testphase-float.sty}{\from{latex-lab-float.dtx}{package}}} -\generate{\file{text-latex-lab-testphase.ltx}{% - \from{latex-lab-text.dtx}{latex-lab}}} +%bib +\generate{\file{bib-latex-lab-testphase.ltx}{\from{latex-lab-bib.dtx}{latex-lab}}} +\generate{\file{latex-lab-testphase-bib.sty}{\from{latex-lab-bib.dtx}{package}}} -\generate{\file{latex-lab-testphase-firstaid.sty}{% - \from{latex-lab-firstaid.dtx}{package}}} +%text +\generate{\file{text-latex-lab-testphase.ltx}{\from{latex-lab-text.dtx}{latex-lab}}} +\generate{\file{latex-lab-testphase-text.sty}{\from{latex-lab-text.dtx}{package}}} -\generate{\file{firstaid-latex-lab-testphase.ltx}{% - \from{latex-lab-firstaid.dtx}{latex-lab}}} +%firstaid +\generate{\file{firstaid-latex-lab-testphase.ltx}{\from{latex-lab-firstaid.dtx}{latex-lab}}} +\generate{\file{latex-lab-testphase-firstaid.sty}{\from{latex-lab-firstaid.dtx}{package}}} + +%table +\generate{\file{table-latex-lab-testphase.ltx}{\from{latex-lab-table.dtx}{latex-lab}}} +\generate{\file{latex-lab-testphase-table.sty}{\from{latex-lab-table.dtx}{package}}} + + +% stop docstrip adding \endinput +\preamble +\endpreamble +\postamble +\endpostamble +% namespace definitions +\generate{\file{tagpdf-ns-latex-lab.def}{\from{latex-lab-namespace.dtx}{ns-latex-lab}}} \endbatchfile diff --git a/Master/texmf-dist/source/latex/tools/afterpage.dtx b/Master/texmf-dist/source/latex/tools/afterpage.dtx index b94a85d26d9..518b70761d9 100644 --- a/Master/texmf-dist/source/latex/tools/afterpage.dtx +++ b/Master/texmf-dist/source/latex/tools/afterpage.dtx @@ -25,7 +25,7 @@ % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{afterpage} -% [2014/10/28 v1.08 After-Page Package (DPC)] +% [2023/07/04 v1.08 After-Page Package (DPC)] % %<*driver> \documentclass{ltxdoc} @@ -199,7 +199,7 @@ \global\setbox\@ne\lastbox}% % \end{macrocode} % If the text that is saved in |\AP@partial| had footnotes, we'd -% better grab them as well otherwise they may come out on a page +% better grab them as well, otherwise they may come out on a page % with the `afterpage' text, before the page that has the % footnote mark! (Added at v1.08.) % \begin{macrocode} @@ -218,7 +218,7 @@ % \end{macrocode} % % Restore the |\everydisplay| register. |\ignorespaces| prevents a space -% or newline after |$$| creating rogue a indentation or paragraph. +% or newline after |$$| creating a rogue indentation or paragraph. % \begin{macrocode} \def\AP@ed{\everydisplay\expandafter{\the\toks@}\ignorespaces} % \end{macrocode} @@ -264,7 +264,7 @@ % `afterpage' commands, so just add the new commands to the end of the % list. Otherwise save the commands in |\AP@|. (within a local group), % and switch the output routine. (The new output routine just calls the -% old one if it is invoked by a \LaTeX{} float. +% old one if it is invoked by a \LaTeX{} float.) % \begin{macrocode} \long\def\afterpage#1{% \ifx\AP@\relax @@ -291,7 +291,7 @@ \global\output\expandafter{\the\AP@output}% \AP@clearpage % \end{macrocode} -% At this point (since v1.08) Need to clear |\AP@| \emph{before} +% At this point (since v1.08) need to clear |\AP@| \emph{before} % using its expansion, as otherwise hit an infinite loop. Sigh. % \begin{macrocode} \global\expandafter\let\expandafter\AP@\expandafter\relax @@ -350,7 +350,7 @@ % \end{macrocode} % Subtract the new height of |#1| from |\skip@|, and add back on % |\splittopskip|, so |\skip@| is now the height of the first row of -% |#1| This may still be 0pt if (eg) a mark or whatsit is between the +% |#1|. This may still be 0pt if (eg) a mark or whatsit is between the % top glue and the first box. Save (this height${}-{}$|\splittopskip|) % in |\skip\tw@|. % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/tools/array.dtx b/Master/texmf-dist/source/latex/tools/array.dtx index 72e2f095e94..6e4e34ea260 100644 --- a/Master/texmf-dist/source/latex/tools/array.dtx +++ b/Master/texmf-dist/source/latex/tools/array.dtx @@ -33,7 +33,7 @@ %<+package>\DeclareCurrentRelease{}{2020-10-01} %<+package> %<+package>\ProvidesPackage{array} -%<+package> [2022/09/04 v2.5g Tabular extension package (FMi)] +%<+package> [2023/10/16 v2.5g Tabular extension package (FMi)] % % \fi % @@ -2272,7 +2272,7 @@ % insert the row strut now as it isn't inside the template (as that % got =\omit=ted). % \changes{v2.4h}{2018/04/30}{Fixing issue 42} - % \begin{macrocode} +% \begin{macrocode} \ifnum\@multicnt >\z@ \do@row@strut \fi \cr} \let\do@row@strut\relax diff --git a/Master/texmf-dist/source/latex/tools/bm.dtx b/Master/texmf-dist/source/latex/tools/bm.dtx index 51ae53f041a..a608c6aeb58 100644 --- a/Master/texmf-dist/source/latex/tools/bm.dtx +++ b/Master/texmf-dist/source/latex/tools/bm.dtx @@ -36,7 +36,7 @@ %\ProvidesFile{bm.drv} % \fi % \ProvidesFile{bm.dtx} - [2022/01/05 v1.2f Bold Symbol Support (DPC/FMi)] + [2023/07/08 v1.2f Bold Symbol Support (DPC/FMi)] % % \iffalse %<*driver> @@ -97,7 +97,7 @@ % % If there is a `heavy' math version defined (usually accessed by a % user-command |\heavymath|) then a similar command |\hm| -% is defined which access these `ultra bold' fonts. Currently this is +% is defined which accesses these `ultra bold' fonts. Currently this is % probably only useful with the `mathtime plus' font collection. % Definitions of commands that use these fonts may be made by % specifying the optional argument `heavy' to |\DeclareBoldMathCommand|. @@ -140,7 +140,7 @@ % your font set. % % \section{Features} -% In most cases this package should work in a fairly self explanatory +% In most cases this package should work in a fairly self-explanatory % way, but there are some things that might not be obvious. % % \subsection{Interaction with Math Alphabet Commands} @@ -209,7 +209,7 @@ % Normally if a command takes arguments the full command, including % any arguments, should be included in |\bm|. % -% So |\bm{\overbrace{abc}}| (producing \smash{$\bm{\overbrace{abc}}$}) +% So |\bm{\overbrace{abc}}| (producing \smash{$\bm{\overbrace{abc}}$}), % not % |\bm{\overbrace}{abc}|. If you do not include all the arguments you % will typically get the error message:\\ @@ -245,7 +245,7 @@ % allocations. % % If no bold font appears to be available for a particular symbol, -% |\bm| will use `poor man's bold' that is, overprinting the same +% |\bm| will use `poor man's bold', which will overprint the same % character in slightly offset % positions to give an appearance of boldness. % @@ -255,8 +255,8 @@ % font set there are suitable fonts for bold and heavy math setting, % and so |\bm| and |\hm| work well. Similarly in the basic Lucida % New Math font set there are no bold math fonts, so |\bm| will -% use `poor man's bold. However if the Lucida Expert set is used, -% Then |\bm| will detect, and use the bold math fonts that are +% use `poor man's bold'. However, if the Lucida Expert set is used, +% then |\bm| will detect, and use, the bold math fonts that are % available. % % As discussed above, one may set |\bmmax| higher or lower than its @@ -310,7 +310,7 @@ % ``poor man's bold''. That is, over-printing the character with slight offsets. % Since version 1.2e, the package now warns if a font is set up to use this over-printing and % the package option |nopbm| is available which prevents its use in which case |\bm| will -% use the non-bold for characters from the affected font, +% use the non-bold for characters from the affected font. % % \MaybeStop{} % @@ -339,7 +339,7 @@ % % \changes{v1.2e}{2021/04/25} % {Package options gh/71} -% Options to use or not use poor mans bold (over-printing) +% Options to use or not use poor man's bold (over-printing) % and level of warning messages. % \begin{macrocode} %<*package> @@ -399,7 +399,7 @@ % code, which is temporarily defined to |\bm|, to save wasting a csname. % Similarly |\bm@pmb|\ldots\ (which will be defined later) are used % as scratch macros. -% (This csname saving no longer used, setup command is |\bm@setup| not |\bm|). +% (This csname saving no longer used, setup command is |\bm@setup|, not |\bm|.) % % The general plan. Run through the fonts allocated to the normal math % version. Ignore \meta{math alphabet} allocations\footnote{For now?} @@ -505,11 +505,11 @@ \ifx\bm@pmb@\@firstofone\else, using \string\pmb\fi}% \else % \end{macrocode} -% Else make a new name by adjoining |#1| to the name of the symbol font +% Else make a new name by adjoining |#1| to the name of the symbol font, % eg, |\symboldsymbols| to match |\symsymbols|. If that font has already % been allocated, or if |\@tempcnta| is positive so we can allocate a % new slot for this font, then the table will be -% set with the offset between the two fonts. otherwise set the offset to +% set with the offset between the two fonts. Otherwise set the offset to % zero (so |\boldmath| will be used to access the font). % \begin{macrocode} \edef\@tempa{sym#1\expandafter\@gobblefour\string##1}% @@ -673,8 +673,8 @@ \fi % \end{macrocode} % -% If there is no bold math version, It is very easy to set up -% the table, no need to use all the tricky code above. +% If there is no bold math version, it is very easy to set up +% the table since there is no need to use all the tricky code above. % Also, at the end of the package redefine the internal macro % that |\bm| uses to call |\boldmath|, to use poor man's bold % instead. @@ -711,7 +711,7 @@ % % \begin{macro}{\hmmax} % -% Same for heavy (but default to three this time (enough for mathtime +% Same for heavy, but default to three this time (enough for mathtime % plus, as no heavy operators font). % \begin{macrocode} \ifx\hmmax\@undefined @@ -777,7 +777,7 @@ \let\protect\@empty \let\@typeset@protect\@empty % \end{macrocode} -% Set up either bold or heavy +% Set up either bold or heavy. % \begin{macrocode} \def\bm@mathchoice{\bm@m@thchoice#1}% \def\bm@group{\bm@gr@up#1}% @@ -848,9 +848,9 @@ \let\next@\copy \global\let\bm@first\@empty % \end{macrocode} -% For AMS version of |\sqrt|: don't expand just wrap in brace group -% so that it can be made bold in a safe but slow way. Do the same for -% internal accent command +% For AMS version of |\sqrt|: don't expand, just wrap it in a brace +% group so that it can be made bold in a safe but slow way. Do the same +% for internal accent command. % \changes{v1.1b}{2003/10/05}{AMS \cs{sqrt} not working} % % \changes{v1.1c}{2004/02/26}{\cs{accentV} made safe (pr/3625)} @@ -886,7 +886,7 @@ % |\mv@bold| or |\mv@heavy| and we execute that after redefining % |\install@mathalphabet| and |\getanddefine@fonts| suitably. % The definitions are reverted back to their original the moment -% the scanning is done +% the scanning is done. % \changes{v1.0h}{2002/11/22}{Get math alphabets right (pr/3476)} % \begin{macrocode} \let\install@mathalphabet\def @@ -972,7 +972,7 @@ % |\bm| is empty within the definition, so that either\\ % |\bmdefine\balpha{\bm\alpha}| or |\bmdefine\balpha{\alpha}| \\ % may be used. (The former just for compatibility with the original -% version for plain \TeX). +% version for plain \TeX.) % \begin{macrocode} \def\bmdefine{\DeclareBoldMathCommand[bold]} % \end{macrocode} @@ -1092,8 +1092,8 @@ % \begin{macro}{\bm@gr@up} % \changes{v1.0c}{1997/10/09} % {Extra brace around argument for \cs{over}} -% If faced with a group, -% If we are in math mode, stick it in a |\boldsymbol| like construct +% If faced with a group +% when we are in math mode, put it in a |\boldsymbol|-like construct % and then recurse on |\bm@expand|. % Otherwise just use |\bfseries\boldmath|. % The actual test is deferred till `run time'. @@ -1131,7 +1131,7 @@ % Other things just copy straight over to the command being built. % (Anything inside a |\mathop| or similar will end up being made bold % as the |\mathop| will be copied over, but its argument will be made -% bold by the group code above. +% bold by the group code above.) % \begin{macrocode} \def\bm@test@token#1{% \let\bm@next\@empty @@ -1139,7 +1139,7 @@ % % Stop here. Note that it is vital that the terminating token % is non-expandable and defined, rather than the usual \LaTeX\ -% terminators |\@nil| or |\@@|. (Worse still would be a `quark' +% terminators |\@nil| and |\@@|. (Worse still would be a `quark' % like |docstrip|'s |\qStop|.) % \begin{macrocode} \ifx#1\@@end @@ -1166,7 +1166,7 @@ \afterassignment\bm@radical\count@ % \end{macrocode} % -% Need to trap spaces otherwise digits will get turned to bold +% Need to trap spaces, otherwise digits will get turned to bold % mathchars. % \changes{v1.1a}{2003/09/01}{Forgotten to check for \cs{hskip} (pr/3572)} % \begin{macrocode} @@ -1451,7 +1451,7 @@ % \begin{macro}{\bm@pmb@} % \changes{v0.10}{1997/01/04} % {Macro added} -% |\pmb| variant. (See \TeX{}Book, or AMS \textsf{amsbsy} package). +% |\pmb| variant. (See \TeX{}book, or AMS \textsf{amsbsy} package.) % This one takes a bit more care to use smaller offsets in subscripts. % \begin{macrocode} \ifx\bm@pmb@\@firstofone\else @@ -1544,7 +1544,7 @@ \def\bm@mathaccent{% \bm@changefam{}% % \end{macrocode} -% The next four lines were added a v1.0e. Without them |\bm{\hat{A}}| +% The next four lines were added in v1.0e. Without them |\bm{\hat{A}}| % makes the accent bold using |\bm| but the group |{A}| is made bold % via a |\mathchoice| construction as for any other group, as |\bm| % does not attempt to parse inside brace groups. While that produces @@ -1674,9 +1674,10 @@ % \begin{macro}{\bm@changefam} % \changes{v0.10}{1997/01/04} % {Rewrite for new \cs{bm@table} system} -% Pull out one specified hex digit and passes -% it to |\bm@modify| to change. argument is empty normally but |000| to -% access the second math group in a delimiter code. +% Pull out one specified hex digit and pass +% it to |\bm@modify| to change. Its one argument is normally empty, +% but it will be |000| when necessary to access the second math group +% in a delimiter code. % \begin{macrocode} \def\bm@changefam#1{% \@tempcnta\count@ diff --git a/Master/texmf-dist/source/latex/tools/calc.dtx b/Master/texmf-dist/source/latex/tools/calc.dtx index c243eed8d32..2c4cecbf038 100644 --- a/Master/texmf-dist/source/latex/tools/calc.dtx +++ b/Master/texmf-dist/source/latex/tools/calc.dtx @@ -40,7 +40,7 @@ % \ProvidesFile{calc.drv} % \fi % \ProvidesFile{calc.dtx} - [2017/05/25 v4.3 Infix arithmetic (KKT,FJ)] + [2023/07/08 v4.3 Infix arithmetic (KKT,FJ)] % % \iffalse %<*driver> @@ -102,7 +102,7 @@ % Arithmetic in \TeX\ is done using low-level operations such as % |\advance| and |\multiply|. This may be acceptable when developing % a macro package, but it is not an acceptable interface for the -% end-user. +% end user. % % This package introduces proper infix notation arithmetic which is % much more familiar to most people. The infix notation is more @@ -271,7 +271,7 @@ % or at the end of the expression being evaluated. % % When \TeX\ performs arithmetic on integers, any fractional part of -% the results are discarded. For example, +% the result is discarded. For example, %\begin{verbatim} % \setcounter{x}{7/2} % \setcounter{y}{3*\real{1.6}} @@ -318,7 +318,7 @@ % \setlength{\parindent}{% % \minof{3pt}{\parskip}*\real{1.5}*\maxof{2*\real{1.6}}{2-1}} %\end{verbatim} -% will assign $\min(13.5\textrm{pt},4.5\cs{parskip})$ to \cs{parindent} +% will assign $\min(13.5\textrm{pt},4.5\cs{parskip})$ to \cs{parindent}. % % % @@ -453,7 +453,7 @@ % or a parenthesized expression~$(E')$. % % Since the \TeX\ engine can only execute arithmetic operations in a -% machine-code like manner, we have to find a way to translate the +% machine-code-like manner, we have to find a way to translate the % infix notation into this `instruction set'. % % Our goal is to design a translation scheme that translates~$X$ (an @@ -565,9 +565,9 @@ % When an \ is expected, we must change $A$ and~$B$ to % refer to integer type registers. We can accomplish this by % including instructions to change the type of $A$ and~$B$ to integer -% type as part of the replacement code for~`$*$; if we append such +% type as part of the replacement code for~`$*$'; if we append such % instructions to the replacement code described above, we also ensure -% that the type-change is local (provided that the type-changing +% that the type change is local (provided that the type-changing % instructions only have local effect). However, note that the % instance of~$A$ referred to in $\savecode{B\lassign B*A}$ is the % integer instance of~$A$. @@ -933,7 +933,7 @@ % \begin{macro}{\calc@addAtoB} % \begin{macro}{\calc@subtractAfromB} % The replacement code for the binary operators `\texttt{+}' and -% `\texttt{-}' follow a common pattern; the only difference is the +% `\texttt{-}' follows a common pattern; the only difference is the % token that is stored away by |\aftergroup|. After this replacement % code, control is transferred to |\calc@pre@scan|. % \begin{macrocode} @@ -1063,7 +1063,7 @@ % \begin{macro}{\calc@ratio@multiply} % \begin{macro}{\calc@ratio@divide} % When |\calc@post@scan| encounters a |\ratio| control sequence, it hands -% control to one of the macros |\calc@ratio@multiply| or |\calc@ratio@divide|, +% control to one of the macros |\calc@ratio@multiply| and |\calc@ratio@divide|, % depending on the preceding character. Those macros both forward the % control to the macro |\calc@ratio@evaluate|, which performs two steps: (1) it % calculates the ratio, which is saved in the global macro token @@ -1109,7 +1109,7 @@ % Here we calculate the ratio. First, we check for negative numerator % and/or denominator; note that \TeX\ interprets two minus signs the % same as a plus sign. Then, we calculate the integer part. -% The minus sign(s), the integer part, and a decimal point, form the +% The minus sign(s), the integer part, and a decimal point form the % initial expansion of the |\calc@the@ratio| macro. % \begin{macrocode} \gdef\calc@the@ratio{}% @@ -1305,8 +1305,8 @@ % {Use \cs{PackageError} for error messages (DPC)} % \changes{v4.0e}{1997/11/11} % {typo fixed} -% If |\calc@post@scan| reads a character that is not one of `\texttt{+}', -% `\texttt{-}', `\texttt{*}', `\texttt{/}', or `\texttt{)}', an error +% If |\calc@post@scan| reads a character that is neither `\texttt{+}', +% `\texttt{-}', `\texttt{*}', `\texttt{/}', nor `\texttt{)}', an error % has occurred, and this is reported to the user. Violations in the % syntax of \s will be detected and reported by \TeX. % \changes{v4.1a}{1998/06/07} @@ -1327,7 +1327,7 @@ % \changes{v4.2}{2005/08/06} % {Added macro} % The kernel macro \cs{@settodim} is changed so that it runs through a list -% containing \cs{ht}, \cs{wd}, and \cs{dp} and than advance the length +% containing \cs{ht}, \cs{wd}, and \cs{dp} and then advances the length % one step at a time. We just have to use a scratch register in case the % user decides to put in a \cs{global} prefix on the length register. % A search on the internet confirmed that some people do that kind of thing. diff --git a/Master/texmf-dist/source/latex/tools/dcolumn.dtx b/Master/texmf-dist/source/latex/tools/dcolumn.dtx index cfb7b4d33e8..c8ddaf4ce6b 100644 --- a/Master/texmf-dist/source/latex/tools/dcolumn.dtx +++ b/Master/texmf-dist/source/latex/tools/dcolumn.dtx @@ -31,7 +31,7 @@ %\ProvidesFile{dcolumn.drv} % \fi % \ProvidesFile{dcolumn.dtx} - [2014/10/28 v1.06 decimal alignment package (DPC)] + [2023/07/08 v1.06 decimal alignment package (DPC)] % % \iffalse %<*driver> @@ -117,7 +117,7 @@ % % \noindent"\newcolumntype{,}{D{,}{,}{2}}" % -% {\tt ,} specifies takes a column of entries with at most two decimal +% {\tt ,} specifies a column of entries with at most two decimal % places after a~$,$. % % \newcolumntype{d}[1]{D{.}{\cdot}{#1}} @@ -138,7 +138,7 @@ % \end{center} % % Note that the first column, which had a negative \meta{decimal places} -% argument is wider than the second column, so that the decimal point +% argument, is wider than the second column, so that the decimal point % appears in the middle of the column. % Also note that this package deals correctly with entries with no % decimal part, no integer part, and blank entries. @@ -200,7 +200,7 @@ %<*package> % \end{macrocode} % -% First we load {\tt array.sty} if it not already loaded. +% First we load {\tt array.sty} if it is not already loaded. % \begin{macrocode} \RequirePackage{array} % \end{macrocode} @@ -243,10 +243,10 @@ % \begin{macro}{\DC@x} % \changes{v1.03}{1996/02/28}{Macro added} % If "\count@" is negative, centre on the decimal point. If it is -% positive either "#1" will be empty in which case bad out decimal +% positive either "#1" will be empty in which case pad out decimal % part to the number of digits specified by "\count@" or (new feature % in v1.03) it is none empty in which case "\count@" contains the -% number of digits to the left of the point, and "#1" contains a junk +% number of digits to the left of the point and "#1" contains a junk % token (probably ".") followed by the number of digits to the right % of the point. In either of these latter cases, "\DC@right" is used. % \begin{macrocode} @@ -261,7 +261,7 @@ % \end{macro} % % \begin{macro}{\DC@centre} -% If centering on the decimal point, just need to box up the two halves. +% If centering on the decimal point, just need to box up the two halves: % \begin{macrocode} \def\DC@centre#1#2#3{% \let\DC@end\DC@endcentre @@ -293,16 +293,16 @@ \ifx\relax#3\relax % \end{macrocode} % If "#3" is empty, add "\hfill" to right align the column, and -% Just set "\DC@rl" to begin a group, so nothing fancy is done with +% just set "\DC@rl" to begin a group, so that nothing fancy is done with % the whole number part. % \begin{macrocode} \hfill \let\DC@rl\bgroup \else % \end{macrocode} -% Otherwise set "\DC@rl" so that the whole number part is put in a +% Otherwise set "\DC@rl" so that the whole number part is put in a % box "\count@" times as wide as a digit. -% In order to share code with the other branch, then move "#3" (the +% In order to share code with the other branch, move "#3" (the % number of decimal places) into "\count@" throwing away the `.' from % the user syntax. % \changes{v1.04}{1996/09/23}{Add \cs{hfill} so integer part @@ -318,7 +318,7 @@ % \end{macrocode} % Box 2 contains the decimal part, set to "\dimen@" which is % calculated below to be "\count@" times the width of a digit, plus -% the with of the `decimal point'. +% the width of the `decimal point'. % \begin{macrocode} \uppercase{\def~}{$\egroup\setbox\tw@\hbox to\dimen@\bgroup${#2}}% \setbox\z@\hbox{$1$}\dimen@ii\wd\z@ diff --git a/Master/texmf-dist/source/latex/tools/enumerate.dtx b/Master/texmf-dist/source/latex/tools/enumerate.dtx index 49179cfa067..2818a73a09b 100644 --- a/Master/texmf-dist/source/latex/tools/enumerate.dtx +++ b/Master/texmf-dist/source/latex/tools/enumerate.dtx @@ -31,7 +31,7 @@ % \ProvidesFile{enumerate.drv} % \fi % \ProvidesFile{enumerate.dtx} - [2015/07/23 v3.00 enumerate extensions (DPC)] + [2023/07/04 v3.00 enumerate extensions (DPC)] % % \iffalse %<*driver> @@ -66,7 +66,7 @@ % This package gives the enumerate environment an optional argument % which determines the style in which the counter is printed. % -% An occurrence of one of the tokens |A a I i| or |1| produces the value +% An occurrence of one of the tokens |A a I i 1| produces the value % of the counter printed with (respectively) |\Alph \alph \Roman \roman| % or |\arabic|. % @@ -233,7 +233,7 @@ % % To enable a new counter type based on a letter, you just need % to add a new |\ifx| clause by analogy with the code above. -% So for example to make |*| trigger footnote symbol counting. +% So for example to make |*| trigger footnote symbol counting, % a package should do the following. % % Initialise the hook, in case the package is loaded before @@ -255,7 +255,7 @@ % in this way. % % At this point we just need initialise the hook, taking care not -% to over write any definitions another package may already have added. +% to overwrite any definitions another package may already have added. % \begin{macrocode} \providecommand\@enhook{} % \end{macrocode} @@ -276,7 +276,7 @@ % \end{macro} % % \begin{macro}{\@@enum@} -% Handle the optional argument.. +% Handle the optional argument. % \begin{macrocode} \def\@@enum@[#1]{% % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/tools/ftnright.dtx b/Master/texmf-dist/source/latex/tools/ftnright.dtx index 00e98c3f773..663fa304a94 100644 --- a/Master/texmf-dist/source/latex/tools/ftnright.dtx +++ b/Master/texmf-dist/source/latex/tools/ftnright.dtx @@ -26,7 +26,7 @@ %% Copyright (C) 1989-2004 Frank Mittelbach, all rights reserved. %<+package>\NeedsTeXFormat{LaTeX2e}[1995/06/01] %<+package>\ProvidesPackage{ftnright} -%<+package> [2014/10/28 v1.1f footnote layout package (FMi)] +%<+package> [2023/07/08 v1.1f footnote layout package (FMi)] % % \fi %% @@ -171,7 +171,7 @@ % % I also upgraded the documentation to conform to the \LaTeXe{} % terminology, e.g., this is a package since document classes will not -% know about it. However it is very likely that i have missed some +% know about it. However it is very likely that I have missed some % necessary corrections. % % \section{Introduction} @@ -220,7 +220,7 @@ % % The result of this effort is presented in this paper and the reader % can judge for himself whether it was successful or -% not.\footnote{Please note, that this option only changed the +% not.\footnote{Please note that this option changed only the % placement of footnotes. Since this article also makes use of the % {\tt doc} package \cite{bk:GMS94}, that assigns tiny numbers to % code lines sprinkled throughout the text, the resulting design is @@ -235,7 +235,7 @@ % footnote separator rule which is used in most publications prepared % with \TeX{}.\footnote{People who prefer the rule can add it by % redefining the command {\tt\bslash footnoterule} -% \cite[p.~156]{book:LLa86}. Please, note, that this command should +% \cite[p.~156]{book:LLa86}. Please note that this command should % occupy no space, so that a negative space should be used to % compensate for the width of the rule used.} Furthermore, I decided % to place the footnote markers\footnote{\label{thisftn}The tiny @@ -572,7 +572,7 @@ % are only partly typeset on the preceding page are not resolved. % They are held over until \LaTeX{} starts a page (or column) % containing text besides floats again. For our current layout, -% this would mean, that if \LaTeX{} decided to make the right +% this would mean that if \LaTeX{} decided to make the right % column of a page a float column, footnotes from the left column % would appear on a later page. A real cure for this problem would % be to rewrite two-thirds of \LaTeX{}'s output routine, so I am @@ -615,8 +615,8 @@ % footnotes from the left column. So we have to change the output % routine at least in the part that contributes floats to the next % column. The macro involved is called |\@startcolumn|. The first -% thing we do is to check and see whether any deferred floats -% exists. +% thing we do is to check and see whether there are any deferred +% floats. % \begin{macrocode} \def\@startcolumn{% \ifx\@deferlist\@empty @@ -764,7 +764,7 @@ % and output the footnotes on a separate page in an % emergency.\footnote{Otherwise, the footnotes are held over for % ever, preventing \TeX{} from finishing the document successfully. -% Instead, \TeX{} will produce infinity many empty pages at the end +% Instead, \TeX{} will produce infinitely many empty pages at the end % of the document, trying in vain to output the held over % footnotes. This problem was found by Rainer Sch\"opf when we % prepared the paper for the Cork conference.} @@ -790,7 +790,7 @@ % moment we simply detect it here, perhaps some better scheme can be % implemented. One way to avoid this is to allow more than |\textheight| of % footnotes in |\preparefootins|. However, that isn't such a good idea -% either as that means that a footnote from column one, might end up +% either since it means that a footnote from column one might end up % completely on a later page. % \changes{v1.1f}{2010/02/25}{Check for split footnotes (pr/4099)} % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/tools/indentfirst.dtx b/Master/texmf-dist/source/latex/tools/indentfirst.dtx index 295b678fd86..2314db1c70c 100644 --- a/Master/texmf-dist/source/latex/tools/indentfirst.dtx +++ b/Master/texmf-dist/source/latex/tools/indentfirst.dtx @@ -25,7 +25,7 @@ % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{indentfirst} -% [1995/11/23 v1.03 Indent first paragraph (DPC)] +% [2023/07/02 v1.03 Indent first paragraph (DPC)] % %<*driver> \documentclass{ltxdoc} @@ -52,7 +52,7 @@ % \changes{v1.03}{1995/11/23}{Typo fixes in documentation} % % \begin{abstract} -% Make the first line of all sections etc., be indented by the usual +% Make the first line of all sections etc. be indented by the usual % paragraph indentation. This should work with all the standard document % classes. % \end{abstract} diff --git a/Master/texmf-dist/source/latex/tools/layout.dtx b/Master/texmf-dist/source/latex/tools/layout.dtx index fffa6d8e189..2798bd4f60d 100644 --- a/Master/texmf-dist/source/latex/tools/layout.dtx +++ b/Master/texmf-dist/source/latex/tools/layout.dtx @@ -30,7 +30,7 @@ %<+package>\ProvidesPackage{layout} %<+driver>\ProvidesFile{layout.drv} %\ProvidesFile{layout.dtx} - [2021-03-10 v1.2e Show layout parameters] + [2023-08-20 v1.2e Show layout parameters] % % A short driver is provided that can be extracted if necessary by % the \textsf{DocStrip} program provided with \LaTeXe. @@ -409,7 +409,7 @@ % % \begin{macro}{\cnt@paperwidth} % \begin{macro}{\cnt@paperheight} -% The dimensions of the paper +% The dimensions of the paper, % \begin{macrocode} \newcount\cnt@paperwidth \newcount\cnt@paperheight @@ -514,7 +514,7 @@ \newcount\ref@hoffset \newcount\ref@voffset % \end{macrocode} -% The |\hoffset| and |\voffset| values are added to the default +% the |\hoffset| and |\voffset| values are added to the default % offset of one inch. % \begin{macrocode} \ref@hoffset=\cnt@hoffset \advance\cnt@hoffset by \oneinch @@ -531,7 +531,7 @@ % \end{macro} % % \begin{macro}{\ref@head} -% and the text areas, running heads, +% And the text areas, running heads, % \begin{macrocode} \newcount\ref@head % \end{macrocode} @@ -566,7 +566,7 @@ % \end{macro} % % The following are a number of scratch registers, used in the -% positioning of the various pices of the picture. +% positioning of the various pieces of the picture. % \begin{macrocode} \newcount\Interval \newcount\ExtraYPos @@ -639,7 +639,7 @@ \ifodd\count\z@ % \end{macrocode} % -% Here we deal with an odd page in the twosided case. +% Here we deal with an odd page in the two-sided case. % % \begin{macrocode} \typeout{Two-sided document style, odd page.} @@ -667,7 +667,7 @@ \else % \end{macrocode} % -% Here we deal with an even page in the twosided case. +% Here we deal with an even page in the two-sided case. % % \begin{macrocode} \typeout{Two-sided document style, even page.} @@ -696,7 +696,7 @@ \else % \end{macrocode} % -% Finally we the case for single sided printing. +% Finally we deal with the case for single-sided printing. % % \changes{v1.1}{1994/02/23}{Added check for reversemargin} % \begin{macrocode} @@ -718,7 +718,7 @@ % % % Now we begin the picture environment; dividing all the lengths by -% two is done by setting |\unitlength| to \texttt{0.5pt} +% two is done by setting |\unitlength| to \texttt{0.5pt}. % \begin{macrocode} \setlength{\unitlength}{.5pt} \begin{picture}(\cnt@paperwidth,\cnt@paperheight) @@ -790,7 +790,7 @@ \InsideHArrow\cnt@textwidth % \end{macrocode} % -% Now the |\textheight| +% Now the |\textheight|. % \begin{macrocode} \SetToHalf\PositionY\cnt@textheight \advance\PositionY by \ref@body @@ -812,7 +812,7 @@ % \end{macrocode} % % -% The |\hoffset|, +% The |\hoffset|. % \changes{v1.2}{1998/04/13}{\cs{PositionY} for label 1 is % fixed at 50} % \begin{macrocode} @@ -840,12 +840,12 @@ \Identify{3} % \end{macrocode} % -% the |\marginparwidth|, +% The |\marginparwidth|. % \begin{macrocode} \SetToQuart\PositionY\cnt@textheight \advance\PositionY by \ref@body % \end{macrocode} -% This arrow has to be bit below the one for the |\oddsidemargin| +% This arrow has to be a bit below the one for the |\oddsidemargin| % or\\ |\evensidemargin|. % \begin{macrocode} \advance\PositionY by 30 @@ -856,14 +856,14 @@ % \end{macrocode} % % -% The |\marginparsep|, this depends on single or double sided +% The |\marginparsep|, this depends on single- or double-sided % printing. % \begin{macrocode} \advance\PositionY by 30 \if@twoside % \end{macrocode} % -% Twosided mode, reversemargin; +% Two-sided mode, reversemargin: % \changes{v1.1b}{1994/03/23}{\cs{OutSideHArrow} should be % \cs{OutsideHArrow}} % \changes{v1.2}{1998/04/13}{Added check for reversemargin} @@ -878,7 +878,7 @@ \fi \else % \end{macrocode} -% Not reversemargin; +% Not reversemargin: % \begin{macrocode} \ifodd\count\z@ \OutsideHArrow\ref@marginpar\cnt@marginparsep{20} @@ -891,7 +891,7 @@ \else % \end{macrocode} % -% Single sided mode. +% Single-sided mode. % \changes{v1.2}{1998/04/13}{Added check for reversemargin} % \begin{macrocode} \if@reversemargin @@ -911,7 +911,7 @@ \Identify{9} % \end{macrocode} % -% Identify the |\footskip|. The arrow will be located on $1/8$th of +% Identify the |\footskip|. The arrow will be located on $1/8$ of % the |\textwidth|. % \changes{v1.2}{1998/04/13}{The \cs{PositionY} of the label 11 is % changed to the upper side of the arrows} @@ -942,7 +942,7 @@ % % Identify |\topmargin|, |\headheight| and |\headsep|. % -% The arrows will be located on $1/8$th of the |\textwidth|, with +% The arrows will be located on $1/8$ of the |\textwidth|, with % intervals of the same size, stored in |\Interval|. % \begin{macrocode} \Interval = \cnt@textwidth @@ -983,7 +983,7 @@ \Identify{5} \advance\PositionX by \Interval % \end{macrocode} -% and finally the |\headsep| +% and finally the |\headsep|. % \changes{v1.2}{1998/04/13}{The \cs{PositionY} of the label 6 is % fixed} % \begin{macrocode} @@ -1006,7 +1006,7 @@ % % Below the picture we put a table to show the actual values of the % parameters. Note that fractional points are truncated, i.e., -% \texttt{72.27pt} is displayed as \texttt{72pt} +% \texttt{72.27pt} is displayed as \texttt{72pt}. % % The table is typeset inside a box with a depth of 0 to always % keep it on the same page as the picture. diff --git a/Master/texmf-dist/source/latex/tools/longtable.dtx b/Master/texmf-dist/source/latex/tools/longtable.dtx index 332a95d224e..5fb6364e75b 100644 --- a/Master/texmf-dist/source/latex/tools/longtable.dtx +++ b/Master/texmf-dist/source/latex/tools/longtable.dtx @@ -37,7 +37,7 @@ % \ProvidesFile{longtable.drv} % \fi % \ProvidesFile{longtable.dtx} - [2021-09-01 v4.17 Multi-page Table package (DPC)] + [2025-10-25 v4.18 Multi-page Table package (DPC)] % % \iffalse %<*driver> @@ -54,7 +54,7 @@ % has version number \fileversion, last % revised \filedate.}} % \author{David Carlisle\thanks{The new algorithm for aligning `chunks' -% of a table used in version 4 of this package was devised coded +% of a table used in version 4 of this package was devised, coded % and documented by David Kastrup.}} % \date{\filedate} % @@ -317,7 +317,7 @@ % ".aux" file, so that it can line up the different chunks. % Prior to version~4 of this package, this information was not used % unless a "\setlongtables" command was issued, however, now the -% information is always used, using a new algorithm\footnote{Due to +% information is always used, via a new algorithm,\footnote{Due to % David Kastrup.} and so "\setlongtables" is no longer needed. It is % defined (but does nothing) for the benefit of old documents that % use it. @@ -396,7 +396,7 @@ % are modified in a compatible manner. % % You may use the "\label" command so that you can cross reference -% \env{longtable}s with "\ref". Note however, that the "\label" command +% \env{longtable}s with "\ref". Note, however, that the "\label" command % should not be used in a heading that may appear more than once. Place % it either in the \env{firsthead}, or in the body of the table. It % should not be the \emph{first} command in any entry. @@ -493,7 +493,7 @@ % always converged in three passes as described above, but in examples % such as the ones in Tables \ref{pass1}--\ref{pass4}, the final % widths were not optimal as the width of column~2, which is -% determined by a "\multicolumn" entry was not known when the final +% determined by a "\multicolumn" entry, was not known when the final % width for column~3 was fixed, due to the fact that \emph{both} % "\multicolumn" commands were switched from `draft' mode to `normal' % mode at the same time. @@ -511,7 +511,7 @@ % many overlapping "\multicolumn" entries, all being wider than the % natural widths of the columns they span, and all occurring in % different chunks. In the typical case the algorithm will converge -% after three or four passes, and, the benefits of not needing to edit +% after three or four passes, and the benefits of not needing to edit % the document before the final run to add "\setlongtables", and the % better choice of final column widths in the case of multiple % "\multicolumn" entries will hopefully more than pay for the extra @@ -576,7 +576,7 @@ % \item The mechanism for adding the head and foot of the table has been % completely rewritten. With this new mechanism, \env{longtable} does % not need to issue a "\clearpage" at the start of the table, and so the -% table may start half way down a page. Also the "\endlastfoot" command +% table may start half way down a page. Also the "\endlastfoot" command, % which could not safely be implemented under the old scheme, has been % added. % \item \env{longtable} now issues an error if started in the scope of @@ -673,7 +673,7 @@ % "\endhead"& % Specifies rows to appear at the top of every page.\\ % "\endfirsthead"& -% Specifies rows to appear at the top the first page.\\ +% Specifies rows to appear at the top of the first page.\\ % "\endfoot"& % Specifies rows to appear at the bottom of every page.\\ % "\endlastfoot"& @@ -885,7 +885,7 @@ % \begin{macro}{\LTchunksize} % \changes{v4.14}{2020/02/07} % {Increase default chunksize from 20 to 200} -% Chunk size (The number of rows taken per "\halign"). Default 200. +% Chunk size (the number of rows taken per "\halign"). Default 200. % \begin{macrocode} \newcount\LTchunksize \LTchunksize=200 % \end{macrocode} @@ -1189,12 +1189,12 @@ % \changes{v4.05}{1996/11/12} % {\cs{LT@setprevdepth} added} % The following line was added in v4.05. -% In order to get the "\penalties" to work at chunk boundaries -% Need to take more care about where and when "\lineskip" glue +% In order to get the "\penalties" to work at chunk boundaries, +% we need to take more care about where and when "\lineskip" glue % is added. The following does nothing at top of table, and in % header chunks, but in normal body chunks it sets "\prevdepth" % (to 0pt, but any value would do) so that "\lineskip" glue will -% be added. the important thing to note is that the glue will be +% be added. The important thing to note is that the glue will be % added \emph{after} any vertical material coming from "\noalign". % \begin{macrocode} \LT@setprevdepth @@ -1257,7 +1257,7 @@ % \end{macrocode} % \changes{v4.14}{2020/02/07} % {Guard against shrink glue on current page tools/3396 and github 183} -% This next block was suggested by Lars Hellström in pr tools/3396 +% This next block was suggested by Lars Hellström in pr tools/3396. % He documents it as: % % The original problem occurs because TeX has not yet found an awfully bad @@ -1325,7 +1325,7 @@ % \changes{v4.14}{2020/02/07} % {Guard against shrink glue on current page see github 183} % The LT output routine does not handle shrink on the page, which can cause -% The first page to be over-long, so forget it is there. +% the first page to be over-long, so forget it is there. % \begin{macrocode} \ifdim\pageshrink>\z@\pageshrink\z@\fi \fi @@ -1551,7 +1551,7 @@ % Increment the counter, and do \env{tabular}'s "\\" or finish the % chunk.\\ The "\expandafter" trick was added in Version~3. % Set the "\prevdepth" at the start of a new chunk. (Done here -% so not set in header chunks). +% so not set in header chunks.) % \begin{macrocode} \global\advance\LT@rows\@ne \ifnum\LT@rows=\LTchunksize @@ -2206,12 +2206,16 @@ \bgroup % \end{macrocode} % \changes{v4.12}{2019/02/06}{Color group to match array package} +% \changes{v4.18}{2023/08/25}{Use \cs{everypar} to match array package, github 1128}% % \begin{macrocode} \color@begingroup \let\@footnotetext\LT@p@ftntext \setlength\hsize{#1}% \@arrayparboxrestore - \vrule \@height \ht\@arstrutbox \@width \z@} + \everypar{% + \vrule \@height \ht\@arstrutbox \@width \z@ + \everypar{}}% + } % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/tools/shellesc.dtx b/Master/texmf-dist/source/latex/tools/shellesc.dtx index 97ec542b662..aa707fe550a 100644 --- a/Master/texmf-dist/source/latex/tools/shellesc.dtx +++ b/Master/texmf-dist/source/latex/tools/shellesc.dtx @@ -20,7 +20,7 @@ % \ProvidesFile{shellesc.drv} % \fi % \ProvidesFile{shellesc.dtx} - [2023/04/15 v1.0d unified shell escape interface for LaTeX] + [2023/07/08 v1.0d unified shell escape interface for LaTeX] % % \iffalse %<*driver> @@ -50,7 +50,7 @@ % \section{Introduction} % % -% For many years web2c based \TeX\ implementations have used the syntax +% For many years web2c-based \TeX\ implementations have used the syntax % of the \verb|\write| command to access system commands by using a % special stream 18 (streams above 15 can not be allocated to files in % classical \TeX\ so stream 18 would otherwise just print to the @@ -59,9 +59,9 @@ % This is a useful extension that did not break the strict rules on % extensions in classical \TeX. This package provides a simple % macro level interface hiding the \verb|write18| implementation -% so a command to remove a file on a unix-like system could be +% so a command to remove a file on a Unix-like system could be % specified using \verb|\ShellEscape{rm file.txt}| (or \verb|del| in -% windows). Note that by default system access is not allowed and +% Windows). Note that by default system access is not allowed and % \LaTeX\ will typically need to be called with the \verb|--shell-escape| % command line option. % @@ -77,7 +77,7 @@ % \verb|\ShellEscape| in fact corresponds to \verb|\immediate\write18| % (or \verb|\directlua|). Very rarely you may need to delay a system % command until the current page is output (when page numbers are -% known) for this classically you could use \verb|\write18| (or +% known), for this you could classically use \verb|\write18| (or % (\verb|\latelua|). This package provides \verb|\DelayedShellEscape| % as a common syntax for this use. % @@ -92,7 +92,7 @@ % \verb|\immediate| will work as normal when writing to file streams % or the terminal but the special case of stream 18 which is defined to % use \verb|os.execute| always uses \verb|\directlua| (so corresponds -% to \verb|\immediate\write18|. In the rare situations that you need +% to \verb|\immediate\write18|). In the rare situations that you need % non-immediate \verb|\write18| in a document being ported to current % Lua\TeX, you will need to change to use the % \verb|\DelayedShellEscape| command. @@ -118,7 +118,7 @@ % % \begin{macro}{\ShellEscapeStatus} % \changes{v1.0a}{2019/10/13}{Command Introduced} -% Integer value with meanings 0 (shell escape disabled), 1 (shell escape allowed), 2 (Restricted shell escape). +% Integer value with meanings 0 (shell escape disabled), 1 (shell escape allowed), 2 (restricted shell escape). % % \begin{macrocode} \chardef\ShellEscapeStatus @@ -215,8 +215,8 @@ if status == nil then % % \subsection{The write18 package interface} % -% In web2c based engines other than Lua\TeX, |\write18| may be used -% directly. The same was true in older LuaTeX, but from version 0.85 +% In web2c-based engines other than Lua\TeX, |\write18| may be used +% directly. The same was true in older Lua\TeX, but from version 0.85 % onwards that is not available. % % The above |shellesc| package interface is recommended for new code, diff --git a/Master/texmf-dist/source/latex/tools/showkeys.dtx b/Master/texmf-dist/source/latex/tools/showkeys.dtx index 98410041569..c90b3863e1a 100644 --- a/Master/texmf-dist/source/latex/tools/showkeys.dtx +++ b/Master/texmf-dist/source/latex/tools/showkeys.dtx @@ -39,7 +39,7 @@ % \ProvidesFile{showkeys.drv} % \fi % \ProvidesFile{showkeys.dtx} - [2023/05/11 v3.19 Show cite and label keys (DPC, MH)] + [2023/07/08 v3.19 Show cite and label keys (DPC, MH)] % % \iffalse %<*driver> @@ -112,13 +112,13 @@ % print its key argument (usually in the margin). % % If you find the printed keys distracting, but don't want to use the -% above options to stop them altogether you may use: +% above options to stop them altogether, you may use: % \begin{description} % \item[color] Print the keys in a distinguishing colour. The default % value is a light grey. % \end{description} % The colours may be changed by redefining the following two colours -% after the package is loaded. +% after the package is loaded: % |refkey| (also used for |\cite|) and % |labelkey| (also used for |\bibitem|). % The defaults are: @@ -131,7 +131,7 @@ % % The package accepts two further options. % \begin{description} -% \item[final] to suporess the action of this package, for `final' +% \item[final] to suppress the action of this package, for `final' % versions. % \item[draft] the normal behaviour of this package. % \end{description} @@ -437,7 +437,7 @@ % change |\prevdepth| as that would affect vertical spacing in the % document. (The box itself should not cause any difference in break % points as there is a node there anyway coming from the |\write| to -% the aux file. +% the aux file.) % \begin{macrocode} \dimen@\prevdepth \nointerlineskip @@ -451,8 +451,8 @@ % In inner vertical mode, attach the label to the right of the % immediately preceding box, if it is a box before the current point. % Otherwise just put it in a box of zero dimensions, with no interline -% skip. (This may slightly move the surrounding text (but perhaps not -% now that |\prevdepth| is restored.) +% skip. This may slightly move the surrounding text (but perhaps not +% now that |\prevdepth| is restored). % \changes{v3.00}{1994/09/07} % {Back up over a previous skip because of the new % \cs{belowcaptionskip}} @@ -502,7 +502,7 @@ \fi \else % \end{macrocode} -% If we are in an numbered equation-style environment, do nothing as the +% If we are in a numbered equation-style environment, do nothing as the % code to print the number will also print the label, otherwise just % stick the label at the current point, in a box of zero dimensions. % \changes{v3.02}{1995/03/17} @@ -650,7 +650,7 @@ % The following environments print an equation number, so |\label| % should not print its argument at the point where it appears. % Note this will fail to show the label if you are in an |eqnarray| -% environment, and use |\label| together with |\nonumber| This might +% environment, and use |\label| together with |\nonumber|. This might % just about make sense if you are going to use |\pageref|, but that is % too bad\ldots % \begin{macrocode} @@ -665,7 +665,7 @@ % \changes{v3.09}{1996/08/30} % {Fix eqnarray AMS incompatibility. tools/2252} % When the AMS packages are loaded |showkeys| assumes environments -% work `The AMS way' However |eqnarray| (unlike |equation|) is not +% work `The AMS way'. However, |eqnarray| (unlike |equation|) is not % redefined, so here we need to remove some of the AMS hacks. % \begin{macrocode} \toks@\expandafter{\eqnarray} diff --git a/Master/texmf-dist/source/latex/tools/tabularx.dtx b/Master/texmf-dist/source/latex/tools/tabularx.dtx index 177d92f12fd..6d59ca4c228 100644 --- a/Master/texmf-dist/source/latex/tools/tabularx.dtx +++ b/Master/texmf-dist/source/latex/tools/tabularx.dtx @@ -31,7 +31,7 @@ % \ProvidesFile{tabularx.drv} % \fi % \ProvidesFile{tabularx.dtx} - [2020/01/15 v2.11c `tabularx' package (DPC)] + [2023/07/08 v2.11c `tabularx' package (DPC)] % \iffalse %<*driver> \documentclass{ltxdoc} @@ -164,7 +164,7 @@ % \item The body of the {\ttfamily tabularx} environment is in fact the % argument to a command, and so certain constructions which are not % allowed in command arguments (like "\verb") may not be used.\footnote -% {Since Version 1.02, {\ttfamily\bslash verb and \ttfamily\bslash +% {Since Version 1.02, {\ttfamily\bslash verb} and {\ttfamily\bslash % verb*} may be used, but they may treat spaces incorrectly, and the % argument can not contain an unmatched {\ttfamily\char`\{} or % {\ttfamily\char`\}}, or a {\ttfamily\char`\%} character.} @@ -207,7 +207,7 @@ % % \DescribeMacro{\newcolumntype} % These preamble specifications may of course be saved using the -% command, "\newcolumntype", defined in {\ttfamily array.sty}. Thus we +% command "\newcolumntype" defined in {\ttfamily array.sty}. Thus we % may say\\ % "\newcolumntype{Y}{>{\small\raggedright\arraybackslash}X}"\\ % and then use {\ttfamily Y} in the {\ttfamily tabularx} preamble @@ -314,7 +314,7 @@ % \footnote{This adds an extra level of grouping, % which is not really needed. Instead, I could use \box0\ here, and % \box2\ below, however the code here would then have to be moved after -% the first line, because of the footnote to page 386 of the \TeX{}Book, +% the first line, because of the footnote to page 386 of the \TeX{}book, % and I do not think I should be writing code that is so obscure as to % be documented in a footnote in an appendix called ``Dirty Tricks''!} % @@ -331,9 +331,9 @@ %\newenvironment{foo}{\tabularx{XX}}{\endtabularx} %\end{verbatim} % The scanner now looks for the end of the current environment ("foo" in -% this example.) There are some restrictions on this usage, the -% principal one being that "\endtabularx" must not be inside any "{ }" pairs -% ao that the code before "\endtabularx" may be extracted and added to the table body +% this example). There are some restrictions on this usage, the +% principal one being that "\endtabularx" must not be inside any "{ }" pairs, +% so that the code before "\endtabularx" may be extracted and added to the table body % (prior to version 2.09 "\endtabularx" had to be % the \emph{first} token of the `end code' of the environment). % \begin{macrocode} @@ -396,7 +396,7 @@ % \changes{v2.09}{2014/04/22}{macro added} % \changes{v2.10}{2014/05/13}{macro modified to test for missing \cs{endtabularx}} % \changes{v2.11}{2016/01/03}{Fix to previous change to guard against empty arg 2. (Ulrike Fischer)} -% split up the end code, and extract the part that lives in the table body. +% Split up the end code, and extract the part that lives in the table body. % \begin{macrocode} \long\def\TX@find@endtabularxa #1\endtabularx#2\endtabularx#3\TX@find@endtabularxa{% @@ -408,7 +408,7 @@ % \begin{macro}{\TX@find@endtabularxb} % \changes{v2.09}{2014/04/22}{macro added} % \changes{v2.10}{2014/05/13}{macro modified to test for missing \cs{endtabularx}} -% split up the end code, and extract the part that lives outside the table body. +% Split up the end code, and extract the part that lives outside the table body. % \begin{macrocode} \long\def\TX@find@endtabularxb #1\endtabularx#2\endtabularx#3\TX@find@endtabularxb{% @@ -502,7 +502,7 @@ \TX@col@width\TX@target \global\TX@cols\@ne % \end{macrocode} -% Typeout some headings (unless this is disabled). +% Type out some headings (unless this is disabled). % \begin{macrocode} \TX@typeout@ {\@spaces Table Width\@spaces Column Width\@spaces X Columns}% @@ -514,7 +514,7 @@ \global\advance\TX@cols\@ne\NC@find p{\TX@col@width}}}% % \end{macrocode} % Repeatedly decrease column width until table is the correct width, -% or stops shrinking, or the columns become two narrow. +% or stops shrinking, or the columns become too narrow. % If there are no multicolumn entries, this will only take one attempt. % \begin{macrocode} \loop @@ -601,7 +601,7 @@ \ifdim\dimen@<\TX@delta % \end{macrocode} % If this amount is less than "\TX@delta", stop. ("\TX@delta" -% should be non-zero otherwise we may miss the target due to rounding +% should be non-zero, otherwise we may miss the target due to rounding % error.) % \begin{macrocode} \TX@typeout@{Reached target.}% @@ -621,7 +621,7 @@ \ifdim \dimen@ >\z@ % \end{macrocode} % If the new width would be too narrow, abort the loop. At the moment -% too narrow, means less than 0\,pt! +% too narrow means less than 0\,pt! % % Prior to v2.03, if the loop was aborted here, the X columns were left % with the width of the previous run, but this may make the table far @@ -715,7 +715,7 @@ \expandafter\let\expandafter\endtabularx\csname endtabular*\endcsname % \end{macrocode} % Added at v1.05: disable "\write"s during a trial run. This trick is -% from the \TeX{}Book.\footnote{Actually the \TeX{}Book trick does +% from the \TeX{}book.\footnote{Actually the \TeX{}book trick does % not work correctly, so changed for v2.05.} % \changes{v2.05}{1997/09/18} % {New \cs{write} trick. tools/2607} @@ -789,7 +789,7 @@ % \end{macro} % % \begin{macro}{\TX@typeout} -% The default is to be to be quiet +% The default is to be quiet. % \begin{macrocode} \let\TX@typeout\@gobble \let\TX@typeout@\@gobble @@ -830,7 +830,7 @@ % tabularx}, but that did not stop people using it! This usually put % \LaTeX\ into an irrecoverable error position, with error messages that % did not mention the cause of the error. The `poor man's "\verb"' (and -% "\verb*") defined here is based on page 382 of the \TeX{}Book. As +% "\verb*") defined here is based on page 382 of the \TeX{}book. As % explained there, doing verbatim this way means that spaces are not % treated correctly, and so "\verb*" may well be useless, however I % consider this section of code to be error-recovery, rather than a real @@ -882,10 +882,10 @@ % does not consist of a single "{ }" group. \TeX\ would strip the outer % braces from such a group. The `"!"' will be removed later. % -% Originally I followed Knuth, and had "\def\@tempa{##1}", however this +% Originally I followed Knuth, and had "\def\@tempa{##1}", however, this % did not allow "#" to appear in the argument. So in v1.04, I changed -% this to use a token register, and "\edef". This allows "#" appear, -% but makes each one appear twice!, so later we loop through, replacing +% this to use a token register, and "\edef". This allows "#" to appear +% but makes each one appear twice, so later we loop through, replacing % "##" by "#". % \begin{macrocode} \def\TX@vb#1{\def\@tempa##1#1{\toks@{##1}\edef\@tempa{\the\toks@}% diff --git a/Master/texmf-dist/source/latex/tools/theorem.dtx b/Master/texmf-dist/source/latex/tools/theorem.dtx index 58476db07ee..e3a8e90b8c2 100644 --- a/Master/texmf-dist/source/latex/tools/theorem.dtx +++ b/Master/texmf-dist/source/latex/tools/theorem.dtx @@ -24,7 +24,7 @@ %% % % -\def\FMithmInfo{2014/10/28 v2.2c Theorem extension package (FMi)} +\def\FMithmInfo{2023/07/05 v2.2c Theorem extension package (FMi)} % % \ProvidesFile{theorem.dtx}[\FMithmInfo] %\iffalse % this is a METACOMMENT ! @@ -100,7 +100,7 @@ % % \begin{abstract} % The macros described in this paper yield an extension of the -% \LaTeX{} theorem mechanism. It is designed is to satisfy the +% \LaTeX{} theorem mechanism. It is designed to satisfy the % different requirements of various journals. Thus, the % layout of the ``theorems'' can be manipulated by determining a % ``style''. This article describes not only the use, but @@ -226,7 +226,7 @@ % |\theorempreskipamount| and |\theorempostskipamount| define, % respectively, the spacing before and after such an environment. % These parameters apply for all theorem sets and can be manipulated -% with the ordinary length macros. They are rubber lengths, +% with the ordinary length macros. They are rubber lengths % (`\textsf{skips}'), and therefore can contain \texttt{plus} and % \texttt{minus} parts. % @@ -385,7 +385,7 @@ % \section{Definition of the Macros} % % If the file has been loaded before, we abort immediately. If not the -% package announces itself (this is actually done at the very top if +% package announces itself (this is actually done at the very top of % the file---the way it is done isn't good style so don't copy it). % \changes{v2.0e}{89/07/19}{Spaces removed from `typeout'.} % \changes{v2.2b}{95/11/19}{Announce moved to top of file} @@ -546,8 +546,8 @@ % ``non-Big-versions'', we have to avoid offering too many unused % definitions. Therefore we define these styles in separate files % that can be loaded on demand. Thus the commands themselves only -% load these files. We use |\@input@| a \LaTeXe{} internal command -% that ensures that the file will be listed with |\listfiles| +% load these files. We use |\@input@|, a \LaTeXe{} internal command +% that ensures that the file will be listed with |\listfiles|. % \changes{v2.2a}{94/02/02}{Use `@input@ to load theorem layout files} % \begin{macrocode} \gdef\th@plain{\@input@{thp.sty}} diff --git a/Master/texmf-dist/source/latex/tools/verbatim.dtx b/Master/texmf-dist/source/latex/tools/verbatim.dtx index 0085f166ea1..832f80ef3a0 100644 --- a/Master/texmf-dist/source/latex/tools/verbatim.dtx +++ b/Master/texmf-dist/source/latex/tools/verbatim.dtx @@ -48,14 +48,14 @@ \pagestyle{myheadings} \title{A New Implementation of \LaTeX{}'s \\ \texttt{verbatim} - and \texttt{verbatim*} Environments.} + and \texttt{verbatim*} Environments} \author{Rainer Sch\"opf\\ \and Bernd Raichle\\ \and Chris Rowley} -\date{2022/07/02} +\date{2023/07/08} \begin{document} \markboth{Verbatim style option}{Verbatim style option} \MaintainedByLaTeXTeam{tools} @@ -434,7 +434,7 @@ % % A further possibility is to define a variant of the |verbatim| % environment that boxes and centers the whole verbatim text. -% Note that the boxed text should be less than a page otherwise you +% Note that the boxed text should be less than a page, otherwise you % have to change this example. % %\begin{verbatim} @@ -706,7 +706,7 @@ % necessary for correct vertical spacing if \texttt{verbatim} % is nested inside \texttt{quote}.} % The following extra vertical space is for compatibility with the -% \LaTeX kernel: otherwise, using the |verbatim| package changes +% \LaTeX{} kernel: otherwise, using the |verbatim| package changes % the vertical spacing of a |verbatim| environment nested within a % |quote| environment. % \begin{macrocode} @@ -790,18 +790,18 @@ \def\@noitemerr{\@warning{No verbatim text}}% % \end{macrocode} % Now we call |\obeylines| to make the end of line character -% active, +% active. % \begin{macrocode} \obeylines % \end{macrocode} -% change the category code of all special characters, +% The category code of all special characters is changed, % to $12$ (other). % \changes{v1.5i}{1996/06/04}{Moved \cs{verbatim@font} after % \cs{dospecials}.} % \begin{macrocode} \let\do\@makeother \dospecials % \end{macrocode} -% and switch to the font to be used. +% We switch to the font to be used. % \begin{macrocode} \verbatim@font % \end{macrocode} @@ -1391,7 +1391,7 @@ % (This token list was inserted after the current macro % by |\verbatim@@@|.) % Since we are still in an |\edef| we protect it -% by means of|\noexpand|. +% by means of |\noexpand|. % \begin{macrocode} \noexpand\verbatim@rescan{\@currenvir}}% % \end{macrocode} @@ -1493,7 +1493,7 @@ \else % \end{macrocode} % At this point we pass the name of the file to |\@addtofilelist| -% so that its appears in the output of a |\listfiles| +% so that it appears in the output of a |\listfiles| % command. % \changes{v1.5j}{1996/09/25}{Add \cs{@addtofilelist} and % \cs{ProvidesFile} so that the name of the file @@ -1579,9 +1579,9 @@ % the contents of |\@filef@und|, we need to save it by expanding it % first. The use of |\@swaptwoargs| makes it so that the % \emph{expansion} of |\@filef@und| gets to be the second argument -% of |\verbatim@readfile|. +% of |\verbatim@readfile|. % \changes{v1.5t}{2020-07-06}{Expand \cs{@filef@und} before the call -% of \cs{@verbatim} (gh/222)}m +% of \cs{@verbatim} (gh/222)} % \begin{macrocode} \def\verbatim@input#1#2{% \IfFileExists {#2}{% @@ -1606,7 +1606,7 @@ % \end{macro} % % -% \subsection{Getting verbatim text into arguments.} +% \subsection{Getting verbatim text into arguments} % % One way of achieving this is to define a macro (command) whose % expansion is the required verbatim text. This command can then be diff --git a/Master/texmf-dist/source/latex/tools/xr.dtx b/Master/texmf-dist/source/latex/tools/xr.dtx index 0dd5f3ad95f..be48f5a01b2 100644 --- a/Master/texmf-dist/source/latex/tools/xr.dtx +++ b/Master/texmf-dist/source/latex/tools/xr.dtx @@ -25,7 +25,7 @@ % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{xr} -% [2020-05-10 v5.06 eXternal References (DPC)] +% [2023-07-04 v5.06 eXternal References (DPC)] % %<*driver> \documentclass{ltxdoc} @@ -74,7 +74,7 @@ % If any of the external documents, or the main document, use the same % |\label| then an error will occur as the label will be multiply % defined. To overcome this problem |\externaldocument| has an optional -% argument. If you declare |\externaldocument[A-]{aaa}| Then all +% argument. If you declare |\externaldocument[A-]{aaa}|, then all % references from |aaa| are prefixed by |A-|. So for instance, if a % section of |aaa| had |\label{intro}|, then this could be referenced % with |\ref{A-intro}|. The prefix need not be |A-|, it can be any -- cgit v1.2.3