diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3basics.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3basics.dtx | 213 |
1 files changed, 119 insertions, 94 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index 7bd9da7f78a..c6f643eb75a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3basics.dtx 3023 2011-12-04 07:25:04Z bruno $ +\GetIdInfo$Id: l3basics.dtx 3090 2011-12-23 03:12:53Z bruno $ {L3 Experimental basic definitions} %</driver|package> %<*driver> @@ -626,7 +626,7 @@ % % \subsection{Showing control sequences} % -% \begin{function}[EXP]{\cs_meaning:N, \cs_meaning:c} +% \begin{function}[EXP, updated = 2011-12-22]{\cs_meaning:N, \cs_meaning:c} % \begin{syntax} % \cs{cs_meaning:N} \meta{control sequence} % \end{syntax} @@ -635,10 +635,11 @@ % macro. % \begin{texnote} % This is \TeX{}'s \tn{meaning} primitive. +% The \texttt{c} variant correctly reports undefined arguments. % \end{texnote} % \end{function} % -% \begin{function}{\cs_show:N, \cs_show:c} +% \begin{function}[updated = 2011-12-22]{\cs_show:N, \cs_show:c} % \begin{syntax} % \cs{cs_show:N} \meta{control sequence} % \end{syntax} @@ -722,11 +723,13 @@ % characters with category code $12$ (other), except spaces, % of category code $10$. The sequence will \emph{not} include % the current escape token, \emph{cf.}~\cs{token_to_str:N}. -% Full expansion of this function requires a variable number -% of expansion steps (either 3 or 4), and so an -% \texttt{f}- or \texttt{x}-type expansion will be required to +% Full expansion of this function requires exactly $2$ expansion +% steps, and so an \texttt{x}-type expansion, or two +% \texttt{o}-type expansions will be required to % convert the \meta{control sequence} to a sequence of characters -% in the input stream. +% in the input stream. In most cases, an \texttt{f}-expansion +% will be correct as well, but this loses a space at the start +% of the result. % \end{function} % % \section{Using or removing tokens and arguments} @@ -1389,16 +1392,77 @@ % \begin{macro}{\token_to_str:c} % \begin{macro}{\cs_meaning:c} % \begin{macro}{\cs_show:c} -%% A small number of variants by hand. +% A small number of variants by hand. Some of the necessary functions +% (\cs{use_i:nn}, \cs{use_ii:nn}, and \cs{exp_args:NNc}) are not defined +% at that point yet, but will be defined before those variants are used. +% The \cs{cs_meaning:c} command must check for an undefined control +% sequence to avoid defining it mistakenly. +% The \cs{cs_show:c} command is \enquote{protected} because its action +% is not expandable. Also, the conversion of its argument to a control +% sequence is done within a group to avoid converting it to \tn{relax}. % \begin{macrocode} -\tex_def:D \cs_meaning:c { \exp_args:Nc \cs_meaning:N } \tex_def:D \token_to_str:c { \exp_args:Nc \token_to_str:N } -\tex_def:D \cs_show:c { \exp_args:Nc \cs_show:N } +\tex_long:D \tex_def:D \cs_meaning:c #1 + { + \if_cs_exist:w #1 \cs_end: + \exp_after:wN \use_i:nn + \else: + \exp_after:wN \use_ii:nn + \fi: + { \exp_args:Nc \cs_meaning:N {#1} } + { \tl_to_str:n {undefined} } + } +\tex_protected:D \tex_def:D \cs_show:c + { \group_begin: \exp_args:NNc \group_end: \cs_show:N } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % +% \subsection{Defining some constants} +% +% \begin{macro}{\c_minus_one, \c_zero, \c_sixteen} +% \begin{macro}{\c_six, \c_seven, \c_twelve} +% We need the constants |\c_minus_one| and |\c_sixteen| now for +% writing information to the log and the terminal and |\c_zero| +% which is used by some functions in the \textsf{l3alloc} module. The +% rest are defined in the \textsf{l3int} module -- at least for the +% ones that can be defined with |\tex_chardef:D| or +% |\tex_mathchardef:D|. For other constants the \textsf{l3int} module is +% required but it can't be used until the allocation has been set +% up properly! The actual allocation mechanism is in +% \textsf{l3alloc} and as \TeX{} wants to reserve count registers +% 0--9, the first available one is~10 so we use that for +% |\c_minus_one|. +% \begin{macrocode} +%<*package> +\tex_let:D \c_minus_one \m@ne +%</package> +%<*initex> +\tex_countdef:D \c_minus_one = 10 ~ +\c_minus_one = -1 ~ +%</initex> +\tex_chardef:D \c_sixteen = 16~ +\tex_chardef:D \c_zero = 0~ +\tex_chardef:D \c_six = 6~ +\tex_chardef:D \c_seven = 7~ +\tex_chardef:D \c_twelve = 12~ +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{variable}{\c_max_register_int} +% This is here as this particular integer is needed both in package +% mode and to bootstrap \pkg{l3alloc}. +% \begin{macrocode} +\etex_ifdefined:D \luatex_luatexversion:D + \tex_chardef:D \c_max_register_int = 65 535 ~ +\tex_else:D + \tex_mathchardef:D \c_max_register_int = 32 767 ~ +\tex_fi:D +% \end{macrocode} +% \end{variable} +% % \subsection{Defining functions} % % We start by providing functions for the typical definition @@ -1948,6 +2012,7 @@ % \subsection{Dissecting a control sequence} % % \begin{macro}{\cs_to_str:N} +% \begin{macro}[aux]{\cs_to_str_aux:N} % \begin{macro}[aux]{\cs_to_str_aux:w} % This converts a control sequence into the character string of its % name, removing the leading escape character. This turns out to be @@ -1968,43 +2033,39 @@ % lost in the process of converting to a string. So the approach adopted is % a little more intricate still. When the escape character is printable, % \verb*|\token_to_str:N \ | yields the escape character itself and a space. -% The escape sequence will terminate the expansion started by -% \cs{int_to_roman:w}, which is a negative number and so will not -% gobble the escape character even if it's a number. The \cs{if:w} -% test will then be \texttt{false}, and the na\"ive approach of gobbling -% the first character of the \cs{token_to_str:N} version of the control -% sequence will work, even if the first character is a space. -% The second case is that the escape character is itself a space. In this -% case, the escape character space is consumed terminating the first -% \cs{int_to_roman:w}, and \cs{cs_to_str_aux:w} is expanded. This -% inserts a space, making the \cs{if:w} test \texttt{true}. The -% second \cs{int_to_roman:w} will then execute the \cs{token_to_str:N}, -% with the escape-character space being consumed by the -% \cs{int_to_roman:w}, and thus leaving the control sequence name in the -% input stream. The final case is where the escape character is not -% printable. -% The flow here starts with the \verb*|\token_to_str:N \ | giving just a -% space, which terminates the first \cs{int_to_roman:w} but leaves no -% token for the \cs{if:w} test. This means that the \cs{int_to_roman:w} -% is executed before the test is finished. The result is that the -% \cs{fi:}, expanded before the \cs{if:w} is finished, becomes -% \cs{scan_stop:} \cs{fi:}, and the \cs{scan_stop:} is then used in -% the \cs{if:w} test. -% In this case, \cs{token_to_str:N} is therefore used with no gobbling at -% all, which is exactly what is needed in this case. +% The character codes are different, thus the \cs{if:w} test is false, +% and \TeX{} reads \cs{cs_to_str_aux: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}. +% 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_aux: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}. +% 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_aux: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 +% |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}. +% 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 { - \if:w \int_to_roman:w - `0 \token_to_str:N \ % - \cs_to_str_aux:w - \fi: - \exp_after:wN \use_none:n \token_to_str:N - } -\cs_set_nopar:Npn \cs_to_str_aux:w #1 \use_none:n - { ~ \int_to_roman:w - `0 \fi: } + \int_to_roman:w + \if:w \token_to_str:N \ \cs_to_str_aux:w \fi: + \exp_after:wN \cs_to_str_aux:N \token_to_str:N + } +\cs_set:Npn \cs_to_str_aux:N #1 { \c_zero } +\cs_set:Npn \cs_to_str_aux:w #1 \cs_to_str_aux:N + { - \int_value:w \fi: \exp_after:wN \c_zero } % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\cs_split_function:NN} % \begin{macro}[aux]{\cs_split_function_aux:w} @@ -2030,14 +2091,15 @@ { \group_end: % \end{macrocode} -% First ensure that we actually get a properly evaluated str as we -% don't know how many expansions |\cs_to_str:N| requires. Insert +% First ensure that we actually get a properly evaluated str +% by expanding |\cs_to_str:N| twice. Insert % extra colon to catch the error cases. % \begin{macrocode} \cs_set:Npn \cs_split_function:NN #1#2 { + \exp_after:wN \exp_after:wN \exp_after:wN \cs_split_function_aux:w - \int_to_roman:w - `\q \cs_to_str:N #1 @ a \q_stop #2 + \cs_to_str:N #1 @ a \q_stop #2 } % \end{macrocode} % If no colon in the name, |#2| is |a| with catcode 11 and |#3| is @@ -2200,44 +2262,6 @@ % % \subsection{Defining and checking (new) functions} % -% \begin{macro}{\c_minus_one, \c_zero, \c_sixteen} -% \begin{macro}{\c_six, \c_seven, \c_twelve} -% We need the constants |\c_minus_one| and |\c_sixteen| now for -% writing information to the log and the terminal and |\c_zero| -% which is used by some functions in the \textsf{l3alloc} module. The -% rest are defined in the \textsf{l3int} module -- at least for the -% ones that can be defined with |\tex_chardef:D| or -% |\tex_mathchardef:D|. For other constants the \textsf{l3int} module is -% required but it can't be used until the allocation has been set -% up properly! The actual allocation mechanism is in -% \textsf{l3alloc} and as \TeX{} wants to reserve count registers -% 0--9, the first available one is~10 so we use that for -% |\c_minus_one|. -% \begin{macrocode} -%<*package> -\tex_let:D \c_minus_one \m@ne -%</package> -%<*initex> -\tex_countdef:D \c_minus_one = 10 ~ -\c_minus_one = -1 ~ -%</initex> -\tex_chardef:D \c_sixteen = 16~ -\tex_chardef:D \c_zero = 0~ -\tex_chardef:D \c_six = 6~ -\tex_chardef:D \c_seven = 7~ -\tex_chardef:D \c_twelve = 12~ -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\c_max_register_int} -% This is here as this particular integer is needed both in package -% mode and to bootstrap \pkg{l3alloc} -% \begin{macrocode} -\tex_mathchardef:D \c_max_register_int = 32 767 \scan_stop: -% \end{macrocode} -% \end{macro} -% % We provide two kinds of functions that can be used to define % control sequences. On the one hand we have functions that check % if their argument doesn't already exist, they are called @@ -2270,7 +2294,7 @@ % can only happen if a coding error is made by the team, so this is % a reasonable response. % \begin{macrocode} -\cs_set_protected_nopar:Npn \msg_kernel_error:nnxx #1#2#3#4 +\cs_set_protected:Npn \msg_kernel_error:nnxx #1#2#3#4 { \tex_errmessage:D { @@ -2282,9 +2306,9 @@ } \tex_end:D } -\cs_set_protected_nopar:Npn \msg_kernel_error:nnx #1#2#3 +\cs_set_protected:Npn \msg_kernel_error:nnx #1#2#3 { \msg_kernel_error:nnxx {#1} {#2} {#3} { } } -\cs_set_protected_nopar:Npn \msg_kernel_error:nn #1#2 +\cs_set_protected:Npn \msg_kernel_error:nn #1#2 { \msg_kernel_error:nnxx {#1} {#2} { } { } } % \end{macrocode} % \end{macro} @@ -2308,7 +2332,7 @@ % issued. We have to make sure we don't put the argument into the % conditional processing since it may be an |\if...| type function! % \begin{macrocode} -\cs_set_protected_nopar:Npn \chk_if_free_cs:N #1 +\cs_set_protected:Npn \chk_if_free_cs:N #1 { \cs_if_free:NF #1 { @@ -2318,7 +2342,7 @@ } %<*package> \tex_ifodd:D \l@expl@log@functions@bool - \cs_set_protected_nopar:Npn \chk_if_free_cs:N #1 + \cs_set_protected:Npn \chk_if_free_cs:N #1 { \cs_if_free:NF #1 { @@ -2338,7 +2362,7 @@ % This function issues a warning message when the control sequence % in its argument does not exist. % \begin{macrocode} -\cs_set_protected_nopar:Npn \chk_if_exist_cs:N #1 +\cs_set_protected:Npn \chk_if_exist_cs:N #1 { \cs_if_exist:NF #1 { @@ -2365,7 +2389,7 @@ % \begin{macrocode} \cs_set:Npn \cs_tmp:w #1#2 { - \cs_set_protected_nopar:Npn #1 ##1 + \cs_set_protected:Npn #1 ##1 { \chk_if_free_cs:N ##1 #2 ##1 @@ -2563,9 +2587,9 @@ % to the hash table if it isn't there yet, and it also avoids nesting % \TeX{} conditionals in case |#1| is unbalanced in this matter. % \begin{macrocode} -\cs_new_protected_nopar:Npn \cs_undefine:N #1 +\cs_new_protected:Npn \cs_undefine:N #1 { \cs_gset_eq:NN #1 \c_undefined:D } -\cs_new_protected_nopar:Npn \cs_undefine:c #1 +\cs_new_protected:Npn \cs_undefine:c #1 { \if_cs_exist:w #1 \cs_end: \exp_after:wN \use:n @@ -2652,7 +2676,7 @@ {#2#1} {#4} } -\cs_new_protected_nopar:Npn +\cs_new_protected:Npn \cs_generate_from_arg_count_aux:nwn #1 #2 \fi: #3 { \fi: #3 #1 } % \end{macrocode} @@ -2909,7 +2933,7 @@ % % \begin{macro}{\kernel_register_show:N, \kernel_register_show:c} % \begin{macrocode} -\cs_new_nopar:Npn \kernel_register_show:N #1 +\cs_new:Npn \kernel_register_show:N #1 { \cs_if_exist:NTF #1 { \tex_showthe:D #1 } @@ -2918,7 +2942,8 @@ { \token_to_str:N #1 } } } -\cs_new_nopar:Npn \kernel_register_show:c { \exp_args:Nc \int_show:N } +\cs_new_nopar:Npn \kernel_register_show:c + { \exp_args:Nc \kernel_register_show:N } % \end{macrocode} % \end{macro} % |