texlive[60998] Master/texmf-dist: etl (9nov21)

commits+karl at tug.org commits+karl at tug.org
Tue Nov 9 00:17:00 CET 2021


Revision: 60998
          http://tug.org/svn/texlive?view=revision&revision=60998
Author:   karl
Date:     2021-11-09 00:16:59 +0100 (Tue, 09 Nov 2021)
Log Message:
-----------
etl (9nov21)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/etl/README.md
    trunk/Master/texmf-dist/doc/latex/etl/etl.pdf
    trunk/Master/texmf-dist/source/latex/etl/etl.dtx
    trunk/Master/texmf-dist/tex/latex/etl/etl.sty

Modified: trunk/Master/texmf-dist/doc/latex/etl/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/etl/README.md	2021-11-08 23:16:12 UTC (rev 60997)
+++ trunk/Master/texmf-dist/doc/latex/etl/README.md	2021-11-08 23:16:59 UTC (rev 60998)
@@ -1,7 +1,7 @@
 -------------------------------------------------------------------------------
 # etl -- expandable token list operations
 
-Version 2021-08-28 v0.2
+Version 2021-11-07 v0.3
 
 Released under the LaTeX Project Public License v1.3c or later
 See http://www.latex-project.org/lppl.txt

Modified: trunk/Master/texmf-dist/doc/latex/etl/etl.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/etl/etl.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/etl/etl.dtx	2021-11-08 23:16:12 UTC (rev 60997)
+++ trunk/Master/texmf-dist/source/latex/etl/etl.dtx	2021-11-08 23:16:59 UTC (rev 60998)
@@ -109,10 +109,11 @@
 % The \pkg{etl} package provides a few \emph{slow but expandable} alternatives
 % to unexpandable functions found inside the \pkg{l3tl} module of \pkg{expl3}.
 % All user functions must not contain the tokens \cs{s__etl_stop}\footnote{At
-% any nesting level of groups} or \cs{__etl_act_result:n}\footnote{Outside of
-% some local brace groups} in any argument unless specified otherwise (there
-% might be other forbidden tokens, all of which are internals to this package,
-% and usually shouldn't somehow end up inside the input stream by accident).
+% any nesting level of groups} or \cs{__etl_act_result:n}\footnote{On the top
+% level (so nested usages in groups are fine)} in any argument unless specified
+% otherwise (there might be other forbidden tokens, all of which are internals
+% to this package, and usually shouldn't somehow end up inside the input stream
+% by accident).
 %
 % There is another limitation of this package: There are tokens which cannot
 % expandably be differentiated from each other, those are active characters let
@@ -132,7 +133,10 @@
 % the parser doesn't consider the character code of tokens with category 1 or 2
 % (group begin and group end, typically |{}|), instead all tokens found with
 % these two category codes are normalised to \texttt{\{\textsubscript{1}} and
-% \texttt{\}\textsubscript{2}}.
+% \texttt{\}\textsubscript{2}} (an exception to this rule are the functions
+% \cs{etl_token_replace_once:nNn} and \cs{etl_replace_once:nnn} in which this
+% normalisation is only done up to the replacement, and the rest of the input is
+% forwarded unchanged).
 %
 % The core macro \cs{etl_act:nnnnnnn} is modelled after an internal of
 % \pkg{l3tl} called \cs{__tl_act:NNNn} but with some more possibilities added.
@@ -160,9 +164,8 @@
 %   expansion using \cs{exp_not:n}). Also you can specify some \meta{output}
 %   which should be there from the beginning.
 %
-%   Functions without the argument \meta{output} will start with an empty
-%   output, and those without \meta{final} will just output the results at the
-%   end.
+%   Variants without the argument \meta{output} will start with an empty output,
+%   and those without \meta{final} will just output the results at the end.
 %
 %   \begin{texnote}
 %     The result is returned within \cs{exp_not:n}, which means that the token
@@ -174,6 +177,9 @@
 %   \end{texnote}
 % \end{function}
 %
+% All other functions which start in |\etl_act_| should only be used inside the
+% \meta{normal}, \meta{space}, or \meta{group} code of \cs{etl_act:nnnnnnn}.
+%
 % \begin{function}[EXP]{\etl_act_output:n, \etl_act_output_pre:n}
 %   \begin{syntax}
 %     \cs{etl_act_output:n} \Arg{token list}
@@ -181,8 +187,6 @@
 %   This will add \meta{token list} to the output of \cs{etl_act:nnnnnnn}. The
 %   normal version will add \meta{token list} after the current output, the
 %   |pre| variant will put it before the current output.
-%   Might be used inside of the \meta{normal}, \meta{space}, or \meta{group}
-%   code of \cs{etl_act:nnnnnnn}.
 % \end{function}
 %
 % \begin{function}[EXP]{\etl_act_output_rest:, \etl_act_output_rest_pre:}
@@ -192,9 +196,12 @@
 %   After this macro was used all remaining things inside the \meta{token list}
 %   argument of \cs{etl_act:nnnnnnn} will be added to the output. The normal
 %   version will add it to the end of the output, the |pre| variant will put the
-%   remainder before the current output in reversed order.
-%   Might be used inside of the \meta{normal}, \meta{space}, or \meta{group}
-%   code of \cs{etl_act:nnnnnnn}.
+%   remainder before the current output in reversed order. Any begin group and
+%   end group tokens inside \meta{token list} will be normalised by this. A
+%   faster alternative (that doesn't normalise) would be
+% \begin{verbatim}
+% \etl_act_apply_to_rest:n { \etl_act_break_post:n }
+% \end{verbatim}
 % \end{function}
 %
 % \begin{function}[EXP]{\etl_act_status:n}
@@ -203,8 +210,6 @@
 %   \end{syntax}
 %   This will change the current status of \cs{etl_act:nnnnnnn} to
 %   \meta{status}.
-%   Might be used inside of the \meta{normal}, \meta{space}, or \meta{group}
-%   code of \cs{etl_act:nnnnnnn}.
 % \end{function}
 %
 % \begin{function}[EXP]{\etl_act_put_back:n}
@@ -214,8 +219,6 @@
 %   You can put \meta{token list} back into the input stream to be reconsidered
 %   by the current \cs{etl_act:nnnnnnn} loop (of course this doesn't have to be
 %   literally put back, you might add completely new contents with this).
-%   Might be used inside of the \meta{normal}, \meta{space}, or \meta{group}
-%   code of \cs{etl_act:nnnnnnn}.
 % \end{function}
 %
 % \begin{function}[EXP]
@@ -231,10 +234,21 @@
 %   \end{syntax}
 %   With these functions you can change the provided code to act on
 %   \meta{normal} (so |N|-type) tokens, \meta{space}s, and \meta{group}s.
-%   Might be used inside of the \meta{normal}, \meta{space}, or \meta{group}
-%   code of \cs{etl_act:nnnnnnn}.
 % \end{function}
 %
+% \begin{function}[EXP]{\etl_act_apply_to_rest:n}
+%   \begin{syntax}
+%     \cs{etl_act_apply_to_rest:n} \Arg{code}
+%   \end{syntax}
+%   This will fetch the rest of the input \meta{token list} of the current
+%   \cs{etl_act:nnnnnnn} call and leave \meta{code}\Arg{rest} in the input
+%   stream (without brace normalisation). It will not end the current
+%   \cs{etl_act:nnnnnnn} loop (but since the \meta{token list} remainder is now
+%   empty it'll end after your \meta{code} is done, except if you put new
+%   contents in the list using \cs{etl_act_put_back:n}) nor affect it in any
+%   other way.
+% \end{function}
+%
 % \begin{function}[EXP]{\etl_act_do_final:}
 %   \begin{syntax}
 %     \cs{etl_act_do_final:}
@@ -244,8 +258,6 @@
 %   \meta{final} code was used, the output). The \meta{final} code will receive
 %   the current status followed by the current output as two arguments (just
 %   like it would when the end of the \meta{token list} was reached).
-%   Might be used inside of the \meta{normal}, \meta{space}, or \meta{group}
-%   code of \cs{etl_act:nnnnnnn}.
 % \end{function}
 %
 % \begin{function}[EXP]{\etl_act_break:, \etl_act_break_discard:}
@@ -255,8 +267,6 @@
 %   This will immediately stop the current \cs{etl_act:nnnnnnn} invocation and
 %   leave the current output in the input stream. The |discard| variant will
 %   gobble the current output and leave nothing in the input stream.
-%   Might be used inside of the \meta{normal}, \meta{space}, or \meta{group}
-%   code of \cs{etl_act:nnnnnnn}.
 % \end{function}
 %
 % \begin{function}[EXP]{\etl_act_break:n}
@@ -265,8 +275,6 @@
 %   \end{syntax}
 %   This will immediately stop the current \cs{etl_act:nnnnnnn} invocation,
 %   gobble the current output and leave \meta{token list} in the input stream.
-%   Might be used inside of the \meta{normal}, \meta{space}, or \meta{group}
-%   code of \cs{etl_act:nnnnnnn}.
 % \end{function}
 %
 % \begin{function}[EXP]{\etl_act_break_pre:n, \etl_act_break_post:n}
@@ -280,6 +288,119 @@
 % \end{function}
 %
 %
+% \subsubsection{Examples}
+%
+% To give examples how you could use \cs{etl_act:nnnnnnn} the following could
+% be used to reimplement \cs{tl_reverse:n}. We work with a bit of currying here
+% (this gives a small speed gain in general, though for code clarity you might
+% decide to not curry each and every argument). Since a reversing function
+% doesn't need to postprocess its output we can use the shorter
+% \cs{etl_act:nnnnn}. The three internal functions all need to gobble the
+% status.
+%
+% \begin{verbatim}
+% % argument #2 is curried
+% \cs_new:Npn \__my_reverse_normal:nN #1 { \etl_act_output_pre:n }
+% \cs_new:Npn \__my_reverse_space:n #1 { \etl_act_output_pre:n { ~ } }
+% \cs_new:Npn \__my_reverse_group:nn #1#2 { \etl_act_output_pre:n { {#2} } }
+% % argument #1 is curried
+% \cs_new:Npn \my_reverse:n
+%   {
+%     \etl_act:nnnnn
+%       \__my_reverse_normal:nN
+%       \__my_reverse_space:n
+%       \__my_reverse_group:nn
+%       {} % empty status
+%   }
+% \end{verbatim}
+%
+% We could also create a similar function that'll reverse the input up to the
+% first space and discard the remainder (no idea why somebody would want to do
+% that).
+%
+% \begin{verbatim}
+% % argument #1 is curried
+% \cs_new:Npn \my_reverse_discard_after_space:n
+%   {
+%     \etl_act:nnnnn
+%       \__my_reverse_normal:nN
+%       \etl_act_break:
+%       \__my_reverse_group:nn
+%       {} % empty status
+%   }
+% \end{verbatim}
+%
+% Or a function that reverses the contents of groups as well.
+%
+% \begin{verbatim}
+% \cs_generate_variant:Nn \etl_act_output_pre:n { e }
+% \cs_new:Npn \__my_reverse_group_reversed:nn #1#2
+%   { \etl_act_output_pre:e { { \my_reverse_deep:n {#2} } } }
+% % argument #1 is curried
+% \cs_new:Npn \my_reverse_deep:n
+%   {
+%     \etl_act:nnnnn
+%       \__my_reverse_normal:nN
+%       \__my_reverse_space:n
+%       \__my_reverse_group_reversed:nn
+%       {} % empty status
+%   }
+% \end{verbatim}
+%
+% Another function could count a specific token inside a token list. Since for
+% this neither output-reordering nor post processing is needed we shortcut by
+% not using \cs{etl_output:n} but instead directly leaving |+ \c_one_int| (which
+% also doesn't need to be protected against further expansion) in the input.
+%
+% \begin{verbatim}
+% \cs_new:Npn \__my_count_token:NN #1#2
+%   { \etl_token_if_eq:NNT #1#2 { + \c_one_int } }
+% \cs_new:Npn \my_count_token:Nn #1#2
+%   {
+%     \int_eval:n
+%       {
+%         \c_zero_int
+%         \etl_act:nnnnn
+%           \__my_count_token:NN
+%           \use_none:n
+%           \use_none:nn
+%           {#1}
+%           {#2}
+%       }
+%   }
+% \end{verbatim}
+%
+% As a last example we reimplement the \cs{etl_token_replace_once:nNn} function.
+% The function doesn't need to reorder any tokens, so we shortcut with
+% \cs{exp_not:n} to output things in place. We put the token we want to replace
+% in the code for |N|-type processing and the replacement in the status. When we
+% found the token we want to replace we put our replacement there and output the
+% rest unaltered.
+%
+% \begin{verbatim}
+% \cs_new:Npn \my_replace_token:nNn #1#2#3
+%   {
+%     \etl_act:nnnnn
+%       { \__my_replace_token:NnN #2 }
+%       { ~ \use_none:n }
+%       { \__my_replace_token:nn }
+%       {#3}
+%       {#1}
+%   }
+% \cs_new:Npn \__my_replace_token:nn #1#2 { { \exp_not:n {#2} } }
+% \cs_new:Npn \__my_replace_token:NnN #1#2#3
+%   {
+%     \etl_token_if_eq:NNTF #1#3
+%       { \exp_not:n {#2} \etl_act_apply_to_rest:n { \etl_act_break:n } }
+%       { \exp_not:N #3 }
+%   }
+% \end{verbatim}
+%
+% I hope this gave you at least an idea on how to use the loop and that the
+% explanations on the functions not used in these examples suffice to also give
+% you an idea on how to use them.
+%
+%
 % \subsection{Conditionals}\label{sec:conditionals}
 %
 % \begin{function}[pTF]{\etl_token_if_eq:NN}
@@ -293,18 +414,6 @@
 %   \cs{str_if_eq:nnTF} is true).
 % \end{function}
 %
-% \begin{function}[pTF]{\etl_if_eq:nn}
-%   \begin{syntax}
-%     \cs{etl_if_eq_p:nn} \Arg{token list_1} \Arg{token list_2}
-%     \cs{etl_if_eq:nnTF} \Arg{token list_1} \Arg{token list_2} \Arg{true code} \Arg{false code}
-%   \end{syntax}
-%   Compares \meta{token list_1} and \meta{token list_2} with each other on a
-%   token-by-token basis. Keep in mind that there are tokens which can't be told
-%   apart from each other, and that groups are normalised. If both token lists
-%   match (modulo the mentioned limitations) the \meta{true code} is left in the
-%   input stream, else the \meta{false code}.
-% \end{function}
-%
 % \begin{function}[pTF]{\etl_token_if_in:nN}
 %   \begin{syntax}
 %     \cs{etl_token_if_in_p:nN} \Arg{token list} \meta{token}
@@ -324,6 +433,18 @@
 %   searched as well.
 % \end{function}
 %
+% \begin{function}[pTF]{\etl_if_eq:nn}
+%   \begin{syntax}
+%     \cs{etl_if_eq_p:nn} \Arg{token list_1} \Arg{token list_2}
+%     \cs{etl_if_eq:nnTF} \Arg{token list_1} \Arg{token list_2} \Arg{true code} \Arg{false code}
+%   \end{syntax}
+%   Compares \meta{token list_1} and \meta{token list_2} with each other on a
+%   token-by-token basis. Keep in mind that there are tokens which can't be told
+%   apart from each other, and that groups are normalised. If both token lists
+%   match (modulo the mentioned limitations) the \meta{true code} is left in the
+%   input stream, else the \meta{false code}.
+% \end{function}
+%
 % \begin{function}[pTF]{\etl_if_in:nn}
 %   \begin{syntax}
 %     \cs{etl_if_in_p:nn} \Arg{token list} \Arg{search text}
@@ -334,9 +455,8 @@
 %   code}. Both macro parameter tokens as well as tokens with category code~1
 %   and 2 (normally |{}|) can be part of \meta{search text} (unlike for the
 %   similar function \cs{tl_if_in:nnTF}). Material inside of groups in
-%   \meta{token list} is ignored (except for the groups contained in
-%   \meta{search text}). So the following would first yield |true| and then
-%   |false|:
+%   \meta{token list} is ignored (except for groups contained in \meta{search
+%   text}). So the following would first yield |true| and then |false|:
 % \end{function}
 % \begin{verbatim}
 % \etl_if_in:nnTF { a{b{c}} } { {b{c}} } { true } { false }
@@ -564,7 +684,7 @@
 % Tell who we are:
 %    \begin{macrocode}
 \ProvidesExplPackage{etl}
-  {2021-08-28} {0.2}
+  {2021-11-07} {0.3}
   {expandable token list manipulation}
 %    \end{macrocode}
 %
@@ -603,18 +723,6 @@
 %
 % \subsection{Small auxiliaries}
 %
-% \begin{macro}[EXP]{\@@_if_mark:nTF,\@@_if_mark:w,\@@_if_mark_true:w}
-%   A small check whether some argument contains the scan mark \cs{s_@@_mark},
-%   the mark should always be the last token of the argument (and only a single
-%   such mark should be contained) to ensure correct behaviour.
-%    \begin{macrocode}
-\cs_new:Npn \@@_if_mark:nTF #1
-  { \@@_if_mark:w #1 \@@_if_mark_true:w \s_@@_mark \use_ii:nn }
-\cs_new:Npn \@@_if_mark:w #1 \s_@@_mark {}
-\cs_new:Npn \@@_if_mark_true:w \s_@@_mark \use_ii:nn #1#2 {#1}
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}[EXP]{\@@_split_first:w}
 %   Can be used to extract the first element from a token list, it should always
 %   be used like this:
@@ -732,15 +840,14 @@
 %    \end{macrocode}
 %   We also provide a version without the \cs{@@_unexpanded:w} around it for
 %   internal purposes, in which we'd otherwise have to remove it for correct
-%   behaviour.
+%   behaviour. For that we use \cs{use_ii_iii:nnn} which will remove one set
+%   of braces and the \cs{@@_unexpanded:w}.
 %    \begin{macrocode}
-\cs_new:Npn \@@_act:nnnnnnn #1#2#3#4#5#6#7
+\exp_args:NNno \exp_args:Nno \use:n
+  { \cs_new:Npn \@@_act:nnnnnnn #1#2#3#4#5#6#7 }
   {
-    \@@_expanded:w
-      {
-        \@@_act:w #7 {\s_@@_stop} . \s_@@_stop {#5} {#1} {#2} {#3}
-        \@@_act_result:n {#6} {#4}
-      }
+    \exp_after:wN \use_ii_iii:nnn
+    \etl_act:nnnnnnn {#1} {#2} {#3} {#4} {#5} {#6} {#7}
   }
 %    \end{macrocode}
 %   We also provide two reduced function variants, the first without presetting
@@ -921,6 +1028,45 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}[EXP]
+%   {
+%     \@@_act_unexpanded_rest:w,
+%     \@@_act_unexpanded_rest_aux:w, \@@_act_unexpanded_rest_aux:n,
+%     \@@_act_unexpanded_rest_done:w
+%   }
+%   This function tries to shortcut as much as possible to output the
+%   remainder of the token list in an unchanged way. This can be done by
+%   grabbing everything up to the next opening brace (since the stop marker is
+%   contained in a group), outputting that, and checking whether we're done. If
+%   not output the next group and loop. The first step removes the act code.
+%
+%   Drawback of this is that spaces and braces are not normalised for the
+%   remainder of that call (which is what we had documented).
+%    \begin{macrocode}
+\cs_new:Npn \@@_act_unexpanded_rest:w #1 \@@_act:w #2#
+  {
+    \@@_unexpanded:w {#2}
+    \@@_act_unexpanded_rest_aux:n
+  }
+\cs_new:Npn \@@_act_unexpanded_rest_aux:w #1#
+  {
+    \@@_unexpanded:w {#1}
+    \@@_act_unexpanded_rest_aux:n
+  }
+\cs_new:Npn \@@_act_unexpanded_rest_aux:n #1
+  {
+    \@@_act_if_end:w #1 \@@_act_unexpanded_rest_done:w \s_@@_stop
+    { \@@_unexpanded:w {#1} }
+    \@@_act_unexpanded_rest_aux:w
+  }
+\cs_new:Npn \@@_act_unexpanded_rest_done:w
+    \s_@@_stop #1 \@@_act_unexpanded_rest_aux:w
+    . \s_@@_stop #2#3#4#5
+    \@@_act_result:n #6#7
+  {}
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}[EXP]{\etl_act_status:n}
 %   Just switch out the status which is stored immediately after \cs{s_@@_stop}.
 %    \begin{macrocode}
@@ -964,6 +1110,7 @@
   { #2 \s_@@_stop {#3} {#4} {#5} {#1} }
 %    \end{macrocode}
 % \end{macro}
+%
 % \begin{macro}[EXP]
 %   {
 %     \etl_act_do_final:,
@@ -990,7 +1137,67 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}[EXP]{\etl_act_apply_to_rest:n}
+%   This function can be used to get the remainder of the input \meta{token
+%   list} and apply some user code on it. To get past the user code we use
+%   \cs{@@_expanded:w} with a brace trick. The heavy lifting is done by
+%   \cs{@@_act_get_rest:w}. The \cs{prg_do_nothing:} prevents accidental brace
+%   stripping and will be removed by \cs{@@_act_get_rest:w}.
+%    \begin{macrocode}
+\cs_new:Npn \etl_act_apply_to_rest:n #1
+  {
+    \@@_expanded:w { \@@_unexpanded:w {#1} { \if_false: }} \fi:
+    \@@_act_get_rest:w \prg_do_nothing:
+  }
+%    \end{macrocode}
+% \end{macro}
 %
+% \begin{macro}[EXP]{\@@_act_get_rest:w}
+%   This macro should be used with two unbalanced opening braces before it and
+%   inside an \cs{@@_expanded:w} context with a \cs{prg_do_nothing:} following
+%   it to prevent accidental brace stripping. It'll expand to the remainder of
+%   the input \meta{token list} followed by a closing brace and leaves
+%   everything else untouched.
+% \begin{macro}[EXP]
+%   {\@@_act_get_rest_aux:nw, \@@_act_get_rest_aux:nn, \@@_act_get_rest_done:w}
+%    \begin{macrocode}
+\cs_new:Npn \@@_act_get_rest:w #1 \@@_act:w #2#
+  {
+    \@@_unexpanded:w {#2}
+    \@@_act_get_rest_aux:nn {#1}
+  }
+\cs_new:Npn \@@_act_get_rest_aux:nw #1 #2#
+  {
+    \@@_unexpanded:w {#2}
+    \@@_act_get_rest_aux:nn {#1}
+  }
+%    \end{macrocode}
+%   Each group might be the end marker, so we check that, else leave the group
+%   there and grab until the next group starts.
+%    \begin{macrocode}
+\cs_new:Npn \@@_act_get_rest_aux:nn #1#2
+  {
+    \@@_act_if_end:w #2 \@@_act_get_rest_done:w \s_@@_stop
+    { \@@_unexpanded:w {#2} }
+    \@@_act_get_rest_aux:nw {#1}
+  }
+%    \end{macrocode}
+%   This closes the two unbalanced opening braces (ending the \cs{@@_expanded:w}
+%   context) and puts the remaining code back in the input stream (as well as
+%   the now empty next \cs{@@_act:w} step). The \cs{exp_after:wN} removes the
+%   leading \cs{prg_do_nothing:}.
+%    \begin{macrocode}
+\cs_new:Npn \@@_act_get_rest_done:w \s_@@_stop #1 \@@_act_get_rest_aux:nw #2
+  {
+    \if_false: {{ \fi: } \exp_after:wN }
+    #2
+    \@@_act:w { \s_@@_stop }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
 % \subsection{Expandable tests}
 %
 % \begin{macro}[pTF]{\etl_token_if_eq:NN}
@@ -1359,7 +1566,7 @@
 %
 % \begin{macro}[EXP]{\etl_token_replace_all:nNn}
 % \begin{macro}[EXP]{\@@_token_replace:NnnN}
-%   Replaceing a single token (and in fact the same is true for all the
+%   Replacing a single token (and in fact the same is true for all the
 %   replacement actions in this package) doesn't need reordering and no post
 %   processing, so we can use in place output using \cs{@@_unexpanded:w}. We
 %   store the token we want to replace inside the act function, as well as an
@@ -1418,10 +1625,7 @@
 \exp_args:Nno \use:n { \cs_new:Npn \etl_token_replace_once:nNn #1#2#3 }
   {
     \etl_act:nnnnnn
-      {
-        \@@_token_replace:NnnN #2
-          { \etl_act_switch_normal:n \@@_act_unexpanded_normal:nN }
-      }
+      { \@@_token_replace:NnnN #2 \@@_act_unexpanded_rest:w }
       \@@_act_unexpanded_space:n
       \@@_act_unexpanded_group:nn
       \use_none:nn
@@ -1458,7 +1662,7 @@
 %   the remainder of the pattern, the full pattern, delayed tokens (those
 %   which matched the pattern), the replacement, and a marker which should tell
 %   us whether we want to only replace the first match (if so use
-%   \cs{s_@@_mark}, else any other single token).
+%   \cs{@@_act_unexpanded_rest:w}, else \cs{prg_do_nothing:}).
 %    \begin{macrocode}
 \exp_args:Nno \use:n { \cs_new:Npn \etl_replace_all:nnn #1#2#3 }
   {
@@ -1467,7 +1671,7 @@
       \@@_replace_space:n
       \@@_replace_group:nn
       \@@_replace_final:nn
-      { {#2} {#2} {} {#3} \scan_stop: }
+      { {#2} {#2} {} {#3} \prg_do_nothing: }
       {#1}
   }
 %    \end{macrocode}
@@ -1524,15 +1728,8 @@
         \@@_if_empty:nTF {#2}
           {
             \@@_unexpanded:w {#5}
-            \@@_if_mark:nTF {#6}
-              {
-                \etl_act_switch:nnn
-                  \@@_act_unexpanded_normal:nN
-                  \@@_act_unexpanded_space:n
-                  \@@_act_unexpanded_group:nn
-                \etl_act_status:n { {} {} {} {} #6 }
-              }
-              { \etl_act_status:n { {#3} {#3} {} {#5} #6 } }
+            #6
+            \etl_act_status:n { {#3} {#3} {} {#5} #6 }
           }
           { \etl_act_status:n { {#2} {#3} { #4 #7 } {#5} #6 } }
       }
@@ -1561,15 +1758,8 @@
     \@@_if_empty:nTF {#1}
       {
         \@@_unexpanded:w {#4}
-        \@@_if_mark:nTF {#5}
-          {
-            \etl_act_switch:nnn
-              \@@_act_unexpanded_normal:nN
-              \@@_act_unexpanded_space:n
-              \@@_act_unexpanded_group:nn
-            \etl_act_status:n { {} {} {} {} #5 }
-          }
-          { \etl_act_status:n { {#2} {#2} {} {#4} #5 } }
+        #5
+        \etl_act_status:n { {#2} {#2} {} {#4} #5 }
       }
       { \etl_act_status:n { {#1} {#2} { #3 ~ } {#4} #5 } }
   }
@@ -1598,15 +1788,8 @@
         \@@_if_empty:nTF {#2}
           {
             \@@_unexpanded:w {#5}
-            \@@_if_mark:nTF {#6}
-              {
-                \etl_act_switch:nnn
-                  \@@_act_unexpanded_normal:nN
-                  \@@_act_unexpanded_space:n
-                  \@@_act_unexpanded_group:nn
-                \etl_act_status:n { {} {} {} {} #6 }
-              }
-              { \etl_act_status:n { {#3} {#3} {} {#5} #6 } }
+            #6
+            \etl_act_status:n { {#3} {#3} {} {#5} #6 }
           }
           { \etl_act_status:n { {#2} {#3} { #4 {#7} } {#5} #6 } }
       }
@@ -1640,7 +1823,7 @@
       \@@_replace_space:n
       \@@_replace_group_deep:nn
       \@@_replace_final:nn
-      { {#2} {#2} {} {#3} \scan_stop: }
+      { {#2} {#2} {} {#3} \prg_do_nothing: }
       {#1}
   }
 \cs_new:Npn \@@_replace_group_deep:nn #1
@@ -1691,7 +1874,7 @@
 %
 % \begin{macro}[EXP]{\etl_replace_once:nnn}
 %   And this is the same as the |all| variant except that we now use the
-%   \cs{s_@@_mark} marker inside the status.
+%   \cs{@@_act_unexpanded_rest:w} marker inside the status.
 %    \begin{macrocode}
 \exp_args:Nno \use:n { \cs_new:Npn \etl_replace_once:nnn #1#2#3 }
   {
@@ -1700,7 +1883,7 @@
       \@@_replace_space:n
       \@@_replace_group:nn
       \@@_replace_final:nn
-      { {#2} {#2} {} {#3} \s_@@_mark }
+      { {#2} {#2} {} {#3} \@@_act_unexpanded_rest:w }
       {#1}
   }
 %    \end{macrocode}
@@ -1909,7 +2092,13 @@
 % \end{macro}
 % \end{macro}
 %
+% \subsection{Undefine now unnecessary functions}
+%
 %    \begin{macrocode}
+\cs_undefine:N \@@_act:nnnnnnn
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 %</pkg>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/tex/latex/etl/etl.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/etl/etl.sty	2021-11-08 23:16:12 UTC (rev 60997)
+++ trunk/Master/texmf-dist/tex/latex/etl/etl.sty	2021-11-08 23:16:59 UTC (rev 60998)
@@ -30,7 +30,7 @@
 %%                                 etl.sty
 %% 
 \ProvidesExplPackage{etl}
-  {2021-08-28} {0.2}
+  {2021-11-07} {0.3}
   {expandable token list manipulation}
 \cs_if_exist:NF \tex_expanded:D
   {
@@ -43,10 +43,6 @@
 \cs_new_eq:NN \__etl_detokenize:w \tex_detokenize:D
 \scan_new:N \s__etl_stop
 \scan_new:N \s__etl_mark
-\cs_new:Npn \__etl_if_mark:nTF #1
-  { \__etl_if_mark:w #1 \__etl_if_mark_true:w \s__etl_mark \use_ii:nn }
-\cs_new:Npn \__etl_if_mark:w #1 \s__etl_mark {}
-\cs_new:Npn \__etl_if_mark_true:w \s__etl_mark \use_ii:nn #1#2 {#1}
 \cs_new:Npn \__etl_split_first:w #1
   {
     { \__etl_unexpanded:w {#1} }
@@ -98,13 +94,11 @@
         \__etl_act_result:n {#6} {#4}
       }}
   }
-\cs_new:Npn \__etl_act:nnnnnnn #1#2#3#4#5#6#7
+\exp_args:NNno \exp_args:Nno \use:n
+  { \cs_new:Npn \__etl_act:nnnnnnn #1#2#3#4#5#6#7 }
   {
-    \__etl_expanded:w
-      {
-        \__etl_act:w #7 {\s__etl_stop} . \s__etl_stop {#5} {#1} {#2} {#3}
-        \__etl_act_result:n {#6} {#4}
-      }
+    \exp_after:wN \use_ii_iii:nnn
+    \etl_act:nnnnnnn {#1} {#2} {#3} {#4} {#5} {#6} {#7}
   }
 \exp_args:Nno \use:n { \cs_new:Npn \etl_act:nnnnnn #1#2#3#4#5#6 }
   { \etl_act:nnnnnnn {#1} {#2} {#3} {#4} {#5} {} {#6} }
@@ -193,6 +187,27 @@
 \cs_new:Npn \__etl_act_unexpanded_normal:nN #1 { \exp_not:N }
 \cs_new:Npn \__etl_act_unexpanded_space:n #1 { ~ }
 \cs_new:Npn \__etl_act_unexpanded_group:nn #1#2 { { \__etl_unexpanded:w {#2} } }
+\cs_new:Npn \__etl_act_unexpanded_rest:w #1 \__etl_act:w #2#
+  {
+    \__etl_unexpanded:w {#2}
+    \__etl_act_unexpanded_rest_aux:n
+  }
+\cs_new:Npn \__etl_act_unexpanded_rest_aux:w #1#
+  {
+    \__etl_unexpanded:w {#1}
+    \__etl_act_unexpanded_rest_aux:n
+  }
+\cs_new:Npn \__etl_act_unexpanded_rest_aux:n #1
+  {
+    \__etl_act_if_end:w #1 \__etl_act_unexpanded_rest_done:w \s__etl_stop
+    { \__etl_unexpanded:w {#1} }
+    \__etl_act_unexpanded_rest_aux:w
+  }
+\cs_new:Npn \__etl_act_unexpanded_rest_done:w
+    \s__etl_stop #1 \__etl_act_unexpanded_rest_aux:w
+    . \s__etl_stop #2#3#4#5
+    \__etl_act_result:n #6#7
+  {}
 \cs_new:Npn \etl_act_status:n #1 #2 \s__etl_stop #3
   { #2 \s__etl_stop {#1} }
 \cs_new:Npn \etl_act_put_back:n #1 #2 \__etl_act:w { #2 \__etl_act:w #1 }
@@ -214,6 +229,33 @@
   { \__etl_unexpanded:w { #1 #3 } }
 \cs_new:Npn \etl_act_break_post:n #1 #2 \__etl_act_result:n #3#4
   { \__etl_unexpanded:w { #3 #1 } }
+\cs_new:Npn \etl_act_apply_to_rest:n #1
+  {
+    \__etl_expanded:w { \__etl_unexpanded:w {#1} { \if_false: }} \fi:
+    \__etl_act_get_rest:w \prg_do_nothing:
+  }
+\cs_new:Npn \__etl_act_get_rest:w #1 \__etl_act:w #2#
+  {
+    \__etl_unexpanded:w {#2}
+    \__etl_act_get_rest_aux:nn {#1}
+  }
+\cs_new:Npn \__etl_act_get_rest_aux:nw #1 #2#
+  {
+    \__etl_unexpanded:w {#2}
+    \__etl_act_get_rest_aux:nn {#1}
+  }
+\cs_new:Npn \__etl_act_get_rest_aux:nn #1#2
+  {
+    \__etl_act_if_end:w #2 \__etl_act_get_rest_done:w \s__etl_stop
+    { \__etl_unexpanded:w {#2} }
+    \__etl_act_get_rest_aux:nw {#1}
+  }
+\cs_new:Npn \__etl_act_get_rest_done:w \s__etl_stop #1 \__etl_act_get_rest_aux:nw #2
+  {
+    \if_false: {{ \fi: } \exp_after:wN }
+    #2
+    \__etl_act:w { \s__etl_stop }
+  }
 \exp_args:Nno \use:n { \cs_new:Npn \etl_token_if_eq:NNTF #1#2 }
   {
     \token_if_eq_meaning:NNT {#1} {#2} { \str_if_eq:nnT #1#2 \use_ii:nnn }
@@ -477,10 +519,7 @@
 \exp_args:Nno \use:n { \cs_new:Npn \etl_token_replace_once:nNn #1#2#3 }
   {
     \etl_act:nnnnnn
-      {
-        \__etl_token_replace:NnnN #2
-          { \etl_act_switch_normal:n \__etl_act_unexpanded_normal:nN }
-      }
+      { \__etl_token_replace:NnnN #2 \__etl_act_unexpanded_rest:w }
       \__etl_act_unexpanded_space:n
       \__etl_act_unexpanded_group:nn
       \use_none:nn
@@ -494,7 +533,7 @@
       \__etl_replace_space:n
       \__etl_replace_group:nn
       \__etl_replace_final:nn
-      { {#2} {#2} {} {#3} \scan_stop: }
+      { {#2} {#2} {} {#3} \prg_do_nothing: }
       {#1}
   }
 \exp_args:Nno \use:n { \cs_new:Npn \__etl_replace_put_back:nnnN #1#2#3#4 }
@@ -539,15 +578,8 @@
         \__etl_if_empty:nTF {#2}
           {
             \__etl_unexpanded:w {#5}
-            \__etl_if_mark:nTF {#6}
-              {
-                \etl_act_switch:nnn
-                  \__etl_act_unexpanded_normal:nN
-                  \__etl_act_unexpanded_space:n
-                  \__etl_act_unexpanded_group:nn
-                \etl_act_status:n { {} {} {} {} #6 }
-              }
-              { \etl_act_status:n { {#3} {#3} {} {#5} #6 } }
+            #6
+            \etl_act_status:n { {#3} {#3} {} {#5} #6 }
           }
           { \etl_act_status:n { {#2} {#3} { #4 #7 } {#5} #6 } }
       }
@@ -571,15 +603,8 @@
     \__etl_if_empty:nTF {#1}
       {
         \__etl_unexpanded:w {#4}
-        \__etl_if_mark:nTF {#5}
-          {
-            \etl_act_switch:nnn
-              \__etl_act_unexpanded_normal:nN
-              \__etl_act_unexpanded_space:n
-              \__etl_act_unexpanded_group:nn
-            \etl_act_status:n { {} {} {} {} #5 }
-          }
-          { \etl_act_status:n { {#2} {#2} {} {#4} #5 } }
+        #5
+        \etl_act_status:n { {#2} {#2} {} {#4} #5 }
       }
       { \etl_act_status:n { {#1} {#2} { #3 ~ } {#4} #5 } }
   }
@@ -602,15 +627,8 @@
         \__etl_if_empty:nTF {#2}
           {
             \__etl_unexpanded:w {#5}
-            \__etl_if_mark:nTF {#6}
-              {
-                \etl_act_switch:nnn
-                  \__etl_act_unexpanded_normal:nN
-                  \__etl_act_unexpanded_space:n
-                  \__etl_act_unexpanded_group:nn
-                \etl_act_status:n { {} {} {} {} #6 }
-              }
-              { \etl_act_status:n { {#3} {#3} {} {#5} #6 } }
+            #6
+            \etl_act_status:n { {#3} {#3} {} {#5} #6 }
           }
           { \etl_act_status:n { {#2} {#3} { #4 {#7} } {#5} #6 } }
       }
@@ -627,7 +645,7 @@
       \__etl_replace_space:n
       \__etl_replace_group_deep:nn
       \__etl_replace_final:nn
-      { {#2} {#2} {} {#3} \scan_stop: }
+      { {#2} {#2} {} {#3} \prg_do_nothing: }
       {#1}
   }
 \cs_new:Npn \__etl_replace_group_deep:nn #1
@@ -679,7 +697,7 @@
       \__etl_replace_space:n
       \__etl_replace_group:nn
       \__etl_replace_final:nn
-      { {#2} {#2} {} {#3} \s__etl_mark }
+      { {#2} {#2} {} {#3} \__etl_act_unexpanded_rest:w }
       {#1}
   }
 \exp_args:Nno \use:n { \cs_new_protected:Npn \etl_new_if_in:Nnn #1#2#3 }
@@ -806,6 +824,7 @@
           }}
       }
   }
+\cs_undefine:N \__etl_act:nnnnnnn
 %% 
 %%
 %% End of file `etl.sty'.



More information about the tex-live-commits mailing list.