[latex3-commits] [git/LaTeX3-latex3-latex3] master: Make all "map_variable" leave the variable set to the last item (fixes #581) (3232786fd)

Bruno Le Floch bruno at le-floch.fr
Sun Aug 25 09:52:31 CEST 2019


Repository : https://github.com/latex3/latex3
On branch  : master
Link       : https://github.com/latex3/latex3/commit/3232786fd37f6450db6856586dcc41e51a26ea06

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

commit 3232786fd37f6450db6856586dcc41e51a26ea06
Author: Bruno Le Floch <bruno at le-floch.fr>
Date:   Sun Aug 25 09:52:31 2019 +0200

    Make all "map_variable" leave the variable set to the last item (fixes #581)


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

3232786fd37f6450db6856586dcc41e51a26ea06
 l3kernel/l3candidates.dtx         | 12 ++++++++----
 l3kernel/l3clist.dtx              |  8 ++++++--
 l3kernel/l3seq.dtx                |  4 +++-
 l3kernel/l3str.dtx                |  8 ++++++--
 l3kernel/l3tl.dtx                 | 17 +++++++++++------
 l3kernel/testfiles/m3clist002.lvt |  7 ++++++-
 l3kernel/testfiles/m3clist002.tlg |  4 ++++
 l3kernel/testfiles/m3ior002.lvt   |  4 ++++
 l3kernel/testfiles/m3ior002.tlg   |  3 +++
 l3kernel/testfiles/m3seq002.lvt   |  5 ++++-
 l3kernel/testfiles/m3seq002.tlg   |  2 ++
 l3kernel/testfiles/m3str004.lvt   |  8 ++++++--
 l3kernel/testfiles/m3str004.tlg   |  8 +++++++-
 l3kernel/testfiles/m3tl002.lvt    |  5 ++++-
 l3kernel/testfiles/m3tl002.tlg    |  2 ++
 l3kernel/testfiles/m3tlist002.lvt |  5 ++++-
 l3kernel/testfiles/m3tlist002.tlg |  2 ++
 17 files changed, 82 insertions(+), 22 deletions(-)

diff --git a/l3kernel/l3candidates.dtx b/l3kernel/l3candidates.dtx
index 82a756fa7..4875295f8 100644
--- a/l3kernel/l3candidates.dtx
+++ b/l3kernel/l3candidates.dtx
@@ -326,22 +326,26 @@
 %   until reaching the end of the file, stores the \meta{lines} in the
 %   \meta{tl~var} then applies the \meta{code}.  The \meta{code} will
 %   usually make use of the \meta{variable}, but this is not enforced.
-%   The assignments to the \meta{variable} are local.  \TeX{} ignores
+%   The assignments to the \meta{variable} are local.
+%   Its value after the loop is the last set of \meta{lines}, or its
+%   original value if the \meta{stream} is empty.  \TeX{} ignores
 %   any trailing new-line marker from the file it reads.
 %   This function is typically faster than \cs{ior_map_inline:Nn}.
 % \end{function}
 %
 % \begin{function}[added = 2019-01-13]{\ior_str_map_variable:NNn}
 %   \begin{syntax}
-%     \cs{ior_str_map_variable:NNn} \meta{stream} \meta{tl~var} \Arg{code}
+%     \cs{ior_str_map_variable:NNn} \meta{stream} \meta{variable} \Arg{code}
 %   \end{syntax}
 %   For each \meta{line} in the \meta{stream}, stores the \meta{line} in
-%   the \meta{tl~var} then applies the \meta{code}.  The material is
+%   the \meta{variable} then applies the \meta{code}.  The material is
 %   read from the \meta{stream} as a series of tokens with category code
 %   $12$ (other), with the exception of space characters which are given
 %   category code $10$ (space).  The \meta{code} will usually make use
 %   of the \meta{variable}, but this is not enforced.  The assignments
-%   to the \meta{variable} are local.  Note that \TeX{} removes trailing
+%   to the \meta{variable} are local.  Its value after the loop is the
+%   last \meta{line}, or its original value if the \meta{stream} is
+%   empty.  Note that \TeX{} removes trailing
 %   space and tab characters (character codes 32 and 9) from every line
 %   upon input.  \TeX{} also ignores any trailing new-line marker from
 %   the file it reads.
diff --git a/l3kernel/l3clist.dtx b/l3kernel/l3clist.dtx
index c08a1129e..797a0ca67 100644
--- a/l3kernel/l3clist.dtx
+++ b/l3kernel/l3clist.dtx
@@ -451,7 +451,9 @@
 %   (token list) \meta{variable} and applies the \meta{code}.  The
 %   \meta{code} will usually make use of the \meta{variable}, but this
 %   is not enforced.  The assignments to the \meta{variable} are local.
-%   The \meta{items} are returned from left to right.
+%   Its value after the loop is the last \meta{item} in the \meta{comma
+%   list}, or its original value if there were no \meta{item}.  The
+%   \meta{items} are returned from left to right.
 % \end{function}
 %
 % \begin{function}[rEXP, updated = 2012-06-29]{\clist_map_break:}
@@ -1697,6 +1699,8 @@
 %   additionally we store each item in the given variable.
 %   As for inline mappings, space trimming for the \texttt{n}
 %   variant is done by storing the comma list in a variable.
+%   The quark test is done before assigning the item to the variable:
+%   this avoids storing a quark which the user wouldn't expect.
 %   The strange \cs{use:n} avoids unlikely problems when |#2| would
 %   contain \cs{q_recursion_stop}.
 %    \begin{macrocode}
@@ -1718,8 +1722,8 @@
   }
 \cs_new_protected:Npn \@@_map_variable:Nnw #1#2#3,
   {
+    \quark_if_recursion_tail_stop:n {#3}
     \tl_set:Nn #1 {#3}
-    \quark_if_recursion_tail_stop:N #1
     \use:n {#2}
     \@@_map_variable:Nnw #1 {#2}
   }
diff --git a/l3kernel/l3seq.dtx b/l3kernel/l3seq.dtx
index eb6da6501..3909ae601 100644
--- a/l3kernel/l3seq.dtx
+++ b/l3kernel/l3seq.dtx
@@ -525,7 +525,9 @@
 %   Stores each \meta{item} of the \meta{sequence} in turn in the (token
 %   list) \meta{variable} and applies the \meta{code}.  The \meta{code}
 %   will usually make use of the \meta{variable}, but this is not
-%   enforced.  The assignments to the \meta{variable} are local.  The
+%   enforced.  The assignments to the \meta{variable} are local.  Its
+%   value after the loop is the last \meta{item} in the \meta{sequence},
+%   or its original value if the \meta{sequence} is empty.  The
 %   \meta{items} are returned from left to right.
 % \end{function}
 %
diff --git a/l3kernel/l3str.dtx b/l3kernel/l3str.dtx
index d769fe77c..7eda8d4a4 100644
--- a/l3kernel/l3str.dtx
+++ b/l3kernel/l3str.dtx
@@ -458,7 +458,9 @@
 %   in turn in the (string or token list) \meta{variable} and applies
 %   the \meta{code}.  The \meta{code} will usually make use of the
 %   \meta{variable}, but this is not enforced.  The assignments to the
-%   \meta{variable} are local.  See also \cs{str_map_inline:Nn}.
+%   \meta{variable} are local.  Its value after the loop is the last
+%   \meta{character} in the \meta{string}, or its original value if the
+%   \meta{string} is empty.  See also \cs{str_map_inline:Nn}.
 % \end{function}
 %
 % \begin{function}[added = 2017-11-14]
@@ -471,7 +473,9 @@
 %   the (string or token list) \meta{variable} and applies the
 %   \meta{code}.  The \meta{code} will usually make use of the
 %   \meta{variable}, but this is not enforced.  The assignments to the
-%   \meta{variable} are local.  See also \cs{str_map_inline:Nn}.
+%   \meta{variable} are local.  Its value after the loop is the last
+%   \meta{character} in the \meta{string}, or its original value if the
+%   \meta{string} is empty.  See also \cs{str_map_inline:Nn}.
 % \end{function}
 %
 % \begin{function}[added = 2017-10-08, rEXP]{\str_map_break:}
diff --git a/l3kernel/l3tl.dtx b/l3kernel/l3tl.dtx
index 836faaa7e..9821d6437 100644
--- a/l3kernel/l3tl.dtx
+++ b/l3kernel/l3tl.dtx
@@ -559,8 +559,10 @@
 %   Stores each \meta{item} of the \meta{tl~var} in turn in the (token
 %   list) \meta{variable} and applies the \meta{code}.  The \meta{code}
 %   will usually make use of the \meta{variable}, but this is not
-%   enforced.  The assignments to the \meta{variable} are local.  See
-%   also \cs{tl_map_inline:Nn}.
+%   enforced.  The assignments to the \meta{variable} are local.  Its
+%   value after the loop is the last \meta{item} in the \meta{tl~var},
+%   or its original value if the \meta{tl~var} is blank.  See also
+%   \cs{tl_map_inline:Nn}.
 % \end{function}
 %
 % \begin{function}[updated = 2012-06-29]{\tl_map_variable:nNn}
@@ -571,6 +573,8 @@
 %   (token list) \meta{variable} and applies the \meta{code}.  The
 %   \meta{code} will usually make use of the \meta{variable}, but this
 %   is not enforced.  The assignments to the \meta{variable} are local.
+%   Its value after the loop is the last \meta{item} in the
+%   \meta{tl~var}, or its original value if the \meta{tl~var} is blank.
 %   See also \cs{tl_map_inline:nn}.
 % \end{function}
 %
@@ -2407,9 +2411,10 @@
 % \begin{macro}{\tl_map_variable:nNn}
 % \begin{macro}{\tl_map_variable:NNn, \tl_map_variable:cNn}
 % \begin{macro}{\@@_map_variable:Nnn}
-%   \cs{tl_map_variable:nNn} \meta{token list} \meta{temp} \meta{action}
-%   assigns
-%   \meta{temp} to each element and executes \meta{action}.
+%   \cs{tl_map_variable:nNn} \meta{token list} \meta{tl~var}
+%   \meta{action} assigns \meta{tl~var} to each element and executes
+%   \meta{action}.  The assignment to \meta{tl~var} is done after the
+%   quark test so that this variable does not get set to a quark.
 %    \begin{macrocode}
 \cs_new_protected:Npn \tl_map_variable:nNn #1#2#3
   {
@@ -2421,8 +2426,8 @@
   { \exp_args:No \tl_map_variable:nNn }
 \cs_new_protected:Npn \@@_map_variable:Nnn #1#2#3
   {
+    \quark_if_recursion_tail_break:nN {#3} \tl_map_break:
     \tl_set:Nn #1 {#3}
-    \quark_if_recursion_tail_break:NN #1 \tl_map_break:
     \use:n {#2}
     \@@_map_variable:Nnn #1 {#2}
   }
diff --git a/l3kernel/testfiles/m3clist002.lvt b/l3kernel/testfiles/m3clist002.lvt
index cc0151d7e..dfd9c62d3 100644
--- a/l3kernel/testfiles/m3clist002.lvt
+++ b/l3kernel/testfiles/m3clist002.lvt
@@ -1,5 +1,5 @@
 %
-% Copyright (C) 2008-2013,2015,2018 The LaTeX Project
+% Copyright (C) 2008-2013,2015,2018,2019 The LaTeX Project
 %
 \documentclass{minimal}
 \input{regression-test}
@@ -385,12 +385,16 @@
   \clist_map_variable:NNn \l_tmpa_clist  \l_tmpa_tl {
     \exp_args:No \TYPE { \tl_to_str:N \l_tmpa_tl }
   }
+  \TYPE { Final : ~ [\l_tmpa_tl] }
   \clist_map_variable:cNn {l_tmpa_clist} \l_tmpa_tl {
     \exp_args:No \TYPE { \tl_to_str:N \l_tmpa_tl }
   }
+  \TYPE { Final : ~ [\l_tmpa_tl] }
   \clist_map_variable:nNn {aa,bb\par,cc} \l_tmpa_tl {
     \exp_args:No \TYPE { \tl_to_str:N \l_tmpa_tl }
   }
+  \clist_map_variable:nNn { , ~ , ~ } \l_tmpa_tl { }
+  \TYPE { Final : ~ [\l_tmpa_tl] }
 }
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -571,6 +575,7 @@
   \clist_map_variable:nNn {,aa,,~,aa,bb\par,cc,~} \l_tmpa_tl {
     \exp_args:Nx \TYPE { [\tl_to_str:N \l_tmpa_tl] }
   }
+  \TYPE { Final : ~ [\l_tmpa_tl] }
 }
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/l3kernel/testfiles/m3clist002.tlg b/l3kernel/testfiles/m3clist002.tlg
index aa6f21458..b98207c04 100644
--- a/l3kernel/testfiles/m3clist002.tlg
+++ b/l3kernel/testfiles/m3clist002.tlg
@@ -305,12 +305,15 @@ TEST 25: map_variable
 c
 b\par 
 a
+Final: [a]
 c
 b\par 
 a
+Final: [a]
 aa
 bb\par 
 cc
+Final: [cc]
 ============================================================
 ============================================================
 TEST 26: pop
@@ -423,6 +426,7 @@ TEST 32: map check empties
 [aa]
 [bb\par ]
 [cc]
+Final: [cc]
 ============================================================
 ============================================================
 TEST 33: clist show
diff --git a/l3kernel/testfiles/m3ior002.lvt b/l3kernel/testfiles/m3ior002.lvt
index bc6283813..76f37bdf6 100644
--- a/l3kernel/testfiles/m3ior002.lvt
+++ b/l3kernel/testfiles/m3ior002.lvt
@@ -90,6 +90,7 @@
         \int_incr:N \l_tmpa_int
       }
     \TYPE { \int_use:N \l_tmpa_int \c_space_tl lines }
+    \TYPE { Last~one: ~ [ \tl_to_str:N \l_tmpa_tl ] }
     \ior_open:Nn \test { secondfile.txt }
     \int_zero:N \l_tmpa_int
     \ior_str_map_variable:NNn \test \l_tmpa_tl
@@ -98,6 +99,9 @@
         \int_incr:N \l_tmpa_int
       }
     \TYPE { \int_use:N \l_tmpa_int \c_space_tl lines }
+    \TYPE { Last~one: ~ [ \tl_to_str:N \l_tmpa_tl ] }
+    \ior_str_map_variable:NNn \test \l_tmpa_tl { }
+    \TYPE { Same~one: ~ [ \tl_to_str:N \l_tmpa_tl ] }
     \OMIT
     \ior_close:N \test
     \TIMO
diff --git a/l3kernel/testfiles/m3ior002.tlg b/l3kernel/testfiles/m3ior002.tlg
index c440ad5fb..3e6e0bbe6 100644
--- a/l3kernel/testfiles/m3ior002.tlg
+++ b/l3kernel/testfiles/m3ior002.tlg
@@ -33,9 +33,12 @@ TEST 3: Mapping variable with newline at end-of-file
 |macro:->Foobarbaz|
 |macro:->|
 2 lines
+Last one: []
 |macro:->Foobar baz|
 |macro:->|
 2 lines
+Last one: []
+Same one: []
 ============================================================
 ============================================================
 TEST 4: Open read stream with conditional
diff --git a/l3kernel/testfiles/m3seq002.lvt b/l3kernel/testfiles/m3seq002.lvt
index 42f961bc2..e944f652c 100644
--- a/l3kernel/testfiles/m3seq002.lvt
+++ b/l3kernel/testfiles/m3seq002.lvt
@@ -1,5 +1,5 @@
 %
-% Copyright (C) 2009-2012,2014,2015,2018 The LaTeX3 Project
+% Copyright (C) 2009-2012,2014,2015,2018,2019 The LaTeX3 Project
 %
 \documentclass{minimal}
 \input{regression-test}
@@ -306,9 +306,12 @@
   \seq_map_variable:NNn \l_tmpa_seq  \l_tmpa_tl {
     \exp_args:No \TYPE { \tl_to_str:N \l_tmpa_tl }
   }
+  \TYPE { Final:~ [\tl_to_str:N \l_tmpa_tl] }
   \seq_map_variable:cNn {l_tmpa_seq} \l_tmpa_tl {
     \exp_args:No \TYPE { \tl_to_str:N \l_tmpa_tl }
   }
+  \seq_map_variable:NNn \c_empty_seq \l_tmpa_tl { \ERROR }
+  \TYPE { Final:~ [\tl_to_str:N \l_tmpa_tl] }
 }
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/l3kernel/testfiles/m3seq002.tlg b/l3kernel/testfiles/m3seq002.tlg
index c8ad4e6a2..b740a2c40 100644
--- a/l3kernel/testfiles/m3seq002.tlg
+++ b/l3kernel/testfiles/m3seq002.tlg
@@ -238,9 +238,11 @@ TEST 20: map_variable
 c
 b\par 
 a
+Final: [a]
 c
 b\par 
 a
+Final: [a]
 ============================================================
 ============================================================
 TEST 21: pop
diff --git a/l3kernel/testfiles/m3str004.lvt b/l3kernel/testfiles/m3str004.lvt
index afd8bdabc..26cb18d7f 100644
--- a/l3kernel/testfiles/m3str004.lvt
+++ b/l3kernel/testfiles/m3str004.lvt
@@ -53,7 +53,11 @@
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \cs_set:Npn \test_store:x { \tl_put_right:Nx \l_tmpa_tl }
-\cs_set:Npn \test_done: { \TYPE { | \l_tmpa_tl | } \tl_clear:N \l_tmpa_tl }
+\cs_set:Npn \test_done: {
+  \TYPE { | \l_tmpa_tl | }
+  \TYPE { Last~char~seen:~ [\tl_to_str:N \l_tmpb_tl] }
+  \tl_clear:N \l_tmpa_tl
+}
 \TEST { str_map_variable }
   {
     \tl_clear:N \l_tmpa_tl
@@ -61,7 +65,7 @@
     \test_done:
     \str_map_variable:nNn { ~ } \l_tmpb_tl { \test_store:x { ; \l_tmpb_tl } }
     \test_done:
-    \str_map_variable:nNn { \par } \l_tmpb_tl { \test_store:x { ; \l_tmpb_tl } }
+    \str_map_variable:nNn { \par ^ } \l_tmpb_tl { \test_store:x { ; \l_tmpb_tl } }
     \test_done:
     \str_map_variable:NNn \c_empty_tl \l_tmpb_tl { \test_store:x { ; \l_tmpb_tl } }
     \test_done:
diff --git a/l3kernel/testfiles/m3str004.tlg b/l3kernel/testfiles/m3str004.tlg
index ef2f47c31..c296f4bb2 100644
--- a/l3kernel/testfiles/m3str004.tlg
+++ b/l3kernel/testfiles/m3str004.tlg
@@ -25,9 +25,15 @@ TEST 2: str_map_inline
 TEST 3: str_map_variable
 ============================================================
 ||
+Last char seen: []
 |; |
-|;\;p;a;r; |
+Last char seen: [ ]
+|;\;p;a;r; ;^|
+Last char seen: [^]
 ||
+Last char seen: [^]
 |; |
+Last char seen: [ ]
 |;\;p;a;r; |
+Last char seen: [ ]
 ============================================================
diff --git a/l3kernel/testfiles/m3tl002.lvt b/l3kernel/testfiles/m3tl002.lvt
index 99a4d1228..49df867ff 100644
--- a/l3kernel/testfiles/m3tl002.lvt
+++ b/l3kernel/testfiles/m3tl002.lvt
@@ -1,5 +1,5 @@
 %
-% Copyright (C) 2009-2012,2015,2018 The LaTeX3 Project
+% Copyright (C) 2009-2012,2015,2018,2019 The LaTeX3 Project
 %
 \documentclass{minimal}
 \input{regression-test}
@@ -73,6 +73,8 @@
   \tl_map_variable:NNn \l_tmpa_tl \l_ii_tl {
     \TYPE{[\l_ii_tl]~}
   }
+  \tl_map_variable:NNn \c_space_tl \l_ii_tl { }
+  \TYPE{Final:~[\l_ii_tl]}
 }
 
 \tl_set:Nn \l_tmpa_tl {a{bb}cdzyx\ERROR}
@@ -95,6 +97,7 @@
       \TYPE{[\l_ii_tl]}
     }
   }
+  \TYPE{Final:~[\l_ii_tl]}
 }
 
 \cs_set:Npn \tl_tmp:n #1 {
diff --git a/l3kernel/testfiles/m3tl002.tlg b/l3kernel/testfiles/m3tl002.tlg
index 6812d7222..b160b4504 100644
--- a/l3kernel/testfiles/m3tl002.tlg
+++ b/l3kernel/testfiles/m3tl002.tlg
@@ -43,6 +43,7 @@ TEST 6: map_variable
 [c] 
 [{A}B] 
 [C] 
+Final: [C]
 ============================================================
 ============================================================
 TEST 7: map_break inline/variable
@@ -56,6 +57,7 @@ TEST 7: map_break inline/variable
 [bb]
 [c]
 [d]
+Final: [z]
 ============================================================
 ============================================================
 TEST 8: map_break function
diff --git a/l3kernel/testfiles/m3tlist002.lvt b/l3kernel/testfiles/m3tlist002.lvt
index 1207741de..dac6dda0c 100644
--- a/l3kernel/testfiles/m3tlist002.lvt
+++ b/l3kernel/testfiles/m3tlist002.lvt
@@ -1,5 +1,5 @@
 %
-% Copyright (C) 2009-2014,2018 LaTeX3 Project
+% Copyright (C) 2009-2014,2018,2019 LaTeX3 Project
 %
 \documentclass{minimal}
 \input{regression-test}
@@ -195,6 +195,8 @@
   \tl_map_variable:nNn {ab{c{A}B}C} \l_ii_tl {
     \TYPE{[\l_ii_tl]~}
   }
+  \tl_map_variable:nNn { } \l_ii_tl { }
+  \TYPE{Final:~[\l_ii_tl]}
 }
 
 \TEST{map_break~inline/variable}{
@@ -213,6 +215,7 @@
       \TYPE{[\l_ii_tl]}
     }
   }
+  \TYPE{Final:~[\l_ii_tl]}
 }
 
 \cs_set:Npn \tl_tmp:w #1 {
diff --git a/l3kernel/testfiles/m3tlist002.tlg b/l3kernel/testfiles/m3tlist002.tlg
index 40e3756a4..a159045c1 100644
--- a/l3kernel/testfiles/m3tlist002.tlg
+++ b/l3kernel/testfiles/m3tlist002.tlg
@@ -137,6 +137,7 @@ TEST 13: map_variable
 [b] 
 [c{A}B] 
 [C] 
+Final: [C]
 ============================================================
 ============================================================
 TEST 14: map_break inline/variable
@@ -146,6 +147,7 @@ TEST 14: map_break inline/variable
 ============================================================
 [a]
 [b]
+Final: [c]
 ============================================================
 ============================================================
 TEST 15: map_break function





More information about the latex3-commits mailing list