summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3kernel/l3basics.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/l3kernel/l3basics.dtx')
-rw-r--r--macros/latex/contrib/l3kernel/l3basics.dtx170
1 files changed, 121 insertions, 49 deletions
diff --git a/macros/latex/contrib/l3kernel/l3basics.dtx b/macros/latex/contrib/l3kernel/l3basics.dtx
index 0be8bdc8b2..bc79956d05 100644
--- a/macros/latex/contrib/l3kernel/l3basics.dtx
+++ b/macros/latex/contrib/l3kernel/l3basics.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-01-22}
+% \date{Released 2024-02-13}
%
% \maketitle
%
@@ -92,6 +92,9 @@
% to occur within the same function. Indeed, it is often necessary
% to start a group within one function and finish it within another,
% for example when seeking to use non-standard category codes.
+% \begin{texnote}
+% These are the \TeX{} primitives \tn{begingroup} and \tn{endgroup}.
+% \end{texnote}
% \end{function}
%
% \begin{function}{\group_insert_after:N}
@@ -1248,11 +1251,13 @@
%
% \begin{function}[EXP]{\if:w, \if_charcode:w, \if_catcode:w}
% \begin{syntax}
-% "\if:w" <token_1> <token_2> <true code> "\else:" <false code> "\fi:" \\
-% "\if_catcode:w" <token_1> <token_2> <true code> "\else:" <false code> "\fi:"
+% "\if:w" <token(s)> <true code> "\else:" <false code> "\fi:" \\
+% "\if_catcode:w" <token(s_> <true code> "\else:" <false code> "\fi:"
% \end{syntax}
-% These conditionals expand any following tokens until two
-% unexpandable tokens are left. If you wish to prevent this expansion,
+% These conditionals expand \meta{token(s)} until two
+% unexpandable tokens \meta{token_1} and \meta{tokens_2} are left;
+% any further tokens become part of the \meta{true code}.
+% If you wish to prevent this expansion,
% prefix the token in question with "\exp_not:N". "\if_catcode:w"
% tests if the category codes of the two tokens are the same whereas
% "\if:w" tests if the character codes are
@@ -2451,22 +2456,28 @@
% (to be defined) if it does not already exist.
%
% \begin{macro}[pTF, EXP]{\cs_if_exist:N, \cs_if_exist:c}
+% \begin{macro}{\@@_if_exist_c_aux:,\@@_if_exist_c_aux:w}
% Two versions for checking existence. For the |N| form we firstly
% check for \cs{scan_stop:} and then if it is in the hash
% table. There is no problem when inputting something like \cs{else:}
% or \cs{fi:} as \TeX{} will only ever skip input in case the token
% tested against is \cs{scan_stop:}.
+%
+% In both the |N| and |c| form we use the way \cs{prg_set_conditional:Npnn}
+% optimizes the conditionals to negate the tests using \cs{else:} (the
+% \cs{else:} in the top level functions will be removed by the optimization,
+% and this usage of \cs{else:} will be fine).
% \begin{macrocode}
\prg_set_conditional:Npnn \cs_if_exist:N #1 { p , T , F , TF }
{
\if_meaning:w #1 \scan_stop:
- \prg_return_false:
+ \use_i:nnnn
+ \else:
+ \fi:
+ \if_cs_exist:N #1
+ \prg_return_true:
\else:
- \if_cs_exist:N #1
- \prg_return_true:
- \else:
- \prg_return_false:
- \fi:
+ \prg_return_false:
\fi:
}
% \end{macrocode}
@@ -2477,87 +2488,148 @@
% disturb the scanner. Therefore, we ensure that the second test is
% performed after the first one has concluded completely.
% \begin{macrocode}
-\prg_set_conditional:Npnn \cs_if_exist:c #1 { p , T , F , TF }
+\cs_if_exist:NTF \tex_lastnamedcs:D
{
- \if_cs_exist:w #1 \cs_end:
- \exp_after:wN \use_i:nn
- \else:
- \exp_after:wN \use_ii:nn
- \fi:
- {
- \exp_after:wN \if_meaning:w \cs:w #1 \cs_end: \scan_stop:
- \prg_return_false:
- \else:
- \prg_return_true:
- \fi:
- }
- \prg_return_false:
+ \prg_set_conditional:Npnn \cs_if_exist:c #1 { p , T , F , TF }
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \@@_if_exist_c_aux:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ \cs_set:Npn \@@_if_exist_c_aux:
+ { \fi: \exp_after:wN \if_meaning:w \tex_lastnamedcs:D \scan_stop: \else: }
+ }
+ {
+ \prg_set_conditional:Npnn \cs_if_exist:c #1 { p , T , F , TF }
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \@@_if_exist_c_aux:w
+ \fi:
+ \use_none:n {#1}
+ \if_false:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ \cs_set:Npn \@@_if_exist_c_aux:w \fi: \use_none:n #1 \if_false:
+ { \fi: \exp_after:wN \if_meaning:w \cs:w #1 \cs_end: \scan_stop: \else: }
}
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
% \begin{macro}[pTF, EXP]{\cs_if_free:N, \cs_if_free:c}
% The logical reversal of the above.
% \begin{macrocode}
\prg_set_conditional:Npnn \cs_if_free:N #1 { p , T , F , TF }
{
+ \if_cs_exist:N #1
+ \else:
+ \use_none:nnnn
+ \fi:
\if_meaning:w #1 \scan_stop:
\prg_return_true:
\else:
- \if_cs_exist:N #1
- \prg_return_false:
- \else:
- \prg_return_true:
- \fi:
+ \prg_return_false:
\fi:
}
-\prg_set_conditional:Npnn \cs_if_free:c #1 { p , T , F , TF }
+\cs_if_exist:NTF \tex_lastnamedcs:D
{
- \if_cs_exist:w #1 \cs_end:
- \exp_after:wN \use_i:nn
- \else:
- \exp_after:wN \use_ii:nn
- \fi:
+ \prg_set_conditional:Npnn \cs_if_free:c #1 { p , T , F , TF }
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \@@_if_free_c_aux:w
+ \fi:
+ \if_true:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ \cs_set:Npn \@@_if_free_c_aux:w \fi: \if_true:
+ { \fi: \exp_after:wN \if_meaning:w \tex_lastnamedcs:D \scan_stop: }
+ }
+ {
+ \prg_set_conditional:Npnn \cs_if_free:c #1 { p , T , F , TF }
{
- \exp_after:wN \if_meaning:w \cs:w #1 \cs_end: \scan_stop:
+ \if_cs_exist:w #1 \cs_end:
+ \@@_if_free_c_aux:w
+ \fi:
+ \use_none:n {#1}
+ \if_true:
\prg_return_true:
\else:
\prg_return_false:
\fi:
}
- { \prg_return_true: }
+ \cs_set:Npn \@@_if_free_c_aux:w \fi: \use_none:n #1 \if_true:
+ { \fi: \exp_after:wN \if_meaning:w \cs:w #1 \cs_end: \scan_stop: }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[EXP,noTF,added=2011-10-10]
% {\cs_if_exist_use:N, \cs_if_exist_use:c}
+% \begin{macro}{\@@_if_exist_use_aux:w, \@@_if_exist_use_aux:Nnn}
% The \cs[index=cs_if_exist_use:N]{cs_if_exist_use:\ldots{}}
% functions cannot be implemented
% as conditionals because the true branch must leave both the control
% sequence itself and the true code in the input stream.
% For the \texttt{c} variants, we are careful not to put the control
% sequence in the hash table if it does not exist.
-% In \LuaTeX{} we could use the \tn{lastnamedcs} primitive.
+% If available we use the \tn{lastnamedcs} primitive.
% \begin{macrocode}
\cs_set:Npn \cs_if_exist_use:NTF #1#2
{ \cs_if_exist:NTF #1 { #1 #2 } }
\cs_set:Npn \cs_if_exist_use:NF #1
- { \cs_if_exist:NTF #1 { #1 } }
+ { \cs_if_exist:NTF #1 #1 }
\cs_set:Npn \cs_if_exist_use:NT #1 #2
- { \cs_if_exist:NTF #1 { #1 #2 } { } }
+ { \cs_if_exist:NT #1 { #1 #2 } }
\cs_set:Npn \cs_if_exist_use:N #1
- { \cs_if_exist:NTF #1 { #1 } { } }
-\cs_set:Npn \cs_if_exist_use:cTF #1#2
- { \cs_if_exist:cTF {#1} { \use:c {#1} #2 } }
+ { \cs_if_exist:NT #1 #1 }
+\cs_if_exist:NTF \tex_lastnamedcs:D
+ {
+ \cs_set:Npn \cs_if_exist_use:cTF #1
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \@@_if_exist_use_aux:w
+ \fi:
+ \use_ii:nn
+ }
+ \cs_set:Npn \@@_if_exist_use_aux:w \fi: \use_ii:nn
+ { \fi: \exp_after:wN \@@_if_exist_use_aux:Nnn \tex_lastnamedcs:D }
+ }
+ {
+ \cs_set:Npn \cs_if_exist_use:cTF #1
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \@@_if_exist_use_aux:w
+ \fi:
+ \use_iii:nnn {#1}
+ }
+ \cs_set:Npn \@@_if_exist_use_aux:w \fi: \use_iii:nnn #1
+ { \fi: \exp_after:wN \@@_if_exist_use_aux:Nnn \cs:w #1 \cs_end: }
+ }
+\cs_set:Npn \@@_if_exist_use_aux:Nnn #1#2
+ {
+ \if_meaning:w #1 \scan_stop:
+ \exp_after:wN \use_iii:nnn
+ \fi:
+ \use_i:nn { #1 #2 }
+ }
\cs_set:Npn \cs_if_exist_use:cF #1
- { \cs_if_exist:cTF {#1} { \use:c {#1} } }
+ { \cs_if_exist_use:cTF {#1} {} }
\cs_set:Npn \cs_if_exist_use:cT #1#2
- { \cs_if_exist:cTF {#1} { \use:c {#1} #2 } { } }
+ { \cs_if_exist_use:cTF {#1} {#2} {} }
\cs_set:Npn \cs_if_exist_use:c #1
- { \cs_if_exist:cTF {#1} { \use:c {#1} } { } }
+ { \cs_if_exist_use:cTF {#1} {} {} }
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
% \subsection{Preliminaries for new functions}
%
@@ -3270,7 +3342,7 @@
\cs_new_protected:Npn \group_show_list:
{ \@@_group_show:NN \use_none:n 1 }
\cs_new_protected:Npn \group_log_list:
- { \@@_group_show:NN \int_zero:N 0 }
+ { \@@_group_show:NN \int_gzero:N 0 }
\cs_new_protected:Npn \@@_group_show:NN #1#2
{
\use:e
@@ -3280,7 +3352,7 @@
\int_set:Nn \tex_errorcontextlines:D { -1 }
\exp_not:N \exp_after:wN \scan_stop:
\tex_showgroups:D
- \int_set:Nn \tex_interactionmode:D
+ \int_gset:Nn \tex_interactionmode:D
{ \int_use:N \tex_interactionmode:D }
\int_set:Nn \tex_tracingonline:D
{ \int_use:N \tex_tracingonline:D }