diff options
author | Karl Berry <karl@freefriends.org> | 2014-07-20 22:14:30 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2014-07-20 22:14:30 +0000 |
commit | 6c2678db440b5260ec13602bde6efebdd00f8549 (patch) | |
tree | ed93fc7244f4e5ef1baf86ccb157597dabf6ac1e /Master/texmf-dist/source/latex/l3kernel/l3seq.dtx | |
parent | 9790eead4cceaffc951c93887d06de70c02e196a (diff) |
l3
git-svn-id: svn://tug.org/texlive/trunk@34671 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3seq.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3seq.dtx | 190 |
1 files changed, 189 insertions, 1 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx index 6924433ab00..813aee51c33 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} %</driver> %<*driver|package> -\GetIdInfo$Id: l3seq.dtx 4712 2014-04-30 08:17:49Z joseph $ +\GetIdInfo$Id: l3seq.dtx 5232 2014-07-18 19:32:54Z joseph $ {L3 Sequences and stacks} %</driver|package> %<*driver> @@ -116,6 +116,22 @@ % \meta{sequence_2}. % \end{function} % +% \begin{function}[added = 2014-07-17] +% { +% \seq_set_from_clist:NN, \seq_set_from_clist:cN, +% \seq_set_from_clist:Nc, \seq_set_from_clist:cc, +% \seq_set_from_clist:Nn, \seq_set_from_clist:cn, +% \seq_gset_from_clist:NN, \seq_gset_from_clist:cN, +% \seq_gset_from_clist:Nc, \seq_gset_from_clist:cc, +% \seq_gset_from_clist:Nn, \seq_gset_from_clist:cn +% } +% \begin{syntax} +% \cs{seq_set_from_clist:NN} \meta{sequence} \meta{comma-list} +% \end{syntax} +% Converts the data in the \meta{comma list} into a \meta{sequence}: +% the original \meta{comma list} is unchanged. +% \end{function} +% % \begin{function}[added = 2011-08-15, updated = 2012-07-02] % { % \seq_set_split:Nnn , \seq_set_split:NnV , @@ -273,6 +289,26 @@ % contain the special marker \cs{q_no_value}. % \end{function} % +% \begin{function}[added = 2014-07-17, EXP]{\seq_item:Nn, \seq_item:cn} +% \begin{syntax} +% \cs{seq_item:Nn} \meta{sequence} \Arg{integer expression} +% \end{syntax} +% Indexing items in the \meta{sequence} from~$1$ at the top (left), this +% function will evaluate the \meta{integer expression} and leave the +% appropriate item from the sequence in the input stream. If the +% \meta{integer expression} is negative, indexing occurs from the +% bottom (right) of the sequence. When the \meta{integer expression} +% is larger than the number of items in the \meta{sequence} (as +% calculated by \cs{seq_count:N}) then the function will expand 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{Recovering values from sequences with branching} % % The functions in this section combine tests for non-empty sequences @@ -407,6 +443,18 @@ % \cs{tl_if_eq:nn(TF)}. % \end{function} % +% +% \begin{function}[added = 2014-07-18]^^A +% {^^A +% \seq_reverse:N, \seq_reverse:c, +% \seq_greverse:N, \seq_greverse:c +% } +% \begin{syntax} +% \cs{seq_reverse:N} \meta{sequence} +% \end{syntax} +% Reverses the order of the items stored in the \meta{sequence}. +% \end{function} +% % \section{Sequence conditionals} % % \begin{function}[EXP,pTF]{\seq_if_empty:N, \seq_if_empty:c} @@ -885,6 +933,51 @@ % % \begin{macro} % { +% \seq_set_from_clist:NN, \seq_set_from_clist:cN, +% \seq_set_from_clist:Nc, \seq_set_from_clist:cc, +% \seq_set_from_clist:Nn, \seq_set_from_clist:cn +% } +% \begin{macro} +% { +% \seq_gset_from_clist:NN, \seq_gset_from_clist:cN, +% \seq_gset_from_clist:Nc, \seq_gset_from_clist:cc, +% \seq_gset_from_clist:Nn, \seq_gset_from_clist:cn +% } +% Setting a sequence from a comma-separated list is done using a simple +% mapping. +% \begin{macrocode} +\cs_new_protected:Npn \seq_set_from_clist:NN #1#2 + { + \tl_set:Nx #1 + { \s_@@ \clist_map_function:NN #2 \@@_wrap_item:n } + } +\cs_new_protected:Npn \seq_set_from_clist:Nn #1#2 + { + \tl_set:Nx #1 + { \s_@@ \clist_map_function:nN {#2} \@@_wrap_item:n } + } +\cs_new_protected:Npn \seq_gset_from_clist:NN #1#2 + { + \tl_gset:Nx #1 + { \s_@@ \clist_map_function:NN #2 \@@_wrap_item:n } + } +\cs_new_protected:Npn \seq_gset_from_clist:Nn #1#2 + { + \tl_gset:Nx #1 + { \s_@@ \clist_map_function:nN {#2} \@@_wrap_item:n } + } +\cs_generate_variant:Nn \seq_set_from_clist:NN { Nc } +\cs_generate_variant:Nn \seq_set_from_clist:NN { c , cc } +\cs_generate_variant:Nn \seq_set_from_clist:Nn { c } +\cs_generate_variant:Nn \seq_gset_from_clist:NN { Nc } +\cs_generate_variant:Nn \seq_gset_from_clist:NN { c , cc } +\cs_generate_variant:Nn \seq_gset_from_clist:Nn { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro} +% { % \seq_set_split:Nnn , \seq_set_split:NnV , % \seq_gset_split:Nnn, \seq_gset_split:NnV % } @@ -1155,6 +1248,65 @@ % \end{macro} % \end{macro} % +% \begin{macro} +% {\seq_reverse:N, \seq_reverse:c, \seq_greverse:N, \seq_greverse:c} +% \begin{macro}[aux]{\@@_reverse:NN} +% \begin{macro}[aux, EXP]{\@@_reverse_item:nwn} +% Previously, \cs{seq_reverse:N} was coded by collecting the items +% in reverse order after an \cs{exp_stop_f:} marker. +% \begin{verbatim} +% \cs_new_protected:Npn \seq_reverse:N #1 +% { +% \cs_set_eq:NN \@@_item:n \@@_reverse_item:nw +% \tl_set:Nf #2 { #2 \exp_stop_f: } +% } +% \cs_new:Npn \@@_reverse_item:nw #1 #2 \exp_stop_f: +% { +% #2 \exp_stop_f: +% \@@_item:n {#1} +% } +% \end{verbatim} +% At first, this seems optimal, since we can forget about each item +% as soon as it is placed after \cs{exp_stop_f:}. Unfortunately, +% \TeX{}'s usual tail recursion does not take place in this case: +% since the following \cs{@@_reverse_item:nw} only reads +% tokens until \cs{exp_stop_f:}, and never reads the +% |\@@_item:n {#1}| left by the previous call, \TeX{} cannot +% remove that previous call from the stack, and in particular +% must retain the various macro parameters in memory, until the +% end of the replacement text is reached. The stack is thus +% only flushed after all the \cs{@@_reverse_item:nw} are +% expanded. Keeping track of the arguments of all those calls +% uses up a memory quadratic in the length of the sequence. +% \TeX{} can then not cope with more than a few thousand items. +% +% Instead, we collect the items in the argument +% of \cs{exp_not:n}. The previous calls are cleanly removed +% from the stack, and the memory consumption becomes linear. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \seq_reverse:N + { \@@_reverse:NN \tl_set:Nx } +\cs_new_protected_nopar:Npn \seq_greverse:N + { \@@_reverse:NN \tl_gset:Nx } +\cs_new_protected:Npn \@@_reverse:NN #1 #2 + { + \cs_set_eq:NN \@@_tmp:w \@@_item:n + \cs_set_eq:NN \@@_item:n \@@_reverse_item:nwn + #1 #2 { #2 \exp_not:n { } } + \cs_set_eq:NN \@@_item:n \@@_tmp:w + } +\cs_new:Npn \@@_reverse_item:nwn #1 #2 \exp_not:n #3 + { + #2 + \exp_not:n { \@@_item:n {#1} #3 } + } +\cs_generate_variant:Nn \seq_reverse:N { c } +\cs_generate_variant:Nn \seq_greverse:N { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% % \subsection{Sequence conditionals} % % \begin{macro}[pTF]{\seq_if_empty:N, \seq_if_empty:c} @@ -1434,6 +1586,42 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\seq_item:Nn, \seq_item:cn} +% \begin{macro}[aux]{\@@_item:wNn, \@@_item:nnn} +% 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 the stop code |{ ? \__prg_break: } { }| will be used by the auxiliary, +% terminating the loop and returning nothing at all. +% \begin{macrocode} +\cs_new:Npn \seq_item:Nn #1 + { \exp_after:wN \@@_item:wNn #1 \q_stop #1 } +\cs_new:Npn \@@_item:wNn \s_@@ #1 \q_stop #2#3 + { + \exp_args:Nf \@@_item:nnn + { + \int_eval:n + { + \int_compare:nNnT {#3} < \c_zero + { \seq_count:N #2 + \c_one + } + #3 + } + } + #1 + { ? \__prg_break: } { } + \__prg_break_point: + } +\cs_new:Npn \@@_item:nnn #1#2#3 + { + \use_none:n #2 + \int_compare:nNnTF {#1} = \c_one + { \__prg_break:n { \exp_not:n {#3} } } + { \exp_args:Nf \@@_item:nnn { \int_eval:n { #1 - 1 } } } + } +\cs_generate_variant:Nn \seq_item:Nn { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \subsection{Mapping to sequences} % % \begin{macro}{\seq_map_break:} |