[latex3-commits] [latex3/latex2e] ltmarks-multicol: getting there (a901aee42)
github at latex-project.org
github at latex-project.org
Mon Nov 11 23:35:05 CET 2024
Repository : https://github.com/latex3/latex2e
On branch : ltmarks-multicol
Link : https://github.com/latex3/latex2e/commit/a901aee42d230e5aa711b414a64dabd229df71d6
>---------------------------------------------------------------
commit a901aee42d230e5aa711b414a64dabd229df71d6
Author: Frank Mittelbach <frank.mittelbach at latex-project.org>
Date: Mon Nov 11 23:35:05 2024 +0100
getting there
>---------------------------------------------------------------
a901aee42d230e5aa711b414a64dabd229df71d6
base/ltmarks.dtx | 56 +++++-----
required/tools/multicol.dtx | 261 ++++++++++++++++++++++++++++++--------------
2 files changed, 206 insertions(+), 111 deletions(-)
diff --git a/base/ltmarks.dtx b/base/ltmarks.dtx
index dacc1cdb8..8f507e9e1 100644
--- a/base/ltmarks.dtx
+++ b/base/ltmarks.dtx
@@ -397,7 +397,7 @@
% The \texttt{column} region is used by the \enquote{current
% column} that is being built (moving through all columns with
-% \texttt{previous-column} traling behind (to handle top marks
+% \texttt{previous-column} trailing behind (to handle top marks
% properly).
%
% \item
@@ -410,7 +410,7 @@
% \item
%
% If the \env{multicols} extends beyond the current page, then the
-% material destinated for the current page is split into columns.
+% material designated for the current page is split into columns.
% The \texttt{column} region is used to represent each column in
% turn.
@@ -427,7 +427,7 @@
%
% \item Finally, the first and the last column of that page is also
% made available as \texttt{first-column} and
-% \texttt{last-column}, repectively.
+% \texttt{last-column}, respectively.
% \end{itemize}
%
% \item
@@ -759,9 +759,9 @@
%
%
%
-% \begin{function}{\@@_update_alias_structure:nn}
+% \begin{function}{\@@_copy_structure:nn}
% \begin{syntax}
-% \cs{@@_update_alias_structure:nn} \Arg{alias} \Arg{source}
+% \cs{@@_copy_structure:nn} \Arg{alias} \Arg{source}
% \end{syntax}
% Helper function that copies all mark values in the \meta{source}
% region to \meta{alias}, i.e., make the structures identical. Used
@@ -774,9 +774,9 @@
%
%
%
-% \begin{function}{\@@_update_structure_to_err:n}
+% \begin{function}{\@@_set_structure_to_err:n}
% \begin{syntax}
-% \cs{@@_update_structure_to_err:n} \Arg{region}
+% \cs{@@_set_structure_to_err:n} \Arg{region}
% \end{syntax}
% Helper function that sets all mark values in the \meta{region} to
% an error message. This is currently used for \texttt{last-column}
@@ -789,7 +789,7 @@
% \cs{@@_clear_structure:n} \Arg{region}
% \end{syntax}
% Helper function that sets all mark values in the \meta{region} to
-% empty. This is currently used for \texttt{mcol} when a multicol
+% empty. This is currently used for \texttt{column} when a multicol
% environment starts because it wouldn't make sense if the top mark
% in the first column would return the last mark from a previous
% multicol (which may have been much earlier with intermediate
@@ -932,7 +932,7 @@
% To support multiple columns produced by the \pkg{multicol}
% package, we preallocate twenty alias regions (that is what
% \pkg{multicol} supports as a maximum). They are filled by copying
-% the current \texttt{column} into the appropiate \texttt{mcol-...}.
+% the current \texttt{column} into the appropriate \texttt{mcol-...}.
% \begin{macrocode}
%fmi \@@_init_region:nn {mcol}{#1}
%fmi \@@_init_region:nn {previous-mcol}{#1}
@@ -1289,7 +1289,7 @@
% \texttt{previous-...}; this leaves the current structure
% untouched so we can update it class by class (which is necessary).
% \begin{macrocode}
- \@@_update_alias_structure:nn { previous-#1 } {#1}
+ \@@_copy_structure:nn { previous-#1 } {#1}
% \end{macrocode}
% After this action we can get first and last marks of the various
% classes through \cs{tex_splitfirstmarks:D} and
@@ -1503,13 +1503,13 @@
% \end{macro}
%
%
-% \begin{macro}{\@@_update_alias_structure:nn}
+% \begin{macro}{\@@_copy_structure:nn}
% This function copies the structure for one region to another
% (name), e.g., from \texttt{page} to \texttt{previous-page} above,
% or later from \texttt{column} to \texttt{first-column}, etc.
% \changes{v1.1a}{2024/11/09}{Macro renamed}
% \begin{macrocode}
-\cs_new_protected:Npn \@@_update_alias_structure:nn #1#2 {
+\cs_new_protected:Npn \@@_copy_structure:nn #1#2 {
% \end{macrocode}
% This requires a simple loop through all mark classes copying the
% token list from one name to the next.
@@ -1552,11 +1552,11 @@
%
%
%
-% \begin{macro}{\@@_update_structure_to_err:n,\@@_error:n}
+% \begin{macro}{\@@_set_structure_to_err:n,\@@_error:n}
% A slight variation is to install a fixed error message as the
% value.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_update_structure_to_err:n #1 {
+\cs_new_protected:Npn \@@_set_structure_to_err:n #1 {
\seq_map_inline:Nn \g_@@_classes_seq
{
\tl_gset:ce { g_@@_ #1 _top_ ##1 _tl } { \@@_value:nn{?}{\@@_error:n {#1}} }
@@ -1890,13 +1890,13 @@
%
% \begin{macro}{\@@_class_status:nnn}
% Shows the mark values across all regions for one mark class
-% (\verb=#2=). Actually this is a lie, we only show \texttt{mcol-1}
-% to \texttt{mcol-4} for now and not up to 20. We could keep track
-% of how many mcols have been used, but for now just the simple
-% version.
+% (\verb=#2=).
%
% The first argument gives some \meta{info} to help
-% identifying where the command was called.
+% identifying where the command was called, the second is
+% the class and the third holds the number of \texttt{mcol-...} we
+% should display (inside a \env{multicols} environment it will get \cs{col at number}
+% passed, in \LaTeX{}'s normal output routines it will be \texttt{0}.
% \changes{v1.1a}{2024/11/09}{Add a third argument}
% \begin{macrocode}
%<*trace>
@@ -2074,10 +2074,10 @@
% \end{macrocode}
% The we provide the necessary updates for the aliases.
% \begin{macrocode}
- \@@_update_alias_structure:nn {previous-column}{previous-page}
- \@@_update_alias_structure:nn {column}{page}
- \@@_update_alias_structure:nn {first-column}{page}
- \@@_update_alias_structure:nn {last-column}{page}
+ \@@_copy_structure:nn {previous-column}{previous-page}
+ \@@_copy_structure:nn {column}{page}
+ \@@_copy_structure:nn {first-column}{page}
+ \@@_copy_structure:nn {last-column}{page}
%<*trace>
% move this into status itself?
\@@_debug:n
@@ -2128,8 +2128,8 @@
% \texttt{first-column} and there is no \texttt{last-column} yet,
% so we make those an error.
% \begin{macrocode}
- \@@_update_alias_structure:nn {first-column}{column}
- \@@_update_structure_to_err:n {last-column}
+ \@@_copy_structure:nn {first-column}{column}
+ \@@_set_structure_to_err:n {last-column}
}
{
% \end{macrocode}
@@ -2139,11 +2139,11 @@
% (because is was set to \texttt{column} last time which is now the
% \texttt{previous-column}), thus there is no need to make an update.
% \begin{macrocode}
-% \@@_update_alias_structure:nn {first-column}{previous-column}
+% \@@_copy_structure:nn {first-column}{previous-column}
% \end{macrocode}
% However, we now have a proper \texttt{last-column} so we assign that.
% \begin{macrocode}
- \@@_update_alias_structure:nn {last-column}{column}
+ \@@_copy_structure:nn {last-column}{column}
% \end{macrocode}
% What now remains doing is to update the \texttt{page} and
% \texttt{previous-page} regions. For this we have to copy the
@@ -2243,7 +2243,7 @@
% \subsection{Other \LaTeXe{} output routines}
%
% This section will cover support for packages that alter the
-% \LaTeX{} output rotine (as necessary). The support for
+% \LaTeX{} output routine (as necessary). The support for
% \pkg{multicol} (for now) is handled directly in that package.
%
%
diff --git a/required/tools/multicol.dtx b/required/tools/multicol.dtx
index 55617c257..ca350b493 100644
--- a/required/tools/multicol.dtx
+++ b/required/tools/multicol.dtx
@@ -920,7 +920,7 @@
%
% The following redefinitions have to be moved until after the
% preamble because version 3 of \pkg{doc} resets them after the
-% premable (this is tmp, because \pkg{hypdoc} is not yet
+% preamble (this is tmp, because \pkg{hypdoc} is not yet
% integrated, but as we all know, tmp solutions have a tendency to
% survive for a long time\ldots).
% \begin{macrocode}
@@ -3883,8 +3883,8 @@
\else
% \end{macrocode}
% Increasingly lower penalty based on argument value. This is like
-% \cs{pagebreak} but we use other penalty values are the \LaTeX{}
-% defaults aree rather pointless for pagination.
+% \cs{pagebreak} but we use other penalty values as the \LaTeX{}
+% defaults are rather useless for pagination.
% \begin{macrocode}
\edef\mc at break@pen
{-\ifcase#1\@m\or 3333\or 6666\or 9999\else\@Mv\fi\relax}%
@@ -4132,7 +4132,9 @@
%
% The \verb=\docolaction= scans for a star and optional argument
% and 3 mandatory ones, but we do this in chunks (not having xparse
-% available).
+% available).\footnote{We can do better now, as
+% \cs{NewDocumentCommand} is part of the kernel. So this should be
+% cleaned up one day.}
%
% \changes{v1.8u}{2018/11/09}{Support star with \cs{docolaction}}
% \begin{macrocode}
@@ -4307,11 +4309,12 @@
%
% \subsection{Using the new mark mechanism}
%
+% \subsubsection{Helpers}
%
-% \changes{v2.0a}{2024/11/10}{}
+% \changes{v2.0a}{2024/11/10}{Using the new mark mechanism}
% \begin{macrocode}
\ExplSyntaxOn
-%<@@=mark>
+%<@@=mc>
% \end{macrocode}
%
%
@@ -4328,111 +4331,196 @@
%
%
%
-% \begin{macro}{\__mc_update_col_structures:}
+% \begin{macro}{\@@_debug_marks:n}
+% For now we reuse the internal debugging interface of ltmarks,
+% this will probably change
+% \begin{macrocode}
+\cs_new:Npn \@@_debug_marks:n #1 { \__mark_debug:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_update_mcol_structures:}
+%
+% Helper function to update the \texttt{mcol-...} regions when we
+% finish a page while within a \mc{} environment or when we finish
+% the \mc{} and return the balanced columns back to the galley.
%
% \begin{macrocode}
-\cs_new_protected:Npn \__mc_update_col_structures: {
- \@@_debug:n
- {
- \typeout{Marks:~ update~ mcol~ structures~ (multicol)}
- }
- \int_step_inline:nnn {3} { \g_mc_curr_col_int }
- { \@@_update_structure_to_err:n { mcol - ##1 } }
- \int_gset:Nn \g_mc_curr_col_int {1}
+\cs_new_protected:Npn \@@_update_mcol_structures: {
+ \@@_debug_marks:n
+ { \typeout{Marks:~ update~ mcol~ structures~ (multicol)} }
% \end{macrocode}
+% It might be possible that there was a previous \mc{} (either
+% before the current one, or a boxed one inside) and that one might
+% had more columns than the current one. If so we should make these
+% column structures am error as they are no longer valid (or at
+% least empty them, not sure what is better).
+% \begin{macrocode}
+ \int_step_inline:nnn {\col at number + 1} { \g_mc_curr_col_int }
+ { \__mark_set_structure_to_err:n { mcol - ##1 } }
+% \end{macrocode}
+%
+% There is no need to do anything to \texttt{mcol-1} up to
+% \texttt{mcol-\meta{\cs{col at number}}} because those regions get
+% new data in a second.
%
+% Once we have done this we reset the column counter for further
+% processing.
+% \begin{macrocode}
+ \int_gset:Nn \g_mc_curr_col_int {1}
+% \end{macrocode}
+% Now we loop through all the assembled column material, using the
+% \texttt{column} and \texttt{previous-column} regions as an
+% intermediate holding area.
% \begin{macrocode}
\process at cols\mult at firstbox
{
- \@@_update_structure_from_material:nn
+ \__mark_update_structure_from_material:nn
%fmi {mcol}
{column}
{\unvcopy\count@}
- \@@_update_alias_structure:nn
- {mcol - \int_use:N\g_mc_curr_col_int}
+% \end{macrocode}
+% Once the \texttt{column} region got updated we copy it to
+% \texttt{mcol-\meta{\cs{\detokenize{g_mc_curr_col_int}}}} and then increment
+% the counter.
+% \begin{macrocode}
+ \__mark_copy_structure:nn
+ {mcol - \int_use:N\g_mc_curr_col_int }
%fmi {mcol}
{column}
\int_gincr:N \g_mc_curr_col_int
}
- \@@_update_structure_from_material:nn
+% \end{macrocode}
+% The above loop takes care of all columns, except for the last one
+% (which is stored in \cs{mult at rightbox}. So we have to do that separately.
+% \begin{macrocode}
+ \__mark_update_structure_from_material:nn
%fmi {mcol}
{column}
{\unvcopy\mult at rightbox}
- \@@_update_alias_structure:nn
+ \__mark_copy_structure:nn
{ mcol - \int_use:N\g_mc_curr_col_int }
%fmi {mcol}
{column}
- \@@_update_alias_structure:nn{first-column}{mcol-1}
-%fmi \@@_update_alias_structure:nn{last-column} {mcol}
- \@@_update_alias_structure:nn{last-column} {column}
+% \end{macrocode}
+% Two more aliases to take care of: \texttt{first-column} and
+% \texttt{last-column} and we are done:
+% \begin{macrocode}
+ \__mark_copy_structure:nn{first-column}{mcol-1}
+%fmi \__mark_copy_structure:nn{last-column} {mcol}
+ \__mark_copy_structure:nn{last-column} {column}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\__mc_update_page_structures:}
-%
+% \begin{macro}{\@@_update_page_structures:}
+% If we are making a page while inside a \mc{} environment, we also
+% have to take care of the page region.
% \begin{macrocode}
-\cs_new_protected:Npn \__mc_update_page_structures: {
- \@@_debug:n
+\cs_new_protected:Npn \@@_update_page_structures: {
+ \@@_debug_marks:n
{
\typeout{Marks:~ update~ page~ structure~ (multicol)}
}
- \@@_update_structure_from_material:nn
+% \end{macrocode}
+% Since for the \texttt{page} region we are only interested in the
+% top, first, and last marks on the whole page regardless in which
+% column they appear, we simply string together all columns in a big
+% box and update the structure from that.
+% \begin{macrocode}
+ \__mark_update_structure_from_material:nn
{page}
{
+% \end{macrocode}
+% And we better not forget the \cs{partial at page} in case this is
+% the first page of the \mc{} (on later pages this box will be void).
+% \begin{macrocode}
\unvcopy\partial at page
\process at cols \mult at firstbox { \unvcopy\count@ }
\unvcopy\mult at rightbox
}
-% \end{macrocode}
-%
-% \begin{macrocode}
-% \@@_update_alias_structure:nn {column}{page}
-% \@@_update_alias_structure:nn {first-column}{page}
-% \@@_update_alias_structure:nn {last-column}{page}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\__mc_prepare_mark_reinserts:}
-%
-% \begin{macrocode}
-\tl_new:N \l__mc_first_marks_tl
-\tl_new:N \l__mc_last_marks_tl
-
-\cs_new_protected:Npn \__mc_prepare_mark_reinserts: {
- \@@_debug:n
- {
- \typeout{Marks:~ prepare~ for~ reinserting~ marks~ (multicol)}
- }
- \@@_get_marks_for_reinsertion:nNN
+% \begin{macro}{\@@_prepare_mark_reinserts:}
+%
+% When finishing a \mc{} environment, we have to return marks (in
+% then boxed columns) to the current page so that they are
+% available when that page is produced.
+% This is what this helper does.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_prepare_mark_reinserts: {
+ \@@_debug_marks:n
+ { \typeout{Marks:~ prepare~ for~ reinserting~ marks~ (multicol)} }
+% \end{macrocode}
+% We are only interested in the top, first, and last marks of each
+% class regardless in which column they appeared, so we can copy
+% all column boxes together and process them in one go. The result
+% is returned in \cs{l_@@_first_marks_tl} and
+% \cs{l_@@_last_marks_tl} in form of \cs{mark_insert:nn} statements
+% so we can later execute such token lists directly (and if there
+% were no marks they will be empty).
+% \begin{macrocode}
+ \__mark_get_marks_for_reinsertion:nNN
{
\process at cols \mult at firstbox { \unvcopy\count@ }
\unvcopy\mult at rightbox
}
- \l__mc_first_marks_tl
- \l__mc_last_marks_tl
+ \l_@@_first_marks_tl
+ \l_@@_last_marks_tl
+}
+% \end{macrocode}
+% And here are the token lists used above.
+% \begin{macrocode}
+\tl_new:N \l_@@_first_marks_tl
+\tl_new:N \l_@@_last_marks_tl
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{mc at reinsert@marks}
+% So reinserting it just means executing the token lists (with some
+% surrounding debugging statements).
+% \begin{macrocode}
+\def\mc at reinsert@marks{
+ \@@_debug_marks:n
+ { \typeout{Marks:~ --~ reinsert~ marks~ (multicol)} }
+ \l_@@_first_marks_tl \l_@@_last_marks_tl
+ \@@_debug_marks:n
+ { \typeout{Marks:~ --~ finished~ reinserting~ marks~ (multicol)} }
}
% \end{macrocode}
% \end{macro}
%
%
+% \subsubsection{Interfaces used in the \mc{} code and its output routines}
%
-% \begin{macro}{\mc at prepare@mark at regions}
%
+% \begin{macro}{\mc at prepare@mark at regions}
+% When a \mc{} environment starts we need to clear the column
+% region as it it may contain quite old data. Otherwise, that data
+% would be used to generate the top marks and that would be
+% obviously wrong for the first column.
% \begin{macrocode}
\def \mc at prepare@mark at regions {
- \@@_debug:n
- {
- \typeout{Marks:~ empty~ mcol~ regions~ (multicol)}
- }
+% \end{macrocode}
+% However, before we do this we need to save away the current
+% column data in case this is a boxed multicol, because when that
+% finishes we need to restore the previous state --- this is not
+% necessary for a normal \mc{} environment, because there the
+% \texttt{column} region is overwritten in the standard output
+% routine by copying the \texttt{page} region.
+% \begin{macrocode}
\if at boxedmulticols
- \@@_update_alias_structure:nn{saved-column}{column}
+ \__mark_copy_structure:nn{saved-column}{column}
\fi
- \@@_clear_structure:n {column}
+ \@@_debug_marks:n
+ { \typeout{Marks:~ empty~ mcol~ regions~ (multicol)} }
+ \__mark_clear_structure:n {column}
}
% \end{macrocode}
% \end{macro}
@@ -4441,56 +4529,59 @@
%
% \begin{macro}{\mc at handle@marks at and@reinserts}
%
+% If a \mc{} ends the columns are balanced and then returned to the
+% galley. in that situation we do have to prepare the
+% \texttt{mcol-...} regions and also do this reinsertion.
% \begin{macrocode}
\def \mc at handle@marks at and@reinserts #1 {
- \__mc_update_col_structures:
- \@@_debug:n { \@@_status:nn {#1} {\the\col at number} }
- %
- \__mc_prepare_mark_reinserts:
+ \@@_update_mcol_structures:
+% \end{macrocode}
+% Show the current region status when debugging:
+% \begin{macrocode}
+ \@@_debug_marks:n { \__mark_status:nn {#1} {\the\col at number} }
+% \end{macrocode}
+% Then prepare for reinserting the marks:
+% \begin{macrocode}
+ \@@_prepare_mark_reinserts:
+% \end{macrocode}
+% Finally, we restore the \texttt{column} region in case this was a
+% boxed \mc{} environment.
+% \begin{macrocode}
\if at boxedmulticols
- \@@_update_alias_structure:nn {column}{saved-column}
+ \__mark_copy_structure:nn {column}{saved-column}
\fi
}
-\def\mc at reinsert@marks{
- \@@_debug:n
- {
- \typeout{Marks:~ --~ reinsert~ marks~ (multicol)}
- }
- \l__mc_first_marks_tl \l__mc_last_marks_tl
- \@@_debug:n
- {
- \typeout{Marks:~ --~ finished~ reinserting~ marks~ (multicol)}
- }
-}
% \end{macrocode}
% \end{macro}
%
%
%
% \begin{macro}{\mc at handle@col at andpage@marks}
-%
+% If a page is generated while we are processing a \mc{} then we
+% have to update the \texttt{mcol-...} regions but also the
+% \texttt{page} region.
% \begin{macrocode}
\def \mc at handle@col at andpage@marks #1 {
- \__mc_update_col_structures:
- \__mc_update_page_structures:
- \@@_debug:n { \@@_status:nn {#1} {\the\col at number} }
-}
+ \@@_update_mcol_structures:
+ \@@_update_page_structures:
% \end{macrocode}
-% \end{macro}
-%
-%
-%
-%
+% Once done we display the current status of the marks.
% \begin{macrocode}
-%<@@=>
+ \@@_debug_marks:n { \__mark_status:nn {#1} {\the\col at number} }
+}
% \end{macrocode}
+% \end{macro}
%
%
%
% \begin{macro}{\leftmark,\rightmark}
+% We change the legacy \cs{leftmark} and \cs{rightmark} to the use
+% the new mark mechanism. For now we do this only if pkg{multicol}
+% is loaded, but eventually this will move to the kernel which then
+% also simplifies the definitions for \cs{markboth} and friends.
%
-% \changes{v2.0a}{2024/11/10}{}
+% \changes{v2.0a}{2024/11/10}{Use the new mark mechanism}
% \begin{macrocode}
\def\leftmark{\mark_use_last:nn{page}{2e-left}}
\def\rightmark{\mark_use_first:nn{page}{2e-right}}
@@ -4498,6 +4589,10 @@
% \end{macro}
%
% \begin{macrocode}
+%<@@=>
+% \end{macrocode}
+%
+% \begin{macrocode}
\ExplSyntaxOff
% \end{macrocode}
%
More information about the latex3-commits
mailing list.