summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx219
1 files changed, 213 insertions, 6 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
index aa0f4e1f8ae..b03b3831c57 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
%
% \maketitle
%
@@ -216,7 +216,7 @@
% If piped system calls are disabled an error is raised.
%
% For details of handling of the \meta{shell command}, see
-% \cs{sys_get_shell:nnN(TF)}.
+% \cs{sys_get_shell:nnNTF}.
% \end{function}
%
% \section{Additions to \pkg{l3flag}}
@@ -434,6 +434,42 @@
% mappings.
% \end{function}
%
+% \begin{function}[added = 2021-04-29, noTF]
+% {\seq_set_item:Nnn, \seq_set_item:cnn, \seq_gset_item:Nnn, \seq_gset_item:cnn}
+% \begin{syntax}
+% \cs{seq_set_item:Nnn} \meta{seq~var} \Arg{intexpr} \Arg{item}
+% \cs{seq_set_item:NnnTF} \meta{seq~var} \Arg{intexpr} \Arg{item} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Removes the item of \meta{sequence} at the position given by
+% evaluating the \meta{integer expression} and replaces it by
+% \meta{item}. Items are indexed from $1$ on the left/top of the
+% \meta{sequence}, or from $-1$ on the right/bottom. If the
+% \meta{integer expression} is zero or is larger (in absolute value)
+% than the number of items in the sequence, the \meta{sequence} is not
+% modified. In these cases, \cs{seq_set_item:Nnn} raises an error
+% while \cs{seq_set_item:NnnTF} runs the \meta{false code}. In cases
+% where the assignment was successful, \meta{true code} is run
+% 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}
@@ -936,7 +972,7 @@
% \begin{macro}{\@@_case:NnTF}
% \begin{macro}{\@@_case_true:w, \@@_case_false:w, \@@_case_end:nw}
% For boolean cases the overall idea is the same as for
-% \cs{tl_case:nn(TF)} as described in \pkg{l3tl}.
+% \cs{tl_case:nnTF} as described in \pkg{l3tl}.
% \begin{macrocode}
\cs_new:Npn \bool_case_true:nTF
{ \exp:w \@@_case:NnTF \c_true_bool }
@@ -1126,6 +1162,177 @@
% \end{macrocode}
% \end{macro}
%
+%
+% \begin{macro}{\@@_int_eval:w}
+% Useful to more quickly go through items.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_int_eval:w \tex_numexpr:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[noTF]{\seq_set_item:Nnn, \seq_set_item:cnn, \seq_gset_item:Nnn, \seq_gset_item:cnn}
+% \begin{macro}{\@@_set_item:NnnNN, \@@_set_item:nnNNNN, \@@_set_item_false:nnNNNN, \@@_set_item:nNnnNNNN}
+% \begin{macro}[rEXP]{\@@_set_item:wn, \@@_set_item_end:w}
+% The conditionals are distinguished from the |Nnn| versions by the
+% last argument \cs{use_ii:nn} vs \cs{use_i:nn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_set_item:Nnn #1#2#3
+ { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_set:Nx \use_i:nn }
+\cs_new_protected:Npn \seq_gset_item:Nnn #1#2#3
+ { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_gset:Nx \use_i:nn }
+\cs_generate_variant:Nn \seq_set_item:Nnn { c }
+\cs_generate_variant:Nn \seq_gset_item:Nnn { c }
+\prg_new_protected_conditional:Npnn \seq_set_item:Nnn #1#2#3 { TF , T , F }
+ { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_set:Nx \use_ii:nn }
+\prg_new_protected_conditional:Npnn \seq_gset_item:Nnn #1#2#3 { TF , T , F }
+ { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_gset:Nx \use_ii:nn }
+\prg_generate_conditional_variant:Nnn \seq_set_item:Nnn { c } { TF , T , F }
+\prg_generate_conditional_variant:Nnn \seq_gset_item:Nnn { c } { TF , T , F }
+% \end{macrocode}
+% Save the item to be stored and evaluate the position and the sequence
+% length only once. Then depending on the sign of the position, check
+% that it is not bigger than the length (in absolute value) nor zero.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_item:NnnNN #1#2#3
+ {
+ \tl_set:Nn \l_@@_internal_a_tl { \@@_item:n {#3} }
+ \exp_args:Nff \@@_set_item:nnNNNN
+ { \int_eval:n {#2} } { \seq_count:N #1 } #1 \use_none:nn
+ }
+\cs_new_protected:Npn \@@_set_item:nnNNNN #1#2
+ {
+ \int_compare:nNnTF {#1} > 0
+ { \int_compare:nNnF {#1} > {#2} { \@@_set_item:nNnnNNNN { #1 - 1 } } }
+ {
+ \int_compare:nNnF {#1} < {-#2}
+ {
+ \int_compare:nNnF {#1} = 0
+ { \@@_set_item:nNnnNNNN { #2 + #1 } }
+ }
+ }
+ \@@_set_item_false:nnNNNN {#1} {#2}
+ }
+% \end{macrocode}
+% If the position is not ok, \cs{@@_set_item_false:nnNNNN} calls an
+% error or returns \texttt{false} (depending on the \cs{use_i:nn} vs
+% \cs{use_ii:nn} argument mentioned above).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_item_false:nnNNNN #1#2#3#4#5#6
+ {
+ #6
+ {
+ \__kernel_msg_error:nnxxx { seq } { item-too-large }
+ { \token_to_str:N #3 } {#2} {#1}
+ }
+ { \prg_return_false: }
+ }
+\__kernel_msg_new:nnnn { seq } { item-too-large }
+ { Sequence~'#1'~does~not~have~an~item~#3 }
+ {
+ An~attempt~was~made~to~push~or~pop~the~item~at~position~#3~
+ of~'#1',~but~this~
+ \int_compare:nTF { #3 = 0 }
+ { position~does~not~exist. }
+ { sequence~only~has~#2~item \int_compare:nF { #2 = 1 } {s}. }
+ }
+% \end{macrocode}
+% If the position is ok, \cs{@@_set_item:nNnnNNNN} makes the assignment
+% and returns \texttt{true} (in the case of conditionnals). Here |#1|
+% is an integer expression (position minus one), it needs to be
+% evaluated. The sequence |#5| starts with \cs{s_@@} (even if empty),
+% which stops the integer expression and is absorbed by it. The
+% \cs{if_meaning:w} test is slightly faster than an integer test (but
+% only works when testing against zero, hence the offset we chose in
+% the position). When we are done skipping items, insert the saved
+% item \cs{l_@@_internal_a_tl}. For |put| functions the last argument
+% of \cs{@@_set_item_end:w} is \cs{use_none:nn} and it absorbs the
+% item |#2| that we are removing: this is only useful for the |pop|
+% functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_item:nNnnNNNN #1#2#3#4#5#6#7#8
+ {
+ #7 #5
+ {
+ \s_@@
+ \exp_after:wN \@@_set_item:wn
+ \int_value:w \@@_int_eval:w #1
+ #5 \s_@@_stop #6
+ }
+ #8 { } { \prg_return_true: }
+ }
+\cs_new:Npn \@@_set_item:wn #1 \@@_item:n #2
+ {
+ \if_meaning:w 0 #1 \@@_set_item_end:w \fi:
+ \exp_not:n { \@@_item:n {#2} }
+ \exp_after:wN \@@_set_item:wn
+ \int_value:w \@@_int_eval:w #1 - 1 \s_@@
+ }
+\cs_new:Npn \@@_set_item_end:w #1 \exp_not:n #2 #3 \s_@@ #4 \s_@@_stop #5
+ {
+ #1
+ \exp_not:o \l_@@_internal_a_tl
+ \exp_not:n {#4}
+ #5 #2
+ }
+% \end{macrocode}
+% \end{macro}
+% \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_set_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{@@_set_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 \@@_set_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}
@@ -1209,18 +1416,18 @@
{
\sys_if_shell:TF
{ \exp_args:No \@@_shell_open:nN { \tl_to_str:n {#2} } #1 }
- { \__kernel_msg_error:nn { kernel } { pipe-failed } }
+ { \__kernel_msg_error:nn { ior } { pipe-failed } }
}
\cs_new_protected:Npn \@@_shell_open:nN #1#2
{
\tl_if_in:nnTF {#1} { " }
{
\__kernel_msg_error:nnx
- { kernel } { quote-in-shell } {#1}
+ { ior } { quote-in-shell } {#1}
}
{ \__kernel_ior_open:Nn #2 { |#1 } }
}
-\__kernel_msg_new:nnnn { kernel } { pipe-failed }
+\__kernel_msg_new:nnnn { ior } { pipe-failed }
{ Cannot~run~piped~system~commands. }
{
LaTeX~tried~to~call~a~system~process~but~this~was~not~possible.\\