[latex3-commits] [git/LaTeX3-latex3-latex3] xmarks: some code cleanup and additional documentation (5679e46)

Frank Mittelbach frank.mittelbach at latex-project.org
Wed Nov 21 16:30:16 CET 2018


Repository : https://github.com/latex3/latex3
On branch  : xmarks
Link       : https://github.com/latex3/latex3/commit/5679e46b7daa6a1da8f298023139ec1b037a50e9

>---------------------------------------------------------------

commit 5679e46b7daa6a1da8f298023139ec1b037a50e9
Author: Frank Mittelbach <frank.mittelbach at latex-project.org>
Date:   Wed Nov 21 16:30:16 2018 +0100

    some code cleanup and additional documentation


>---------------------------------------------------------------

5679e46b7daa6a1da8f298023139ec1b037a50e9
 l3trial/xmarks/testfiles/xmarks-005.lvt |    3 +-
 l3trial/xmarks/testfiles/xmarks-005.tlg |   38 ----
 l3trial/xmarks/xmarks2.dtx              |  298 +++++++++++++++++++++++--------
 3 files changed, 223 insertions(+), 116 deletions(-)

diff --git a/l3trial/xmarks/testfiles/xmarks-005.lvt b/l3trial/xmarks/testfiles/xmarks-005.lvt
index ba4d2e3..c0f9c84 100644
--- a/l3trial/xmarks/testfiles/xmarks-005.lvt
+++ b/l3trial/xmarks/testfiles/xmarks-005.lvt
@@ -12,8 +12,6 @@
 
 \tracingmarks=2
 
-\START
-
 
 
 %\showoutput
@@ -21,6 +19,7 @@
 \begin{document}
 
 \section*{A test}
+\subsection*{A subtest}
 Get some fonts loaded without generating log entries (for uptex and friends)
 And for the running header: {\slshape \MakeUppercase{\thesection slanted}}.
 
diff --git a/l3trial/xmarks/testfiles/xmarks-005.tlg b/l3trial/xmarks/testfiles/xmarks-005.tlg
index 31d6b60..82ff206 100644
--- a/l3trial/xmarks/testfiles/xmarks-005.tlg
+++ b/l3trial/xmarks/testfiles/xmarks-005.tlg
@@ -1,43 +1,5 @@
 This is a generated file for the LaTeX (2e + expl3) validation system.
 Don't change this file in any respect.
-(xmarks-005.aux)
-LaTeX Font Info:    Checking defaults for OML/cmm/m/it on input line ....
-LaTeX Font Info:    ... okay on input line ....
-LaTeX Font Info:    Checking defaults for T1/cmr/m/n on input line ....
-LaTeX Font Info:    ... okay on input line ....
-LaTeX Font Info:    Checking defaults for OT1/cmr/m/n on input line ....
-LaTeX Font Info:    ... okay on input line ....
-LaTeX Font Info:    Checking defaults for OMS/cmsy/m/n on input line ....
-LaTeX Font Info:    ... okay on input line ....
-LaTeX Font Info:    Checking defaults for OMX/cmex/m/n on input line ....
-LaTeX Font Info:    ... okay on input line ....
-LaTeX Font Info:    Checking defaults for U/cmr/m/n on input line ....
-LaTeX Font Info:    ... okay on input line ....
-OR: (twoside-odd) ltxleft:
-    page (current):||||
-    page (verso):||||
-    page (recto):||||
-    column (current):||||
-    column (first):||||
-    column (second):||||
-OR: (twoside-odd) ltxright:
-    page (current):||||
-    page (verso):||||
-    page (recto):||||
-    column (current):||||
-    column (first):||||
-    column (second):||||
-OR: (twoside-odd) ltxrightnonempty:
-    page (current):||||
-    page (verso):||||
-    page (recto):||||
-    column (current):||||
-    column (first):||||
-    column (second):||||
-[1
-]
-This is a generated file for the LaTeX (2e + expl3) validation system.
-Don't change this file in any respect.
 Marks: set ltxleft <- '\protect \MakeUppercase  {1\hskip 1em\relax A}' on line ...
 Marks: set ltxright <- '' on line ...
 Marks: set ltxright <- '1.1\hskip 1em\relax S-1' on line ...
diff --git a/l3trial/xmarks/xmarks2.dtx b/l3trial/xmarks/xmarks2.dtx
index 1c64b1b..af479b6 100644
--- a/l3trial/xmarks/xmarks2.dtx
+++ b/l3trial/xmarks/xmarks2.dtx
@@ -130,7 +130,7 @@
 %     \cs{marks_put:nn} \Arg{type} \Arg{entry}
 %   \end{syntax}
 %   Adds a mark to the current page for the \meta{type}, containing the
-%   \meta{entry} text.
+%   \meta{entry} text. The \meta{entry} is expanded at the time of use.
 % \end{function}
 %
 %
@@ -144,10 +144,62 @@
 %     \cs{marks_use_last:nn}     \Arg{region} \Arg{type}
 %   \end{syntax}
 %   These functions expand to the appropriate mark \meta{entry} for
-%   the given \meta{type} in the specified region. The \enquote{first} and
+%   the given \meta{type} in the specified \meta{region}. The \enquote{first} and
 %   \enquote{last} marks are those seen first and last in the region,
 %   respectively. The \enquote{previous} mark is the last mark of the
-%   \meta{type} seen on earlier regions.
+%   \meta{type} seen on earlier regions. These functions should be used only in
+%   output routines after \cs{marks_update_structure:nnn} has acted, otherwise their
+%   values will be wrong.
+% \end{function}
+%
+% \subsection{Output routine functions}
+%
+% These functions are tied to the output routine. 
+%
+% \begin{function}{\marks_update_structure:nnn}
+%   \begin{syntax}
+%     \cs{marks_update_structure:nnN} \Arg{last} \Arg{current} \Arg{material with marks}
+%   \end{syntax}
+%   \meta{last} is the region from which to take the last marks to
+%   make them new top marks. \meta{current} is the region to update
+%   and \meta{material} holds material that contain new marks.  Thus if this
+%   material consists of boxes we need to do the unpacking with the
+%   argument so that the marks can be seen.
+% \end{function}
+%
+%
+%
+% \begin{function}{\marks_update_structure_alias:nn}
+%   \begin{syntax}
+%     \cs{marks_update_structure_alias:nn} \Arg{alias} \Arg{source}
+%   \end{syntax}
+%   Assigns all marks for the \meta{source} region also to
+%   \meta{alias}, e.g., if we finished a a \texttt{verso} page we
+%   could make the generic \texttt{page} region hold the same
+%   marks. In most cases this is automatically done already by
+%   \cs{marks_update_structure:nnN} so this is only needed in a few
+%   cases.
+% \end{function}
+%
+%
+% \begin{function}{\marks_update_singlecol_structure:n}
+%   \begin{syntax}
+%     \cs{marks_update_singlecol_structure:n} \Arg{material with marks}
+%   \end{syntax}
+%   \LaTeXe{} integration function receiving the content of box 255 for
+%   mark processing when we are doing single column documents.
+% \end{function}
+%
+%
+% \begin{function}{\marks_update_dblcol_structure:nn}
+%   \begin{syntax}
+%     \cs{marks_update_singlecol_structure:n} \Arg{current column material}
+%                                             \Arg{whole page material}
+%   \end{syntax}
+%   \LaTeXe{} integration function mark processing when we are doing
+%   double column documents. The first argument handles the column marks
+%   and the second the marks for the complete page and is only
+%   relevant if we are doing the second column.
 % \end{function}
 %
 %
@@ -250,6 +302,69 @@
 %
 % \section{\pkg{xmarks2} Implementation}
 %
+% \subsection{Notes on the mechanism}
+%
+% \eTeX{} extends the \TeX{} mark system to allow multiple independent
+% marks. However, it does not solve a problem which means that \LaTeX{} needs
+% to manage marks almost independently of \TeX{}. The reason for this is that
+% the complex output routine used by \LaTeX{} to handle floats (and related
+% structures) means that \tn{topmark(s)} are not reliable. Each time the
+% output routine is fired up, \TeX{} moves \tn{botmark} to \tn{topmark}, and
+% while \eTeX{} extends this the fundamental concept remains the same. That
+% means that instead the state of marks needs to be tracked by
+%   \LaTeX{} itself. An early implementation of this package used
+%   \TeX{}'s \tn{botmark} only to ensure the correct interaction with
+% the output routine (this was before the \eTeX{} mechanism was even
+%   available. However, other than in a prototype implementation for
+%   \LaTeX3 this package was never made public.
+%
+% The new implementation now does use \eTeX{}'s marks as they have
+%   some advantages as with them we can leave the mark text within the
+%   galley and only extract the marks during the output routine when
+%   we are finally shipping out a page or storing away a column for
+%   use in the next page. That means we do not have to maintain a
+%   global data structure that we have to keep in sync with
+%   informational marks in the galley but can rely on everything being
+%   in one place and thus manipulations (e.g. reordering of material)
+%   will take the marks with them without a need for updating a
+%   fragile linkage.
+
+% To allow for completely independent marks we use the following
+% procedure:
+% \begin{itemize}
+%   \item
+%     For every mark of type \meta{type} we allocate a mark class so
+%   that in the output routine \TeX{} can calculate for each type top,
+%   first and bottom mark independently.
+%
+%   \item As already mentioned firing up an output routine without
+%   shipping out a page means that \TeX's top marks get wrong so it is
+%   impossible to rely on \TeX's approach directly. What we do instead
+%   is to keep  track of the real marks (from last page or
+%   more generally last region) in some global variables.
+%
+%   \item These variables are updated in the ouput routine at defined
+%   places, i.e., when we do real output processing but not if we use
+%   special output routines to do internal housekeeping.
+%
+%   \item The trick we use to get correctly updated variables is the
+%   following: the material that contains new marks (for example the
+%   page to be shipped out) is stored in a box. We then use \TeX{}
+%   primitive box splitting functions by splitting off the largest
+%   amount possible (which should be the whole box if nothing goes
+%   really wrong). While that seems a rather pointless thing to do, it
+%   has one important side effect: \TeX{} sets up first and bottom
+%   marks for each mark class from the material it has split off. This
+%   way we get the first and last marks (if there have been any) from
+%   the material in the box.
+%
+%   \item The top marks are simply the last marks from the previous
+%   page or region. And if there hasn't been a first or bottom mark in
+%   the box then the new top mark also becomes new first and last mark
+%   for that class.
+%  \end{itemize}
+%  That's about it in a nutshell. Of course, there are some details to
+%   be taken care off and those are discussed further below.
 %
 %
 %
@@ -351,65 +466,6 @@
 %
 %
 %
-%    \begin{macrocode}
-\cs_new:Npn \@@_update_singlecol_structure:
-   {
-    \if at twoside
-      \ifodd \c at page
-        \marks_update_structure:nnn {page}{recto}\@outputbox
-      \else
-        \marks_update_structure:nnn {page}{verso}\@outputbox
-      \fi
-    \else
-      \marks_update_structure:nnn {page}{recto}\@outputbox
-      \marks_update_structure_alias:nn {verso}{page}
-    \fi
-    \marks_update_structure_alias:nn {col}{page}  
-    \marks_update_structure_alias:nn {1col}{page}  
-    \marks_update_structure_alias:nn {2col}{page}
-%<*trace>
-    \marks_status:n {OR:~(\if at twoside twoside- \ifodd \c at page odd\else
-      even\fi\else oneside\fi)}
-%</trace>
-   }
-%    \end{macrocode}
-%    
-%    \begin{macrocode}
-\cs_new:Npn \@@_update_dblcol_structure:
-   {
-    \if at firstcolumn
-      \marks_update_structure:nnn {col}{1col}\@outputbox
-    \else
-      \marks_update_structure:nnn {col}{2col}\@outputbox
-      \if at twoside
-        \ifodd \c at page
-          \marks_update_complex_structure:nnn {page}{recto}
-            { \unvcopy\@leftcolumn\unskip
-              \unvcopy\@outputbox\unskip }
-        \else
-          \marks_update_complex_structure:nnn {page}{verso}
-            { \unvcopy\@leftcolumn\unskip
-              \unvcopy\@outputbox\unskip }
-        \fi
-      \else
-        \marks_update_complex_structure:nnn {page}{recto}
-            { \unvcopy\@leftcolumn\unskip
-              \unvcopy\@outputbox\unskip }
-      \fi
-    \fi
-%<*trace>
-    \marks_status:n {OR:~(
-      \if at twoside twoside- \ifodd \c at page odd\else
-      even\fi\else oneside\fi
-      \space
-      \if at firstcolumn first~ \else second~ \fi
-       column)}
-%</trace>
-   }
-  
-%    \end{macrocode}
-%
-%
 %    
 %    \begin{macrocode}
 
@@ -418,15 +474,10 @@
   \tl_new:N \g_@@_tmp_tl
   \tl_new:N \g_@@_new_top_tl
   
-\cs_new:Npn \marks_update_structure:nnn #1#2#3
-   { \marks_update_complex_structure:nnn
-     {#1}{#2}{ \unvcopy #3 \unskip }
-   }
-  
 %    \end{macrocode}
 %    
 
-%  \begin{macro}{\marks_update_complex_structure:nnn}
+%  \begin{macro}{\marks_update_structure:nnn}
 
 %    This function updates the mark structure. The first argument is
 %    the region from which we pick up the last mark to make it the new
@@ -443,7 +494,7 @@
 %    need for \cs{marks_update_structure_alias:nn}) which save a bit of
 %    processing time as we don't have to construct csnames unnecessarily.
 %    \begin{macrocode}
-\cs_new:Npn \marks_update_complex_structure:nnn #1#2#3
+\cs_new:Npn \marks_update_structure:nnn #1#2#3
 {
   \group_begin:
 %    \end{macrocode}
@@ -457,7 +508,6 @@
     \dim_set:Nn \tex_splitmaxdepth:D \c_max_dim
     \int_set:Nn \tex_vbadness:D      \c_max_int
     \vbox_set:Nn \@@_box {#3}
-%    \showoutput\showbox \@@_box
     \vbox_set_split_to_ht:NNn \@@_box \@@_box \c_max_dim
 %    \end{macrocode}
 %    After this action we can get first and last marks of the various
@@ -582,6 +632,12 @@
 %
 %
 %    
+% \begin{macro}[EXP]
+%   {\marks_get_first:nn, \marks_get_last:nn, \marks_get_previous:nn}
+%   To retrieve the first, last or previous region mark, we grab the appropriate
+%   value stored in some tl var. These functions should be used only in
+%   output routines after \cs{marks_update_structure:nnn} has acted, otherwise their
+%   value will be wrong.
 %    \begin{macrocode}
 \cs_new:Npn \marks_use_first:nn #1#2
    { \use:c { g_@@_ #1 _first_ #2 _tl } }
@@ -590,10 +646,12 @@
 \cs_new:Npn \marks_use_previous:nn #1#2
   {  \use:c { g_@@_ #1 _top_ #2 _tl }  }
 %    \end{macrocode}
+% \end{macro}
 %
 %
 %
-%    
+%  \begin{macro}{\marks_status:nn}
+%    Some simple tracing, should be changed \ldots
 %    \begin{macrocode}
   \cs_new:Npn \marks_status:n #1
      {
@@ -633,6 +691,8 @@
        }
 }       
 %    \end{macrocode}
+%  \end{macro}
+%    
 %
 %
 %
@@ -726,6 +786,18 @@
 %
 %  \section{\LaTeXe{} integration} 
 %
+%  \begin{macro}[TF, int]{\legacy_switch_if:n}
+%    To evaluate \LaTeXe{} boolean switches in a nice way, we need a
+%    conditional. Eventually this will probably make it into the \pkg{expl3}
+%    code in this or a similar form, but right now it is missing.
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \legacy_switch_if:n #1 {p, T , F , TF }
+  { \exp_args:Nc\if_meaning:w { if#1 } \iftrue \prg_return_true:
+                                        \else: \prg_return_false: \fi: }
+%    \end{macrocode}
+%  \end{macro}
+%
+%
 %    \begin{macrocode}
 \RequirePackage{etoolbox}
 %    \end{macrocode}
@@ -781,7 +853,8 @@
 \patchcmd\@opcol
   {\@outputpage}
   {
-    \@@_update_singlecol_structure:
+    \marks_update_singlecol_structure:n 
+       { \unvcopy\@outputbox\unskip }
     \@outputpage
   }
   {\typeout{\noexpand\@opcol patch~ 1~ successful}}
@@ -792,7 +865,10 @@
 \patchcmd\@opcol
   {\@outputdblcol}
   {
-    \@@_update_dblcol_structure:
+    \marks_update_dblcol_structure:nn
+       { \unvcopy\@outputbox\unskip }
+       { \unvcopy\@leftcolumn\unskip
+         \unvcopy\@outputbox\unskip }
     \@outputdblcol
   }
   {\typeout{\noexpand\@opcol patch~ 2~ successful}}
@@ -801,6 +877,78 @@
 %  \end{macro}
 %
 %    
+%  \begin{macro}{\marks_update_singlecol_structure:n}
+%    
+%    \begin{macrocode}
+\cs_new:Npn \marks_update_singlecol_structure:n #1
+   {
+     \legacy_switch_if:nTF {@twoside}
+     {
+      \int_if_odd:nTF \c at page
+        { \marks_update_structure:nnn {page}{recto}{#1} }
+        { \marks_update_structure:nnn {page}{verso}{#1} }
+     }
+     {
+       \marks_update_structure:nnn {page}{recto}{#1}
+       \marks_update_structure_alias:nn {verso}{page}
+     }
+    \marks_update_structure_alias:nn {col}{page}  
+    \marks_update_structure_alias:nn {1col}{page}  
+    \marks_update_structure_alias:nn {2col}{page}
+%<*trace>
+    \marks_status:n
+     { OR:~(
+       \legacy_switch_if:nTF {@twoside}
+              { twoside-
+                \int_if_odd:nTF \c at page
+                    { odd }{ even }
+              }
+              { oneside }
+       )
+     }
+%</trace>
+   }
+%    \end{macrocode}
+%  \end{macro}
+%    
+%  \begin{macro}{\marks_update_dblcol_structure:nn}
+%    
+%    \begin{macrocode}
+\cs_new:Npn \marks_update_dblcol_structure:nn #1#2
+   {
+    \legacy_switch_if:nTF {@firstcolumn}
+      { \marks_update_structure:nnn {col}{1col}{#1} }
+      {
+        \marks_update_structure:nnn {col}{2col}{#1}
+        \legacy_switch_if:nTF {@twoside}
+               {
+                 \int_if_odd:nTF \c at page
+                     { \marks_update_structure:nnn {page}{recto}{#2} }
+                     { \marks_update_structure:nnn {page}{verso}{#2} }
+               }
+               { \marks_update_structure:nnn {page}{recto}{#2} }
+      }
+%<*trace>
+   \marks_status:n
+     { OR:~(
+       \legacy_switch_if:nTF {@twoside}
+              { twoside-
+                \int_if_odd:nTF \c at page
+                    { odd }{ even }
+              }
+              { oneside }
+      \space
+      \legacy_switch_if:nTF {@firstcolumn}
+             { first~ }{ second~ }
+      column )
+     }
+%</trace>
+   }
+%    \end{macrocode}
+%  \end{macro}
+%    
+%
+%
 %    \begin{macrocode}
 %</package>
 %    \end{macrocode}
@@ -858,13 +1006,11 @@
 %    reality that gets even more complex for two columns as we have
 %    more float areas then.
 %    \begin{macrocode}
-\cs_new:Npn \marks_update_structure:nnn #1#2#3
-   { \marks_update_complex_structure:nnn
+     \marks_update_structure:nnn
      {#1}{#2}
      { \unvcopy\@@_tfloats_box
        \unvcopy #3 \unskip
        \unvcopy\@@_bfloats_box }
-   }
 %    \end{macrocode}
 %    
 %    \begin{macrocode}





More information about the latex3-commits mailing list