summaryrefslogtreecommitdiff
path: root/macros/latex-dev/required/tools/array.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex-dev/required/tools/array.dtx')
-rw-r--r--macros/latex-dev/required/tools/array.dtx465
1 files changed, 399 insertions, 66 deletions
diff --git a/macros/latex-dev/required/tools/array.dtx b/macros/latex-dev/required/tools/array.dtx
index 6e4e34ea26..66c40a5267 100644
--- a/macros/latex-dev/required/tools/array.dtx
+++ b/macros/latex-dev/required/tools/array.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 1993-2023
+% Copyright (C) 1993-2024
%
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
@@ -30,10 +30,15 @@
%<+package>
%<+package>\DeclareRelease{}{2016-10-06}{array-2016-10-06.sty}
%<+package>\DeclareRelease{v2.4}{2020-02-10}{array-2020-02-10.sty}
-%<+package>\DeclareCurrentRelease{}{2020-10-01}
+%<+package>\DeclareRelease{v2.5}{2023-11-01}{array-2023-11-01.sty}
+%<+package>\DeclareCurrentRelease{}{2024-06-01}
%<+package>
+% \end{macrocode}
+% Current version needs a new kernel.
+% \begin{macrocode}
+%<+package>\NeedsTeXFormat{LaTeX2e}[2024/06/01]
%<+package>\ProvidesPackage{array}
-%<+package> [2023/10/16 v2.5g Tabular extension package (FMi)]
+%<+package> [2023/12/11 v2.6a Tabular extension package (FMi)]
%
% \fi
%
@@ -177,6 +182,18 @@
% \DoNotIndex{\xdef}
% \DoNotIndex{\z@}
%
+%
+% \providecommand\env[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}
+%
+%
% \GetFileInfo{array.sty}
%
% \title{A new implementation of \LaTeX's \textsf{tabular}
@@ -195,6 +212,8 @@
% \MaintainedByLaTeXTeam{tools}
% \maketitle
%
+%
+%
% \MakeShortVerb{\=}
%
% \begin{abstract}
@@ -750,12 +769,29 @@
% \end{itemize}
%
%
+% \section{Support for tagged PDF}
%
-% \changes{v2.2b}{1994/02/04}{Removed interactive prompt}
+% With version 2.6a the package is made tagging aware, which means that
+% it will automatically produce tagged tables (necessary, for example, for
+% accessibility) if tagging is requested via \cs{DocumentMetadata}.
%
-% \MaybeStop{
+% More granular control, e.g., explicitly deciding which cells are
+% header cells, etc., is currently under development, but syntax for
+% this will not appear in this package. Instead it will become
+% available across all tabular-generating packages and then
+% automatically apply here as well.
+%
+% Enabling \LaTeX{} to automatically produce tagged PDF is a long-term
+% project and this is a tiny step in this puzzle. For more information
+% on the project and already available functionality, see
+% \url{https://latex-project.org/publications/indexbytopic/pdf} and
+% \url{https://github.com/latex3/tagging-project}.
%
%
+%
+% \changes{v2.2b}{1994/02/04}{Removed interactive prompt}
+%
+% \MaybeStop{
% \begin{thebibliography}{1}
% \bibitem{bk:GMS94} \textsc{M.~Goossens}, \textsc{F.~Mittelbach}
% and \textsc{A.~Samarin}.
@@ -772,7 +808,6 @@
% \newblock
% Addison-Wesley, Reading, Massachusetts, 1986.
% \end{thebibliography}
-%
% } ^^A end of \MaybeStop
%
%
@@ -786,8 +821,49 @@
% \texttt{docstrip} program.
% \begin{macrocode}
%<*driver>
-\NeedsTeXFormat{LaTeX2e}[1995/12/01]
-\documentclass{ltxdoc}
+\NeedsTeXFormat{LaTeX2e}[2024/06/01]
+% \end{macrocode}
+%
+% We switched from \cls{ltxdoc} to \cls{l3doc} to get support for
+% code written in the L3 programming layer. The first is that we
+% are currently missing \cs{MaintainedByLaTeXTeam}, so we have to
+% provide that for now.
+% \begin{macrocode}
+\documentclass{l3doc}
+
+% currently missing in l3doc
+\makeatletter
+\def\MaintainedBy#1{\gdef\@maintainedby{#1}}
+\let\@maintainedby\@empty
+\def\MaintainedByLaTeXTeam#1{%
+{\gdef\@maintainedby{%
+This file is maintained by the \LaTeX{} Project team.\\%
+Bug reports can be opened (category \texttt{#1}) at\\%
+\url{https://latex-project.org/bugs.html}.}}}
+\def\@maketitle{%
+ \newpage
+ \null
+ \vskip 2em%
+ \begin{center}%
+ \let \footnote \thanks
+ {\LARGE \@title \par}%
+ \vskip 1.5em%
+ {\large
+ \lineskip .5em%
+ \begin{tabular}[t]{c}%
+ \@author
+ \end{tabular}\par}%
+ \vskip 1em%
+ {\large \@date}%
+ \ifx\@maintainedby\@empty
+ \else
+ \vskip 1em%
+ \fbox{\fbox{\begin{tabular}{@{}l@{}}\@maintainedby\end{tabular}}}%
+ \fi
+ \end{center}%
+ \par
+ \vskip 1.5em}
+\makeatother
% undo the default is not used:
@@ -817,6 +893,29 @@
% \end{macrocode}
%
%
+% \section{A note on the updates done December 2023}
+%
+% We introduced support for tagged PDf and at the same time we added
+% code to determine row and column numbers for each cell in
+% preparation for supporting formatting or type specifications for individual
+% cells (or group of cells) from the outside, e.g., \enquote{rows 1,
+% 2, and 10 are header rows} (syntax to be decided).
+%
+% This new code is already written with L3 programming layer conventions
+% while most of the legay code is still as it was before. This make the code
+% currently somewhat clattered, unfortunately. Eventually this will all move to L3
+% programming layer but this will take time.
+%
+%
+% \begin{macrocode}
+%<@@=tbl>
+\ExplSyntaxOn
+% \end{macrocode}
+%
+%
+%
+%
+%
% \section{The construction of the preamble}
%
% \DeleteShortVerb{\"}
@@ -972,6 +1071,7 @@
% =\@chclass= and =\@chnum=.
% \changes{v2.0f}{1992/02/29}{Argument removed since implicitly known}
% \begin{macrocode}
+\ExplSyntaxOff
\def\@testpach{\@chclass
% \end{macrocode}
% First we deal with the cases in which the \textsf{token}
@@ -981,7 +1081,7 @@
\ifnum \@lastchclass=6 \@ne \@chnum \@ne \else
\ifnum \@lastchclass=7 5 \else
\ifnum \@lastchclass=8 \tw@ \else
- \ifnum \@lastchclass=9 \thr@@
+ \ifnum \@lastchclass=9 \thr@@@@
% \end{macrocode}
% Otherwise we will assume that the \textsf{token} belongs to the
% class $0$
@@ -1032,7 +1132,7 @@
% \begin{macrocode}
10
\@chnum
- \if \@nextchar m\thr@@\else
+ \if \@nextchar m\thr@@@@ \else
\if \@nextchar p4 \else
\if \@nextchar b5 \else
% \end{macrocode}
@@ -1042,6 +1142,7 @@
% \begin{macrocode}
\z@ \@chclass \z@ \@preamerr \z@ \fi \fi \fi \fi
\fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi}
+\ExplSyntaxOn
% \end{macrocode}
% \end{macro}
%
@@ -1062,10 +1163,10 @@
% they are in explicit braces, as in =@{*}=.
%
% This macro is called via
-% =\@xexpast=\meta{preamble}=*0x\@@=.
+% =\@xexpast=\meta{preamble}=*0x\@@@@=.
% The $*$--expression =*0x= is being used to terminate the
% recursion,
-% as we shall see later, and =\@@= serves as an argument
+% as we shall see later, and =\@@@@= serves as an argument
% delimiter. =\@xexpast= has four arguments. The first
% one is the part of the
% user preamble before the first $*$--expression while the second
@@ -1074,7 +1175,7 @@
% above).
% The fourth argument is the rest of the preamble.
% \begin{macrocode}
-\def\@xexpast#1*#2#3#4\@@{%
+\def\@xexpast#1*#2#3#4\@@@@{%
% \end{macrocode}
% The number of copies of \textit{String} (=#2=) that are to be
% produced will be saved in a \textsf{count} register.
@@ -1111,7 +1212,7 @@
% \end{macrocode}
% If \textit{N\/} was greater than zero we prepare for another call
% of =\@xexpast=. Otherwise we assume we have reached the end of
-% the user preamble, because we had appended =*0x\@@= when we first
+% the user preamble, because we had appended =*0x\@@@@= when we first
% called =\@xexpast=. In other words: if the user inserts
% =*{0}{..}= in his preamble, \LaTeX\ ignores the rest of it.
% \begin{macrocode}
@@ -1133,7 +1234,7 @@
% $*$--expression is handled, or to the macro =\@xexnoop=,
% which only ends the recursion by deleting its argument.
% \begin{macrocode}
- \expandafter \@tempb \@tempa #4\@@}
+ \expandafter \@tempb \@tempa #4\@@@@}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1142,10 +1243,10 @@
% \begin{macro}{\@xexnoop}
% So the first big problem is solved. Now it is easy to
% specify =\@xexnoop=.
-% Its argument is delimited by =\@@= and it simply expands to
+% Its argument is delimited by =\@@@@= and it simply expands to
% nothing.
% \begin{macrocode}
-% \def\@xexnoop#1\@@{}
+% \def\@xexnoop#1\@@@@{}
% \end{macrocode}
% \end{macro}
%
@@ -1275,6 +1376,13 @@
% \begin{macrocode}
\def\insert@column{%
% \end{macrocode}
+%
+% For tagging we insert as special socket, that adds the necessary
+% PDF tag at the beginning of the cell if tagging is enabled.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+% \begin{macrocode}
+ \UseTaggingSocket{tbl/cell/begin}%
+% \end{macrocode}
% Here, we assume that the \textsf{count} register
% =\@tempcnta= has saved the value $=\count@= - 1$.
% \begin{macrocode}
@@ -1302,12 +1410,36 @@
% \changes{v2.0c}{1990/08/14}{\cs{relax} added to avoid problem
% \cs{the}\cs{toks0}\cs{the}\cs{toks1}.}
% \begin{macrocode}
- \the@toks \the \count@ \relax}
+ \the@toks \the \count@ \relax
+% \end{macrocode}
+%
+% And another socket for tagging that adds the necessary closing tag
+% if enabled.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+% \begin{macrocode}
+ \UseTaggingSocket{tbl/cell/end}%
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
+% \begin{macro}{\insert@pcolumn}
+% Handling pcolumn-cells needs slightly different handling when
+% doing tagging. Rather than changing the plugs in
+% \cs{insert@column} back and forth, we simply use a different
+% version of \cs{insert@column} that has its own sockets.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+% \begin{macrocode}
+\def\insert@pcolumn{%
+ \UseTaggingSocket{tbl/pcell/begin}%
+ \the@toks \the \@tempcnta
+ \ignorespaces \@sharp \unskip
+ \the@toks \the \count@ \relax
+ \UseTaggingSocket{tbl/pcell/end}%
+}
+% \end{macrocode}
+% \end{macro}
%
%
% \subsection{The separation of columns}
@@ -1321,11 +1453,24 @@
% =\@addamp=, the macro that inserts the =&=.
% \begin{macrocode}
% \newif \@iffirstamp
-% \def\@addamp{\if@firstamp \@firstampfalse
-% \else \@addtopreamble &\fi}
+\def\@addamp {
+ \if@firstamp
+ \@firstampfalse
+ \else
+% \end{macrocode}
+% If we are after the first column we have to insert a \verb=&= and
+% also update the cell data.
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
+% \begin{macrocode}
+ \edef\@preamble{\@preamble &
+ \noexpand\tbl_update_cell_data: }
+ \fi
+}
% \end{macrocode}
% \end{macro}
%
+%
+%
% \begin{macro}{\@acol}
% \begin{macro}{\@acolampacol}
% \begin{macro}{\col@sep}
@@ -1393,7 +1538,7 @@
% command =\@xexpast=. As we already know, this command saves
% its result in the macro =\@tempa=.
% \begin{macrocode}
-% \@xexpast #1*0x\@@
+% \@xexpast #1*0x\@@@@
% \end{macrocode}
% Afterwards we initialize all registers and macros, that we need
% for the build-up of the preamble.
@@ -1477,7 +1622,7 @@
% \texttt{r}, \texttt{p},\texttt{m} or \texttt{b}. We report an
% error and ignore the declaration given by ={..}=.
% \begin{macrocode}
-% \@preamerr \thr@@ \or
+% \@preamerr \thr@@@@ \or
% \end{macrocode}
% If =\@lastchclass= is $4$ the user preamble has been empty.
% To continue, we insert a =#= in the preamble.
@@ -1671,18 +1816,17 @@
\setbox\ar@mcellbox\vbox
% \end{macrocode}
% The part of the templates which is the same in all three cases
-% (\texttt{p}, \texttt{m} and \texttt{b})
-% is built by the macros =\@startpbox= and
-% =\@endpbox=. =\@startpbox= has an argument:
-% the width of the column which is stored in the current
-% \textsf{token} (i.e.\ =\@nextchar=).
-% Between these two macros we find the well known
-% =\insert@column=.
-% The strut is places after the box
+% (\texttt{p}, \texttt{m} and \texttt{b}) is built by the macros
+% =\@startpbox= and =\@endpbox=. =\@startpbox= has an argument: the
+% width of the column which is stored in the current \textsf{token}
+% (i.e.\ =\@nextchar=). Between these two macros we find the well
+% known =\insert@column= or rather the variant for tagging:
+% \cs{insert@pcolumn}. The strut is placed after the box.
% \changes{v2.4e}{2016/10/07}{Fixing SX68732}
% \changes{v2.4f}{2017/11/04}{Managing m-cells without \cs{vcenter}}
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
% \begin{macrocode}
- \@startpbox{\@nextchar}\insert@column \@endpbox
+ \@startpbox{\@nextchar}\insert@pcolumn \@endpbox
\ar@align@mcell
\do@row@strut \or
% \end{macrocode}
@@ -1690,9 +1834,10 @@
% same way though we do not need the =$= characters because we use
% =\vtop= or =\vbox=.
% \changes{v2.4e}{2016/10/07}{Fixing SX68732}
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
% \begin{macrocode}
- \vtop \@startpbox{\@nextchar}\insert@column \@endpbox\do@row@strut \or
- \vbox \@startpbox{\@nextchar}\insert@column \@endpbox\do@row@strut
+ \vtop \@startpbox{\@nextchar}\insert@pcolumn \@endpbox\do@row@strut \or
+ \vbox \@startpbox{\@nextchar}\insert@pcolumn \@endpbox\do@row@strut
% \end{macrocode}
% Other values for =\@chnum= are impossible. Therefore we
% end the arguments to =\@addtopreamble= and =\ifcase=.
@@ -1783,8 +1928,8 @@
% So the declarations defined by the first =>{...}=
% are ignored.
% \begin{macrocode}
-%\def\@classix{\ifnum \@lastchclass = \thr@@
-% \@preamerr \thr@@ \fi
+%\def\@classix{\ifnum \@lastchclass = \thr@@@@
+% \@preamerr \thr@@@@ \fi
% \end{macrocode}
% Furthermore, we call up =\@class10= because afterwards always a
% new column is started by \texttt{c}, \texttt{l}, \texttt{r},
@@ -1836,14 +1981,14 @@
% We only check if the last \textsf{token} was of class $3$ which is
% forbidden.
% \begin{macrocode}
-\def\@classvii{\ifnum \@lastchclass = \thr@@
+\def\@classvii{\ifnum \@lastchclass = \thr@@@@
% \end{macrocode}
% If this is true we output an error message and
% ignore the declarations stored
% by the last =>{...}=, because these are overwritten
% by the argument of \texttt{@}.
% \begin{macrocode}
- \@preamerr \thr@@ \fi}
+ \@preamerr \thr@@@@ \fi}
% \end{macrocode}
% \end{macro}
%
@@ -2032,7 +2177,7 @@
% second one describes the wanted preamble,
% e.g.\ it has the form =|c|c|c|=.
% \begin{macrocode}
-\def\@array[#1]#2{%
+\def\@array[#1]#2{
% \end{macrocode}
% First we define a \textsf{strut} whose size basically corresponds
% to a normal \textsf{strut} multiplied by the factor
@@ -2051,6 +2196,14 @@
\@depth \arraystretch \dp \strutbox
\@width \z@}%
% \end{macrocode}
+% The total number of table columns of the current table is
+% determined in \cs{tbl_count_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.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+% \begin{macrocode}
+ \tbl_save_outer_table_cols:
+% \end{macrocode}
% Then we open a group, in which the user preamble is evaluated by
% the macro =\@mkpream=. As we know this must happen locally.
% This macro creates a preamble for a =\halign= and saves
@@ -2059,6 +2212,11 @@
\begingroup
\@mkpream{#2}%
% \end{macrocode}
+% Figure out how many columns this table has:
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
+% \begin{macrocode}
+ \tbl_count_table_cols:
+% \end{macrocode}
% We again redefine =\@preamble= so that a call up of =\@preamble=
% now starts the =\halign=. Thus also the arguments of \texttt{>},
% \texttt{<}, \texttt{@} and \texttt{!}, saved in the
@@ -2085,13 +2243,38 @@
% unsupported redefinition of a \TeX{} primitive for the moment (as people rely
% on that experimental code).
% \begin{macrocode}
- \xdef\@preamble{\noexpand \ialign \@halignto
- \bgroup \@arstrut \@preamble
- \tabskip \z@ \cr}%
+ \xdef\@preamble{
+% \end{macrocode}
+% \cs{ialign} in the original definition is replaced by
+% \cs{ar@ialign} defined below. This does what \cs{ialign} does but
+% additionally handles the tagging structure for the whole table if necessary.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+% \begin{macrocode}
+ \noexpand \ar@ialign
+ \@halignto
+ \bgroup \@arstrut
% \end{macrocode}
% What we have not explained yet is the macro =\@halignto=
% that was just used. Depending on its replacement text the
% =\halign= becomes a =\halign= \texttt{to} \meta{dimen}.
+%
+% Next, a tagging support socket is inserted adding the start row tag.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+% \begin{macrocode}
+ \UseTaggingSocket{tbl/row/begin}
+% \end{macrocode}
+% At the start of the preamble for the first column we call
+% \cs{tbl_init_cell_data_for_row:} to initialize the cell index data. In
+% later columns this data is updated via \cs{tbl_update_cell_data:}.
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
+% \begin{macrocode}
+ \tbl_init_cell_data_for_row:
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \@preamble
+ \tabskip \z@ \cr}
+% \end{macrocode}
% Now we close the group again. Thus
% =\@startpbox= and =\@endpbox= as well as all
% \textsf{token} registers get their former meaning back.
@@ -2128,12 +2311,16 @@
% around every column in the \textsf{array}--environment
% the parameter =\mathsurround= should
% also be set to \textsf{0pt}. This prevents additional space between
-% the rows. The
-% \PlainTeX--macro =\m@th= does this.
+% the rows.
% \begin{macrocode}
\lineskip \z@
\baselineskip \z@
- \m@th
+% \end{macrocode}
+% Don't use \cs{m@th} here as that signals to the math taggingg
+% code that this is fake math that should not be tagged.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+% \begin{macrocode}
+ \mathsurround \z@
% \end{macrocode}
% Beside, we have to assign a special meaning (which we still have
% to specify) to the line separator =\\=. We also have to
@@ -2144,10 +2331,61 @@
% start the wanted =\halign=.
% \changes{1994/12/08}{v2.3b}{add \cs{tabularnewline}}
% \begin{macrocode}
- \let\\\@arraycr \let\tabularnewline\\\let\par\@empty \@preamble}
+ \let\\\@arraycr \let\tabularnewline\\\let\par\@empty
+% \end{macrocode}
+% Another socket for tagging. TODO: what about \cs{arrayleft} above?
+% \begin{macrocode}
+ \UseTaggingSocket{tbl/init}
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \@preamble
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\ar@ialign}
+% A new command that replaces \cs{ialign} used previously. \cs{everycr} is
+% also applied to the \cs{cr} ending the preamble so we have to
+% program around that.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+% \begin{macrocode}
+\def\ar@ialign{%
+% \end{macrocode}
+% Before starting a table we have to initialize the variables
+% holding row and column information for cells. We also have
+% locally store the information related to the current cell (if we
+% are already inside a table) so that we can restore it once the
+% inner table is finished.
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
+% \begin{macrocode}
+ \tbl_init_cell_data_for_table:
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \everycr{%
+ \noalign{%
+% \end{macrocode}
+% If this \cs{cr} was at the end of a real row (e.g., not at the
+% end of the table preamble) we have add a row end tag.
+% \begin{macrocode}
+ \tbl_if_row_was_started:T { \UseTaggingSocket{tbl/row/end} }
+% \end{macrocode}
+% The we prepare for the next row.
+% \begin{macrocode}
+ \tbl_update_cell_data_for_next_row:
+ }%
+ }%
+ \tabskip\z@skip\halign}
% \end{macrocode}
% \end{macro}
%
+%
+%
+%
+%
% \begin{macro}{\arraybackslash}
% \changes{v2.4a}{2003/12/17}{(DPC) Macro added (from tabularx)}
% Restore =\\= for use in array and tabular environment (after
@@ -2182,7 +2420,27 @@
% \begin{macro}{\@arraycr}
% In the macro =\@array= the line separator =\\= is
% =\let= to the command =\@arraycr=.
-% Its definition starts with a special brace which I have directly
+% \changes{v2.3c}{1995/04/23}{Avoid adding an ord atom in math}
+% \changes{v2.5e}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)}
+% \begin{macrocode}
+\protected\def\@arraycr {
+% \end{macrocode}
+% 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.
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
+% \begin{macrocode}
+ \tbl_count_missing_cells:n {@arraycr}
+% \end{macrocode}
+% TODO: maybe this is also the right place to add a socket that
+% could be used to actually enter missing cells instead of just
+% adding tagging structures for them later. This would be optional
+% but in many cases it would be the right thing to do (for example
+% if tables contain vertical lines or similar visual structures
+% that require fully specified rows.
+%
+%
+% We then start a special brace which I have directly
% copied from the original definition. It is
% necessary, because the =\futurlet= in =\@ifnextchar=
% might
@@ -2198,10 +2456,8 @@
% =\halign= while we are looking for a =*= or =[=.
% For further information see
% \cite[Appendix D]{bk:knuth}.
-% \changes{v2.3c}{1995/04/23}{Avoid adding an ord atom in math}
-% \changes{v2.5e}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)}
% \begin{macrocode}
-\protected\def\@arraycr{\relax\iffalse{\fi\ifnum 0=`}\fi
+ \iffalse{\fi\ifnum 0=`}\fi
% \end{macrocode}
% Then we test whether the user is using the star form and ignore
% a possible star (I also disagree with this procedure, because a
@@ -2210,6 +2466,11 @@
\@ifstar \@xarraycr \@xarraycr}
% \end{macrocode}
% \end{macro}
+
+
+
+
+
%
% \begin{macro}{\@xarraycr}
% In the command =\@xarraycr= we test if an optional argument
@@ -2301,6 +2562,7 @@
% the result column and the actual column entry.
% \changes{v2.3j}{1998/01/29}{Command made \cs{long} to match
% kernel change for pr/2180}
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
% \begin{macrocode}
\long\def\multicolumn#1#2#3{%
% \end{macrocode}
@@ -2310,6 +2572,16 @@
% \begin{macrocode}
\multispan{#1}\begingroup
% \end{macrocode}
+% For tagging support we have to solve two problems:
+% \cs{multicolumn} 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. We do this in the next macro
+% (which in turn calls the \texttt{tbl/row/begin} socket, if
+% necessary).
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
+% \begin{macrocode}
+ \tbl_update_multicolumn_cell_data:n {#1}
+% \end{macrocode}
% Since a =\multicolumn= should only describe the format of a
% result column, we redefine =\@addamp= in such a way that one gets
% an error message if one uses more than one \texttt{c},
@@ -2336,6 +2608,12 @@
% \begin{macrocode}
\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}.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+% \begin{macrocode}
+ \UseTaggingSocket{tbl/colspan}{#1}%
+% \end{macrocode}
% In the special situation of =\multicolumn= =\@preamble=
% is not needed as preamble for a =\halign= but it is directly
% inserted into our table. Thus instead of =\sharp=
@@ -2458,6 +2736,12 @@
% \begin{macrocode}
\leavevmode
% \end{macrocode}
+% Now that we know we are in hmode we can add the start tag for the
+% whole table.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+% \begin{macrocode}
+ \UseTaggingSocket{tbl/hmode/begin}%
+% \end{macrocode}
% It should be taken into consideration that the macro =\@array=
% must be called in math mode. Therefore we open a \textsf{box},
% insert a =$= and then assign the correct values to =\col@sep= and
@@ -2486,11 +2770,41 @@
% =\@array=. To save \textsf{token} space we then redefine
% =\@preamble=
% because its replacement text isn't longer needed.
+%
+% To handle cell indexes, we do not use \cs{crcr} but a variant
+% that also handles missing cells as necessary.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+% \begin{macrocode}
+\def\endarray {
+ \tbl_crcr:n{endarray} \egroup
+ \UseTaggingSocket{tbl/finalize}
+% \end{macrocode}
+%
+% If tables are nested into another then it is necessary to
+% restore information about the cell the inner table started
+% in. Otherwise, the cell index data structures 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} uses a similar method.
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
% \begin{macrocode}
-%\def\endarray{\crcr \egroup \egroup \gdef\@preamble{}}
+ \tbl_restore_outer_cell_data:
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \egroup
+ \@arrayright \gdef\@preamble{}%
+}
% \end{macrocode}
% \end{macro}
%
+%
+%
+%
% \begin{macro}{\endtabular}
% \begin{macro}{\endtabular*}
% To end a \textsf{tabular} or \textsf{tabular$*$} environment we
@@ -2499,7 +2813,13 @@
% any =\mathsurround= so we cancel that with =\m@th=.
% \changes{v2.5f}{2021/07/12}{Cancel any outside \cs{mathsurround} (gh/614)}
% \begin{macrocode}
-\def\endtabular{\endarray\m@th $\egroup}
+\def\endtabular{\endarray\m@th $\egroup
+% \end{macrocode}
+%
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+% \begin{macrocode}
+ \UseTaggingSocket{tbl/hmode/end}%
+}
\expandafter\let\csname endtabular*\endcsname=\endtabular
% \end{macrocode}
% \end{macro}
@@ -2518,7 +2838,7 @@
\let\@arrayclassiv=\relax \let\@arrayclassz=\relax
\let\@tabclassiv=\relax \let\@tabclassz=\relax
\let\@arrayacol=\relax \let\@tabacol=\relax
-\let\@tabularcr=\relax \let\@@endpbox=\relax
+\let\@tabularcr=\relax \let\@@@@endpbox=\relax
\let\@argtabularcr=\relax \let\@xtabularcr=\relax
% \end{macrocode}
%
@@ -2576,6 +2896,7 @@
% to define letters, to be used in the same way as the primitive
% column specifiers, `c' `p' etc.
% \begin{macrocode}
+\ExplSyntaxOff % this is really oldstyle using \@tfor :=
\def\newcolumntype#1{%
% \end{macrocode}
% "\NC@char" was added in V2.01 so that active characters, like "@" in
@@ -2615,6 +2936,7 @@
% If an optional argument was not given, give a default argument of 0.
% \begin{macrocode}
\@ifnextchar[{\newcol@{\NC@char}}{\newcol@{\NC@char}[0]}}
+\ExplSyntaxOn
% \end{macrocode}
% \end{macro}
% \begin{macro}{\newcol@}
@@ -2710,16 +3032,18 @@
% produced and then "\typeout" the required string.
% \begin{macrocode}
\def\NC@show#1{%
- \typeout{Column #1\expandafter\expandafter\expandafter\NC@strip
- \expandafter\meaning\csname NC@rewrite@#1\endcsname\@@}}
+ \typeout{Column~ #1\expandafter\expandafter\expandafter\NC@strip
+ \expandafter\meaning\csname NC@rewrite@#1\endcsname\@@@@}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\NC@strip}
% Delimit the arguments to "\NC@strip" with `\texttt{:}', `\texttt{->}',
-% a space, and "\@@" to pull out the required parts of the output from
+% a space, and "\@@@@" to pull out the required parts of the output from
% "\meaning".
% \begin{macrocode}
-\def\NC@strip#1:#2->#3 #4\@@{#2 -> #4}
+\ExplSyntaxOff
+\def\NC@strip#1:#2->#3 #4\@@@@{#2 -> #4}
+\ExplSyntaxOn
% \end{macrocode}
% \end{macro}
% \begin{macro}{\NC@list}
@@ -2807,6 +3131,7 @@
% \changes{v2.4e}{2016/10/07}{Fixing SX68732}
% \changes{v2.4f}{2017/11/04}{Managing m-cells without \cs{vcenter}}
% \begin{macrocode}
+\ExplSyntaxOff % really oldstyle using \@tfor :=
\def\@mkpream#1{\gdef\@preamble{}\@lastchclass 4 \@firstamptrue
\let\@sharp\relax
% \end{macrocode}
@@ -2869,11 +3194,12 @@
\@acol \or
\or
\@acol \or
- \@preamerr \thr@@ \or
+ \@preamerr \thr@@@@ \or
\@preamerr \tw@ \@addtopreamble\@sharp \or
\or
\else \@preamerr \@ne \fi
\def\the@toks{\the\toks}}
+\ExplSyntaxOn
% \end{macrocode}
% \end{macro}
%
@@ -2908,7 +3234,7 @@
% \texttt{array.sty} 2.0h.
% \begin{macrocode}
\def\@classv{\save@decl
- \expandafter\NC@ecs\@nextchar\extracolsep{}\extracolsep\@@@
+ \expandafter\NC@ecs\@nextchar\extracolsep{}\extracolsep\@@@@@@
\@addtopreamble{\d@llarbegin\the@toks\the\count@\relax\d@llarend}%
\prepnext@tok}
% \end{macrocode}
@@ -2920,7 +3246,7 @@
% second "\extracolsep", there is no point in the user entering two of
% these commands anyway, so this is not really a restriction.
% \begin{macrocode}
-\def\NC@ecs#1\extracolsep#2#3\extracolsep#4\@@@{\def\@tempa{#2}%
+\def\NC@ecs#1\extracolsep#2#3\extracolsep#4\@@@@@@{\def\@tempa{#2}%
\ifx\@tempa\@empty\else\toks\count@={#1\tabskip#2\relax#3}\fi}
%</ncols>
% \end{macrocode}
@@ -2936,28 +3262,27 @@
%
% \begin{macro}{\@tabarray}
% This macro tests for an optional bracket and then calls up
-% "\@@array" or "\@@array[c]" (as default).
+% "\@@@@array" or "\@@@@array[c]" (as default).
% \begin{macrocode}
%<*package>
-\def\@tabarray{\@ifnextchar[{\@@array}{\@@array[c]}}
+\def\@tabarray{\@ifnextchar[{\@@@@array}{\@@@@array[c]}}
% \end{macrocode}
% \end{macro}
-% \begin{macro}{\@@array}
+% \begin{macro}{\@@@@array}
% This macro tests could then test an optional delimiter before the
% left brace of the main preamble argument. Here in the main package
% it simply is let to be "\@array".
% \begin{macrocode}
-\let\@@array\@array
+\let\@@@@array\@array
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\endarray}
+% \begin{macro}{\@arrrayleft}
% \begin{macro}{\@arrayright}
% We have to declare the hook we put into "\@array" above.
-% A similar hook `"\@arrayright"' will be inserted into the
+% A similar hook \cs{@arrayright} will be inserted into the
% "\endarray" to gain control. Both defaults to empty.
% \begin{macrocode}
-\def\endarray{\crcr \egroup \egroup \@arrayright \gdef\@preamble{}}
\let\@arrayleft\@empty
\let\@arrayright\@empty
% \end{macrocode}
@@ -3182,6 +3507,14 @@
% \end{macro}
%
%
+%
+%
+%
+% \begin{macrocode}
+\ExplSyntaxOff
+% \end{macrocode}
+%
+%
% \PrintIndex
% \PrintChanges
%