[latex3-commits] [git/LaTeX3-latex3-latex2e] hotfix/gh441: Move 'top-level' chunks always at the end of the hook (6ae3cee4)
PhelypeOleinik
phelype.oleinik at latex-project.org
Thu Dec 10 03:29:58 CET 2020
Repository : https://github.com/latex3/latex2e
On branch : hotfix/gh441
Link : https://github.com/latex3/latex2e/commit/6ae3cee46507ed5f54abc8e1d6384d0f162543ee
>---------------------------------------------------------------
commit 6ae3cee46507ed5f54abc8e1d6384d0f162543ee
Author: PhelypeOleinik <phelype.oleinik at latex-project.org>
Date: Wed Dec 9 23:29:58 2020 -0300
Move 'top-level' chunks always at the end of the hook
Fixes #441
>---------------------------------------------------------------
6ae3cee46507ed5f54abc8e1d6384d0f162543ee
base/lthooks.dtx | 106 ++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 78 insertions(+), 28 deletions(-)
diff --git a/base/lthooks.dtx b/base/lthooks.dtx
index 1a344741..3021e107 100644
--- a/base/lthooks.dtx
+++ b/base/lthooks.dtx
@@ -1808,6 +1808,12 @@
% $\meta{reversed}1$ is $+1$ for normal hooks and $-1$ for reversed
% ones.
%
+% \item[\cs{@@_toplevel~\meta{name}}] This token list stores the code
+% inserted in the hook from the user's document, in the |top-level|
+% label. This label is special, and doesn't participate in sorting.
+% Instead, all code is appended to it and executed after the normal
+% hook code, but before the |next| code chunk.
+%
% \item[\cs{@@_next~\meta{name}}] Finally there is extra code
% (normally empty) that is used on the next invocation of the hook
% (and then deleted). This can be used to define some special
@@ -1899,6 +1905,7 @@
\@@_if_exist:nF {#1}
{
\prop_new:c { g_@@_#1_code_prop }
+ \tl_new:c { @@_toplevel~#1 }
\tl_new:c { @@_next~#1 }
}
}
@@ -2215,12 +2222,20 @@
% If there's code already there, then append \verb=#3= to that,
% otherwise just put \verb=#3=.
% \begin{macrocode}
- \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl
+ \str_if_eq:nnTF {#2} { top-level }
+ {
+ \debug_suspend:
+ \tl_gput_right:cn { @@_toplevel~#1 } {#3}
+ \debug_resume:
+ }
{
- \prop_gput:cno { g_@@_#1_code_prop } {#2}
- { \l_@@_return_tl #3 }
+ \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl
+ {
+ \prop_gput:cno { g_@@_#1_code_prop } {#2}
+ { \l_@@_return_tl #3 }
+ }
+ { \prop_gput:cnn { g_@@_#1_code_prop } {#2} {#3} }
}
- { \prop_gput:cnn { g_@@_#1_code_prop } {#2} {#3} }
}
% \end{macrocode}
% \end{macro}
@@ -2440,8 +2455,13 @@
% \verb=\begin{document}=.
% \begin{macrocode}
{
+ \debug_suspend:
\str_if_eq:nnTF {#2} {*}
- { \prop_gclear:c { g_@@_#1_code_prop } }
+ {
+ \prop_gclear:c { g_@@_#1_code_prop }
+ \tl_gclear:c { @@_toplevel~#1 }
+ \tl_gclear:c { @@_next~#1 }
+ }
{
% \end{macrocode}
% Check if the label being removed exists in the code pool. If it does,
@@ -2453,6 +2473,7 @@
{ \@@_mark_removal:nn }
{#1} {#2}
}
+ \debug_resume:
% \end{macrocode}
% Finally update the code, if the hook exists.
% \begin{macrocode}
@@ -2472,7 +2493,11 @@
% \begin{macro}{\@@_gremove_code_do:nn}
% \begin{macrocode}
\cs_new_protected:Npn \@@_gremove_code_do:nn #1 #2
- { \prop_gremove:cn { g_@@_#1_code_prop } {#2} }
+ {
+ \str_if_eq:nnTF {#2} { top-level }
+ { \tl_gclear:c { @@_toplevel~#1 } }
+ { \prop_gremove:cn { g_@@_#1_code_prop } {#2} }
+ }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -2722,7 +2747,7 @@
% \end{macro}
%
% \begin{macro}[EXP]{\@@_if_label_case:nnnnn}
-% To avoid doing the string comparison twice in \cs{@@_initialize_single:NNNn}
+% To avoid doing the string comparison twice in \cs{@@_initialize_single:NNNNn}
% (once with \cs{str_if_eq:nn} and again with \cs{@@_label_ordered:nn}),
% we use a three-way branching macro that will compare |#1| and |#2|
% and expand to \cs{use_i:nnn} if they are equal, \cs{use_ii:nn} if
@@ -2815,17 +2840,22 @@
% If there aren't any code
% chunks for the current hook, there is no point in even starting
% the sorting routine so we make a quick test for that and in that
-% case just update \cs{@@~\meta{hook}} to hold the next
+% case just update \cs{@@~\meta{hook}} to hold the |next|
% code. If there are code chunks we call
-% \cs{@@_initialize_single:NNNn} and pass to it ready made csnames
+% \cs{@@_initialize_single:NNNNn} and pass to it ready made csnames
% as they are needed several times inside. This way we save a bit
% on processing time if we do that up front.
% \begin{macrocode}
\hook_if_exist:nT {#1}
{
\prop_if_empty:cTF {g_@@_#1_code_prop}
- { \tl_gset:co { @@~#1 }
- { \cs:w @@_next~#1 \cs_end: } }
+ {
+ \tl_gset:co { @@~#1 }
+ {
+ \cs:w @@_toplevel~#1 \exp_after:wN \cs_end:
+ \cs:w @@_next~#1 \cs_end:
+ }
+ }
{
% \end{macrocode}
% By default the algorithm sorts the code chunks and then saves the
@@ -2848,8 +2878,8 @@
% save the old code property list so that it can be restored later.
% \begin{macrocode}
\prop_set_eq:Nc \l_@@_work_prop { g_@@_#1_code_prop }
- \@@_initialize_single:cccn
- { @@~#1 } { @@_next~#1 }
+ \@@_initialize_single:ccccn
+ { @@~#1 } { @@_toplevel~#1 } { @@_next~#1 }
{ g_@@_#1_labels_clist } {#1}
% \end{macrocode}
% For debug display we want to keep track of those hooks that
@@ -2918,12 +2948,13 @@
% \end{macro}
%
%
-% \begin{macro}{\@@_initialize_single:NNNn,\@@_initialize_single:cccn}
+% \begin{macro}{\@@_initialize_single:NNNNn,\@@_initialize_single:ccccn}
%
-% \cs{@@_initialize_single:NNNn} implements the sorting of the code
+% \cs{@@_initialize_single:NNNNn} implements the sorting of the code
% chunks for a hook and saves the result in the token list for fast
-% execution (\verb=#3=). The arguments are \meta{hook-code-plist},
-% \meta{hook-code-tl}, \meta{hook-next-code-tl},
+% execution (\verb=#4=). The arguments are \meta{hook-code-plist},
+% \meta{hook-code-tl}, \meta{hook-top-level-code-tl},
+% \meta{hook-next-code-tl},
% \meta{hook-ordered-labels-clist} and \meta{hook-name} (the latter
% is only used for debugging---the \meta{hook-rule-plist} is accessed
% using the \meta{hook-name}).
@@ -2935,8 +2966,14 @@
% far as possible. The result is a restriction I do not test for at
% the moment: a label can't be equal to the number 0! \fmi{Needs
% checking for, just in case}
+%
+% ^^A #1 <- \@@~#1
+% ^^A #2 <- \@@_toplevel~#1
+% ^^A #3 <- \@@_next~#1
+% ^^A #4 <- \g_@@_#1_labels_clist
+% ^^A #5 <- #1
% \begin{macrocode}
-\cs_new_protected:Npn \@@_initialize_single:NNNn #1#2#3#4
+\cs_new_protected:Npn \@@_initialize_single:NNNNn #1#2#3#4#5
{
% \end{macrocode}
% Step T1: Initialize the data structure \ldots
@@ -2947,7 +2984,7 @@
%
% Store the name of the hook:
% \begin{macrocode}
- \tl_set:Nn \l_@@_cur_hook_tl {#4}
+ \tl_set:Nn \l_@@_cur_hook_tl {#5}
% \end{macrocode}
%
% We loop over the property list holding the code and record all
@@ -2961,7 +2998,7 @@
{
\int_incr:N \l_@@_labels_int
\seq_put_right:Nn \l_@@_labels_seq {##1}
- \tl_set:cn { \@@_tl_csname:n {##1} }{0}
+ \tl_set:cn { \@@_tl_csname:n {##1} } { 0 }
\seq_clear_new:c { \@@_seq_csname:n {##1} }
}
% \end{macrocode}
@@ -2987,7 +3024,7 @@
{ \prop_map_break: }
{ \@@_apply_label_pair:nnn {##1} {####1} }
{ \@@_apply_label_pair:nnn {####1} {##1} }
- {#4}
+ {#5}
}
}
% \end{macrocode}
@@ -3015,7 +3052,7 @@
%
% \begin{macrocode}
\tl_gclear:N #1
- \clist_gclear:N #3
+ \clist_gclear:N #4
% \end{macrocode}
%
% The whole loop combines steps T5--T7:
@@ -3031,7 +3068,7 @@
% \end{macrocode}
%
% \begin{macrocode}
- \@@_clist_gput:NV #3 \l_@@_front_tl
+ \@@_clist_gput:NV #4 \l_@@_front_tl
\@@_debug:n{ \iow_term:x{Handled~ code~ for~ \l_@@_front_tl} }
% \end{macrocode}
%
@@ -3079,14 +3116,14 @@
% \end{macrocode}
% After we have added all hook code to \verb=#1= we finish it off
% with adding extra code for a one time execution. That is stored
-% in \verb=#2= but is normally empty.
+% in \verb=#3= but is normally empty.
% \begin{macrocode}
- \tl_gput_right:Nn #1 {#2}
+ \tl_gput_right:Nn #1 { #2 #3 }
}
% \end{macrocode}
%
% \begin{macrocode}
-\cs_generate_variant:Nn \@@_initialize_single:NNNn {ccc}
+\cs_generate_variant:Nn \@@_initialize_single:NNNNn { cccc }
% \end{macrocode}
% \end{macro}
%
@@ -3359,6 +3396,16 @@
% \end{macrocode}
%
% \begin{macrocode}
+ \@@_log_line:x { Document-level~(top-level)~code:}
+ \@@_log_line_indent:x
+ {
+ \tl_if_empty:cTF { @@_toplevel~#1 }
+ { --- }
+ { ->~ \exp_args:Nv \tl_to_str:n { @@_toplevel~#1 } }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
\@@_log_line:x { Extra~code~for~next~invocation:}
\@@_log_line_indent:x
{
@@ -3565,7 +3612,6 @@
% \end{macro}
% \end{macro}
%
-%
% \subsection{Using the hook}
%
% \begin{macro}{\hook_use:n}
@@ -3730,7 +3776,11 @@
{
\bool_lazy_and:nnTF
{ \prop_if_empty_p:c { g_@@_#1_code_prop } }
- { \tl_if_empty_p:c { @@_next~#1 } }
+ {
+ \bool_lazy_and_p:nn
+ { \tl_if_empty_p:c { @@_toplevel~#1 } }
+ { \tl_if_empty_p:c { @@_next~#1 } }
+ }
{ \prg_return_true: }
{ \prg_return_false: }
}
More information about the latex3-commits
mailing list.