[latex3-commits] [git/LaTeX3-latex3-latex3] main: Implement \clist_use:nnnn and \clist_use:nn (fixes #561) (0bf9f778e)

Bruno Le Floch blflatex at gmail.com
Tue May 11 02:08:17 CEST 2021


Repository : https://github.com/latex3/latex3
On branch  : main
Link       : https://github.com/latex3/latex3/commit/0bf9f778e23e831da91ea3e4c7e6014e39f5c810

>---------------------------------------------------------------

commit 0bf9f778e23e831da91ea3e4c7e6014e39f5c810
Author: Bruno Le Floch <blflatex at gmail.com>
Date:   Tue May 11 02:07:44 2021 +0200

    Implement \clist_use:nnnn and \clist_use:nn (fixes #561)
    
    We already had \clist_use:Nnnn and \clist_use:Nn.  This simply provides
    feature parity for n-type comma lists.


>---------------------------------------------------------------

0bf9f778e23e831da91ea3e4c7e6014e39f5c810
 l3kernel/CHANGELOG.md             |  1 +
 l3kernel/l3clist.dtx              | 72 +++++++++++++++++++++++++++++++++++++++
 l3kernel/testfiles/m3clist005.lvt | 20 +++++++++++
 l3kernel/testfiles/m3clist005.tlg | 20 +++++++++++
 4 files changed, 113 insertions(+)

diff --git a/l3kernel/CHANGELOG.md b/l3kernel/CHANGELOG.md
index c6f03a29c..341961b0c 100644
--- a/l3kernel/CHANGELOG.md
+++ b/l3kernel/CHANGELOG.md
@@ -9,6 +9,7 @@ this project uses date-based 'snapshot' version identifiers.
 
 ### Added
 - `\cctab_item:Nn` (issue #880)
+- `\clist_use:nnnn` and `\clist_use:nn` (issue #561)
 
 ### Fixed
 - Loading of backend in generic DVI mode (issue #905)
diff --git a/l3kernel/l3clist.dtx b/l3kernel/l3clist.dtx
index 3db9365a1..314c6d342 100644
--- a/l3kernel/l3clist.dtx
+++ b/l3kernel/l3clist.dtx
@@ -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}
diff --git a/l3kernel/testfiles/m3clist005.lvt b/l3kernel/testfiles/m3clist005.lvt
index ac7a9a4ce..14fdd1747 100644
--- a/l3kernel/testfiles/m3clist005.lvt
+++ b/l3kernel/testfiles/m3clist005.lvt
@@ -58,4 +58,24 @@
     \test:f { \clist_use:Nn \l_tmpa_clist { ~and~ } }
   }
 
+\TEST { clist_use:nnnn }
+  {
+    \test:x { \clist_use:nnnn { } { ~and~ } { ,~ } { ,~and~ } }
+    \test:x { | \clist_use:nnnn { , ~ , { ~ } , } { ~and~ } { ,~ } { ,~and~ } | }
+    \test:x { \clist_use:nnnn { \AA } { ~and~ } { ,~ } { ,~and~ } }
+    \test:x { \clist_use:nnnn { \AA , { } } { ~and~ } { ,~ } { ,~and~ } }
+    \test:x { \clist_use:nnnn { \AA , { # \par } , {~} } { ++\TRUE++ } { *\TRUE* } { -\FALSE- } }
+    \test:x { \clist_use:nnnn { a , {b,c} , , d , ~ { } ~ , , , , e , f , \g , h , i } { ~and~ } { ,~ } { ,~and~ } }
+  }
+
+\TEST { clist_use:nn }
+  {
+    \test:x { \clist_use:nn { } { ~and~ } }
+    \test:x { | \clist_use:nn { , ~ , { ~ } , } { ~and~ } | }
+    \test:x { \clist_use:nn { \AA } { ~and~ } }
+    \test:x { \clist_use:nn { \AA , { } } { ~and~ } }
+    \test:x { \clist_use:nn { \AA , { # \par } , {~} } { +\TRUE+ } }
+    \test:x { \clist_use:nn { a , {b,c} , , d , ~ { } ~ , , , , e , f , \g , h , i } { ~and~ } }
+  }
+
 \END
diff --git a/l3kernel/testfiles/m3clist005.tlg b/l3kernel/testfiles/m3clist005.tlg
index 01f1b33a9..c6674313e 100644
--- a/l3kernel/testfiles/m3clist005.tlg
+++ b/l3kernel/testfiles/m3clist005.tlg
@@ -23,3 +23,23 @@ TEST 2: clist_use:Nn
 > a and b and c and d and e and f and \g  and h and i.
 > AAA and \g  and (x,y).
 ============================================================
+============================================================
+TEST 3: clist_use:nnnn
+============================================================
+> .
+> | |.
+> \AA .
+> \AA  and .
+> \AA *\TRUE *##\par -\FALSE - .
+> a, b,c, d, , e, f, \g , h, and i.
+============================================================
+============================================================
+TEST 4: clist_use:nn
+============================================================
+> .
+> | |.
+> \AA .
+> \AA  and .
+> \AA +\TRUE +##\par +\TRUE + .
+> a and b,c and d and  and e and f and \g  and h and i.
+============================================================





More information about the latex3-commits mailing list.