summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3basics.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3basics.dtx166
1 files changed, 104 insertions, 62 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
index 549ec6de6f8..ede47fd6312 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
@@ -34,8 +34,8 @@
%% -----------------------------------------------------------------------
%
%<*driver|package>
-\RequirePackage{l3names}
-\GetIdInfo$Id: l3basics.dtx 3987 2012-07-15 21:57:39Z joseph $
+\RequirePackage{l3bootstrap}
+\GetIdInfo$Id: l3basics.dtx 4069 2012-08-08 23:12:57Z bruno $
{L3 Basic definitions}
%</driver|package>
%<*driver>
@@ -1019,7 +1019,7 @@
% \cs{cs_if_eq:NNTF} \Arg{cs_1} \Arg{cs_2} \Arg{true code} \Arg{false code}
% \end{syntax}
% Compares the definition of two \meta{control sequences} and
-% is logically \texttt{true} the same, \emph{i.e.}~if the have exactly
+% is logically \texttt{true} the same, \emph{i.e.}~if they have exactly
% the same definition when examined with \cs{cs_show:N}.
% \end{function}
%
@@ -1454,7 +1454,7 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[EXP]{\token_to_str:c, \cs_meaning:c}
+% \begin{macro}[EXP]{\token_to_meaning:c, \token_to_str:c, \cs_meaning:c}
% \begin{macro}{\cs_show:c}
% A small number of variants defined by hand.
% Some of the necessary functions
@@ -1478,6 +1478,7 @@
{ \exp_args:Nc \cs_meaning:N {#1} }
{ \tl_to_str:n {undefined} }
}
+\tex_let:D \token_to_meaning:c = \cs_meaning:c
\etex_protected:D \tex_def:D \cs_show:c
{ \group_begin: \exp_args:NNc \group_end: \cs_show:N }
% \end{macrocode}
@@ -1589,6 +1590,15 @@
%
% \subsection{Selecting tokens}
%
+% \begin{variable}{\l__exp_internal_tl}
+% Scratch token list variable for \pkg{l3expan}, used by \cs{use:x},
+% used in defining conditionals. We don't use |tl| methods because
+% \pkg{l3basics} is loaded earlier.
+% \begin{macrocode}
+\cs_set_nopar:Npn \l__exp_internal_tl { }
+% \end{macrocode}
+% \end{variable}
+%
% \begin{macro}[EXP]{\use:c}
% This macro grabs its argument and returns a csname from it.
% \begin{macrocode}
@@ -1856,41 +1866,44 @@
% defining function. The sixth is the parameters to use (possibly
% empty), the seventh is the list of forms to define, the eigth is the
% replacement text which we will augment when defining the forms.
+% The use of \cs{etex_detokenize:D} makes the later loop more robust.
% \begin{macrocode}
\cs_set_protected:Npn \__prg_generate_conditional:nnNnnnnn #1#2#3#4#5#6#7#8
{
- \if_meaning:w \c_true_bool #3
- \exp_after:wN \use_i:nn
- \else:
- \exp_after:wN \use_ii:nn
- \fi:
- {
- \__prg_generate_conditional:nnnnnnw
- {#4} {#5} {#1} {#2} {#6} {#8}
- #7 , , \q_recursion_stop
- }
- {
+ \if_meaning:w \c_false_bool #3
\__msg_kernel_error:nnx { kernel } { missing-colon }
{ \token_to_str:c {#1} }
- }
+ \exp_after:wN \use_none:nn
+ \fi:
+ \use:x
+ {
+ \exp_not:N \__prg_generate_conditional:nnnnnnw
+ \exp_not:n { {#4} {#5} {#1} {#2} {#6} {#8} }
+ \etex_detokenize:D {#7}
+ \exp_not:n { , \q_recursion_tail , \q_recursion_stop }
+ }
}
% \end{macrocode}
% Looping through the list of desired forms. First are six arguments
% and seventh is the form. Use the form to call the
% correct type. If the form does not exist, the \cs{use:c}
% construction results in \tn{relax}, and the error message is
-% displayed, then \cs{use_none:nnnnnnn} cleans up. Otherwise, the
+% displayed (unless the form is empty, to allow for |{T, , F}|),
+% then \cs{use_none:nnnnnnn} cleans up. Otherwise, the
% error message is removed by the variant form.
% \begin{macrocode}
\cs_set_protected:Npn \__prg_generate_conditional:nnnnnnw #1#2#3#4#5#6#7 ,
{
- \if_catcode:w \scan_stop: \etex_detokenize:D {#7} \scan_stop:
+ \if_meaning:w \q_recursion_tail #7
\exp_after:wN \use_none_delimit_by_q_recursion_stop:w
\fi:
- \use:c { __prg_generate_ \etex_detokenize:D {#7} _form:wnnnnnn }
- \__msg_kernel_error:nnxx
- { kernel } { conditional-form-unknown }
- { \tl_to_str:n {#7} } { \token_to_str:c { #3 : #4 } }
+ \use:c { __prg_generate_ #7 _form:wnnnnnn }
+ \tl_if_empty:nF {#7}
+ {
+ \__msg_kernel_error:nnxx
+ { kernel } { conditional-form-unknown }
+ {#7} { \token_to_str:c { #3 : #4 } }
+ }
\use_none:nnnnnnn
\q_stop
{#1} {#2} {#3} {#4} {#5} {#6}
@@ -1951,35 +1964,44 @@
% \end{macro}
%
% \begin{macro}{\prg_set_eq_conditional:NNn,\prg_new_eq_conditional:NNn}
-% The setting-equal functions. Split the base function to be copied,
-% and feed a first auxiliary \Arg{name} \Arg{signature} \meta{boolean}
-% \meta{copying~function} \meta{new~function} \Arg{conditions}.
-% \begin{macrocode}
-\cs_set_protected:Npn \prg_set_eq_conditional:NNn #1#2
+% \begin{macro}[aux]{\__prg_set_eq_conditional:NNNn}
+% The setting-equal functions. Split the two functions and feed a
+% first auxiliary \Arg{name_1} \Arg{signature_1} \meta{boolean_1}
+% \Arg{name_2} \Arg{signature_2} \meta{boolean_2}
+% \meta{copying~function} \meta{conditions} |,| \cs{q_recursion_tail}
+% |,| \cs{q_recursion_stop}
+% \begin{macrocode}
+\cs_set_protected_nopar:Npn \prg_set_eq_conditional:NNn
+ { \__prg_set_eq_conditional:NNNn \cs_set_eq:cc }
+\cs_set_protected_nopar:Npn \prg_new_eq_conditional:NNn
+ { \__prg_set_eq_conditional:NNNn \cs_new_eq:cc }
+\cs_set_protected:Npn \__prg_set_eq_conditional:NNNn #1#2#3#4
{
- \__cs_split_function:NN #2 \__prg_set_eq_conditional:nnNNNn
- \cs_set_eq:cc #1
- }
-\cs_set_protected:Npn \prg_new_eq_conditional:NNn #1#2
- {
- \__cs_split_function:NN #2 \__prg_set_eq_conditional:nnNNNn
- \cs_new_eq:cc #1
+ \use:x
+ {
+ \exp_not:N \__prg_set_eq_conditional:nnNnnNNw
+ \__cs_split_function:NN #2 \prg_do_nothing:
+ \__cs_split_function:NN #3 \prg_do_nothing:
+ \exp_not:N #1
+ \etex_detokenize:D {#4}
+ \exp_not:n { , \q_recursion_tail , \q_recursion_stop }
+ }
}
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
% \begin{macro}[aux]
% {
-% \__prg_set_eq_conditional:nnNNNn ,
% \__prg_set_eq_conditional:nnNnnNNw ,
% \__prg_set_eq_conditional_loop:nnnnNw
% }
% \begin{macro}[aux, EXP]
% {
-% \__prg_conditional_p_form:nnn ,
-% \__prg_conditional_TF_form:nnn ,
-% \__prg_conditional_T_form:nnn ,
-% \__prg_conditional_F_form:nnn ,
+% \__prg_set_eq_conditional_p_form:nnn ,
+% \__prg_set_eq_conditional_TF_form:nnn ,
+% \__prg_set_eq_conditional_T_form:nnn ,
+% \__prg_set_eq_conditional_F_form:nnn ,
% }
% Split the function to be defined, and setup a manual clist loop over
% argument |#6| of the first auxiliary. The second auxiliary receives
@@ -1992,12 +2014,6 @@
% step in the loop, make sure that the conditional form we copy is
% defined, and copy it, otherwise abort.
% \begin{macrocode}
-\cs_set_protected:Npn \__prg_set_eq_conditional:nnNNNn #1#2#3#4#5#6
- {
- \__cs_split_function:NN #5 \__prg_set_eq_conditional:nnNnnNNw
- {#1} {#2} #3 #4
- #6 , \scan_stop: , \q_recursion_stop
- }
\cs_set_protected:Npn \__prg_set_eq_conditional:nnNnnNNw #1#2#3#4#5#6
{
\if_meaning:w \c_false_bool #3
@@ -2014,29 +2030,41 @@
}
\cs_set_protected:Npn \__prg_set_eq_conditional_loop:nnnnNw #1#2#3#4#5#6 ,
{
- \if_meaning:w \scan_stop: #6 \scan_stop:
+ \if_meaning:w \q_recursion_tail #6
\exp_after:wN \use_none_delimit_by_q_recursion_stop:w
\fi:
- \cs_if_exist:cTF
- { \use:c { __prg_conditional_ #6 _form:nn } {#3} {#4} }
- {
- #5
- { \use:c { __prg_conditional_ #6 _form:nn } {#1} {#2} }
- { \use:c { __prg_conditional_ #6 _form:nn } {#3} {#4} }
- }
- {
- \__msg_kernel_error:nnx { kernel } { command-not-defined }
+ \use:c { __prg_set_eq_conditional_ #6 _form:wNnnnn }
+ \tl_if_empty:nF {#6}
{
- \token_to_str:c
- { \use:c { __prg_conditional_ #6 _form:nn } {#3} {#4} }
+ \__msg_kernel_error:nnxx
+ { kernel } { conditional-form-unknown }
+ {#6} { \token_to_str:c { #1 : #2 } }
}
- }
+ \use_none:nnnnnn
+ \q_stop
+ #5 {#1} {#2} {#3} {#4}
\__prg_set_eq_conditional_loop:nnnnNw {#1} {#2} {#3} {#4} #5
}
-\cs_set:Npn \__prg_conditional_p_form:nn #1#2 { #1 _p : #2 }
-\cs_set:Npn \__prg_conditional_TF_form:nn #1#2 { #1 : #2 TF }
-\cs_set:Npn \__prg_conditional_T_form:nn #1#2 { #1 : #2 T }
-\cs_set:Npn \__prg_conditional_F_form:nn #1#2 { #1 : #2 F }
+\cs_set:Npn \__prg_set_eq_conditional_p_form:wNnnnn #1 \q_stop #2#3#4#5#6
+ {
+ \__chk_if_exist_cs:c { #5 _p : #6 }
+ #2 { #3 _p : #4 } { #5 _p : #6 }
+ }
+\cs_set:Npn \__prg_set_eq_conditional_TF_form:wNnnnn #1 \q_stop #2#3#4#5#6
+ {
+ \__chk_if_exist_cs:c { #5 : #6 TF }
+ #2 { #3 : #4 TF } { #5 : #6 TF }
+ }
+\cs_set:Npn \__prg_set_eq_conditional_T_form:wNnnnn #1 \q_stop #2#3#4#5#6
+ {
+ \__chk_if_exist_cs:c { #5 : #6 T }
+ #2 { #3 : #4 T } { #5 : #6 T }
+ }
+\cs_set:Npn \__prg_set_eq_conditional_F_form:wNnnnn #1 \q_stop #2#3#4#5#6
+ {
+ \__chk_if_exist_cs:c { #5 : #6 F }
+ #2 { #3 : #4 F } { #5 : #6 F }
+ }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -3035,6 +3063,20 @@
}
% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}{\__prg_break_point:}
+% \begin{macro}{\__prg_break:, \__prg_break:n}
+% Very simple analogues of \cs{__prg_break_point:Nn} and
+% \cs{__prg_map_break:Nn}, for use in fast short-term recursions which
+% are not mappings, do not need to support nesting, and in which
+% nothing has to be done at the end of the loop.
+% \begin{macrocode}
+\cs_new_eq:NN \__prg_break_point: \prg_do_nothing:
+\cs_new:Npn \__prg_break: #1 \__prg_break_point: { }
+\cs_new:Npn \__prg_break:n #1#2 \__prg_break_point: {#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
%
% \subsection{Deprecated functions}
%