diff options
Diffstat (limited to 'macros/latex/contrib/l3kernel/l3basics.dtx')
-rw-r--r-- | macros/latex/contrib/l3kernel/l3basics.dtx | 170 |
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 } |