[latex3-commits] [latex3/latex2e] ltmarks-enhance: a bit more docu cleanup (0d35a5f5)
github at latex-project.org
github at latex-project.org
Thu Nov 16 00:02:27 CET 2023
Repository : https://github.com/latex3/latex2e
On branch : ltmarks-enhance
Link : https://github.com/latex3/latex2e/commit/0d35a5f5cb11b9c8305537cf9db779f271be299d
>---------------------------------------------------------------
commit 0d35a5f5cb11b9c8305537cf9db779f271be299d
Author: Frank Mittelbach <frank.mittelbach at latex-project.org>
Date: Thu Nov 16 00:02:27 2023 +0100
a bit more docu cleanup
>---------------------------------------------------------------
0d35a5f5cb11b9c8305537cf9db779f271be299d
base/doc/ltnews39.tex | 6 +
base/ltmarks.dtx | 211 +++++++++++++++++++---------------
base/testfiles-ltmarks/xmarks-009.lvt | 43 +++++++
base/testfiles-ltmarks/xmarks-009.tlg | 43 +++++++
4 files changed, 208 insertions(+), 95 deletions(-)
diff --git a/base/doc/ltnews39.tex b/base/doc/ltnews39.tex
index c64d4421..a49691e3 100644
--- a/base/doc/ltnews39.tex
+++ b/base/doc/ltnews39.tex
@@ -144,6 +144,8 @@
\section{Introduction}
+\emph{to write}
+
\section{Enhancements to the new mark mechanism}
@@ -200,6 +202,10 @@ wasn't possible at all before. This is, for example, necessary to
support extended marks in \env{multicols} environments or extract them
from floats, marginpars, etc.
+Details about the implementation can be found in \texttt{texdoc
+ ltmarks-code} or in the shorter \texttt{texdoc ltmarks-doc} (which
+only describes the general concepts and the command interfaces).
+
\section{New or improved commands}
diff --git a/base/ltmarks.dtx b/base/ltmarks.dtx
index d41104de..25172af7 100644
--- a/base/ltmarks.dtx
+++ b/base/ltmarks.dtx
@@ -16,7 +16,7 @@
%
% \begin{macrocode}
\def\ltmarksversion{v1.0e}
-\def\ltmarksdate{2023/11/15}
+\def\ltmarksdate{2023/11/16}
% \end{macrocode}
%<*driver>
\documentclass{l3doc}
@@ -299,6 +299,8 @@
% \emph{true}; if a declared and an undeclared mark class is used
% it is always \emph{false}.}
%
+% \subsection{Use cases for conditionals}
+%
% However, the basic version is enough for the following typical use cases:
% \begin{description}
% \item[Test for at most one mark of class \texttt{myclass} on current
@@ -661,25 +663,32 @@
% \end{function}
%
%
-% \begin{function}{@@_get_marks_for_reinsertion:nNN}
+% \begin{function}{\@@_get_marks_for_reinsertion:nNN}
% \begin{syntax}
% \cs{@@_get_marks_for_reinsertion:nNN} \Arg{source}
-% \Arg{token-list-var for collecting first marks}
-% \Arg{token-list-var for collecting last marks}
+% \qquad \meta{token-list-var for collecting first marks}
+% \qquad \meta{token-list-var for collecting last marks}
% \end{syntax}
% Helper function for extracting marks that would otherwise get
% lost, for example when they are hidden inside a box. This helper
% does not update mark structures and can therefore be used outside
% the output routine as well.
%
-% It collect all the marks from inside the \meta{source} and adds suitable
-% \cs{mark_insert:nn} in the two token lists. These token lists can
-% then be executed at the right place to reinsert the marks, e.g.,
-% directly after the box. This is, for example, used by
-% \pkg{multicol} when a short balanced \env{multicols} is returned
-% to the galley for typesetting.
-%
-% It is quite likely that one only needs a single token list for
+% It collect all the top-level marks from inside the \meta{source}
+% and adds suitable \cs{mark_insert:nn} in the two token
+% lists. These token lists can then be executed at the right place
+% to reinsert the marks, e.g., directly after the box. This is, for
+% example, used by \pkg{multicol} when a short balanced
+% \env{multicols} is returned to the galley for typesetting.
+%
+% If the \meta{source} consists of a single vertical box (plus
+% possibly followed by some glue but nothing else) then the box is
+% unpacked and the top-level marks are collected from its
+% content. However, if it is not a vertical box or there are are
+% other data then nothing is unpacked and you have to do the
+% unpacking yourself to get at the marks inside.
+%
+% It is quite likely that one only needs a single token list for
% returning the \cs{mark_insert:nn} statements. If that is the case
% this command may change to take only two arguments.
% \end{function}
@@ -726,12 +735,13 @@
%
%
% \begin{macro}{\mark_new_class:n,\@@_new_class:nn}
+%
% A mark class is created by initializing a number of data
-% structures. First, we get a register number to refer to the mark class.
-% The new mark class is then added to the \cs{g_@@_classes_seq}
-% sequence to be able to easily loop over all classes. Finally a
-% number of top-level global token lists are declared that hold
-% various versions of the mark for access.
+% structures. First, we get a register number to refer to the mark
+% class. The new mark class is then added to the
+% \cs{g_@@_classes_seq} sequence to be able to easily loop over all
+% classes. Finally a number of top-level global token lists are
+% declared that hold various versions of the mark for access.
% \begin{macrocode}
\cs_new_protected:Npn \mark_new_class:n #1
{
@@ -833,20 +843,22 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_extract_and_handle_marks:nn #1#2 {
% \end{macrocode}
-% This macro expects a region name as its third argument and
-% vertical material (not boxed) as its fourth. It attempts to
-% extract mark information from \verb/#3/ and, if it succeeds, it then
-% executes \verb/#1/ to do something with the marks, e.g., to
-% update the mark structure for the region.
-%
-% If it finds infinite negative glue it generates an error message
-% and then calls \verb/#2/ to handle anything special in that
-% case.
+% This macro expects code to handle extracted marks in its first argument and
+% vertical material (not boxed or just consisting of a single
+% vertical box) as its second. It
+% extracts top-level mark information from \verb/#2/, stores them
+% as split marks and then calls
+% \verb/#1/ to make use of this information.
%
% If it finds a forced break in the material it removes it and then
% restarts the attempt without it.
%
-% Getting the first and last marks out of the material in \verb=#4=
+% We start with a group to keep most changes local.
+% \begin{macrocode}
+ \group_begin:
+% \end{macrocode}
+%
+% Getting the first and last marks out of the material in \verb=#2=
% is done by putting the material in a box and then doing a split
% operation to the maximum size possible (which hopefully gets us
% all of the content).\footnote{With normal column material cut
@@ -857,21 +869,22 @@
% handle.} Because this action is used only to get the mark
% values, we don't want any underfull box warnings so we (locally)
% turn those off.
+%
% \begin{macrocode}
- \group_begin:
\dim_set_eq:NN \tex_splitmaxdepth:D \c_max_dim
\int_set_eq:NN \tex_vbadness:D \c_max_int
\dim_set_eq:NN \tex_vfuzz:D \c_max_dim
% \end{macrocode}
-% There is a further complication: if the region contains infinite
+%
+% There is a further complication: if the material contains infinite
% shrinking glue then a \tn{vsplit} operation will balk with a
-% low-level error. Now pages or columns, which are our main concern here, can't
-% have such infinite shrinkage if they are cut straight from the
-% galley, however the use of \tn{enlargethispage} actually does add
-% some at the very bottom (and also wraps the whole page into a box
-% by itself, so if we leave it this way then a) we get this error
-% and b) we don't see any marks because they are hidden one level
-% down).
+% low-level error. Now pages or columns, which are our main concern
+% here, can't have such infinite shrinkage if they are cut straight
+% from the galley, however the use of \tn{enlargethispage} actually
+% does add some at the very bottom (and also wraps the whole page
+% into a box by itself, so if we leave it this way then a) we get
+% this error and b) we don't see any marks because they are hidden
+% one level down).
%
% Another possible issue are packages or user code that place stray
% \tn{vbox}es directly into the main galley (an example is
@@ -895,50 +908,51 @@
% \end{macro}
%
%
-% \begin{macro}{@@_prepare_and_extract:nn}
+% \begin{macro}{\@@_prepare_and_extract:nn}
%
+% This macro does the dirty work. It is not directly integrated in
+% \cs{@@_extract_and_handle_marks:nn} because we may have to call
+% it recursively if we find forced breaks.
% \begin{macrocode}
\cs_new_protected:Npn \@@_prepare_and_extract:nn #1#2 {
% \end{macrocode}
%
% To handle the \cs{enlargethispage} case we do an \tn{unskip} to
-% get rid of any glue that is present at the end of the material
+% get rid of any glue that is present at the very end of the material
% and also check if we have then a \tn{vbox} as the last item and
% if so unpack that too, but only under certain conditions, see
% below. All this is temporary done in a group, just for getting
% the marks out, so it doesn't affect the final page production.
%
% \begin{macrocode}
- \vbox_set:Nn \l_@@_box
- {
- #2
- \tex_unskip:D
- \box_set_to_last:N \l_@@_box
+ \vbox_set:Nn \l_@@_box
+ {
+ #2
+ \tex_unskip:D
+ \box_set_to_last:N \l_@@_box
% \end{macrocode}
% After having removed the last box from the current list (if there
-% was one) we check whether the vertical list is now empty. If not, then the last
-% box is definitely not the one from \tn{enlargethispage} and so we
-% can, and should, leave it alone. Otherwise we check if this last
-% box is a \tn{vbox}.
+% was one) we check whether the vertical list is now empty. If not,
+% then the last box is definitely not the one from
+% \tn{enlargethispage} and so we can, and should, leave it
+% alone. Otherwise we check if this last box is a \tn{vbox}.
% \changes{v1.0d}{2022/06/01}{Extend the logic for detecting the marks
% in the box (gh/836)}
% \begin{macrocode}
- \int_compare:nNnT \tex_lastnodetype:D < 0
- {
- \box_if_vertical:NT \l_@@_box
- {
+ \int_compare:nNnT \tex_lastnodetype:D < 0
+ {
+ \box_if_vertical:NT \l_@@_box
% \end{macrocode}
% If it is, we unpack the box.
% \begin{macrocode}
- \vbox_unpack:N \l_@@_box
- }
- }
+ { \vbox_unpack:N \l_@@_box }
+ }
% \end{macrocode}
% If it wasn't a vbox, it was either an hbox or there was no box.
% Given that we are only interested in the marks we don't need put
% it back in that case.
% \begin{macrocode}
- }
+ }
% \end{macrocode}
% We are now ready to \cs{vsplit} the box to get at the marks. If
% the box contains some infinite negative glue the \TeX{} will
@@ -949,29 +963,29 @@
% as best as possible---see the definition of
% \cs{@@_vbox_set_split_to_maxdimen:NN} for the tricks employed.
% \begin{macrocode}
- \@@_vbox_set_split_to_maxdimen:NN \l_@@_ii_box \l_@@_box
+ \@@_vbox_set_split_to_maxdimen:NN \l_@@_ii_box \l_@@_box
% \end{macrocode}
% After splitting we check if there is anything left in
% \cs{l_@@_box}. If not then the above split has set some split marks
% that we can then use to finish the extraction:
% \begin{macrocode}
- \box_if_empty:NTF \l_@@_box
- { #1 }
+ \box_if_empty:NTF \l_@@_box
+ { #1 }
% \end{macrocode}
% If we have a remainder after the split then this means that there
% was some forced break in the material. We get rid of that by
% combining the content of the two boxes and restart.
% \begin{macrocode}
- {
+ {
%<*trace>
- \@@_debug:n { \iow_term:x
- { Marks:~ mark~ extraction~needs~ recursion~
- \msg_line_context: } }
+ \@@_debug:n { \iow_term:x
+ { Marks:~ mark~ extraction~needs~ recursion~
+ \msg_line_context: } }
%</trace>
- \@@_prepare_and_extract:nn {#1}
- { \vbox_unpack:N \l_@@_ii_box
- \vbox_unpack:N \l_@@_box }
- }
+ \@@_prepare_and_extract:nn {#1}
+ { \vbox_unpack:N \l_@@_ii_box
+ \vbox_unpack:N \l_@@_box }
+ }
}
% \end{macrocode}
% \end{macro}
@@ -1004,7 +1018,7 @@
%
% The whole definition of \cs{@@_vbox_set_split_to_maxdimen:NN}
% below is fully expanded, so we have to use a lot of
-% \cs{exp_not:N}s to prevent expansion where necessary.
+% \cs{exp_not:N} commands to prevent expansion where necessary.
% \begin{macrocode}
\cs_new_protected:Npx \@@_vbox_set_split_to_maxdimen:NN #1#2 {
% \end{macrocode}
@@ -1042,8 +1056,6 @@
% (try it).
% \begin{macrocode}
\exp_not:N \use:n {
-% \use:c{~Ignore~infinite~glue~shrinkage~error}
-% \use:c{Glue~shrinkage~error~is~harmless~!}
\use:c{Infinite~shrink~error~above~ignored~!}
}
% \end{macrocode}
@@ -1092,14 +1104,13 @@
%
%
% \begin{macro}{\@@_update_structure_from_splitmarks:n}
-% This macro is called when it is possible to \cs{vsplit} the
-% material to extract the marks (or at least if we think it is
-% possible, see notes).
+% This macro is called after we have done a \cs{tex_vsplit:D}
+% operation and the mark data is in the split marks.
% \begin{macrocode}
\cs_new_protected:Npn \@@_update_structure_from_splitmarks:n #1 {
% \end{macrocode}
%
-% The first thing we do is to copy the current structure to
+% The first thing we do is to copy the current region structure to
% \texttt{previous-...}; this leaves the current structure
% untouched so we can update it class by class (which is necessary).
% \begin{macrocode}
@@ -1139,7 +1150,7 @@
% not be confused with no mark at all. But no mark in our material
% will result in \cs{g_@@_tmp_tl} being fully empty. This is why we
% have to make sure that \enquote{empty} from \cs{mark_insert:nn} only
-% appears to be empty but fails the next test (see below how this
+% appears to be empty when typeset but fails the next test (see below how this
% is done).
% \begin{macrocode}
\tl_if_empty:NTF \g_@@_tmp_tl
@@ -1184,7 +1195,7 @@
% executing the token lists.\footnote{It is probably enough to
% collect everything in a single token list as long as we put the
% first marks first and the last marks last). But for extra
-% flexibility, I currently use 2 tls. This might change when it is
+% flexibility, I currently use 2 token lists. This might change when it is
% really clear that this is never needed.}
%
% \begin{macrocode}
@@ -1195,23 +1206,24 @@
\tl_clear:N \g_@@_first_marks_tl
\tl_clear:N \g_@@_last_marks_tl
% \end{macrocode}
-% The we try to extract all marks, thereby filling the token lists
+% Then we extract all top-level marks, thereby filling the token lists
% with suitable \cs{mark_insert:nn} calls.
% \begin{macrocode}
\@@_extract_and_handle_marks:nn
% \end{macrocode}
-% If we can extract them (i.e., if we don't detect negative infinite
-% glue) then this is done with \cs{@@_get_from_splitmarks:} otherwise
-% we issue a warning that mark extraction was not possible.
+% The first argument holds the code for fill the token lists and
+% the second is the material we extract from.
% \begin{macrocode}
\@@_get_from_splitmarks:
{ #1 }
% \end{macrocode}
-% Finally we copy the updated (or not updated) temporary token lists to
-% the two that have been supplied when the function was called.
-% By convention they are local variables and
-% \cs{@@_extract_and_handle_marks:nn} runs in a group, which is
-% why we have to use global variables for collecting.
+%
+% Finally, we copy the updated (or not updated) temporary token
+% lists to the two that have been supplied when the function was
+% called. By convention \enquote{get} operations return their
+% values in local variables and \cs{@@_extract_and_handle_marks:nn}
+% runs in a group, which is why we have to use global temporary
+% variables for collecting.
% \begin{macrocode}
\tl_set_eq:NN #2 \g_@@_first_marks_tl
\tl_set_eq:NN #3 \g_@@_last_marks_tl
@@ -1503,7 +1515,7 @@
%
% \subsection{Messages}
%
-% Mark errors are LaTeX kernel errors:
+% Mark errors are \LaTeX{} kernel errors:
% \changes{v1.0d}{2022/06/01}{Marks are kernel errors}
% \begin{macrocode}
\prop_gput:Nnn \g_msg_module_type_prop { mark } { LaTeX }
@@ -1667,10 +1679,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \ShowMarksAt #1 {
%<*trace>
- \@@_debug:n
- {
- \@@_status:n{#1}
- }
+ \@@_debug:n { \@@_status:n {#1} }
%</trace>
}
% \end{macrocode}
@@ -1730,9 +1739,9 @@
%
%
%
-% \section{\LaTeXe{} integration}
+% \section{\LaTeXe{} integration}
%
-% \subsection{Core \LaTeXe{} integration}
+% \subsection{Core \LaTeXe{} integration}
%
% \begin{macro}{\@@_update_singlecol_structures:}
% This command updates the mark structures if we are producing a
@@ -1888,17 +1897,26 @@
%<@@=>
% \end{macrocode}
%
-% \begin{macro}[int]{\@expl@@@mark at update@singlecol at structures@@,
-% \@expl@@@mark at update@dblcol at structures@@}
+% \begin{macro}[int]{\@expl@@@mark at update@singlecol at structures@@}
% \begin{macrocode}
\cs_new_eq:NN \@expl@@@mark at update@singlecol at structures@@
\__mark_update_singlecol_structures:
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}[int]{\@expl@@@mark at update@dblcol at structures@@}
+% \begin{macrocode}
\cs_new_eq:NN \@expl@@@mark at update@dblcol at structures@@
\__mark_update_dblcol_structures:
% \end{macrocode}
% \end{macro}
%
-% \subsection{Other \LaTeXe{} output routines}
+%
+%
+%
+% \subsection{Other \LaTeXe{} output routines}
%
% This section will cover \pkg{multicol} and other packages altering
% or providing their own output routine. Not done yet.
@@ -1906,6 +1924,9 @@
%
%
%
+% \subsection{Rollback information}
+%
+%
% \begin{macrocode}
%<latexrelease>\IncludeInRelease{0000/00/00}{ltmarks}%
%<latexrelease> {Undo~Marks~handling}
@@ -1914,7 +1935,7 @@
% We keep the interface commands around even if we roll back in
% case they are used in packages that don't roll back. Not likely
% to do a lot of good, but then there is not much we can do, but
-% this at least then doesn't give errors.
+% this at least they won't give unknown csname errors.
% \begin{macrocode}
%<latexrelease>\DeclareRobustCommand \NewMarkClass[1]{}
%<latexrelease>\DeclareRobustCommand \InsertMark[2]{}
diff --git a/base/testfiles-ltmarks/xmarks-009.lvt b/base/testfiles-ltmarks/xmarks-009.lvt
index 717e7ffd..c41524be 100644
--- a/base/testfiles-ltmarks/xmarks-009.lvt
+++ b/base/testfiles-ltmarks/xmarks-009.lvt
@@ -91,6 +91,49 @@
\l_last_marks_tl
+\tl_show:N \l_first_marks_tl
+\tl_show:N \l_last_marks_tl
+
+
+\typeout{------------~ vbox~ test~ ----------------}
+% test what happens if you pass a vbox as source without unboxing it:
+
+\box_new:N \l_test_box
+
+\vbox_set:Nn \l_test_box
+ {
+ text\markboth{A1}{A2} \par
+ \break
+ text\markboth{B1}{B2} \par
+ \break
+ text\markright{A3} \par
+ }
+
+\__mark_get_marks_for_reinsertion:nNN
+ { \box_use_drop:N \l_test_box }
+ \l_first_marks_tl
+ \l_last_marks_tl
+
+
+\tl_show:N \l_first_marks_tl
+\tl_show:N \l_last_marks_tl
+
+
+\typeout{------------~ hbox~ test~ ----------------}
+% test what happens if you pass a hbox as source without unboxing it:
+
+\hbox_set:Nn \l_test_box
+ {
+ text\markboth{A1}{A2}
+ text\markright{A3}
+ }
+
+\__mark_get_marks_for_reinsertion:nNN
+ { \box_use_drop:N \l_test_box }
+ \l_first_marks_tl
+ \l_last_marks_tl
+
+
\tl_show:N \l_first_marks_tl
\tl_show:N \l_last_marks_tl
diff --git a/base/testfiles-ltmarks/xmarks-009.tlg b/base/testfiles-ltmarks/xmarks-009.tlg
index f9733a89..fe8acfe9 100644
--- a/base/testfiles-ltmarks/xmarks-009.tlg
+++ b/base/testfiles-ltmarks/xmarks-009.tlg
@@ -210,3 +210,46 @@ l. ...\tl_show:N \l_first_marks_tl
{2e-right}{A3}\mark_insert:nn {2e-right-nonempty}{A3}.
<recently read> }
l. ...\tl_show:N \l_last_marks_tl
+------------ vbox test ----------------
+\l_test_box=\box...
+Marks: set 2e-left <- 'A1' on line ...
+Marks: set 2e-right <- 'A2' on line ...
+Marks: set 2e-right-nonempty <- 'A2' on line ...
+Marks: set 2e-left <- 'B1' on line ...
+Marks: set 2e-right <- 'B2' on line ...
+Marks: set 2e-right-nonempty <- 'B2' on line ...
+Marks: set 2e-right <- 'A3' on line ...
+Marks: set 2e-right-nonempty <- 'A3' on line ...
+Marks: mark extraction needs recursion on line ...
+Marks: mark extraction needs recursion on line ...
+Marks: extract last mark for class '2e-left' = B1
+Marks: extract first mark for class '2e-left' = A1
+Marks: extract last mark for class '2e-right' = A3
+Marks: extract first mark for class '2e-right' = A2
+Marks: extract last mark for class '2e-right-nonempty' = A3
+Marks: extract first mark for class '2e-right-nonempty' = A2
+Marks: no marks for class 'unused' on line ...
+> \l_first_marks_tl=\mark_insert:nn {2e-left}{A1}\mark_insert:nn
+{2e-right}{A2}\mark_insert:nn {2e-right-nonempty}{A2}.
+<recently read> }
+l. ...\tl_show:N \l_first_marks_tl
+> \l_last_marks_tl=\mark_insert:nn {2e-left}{B1}\mark_insert:nn
+{2e-right}{A3}\mark_insert:nn {2e-right-nonempty}{A3}.
+<recently read> }
+l. ...\tl_show:N \l_last_marks_tl
+------------ hbox test ----------------
+Marks: set 2e-left <- 'A1' on line ...
+Marks: set 2e-right <- 'A2' on line ...
+Marks: set 2e-right-nonempty <- 'A2' on line ...
+Marks: set 2e-right <- 'A3' on line ...
+Marks: set 2e-right-nonempty <- 'A3' on line ...
+Marks: no marks for class '2e-left' on line ...
+Marks: no marks for class '2e-right' on line ...
+Marks: no marks for class '2e-right-nonempty' on line ...
+Marks: no marks for class 'unused' on line ...
+> \l_first_marks_tl=.
+<recently read> }
+l. ...\tl_show:N \l_first_marks_tl
+> \l_last_marks_tl=.
+<recently read> }
+l. ...\tl_show:N \l_last_marks_tl
More information about the latex3-commits
mailing list.