diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3tl.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3tl.dtx | 145 |
1 files changed, 89 insertions, 56 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx index cb617cc5a25..77444e6d13c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-08-14} +% \date{Released 2019-08-25} % % \maketitle % @@ -505,6 +505,10 @@ % % \section{Mapping to token lists} % +% All mappings are done at the current group level, \emph{i.e.}~any +% local assignments made by the \meta{function} or \meta{code} discussed +% below remain in effect after the loop. +% % \begin{function}[updated = 2012-06-29, rEXP] % {\tl_map_function:NN, \tl_map_function:cN} % \begin{syntax} @@ -555,8 +559,10 @@ % Stores each \meta{item} of the \meta{tl~var} in turn in the (token % list) \meta{variable} and applies the \meta{code}. The \meta{code} % will usually make use of the \meta{variable}, but this is not -% enforced. The assignments to the \meta{variable} are local. See -% also \cs{tl_map_inline:Nn}. +% enforced. The assignments to the \meta{variable} are local. Its +% value after the loop is the last \meta{item} in the \meta{tl~var}, +% or its original value if the \meta{tl~var} is blank. See also +% \cs{tl_map_inline:Nn}. % \end{function} % % \begin{function}[updated = 2012-06-29]{\tl_map_variable:nNn} @@ -567,6 +573,8 @@ % (token list) \meta{variable} and applies the \meta{code}. The % \meta{code} will usually make use of the \meta{variable}, but this % is not enforced. The assignments to the \meta{variable} are local. +% Its value after the loop is the last \meta{item} in the +% \meta{tl~var}, or its original value if the \meta{tl~var} is blank. % See also \cs{tl_map_inline:nn}. % \end{function} % @@ -1558,12 +1566,12 @@ % \begin{macro}[EXP]{\@@_rescan:NNw} % In a group, after some initial setup explained below and the user % setup~|#3| (followed by \cs{scan_stop:} to be safe), there is a call -% to \cs{@@_set_rescan:nNN}. This shared auxiliary distinguishes -% single-line and multi-line files as explained below. In the -% simplest case of multi-line files it calls (with the same arguments) +% to \cs{@@_set_rescan:nNN}. This shared auxiliary defined later +% distinguishes single-line and multi-line ``files''. In the simplest +% case of multi-line files, it calls (with the same arguments) % \cs{@@_set_rescan_multi:nNN}, whose code is included here to help -% understand the approach: it rescans its argument |#1|, closes the -% group, and performs the assignment. +% understand the approach. This function rescans its argument |#1|, +% closes the group, and performs the assignment. % % One difficulty when rescanning is that \tn{scantokens} treats the % argument as a file, and without the correct settings a \TeX{} error @@ -1575,9 +1583,9 @@ % \tn{scantokens} and closing it inside that temporary file; we avoid % that by setting \tn{tracingnesting}. The standard solution to the % ``File ended'' error is to grab the rescanned tokens as a delimited -% argument of an auxiliary, here \cs{@@_set_rescan:NNw}, that performs -% the assignment, then let \TeX{} ``execute'' the end of file marker. -% As usual in delimited arguments we use \cs{prg_do_nothing:} to avoid +% argument of an auxiliary, here \cs{@@_rescan:NNw}, that performs the +% assignment, then let \TeX{} ``execute'' the end of file marker. As +% usual in delimited arguments we use \cs{prg_do_nothing:} to avoid % stripping an outer set braces: this is removed by using % \texttt{o}-expanding assignments. The delimiter cannot appear % within the rescanned token list because it contains twice the same @@ -1589,6 +1597,19 @@ % rescanned result is code that looks further in the input stream for % arguments, it would break. % +% For multi-line files the only subtlety is that \tn{newlinechar} +% should be equal to \tn{endlinechar} because \tn{newlinechar} +% characters become new lines and then become \tn{endlinechar} +% characters when writing to an abstract file and reading back. This +% equality is ensured by setting \tn{newlinechar} equal to +% \tn{endlinechar}. Prior to this, \tn{endlinechar} is set to $-1$ if +% it was $32$ (in particular true after \cs{ExplSyntaxOn}) to avoid +% unreasonable line-breaks at every space for instance in error +% messages triggered by the user setup. Another side effect of +% reading back from the file is that spaces (catcode $10$) are ignored +% at the beginning of lines, and spaces and tabs (character code $32$ +% and $9$) are ignored at the end of lines. +% % The two \cs{if_false:} \ldots{} \cs{fi:} are there to prevent % alignment tabs to cause a change of tabular cell while rescanning. % We put the \enquote{opening} one after \cs{group_begin:} so that if @@ -1596,22 +1617,21 @@ % remain balanced. This is essential in \texttt{e}-type arguments % when \tn{expanded} is not available. % \begin{macrocode} -\cs_new_protected:Npn \tl_set_rescan:Nnn - { \@@_set_rescan:NNnn \tl_set:No } -\cs_new_protected:Npn \tl_gset_rescan:Nnn - { \@@_set_rescan:NNnn \tl_gset:No } \cs_new_protected:Npn \tl_rescan:nn #1#2 { \tl_set_rescan:Nnn \l_@@_internal_a_tl {#1} {#2} \exp_after:wN \tl_clear:N \exp_after:wN \l_@@_internal_a_tl \l_@@_internal_a_tl } +\cs_new_protected:Npn \tl_set_rescan:Nnn + { \@@_set_rescan:NNnn \tl_set:No } +\cs_new_protected:Npn \tl_gset_rescan:Nnn + { \@@_set_rescan:NNnn \tl_gset:No } \cs_new_protected:Npn \@@_set_rescan:NNnn #1#2#3#4 { \group_begin: \if_false: { \fi: \int_set_eq:NN \tex_tracingnesting:D \c_zero_int - \exp_args:No \tex_everyeof:D { \c_@@_rescan_marker_tl } \int_compare:nNnT \tex_endlinechar:D = { 32 } { \int_set:Nn \tex_endlinechar:D { -1 } } \int_set_eq:NN \tex_newlinechar:D \tex_endlinechar:D @@ -1621,6 +1641,7 @@ } \cs_new_protected:Npn \@@_set_rescan_multi:nNN #1#2#3 { + \exp_args:No \tex_everyeof:D { \c_@@_rescan_marker_tl } \exp_after:wN \@@_rescan:NNw \exp_after:wN #2 \exp_after:wN #3 @@ -1645,27 +1666,14 @@ % \end{macro} % % \begin{macro}{\@@_set_rescan:nNN} -% \begin{macro}{\@@_set_rescan_single:nnNN, \@@_set_rescan_single_aux:nnNN} -% This function calls \cs{@@_set_rescan_multi:nNN} or -% \cs{@@_set_rescan_single:nnNN} |{ ' }| depending on whether its -% argument is a single-line fragment of code/data or is made of -% multiple lines by testing for the presence of a \tn{newlinechar} -% character. If \tn{newlinechar} is out of range, the argument is -% assumed to be a single line. -% -% The case of multiple lines is a straightforward application of -% \tn{scantokens} as described above. The only subtlety is that -% \tn{newlinechar} should be equal to \tn{endlinechar} because -% \tn{newlinechar} characters become new lines and then become -% \tn{endlinechar} characters when writing to an abstract file and -% reading back. This equality is ensured by setting \tn{newlinechar} -% equal to \tn{endlinechar}. Prior to this, \tn{endlinechar} is set -% to $-1$ if it was $32$ (in particular true after \cs{ExplSyntaxOn}) -% to avoid unreasonable line-breaks at every space for instance in -% error messages triggered by the user setup. Another side effect of -% reading back from the file is that spaces (catcode $10$) are -% ignored at the beginning of lines, and spaces and tabs (character -% code $32$ and $9$) are ignored at the end of lines. +% \begin{macro}{\@@_set_rescan_single:nnNN, \@@_set_rescan_single_aux:nnnNN} +% \begin{macro}[rEXP]{\@@_set_rescan_single_aux:w} +% The function \cs{@@_set_rescan:nNN} calls \cs{@@_set_rescan_multi:nNN} or +% \cs{@@_set_rescan_single:nnNN} |{ ' }| depending on whether its argument +% is a single-line fragment of code/data or is made of multiple lines +% by testing for the presence of a \tn{newlinechar} character. If +% \tn{newlinechar} is out of range, the argument is assumed to be a +% single line. % % For a single line, no \tn{endlinechar} should be added, so it is % set to $-1$, and spaces should not be removed. @@ -1682,13 +1690,27 @@ % of starting point was made because this is the start of a very long % range of characters whose standard category is letter or other, % thus minimizing the number of steps needed by the loop (most often -% just a single one). Once a valid character is found, run some code -% very similar to \cs{@@_set_rescan_multi:nNN} but with that character -% put at the start and end. The auxiliary \cs{@@_rescan:NNw} must be -% redefined to also remove the additional character (with the -% appropriate catcode thanks to \cs{char_generate:nn}). If no valid -% character is found (very rare), fall-back on -% \cs{@@_set_rescan_multi:nNN}. +% just a single one). If no valid character is found (very rare), +% fall-back on \cs{@@_set_rescan_multi:nNN}. +% +% Otherwise, once a valid character is found (let us use |'| in this +% explanation) run some code very similar to \cs{@@_set_rescan_multi:nNN} +% but with |'| added at both ends of the input. Of course, we need to +% define the auxiliary \cs{@@_set_rescan_single:NNww} on the fly to remove +% the additional~|'| that is just before |::| (by which we mean +% \cs{c_@@_rescan_marker_tl}). Note that the argument must be +% delimited by |'| with the current catcode; this is done thanks to +% \cs{char_generate:nn}. Yet another issue is that the rescanned +% token list may contain a comment character, in which case the |'| we +% expected is not there. We fix this as follows: rather than just +% |::| we set \tn{everyeof} to |::|\Arg{code1} |'::|\Arg{code2} +% \cs{q_stop}. The auxiliary \cs{@@_set_rescan_single:NNww} runs the +% \texttt{o}-expanding assignment, expanding either \meta{code1} or +% \meta{code2} before its the main argument~|#3|. In the typical case +% without comment character, \meta{code1} is expanded, removing the +% leading~|'|. In the rarer case with comment character, \meta{code2} +% is expanded, calling \cs{@@_set_rescan_single_aux:w}, which removes the +% trailing |::|\Arg{code1} and the leading~|'|. % \begin{macrocode} \cs_new_protected:Npn \@@_set_rescan:nNN #1 { @@ -1710,7 +1732,8 @@ \int_compare:nNnTF { \char_value_catcode:n {#1} / 2 } = 6 { - \exp_args:Nf \@@_set_rescan_single_aux:nnNN + \exp_args:Nof \@@_set_rescan_single_aux:nnnNN + \c_@@_rescan_marker_tl { \char_generate:nn {#1} { \char_value_catcode:n {#1} } } } { @@ -1722,23 +1745,32 @@ { \@@_set_rescan_multi:nNN } } } -\cs_new_protected:Npn \@@_set_rescan_single_aux:nnNN #1#2#3#4 +\cs_new_protected:Npn \@@_set_rescan_single_aux:nnnNN #1#2#3#4#5 { - \exp_args:Nno \use:nn - { \cs_set:Npn \@@_rescan:NNw ##1##2##3 #1 } - \c_@@_rescan_marker_tl + \tex_everyeof:D + { + #1 \use_none:n + #2 #1 { \exp:w \@@_set_rescan_single_aux:w } + \q_stop + } + \cs_set:Npn \@@_rescan:NNw ##1##2##3 #2 #1 ##4 ##5 \q_stop { \group_end: - ##1 ##2 { \use_none:n ##3 } + ##1 ##2 { ##4 ##3 } } \exp_after:wN \@@_rescan:NNw - \exp_after:wN #3 \exp_after:wN #4 - \tex_scantokens:D { #1 #2 #1 } + \exp_after:wN #5 + \tex_scantokens:D { #2 #3 #2 } } +\exp_args:Nno \use:nn + { \cs_new:Npn \@@_set_rescan_single_aux:w #1 } + \c_@@_rescan_marker_tl #2 + { \use_i:nn \exp_end: #1 } % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % \subsection{Modifying token list variables} % @@ -2379,9 +2411,10 @@ % \begin{macro}{\tl_map_variable:nNn} % \begin{macro}{\tl_map_variable:NNn, \tl_map_variable:cNn} % \begin{macro}{\@@_map_variable:Nnn} -% \cs{tl_map_variable:nNn} \meta{token list} \meta{temp} \meta{action} -% assigns -% \meta{temp} to each element and executes \meta{action}. +% \cs{tl_map_variable:nNn} \meta{token list} \meta{tl~var} +% \meta{action} assigns \meta{tl~var} to each element and executes +% \meta{action}. The assignment to \meta{tl~var} is done after the +% quark test so that this variable does not get set to a quark. % \begin{macrocode} \cs_new_protected:Npn \tl_map_variable:nNn #1#2#3 { @@ -2393,8 +2426,8 @@ { \exp_args:No \tl_map_variable:nNn } \cs_new_protected:Npn \@@_map_variable:Nnn #1#2#3 { + \quark_if_recursion_tail_break:nN {#3} \tl_map_break: \tl_set:Nn #1 {#3} - \quark_if_recursion_tail_break:NN #1 \tl_map_break: \use:n {#2} \@@_map_variable:Nnn #1 {#2} } |