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.dtx215
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}
%