diff options
author | Karl Berry <karl@freefriends.org> | 2015-09-06 23:19:17 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2015-09-06 23:19:17 +0000 |
commit | 3cb4e75696df6c7abebf17fbc606ca86dcdfb520 (patch) | |
tree | 729978e0726cdb9d9f34a3d2e249c71a82e07f97 /Master/texmf-dist/source/latex/l3kernel/l3basics.dtx | |
parent | 32f50b97c2ae44e93225d1024afab9727fc02e00 (diff) |
l3 (6sep15)
git-svn-id: svn://tug.org/texlive/trunk@38305 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3basics.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3basics.dtx | 215 |
1 files changed, 134 insertions, 81 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index 5e97b697fdf..63bde464f33 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} %</driver> %<*driver|package> -\GetIdInfo$Id: l3basics.dtx 5500 2015-01-27 14:37:04Z joseph $ +\GetIdInfo$Id: l3basics.dtx 5897 2015-08-28 09:06:29Z joseph $ {L3 Basic definitions} %</driver|package> %<*driver> @@ -699,7 +699,7 @@ % \end{texnote} % \end{function} % -% \begin{function}[updated = 2012-09-09]{\cs_show:N, \cs_show:c} +% \begin{function}[updated = 2015-08-03]{\cs_show:N, \cs_show:c} % \begin{syntax} % \cs{cs_show:N} \meta{control sequence} % \end{syntax} @@ -744,7 +744,7 @@ % after two expansions of \cs{use:c}. % % \begin{function}[EXP,added = 2012-11-10] -% {\cs_if_exist_use:N,\cs_if_exist_use:c} +% {\cs_if_exist_use:N, \cs_if_exist_use:c} % \begin{syntax} % \cs{cs_if_exist_use:N} \meta{control sequence} % \end{syntax} @@ -754,7 +754,7 @@ % \end{function} % % \begin{function}[TF,EXP, added = 2012-11-10] -% {\cs_if_exist_use:N,\cs_if_exist_use:c} +% {\cs_if_exist_use:N, \cs_if_exist_use:c} % \begin{syntax} % \cs{cs_if_exist_use:NTF} \meta{control sequence} \Arg{true code} \Arg{false code} % \end{syntax} @@ -1155,7 +1155,7 @@ % \end{texnote} % \end{function} % -% \begin{function}[EXP]{\if:w, \if_charcode:w,\if_catcode:w} +% \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:" @@ -1222,6 +1222,23 @@ % \texttt{check-declarations} is active. % \end{function} % +% \begin{function}{\__chk_log:x} +% \begin{syntax} +% \cs{__chk_log:x} \Arg{message text} +% \end{syntax} +% If the \texttt{log-functions} option is active, this function writes +% the \meta{message text} to the log file using \cs{iow_log:x}. +% Otherwise, the \meta{message text} is ignored using \cs{use_none:n}. +% \end{function} +% +% \begin{function}{\__chk_suspend_log:, \__chk_resume_log:} +% \begin{syntax} +% \cs{__chk_suspend_log:} \ldots{} \cs{__chk_log:x} \ldots{} \cs{__chk_resume_log:} +% \end{syntax} +% Any \cs{__chk_log:x} command between \cs{__chk_suspend_log:} and +% \cs{__chk_resume_log:} is suppressed. These commands can be nested. +% \end{function} +% % \begin{function}[EXP]{\__cs_count_signature:N, \__cs_count_signature:c} % \begin{syntax} % \cs{__cs_count_signature:N} \meta{function} @@ -1361,24 +1378,35 @@ % \end{macro} % % \begin{macro}[EXP]{\exp_after:wN, \exp_not:N, \exp_not:n} -% The three |\exp_| functions are used in the \textsf{l3expan} module +% The five |\exp_| functions are used in the \textsf{l3expan} module % where they are described. % \begin{macrocode} \tex_let:D \exp_after:wN \tex_expandafter:D \tex_let:D \exp_not:N \tex_noexpand:D \tex_let:D \exp_not:n \etex_unexpanded:D +\tex_let:D \exp:w \tex_romannumeral:D +\tex_chardef:D \exp_end: = 0 ~ % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\token_to_meaning:N, \token_to_str:N, \cs_meaning:N} + + +% \begin{macro}[EXP]{\token_to_meaning:N, \cs_meaning:N} % Examining a control sequence or token. % \begin{macrocode} \tex_let:D \token_to_meaning:N \tex_meaning:D -\tex_let:D \token_to_str:N \tex_string:D \tex_let:D \cs_meaning:N \tex_meaning:D % \end{macrocode} % \end{macro} % +% \begin{macro}[EXP]{\tl_to_str:n, \token_to_str:N} +% Making strings. +% \begin{macrocode} +\tex_let:D \tl_to_str:n \etex_detokenize:D +\tex_let:D \token_to_str:N \tex_string:D +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\scan_stop:, \group_begin:, \group_end:} % The next three are basic functions for which there also exist % versions that are safe inside alignments. These safe versions are @@ -1692,18 +1720,18 @@ % interface. % % \begin{macro}[EXP]{\prg_return_true:, \prg_return_false:} -% The idea here is that \cs{__int_to_roman:w} will expand fully any +% The idea here is that \cs{exp:w} will expand fully any % \cs{else:} and the \cs{fi:} that are waiting to be discarded, -% before reaching the \cs{c_zero} which will leave the expansion null. +% before reaching the \cs{exp_end:} which will leave the expansion null. % The code can then leave either the first or second argument in the % input stream. This means that all of the branching code has to contain % at least two tokens: see how the logical tests are actually implemented % to see this. % \begin{macrocode} \cs_set_nopar:Npn \prg_return_true: - { \exp_after:wN \use_i:nn \__int_to_roman:w } + { \exp_after:wN \use_i:nn \exp:w } \cs_set_nopar:Npn \prg_return_false: - { \exp_after:wN \use_ii:nn \__int_to_roman:w} + { \exp_after:wN \use_ii:nn \exp:w} % \end{macrocode} % An extended state space could be implemented by including a more % elaborate function in place of \cs{use_i:nn}/\cs{use_ii:nn}. Provided @@ -1813,7 +1841,7 @@ % defining function. The sixth is the parameters to use (possibly % empty), the seventh is the list of forms to define, the eighth 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. +% The use of \cs{tl_to_str:n} makes the later loop more robust. % \begin{macrocode} \cs_set_protected:Npn \__prg_generate_conditional:nnNnnnnn #1#2#3#4#5#6#7#8 { @@ -1826,7 +1854,7 @@ { \exp_not:N \__prg_generate_conditional:nnnnnnw \exp_not:n { {#4} {#5} {#1} {#2} {#6} {#8} } - \etex_detokenize:D {#7} + \tl_to_str:n {#7} \exp_not:n { , \q_recursion_tail , \q_recursion_stop } } } @@ -1870,7 +1898,7 @@ % following arguments: 1: \texttt{set} or \texttt{new}, 2: empty or % \texttt{\_protected}, 3: function name 4: signature, 5: parameter % text (or empty), 6: replacement. Remember that the logic-returning -% functions expect two arguments to be present after \cs{c_zero}: +% functions expect two arguments to be present after \cs{exp_end:}: % notice the construction of the different variants relies on this, % and that the |TF| variant will be slightly faster than the |T| % version. The |p| form is only valid for expandable tests, we check @@ -1886,7 +1914,7 @@ \fi: { \exp_args:cc { cs_ #2 #3 :Npn } { #4 _p: #5 } #6 - { #7 \c_zero \c_true_bool \c_false_bool } + { #7 \exp_end: \c_true_bool \c_false_bool } } { \__msg_kernel_error:nnx { kernel } { protected-predicate } @@ -1897,24 +1925,24 @@ #1 \q_stop #2#3#4#5#6#7 { \exp_args:cc { cs_ #2 #3 :Npn } { #4 : #5 T } #6 - { #7 \c_zero \use:n \use_none:n } + { #7 \exp_end: \use:n \use_none:n } } \cs_set_protected:Npn \__prg_generate_F_form:wnnnnnn #1 \q_stop #2#3#4#5#6#7 { \exp_args:cc { cs_ #2 #3 :Npn } { #4 : #5 F } #6 - { #7 \c_zero { } } + { #7 \exp_end: { } } } \cs_set_protected:Npn \__prg_generate_TF_form:wnnnnnn #1 \q_stop #2#3#4#5#6#7 { \exp_args:cc { cs_ #2 #3 :Npn } { #4 : #5 TF } #6 - { #7 \c_zero } + { #7 \exp_end: } } % \end{macrocode} % \end{macro} % -% \begin{macro}{\prg_set_eq_conditional:NNn,\prg_new_eq_conditional:NNn} +% \begin{macro}{\prg_set_eq_conditional:NNn, \prg_new_eq_conditional:NNn} % \begin{macro}[aux]{\__prg_set_eq_conditional:NNNn} % The setting-equal functions. Split both functions and feed % \Arg{name_1} \Arg{signature_1} \meta{boolean_1} @@ -1935,7 +1963,7 @@ \__cs_split_function:NN #2 \prg_do_nothing: \__cs_split_function:NN #3 \prg_do_nothing: \exp_not:N #1 - \etex_detokenize:D {#4} + \tl_to_str:n {#4} \exp_not:n { , \q_recursion_tail , \q_recursion_stop } } } @@ -2064,26 +2092,33 @@ % The character codes are different, thus the \cs{if:w} test is false, % and \TeX{} reads \cs{__cs_to_str:N} after turning the following % control sequence into a string; this auxiliary removes the escape -% character, and stops the expansion of the initial \cs{__int_to_roman:w}. +% character, and stops the expansion of the initial \cs{tex_romannumeral:D}. % The second case is that the escape character is not printable. Then % the \cs{if:w} test is unfinished after reading a the space from % \verb*|\token_to_str:N \ |, and the auxiliary \cs{__cs_to_str:w} % is expanded, feeding |-| as a second character for the test; % the test is false, and \TeX{} skips to \cs{fi:}, then performs -% \cs{token_to_str:N}, and stops the \cs{__int_to_roman:w} with \cs{c_zero}. +% \cs{token_to_str:N}, and stops the \cs{tex_romannumeral:D} with \cs{c_zero}. % The last case is that the escape character is itself a space. In this % case, the \cs{if:w} test is true, and the auxiliary \cs{__cs_to_str:w} % comes into play, inserting |-\__int_value:w|, which expands \cs{c_zero} -% to the character |0|. The initial \cs{__int_to_roman:w} then sees +% to the character |0|. The initial \cs{tex_romannumeral:D} then sees % |0|, which is not a terminated number, followed by the escape character, -% a space, which is removed, terminating the argument of -% \cs{__int_to_roman:w}. +% a space, which is removed, terminating the expansion of +% \cs{tex_romannumeral:D}. % In all three cases, \cs{cs_to_str:N} takes two expansion steps % to be fully expanded. % \begin{macrocode} \cs_set_nopar:Npn \cs_to_str:N { - \__int_to_roman:w +% \end{macrocode} +% We implement the expansion scheme using \cs{tex_romannumeral:D} +% terminating it with \cs{c_zero} rather than using \cs{exp:w} and +% \cs{exp_end:} as we normally do. The reason is that the code +% heavily depends on terminating the expansion with \cs{c_zero} so +% we make this dependency explicit. +% \begin{macrocode} + \tex_romannumeral:D \if:w \token_to_str:N \ \__cs_to_str:w \fi: \exp_after:wN \__cs_to_str:N \token_to_str:N } @@ -2107,9 +2142,9 @@ % for the boolean. For example, % |\__cs_split_function:NN \foo_bar:cnx \use_i:nnn| as input % becomes |\use_i:nnn {foo_bar} {cnx} \c_true_bool|. -% -% We can't use a literal |:| because it has the wrong catcode here, so -% it's transformed from |@| with \cs{tex_lowercase:D}. +% +% We cannot use |:| directly as it has the wrong category code so +% an |x|-type expansion is used to force the conversion. % % First ensure that we actually get a properly evaluated string by % expanding \cs{cs_to_str:N} twice. If the function contained a @@ -2122,25 +2157,22 @@ % auxiliary trims the trailing \cs{q_mark} from the function name if % present (that is, if the original function had no colon). % \begin{macrocode} -\group_begin: -\tex_lccode:D `\@ = `\: \scan_stop: -\tex_catcode:D `\@ = 12 ~ -\tex_lowercase:D +\cs_set:Npx \__cs_split_function:NN #1 { - \group_end: - \cs_set:Npn \__cs_split_function:NN #1 - { - \exp_after:wN \exp_after:wN - \exp_after:wN \__cs_split_function_auxi:w - \cs_to_str:N #1 \q_mark \c_true_bool - @ \q_mark \c_false_bool - \q_stop - } - \cs_set:Npn \__cs_split_function_auxi:w #1 @ #2 \q_mark #3#4 \q_stop #5 - { \__cs_split_function_auxii:w #5 #1 \q_mark \q_stop {#2} #3 } - \cs_set:Npn \__cs_split_function_auxii:w #1#2 \q_mark #3 \q_stop - { #1 {#2} } + \exp_not:N \exp_after:wN \exp_not:N \exp_after:wN + \exp_not:N \exp_after:wN \exp_not:N \__cs_split_function_auxi:w + \exp_not:N \cs_to_str:N #1 \exp_not:N \q_mark \c_true_bool + \token_to_str:N : \exp_not:N \q_mark \c_false_bool + \exp_not:N \q_stop } +\use:x + { + \cs_set:Npn \exp_not:N \__cs_split_function_auxi:w + ##1 \token_to_str:N : ##2 \exp_not:N \q_mark ##3##4 \exp_not:N \q_stop ##5 + } + { \__cs_split_function_auxii:w #5 #1 \q_mark \q_stop {#2} #3 } +\cs_set:Npn \__cs_split_function_auxii:w #1#2 \q_mark #3 \q_stop + { #1 {#2} } % \end{macrocode} % \end{macro} % \end{macro} @@ -2163,7 +2195,7 @@ % \tn{relax} token. A control sequence is said to be \emph{free} % (to be defined) if it does not already exist. % -% \begin{macro}[pTF, EXP]{\cs_if_exist:N,\cs_if_exist:c} +% \begin{macro}[pTF, EXP]{\cs_if_exist:N, \cs_if_exist:c} % 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:} @@ -2209,7 +2241,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[pTF, EXP]{\cs_if_free:N,\cs_if_free:c} +% \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 } @@ -2297,6 +2329,47 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}[int]{\__chk_log:x, \__chk_suspend_log:, \__chk_resume_log:} +% This function is used to write some information to the \texttt{log} +% file in case the |log-function| option is set. Otherwise its +% argument is ignored. Using this function rather than directly using +% \cs{iow_log:x} allows for \cs{__chk_suspend_log:} which disables +% such messages until the matching \cs{__chk_resume_log:}. These two +% commands are used to improve the logging for complicated datatypes. +% They should come in pairs, which can be nested. The function +% \cs{exp_not:o} is defined in \pkg{l3expan} later on but +% \cs{__chk_suspend_log:} and \cs{__chk_resume_log:} are not used +% before that point. +% \begin{macrocode} +%<*initex> +\cs_set_protected_nopar:Npn \__chk_log:x { \use_none:n } +\cs_set_protected_nopar:Npn \__chk_suspend_log: { } +\cs_set_protected_nopar:Npn \__chk_resume_log: { } +%</initex> +%<*package> +\tex_ifodd:D \l@expl@log@functions@bool + \cs_set_protected_nopar:Npn \__chk_log:x { \iow_log:x } + \cs_set_protected_nopar:Npn \__chk_suspend_log: + { + \cs_set_protected_nopar:Npx \__chk_resume_log: + { + \cs_set_protected_nopar:Npn \__chk_resume_log: + { \exp_not:o { \__chk_resume_log: } } + \cs_set_protected_nopar:Npn \__chk_log:x + { \exp_not:o { \__chk_log:x } } + } + \cs_set_protected_nopar:Npn \__chk_log:x { \use_none:n } + } + \cs_set_protected_nopar:Npn \__chk_resume_log: { } +\else: + \cs_set_protected_nopar:Npn \__chk_log:x { \use_none:n } + \cs_set_protected_nopar:Npn \__chk_suspend_log: { } + \cs_set_protected_nopar:Npn \__chk_resume_log: { } +\fi: +%</package> +% \end{macrocode} +% \end{macro} +% % \begin{macro}[int] % {\__msg_kernel_error:nnxx, \__msg_kernel_error:nnx, \__msg_kernel_error:nn} % If an internal error occurs before \LaTeX3 has loaded \pkg{l3msg} then @@ -2359,7 +2432,7 @@ \__msg_kernel_error:nnxx { kernel } { command-already-defined } { \token_to_str:N #1 } { \token_to_meaning:N #1 } } - \iow_log:x { Defining~\token_to_str:N #1~ \msg_line_context: } + \__chk_log:x { Defining~\token_to_str:N #1~ \msg_line_context: } } \fi: %</package> @@ -2866,17 +2939,16 @@ % \subsection{Diagnostic functions} % % \begin{macro}[int]{\__kernel_register_show:N, \__kernel_register_show:c} -% Check that the variable exists, then apply the \tn{showthe} primitive to -% the variable. The odd-looking \cs{use:n} gives a nicer output. +% Simply using the \tn{showthe} primitive does not allow for +% line-wrapping, so instead use \cs{__msg_show_variable:NNNnn} (defined +% in \pkg{l3msg}). This checks that the variable exists (using +% \cs{cs_if_exist:NTF}), then displays the third argument, namely +% |>~|\meta{variable}|=|\meta{value}. % \begin{macrocode} \cs_new_protected:Npn \__kernel_register_show:N #1 { - \cs_if_exist:NTF #1 - { \tex_showthe:D \use:n {#1} } - { - \__msg_kernel_error:nnx { kernel } { variable-not-defined } - { \token_to_str:N #1 } - } + \__msg_show_variable:NNNnn #1 \cs_if_exist:NTF ? { } + { > ~ \token_to_str:N #1 = \tex_the:D #1 } } \cs_new_protected_nopar:Npn \__kernel_register_show:c { \exp_args:Nc \__kernel_register_show:N } @@ -2884,39 +2956,20 @@ % \end{macro} % % \begin{macro}{\cs_show:N, \cs_show:c} -% \begin{macro}[aux, EXP]{\__cs_show:www} % Some control sequences have a very long name or meaning. Thus, % simply using \TeX{}'s primitive \tn{show} could lead to overlong -% lines. The output of this primitive is mimicked to some extent: a -% line-break is added after the first colon in the meaning (this is -% what \TeX{} does for macros and five |\...mark| primitives). Then -% the re-built string is given to \cs{iow_wrap:nnnN} for +% lines. The output of this primitive is mimicked to some extent, +% then the re-built string is given to \cs{iow_wrap:nnnN} for % line-wrapping. The \cs{cs_show:c} command converts its argument to % a control sequence within a group to avoid showing \tn{relax} for % undefined control sequences. % \begin{macrocode} -\group_begin: - \tex_lccode:D `? = `: \scan_stop: - \tex_catcode:D `? = 12 \scan_stop: -\tex_lowercase:D - { - \group_end: - \cs_new_protected:Npn \cs_show:N #1 - { - \__msg_show_variable:n - { - > ~ \token_to_str:N #1 = - \exp_after:wN \__cs_show:www \cs_meaning:N #1 - \use_none:nn ? \prg_do_nothing: - } - } - \cs_new:Npn \__cs_show:www #1 ? { #1 ? \\ } - } +\cs_new_protected:Npn \cs_show:N #1 + { \__msg_show_wrap:n { > ~ \token_to_str:N #1 = \cs_meaning:N #1 } } \cs_new_protected_nopar:Npn \cs_show:c { \group_begin: \exp_args:NNc \group_end: \cs_show:N } % \end{macrocode} % \end{macro} -% \end{macro} % % \subsection{Engine specific definitions} % |