diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3tl.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3tl.dtx | 359 |
1 files changed, 263 insertions, 96 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx index 30347d12150..59d0b161e94 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} %</driver> %<*driver|package> -\GetIdInfo$Id: l3tl.dtx 5659 2015-07-14 18:58:00Z joseph $ +\GetIdInfo$Id: l3tl.dtx 5908 2015-09-02 14:50:27Z joseph $ {L3 Token lists} %</driver|package> %<*driver> @@ -323,7 +323,15 @@ % % \section{Reassigning token list category codes} % -% \begin{function}[updated = 2011-12-18] +% These functions allow the rescanning of tokens: re-apply \TeX{}'s +% tokenization process to apply category codes different from those +% in force when the tokens were absorbed. Whilst this functionality is +% supported, it is often preferable to find alternative approaches +% to achieving outcomes rather than rescanning tokens (for example +% construction of token lists token-by-token with intervening category +% code changes). +% +% \begin{function}[updated = 2015-08-11] % { % \tl_set_rescan:Nnn, \tl_set_rescan:Nno, \tl_set_rescan:Nnx, % \tl_set_rescan:cnn, \tl_set_rescan:cno, \tl_set_rescan:cnx, @@ -333,29 +341,60 @@ % \begin{syntax} % \cs{tl_set_rescan:Nnn} \meta{tl~var} \Arg{setup} \Arg{tokens} % \end{syntax} -% Sets \meta{tl~var} to contain \meta{tokens}, -% applying the category code r\'{e}gime specified in the -% \meta{setup} before carrying out the assignment. This allows the -% \meta{tl~var} to contain material with category codes -% other than those that apply when \meta{tokens} are absorbed. -% Trailing spaces at the end of the \meta{tokens} are discarded -% in the rescanning process. The \meta{setup} is not limited to -% changes of category code but may contain any valid input, for -% example assignment of the expansion of active tokens. -% See also \cs{tl_rescan:nn}. +% Sets \meta{tl~var} to contain \meta{tokens}, applying the category +% code r\'{e}gime specified in the \meta{setup} before carrying out +% the assignment. (Category codes applied to tokens not explicitly covered +% by the \meta{setup} will be those in force at the point of use of +% \cs{tl_set_rescan:Nnn}.) +% This allows the \meta{tl~var} to contain material +% with category codes other than those that apply when \meta{tokens} +% are absorbed. The \meta{setup} is run within a group and may +% contain any valid input, although only changes in category codes +% are relevant. See also \cs{tl_rescan:nn}. +% \begin{texnote} +% The \meta{tokens} are first turned into a string (using +% \cs{tl_to_str:n}). If the string contains one or more characters +% with character code \tn{newlinechar} (set equal to +% \tn{endlinechar} unless that is equal to $32$, before the user +% \meta{setup}), then it is split into lines at these characters, +% then read as if reading multiple lines from a file, ignoring +% spaces (catcode $10$) at the beginning and spaces and tabs +% (character code $32$ or $9$) at the end of every line. +% Otherwise, spaces (and tabs) are retained at both ends of the +% single-line string, as if it appeared in the middle of a line +% read from a file. Only the case of a single line is supported in +% \LuaTeX{} because of a bug in this engine. +% \end{texnote} % \end{function} % -% \begin{function}[updated = 2011-12-18]{\tl_rescan:nn} +% \begin{function}[updated = 2015-08-11]{\tl_rescan:nn} % \begin{syntax} % \cs{tl_rescan:nn} \Arg{setup} \Arg{tokens} % \end{syntax} -% Rescans \meta{tokens} applying the category code r\'{e}gime specified -% in the \meta{setup}, and leaves the resulting tokens in the input -% stream. Trailing spaces at the end of the \meta{tokens} are discarded -% in the rescanning process. The \meta{setup} is not limited to -% changes of category code but may contain any valid input, for -% example assignment of the expansion of active tokens. -% See also \cs{tl_set_rescan:Nnn}. +% Rescans \meta{tokens} applying the category code r\'{e}gime +% specified in the \meta{setup}, and leaves the resulting tokens in +% the input stream. (Category codes applied to tokens not explicitly covered +% by the \meta{setup} will be those in force at the point of use of +% \cs{tl_rescan:nn}.) +% The \meta{setup} is run within a group and may +% contain any valid input, although only changes in category codes +% are relevant. See also \cs{tl_set_rescan:Nnn}, which is more +% robust than using \cs{tl_set:Nn} in the \meta{tokens} argument of +% \cs{tl_rescan:nn}. +% \begin{texnote} +% The \meta{tokens} are first turned into a string (using +% \cs{tl_to_str:n}). If the string contains one or more characters +% with character code \tn{newlinechar} (set equal to +% \tn{endlinechar} unless that is equal to $32$, before the user +% \meta{setup}), then it is split into lines at these characters, +% then read as if reading multiple lines from a file, ignoring +% spaces (catcode $10$) at the beginning and spaces and tabs +% (character code $32$ or $9$) at the end of every line. +% Otherwise, spaces (and tabs) are retained at both ends of the +% single-line string, as if it appeared in the middle of a line +% read from a file. Only the case of a single line is supported in +% \LuaTeX{} because of a bug in this engine. +% \end{texnote} % \end{function} % % \section{Reassigning token list character codes} @@ -424,8 +463,8 @@ % \begin{function}[EXP,pTF] % {\tl_if_eq:NN, \tl_if_eq:Nc, \tl_if_eq:cN, \tl_if_eq:cc} % \begin{syntax} -% \cs{tl_if_eq_p:NN} \Arg{tl~var_1} \Arg{tl~var_2} -% \cs{tl_if_eq:NNTF} \Arg{tl~var_1} \Arg{tl~var_2} \Arg{true code} \Arg{false code} +% \cs{tl_if_eq_p:NN} \meta{tl~var_1} \meta{tl~var_2} +% \cs{tl_if_eq:NNTF} \meta{tl~var_1} \meta{tl~var_2} \Arg{true code} \Arg{false code} % \end{syntax} % Compares the content of two \meta{token list variables} and % is logically \texttt{true} if the two contain the same list of @@ -441,7 +480,7 @@ % % \begin{function}[TF]{\tl_if_eq:nn} % \begin{syntax} -% \cs{tl_if_eq:nnTF} \meta{token list_1} \Arg{token list_2} \Arg{true code} \Arg{false code} +% \cs{tl_if_eq:nnTF} \Arg{token list_1} \Arg{token list_2} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if \meta{token list_1} and \meta{token list_2} contain the % same list of tokens, both in respect of character codes and category @@ -998,7 +1037,7 @@ % % \section{Viewing token lists} % -% \begin{function}[updated = 2012-09-09]{\tl_show:N, \tl_show:c} +% \begin{function}[updated = 2015-08-01]{\tl_show:N, \tl_show:c} % \begin{syntax} % \cs{tl_show:N} \meta{tl~var} % \end{syntax} @@ -1009,7 +1048,7 @@ % \end{texnote} % \end{function} % -% \begin{function}[updated = 2012-09-09]{\tl_show:n} +% \begin{function}[updated = 2015-08-07]{\tl_show:n} % \begin{syntax} % \cs{tl_show:n} \meta{token list} % \end{syntax} @@ -1189,7 +1228,7 @@ \prg_new_eq_conditional:NNn \tl_if_exist:c \cs_if_exist:c { TF , T , F , p } % \end{macrocode} % \end{macro} -%% +% % \subsection{Constant token lists} % % \begin{variable}{\c_empty_tl} @@ -1358,7 +1397,7 @@ \tex_ifodd:D \l@expl@check@declarations@bool \cs_set_protected:Npn \__cs_tmp:w #1 { - \if_meaning:w ? #1 + \if_meaning:w \q_recursion_tail #1 \exp_after:wN \use_none_delimit_by_q_recursion_stop:w \fi: \use:x @@ -1382,7 +1421,7 @@ \tl_put_right:No \tl_put_right:Nx \tl_gput_right:Nn \tl_gput_right:NV \tl_gput_right:No \tl_gput_right:Nx - ? \q_recursion_stop + \q_recursion_tail \q_recursion_stop %</package> % \end{macrocode} % The two \texttt{set_eq} functions are done by hand as the internals there @@ -1430,9 +1469,9 @@ % % \begin{variable}{\c_@@_rescan_marker_tl} % The rescanning code needs a special token list containing the same -% character with two different category codes. This is set up here, -% while the detail is described below. Note that we are sure that the -% colon has category letter at this stage. +% character (chosen here to be a colon) with two different category +% codes: it cannot appear in the tokens being rescanned since all +% colons have the same category code. % \begin{macrocode} \tl_const:Nx \c_@@_rescan_marker_tl { : \token_to_str:N : } % \end{macrocode} @@ -1449,25 +1488,35 @@ % \tl_gset_rescan:cnn, \tl_gset_rescan:cno, \tl_gset_rescan:cnx % } % \begin{macro}{\tl_rescan:nn} -% \begin{macro}[aux]{\@@_set_rescan:NNnn} -% \begin{macro}[aux]{\@@_rescan:w} -% The idea here is to deal cleanly with the problem that -% \tn{scantokens} treats the argument as a file, and without -% the correct settings a \TeX{} error occurs: +% \begin{macro}[aux]{\@@_set_rescan:NNnn, \@@_set_rescan_multi:n} +% \begin{macro}[aux, EXP]{\@@_rescan:w} +% These functions use a common auxiliary. After some initial setup +% explained below, and the user setup |#3| (followed by +% \cs{scan_stop:} to be safe), the tokens are rescanned by +% \cs{@@_set_rescan:n} and stored into \cs{l_@@_internal_a_tl}, then +% passed to |#1#2| outside the group after expansion. The auxiliary +% \cs{@@_set_rescan:n} is defined later: in the simplest case, this +% auxiliary calls \cs{@@_set_rescan_multi:n}, whose code is included +% here to help understand the approach. +% +% One difficulty when rescanning is that \tn{scantokens} treats the +% argument as a file, and without the correct settings a \TeX{} error +% occurs: % \begin{verbatim} % ! File ended while scanning definition of ... % \end{verbatim} -% When expanding a token list this can be handled using \cs{exp_not:N} -% but this fails if the token list is not being expanded. So instead -% a delimited argument is used with an end marker which cannot appear -% within the token list which is scanned: two `|:|' symbols with different -% category codes. The rescanned token list cannot contain the end marker, -% because all `|:|' present in the token list are read with the same category -% code. As every character with charcode \tn{newlinechar} is replaced -% by the \tn{endlinechar}, and an extra \tn{endlinechar} is -% added at the end, we need to set both of those to $-1$, -% \enquote{unprintable}. -% To be safe, the \meta{setup} |#3| is followed by \cs{scan_stop:}. +% The standard solution is to use an \texttt{x}-expanding assignment +% and set \tn{everyeof} to \cs{exp_not:N} to suppress the error at +% the end of the file. Since the rescanned tokens should not be +% expanded, they will be taken as a delimited argument of an +% auxiliary which wraps them in \cs{exp_not:n} (in fact +% \cs{exp_not:o}, as there is a \cs{prg_do_nothing:} to avoid losing +% braces). The delimiter cannot appear within the rescanned token +% list because it contains twice the same character, with different +% catcodes. +% +% The difference between single-line and multiple-line files +% complicates the story, as explained below. % \begin{macrocode} \cs_new_protected_nopar:Npn \tl_set_rescan:Nnn { \@@_set_rescan:NNnn \tl_set:Nn } @@ -1479,26 +1528,27 @@ { \group_begin: \exp_args:No \etex_everyeof:D { \c_@@_rescan_marker_tl \exp_not:N } - \tex_endlinechar:D \c_minus_one - \tex_newlinechar:D \c_minus_one + \int_compare:nNnT \tex_endlinechar:D = { 32 } + { \tex_endlinechar:D \c_minus_one } + \tex_newlinechar:D \tex_endlinechar:D #3 \scan_stop: - \use:x - { - \group_end: - #1 \exp_not:N #2 - { - \exp_after:wN \@@_rescan:w - \exp_after:wN \prg_do_nothing: - \etex_scantokens:D {#4} - } - } + \exp_args:No \@@_set_rescan:n { \tl_to_str:n {#4} } + \exp_args:NNNo + \group_end: + #1 #2 \l_@@_internal_a_tl } -\use:x +\cs_new_protected:Npn \@@_set_rescan_multi:n #1 { - \cs_new:Npn \exp_not:N \@@_rescan:w ##1 - \c_@@_rescan_marker_tl - { \exp_not:N \exp_not:o { ##1 } } + \tl_set:Nx \l_@@_internal_a_tl + { + \exp_after:wN \@@_rescan:w + \exp_after:wN \prg_do_nothing: + \etex_scantokens:D {#1} + } } +\exp_args:Nno \use:nn + { \cs_new:Npn \@@_rescan:w #1 } \c_@@_rescan_marker_tl + { \exp_not:o {#1} } \cs_generate_variant:Nn \tl_set_rescan:Nnn { Nno , Nnx } \cs_generate_variant:Nn \tl_set_rescan:Nnn { c , cno , cnx } \cs_generate_variant:Nn \tl_gset_rescan:Nnn { Nno , Nnx } @@ -1510,6 +1560,130 @@ % \end{macro} % \end{macro} % +% \begin{macro}[aux]{\@@_set_rescan:n, \@@_set_rescan:NnTF} +% \begin{macro}[aux]{\@@_set_rescan_single:nn, \@@_set_rescan_single_aux:nn} +% This function calls \cs{@@_set_rescan_multiple:n} or +% \cs{@@_set_rescan_single:nn} |{ ' }| 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. +% +% For a single line, no \tn{endlinechar} should be added, so it will +% be set to $-1$, and spaces should not be removed. +% +% Trailing spaces and tabs are a difficult matter, as \TeX{} removes +% these at a very low level. The only way to preserve them is to +% rescan not the argument but the argument followed by a character +% with a reasonable category code. Here, $11$ (letter), $12$ (other) +% and $13$ (active) are accepted, as these are suitable for +% delimiting an argument, and it is very unlikely that none of the +% ASCII characters are in one of these categories. To avoid +% selecting one particular character to put at the end, whose +% category code may have been modified, there is a loop through +% characters from |'| (ASCII $39$) to |~| (ASCII $127$). The choice +% 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:n}, except that +% \cs{@@_rescan:w} must be redefined to also remove the additional +% character (with the appropriate catcode). Getting the delimiter +% with the right catcode requires using \tn{scantokens} inside an +% \texttt{x}-expansion, hence using the previous definition of +% \cs{@@_rescan:w} as well. The odd \cs{exp_not:N} \cs{use:n} +% ensures that the trailing \cs{exp_not:N} in \tn{everyeof} does +% not prevent the expansion of \cs{c_@@_rescan_marker_tl}, but +% rather of a closing brace (this does nothing). +% If no valid character is found, similar code is ran, +% and the only difference is that trailing spaces are not preserved +% (bear in mind that this only happens if no character between $39$ +% and $127$ has catcode letter, other or active). +% +% There is also some work to preserve leading spaces: test whether +% the first character (given by \cs{str_head:n}, with an extra space +% to circumvent a limitation of \texttt{f}-expansion) has catcode +% $10$ and add what \TeX{} would add in the middle of a line for any +% sequence of such characters: a single space with catcode $10$ and +% character code $32$. +% \begin{macrocode} +\group_begin: + \tex_catcode:D `\^^@ = 12 \scan_stop: + \cs_new_protected:Npn \@@_set_rescan:n #1 + { + \int_compare:nNnTF \tex_newlinechar:D < \c_zero + { \use_ii:nn } + { + \char_set_lccode:nn { 0 } { \tex_newlinechar:D } + \tl_to_lowercase:n { \@@_set_rescan:NnTF ^^@ } {#1} + } + { \@@_set_rescan_multi:n } + { \@@_set_rescan_single:nn { ' } } + {#1} + } + \cs_new_protected:Npn \@@_set_rescan:NnTF #1#2 + { \tl_if_in:nnTF {#2} {#1} } + \cs_new_protected:Npn \@@_set_rescan_single:nn #1 + { + \int_compare:nNnTF + { \char_value_catcode:n { `#1 } / \c_three } = \c_four + { \@@_set_rescan_single_aux:nn {#1} } + { + \int_compare:nNnTF { `#1 } < { `\~ } + { + \char_set_lccode:nn { 0 } { `#1 + 1 } + \tl_to_lowercase:n { \@@_set_rescan_single:nn { ^^@ } } + } + { \@@_set_rescan_single_aux:nn { } } + } + } + \cs_new_protected:Npn \@@_set_rescan_single_aux:nn #1#2 + { + \tex_endlinechar:D \c_minus_one + \use:x + { + \exp_not:N \use:n + { + \exp_not:n { \cs_set:Npn \@@_rescan:w ##1 } + \exp_after:wN \@@_rescan:w + \exp_after:wN \prg_do_nothing: + \etex_scantokens:D {#1} + } + \c_@@_rescan_marker_tl + } + { \exp_not:o {##1} } + \tl_set:Nx \l_@@_internal_a_tl + { + \int_compare:nNnT + { + \char_value_catcode:n + { \exp_last_unbraced:Nf ` \str_head:n {#2} ~ } + } + = \c_ten { ~ } + \exp_after:wN \@@_rescan:w + \exp_after:wN \prg_do_nothing: + \etex_scantokens:D { #2 #1 } + } + } +\group_end: +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \subsection{Reassigning token list character codes} % % \begin{macro}{\tl_to_lowercase:n} @@ -1760,7 +1934,7 @@ % % \subsection{Token list conditionals} % -% \begin{macro}[pTF]{\tl_if_blank:n,\tl_if_blank:V,\tl_if_blank:o} +% \begin{macro}[pTF]{\tl_if_blank:n, \tl_if_blank:V, \tl_if_blank:o} % \begin{macro}[aux]{\@@_if_blank_p:NNw} % \TeX{} skips spaces when reading a non-delimited arguments. Thus, % a \meta{token list} is blank if and only if \cs{use_none:n} @@ -1784,7 +1958,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}[pTF]{\tl_if_empty:N,\tl_if_empty:c} +% \begin{macro}[pTF]{\tl_if_empty:N, \tl_if_empty:c} % These functions check whether the token list in the argument is % empty and execute the proper code from their argument(s). % \begin{macrocode} @@ -1803,7 +1977,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[pTF]{\tl_if_empty:n,\tl_if_empty:V} +% \begin{macro}[pTF]{\tl_if_empty:n, \tl_if_empty:V} % Convert the argument to a string: this will be empty if and only if % the argument is. Then |\if_meaning:w \q_nil ... \q_nil| is % \texttt{true} if and only if the string |...| is empty. @@ -1842,13 +2016,13 @@ % The test for emptiness is based on \cs{tl_if_empty:n(TF)}, but % the expansion is hard-coded for efficiency, as this auxiliary % function is used in many places. -% Note that this works because \cs{tl_to_str:n} expands tokens +% Note that this works because \cs{etex_detokenize:D} expands tokens % that follow until reading a catcode $1$ (begin-group) token. % \begin{macrocode} \cs_new:Npn \@@_if_empty_return:o #1 { \exp_after:wN \if_meaning:w \exp_after:wN \q_nil - \tl_to_str:n \exp_after:wN {#1} \q_nil + \etex_detokenize:D \exp_after:wN {#1} \q_nil \prg_return_true: \else: \prg_return_false: @@ -2006,22 +2180,22 @@ % \begin{macrocode} \cs_new:Npn \tl_case:Nn #1#2 { - \tex_romannumeral:D + \exp:w \@@_case:NnTF #1 {#2} { } { } } \cs_new:Npn \tl_case:NnT #1#2#3 { - \tex_romannumeral:D + \exp:w \@@_case:NnTF #1 {#2} {#3} { } } \cs_new:Npn \tl_case:NnF #1#2#3 { - \tex_romannumeral:D + \exp:w \@@_case:NnTF #1 {#2} { } {#3} } \cs_new:Npn \tl_case:NnTF #1#2 { - \tex_romannumeral:D + \exp:w \@@_case:NnTF #1 {#2} } \cs_new:Npn \@@_case:NnTF #1#2#3#4 @@ -2153,10 +2327,7 @@ % \subsection{Using token lists} % % \begin{macro}{\tl_to_str:n} -% Another name for a primitive. -% \begin{macrocode} -\cs_new_eq:NN \tl_to_str:n \etex_detokenize:D -% \end{macrocode} +% Another name for a primitive: defined in \pkg{l3basics}. % \end{macro} % % \begin{macro}{\tl_to_str:N, \tl_to_str:c} @@ -2332,7 +2503,7 @@ % % \subsection{Token by token changes} % -% \begin{variable}{\q_@@_act_mark,\q_@@_act_stop} +% \begin{variable}{\q_@@_act_mark, \q_@@_act_stop} % The \cs{tl_act} functions may be applied to any token list. % Hence, we use two private quarks, to allow any token, even quarks, % in the token list.^^A in particular critical for future \::e. @@ -2349,7 +2520,7 @@ % \begin{macro}[EXP,aux]{\@@_act_space:wwnNNN} % \begin{macro}[EXP,aux]{\@@_act_end:w} % To help control the expansion, \cs{@@_act:NNNnn} should always -% be proceeded by \tn{romannumeral} and ends by producing \cs{c_zero} +% be proceeded by \cs{exp:w} and ends by producing \cs{exp_end:} % once the result has been obtained. Then loop over tokens, % groups, and spaces in |#5|. The marker \cs{q_@@_act_mark} % is used both to avoid losing outer braces and to detect the @@ -2367,8 +2538,8 @@ % In the loop, we check how the token list begins and act % accordingly. In the \enquote{normal} case, we may have % reached \cs{q_@@_act_mark}, the end of the list. Then -% leave \cs{c_zero} and the result in the input stream, -% to terminate the expansion of \tn{romannumeral}. +% leave \cs{exp_end:} and the result in the input stream, +% to terminate the expansion of \cs{exp:w}. % Otherwise, apply the relevant function to the % \enquote{arguments}, |#3| % and to the head of the token list. Then repeat the loop. @@ -2397,7 +2568,7 @@ {#3} #4 } \cs_new:Npn \@@_act_end:wn #1 \@@_act_result:n #2 - { \group_align_safe_end: \c_zero #2 } + { \group_align_safe_end: \exp_end: #2 } \cs_new:Npn \@@_act_group:nwnNNN #1 #2 \q_@@_act_stop #3#4#5 { #5 {#3} {#1} @@ -2445,7 +2616,7 @@ { \etex_unexpanded:D \exp_after:wN { - \tex_romannumeral:D + \exp:w \@@_act:NNNnn \@@_reverse_normal:nN \@@_reverse_group_preserve:nn @@ -2750,20 +2921,20 @@ % |\if_false: { \fi: ... }| construction) both to hide potential % alignment tab characters from \TeX{} in a table, and to allow for % removing what remains of the token list after its first space. The -% \cs{tex_romannumeral:D} and \cs{c_zero} ensure that the result of a +% \cs{exp:w} and \cs{exp_end:} ensure that the result of a % single step of expansion directly yields a balanced token list (no % trailing closing brace). % \begin{macrocode} \prg_new_conditional:Npnn \tl_if_head_is_space:n #1 { p , T , F , TF } { - \tex_romannumeral:D \if_false: { \fi: + \exp:w \if_false: { \fi: \@@_if_head_is_space:w ? #1 ? ~ } } \cs_new:Npn \@@_if_head_is_space:w #1 ~ { \tl_if_empty:oTF { \use_none:n #1 } - { \exp_after:wN \c_zero \exp_after:wN \prg_return_true: } - { \exp_after:wN \c_zero \exp_after:wN \prg_return_false: } + { \exp_after:wN \exp_end: \exp_after:wN \prg_return_true: } + { \exp_after:wN \exp_end: \exp_after:wN \prg_return_false: } \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi: } % \end{macrocode} @@ -2811,30 +2982,26 @@ % % \begin{macro}{\tl_show:N, \tl_show:c} % Showing token list variables is done after checking that the -% variable is defined (see \cs{__kernel_register_show:N}. +% variable is defined (see \cs{__kernel_register_show:N}). % \begin{macrocode} \cs_new_protected:Npn \tl_show:N #1 { - \tl_if_exist:NTF #1 - { \cs_show:N #1 } - { - \__msg_kernel_error:nnx { kernel } { variable-not-defined } - { \token_to_str:N #1 } - } + \__msg_show_variable:NNNnn #1 \tl_if_exist:NTF ? { } + { > ~ \token_to_str:N #1 = \tl_to_str:N #1 } } \cs_generate_variant:Nn \tl_show:N { c } % \end{macrocode} % \end{macro} % % \begin{macro}{\tl_show:n} -% The \cs{__msg_show_variable:n} internal function performs -% line-wrapping, removes a leading \verb*|> |, then shows the result +% The \cs{__msg_show_wrap:n} internal function performs +% line-wrapping and shows the result % using the \cs{etex_showtokens:D} primitive. Since \cs{tl_to_str:n} % is expanded within the line-wrapping code, the escape character is % always a backslash. % \begin{macrocode} \cs_new_protected:Npn \tl_show:n #1 - { \__msg_show_variable:n { > ~ \tl_to_str:n {#1} } } + { \__msg_show_wrap:n { > ~ \tl_to_str:n {#1} } } % \end{macrocode} % \end{macro} % |