summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3tl.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3tl.dtx151
1 files changed, 87 insertions, 64 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
index 88874c36241..d5798d44b3a 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 5070 2014-06-06 18:00:24Z bruno $
+\GetIdInfo$Id: l3tl.dtx 5214 2014-07-17 08:39:43Z joseph $
{L3 Token lists}
%</driver|package>
%<*driver>
@@ -894,20 +894,6 @@
% \end{texnote}
% \end{function}
%
-% \begin{function}[added = 2011-08-10, EXP]{\str_head:n,\str_tail:n}
-% \begin{syntax}
-% \cs{str_head:n} \Arg{token list}
-% \cs{str_tail:n} \Arg{token list}
-% \end{syntax}
-% Converts the \meta{token list} into a string, as described for
-% \cs{tl_to_str:n}. The \cs{str_head:n} function then leaves
-% the first character of this string in the input stream.
-% The \cs{str_tail:n} function leaves all characters except
-% the first in the input stream. The first character may be
-% a space. If the \meta{token list} argument is entirely empty,
-% nothing is left in the input stream.
-% \end{function}
-%
% \begin{function}[updated = 2012-07-09, EXP, pTF]{\tl_if_head_eq_catcode:nN}
% \begin{syntax}
% \cs{tl_if_head_eq_catcode_p:nN} \Arg{token list} \meta{test token}
@@ -989,6 +975,27 @@
% a token by token basis.
% \end{function}
%
+% \section{Using a single item}
+%
+% \begin{function}[added = 2014-07-17, EXP]
+% {\tl_item:nn, \tl_item:Nn, \tl_item:cn}
+% \begin{syntax}
+% \cs{tl_item:nn} \Arg{token list} \Arg{integer expression}
+% \end{syntax}
+% Indexing items in the \meta{token list} from~$1$ on the left, this
+% function will evaluate the \meta{integer expression} and leave the
+% appropriate item from the \meta{token list} in the input stream.
+% If the \meta{integer expression} is negative, indexing occurs from
+% the right of the token list, starting at $-1$ for the right-most item.
+% If the index is out of bounds, then thr function expands to nothing.
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{item}
+% will not expand further when appearing in an \texttt{x}-type
+% argument expansion.
+% \end{texnote}
+% \end{function}
+%
% \section{Viewing token lists}
%
% \begin{function}[updated = 2012-09-09]{\tl_show:N, \tl_show:c}
@@ -1471,6 +1478,7 @@
% 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:}.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \tl_set_rescan:Nnn
{ \@@_set_rescan:NNnn \tl_set:Nn }
@@ -1484,7 +1492,7 @@
\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
- #3
+ #3 \scan_stop:
\use:x
{
\group_end:
@@ -1892,8 +1900,15 @@
% \begin{macro}[EXP, TF]{\tl_case:Nn, \tl_case:cn}
% \begin{macro}[EXP, aux]{\@@_case:nnTF}
% \begin{macro}[aux, EXP]{\@@_case:Nw}
+% \begin{macro}[int, EXP]{\__prg_case_end:nw}
% \begin{macro}[aux, EXP]{\@@_case_end:nw}
-% Similar set up to \cs{str_case:nn(TF)} as described in \pkg{l3basics}.
+% The aim here is to allow the case statement to be evaluated
+% using a known number of expansion steps (two), and without
+% needing to use an explicit \enquote{end of recursion} marker.
+% That is achieved by using the test input as the final case,
+% as this will always be true. The trick is then to tidy up
+% the output such that the appropriate case code plus either
+% the \texttt{true} or \texttt{false} branch code is inserted.
% \begin{macrocode}
\cs_new:Npn \tl_case:Nn #1#2
{
@@ -1927,6 +1942,20 @@
\cs_generate_variant:Nn \tl_case:NnT { c }
\cs_generate_variant:Nn \tl_case:NnF { c }
\cs_generate_variant:Nn \tl_case:NnTF { c }
+% \end{macrocode}
+% To tidy up the recursion, there are two outcomes. If there was a hit to
+% one of the cases searched for, then |#1| will be the code to insert,
+% |#2| will be the \emph{next} case to check on and |#3| will be all of
+% the rest of the cases code. That means that |#4| will be the \texttt{true}
+% branch code, and |#5| will be tidy up the spare \cs{q_mark} and the
+% \texttt{false} branch. On the other hand, if none of the cases matched
+% then we arrive here using the \enquote{termination} case of comparing
+% the search with itself. That means that |#1| will be empty, |#2| will be
+% the first \cs{q_mark} and so |#4| will be the \texttt{false} code (the
+% \texttt{true} code is mopped up by |#3|).
+% \begin{macrocode}
+\cs_new:Npn \__prg_case_end:nw #1#2#3 \q_mark #4#5 \q_stop
+ { \c_zero #1 #4 }
\cs_new_eq:NN \@@_case_end:nw \__prg_case_end:nw
% \end{macrocode}
% \end{macro}
@@ -1934,6 +1963,7 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \subsection{Mapping to token lists}
%
@@ -2356,7 +2386,7 @@
% \subsection{The first token from a token list}
%
% \begin{macro}{\tl_head:N, \tl_head:n, \tl_head:V, \tl_head:v, \tl_head:f}
-% \begin{macro}[aux]{\@@_head_auxi:nw, \@@_head_auxii:nw}
+% \begin{macro}[aux]{\@@_head_auxi:nw, \@@_head_auxii:n}
% \begin{macro}{\tl_head:w}
% \begin{macro}{\tl_tail:N, \tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f}
% Finding the head of a token list expandably will always strip braces, which
@@ -2377,8 +2407,8 @@
\if_false: { \fi: \@@_head_auxi:nw #1 { } \q_stop }
}
\cs_new:Npn \@@_head_auxi:nw #1#2 \q_stop
- { \exp_after:wN \@@_head_auxii:nw \exp_after:wN { \if_false: } \fi: {#1} }
-\cs_new:Npn \@@_head_auxii:nw #1
+ { \exp_after:wN \@@_head_auxii:n \exp_after:wN { \if_false: } \fi: {#1} }
+\cs_new:Npn \@@_head_auxii:n #1
{
\exp_after:wN \if_meaning:w \exp_after:wN \q_nil
\tl_to_str:n \exp_after:wN { \use_none:n #1 } \q_nil
@@ -2423,50 +2453,6 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\str_head:n, \str_tail:n}
-% \begin{macro}[aux]{\__str_head:w}
-% \begin{macro}[aux]{\__str_tail:w}
-% After \cs{tl_to_str:n}, we have a list of character tokens,
-% all with category code 12, except the space, which has category
-% code 10. Directly using \cs{tl_head:w} would thus lose leading spaces.
-% Instead, we take an argument delimited by an explicit space, and
-% then only use \cs{tl_head:w}. If the string started with a
-% space, then the argument of \cs{__str_head:w} is empty, and
-% the function correctly returns a space character. Otherwise,
-% it returns the first token of |#1|, which is the first token
-% of the string. If the string is empty, we return an empty result.
-%
-% To remove the first character of \cs{tl_to_str:n} |{#1}|,
-% we test it using \cs{if_charcode:w} \cs{scan_stop:},
-% always \texttt{false} for characters. If the argument was non-empty,
-% then \cs{__str_tail:w} returns everything until the first
-% \texttt{X} (with category code letter, no risk of confusing
-% with the user input). If the argument was empty, the first
-% \texttt{X} is taken by \cs{if_charcode:w}, and nothing
-% is returned. We use \texttt{X} as a \meta{marker}, rather than
-% a quark because the test \cs{if_charcode:w} \cs{scan_stop:}
-% \meta{marker} has to be \texttt{false}.
-% \begin{macrocode}
-\cs_new:Npn \str_head:n #1
- {
- \exp_after:wN \__str_head:w
- \tl_to_str:n {#1}
- { { } } ~ \q_stop
- }
-\cs_new:Npn \__str_head:w #1 ~ %
- { \tl_head:w #1 { ~ } }
-\cs_new:Npn \str_tail:n #1
- {
- \exp_after:wN \__str_tail:w
- \reverse_if:N \if_charcode:w
- \scan_stop: \tl_to_str:n {#1} X X \q_stop
- }
-\cs_new:Npn \__str_tail:w #1 X #2 \q_stop { \fi: #1 }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
% \begin{macro}[pTF]{\tl_if_head_eq_meaning:nN}
% \begin{macro}[pTF]{\tl_if_head_eq_charcode:nN}
% \begin{macro}[pTF]{\tl_if_head_eq_charcode:fN}
@@ -2670,6 +2656,43 @@
% \end{macro}
% \end{macro}
%
+% \subsection{Using a single item}
+%
+% \begin{macro}{\tl_item:nn, \tl_item:Nn, \tl_item:cn}
+% \begin{macro}[aux]{\@@_item:nn}
+% The idea here is to find the offset of the item from the left, then use
+% a loop to grab the correct item. If the resulting offset is too large,
+% then \cs{quark_if_recursion_tail_stop:n} terminates the loop, and returns
+% nothing at all.
+% \begin{macrocode}
+\cs_new:Npn \tl_item:nn #1#2
+ {
+ \exp_args:Nf \@@_item:nn
+ {
+ \int_eval:n
+ {
+ \int_compare:nNnT {#2} < \c_zero
+ { \tl_count:n {#1} + \c_one + }
+ #2
+ }
+ }
+ #1
+ \q_recursion_tail
+ \__prg_break_point:
+ }
+\cs_new:Npn \@@_item:nn #1#2
+ {
+ \__quark_if_recursion_tail_break:nN {#2} \__prg_break:
+ \int_compare:nNnTF {#1} = \c_one
+ { \__prg_break:n { \exp_not:n {#2} } }
+ { \exp_args:Nf \@@_item:nn { \int_eval:n { #1 - 1 } } }
+ }
+\cs_new_nopar:Npn \tl_item:Nn { \exp_args:No \tl_item:nn }
+\cs_generate_variant:Nn \tl_item:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \subsection{Viewing token lists}
%
% \begin{macro}{\tl_show:N, \tl_show:c}