[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.