diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3tl.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3tl.dtx | 151 |
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} |