[latex3-commits] [git/LaTeX3-latex3-latex3] gh844: Implement \seq_pop_item:NnN(TF) (fixes #844) (d2688c48c)
Bruno Le Floch
blflatex at gmail.com
Wed Apr 28 08:24:12 CEST 2021
Repository : https://github.com/latex3/latex3
On branch : gh844
Link : https://github.com/latex3/latex3/commit/d2688c48cd92d7d7ebebd3aa9fa0620558136705
>---------------------------------------------------------------
commit d2688c48cd92d7d7ebebd3aa9fa0620558136705
Author: Bruno Le Floch <blflatex at gmail.com>
Date: Wed Apr 28 08:12:54 2021 +0200
Implement \seq_pop_item:NnN(TF) (fixes #844)
>---------------------------------------------------------------
d2688c48cd92d7d7ebebd3aa9fa0620558136705
l3kernel/CHANGELOG.md | 2 +-
l3kernel/l3candidates.dtx | 72 +++++++++++++++++++++++++++++++++
l3kernel/testfiles/m3seq005.lvt | 43 ++++++++++++++++++++
l3kernel/testfiles/m3seq005.tlg | 90 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 206 insertions(+), 1 deletion(-)
diff --git a/l3kernel/CHANGELOG.md b/l3kernel/CHANGELOG.md
index 0a219856d..3c34ad55d 100644
--- a/l3kernel/CHANGELOG.md
+++ b/l3kernel/CHANGELOG.md
@@ -12,7 +12,7 @@ this project uses date-based 'snapshot' version identifiers.
- `\tracingstacklevels`
- Color export in comma-separated format
- `\ur{...}` escape in `l3regex` to compose regexes
-- `\seq_put_item:Nnn(TF)` to change an entry of a sequence
+- `\seq_put_item:Nnn(TF)` and `\seq_pop_item:NnN(TF)`
### Changed
- Breaking change: use prevailing catcodes instead of string in
diff --git a/l3kernel/l3candidates.dtx b/l3kernel/l3candidates.dtx
index 381f9779a..5ddfe2578 100644
--- a/l3kernel/l3candidates.dtx
+++ b/l3kernel/l3candidates.dtx
@@ -452,6 +452,24 @@
% afterwards.
% \end{function}
%
+% \begin{function}[added = 2021-04-28, noTF]
+% {\seq_pop_item:NnN, \seq_pop_item:cnN, \seq_gpop_item:NnN, \seq_gpop_item:cnN}
+% \begin{syntax}
+% \cs{seq_pop_item:NnN} \meta{seq~var} \Arg{intexpr} \Arg{tl~var}
+% \cs{seq_pop_item:NnNTF} \meta{seq~var} \Arg{intexpr} \Arg{tl~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Removes the \meta{item} at position \meta{integer expression} in the
+% \meta{sequence}, and places it in the \meta{token list variable}.
+% Items are indexed from $1$ on the left/top of the \meta{sequence},
+% or from $-1$ on the right/bottom. If the position is zero or is
+% larger (in absolute value) than the number of items in the sequence,
+% the \meta{seq~var} is not modified, the \meta{token list} is set to
+% the special marker \cs{q_no_value}, and the \meta{false code} is
+% left in the input stream; otherwise the \meta{true code} is. The
+% \meta{token list} assignment is local while the \meta{sequence} is
+% assigned locally for |pop| or globally for |gpop| functions.
+% \end{function}
+%
% \section{Additions to \pkg{l3sys}}
%
% \begin{variable}[added = 2018-05-02]{\c_sys_engine_version_str}
@@ -1261,6 +1279,60 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}[noTF]{\seq_pop_item:NnN, \seq_pop_item:cnN, \seq_gpop_item:NnN, \seq_gpop_item:cnN}
+% \begin{macro}{\@@_pop_item:NnNNN}
+% The |NnN| versions simply call the conditionals, for which we will
+% rely on the internals of \cs{seq_put_item:Nnn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_pop_item:NnN #1#2#3
+ { \seq_pop_item:NnNTF #1 {#2} #3 { } { } }
+\cs_new_protected:Npn \seq_gpop_item:NnN #1#2#3
+ { \seq_gpop_item:NnNTF #1 {#2} #3 { } { } }
+\cs_generate_variant:Nn \seq_pop_item:NnN { c }
+\cs_generate_variant:Nn \seq_gpop_item:NnN { c }
+\prg_new_protected_conditional:Npnn \seq_pop_item:NnN #1#2#3 { TF , T , F }
+ { \@@_pop_item:NnNN #1 {#2} #3 \__kernel_tl_set:Nx }
+\prg_new_protected_conditional:Npnn \seq_gpop_item:NnN #1#2#3 { TF , T , F }
+ { \@@_pop_item:NnNN #1 {#2} #3 \__kernel_tl_gset:Nx }
+\prg_generate_conditional_variant:Nnn \seq_pop_item:NnN { c } { TF , T , F }
+\prg_generate_conditional_variant:Nnn \seq_gpop_item:NnN { c } { TF , T , F }
+% \end{macrocode}
+% Save in \cs{l_@@_internal_b_tl} the token list variable |#3| in
+% which we will store the item. The \cs{@@_put_item:nnNNNN} auxiliary
+% eventually inserts \cs{l_@@_internal_a_tl} in place of the item
+% found in the sequence, so we empty that. Instead of the last
+% argument \cs{use_i:nn} or \cs{use_ii:nn} used for |put| functions,
+% we introduce \cs{@@_pop_item:nn}, which stores \cs{q_no_value}
+% before calling its second argument
+% (\cs{prg_return_true:}/\texttt{false:}) to end the conditional. The
+% item found is passed to \cs{@@_pop_item_aux:w}, which interrupts the
+% |x|-expanding sequence assignment and stores the item using the
+% assignment function in \cs{l_@@_internal_b_tl}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_pop_item:NnNN #1#2#3#4
+ {
+ \tl_clear:N \l_@@_internal_a_tl
+ \tl_set:Nn \l_@@_internal_b_tl { \__kernel_tl_set:Nx #3 }
+ \exp_args:Nff \@@_put_item:nnNNNN
+ { \int_eval:n {#2} } { \seq_count:N #1 }
+ #1 \@@_pop_item_aux:w #4 \@@_pop_item:nn
+ }
+\cs_new_protected:Npn \@@_pop_item:nn #1#2
+ {
+ \if_meaning:w \prg_return_false: #2
+ \l_@@_internal_b_tl { \exp_not:N \q_no_value }
+ \fi:
+ #2
+ }
+\cs_new:Npn \@@_pop_item_aux:w \@@_item:n #1
+ {
+ \if_false: { \fi: }
+ \l_@@_internal_b_tl { \if_false: } \fi: \exp_not:n {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \subsection{Additions to \pkg{l3sys}}
%
% \begin{macrocode}
diff --git a/l3kernel/testfiles/m3seq005.lvt b/l3kernel/testfiles/m3seq005.lvt
index 35b93c065..499615262 100644
--- a/l3kernel/testfiles/m3seq005.lvt
+++ b/l3kernel/testfiles/m3seq005.lvt
@@ -90,4 +90,47 @@
\seq_gput_item:NnnTF \g_tmpa_seq { 5 } { #\par } { \TRUE } { \FALSE } \seq_show:N \g_tmpa_seq
}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\TEST { seq_pop_item:NnN }
+ {
+ \cs_set_protected:Npn \test_log: { \seq_log:N \l_tmpa_seq \tl_log:N \l_tmpa_tl }
+ %
+ \seq_clear:N \l_tmpa_seq
+ \tl_clear:N \l_tmpa_tl
+ \seq_pop_item:NnN \l_tmpa_seq { 0 } \l_tmpa_tl \test_log:
+ \tl_clear:N \l_tmpa_tl
+ \seq_pop_item:cnN { l_tmpa_seq } { 1 } \l_tmpa_tl \test_log:
+ \tl_clear:N \l_tmpa_tl
+ \seq_pop_item:cnNTF { l_tmpa_seq } { -11 } \l_tmpa_tl { \TRUE } { \FALSE } \test_log:
+ %
+ \SEPARATOR
+ \tl_clear:N \l_tmpa_tl
+ \seq_put_right:Nn \l_tmpa_seq { \AAA }
+ \seq_put_right:Nn \l_tmpa_seq { \BBB }
+ \seq_pop_item:cnN { l_tmpa_seq } { 0 } \l_tmpa_tl \test_log:
+ \group_begin:
+ \seq_pop_item:NnN \l_tmpa_seq { 1 } \l_tmpa_tl \test_log:
+ \group_end:
+ \seq_pop_item:cnNTF { l_tmpa_seq } { 0 } \l_tmpa_tl { \TRUE } { \FALSE } \test_log:
+ \seq_pop_item:NnNTF \l_tmpa_seq { 2+3-4 } \g_tmpa_tl { \TRUE } { \FALSE } \test_log:
+ \tl_log:N \g_tmpa_tl
+ \seq_gpop_item:cnNTF { l_tmpa_seq } { -1 } \l_tmpa_tl { \TRUE } { \FALSE } \test_log:
+ %
+ \SEPARATOR
+ \cs_set_protected:Npn \test_log: { \seq_log:N \g_tmpa_seq \tl_log:N \l_tmpa_tl }
+ \seq_gset_split:Nnn \g_tmpa_seq { } { { \AAA } { \B\B } { { } } { # } }
+ \tl_clear:N \l_tmpa_tl
+ \seq_gpop_item:cnN { g_tmpa_seq } { 0 } \l_tmpa_tl \test_log:
+ \seq_gpop_item:NnN \g_tmpa_seq { 1 } \l_tmpa_tl \test_log:
+ \group_begin:
+ \seq_gpop_item:cnN { g_tmpa_seq } { 1+2-5 } \l_tmpa_tl \test_log:
+ \seq_gpop_item:NnNTF \g_tmpa_seq { 0 } \l_tmpa_tl { \TRUE } { \FALSE } \test_log:
+ \seq_gpop_item:cnNTF { g_tmpa_seq } { -1 } \l_tmpa_tl { \TRUE } { \FALSE } \test_log:
+ \group_end:
+ \seq_gpop_item:NnNTF \g_tmpa_seq { 5 } \l_tmpa_tl { \TRUE } { \FALSE } \test_log:
+ \seq_gpop_item:NnNTF \g_tmpa_seq { 1 } \g_tmpa_tl { \TRUE } { \FALSE } \test_log:
+ \tl_show:N \g_tmpa_tl
+ }
+
\END
diff --git a/l3kernel/testfiles/m3seq005.tlg b/l3kernel/testfiles/m3seq005.tlg
index a6f025ae5..7e6b958f7 100644
--- a/l3kernel/testfiles/m3seq005.tlg
+++ b/l3kernel/testfiles/m3seq005.tlg
@@ -144,3 +144,93 @@ The sequence \g_tmpa_seq contains the items (without outer braces):
<recently read> }
l. ... }
============================================================
+============================================================
+TEST 4: seq_pop_item:NnN
+============================================================
+The sequence \l_tmpa_seq is empty
+> .
+> \l_tmpa_tl=\q_no_value .
+The sequence \l_tmpa_seq is empty
+> .
+> \l_tmpa_tl=\q_no_value .
+FALSE
+The sequence \l_tmpa_seq is empty
+> .
+> \l_tmpa_tl=\q_no_value .
+============================================================
+The sequence \l_tmpa_seq contains the items (without outer braces):
+> {\AAA }
+> {\BBB }.
+> \l_tmpa_tl=\q_no_value .
+The sequence \l_tmpa_seq contains the items (without outer braces):
+> {\BBB }.
+> \l_tmpa_tl=\AAA .
+FALSE
+The sequence \l_tmpa_seq contains the items (without outer braces):
+> {\AAA }
+> {\BBB }.
+> \l_tmpa_tl=\q_no_value .
+! LaTeX3 Error: Inconsistent local/global assignment
+For immediate help type H <return>.
+ ...
+l. ... }
+This is a coding error.
+Local assignment to a global variable '\g_tmpa_tl'.
+TRUE
+The sequence \l_tmpa_seq contains the items (without outer braces):
+> {\BBB }.
+> \l_tmpa_tl=\q_no_value .
+> \g_tmpa_tl=\AAA .
+! LaTeX3 Error: Inconsistent local/global assignment
+For immediate help type H <return>.
+ ...
+l. ... }
+This is a coding error.
+Global assignment to a local variable '\l_tmpa_seq'.
+TRUE
+The sequence \l_tmpa_seq is empty
+> .
+> \l_tmpa_tl=\BBB .
+============================================================
+The sequence \g_tmpa_seq contains the items (without outer braces):
+> {\AAA }
+> {\B \B }
+> {{}}
+> {##}.
+> \l_tmpa_tl=\q_no_value .
+The sequence \g_tmpa_seq contains the items (without outer braces):
+> {\B \B }
+> {{}}
+> {##}.
+> \l_tmpa_tl=\AAA .
+The sequence \g_tmpa_seq contains the items (without outer braces):
+> {\B \B }
+> {##}.
+> \l_tmpa_tl={}.
+FALSE
+The sequence \g_tmpa_seq contains the items (without outer braces):
+> {\B \B }
+> {##}.
+> \l_tmpa_tl=\q_no_value .
+TRUE
+The sequence \g_tmpa_seq contains the items (without outer braces):
+> {\B \B }.
+> \l_tmpa_tl=##.
+FALSE
+The sequence \g_tmpa_seq contains the items (without outer braces):
+> {\B \B }.
+> \l_tmpa_tl=\q_no_value .
+! LaTeX3 Error: Inconsistent local/global assignment
+For immediate help type H <return>.
+ ...
+l. ... }
+This is a coding error.
+Local assignment to a global variable '\g_tmpa_tl'.
+TRUE
+The sequence \g_tmpa_seq is empty
+> .
+> \l_tmpa_tl=\q_no_value .
+> \g_tmpa_tl=\B \B .
+<recently read> }
+l. ... }
+============================================================
More information about the latex3-commits
mailing list.