diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3basics.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3basics.dtx | 166 |
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} % |