summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3kernel/l3clist.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/l3kernel/l3clist.dtx')
-rw-r--r--macros/latex/contrib/l3kernel/l3clist.dtx74
1 files changed, 73 insertions, 1 deletions
diff --git a/macros/latex/contrib/l3kernel/l3clist.dtx b/macros/latex/contrib/l3kernel/l3clist.dtx
index 3db9365a1f..f61fedb483 100644
--- a/macros/latex/contrib/l3kernel/l3clist.dtx
+++ b/macros/latex/contrib/l3kernel/l3clist.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-07}
+% \date{Released 2021-05-11}
%
% \maketitle
%
@@ -591,6 +591,20 @@
% \end{texnote}
% \end{function}
%
+% \begin{function}[EXP, added = 2021-05-10]{\clist_use:nnnn, \clist_use:nn}
+% \begin{syntax}
+% \cs{clist_use:nnnn} \meta{comma~list} \Arg{separator~between~two} \Arg{separator~between~more~than~two} \Arg{separator~between~final~two}
+% \cs{clist_use:nn} \meta{comma~list} \Arg{separator}
+% \end{syntax}
+% Places the contents of the \meta{comma~list} in the input stream,
+% with the appropriate \meta{separator} between the items. As for
+% \cs{clist_set:Nn}, blank items are omitted, spaces are removed from
+% both sides of each item, then a set of braces is removed if the
+% resulting space-trimmed item is braced. The \meta{separators} are
+% then inserted in the same way as for \cs{clist_use:Nnnn} and
+% \cs{clist_use:Nn}, respectively.
+% \end{function}
+%
% \section{Comma lists as stacks}
%
% Comma lists can be used as stacks, where data is pushed to and popped
@@ -805,11 +819,13 @@
% \end{variable}
%
% \begin{macro}[EXP]{
+% \@@_use_none_delimit_by_s_mark:w,
% \@@_use_none_delimit_by_s_stop:w,
% \@@_use_i_delimit_by_s_stop:nw
% }
% Functions to gobble up to a scan mark.
% \begin{macrocode}
+\cs_new:Npn \@@_use_none_delimit_by_s_mark:w #1 \s_@@_mark { }
\cs_new:Npn \@@_use_none_delimit_by_s_stop:w #1 \s_@@_stop { }
\cs_new:Npn \@@_use_i_delimit_by_s_stop:nw #1 #2 \s_@@_stop {#1}
% \end{macrocode}
@@ -1941,6 +1957,62 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}
+% {
+% \clist_use:nnnn, \clist_use:nn, \@@_use:Nw,
+% \@@_use_one:w, \@@_use_end:w, \@@_use_more:w
+% }
+% Items are grabbed by \cs{@@_use:Nw}, which detects blank items with
+% a \cs{tl_if_empty:oTF} test (in which case it recurses). Non-blank
+% items are either the end of the list, in which case the argument
+% |#1| of \cs{@@_use:Nw} is used to properly end the list, or are
+% normal items, which must be trimmed and properly unbraced. As we
+% find successive items, the long list of \cs{@@_use:Nw} calls gets
+% shortened and we end up calling \cs{@@_use_more:w} once we have
+% found $3$ items. This auxiliary leaves the first-found item and the
+% general separator, and calls \cs{@@_use:Nw} to find more items.
+% A subtlety is that we use \cs{@@_use_end:w} both in the case of a
+% two-item list and for the last two items of a general list: to get
+% the correct separator, \cs{@@_use_more:w} replaces the
+% separator-of-two by the last-separator when called, namely as soon
+% as we have found three items.
+% \begin{macrocode}
+\cs_new:Npn \clist_use:nnnn #1#2#3#4
+ {
+ \@@_use:Nw \@@_use_none_delimit_by_s_stop:w
+ \@@_use:Nw \@@_use_one:w
+ \@@_use:Nw \@@_use_end:w
+ \@@_use_more:w ;
+ {#2} {#3} {#4} ;
+ \prg_do_nothing: #1 , \s_@@_mark ,
+ \s_@@_stop
+ }
+\cs_new:Npn \@@_use:Nw #1#2 ; #3 ; #4 ,
+ {
+ \tl_if_empty:oTF { \use_none:nn #4 ? }
+ { \@@_use:Nw #1#2 ; }
+ {
+ \@@_use_none_delimit_by_s_mark:w #4 #1 \s_@@_mark
+ \tl_trim_spaces_apply:oN {#4} \@@_use_ii_i:nn
+ \@@_map_unbrace:wn , { #2 ; }
+ }
+ #3 ; \prg_do_nothing:
+ }
+\cs_new:Npn \@@_use_one:w \s_@@_mark #1 , #2#3#4 \s_@@_stop
+ { \exp_not:n {#3} }
+\cs_new:Npn \@@_use_end:w
+ \s_@@_mark #1 , #2#3#4#5#6 \s_@@_stop
+ { \exp_not:n { #4 #5 #3 } }
+\cs_new:Npn \@@_use_more:w ; #1#2#3#4#5#6 ;
+ {
+ \exp_not:n { #3 #5 }
+ \@@_use:Nw \@@_use_end:w \@@_use_more:w ;
+ {#1} {#2} {#6} {#5} {#6} ;
+ }
+\cs_new:Npn \clist_use:nn #1#2 { \clist_use:nnnn {#1} {#2} {#2} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{Using a single item}
%
% \begin{macro}{\clist_item:Nn, \clist_item:cn}