diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel')
54 files changed, 7744 insertions, 6442 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx index f001b8c12c1..84f7141bb7c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx @@ -21,7 +21,7 @@ % for those people who are interested. % %<*driver|generic|package> -\def\ExplFileDate{2018/03/05}% +\def\ExplFileDate{2018-04-30}% %</driver|generic|package> %<*driver> \documentclass[full]{l3doc} @@ -49,7 +49,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -575,11 +575,11 @@ % arguments before passing it to the base function: % \begin{description} % \item[c] Character string used as a command name.\\ The argument (a -% token or braced token list) must, when fully expanded, produce a -% sequence of characters which is then used to construct a command -% name (\emph{via}~\tn{csname} \ldots \tn{endcsname}). -% This command name is the -% single token that is passed to the function as the argument. Hence +% token or braced token list) is \emph{fully expanded}; the result +% must be a sequence of characters which is then used to construct a +% command name (\emph{via}~\tn{csname} \ldots \tn{endcsname}). This +% command name is a single token that is passed to the function as +% the argument. Hence % \begin{quote} % \cs{seq_gpush:cV} |{ g_file_name_seq }| \cs{l_tmpa_tl} % \end{quote} @@ -587,8 +587,7 @@ % \begin{quote} % \cs{seq_gpush:NV} |\g_file_name_seq| \cs{l_tmpa_tl}. % \end{quote} -% Remember that \texttt{c} arguments are \emph{fully expanded} by -% \TeX{} when creating csnames. This means that (a) the entire +% Full expansion means that (a) the entire % argument must be expandable and (b) any variables are % converted to their content. So the preceding examples are also % equivalent to @@ -599,21 +598,23 @@ % \end{quote} % (Token list variables are expandable and we could omit the % accessor function \cs{tl_use:N}. Other variable types require the -% appropriate \cs{<var>_use:N} functions to be used in this +% appropriate \cs{\meta{var}_use:N} functions to be used in this % context.) % \item[V] Value of a variable.\\ -% This means that the contents of the register in question is used as the -% argument, be it an integer, a length-type register, a token list variable -% or similar. The value is passed to the function as a braced token list. -% Can be applied to variables which have a \cs{\meta{var}_use:N} function, -% and which therefore deliver a single \enquote{value}. +% This means that the contents of the register in question is used +% as the argument, be it an integer, a length-type register, a token +% list variable or similar. The value is passed to the function as a +% braced token list. Can be applied to variables which have a +% \cs{\meta{var}_use:N} function (other than floating points and +% boxes), and which therefore deliver a single \enquote{value}. % \item[v] Value of a register, constructed from a character string % used as a command name.\\ % This is a combination of |c| and |V| which first constructs a -% control sequence from the argument and then passes the value of the -% resulting register to the function. -% Can be applied to variables which have a \cs{\meta{var}_use:N} function, -% and which therefore deliver a single \enquote{value}. +% control sequence from the argument and then passes the value of +% the resulting register to the function. Can be applied to +% variables which have a \cs{\meta{var}_use:N} function (other than +% floating points and boxes), and which therefore deliver a single +% \enquote{value}. % \item[x] Fully-expanded token or braced token list.\\ % This means that the argument is expanded as in the replacement % text of an~\tn{edef}, and the expansion is passed to the function as @@ -920,15 +921,16 @@ % which are constructed using macros as the underlying storage system. The % \texttt{check-declarations} option enables checking for all variable % assignments, issuing an error if any variables are assigned without being -% initialised. See also the function \cs{debug_check_declarations_on:}. +% initialised. +% See also \cs{debug_on:n} \texttt{\{check-declarations\}} for finer control. % % \DescribeOption{log-functions} % The \texttt{log-functions} option is used to enable recording of every new % function name in the \texttt{.log} file. This is useful for debugging % purposes, as it means that there is a complete list of all functions % created by each module loaded (with the exceptions of a very small number -% required by the bootstrap code for \LaTeX3). See also the function -% \cs{debug_log_functions_on:}. +% required by the bootstrap code for \LaTeX3). +% See also \cs{debug_on:n} \texttt{\{log-functions\}} for finer control. % % \DescribeOption{enable-debug} % To allow more localized checking and logging than provided by @@ -998,7 +1000,7 @@ % \item \pdfTeX{} v1.40 or later. % \item \XeTeX{} v0.9994 or later. % \item \LuaTeX{} v0.70 or later. -% \item e-(u)p\TeX{} mid-2012 or later. +% \item e-(u)\pTeX{} mid-2012 or later. % \end{itemize} % % Additional modules beyond the core of \pkg{expl3} may require additional @@ -1207,13 +1209,13 @@ \DeclareOption{#1=false}{\chardef #2=0 }% \newcommand*#2{}% \chardef #2=0 % - } + }% \expl@create@bool@option{check-declarations}\l@expl@check@declarations@bool \expl@create@bool@option{log-functions}\l@expl@log@functions@bool \expl@create@bool@option{enable-debug}\l@expl@enable@debug@bool \let\expl@create@bool@option\@undefined \chardef\l@expl@enable@debug@bool=0 % -\newcommand*\l@expl@options@clist{} +\newcommand*\l@expl@options@clist{}% \DeclareOption* {% \ifx\l@expl@options@clist\@empty @@ -1224,7 +1226,7 @@ \expandafter\expandafter\expandafter {\expandafter\l@expl@options@clist\expandafter,\CurrentOption} \fi - } + }% \ProcessOptions\relax \ifodd\l@expl@check@declarations@bool \chardef\l@expl@enable@debug@bool=1 % @@ -1249,23 +1251,23 @@ {% \ProvidesPackage{#1}[#2 \ifx\relax#3\relax\else v#3\space\fi #4]% \ExplSyntaxOn - } + }% \protected\def\ProvidesExplClass#1#2#3#4% {% \ProvidesClass{#1}[#2 \ifx\relax#3\relax\else v#3\space\fi #4]% \ExplSyntaxOn - } + }% \protected\def\ProvidesExplFile#1#2#3#4% {% \ProvidesFile{#1}[#2 \ifx\relax#3\relax\else v#3\space\fi #4]% \ExplSyntaxOn - } + }% % \end{macrocode} % \end{macro} % % Load the business end: this leaves \cs{expl3} syntax on. % \begin{macrocode} -\input{expl3-code.tex} +\input{expl3-code.tex}% % \end{macrocode} % % A check that the bootstrap code did not abort loading: if it did, @@ -1472,8 +1474,8 @@ \hbox_set:Nn #1 { \resizebox * - { \__dim_eval:n {#2} } - { \__dim_eval:n {#3} } + { \dim_eval:n {#2} } + { \dim_eval:n {#3} } { \box_use:N #1 } } } @@ -1481,7 +1483,7 @@ { \hbox_set:Nn #1 { - \resizebox * { ! } { \__dim_eval:n {#2} } + \resizebox * { ! } { \dim_eval:n {#2} } { \box_use:N #1 } } } @@ -1489,7 +1491,7 @@ { \hbox_set:Nn #1 { - \resizebox * { \__dim_eval:n {#2} } { ! } + \resizebox * { \dim_eval:n {#2} } { ! } { \box_use:N #1 } } } @@ -1534,7 +1536,7 @@ % \begin{macrocode} \tl_put_left:Nn \@pushfilename { - \exp_args:Nx \__file_input_push:n + \exp_args:Nx \__kernel_file_input_push:n { \tl_to_str:N \@currname \tl_to_str:N \@currext @@ -1559,7 +1561,7 @@ } \tl_put_right:Nn \@popfilename { - \__file_input_pop: + \__kernel_file_input_pop: \tl_if_empty:NTF \l__expl_status_stack_tl { \ExplSyntaxOff } { \exp_after:wN \__expl_status_pop:w \l__expl_status_stack_tl \q_stop } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3.ins b/Master/texmf-dist/source/latex/l3kernel/l3.ins index 244c385eca5..ad2b6330ecf 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3.ins +++ b/Master/texmf-dist/source/latex/l3kernel/l3.ins @@ -65,12 +65,12 @@ and all files in that bundle must be distributed together. \from{l3expan.dtx} {package} \from{l3tl.dtx} {package} \from{l3str.dtx} {package} + \from{l3quark.dtx} {package} \from{l3seq.dtx} {package} \from{l3int.dtx} {package} - \from{l3intarray.dtx} {package} \from{l3flag.dtx} {package} - \from{l3quark.dtx} {package} \from{l3prg.dtx} {package} + \from{l3sys.dtx} {package} \from{l3clist.dtx} {package} \from{l3token.dtx} {package} \from{l3prop.dtx} {package} @@ -91,17 +91,17 @@ and all files in that bundle must be distributed together. \from{l3fp-trig.dtx} {package} \from{l3fp-convert.dtx} {package} \from{l3fp-random.dtx} {package} + \from{l3intarray.dtx} {package} \from{l3sort.dtx} {package} - \from{l3tl-build.dtx} {package} \from{l3tl-analysis.dtx}{package} \from{l3regex.dtx} {package} \from{l3box.dtx} {package} \from{l3color-base.dtx} {package} \from{l3coffins.dtx} {package} - \from{l3sys.dtx} {package} - \from{l3deprecation.dtx}{package} - \from{l3candidates.dtx} {package} \from{l3luatex.dtx} {package,tex} + \from{l3unicode.dtx} {package} + \from{l3candidates.dtx} {package} + \from{l3deprecation.dtx}{package} } } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx index e4928419daa..25a0f22d0b4 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -164,7 +164,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_reg:nNnN #1#2#3#4 { - \__chk_if_free_cs:N #4 + \__kernel_chk_if_free_cs:N #4 \int_compare:nNnTF { \int_use:c { g_@@_ #1 _int } } < {#3} { \int_gincr:c { g_@@_ #1 _int } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index a1743469432..c3517204991 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -673,6 +673,8 @@ % control sequence. For a macro, this includes the \meta{replacement text}. % \begin{texnote} % This is \TeX{}'s \tn{meaning} primitive. +% For tokens that are not control sequences, it is more logical to +% use \cs{token_to_meaning:N}. % The \texttt{c} variant correctly reports undefined arguments. % \end{texnote} % \end{function} @@ -704,14 +706,19 @@ % \begin{syntax} % \cs{use:c} \Arg{control sequence name} % \end{syntax} -% Converts the given \meta{control sequence name} into a single -% control sequence token. This process requires two expansions. -% The content for \meta{control sequence name} may be literal -% material or from other expandable functions. The -% \meta{control sequence name} must, when fully expanded, consist -% of character tokens which are not active: typically -% of category code $10$ (space), $11$ (letter) -% or $12$ (other), or a mixture of these. +% Expands the \meta{control sequence name} until only characters +% remain, and then converts this into a control sequence. This process +% requires two expansions. As in other \texttt{c}-type arguments the +% \meta{control sequence name} must, when fully expanded, consist of +% character tokens, typically a mixture of category code $10$ (space), +% $11$ (letter) and $12$ (other). +% \begin{texnote} +% Protected macros that appear in a \texttt{c}-type argument are +% expanded despite being protected; \cs{exp_not:n} also has no +% effect. An internal error occurs if non-characters or active +% characters remain after full expansion, as the conversion to a +% control sequence is not possible. +% \end{texnote} % \end{function} % % As an example of the \cs{use:c} function, both @@ -793,6 +800,23 @@ % of the result. % \end{function} % +% \section{Analysing control sequence names} +% +% \begin{function}[EXP, added = 2018-04-06]{\cs_split_function:N} +% \begin{syntax} +% \cs{cs_split_function:N} \meta{function} +% \end{syntax} +% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part +% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon). +% This information is then placed in the input stream +% in three parts: the \meta{name}, the +% \meta{signature} and a logic token indicating if a colon was found +% (to differentiate variables from function names). The \meta{name} +% does not include the escape character, and both the \meta{name} and +% \meta{signature} are made up of tokens with category code $12$ +% (other). +% \end{function} +% % \section{Using or removing tokens and arguments} % % Tokens in the input can be read and used or read and discarded. @@ -1148,255 +1172,6 @@ % execute <false code>. Similar for the other functions. % \end{function} % -% \section{Internal kernel functions} -% -% \begin{function}{\__chk_if_free_cs:N, \__chk_if_free_cs:c} -% \begin{syntax} -% \cs{__chk_if_free_cs:N} \meta{cs} -% \end{syntax} -% This function checks that \meta{cs} is free according to the -% criteria for \cs{cs_if_free_p:N}, and if not raises a kernel-level -% error. -% \end{function} -% -% \begin{function}[EXP]{\__cs_count_signature:N, \__cs_count_signature:c} -% \begin{syntax} -% \cs{__cs_count_signature:N} \meta{function} -% \end{syntax} -% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part -% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon). -% The \meta{number} of tokens in the \meta{signature} is then left in -% the input stream. If there was no \meta{signature} then the result is -% the marker value $-1$. -% \end{function} -% -% \begin{function}[EXP]{\__cs_split_function:NN} -% \begin{syntax} -% \cs{__cs_split_function:NN} \meta{function} \meta{processor} -% \end{syntax} -% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part -% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon). -% This information is then placed in the input stream after the -% \meta{processor} function in three parts: the \meta{name}, the -% \meta{signature} and a logic token indicating if a colon was found -% (to differentiate variables from function names). The \meta{name} -% does not include the escape character, and both the \meta{name} and -% \meta{signature} are made up of tokens with category code $12$ -% (other). The \meta{processor} should be a function with argument -% specification \texttt{:nnN} (plus any trailing arguments needed). -% \end{function} -% -% \begin{function}[EXP]{\__cs_get_function_name:N} -% \begin{syntax} -% \cs{__cs_get_function_name:N} \meta{function} -% \end{syntax} -% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part -% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon). -% The \meta{name} is then left in the input stream without the escape -% character present made up of tokens with category code $12$ -% (other). -% \end{function} -% -% \begin{function}[EXP]{\__cs_get_function_signature:N} -% \begin{syntax} -% \cs{__cs_get_function_signature:N} \meta{function} -% \end{syntax} -% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part -% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon). -% The \meta{signature} is then left in the input stream made up of -% tokens with category code $12$ (other). -% \end{function} -% -% \begin{function}{\__cs_tmp:w} -% Function used for various short-term usages, for instance defining -% functions whose definition involves tokens which are hard to insert -% normally (spaces, characters with category other). -% \end{function} -% -% \begin{function}{\__kernel_debug:TF} -% \begin{syntax} -% \cs{__kernel_debug:TF} \Arg{true code} \Arg{false code} -% \end{syntax} -% Runs the \meta{true code} if debugging is enabled, namely only in -% \LaTeXe{} package mode with one of the options -% \texttt{check-declarations}, \texttt{enable-debug}, or -% \texttt{log-functions}. Otherwise runs the \meta{false code}. The -% |T| and |F| variants are not provided for this low-level -% conditional. -% \end{function} -% -% \begin{function}{\__kernel_chk_cs_exist:N, \__kernel_chk_cs_exist:c} -% \begin{syntax} -% \cs{__kernel_chk_cs_exist:N} \meta{cs} -% \end{syntax} -% This function is only created if debugging is enabled. It checks -% that \meta{cs} exists according to the criteria for -% \cs{cs_if_exist_p:N}, and if not raises a kernel-level error. -% \end{function} -% -% \begin{function}{\__kernel_chk_expr:nNnN} -% \begin{syntax} -% \cs{__kernel_chk_expr:nNnN} \Arg{expr} \meta{eval} \Arg{convert} \meta{caller} -% \end{syntax} -% This function is only created if debugging is enabled. By default -% it is equivalent to \cs{use_i:nnnn}. When expression checking is -% enabled, it leaves in the input stream the result of \cs{tex_the:D} -% \meta{eval} \meta{expr} \cs{tex_relax:D} after checking that no -% token was left over. If any token was not taken as part of the -% expression, there is an error message displaying the result of the -% evaluation as well as the \meta{caller}. For instance \meta{eval} -% can be \cs{__int_eval:w} and \meta{caller} can be \cs{int_eval:n} or -% \cs{int_set:Nn}. The argument \meta{convert} is empty except for mu -% expressions where it is \cs{etex_mutoglue:D}, used for internal -% purposes. -% \end{function} -% -% \begin{function}{\__kernel_chk_var_exist:N} -% \begin{syntax} -% \cs{__kernel_chk_var_exist:N} \meta{var} -% \end{syntax} -% This function is only created if debugging is enabled. It checks -% that \meta{var} is defined according to the criteria for -% \cs{cs_if_exist_p:N}, and if not raises a kernel-level error. -% \end{function} -% -% \begin{function}{\__kernel_chk_var_scope:NN} -% \begin{syntax} -% \cs{__kernel_chk_var_scope:NN} \meta{scope} \meta{var} -% \end{syntax} -% Checks the \meta{var} has the correct \meta{scope}, and if not -% raises a kernel-level error. This function is only created if -% debugging is enabled. The \meta{scope} is a single letter |l|, |g|, -% |c| denoting local variables, global variables, or constants. More -% precisely, if the variable name starts with a letter and an -% underscore (normal \pkg{expl3} convention) the function checks that -% this single letter matches the \meta{scope}. Otherwise the function -% cannot know the scope \meta{var} the first time: instead, it defines -% |\__debug_chk_/|\meta{var name} to store that information for the -% next call. Thus, if a given \meta{var} is subject to assignments of -% different scopes a kernel error will result. -% \end{function} -% -% \begin{function}{\__kernel_chk_var_local:N, \__kernel_chk_var_global:N} -% \begin{syntax} -% \cs{__kernel_chk_var_local:N} \meta{var} -% \cs{__kernel_chk_var_global:N} \meta{var} -% \end{syntax} -% Applies \cs{__kernel_chk_var_exist:N} \meta{var}, then -% \cs{__kernel_chk_var_scope:NN} \meta{scope} \meta{var}, where -% \meta{scope} is |l| or~|g|. -% \end{function} -% -% \begin{function}{\__kernel_debug_log:x} -% \begin{syntax} -% \cs{__kernel_debug_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}. -% This function is only created if debugging is enabled. -% \end{function} -% -% \begin{function}{\__kernel_patch:nnNNpn} -% \begin{syntax} -% \cs{__kernel_patch:nnNNpn} \Arg{before} \Arg{after} -% \meta{definition} \meta{function} \meta{parameters} \Arg{code} -% \end{syntax} -% If debugging is not enabled, this function ignores the \meta{before} -% and \meta{after} code and performs the \meta{definition} with no -% patching. Otherwise it replaces \meta{code} by \meta{before} -% \meta{code} \meta{after} (which can involve |#1| and so on) in the -% \meta{definition} that follows. The \meta{definition} must start -% with \cs{cs_new:Npn} or \cs{cs_set:Npn} or \cs{cs_gset:Npn} or their -% \texttt{_protected} counterparts. Other cases can be added as -% needed. -% \end{function} -% -% \begin{function}{\__kernel_patch_conditional:nNNpnn} -% \begin{syntax} -% \cs{__kernel_patch_conditional:nNNpnn} \Arg{before} -% \meta{definition} \meta{conditional} \meta{parameters} \Arg{type} \Arg{code} -% \end{syntax} -% Similar to \cs{__kernel_patch:nnNNpn} for conditionals, namely -% \meta{definition} must be \cs{prg_new_conditional:Npnn} or its -% \texttt{_protected} counterpart. There is no \meta{after} code -% because that would interfere with the action of the conditional. -% \end{function} -% -% \begin{function} -% {\__kernel_patch_args:nNNpn, \__kernel_patch_conditional_args:nNNpnn} -% \begin{syntax} -% \cs{__kernel_patch_args:nNNpn} \Arg{arguments} -% \meta{definition} \meta{function} \meta{parameters} \Arg{code} -% \end{syntax} -% Like \cs{__kernel_patch:nnNNpn}, this tweaks the following -% definition, but from the \enquote{inside out} (and if debugging is -% not enabled, the \meta{arguments} are ignored). It replaces |#1|, -% |#2| and so on in the \meta{code} of the definition as indicated by -% the \meta{arguments}. More precisely, a temporary function is -% defined using the \meta{definition} with the \meta{parameters} and -% \meta{code}, then the result of expanding that function once in -% front of the \meta{arguments} is used instead of the \meta{code} -% when defining the actual function. For instance, -% \begin{quote} -% \cs{__kernel_patch_args:nNNpn} |{ { (#1) } }| \\ -% \cs{cs_new:Npn} \cs{int_eval:n} |#1| \\ -% ~~|{ \__int_value:w \__int_eval:w #1 \__int_eval_end: }| -% \end{quote} -% would replace |#1| by |(#1)| in the definition of \cs{int_eval:n} when -% debugging is enabled. This fails if the \meta{code} contains~|##|. -% The \cs{__kernel_patch_conditional_args:nNNpnn} function is for use -% before \cs{prg_new_conditional:Npnn} or its \texttt{_protected} -% counterpart. -% \end{function} -% -% \begin{function} -% {\__kernel_patch_args:nnnNNpn, \__kernel_patch_conditional_args:nnnNNpnn} -% \begin{syntax} -% \cs{__kernel_patch_args:nnnNNpn} \Arg{before} \Arg{after} \Arg{arguments} -% \meta{definition} \meta{function} \meta{parameters} \Arg{code} -% \end{syntax} -% A combination of \cs{__kernel_patch:nnNNpn} and -% \cs{__kernel_patch_args:nNNpn}. -% \end{function} -% -% \begin{function}{\__kernel_check_defined:NT} -% \begin{syntax} -% \cs{__kernel_check_defined:NT} \meta{variable} \Arg{true code} -% \end{syntax} -% If \meta{variable} is not defined (according to -% \cs{cs_if_exist:NTF}), this triggers an error, otherwise the -% \meta{true code} is run. -% \end{function} -% -% \begin{function}{\__kernel_register_show:N, \__kernel_register_show:c} -% \begin{syntax} -% \cs{__kernel_register_show:N} \meta{register} -% \end{syntax} -% Used to show the contents of a \TeX{} register at the terminal, formatted -% such that internal parts of the mechanism are not visible. -% \end{function} -% -% \begin{function}[updated = 2015-08-03] -% {\__kernel_register_log:N, \__kernel_register_log:c} -% \begin{syntax} -% \cs{__kernel_register_log:N} \meta{register} -% \end{syntax} -% Used to write the contents of a \TeX{} register to the log file in a -% form similar to \cs{__kernel_register_show:N}. -% \end{function} -% -% \begin{function}[EXP]{\__prg_case_end:nw} -% \begin{syntax} -% \cs{__prg_case_end:nw} \Arg{code} \meta{tokens} \cs{q_mark} \Arg{true code} \cs{q_mark} \Arg{false code} \cs{q_stop} -% \end{syntax} -% Used to terminate case statements (\cs{int_case:nnTF}, \emph{etc.}) -% by removing trailing \meta{tokens} and the end marker -% \cs{q_stop}, inserting the \meta{code} for the successful -% case (if one is found) and either the \texttt{true code} or -% \texttt{false code} for the over all outcome, as appropriate. -% \end{function} -% % \end{documentation} % % \begin{implementation} @@ -1482,11 +1257,12 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\tl_to_str:n, \token_to_str:N} +% \begin{macro}[EXP]{\tl_to_str:n, \token_to_str:N, \__kernel_tl_to_str:w} % Making strings. % \begin{macrocode} -\tex_let:D \tl_to_str:n \etex_detokenize:D -\tex_let:D \token_to_str:N \tex_string:D +\tex_let:D \tl_to_str:n \etex_detokenize:D +\tex_let:D \token_to_str:N \tex_string:D +\tex_let:D \__kernel_tl_to_str:w \etex_detokenize:D % \end{macrocode} % \end{macro} % @@ -1674,8 +1450,24 @@ % \end{macrocode} % \end{macro} % +% \begin{macrocode} +%<@@=use> +% \end{macrocode} +% +% \begin{macro}[EXP]{\use_x:n} +% A candidate, but needed early as it links to string comparisons. +% Currently \LuaTeX-only. +% \begin{macrocode} +\cs_set:Npn \use_x:n #1 { \luatex_expanded:D {#1} } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%<@@=exp> +% \end{macrocode} +% % \begin{macro}[EXP]{\use:n, \use:nn, \use:nnn, \use:nnnn} -% These macros grab their arguments and returns them back to the input +% These macros grab their arguments and return them back to the input % (with outer braces removed). % \begin{macrocode} \cs_set:Npn \use:n #1 {#1} @@ -1738,7 +1530,8 @@ % \begin{macrocode} \cs_set:Npn \use_i_delimit_by_q_nil:nw #1#2 \q_nil {#1} \cs_set:Npn \use_i_delimit_by_q_stop:nw #1#2 \q_stop {#1} -\cs_set:Npn \use_i_delimit_by_q_recursion_stop:nw #1#2 \q_recursion_stop {#1} +\cs_set:Npn \use_i_delimit_by_q_recursion_stop:nw + #1#2 \q_recursion_stop {#1} % \end{macrocode} % \end{macro} % @@ -1782,7 +1575,7 @@ %<@@=debug> % \end{macrocode} % -% \begin{macro}{\__kernel_debug:TF} +% \begin{macro}{\__kernel_if_debug:TF} % A more meaningful test of whether debugging is enabled than messing % up with guards. We can also more easily change the logic in one % place then. At present, debugging is disabled in the format and in @@ -1790,25 +1583,25 @@ % options \texttt{enable-debug}, \texttt{log-functions} or % \texttt{check-declarations} was given. % \begin{macrocode} -\cs_set_protected:Npn \__kernel_debug:TF #1#2 {#2} +\cs_set_protected:Npn \__kernel_if_debug:TF #1#2 {#2} %<*package> \tex_ifodd:D \l@expl@enable@debug@bool - \cs_set_protected:Npn \__kernel_debug:TF #1#2 {#1} + \cs_set_protected:Npn \__kernel_if_debug:TF #1#2 {#1} \fi: %</package> % \end{macrocode} % \end{macro} % % \begin{macro}{\debug_on:n, \debug_off:n} -% +% % \begin{macrocode} -\__kernel_debug:TF +\__kernel_if_debug:TF { \cs_set_protected:Npn \debug_on:n #1 { \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} } { - \cs_if_exist_use:cF { __debug_##1_on: } + \cs_if_exist_use:cF { @@_ ##1 _on: } { \__kernel_msg_error:nnn { kernel } { debug } {##1} } } } @@ -1816,7 +1609,7 @@ { \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} } { - \cs_if_exist_use:cF { __debug_##1_off: } + \cs_if_exist_use:cF { @@_ ##1 _off: } { \__kernel_msg_error:nnn { kernel } { debug } {##1} } } } @@ -1837,32 +1630,32 @@ % \end{macro} % % \begin{macro}{\debug_suspend:, \debug_resume:} -% \begin{macro}{\__debug_suspended:T} -% \begin{macro}{\l__debug_suspended_tl} +% \begin{macro}{\@@_suspended:T} +% \begin{macro}{\l_@@_suspended_tl} % Suspend and resume locally all debug-related errors and logging % except deprecation errors. The \cs{debug_suspend:} and \cs{debug_resume:} % pairs can be nested. We keep track of nesting in a token list % containing a number of periods. At first begin with the -% \enquote{non-suspended} version of \cs{__debug_suspended:T}. +% \enquote{non-suspended} version of \cs{@@_suspended:T}. % \begin{macrocode} -\__kernel_debug:TF +\__kernel_if_debug:TF { - \cs_set_nopar:Npn \l__debug_suspended_tl { } + \cs_set_nopar:Npn \l_@@_suspended_tl { } \cs_set_protected:Npn \debug_suspend: { - \tl_put_right:Nn \l__debug_suspended_tl { . } - \cs_set_eq:NN \__debug_suspended:T \use:n + \tl_put_right:Nn \l_@@_suspended_tl { . } + \cs_set_eq:NN \@@_suspended:T \use:n } \cs_set_protected:Npn \debug_resume: { - \tl_set:Nx \l__debug_suspended_tl - { \tl_tail:N \l__debug_suspended_tl } - \tl_if_empty:NT \l__debug_suspended_tl + \tl_set:Nx \l_@@_suspended_tl + { \tl_tail:N \l_@@_suspended_tl } + \tl_if_empty:NT \l_@@_suspended_tl { - \cs_set_eq:NN \__debug_suspended:T \use_none:n + \cs_set_eq:NN \@@_suspended:T \use_none:n } } - \cs_set:Npn \__debug_suspended:T #1 { } + \cs_set:Npn \@@_suspended:T #1 { } } { \cs_set_protected:Npn \debug_suspend: { } @@ -1874,7 +1667,7 @@ % \end{macro} % % \begin{macro} -% {\__debug_check-declarations_on:, \__debug_check-declarations_off:} +% {\@@_check-declarations_on:, \@@_check-declarations_off:} % \begin{macro}{\__kernel_chk_var_exist:N} % \begin{macro}{\__kernel_chk_cs_exist:N, \__kernel_chk_cs_exist:c} % \begin{macro}{\__kernel_chk_var_local:N, \__kernel_chk_var_global:N} @@ -1890,13 +1683,13 @@ % perform both checks. % \end{itemize} % \begin{macrocode} -\__kernel_debug:TF +\__kernel_if_debug:TF { - \exp_args:Nc \cs_set_protected:Npn { __debug_check-declarations_on: } + \exp_args:Nc \cs_set_protected:Npn { @@_check-declarations_on: } { \cs_set_protected:Npn \__kernel_chk_var_exist:N ##1 { - \__debug_suspended:T \use_none:nnn + \@@_suspended:T \use_none:nnn \cs_if_exist:NF ##1 { \__kernel_msg_error:nnx { kernel } { non-declared-variable } @@ -1905,7 +1698,7 @@ } \cs_set_protected:Npn \__kernel_chk_cs_exist:N ##1 { - \__debug_suspended:T \use_none:nnn + \@@_suspended:T \use_none:nnn \cs_if_exist:NF ##1 { \__kernel_msg_error:nnx { kernel } { command-not-defined } @@ -1914,23 +1707,23 @@ } \cs_set_protected:Npn \__kernel_chk_var_scope:NN { - \__debug_suspended:T \use_none:nnn - \__debug_chk_var_scope_aux:NN + \@@_suspended:T \use_none:nnn + \@@_chk_var_scope_aux:NN } \cs_set_protected:Npn \__kernel_chk_var_local:N ##1 { - \__debug_suspended:T \use_none:nnnnn + \@@_suspended:T \use_none:nnnnn \__kernel_chk_var_exist:N ##1 - \__debug_chk_var_scope_aux:NN l ##1 + \@@_chk_var_scope_aux:NN l ##1 } \cs_set_protected:Npn \__kernel_chk_var_global:N ##1 { - \__debug_suspended:T \use_none:nnnnn + \@@_suspended:T \use_none:nnnnn \__kernel_chk_var_exist:N ##1 - \__debug_chk_var_scope_aux:NN g ##1 + \@@_chk_var_scope_aux:NN g ##1 } } - \exp_args:Nc \cs_set_protected:Npn { __debug_check-declarations_off: } + \exp_args:Nc \cs_set_protected:Npn { @@_check-declarations_off: } { \cs_set_protected:Npn \__kernel_chk_var_exist:N ##1 { } \cs_set_protected:Npn \__kernel_chk_cs_exist:N ##1 { } @@ -1941,9 +1734,9 @@ \cs_set_protected:Npn \__kernel_chk_cs_exist:c { \exp_args:Nc \__kernel_chk_cs_exist:N } \tex_ifodd:D \l@expl@check@declarations@bool - \use:c { __debug_check-declarations_on: } + \use:c { @@_check-declarations_on: } \else: - \use:c { __debug_check-declarations_off: } + \use:c { @@_check-declarations_off: } \fi: } { } @@ -1954,13 +1747,13 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\__debug_chk_var_scope_aux:NN} -% \begin{macro}{\__debug_chk_var_scope_aux:Nn} -% \begin{macro}{\__debug_chk_var_scope_aux:NNn} +% \begin{macro}{\@@_chk_var_scope_aux:NN} +% \begin{macro}{\@@_chk_var_scope_aux:Nn} +% \begin{macro}{\@@_chk_var_scope_aux:NNn} % First check whether the name of the variable |#2| starts with % \meta{letter}|_|. If it does then pass that letter, the % \meta{scope}, and the variable name to -% \cs{__debug_chk_var_scope_aux:NNn}. That function compares the two +% \cs{@@_chk_var_scope_aux:NNn}. That function compares the two % letters and triggers an error if they differ (the \cs{scan_stop:} % case is not reachable here). If the second character was not |_| % then pass the same data to the same auxiliary, except for its first @@ -1970,23 +1763,23 @@ % letter \meta{scope} according to what the first assignment to the % given variable was. % \begin{macrocode} -\__kernel_debug:TF +\__kernel_if_debug:TF { - \cs_set_protected:Npn \__debug_chk_var_scope_aux:NN #1#2 - { \exp_args:NNf \__debug_chk_var_scope_aux:Nn #1 { \cs_to_str:N #2 } } - \cs_set_protected:Npn \__debug_chk_var_scope_aux:Nn #1#2 + \cs_set_protected:Npn \@@_chk_var_scope_aux:NN #1#2 + { \exp_args:NNf \@@_chk_var_scope_aux:Nn #1 { \cs_to_str:N #2 } } + \cs_set_protected:Npn \@@_chk_var_scope_aux:Nn #1#2 { \if:w _ \use_i:nn \use_i_delimit_by_q_stop:nw #2 ? ? \q_stop - \exp_after:wN \__debug_chk_var_scope_aux:NNn + \exp_after:wN \@@_chk_var_scope_aux:NNn \use_i_delimit_by_q_stop:nw #2 ? \q_stop #1 {#2} \else: - \exp_args:Nc \__debug_chk_var_scope_aux:NNn - { __debug_chk_/ #2 } + \exp_args:Nc \@@_chk_var_scope_aux:NNn + { @@_chk_/ #2 } #1 {#2} \fi: } - \cs_set_protected:Npn \__debug_chk_var_scope_aux:NNn #1#2#3 + \cs_set_protected:Npn \@@_chk_var_scope_aux:NNn #1#2#3 { \if:w #1 #2 \else: @@ -2006,9 +1799,9 @@ % \end{macro} % % \begin{macro} -% {\__debug_check-expressions_on:, \__debug_check-expressions_off:} +% {\@@_check-expressions_on:, \@@_check-expressions_off:} % \begin{macro}{\__kernel_chk_expr:nNnN} -% \begin{macro}{\__debug_chk_expr_aux:nNnN} +% \begin{macro}{\@@_chk_expr_aux:nNnN} % When debugging is enabled these two functions set % \cs{__kernel_chk_expr:nNnN} to test or not whether the given % expression is valid. The idea is to evaluate the expression within @@ -2028,28 +1821,28 @@ % |1+2\relax+3| would incorrectly be accepted as a valid integer % expression. % \begin{macrocode} -\__kernel_debug:TF +\__kernel_if_debug:TF { - \exp_args:Nc \cs_set_protected:Npn { __debug_check-expressions_on: } + \exp_args:Nc \cs_set_protected:Npn { @@_check-expressions_on: } { \cs_set:Npn \__kernel_chk_expr:nNnN ##1##2 { - \__debug_suspended:T { ##1 \use_none:nnnnnnn } - \exp_after:wN \__debug_chk_expr_aux:nNnN - \exp_after:wN { \tex_the:D ##2 ##1 \tex_relax:D } + \@@_suspended:T { ##1 \use_none:nnnnnnn } + \exp_after:wN \@@_chk_expr_aux:nNnN + \exp_after:wN { \tex_the:D ##2 ##1 \scan_stop: } ##2 } } - \exp_args:Nc \cs_set_protected:Npn { __debug_check-expressions_off: } + \exp_args:Nc \cs_set_protected:Npn { @@_check-expressions_off: } { \cs_set:Npn \__kernel_chk_expr:nNnN ##1##2##3##4 {##1} } - \use:c { __debug_check-expressions_off: } - \cs_set:Npn \__debug_chk_expr_aux:nNnN #1#2#3#4 + \use:c { @@_check-expressions_off: } + \cs_set:Npn \@@_chk_expr_aux:nNnN #1#2#3#4 { \tl_if_empty:oF { \tex_romannumeral:D - 0 \exp_after:wN \use_none:n - \__int_value:w #3 #2 #1 \tex_relax:D + \int_value:w #3 #2 #1 \scan_stop: } { \__kernel_msg_expandable_error:nnnn @@ -2064,7 +1857,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\__debug_log-functions_on:, \__debug_log-functions_off:} +% \begin{macro}{\@@_log-functions_on:, \@@_log-functions_off:} % \begin{macro}{\__kernel_debug_log:x} % These two functions (corresponding to the \pkg{expl3} option % \texttt{log-functions}) control whether \cs{__kernel_debug_log:x} writes to the @@ -2074,19 +1867,19 @@ % option was given. When debugging is not enabled, simply produce an % error. % \begin{macrocode} -\__kernel_debug:TF +\__kernel_if_debug:TF { - \exp_args:Nc \cs_set_protected:Npn { __debug_log-functions_on: } + \exp_args:Nc \cs_set_protected:Npn { @@_log-functions_on: } { \cs_set_protected:Npn \__kernel_debug_log:x - { \__debug_suspended:T \use_none:nn \iow_log:x } + { \@@_suspended:T \use_none:nn \iow_log:x } } - \exp_args:Nc \cs_set_protected:Npn { __debug_log-functions_off: } + \exp_args:Nc \cs_set_protected:Npn { @@_log-functions_off: } { \cs_set_protected:Npn \__kernel_debug_log:x { \use_none:n } } \tex_ifodd:D \l@expl@log@functions@bool - \use:c { __debug_log-functions_on: } + \use:c { @@_log-functions_on: } \else: - \use:c { __debug_log-functions_off: } + \use:c { @@_log-functions_off: } \fi: } { } @@ -2094,26 +1887,26 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\__debug_deprecation_on:, \__debug_deprecation_off:} +% \begin{macro}{\@@_deprecation_on:, \@@_deprecation_off:} % \begin{macro}{\__kernel_deprecation_code:nn} -% \begin{variable}{\g__debug_deprecation_on_tl, \g__debug_deprecation_off_tl} +% \begin{variable}{\g_@@_deprecation_on_tl, \g_@@_deprecation_off_tl} % Some commands were more recently deprecated and not yet removed; % only make these into errors if the user requests it. This relies on % two token lists, mostly filled up by calls to % \cs{__kernel_patch_deprecation:nnNNpn} in each module. % \begin{macrocode} -\__kernel_debug:TF +\__kernel_if_debug:TF { - \cs_set_protected:Npn \__debug_deprecation_on: - { \g__debug_deprecation_on_tl } - \cs_set_protected:Npn \__debug_deprecation_off: - { \g__debug_deprecation_off_tl } - \cs_set_nopar:Npn \g__debug_deprecation_on_tl { } - \cs_set_nopar:Npn \g__debug_deprecation_off_tl { } + \cs_set_protected:Npn \@@_deprecation_on: + { \g_@@_deprecation_on_tl } + \cs_set_protected:Npn \@@_deprecation_off: + { \g_@@_deprecation_off_tl } + \cs_set_nopar:Npn \g_@@_deprecation_on_tl { } + \cs_set_nopar:Npn \g_@@_deprecation_off_tl { } \cs_set_protected:Npn \__kernel_deprecation_code:nn #1#2 { - \tl_gput_right:Nn \g__debug_deprecation_on_tl {#1} - \tl_gput_right:Nn \g__debug_deprecation_off_tl {#2} + \tl_gput_right:Nn \g_@@_deprecation_on_tl {#1} + \tl_gput_right:Nn \g_@@_deprecation_off_tl {#2} } } { @@ -2125,40 +1918,48 @@ % \end{macro} % % \begin{macro}{\__kernel_patch_deprecation:nnNNpn} -% \begin{macro}{\__debug_deprecation_aux:nnNnn} -% Grab a definition (at present, must be \cs{cs_new_protected:Npn}). -% Add to \cs{g__debug_deprecation_on_tl} some code that makes the +% \begin{macro}{\@@_deprecation_aux:nnNnn} +% Grab a definition (at present, must be \cs{cs_new_protected:Npn} or \cs{cs_new:Npn}). +% Add to \cs{g_@@_deprecation_on_tl} some code that makes the % defined macro |#3| outer (and defines it as an error). Add to -% \cs{g__debug_deprecation_off_tl} the definition itself. In both +% \cs{g_@@_deprecation_off_tl} the definition itself. In both % cases we undefine the token with \cs{tex_let:D} to avoid taking a % potentially outer macro as the argument of some \pkg{expl3} -% function. Finally define the macro itself to produce a warning then -% redefine and call itself. The macro initially takes no parameters: +% function. Finally, define the macro itself: if it is protected, +% make it produce a warning then redefine and call itself. The macro +% initially takes no parameters: % together with the \texttt{x}-expanding assignment and \cs{exp_not:n} % this gives a convenient way of storing the macro's definition in % itself in order to only produce the warning once for each macro. % If debugging is disabled, \cs{__kernel_patch_deprecation:nnNNpn} lets the % definition happen. % \begin{macrocode} -\__kernel_debug:TF +\__kernel_if_debug:TF { \cs_set_protected:Npn \__kernel_patch_deprecation:nnNNpn #1#2#3#4#5# { \if_meaning:w \cs_new_protected:Npn #3 + \exp_after:wN \use_i:nn \else: - \__kernel_msg_error:nnx { kernel } { debug-unpatchable } - { \token_to_str:N #3 ~(for~deprecation) } + \if_meaning:w \cs_new:Npn #3 + \exp_after:wN \exp_after:wN \exp_after:wN \use_ii:nn + \else: + \__kernel_msg_error:nnx { kernel } { debug-unpatchable } + { \token_to_str:N #3 ~(for~deprecation) } + \exp_after:wN \exp_after:wN \exp_after:wN \use_none:nn + \fi: \fi: - \__debug_deprecation_aux:nnNnn {#1} {#2} #4 {#5} + { \@@_deprecation_aux:nnNnn {#1} {#2} #4 {#5} } + { \@@_deprecation_expandable:nnNnn {#1} {#2} #4 {#5} } } - \cs_set_protected:Npn \__debug_deprecation_aux:nnNnn #1#2#3#4#5 + \cs_set_protected:Npn \@@_deprecation_aux:nnNnn #1#2#3#4#5 { - \tl_gput_right:Nn \g__debug_deprecation_on_tl + \tl_gput_right:Nn \g_@@_deprecation_on_tl { \tex_let:D #3 \scan_stop: - \__deprecation_error:Nnn #3 {#2} {#1} + \__kernel_deprecation_error:Nnn #3 {#2} {#1} } - \tl_gput_right:Nn \g__debug_deprecation_off_tl + \tl_gput_right:Nn \g_@@_deprecation_off_tl { \tex_let:D #3 \scan_stop: \cs_set_protected:Npn #3 #4 {#5} @@ -2172,6 +1973,20 @@ \exp_not:N #3 } } + \cs_set_protected:Npn \@@_deprecation_expandable:nnNnn #1#2#3#4#5 + { + \tl_gput_right:Nn \g_@@_deprecation_on_tl + { + \tex_let:D #3 \scan_stop: + \__kernel_deprecation_error:Nnn #3 {#2} {#1} + } + \tl_gput_right:Nn \g_@@_deprecation_off_tl + { + \tex_let:D #3 \scan_stop: + \cs_set:Npn #3 #4 {#5} + } + \cs_new:Npn #3 #4 {#5} + } } { \cs_set_protected:Npn \__kernel_patch_deprecation:nnNNpn #1#2 { } } % \end{macrocode} @@ -2181,7 +1996,7 @@ % \begin{macro} % {\__kernel_patch:nnNNpn, \__kernel_patch_conditional:nNNpnn} % \begin{macro} -% {\__debug_patch_aux:nnnn, \__debug_patch_auxii:nnnn} +% {\@@_patch_aux:nnnn, \@@_patch_auxii:nnnn} % When debugging is not enabled, \cs{__kernel_patch:nnNNpn} and % \cs{__kernel_patch_conditional:nNNpnn} throw the patch away. % Otherwise they can be followed by \cs{cs_new:Npn} (or similar), and @@ -2189,15 +2004,15 @@ % case, grab the name of the function to be defined and its parameters % then insert tokens before and/or after the definition. % \begin{macrocode} -\__kernel_debug:TF +\__kernel_if_debug:TF { \cs_set_protected:Npn \__kernel_patch:nnNNpn #1#2#3#4#5# - { \__debug_patch_aux:nnnn {#1} {#2} { #3 #4 #5 } } + { \@@_patch_aux:nnnn {#1} {#2} { #3 #4 #5 } } \cs_set_protected:Npn \__kernel_patch_conditional:nNNpnn #1#2#3#4# - { \__debug_patch_auxii:nnnn {#1} { #2 #3 #4 } } - \cs_set_protected:Npn \__debug_patch_aux:nnnn #1#2#3#4 + { \@@_patch_auxii:nnnn {#1} { #2 #3 #4 } } + \cs_set_protected:Npn \@@_patch_aux:nnnn #1#2#3#4 { #3 { #1 #4 #2 } } - \cs_set_protected:Npn \__debug_patch_auxii:nnnn #1#2#3#4 + \cs_set_protected:Npn \@@_patch_auxii:nnnn #1#2#3#4 { #2 {#3} { #1 #4 } } } { @@ -2214,10 +2029,10 @@ % {\__kernel_patch_args:nnnNNpn, \__kernel_patch_conditional_args:nnnNNpnn} % \begin{macro} % { -% \__debug_tmp:w, -% \__debug_patch_args_aux:nnnNNnn, -% \__debug_patch_args_aux:nnnNNnnn, -% \__debug_patch_args_aux:nnnn +% \@@_tmp:w, +% \@@_patch_args_aux:nnnNNnn, +% \@@_patch_args_aux:nnnNNnnn, +% \@@_patch_args_aux:nnnn % } % See \cs{__kernel_patch:nnNNpn}. The first argument is something like % |{#1}{(#2)}|. Define a temporary macro using the \meta{parameters} @@ -2230,30 +2045,32 @@ { \__kernel_patch_args:nnnNNpn { } { } } \cs_set_protected:Npn \__kernel_patch_conditional_args:nNNpnn { \__kernel_patch_conditional_args:nnnNNpnn { } { } } -\__kernel_debug:TF +\__kernel_if_debug:TF { \cs_set_protected:Npn \__kernel_patch_args:nnnNNpn #1#2#3#4#5#6# - { \__debug_patch_args_aux:nnnNNnn {#1} {#2} {#3} #4 #5 {#6} } - \cs_set_protected:Npn \__kernel_patch_conditional_args:nnnNNpnn #1#2#3#4#5#6# - { \__debug_patch_args_aux:nnnNNnnn {#1} {#2} {#3} #4 #5 {#6} } - \cs_set_protected:Npn \__debug_patch_args_aux:nnnNNnn #1#2#3#4#5#6#7 + { \@@_patch_args_aux:nnnNNnn {#1} {#2} {#3} #4 #5 {#6} } + \cs_set_protected:Npn \__kernel_patch_conditional_args:nnnNNpnn + #1#2#3#4#5#6# + { \@@_patch_args_aux:nnnNNnnn {#1} {#2} {#3} #4 #5 {#6} } + \cs_set_protected:Npn \@@_patch_args_aux:nnnNNnn #1#2#3#4#5#6#7 { - \cs_set:Npn \__debug_tmp:w #6 {#7} - \exp_after:wN \__debug_patch_args_aux:nnnn \exp_after:wN - { \__debug_tmp:w #3 } { #4 #5 #6 } {#1} {#2} + \cs_set:Npn \@@_tmp:w #6 {#7} + \exp_after:wN \@@_patch_args_aux:nnnn \exp_after:wN + { \@@_tmp:w #3 } { #4 #5 #6 } {#1} {#2} } - \cs_set_protected:Npn \__debug_patch_args_aux:nnnNNnnn #1#2#3#4#5#6#7#8 + \cs_set_protected:Npn \@@_patch_args_aux:nnnNNnnn #1#2#3#4#5#6#7#8 { - \cs_set:Npn \__debug_tmp:w #6 {#8} - \exp_after:wN \__debug_patch_args_aux:nnnn \exp_after:wN - { \__debug_tmp:w #3 } { #4 #5 #6 {#7} } {#1} {#2} + \cs_set:Npn \@@_tmp:w #6 {#8} + \exp_after:wN \@@_patch_args_aux:nnnn \exp_after:wN + { \@@_tmp:w #3 } { #4 #5 #6 {#7} } {#1} {#2} } - \cs_set_protected:Npn \__debug_patch_args_aux:nnnn #1#2#3#4 + \cs_set_protected:Npn \@@_patch_args_aux:nnnn #1#2#3#4 { #2 { #3 #1 #4 } } } { \cs_set_protected:Npn \__kernel_patch_args:nnnNNpn #1#2#3 { } - \cs_set_protected:Npn \__kernel_patch_conditional_args:nnnNNpnn #1#2#3 { } + \cs_set_protected:Npn \__kernel_patch_conditional_args:nnnNNpnn + #1#2#3 { } } % \end{macrocode} % \end{macro} @@ -2335,8 +2152,12 @@ { \@@_generate_conditional_parm:nnNpnn { new } { _protected } } \cs_set_protected:Npn \@@_generate_conditional_parm:nnNpnn #1#2#3#4# { - \__cs_split_function:NN #3 \@@_generate_conditional:nnNnnnnn - {#1} {#2} {#4} + \use:x + { + \@@_generate_conditional:nnNnnnnn + \cs_split_function:N #3 + } + {#1} {#2} {#4} } % \end{macrocode} % \end{macro} @@ -2377,12 +2198,16 @@ { \@@_generate_conditional_count:nnNnn { new } { _protected } } \cs_set_protected:Npn \@@_generate_conditional_count:nnNnn #1#2#3 { - \__cs_split_function:NN #3 \@@_generate_conditional_count:nnNnnnn - {#1} {#2} + \use:x + { + \@@_generate_conditional_count:nnNnnnn + \cs_split_function:N #3 + } + {#1} {#2} } \cs_set_protected:Npn \@@_generate_conditional_count:nnNnnnn #1#2#3#4#5 { - \__cs_parm_from_arg_count:nnF + \__kernel_cs_parm_from_arg_count:nnF { \@@_generate_conditional:nnNnnnnn {#1} {#2} #3 {#4} {#5} } { \tl_count:n {#2} } { @@ -2529,8 +2354,8 @@ \use:x { \exp_not:N \@@_set_eq_conditional:nnNnnNNw - \__cs_split_function:NN #2 \prg_do_nothing: - \__cs_split_function:NN #3 \prg_do_nothing: + \cs_split_function:N #2 + \cs_split_function:N #3 \exp_not:N #1 \tl_to_str:n {#4} \exp_not:n { , \q_recursion_tail , \q_recursion_stop } @@ -2637,6 +2462,44 @@ %<@@=cs> % \end{macrocode} % +% \begin{function}{\@@_count_signature:N} +% \begin{syntax} +% \cs{@@_count_signature:N} \meta{function} +% \end{syntax} +% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part +% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon). +% The \meta{number} of tokens in the \meta{signature} is then left in +% the input stream. If there was no \meta{signature} then the result is +% the marker value $-1$. +% \end{function} +% +% \begin{function}[EXP]{\@@_get_function_name:N} +% \begin{syntax} +% \cs{@@_get_function_name:N} \meta{function} +% \end{syntax} +% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part +% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon). +% The \meta{name} is then left in the input stream without the escape +% character present made up of tokens with category code $12$ +% (other). +% \end{function} +% +% \begin{function}[EXP]{\@@_get_function_signature:N} +% \begin{syntax} +% \cs{@@_get_function_signature:N} \meta{function} +% \end{syntax} +% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part +% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon). +% The \meta{signature} is then left in the input stream made up of +% tokens with category code $12$ (other). +% \end{function} +% +% \begin{function}{\@@_tmp:w} +% Function used for various short-term usages, for instance defining +% functions whose definition involves tokens which are hard to insert +% normally (spaces, characters with category other). +% \end{function} +% % \begin{macro}[EXP]{\cs_to_str:N} % \begin{macro}[EXP]{\@@_to_str:N, \@@_to_str:w} % This converts a control sequence into the character string of its @@ -2670,7 +2533,7 @@ % \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{@@_to_str:w} -% comes into play, inserting |-\__int_value:w|, which expands \cs{c_zero} +% comes into play, inserting |-\int_value:w|, which expands \cs{c_zero} % 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 expansion of @@ -2693,7 +2556,7 @@ } \cs_set:Npn \@@_to_str:N #1 { \c_zero } \cs_set:Npn \@@_to_str:w #1 \@@_to_str:N - { - \__int_value:w \fi: \exp_after:wN \c_zero } + { - \int_value:w \fi: \exp_after:wN \c_zero } % \end{macrocode} % If speed is a concern we could use \tn{csstring} in \LuaTeX{}. For % the empty csname that primitive gives an empty result while the @@ -2702,19 +2565,14 @@ % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\@@_split_function:NN} +% \begin{macro}[EXP]{\cs_split_function:N} % \begin{macro}[EXP] % {\@@_split_function_auxi:w, \@@_split_function_auxii:w} % This function takes a function name and splits it into name with % the escape char removed and argument specification. In addition to % this, a third argument, a boolean \meta{true} or \meta{false} is % returned with \meta{true} for when there is a colon in the function -% and \meta{false} if there is not. Lastly, the second argument of -% \cs{@@_split_function:NN} is supposed to be a function -% taking three variables, one for name, one for signature, and one -% for the boolean. For example, -% |\@@_split_function:NN \foo_bar:cnx \use_i:nnn| as input -% becomes |\use_i:nnn {foo_bar} {cnx} \c_true_bool|. +% and \meta{false} if there is not. % % We cannot use |:| directly as it has the wrong category code so % an |x|-type expansion is used to force the conversion. @@ -2726,41 +2584,30 @@ % then \cs{c_true_bool} as |#3|, and |#4| cleans up until \cs{q_stop}. % Otherwise, the |#1| contains the function name and \cs{q_mark} % \cs{c_true_bool}, |#2| is empty, |#3| is \cs{c_false_bool}, and |#4| -% cleans up. In both cases, |#5| is the \meta{processor}. The second +% cleans up. The second % auxiliary trims the trailing \cs{q_mark} from the function name if % present (that is, if the original function had no colon). % \begin{macrocode} -\cs_set:Npx \@@_split_function:NN #1 +\cs_set_protected:Npn \@@_tmp:w #1 { - \exp_not:N \exp_after:wN \exp_not:N \exp_after:wN - \exp_not:N \exp_after:wN \exp_not:N \@@_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 \@@_split_function_auxi:w - ##1 \token_to_str:N : ##2 \exp_not:N \q_mark ##3##4 \exp_not:N \q_stop ##5 + \cs_set:Npn \cs_split_function:N ##1 + { + \exp_after:wN \exp_after:wN \exp_after:wN + \@@_split_function_auxi:w + \cs_to_str:N ##1 \q_mark \c_true_bool + #1 \q_mark \c_false_bool \q_stop + } + \cs_set:Npn \@@_split_function_auxi:w + ##1 #1 ##2 \q_mark ##3##4 \q_stop + { \@@_split_function_auxii:w ##1 \q_mark \q_stop {##2} ##3 } + \cs_set:Npn \@@_split_function_auxii:w ##1 \q_mark ##2 \q_stop + { {##1} } } - { \@@_split_function_auxii:w #5 #1 \q_mark \q_stop {#2} #3 } -\cs_set:Npn \@@_split_function_auxii:w #1#2 \q_mark #3 \q_stop - { #1 {#2} } +\exp_after:wN \@@_tmp:w \token_to_str:N : % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[EXP] -% {\@@_get_function_name:N, \@@_get_function_signature:N} -% Simple wrappers. -% \begin{macrocode} -\cs_set:Npn \@@_get_function_name:N #1 - { \@@_split_function:NN #1 \use_i:nnn } -\cs_set:Npn \@@_get_function_signature:N #1 - { \@@_split_function:NN #1 \use_ii:nnn } -% \end{macrocode} -% \end{macro} -% % \subsection{Exist or free} % % A control sequence is said to \emph{exist} (to be used) if has an entry in @@ -2899,7 +2746,7 @@ % \begin{macrocode} \cs_set_protected:Npn \__kernel_msg_error:nnxx #1#2#3#4 { - \tex_newlinechar:D = `\^^J \tex_relax:D + \tex_newlinechar:D = `\^^J \scan_stop: \tex_errmessage:D { !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!~! ^^J @@ -2937,7 +2784,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\__chk_if_free_cs:N, \__chk_if_free_cs:c} +% \begin{macro}{\__kernel_chk_if_free_cs:N, \__kernel_chk_if_free_cs:c} % This command is called by \cs{cs_new_nopar:Npn} and \cs{cs_new_eq:NN} % \emph{etc.}\ % to make sure that the argument sequence is not already in use. If @@ -2947,8 +2794,11 @@ % conditional processing since it may be an |\if...| type function! % \begin{macrocode} \__kernel_patch:nnNNpn { } - { \__kernel_debug_log:x { Defining~\token_to_str:N #1~ \msg_line_context: } } -\cs_set_protected:Npn \__chk_if_free_cs:N #1 + { + \__kernel_debug_log:x + { Defining~\token_to_str:N #1~ \msg_line_context: } + } +\cs_set_protected:Npn \__kernel_chk_if_free_cs:N #1 { \cs_if_free:NF #1 { @@ -2956,8 +2806,8 @@ { \token_to_str:N #1 } { \token_to_meaning:N #1 } } } -\cs_set_protected:Npn \__chk_if_free_cs:c - { \exp_args:Nc \__chk_if_free_cs:N } +\cs_set_protected:Npn \__kernel_chk_if_free_cs:c + { \exp_args:Nc \__kernel_chk_if_free_cs:N } % \end{macrocode} % \end{macro} % @@ -2982,7 +2832,7 @@ { \cs_set_protected:Npn #1 ##1 { - \__chk_if_free_cs:N ##1 + \__kernel_chk_if_free_cs:N ##1 #2 ##1 } } @@ -3111,7 +2961,7 @@ \cs_new_protected:Npn \cs_gset_eq:cc { \exp_args:Ncc \cs_gset_eq:NN } \cs_new_protected:Npn \cs_new_eq:NN #1 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \tex_global:D \cs_set_eq:NN #1 } \cs_new_protected:Npn \cs_new_eq:cN { \exp_args:Nc \cs_new_eq:NN } @@ -3149,7 +2999,7 @@ %<@@=cs> % \end{macrocode} % -% \begin{macro}{\@@_parm_from_arg_count:nnF} +% \begin{macro}{\__kernel_cs_parm_from_arg_count:nnF} % \begin{macro}{\@@_parm_from_arg_count_test:nnF} % \LaTeX3 provides shorthands to define control sequences and % conditionals with a simple parameter text, derived directly from the @@ -3163,12 +3013,12 @@ % the functions use here are not defined yet, but will be defined % before this function is called. % \begin{macrocode} -\cs_set_protected:Npn \@@_parm_from_arg_count:nnF #1#2 +\cs_set_protected:Npn \__kernel_cs_parm_from_arg_count:nnF #1#2 { \exp_args:Nx \@@_parm_from_arg_count_test:nnF { \exp_after:wN \exp_not:n - \if_case:w \__int_eval:n {#2} + \if_case:w \int_eval:n {#2} { } \or: { ##1 } \or: { ##1##2 } @@ -3204,6 +3054,7 @@ % \end{macrocode} % % \begin{macro}[EXP]{\@@_count_signature:N, \@@_count_signature:c} +% \begin{macro}[EXP]{\@@_count_signature:n} % \begin{macro}[EXP]{\@@_count_signature:nnN} % Counting the number of tokens in the signature, \emph{i.e.}, the % number of arguments the function should take. Since this is not @@ -3212,7 +3063,9 @@ % We need a variant form right away. % \begin{macrocode} \cs_new:Npn \@@_count_signature:N #1 - { \int_eval:n { \@@_split_function:NN #1 \@@_count_signature:nnN } } + { \exp_args:Nf \@@_count_signature:n { \cs_split_function:N #1 } } +\cs_new:Npn \@@_count_signature:n #1 + { \int_eval:n { \@@_count_signature:nnN #1 } } \cs_new:Npn \@@_count_signature:nnN #1#2#3 { \if_meaning:w \c_true_bool #3 @@ -3226,6 +3079,7 @@ % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro} % { @@ -3246,7 +3100,7 @@ % \begin{macrocode} \cs_new_protected:Npn \cs_generate_from_arg_count:NNnn #1#2#3#4 { - \@@_parm_from_arg_count:nnF { \use:nnn #2 #1 } {#3} + \__kernel_cs_parm_from_arg_count:nnF { \use:nnn #2 #1 } {#3} { \__kernel_msg_error:nnxx { kernel } { bad-number-of-arguments } { \token_to_str:N #1 } { \int_eval:n {#3} } @@ -3296,7 +3150,7 @@ % \cs_set_protected:Npn \cs_set:Nn #1#2 % { % \cs_generate_from_arg_count:NNnn #1 \cs_set:Npn -% { \__cs_count_signature:N #1 } {#2} +% { \@@_count_signature:N #1 } {#2} % } % \end{verbatim} % In short, to define \cs{cs_set:Nn} we need just use \cs{cs_set:Npn}, @@ -3314,8 +3168,12 @@ } \cs_new_protected:Npn \@@_generate_from_signature:NNn #1#2 { - \@@_split_function:NN #2 \@@_generate_from_signature:nnNNNn - #1 #2 + \use:x + { + \@@_generate_from_signature:nnNNNn + \cs_split_function:N #2 + } + #1 #2 } \cs_new_protected:Npn \@@_generate_from_signature:nnNNNn #1#2#3#4#5#6 { @@ -3454,10 +3312,10 @@ %<@@=kernel> % \end{macrocode} % -% \begin{macro}{\@@_check_defined:NT} +% \begin{macro}{\@@_chk_defined:NT} % Error if the variable |#1| is not defined. % \begin{macrocode} -\cs_new_protected:Npn \@@_check_defined:NT #1#2 +\cs_new_protected:Npn \@@_chk_defined:NT #1#2 { \cs_if_exist:NTF #1 {#2} @@ -3490,7 +3348,7 @@ { \exp_args:Nc \@@_register_log:N } \cs_new_protected:Npn \@@_register_show_aux:NN #1#2 { - \@@_check_defined:NT #2 + \@@_chk_defined:NT #2 { \exp_args:No \@@_register_show_aux:nNN { \tex_the:D #2 } #2 #1 @@ -3537,7 +3395,7 @@ % \begin{macro}[EXP]{\prg_do_nothing:} % This does not fit anywhere else! % \begin{macrocode} -\cs_new_nopar:Npn \prg_do_nothing: { } +\cs_new:Npn \prg_do_nothing: { } % \end{macrocode} % \end{macro} % @@ -3547,7 +3405,7 @@ %<@@=prg> % \end{macrocode} % -% \begin{macro}[EXP]{\@@_break_point:Nn, \@@_map_break:Nn} +% \begin{macro}[EXP]{\prg_break_point:Nn, \prg_map_break:Nn} % In inline mappings, the nesting level must be reset % at the end of the mapping, even when the user decides % to break out. This is done by putting the code that @@ -3557,28 +3415,28 @@ % before the user's code (if any). There is a check that we close the % correct loop, otherwise we continue breaking. % \begin{macrocode} -\cs_new_eq:NN \@@_break_point:Nn \use_ii:nn -\cs_new:Npn \@@_map_break:Nn #1#2#3 \@@_break_point:Nn #4#5 +\cs_new_eq:NN \prg_break_point:Nn \use_ii:nn +\cs_new:Npn \prg_map_break:Nn #1#2#3 \prg_break_point:Nn #4#5 { #5 \if_meaning:w #1 #4 \exp_after:wN \use_iii:nnn \fi: - \@@_map_break:Nn #1 {#2} + \prg_map_break:Nn #1 {#2} } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_break_point:} -% \begin{macro}{\@@_break:, \@@_break:n} -% Very simple analogues of \cs{@@_break_point:Nn} and -% \cs{@@_map_break:Nn}, for use in fast short-term recursions which +% \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 \@@_break_point: \prg_do_nothing: -\cs_new:Npn \@@_break: #1 \@@_break_point: { } -\cs_new:Npn \@@_break:n #1#2 \@@_break_point: {#1} +\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} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx index 63e80a95630..7d4e945dbfc 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx @@ -138,7 +138,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -211,14 +211,6 @@ % {\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} % \end{verbatim} % -% \subsection{Internal functions and variables} -% -% \begin{variable}{\l__kernel_expl_bool} -% A boolean which records the current code syntax status: \texttt{true} if -% currently inside a code environment. This variable should only be -% set by \cs{ExplSyntaxOn}/\cs{ExplSyntaxOff}. -% \end{variable} -% % \end{documentation} % % \begin{implementation} @@ -505,7 +497,7 @@ \begingroup % \end{macrocode} % Lower case chars: map to themselves when lower casing and down by |"20| when -% upper casing. (The characters |a|--|z| are set up correctly by Ini\TeX{}.) +% upper casing. (The characters |a|--|z| are set up correctly by \IniTeX{}.) % \begin{macrocode} \def\temp{% \ifnum\count0>\count2 % @@ -525,7 +517,7 @@ % \end{macrocode} % Upper case chars: map up by |"20| when lower casing, to themselves when upper % casing and require an \tn{sfcode} of $999$. (The characters |A|--|Z| are set -% up correctly by Ini\TeX{}.) +% up correctly by \IniTeX{}.) % \begin{macrocode} \def\temp{% \ifnum\count0>\count2 % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx index 0ae3b450f40..f7e6ad1f824 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -842,8 +842,27 @@ %<@@=box> % \end{macrocode} % -% The code in this module is very straight forward so I'm not going to -% comment it very extensively. +% \subsection{Support code} +% +% \begin{macro}{\@@_dim_eval:w} +% \begin{macro}{\@@_dim_eval:n} +% Evaluating a dimension expression expandably. The only +% difference with \cs{dim_eval:n} is the lack of \cs{dim_use:N}, to +% produce an internal dimension rather than expand it into characters. +% \begin{macrocode} +\cs_new_eq:NN \@@_dim_eval:w \etex_dimexpr:D +\__kernel_patch_args:nNNpn + { + { + \__kernel_chk_expr:nNnN {#1} + \@@_dim_eval:w { } \@@_dim_eval:n + } + } +\cs_new:Npn \@@_dim_eval:n #1 + { \@@_dim_eval:w #1 \scan_stop: } +% \end{macrocode} +% \end{macro} +% \end{macro} % % \subsection{Creating and initialising boxes} % @@ -856,7 +875,7 @@ %<*package> \cs_new_protected:Npn \box_new:N #1 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \cs:w newbox \cs_end: #1 } %</package> @@ -978,11 +997,11 @@ % parentheses to catch early termination. % \begin{macrocode} \cs_new_protected:Npn \box_set_dp:Nn #1#2 - { \box_dp:N #1 \__dim_eval:n {#2} } + { \box_dp:N #1 \@@_dim_eval:n {#2} } \cs_new_protected:Npn \box_set_ht:Nn #1#2 - { \box_ht:N #1 \__dim_eval:n {#2} } + { \box_ht:N #1 \@@_dim_eval:n {#2} } \cs_new_protected:Npn \box_set_wd:Nn #1#2 - { \box_wd:N #1 \__dim_eval:n {#2} } + { \box_wd:N #1 \@@_dim_eval:n {#2} } \cs_generate_variant:Nn \box_set_ht:Nn { c } \cs_generate_variant:Nn \box_set_dp:Nn { c } \cs_generate_variant:Nn \box_set_wd:Nn { c } @@ -1014,13 +1033,13 @@ % parentheses to catch early termination. % \begin{macrocode} \cs_new_protected:Npn \box_move_left:nn #1#2 - { \tex_moveleft:D \__dim_eval:n {#1} #2 } + { \tex_moveleft:D \@@_dim_eval:n {#1} #2 } \cs_new_protected:Npn \box_move_right:nn #1#2 - { \tex_moveright:D \__dim_eval:n {#1} #2 } + { \tex_moveright:D \@@_dim_eval:n {#1} #2 } \cs_new_protected:Npn \box_move_up:nn #1#2 - { \tex_raise:D \__dim_eval:n {#1} #2 } + { \tex_raise:D \@@_dim_eval:n {#1} #2 } \cs_new_protected:Npn \box_move_down:nn #1#2 - { \tex_lower:D \__dim_eval:n {#1} #2 } + { \tex_lower:D \@@_dim_eval:n {#1} #2 } % \end{macrocode} % \end{macro} % \end{macro} @@ -1200,7 +1219,10 @@ % \begin{macrocode} \__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \hbox_set:Nn #1#2 - { \tex_setbox:D #1 \tex_hbox:D { \color_group_begin: #2 \color_group_end: } } + { + \tex_setbox:D #1 \tex_hbox:D + { \color_group_begin: #2 \color_group_end: } + } \__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \hbox_gset:Nn #1#2 { @@ -1222,13 +1244,13 @@ \__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \hbox_set_to_wd:Nnn #1#2#3 { - \tex_setbox:D #1 \tex_hbox:D to \__dim_eval:n {#2} + \tex_setbox:D #1 \tex_hbox:D to \@@_dim_eval:n {#2} { \color_group_begin: #3 \color_group_end: } } \__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \hbox_gset_to_wd:Nnn #1#2#3 { - \tex_global:D \tex_setbox:D #1 \tex_hbox:D to \__dim_eval:n {#2} + \tex_global:D \tex_setbox:D #1 \tex_hbox:D to \@@_dim_eval:n {#2} { \color_group_begin: #3 \color_group_end: } } \cs_generate_variant:Nn \hbox_set_to_wd:Nnn { c } @@ -1278,14 +1300,14 @@ \__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \hbox_set_to_wd:Nnw #1#2 { - \tex_setbox:D #1 \tex_hbox:D to \__dim_eval:n {#2} + \tex_setbox:D #1 \tex_hbox:D to \@@_dim_eval:n {#2} \c_group_begin_token \color_group_begin: } \__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \hbox_gset_to_wd:Nnw #1#2 { - \tex_global:D \tex_setbox:D #1 \tex_hbox:D to \__dim_eval:n {#2} + \tex_global:D \tex_setbox:D #1 \tex_hbox:D to \@@_dim_eval:n {#2} \c_group_begin_token \color_group_begin: } @@ -1302,11 +1324,14 @@ % \begin{macrocode} \cs_new_protected:Npn \hbox_to_wd:nn #1#2 { - \tex_hbox:D to \__dim_eval:n {#1} + \tex_hbox:D to \@@_dim_eval:n {#1} { \color_group_begin: #2 \color_group_end: } } \cs_new_protected:Npn \hbox_to_zero:n #1 - { \tex_hbox:D to \c_zero_dim { \color_group_begin: #1 \color_group_end: } } + { + \tex_hbox:D to \c_zero_dim + { \color_group_begin: #1 \color_group_end: } + } % \end{macrocode} % \end{macro} % \end{macro} @@ -1362,7 +1387,7 @@ % \begin{macrocode} \cs_new_protected:Npn \vbox_to_ht:nn #1#2 { - \tex_vbox:D to \__dim_eval:n {#1} + \tex_vbox:D to \@@_dim_eval:n {#1} { \color_group_begin: #2 \color_group_end: } } \cs_new_protected:Npn \vbox_to_zero:n #1 @@ -1429,13 +1454,13 @@ \__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \vbox_set_to_ht:Nnn #1#2#3 { - \tex_setbox:D #1 \tex_vbox:D to \__dim_eval:n {#2} + \tex_setbox:D #1 \tex_vbox:D to \@@_dim_eval:n {#2} { \color_group_begin: #3 \color_group_end: } } \__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \vbox_gset_to_ht:Nnn #1#2#3 { - \tex_global:D \tex_setbox:D #1 \tex_vbox:D to \__dim_eval:n {#2} + \tex_global:D \tex_setbox:D #1 \tex_vbox:D to \@@_dim_eval:n {#2} { \color_group_begin: #3 \color_group_end: } } \cs_generate_variant:Nn \vbox_set_to_ht:Nnn { c } @@ -1485,14 +1510,14 @@ \__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \vbox_set_to_ht:Nnw #1#2 { - \tex_setbox:D #1 \tex_vbox:D to \__dim_eval:n {#2} + \tex_setbox:D #1 \tex_vbox:D to \@@_dim_eval:n {#2} \c_group_begin_token \color_group_begin: } \__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \vbox_gset_to_ht:Nnw #1#2 { - \tex_global:D \tex_setbox:D #1 \tex_vbox:D to \__dim_eval:n {#2} + \tex_global:D \tex_setbox:D #1 \tex_vbox:D to \@@_dim_eval:n {#2} \c_group_begin_token \color_group_begin: } @@ -1521,7 +1546,7 @@ % \begin{macrocode} \__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \vbox_set_split_to_ht:NNn #1#2#3 - { \tex_setbox:D #1 \tex_vsplit:D #2 to \__dim_eval:n {#3} } + { \tex_setbox:D #1 \tex_vsplit:D #2 to \@@_dim_eval:n {#3} } % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx index 3208f1ec9bb..cd1e06fd6c2 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx @@ -42,7 +42,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -136,6 +136,19 @@ % \end{texnote} % \end{function} % +% \begin{function}[EXP, added = 2018-04-17]{\use_x:n} +% \begin{syntax} +% \cs{use_x:n} \Arg{token list} +% \end{syntax} +% Fully expands the \meta{token list} in an \texttt{x}-type manner, +% \emph{but} the function remains fully expandable, and parameter +% character (usually~|#|) need not be doubled. +% \begin{texnote} +% \cs{use_x:n} the a wrapper around the primitive \tn{expanded}: +% it requires two expansions to complete its action. +% \end{texnote} +% \end{function} +% % \section{Additions to \pkg{l3box}} % % \subsection{Viewing part of a box} @@ -201,8 +214,8 @@ % \cs{clist_rand_item:n} \Arg{comma list} % \end{syntax} % Selects a pseudo-random item of the \meta{comma list}. If the -% \meta{comma list} has no item, the result is empty. This is only -% available in \pdfTeX{} and \LuaTeX{}. +% \meta{comma list} has no item, the result is empty. This not +% yet available in \XeTeX{}. % \begin{texnote} % The result is returned within the \tn{unexpanded} % primitive (\cs{exp_not:n}), which means that the \meta{item} @@ -255,6 +268,19 @@ % should be defined. % \end{function} % +% \begin{function}[added = 2018-04-04]{\exp_args_generate:n} +% \begin{syntax} +% \cs{exp_args_generate:n} \Arg{variant argument specifiers} +% \end{syntax} +% Defines \cs[no-index]{exp_args:N\meta{variant}} functions for each +% \meta{variant} given in the comma list \Arg{variant argument +% specifiers}. Each \meta{variant} should consist of the letters |N|, +% |c|, |n|, |V|, |v|, |o|, |f|, |x|, |p| and the resulting function is +% protected if the letter |x| appears in the \meta{variant}. This is +% only useful for cases where \cs{cs_generate_variant:Nn} is not +% applicable. +% \end{function} +% % \section{Additions to \pkg{l3file}} % % \begin{function}[added = 2017-07-11]{\file_get_mdfive_hash:nN} @@ -335,15 +361,14 @@ % \end{texnote} % \end{function} % -% \section{Additions to \pkg{l3int}} +% \section{Additions to \pkg{l3flag}} % -% \begin{function}[EXP, added = 2016-12-06]{\int_rand:nn} +% \begin{function}[EXP, added = 2018-04-02]{\flag_raise_if_clear:n} % \begin{syntax} -% \cs{int_rand:nn} \Arg{intexpr_1} \Arg{intexpr_2} +% \cs{flag_raise_if_clear:n} \Arg{flag name} % \end{syntax} -% Evaluates the two \meta{integer expressions} and produces a -% pseudo-random number between the two (with bounds included). This -% is only available in \pdfTeX{} and \LuaTeX{}. +% Ensures the \meta{flag} is raised by making its height at least~$1$, +% locally. % \end{function} % % \section{Additions to \pkg{l3msg}} @@ -478,10 +503,9 @@ % \begin{syntax} % \cs{prop_rand_key_value:N} \meta{prop~var} % \end{syntax} -% Selects a pseudo-random key--value pair in the \meta{property list} -% and returns \Arg{key}\Arg{value}. If the \meta{property list} is -% empty the result is empty. This is only available in \pdfTeX{} and -% \LuaTeX{}. +% Selects a pseudo-random key--value pair from the \meta{property list} +% and returns \Arg{key} and \Arg{value}. If the \meta{property list} is +% empty the result is empty. This is not yet available in \XeTeX{}. % \begin{texnote} % The result is returned within the \tn{unexpanded} % primitive (\cs{exp_not:n}), which means that the \meta{value} @@ -578,8 +602,8 @@ % \cs{seq_rand_item:N} \meta{seq~var} % \end{syntax} % Selects a pseudo-random item of the \meta{sequence}. If the -% \meta{sequence} is empty the result is empty. This is only -% available in \pdfTeX{} and \LuaTeX{}. +% \meta{sequence} is empty the result is empty. This is not yet +% available in \XeTeX{}. % \begin{texnote} % The result is returned within the \tn{unexpanded} % primitive (\cs{exp_not:n}), which means that the \meta{item} @@ -598,6 +622,61 @@ % items in the \meta{comma list}. % \end{function} % +% \begin{function}[added = 2018-04-06] +% {\seq_set_from_function:NnN, \seq_gset_from_function:NnN} +% \begin{syntax} +% \cs{seq_set_from_function:NnN} \meta{seq~var} \Arg{loop~code} \meta{function} +% \end{syntax} +% Sets the \meta{seq~var} equal to a sequence whose items are obtained +% by \texttt{x}-expanding \meta{loop~code} \meta{function}. This +% expansion must result in successive calls to the \meta{function} +% with no nonexpandable tokens in between. More precisely the +% \meta{function} is replaced by a wrapper function that inserts the +% appropriate separators between items in the sequence. The +% \meta{loop~code} must be expandable; it can be for example +% \cs{tl_map_function:NN} \meta{tl~var} or \cs{clist_map_function:nN} +% \Arg{clist} or \cs{int_step_function:nnnN} \Arg{initial value} +% \Arg{step} \Arg{final value}. +% \end{function} +% +% \begin{function}[added = 2018-04-06] +% {\seq_set_from_inline_x:Nnn, \seq_gset_from_inline_x:Nnn} +% \begin{syntax} +% \cs{seq_set_from_inline_x:Nnn} \meta{seq~var} \Arg{loop~code} \Arg{inline~code} +% \end{syntax} +% Sets the \meta{seq~var} equal to a sequence whose items are obtained +% by \texttt{x}-expanding \meta{loop~code} applied to a +% \meta{function} derived from the \meta{inline~code}. A +% \meta{function} is defined, that takes one argument, +% \texttt{x}-expands the \meta{inline~code} with that argument +% as~|#1|, then adds appropriate separators to turn the result into an +% item of the sequence. The \texttt{x}-expansion of \meta{loop~code} +% \meta{function} must result in successive calls to the +% \meta{function} with no nonexpandable tokens in between. The +% \meta{loop~code} must be expandable; it can be for example +% \cs{tl_map_function:NN} \meta{tl~var} or \cs{clist_map_function:nN} +% \Arg{clist} or \cs{int_step_function:nnnN} \Arg{initial value} +% \Arg{step} \Arg{final value}, but not the analogous \enquote{inline} +% mappings. +% \end{function} +% +% \begin{function}[added = 2018-04-29]{\seq_shuffle:N, \seq_gshuffle:N} +% \begin{syntax} +% \cs{seq_shuffle:N} \meta{seq~var} +% \end{syntax} +% Sets the \meta{seq~var} to the result of placing the items of the +% \meta{seq~var} in a random order. Each item is (roughly) as likely +% to end up in any given position. +% \begin{texnote} +% For sequences with more than $13$ items or so, only a small +% proportion of all possible permutations can be reached, because +% the random seed \cs{sys_rand_seed:} only has $28$-bits. The use +% of \tn{toks} internally means that sequences with more than +% $32767$ or $65535$ items (depending on the engine) cannot be +% shuffled. +% \end{texnote} +% \end{function} +% % \section{Additions to \pkg{l3skip}} % % \begin{function}{\skip_split_finite_else_action:nnNN} @@ -622,7 +701,7 @@ % \cs{sys_if_rand_exist:TF} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if the engine has a pseudo-random number generator. Currently -% this is the case in \pdfTeX{} and \LuaTeX{}. +% this is the case in \pdfTeX{}, \LuaTeX{}, \pTeX{} and \upTeX{}. % \end{function} % % \begin{function}[added = 2017-05-27, EXP]{\sys_rand_seed:} @@ -638,13 +717,18 @@ % \begin{syntax} % \cs{sys_gset_rand_seed:n} \Arg{intexpr} % \end{syntax} -% Sets the seed for the engine's pseudo-random number generator to the -% \meta{integer expression}. The assignment is global. This random -% seed affects all \cs[no-index]{\ldots{}_rand} functions (such as +% Globally sets the seed for the engine's pseudo-random number +% generator to the \meta{integer expression}. This random seed +% affects all \cs[no-index]{\ldots{}_rand} functions (such as % \cs{int_rand:nn} or \cs{clist_rand_item:n}) as well as other -% packages relying on the engine's random number generator. Currently -% only the absolute value of the seed is used. In engines without -% random number support this produces an error. +% packages relying on the engine's random number generator. In +% engines without random number support this produces an error. +% \begin{texnote} +% While a $32$-bit (signed) integer can be given as a seed, only the +% absolute value is used and any number beyond $2^{28}$ is divided +% by an appropriate power of~$2$. We recommend using an integer in +% $[0,2^{28}-1]$. +% \end{texnote} % \end{function} % % \begin{variable}[added = 2017-05-27]{\c_sys_shell_escape_int} @@ -974,8 +1058,8 @@ % \cs{tl_rand_item:n} \Arg{token list} % \end{syntax} % Selects a pseudo-random item of the \meta{token list}. If the -% \meta{token list} is blank, the result is empty. This is only -% available in \pdfTeX{} and \LuaTeX{}. +% \meta{token list} is blank, the result is empty. This is not yet +% available in \XeTeX{}. % \begin{texnote} % The result is returned within the \tn{unexpanded} % primitive (\cs{exp_not:n}), which means that the \meta{item} @@ -984,7 +1068,8 @@ % \end{texnote} % \end{function} % -% \begin{function}[EXP, added = 2017-02-17, updated = 2017-07-15]{\tl_range:nnn} +% \begin{function}[EXP, added = 2017-02-17, updated = 2017-07-15] +% {\tl_range:Nnn, \tl_range:nnn} % \begin{syntax} % \cs{tl_range:Nnn} \meta{tl~var} \Arg{start index} \Arg{end index} % \cs{tl_range:nnn} \Arg{token list} \Arg{start index} \Arg{end index} @@ -1067,6 +1152,73 @@ % \end{texnote} % \end{function} % +% \begin{function}[added = 2018-04-01]{\tl_build_begin:N, \tl_build_gbegin:N} +% \begin{syntax} +% \cs{tl_build_begin:N} \meta{tl~var} +% \end{syntax} +% Clears the \meta{tl~var} and sets it up to support other +% \cs[no-index]{tl_build_\ldots{}} functions, which allow accumulating +% large numbers of tokens piece by piece much more efficiently than +% standard \pkg{l3tl} functions. Until \cs{tl_build_end:N} +% \meta{tl~var} is called, applying any function from \pkg{l3tl} other +% than \cs[no-index]{tl_build_\ldots{}} will lead to incorrect +% results. The |begin| and |gbegin| functions must be used for local +% and global \meta{tl~var} respectively. +% \end{function} +% +% \begin{function}[added = 2018-04-01]{\tl_build_clear:N, \tl_build_gclear:N} +% \begin{syntax} +% \cs{tl_build_clear:N} \meta{tl~var} +% \end{syntax} +% Clears the \meta{tl~var} and sets it up to support other +% \cs[no-index]{tl_build_\ldots{}} functions. The |clear| and +% |gclear| functions must be used for local and global \meta{tl~var} +% respectively. +% \end{function} +% +% \begin{function}[added = 2018-04-01] +% { +% \tl_build_put_left:Nn, \tl_build_put_left:Nx, +% \tl_build_gput_left:Nn, \tl_build_gput_left:Nx, +% \tl_build_put_right:Nn, \tl_build_put_right:Nx, +% \tl_build_gput_right:Nn, \tl_build_gput_right:Nx, +% } +% \begin{syntax} +% \cs{tl_build_put_left:Nn} \meta{tl~var} \Arg{tokens} +% \cs{tl_build_put_right:Nn} \meta{tl~var} \Arg{tokens} +% \end{syntax} +% Adds \meta{tokens} to the left or right side of the current contents +% of \meta{tl~var}. The \meta{tl~var} must have been set up with +% \cs{tl_build_begin:N} or \cs{tl_build_gbegin:N}. The |put| and +% |gput| functions must be used for local and global \meta{tl~var} +% respectively. The |right| functions are about twice faster than the +% |left| functions. +% \end{function} +% +% \begin{function}[added = 2018-04-01]{\tl_build_get:NN} +% \begin{syntax} +% \cs{tl_build_get:N} \meta{tl~var_1} \meta{tl~var_2} +% \end{syntax} +% Stores the contents of the \meta{tl~var_1} in the \meta{tl~var_2}. +% The \meta{tl~var_1} must have been set up with \cs{tl_build_begin:N} +% or \cs{tl_build_gbegin:N}. The \meta{tl~var_2} is a +% \enquote{normal} token list variable, assigned locally using +% \cs{tl_set:Nn}. +% \end{function} +% +% \begin{function}[added = 2018-04-01]{\tl_build_end:N, \tl_build_gend:N} +% \begin{syntax} +% \cs{tl_build_end:N} \meta{tl~var} +% \end{syntax} +% Gets the contents of \meta{tl~var} and stores that into the +% \meta{tl~var} using \cs{tl_set:Nn}. The \meta{tl~var} must have +% been set up with \cs{tl_build_begin:N} or \cs{tl_build_gbegin:N}. +% The |end| and |gend| functions must be used for local and global +% \meta{tl~var} respectively. These functions completely remove the +% setup code that enabled \meta{tl~var} to be used for other +% \cs[no-index]{tl_build_\ldots{}} functions. +% \end{function} +% % \section{Additions to \pkg{l3token}} % % \begin{variable}[added = 2017-08-07]{\c_catcode_active_space_tl} @@ -1074,6 +1226,31 @@ % (\enquote{active}), and character code $32$ (space). % \end{variable} % +% \begin{function}[added = 2018-04-06, EXP] +% { +% \char_lower_case:N, \char_upper_case:N, +% \char_mixed_case:N, \char_fold_case:N +% } +% \begin{syntax} +% \cs{char_lower_case:N} \meta{char} +% \end{syntax} +% Converts the \meta{char} to the equivalent case-changed character +% as detailed by the function name (see \cs{str_fold_case:n} +% and \cs{tl_mixed_case:n} for details of these terms). The case mapping +% is carried out with no context-dependence (\emph{cf.}~\cs{tl_upper_case:n}, +% \emph{etc.}) +% \end{function} +% +% \begin{function}[added = 2018-04-02]{\char_codepoint_to_bytes:n} +% \begin{syntax} +% \cs{char_codepoint_to_bytes:n} \Arg{codepoint} +% \end{syntax} +% Converts the (Unicode) \meta{codepoint} to UTF-8 bytes. The expansion +% of this function comprises a leading integer (|1|--|4|) followed by the +% appropriate number of brace groups, each of which contains one byte of +% the UTF-8 sequence for the codepoint. +% \end{function} +% % \begin{function}[TF, updated = 2012-12-20]{\peek_N_type:} % \begin{syntax} % \cs{peek_N_type:TF} \Arg{true code} \Arg{false code} @@ -1159,9 +1336,9 @@ { \hbox_set:Nn \l_@@_internal_box { - \tex_kern:D - \__dim_eval:n {#2} + \tex_kern:D - \@@_dim_eval:n {#2} \box_use:N #1 - \tex_kern:D - \__dim_eval:n {#4} + \tex_kern:D - \@@_dim_eval:n {#4} } % \end{macrocode} % For the height and depth, there is a need to watch the baseline is @@ -1225,9 +1402,9 @@ { \hbox_set:Nn \l_@@_internal_box { - \tex_kern:D - \__dim_eval:n {#2} + \tex_kern:D - \@@_dim_eval:n {#2} \box_use:N #1 - \tex_kern:D \__dim_eval:n { #4 - \box_wd:N #1 } + \tex_kern:D \@@_dim_eval:n { #4 - \box_wd:N #1 } } \dim_compare:nNnTF {#3} < \c_zero_dim { @@ -1236,7 +1413,7 @@ \box_move_down:nn \c_zero_dim { \box_use:N \l_@@_internal_box } } - \box_set_dp:Nn \l_@@_internal_box { - \__dim_eval:n {#3} } + \box_set_dp:Nn \l_@@_internal_box { - \@@_dim_eval:n {#3} } } { \hbox_set:Nn \l_@@_internal_box @@ -1260,7 +1437,7 @@ { \hbox_set:Nn \l_@@_internal_box { - \box_move_up:nn { - \__dim_eval:n {#5} } + \box_move_up:nn { - \@@_dim_eval:n {#5} } { \box_use:N \l_@@_internal_box } } \box_set_ht:Nn \l_@@_internal_box \c_zero_dim @@ -1369,9 +1546,9 @@ % The corners and poles of the coffin can now be rotated around the % origin. This is best achieved using mapping functions. % \begin{macrocode} - \prop_map_inline:cn { l_@@_corners_ \__int_value:w #1 _prop } + \prop_map_inline:cn { l_@@_corners_ \@@_to_value:N #1 _prop } { \@@_rotate_corner:Nnnn #1 {##1} ##2 } - \prop_map_inline:cn { l_@@_poles_ \__int_value:w #1 _prop } + \prop_map_inline:cn { l_@@_poles_ \@@_to_value:N #1 _prop } { \@@_rotate_pole:Nnnnnn #1 {##1} ##2 } % \end{macrocode} % The bounding box of the coffin needs to be rotated, and to do this @@ -1400,8 +1577,9 @@ \hbox_set:Nn \l_@@_internal_box { \tex_kern:D - \__dim_eval:n + \dim_eval:n { \l_@@_bounding_shift_dim - \l_@@_left_corner_dim } + \exp_stop_f: \box_move_down:nn { \l_@@_bottom_corner_dim } { \box_use:N #1 } } @@ -1423,9 +1601,9 @@ % The final task is to move the poles and corners such that they are % back in alignment with the box reference point. % \begin{macrocode} - \prop_map_inline:cn { l_@@_corners_ \__int_value:w #1 _prop } + \prop_map_inline:cn { l_@@_corners_ \@@_to_value:N #1 _prop } { \@@_shift_corner:Nnnn #1 {##1} ##2 } - \prop_map_inline:cn { l_@@_poles_ \__int_value:w #1 _prop } + \prop_map_inline:cn { l_@@_poles_ \@@_to_value:N #1 _prop } { \@@_shift_pole:Nnnnnn #1 {##1} ##2 } } \cs_generate_variant:Nn \coffin_rotate:Nn { c } @@ -1442,12 +1620,18 @@ \prop_put:Nnx \l_@@_bounding_prop { tl } { { 0 pt } { \dim_eval:n { \box_ht:N #1 } } } \prop_put:Nnx \l_@@_bounding_prop { tr } - { { \dim_eval:n { \box_wd:N #1 } } { \dim_eval:n { \box_ht:N #1 } } } + { + { \dim_eval:n { \box_wd:N #1 } } + { \dim_eval:n { \box_ht:N #1 } } + } \dim_set:Nn \l_@@_internal_dim { -\box_dp:N #1 } \prop_put:Nnx \l_@@_bounding_prop { bl } { { 0 pt } { \dim_use:N \l_@@_internal_dim } } \prop_put:Nnx \l_@@_bounding_prop { br } - { { \dim_eval:n { \box_wd:N #1 } } { \dim_use:N \l_@@_internal_dim } } + { + { \dim_eval:n { \box_wd:N #1 } } + { \dim_use:N \l_@@_internal_dim } + } } % \end{macrocode} % \end{macro} @@ -1468,7 +1652,7 @@ \cs_new_protected:Npn \@@_rotate_corner:Nnnn #1#2#3#4 { \@@_rotate_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim - \prop_put:cnx { l_@@_corners_ \__int_value:w #1 _prop } {#2} + \prop_put:cnx { l_@@_corners_ \@@_to_value:N #1 _prop } {#2} { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } } } % \end{macrocode} @@ -1539,7 +1723,7 @@ \dim_set:Nn \l_@@_right_corner_dim { -\c_max_dim } \dim_set:Nn \l_@@_bottom_corner_dim { \c_max_dim } \dim_set:Nn \l_@@_left_corner_dim { \c_max_dim } - \prop_map_inline:cn { l_@@_corners_ \__int_value:w #1 _prop } + \prop_map_inline:cn { l_@@_corners_ \@@_to_value:N #1 _prop } { \@@_find_corner_maxima_aux:nn ##2 } } \cs_new_protected:Npn \@@_find_corner_maxima_aux:nn #1#2 @@ -1586,7 +1770,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_shift_corner:Nnnn #1#2#3#4 { - \prop_put:cnx { l_@@_corners_ \__int_value:w #1 _ prop } {#2} + \prop_put:cnx { l_@@_corners_ \@@_to_value:N #1 _ prop } {#2} { { \dim_eval:n { #3 - \l_@@_left_corner_dim } } { \dim_eval:n { #4 - \l_@@_bottom_corner_dim } } @@ -1594,7 +1778,7 @@ } \cs_new_protected:Npn \@@_shift_pole:Nnnnnn #1#2#3#4#5#6 { - \prop_put:cnx { l_@@_poles_ \__int_value:w #1 _ prop } {#2} + \prop_put:cnx { l_@@_poles_ \@@_to_value:N #1 _ prop } {#2} { { \dim_eval:n { #3 - \l_@@_left_corner_dim } } { \dim_eval:n { #4 - \l_@@_bottom_corner_dim } } @@ -1656,9 +1840,9 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_resize_common:Nnn #1#2#3 { - \prop_map_inline:cn { l_@@_corners_ \__int_value:w #1 _prop } + \prop_map_inline:cn { l_@@_corners_ \@@_to_value:N #1 _prop } { \@@_scale_corner:Nnnn #1 {##1} ##2 } - \prop_map_inline:cn { l_@@_poles_ \__int_value:w #1 _prop } + \prop_map_inline:cn { l_@@_poles_ \@@_to_value:N #1 _prop } { \@@_scale_pole:Nnnnnn #1 {##1} ##2 } % \end{macrocode} % Negative $x$-scaling values place the poles in the wrong @@ -1666,9 +1850,11 @@ % \begin{macrocode} \fp_compare:nNnT \l_@@_scale_x_fp < \c_zero_fp { - \prop_map_inline:cn { l_@@_corners_ \__int_value:w #1 _prop } + \prop_map_inline:cn + { l_@@_corners_ \@@_to_value:N #1 _prop } { \@@_x_shift_corner:Nnnn #1 {##1} ##2 } - \prop_map_inline:cn { l_@@_poles_ \__int_value:w #1 _prop } + \prop_map_inline:cn + { l_@@_poles_ \@@_to_value:N #1 _prop } { \@@_x_shift_pole:Nnnnnn #1 {##1} ##2 } } } @@ -1723,7 +1909,7 @@ \cs_new_protected:Npn \@@_scale_corner:Nnnn #1#2#3#4 { \@@_scale_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim - \prop_put:cnx { l_@@_corners_ \__int_value:w #1 _prop } {#2} + \prop_put:cnx { l_@@_corners_ \@@_to_value:N #1 _prop } {#2} { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } } } \cs_new_protected:Npn \@@_scale_pole:Nnnnnn #1#2#3#4#5#6 @@ -1746,14 +1932,14 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_x_shift_corner:Nnnn #1#2#3#4 { - \prop_put:cnx { l_@@_corners_ \__int_value:w #1 _prop } {#2} + \prop_put:cnx { l_@@_corners_ \@@_to_value:N #1 _prop } {#2} { { \dim_eval:n { #3 + \box_wd:N #1 } } {#4} } } \cs_new_protected:Npn \@@_x_shift_pole:Nnnnnn #1#2#3#4#5#6 { - \prop_put:cnx { l_@@_poles_ \__int_value:w #1 _prop } {#2} + \prop_put:cnx { l_@@_poles_ \@@_to_value:N #1 _prop } {#2} { { \dim_eval:n { #3 + \box_wd:N #1 } } {#4} {#5} {#6} @@ -1795,7 +1981,7 @@ { \l_@@_full_name_str } } } -\cs_if_exist:NTF \luatex_directlua:D +\sys_if_engine_luatex:TF { \cs_set_protected:Npn \@@_get_details:nnN #1#2#3 { @@ -1820,7 +2006,7 @@ { \l_@@_full_name_str } } } - \cs_if_exist:NT \xetex_XeTeXversion:D + \sys_if_engine_xetex:T { \cs_set_protected:Npn \@@_get_details:nnN #1#2#3 { @@ -1869,99 +2055,28 @@ % \end{macrocode} % \end{macro} % -% \subsection{Additions to \pkg{l3int}} +% \subsection{Additions to \pkg{l3flag}} % % \begin{macrocode} -%<@@=int> +%<@@=flag> % \end{macrocode} % -% \begin{macro}[EXP]{\int_rand:nn} -% \begin{macro}[EXP] -% { -% \@@_rand:ww, \@@_rand_narrow:n, -% \@@_rand_narrow:nnn, \@@_rand_narrow:nnnn -% } -% Evaluate the argument and filter out the case where the lower -% bound~|#1| is more than the upper bound~|#2|. Then determine -% whether the range is narrower than \cs{c__fp_rand_size_int}; |#2-#1| -% may overflow for very large positive~|#2| and negative~|#1|. If the -% range is wide, use slower code from \pkg{l3fp}. If the range is -% narrow, call \cs{@@_rand_narrow:nn} \Arg{choices} |{#1}| where -% \meta{choices} is the number of possible outcomes. Then -% \cs{@@_rand_narrow:nnnn} receives a random number reduced modulo -% \meta{choices}, the random number itself, \meta{choices} and |#1|. -% To avoid bias, throw away the random number if it lies in the last, -% incomplete, interval of size \meta{choices} in -% $[0,\cs{c__fp_rand_size_int}-1]$, and try again. +% \begin{macro}[EXP]{\flag_raise_if_clear:n} +% It might be faster to just call the \enquote{trap} function in all +% cases but conceptually the function name suggests we should only run +% it if the flag is zero in case the \enquote{trap} made customizable +% in the future. % \begin{macrocode} -\cs_if_exist:NTF \pdftex_uniformdeviate:D - { - \__kernel_patch_args:nNNpn - { - { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_rand:nn } - { \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } \int_rand:nn } - } - \cs_new:Npn \int_rand:nn #1#2 - { - \exp_after:wN \@@_rand:ww - \@@_value:w \@@_eval:w #1 \exp_after:wN ; - \@@_value:w \@@_eval:w #2 ; - } - \cs_new:Npn \@@_rand:ww #1; #2; - { - \int_compare:nNnTF {#1} > {#2} - { - \__kernel_msg_expandable_error:nnnn - { kernel } { backward-range } {#1} {#2} - \@@_rand:ww #2; #1; - } - { - \int_compare:nNnTF {#1} > 0 - { \int_compare:nNnTF { #2 - #1 } < \c__fp_rand_size_int } - { \int_compare:nNnTF {#2} < { #1 + \c__fp_rand_size_int } } - { - \exp_args:Nf \@@_rand_narrow:nn - { \int_eval:n { #2 - #1 + 1 } } {#1} - } - { \fp_to_int:n { randint(#1,#2) } } - } - } - \cs_new:Npn \@@_rand_narrow:nn - { - \exp_args:No \@@_rand_narrow:nnn - { \pdftex_uniformdeviate:D \c__fp_rand_size_int } - } - \cs_new:Npn \@@_rand_narrow:nnn #1#2 - { - \exp_args:Nf \@@_rand_narrow:nnnn - { \int_mod:nn {#1} {#2} } {#1} {#2} - } - \cs_new:Npn \@@_rand_narrow:nnnn #1#2#3#4 - { - \int_compare:nNnTF { #2 - #1 + #3 } > \c__fp_rand_size_int - { \@@_rand_narrow:nn {#3} {#4} } - { \int_eval:n { #4 + #1 } } - } - } +\__kernel_patch:nnNNpn { \@@_chk_exist:n {#1} } { } +\cs_new:Npn \flag_raise_if_clear:n #1 { - \cs_new:Npn \int_rand:nn #1#2 - { - \__kernel_msg_expandable_error:nn { kernel } { fp-no-random } - \int_eval:n {#1} - } + \if_cs_exist:w flag~#1~0 \cs_end: + \else: + \cs:w flag~#1 \cs_end: 0 ; + \fi: } % \end{macrocode} % \end{macro} -% \end{macro} -% -% The following must be added to \pkg{l3msg}. -% \begin{macrocode} -\cs_if_exist:NT \pdftex_uniformdeviate:D - { - \__kernel_msg_new:nnn { kernel } { backward-range } - { Bounds~ordered~backwards~in~\int_rand:nn {#1}~{#2}. } - } -% \end{macrocode} % % \subsection{Additions to \pkg{l3msg}} % @@ -2075,7 +2190,7 @@ \__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN c #1 } { } \cs_new_protected:Npn \bool_const:Nn #1#2 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \tex_global:D \tex_chardef:D #1 = \bool_if_p:n {#2} } \cs_generate_variant:Nn \bool_const:Nn { c } @@ -2111,25 +2226,23 @@ % % \begin{macro}[rEXP]{\prop_map_tokens:Nn, \prop_map_tokens:cn} % \begin{macro}{\@@_map_tokens:nwwn} -% The mapping is very similar to \cs{prop_map_function:NN}. It grabs -% one key--value pair at a time, and stops when reaching the marker -% key \cs{q_recursion_tail}, which cannot appear in normal keys since -% those are strings. The odd construction |\use:n {#1}| allows |#1| -% to contain any token without interfering with \cs{prop_map_break:}. -% Argument |#2| of \cs{@@_map_tokens:nwwn} is \cs{s_@@} the first -% time, and is otherwise empty. +% The mapping is very similar to \cs{prop_map_function:NN}. The +% \cs{use_i:nn} removes the leading \cs{s_@@}. The odd construction +% |\use:n {#1}| allows |#1| to contain any token without interfering +% with \cs{prop_map_break:}. The loop stops when the argument +% delimited by \cs{@@_pair:wn} is \cs{prg_break:} instead of being +% empty. % \begin{macrocode} \cs_new:Npn \prop_map_tokens:Nn #1#2 { - \exp_last_unbraced:Nno \@@_map_tokens:nwwn {#2} #1 - \@@_pair:wn \q_recursion_tail \s_@@ { } - \__prg_break_point:Nn \prop_map_break: { } + \exp_last_unbraced:Nno + \use_i:nn { \@@_map_tokens:nwwn {#2} } #1 + \prg_break: \@@_pair:wn \s_@@ { } \prg_break_point: + \prg_break_point:Nn \prop_map_break: { } } \cs_new:Npn \@@_map_tokens:nwwn #1#2 \@@_pair:wn #3 \s_@@ #4 { - \if_meaning:w \q_recursion_tail #3 - \exp_after:wN \prop_map_break: - \fi: + #2 \use:n {#1} {#3} {#4} \@@_map_tokens:nwwn {#1} } @@ -2140,33 +2253,30 @@ % % \begin{macro}[EXP] % {\prop_rand_key_value:N, \prop_rand_key_value:c} -% \begin{macro}[EXP]{\@@_rand:NN, \@@_rand_item:Nw} +% \begin{macro}[EXP]{\@@_rand_item:w} % Contrarily to |clist|, |seq| and |tl|, there is no function to get % an item of a |prop| given an integer between $1$ and the number of % items, so we write the appropriate code. There is no bounds -% checking because \cs{int_rand:nn} is always within bounds. At the -% end, leave either the key |#3| or the value |#4| in the input -% stream. +% checking because \cs{int_rand:nn} is always within bounds. The +% initial \cs{int_value:w} is stopped by the first \cs{s_@@} in~|#1|. % \begin{macrocode} -\cs_new:Npn \prop_rand_key_value:N { \@@_rand:NN \@@_rand:nNn } -\cs_new:Npn \@@_rand:nNn #1#2#3 { \exp_not:n { {#1} {#3} } } -\cs_new:Npn \@@_rand:NN #1#2 +\cs_new:Npn \prop_rand_key_value:N #1 { - \prop_if_empty:NTF #2 { } + \prop_if_empty:NF #1 { - \exp_after:wN \@@_rand_item:Nw \exp_after:wN #1 - \__int_value:w \int_rand:nn { 1 } { \prop_count:N #2 } #2 - \q_stop + \exp_after:wN \@@_rand_item:w + \int_value:w \int_rand:nn { 1 } { \prop_count:N #1 } + #1 \q_stop } } -\cs_new:Npn \@@_rand_item:Nw #1#2 \s_@@ \@@_pair:wn #3 \s_@@ #4 +\cs_generate_variant:Nn \prop_rand_key_value:N { c } +\cs_new:Npn \@@_rand_item:w #1 \s_@@ \@@_pair:wn #2 \s_@@ #3 { - \int_compare:nNnF {#2} > 1 - { \use_i_delimit_by_q_stop:nw { #1 {#3} \exp_not:n {#4} } } - \exp_after:wN \@@_rand_item:Nw \exp_after:wN #1 - \__int_value:w \int_eval:n { #2 - 1 } \s_@@ + \int_compare:nNnF {#1} > 1 + { \use_i_delimit_by_q_stop:nw { \exp_not:n { {#2} {#3} } } } + \exp_after:wN \@@_rand_item:w + \int_value:w \int_eval:n { #1 - 1 } \s_@@ } -\cs_generate_variant:Nn \prop_rand_key_value:N { c } % \end{macrocode} % \end{macro} % \end{macro} @@ -2188,7 +2298,7 @@ % \@@_mapthread_function:Nnnwnn % } % The idea is to first expand both sequences, adding the -% usual |{ ? \__prg_break: } { }| to the end of each one. This is +% usual |{ ? \prg_break: } { }| to the end of each one. This is % most conveniently done in two steps using an auxiliary function. % The mapping then throws away the first tokens of |#2| and |#5|, % which for items in both sequences are \cs{s_@@} @@ -2203,13 +2313,13 @@ \cs_new:Npn \@@_mapthread_function:wNN \s_@@ #1 \q_stop #2#3 { \exp_after:wN \@@_mapthread_function:wNw #2 \q_stop #3 - #1 { ? \__prg_break: } { } - \__prg_break_point: + #1 { ? \prg_break: } { } + \prg_break_point: } \cs_new:Npn \@@_mapthread_function:wNw \s_@@ #1 \q_stop #2 { \@@_mapthread_function:Nnnwnn #2 - #1 { ? \__prg_break: } { } + #1 { ? \prg_break: } { } \q_stop } \cs_new:Npn \@@_mapthread_function:Nnnwnn #1#2#3#4 \q_stop #5#6 @@ -2227,7 +2337,7 @@ % \begin{macro}{\seq_set_filter:NNn, \seq_gset_filter:NNn} % \begin{macro}{\@@_set_filter:NNNn} % Similar to \cs{seq_map_inline:Nn}, without a -% \cs{__prg_break_point:} because the user's code +% \cs{prg_break_point:} because the user's code % is performed within the evaluation of a boolean expression, % and skipping out of that would break horribly. % The \cs{@@_wrap_item:n} function inserts the relevant @@ -2268,6 +2378,34 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\seq_set_from_inline_x:Nnn, \seq_gset_from_inline_x:Nnn} +% \begin{macro}{\@@_set_from_inline_x:NNnn} +% Set \cs{@@_item:n} then map it using the loop code. +% \begin{macrocode} +\cs_new_protected:Npn \seq_set_from_inline_x:Nnn + { \@@_set_from_inline_x:NNnn \tl_set:Nx } +\cs_new_protected:Npn \seq_gset_from_inline_x:Nnn + { \@@_set_from_inline_x:NNnn \tl_gset:Nx } +\cs_new_protected:Npn \@@_set_from_inline_x:NNnn #1#2#3#4 + { + \@@_push_item_def:n { \exp_not:N \@@_item:n {#4} } + #1 #2 { \s_@@ #3 \@@_item:n } + \@@_pop_item_def: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\seq_set_from_function:NnN, \seq_gset_from_function:NnN} +% Reuse \cs{seq_set_from_inline_x:Nnn}. +% \begin{macrocode} +\cs_new_protected:Npn \seq_set_from_function:NnN #1#2#3 + { \seq_set_from_inline_x:Nnn #1 {#2} { #3 {##1} } } +\cs_new_protected:Npn \seq_gset_from_function:NnN #1#2#3 + { \seq_gset_from_inline_x:Nnn #1 {#2} { #3 {##1} } } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\seq_rand_item:N, \seq_rand_item:c} % Importantly, \cs{seq_item:Nn} only evaluates its argument once. % \begin{macrocode} @@ -2292,6 +2430,70 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\seq_shuffle:N, \seq_gshuffle:N, \@@_shuffle:NN, \@@_shuffle_item:n} +% \begin{variable}{\g_@@_internal_seq, \l_@@_internal_a_int, \l_@@_internal_b_int} +% We apply the Fisher–Yates shuffle, storing items in \tn{toks} +% registers. We use the primitive \cs{pdftex_uniformdeviate:D} for +% speed reasons. Its non-uniformity is of order its argument divided +% by $2^{28}$, not too bad for small lists. For sequences with more +% than $13$ elements there are more possible permutations than +% possible seeds ($13!>2^{28}$) so the question of uniformity is +% somewhat moot. +% \begin{macrocode} +\cs_if_exist:NTF \pdftex_uniformdeviate:D + { + \int_new:N \l_@@_internal_a_int + \int_new:N \l_@@_internal_b_int + \seq_new:N \g_@@_internal_seq + \cs_new_protected:Npn \seq_shuffle:N { \@@_shuffle:NN \seq_set_eq:NN } + \cs_new_protected:Npn \seq_gshuffle:N { \@@_shuffle:NN \seq_gset_eq:NN } + \cs_new_protected:Npn \@@_shuffle:NN #1#2 + { + \int_compare:nNnTF { \seq_count:N #2 } > \c_max_register_int + { + \__kernel_msg_error:nnx { kernel } { shuffle-too-large } + { \token_to_str:N #2 } + } + { + \group_begin: + \cs_set_eq:NN \@@_item:n \@@_shuffle_item:n + \int_zero:N \l_@@_internal_a_int + #2 + \seq_gset_from_inline_x:Nnn \g_@@_internal_seq + { \int_step_function:nN { \l_@@_internal_a_int } } + { \tex_the:D \tex_toks:D ##1 } + \group_end: + #1 #2 \g_@@_internal_seq + \seq_gclear:N \g_@@_internal_seq + } + } + \cs_new_protected:Npn \@@_shuffle_item:n + { + \int_incr:N \l_@@_internal_a_int + \int_set:Nn \l_@@_internal_b_int + { 1 + \pdftex_uniformdeviate:D \l_@@_internal_a_int } + \tex_toks:D \l_@@_internal_a_int + = \tex_toks:D \l_@@_internal_b_int + \tex_toks:D \l_@@_internal_b_int + } + \__kernel_msg_new:nnnn { kernel } { shuffle-too-large } + { The~sequence~#1~is~too~long~to~be~shuffled~by~TeX. } + { + TeX~has~ \int_eval:n { \c_max_register_int + 1 } ~ + toks~registers:~this~only~allows~to~shuffle~up~to~ + \int_use:N \c_max_register_int \ items.~ + The~list~will~not~be~shuffled. + } + } + { + \cs_new_protected:Npn \seq_shuffle:N #1 + { \__kernel_msg_error:nn { kernel } { fp-no-random } } + \cs_new_eq:NN \seq_gshuffle:N \seq_shuffle:N + } +% \end{macrocode} +% \end{variable} +% \end{macro} +% % \subsection{Additions to \pkg{l3skip}} % % \begin{macrocode} @@ -2329,17 +2531,10 @@ % \end{macrocode} % % \begin{macro}[EXP, pTF]{\sys_if_rand_exist:} -% Currently, randomness exists under \pdfTeX{} and \LuaTeX{}. +% Currently, randomness exists under \pdfTeX{}, \LuaTeX{}, \pTeX{} and \upTeX{}. % \begin{macrocode} -\cs_if_exist:NTF \pdftex_uniformdeviate:D - { - \prg_new_conditional:Npnn \sys_if_rand_exist: { p , T , F , TF } - { \prg_return_true: } - } - { - \prg_new_conditional:Npnn \sys_if_rand_exist: { p , T , F , TF } - { \prg_return_false: } - } +\@@_const:nn { sys_if_rand_exist } + { \cs_if_exist_p:N \pdftex_uniformdeviate:D } % \end{macrocode} % \end{macro} % @@ -2356,7 +2551,7 @@ % The primitive always assigns the seed globally. % \begin{macrocode} \cs_new_protected:Npn \sys_gset_rand_seed:n #1 - { \pdftex_setrandomseed:D \__int_eval:n {#1} } + { \pdftex_setrandomseed:D \int_eval:n {#1} \exp_stop_f: } % \end{macrocode} % \end{macro} % @@ -2368,9 +2563,7 @@ \sys_if_engine_luatex:TF { \luatex_directlua:D - { - tex.sprint((status.shell_escape~or~os.execute()) .. " ") - } + { tex.sprint(status.shell_escape~or~os.execute()) } } { \pdftex_shellescape:D @@ -2379,52 +2572,18 @@ % \end{macrocode} % \end{variable} % -% \begin{macro}[EXP, pTF]{\sys_if_shell:} -% Performs a check for whether shell escape is enabled. This -% returns true if either of restricted or unrestricted shell escape -% is enabled. -% \begin{macrocode} -\prg_new_conditional:Nnn \sys_if_shell: { p , T , F , TF } - { - \if_int_compare:w \c_sys_shell_escape_int = 0 ~ - \prg_return_false: - \else: - \prg_return_true: - \fi: - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[EXP, pTF]{\sys_if_shell_unrestricted:} -% Performs a check for whether \emph{unrestricted} shell escape is -% enabled. -% \begin{macrocode} -\prg_new_conditional:Nnn \sys_if_shell_unrestricted: { p , T , F , TF } - { - \if_int_compare:w \c_sys_shell_escape_int = 1 ~ - \prg_return_true: - \else: - \prg_return_false: - \fi: - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[EXP, pTF]{\sys_if_shell_restricted:} -% Performs a check for whether \emph{restricted} shell escape is -% enabled. This returns false if unrestricted shell escape is -% enabled. Unrestricted shell escape is not considered a superset -% of restricted shell escape in this case. To find whether any -% shell escape is enabled use \cs{sys_if_shell:}. +% \begin{macro}[EXP, pTF]{\sys_if_shell:, \sys_if_shell_unrestricted:, \sys_if_shell_restricted:} +% Performs a check for whether shell escape is enabled. The first set +% of functions returns true if either of restricted or unrestricted +% shell escape is enabled, while the other two sets of functions +% return true in only one of these two cases. % \begin{macrocode} -\prg_new_conditional:Nnn \sys_if_shell_restricted: { p , T , F , TF } - { - \if_int_compare:w \c_sys_shell_escape_int = 2 ~ - \prg_return_true: - \else: - \prg_return_false: - \fi: - } +\@@_const:nn { sys_if_shell } + { \int_compare_p:nNn \c_sys_shell_escape_int > 0 } +\@@_const:nn { sys_if_shell_unrestricted } + { \int_compare_p:nNn \c_sys_shell_escape_int = 1 } +\@@_const:nn { sys_if_shell_restricted } + { \int_compare_p:nNn \c_sys_shell_escape_int = 2 } % \end{macrocode} % \end{macro} % @@ -2444,19 +2603,13 @@ { \cs_new_protected:Npn \sys_shell_now:n #1 { - \luatex_directlua:D - { - os.execute(" - \luatex_luaescapestring:D { \etex_detokenize:D {#1} } - ") - } + \lua_now_x:n + { os.execute(" \lua_escape_x:n { \tl_to_str:n {#1} } ") } } } { \cs_new_protected:Npn \sys_shell_now:n #1 - { - \iow_now:Nn \c_@@_shell_stream_int { #1 } - } + { \iow_now:Nn \c_@@_shell_stream_int {#1} } } \cs_generate_variant:Nn \sys_shell_now:n { x } % \end{macrocode} @@ -2469,19 +2622,13 @@ { \cs_new_protected:Npn \sys_shell_shipout:n #1 { - \luatex_latelua:D - { - os.execute(" - \luatex_luaescapestring:D { \etex_detokenize:D {#1} } - ") - } + \lua_shipout_x:n + { os.execute(" \lua_escape_x:n { \tl_to_str:n {#1} } ") } } } { \cs_new_protected:Npn \sys_shell_shipout:n #1 - { - \iow_shipout:Nn \c_@@_shell_stream_int { #1 } - } + { \iow_shipout:Nn \c_@@_shell_stream_int {#1} } } \cs_generate_variant:Nn \sys_shell_shipout:n { x } % \end{macrocode} @@ -2521,7 +2668,7 @@ % \begin{macrocode} \cs_new:Npn \tl_reverse_tokens:n #1 { - \etex_unexpanded:D \exp_after:wN + \__kernel_exp_not:w \exp_after:wN { \exp:w \@@_act:NNNnn @@ -2605,9 +2752,9 @@ \cs_generate_variant:Nn \tl_gset_from_file:Nnn { c } \cs_new_protected:Npn \@@_set_from_file:NNnn #1#2#3#4 { - \file_get_full_name:nN {#4} \l__file_full_name_str - \str_if_empty:NTF \l__file_full_name_str - { \__file_missing:n {#4} } + \file_get_full_name:nN {#4} \l_@@_file_name_str + \str_if_empty:NTF \l_@@_file_name_str + { \__kernel_file_missing:n {#4} } { \group_begin: \exp_args:No \etex_everyeof:D @@ -2615,7 +2762,7 @@ #3 \scan_stop: \exp_after:wN \@@_from_file_do:w \exp_after:wN \prg_do_nothing: - \tex_input:D \l__file_full_name_str \scan_stop: + \tex_input:D \l_@@_file_name_str \scan_stop: \exp_args:NNNo \group_end: #1 #2 \l_@@_internal_a_tl } @@ -2649,15 +2796,15 @@ \cs_generate_variant:Nn \tl_gset_from_file_x:Nnn { c } \cs_new_protected:Npn \@@_set_from_file_x:NNnn #1#2#3#4 { - \file_get_full_name:nN {#4} \l__file_full_name_str - \str_if_empty:NTF \l__file_full_name_str - { \__file_missing:n {#4} } + \file_get_full_name:nN {#4} \l_@@_file_name_str + \str_if_empty:NTF \l_@@_file_name_str + { \__kernel_file_missing:n {#4} } { \group_begin: \etex_everyeof:D { \exp_not:N } #3 \scan_stop: \tl_set:Nx \l_@@_internal_a_tl - { \tex_input:D \l__file_full_name_str \c_space_token } + { \tex_input:D \l_@@_file_name_str \c_space_token } \exp_args:NNNo \group_end: #1 #2 \l_@@_internal_a_tl } @@ -2665,6 +2812,11 @@ % \end{macrocode} % \end{macro} % \end{macro} +% \begin{variable}{\l_@@_file_name_str} +% \begin{macrocode} +\str_new:N \l_@@_file_name_str +% \end{macrocode} +% \end{variable} % % \subsubsection{Unicode case changing} % @@ -2673,6 +2825,119 @@ % appropriate data extracted from the Unicode documentation (either manually % or automatically). % +% First, some code which \enquote{belongs} in \pkg{l3tokens} but has to come +% here. +% \begin{macrocode} +%<@@=char> +% \end{macrocode} +% +% \begin{macro} +% { +% \char_lower_case:N, \char_upper_case:N, +% \char_mixed_case:N, \char_fold_case:N +% } +% \begin{macro}{\@@_change_case:nNN} +% \begin{macro}{\@@_change_case:nN} +% Expandable character generation is done using a two-part approach. +% First, see if the current character has a special mapping for the current +% transformation. If it does, insert that. Otherwise, use the \TeX{} data +% to look up the one-to-one mapping, and generate the appropriate character +% with the appropriate category code. Mixed case needs an extra step as it +% may be special-cased or might be a special upper case outcome. The internal +% when using non-Unicode engines has to be set up to only do anything +% with ASCII characters. +% \begin{macrocode} +\cs_new:Npn \char_lower_case:N #1 + { \@@_change_case:nNN { lower } \char_value_lccode:n #1 } +\cs_new:Npn \char_upper_case:N #1 + { \@@_change_case:nNN { upper } \char_value_uccode:n #1 } +\cs_new:Npn \char_mixed_case:N #1 + { + \tl_if_exist:cTF { c_@@_mixed_case_ \token_to_str:N #1 _tl } + { \tl_use:c { c_@@_mixed_case_ \token_to_str:N #1 _tl } } + { \char_upper_case:N #1 } + } +\cs_new:Npn \char_fold_case:N #1 + { \@@_change_case:nNN { fold } \char_value_lccode:n #1 } +\cs_new:Npn \@@_change_case:nNN #1#2#3 + { + \tl_if_exist:cTF { c_@@_ #1 _case_ \token_to_str:N #3 _tl } + { \tl_use:c { c_@@_ #1 _case_ \token_to_str:N #3 _tl } } + { \exp_args:Nf \@@_change_case:nN { #2 { `#3 } } #3 } + } +\cs_new:Npn \@@_change_case:nN #1#2 + { + \int_compare:nNnTF {#1} = 0 + {#2} + { \char_generate:nn {#1} { \char_value_catcode:n {#1} } } + } +\bool_lazy_or:nnF { \sys_if_engine_luatex_p: } { \sys_if_engine_xetex_p: } + { + \cs_set_eq:NN \@@_change_case:nN \use_ii:nn + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\char_codepoint_to_bytes:n} +% \begin{macro}[EXP]{\@@_codepoint_to_bytes_auxi:n} +% \begin{macro}[EXP]{\@@_codepoint_to_bytes_auxii:Nnn} +% \begin{macro}[EXP]{\@@_codepoint_to_bytes_auxiii:n} +% This code converts a codepoint into the correct UTF-8 representation. +% As there are a variable number of octets, the result starts with the +% numeral |1|--|4| to indicate the nature of the returned value. +% In terms of the algorithm itself, see +% \url{https://en.wikipedia.org/wiki/UTF-8} for the octet pattern. +% \begin{macrocode} +\cs_new:Npn \char_codepoint_to_bytes:n #1 + { + \exp_args:Nf \@@_codepoint_to_bytes_auxi:n + { \int_eval:n {#1} } + } +\cs_new:Npn \@@_codepoint_to_bytes_auxi:n #1 + { + \if_int_compare:w #1 > "80 \exp_stop_f: + \if_int_compare:w #1 < "800 \exp_stop_f: + 2 + \@@_codepoint_to_bytes_auxii:Nnn C {#1} { 64 } + \@@_codepoint_to_bytes_auxiii:n {#1} + \else: + \if_int_compare:w #1 < "10000 \exp_stop_f: + 3 + \@@_codepoint_to_bytes_auxii:Nnn E {#1} { 64 * 64 } + \@@_codepoint_to_bytes_auxiii:n + { \int_div_truncate:nn {#1} { 64 } } + \@@_codepoint_to_bytes_auxiii:n {#1} + \else: + 4 + \@@_codepoint_to_bytes_auxii:Nnn F + {#1} { 64 * 64 * 64 } + \@@_codepoint_to_bytes_auxiii:n + { \int_div_truncate:nn {#1} { 64 * 64 } } + \@@_codepoint_to_bytes_auxiii:n + { \int_div_truncate:nn {#1} { 64 } } + \@@_codepoint_to_bytes_auxiii:n {#1} + \fi: + \fi: + \else: + 1 {#1} + \fi: + } +\cs_new:Npn \@@_codepoint_to_bytes_auxii:Nnn #1#2#3 + { { \int_eval:n { "#10 + \int_div_truncate:nn {#2} {#3} } } } +\cs_new:Npn \@@_codepoint_to_bytes_auxiii:n #1 + { { \int_eval:n { \int_mod:nn {#1} { 64 } + 128 } } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macrocode} +%<@@=tl> +% \end{macrocode} +% % \begin{macro}[EXP, documented-as=\tl_if_head_eq_catcode:nNTF] % {\tl_if_head_eq_catcode:oNTF} % Extra variants. @@ -2731,16 +2996,6 @@ % \@@_change_case_char_mixed:Nnn % } % \begin{macro}[EXP]{\@@_change_case_char:nN} -% \begin{macro}[EXP] -% {\@@_change_case_char_auxi:nN, \@@_change_case_char_auxii:nN} -% \begin{macro}[EXP] -% { -% \@@_change_case_char_mixed:N, -% \@@_change_case_char_lower:N, -% \@@_change_case_char_upper:N -% } -% \begin{macro} -% {\@@_lookup_mixed:N, \@@_lookup_lower:N, \@@_lookup_upper:N} % \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nNN} % \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nNNN} % \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nNNNN} @@ -2769,7 +3024,7 @@ % \begin{macrocode} \cs_new:Npn \@@_change_case:nnn #1#2#3 { - \etex_unexpanded:D \exp_after:wN + \__kernel_exp_not:w \exp_after:wN { \exp:w \@@_change_case_aux:nnn {#1} {#2} {#3} @@ -3005,10 +3260,15 @@ % Unicode character, which is then used in a lookup. (As will become % obvious below, there is no intention here of covering all of Unicode.) % \begin{macrocode} -\cs_if_exist:NTF \utex_char:D +\bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } { \cs_new:Npn \@@_change_case_char:nN #1#2 - { \@@_change_case_char_auxi:nN {#1} #2 } + { + \@@_change_case_output:fwn + { \use:c { char_ #1 _case:N } #2 } + } } { \cs_new:Npn \@@_change_case_char:nN #1#2 @@ -3023,58 +3283,20 @@ { \@@_change_case_char_UTFviii:nNNNNN {#1} #2 } } } - { \@@_change_case_char_auxi:nN {#1} #2 } + { + \@@_change_case_output:fwn + { \use:c { char_ #1 _case:N } #2 } + } } } % \end{macrocode} % To allow for the special case of mixed case, we insert here a % action-dependent auxiliary. % \begin{macrocode} -\cs_new:Npn \@@_change_case_char_auxi:nN #1#2 - { \use:c { @@_change_case_char_ #1 :N } #2 } -\cs_new:Npn \@@_change_case_char_lower:N #1 - { - \@@_change_case_output:fwn - { - \cs_if_exist_use:cF { c__unicode_lower_ \token_to_str:N #1 _tl } - { \@@_change_case_char_auxii:nN { lower } #1 } - } - } -\cs_new:Npn \@@_change_case_char_upper:N #1 - { - \@@_change_case_output:fwn - { - \cs_if_exist_use:cF { c__unicode_upper_ \token_to_str:N #1 _tl } - { \@@_change_case_char_auxii:nN { upper } #1 } - } - } -\cs_new:Npn \@@_change_case_char_mixed:N #1 - { - \cs_if_exist:cTF { c__unicode_mixed_ \token_to_str:N #1 _tl } - { - \@@_change_case_output:fwn - { \tl_use:c { c__unicode_mixed_ \token_to_str:N #1 _tl } } - } - { \@@_change_case_char_upper:N #1 } - } -\cs_if_exist:NTF \utex_char:D - { - \cs_new:Npn \@@_change_case_char_auxii:nN #1#2 - { - \int_compare:nNnTF { \use:c { @@_lookup_ #1 :N } #2 } = { 0 } - { \exp_stop_f: #2 } - { - \char_generate:nn - { \use:c { @@_lookup_ #1 :N } #2 } - { \char_value_catcode:n { \use:c { @@_lookup_ #1 :N } #2 } } - } - } - \cs_new_protected:Npn \@@_lookup_lower:N #1 { \tex_lccode:D `#1 } - \cs_new_protected:Npn \@@_lookup_upper:N #1 { \tex_uccode:D `#1 } - \cs_new_eq:NN \@@_lookup_mixed:N \@@_lookup_upper:N - } +\bool_lazy_or:nnF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } { - \cs_new:Npn \@@_change_case_char_auxii:nN #1#2 { \exp_stop_f: #2 } \cs_new:Npn \@@_change_case_char_UTFviii:nNNN #1#2#3#4 { \@@_change_case_char_UTFviii:nnN {#1} {#2#4} #3 } \cs_new:Npn \@@_change_case_char_UTFviii:nNNNN #1#2#3#4#5 @@ -3083,10 +3305,10 @@ { \@@_change_case_char_UTFviii:nnN {#1} {#2#4#5#6} #3 } \cs_new:Npn \@@_change_case_char_UTFviii:nnN #1#2#3 { - \cs_if_exist:cTF { c__unicode_ #1 _ \tl_to_str:n {#2} _tl } + \cs_if_exist:cTF { c_@@_ #1 _case_ \tl_to_str:n {#2} _tl } { \@@_change_case_output:vwn - { c__unicode_ #1 _ \tl_to_str:n {#2} _tl } + { c_@@_ #1 _case_ \tl_to_str:n {#2} _tl } } { \@@_change_case_output:nwn {#2} } #3 @@ -3294,9 +3516,6 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}[EXP]{\@@_change_case_lower_sigma:Nnw} % \begin{macro}[EXP]{\@@_change_case_lower_sigma:w} @@ -3320,7 +3539,7 @@ { \tl_if_head_is_N_type:nTF {#1} { \@@_change_case_lower_sigma:Nw #1 \q_recursion_stop } - { \c__unicode_final_sigma_tl } + { \c_@@_final_sigma_tl } } \cs_new:Npn \@@_change_case_lower_sigma:Nw #1#2 \q_recursion_stop { @@ -3331,8 +3550,8 @@ } { \token_if_letter:NTF #1 - { \c__unicode_std_sigma_tl } - { \c__unicode_final_sigma_tl } + { \c_@@_std_sigma_tl } + { \c_@@_final_sigma_tl } } } % \end{macrocode} @@ -3356,7 +3575,9 @@ % either a dotless-I or a dotted-I. In the latter case the mapping is % easy, but in the former there is a second stage search. % \begin{macrocode} -\cs_if_exist:NTF \utex_char:D +\bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } { \cs_new:Npn \@@_change_case_lower_tr:Nnw #1#2 { @@ -3380,7 +3601,7 @@ { \tl_if_head_is_N_type:nTF {#2} { \@@_change_case_lower_tr_auxii:Nw #2 \q_recursion_stop } - { \@@_change_case_output:Vwn \c__unicode_dotless_i_tl } + { \@@_change_case_output:Vwn \c_@@_dotless_i_tl } #1 #2 \q_recursion_stop } \cs_new:Npn \@@_change_case_lower_tr_auxii:Nw #1#2 \q_recursion_stop @@ -3394,7 +3615,7 @@ \bool_lazy_or:nnTF { \token_if_cs_p:N #1 } { ! \int_compare_p:nNn { `#1 } = { "0307 } } - { \@@_change_case_output:Vwn \c__unicode_dotless_i_tl } + { \@@_change_case_output:Vwn \c_@@_dotless_i_tl } { \@@_change_case_output:nwn { i } \use_i:nn @@ -3412,7 +3633,7 @@ \cs_new:Npn \@@_change_case_lower_tr:Nnw #1#2 { \int_compare:nNnTF { `#1 } = { "0049 } - { \@@_change_case_output:Vwn \c__unicode_dotless_i_tl } + { \@@_change_case_output:Vwn \c_@@_dotless_i_tl } { \int_compare:nNnTF { `#1 } = { 196 } { \@@_change_case_lower_tr_auxi:Nw #1 {#2} } @@ -3438,7 +3659,7 @@ \cs_new:Npn \@@_change_case_upper_tr:Nnw #1#2 { \int_compare:nNnTF { `#1 } = { "0069 } - { \@@_change_case_output:Vwn \c__unicode_dotted_I_tl } + { \@@_change_case_output:Vwn \c_@@_dotted_I_tl } {#2} } % \end{macrocode} @@ -3476,7 +3697,7 @@ \cs_new:Npn \@@_change_case_lower_lt:Nnw #1 { \exp_args:Nf \@@_change_case_lower_lt:nNnw - { \str_case:nVF #1 \c__unicode_accents_lt_tl \exp_stop_f: } + { \str_case:nVF #1 \c_@@_accents_lt_tl \exp_stop_f: } #1 } \cs_new:Npn \@@_change_case_lower_lt:nNnw #1#2 @@ -3489,7 +3710,7 @@ { { "0049 } i { "004A } j - { "012E } \c__unicode_i_ogonek_tl + { "012E } \c_@@_i_ogonek_tl } \exp_stop_f: } @@ -3536,7 +3757,7 @@ { \int_compare_p:nNn { `#2 } = { "0303 } } } } - { \@@_change_case_output:Vwn \c__unicode_dot_above_tl } + { \@@_change_case_output:Vwn \c_@@_dot_above_tl } #1 #2#3 \q_recursion_stop } } @@ -3553,7 +3774,7 @@ { { "0069 } I { "006A } J - { "012F } \c__unicode_I_ogonek_tl + { "012F } \c_@@_I_ogonek_tl } \exp_stop_f: } @@ -3606,122 +3827,87 @@ \cs_new:cpn { @@_change_case_upper_de-alt:Nnw } #1#2 { \int_compare:nNnTF { `#1 } = { 223 } - { \@@_change_case_output:Vwn \c__unicode_upper_Eszett_tl } + { \@@_change_case_output:Vwn \c_@@_upper_Eszett_tl } {#2} } % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\__unicode_codepoint_to_UTFviii:n} -% \begin{macro}[EXP]{\__unicode_codepoint_to_UTFviii_auxi:n} -% \begin{macro}[EXP]{\__unicode_codepoint_to_UTFviii_auxii:Nnn} -% \begin{macro}[EXP]{\__unicode_codepoint_to_UTFviii_auxiii:n} -% This code converts a codepoint into the correct UTF-8 representation. -% As there are a variable number of octets, the result starts with the -% numeral |1|--|4| to indicate the nature of the returned value. Note that -% this code covers the full range even though at this stage it is not -% required here. Also note that longer-term this is likely to need a public -% interface and/or moving to \pkg{l3str} (see experimental string -% conversions). In terms of the algorithm itself, see -% \url{https://en.wikipedia.org/wiki/UTF-8} for the octet pattern. -% \begin{macrocode} -\cs_new:Npn \__unicode_codepoint_to_UTFviii:n #1 - { - \exp_args:Nf \__unicode_codepoint_to_UTFviii_auxi:n - { \int_eval:n {#1} } - } -\cs_new:Npn \__unicode_codepoint_to_UTFviii_auxi:n #1 - { - \if_int_compare:w #1 > "80 ~ - \if_int_compare:w #1 < "800 ~ - 2 - \__unicode_codepoint_to_UTFviii_auxii:Nnn C {#1} { 64 } - \__unicode_codepoint_to_UTFviii_auxiii:n {#1} - \else: - \if_int_compare:w #1 < "10000 ~ - 3 - \__unicode_codepoint_to_UTFviii_auxii:Nnn E {#1} { 64 * 64 } - \__unicode_codepoint_to_UTFviii_auxiii:n {#1} - \__unicode_codepoint_to_UTFviii_auxiii:n - { \int_div_truncate:nn {#1} { 64 } } - \else: - 4 - \__unicode_codepoint_to_UTFviii_auxii:Nnn F - {#1} { 64 * 64 * 64 } - \__unicode_codepoint_to_UTFviii_auxiii:n - { \int_div_truncate:nn {#1} { 64 * 64 } } - \__unicode_codepoint_to_UTFviii_auxiii:n - { \int_div_truncate:nn {#1} { 64 } } - \__unicode_codepoint_to_UTFviii_auxiii:n {#1} - - \fi: - \fi: - \else: - 1 {#1} - \fi: - } -\cs_new:Npn \__unicode_codepoint_to_UTFviii_auxii:Nnn #1#2#3 - { { \int_eval:n { "#10 + \int_div_truncate:nn {#2} {#3} } } } -\cs_new:Npn \__unicode_codepoint_to_UTFviii_auxiii:n #1 - { { \int_eval:n { \int_mod:nn {#1} { 64 } + 128 } } } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% % \begin{variable} % { -% \c__unicode_std_sigma_tl , -% \c__unicode_final_sigma_tl , -% \c__unicode_accents_lt_tl , -% \c__unicode_dot_above_tl , -% \c__unicode_upper_Eszett_tl +% \c_@@_std_sigma_tl , +% \c_@@_final_sigma_tl , +% \c_@@_accents_lt_tl , +% \c_@@_dot_above_tl , +% \c_@@_upper_Eszett_tl % } -% The above needs various special token lists containg pre-formed characters. +% The above needs various special token lists containing pre-formed characters. % This set are only available in Unicode engines, with no-op definitions % for $8$-bit use. % \begin{macrocode} -\cs_if_exist:NTF \utex_char:D - { - \tl_const:Nx \c__unicode_std_sigma_tl { \utex_char:D "03C3 ~ } - \tl_const:Nx \c__unicode_final_sigma_tl { \utex_char:D "03C2 ~ } - \tl_const:Nx \c__unicode_accents_lt_tl - { - \utex_char:D "00CC ~ - { \utex_char:D "0069 ~ \utex_char:D "0307 ~ \utex_char:D "0300 ~ } - \utex_char:D "00CD ~ - { \utex_char:D "0069 ~ \utex_char:D "0307 ~ \utex_char:D "0301 ~ } - \utex_char:D "0128 ~ - { \utex_char:D "0069 ~ \utex_char:D "0307 ~ \utex_char:D "0303 ~ } - } - \tl_const:Nx \c__unicode_dot_above_tl { \utex_char:D "0307 ~ } - \tl_const:Nx \c__unicode_upper_Eszett_tl { \utex_char:D "1E9E ~ } +\bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \group_begin: + \cs_set:Npn \@@_tmp:n #1 + { \char_generate:nn {#1} { \char_value_catcode:n {#1} } } + \tl_const:Nx \c_@@_std_sigma_tl { \@@_tmp:n { "03C3 } } + \tl_const:Nx \c_@@_final_sigma_tl { \@@_tmp:n { "03C2 } } + \tl_const:Nx \c_@@_accents_lt_tl + { + \@@_tmp:n { "00CC } + { + \@@_tmp:n { "0069 } + \@@_tmp:n { "0307 } + \@@_tmp:n { "0300 } + } + \@@_tmp:n { "00CD } + { + \@@_tmp:n { "0069 } + \@@_tmp:n { "0307 } + \@@_tmp:n { "0301 } + } + \@@_tmp:n { "0128 } + { + \@@_tmp:n { "0069 } + \@@_tmp:n { "0307 } + \@@_tmp:n { "0303 } + } + } + \tl_const:Nx \c_@@_dot_above_tl { \@@_tmp:n { "0307 } } + \tl_const:Nx \c_@@_upper_Eszett_tl { \@@_tmp:n { "1E9E } } + \group_end: } { - \tl_const:Nn \c__unicode_std_sigma_tl { } - \tl_const:Nn \c__unicode_final_sigma_tl { } - \tl_const:Nn \c__unicode_accents_lt_tl { } - \tl_const:Nn \c__unicode_dot_above_tl { } - \tl_const:Nn \c__unicode_upper_Eszett_tl { } + \tl_const:Nn \c_@@_std_sigma_tl { } + \tl_const:Nn \c_@@_final_sigma_tl { } + \tl_const:Nn \c_@@_accents_lt_tl { } + \tl_const:Nn \c_@@_dot_above_tl { } + \tl_const:Nn \c_@@_upper_Eszett_tl { } } % \end{macrocode} % \end{variable} % \begin{variable} % { -% \c__unicode_dotless_i_tl , -% \c__unicode_dotted_I_tl , -% \c__unicode_i_ogonek_tl , -% \c__unicode_I_ogonek_tl , +% \c_@@_dotless_i_tl , +% \c_@@_dotted_I_tl , +% \c_@@_i_ogonek_tl , +% \c_@@_I_ogonek_tl , % } % For cases where there is an $8$-bit option in the |T1| font set up, % a variant is provided in both cases. % \begin{macrocode} \group_begin: - \cs_if_exist:NTF \utex_char:D + \bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } { \cs_set_protected:Npn \@@_tmp:w #1#2 - { \tl_const:Nx #1 { \utex_char:D "#2 ~ } } + { + \tl_const:Nx #1 + { \char_generate:nn {"#2} { \char_value_catcode:n {"#2} } } + } } { \cs_set_protected:Npn \@@_tmp:w #1#2 @@ -3732,21 +3918,21 @@ \tl_const:Nx #1 { \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \__char_generate:nn {##2} { 13 } + \exp_not:N \char_generate:nn {##2} { 13 } \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \__char_generate:nn {##3} { 13 } + \exp_not:N \char_generate:nn {##3} { 13 } } } \tl_set:Nx \l_@@_internal_a_tl - { \__unicode_codepoint_to_UTFviii:n {"#2} } + { \char_codepoint_to_bytes:n {"#2} } \exp_after:wN \@@_tmp:w \l_@@_internal_a_tl \group_end: } } - \@@_tmp:w \c__unicode_dotless_i_tl { 0131 } - \@@_tmp:w \c__unicode_dotted_I_tl { 0130 } - \@@_tmp:w \c__unicode_i_ogonek_tl { 012F } - \@@_tmp:w \c__unicode_I_ogonek_tl { 012E } + \@@_tmp:w \c_@@_dotless_i_tl { 0131 } + \@@_tmp:w \c_@@_dotted_I_tl { 0130 } + \@@_tmp:w \c_@@_i_ogonek_tl { 012F } + \@@_tmp:w \c_@@_I_ogonek_tl { 012E } \group_end: % \end{macrocode} % \end{variable} @@ -3767,8 +3953,8 @@ \quark_if_recursion_tail_stop:n {#1} \tl_set:Nx \l_@@_internal_a_tl { - \__unicode_codepoint_to_UTFviii:n {"#1} - \__unicode_codepoint_to_UTFviii:n {"#2} + \char_codepoint_to_bytes:n {"#1} + \char_codepoint_to_bytes:n {"#2} } \exp_after:wN \@@_tmp:w \l_@@_internal_a_tl \@@_loop:nn @@ -3777,29 +3963,29 @@ { \tl_const:cx { - c__unicode_lower_ + c_@@_lower_case_ \char_generate:nn {#2} { 12 } \char_generate:nn {#3} { 12 } _tl } { \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \__char_generate:nn {#5} { 13 } + \exp_not:N \char_generate:nn {#5} { 13 } \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \__char_generate:nn {#6} { 13 } + \exp_not:N \char_generate:nn {#6} { 13 } } \tl_const:cx { - c__unicode_upper_ + c_@@_upper_case_ \char_generate:nn {#5} { 12 } \char_generate:nn {#6} { 12 } _tl } { \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \__char_generate:nn {#2} { 13 } + \exp_not:N \char_generate:nn {#2} { 13 } \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \__char_generate:nn {#3} { 13 } + \exp_not:N \char_generate:nn {#3} { 13 } } } \@@_loop:nn @@ -3911,7 +4097,7 @@ { \tl_const:cx { - c__unicode_ #3 _ + c_@@_ #3 _case_ \char_generate:nn {##2} { 12 } \char_generate:nn {##3} { 12 } _tl @@ -3919,7 +4105,7 @@ {#2} } \tl_set:Nx \l_@@_internal_a_tl - { \__unicode_codepoint_to_UTFviii:n { "#1 } } + { \char_codepoint_to_bytes:n { "#1 } } \exp_after:wN \@@_tmp:w \l_@@_internal_a_tl \group_end: } @@ -3936,8 +4122,10 @@ \cs_set_protected:Npn \@@_change_case_setup:NN #1#2 { \quark_if_recursion_tail_stop:N #1 - \tl_const:cn { c_@@_change_case_lower_ \token_to_str:N #1 _tl } { #2 } - \tl_const:cn { c_@@_change_case_upper_ \token_to_str:N #2 _tl } { #1 } + \tl_const:cn { c_@@_change_case_lower_ \token_to_str:N #1 _tl } + { #2 } + \tl_const:cn { c_@@_change_case_upper_ \token_to_str:N #2 _tl } + { #1 } \@@_change_case_setup:NN } \@@_change_case_setup:NN @@ -4058,6 +4246,230 @@ % \end{macrocode} % \end{variable} % +% \subsubsection{Building a token list} +% +% Between \cs{tl_build_begin:N} \meta{tl~var} and \cs{tl_build_end:N} +% \meta{tl~var}, the \meta{tl~var} has the structure +% \begin{quote} +% \cs{exp_end:} \ldots{} \cs{exp_end:} \cs{@@_build_last:NNn} +% \meta{assignment} \meta{next~tl} \Arg{left} \meta{right} +% \end{quote} +% where \meta{right} is not braced. The \enquote{data} it represents is +% \meta{left} followed by the \enquote{data} of \meta{next~tl} followed +% by \meta{right}. The \meta{next~tl} is a token list variable whose +% name is that of \meta{tl~var} followed by~|'|. There are between $0$ +% and $4$ \cs{exp_end:} to keep track of when \meta{left} and +% \meta{right} should be put into the \meta{next~tl}. The +% \meta{assignment} is \cs{cs_set_nopar:Npx} if the variable is local, +% and \cs{cs_gset_nopar:Npx} if it is global. +% +% \begin{macro}{\tl_build_begin:N, \tl_build_gbegin:N} +% \begin{macro}{\@@_build_begin:NN, \@@_build_begin:NNN} +% First construct the \meta{next~tl}: using a prime here conflicts +% with the usual \pkg{expl3} convention but we need a name that can be +% derived from |#1| without any external data such as a counter. +% Empty that \meta{next~tl} and setup the structure. The local and +% global versions only differ by a single function +% \cs[no-index]{cs_(g)set_nopar:Npx} used for all assignments: this is +% important because only that function is stored in the \meta{tl~var} +% and \meta{next~tl} for subsequent assignments. In principle +% \cs{@@_build_begin:NNN} could use \cs[no-index]{tl_(g)clear_new:N} +% to empty |#1| and make sure it is defined, but logging the +% definition does not seem useful so we just do |#3| |#1| |{}| to +% clear it locally or globally as appropriate. +% \begin{macrocode} +\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } +\cs_new_protected:Npn \tl_build_begin:N #1 + { \@@_build_begin:NN \cs_set_nopar:Npx #1 } +\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } +\cs_new_protected:Npn \tl_build_gbegin:N #1 + { \@@_build_begin:NN \cs_gset_nopar:Npx #1 } +\cs_new_protected:Npn \@@_build_begin:NN #1#2 + { \exp_args:Nc \@@_build_begin:NNN { \cs_to_str:N #2 ' } #2 #1 } +\cs_new_protected:Npn \@@_build_begin:NNN #1#2#3 + { + #3 #1 { } + #3 #2 + { + \exp_not:n { \exp_end: \exp_end: \exp_end: \exp_end: } + \exp_not:n { \@@_build_last:NNn #3 #1 { } } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_build_clear:N, \tl_build_gclear:N} +% The |begin| and |gbegin| functions already clear enough to make the +% token list variable effectively empty. Eventually the |begin| and +% |gbegin| functions should check that |#1'| is empty or undefined, +% while the |clear| and |gclear| functions ought to empty |#1'|, +% |#1''| and so on, similar to \cs{tl_build_end:N}. This only affects +% memory usage. +% \begin{macrocode} +\cs_new_eq:NN \tl_build_clear:N \tl_build_begin:N +\cs_new_eq:NN \tl_build_gclear:N \tl_build_gbegin:N +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \tl_build_put_right:Nn, \tl_build_put_right:Nx, +% \tl_build_gput_right:Nn, \tl_build_gput_right:Nx, +% \@@_build_last:NNn, \@@_build_put:nn, \@@_build_put:nw +% } +% Similar to \cs{tl_put_right:Nn}, but apply \cs{exp:w} to |#1|. Most +% of the time this just removes one \cs{exp_end:}. When there are +% none left, \cs{@@_build_last:NNn} is expanded instead. It resets +% the definition of the \meta{tl~var} by ending the \cs{exp_not:n} and +% the definition early. Then it makes sure the \meta{next~tl} (its +% argument |#1|) is set-up and starts a new definition. Then +% \cs{@@_build_put:nn} and \cs{@@_build_put:nw} place the \meta{left} +% part of the original \meta{tl~var} as appropriate for the definition +% of the \meta{next~tl} (the \meta{right} part is left in the right +% place without ever becoming a macro argument). We use +% \cs{exp_after:wN} rather than some \cs{exp_args:No} to avoid reading +% arguments that are likely very long token lists. We use +% \cs[no-index]{cs_(g)set_nopar:Npx} rather than +% \cs[no-index]{tl_(g)set:Nx} partly for the same reason and partly +% because the assignments are interrupted by brace tricks, which +% implies that the assignment does not simply set the token list to an +% |x|-expansion of the second argument. +% \begin{macrocode} +\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } +\cs_new_protected:Npn \tl_build_put_right:Nn #1#2 + { + \cs_set_nopar:Npx #1 + { \exp_after:wN \exp_not:n \exp_after:wN { \exp:w #1 #2 } } + } +\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } +\cs_new_protected:Npn \tl_build_put_right:Nx #1#2 + { + \cs_set_nopar:Npx #1 + { \exp_after:wN \exp_not:n \exp_after:wN { \exp:w #1 } #2 } + } +\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } +\cs_new_protected:Npn \tl_build_gput_right:Nn #1#2 + { + \cs_gset_nopar:Npx #1 + { \exp_after:wN \exp_not:n \exp_after:wN { \exp:w #1 #2 } } + } +\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } +\cs_new_protected:Npn \tl_build_gput_right:Nx #1#2 + { + \cs_gset_nopar:Npx #1 + { \exp_after:wN \exp_not:n \exp_after:wN { \exp:w #1 } #2 } + } +\cs_new_protected:Npn \@@_build_last:NNn #1#2 + { + \if_false: { { \fi: + \exp_end: \exp_end: \exp_end: \exp_end: \exp_end: + \@@_build_last:NNn #1 #2 { } + } + } + \if_meaning:w \c_empty_tl #2 + \@@_build_begin:NN #1 #2 + \fi: + #1 #2 + { + \exp_after:wN \exp_not:n \exp_after:wN + { + \exp:w \if_false: } } \fi: + \exp_after:wN \@@_build_put:nn \exp_after:wN {#2} + } +\cs_new_protected:Npn \@@_build_put:nn #1#2 { \@@_build_put:nw {#2} #1 } +\cs_new_protected:Npn \@@_build_put:nw #1#2 \@@_build_last:NNn #3#4#5 + { #2 \@@_build_last:NNn #3 #4 { #1 #5 } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \tl_build_put_left:Nn, \tl_build_put_left:Nx, +% \tl_build_gput_left:Nn, \tl_build_gput_left:Nx, \@@_build_put_left:NNn +% } +% See \cs{tl_build_put_right:Nn} for all the machinery. We could +% easily provide \cs[no-index]{tl_build_put_left_right:Nnn}, by just +% add the \meta{right} material after the \Arg{left} in the +% |x|-expanding assignment. +% \begin{macrocode} +\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } +\cs_new_protected:Npn \tl_build_put_left:Nn #1 + { \@@_build_put_left:NNn \cs_set_nopar:Npx #1 } +\cs_generate_variant:Nn \tl_build_put_left:Nn { Nx } +\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } +\cs_new_protected:Npn \tl_build_gput_left:Nn #1 + { \@@_build_put_left:NNn \cs_gset_nopar:Npx #1 } +\cs_generate_variant:Nn \tl_build_gput_left:Nn { Nx } +\cs_new_protected:Npn \@@_build_put_left:NNn #1#2#3 + { + #1 #2 + { + \exp_after:wN \exp_not:n \exp_after:wN + { + \exp:w \exp_after:wN \@@_build_put:nn + \exp_after:wN {#2} {#3} + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tl_build_get:NN} +% \begin{macro}{\@@_build_get:NNN, \@@_build_get:w, \@@_build_get_end:w} +% The idea is to expand the \meta{tl~var} then the \meta{next~tl} and +% so on, all within an |x|-expanding assignment, and wrap as +% appropriate in \cs{exp_not:n}. The various \meta{left} parts are +% left in the assignment as we go, which enables us to expand the +% \meta{next~tl} at the right place. The various \meta{right} parts +% are eventually picked up in one last \cs{exp_not:n}, with a brace +% trick to wrap all the \meta{right} parts together. +% \begin{macrocode} +\cs_new_protected:Npn \tl_build_get:NN + { \@@_build_get:NNN \tl_set:Nx } +\cs_new_protected:Npn \@@_build_get:NNN #1#2#3 + { #1 #3 { \if_false: { \fi: \exp_after:wN \@@_build_get:w #2 } } } +\cs_new:Npn \@@_build_get:w #1 \@@_build_last:NNn #2#3#4 + { + \exp_not:n {#4} + \if_meaning:w \c_empty_tl #3 + \exp_after:wN \@@_build_get_end:w + \fi: + \exp_after:wN \@@_build_get:w #3 + } +\cs_new:Npn \@@_build_get_end:w #1#2#3 + { \exp_after:wN \exp_not:n \exp_after:wN { \if_false: } \fi: } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_build_end:N, \tl_build_gend:N, \@@_build_end_loop:NN} +% Get the data then clear the \meta{next~tl} recursively until finding +% an empty one. It is perhaps wasteful to repeatedly use +% \cs{cs_to_sr:N}. The local/global scope is checked by +% \cs{tl_set:Nx} or \cs{tl_gset:Nx}. +% \begin{macrocode} +\cs_new_protected:Npn \tl_build_end:N #1 + { + \@@_build_get:NNN \tl_set:Nx #1 #1 + \exp_args:Nc \@@_build_end_loop:NN { \cs_to_str:N #1 ' } \tl_clear:N + } +\cs_new_protected:Npn \tl_build_gend:N #1 + { + \@@_build_get:NNN \tl_gset:Nx #1 #1 + \exp_args:Nc \@@_build_end_loop:NN { \cs_to_str:N #1 ' } \tl_gclear:N + } +\cs_new_protected:Npn \@@_build_end_loop:NN #1#2 + { + \if_meaning:w \c_empty_tl #1 + \exp_after:wN \use_none:nnnnnn + \fi: + #2 #1 + \exp_args:Nc \@@_build_end_loop:NN { \cs_to_str:N #1 ' } #2 + } +% \end{macrocode} +% \end{macro} +% % \subsubsection{Other additions to \pkg{l3tl}} % % \begin{macro}{\tl_rand_item:n, \tl_rand_item:N, \tl_rand_item:c} @@ -4121,9 +4533,11 @@ \cs_new:Npn \tl_range_braced:Nnn { \exp_args:No \tl_range_braced:nnn } \cs_generate_variant:Nn \tl_range_braced:Nnn { c } \cs_new:Npn \tl_range_braced:nnn { \@@_range:Nnnn \@@_range_braced:w } -\cs_new:Npn \tl_range_unbraced:Nnn { \exp_args:No \tl_range_unbraced:nnn } +\cs_new:Npn \tl_range_unbraced:Nnn + { \exp_args:No \tl_range_unbraced:nnn } \cs_generate_variant:Nn \tl_range_unbraced:Nnn { c } -\cs_new:Npn \tl_range_unbraced:nnn { \@@_range:Nnnn \@@_range_unbraced:w } +\cs_new:Npn \tl_range_unbraced:nnn + { \@@_range:Nnnn \@@_range_unbraced:w } \cs_new:Npn \@@_range:Nnnn #1#2#3#4 { \tl_head:f @@ -4150,14 +4564,14 @@ \exp_after:wN { \exp_after:wN } \fi: \exp_after:wN #3 - \__int_value:w \__int_eval:w #2 - #1 \exp_after:wN ; + \int_value:w \int_eval:n { #2 - #1 } \exp_after:wN ; \exp_after:wN { \exp:w \@@_range_skip:w #1 ; { } #4 } } \cs_new:Npn \@@_range_skip:w #1 ; #2 { \if_int_compare:w #1 > 0 \exp_stop_f: \exp_after:wN \@@_range_skip:w - \__int_value:w \__int_eval:w #1 - 1 \exp_after:wN ; + \int_value:w \int_eval:n { #1 - 1 } \exp_after:wN ; \else: \exp_after:wN \exp_end: \fi: @@ -4170,7 +4584,7 @@ { \if_int_compare:w #1 > 1 \exp_stop_f: \exp_after:wN \@@_range_collect_braced:w - \__int_value:w \__int_eval:w #1 - 1 \exp_after:wN ; + \int_value:w \int_eval:n { #1 - 1 } \exp_after:wN ; \fi: { #2 {#3} } } @@ -4178,7 +4592,7 @@ { \if_int_compare:w #1 > 1 \exp_stop_f: \exp_after:wN \@@_range_collect_unbraced:w - \__int_value:w \__int_eval:w #1 - 1 \exp_after:wN ; + \int_value:w \int_eval:n { #1 - 1 } \exp_after:wN ; \fi: { #2 #3 } } @@ -4258,7 +4672,7 @@ % \subsection{Additions to \pkg{l3token}} % % \begin{variable}{\c_catcode_active_space_tl} -% While \cs{__char_generate:nn} can produce active characters in some +% While \cs{char_generate:nn} can produce active characters in some % engines it cannot in general. It would be possible to simply change % the catcode of space but then the code would need to avoid all % spaces, making it quite unreadable. Instead we use the primitive @@ -4335,7 +4749,10 @@ { \tl_if_empty:nTF {#2} { \@@_true:w } { \@@_false:w } } } \cs_new_protected:Npn \peek_N_type:TF - { \@@_token_generic:NNTF \@@_execute_branches_N_type: \scan_stop: } + { + \@@_token_generic:NNTF + \@@_execute_branches_N_type: \scan_stop: + } \cs_new_protected:Npn \peek_N_type:T { \@@_token_generic:NNT \@@_execute_branches_N_type: \scan_stop: } \cs_new_protected:Npn \peek_N_type:F diff --git a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx index a11c54cb818..8825e0c6dab 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx @@ -2,7 +2,7 @@ % %% File: l3clist.dtx Copyright (C) 2004-2011 Frank Mittelbach, %% The LaTeX3 project -%% (C) 2012-2017 The LaTeX3 Project +%% (C) 2012-2018 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,34 +43,58 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % % \begin{documentation} % % Comma lists contain ordered data where items can be added to the left -% or right end of the list. The resulting ordered list can then -% be mapped over using \cs{clist_map_function:NN}. Several items can -% be added at once, and spaces are removed from both sides of each item -% on input. Hence, +% or right end of the list. The features of this data type largely +% overlap with those of the sequence data type, for instance applying a +% function to every item, removing duplicate items, extracting a given +% item, using the comma list with specified separators, and so on. +% +% Several items can be added at once. To ease input of comma lists from +% data provided by a user outside an \cs{ExplSyntaxOn} \ldots{} +% \cs{ExplSyntaxOff} block, spaces are removed from both sides of each +% comma-delimited argument upon input. Blank arguments are ignored, to +% allow for trailing commas or repeated commas (which may otherwise +% arise when concatenating comma lists \enquote{by hand}). In addition, +% a set of braces is removed if the result of space-trimming is braced: +% this allows the storage of any item in a comma list. For instance, % \begin{verbatim} % \clist_new:N \l_my_clist -% \clist_put_left:Nn \l_my_clist { ~ a ~ , ~ {b} ~ } -% \clist_put_right:Nn \l_my_clist { ~ { c ~ } , d } +% \clist_put_left:Nn \l_my_clist { ~a~ , ~{b}~ , c~\d } +% \clist_put_right:Nn \l_my_clist { ~{e~} , , {{f}} , } % \end{verbatim} -% results in |\l_my_clist| containing |a,{b},{c~},d|. -% Comma lists cannot contain empty items, thus +% results in |\l_my_clist| containing |a,b,c~\d,{e~},{{f}}| namely the +% five items |a|, |b|, |c~\d|, |e~| and~|{f}|. Comma lists normally do +% not contain empty items so the following gives an empty comma list: % \begin{verbatim} % \clist_clear_new:N \l_my_clist % \clist_put_right:Nn \l_my_clist { , ~ , , } % \clist_if_empty:NTF \l_my_clist { true } { false } % \end{verbatim} -% leaves \texttt{true} in the input stream. To include an item -% which contains a comma, or starts or ends with a space, -% surround it with braces. The sequence data type should be preferred -% to comma lists if items are to contain |{|, |}|, or |#| (assuming the -% usual \TeX{} category codes apply). +% and it leaves \texttt{true} in the input stream. To include an +% \enquote{unsafe} item (empty, or one that contains a comma, or starts +% or ends with a space, or is a single brace group), surround it with +% braces. +% +% Comma lists are particularly useful when implementing user interfaces, +% or when interfacing with \LaTeXe{} or other code that expects or +% provides comma list data. Almost all operations on comma lists are +% noticeably slower than those on sequences so converting the data to +% sequences using \cs{seq_set_from_clist:Nn} (see \pkg{l3seq}) may be +% advisable if speed is important. The exception is that +% \cs{clist_if_in:NnTF} and \cs{clist_remove_duplicates:N} may be faster +% than their sequence analogues for large lists. However, these +% functions work slowly for \enquote{unsafe} items that must be braced, +% and may produce errors when their argument contains |{|, |}| or |#| +% (assuming the usual \TeX{} category codes apply). In addition, comma +% lists cannot store quarks \cs{q_mark} or \cs{q_stop}. The sequence +% data type should thus certainly be preferred to comma lists to store +% such items. % % \section{Creating and initialising comma lists} % @@ -189,7 +213,12 @@ % \end{syntax} % Sets \meta{comma list} to contain the \meta{items}, % removing any previous content from the variable. -% Spaces are removed from both sides of each item. +% Blank items are omitted, spaces are removed from both sides of each +% item, then a set of braces is removed if the resulting space-trimmed +% item is braced. +% To store some \meta{tokens} as a single \meta{item} even if the +% \meta{tokens} contain commas or spaces, add a set of braces: +% \cs{clist_set:Nn} \meta{comma list} |{| \Arg{tokens} |}|. % \end{function} % % \begin{function}[updated = 2011-09-05] @@ -207,7 +236,12 @@ % \cs{clist_put_left:Nn} \meta{comma list} |{|\meta{item_1},\ldots{},\meta{item_n}|}| % \end{syntax} % Appends the \meta{items} to the left of the \meta{comma list}. -% Spaces are removed from both sides of each item. +% Blank items are omitted, spaces are removed from both sides of each +% item, then a set of braces is removed if the resulting space-trimmed +% item is braced. +% To append some \meta{tokens} as a single \meta{item} even if the +% \meta{tokens} contain commas or spaces, add a set of braces: +% \cs{clist_put_left:Nn} \meta{comma list} |{| \Arg{tokens} |}|. % \end{function} % % \begin{function}[updated = 2011-09-05] @@ -225,7 +259,12 @@ % \cs{clist_put_right:Nn} \meta{comma list} |{|\meta{item_1},\ldots{},\meta{item_n}|}| % \end{syntax} % Appends the \meta{items} to the right of the \meta{comma list}. -% Spaces are removed from both sides of each item. +% Blank items are omitted, spaces are removed from both sides of each +% item, then a set of braces is removed if the resulting space-trimmed +% item is braced. +% To append some \meta{tokens} as a single \meta{item} even if the +% \meta{tokens} contain commas or spaces, add a set of braces: +% \cs{clist_put_right:Nn} \meta{comma list} |{| \Arg{tokens} |}|. % \end{function} % % \section{Modifying comma lists} @@ -250,7 +289,7 @@ % This function iterates through every item in the \meta{comma list} and % does a comparison with the \meta{items} already checked. It is therefore % relatively slow with large comma lists. -% Furthermore, it does not work if any of the items in the +% Furthermore, it may fail if any of the items in the % \meta{comma list} contains |{|, |}|, or |#| % (assuming the usual \TeX{} category codes apply). % \end{texnote} @@ -268,7 +307,7 @@ % The \meta{item} comparison takes place on a token basis, as for % \cs{tl_if_eq:nn(TF)}. % \begin{texnote} -% The \meta{item} may not contain |{|, |}|, or |#| +% The function may fail if the \meta{item} contains |{|, |}|, or |#| % (assuming the usual \TeX{} category codes apply). % \end{texnote} % \end{function} @@ -289,7 +328,9 @@ % \cs{clist_reverse:n} \Arg{comma list} % \end{syntax} % Leaves the items in the \meta{comma list} in the input stream in -% reverse order. Braces and spaces are preserved by this process. +% reverse order. Contrarily to other what is done for other +% \texttt{n}-type \meta{comma list} arguments, braces and spaces are +% preserved by this process. % \begin{texnote} % The result is returned within \tn{unexpanded}, which means that the % comma list does not expand further when appearing in an @@ -341,17 +382,15 @@ % \cs{clist_if_in:NnTF} \meta{comma list} \Arg{item} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{item} is present in the \meta{comma list}. -% In the case of an \texttt{n}-type \meta{comma list}, -% spaces are stripped from each item, but braces are not removed. -% Hence, +% In the case of an \texttt{n}-type \meta{comma list}, the usual rules +% of space trimming and brace stripping apply. Hence, % \begin{verbatim} % \clist_if_in:nnTF { a , {b}~ , {b} , c } { b } {true} {false} % \end{verbatim} -% yields \texttt{false}. +% yields \texttt{true}. % \begin{texnote} -% The \meta{item} may not contain |{|, |}|, or |#| -% (assuming the usual \TeX{} category codes apply), -% and should not contain |,| nor start or end with a space. +% The function may fail if the \meta{item} contains |{|, |}|, or |#| +% (assuming the usual \TeX{} category codes apply). % \end{texnote} % \end{function} % @@ -364,7 +403,7 @@ % spaces are trimmed around each item. % If the result of trimming spaces is empty, the item is ignored. % Otherwise, if the item is surrounded by braces, one set is removed, -% and the result is passed to the mapped function. Thus, if your +% and the result is passed to the mapped function. Thus, if the % comma list that is being mapped is \verb*|{a , {{b} }, ,{}, {c},}| % then the arguments passed to the mapped function are % `\verb*|a|', `\verb*|{b} |', an empty argument, and `\verb*|c|'. @@ -413,7 +452,7 @@ % \begin{syntax} % \cs{clist_map_break:} % \end{syntax} -% Used to terminate a |\clist_map_...| function before all +% Used to terminate a \cs[no-index]{clist_map_\ldots{}} function before all % entries in the \meta{comma list} have been processed. This % normally takes place within a conditional statement, for example % \begin{verbatim} @@ -426,7 +465,7 @@ % } % } % \end{verbatim} -% Use outside of a |\clist_map_...| scenario leads to low +% Use outside of a \cs[no-index]{clist_map_\ldots{}} scenario leads to low % level \TeX{} errors. % \begin{texnote} % When the mapping is broken, additional tokens may be inserted @@ -440,7 +479,7 @@ % \begin{syntax} % \cs{clist_map_break:n} \Arg{code} % \end{syntax} -% Used to terminate a |\clist_map_...| function before all +% Used to terminate a \cs[no-index]{clist_map_\ldots{}} function before all % entries in the \meta{comma list} have been processed, inserting % the \meta{code} after the mapping has ended. This % normally takes place within a conditional statement, for example @@ -454,7 +493,7 @@ % } % } % \end{verbatim} -% Use outside of a |\clist_map_...| scenario leads to low +% Use outside of a \cs[no-index]{clist_map_\ldots{}} scenario leads to low % level \TeX{} errors. % \begin{texnote} % When the mapping is broken, additional tokens may be inserted @@ -472,7 +511,7 @@ % Leaves the number of items in the \meta{comma list} in the input % stream as an \meta{integer denotation}. The total number of items % in a \meta{comma list} includes those which are duplicates, -% \emph{i.e.}~every item in a \meta{comma list} is unique. +% \emph{i.e.}~every item in a \meta{comma list} is counted. % \end{function} % % \section{Using the content of comma lists directly} @@ -624,7 +663,8 @@ % \cs{clist_push:Nn} \meta{comma list} \Arg{items} % \end{syntax} % Adds the \Arg{items} to the top of the \meta{comma list}. -% Spaces are removed from both sides of each item. +% Spaces are removed from both sides of each item as for any +% \texttt{n}-type comma list. % \end{function} % % \section{Using a single item} @@ -740,6 +780,110 @@ % \end{macrocode} % \end{macro} % +% \subsection{Removing spaces around items} +% +% \begin{macro}{\@@_trim_next:w} +% Called as \cs{exp:w} \cs{@@_trim_next:w} \cs{prg_do_nothing:} +% \meta{comma list} \ldots{} it expands to \Arg{trimmed item} where +% the \meta{trimmed item} is the first non-empty result from removing +% spaces from both ends of comma-delimited items in the \meta{comma +% list}. The \cs{prg_do_nothing:} marker avoids losing braces. The +% test for blank items is a somewhat optimized \cs{tl_if_empty:oTF} +% construction; if blank, another item is sought, otherwise trim +% spaces. +% \begin{macrocode} +\cs_new:Npn \@@_trim_next:w #1 , + { + \tl_if_empty:oTF { \use_none:nn #1 ? } + { \@@_trim_next:w \prg_do_nothing: } + { \tl_trim_spaces_apply:oN {#1} \exp_end: } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[rEXP]{\@@_sanitize:n} +% \begin{macro}{\@@_sanitize:Nn} +% The auxiliary \cs{@@_sanitize:Nn} receives a delimiter +% (\cs{c_empty_tl} the first time, afterwards a comma) and that item +% as arguments. Unless we are done with the loop it calls +% \cs{@@_wrap_item:w} to unbrace the item (using a comma delimiter is +% safe since |#2| came from removing spaces from an argument delimited +% by a comma) and possibly re-brace it if needed. +% \begin{macrocode} +\cs_new:Npn \@@_sanitize:n #1 + { + \exp_after:wN \@@_sanitize:Nn \exp_after:wN \c_empty_tl + \exp:w \@@_trim_next:w \prg_do_nothing: + #1 , \q_recursion_tail , \q_recursion_stop + } +\cs_new:Npn \@@_sanitize:Nn #1#2 + { + \quark_if_recursion_tail_stop:n {#2} + #1 \@@_wrap_item:w #2 , + \exp_after:wN \@@_sanitize:Nn \exp_after:wN , + \exp:w \@@_trim_next:w \prg_do_nothing: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[TF]{\@@_if_wrap:n} +% \begin{macro}{\@@_if_wrap:w} +% True if the argument must be wrapped to avoid getting altered by some +% clist operations. That is the case whenever the argument +% \begin{itemize} +% \item starts or end with a space or contains a comma, +% \item is empty, or +% \item consists of a single braced group. +% \end{itemize} +% All \pkg{l3clist} functions go through the same test when they need +% to determine whether to brace an item, so it is not a problem that +% this test has false positives such as \enquote{\cs{q_mark} +% \texttt{?}}. If the argument starts or end with a space or contains +% a comma then one of the three arguments of \cs{@@_if_wrap:w} will +% have its end delimiter (partly) in one of the three copies of |#1| +% in \cs{@@_if_wrap:nTF}; this has a knock-on effect meaning that the +% result of the expansion is not empty; in that case, wrap. +% Otherwise, the argument is safe unless it starts with a brace group +% (or is empty) and it is empty or consists of a single +% \texttt{n}-type argument. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_if_wrap:n #1 { TF } + { + \tl_if_empty:oTF + { + \@@_if_wrap:w + \q_mark ? #1 ~ \q_mark ? ~ #1 \q_mark , ~ \q_mark #1 , + } + { + \tl_if_head_is_group:nTF { #1 { } } + { + \tl_if_empty:nTF {#1} + { \prg_return_true: } + { + \tl_if_empty:oTF { \use_none:n #1} + { \prg_return_true: } + { \prg_return_false: } + } + } + { \prg_return_false: } + } + { \prg_return_true: } + } +\cs_new:Npn \@@_if_wrap:w #1 \q_mark ? ~ #2 ~ \q_mark #3 , { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_wrap_item:w} +% Safe items are put in \cs{exp_not:n}, otherwise we put an extra set +% of braces. +% \begin{macrocode} +\cs_new:Npn \@@_wrap_item:w #1 , + { \@@_if_wrap:nTF {#1} { \exp_not:n { {#1} } } { \exp_not:n {#1} } } +% \end{macrocode} +% \end{macro} +% % \subsection{Allocation and initialisation} % % \begin{macro}{\clist_new:N, \clist_new:c} @@ -756,12 +900,11 @@ % \clist_const:Nn, \clist_const:cn, % \clist_const:Nx, \clist_const:cx % } -% Creating and initializing a constant comma list is done in a way -% similar to \cs{clist_set:Nn} and \cs{clist_gset:Nn}, being careful -% to strip spaces. +% Creating and initializing a constant comma list is done by +% sanitizing all items (stripping spaces and braces). % \begin{macrocode} \cs_new_protected:Npn \clist_const:Nn #1#2 - { \tl_const:Nx #1 { \@@_trim_spaces:n {#2} } } + { \tl_const:Nx #1 { \@@_sanitize:n {#2} } } \cs_generate_variant:Nn \clist_const:Nn { c , Nx , cx } % \end{macrocode} % \end{macro} @@ -829,13 +972,11 @@ % \clist_gset_from_seq:Nc, \clist_gset_from_seq:cc % } % \UnitTested -% \begin{macro}{\@@_set_from_seq:NNNN} -% \begin{macro}{\@@_wrap_item:n} -% \begin{macro}{\@@_set_from_seq:w} -% Setting a comma list from a comma-separated list is done using a simple -% mapping. We wrap most items with \cs{exp_not:n}, and a comma. Items which -% contain a comma or a space are surrounded by an extra set of braces. The -% first comma must be removed, except in the case of an empty comma-list. +% \begin{macro}{\@@_set_from_seq:NNNN, \@@_set_from_seq:n} +% Setting a comma list from a comma-separated list is done using a +% simple mapping. Safe items are put in \cs{exp_not:n}, otherwise we +% put an extra set of braces. The first comma must be removed, except +% in the case of an empty comma-list. % \begin{macrocode} \cs_new_protected:Npn \clist_set_from_seq:NN { \@@_set_from_seq:NNNN \clist_clear:N \tl_set:Nx } @@ -848,19 +989,18 @@ { #2 #3 { - \exp_last_unbraced:Nf \use_none:n - { \seq_map_function:NN #4 \@@_wrap_item:n } + \exp_after:wN \use_none:n \exp:w \exp_end_continue_f:w + \seq_map_function:NN #4 \@@_set_from_seq:n } } } -\cs_new:Npn \@@_wrap_item:n #1 +\cs_new:Npn \@@_set_from_seq:n #1 { , - \tl_if_empty:oTF { \@@_set_from_seq:w #1 ~ , #1 ~ } - { \exp_not:n {#1} } + \@@_if_wrap:nTF {#1} { \exp_not:n { {#1} } } + { \exp_not:n {#1} } } -\cs_new:Npn \@@_set_from_seq:w #1 , #2 ~ { } \cs_generate_variant:Nn \clist_set_from_seq:NN { Nc } \cs_generate_variant:Nn \clist_set_from_seq:NN { c , cc } \cs_generate_variant:Nn \clist_gset_from_seq:NN { Nc } @@ -869,8 +1009,6 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\clist_concat:NNN, \clist_concat:ccc} % \UnitTested @@ -911,66 +1049,6 @@ % \end{macrocode} % \end{macro} % -% \subsection{Removing spaces around items} -% -% \begin{macro}[EXP]{\@@_trim_spaces_generic:nw} -% \begin{macro}{\@@_trim_spaces_generic:nn} -% \begin{syntax} -% \cs{@@_trim_spaces_generic:nw} \Arg{code} \cs{q_mark} \meta{item} |,| -% \end{syntax} -% This expands to the \meta{code}, followed by a brace group -% containing the \meta{item}, with leading and trailing spaces -% removed. The calling function is responsible for inserting -% \cs{q_mark} in front of the \meta{item}, as well as testing for the -% end of the list. We reuse a \pkg{l3tl} internal function, whose -% first argument must start with \cs{q_mark}. That trims the item -% |#2|, then feeds the result (after having to do an \texttt{o}-type -% expansion) to \cs{@@_trim_spaces_generic:nn} which places the -% \meta{code} in front of the \meta{trimmed item}. -% \begin{macrocode} -\cs_new:Npn \@@_trim_spaces_generic:nw #1#2 , - { - \__tl_trim_spaces:nn {#2} - { \exp_args:No \@@_trim_spaces_generic:nn } {#1} - } -\cs_new:Npn \@@_trim_spaces_generic:nn #1#2 { #2 {#1} } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[rEXP]{\@@_trim_spaces:n} -% \begin{macro}{\@@_trim_spaces:nn} -% The first argument of \cs{@@_trim_spaces:nn} is initially empty, -% and later a comma, namely, as soon as we have added an item to the -% resulting list. The auxiliary tests for the end of the list, -% and also prevents empty arguments from finding their way into the -% output. -% \begin{macrocode} -\cs_new:Npn \@@_trim_spaces:n #1 - { - \@@_trim_spaces_generic:nw - { \@@_trim_spaces:nn { } } - \q_mark #1 , - \q_recursion_tail, \q_recursion_stop - } -\cs_new:Npn \@@_trim_spaces:nn #1 #2 - { - \quark_if_recursion_tail_stop:n {#2} - \tl_if_empty:nTF {#2} - { - \@@_trim_spaces_generic:nw - { \@@_trim_spaces:nn {#1} } \q_mark - } - { - #1 \exp_not:n {#2} - \@@_trim_spaces_generic:nw - { \@@_trim_spaces:nn { , } } \q_mark - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% % \subsection{Adding data to comma lists} % % \begin{macro} @@ -989,9 +1067,9 @@ % } % \begin{macrocode} \cs_new_protected:Npn \clist_set:Nn #1#2 - { \tl_set:Nx #1 { \@@_trim_spaces:n {#2} } } + { \tl_set:Nx #1 { \@@_sanitize:n {#2} } } \cs_new_protected:Npn \clist_gset:Nn #1#2 - { \tl_gset:Nx #1 { \@@_trim_spaces:n {#2} } } + { \tl_gset:Nx #1 { \@@_sanitize:n {#2} } } \cs_generate_variant:Nn \clist_set:Nn { NV , No , Nx , c , cV , co , cx } \cs_generate_variant:Nn \clist_gset:Nn { NV , No , Nx , c , cV , co , cx } % \end{macrocode} @@ -1015,8 +1093,9 @@ % } % \UnitTested % \begin{macro}{\@@_put_left:NNNn} -% Comma lists cannot hold empty values: there are therefore a couple -% of sanity checks to avoid accumulating commas. +% Everything is based on concatenation after storing in +% \cs{l_@@_internal_clist}. This avoids having to worry here about +% space-trimming and so on. % \begin{macrocode} \cs_new_protected:Npn \clist_put_left:Nn { \@@_put_left:NNNn \clist_concat:NNN \clist_set:Nn } @@ -1078,7 +1157,11 @@ % \UnitTested % \begin{macro}{\@@_get:wN} % Getting an item from the left of a comma list is pretty easy: just -% trim off the first item using the comma. +% trim off the first item using the comma. No need to trim spaces as +% comma-list \emph{variables} are assumed to have \enquote{cleaned-up} +% items. (Note that grabbing a comma-delimited item removes an outer +% pair of braces if present, exactly as needed to uncover the +% underlying item.) % \begin{macrocode} \cs_new_protected:Npn \clist_get:NN #1#2 { @@ -1211,10 +1294,11 @@ % % \subsection{Modifying comma lists} % -% \begin{variable}{\l_@@_internal_remove_clist} -% An internal comma list for the removal routines. +% \begin{variable}{\l_@@_internal_remove_clist, \l_@@_internal_remove_seq} +% An internal comma list and a sequence for the removal routines. % \begin{macrocode} \clist_new:N \l_@@_internal_remove_clist +\seq_new:N \l_@@_internal_remove_seq % \end{macrocode} % \end{variable} % @@ -1250,11 +1334,20 @@ % \UnitTested % \begin{macro}{\clist_gremove_all:Nn, \clist_gremove_all:cn} % \UnitTested -% \begin{macro}{\@@_remove_all:NNn} +% \begin{macro}{\@@_remove_all:NNNn} % \begin{macro}{\@@_remove_all:w} % \begin{macro}{\@@_remove_all:} -% The method used here is very similar to \cs{tl_replace_all:Nnn}. -% Build a function delimited by the \meta{item} that should be removed, +% The method used here for safe items is very similar to +% \cs{tl_replace_all:Nnn}. However, if the item contains commas or +% leading/trailing spaces, or is empty, or consists of a single brace +% group, we know that it can only appear within braces so the code +% would fail; instead just convert to a sequence and do the removal +% with \pkg{l3seq} code (it involves somewhat elaborate code to do +% most of the work expandably but the final token list comparisons +% non-expandably). +% +% For \enquote{safe} items, build a function delimited by the +% \meta{item} that should be removed, % surrounded with commas, and call that function followed by % the expanded comma list, and another copy of the \meta{item}. % The loop is controlled by the argument grabbed by @@ -1276,28 +1369,36 @@ % the second step removes it. % \begin{macrocode} \cs_new_protected:Npn \clist_remove_all:Nn - { \@@_remove_all:NNn \tl_set:Nx } + { \@@_remove_all:NNNn \clist_set_from_seq:NN \tl_set:Nx } \cs_new_protected:Npn \clist_gremove_all:Nn - { \@@_remove_all:NNn \tl_gset:Nx } -\cs_new_protected:Npn \@@_remove_all:NNn #1#2#3 + { \@@_remove_all:NNNn \clist_gset_from_seq:NN \tl_gset:Nx } +\cs_new_protected:Npn \@@_remove_all:NNNn #1#2#3#4 { - \cs_set:Npn \@@_tmp:w ##1 , #3 , - { - ##1 - , \q_mark , \use_none_delimit_by_q_stop:w , - \@@_remove_all: - } - #1 #2 + \@@_if_wrap:nTF {#4} { - \exp_after:wN \@@_remove_all: - #2 , \q_mark , #3 , \q_stop + \seq_set_from_clist:NN \l_@@_internal_remove_seq #3 + \seq_remove_all:Nn \l_@@_internal_remove_seq {#4} + #1 #3 \l_@@_internal_remove_seq } - \clist_if_empty:NF #2 { - #1 #2 + \cs_set:Npn \@@_tmp:w ##1 , #4 , + { + ##1 + , \q_mark , \use_none_delimit_by_q_stop:w , + \@@_remove_all: + } + #2 #3 + { + \exp_after:wN \@@_remove_all: + #3 , \q_mark , #4 , \q_stop + } + \clist_if_empty:NF #3 { - \exp_args:No \exp_not:o - { \exp_after:wN \use_none:n #2 } + #2 #3 + { + \exp_args:No \exp_not:o + { \exp_after:wN \use_none:n #3 } + } } } } @@ -1425,26 +1526,46 @@ % \clist_if_in:cn, \clist_if_in:cV, \clist_if_in:co, % \clist_if_in:nn, \clist_if_in:nV, \clist_if_in:no % } -% \begin{macro}{\@@_if_in_return:nn} +% \begin{macro}{\@@_if_in_return:nnN} % \UnitTested -% See description of the \cs{tl_if_in:Nn} function for details. -% We simply surround the comma list, and the item, with commas. +% For \enquote{safe} items, we simply surround the comma list, and the +% item, with commas, then use the same code as for \cs{tl_if_in:Nn}. +% For \enquote{unsafe} items we follow the same route as +% \cs{seq_if_in:Nn}, mapping through the list a comparison function. +% If found, return \texttt{true} and remove \cs{prg_return_false:}. % \begin{macrocode} \prg_new_protected_conditional:Npnn \clist_if_in:Nn #1#2 { T , F , TF } { - \exp_args:No \@@_if_in_return:nn #1 {#2} + \exp_args:No \@@_if_in_return:nnN #1 {#2} #1 } \prg_new_protected_conditional:Npnn \clist_if_in:nn #1#2 { T , F , TF } { \clist_set:Nn \l_@@_internal_clist {#1} - \exp_args:No \@@_if_in_return:nn \l_@@_internal_clist {#2} + \exp_args:No \@@_if_in_return:nnN \l_@@_internal_clist {#2} + \l_@@_internal_clist } -\cs_new_protected:Npn \@@_if_in_return:nn #1#2 +\cs_new_protected:Npn \@@_if_in_return:nnN #1#2#3 { - \cs_set:Npn \@@_tmp:w ##1 ,#2, { } - \tl_if_empty:oTF - { \@@_tmp:w ,#1, {} {} ,#2, } - { \prg_return_false: } { \prg_return_true: } + \@@_if_wrap:nTF {#2} + { + \cs_set:Npx \@@_tmp:w ##1 + { + \exp_not:N \tl_if_eq:nnT {##1} + \exp_not:n + { + {#2} + { \clist_map_break:n { \prg_return_true: \use_none:n } } + } + } + \clist_map_function:NN #3 \@@_tmp:w + \prg_return_false: + } + { + \cs_set:Npn \@@_tmp:w ##1 ,#2, { } + \tl_if_empty:oTF + { \@@_tmp:w ,#1, {} {} ,#2, } + { \prg_return_false: } { \prg_return_true: } + } } \prg_generate_conditional_variant:Nnn \clist_if_in:Nn { NV , No , c , cV , co } { T , F , TF } @@ -1463,8 +1584,8 @@ % that comma-list would be seen as consisting of one empty item). % Then loop over the comma-list, grabbing one comma-delimited % item at a time. The end is marked by \cs{q_recursion_tail}. -% The auxiliary function \cs{@@_map_function:Nw} is used -% directly in \cs{clist_map_inline:Nn}. Change with care. +% The auxiliary function \cs{@@_map_function:Nw} is also used +% in \cs{clist_map_inline:Nn}. % \begin{macrocode} \cs_new:Npn \clist_map_function:NN #1#2 { @@ -1472,12 +1593,12 @@ { \exp_last_unbraced:NNo \@@_map_function:Nw #2 #1 , \q_recursion_tail , - \__prg_break_point:Nn \clist_map_break: { } + \prg_break_point:Nn \clist_map_break: { } } } \cs_new:Npn \@@_map_function:Nw #1#2 , { - \__quark_if_recursion_tail_break:nN {#2} \clist_map_break: + \quark_if_recursion_tail_break:nN {#2} \clist_map_break: #1 {#2} \@@_map_function:Nw #1 } @@ -1492,25 +1613,24 @@ % \begin{macro}{\@@_map_unbrace:Nw} % The \texttt{n}-type mapping function is a bit more awkward, % since spaces must be trimmed from each item. -% Space trimming is again based on \cs{@@_trim_spaces_generic:nw}. -% The auxiliary \cs{@@_map_function_n:Nn} receives -% as arguments the function, and the result of removing leading -% and trailing spaces from the item which lies until the next comma. -% Empty items are ignored, then one level of braces is removed -% by \cs{@@_map_unbrace:Nw}. +% Space trimming is again based on \cs{@@_trim_next:w}. +% The auxiliary \cs{@@_map_function_n:Nn} receives as arguments the +% function, and the next non-empty item (after space trimming but +% before brace removal). One level of braces is removed by +% \cs{@@_map_unbrace:Nw}. % \begin{macrocode} \cs_new:Npn \clist_map_function:nN #1#2 { - \@@_trim_spaces_generic:nw { \@@_map_function_n:Nn #2 } - \q_mark #1, \q_recursion_tail, - \__prg_break_point:Nn \clist_map_break: { } + \exp_after:wN \@@_map_function_n:Nn \exp_after:wN #2 + \exp:w \@@_trim_next:w \prg_do_nothing: #1 , \q_recursion_tail , + \prg_break_point:Nn \clist_map_break: { } } \cs_new:Npn \@@_map_function_n:Nn #1 #2 { - \__quark_if_recursion_tail_break:nN {#2} \clist_map_break: - \tl_if_empty:nF {#2} { \@@_map_unbrace:Nw #1 #2, } - \@@_trim_spaces_generic:nw { \@@_map_function_n:Nn #1 } - \q_mark + \quark_if_recursion_tail_break:nN {#2} \clist_map_break: + \@@_map_unbrace:Nw #1 #2, + \exp_after:wN \@@_map_function_n:Nn \exp_after:wN #1 + \exp:w \@@_trim_next:w \prg_do_nothing: } \cs_new:Npn \@@_map_unbrace:Nw #1 #2, { #1 {#2} } % \end{macrocode} @@ -1538,14 +1658,14 @@ { \clist_if_empty:NF #1 { - \int_gincr:N \g__prg_map_int + \int_gincr:N \g__kernel_prg_map_int \cs_gset_protected:cpn - { __prg_map_ \int_use:N \g__prg_map_int :w } ##1 {#2} + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1 {#2} \exp_last_unbraced:Nco \@@_map_function:Nw - { __prg_map_ \int_use:N \g__prg_map_int :w } + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } #1 , \q_recursion_tail , - \__prg_break_point:Nn \clist_map_break: - { \int_gdecr:N \g__prg_map_int } + \prg_break_point:Nn \clist_map_break: + { \int_gdecr:N \g__kernel_prg_map_int } } } \cs_new_protected:Npn \clist_map_inline:nn #1 @@ -1567,6 +1687,8 @@ % additionally we store each item in the given variable. % As for inline mappings, space trimming for the \texttt{n} % variant is done by storing the comma list in a variable. +% The strange \cs{use:n} avoids unlikely problems when |#2| would +% contain \cs{q_recursion_stop}. % \begin{macrocode} \cs_new_protected:Npn \clist_map_variable:NNn #1#2#3 { @@ -1576,7 +1698,7 @@ { \@@_map_variable:Nnw #2 {#3} } #1 , \q_recursion_tail , \q_recursion_stop - \__prg_break_point:Nn \clist_map_break: { } + \prg_break_point:Nn \clist_map_break: { } } } \cs_new_protected:Npn \clist_map_variable:nNn #1 @@ -1598,12 +1720,12 @@ % \end{macro} % % \begin{macro}{\clist_map_break:, \clist_map_break:n} -% The break statements use the general \cs{__prg_map_break:Nn} mechanism. +% The break statements use the general \cs{prg_map_break:Nn} mechanism. % \begin{macrocode} \cs_new:Npn \clist_map_break: - { \__prg_map_break:Nn \clist_map_break: { } } + { \prg_map_break:Nn \clist_map_break: { } } \cs_new:Npn \clist_map_break:n - { \__prg_map_break:Nn \clist_map_break: } + { \prg_map_break:Nn \clist_map_break: } % \end{macrocode} % \end{macro} % @@ -1769,6 +1891,7 @@ % \@@_item_n:nw, % \@@_item_n_loop:nw, % \@@_item_n_end:n, +% \@@_item_n_strip:n, % \@@_item_n_strip:w} % This starts in the same way as \cs{clist_item:Nn} by counting the items % of the comma list. The final item should be space-trimmed before being @@ -1800,10 +1923,8 @@ } } \cs_new:Npn \@@_item_n_end:n #1 #2 \q_stop - { - \__tl_trim_spaces:nn { \q_mark #1 } - { \exp_last_unbraced:No \@@_item_n_strip:w } , - } + { \tl_trim_spaces_apply:nN {#1} \@@_item_n_strip:n } +\cs_new:Npn \@@_item_n_strip:n #1 { \@@_item_n_strip:w #1 , } \cs_new:Npn \@@_item_n_strip:w #1 , { \exp_not:n {#1} } % \end{macrocode} % \end{macro} @@ -1812,7 +1933,7 @@ % \subsection{Viewing comma lists} % % \begin{macro}{\clist_show:N, \clist_show:c, \clist_log:N, \clist_log:c, \@@_show:NN} -% Apply the general \cs{__kernel_check_defined:NT} and +% Apply the general \cs{__kernel_chk_defined:NT} and % \cs{msg_show:nnnnnn}. % \begin{macrocode} \cs_new_protected:Npn \clist_show:N { \@@_show:NN \msg_show:nnxxxx } @@ -1821,7 +1942,7 @@ \cs_generate_variant:Nn \clist_log:N { c } \cs_new_protected:Npn \@@_show:NN #1#2 { - \__kernel_check_defined:NT #2 + \__kernel_chk_defined:NT #2 { #1 { LaTeX/kernel } { show-clist } { \token_to_str:N #2 } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx index 42b8793c0d5..97f964fe7f7 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -311,7 +311,7 @@ % which displays the result in the terminal. % \end{function} % -% \subsection{Constants and variables} +% \section{Constants and variables} % % \begin{variable}{\c_empty_coffin} % A permanently empty coffin. @@ -448,6 +448,16 @@ % placing material in them. This all relies on the following data % structures. % +% \begin{macro}[EXP]{\@@_to_value:N} +% Coffins are a two-part structure and we rely on the internal nature of +% box allocation to make everything work. As such, we need an interface +% to turn coffin identifiers into numbers. For the purposes here, the +% signature allowed is |N| despite the nature of the underlying primitive. +% \begin{macrocode} +\cs_new_eq:NN \@@_to_value:N \tex_number:D +% \end{macrocode} +% \end{macro} +% % \begin{macro}[EXP, pTF]{\coffin_if_exist:N, \coffin_if_exist:c} % Several of the higher-level coffin functions would give multiple % errors if the coffin does not exist. A cleaner way to handle this @@ -458,7 +468,7 @@ { \cs_if_exist:NTF #1 { - \cs_if_exist:cTF { l_@@_poles_ \__int_value:w #1 _prop } + \cs_if_exist:cTF { l_@@_poles_ \@@_to_value:N #1 _prop } { \prg_return_true: } { \prg_return_false: } } @@ -516,11 +526,11 @@ { \box_new:N #1 \debug_suspend: - \prop_clear_new:c { l_@@_corners_ \__int_value:w #1 _prop } - \prop_clear_new:c { l_@@_poles_ \__int_value:w #1 _prop } - \prop_gset_eq:cN { l_@@_corners_ \__int_value:w #1 _prop } + \prop_clear_new:c { l_@@_corners_ \@@_to_value:N #1 _prop } + \prop_clear_new:c { l_@@_poles_ \@@_to_value:N #1 _prop } + \prop_gset_eq:cN { l_@@_corners_ \@@_to_value:N #1 _prop } \c_@@_corners_prop - \prop_gset_eq:cN { l_@@_poles_ \__int_value:w #1 _prop } + \prop_gset_eq:cN { l_@@_poles_ \@@_to_value:N #1 _prop } \c_@@_poles_prop \debug_resume: } @@ -732,7 +742,7 @@ \cs_new_protected:Npn \@@_get_pole:NnN #1#2#3 { \prop_get:cnNF - { l_@@_poles_ \__int_value:w #1 _prop } {#2} #3 + { l_@@_poles_ \@@_to_value:N #1 _prop } {#2} #3 { \__kernel_msg_error:nnxx { kernel } { unknown-coffin-pole } {#2} { \token_to_str:N #1 } @@ -747,9 +757,9 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_reset_structure:N #1 { - \prop_set_eq:cN { l_@@_corners_ \__int_value:w #1 _prop } + \prop_set_eq:cN { l_@@_corners_ \@@_to_value:N #1 _prop } \c_@@_corners_prop - \prop_set_eq:cN { l_@@_poles_ \__int_value:w #1 _prop } + \prop_set_eq:cN { l_@@_poles_ \@@_to_value:N #1 _prop } \c_@@_poles_prop } % \end{macrocode} @@ -761,17 +771,17 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_set_eq_structure:NN #1#2 { - \prop_set_eq:cc { l_@@_corners_ \__int_value:w #1 _prop } - { l_@@_corners_ \__int_value:w #2 _prop } - \prop_set_eq:cc { l_@@_poles_ \__int_value:w #1 _prop } - { l_@@_poles_ \__int_value:w #2 _prop } + \prop_set_eq:cc { l_@@_corners_ \@@_to_value:N #1 _prop } + { l_@@_corners_ \@@_to_value:N #2 _prop } + \prop_set_eq:cc { l_@@_poles_ \@@_to_value:N #1 _prop } + { l_@@_poles_ \@@_to_value:N #2 _prop } } \cs_new_protected:Npn \@@_gset_eq_structure:NN #1#2 { - \prop_gset_eq:cc { l_@@_corners_ \__int_value:w #1 _prop } - { l_@@_corners_ \__int_value:w #2 _prop } - \prop_gset_eq:cc { l_@@_poles_ \__int_value:w #1 _prop } - { l_@@_poles_ \__int_value:w #2 _prop } + \prop_gset_eq:cc { l_@@_corners_ \@@_to_value:N #1 _prop } + { l_@@_corners_ \@@_to_value:N #2 _prop } + \prop_gset_eq:cc { l_@@_poles_ \@@_to_value:N #1 _prop } + { l_@@_poles_ \@@_to_value:N #2 _prop } } % \end{macrocode} % \end{macro} @@ -808,7 +818,10 @@ } } \cs_new_protected:Npn \@@_set_pole:Nnn #1#2#3 - { \prop_put:cnn { l_@@_poles_ \__int_value:w #1 _prop } {#2} {#3} } + { + \prop_put:cnn { l_@@_poles_ \@@_to_value:N #1 _prop } + {#2} {#3} + } \cs_generate_variant:Nn \coffin_set_horizontal_pole:Nnn { c } \cs_generate_variant:Nn \coffin_set_vertical_pole:Nnn { c } \cs_generate_variant:Nn \@@_set_pole:Nnn { Nnx } @@ -824,14 +837,24 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_update_corners:N #1 { - \prop_put:cnx { l_@@_corners_ \__int_value:w #1 _prop } { tl } + \prop_put:cnx { l_@@_corners_ \@@_to_value:N #1 _prop } + { tl } { { 0pt } { \dim_eval:n { \box_ht:N #1 } } } - \prop_put:cnx { l_@@_corners_ \__int_value:w #1 _prop } { tr } - { { \dim_eval:n { \box_wd:N #1 } } { \dim_eval:n { \box_ht:N #1 } } } - \prop_put:cnx { l_@@_corners_ \__int_value:w #1 _prop } { bl } + \prop_put:cnx { l_@@_corners_ \@@_to_value:N #1 _prop } + { tr } + { + { \dim_eval:n { \box_wd:N #1 } } + { \dim_eval:n { \box_ht:N #1 } } + } + \prop_put:cnx { l_@@_corners_ \@@_to_value:N #1 _prop } + { bl } { { 0pt } { \dim_eval:n { -\box_dp:N #1 } } } - \prop_put:cnx { l_@@_corners_ \__int_value:w #1 _prop } { br } - { { \dim_eval:n { \box_wd:N #1 } } { \dim_eval:n { -\box_dp:N #1 } } } + \prop_put:cnx { l_@@_corners_ \@@_to_value:N #1 _prop } + { br } + { + { \dim_eval:n { \box_wd:N #1 } } + { \dim_eval:n { -\box_dp:N #1 } } + } } % \end{macrocode} % \end{macro} @@ -845,31 +868,31 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_update_poles:N #1 { - \prop_put:cnx { l_@@_poles_ \__int_value:w #1 _prop } { hc } + \prop_put:cnx { l_@@_poles_ \@@_to_value:N #1 _prop } { hc } { { \dim_eval:n { 0.5 \box_wd:N #1 } } { 0pt } { 0pt } { 1000pt } } - \prop_put:cnx { l_@@_poles_ \__int_value:w #1 _prop } { r } + \prop_put:cnx { l_@@_poles_ \@@_to_value:N #1 _prop } { r } { { \dim_eval:n { \box_wd:N #1 } } { 0pt } { 0pt } { 1000pt } } - \prop_put:cnx { l_@@_poles_ \__int_value:w #1 _prop } { vc } + \prop_put:cnx { l_@@_poles_ \@@_to_value:N #1 _prop } { vc } { { 0pt } { \dim_eval:n { ( \box_ht:N #1 - \box_dp:N #1 ) / 2 } } { 1000pt } { 0pt } } - \prop_put:cnx { l_@@_poles_ \__int_value:w #1 _prop } { t } + \prop_put:cnx { l_@@_poles_ \@@_to_value:N #1 _prop } { t } { { 0pt } { \dim_eval:n { \box_ht:N #1 } } { 1000pt } { 0pt } } - \prop_put:cnx { l_@@_poles_ \__int_value:w #1 _prop } { b } + \prop_put:cnx { l_@@_poles_ \@@_to_value:N #1 _prop } { b } { { 0pt } { \dim_eval:n { -\box_dp:N #1 } } @@ -1028,13 +1051,18 @@ \fp_to_dim:n { ( - \dim_to_fp:n {#1} * \l_@@_slope_x_fp - - ( \dim_to_fp:n {#5} * \l_@@_slope_y_fp ) + \dim_to_fp:n {#1} * + \l_@@_slope_x_fp + - ( \dim_to_fp:n {#5} * + \l_@@_slope_y_fp ) - \dim_to_fp:n {#2} + \dim_to_fp:n {#6} ) / - ( \l_@@_slope_x_fp - \l_@@_slope_y_fp ) + ( + \l_@@_slope_x_fp - + \l_@@_slope_y_fp + ) } } \@@_calculate_intersection_aux:nnnnnN @@ -1115,7 +1143,11 @@ % \begin{macrocode} \@@_reset_structure:N \l_@@_aligned_coffin \prop_clear:c - { l_@@_corners_ \__int_value:w \l_@@_aligned_coffin _ prop } + { + l_@@_corners_ + \@@_to_value:N \l_@@_aligned_coffin + _prop + } \@@_update_poles:N \l_@@_aligned_coffin % \end{macrocode} % The structures of the parent coffins are now transferred to the new @@ -1165,8 +1197,11 @@ \box_set_wd:Nn \l_@@_aligned_coffin { \box_wd:N #1 } \@@_reset_structure:N \l_@@_aligned_coffin \prop_set_eq:cc - { l_@@_corners_ \__int_value:w \l_@@_aligned_coffin _prop } - { l_@@_corners_ \__int_value:w #1 _prop } + { + l_@@_corners_ + \@@_to_value:N \l_@@_aligned_coffin _prop + } + { l_@@_corners_ \@@_to_value:N #1 _prop } \@@_update_poles:N \l_@@_aligned_coffin \@@_offset_poles:Nnn #1 { 0pt } { 0pt } \@@_offset_poles:Nnn #4 @@ -1235,7 +1270,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_offset_poles:Nnn #1#2#3 { - \prop_map_inline:cn { l_@@_poles_ \__int_value:w #1 _prop } + \prop_map_inline:cn { l_@@_poles_ \@@_to_value:N #1 _prop } { \@@_offset_pole:Nnnnnnn #1 {##1} ##2 {#2} {#3} } } \cs_new_protected:Npn \@@_offset_pole:Nnnnnnn #1#2#3#4#5#6#7#8 @@ -1264,13 +1299,16 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_offset_corners:Nnn #1#2#3 { - \prop_map_inline:cn { l_@@_corners_ \__int_value:w #1 _prop } + \prop_map_inline:cn { l_@@_corners_ \@@_to_value:N #1 _prop } { \@@_offset_corner:Nnnnn #1 {##1} ##2 {#2} {#3} } } \cs_new_protected:Npn \@@_offset_corner:Nnnnn #1#2#3#4#5#6 { \prop_put:cnx - { l_@@_corners_ \__int_value:w \l_@@_aligned_coffin _prop } + { + l_@@_corners_ + \@@_to_value:N \l_@@_aligned_coffin _prop + } { #1 - #2 } { { \dim_eval:n { #3 + #5 } } @@ -1538,7 +1576,7 @@ %</package> } \prop_set_eq:Nc \l_@@_display_poles_prop - { l_@@_poles_ \__int_value:w #1 _prop } + { l_@@_poles_ \@@_to_value:N #1 _prop } \@@_get_pole:NnN #1 { H } \l_@@_pole_a_tl \@@_get_pole:NnN #1 { T } \l_@@_pole_b_tl \tl_if_eq:NNT \l_@@_pole_a_tl \l_@@_pole_b_tl @@ -1682,7 +1720,7 @@ } { \prop_map_function:cN - { l_@@_poles_ \int_eval:n {#2} _prop } + { l_@@_poles_ \@@_to_value:N #2 _prop } \msg_show_item_unbraced:nn } { } @@ -1697,10 +1735,9 @@ \__kernel_msg_new:nnnn { kernel } { no-pole-intersection } { No~intersection~between~coffin~poles. } { - \c__msg_coding_error_text_tl LaTeX~was~asked~to~find~the~intersection~between~two~poles,~ but~they~do~not~have~a~unique~meeting~point:~ - the~value~(0~pt,~0~pt)~will~be~used. + the~value~(0pt,~0pt)~will~be~used. } \__kernel_msg_new:nnnn { kernel } { unknown-coffin } { Unknown~coffin~'#1'. } @@ -1708,7 +1745,6 @@ \__kernel_msg_new:nnnn { kernel } { unknown-coffin-pole } { Pole~'#1'~unknown~for~coffin~'#2'. } { - \c__msg_coding_error_text_tl LaTeX~was~asked~to~find~a~typesetting~pole~for~a~coffin,~ but~either~the~coffin~does~not~exist~or~the~pole~name~is~wrong. } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx b/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx index 8e294d166ab..73d2b459aaf 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -76,9 +76,21 @@ % \cs{color_group_begin:} \ldots \cs{color_group_end:} group. % \end{function} % -% \subsection{Internal functions} +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3color-base} Implementation} +% +% \begin{macrocode} +%<*initex|package> +% \end{macrocode} % -% \begin{variable}[added = 2017-06-15, updated = 2017-10-02] +% \begin{macrocode} +%<@@=color> +% \end{macrocode} +% +% \begin{variable} % {\l_@@_current_tl} % The color currently active for foreground (text, \emph{etc.}) material. % This is stored in the form of a color model followed by one or more @@ -109,20 +121,6 @@ % \end{texnote} % \end{variable} % -% \end{documentation} -% -% \begin{implementation} -% -% \section{\pkg{l3color-base} Implementation} -% -% \begin{macrocode} -%<*initex|package> -% \end{macrocode} -% -% \begin{macrocode} -%<@@=color> -% \end{macrocode} -% % \begin{macro}{\color_group_begin:, \color_group_end:} % Grouping for color is almost the same as using the basic \cs{group_begin:} % and \cs{group_end:} functions. However, in vertical mode the end-of-group diff --git a/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx b/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx index 95664eb799d..ca8a79b3227 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -66,12 +66,12 @@ %<@@=deprecation> % \end{macrocode} % -% \begin{macro}{\@@_error:Nnn} +% \begin{macro}{\__kernel_deprecation_error:Nnn} % The \tn{outer} definition here ensures the command cannot appear % in an argument. Use this auxiliary on all commands that have been % removed since 2015. % \begin{macrocode} -\cs_new_protected:Npn \@@_error:Nnn #1#2#3 +\cs_new_protected:Npn \__kernel_deprecation_error:Nnn #1#2#3 { \etex_protected:D \tex_outer:D \tex_edef:D #1 { @@ -83,47 +83,86 @@ { \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} } } } -\@@_error:Nnn \file_if_exist_input:nT { \file_if_exist:nT and~ \file_input:n } { 2018-03-05 } -\@@_error:Nnn \file_if_exist_input:nTF { \file_if_exist:nT and~ \file_input:n } { 2018-03-05 } -\@@_error:Nnn \c_job_name_tl { \c_sys_jobname_str } { 2017-01-01 } -\@@_error:Nnn \dim_case:nnn { \dim_case:nnF } { 2015-07-14 } -\@@_error:Nnn \int_case:nnn { \int_case:nnF } { 2015-07-14 } -\@@_error:Nnn \int_from_binary:n { \int_from_bin:n } { 2016-01-05 } -\@@_error:Nnn \int_from_hexadecimal:n { \int_from_hex:n } { 2016-01-05 } -\@@_error:Nnn \int_from_octal:n { \int_from_oct:n } { 2016-01-05 } -\@@_error:Nnn \int_to_binary:n { \int_to_bin:n } { 2016-01-05 } -\@@_error:Nnn \int_to_hexadecimal:n { \int_to_hex:n } { 2016-01-05 } -\@@_error:Nnn \int_to_octal:n { \int_to_oct:n } { 2016-01-05 } -\@@_error:Nnn \ior_get_str:NN { \ior_str_get:NN } { 2018-03-05 } -\@@_error:Nnn \luatex_if_engine_p: { \sys_if_engine_luatex_p: } { 2017-01-01 } -\@@_error:Nnn \luatex_if_engine:F { \sys_if_engine_luatex:F } { 2017-01-01 } -\@@_error:Nnn \luatex_if_engine:T { \sys_if_engine_luatex:T } { 2017-01-01 } -\@@_error:Nnn \luatex_if_engine:TF { \sys_if_engine_luatex:TF } { 2017-01-01 } -\@@_error:Nnn \pdftex_if_engine_p: { \sys_if_engine_pdftex_p: } { 2017-01-01 } -\@@_error:Nnn \pdftex_if_engine:F { \sys_if_engine_pdftex:F } { 2017-01-01 } -\@@_error:Nnn \pdftex_if_engine:T { \sys_if_engine_pdftex:T } { 2017-01-01 } -\@@_error:Nnn \pdftex_if_engine:TF { \sys_if_engine_pdftex:TF } { 2017-01-01 } -\@@_error:Nnn \prop_get:cn { \prop_item:cn } { 2016-01-05 } -\@@_error:Nnn \prop_get:Nn { \prop_item:Nn } { 2016-01-05 } -\@@_error:Nnn \quark_if_recursion_tail_break:N { } { 2015-07-14 } -\@@_error:Nnn \quark_if_recursion_tail_break:n { }{ 2015-07-14 } -\@@_error:Nnn \scan_align_safe_stop: { protected~commands } { 2017-01-01 } -\@@_error:Nnn \str_case:nnn { \str_case:nnF } { 2015-07-14 } -\@@_error:Nnn \str_case:onn { \str_case:onF } { 2015-07-14 } -\@@_error:Nnn \str_case_x:nnn { \str_case_x:nnF } { 2015-07-14 } -\@@_error:Nnn \tl_case:cnn { \tl_case:cnF } { 2015-07-14 } -\@@_error:Nnn \tl_case:Nnn { \tl_case:NnF } { 2015-07-14 } -\@@_error:Nnn \tl_to_lowercase:n { \tex_lowercase:D } { 2018-03-05 } -\@@_error:Nnn \tl_to_uppercase:n { \tex_uppercase:D } { 2018-03-05 } -\@@_error:Nnn \xetex_if_engine_p: { \sys_if_engine_xetex_p: } { 2017-01-01 } -\@@_error:Nnn \xetex_if_engine:F { \sys_if_engine_xetex:F } { 2017-01-01 } -\@@_error:Nnn \xetex_if_engine:T { \sys_if_engine_xetex:T } { 2017-01-01 } -\@@_error:Nnn \xetex_if_engine:TF { \sys_if_engine_xetex:TF } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \file_if_exist_input:nT + { \file_if_exist:nT and~ \file_input:n } { 2018-03-05 } +\__kernel_deprecation_error:Nnn \file_if_exist_input:nTF + { \file_if_exist:nT and~ \file_input:n } { 2018-03-05 } +\__kernel_deprecation_error:Nnn \c_job_name_tl + { \c_sys_jobname_str } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \dim_case:nnn + { \dim_case:nnF } { 2015-07-14 } +\__kernel_deprecation_error:Nnn \int_case:nnn + { \int_case:nnF } { 2015-07-14 } +\__kernel_deprecation_error:Nnn \int_from_binary:n + { \int_from_bin:n } { 2016-01-05 } +\__kernel_deprecation_error:Nnn \int_from_hexadecimal:n + { \int_from_hex:n } { 2016-01-05 } +\__kernel_deprecation_error:Nnn \int_from_octal:n + { \int_from_oct:n } { 2016-01-05 } +\__kernel_deprecation_error:Nnn \int_to_binary:n + { \int_to_bin:n } { 2016-01-05 } +\__kernel_deprecation_error:Nnn \int_to_hexadecimal:n + { \int_to_hex:n } { 2016-01-05 } +\__kernel_deprecation_error:Nnn \int_to_octal:n + { \int_to_oct:n } { 2016-01-05 } +\__kernel_deprecation_error:Nnn \ior_get_str:NN + { \ior_str_get:NN } { 2018-03-05 } +\__kernel_deprecation_error:Nnn \luatex_if_engine_p: + { \sys_if_engine_luatex_p: } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \luatex_if_engine:F + { \sys_if_engine_luatex:F } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \luatex_if_engine:T + { \sys_if_engine_luatex:T } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \luatex_if_engine:TF + { \sys_if_engine_luatex:TF } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \pdftex_if_engine_p: + { \sys_if_engine_pdftex_p: } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \pdftex_if_engine:F + { \sys_if_engine_pdftex:F } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \pdftex_if_engine:T + { \sys_if_engine_pdftex:T } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \pdftex_if_engine:TF + { \sys_if_engine_pdftex:TF } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \prop_get:cn + { \prop_item:cn } { 2016-01-05 } +\__kernel_deprecation_error:Nnn \prop_get:Nn + { \prop_item:Nn } { 2016-01-05 } +\__kernel_deprecation_error:Nnn \quark_if_recursion_tail_break:N + { } { 2015-07-14 } +\__kernel_deprecation_error:Nnn \quark_if_recursion_tail_break:n + { } { 2015-07-14 } +\__kernel_deprecation_error:Nnn \scan_align_safe_stop: + { protected~commands } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \str_case:nnn + { \str_case:nnF } { 2015-07-14 } +\__kernel_deprecation_error:Nnn \str_case:onn + { \str_case:onF } { 2015-07-14 } +\__kernel_deprecation_error:Nnn \str_case_x:nnn + { \str_case_x:nnF } { 2015-07-14 } +\__kernel_deprecation_error:Nnn \tl_case:cnn + { \tl_case:cnF } { 2015-07-14 } +\__kernel_deprecation_error:Nnn \tl_case:Nnn + { \tl_case:NnF } { 2015-07-14 } +\__kernel_deprecation_error:Nnn \tl_to_lowercase:n + { \tex_lowercase:D } { 2018-03-05 } +\__kernel_deprecation_error:Nnn \tl_to_uppercase:n + { \tex_uppercase:D } { 2018-03-05 } +\__kernel_deprecation_error:Nnn \xetex_if_engine_p: + { \sys_if_engine_xetex_p: } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \xetex_if_engine:F + { \sys_if_engine_xetex:F } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \xetex_if_engine:T + { \sys_if_engine_xetex:T } { 2017-01-01 } +\__kernel_deprecation_error:Nnn \xetex_if_engine:TF + { \sys_if_engine_xetex:TF } { 2017-01-01 } % \end{macrocode} % \end{macro} % -% This is left-over from \pkg{l3expan}. It cannot be done there because -% \pkg{l3tl} is not loaded at that time. +% \begin{macro}[deprecated = 2018-12-31]{\__cs_generate_variant_loop_warning:nnxxxx} +% This is left-over from \pkg{l3expan}. It cannot be done there +% because \pkg{l3tl} is not loaded at that time. Of course what's +% deprecated is actually some combinations of variants; see +% \pkg{l3expan}. % \begin{macrocode} \__kernel_deprecation_code:nn { @@ -135,6 +174,7 @@ { \__kernel_msg_warning:nnxxxx } } % \end{macrocode} +% \end{macro} % % \begin{macrocode} %</initex|package> diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx index 711873fe192..16ccbe2bff8 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx @@ -70,14 +70,14 @@ and all files in that bundle must be distributed together. % This isn't included in the typeset documentation because it's a bit % ugly: %<*class> -\ProvidesExplClass{l3doc}{2018/03/05}{} +\ProvidesExplClass{l3doc}{2018-04-30}{} {L3 Experimental documentation class} %</class> % \fi % % \title{The \cls{l3doc} class} % \author{\Team} -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % \maketitle % \tableofcontents % @@ -564,7 +564,8 @@ and all files in that bundle must be distributed together. % \begin{variable}{\l_@@_detect_internals_bool, \l_@@_detect_internals_tl} % If \texttt{true}, \pkg{l3doc} will check for use of internal % commands \cs[no-index]{__\meta{pkg}_\ldots{}} from other packages in -% \texttt{macrocode} environments and in~\cs{cs}. Also a token list +% the argument of the \texttt{macro} environment, and in the code typeset in +% \texttt{macrocode} environments, but not in~\cs{cs}. Also a token list % to store temporary data for this purpose. % \begin{macrocode} \bool_new:N \l_@@_detect_internals_bool @@ -922,6 +923,7 @@ and all files in that bundle must be distributed together. % \tl_if_head_eq_charcode:oNF, % \tl_if_head_eq_meaning:VNF, % \tl_if_in:noTF, +% \tl_if_in:ooTF, % \tl_if_in:NoTF, % \tl_if_in:NoT, % \tl_if_in:NoF, @@ -1026,11 +1028,6 @@ and all files in that bundle must be distributed together. % \begin{macrocode} \cs_new_protected:Npn \@@_replace_at_at:N #1 { - \bool_if:NT \l_@@_in_implementation_bool - { - \bool_if:NT \l_@@_detect_internals_bool - { \@@_detect_internals:N #1 } - } \tl_if_empty:NF \g_@@_module_name_tl { \exp_args:NNo \@@_replace_at_at_aux:Nn @@ -1051,7 +1048,12 @@ and all files in that bundle must be distributed together. % \end{macro} % \end{macro} % -% \begin{macro}{\@@_detect_internals:N, \@@_if_detect_internals_ok:NF} +% \begin{macro} +% { +% \@@_detect_internals:N, +% \@@_detect_internals_aux:N, +% \@@_if_detect_internals_ok:NF +% } % After splitting at each |__| and removing the leading item from the % sequence (since it does not follow |__|), remove everything after % any space or end-of-line to get a good approximation of the control @@ -1062,9 +1064,14 @@ and all files in that bundle must be distributed together. % remove anything after any |_| or |:| (with either catcode) to get a % guess of the module name. % \begin{macrocode} +\cs_new_protected:Npn \@@_detect_internals:N #1 + { + \bool_if:NT \l_@@_detect_internals_bool + { \@@_detect_internals_aux:N #1 } + } \group_begin: \char_set_catcode_active:N \^^M - \cs_new_protected:Npn \@@_detect_internals:N #1 + \cs_new_protected:Npn \@@_detect_internals_aux:N #1 { \tl_set_eq:NN \l_@@_detect_internals_tl #1 \tl_replace_all:Non \l_@@_detect_internals_tl { \token_to_str:N _ } { _ } @@ -1192,7 +1199,11 @@ and all files in that bundle must be distributed together. % % \begin{macro}[rEXP]{\@@_key_get_base:nN} % Get the base form of a function and store it. As part of getting -% the base form, change trailing |T| or |F| to |TF|. +% the base form, change trailing |T| or |F| to |TF|, skipping that +% change if the function contains no colon to avoid changing for +% instance some names ending in \texttt{PDF} or similar. The various +% letters |z| serve as end-delimiters different from any outcome of +% \cs{tl_to_str:n}. % \begin{macrocode} \cs_new_protected:Npn \@@_key_get_base:nN #1#2 { @@ -1206,22 +1217,23 @@ and all files in that bundle must be distributed together. } \cs_new:Npx \@@_key_get_base_TF:nN #1#2 { - \tl_set:Nx #2 { \exp_not:N \tl_to_str:n {#1} \scan_stop: } - \tl_if_in:NnTF #2 { \tl_to_str:n { F } \scan_stop: } + \tl_set:Nx #2 { \exp_not:N \tl_to_str:n {#1} } + \tl_if_in:NoF #2 { \tl_to_str:n {:} } + { \exp_not:N \prg_break: } + \tl_if_in:onT { #2 z } { \tl_to_str:n {TF} z } + { \exp_not:N \prg_break: } + \tl_if_in:onT { #2 z } { \tl_to_str:n {T} z } { - \tl_if_in:NnF #2 { \tl_to_str:n { TF } \scan_stop: } - { - \tl_replace_once:Nnn #2 - { \tl_to_str:n { F } \scan_stop: } - { \tl_to_str:n { TF } \scan_stop: } - } + \tl_put_right:Nn #2 { \tl_to_str:n {F} } + \exp_not:N \prg_break: } + \tl_if_in:onT { #2 z } { \tl_to_str:n {F} z } { - \tl_replace_once:Nnn #2 - { \tl_to_str:n { T } \scan_stop: } - { \tl_to_str:n { TF } \scan_stop: } + \tl_put_right:Nn #2 { z } + \tl_replace_once:Nnn #2 { \tl_to_str:n {F} z } { \tl_to_str:n {TF} } + \exp_not:N \prg_break: } - \tl_remove_once:Nn #2 { \scan_stop: } + \exp_not:N \prg_break_point: } \cs_new:Npn \@@_base_form_aux:nnN #1#2#3 { @@ -1654,6 +1666,7 @@ and all files in that bundle must be distributed together. \providecommand*\upTeX{up\kern-.2em\hologo{TeX}} \providecommand*\epTeX{$\varepsilon$-\pTeX} \providecommand*\eupTeX{$\varepsilon$-\upTeX} +\providecommand*\ConTeXt{\hologo{ConTeXt}} % \end{macrocode} % \end{macro} % @@ -2092,6 +2105,7 @@ and all files in that bundle must be distributed together. \tl_remove_all:Nx \l_@@_tmpa_tl { \tl_to_str:n { ^ ^ A } } \tl_remove_all:Nx \l_@@_tmpa_tl { \iow_char:N \^^I } \tl_remove_all:Nx \l_@@_tmpa_tl { \iow_char:N \^^M } + \@@_detect_internals:N \l_@@_tmpa_tl \@@_replace_at_at:N \l_@@_tmpa_tl \exp_args:NNx \seq_set_from_clist:Nn #2 { \tl_to_str:N \l_@@_tmpa_tl } @@ -3680,6 +3694,7 @@ and all files in that bundle must be distributed together. { \@@_xmacro_code:w #1 \q_stop } { \tl_set:Nn \l_@@_tmpa_tl {#1} + \@@_detect_internals:N \l_@@_tmpa_tl \@@_replace_at_at:N \l_@@_tmpa_tl \tl_use:N \l_@@_tmpa_tl } @@ -3687,12 +3702,14 @@ and all files in that bundle must be distributed together. \cs_new_protected:Npn \@@_xmacro_code:w #1 < @ @ = #2 > #3 \q_stop { \tl_set:Nn \l_@@_tmpa_tl {#1} + \@@_detect_internals:N \l_@@_tmpa_tl \@@_replace_at_at:N \l_@@_tmpa_tl \tl_gset:Nn \g_@@_module_name_tl {#2} \tl_put_right:Nn \l_@@_tmpa_tl { < @ @ = #2 > } \tl_set:Nn \l_@@_tmpb_tl {#3} + \@@_detect_internals:N \l_@@_tmpb_tl \@@_replace_at_at:N \l_@@_tmpb_tl \tl_put_right:No \l_@@_tmpa_tl { \l_@@_tmpb_tl } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx index d52e130284f..566457d6f5b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx @@ -61,7 +61,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx index 242bc86790c..1e830a52e62 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -61,7 +61,7 @@ % conjugation with \pdfTeX{} or \LuaTeX{} in DVI mode. % \item \texttt{dvisvgm}: The \texttt{dvisvgm} program, which works in % conjugation with \pdfTeX{} or \LuaTeX{} when run in DVI mode as well -% as with (u)p\TeX{} and \XeTeX{}. +% as with (u)\pTeX{} and \XeTeX{}. % \item \texttt{xdvipdfmx}: The driver used by \XeTeX{}. % \end{itemize} % @@ -97,24 +97,28 @@ % % \section{Box rotation and scaling} % -% \begin{function}[added = 2017-12-13]{\driver_box_use_rotate:Nn} +% \begin{function}[added = 2017-12-13, updated = 2018-04-26] +% {\driver_box_use_rotate:Nn} % \begin{syntax} % \cs{driver_box_use_rotate:Nn} \meta{box} \Arg{angle} % \end{syntax} % Inserts the content of the \meta{box} at the current insertion point -% rotated by the \meta{angle} (expressed in degrees). The material is +% rotated by the \meta{angle} (an \meta{fp expression} expressed in degrees). +% The material is % rotated such the the \TeX{} reference point of the box is the center of % rotation and remains the reference point after rotation. It is the % responsibility of the code using this function to adjust the apparent % size of the inserted material. % \end{function} % -% \begin{function}[added = 2017-12-13]{\driver_box_use_scale:Nnn} +% \begin{function}[added = 2017-12-13, updated = 2018-04-26] +% {\driver_box_use_scale:Nnn} % \begin{syntax} % \cs{driver_box_use_scale:Nnn} \meta{box} \Arg{x-scale} \Arg{y-scale} % \end{syntax} % Inserts the content of the \meta{box} at the current insertion point -% scale by the \meta{x-scale} and \meta{y-scale}. The reference point +% scale by the \meta{x-scale} and \meta{y-scale} (both \meta{fp expressions}). +% The reference point % of the material will be unchanged. It is the responsibility of the % code using this function to adjust the apparent size of the inserted % material. @@ -263,7 +267,7 @@ % \meta{path construction} % \cs{driver_draw_stroke:} % \end{syntax} -% Draws a line along the current path, which is also closed by +% Draws a line along the current path, which is also closed in the case of % \cs{driver_draw_closestroke:}. The nature of the line drawn % is influenced by settings for % \begin{itemize} @@ -334,7 +338,7 @@ % Sets the width to be used for stroking to \meta{dimexpr}. % \end{function} % -% \begin{function}{\driver_draw_cap_dash:nn} +% \begin{function}{\driver_draw_dash_pattern:nn} % \begin{syntax} % \cs{driver_draw_dash:nn} \Arg{dash pattern} \Arg{phase} % \end{syntax} @@ -381,10 +385,11 @@ % % \begin{function}{\driver_draw_miterlimit:n} % \begin{syntax} -% \cs{driver_draw_miterlimit:n} \Arg{dimexpr} +% \cs{driver_draw_miterlimit:n} \Arg{factor} % \end{syntax} % Sets the miter limit of lines joined as a miter, as described in the -% PDF and PostScript manuals. +% PDF and PostScript manuals. The \meta{factor} here is an +% \meta{fp expression}. % \end{function} % % \subsection{Color} @@ -476,23 +481,23 @@ %<*package> \ProvidesExplFile %<*dvipdfmx> - {l3dvidpfmx.def}{2017/03/18}{} + {l3dvidpfmx.def}{2018-04-30}{} {L3 Experimental driver: dvipdfmx} %</dvipdfmx> %<*dvips> - {l3dvips.def}{2017/03/18}{} + {l3dvips.def}{2018-04-30}{} {L3 Experimental driver: dvips} %</dvips> %<*dvisvgm> - {l3dvisvgm.def}{2017/03/18}{} + {l3dvisvgm.def}{2018-04-30}{} {L3 Experimental driver: dvisvgm} %</dvisvgm> %<*pdfmode> - {l3pdfmode.def}{2017/03/18}{} + {l3pdfmode.def}{2018-04-30}{} {L3 Experimental driver: PDF mode} %</pdfmode> %<*xdvipdfmx> - {l3xdvidpfmx.def}{2017/03/18}{} + {l3xdvidpfmx.def}{2018-04-30}{} {L3 Experimental driver: xdvipdfmx} %</xdvipdfmx> %</package> @@ -509,6 +514,18 @@ % takes most of the same code. % \end{itemize} % +% \begin{macro}{\@@_literal_x:n, \@@_literal:n, \@@_literal:x} +% The one shared function for all drivers is access to the basic +% \tn{special} primitive: it has slightly odd expansion behaviour +% so a wrapper is provided. +% \begin{macrocode} +\cs_new_eq:NN \@@_literal_x:n \tex_special:D +\cs_new_protected:Npn \@@_literal:n #1 + { \@@_literal_x:n { \exp_not:n {#1} } } +\cs_generate_variant:Nn \@@_literal:n { x } +% \end{macrocode} +% \end{macro} +% % \subsection{Color support} % % Color support is split into two parts: a \enquote{general} concept and @@ -547,7 +564,10 @@ \exp_after:wN \use:n \current@color \c_space_tl 1 } } - { \exp_after:wN \@@_color_pickup:w \current@color \q_stop #1 } + { + \exp_after:wN \@@_color_pickup:w + \current@color \q_stop #1 + } } \cs_new_protected:Npn \@@_color_pickup:w #1 ~ #2 \q_stop #3 { \tl_set:Nn #3 { #1 ~ #2 } } @@ -563,29 +583,40 @@ % \begin{macro}{\driver_color_gray:n} % \begin{macro}{\driver_color_rgb:nnn} % \begin{macro}{\driver_color_spot:nn} -% \begin{macro}{\@@_color_select:n} +% \begin{macro}{\@@_color_select:n, \@@_color_select:x} % \begin{macro}{\@@_color_reset:} % Push the data to the stack. In the case of \texttt{dvips} also reset the % drawing fill color in raw PostScript. % \begin{macrocode} \cs_new_protected:Npn \driver_color_cmyk:nnnn #1#2#3#4 - { \@@_color_select:n { cmyk~ #1 ~ #2 ~ #3 ~ #4 } } + { + \@@_color_select:x + { + cmyk~ + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} + } + } \cs_new_protected:Npn \driver_color_gray:n #1 - { \@@_color_select:n { gray~ #1 } } + { \@@_color_select:x { gray~ \fp_eval:n {#1} } } \cs_new_protected:Npn \driver_color_rgb:nnn #1#2#3 - { \@@_color_select:n { rgb~ #1 ~ #2 ~ #3 } } + { + \@@_color_select:x + { rgb~ \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} } + } \cs_new_protected:Npn \driver_color_spot:nn #1#2 { \@@_color_select:n { \c_space_tl #1 } } \cs_new_protected:Npn \@@_color_select:n #1 { - \tex_special:D { color~push~ #1 } + \@@_literal:n { color~push~ #1 } %<*dvips> - \tex_special:D { ps::/l3fc~{ }~def } + \@@_literal_postscript:n { /l3fc~{ }~def } %</dvips> \group_insert_after:N \@@_color_reset: } +\cs_generate_variant:Nn \@@_color_select:n { x } \cs_new_protected:Npn \@@_color_reset: - { \tex_special:D { color~pop } } + { \@@_literal:n { color~pop } } % \end{macrocode} % \end{macro} % \end{macro} @@ -663,19 +694,45 @@ % \end{macrocode} % \end{variable} % -% \begin{macro}{\driver_color_cmyk:nnnn} -% \begin{macro}{\driver_color_gray:n} -% \begin{macro}{\driver_color_rgb:nnn} +% \begin{macro}{\driver_color_cmyk:nnnn, \@@_color_cmyk:nnnn} +% \begin{macro}{\driver_color_gray:n, @@_color_gray:n} +% \begin{macro}{\driver_color_rgb:nnn, \@@_color_rgb:nnn} % \begin{macro}{\driver_color_spot:nn} -% \begin{macro}{\@@_color_select:n} +% \begin{macro}{\@@_color_select:n, \@@_color_select:x} % \begin{macro}{\@@_color_reset:} % Simply dump the data, but allowing for \LuaTeX{}. % \begin{macrocode} \cs_new_protected:Npn \driver_color_cmyk:nnnn #1#2#3#4 - { \@@_color_select:n { #1 ~ #2 ~ #3 ~ #4 ~ k ~ #1 ~ #2 ~ #3 ~ #4 ~ K } } + { + \use:x + { + \@@_color_cmyk:nnnn + { \fp_eval:n {#1} } + { \fp_eval:n {#2} } + { \fp_eval:n {#3} } + { \fp_eval:n {#4} } + } + } +\cs_new_protected:Npn \@@_color_cmyk:nnnn #1#2#3#4 + { + \@@_color_select:n + { #1 ~ #2 ~ #3 ~ #4 ~ k ~ #1 ~ #2 ~ #3 ~ #4 ~ K } + } \cs_new_protected:Npn \driver_color_gray:n #1 + { \exp_args:Nx \@@_color_gray:n { \fp_eval:n {#1} } } +\cs_new_protected:Npn \@@_color_gray:n #1 { \@@_color_select:n { #1 ~ g ~ #1 ~ G } } \cs_new_protected:Npn \driver_color_rgb:nnn #1#2#3 + { + \use:x + { + \@@_color_rgb:nnn + { \fp_eval:n {#1} } + { \fp_eval:n {#2} } + { \fp_eval:n {#3} } + } + } +\cs_new_protected:Npn \@@_color_rgb:nnn #1#2#3 { \@@_color_select:n { #1 ~ #2 ~ #3 ~ rg ~ #1 ~ #2 ~ #3 ~ RG } } \cs_new_protected:Npn \driver_color_spot:nn #1#2 { \@@_color_select:n { /#1 ~ cs ~ /#1 ~ CS ~ #2 ~ sc ~ #2 ~ SC } } @@ -687,6 +744,7 @@ \exp_not:N \l_@@_color_stack_int push {#1} \group_insert_after:N \exp_not:N \@@_color_reset: } +\cs_generate_variant:Nn \@@_color_select:n { x } \cs_new_protected:Npx \@@_color_reset: { \cs_if_exist:NTF \luatex_pdfextension:D @@ -714,80 +772,83 @@ % % \subsubsection{Basics} % -% \begin{macro}{\@@_literal:n} -% In the case of \texttt{dvips} there is no build-in saving of the current +% \begin{macro}{\@@_literal_postscript:n, \@@_literal_postscript:x} +% Literal PostScript can be included using a few low-level formats. Here, +% we use the form with no positioning: this is overall more convenient as +% a wrapper. Note that this does require that where position is important, +% an appropriate wrapper is included. +% \begin{macrocode} +\cs_new_protected:Npn \@@_literal_postscript:n #1 + { \@@_literal:n { ps:: #1 } } +\cs_generate_variant:Nn \@@_literal_postscript:n { x } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_align_currentpoint_begin:, \@@_align_currentpoint_end:} +% In \texttt{dvips} there is no build-in saving of the current % position, and so some additional PostScript is required to set up the % transformation matrix and also to restore it afterwards. Notice the use % of the stack to save the current position \enquote{up front} and to -% move back to it at the end of the process. +% move back to it at the end of the process. Notice that the |[begin]|/^^A +% |[end]| pair here mean that we can use a run of PostScript statements +% in separate lines: not \emph{required} but does make the code and +% output more clear. % \begin{macrocode} -\cs_new_protected:Npn \@@_literal:n #1 +\cs_new_protected:Npn \@@_align_currentpoint_begin: { - \tex_special:D - { - ps: - currentpoint~ - currentpoint~translate~ - #1 ~ - neg~exch~neg~exch~translate - } + \@@_literal:n { ps::[begin] } + \@@_literal_postscript:n { currentpoint } + \@@_literal_postscript:n { currentpoint~translate } + } +\cs_new_protected:Npn \@@_align_currentpoint_end: + { + \@@_literal_postscript:n { neg~exch~neg~exch~translate } + \@@_literal:n { ps::[end] } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_scope_begin:, \@@_scope_end:} -% Scope saving/restoring is done directly with no need to worry about the -% transformation matrix. General scoping is only for the graphics stack so -% the lower-cost |gsave|/|grestore| pair are used. +% Saving/restoring scope for general operations needs to be done with +% \texttt{dvips} positioning (try without to see this!). Thus we need the +% |ps:| version of the special here. As only the graphics state is ever +% altered within this pairing, we use the lower-cost |g|-versions. % \begin{macrocode} \cs_new_protected:Npn \@@_scope_begin: - { \tex_special:D { ps:gsave } } + { \@@_literal:n { ps:gsave } } \cs_new_protected:Npn \@@_scope_end: - { \tex_special:D { ps:grestore } } -% \end{macrocode} -% \end{macro} -% -% \subsection{Driver-specific auxiliaries} -% -% \begin{macro}[EXP]{\@@_absolute_lengths:n} -% The \texttt{dvips} driver scales all absolute dimensions based -% on the output resolution selected and any \TeX{} magnification. Thus -% for any operation involving absolute lengths there is a correction to -% make. This is based on \texttt{normalscale} from \texttt{special.pro} -% but using the stack rather than a definition to save the current matrix. -% \begin{macrocode} -\cs_new:Npn \@@_absolute_lengths:n #1 - { - matrix~currentmatrix~ - Resolution~72~div~VResolution~72~div~scale~ - DVImag~dup~scale~ - #1 ~ - setmatrix - } + { \@@_literal:n { ps:grestore } } % \end{macrocode} % \end{macro} % % \subsubsection{Box operations} % % \begin{macro}{\driver_box_use_clip:N} -% Much the same idea as for the PDF mode version but with a slightly -% different syntax for creating the clip path. To avoid any scaling -% issues we need the absolute length auxiliary here. +% The \texttt{dvips} driver scales all absolute dimensions based on the +% output resolution selected and any \TeX{} magnification. Thus for any +% operation involving absolute lengths there is a correction to make. See +% \texttt{normalscale} from \texttt{special.pro} for the variables, noting +% that here everything is saved on the stack rather than as a separate +% variable. Once all of that is done, the actual clipping is trivial. % \begin{macrocode} \cs_new_protected:Npn \driver_box_use_clip:N #1 { \@@_scope_begin: - \@@_literal:n + \@@_align_currentpoint_begin: + \@@_literal_postscript:n { matrix~currentmatrix } + \@@_literal_postscript:n + { Resolution~72~div~VResolution~72~div~scale } + \@@_literal_postscript:n { DVImag~dup~scale } + \@@_literal_postscript:x { - \@@_absolute_lengths:n - { - 0 ~ - \dim_to_decimal_in_bp:n { \box_dp:N #1 } ~ - \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~ - \dim_to_decimal_in_bp:n { -\box_ht:N #1 - \box_dp:N #1 } ~ - rectclip - } + 0 ~ + \dim_to_decimal_in_bp:n { \box_dp:N #1 } ~ + \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~ + \dim_to_decimal_in_bp:n { -\box_ht:N #1 - \box_dp:N #1 } ~ + rectclip } + \@@_literal_postscript:n { setmatrix } + \@@_align_currentpoint_end: \hbox_overlap_right:n { \box_use:N #1 } \@@_scope_end: \skip_horizontal:n { \box_wd:N #1 } @@ -796,25 +857,31 @@ % \end{macro} % % \begin{macro}{\driver_box_use_rotate:Nn} +% \begin{macro}{\@@_box_use_rotate:Nn} % Rotating using \texttt{dvips} does not require that the box dimensions % are altered and has a very convenient built-in operation. Zero rotation % must be written as |0| not |-0| so there is a quick test. % \begin{macrocode} \cs_new_protected:Npn \driver_box_use_rotate:Nn #1#2 + { \exp_args:NNf \@@_box_use_rotate:Nn #1 { \fp_eval:n {#2} } } +\cs_new_protected:Npn \@@_box_use_rotate:Nn #1#2 { \@@_scope_begin: - \@@_literal:n + \@@_align_currentpoint_begin: + \@@_literal_postscript:x { \fp_compare:nNnTF {#2} = \c_zero_fp { 0 } - { \fp_eval:n { round ( -#2 , 5 ) } } ~ + { \fp_eval:n { round ( -(#2) , 5 ) } } ~ rotate } + \@@_align_currentpoint_end: \box_use:N #1 \@@_scope_end: } % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}{\driver_box_use_scale:Nnn} % The \texttt{dvips} driver once again has a dedicated operation we can @@ -823,12 +890,14 @@ \cs_new_protected:Npn \driver_box_use_scale:Nnn #1#2#3 { \@@_scope_begin: - \@@_literal:n + \@@_align_currentpoint_begin: + \@@_literal_postscript:x { \fp_eval:n { round ( #2 , 5 ) } ~ \fp_eval:n { round ( #3 , 5 ) } ~ scale } + \@@_align_currentpoint_end: \hbox_overlap_right:n { \box_use:N #1 } \@@_scope_end: } @@ -849,21 +918,17 @@ % sizes here. % \begin{macrocode} \cs_new_protected:Npn \@@_image_include_eps:n #1 - { - \tex_special:D { PSfile = #1 } - } + { \@@_literal:n { PSfile = #1 } } % \end{macrocode} % \end{macro} % % \subsection{Drawing} % % \begin{macro}{\@@_draw_literal:n, \@@_draw_literal:x} -% Literals with no positioning (using |ps:| each one is positioned but -% cut off from everything else, so no good for the stepwise approach needed -% here). +% The same as literal PostScript: same arguments about positioning apply +% her. % \begin{macrocode} -\cs_new_protected:Npn \@@_draw_literal:n #1 - { \tex_special:D { ps:: #1 } } +\cs_new_eq:NN \@@_draw_literal:n \@@_literal_postscript:n \cs_generate_variant:Nn \@@_draw_literal:n { x } % \end{macrocode} % \end{macro} @@ -873,22 +938,25 @@ % continue on to a matching |ps::[end]|: contrast with |ps:|, which positions % but where we can't split material between separate calls. The % |@beginspecial|/|@endspecial| pair are from |special.pro| and correct the -% scale and $y$-axis direction. The reference point at the start of the box -% is saved (as |l3x|/|l3y|) as it is needed when inserting various items. +% scale and $y$-axis direction. The definition of |/l3fc| deals with fill +% color in paths. In contrast to \pkg{pgf}, we don't save the current point: +% discussion with Tom Rokici suggested a better way to handle the necessary +% translations (see \cs{driver_draw_box_use:Nnnnn}). (Note that +% |@beginspecial|/|@endspecial| forms a driver scope.) The |[begin]|/^^A +% |[end]| lines are handled differently from the rest as they are +% conceptually different: not really drawing literals but instructions to +% \texttt{dvips} itself. % \begin{macrocode} \cs_new_protected:Npn \driver_draw_begin: { - \@@_draw_literal:n { [begin] } - \@@_draw_literal:n { save } - \@@_draw_literal:n { /l3x~currentpoint~/l3y~exch~def~def } + \@@_literal:n { ps::[begin] } \@@_draw_literal:n { @beginspecial } \@@_draw_literal:n { /l3fc~{ }~def } } \cs_new_protected:Npn \driver_draw_end: { \@@_draw_literal:n { @endspecial } - \@@_draw_literal:n { restore } - \@@_draw_literal:n { [end] } + \@@_literal:n { ps::[end] } } % \end{macrocode} % \end{macro} @@ -917,12 +985,18 @@ \cs_new_protected:Npn \driver_draw_moveto:nn #1#2 { \@@_draw_literal:x - { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ moveto } + { + \dim_to_decimal_in_bp:n {#1} ~ + \dim_to_decimal_in_bp:n {#2} ~ moveto + } } \cs_new_protected:Npn \driver_draw_lineto:nn #1#2 { \@@_draw_literal:x - { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ lineto } + { + \dim_to_decimal_in_bp:n {#1} ~ + \dim_to_decimal_in_bp:n {#2} ~ lineto + } } \cs_new_protected:Npn \driver_draw_rectangle:nnnn #1#2#3#4 { @@ -984,7 +1058,7 @@ { \@@_draw_literal:n { closepath } } \cs_new_protected:Npn \driver_draw_stroke: { - \@@_draw_literal:n { stroke } + \@@_draw_literal:n { stroke } \bool_if:NT \g_@@_draw_clip_bool { \@@_draw_literal:x @@ -1064,7 +1138,7 @@ % \end{variable} % \end{macro} % -% \begin{macro}{\driver_draw_cap_dash:nn} +% \begin{macro}{\driver_draw_dash_pattern:nn} % \begin{macro}{\@@_draw_dash:n} % \begin{macro}{\driver_draw_linewidth:n} % \begin{macro}{\driver_draw_miterlimit:n} @@ -1076,25 +1150,26 @@ % Converting paths to output is again a case of mapping directly to % PostScript operations. % \begin{macrocode} -\cs_new_protected:Npn \driver_draw_cap_dash:nn #1#2 +\cs_new_protected:Npn \driver_draw_dash_pattern:nn #1#2 { \@@_draw_literal:x { - [ ~ - \clist_map_function:nN {#1} \@@_draw_dash:n + [ + \exp_args:Nf \use:n + { \clist_map_function:nN {#1} \@@_draw_dash:n } ] ~ \dim_to_decimal_in_bp:n {#2} ~ setdash } } \cs_new:Npn \@@_draw_dash:n #1 - { \dim_to_decimal_in_bp:n {#1} ~ } + { ~ \dim_to_decimal_in_bp:n {#1} } \cs_new_protected:Npn \driver_draw_linewidth:n #1 { \@@_draw_literal:x { \dim_to_decimal_in_bp:n {#1} ~ setlinewidth } } \cs_new_protected:Npn \driver_draw_miterlimit:n #1 - { \@@_draw_literal:n { #1 ~ setmiterlimit } } + { \@@_draw_literal:x { \fp_eval:n {#1} ~ setmiterlimit } } \cs_new_protected:Npn \driver_draw_cap_butt: { \@@_draw_literal:n { 0 ~ setlinecap } } \cs_new_protected:Npn \driver_draw_cap_round: @@ -1114,7 +1189,6 @@ % \end{macro} % \end{macro} % -% % \begin{macro} % { % \driver_draw_color_fill_cmyk:nnnn , @@ -1130,31 +1204,57 @@ % \driver_draw_color_fill_rgb:nnn , % \driver_draw_color_stroke_rgb:nnn % } -% \begin{macro}{\@@_draw_color_fill:n, \@@_draw_color_stroke:n} +% \begin{macro} +% { +% \@@_draw_color_fill:n, \@@_draw_color_fill:x, +% \@@_draw_color_stroke:n, \@@_draw_color_stroke:x +% } % For \texttt{dvips}, we can use the standard color stack to deal with % stroke color, but for fills have to switch to raw PostScript. This is % thus not handled by the stack, but the context is very restricted. See % also how fills are implemented. % \begin{macrocode} \cs_new_protected:Npn \driver_draw_color_fill_cmyk:nnnn #1#2#3#4 - { \@@_draw_fill:n { #1 ~ #2 ~ #3 ~ #4 ~ setcmykcolor } } + { + \@@_draw_color_fill:x + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} ~ + setcmykcolor + } + } \cs_new_protected:Npn \driver_draw_color_stroke_cmyk:nnnn #1#2#3#4 - { \@@_draw_stroke:n { cmyk ~ #1 ~ #2 ~ #3 ~ #4 } } + { + \@@_draw_color_stroke:x + { + cmyk ~ + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} + } + } \cs_new_protected:Npn \driver_draw_color_fill_gray:n #1 - { \@@_draw_fill:n { #1 ~ setgray } } + { \@@_draw_color_fill:x { \fp_eval:n {#1} ~ setgray } } \cs_new_protected:Npn \driver_draw_color_stroke_gray:n #1 - { \@@_draw_stroke:n { gray ~ #1 } } + { \@@_draw_color_stroke:x { gray ~ \fp_eval:n {#1} } } \cs_new_protected:Npn \driver_draw_color_fill_rgb:nnn #1#2#3 - { \@@_draw_fill:n { #1 ~ #2 ~ #3 ~ setrgbcolor } } + { + \@@_draw_color_fill:x + { \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ setrgbcolor } + } \cs_new_protected:Npn \driver_draw_color_stroke_rgb:nnn #1#2#3 - { \@@_draw_stroke:n { rgb ~ #1 ~ #2 ~ #3 } } + { + \@@_draw_color_stroke:x + { rgb ~ \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} } + } \cs_new_protected:Npn \@@_draw_color_fill:n #1 { \@@_draw_literal:n { /l3fc ~ { #1 } ~ def } } +\cs_generate_variant:Nn \@@_draw_color_fill:n { x } \cs_new_protected:Npn \@@_draw_color_stroke:n #1 { - \tex_special:D { color~push~#1 } + \@@_literal:n { color~push~#1 } \group_insert_after:N \@@_color_reset: } +\cs_generate_variant:Nn \@@_draw_color_stroke:n { x } % \end{macrocode} % \end{macro} % \end{macro} @@ -1169,31 +1269,55 @@ % path available and simply dump the matrix as given. % \begin{macrocode} \cs_new_protected:Npn \driver_draw_cm:nnnn #1#2#3#4 - { \@@_draw_literal:n { [#1 ~ #2 ~ #3 ~ #4 ~ 0 ~ 0 ] ~ concat } } + { + \@@_draw_literal:n + { + [ + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} ~ + 0 ~ 0 + ] ~ + concat + } + } % \end{macrocode} % \end{macro} % % \begin{macro}{\driver_draw_box_use:Nnnnn} % Inside a picture |@beginspecial|/|@endspecial| are active, which is % normally a good thing but means that the position and scaling would be off -% if the box was inserted directly. Instead, we need to reverse the effect of -% the (normally desirable) shift/scaling within the box. That requires -% knowing where the reference point for the drawing is: saved as |l3x|/|l3y| -% at the start of the picture. Transformation here is relative to the -% drawing origin so has to be done purely in driver code not using \TeX{} -% offsets. +% if the box was inserted directly. To deal with that, there are a number of +% possible approaches. The implementation here was suggested by Tom Rokici +% (author of \texttt{dvips}). We end the current special placement, then +% set the current point with a literal |[begin]|. As for general +% literals, we then use the stack to store the current point and move to +% it. To insert the required transformation, we have to flip the $y$-axis, +% once before and once after it. Then we get back to the \TeX{} reference +% point to insert our content. The clean up has to happen in the right +% places, hence the |[begin]|/|[end]| pair around |restore|. Finally, +% we can return to \enquote{normal} drawing mode. Notice that the set up +% here is very similar to that in \cs{@@_align_currentpoint_\ldots}, but +% the ordering of saving and restoring is different (intermixed). % \begin{macrocode} \cs_new_protected:Npn \driver_draw_box_use:Nnnnn #1#2#3#4#5 { - \@@_scope_begin: + \@@_draw_literal:n { @endspecial } \@@_draw_literal:n { [end] } + \@@_draw_literal:n { [begin] } + \@@_draw_literal:n { save } + \@@_draw_literal:n { currentpoint } + \@@_draw_literal:n { currentpoint~translate } + \driver_draw_cm:nnnn { 1 } { 0 } { 0 } { -1 } \driver_draw_cm:nnnn {#2} {#3} {#4} {#5} - \@@_draw_literal:n { 72~Resolution~div~72~VResolution~div~neg~scale } - \@@_draw_literal:n { magscale~{1~DVImag~div~dup~scale}~if } - \@@_draw_literal:n { l3x~neg~l3y~neg~translate } + \driver_draw_cm:nnnn { 1 } { 0 } { 0 } { -1 } + \@@_draw_literal:n { neg~exch~neg~exch~translate } + \@@_draw_literal:n { [end] } \hbox_overlap_right:n { \box_use:N #1 } \@@_draw_literal:n { [begin] } - \@@_scope_end: + \@@_draw_literal:n { restore } + \@@_draw_literal:n { [end] } + \@@_draw_literal:n { [begin] } + \@@_draw_literal:n { @beginspecial } } % \end{macrocode} % \end{macro} @@ -1209,27 +1333,28 @@ % \end{macrocode} % % The direct PDF driver covers both \pdfTeX{} and \LuaTeX{}. The latter -% renames/restructures the driver primitives but this can be handled +% renames and restructures the driver primitives but this can be handled % at one level of abstraction. As such, we avoid using two separate drivers % for this material at the cost of some \texttt{x}-type definitions to get % everything expanded up-front. % % \subsubsection{Basics} % -% \begin{macro}{\@@_literal:n} +% \begin{macro}{\@@_literal_pdf:n, \@@_literal_pdf:x} % This is equivalent to \verb|\special{pdf:}| but the engine can % track it. Without the \texttt{direct} keyword everything is kept in % sync: the transformation matrix is set to the current point automatically. % Note that this is still inside the text (\texttt{BT} \dots \texttt{ET} % block). % \begin{macrocode} -\cs_new_protected:Npx \@@_literal:n #1 +\cs_new_protected:Npx \@@_literal_pdf:n #1 { \cs_if_exist:NTF \luatex_pdfextension:D { \luatex_pdfextension:D literal } { \pdftex_pdfliteral:D } - {#1} + { \exp_not:N \exp_not:n {#1} } } +\cs_generate_variant:Nn \@@_literal_pdf:n { x } % \end{macrocode} % \end{macro} % @@ -1251,7 +1376,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_matrix:n} +% \begin{macro}{\@@_matrix:n, \@@_matrix:x} % Here the appropriate function is set up to insert an affine matrix % into the PDF. With \pdfTeX{} and \LuaTeX{} in direct PDF output mode there % is a primitive for this, which only needs the rotation/scaling/skew part. @@ -1261,8 +1386,9 @@ \cs_if_exist:NTF \luatex_pdfextension:D { \luatex_pdfextension:D setmatrix } { \pdftex_pdfsetmatrix:D } - {#1} + { \exp_not:N \exp_not:n {#1} } } +\cs_generate_variant:Nn \@@_matrix:n { x } % \end{macrocode} % \end{macro} % @@ -1280,7 +1406,7 @@ \cs_new_protected:Npn \driver_box_use_clip:N #1 { \@@_scope_begin: - \@@_literal:n + \@@_literal_pdf:x { 0~ \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~ @@ -1296,6 +1422,7 @@ % \end{macro} % % \begin{macro}{\driver_box_use_rotate:Nn} +% \begin{macro}{\@@_box_use_rotate:Nn} % \begin{variable}{\l_@@_cos_fp, \l_@@_sin_fp} % Rotations are set using an affine transformation matrix which therefore % requires sine/cosine values not the angle itself. We store the rounded @@ -1305,6 +1432,8 @@ % after rounding. % \begin{macrocode} \cs_new_protected:Npn \driver_box_use_rotate:Nn #1#2 + { \exp_args:NNf \@@_box_use_rotate:Nn #1 { \fp_eval:n {#2} } } +\cs_new_protected:Npn \@@_box_use_rotate:Nn #1#2 { \@@_scope_begin: \box_set_wd:Nn #1 { 0pt } @@ -1312,7 +1441,7 @@ \fp_compare:nNnT \l_@@_cos_fp = \c_zero_fp { \fp_zero:N \l_@@_cos_fp } \fp_set:Nn \l_@@_sin_fp { round ( sind ( #2 ) , 5 ) } - \@@_matrix:n + \@@_matrix:x { \fp_use:N \l_@@_cos_fp \c_space_tl \fp_compare:nNnTF \l_@@_sin_fp = \c_zero_fp @@ -1333,6 +1462,7 @@ % \end{macrocode} % \end{variable} % \end{macro} +% \end{macro} % % \begin{macro}{\driver_box_use_scale:Nnn} % The same idea as for rotation but without the complexity of signs and @@ -1341,7 +1471,7 @@ \cs_new_protected:Npn \driver_box_use_scale:Nnn #1#2#3 { \@@_scope_begin: - \@@_matrix:n + \@@_matrix:x { \fp_eval:n { round ( #2 , 5 ) } ~ 0~0~ @@ -1482,14 +1612,13 @@ % % \subsubsection{Basics} % -% \begin{macro}{\@@_literal:n} +% \begin{macro}{\@@_literal_pdf:n, \@@_literal_pdf:x} % Equivalent to \texttt{pdf:content} but favored as the link to -% the \pdfTeX{} primitive approach is clearer. Some higher-level operations -% use |\tex_special:D| directly: see the later comments on where this is -% useful. +% the \pdfTeX{} primitive approach is clearer. % \begin{macrocode} -\cs_new_protected:Npn \@@_literal:n #1 - { \tex_special:D { pdf:literal~ #1 } } +\cs_new_protected:Npn \@@_literal_pdf:n #1 + { \@@_literal:n { pdf:literal~ #1 } } +\cs_generate_variant:Nn \@@_literal_pdf:n { x } % \end{macrocode} % \end{macro} % @@ -1497,9 +1626,9 @@ % Scoping is done using the driver-specific specials. % \begin{macrocode} \cs_new_protected:Npn \@@_scope_begin: - { \tex_special:D { x:gsave } } + { \@@_literal:n { x:gsave } } \cs_new_protected:Npn \@@_scope_end: - { \tex_special:D { x:grestore } } + { \@@_literal:n { x:grestore } } % \end{macrocode} % \end{macro} % @@ -1512,7 +1641,7 @@ \cs_new_protected:Npn \driver_box_use_clip:N #1 { \@@_scope_begin: - \@@_literal:n + \@@_literal_pdf:x { 0~ \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~ @@ -1528,18 +1657,21 @@ % \end{macro} % % \begin{macro}{\driver_box_use_rotate:Nn} +% \begin{macro}{\@@_box_use_rotate:Nn} % Rotating in \texttt{(x)}dvipdmfx can be implemented using either PDF or % driver-specific code. The former approach however is not \enquote{aware} % of the content of boxes: this means that any embedded links would not be -% adjusted by the rotation. As such, the driver-native approach is prefered: +% adjusted by the rotation. As such, the driver-native approach is preferred: % the code therefore is similar (though not identical) to the \texttt{dvips} % version (notice the rotation angle here is positive). As for % \texttt{dvips}, zero rotation is written as |0| not |-0|. % \begin{macrocode} \cs_new_protected:Npn \driver_box_use_rotate:Nn #1#2 + { \exp_args:NNf \@@_box_use_rotate:Nn #1 { \fp_eval:n {#2} } } +\cs_new_protected:Npn \@@_box_use_rotate:Nn #1#2 { \@@_scope_begin: - \tex_special:D + \@@_literal:x { x:rotate~ \fp_compare:nNnTF {#2} = \c_zero_fp @@ -1551,6 +1683,7 @@ } % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}{\driver_box_use_scale:Nnn} % Much the same idea for scaling: use the higher-level driver operation to allow @@ -1559,7 +1692,7 @@ \cs_new_protected:Npn \driver_box_use_scale:Nnn #1#2#3 { \@@_scope_begin: - \tex_special:D + \@@_literal:x { x:scale~ \fp_eval:n { round ( #2 , 5 ) } ~ @@ -1622,7 +1755,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_image_include_eps:n #1 { - \tex_special:D { PSfile = #1 } + \@@_literal:n { PSfile = #1 } } \cs_new_protected:Npn \@@_image_include_jpg:n #1 { \@@_image_include_auxi:nn {#1} { image } } @@ -1656,7 +1789,7 @@ { \int_if_exist:cTF { c_@@_image_ #2#1 _int } { - \tex_special:D + \@@_literal:x { pdf:usexobj~@image \int_use:c { c_@@_image_ #2#1 _int } } } { \@@_image_include_auxiii:nn {#2} {#1} {#3} } @@ -1672,7 +1805,7 @@ { \int_gincr:N \g_@@_image_int \int_const:cn { c_@@_image_ #1#2 _int } { \g_@@_image_int } - \tex_special:D + \@@_literal:x { pdf:#3~ @image \int_use:c { c_@@_image_ #1#2 _int } @@ -1827,7 +1960,7 @@ % \begin{macro}{\@@_draw_literal:n, \@@_draw_literal:x} % Pass data through using a dedicated interface. % \begin{macrocode} -\cs_new_eq:NN \@@_draw_literal:n \@@_literal:n +\cs_new_eq:NN \@@_draw_literal:n \@@_literal_pdf:n \cs_generate_variant:Nn \@@_draw_literal:n { x } % \end{macrocode} % \end{macro} @@ -1843,13 +1976,10 @@ % \end{macro} % % \begin{macro}{\driver_draw_scope_begin:, \driver_draw_scope_end:} -% In contrast to a general scope, a drawing scope is always done using -% the PDF operators so is the same for all relevant drivers. +% Use the driver-level scope mechanisms. % \begin{macrocode} -\cs_new_protected:Npn \driver_draw_scope_begin: - { \@@_draw_literal:n { q } } -\cs_new_protected:Npn \driver_draw_scope_end: - { \@@_draw_literal:n { Q } } +\cs_new_eq:NN \driver_draw_scope_begin: \@@_scope_begin: +\cs_new_eq:NN \driver_draw_scope_end: \@@_scope_end: % \end{macrocode} % \end{macro} % @@ -1857,9 +1987,7 @@ % \begin{macro}{\driver_draw_curveto:nnnnnn} % \begin{macro}{\driver_draw_rectangle:nnnn} % Path creation operations all resolve directly to PDF primitive steps, with -% only the need to convert to \texttt{bp}. Notice that \texttt{x}-type -% expansion is included here to ensure that any variable values are -% forced to literals before any possible caching. +% only the need to convert to \texttt{bp}. % \begin{macrocode} \cs_new_protected:Npn \driver_draw_moveto:nn #1#2 { @@ -1947,7 +2075,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\driver_draw_cap_dash:nn} +% \begin{macro}{\driver_draw_dash_pattern:nn} % \begin{macro}{\@@_draw_dash:n} % \begin{macro}{\driver_draw_linewidth:n} % \begin{macro}{\driver_draw_miterlimit:n} @@ -1959,25 +2087,26 @@ % Converting paths to output is again a case of mapping directly to % PDF operations. % \begin{macrocode} -\cs_new_protected:Npn \driver_draw_cap_dash:nn #1#2 +\cs_new_protected:Npn \driver_draw_dash_pattern:nn #1#2 { \@@_draw_literal:x { - [ ~ - \clist_map_function:nN {#1} \@@_draw_dash:n + [ + \exp_args:Nf \use:n + { \clist_map_function:nN {#1} \@@_draw_dash:n } ] ~ \dim_to_decimal_in_bp:n {#2} ~ d } } \cs_new:Npn \@@_draw_dash:n #1 - { \dim_to_decimal_in_bp:n {#1} ~ } + { ~ \dim_to_decimal_in_bp:n {#1} } \cs_new_protected:Npn \driver_draw_linewidth:n #1 { \@@_draw_literal:x { \dim_to_decimal_in_bp:n {#1} ~ w } } \cs_new_protected:Npn \driver_draw_miterlimit:n #1 - { \@@_draw_literal:x { #1 ~ M } } + { \@@_draw_literal:x { \fp_eval:n {#1} ~ M } } \cs_new_protected:Npn \driver_draw_cap_butt: { \@@_draw_literal:n { 0 ~ J } } \cs_new_protected:Npn \driver_draw_cap_round: @@ -2012,33 +2141,56 @@ % \driver_draw_color_fill_rgb:nnn , % \driver_draw_color_stroke_rgb:nnn % } +% \begin{macro}{\@@_color_fill_select:n, \@@_color_fill_select:x} % For the stroke color, all engines here can use the color stack to handle % the setting. However, that is not the case for fill color: the stack in % \texttt{(x)dvipdfmx} only covers one type of color. So we have to use % different approaches for the two sets of engines. % \begin{macrocode} \cs_new_protected:Npn \driver_draw_color_fill_cmyk:nnnn #1#2#3#4 - { \@@_color_fill_select:n { #1 ~ #2 ~ #3 ~ #4 ~ k } } + { + \@@_color_fill_select:x + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} ~ + k + } + } \cs_new_protected:Npn \driver_draw_color_stroke_cmyk:nnnn #1#2#3#4 - { \@@_color_select:n { #1 ~ #2 ~ #3 ~ #4 ~ K } } + { + \@@_color_select:x + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} ~ + k + } + } \cs_new_protected:Npn \driver_draw_color_fill_gray:n #1 - { \@@_color_fill_select:n { #1 ~ g } } + { \@@_color_fill_select:x { \fp_eval:n {#1} ~ g } } \cs_new_protected:Npn \driver_draw_color_stroke_gray:n #1 - { \@@_color_select:n { #1 ~ G } } + { \@@_color_select:x { \fp_eval:n {#1} ~ G } } \cs_new_protected:Npn \driver_draw_color_fill_rgb:nnn #1#2#3 - { \@@_color_fill_select:n { #1 ~ #2 ~ #3 ~ rg } } + { + \@@_color_fill_select:x + { \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ rg } + } \cs_new_protected:Npn \driver_draw_color_stroke_rgb:nnn #1#2#3 - { \@@_color_select:n { #1 ~ #2 ~ #3 ~ RG } } + { + \@@_color_select:x + { \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ RG } + } %<*pdfmode> \cs_new_eq:NN \@@_color_fill_select:n \@@_color_select:n %</pdfmode> %<*dvipdfmx|xdvipdfmx> \cs_new_eq:NN \@@_color_fill_select:n \@@_draw_literal:n %</dvipdfmx|xdvipdfmx> +\cs_generate_variant:Nn \@@_color_fill_select:n { x } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\driver_draw_cm:nnnn} % \begin{macro}{\@@_draw_cm:nnnn} @@ -2053,7 +2205,11 @@ \cs_new_protected:Npn \driver_draw_cm:nnnn #1#2#3#4 { %<*pdfmode> - \@@_matrix:n { #1 ~ #2 ~ #3 ~ #4 } + \@@_matrix:x + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} + } %</pdfmode> %<*dvipdfmx|xdvipdfmx> \@@_draw_cm_decompose:nnnnN {#1} {#2} {#3} {#4} @@ -2063,20 +2219,20 @@ %<*dvipdfmx|xdvipdfmx> \cs_new_protected:Npn \@@_draw_cm:nnnn #1#2#3#4 { - \tex_special:D + \@@_literal:x { x:rotate~ \fp_compare:nNnTF {#1} = \c_zero_fp { 0 } { \fp_eval:n { round ( -#1 , 5 ) } } } - \tex_special:D + \@@_literal:x { x:scale~ \fp_eval:n { round ( #2 , 5 ) } ~ \fp_eval:n { round ( #3 , 5 ) } } - \tex_special:D + \@@_literal:x { x:rotate~ \fp_compare:nNnTF {#4} = \c_zero_fp @@ -2207,11 +2363,17 @@ \driver_draw_cm:nnnn {#2} {#3} {#4} {#5} %</pdfmode> %<*dvipdfmx|xdvipdfmx> - \tex_special:D { pdf:btrans~matrix~ #2 ~ #3 ~ #4 ~ #5 ~ 0 ~ 0 } + \@@_literal:x + { + pdf:btrans~matrix~ + \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ + \fp_eval:n {#4} ~ \fp_eval:n {#5} ~ + 0 ~ 0 + } %</dvipdfmx|xdvipdfmx> \hbox_overlap_right:n { \box_use:N #1 } %<*dvipdfmx|xdvipdfmx> - \tex_special:D { pdf:etrans } + \@@_literal:n { pdf:etrans } %</dvipdfmx|xdvipdfmx> \@@_scope_end: } @@ -2230,15 +2392,16 @@ % % \subsubsection{Basics} % -% \begin{macro}{\@@_literal:n} +% \begin{macro}{\@@_literal_svg:n, \@@_literal_svg:x} % Unlike the other drivers, the requirements for making SVG files mean % that we can't conveniently transform all operations to the current point. % That makes life a bit more tricky later as that needs to be accounted for. % A new line is added after each call to help to keep the output readable % for debugging. % \begin{macrocode} -\cs_new_protected:Npn \@@_literal:n #1 - { \tex_special:D { dvisvgm:raw~ #1 { ?nl } } } +\cs_new_protected:Npn \@@_literal_svg:n #1 + { \@@_literal:n { dvisvgm:raw~ #1 { ?nl } } } +\cs_generate_variant:Nn \@@_literal_svg:n { x } % \end{macrocode} % \end{macro} % @@ -2247,22 +2410,23 @@ % operations have to be \enquote{tied} to these not simply inside them. % \begin{macrocode} \cs_new_protected:Npn \@@_scope_begin: - { \@@_literal:n { <g> } } + { \@@_literal_svg:n { <g> } } \cs_new_protected:Npn \@@_scope_end: - { \@@_literal:n { </g> } } + { \@@_literal_svg:n { </g> } } % \end{macrocode} % \end{macro} % % \subsection{Driver-specific auxiliaries} % -% \begin{macro}{\@@_scope_begin:n} +% \begin{macro}{\@@_scope_begin:n, \@@_scope_begin:x} % In SVG transformations, clips and so on are attached directly to scopes so % we need a way or allowing for that. This is rather more useful than % \cs{@@_scope_begin:} as a result. No assumptions are made about the nature % of the scoped operation(s). % \begin{macrocode} \cs_new_protected:Npn \@@_scope_begin:n #1 - { \@@_literal:n { <g~ #1 > } } + { \@@_literal_svg:n { <g~ #1 > } } +\cs_generate_variant:Nn \@@_scope_begin:n { x } % \end{macrocode} % \end{macro} % @@ -2282,9 +2446,9 @@ \cs_new_protected:Npn \driver_box_use_clip:N #1 { \int_gincr:N \g_@@_clip_path_int - \@@_literal:n + \@@_literal_svg:x { < clipPath~id = " l3cp \int_use:N \g_@@_clip_path_int " > } - \@@_literal:n + \@@_literal_svg:x { < path ~ d = @@ -2301,7 +2465,7 @@ " /> } - \@@_literal:n + \@@_literal_svg:n { < /clipPath > } % \end{macrocode} % In general the SVG set up does not try to transform coordinates to the @@ -2319,9 +2483,10 @@ scale ( 1 , -1 ) " } - \@@_scope_begin:n + \@@_scope_begin:x { - clip-path = "url ( \c_hash_str l3cp \int_use:N \g_@@_clip_path_int ) " + clip-path = + "url ( \c_hash_str l3cp \int_use:N \g_@@_clip_path_int ) " } \@@_scope_begin:n { @@ -2350,12 +2515,12 @@ % \begin{macrocode} \cs_new_protected:Npn \driver_box_use_rotate:Nn #1#2 { - \@@_scope_begin:n + \@@_scope_begin:x { transform = " rotate - ( \fp_eval:n { round ( -#2 , 5 ) } , ~ { ?x } , ~ { ?y } ) + ( \fp_eval:n { round ( -(#2) , 5 ) } , ~ { ?x } , ~ { ?y } ) " } \box_use:N #1 @@ -2371,7 +2536,7 @@ % \begin{macrocode} \cs_new_protected:Npn \driver_box_use_scale:Nnn #1#2#3 { - \@@_scope_begin:n + \@@_scope_begin:x { transform = " @@ -2412,7 +2577,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_image_include_png:n #1 { - \tex_special:D + \@@_literal:x { dvisvgm:img~ \dim_to_decimal:n { \l_image_ury_dim } ~ @@ -2421,7 +2586,8 @@ } } \cs_new_eq:NN \@@_image_include_jpg:n \@@_image_include_png:n -\cs_new:Npn \@@_image_include_bitmap_quote:w #1 " #2 " #3 \q_stop { #1#2 } +\cs_new:Npn \@@_image_include_bitmap_quote:w #1 " #2 " #3 \q_stop + { #1#2 } % \end{macrocode} % \end{macro} % \end{macro} @@ -2431,7 +2597,7 @@ % \begin{macro}{\@@_draw_literal:n, \@@_draw_literal:x} % The same as the more general literal call. % \begin{macrocode} -\cs_new_eq:NN \@@_draw_literal:n \@@_literal:n +\cs_new_eq:NN \@@_draw_literal:n \@@_literal_svg:n \cs_generate_variant:Nn \@@_draw_literal:n { x } % \end{macrocode} % \end{macro} @@ -2655,7 +2821,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\driver_draw_cap_dash:nn} +% \begin{macro}{\driver_draw_dash_pattern:nn} % \begin{macro}{\@@_draw_dash:n} % \begin{macro}{\@@_draw_dash_aux:nn} % \begin{macro}{\driver_draw_linewidth:n} @@ -2669,7 +2835,7 @@ % complexity is converting the dash array properly (doing any required % maths). % \begin{macrocode} -\cs_new_protected:Npn \driver_draw_cap_dash:nn #1#2 +\cs_new_protected:Npn \driver_draw_dash_pattern:nn #1#2 { \use:x { @@ -2696,7 +2862,7 @@ \cs_new_protected:Npn \driver_draw_linewidth:n #1 { \@@_draw_scope:x { stroke-width=" \dim_to_decimal:n {#1} " } } \cs_new_protected:Npn \driver_draw_miterlimit:n #1 - { \@@_draw_scope:x { stroke-miterlimit=" #1 " } } + { \@@_draw_scope:x { stroke-miterlimit=" \fp_eval:n {#1} " } } \cs_new_protected:Npn \driver_draw_cap_butt: { \@@_draw_scope:n { stroke-linecap="butt" } } \cs_new_protected:Npn \driver_draw_cap_round: @@ -2813,16 +2979,16 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\driver_draw_hbox:Nnnnnnn} +% \begin{macro}{\driver_draw_box_use:Nnnnn} % No special savings can be made here: simply displace the box inside % a scope. As there is nothing to re-box, just make the box passed of % zero size. % \begin{macrocode} -\cs_new_protected:Npn \driver_draw_hbox:Nnnnnnn #1#2#3#4#5#6#7 +\cs_new_protected:Npn \driver_draw_box_use:Nnnnn #1#2#3#4#5#6#7 { \@@_scope_begin: \driver_draw_cm:nnnn {#2} {#3} {#4} {#5} - \@@_literal:n + \@@_literal_svg:n { < g~ stroke="none"~ @@ -2833,7 +2999,7 @@ \box_set_ht:Nn #1 { 0pt } \box_set_dp:Nn #1 { 0pt } \box_use:N #1 - \@@_literal:n { </g> } + \@@_literal_svg:n { </g> } \@@_scope_end: } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx index 871763ed5fe..46c4acf4cec 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -246,8 +246,14 @@ % \begin{quote} % |\example:f { \int_eval:n { 1 + 2 } , \int_eval:n { 3 + 4 } }| % \end{quote} -% results in the call |\example:n { 3 , \int_eval:n { 3 + 4 } }| -% while using |\example:x| instead results in |\example:n { 3 , 7 }| +% results in the call +% \begin{quote} +% |\example:n { 3 , \int_eval:n { 3 + 4 } }| +% \end{quote} +% while using |\example:x| instead results in +% \begin{quote} +% |\example:n { 3 , 7 }| +% \end{quote} % at the cost of being protected. % If you use this type of expansion in conditional processing then % you should stick to using |TF| type functions only as the expansion @@ -284,14 +290,20 @@ % \end{syntax} % This function absorbs two arguments (the \meta{function} name and % the \meta{tokens}). The \meta{tokens} are expanded until only characters -% remain, and are then turned into a control sequence. (An internal error -% occurs if non-characters remain, as the conversion is not possible.) +% remain, and are then turned into a control sequence. % The result is inserted into the input stream \emph{after} reinsertion % of the \meta{function}. Thus the \meta{function} may take more than % one argument: all others are left unchanged. % % The |:cc| variant constructs the \meta{function} name in the same % manner as described for the \meta{tokens}. +% \begin{texnote} +% Protected macros that appear in a \texttt{c}-type argument are +% expanded despite being protected; \cs{exp_not:n} also has no +% effect. An internal error occurs if non-characters or active +% characters remain after full expansion, as the conversion to a +% control sequence is not possible. +% \end{texnote} % \end{function} % % \begin{function}[EXP]{\exp_args:No} @@ -322,13 +334,19 @@ % \end{syntax} % This function absorbs two arguments (the \meta{function} name and % the \meta{tokens}). The \meta{tokens} are expanded until only characters -% remain, and are then turned into a control sequence. (An internal error -% occurs if non-characters remain, as the conversion is not possible.) +% remain, and are then turned into a control sequence. % This control sequence should % be the name of a \meta{variable}. The content of the \meta{variable} are % recovered and placed inside braces into the input stream \emph{after} % reinsertion of the \meta{function}. Thus the \meta{function} may take more % than one argument: all others are left unchanged. +% \begin{texnote} +% Protected macros that appear in a \texttt{v}-type argument are +% expanded despite being protected; \cs{exp_not:n} also has no +% effect. An internal error occurs if non-characters or active +% characters remain after full expansion, as the conversion to a +% control sequence is not possible. +% \end{texnote} % \end{function} % % \begin{function}[EXP]{\exp_args:Nf} @@ -587,10 +605,11 @@ % \begin{texnote} % This is the \TeX{} \tn{noexpand} primitive. It only prevents % expansion. At the beginning of an |f|-type argument, a space -% \meta{token} is removed despite \cs{exp_not:N}. In an -% |x|-expanding definition (\cs{cs_new:Npx}) a macro parameter -% \meta{token} (normally~|#|) denotes an argument despite -% \cs{exp_not:N} (see \cs{exp_not:n}). +% \meta{token} is removed even if it appears as \cs{exp_not:N} +% \cs{c_space_token}. In an |x|-expanding definition +% (\cs{cs_new:Npx}), a macro parameter introduces an argument even +% if it appears as \cs{exp_not:N} |#| |1|. This differs from +% \cs{exp_not:n}. % \end{texnote} % \end{function} % @@ -599,10 +618,16 @@ % \cs{exp_not:c} \Arg{tokens} % \end{syntax} % Expands the \meta{tokens} until only characters remain, and then -% converts this into a control sequence. (An internal error occurs if -% non-characters remain, as the conversion is not possible.) +% converts this into a control sequence. % Further expansion of this control sequence is then inhibited using % \cs{exp_not:N}. +% \begin{texnote} +% Protected macros that appear in a \texttt{c}-type argument are +% expanded despite being protected; \cs{exp_not:n} also has no +% effect. An internal error occurs if non-characters or active +% characters remain after full expansion, as the conversion to a +% control sequence is not possible. +% \end{texnote} % \end{function} % % \begin{function}[EXP]{\exp_not:n} @@ -610,13 +635,15 @@ % \cs{exp_not:n} \Arg{tokens} % \end{syntax} % Prevents expansion of the \meta{tokens} in an |x|-type argument. In -% other cases (input stream or |o| or |f| arguments) the \meta{tokens} -% continue being expanded. +% all other cases the \meta{tokens} continue to be expanded, for +% example in the input stream or in other types of arguments such as +% \texttt{c}, \texttt{f}, \texttt{v}. The argument of \cs{exp_not:n} +% \emph{must} be surrounded by braces. % \begin{texnote} -% This is the \eTeX{} \tn{unexpanded} primitive. Hence its argument -% \emph{must} be surrounded by braces. In an |x|-expanding -% definition (\cs{cs_new:Npx}), \cs{exp_not:n}~|{#}| inserts a macro -% parameter character in the replacement text. +% This is the \eTeX{} \tn{unexpanded} primitive. In an +% |x|-expanding definition (\cs{cs_new:Npx}), \cs{exp_not:n}~|{#1}| +% is equivalent to |##1| rather than to~|#1|, namely it inserts the +% two characters |#| and~|1|. % \end{texnote} % \end{function} % @@ -642,10 +669,16 @@ % \end{syntax} % Expands the \meta{tokens} until only characters remains, and then % converts this into a control sequence which should be a \meta{variable} -% name. (An internal error occurs if -% non-characters remain, as the conversion is not possible.) +% name. % The content of the \meta{variable} is recovered, and further % expansion in |x|-type arguments is prevented using \cs{exp_not:n}. +% \begin{texnote} +% Protected macros that appear in a \texttt{v}-type argument are +% expanded despite being protected; \cs{exp_not:n} also has no +% effect. An internal error occurs if non-characters or active +% characters remain after full expansion, as the conversion to a +% control sequence is not possible. +% \end{texnote} % \end{function} % % \begin{function}[EXP]{\exp_not:f} @@ -705,12 +738,12 @@ % \exp_end: % } % \begin{syntax} -% \cs{exp:w} \meta{expandable-tokens} \cs{exp_end:} \\ +% \cs{exp:w} \meta{expandable tokens} \cs{exp_end:} \\ % \end{syntax} % Expands \meta{expandable-tokens} until reaching \cs{exp_end:} at % which point expansion stops. -% The full expansion of \meta{expandable-tokens} has to be empty. -% If any token in \meta{expandable-tokens} or any token generated by +% The full expansion of \meta{expandable tokens} has to be empty. +% If any token in \meta{expandable tokens} or any token generated by % expanding the tokens therein is not expandable the expansion will end % prematurely and as a result \cs{exp_end:} will be misinterpreted % later on.\footnotemark @@ -724,6 +757,11 @@ %\end{verbatim} % where somewhere during the expansion of |\@@_case:NnTF| the % \cs{exp_end:} gets generated. +% \begin{texnote} +% The current implementation uses \tn{romannumeral} hence ignores +% space tokens and explicit signs |+| and |-| in the expansion of the +% \meta{expandable tokens}, but this should not be relied upon. +% \end{texnote} % \end{function} % \footnotetext{Due to the implementation you might get the character % in position 0 in the current font (typically \enquote{\texttt{`}}) @@ -797,21 +835,26 @@ % braces will not terminate the \texttt{f}-type expansion. % \end{function} % -% \section{Internal functions and variables} -% -% \begin{variable}{\l__exp_internal_tl} -% The |\exp_| module has its private variable to temporarily store the -% result of |x|-type argument expansion. This is done to avoid interference -% with other functions using temporary variables. -% \end{variable} +% \section{Internal functions} % % \begin{function}{\::n, \::N, \::p, \::c, \::o, \::f, \::x, \::v, \::V, \:::} % \begin{syntax} -% |\cs_set:Npn \exp_args:Ncof { \::c \::o \::f \::: }| +% |\cs_new:Npn \exp_args:Ncof { \::c \::o \::f \::: }| % \end{syntax} % Internal forms for the base expansion types. These names do \emph{not} % conform to the general \LaTeX3 approach as this makes them more readily -% visible in the log and so forth. +% visible in the log and so forth. They should not be used outside this module. +% \end{function} +% +% \begin{function} +% {\::o_unbraced, \::f_unbraced, \::x_unbraced, \::v_unbraced, \::V_unbraced} +% \begin{syntax} +% |\cs_new:Npn \exp_last_unbraced:Nno { \::n \::o_unbraced \::: }| +% \end{syntax} +% Internal forms for the expansion types which leave the terminal argument +% unbraced. These names do \emph{not} +% conform to the general \LaTeX3 approach as this makes them more readily +% visible in the log and so forth. They should not be used outside this module. % \end{function} % % \end{documentation} @@ -828,6 +871,12 @@ %<@@=exp> % \end{macrocode} % +% \begin{variable}{\l_@@_internal_tl} +% The |\exp_| module has its private variable to temporarily store the +% result of |x|-type argument expansion. This is done to avoid interference +% with other functions using temporary variables. +% \end{variable} +% % \begin{macro}{\exp_after:wN} % \begin{macro}{\exp_not:N} % \begin{macro}{\exp_not:n} @@ -963,11 +1012,13 @@ % % \begin{macro}{\::x} % This function is used to expand an argument fully. +% We build in the expansion of \cs{@@_arg_next:nnn}. % \begin{macrocode} \cs_new_protected:Npn \::x #1 \::: #2#3 { - \cs_set_nopar:Npx \l_@@_internal_tl { {#3} } - \exp_after:wN \@@_arg_next:nnn \l_@@_internal_tl {#1} {#2} + \cs_set_nopar:Npx \l_@@_internal_tl + { \exp_not:n { #1 \::: } { \exp_not:n {#2} {#3} } } + \l_@@_internal_tl } % \end{macrocode} % \end{macro} @@ -1450,26 +1501,34 @@ % % \subsection{Preventing expansion} % +% \begin{macro}{\__kernel_exp_not:w} +% At the kernel level, we need the primitive behaviour to allow expansion +% \emph{before} the brace group. +% \begin{macrocode} +\cs_new_eq:NN \__kernel_exp_not:w \etex_unexpanded:D +% \end{macrocode} +% \end{macro} +% % \begin{macro}[EXP]{\exp_not:c} % \begin{macro}[EXP]{\exp_not:o} % \begin{macro}[EXP]{\exp_not:f} % \begin{macro}[EXP]{\exp_not:V} % \begin{macro}[EXP]{\exp_not:v} -% All these except \cs{exp_not:c} call the primitive -% \cs{etex_unexpanded:D} namely \cs{exp_not:n}. +% All these except \cs{exp_not:c} call the kernel-internal +% \cs{__kernel_exp_not:w} namely \tn{etex_unexpanded:D}. % \begin{macrocode} \cs_new:Npn \exp_not:c #1 { \exp_after:wN \exp_not:N \cs:w #1 \cs_end: } -\cs_new:Npn \exp_not:o #1 { \etex_unexpanded:D \exp_after:wN {#1} } +\cs_new:Npn \exp_not:o #1 { \__kernel_exp_not:w \exp_after:wN {#1} } \cs_new:Npn \exp_not:f #1 { \etex_unexpanded:D \exp_after:wN { \exp:w \exp_end_continue_f:w #1 } } \cs_new:Npn \exp_not:V #1 { - \etex_unexpanded:D \exp_after:wN + \__kernel_exp_not:w \exp_after:wN { \exp:w \@@_eval_register:N #1 } } \cs_new:Npn \exp_not:v #1 { - \etex_unexpanded:D \exp_after:wN + \__kernel_exp_not:w \exp_after:wN { \exp:w \@@_eval_register:c {#1} } } % \end{macrocode} @@ -1524,10 +1583,15 @@ % \end{macrocode} % If the above definition ever appears outside its proper context % the active character |^^@| will be executed so we turn this into an -% error. +% error. The test for existence covers the (unlikely) case that some +% other code has already defined |^^@|: this is true for example for +% \texttt{xmltex.tex}. % \begin{macrocode} - \cs_new:Npn ^^@ - { \__kernel_msg_expandable_error:nn { kernel } { bad-exp-end-f } } + \if_cs_exist:N ^^@ + \else: + \cs_new:Npn ^^@ + { \__kernel_msg_expandable_error:nn { kernel } { bad-exp-end-f } } + \fi: % \end{macrocode} % The same but grabbing an argument to remove spaces and braces. % \begin{macrocode} @@ -1565,11 +1629,15 @@ \cs_new_protected:Npn \cs_generate_variant:Nn #1#2 { \@@_generate_variant:N #1 - \exp_after:wN \@@_split_function:NN - \exp_after:wN #1 - \exp_after:wN \@@_generate_variant:nnNN - \exp_after:wN #1 - \tl_to_str:n {#2} , \scan_stop: , \q_recursion_stop + \use:x + { + \@@_generate_variant:nnNN + \cs_split_function:N #1 + \exp_not:N #1 + \tl_to_str:n {#2} , + \exp_not:N \scan_stop: , + \exp_not:N \q_recursion_stop + } } \cs_new_protected:Npn \cs_generate_variant:cn { \exp_args:Nc \cs_generate_variant:Nn } @@ -1872,7 +1940,8 @@ #5 } } -\cs_new:Npn \@@_generate_variant_loop_special:NNwNNnn #1#2#3 \q_stop #4#5#6#7 +\cs_new:Npn \@@_generate_variant_loop_special:NNwNNnn + #1#2#3 \q_stop #4#5#6#7 { #3 \q_stop #4 #5 {#6} {#7} \exp_not:n @@ -1969,12 +2038,9 @@ { : \exp_not:N \use_i:nn } } } -\use:x - { - \cs_new_protected:Npn \exp_not:N \@@_generate_internal_variant:wwnNwnn - ##1 \token_to_str:N x ##2 \exp_not:N \q_mark - ##3 ##4 ##5 \exp_not:N \q_stop ##6 ##7 - } +\exp_last_unbraced:NNNNo + \cs_new_protected:Npn \@@_generate_internal_variant:wwnNwnn #1 + { \token_to_str:N x } #2 \q_mark #3#4#5 \q_stop #6#7 { #3 \cs_if_free:cT {#6} { #4 {#6} {#7} } @@ -2009,7 +2075,13 @@ % } % \begin{macrocode} \cs_new_protected:Npn \prg_generate_conditional_variant:Nnn #1 - { \__cs_split_function:NN #1 \@@_generate_variant:nnNnn } + { + \use:x + { + \@@_generate_variant:nnNnn + \cs_split_function:N #1 + } + } \cs_new_protected:Npn \@@_generate_variant:nnNnn #1#2#3#4#5 { \if_meaning:w \c_false_bool #3 @@ -2051,6 +2123,45 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\exp_args_generate:n, \@@_args_generate:Nn} +% \begin{macro}[EXP]{\@@_args_generate:n} +% This function is not used in the kernel hence we can use functions +% that are defined in later modules. It also does not need to be fast +% so use inline mappings. For each requested variant we check that +% there are no characters besides |NnpcofVvx|, in particular that +% there are no spaces. Then we loop through the variant specifier and +% convert each letter to \cs[no-index]{::\meta{variant letter}}, with a +% trailing \cs{:::}. +% \begin{macrocode} +\cs_new_protected:Npn \exp_args_generate:n #1 + { + \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} } + { + \str_map_inline:nn {##1} + { + \str_if_in:nnF { NnpcofVvx } {####1} + { + \__kernel_msg_error:nnnn { kernel } { invalid-exp-args } + {####1} {##1} + \str_map_break:n { \use_none:nnnn } + } + } + \exp_args:Nc \@@_args_generate:Nn { exp_args:N ##1 } {##1} + } + } +\cs_new_protected:Npn \@@_args_generate:Nn #1#2 + { + \cs_if_exist:NF #1 + { + \str_if_in:nnTF {#2} { x } { \cs_new_protected:Npx } { \cs_new:Npx } + #1 { \tl_map_function:nN { #2 : } \@@_args_generate:n } + } + } +\cs_new:Npn \@@_args_generate:n #1 { \exp_not:c { :: #1 } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macrocode} %</initex|package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx index 76a88d152d4..25449f418c5 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx @@ -42,7 +42,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -67,112 +67,7 @@ % using |"| tokens if they contain spaces: as a result, |"| tokens are % \emph{not} permitted in file names. % -% \section{File operation functions} -% -% \begin{variable}[added = 2017-06-21] -% { -% \g_file_curr_dir_str, -% \g_file_curr_name_str, -% \g_file_curr_ext_str -% } -% Contain the directory, name and extension of the current file. The -% directory is empty if the file was loaded without an explicit -% path (\emph{i.e.}~if it is in the \TeX{} search path), and does -% \emph{not} end in |/| other than the case that it is exactly equal -% to the root directory. The \meta{name} and \meta{ext} parts together -% make up the file name, thus the \meta{name} part may be thought of -% as the \enquote{job name} for the current file. Note that \TeX{} does -% not provide information on the \meta{ext} part for the main (top -% level) file and that this file always has an empty \meta{dir} component. -% Also, the \meta{name} here will be equal to \cs{c_sys_jobname_str}, -% which may be different from the real file name (if set using -% |--jobname|, for example). -% \end{variable} -% -% \begin{variable}[added = 2017-06-18]{\l_file_search_path_seq} -% Each entry is the path to a directory which should be searched when -% seeking a file. Each path can be relative or absolute, and should -% not include the trailing slash. The entries are not expanded when -% used so may contain active characters but should not feature any -% variable content. Spaces need not be quoted. -% -% \begin{texnote} -% When working as a package in \LaTeXe{}, \pkg{expl3} will -% automatically append the current \tn{input@path} to the -% set of values from \cs{l_file_search_path_seq}. -% \end{texnote} -% \end{variable} -% -% \begin{function}[TF, updated = 2012-02-10]{\file_if_exist:n} -% \begin{syntax} -% \cs{file_if_exist:nTF} \Arg{file name} \Arg{true code} \Arg{false code} -% \end{syntax} -% Searches for \meta{file name} using the current \TeX{} search -% path and the additional paths controlled by -% \cs{l_file_search_path_seq}. -% \end{function} -% -% \begin{function}[updated = 2017-06-26] -% {\file_get_full_name:nN, \file_get_full_name:VN} -% \begin{syntax} -% \cs{file_get_full_name:nN} \Arg{file name} \meta{str var} -% \end{syntax} -% Searches for \meta{file name} in the path as detailed for -% \cs{file_if_exist:nTF}, and if found sets the \meta{str var} the -% fully-qualified name of the file, \emph{i.e.}~the path and file name. -% This includes an extension |.tex| when the given \meta{file name} -% has no extension but the file found has that extension. -% If the file is not found then the \meta{str var} is empty. -% \end{function} -% -% \begin{function}[added = 2017-06-23, updated = 2017-06-26] -% {\file_parse_full_name:nNNN} -% \begin{syntax} -% \cs{file_parse_full_name:nNNN} \Arg{full name} \meta{dir} \meta{name} \meta{ext} -% \end{syntax} -% Parses the \meta{full name} and splits it into three parts, each of -% which is returned by setting the appropriate local string variable: -% \begin{itemize} -% \item The \meta{dir}: everything up to the last |/| (path separator) -% in the \meta{file path}. As with system \texttt{PATH} variables -% and related functions, the \meta{dir} does \emph{not} include the -% trailing |/| unless it points to the root directory. If there is no path (only -% a file name), \meta{dir} is empty. -% \item The \meta{name}: everything after the last |/| up to the last |.|, -% where both of those characters are optional. The \meta{name} may -% contain multiple |.| characters. It is empty if \meta{full name} -% consists only of a directory name. -% \item The \meta{ext}: everything after the last |.| (including the dot). -% The \meta{ext} is empty if there is no |.| after the last |/|. -% \end{itemize} -% This function does not expand the \meta{full name} before turning it -% to a string. It assume that the \meta{full name} either contains no -% quote (|"|) characters or is surrounded by a pair of quotes. -% \end{function} -% -% \begin{function}[updated = 2017-06-26]{\file_input:n} -% \begin{syntax} -% \cs{file_input:n} \Arg{file name} -% \end{syntax} -% Searches for \meta{file name} in the path as detailed for -% \cs{file_if_exist:nTF}, and if found reads in the file as -% additional \LaTeX{} source. All files read are recorded -% for information and the file name stack is updated by this -% function. An error is raised if the file is not found. -% \end{function} -% -% \begin{function}{\file_show_list:, \file_log_list:} -% \begin{syntax} -% \cs{file_show_list:} -% \cs{file_log_list:} -% \end{syntax} -% These functions list all files loaded by \LaTeXe{} commands that -% populate \tn{@filelist} or by \cs{file_input:n}. While -% \cs{file_show_list:} displays the list in the terminal, -% \cs{file_log_list:} outputs it to the log file only. -% \end{function} -% -% \subsection{Input--output stream management} +% \section{Input--output stream management} % % As \TeX{} engines have a limited number of input and output streams, direct % use of the streams by the programmer is not supported in \LaTeX3. Instead, an @@ -597,7 +492,7 @@ % by the \cs{iow_wrap:nnnN} % function. This value depends on the \TeX{} system in use: the standard % value is $78$, which is typically correct for unmodified \TeX{}live -% and MiK\TeX{} systems. +% and \hologo{MiKTeX} systems. % \end{variable} % % \subsection{Constant input--output streams, and variables} @@ -647,74 +542,109 @@ % \end{texnote} % \end{function} % -% \subsection{Internal file functions and variables} +% \section{File operation functions} % -% \begin{variable}{\g__file_internal_ior} -% Used to test for the existence of files when opening. +% \begin{variable}[added = 2017-06-21] +% { +% \g_file_curr_dir_str, +% \g_file_curr_name_str, +% \g_file_curr_ext_str +% } +% Contain the directory, name and extension of the current file. The +% directory is empty if the file was loaded without an explicit +% path (\emph{i.e.}~if it is in the \TeX{} search path), and does +% \emph{not} end in |/| other than the case that it is exactly equal +% to the root directory. The \meta{name} and \meta{ext} parts together +% make up the file name, thus the \meta{name} part may be thought of +% as the \enquote{job name} for the current file. Note that \TeX{} does +% not provide information on the \meta{ext} part for the main (top +% level) file and that this file always has an empty \meta{dir} component. +% Also, the \meta{name} here will be equal to \cs{c_sys_jobname_str}, +% which may be different from the real file name (if set using +% |--jobname|, for example). % \end{variable} % -% \begin{variable}{\l__file_base_name_str, \l__file_full_name_str} -% Used to store and transfer the file name (including extension) -% and (partial) file path whilst reading files. (The file base is the -% base name plus any preceding directory name.) +% \begin{variable}[added = 2017-06-18]{\l_file_search_path_seq} +% Each entry is the path to a directory which should be searched when +% seeking a file. Each path can be relative or absolute, and should +% not include the trailing slash. The entries are not expanded when +% used so may contain active characters but should not feature any +% variable content. Spaces need not be quoted. +% +% \begin{texnote} +% When working as a package in \LaTeXe{}, \pkg{expl3} will +% automatically append the current \tn{input@path} to the +% set of values from \cs{l_file_search_path_seq}. +% \end{texnote} % \end{variable} % -% \begin{function}[added = 2017-06-25]{\__file_missing:n} +% \begin{function}[TF, updated = 2012-02-10]{\file_if_exist:n} % \begin{syntax} -% \cs{__file_missing:n} \Arg{name} +% \cs{file_if_exist:nTF} \Arg{file name} \Arg{true code} \Arg{false code} % \end{syntax} -% Expands the \meta{name} as per \cs{__file_name_sanitize:nN} then -% produces an error message indicating that that file was not found. +% Searches for \meta{file name} using the current \TeX{} search +% path and the additional paths controlled by +% \cs{l_file_search_path_seq}. % \end{function} % -% \begin{function}[added = 2017-06-19]{\__file_name_sanitize:nN} +% \begin{function}[updated = 2017-06-26] +% {\file_get_full_name:nN, \file_get_full_name:VN} % \begin{syntax} -% \cs{__file_name_sanitize:nN} \Arg{name} \meta{str var} +% \cs{file_get_full_name:nN} \Arg{file name} \meta{str var} % \end{syntax} -% Exhaustively-expands the \meta{name} with the exception of any -% category \meta{active} (catcode~$13$) tokens, which are not expanded. -% The list of \meta{active} tokens is taken from \cs{l_char_active_seq}. -% The \meta{str var} is then set to the \meta{sanitized name}. +% Searches for \meta{file name} in the path as detailed for +% \cs{file_if_exist:nTF}, and if found sets the \meta{str var} the +% fully-qualified name of the file, \emph{i.e.}~the path and file name. +% This includes an extension |.tex| when the given \meta{file name} +% has no extension but the file found has that extension. +% If the file is not found then the \meta{str var} is empty. % \end{function} % -% \begin{function}[added = 2017-06-19, updated = 2017-06-25] -% {\__file_name_quote:nN} +% \begin{function}[added = 2017-06-23, updated = 2017-06-26] +% {\file_parse_full_name:nNNN} % \begin{syntax} -% \cs{__file_name_quote:nN} \Arg{name} \meta{str var} +% \cs{file_parse_full_name:nNNN} \Arg{full name} \meta{dir} \meta{name} \meta{ext} % \end{syntax} -% Expands the \meta{name} (without special-casing active tokens), then -% sets the \meta{str var} to the \meta{name} quoted using |"| at each -% end if required by the presence of spaces in the \meta{name}. Any existing -% |"| tokens is removed and if their number is odd an error is raised. +% Parses the \meta{full name} and splits it into three parts, each of +% which is returned by setting the appropriate local string variable: +% \begin{itemize} +% \item The \meta{dir}: everything up to the last |/| (path separator) +% in the \meta{file path}. As with system \texttt{PATH} variables +% and related functions, the \meta{dir} does \emph{not} include the +% trailing |/| unless it points to the root directory. If there is no path (only +% a file name), \meta{dir} is empty. +% \item The \meta{name}: everything after the last |/| up to the last |.|, +% where both of those characters are optional. The \meta{name} may +% contain multiple |.| characters. It is empty if \meta{full name} +% consists only of a directory name. +% \item The \meta{ext}: everything after the last |.| (including the dot). +% The \meta{ext} is empty if there is no |.| after the last |/|. +% \end{itemize} +% This function does not expand the \meta{full name} before turning it +% to a string. It assume that the \meta{full name} either contains no +% quote (|"|) characters or is surrounded by a pair of quotes. % \end{function} % -% \subsection{Internal input--output functions} -% -% \begin{function}[added = 2012-01-23]{\__ior_open:Nn, \__ior_open:No} +% \begin{function}[updated = 2017-06-26]{\file_input:n} % \begin{syntax} -% \cs{__ior_open:Nn} \meta{stream} \Arg{file name} +% \cs{file_input:n} \Arg{file name} % \end{syntax} -% This function has identical syntax to the public version. However, -% is does not take precautions against active characters in the -% \meta{file name}, and it does not attempt to add a \meta{path} to -% the \meta{file name}: it is therefore intended to be used by -% higher-level -% functions which have already fully expanded the \meta{file name} and which -% need to perform multiple open or close operations. See for example the -% implementation of \cs{file_get_full_name:nN}, +% Searches for \meta{file name} in the path as detailed for +% \cs{file_if_exist:nTF}, and if found reads in the file as +% additional \LaTeX{} source. All files read are recorded +% for information and the file name stack is updated by this +% function. An error is raised if the file is not found. % \end{function} % -% \begin{function}[added = 2014-08-23]{\__iow_with:Nnn} +% \begin{function}{\file_show_list:, \file_log_list:} % \begin{syntax} -% \cs{__iow_with:Nnn} \meta{integer} \Arg{value} \Arg{code} +% \cs{file_show_list:} +% \cs{file_log_list:} % \end{syntax} -% If the \meta{integer} is equal to the \meta{value} then this -% function simply runs the \meta{code}. Otherwise it saves the -% current value of the \meta{integer}, sets it to the \meta{value}, -% runs the \meta{code}, and restores the \meta{integer} to its former -% value. This is used to ensure that the \tn{newlinechar} is~$10$ -% when writing to a stream, which lets \cs{iow_newline:} work, and -% that \tn{errorcontextlines} is $-1$ when displaying a message. +% These functions list all files loaded by \LaTeXe{} commands that +% populate \tn{@filelist} or by \cs{file_input:n}. While +% \cs{file_show_list:} displays the list in the terminal, +% \cs{file_log_list:} outputs it to the log file only. % \end{function} % % \end{documentation} @@ -729,427 +659,6 @@ %<*initex|package> % \end{macrocode} % -% \begin{macrocode} -%<@@=file> -% \end{macrocode} -% -% \subsection{File operations} -% -% \begin{variable} -% { -% \g_file_curr_dir_str , -% \g_file_curr_ext_str , -% \g_file_curr_name_str -% } -% The name of the current file should be available at all times. -% For the format the file name needs to be picked up at the start of the -% run. In \LaTeXe{} package mode the current file name is collected from -% \tn{@currname}. -% \begin{macrocode} -\str_new:N \g_file_curr_dir_str -\str_new:N \g_file_curr_ext_str -\str_new:N \g_file_curr_name_str -%<*initex> -\tex_everyjob:D \exp_after:wN - { - \tex_the:D \tex_everyjob:D - \str_gset:Nx \g_file_curr_name_str { \tex_jobname:D } - } -%</initex> -%<*package> -\cs_if_exist:NT \@currname - { \str_gset_eq:NN \g_file_curr_name_str \@currname } -%</package> -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\g_@@_stack_seq} -% The input list of files is stored as a sequence stack. In package -% mode we can recover the information from the details held by -% \LaTeXe{} (we must be in the preamble and loaded using \tn{usepackage} -% or \tn{RequirePackage}). As \LaTeXe{} doesn't store directory and -% name separately, we stick to the same convention here. -% \begin{macrocode} -\seq_new:N \g_@@_stack_seq -%<*package> -\group_begin: - \cs_set_protected:Npn \@@_tmp:w #1#2#3 - { - \tl_if_blank:nTF {#1} - { - \cs_set:Npn \@@_tmp:w ##1 " ##2 " ##3 \q_stop { { } {##2} { } } - \seq_gput_right:Nx \g_@@_stack_seq - { - \exp_after:wN \@@_tmp:w \tex_jobname:D - " \tex_jobname:D " \q_stop - } - } - { - \seq_gput_right:Nn \g_@@_stack_seq { { } {#1} {#2} } - \@@_tmp:w - } - } - \cs_if_exist:NT \@currnamestack - { \exp_after:wN \@@_tmp:w \@currnamestack } -\group_end: -%</package> -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\g_@@_record_seq} -% The total list of files used is recorded separately from the current -% file stack, as nothing is ever popped from this list. The current -% file name should be included in the file list! In format mode, this -% is done at the very start of the \TeX{} run. In package mode we -% will eventually copy the contents of \cs{@filelist}. -% \begin{macrocode} -\seq_new:N \g_@@_record_seq -%<*initex> -\tex_everyjob:D \exp_after:wN - { - \tex_the:D \tex_everyjob:D - \seq_gput_right:NV \g_@@_record_seq \g_file_curr_name_str - } -%</initex> -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_@@_tmp_tl} -% Used as a short-term scratch variable. -% \begin{macrocode} -\tl_new:N \l_@@_tmp_tl -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l__file_base_name_str, \l__file_full_name_str} -% For storing the basename and full path whilst passing data internally. -% \begin{macrocode} -\str_new:N \l__file_base_name_str -\str_new:N \l__file_full_name_str -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_@@_dir_str, \l_@@_ext_str, \l_@@_name_str} -% Used in parsing a path into parts: in contrast to the above, these are -% never used outside of the current module. -% \begin{macrocode} -\str_new:N \l_@@_dir_str -\str_new:N \l_@@_ext_str -\str_new:N \l_@@_name_str -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_file_search_path_seq} -% The current search path. -% \begin{macrocode} -\seq_new:N \l_file_search_path_seq -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_@@_tmp_seq} -% Scratch space for comma list conversion in package mode. -% \begin{macrocode} -%<*package> -\seq_new:N \l_@@_tmp_seq -%</package> -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\__file_name_sanitize:nN} -% \begin{macro}{\__file_name_quote:nN} -% \begin{macro}{\@@_name_sanitize_aux:n} -% For converting a token list to a string where active characters are treated -% as strings from the start. The logic to the quoting normalisation is the -% same as used by \texttt{lualatexquotejobname}: check for balanced |"|, and -% assuming they balance strip all of them out before quoting the entire name -% if it contains spaces. -% \begin{macrocode} -\cs_new_protected:Npn \__file_name_sanitize:nN #1#2 - { - \group_begin: - \seq_map_inline:Nn \l_char_active_seq - { - \tl_set:Nx \l_@@_tmp_tl { \iow_char:N ##1 } - \char_set_active_eq:NN ##1 \l_@@_tmp_tl - } - \tl_set:Nx \l_@@_tmp_tl {#1} - \tl_set:Nx \l_@@_tmp_tl - { \tl_to_str:N \l_@@_tmp_tl } - \exp_args:NNNV \group_end: - \str_set:Nn #2 \l_@@_tmp_tl - } -\cs_new_protected:Npn \__file_name_quote:nN #1#2 - { - \str_set:Nx #2 {#1} - \int_if_even:nF - { 0 \tl_map_function:NN #2 \@@_name_quote_aux:n } - { - \__kernel_msg_error:nnx - { kernel } { unbalanced-quote-in-filename } {#2} - } - \tl_remove_all:Nn #2 { " } - \tl_if_in:NnT #2 { ~ } - { \str_set:Nx #2 { " \exp_not:V #2 " } } - } -\cs_new:Npn \@@_name_quote_aux:n #1 - { \token_if_eq_charcode:NNT #1 " { + 1 } } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\file_get_full_name:nN, \file_get_full_name:VN} -% \begin{macro}{\@@_get_full_name_search:nN} -% The way to test if a file exists is to try to open it: if it does -% not exist then \TeX{} reports end-of-file. A search is made -% looking at each potential path in turn (starting from the current -% directory). The first location is of course treated as the correct -% one: this is done by jumping to \cs{__prg_break_point:}. If nothing -% is found, |#2| is returned empty. A special case when there is no -% extension is that once the first location is found we test the -% existence of the file with |.tex| extension in that directory, and -% if it exists we include the |.tex| extension in the result. -% \begin{macrocode} -\cs_new_protected:Npn \file_get_full_name:nN #1#2 - { - \__file_name_sanitize:nN {#1} \l__file_base_name_str - \@@_get_full_name_search:nN { } \use:n - \seq_map_inline:Nn \l_file_search_path_seq - { \@@_get_full_name_search:nN { ##1 / } \seq_map_break:n } -%<*package> - \cs_if_exist:NT \input@path - { - \tl_map_inline:Nn \input@path - { \@@_get_full_name_search:nN { ##1 } \tl_map_break:n } - } -%</package> - \str_clear:N \l__file_full_name_str - \__prg_break_point: - \str_if_empty:NF \l__file_full_name_str - { - \exp_args:NV \file_parse_full_name:nNNN \l__file_full_name_str - \l_@@_dir_str \l_@@_name_str \l_@@_ext_str - \str_if_empty:NT \l_@@_ext_str - { - \__ior_open:No \g_@@_internal_ior - { \l__file_full_name_str .tex } - \ior_if_eof:NF \g_@@_internal_ior - { \str_put_right:Nn \l__file_full_name_str { .tex } } - } - } - \str_set_eq:NN #2 \l__file_full_name_str - \ior_close:N \g_@@_internal_ior - } -\cs_generate_variant:Nn \file_get_full_name:nN { V } -\cs_new_protected:Npn \@@_get_full_name_search:nN #1#2 - { - \__file_name_quote:nN - { \tl_to_str:n {#1} \l__file_base_name_str } - \l__file_full_name_str - \__ior_open:No \g_@@_internal_ior \l__file_full_name_str - \ior_if_eof:NF \g_@@_internal_ior { #2 { \__prg_break: } } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[TF]{\file_if_exist:n} -% The test for the existence of a file is a wrapper around the function to -% add a path to a file. If the file was found, the path contains -% something, whereas if the file was not located then the return value -% is empty. -% \begin{macrocode} -\prg_new_protected_conditional:Npnn \file_if_exist:n #1 { T , F , TF } - { - \file_get_full_name:nN {#1} \l__file_full_name_str - \str_if_empty:NTF \l__file_full_name_str - { \prg_return_false: } - { \prg_return_true: } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\__file_missing:n} -% An error message for a missing file, also used in \cs{ior_open:Nn}. -% \begin{macrocode} -\cs_new_protected:Npn \__file_missing:n #1 - { - \__file_name_sanitize:nN {#1} \l__file_base_name_str - \__kernel_msg_error:nnx { kernel } { file-not-found } - { \l__file_base_name_str } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\file_input:n} -% \begin{macro}{\@@_input:n, \@@_input:V} -% \begin{macro}{\@@_input_push:n} -% \begin{macro}{\@@_input_pop:} -% \begin{macro}{\@@_input_pop:nnn} -% Loading a file is done in a safe way, checking first that the file -% exists and loading only if it does. Push the file name on the -% \cs{g_@@_stack_seq}, and add it to the file list, either -% \cs{g_@@_record_seq}, or \cs{@filelist} in package mode. -% \begin{macrocode} -\cs_new_protected:Npn \file_input:n #1 - { - \file_get_full_name:nN {#1} \l__file_full_name_str - \str_if_empty:NTF \l__file_full_name_str - { \__file_missing:n {#1} } - { \@@_input:V \l__file_full_name_str } - } -\cs_new_protected:Npn \@@_input:n #1 - { -%<*initex> - \seq_gput_right:Nn \g_@@_record_seq {#1} -%</initex> -%<*package> - \clist_if_exist:NTF \@filelist - { \@addtofilelist {#1} } - { \seq_gput_right:Nn \g_@@_record_seq {#1} } -%</package> - \@@_input_push:n {#1} - \tex_input:D #1 \c_space_tl - \@@_input_pop: - } -\cs_generate_variant:Nn \@@_input:n { V } -% \end{macrocode} -% Keeping a track of the file data is easy enough: we store the separated -% parts so we do not need to parse them twice. -% \begin{macrocode} -\cs_new_protected:Npn \@@_input_push:n #1 - { - \seq_gpush:Nx \g_@@_stack_seq - { - { \g_file_curr_dir_str } - { \g_file_curr_name_str } - { \g_file_curr_ext_str } - } - \file_parse_full_name:nNNN {#1} - \l_@@_dir_str \l_@@_name_str \l_@@_ext_str - \str_gset_eq:NN \g_file_curr_dir_str \l_@@_dir_str - \str_gset_eq:NN \g_file_curr_name_str \l_@@_name_str - \str_gset_eq:NN \g_file_curr_ext_str \l_@@_ext_str - } -\cs_new_protected:Npn \@@_input_pop: - { - \seq_gpop:NN \g_@@_stack_seq \l_@@_tmp_tl - \exp_after:wN \@@_input_pop:nnn \l_@@_tmp_tl - } -\cs_new_protected:Npn \@@_input_pop:nnn #1#2#3 - { - \str_gset:Nn \g_file_curr_dir_str {#1} - \str_gset:Nn \g_file_curr_name_str {#2} - \str_gset:Nn \g_file_curr_ext_str {#3} - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\file_parse_full_name:nNNN} -% \begin{macro} -% {\@@_parse_full_name_auxi:w, \@@_parse_full_name_split:nNNNTF} -% Parsing starts by stripping off any surrounding quotes. Then find -% the directory |#4| by splitting at the last~|/|. (The auxiliary -% returns \texttt{true}/\texttt{false} depending on whether it found -% the delimiter.) We correct for the case of a file in the root |/|, -% as in that case we wish to keep the trailing (and only) slash. Then -% split the base name |#5| at the last dot. If there was indeed a -% dot, |#5| contains the name and |#6| the extension without the dot, -% which we add back for convenience. In the special case of no -% extension given, the auxiliary stored the name into |#6|, we just -% have to move it to |#5|. -% \begin{macrocode} -\cs_new_protected:Npn \file_parse_full_name:nNNN #1#2#3#4 - { - \exp_after:wN \@@_parse_full_name_auxi:w - \tl_to_str:n { #1 " #1 " } \q_stop #2#3#4 - } -\cs_new_protected:Npn \@@_parse_full_name_auxi:w #1 " #2 " #3 \q_stop #4#5#6 - { - \@@_parse_full_name_split:nNNNTF {#2} / #4 #5 - { \str_if_empty:NT #4 { \str_set:Nn #4 { / } } } - { } - \exp_args:No \@@_parse_full_name_split:nNNNTF {#5} . #5 #6 - { \str_put_left:Nn #6 { . } } - { - \str_set_eq:NN #5 #6 - \str_clear:N #6 - } - } -\cs_new_protected:Npn \@@_parse_full_name_split:nNNNTF #1#2#3#4 - { - \cs_set_protected:Npn \@@_tmp:w ##1 ##2 #2 ##3 \q_stop - { - \tl_if_empty:nTF {##3} - { - \str_set:Nn #4 {##2} - \tl_if_empty:nTF {##1} - { - \str_clear:N #3 - \use_ii:nn - } - { - \str_set:Nx #3 { \str_tail:n {##1} } - \use_i:nn - } - } - { \@@_tmp:w { ##1 #2 ##2 } ##3 \q_stop } - } - \@@_tmp:w { } #1 #2 \q_stop - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\file_show_list:, \file_log_list:, \@@_list:N} -% \begin{macro}[EXP]{\@@_list_aux:n} -% A function to list all files used to the log, without duplicates. -% In package mode, if \cs{@filelist} is still defined, we need to take -% this list of file names into account (we capture it -% \cs{AtBeginDocument} into \cs{g_@@_record_seq}), turning it to a -% string (this does not affect the commas of this comma list). -% \begin{macrocode} -\cs_new_protected:Npn \file_show_list: { \@@_list:N \msg_show:nnxxxx } -\cs_new_protected:Npn \file_log_list: { \@@_list:N \msg_log:nnxxxx } -\cs_new_protected:Npn \@@_list:N #1 - { - \seq_clear:N \l_@@_tmp_seq -%<*package> - \clist_if_exist:NT \@filelist - { - \exp_args:NNx \seq_set_from_clist:Nn \l_@@_tmp_seq - { \tl_to_str:N \@filelist } - } -%</package> - \seq_concat:NNN \l_@@_tmp_seq \l_@@_tmp_seq \g_@@_record_seq - \seq_remove_duplicates:N \l_@@_tmp_seq - #1 { LaTeX/kernel } { file-list } - { \seq_map_function:NN \l_@@_tmp_seq \@@_list_aux:n } { } { } { } - } -\cs_new:Npn \@@_list_aux:n #1 { \iow_newline: #1 } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% When used as a package, there is a need to hold onto the standard file -% list as well as the new one here. File names recorded in -% \cs{@filelist} must be turned to strings before being added to -% \cs{g_@@_record_seq}. -% \begin{macrocode} -%<*package> -\AtBeginDocument - { - \exp_args:NNx \seq_set_from_clist:Nn \l_@@_tmp_seq - { \tl_to_str:N \@filelist } - \seq_gconcat:NNN \g_@@_record_seq \g_@@_record_seq \l_@@_tmp_seq - } -%</package> -% \end{macrocode} -% % \subsection{Input operations} % % \begin{macrocode} @@ -1195,15 +704,14 @@ % underlying mechanism needs to be queried. For \LaTeXe{} and plain \TeX{} % this data is stored in |\count16|: with the \pkg{etex} package loaded % we need to subtract $1$ as the register holds the number of the next -% stream to use. In Con\TeX{}t, we need to look at |\count38| but there +% stream to use. In \ConTeXt{}, we need to look at |\count38| but there % is no subtraction: like the original plain \TeX{}/\LaTeXe{} mechanism % it holds the value of the \emph{last} stream allocated. % \begin{macrocode} \prop_new:N \g_@@_streams_prop %<*package> -\int_step_inline:nnnn +\int_step_inline:nnn { 0 } - { 1 } { \cs_if_exist:NTF \normalend { \tex_count:D 38 ~ } @@ -1242,11 +750,18 @@ % Use the conditional version, with an error if the file is not found. % \begin{macrocode} \cs_new_protected:Npn \ior_open:Nn #1#2 - { \ior_open:NnF #1 {#2} { \__file_missing:n {#2} } } + { \ior_open:NnF #1 {#2} { \__kernel_file_missing:n {#2} } } \cs_generate_variant:Nn \ior_open:Nn { c } % \end{macrocode} % \end{macro} % +% \begin{variable}{\l_@@_file_name_str} +% Data storage. +% \begin{macrocode} +\str_new:N \l_@@_file_name_str +% \end{macrocode} +% \end{variable} +% % \begin{macro}[TF]{\ior_open:Nn, \ior_open:cn} % An auxiliary searches for the file in the \TeX{}, \LaTeXe{} and % \LaTeX3 paths. Then pass the file found to the lower-level function @@ -1255,11 +770,11 @@ % \begin{macrocode} \prg_new_protected_conditional:Npnn \ior_open:Nn #1#2 { T , F , TF } { - \file_get_full_name:nN {#2} \l__file_full_name_str - \str_if_empty:NTF \l__file_full_name_str + \file_get_full_name:nN {#2} \l_@@_file_name_str + \str_if_empty:NTF \l_@@_file_name_str { \prg_return_false: } { - \@@_open:No #1 \l__file_full_name_str + \__kernel_ior_open:No #1 \l_@@_file_name_str \prg_return_true: } } @@ -1283,7 +798,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_open:Nn, \@@_open:No} +% \begin{macro}{\__kernel_ior_open:Nn, \__kernel_ior_open:No} % \begin{macro}{\@@_open_stream:Nn} % The stream allocation itself uses the fact that there is a list of all of % those available, so allocation is simply a question of using the number at @@ -1293,7 +808,7 @@ % are tracked, so we first try those. If that fails, ask plain \TeX{} or \LaTeXe{} % for a new stream and use that number (after a bit of conversion). % \begin{macrocode} -\cs_new_protected:Npn \@@_open:Nn #1#2 +\cs_new_protected:Npn \__kernel_ior_open:Nn #1#2 { \ior_close:N #1 \seq_gpop:NNTF \g_@@_streams_seq \l_@@_stream_tl @@ -1309,7 +824,7 @@ } %</package> } -\cs_generate_variant:Nn \@@_open:Nn { No } +\cs_generate_variant:Nn \__kernel_ior_open:Nn { No } \cs_new_protected:Npn \@@_open_stream:Nn #1#2 { \tex_global:D \tex_chardef:D #1 = \l_@@_stream_tl \scan_stop: @@ -1412,16 +927,16 @@ % % \begin{macro}{\ior_str_get:NN} % Reading as strings is a more complicated wrapper, as we wish to -% remove the endline character. +% remove the endline character and restore it afterwards. % \begin{macrocode} \cs_new_protected:Npn \ior_str_get:NN #1#2 { - \use:x + \exp_args:Nno \use:n { \int_set:Nn \tex_endlinechar:D { -1 } - \exp_not:n { \etex_readline:D #1 to #2 } - \int_set:Nn \tex_endlinechar:D { \int_use:N \tex_endlinechar:D } - } + \etex_readline:D #1 to #2 + \int_set:Nn \tex_endlinechar:D + } { \int_use:N \tex_endlinechar:D } } % \end{macrocode} % \end{macro} @@ -1430,9 +945,9 @@ % Usual map breaking functions. % \begin{macrocode} \cs_new:Npn \ior_map_break: - { \__prg_map_break:Nn \ior_map_break: { } } + { \prg_map_break:Nn \ior_map_break: { } } \cs_new:Npn \ior_map_break:n - { \__prg_map_break:Nn \ior_map_break: } + { \prg_map_break:Nn \ior_map_break: } % \end{macrocode} % \end{macro} % @@ -1453,16 +968,16 @@ { \@@_map_inline:NNn \ior_str_get:NN } \cs_new_protected:Npn \@@_map_inline:NNn { - \int_gincr:N \g__prg_map_int + \int_gincr:N \g__kernel_prg_map_int \exp_args:Nc \@@_map_inline:NNNn - { __prg_map_ \int_use:N \g__prg_map_int :n } + { @@_map_ \int_use:N \g__kernel_prg_map_int :n } } \cs_new_protected:Npn \@@_map_inline:NNNn #1#2#3#4 { \cs_gset_protected:Npn #1 ##1 {#4} \ior_if_eof:NF #3 { \@@_map_inline_loop:NNN #1#2#3 } - \__prg_break_point:Nn \ior_map_break: - { \int_gdecr:N \g__prg_map_int } + \prg_break_point:Nn \ior_map_break: + { \int_gdecr:N \g__kernel_prg_map_int } } \cs_new_protected:Npn \@@_map_inline_loop:NNN #1#2#3 { @@ -1481,13 +996,6 @@ % \end{macro} % \end{macro} % -% \begin{variable}{\g__file_internal_ior} -% Needed by the higher-level code, but cannot be created until here. -% \begin{macrocode} -\ior_new:N \g__file_internal_ior -% \end{macrocode} -% \end{variable} -% % \subsection{Output operations} % % \begin{macrocode} @@ -1510,30 +1018,30 @@ \int_const:Nn \c_log_iow { -1 } \int_const:Nn \c_term_iow { - \cs_if_exist:NTF \luatex_directlua:D - { - \int_compare:nNnTF \luatex_luatexversion:D > { 80 } - { 128 } - { 16 } - } + \bool_lazy_and:nnTF + { \sys_if_engine_luatex_p: } + { \int_compare_p:nNn \luatex_luatexversion:D > { 80 } } + { 128 } { 16 } } % \end{macrocode} % \end{variable} % % \begin{variable}{\g_@@_streams_seq} -% A list of the currently-available output streams to be used as a stack. +% A list of the currently-available output streams to be used as a +% stack. The stream $18$ is special, as \tn{write}18 is used to +% denote commands to be sent to the OS\@. % \begin{macrocode} \seq_new:N \g_@@_streams_seq %<*initex> -\use:x +\exp_args:Nnx \use:n + { \seq_gset_split:Nnn \g_@@_streams_seq { } } { - \exp_not:n { \seq_gset_split:Nnn \g_@@_streams_seq { } } - { - \int_step_function:nnnN { 0 } { 1 } { \c_term_iow } - \prg_do_nothing: - } + \int_step_function:nnN { 0 } { \c_term_iow } + \prg_do_nothing: } +\int_compare:nNnF \c_term_iow < { 18 } + { \seq_gremove_all:Nn \g_@@_streams_seq { 18 } } %</initex> % \end{macrocode} % \end{variable} @@ -1551,9 +1059,8 @@ % \begin{macrocode} \prop_new:N \g_@@_streams_prop %<*package> -\int_step_inline:nnnn +\int_step_inline:nnn { 0 } - { 1 } { \cs_if_exist:NTF \normalend { \tex_count:D 39 ~ } @@ -1599,6 +1106,13 @@ % \end{macrocode} % \end{macro} % +% \begin{variable}{\l_@@_file_name_str} +% Data storage. +% \begin{macrocode} +\str_new:N \l_@@_file_name_str +% \end{macrocode} +% \end{variable} +% % \begin{macro}{\iow_open:Nn, \iow_open:cn} % \begin{macro}{\@@_open_stream:Nn, \@@_open_stream:NV} % The same idea as for reading, but without the path and without the need @@ -1606,10 +1120,10 @@ % \begin{macrocode} \cs_new_protected:Npn \iow_open:Nn #1#2 { - \__file_name_sanitize:nN {#2} \l__file_base_name_str + \__kernel_file_name_sanitize:nN {#2} \l_@@_file_name_str \iow_close:N #1 \seq_gpop:NNTF \g_@@_streams_seq \l_@@_stream_tl - { \@@_open_stream:NV #1 \l__file_base_name_str } + { \@@_open_stream:NV #1 \l_@@_file_name_str } %<*initex> { \__kernel_msg_fatal:nn { kernel } { output-streams-exhausted } } %</initex> @@ -1617,7 +1131,7 @@ { \@@_new:N #1 \tl_set:Nx \l_@@_stream_tl { \int_eval:n {#1} } - \@@_open_stream:NV #1 \l__file_base_name_str + \@@_open_stream:NV #1 \l_@@_file_name_str } %</package> } @@ -1697,20 +1211,20 @@ % % \subsubsection{Immediate writing} % -% \begin{macro}{\@@_with:Nnn} -% \begin{macro}{\@@_with_aux:nNnn} +% \begin{macro}{\__kernel_iow_with:Nnn} +% \begin{macro}{\@@_with:nNnn} % If the integer~|#1| is equal to~|#2|, just leave~|#3| in the input % stream. Otherwise, pass the old value to an auxiliary, which sets % the integer to the new value, runs the code, and restores the % integer. % \begin{macrocode} -\cs_new_protected:Npn \@@_with:Nnn #1#2 +\cs_new_protected:Npn \__kernel_iow_with:Nnn #1#2 { \int_compare:nNnTF {#1} = {#2} { \use:n } - { \exp_args:No \@@_with_aux:nNnn { \int_use:N #1 } #1 {#2} } + { \exp_args:No \@@_with:nNnn { \int_use:N #1 } #1 {#2} } } -\cs_new_protected:Npn \@@_with_aux:nNnn #1#2#3#4 +\cs_new_protected:Npn \@@_with:nNnn #1#2#3#4 { \int_set:Nn #2 {#3} #4 @@ -1728,14 +1242,14 @@ % get the |Nx| variant, because it differs in subtle ways from % \texttt{x}-expansion, namely, macro parameter characters would not % need to be doubled. We set the \tn{newlinechar} to~$10$ using -% \cs{@@_with:Nnn} to support formats such as plain \TeX{}: otherwise, +% \cs{__kernel_iow_with:Nnn} to support formats such as plain \TeX{}: otherwise, % \cs{iow_newline:} would not work. We do not do this for % \cs{iow_shipout:Nn} or \cs{iow_shipout_x:Nn}, as \TeX{} looks at the % value of the \tn{newlinechar} at shipout time in those cases. % \begin{macrocode} \cs_new_protected:Npn \iow_now:Nn #1#2 { - \@@_with:Nnn \tex_newlinechar:D { `\^^J } + \__kernel_iow_with:Nnn \tex_newlinechar:D { `\^^J } { \tex_immediate:D \tex_write:D #1 { \exp_not:n {#2} } } } \cs_generate_variant:Nn \iow_now:Nn { c, Nx, cx } @@ -1781,7 +1295,7 @@ % This is the \enquote{raw} number of characters in a line which % can be written to the terminal. % The standard value is the line length typically used by -% \TeX{}Live and Mik\TeX{}. +% \TeX{}Live and \hologo{MiKTeX}. % \begin{macrocode} \int_new:N \l_iow_line_count_int \int_set:Nn \l_iow_line_count_int { 78 } @@ -1819,8 +1333,9 @@ \cs_new_protected:Npn \@@_set_indent:n #1 { \tl_set:Nx \l_@@_one_indent_tl - { \exp_args:No \__str_to_other_fast:n { \tl_to_str:n {#1} } } - \int_set:Nn \l_@@_one_indent_int { \str_count:N \l_@@_one_indent_tl } + { \exp_args:No \__kernel_str_to_other_fast:n { \tl_to_str:n {#1} } } + \int_set:Nn \l_@@_one_indent_int + { \str_count:N \l_@@_one_indent_tl } \exp_last_unbraced:NNo \cs_set:Npn \@@_unindent:w \l_@@_one_indent_tl { } } @@ -1940,10 +1455,14 @@ % \verb*|\ | uses an \enquote{other} space rather than a normal space, % because the latter might be absorbed by \TeX{} to end a number or % other \texttt{f}-type expansions. +% Use \cs{conditionally@traceoff} if defined; it is introduced by the +% \pkg{trace} package and suppresses uninteresting tracing of the +% wrapping code. % \begin{macrocode} \cs_new_protected:Npn \iow_wrap:nnnN #1#2#3#4 { \group_begin: +%<package> \use:c { conditionally@traceoff } \int_set:Nn \tex_escapechar:D { -1 } \cs_set:Npx \{ { \token_to_str:N \{ } \cs_set:Npx \# { \token_to_str:N \# } @@ -2004,7 +1523,7 @@ { \tl_set:Nx \l_@@_wrap_tl { - \exp_args:No \__str_to_other_fast:n \l_@@_wrap_tl + \exp_args:No \__kernel_str_to_other_fast:n \l_@@_wrap_tl \c_@@_wrap_end_marker_tl } \tl_set:Nx \l_@@_wrap_tl @@ -2115,7 +1634,7 @@ \tex_edef:D \l_@@_line_part_tl { \if_false: } \fi: #1 \exp_after:wN \@@_wrap_line_loop:w - \__int_value:w \__int_eval:w + \int_value:w \int_eval:w } \cs_new:Npn \@@_wrap_line_loop:w #1 ; #2#3#4#5#6#7#8#9 { @@ -2124,7 +1643,7 @@ \fi: #2 #3 #4 #5 #6 #7 #8 #9 \exp_after:wN \@@_wrap_line_loop:w - \__int_value:w \__int_eval:w #1 - 8 ; + \int_value:w \int_eval:w #1 - 8 ; } \cs_new:Npn \@@_wrap_line_aux:Nw #1#2#3 \exp_after:wN #4 ; { @@ -2148,7 +1667,7 @@ \cs_new:Npn \@@_wrap_line_end:NnnnnnnnN #1#2#3#4#5#6#7#8#9 { #2 #3 #4 #5 #6 #7 #8 - \use_none:nnnnn \__int_eval:w 8 - ; #9 + \use_none:nnnnn \int_eval:w 8 - ; #9 \token_if_eq_charcode:NNTF \c_space_token #9 { \@@_wrap_line_end:nw { } } { \if_false: { \fi: } \@@_wrap_break:w #9 } @@ -2160,7 +1679,7 @@ \@@_wrap_next_line:w } \cs_new:Npn \@@_wrap_end_chunk:w - #1 \__int_eval:w #2 - #3 ; #4#5 \q_stop + #1 \int_eval:w #2 - #3 ; #4#5 \q_stop { \if_false: { \fi: } \exp_args:Nf \@@_wrap_next:nw { \int_eval:n { #2 - #4 } } @@ -2333,15 +1852,452 @@ % \begin{macro}[EXP]{\@@_wrap_trim:N, \@@_wrap_trim:w} % Remove one trailing \enquote{other} space from the argument. % \begin{macrocode} -\cs_set_protected:Npn \@@_tmp:w #1 +\cs_new:Npn \@@_wrap_trim:N #1 + { \tl_if_empty:NF #1 { \exp_after:wN \@@_wrap_trim:w #1 \q_stop } } +\exp_last_unbraced:NNNNo + \cs_new:Npn \@@_wrap_trim:w #1 \c_catcode_other_space_tl \q_stop {#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%<@@=file> +% \end{macrocode} +% +% \subsection{File operations} +% +% \begin{variable}{\g_@@_internal_ior} +% A reserved stream to test for file existence. +% \begin{macrocode} +\ior_new:N \g_@@_internal_ior +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% { +% \g_file_curr_dir_str , +% \g_file_curr_ext_str , +% \g_file_curr_name_str +% } +% The name of the current file should be available at all times. +% For the format the file name needs to be picked up at the start of the +% run. In \LaTeXe{} package mode the current file name is collected from +% \tn{@currname}. +% \begin{macrocode} +\str_new:N \g_file_curr_dir_str +\str_new:N \g_file_curr_ext_str +\str_new:N \g_file_curr_name_str +%<*initex> +\tex_everyjob:D \exp_after:wN { - \cs_new:Npn \@@_wrap_trim:N ##1 - { \tl_if_empty:NF ##1 { \exp_after:wN \@@_wrap_trim:w ##1 \q_stop } } - \cs_new:Npn \@@_wrap_trim:w ##1 #1 \q_stop {##1} + \tex_the:D \tex_everyjob:D + \str_gset:Nx \g_file_curr_name_str { \tex_jobname:D } + } +%</initex> +%<*package> +\cs_if_exist:NT \@currname + { \str_gset_eq:NN \g_file_curr_name_str \@currname } +%</package> +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_@@_stack_seq} +% The input list of files is stored as a sequence stack. In package +% mode we can recover the information from the details held by +% \LaTeXe{} (we must be in the preamble and loaded using \tn{usepackage} +% or \tn{RequirePackage}). As \LaTeXe{} doesn't store directory and +% name separately, we stick to the same convention here. +% \begin{macrocode} +\seq_new:N \g_@@_stack_seq +%<*package> +\group_begin: + \cs_set_protected:Npn \@@_tmp:w #1#2#3 + { + \tl_if_blank:nTF {#1} + { + \cs_set:Npn \@@_tmp:w ##1 " ##2 " ##3 \q_stop + { { } {##2} { } } + \seq_gput_right:Nx \g_@@_stack_seq + { + \exp_after:wN \@@_tmp:w \tex_jobname:D + " \tex_jobname:D " \q_stop + } + } + { + \seq_gput_right:Nn \g_@@_stack_seq { { } {#1} {#2} } + \@@_tmp:w + } + } + \cs_if_exist:NT \@currnamestack + { \exp_after:wN \@@_tmp:w \@currnamestack } +\group_end: +%</package> +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_@@_record_seq} +% The total list of files used is recorded separately from the current +% file stack, as nothing is ever popped from this list. The current +% file name should be included in the file list! In format mode, this +% is done at the very start of the \TeX{} run. In package mode we +% will eventually copy the contents of \cs{@filelist}. +% \begin{macrocode} +\seq_new:N \g_@@_record_seq +%<*initex> +\tex_everyjob:D \exp_after:wN + { + \tex_the:D \tex_everyjob:D + \seq_gput_right:NV \g_@@_record_seq \g_file_curr_name_str + } +%</initex> +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_tmp_tl} +% Used as a short-term scratch variable. +% \begin{macrocode} +\tl_new:N \l_@@_tmp_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_base_name_str, \l_@@_full_name_str} +% For storing the basename and full path whilst passing data internally. +% \begin{macrocode} +\str_new:N \l_@@_base_name_str +\str_new:N \l_@@_full_name_str +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_dir_str, \l_@@_ext_str, \l_@@_name_str} +% Used in parsing a path into parts: in contrast to the above, these are +% never used outside of the current module. +% \begin{macrocode} +\str_new:N \l_@@_dir_str +\str_new:N \l_@@_ext_str +\str_new:N \l_@@_name_str +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_file_search_path_seq} +% The current search path. +% \begin{macrocode} +\seq_new:N \l_file_search_path_seq +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_tmp_seq} +% Scratch space for comma list conversion in package mode. +% \begin{macrocode} +%<*package> +\seq_new:N \l_@@_tmp_seq +%</package> +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\__kernel_file_name_sanitize:nN} +% \begin{macro}{\@@_name_quote:nN} +% \begin{macro}{\@@_name_sanitize_aux:n} +% For converting a token list to a string where active characters are treated +% as strings from the start. The logic to the quoting normalisation is the +% same as used by \texttt{lualatexquotejobname}: check for balanced |"|, and +% assuming they balance strip all of them out before quoting the entire name +% if it contains spaces. +% \begin{macrocode} +\cs_new_protected:Npn \__kernel_file_name_sanitize:nN #1#2 + { + \group_begin: + \seq_map_inline:Nn \l_char_active_seq + { + \tl_set:Nx \l_@@_tmp_tl { \iow_char:N ##1 } + \char_set_active_eq:NN ##1 \l_@@_tmp_tl + } + \tl_set:Nx \l_@@_tmp_tl {#1} + \tl_set:Nx \l_@@_tmp_tl + { \tl_to_str:N \l_@@_tmp_tl } + \exp_args:NNNV \group_end: + \str_set:Nn #2 \l_@@_tmp_tl + } +\cs_new_protected:Npn \@@_name_quote:nN #1#2 + { + \str_set:Nx #2 {#1} + \int_if_even:nF + { 0 \tl_map_function:NN #2 \@@_name_quote_aux:n } + { + \__kernel_msg_error:nnx + { kernel } { unbalanced-quote-in-filename } {#2} + } + \tl_remove_all:Nn #2 { " } + \tl_if_in:NnT #2 { ~ } + { \str_set:Nx #2 { " \exp_not:V #2 " } } + } +\cs_new:Npn \@@_name_quote_aux:n #1 + { \token_if_eq_charcode:NNT #1 " { + 1 } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\file_get_full_name:nN, \file_get_full_name:VN} +% \begin{macro}{\@@_get_full_name_search:nN} +% The way to test if a file exists is to try to open it: if it does +% not exist then \TeX{} reports end-of-file. A search is made +% looking at each potential path in turn (starting from the current +% directory). The first location is of course treated as the correct +% one: this is done by jumping to \cs{prg_break_point:}. If nothing +% is found, |#2| is returned empty. A special case when there is no +% extension is that once the first location is found we test the +% existence of the file with |.tex| extension in that directory, and +% if it exists we include the |.tex| extension in the result. +% \begin{macrocode} +\cs_new_protected:Npn \file_get_full_name:nN #1#2 + { + \__kernel_file_name_sanitize:nN {#1} \l_@@_base_name_str + \@@_get_full_name_search:nN { } \use:n + \seq_map_inline:Nn \l_file_search_path_seq + { \@@_get_full_name_search:nN { ##1 / } \seq_map_break:n } +%<*package> + \cs_if_exist:NT \input@path + { + \tl_map_inline:Nn \input@path + { \@@_get_full_name_search:nN { ##1 } \tl_map_break:n } + } +%</package> + \str_clear:N \l_@@_full_name_str + \prg_break_point: + \str_if_empty:NF \l_@@_full_name_str + { + \exp_args:NV \file_parse_full_name:nNNN \l_@@_full_name_str + \l_@@_dir_str \l_@@_name_str \l_@@_ext_str + \str_if_empty:NT \l_@@_ext_str + { + \__kernel_ior_open:No \g_@@_internal_ior + { \l_@@_full_name_str .tex } + \ior_if_eof:NF \g_@@_internal_ior + { \str_put_right:Nn \l_@@_full_name_str { .tex } } + } + } + \str_set_eq:NN #2 \l_@@_full_name_str + \ior_close:N \g_@@_internal_ior + } +\cs_generate_variant:Nn \file_get_full_name:nN { V } +\cs_new_protected:Npn \@@_get_full_name_search:nN #1#2 + { + \@@_name_quote:nN + { \tl_to_str:n {#1} \l_@@_base_name_str } + \l_@@_full_name_str + \__kernel_ior_open:No \g_@@_internal_ior \l_@@_full_name_str + \ior_if_eof:NF \g_@@_internal_ior { #2 { \prg_break: } } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[TF]{\file_if_exist:n} +% The test for the existence of a file is a wrapper around the function to +% add a path to a file. If the file was found, the path contains +% something, whereas if the file was not located then the return value +% is empty. +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \file_if_exist:n #1 { T , F , TF } + { + \file_get_full_name:nN {#1} \l_@@_full_name_str + \str_if_empty:NTF \l_@@_full_name_str + { \prg_return_false: } + { \prg_return_true: } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\__kernel_file_missing:n} +% An error message for a missing file, also used in \cs{ior_open:Nn}. +% \begin{macrocode} +\cs_new_protected:Npn \__kernel_file_missing:n #1 + { + \__kernel_file_name_sanitize:nN {#1} \l_@@_base_name_str + \__kernel_msg_error:nnx { kernel } { file-not-found } + { \l_@@_base_name_str } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\file_input:n} +% \begin{macro}{\@@_input:n, \@@_input:V} +% \begin{macro}{\@@_input_push:n, \__kernel_file_input_push:n} +% \begin{macro}{\@@_input_pop:, \__kernel_file_input_pop:} +% \begin{macro}{\@@_input_pop:nnn} +% Loading a file is done in a safe way, checking first that the file +% exists and loading only if it does. Push the file name on the +% \cs{g_@@_stack_seq}, and add it to the file list, either +% \cs{g_@@_record_seq}, or \cs{@filelist} in package mode. +% \begin{macrocode} +\cs_new_protected:Npn \file_input:n #1 + { + \file_get_full_name:nN {#1} \l_@@_full_name_str + \str_if_empty:NTF \l_@@_full_name_str + { \__kernel_file_missing:n {#1} } + { \@@_input:V \l_@@_full_name_str } + } +\cs_new_protected:Npn \@@_input:n #1 + { +%<*initex> + \seq_gput_right:Nn \g_@@_record_seq {#1} +%</initex> +%<*package> + \clist_if_exist:NTF \@filelist + { \@addtofilelist {#1} } + { \seq_gput_right:Nn \g_@@_record_seq {#1} } +%</package> + \@@_input_push:n {#1} + \tex_input:D #1 \c_space_tl + \@@_input_pop: + } +\cs_generate_variant:Nn \@@_input:n { V } +% \end{macrocode} +% Keeping a track of the file data is easy enough: we store the separated +% parts so we do not need to parse them twice. +% \begin{macrocode} +\cs_new_protected:Npn \@@_input_push:n #1 + { + \seq_gpush:Nx \g_@@_stack_seq + { + { \g_file_curr_dir_str } + { \g_file_curr_name_str } + { \g_file_curr_ext_str } + } + \file_parse_full_name:nNNN {#1} + \l_@@_dir_str \l_@@_name_str \l_@@_ext_str + \str_gset_eq:NN \g_file_curr_dir_str \l_@@_dir_str + \str_gset_eq:NN \g_file_curr_name_str \l_@@_name_str + \str_gset_eq:NN \g_file_curr_ext_str \l_@@_ext_str + } +%<*package> +\cs_new_eq:NN \__kernel_file_input_push:n \__file_input_push:n +%</package> +\cs_new_protected:Npn \@@_input_pop: + { + \seq_gpop:NN \g_@@_stack_seq \l_@@_tmp_tl + \exp_after:wN \@@_input_pop:nnn \l_@@_tmp_tl + } +%<*package> +\cs_new_eq:NN \__kernel_file_input_pop: \__file_input_pop: +%</package> +\cs_new_protected:Npn \@@_input_pop:nnn #1#2#3 + { + \str_gset:Nn \g_file_curr_dir_str {#1} + \str_gset:Nn \g_file_curr_name_str {#2} + \str_gset:Nn \g_file_curr_ext_str {#3} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\file_parse_full_name:nNNN} +% \begin{macro} +% {\@@_parse_full_name_auxi:w, \@@_parse_full_name_split:nNNNTF} +% Parsing starts by stripping off any surrounding quotes. Then find +% the directory |#4| by splitting at the last~|/|. (The auxiliary +% returns \texttt{true}/\texttt{false} depending on whether it found +% the delimiter.) We correct for the case of a file in the root |/|, +% as in that case we wish to keep the trailing (and only) slash. Then +% split the base name |#5| at the last dot. If there was indeed a +% dot, |#5| contains the name and |#6| the extension without the dot, +% which we add back for convenience. In the special case of no +% extension given, the auxiliary stored the name into |#6|, we just +% have to move it to |#5|. +% \begin{macrocode} +\cs_new_protected:Npn \file_parse_full_name:nNNN #1#2#3#4 + { + \exp_after:wN \@@_parse_full_name_auxi:w + \tl_to_str:n { #1 " #1 " } \q_stop #2#3#4 + } +\cs_new_protected:Npn \@@_parse_full_name_auxi:w + #1 " #2 " #3 \q_stop #4#5#6 + { + \@@_parse_full_name_split:nNNNTF {#2} / #4 #5 + { \str_if_empty:NT #4 { \str_set:Nn #4 { / } } } + { } + \exp_args:No \@@_parse_full_name_split:nNNNTF {#5} . #5 #6 + { \str_put_left:Nn #6 { . } } + { + \str_set_eq:NN #5 #6 + \str_clear:N #6 + } + } +\cs_new_protected:Npn \@@_parse_full_name_split:nNNNTF #1#2#3#4 + { + \cs_set_protected:Npn \@@_tmp:w ##1 ##2 #2 ##3 \q_stop + { + \tl_if_empty:nTF {##3} + { + \str_set:Nn #4 {##2} + \tl_if_empty:nTF {##1} + { + \str_clear:N #3 + \use_ii:nn + } + { + \str_set:Nx #3 { \str_tail:n {##1} } + \use_i:nn + } + } + { \@@_tmp:w { ##1 #2 ##2 } ##3 \q_stop } + } + \@@_tmp:w { } #1 #2 \q_stop } -\exp_args:NV \@@_tmp:w \c_catcode_other_space_tl % \end{macrocode} % \end{macro} +% \end{macro} +% +% \begin{macro}{\file_show_list:, \file_log_list:, \@@_list:N} +% \begin{macro}[EXP]{\@@_list_aux:n} +% A function to list all files used to the log, without duplicates. +% In package mode, if \cs{@filelist} is still defined, we need to take +% this list of file names into account (we capture it +% \cs{AtBeginDocument} into \cs{g_@@_record_seq}), turning it to a +% string (this does not affect the commas of this comma list). +% \begin{macrocode} +\cs_new_protected:Npn \file_show_list: { \@@_list:N \msg_show:nnxxxx } +\cs_new_protected:Npn \file_log_list: { \@@_list:N \msg_log:nnxxxx } +\cs_new_protected:Npn \@@_list:N #1 + { + \seq_clear:N \l_@@_tmp_seq +%<*package> + \clist_if_exist:NT \@filelist + { + \exp_args:NNx \seq_set_from_clist:Nn \l_@@_tmp_seq + { \tl_to_str:N \@filelist } + } +%</package> + \seq_concat:NNN \l_@@_tmp_seq \l_@@_tmp_seq \g_@@_record_seq + \seq_remove_duplicates:N \l_@@_tmp_seq + #1 { LaTeX/kernel } { file-list } + { \seq_map_function:NN \l_@@_tmp_seq \@@_list_aux:n } + { } { } { } + } +\cs_new:Npn \@@_list_aux:n #1 { \iow_newline: #1 } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% When used as a package, there is a need to hold onto the standard file +% list as well as the new one here. File names recorded in +% \cs{@filelist} must be turned to strings before being added to +% \cs{g_@@_record_seq}. +% \begin{macrocode} +%<*package> +\AtBeginDocument + { + \exp_args:NNx \seq_set_from_clist:Nn \l_@@_tmp_seq + { \tl_to_str:N \@filelist } + \seq_gconcat:NNN + \g_@@_record_seq + \g_@@_record_seq + \l_@@_tmp_seq + } +%</package> +% \end{macrocode} % % \subsection{Messages} % @@ -2399,7 +2355,7 @@ \tl_gset:Nn \g_file_current_name_tl { \g_file_curr_name_str } \__kernel_deprecation_code:nn { - \__deprecation_error:Nnn \g_file_current_name_tl + \__kernel_deprecation_error:Nnn \g_file_current_name_tl { \g_file_curr_name_str } { 2018-12-31 } } { \tex_def:D \g_file_current_name_tl { \g_file_curr_name_str } } @@ -2414,16 +2370,16 @@ { \seq_put_right:Nn \l_file_search_path_seq } \cs_new_protected:Npn \file_path_include:n #1 { - \__file_name_sanitize:nN {#1} \l__file_full_name_str - \seq_if_in:NVF \l_file_search_path_seq \l__file_full_name_str - { \seq_put_right:NV \l_file_search_path_seq \l__file_full_name_str } + \__kernel_file_name_sanitize:nN {#1} \l_@@_full_name_str + \seq_if_in:NVF \l_file_search_path_seq \l_@@_full_name_str + { \seq_put_right:NV \l_file_search_path_seq \l_@@_full_name_str } } \__kernel_patch_deprecation:nnNNpn { 2018-12-31 } { \seq_remove_all:Nn \l_file_search_path_seq } \cs_new_protected:Npn \file_path_remove:n #1 { - \__file_name_sanitize:nN {#1} \l__file_full_name_str - \seq_remove_all:NV \l_file_search_path_seq \l__file_full_name_str + \__kernel_file_name_sanitize:nN {#1} \l_@@_full_name_str + \seq_remove_all:NV \l_file_search_path_seq \l_@@_full_name_str } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3final.dtx b/Master/texmf-dist/source/latex/l3kernel/l3final.dtx index b0e54d8aa65..1772a41914f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3final.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3final.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3final.dtx Copyright (C) 1990-2017 The LaTeX3 Project +%% File: l3final.dtx Copyright (C) 1990-2018 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -63,7 +63,11 @@ % % \subsection{Input encoding} % -% The letters |a|--|z| and |A|--|Z| have the correct catcode directly from Ini\TeX{} +% \begin{macrocode} +%<@@=char> +% \end{macrocode} +% +% The letters |a|--|z| and |A|--|Z| have the correct catcode directly from \IniTeX{} % while for Unicode engines (almost) all characters to be treated as letters % are defined by the automatic data parsing. Thus the changes here are to % deal with the additional cases. @@ -71,10 +75,10 @@ % All the characters in the range $0$--$31$ \emph{except} tab (|^^I|), nl % (|^^J|), ff (|^^L|) and cr (|^^M|). % \begin{macrocode} -\int_step_inline:nnnn { 0 } { 1 } { `\^^H } +\int_step_inline:nnn { 0 } { `\^^H } { \char_set_catcode_invalid:n {#1} } \char_set_catcode_invalid:n { `\^^K } -\int_step_inline:nnnn { `\^^N } { 1 } { 31 } +\int_step_inline:nnn { `\^^N } { 31 } { \char_set_catcode_invalid:n {#1} } % \end{macrocode} % The same is true for the top of the $7$-bit range. @@ -122,7 +126,7 @@ % \end{macrocode} % The actual mappings: these are kept low-level for performance reasons. % \begin{macrocode} - \cs_new:cpn { __char_active_C3:N } #1 + \cs_new:cpn { @@_active_C3:N } #1 { \if_meaning:w #1 ^^9f ^^ff \else: % ß - U+00DF - germandbls \if_meaning:w #1 ^^a0 ^^e0 \else: % à - U+00E0 - agrave @@ -160,7 +164,7 @@ \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: } - \cs_new:cpn { __char_active_C4:N } #1 + \cs_new:cpn { @@_active_C4:N } #1 { \if_meaning:w #1 ^^83 ^^a0 \else: % ă - U+0103 - abreve \if_meaning:w #1 ^^85 ^^a1 \else: % ą - U+0105 - aogonek @@ -178,7 +182,7 @@ \__kernel_msg_expandable_error:nn { kernel } { encoding-failure } \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: } - \cs_new:cpn { __char_active_C5:N } #1 + \cs_new:cpn { @@_active_C5:N } #1 { \if_meaning:w #1 ^^82 ^^aa \else: % ł - U+0142 - lslash \if_meaning:w #1 ^^84 ^^ab \else: % ń - U+0144 - nacute @@ -201,7 +205,7 @@ \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: } - \cs_new:cpn { __char_active_C8:N } #1 + \cs_new:cpn { @@_active_C8:N } #1 { \if_meaning:w #1 ^^99 ^^b3 \else: % ș - U+0219 - scommaaccent \if_meaning:w #1 ^^9b ^^b5 \else: % ț - U+021B - tcommaaccent @@ -215,7 +219,7 @@ \clist_map_inline:nn { C3 , C4 , C5 , C8 } { \char_set_catcode_active:n { "#1 } - \char_set_active_eq:nc { "#1 } { __char_active_ #1 :N } + \char_set_active_eq:nc { "#1 } { @@_active_ #1 :N } \seq_put_right:Nx \l_char_special_seq { \exp_not:c { \char_generate:nn { "#1 } { 12 } } } \seq_put_right:Nx \l_char_active_seq @@ -272,7 +276,7 @@ = "[latinmodern-math.otf]/OT:mode=base;script=math;+ssty=0;"~at~7pt \scan_stop: \tex_font:D \exp_not:c { TU/lmm/m/n/5 } = "[latinmodern-math.otf]/OT:mode=base;script=math;+ssty=1;"~at~5pt \scan_stop: - \exp_not:N \int_step_inline:nnnn { 0 } { 1 } { 3 } + \exp_not:N \int_step_inline:nnn { 0 } { 3 } { \tex_textfont:D ##1 = \exp_not:c { TU/lmm/m/n/10 } \tex_scriptfont:D ##1 = \exp_not:c { TU/lmm/m/n/7 } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx b/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx index 4fd4d1e35dc..ab72967823a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx @@ -29,7 +29,7 @@ % \fi % % \title{^^A -% The \textsf{l3flag} package: expandable flags^^A +% The \textsf{l3flag} package: Expandable flags^^A % } % % \author{^^A @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -204,7 +204,7 @@ \if_cs_exist:w flag~#2~#1 \cs_end: \cs_set_eq:cN { flag~#2~#1 } \tex_undefined:D \exp_after:wN \@@_clear:wn - \__int_value:w \__int_eval:w 1 + #1 + \int_value:w \int_eval:w 1 + #1 \else: \use_i:nnn \fi: @@ -231,7 +231,7 @@ \cs_new_protected:Npn \flag_log:n { \@@_show:Nn \tl_log:n } \cs_new_protected:Npn \@@_show:Nn #1#2 { - \exp_args:Nc \__kernel_check_defined:NT { flag~#2 } + \exp_args:Nc \__kernel_chk_defined:NT { flag~#2 } { \exp_args:Nx #1 { \tl_to_str:n { flag~#2~height } = \flag_height:n {#2} } @@ -249,16 +249,18 @@ % to be patched since some are defined in terms of others. % \begin{macrocode} %<*package> -\tex_ifodd:D \l@expl@enable@debug@bool - \cs_new:Npn \@@_chk_exist:n #1 - { - \flag_if_exist:nF {#1} - { - \__kernel_msg_expandable_error:nnn - { kernel } { bad-variable } { flag~#1~ } - } - } -\fi: +\__kernel_if_debug:TF + { + \cs_new:Npn \@@_chk_exist:n #1 + { + \flag_if_exist:nF {#1} + { + \__kernel_msg_expandable_error:nnn + { kernel } { bad-variable } { flag~#1~ } + } + } + } + { } %</package> % \end{macrocode} % \end{macro} @@ -300,7 +302,7 @@ \cs_new:Npn \@@_height_loop:wn #1 ; #2 { \if_cs_exist:w flag~#2~#1 \cs_end: - \exp_after:wN \@@_height_loop:wn \__int_value:w \__int_eval:w 1 + + \exp_after:wN \@@_height_loop:wn \int_value:w \int_eval:w 1 + \else: \exp_after:wN \@@_height_end:wn \fi: @@ -317,7 +319,7 @@ \cs_new:Npn \flag_raise:n #1 { \cs:w flag~#1 \exp_after:wN \cs_end: - \__int_value:w \flag_height:n {#1} ; + \int_value:w \flag_height:n {#1} ; } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3format.ins b/Master/texmf-dist/source/latex/l3kernel/l3format.ins index 472df57f282..323ed20b793 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3format.ins +++ b/Master/texmf-dist/source/latex/l3kernel/l3format.ins @@ -62,15 +62,15 @@ and all files in that bundle must be distributed together. \from{l3expan.dtx} {initex} \from{l3tl.dtx} {initex} \from{l3str.dtx} {initex} + \from{l3quark.dtx} {package} \from{l3seq.dtx} {initex} % ======== FORMAT ONLY ========= \from{l3alloc.dtx} {initex} % ============================== \from{l3int.dtx} {initex} - \from{l3intarray.dtx} {initex} \from{l3flag.dtx} {initex} - \from{l3quark.dtx} {initex} \from{l3prg.dtx} {initex} + \from{l3sys.dtx} {initex} \from{l3clist.dtx} {initex} \from{l3token.dtx} {initex} \from{l3prop.dtx} {initex} @@ -91,17 +91,17 @@ and all files in that bundle must be distributed together. \from{l3fp-trig.dtx} {initex} \from{l3fp-convert.dtx} {initex} \from{l3fp-random.dtx} {initex} + \from{l3intarray.dtx} {initex} \from{l3sort.dtx} {initex} - \from{l3tl-build.dtx} {initex} \from{l3tl-analysis.dtx}{initex} \from{l3regex.dtx} {initex} \from{l3box.dtx} {initex} \from{l3color-base.dtx} {initex} \from{l3coffins.dtx} {initex} - \from{l3sys.dtx} {initex} - \from{l3deprecation.dtx}{initex} - \from{l3candidates.dtx} {initex} \from{l3luatex.dtx} {initex,tex} + \from{l3unicode.dtx} {initex} + \from{l3candidates.dtx} {initex} + \from{l3deprecation.dtx}{initex} % ======== FORMAT ONLY ========= \from{l3final.dtx} {initex} % ============================== diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx index 295748ef5d5..f799a1d55bc 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx @@ -38,7 +38,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % \maketitle % % \begin{documentation} @@ -172,7 +172,7 @@ \cs_generate_variant:Nn \fp_log:N { c } \cs_new_protected:Npn \@@_show:NN #1#2 { - \__kernel_check_defined:NT #2 + \__kernel_chk_defined:NT #2 { \exp_args:Nx #1 { \token_to_str:N #2 = \fp_to_tl:N #2 } } } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx index 6acdf09e1af..db486f01c0d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -63,6 +63,20 @@ % % ^^A todo: make sanitize and pack more homogeneous between modules. % +% \subsection{Access to primitives} +% +% \begin{macro}{\@@_int_eval:w, \@@_int_eval_end:, \@@_int_to_roman:w} +% Largely for performance reasons, we need to directly access primitives +% rather than use \cs{int_eval:n}. This happens \emph{a lot}, so we +% use private names. The same is true for \tn{romannumeral}, although it +% is used much less widely. +% \begin{macrocode} +\cs_new_eq:NN \@@_int_eval:w \etex_numexpr:D +\cs_new_eq:NN \@@_int_eval_end: \scan_stop: +\cs_new_eq:NN \@@_int_to_roman:w \tex_romannumeral:D +% \end{macrocode} +% \end{macro} +% % \subsection{Internal representation} % % Internally, a floating point number \meta{X} is a @@ -223,7 +237,7 @@ % However, when typeset, \cs{s_@@} does nothing, and \cs{@@_chk:w} is % expanded. We define \cs{@@_chk:w} to produce an error. % \begin{macrocode} -\__scan_new:N \s_@@ +\scan_new:N \s_@@ \cs_new_protected:Npn \@@_chk:w #1 ; { \@@_misused:n { \s_@@ \@@_chk:w #1 ; } } % \end{macrocode} @@ -232,8 +246,8 @@ % \begin{macro}{\s_@@_mark, \s_@@_stop} % Aliases of \cs{tex_relax:D}, used to terminate expressions. % \begin{macrocode} -\__scan_new:N \s_@@_mark -\__scan_new:N \s_@@_stop +\scan_new:N \s_@@_mark +\scan_new:N \s_@@_stop % \end{macrocode} % \end{macro} % @@ -245,11 +259,11 @@ % A couple of scan marks used to indicate where special floating point % numbers come from. % \begin{macrocode} -\__scan_new:N \s_@@_invalid -\__scan_new:N \s_@@_underflow -\__scan_new:N \s_@@_overflow -\__scan_new:N \s_@@_division -\__scan_new:N \s_@@_exact +\scan_new:N \s_@@_invalid +\scan_new:N \s_@@_underflow +\scan_new:N \s_@@_overflow +\scan_new:N \s_@@_division +\scan_new:N \s_@@_exact % \end{macrocode} % \end{macro} % @@ -344,12 +358,12 @@ % \end{macro} % % \begin{macro}[EXP]{\@@_neg_sign:N} -% When appearing in an integer expression or after \cs{__int_value:w}, +% When appearing in an integer expression or after \cs{int_value:w}, % this expands to the sign opposite to |#1|, namely $0$ (positive) is % turned to $2$ (negative), $1$ (\texttt{nan}) to $1$, and $2$ to $0$. % \begin{macrocode} \cs_new:Npn \@@_neg_sign:N #1 - { \__int_eval:w 2 - #1 \__int_eval_end: } + { \@@_int_eval:w 2 - #1 \@@_int_eval_end: } % \end{macrocode} % \end{macro} % @@ -454,11 +468,11 @@ { \exp_after:wN \@@_exp_after_normal:Nwwwww \exp_after:wN #2 - \__int_value:w #3 \exp_after:wN ; - \__int_value:w 1 #4 \exp_after:wN ; - \__int_value:w 1 #5 \exp_after:wN ; - \__int_value:w 1 #6 \exp_after:wN ; - \__int_value:w 1 #7 \exp_after:wN ; #1 + \int_value:w #3 \exp_after:wN ; + \int_value:w 1 #4 \exp_after:wN ; + \int_value:w 1 #5 \exp_after:wN ; + \int_value:w 1 #6 \exp_after:wN ; + \int_value:w 1 #7 \exp_after:wN ; #1 } \cs_new:Npn \@@_exp_after_normal:Nwwwww #1 #2; 1 #3 ; 1 #4 ; 1 #5 ; 1 #6 ; @@ -477,7 +491,7 @@ % an error, just like usual floating point numbers. % Tuples may have zero or one element. % \begin{macrocode} -\__scan_new:N \s_@@_tuple +\scan_new:N \s_@@_tuple \cs_new_protected:Npn \@@_tuple_chk:w #1 ; { \@@_misused:n { \s_@@_tuple \@@_tuple_chk:w #1 ; } } \tl_const:Nn \c_@@_empty_tuple_fp @@ -497,10 +511,10 @@ { \@@_tuple_count:w \s_@@_tuple \@@_tuple_chk:w {#1} ; } \cs_new:Npn \@@_tuple_count:w \s_@@_tuple \@@_tuple_chk:w #1 ; { - \__int_value:w \__int_eval:w 0 - \@@_tuple_count_loop:Nw #1 { ? \__prg_break: } ; - \__prg_break_point: - \__int_eval_end: + \int_value:w \@@_int_eval:w 0 + \@@_tuple_count_loop:Nw #1 { ? \prg_break: } ; + \prg_break_point: + \@@_int_eval_end: } \cs_new:Npn \@@_tuple_count_loop:Nw #1#2; { \use_none:n #1 + 1 \@@_tuple_count_loop:Nw } @@ -510,7 +524,7 @@ % % \begin{macro}[EXP]{\@@_if_type_fp:NTwFw} % Used as \cs{@@_if_type_fp:NTwFw} \meta{marker} \Arg{true code} -% \cs{s__fp} \Arg{false code} \cs{q_stop}, this test whether the +% \cs{s_@@} \Arg{false code} \cs{q_stop}, this test whether the % \meta{marker} is \cs{s_@@} or not and runs the appropriate % \meta{code}. The very unusual syntax is for optimization purposes % as that function is used for all floating point operations. @@ -524,14 +538,14 @@ % \begin{macrocode} \cs_new:Npn \@@_array_if_all_fp:nTF #1 { - \@@_array_if_all_fp_loop:w #1 { \s_@@ \__prg_break: } ; - \__prg_break_point: \use_i:nn + \@@_array_if_all_fp_loop:w #1 { \s_@@ \prg_break: } ; + \prg_break_point: \use_i:nn } \cs_new:Npn \@@_array_if_all_fp_loop:w #1#2 ; { \@@_if_type_fp:NTwFw #1 \@@_array_if_all_fp_loop:w - \s_@@ { \__prg_break:n \use_iii:nnn } + \s_@@ { \prg_break:n \use_iii:nnn } \q_stop } % \end{macrocode} @@ -557,12 +571,9 @@ \exp_not:N \token_to_str:N #1 \exp_not:N \q_mark \tl_to_str:n { s_@@ _? } \exp_not:N \q_mark \exp_not:N \q_stop } -\use:x - { - \cs_new:Npn \exp_not:N \@@_type_from_scan:w - ##1 \tl_to_str:n { s_@@ } ##2 \exp_not:N \q_mark ##3 \exp_not:N \q_stop - {##2} - } +\exp_last_unbraced:NNNNo + \cs_new:Npn \@@_type_from_scan:w #1 + { \tl_to_str:n { s_@@ } } #2 \q_mark #3 \q_stop {#2} % \end{macrocode} % \end{macro} % @@ -645,7 +656,8 @@ % \begin{macrocode} \cs_new:Npn \@@_exp_after_tuple_o:w { \@@_exp_after_tuple_f:nw { \exp_after:wN \exp_stop_f: } } -\cs_new:Npn \@@_exp_after_tuple_f:nw #1 \s_@@_tuple \@@_tuple_chk:w #2 ; +\cs_new:Npn \@@_exp_after_tuple_f:nw + #1 \s_@@_tuple \@@_tuple_chk:w #2 ; { \exp_after:wN \s_@@_tuple \exp_after:wN \@@_tuple_chk:w @@ -670,7 +682,7 @@ % \begin{verbatim} % \cs_new:Npn \pack:NNNNNw #1 #2#3#4#5 #6; { {#2#3#4#5} {#6} } % \exp_after:wN \pack:NNNNNw -% \__int_value:w \__int_eval:w 1 0000 0000 + #1 ; +% \__fp_int_value:w \__fp_int_eval:w 1 0000 0000 + #1 ; % \end{verbatim} % The idea is that adding $10^8$ to the number ensures that it has % exactly $9$ digits, and can then easily find which digits correspond @@ -685,19 +697,19 @@ % 6677\,8899$. With simplified names, we would do % \begin{verbatim} % \exp_after:wN \post_processing:w -% \__int_value:w \__int_eval:w - 5 0000 +% \__fp_int_value:w \__fp_int_eval:w - 5 0000 % \exp_after:wN \pack:NNNNNw -% \__int_value:w \__int_eval:w 4 9995 0000 +% \__fp_int_value:w \__fp_int_eval:w 4 9995 0000 % + 12345 * 6677 % \exp_after:wN \pack:NNNNNw -% \__int_value:w \__int_eval:w 5 0000 0000 +% \__fp_int_value:w \__fp_int_eval:w 5 0000 0000 % + 12345 * 8899 ; % \end{verbatim} -% The \cs{exp_after:wN} triggers |\__int_value:w \__int_eval:w|, which +% The \cs{exp_after:wN} triggers \cs{int_value:w} \cs{@@_int_eval:w}, which % starts a first computation, whose initial value is $- 5\,0000$ (the % \enquote{leading shift}). In that computation appears an % \cs{exp_after:wN}, which triggers the nested computation -% |\__int_value:w \__int_eval:w| with starting value $4\,9995\,0000$ (the +% \cs{int_value:w} \cs{@@_int_eval:w} with starting value $4\,9995\,0000$ (the % \enquote{middle shift}). That, in turn, expands \cs{exp_after:wN} % which triggers the third computation. The third computation's value % is $5\,0000\,0000 + 12345 \times 8899$, which has $9$ digits. Adding @@ -858,7 +870,7 @@ \if_meaning:w 2 #1 + 1 \fi: - \__int_eval_end: + \@@_int_eval_end: #2#3#4; {#5} ; } \cs_new:Npn \@@_basics_pack_weird_high:NNNNNNNNw @@ -911,10 +923,10 @@ { \cs:w @@_decimate_ - \if_int_compare:w \__int_eval:w #1 > \c_@@_prec_int + \if_int_compare:w \@@_int_eval:w #1 > \c_@@_prec_int tiny \else: - \__int_to_roman:w \__int_eval:w #1 + \@@_int_to_roman:w \@@_int_eval:w #1 \fi: :Nnnnn \cs_end: @@ -970,7 +982,7 @@ \cs_new:cpn { @@_decimate_ #1 :Nnnnn } ##1 ##2##3##4##5 { \exp_after:wN ##1 - \__int_value:w + \int_value:w \exp_after:wN \@@_round_digit:Nw #2 ; \@@_decimate_pack:nnnnnnnnnnw #3 ; } @@ -996,7 +1008,7 @@ % % \begin{macro}[EXP]{\@@_decimate_pack:nnnnnnnnnnw} % The computation of the \meta{rounding} digit leaves an unfinished -% \cs{__int_value:w}, which expands the following functions. This +% \cs{int_value:w}, which expands the following functions. This % allows us to repack nicely the digits we keep. Those digits come % as an alternation of unbraced and braced blocks of $4$ digits, % such that the first $5$ groups of token consist in $4$ single digits, @@ -1025,12 +1037,12 @@ % treated using a few standard functions which we define now. A typical % use context for those functions would be % \begin{syntax} -% |\if_case:w| \meta{integer} |\exp_stop_f:| -% | \@@_case_return_o:Nw| \meta{fp var} -% |\or: \@@_case_use:nw| \Arg{some computation} -% |\or: \@@_case_return_same_o:w| -% |\or: \@@_case_return:nw| \Arg{something} -% |\fi:| +% \cs{if_case:w} \meta{integer} \cs{exp_stop_f:} +% | |\cs{@@_case_return_o:Nw} \meta{fp var} +% \cs{or:} \cs{@@_case_use:nw} \Arg{some computation} +% \cs{or:} \cs{@@_case_return_same_o:w} +% \cs{or:} \cs{@@_case_return:nw} \Arg{something} +% \cs{fi:} % \meta{junk} % \meta{floating point} % \end{syntax} @@ -1160,7 +1172,7 @@ \or: \@@_case_return:nw { - \exp_after:wN \@@_small_int_true:wTF \__int_value:w + \exp_after:wN \@@_small_int_true:wTF \int_value:w \if_meaning:w 2 #2 - \fi: 1 0000 0000 ; } \else: \@@_case_return:nw \use_ii:nn @@ -1178,7 +1190,7 @@ { \if_meaning:w 0 #1 \exp_after:wN \@@_small_int_true:wTF - \__int_value:w \if_meaning:w 2 #5 - \fi: + \int_value:w \if_meaning:w 2 #5 - \fi: \if_int_compare:w #2 > 0 \exp_stop_f: 1 0000 0000 \else: @@ -1224,6 +1236,33 @@ % \end{macro} % \end{macro} % +% \subsection{Fast string comparison} +% +% \begin{macro}{\@@_str_if_eq_x:nn} +% A private version of the low-level string comparison function. As +% the nature of the arguments is restricted and as speed is of the essence, +% this version does not seek to deal with |#| tokens. +% No \pkg{l3sys} or \pkg{l3luatex} just yet so we have to define in terms of +% primitives. +% \begin{macrocode} +\cs_new:Npn \@@_str_if_eq_x:nn #1#2 { \pdftex_strcmp:D {#1} {#2} } +\sys_if_engine_luatex:T + { + \cs_set:Npn \@@_str_if_eq_x:nn #1#2 + { + \luatex_directlua:D + { + l3kernel.strcmp + ( + " \luatex_luaescapestring:D {#1}", + " \luatex_luaescapestring:D {#2}" + ) + } + } + } +% \end{macrocode} +% \end{macro} +% % \subsection{Name of a function from its \pkg{l3fp-parse} name} % % \begin{macro}[EXP]{\@@_func_to_name:N, \@@_func_to_name_aux:w} @@ -1231,10 +1270,14 @@ % This is used in error messages hence does not need to be fast. % \begin{macrocode} \cs_new:Npn \@@_func_to_name:N #1 - { \exp_last_unbraced:Nf \@@_func_to_name_aux:w { \cs_to_str:N #1 } X } + { + \exp_last_unbraced:Nf + \@@_func_to_name_aux:w { \cs_to_str:N #1 } X + } \cs_set_protected:Npn \@@_tmp:w #1 #2 { \cs_new:Npn \@@_func_to_name_aux:w ##1 #1 ##2 #2 ##3 X {##2} } -\exp_args:Nff \@@_tmp:w { \tl_to_str:n { @@_ } } { \tl_to_str:n { _o: } } +\exp_args:Nff \@@_tmp:w { \tl_to_str:n { @@_ } } + { \tl_to_str:n { _o: } } % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx index 347172c2a1f..76948f5a45c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx @@ -38,7 +38,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -110,7 +110,7 @@ % opposite signs, shift the significand of the smaller one to match the % bigger one, perform the addition or subtraction of significands, % check for a carry, round, and pack using the -% \cs[no-index]{__fp_basics_pack_\ldots{}} functions. +% \cs[no-index]{@@_basics_pack_\ldots{}} functions. % \end{itemize} % The trickiest part is to round correctly when adding or subtracting % normal floating point numbers. @@ -139,7 +139,7 @@ % the second operand's sign should be changed. If the % \meta{types} |#2| and |#4| are the same, dispatch to case |#2| ($0$, % $1$, $2$, or $3$), where we call specialized functions: thanks to -% \cs{__int_value:w}, those receive the tweaked \meta{sign_2} +% \cs{int_value:w}, those receive the tweaked \meta{sign_2} % (expansion of |#1#5|) as an argument. If the \meta{types} are % distinct, the result is simply the floating point number with the % highest \meta{type}. Since case $3$ (used for two \texttt{nan}) @@ -162,11 +162,11 @@ \fi: \fi: \exp_stop_f: - \exp_after:wN \@@_add_zeros_o:Nww \__int_value:w - \or: \exp_after:wN \@@_add_normal_o:Nww \__int_value:w - \or: \exp_after:wN \@@_add_inf_o:Nww \__int_value:w + \exp_after:wN \@@_add_zeros_o:Nww \int_value:w + \or: \exp_after:wN \@@_add_normal_o:Nww \int_value:w + \or: \exp_after:wN \@@_add_inf_o:Nww \int_value:w \or: \@@_case_return_i_o:ww - \else: \exp_after:wN \@@_add_return_ii_o:Nww \__int_value:w + \else: \exp_after:wN \@@_add_return_ii_o:Nww \int_value:w \fi: #1 #5 \s_@@ \@@_chk:w #2 #3 ; @@ -261,7 +261,7 @@ % \meta{body_2} |;| % \end{quote} % Since we are doing an addition, the final sign is \meta{sign_1}. -% Start an \cs{__int_eval:w}, responsible for computing the exponent: +% Start an \cs{@@_int_eval:w}, responsible for computing the exponent: % the result, and the \meta{final sign} are then given to % \cs{@@_sanitize:Nw} which checks for overflow. The exponent is % computed as the largest exponent |#2| or |#5|, incremented if there @@ -275,15 +275,15 @@ { \exp_after:wN \@@_sanitize:Nw \exp_after:wN #1 - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \if_int_compare:w #2 > #5 \exp_stop_f: #2 - \exp_after:wN \@@_add_big_i_o:wNww \__int_value:w - + \exp_after:wN \@@_add_big_i_o:wNww \int_value:w - \else: #5 - \exp_after:wN \@@_add_big_ii_o:wNww \__int_value:w + \exp_after:wN \@@_add_big_ii_o:wNww \int_value:w \fi: - \__int_eval:w #5 - #2 ; #1 #3; + \@@_int_eval:w #5 - #2 ; #1 #3; } % \end{macrocode} % \end{macro} @@ -340,9 +340,9 @@ \cs_new:Npn \@@_add_significand_o:NnnwnnnnN #1 #2#3 #4; #5#6#7#8 { \exp_after:wN \@@_add_significand_test_o:N - \__int_value:w \__int_eval:w 1#5#6 + #2 + \int_value:w \@@_int_eval:w 1#5#6 + #2 \exp_after:wN \@@_add_significand_pack:NNNNNNN - \__int_value:w \__int_eval:w 1#7#8 + #3 ; #1 + \int_value:w \@@_int_eval:w 1#7#8 + #3 ; #1 } \cs_new:Npn \@@_add_significand_pack:NNNNNNN #1 #2#3#4#5#6#7 { @@ -377,9 +377,9 @@ #1; #2; #3#4 ; #5#6 { \exp_after:wN \@@_basics_pack_high:NNNNNw - \__int_value:w \__int_eval:w 1 #1 + \int_value:w \@@_int_eval:w 1 #1 \exp_after:wN \@@_basics_pack_low:NNNNNw - \__int_value:w \__int_eval:w 1 #2 #3#4 + \int_value:w \@@_int_eval:w 1 #2 #3#4 + \@@_round:NNN #6 #4 #5 \exp_after:wN ; } @@ -400,13 +400,13 @@ { + 1 \exp_after:wN \@@_basics_pack_weird_high:NNNNNNNNw - \__int_value:w \__int_eval:w 1 1 #1 + \int_value:w \@@_int_eval:w 1 1 #1 \exp_after:wN \@@_basics_pack_weird_low:NNNNw - \__int_value:w \__int_eval:w 1 #2#3 + + \int_value:w \@@_int_eval:w 1 #2#3 + \exp_after:wN \@@_round:NNN \exp_after:wN #6 \exp_after:wN #3 - \__int_value:w \@@_round_digit:Nw #4 #5 ; + \int_value:w \@@_round_digit:Nw #4 #5 ; \exp_after:wN ; } % \end{macrocode} @@ -443,7 +443,7 @@ \cs_new:Npn \@@_sub_npos_ii_o:Nnwnw #1 #2; #3; { \exp_after:wN \@@_sub_npos_i_o:Nnwnw - \__int_value:w \@@_neg_sign:N #1 + \int_value:w \@@_neg_sign:N #1 #3; #2; } % \end{macrocode} @@ -465,13 +465,13 @@ { \exp_after:wN \@@_sanitize:Nw \exp_after:wN #1 - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w #2 \if_int_compare:w #2 = #4 \exp_stop_f: \exp_after:wN \@@_sub_back_near_o:nnnnnnnnN \else: \exp_after:wN \@@_decimate:nNnnnn \exp_after:wN - { \__int_value:w \__int_eval:w #2 - #4 - 1 \exp_after:wN } + { \int_value:w \@@_int_eval:w #2 - #4 - 1 \exp_after:wN } \exp_after:wN \@@_sub_back_far_o:NnnwnnnnN \fi: #5 @@ -500,9 +500,9 @@ \cs_new:Npn \@@_sub_back_near_o:nnnnnnnnN #1#2#3#4 #5#6#7#8 #9 { \exp_after:wN \@@_sub_back_near_after:wNNNNw - \__int_value:w \__int_eval:w 10#5#6 - #1#2 - 11 + \int_value:w \@@_int_eval:w 10#5#6 - #1#2 - 11 \exp_after:wN \@@_sub_back_near_pack:NNNNNNw - \__int_value:w \__int_eval:w 11#7#8 - #3#4 \exp_after:wN ; + \int_value:w \@@_int_eval:w 11#7#8 - #3#4 \exp_after:wN ; } \cs_new:Npn \@@_sub_back_near_pack:NNNNNNw #1#2#3#4#5#6#7 ; { + #1#2 ; {#3#4#5#6} {#7} ; } @@ -543,7 +543,7 @@ \cs_new:Npn \@@_sub_back_shift:wnnnn ; #1#2 { \exp_after:wN \@@_sub_back_shift_ii:ww - \__int_value:w #1 #2 0 ; + \int_value:w #1 #2 0 ; } \cs_new:Npn \@@_sub_back_shift_ii:ww #1 0 ; #2#3 ; { @@ -551,7 +551,7 @@ - 7 - \exp_after:wN \use_i:nnn \exp_after:wN \@@_sub_back_shift_iii:NNNNNNNNw - \__int_value:w #2#3 0 ~ 123456789; + \int_value:w #2#3 0 ~ 123456789; \else: - \@@_sub_back_shift_iii:NNNNNNNNw #1 123456789; \fi: @@ -559,7 +559,7 @@ \exp_after:wN \@@_pack_twice_four:wNNNNNNNN \exp_after:wN \@@_sub_back_shift_iv:nnnnw \exp_after:wN ; - \__int_value:w + \int_value:w #1 ~ #2#3 0 ~ 0000 0000 0000 000 ; } \cs_new:Npn \@@_sub_back_shift_iii:NNNNNNNNw #1#2#3#4#5#6#7#8#9; {#8} @@ -658,9 +658,9 @@ { - 1 \exp_after:wN \@@_sub_back_near_after:wNNNNw - \__int_value:w \__int_eval:w 1#30 - #1 - 11 + \int_value:w \@@_int_eval:w 1#30 - #1 - 11 \exp_after:wN \@@_sub_back_near_pack:NNNNNNw - \__int_value:w \__int_eval:w 11 0000 0000 + #40 - #2 + \int_value:w \@@_int_eval:w 11 0000 0000 + #40 - #2 - \exp_after:wN \@@_round_neg:NNN \exp_after:wN #6 \use_none:nnnnnnn #2 #5 @@ -678,7 +678,7 @@ % complicated: we have two \meta{rounding} digits |#3| and |#6| (from % the decimation, and from the new shift) to take into account, and % getting the parity of the main result requires a computation. The -% first \cs{__int_value:w} triggers the second one because the number +% first \cs{int_value:w} triggers the second one because the number % is unfinished; we can thus not use $0$ in place of $2$ there. % \begin{macrocode} \cs_new:Npn \@@_sub_back_very_far_o:wwwwNN #1#2#3#4#5#6#7 @@ -691,15 +691,15 @@ \cs_new:Npn \@@_sub_back_very_far_ii_o:nnNwwNN #1#2 ; #3 ; #4 ~ #5; #6#7 { \exp_after:wN \@@_basics_pack_high:NNNNNw - \__int_value:w \__int_eval:w 1#4 - #1 - 1 + \int_value:w \@@_int_eval:w 1#4 - #1 - 1 \exp_after:wN \@@_basics_pack_low:NNNNNw - \__int_value:w \__int_eval:w 2#5 - #2 + \int_value:w \@@_int_eval:w 2#5 - #2 - \exp_after:wN \@@_round_neg:NNN \exp_after:wN #7 - \__int_value:w - \if_int_odd:w \__int_eval:w #5 - #2 \__int_eval_end: + \int_value:w + \if_int_odd:w \@@_int_eval:w #5 - #2 \@@_int_eval_end: 1 \else: 2 \fi: - \__int_value:w \@@_round_digit:Nw #3 #6 ; + \int_value:w \@@_round_digit:Nw #3 #6 ; \exp_after:wN ; } % \end{macrocode} @@ -752,7 +752,7 @@ \cs_new:Npn \@@_mul_cases_o:NnNnww #1#2#3#4 \s_@@ \@@_chk:w #5#6#7; \s_@@ \@@_chk:w #8#9 { - \if_case:w \__int_eval:w + \if_case:w \@@_int_eval:w \if_int_compare:w #5 #8 = 11 ~ 1 \else: @@ -771,7 +771,7 @@ \fi: \fi: \if_meaning:w #6 #9 - 1 \fi: - \__int_eval_end: + \@@_int_eval_end: \@@_case_use:nw { #3 0 } \or: \@@_case_use:nw { #3 2 } \or: \@@_case_return_i_o:ww @@ -802,7 +802,7 @@ % \cs{s_@@} \cs{@@_chk:w} |1| \meta{sign_2} \Arg{exp_2} \meta{body_2} |;| % \end{quote} % After the computation, \cs{@@_sanitize:Nw} checks for overflow or -% underflow. As we did for addition, \cs{__int_eval:w} computes the +% underflow. As we did for addition, \cs{@@_int_eval:w} computes the % exponent, catching any shift coming from the computation in the % significand. The \meta{final sign} is needed to do the rounding % properly in the significand computation. We setup the post-expansion @@ -815,7 +815,7 @@ { \exp_after:wN \@@_sanitize:Nw \exp_after:wN #1 - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w #4 + #8 \@@_mul_significand_o:nnnnNnnnn #5 #1 #9 } @@ -834,7 +834,7 @@ % the last \cs{@@_mul_significand_drop:NNNNNw}; one is for % \cs{@@_round_digit:Nw} later on; and one, preceded by % \cs{exp_after:wN}, which is correctly expanded (within an -% \cs{__int_eval:w}), is used by \cs{@@_basics_pack_low:NNNNNw}. +% \cs{@@_int_eval:w}), is used by \cs{@@_basics_pack_low:NNNNNw}. % % The product of two $16$ digit integers has $31$ or $32$ digits, % but it is impossible to know which one before computing. The place @@ -844,25 +844,27 @@ % is between $100$ and $9999$ inclusive), and a compact version of % the remaining $3$ blocks. Afterwards, the number of digits is % known, and we can do the rounding within yet another set of -% \cs{__int_eval:w}. +% \cs{@@_int_eval:w}. % \begin{macrocode} \cs_new:Npn \@@_mul_significand_o:nnnnNnnnn #1#2#3#4 #5 #6#7#8#9 { \exp_after:wN \@@_mul_significand_test_f:NNN \exp_after:wN #5 - \__int_value:w \__int_eval:w 99990000 + #1*#6 + + \int_value:w \@@_int_eval:w 99990000 + #1*#6 + \exp_after:wN \@@_mul_significand_keep:NNNNNw - \__int_value:w \__int_eval:w 99990000 + #1*#7 + #2*#6 + + \int_value:w \@@_int_eval:w 99990000 + #1*#7 + #2*#6 + \exp_after:wN \@@_mul_significand_keep:NNNNNw - \__int_value:w \__int_eval:w 99990000 + #1*#8 + #2*#7 + #3*#6 + + \int_value:w \@@_int_eval:w 99990000 + #1*#8 + #2*#7 + #3*#6 + \exp_after:wN \@@_mul_significand_drop:NNNNNw - \__int_value:w \__int_eval:w 99990000 + #1*#9 + #2*#8 + #3*#7 + #4*#6 + + \int_value:w \@@_int_eval:w 99990000 + #1*#9 + #2*#8 + + #3*#7 + #4*#6 + \exp_after:wN \@@_mul_significand_drop:NNNNNw - \__int_value:w \__int_eval:w 99990000 + #2*#9 + #3*#8 + #4*#7 + + \int_value:w \@@_int_eval:w 99990000 + #2*#9 + #3*#8 + + #4*#7 + \exp_after:wN \@@_mul_significand_drop:NNNNNw - \__int_value:w \__int_eval:w 99990000 + #3*#9 + #4*#8 + + \int_value:w \@@_int_eval:w 99990000 + #3*#9 + #4*#8 + \exp_after:wN \@@_mul_significand_drop:NNNNNw - \__int_value:w \__int_eval:w 100000000 + #4*#9 ; + \int_value:w \@@_int_eval:w 100000000 + #4*#9 ; ; \exp_after:wN ; } \cs_new:Npn \@@_mul_significand_drop:NNNNNw #1#2#3#4#5 #6; @@ -910,13 +912,13 @@ \cs_new:Npn \@@_mul_significand_large_f:NwwNNNN #1 #2; #3; #4#5#6#7; + { \exp_after:wN \@@_basics_pack_high:NNNNNw - \__int_value:w \__int_eval:w 1#2 + \int_value:w \@@_int_eval:w 1#2 \exp_after:wN \@@_basics_pack_low:NNNNNw - \__int_value:w \__int_eval:w 1#3#4#5#6#7 + \int_value:w \@@_int_eval:w 1#3#4#5#6#7 + \exp_after:wN \@@_round:NNN \exp_after:wN #1 \exp_after:wN #7 - \__int_value:w \@@_round_digit:Nw + \int_value:w \@@_round_digit:Nw } % \end{macrocode} % \end{macro} @@ -933,13 +935,13 @@ { - 1 \exp_after:wN \@@_basics_pack_high:NNNNNw - \__int_value:w \__int_eval:w 1#3#4 + \int_value:w \@@_int_eval:w 1#3#4 \exp_after:wN \@@_basics_pack_low:NNNNNw - \__int_value:w \__int_eval:w 1#5#6#7 + \int_value:w \@@_int_eval:w 1#5#6#7 + \exp_after:wN \@@_round:NNN \exp_after:wN #1 \exp_after:wN #7 - \__int_value:w \@@_round_digit:Nw + \int_value:w \@@_round_digit:Nw } % \end{macrocode} % \end{macro} @@ -1003,10 +1005,10 @@ { \exp_after:wN \@@_sanitize:Nw \exp_after:wN #1 - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w #3 - #6 \exp_after:wN \@@_div_significand_i_o:wnnw - \__int_value:w \__int_eval:w #7 \use_i:nnnn #8 + 1 ; + \int_value:w \@@_int_eval:w #7 \use_i:nnnn #8 + 1 ; #4 {#7}{#8}#9 ; #1 @@ -1052,7 +1054,7 @@ % \leq 10^{4} \frac{A}{Z} % \end{equation*} % Subtracting $1$ at the end takes care of the fact that \eTeX{}'s -% \cs{__int_eval:w} rounds divisions instead of truncating (really, +% \cs{@@_int_eval:w} rounds divisions instead of truncating (really, % $1/2$ would be sufficient, but we work with integers). We add $1$ to % $Z_{1}$ because $Z_{1} \leq 10^{4}Z < Z_{1}+1$ and we need $Q_{A}$ to % be an underestimate. However, we are now underestimating $Q_{A}$ too @@ -1196,21 +1198,21 @@ % \meta{continuation} arguments for $4$ consecutive calls to % \cs{@@_div_significand_calc:wwnnnnnnn}. Each of these calls needs % \meta{y} (|#1|), and it turns out that we need post-expansion there, -% hence the \cs{__int_value:w}. Here, |#4| is six brace groups, which +% hence the \cs{int_value:w}. Here, |#4| is six brace groups, which % give the six first |n|-type arguments of the \texttt{calc} function. % \begin{macrocode} \cs_new:Npn \@@_div_significand_i_o:wnnw #1 ; #2#3 #4 ; { \exp_after:wN \@@_div_significand_test_o:w - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \exp_after:wN \@@_div_significand_calc:wwnnnnnnn - \__int_value:w \__int_eval:w 999999 + #2 #3 0 / #1 ; + \int_value:w \@@_int_eval:w 999999 + #2 #3 0 / #1 ; #2 #3 ; #4 - { \exp_after:wN \@@_div_significand_ii:wwn \__int_value:w #1 } - { \exp_after:wN \@@_div_significand_ii:wwn \__int_value:w #1 } - { \exp_after:wN \@@_div_significand_ii:wwn \__int_value:w #1 } - { \exp_after:wN \@@_div_significand_iii:wwnnnnn \__int_value:w #1 } + { \exp_after:wN \@@_div_significand_ii:wwn \int_value:w #1 } + { \exp_after:wN \@@_div_significand_ii:wwn \int_value:w #1 } + { \exp_after:wN \@@_div_significand_ii:wwn \int_value:w #1 } + { \exp_after:wN \@@_div_significand_iii:wwnnnnn \int_value:w #1 } } % \end{macrocode} % \end{macro} @@ -1282,37 +1284,39 @@ \exp_after:wN \@@_div_significand_calc_ii:wwnnnnnnn \fi: } -\cs_new:Npn \@@_div_significand_calc_i:wwnnnnnnn #1; #2;#3#4 #5#6#7#8 #9 +\cs_new:Npn \@@_div_significand_calc_i:wwnnnnnnn + #1; #2;#3#4 #5#6#7#8 #9 { 1 1 #1 #9 \exp_after:wN ; - \__int_value:w \__int_eval:w \c_@@_Bigg_leading_shift_int + \int_value:w \@@_int_eval:w \c_@@_Bigg_leading_shift_int + #2 - #1 * #5 - #5#60 \exp_after:wN \@@_pack_Bigg:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_Bigg_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_Bigg_middle_shift_int + #3 - #1 * #6 - #70 \exp_after:wN \@@_pack_Bigg:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_Bigg_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_Bigg_middle_shift_int + #4 - #1 * #7 - #80 \exp_after:wN \@@_pack_Bigg:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_Bigg_trailing_shift_int + \int_value:w \@@_int_eval:w \c_@@_Bigg_trailing_shift_int - #1 * #8 ; {#5}{#6}{#7}{#8} } -\cs_new:Npn \@@_div_significand_calc_ii:wwnnnnnnn #1; #2;#3#4 #5#6#7#8 #9 +\cs_new:Npn \@@_div_significand_calc_ii:wwnnnnnnn + #1; #2;#3#4 #5#6#7#8 #9 { 1 0 #1 #9 \exp_after:wN ; - \__int_value:w \__int_eval:w \c_@@_Bigg_leading_shift_int + \int_value:w \@@_int_eval:w \c_@@_Bigg_leading_shift_int + #2 - #1 * #5 \exp_after:wN \@@_pack_Bigg:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_Bigg_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_Bigg_middle_shift_int + #3 - #1 * #6 \exp_after:wN \@@_pack_Bigg:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_Bigg_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_Bigg_middle_shift_int + #4 - #1 * #7 \exp_after:wN \@@_pack_Bigg:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_Bigg_trailing_shift_int + \int_value:w \@@_int_eval:w \c_@@_Bigg_trailing_shift_int - #1 * #8 ; {#5}{#6}{#7}{#8} } @@ -1328,7 +1332,7 @@ % \meta{continuations} \meta{sign} % \end{quote} % Compute $Q_{B}$ by evaluating $\meta{B_1}\meta{B_2}0 / y - 1$. The -% result is output to the left, in an \cs{__int_eval:w} which we +% result is output to the left, in an \cs{@@_int_eval:w} which we % start now. Once that is evaluated (and the other $Q_{i}$ also, % since later expansions are triggered by this one), a packing % auxiliary takes care of placing the digits of $Q_{B}$ in an @@ -1339,9 +1343,9 @@ \cs_new:Npn \@@_div_significand_ii:wwn #1; #2;#3 { \exp_after:wN \@@_div_significand_pack:NNN - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \exp_after:wN \@@_div_significand_calc:wwnnnnnnn - \__int_value:w \__int_eval:w 999999 + #2 #3 0 / #1 ; #2 #3 ; + \int_value:w \@@_int_eval:w 999999 + #2 #3 0 / #1 ; #2 #3 ; } % \end{macrocode} % \end{macro} @@ -1361,7 +1365,7 @@ { 0 \exp_after:wN \@@_div_significand_iv:wwnnnnnnn - \__int_value:w \__int_eval:w ( 2 * #2 #3) / #6 #7 ; % <- P + \int_value:w \@@_int_eval:w ( 2 * #2 #3) / #6 #7 ; % <- P #2 ; {#3} {#4} {#5} {#6} {#7} } @@ -1420,17 +1424,17 @@ { + 5 * #1 \exp_after:wN \@@_div_significand_vi:Nw - \__int_value:w \__int_eval:w -20 + 2*#2#3 - #1*#6#7 + + \int_value:w \@@_int_eval:w -20 + 2*#2#3 - #1*#6#7 + \exp_after:wN \@@_div_significand_v:NN - \__int_value:w \__int_eval:w 199980 + 2*#4 - #1*#8 + + \int_value:w \@@_int_eval:w 199980 + 2*#4 - #1*#8 + \exp_after:wN \@@_div_significand_v:NN - \__int_value:w \__int_eval:w 200000 + 2*#5 - #1*#9 ; + \int_value:w \@@_int_eval:w 200000 + 2*#5 - #1*#9 ; } -\cs_new:Npn \@@_div_significand_v:NN #1#2 { #1#2 \__int_eval_end: + } +\cs_new:Npn \@@_div_significand_v:NN #1#2 { #1#2 \@@_int_eval_end: + } \cs_new:Npn \@@_div_significand_vi:Nw #1#2; { \if_meaning:w 0 #1 - \if_int_compare:w \__int_eval:w #2 > 0 + 1 \fi: + \if_int_compare:w \@@_int_eval:w #2 > 0 + 1 \fi: \else: \if_meaning:w - #1 - \else: + \fi: 1 \fi: @@ -1500,9 +1504,9 @@ 0 #1; #2; #3; #4#5#6#7#8; #9 { \exp_after:wN \@@_basics_pack_high:NNNNNw - \__int_value:w \__int_eval:w 1 #1#2 + \int_value:w \@@_int_eval:w 1 #1#2 \exp_after:wN \@@_basics_pack_low:NNNNNw - \__int_value:w \__int_eval:w 1 #3#4#5#6#7 + \int_value:w \@@_int_eval:w 1 #3#4#5#6#7 + \@@_round:NNN #9 #7 #8 \exp_after:wN ; } @@ -1524,13 +1528,13 @@ { + 1 \exp_after:wN \@@_basics_pack_weird_high:NNNNNNNNw - \__int_value:w \__int_eval:w 1 #1 #2 + \int_value:w \@@_int_eval:w 1 #1 #2 \exp_after:wN \@@_basics_pack_weird_low:NNNNw - \__int_value:w \__int_eval:w 1 #3 #4 #5 #6 + + \int_value:w \@@_int_eval:w 1 #3 #4 #5 #6 + \exp_after:wN \@@_round:NNN \exp_after:wN #9 \exp_after:wN #6 - \__int_value:w \@@_round_digit:Nw #7 #8 ; + \int_value:w \@@_round_digit:Nw #7 #8 ; \exp_after:wN ; } % \end{macrocode} @@ -1574,7 +1578,7 @@ { \exp_after:wN \@@_sanitize:Nw \exp_after:wN 0 - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \if_int_odd:w #1 \exp_stop_f: \exp_after:wN \@@_sqrt_npos_auxi_o:wwnnN \fi: @@ -1663,11 +1667,11 @@ { \if_int_compare:w #1 = #2 \exp_stop_f: \exp_after:wN \@@_sqrt_auxi_o:NNNNwnnN - \__int_value:w \__int_eval:w 9999 9999 + + \int_value:w \@@_int_eval:w 9999 9999 + \exp_after:wN \@@_use_none_until_s:w \fi: \exp_after:wN \@@_sqrt_Newton_o:wwn - \__int_value:w \__int_eval:w (#1 + #3 * 1 0000 0000 / #1) / 2 ; + \int_value:w \@@_int_eval:w (#1 + #3 * 1 0000 0000 / #1) / 2 ; #1; {#3} } % \end{macrocode} @@ -1756,32 +1760,32 @@ \cs_new:Npn \@@_sqrt_auxii_o:NnnnnnnnN #1 #2#3#4#5#6 #7#8#9 { \exp_after:wN #1 - \__int_value:w \__int_eval:w \c_@@_big_leading_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_leading_shift_int + #7 - #2 * #2 \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_big_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int - 2 * #2 * #3 \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_big_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int + #8 - #3 * #3 - 2 * #2 * #4 \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_big_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int - 2 * #3 * #4 - 2 * #2 * #5 \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_big_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int + #9 000 0000 - #4 * #4 - 2 * #3 * #5 - 2 * #2 * #6 \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_big_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int - 2 * #4 * #5 - 2 * #3 * #6 \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_big_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int - #5 * #5 - 2 * #4 * #6 \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int - 2 * #5 * #6 \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \c_@@_big_trailing_shift_int - #6 * #6 ; % ( @@ -1839,18 +1843,18 @@ { \if_int_compare:w #1 > 1 \exp_stop_f: \exp_after:wN \@@_sqrt_auxiv_o:NNNNNw - \__int_value:w \__int_eval:w (#1#2 %) + \int_value:w \@@_int_eval:w (#1#2 %) \else: \if_int_compare:w #1#2 > 1 \exp_stop_f: \exp_after:wN \@@_sqrt_auxv_o:NNNNNw - \__int_value:w \__int_eval:w (#1#2#3 %) + \int_value:w \@@_int_eval:w (#1#2#3 %) \else: \if_int_compare:w #1#2#3 > 1 \exp_stop_f: \exp_after:wN \@@_sqrt_auxvi_o:NNNNNw - \__int_value:w \__int_eval:w (#1#2#3#4 %) + \int_value:w \@@_int_eval:w (#1#2#3#4 %) \else: \exp_after:wN \@@_sqrt_auxvii_o:NNNNNw - \__int_value:w \__int_eval:w (#1#2#3#4#5 %) + \int_value:w \@@_int_eval:w (#1#2#3#4#5 %) \fi: \fi: \fi: @@ -1880,11 +1884,11 @@ \cs_new:Npn \@@_sqrt_auxviii_o:nnnnnnn #1#2 #3#4#5#6#7 { \exp_after:wN \@@_sqrt_auxix_o:wnwnw - \__int_value:w \__int_eval:w #3 + \int_value:w \@@_int_eval:w #3 \exp_after:wN \@@_basics_pack_low:NNNNNw - \__int_value:w \__int_eval:w #1 + 1#4#5 + \int_value:w \@@_int_eval:w #1 + 1#4#5 \exp_after:wN \@@_basics_pack_low:NNNNNw - \__int_value:w \__int_eval:w #2 + 1#6#7 ; + \int_value:w \@@_int_eval:w #2 + 1#6#7 ; } \cs_new:Npn \@@_sqrt_auxix_o:wnwnw #1; #2#3; #4#5; { @@ -1930,7 +1934,7 @@ \cs_new:Npn \@@_sqrt_auxx_o:Nnnnnnnn #1#2#3 #4#5#6#7#8 { \exp_after:wN \@@_sqrt_auxxi_o:wwnnN - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w (#8 + 2499) / 5000 * 5000 ; {#4} {#5} {#6} {#7} ; } @@ -1969,10 +1973,10 @@ \fi: \fi: \exp_after:wN \@@_sqrt_auxxiv_o:wnnnnnnnN - \__int_value:w 9998 + \int_value:w 9998 \else: \exp_after:wN \@@_sqrt_auxxiv_o:wnnnnnnnN - \__int_value:w 10000 + \int_value:w 10000 \fi: ; } @@ -2008,18 +2012,18 @@ \cs_new:Npn \@@_sqrt_auxxiv_o:wnnnnnnnN #1; #2#3#4#5#6 #7#8#9 { \exp_after:wN \@@_basics_pack_high:NNNNNw - \__int_value:w \__int_eval:w 1 0000 0000 + #2#3 + \int_value:w \@@_int_eval:w 1 0000 0000 + #2#3 \exp_after:wN \@@_basics_pack_low:NNNNNw - \__int_value:w \__int_eval:w 1 0000 0000 + \int_value:w \@@_int_eval:w 1 0000 0000 + #4#5 \if_int_compare:w #6 > #1 \exp_stop_f: + 1 \fi: + \exp_after:wN \@@_round:NNN \exp_after:wN 0 \exp_after:wN 0 - \__int_value:w + \int_value:w \exp_after:wN \use_i:nn \exp_after:wN \@@_round_digit:Nw - \__int_value:w \__int_eval:w #6 + 19999 - #1 ; + \int_value:w \@@_int_eval:w #6 + 19999 - #1 ; \exp_after:wN ; } % \end{macrocode} @@ -2061,7 +2065,7 @@ \exp_after:wN \s_@@ \exp_after:wN \@@_chk:w \exp_after:wN #2 - \__int_value:w + \int_value:w \if_case:w #3 \exp_stop_f: #1 \or: 1 \or: 0 \fi: \exp_stop_f: #4; } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx index 18253136f24..7d32164b5b9 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -109,11 +109,11 @@ \cs_new:Npn \@@_trim_zeros:w #1 ; { \@@_trim_zeros_loop:w #1 - ; \@@_trim_zeros_loop:w 0; \@@_trim_zeros_dot:w .; \s__stop + ; \@@_trim_zeros_loop:w 0; \@@_trim_zeros_dot:w .; \s_stop } \cs_new:Npn \@@_trim_zeros_loop:w #1 0; #2 { #2 #1 ; #2 } \cs_new:Npn \@@_trim_zeros_dot:w #1 .; { \@@_trim_zeros_end:w #1 ; } -\cs_new:Npn \@@_trim_zeros_end:w #1 ; #2 \s__stop { #1 } +\cs_new:Npn \@@_trim_zeros_end:w #1 ; #2 \s_stop { #1 } % \end{macrocode} % \end{macro} % \end{macro} @@ -203,7 +203,7 @@ { \exp_after:wN \@@_to_scientific_normal:wNw \exp_after:wN e - \__int_value:w \__int_eval:w #2 - 1 + \int_value:w \@@_int_eval:w #2 - 1 ; #3 #4 #5 #6 ; } \cs_new:Npn \@@_to_scientific_normal:wNw #1 ; #2#3; @@ -265,7 +265,7 @@ % most likely won't be needed. Normal numbers with an exponent in the % range $[1,15]$ have that number of digits before the decimal % separator: \enquote{decimate} them, and remove leading zeros with -% \cs{__int_value:w}, then trim trailing zeros and dot. Normal +% \cs{int_value:w}, then trim trailing zeros and dot. Normal % numbers with an exponent $16$ or larger have no decimal separator, % we only need to add trailing zeros. When the exponent is % non-positive, the result should be $0.\meta{zeros}\meta{digits}$, @@ -321,7 +321,7 @@ } \cs_new:Npn \@@_to_decimal_large:Nnnw #1#2#3#4; { - \exp_after:wN \@@_trim_zeros:w \__int_value:w + \exp_after:wN \@@_trim_zeros:w \int_value:w \if_int_compare:w #2 > 0 \exp_stop_f: #2 \fi: @@ -397,7 +397,7 @@ { \exp_after:wN \@@_to_tl_scientific:wNw \exp_after:wN e - \__int_value:w \__int_eval:w #2 - 1 + \int_value:w \@@_int_eval:w #2 - 1 ; #3 #4 #5 #6 ; } \cs_new:Npn \@@_to_tl_scientific:wNw #1 ; #2#3; @@ -503,7 +503,7 @@ \exp_after:wN \@@_from_dim_test:ww \exp_after:wN 0 \exp_after:wN , - \__int_value:w \etex_glueexpr:D #1 ; + \int_value:w \etex_glueexpr:D #1 ; } \cs_new:Npn \@@_from_dim_test:ww #1, #2 { @@ -511,11 +511,11 @@ \@@_case_return:nw { \exp_after:wN \c_zero_fp } \else: \exp_after:wN \@@_from_dim:wNw - \__int_value:w \__int_eval:w #1 - 4 + \int_value:w \@@_int_eval:w #1 - 4 \if_meaning:w - #2 - \exp_after:wN , \exp_after:wN 2 \__int_value:w + \exp_after:wN , \exp_after:wN 2 \int_value:w \else: - \exp_after:wN , \exp_after:wN 0 \__int_value:w #2 + \exp_after:wN , \exp_after:wN 0 \int_value:w #2 \fi: \fi: } @@ -593,8 +593,8 @@ \@@_expand:n { { \use_ii:nn } - \@@_array_to_clist_loop:Nw #1 { ? \__prg_break: } ; - \__prg_break_point: + \@@_array_to_clist_loop:Nw #1 { ? \prg_break: } ; + \prg_break_point: } } } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx index aa85f1584f5..bda1371504a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3fp-expo.dtx Copyright (C) 2011-2017 The LaTeX3 Project +%% File: l3fp-expo.dtx Copyright (C) 2011-2018 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -38,7 +38,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -176,14 +176,14 @@ \cs_new:Npn \@@_ln_npos_o:w \s_@@ \@@_chk:w 10#1#2#3; { %^^A todo: ln(1) should be "exact zero", not "underflow" \exp_after:wN \@@_sanitize:Nw - \__int_value:w % for the overall sign + \int_value:w % for the overall sign \if_int_compare:w #1 < 1 \exp_stop_f: 2 \else: 0 \fi: \exp_after:wN \exp_stop_f: - \__int_value:w \__int_eval:w % for the exponent + \int_value:w \@@_int_eval:w % for the exponent \@@_ln_significand:NNNNnnnN #2#3 \@@_ln_exponent:wn {#1} } @@ -203,11 +203,11 @@ \cs_new:Npn \@@_ln_significand:NNNNnnnN #1#2#3#4 { \exp_after:wN \@@_ln_x_ii:wnnnn - \__int_value:w + \int_value:w \if_case:w #1 \exp_stop_f: \or: \if_int_compare:w #2 < 4 \exp_stop_f: - \__int_eval:w 10 - #2 + \@@_int_eval:w 10 - #2 \else: 6 \fi: @@ -230,14 +230,14 @@ \cs_new:Npn \@@_ln_x_ii:wnnnn #1; #2#3#4#5 { \exp_after:wN \@@_ln_div_after:Nw - \cs:w c_@@_ln_ \__int_to_roman:w #1 _fixed_tl \exp_after:wN \cs_end: - \__int_value:w + \cs:w c_@@_ln_ \@@_int_to_roman:w #1 _fixed_tl \exp_after:wN \cs_end: + \int_value:w \exp_after:wN \@@_ln_x_iv:wnnnnnnnn - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \exp_after:wN \@@_ln_x_iii_var:NNNNNw - \__int_value:w \__int_eval:w 9999 9990 + #1*#2#3 + + \int_value:w \@@_int_eval:w 9999 9990 + #1*#2#3 + \exp_after:wN \@@_ln_x_iii:NNNNNNw - \__int_value:w \__int_eval:w 10 0000 0000 + #1*#4#5 ; + \int_value:w \@@_int_eval:w 10 0000 0000 + #1*#4#5 ; {20000} {0000} {0000} {0000} } %^^A todo: reoptimize (a generalization attempt failed). \cs_new:Npn \@@_ln_x_iii:NNNNNNw #1#2 #3#4#5#6 #7; @@ -280,7 +280,7 @@ % \frac {\left\lfloor 10^8 \cdot A\right\rfloor} {y} - \frac{1}{2} % \right\rfloor. % \] -% (The $1/2$ comes from how e\TeX{} rounds.) As for division, it is +% (The $1/2$ comes from how \eTeX{} rounds.) As for division, it is % easy to see that $Q_{1} \leq 10^4 A / Z$, \emph{i.e.}, $Q_{1}$ % is an underestimate. % @@ -322,33 +322,33 @@ \cs_new:Npn \@@_ln_x_iv:wnnnnnnnn #1; #2#3#4#5 #6#7#8#9 { \exp_after:wN \@@_div_significand_pack:NNN - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \@@_ln_div_i:w #1 ; #6 #7 ; {#8} {#9} {#2} {#3} {#4} {#5} - { \exp_after:wN \@@_ln_div_ii:wwn \__int_value:w #1 } - { \exp_after:wN \@@_ln_div_ii:wwn \__int_value:w #1 } - { \exp_after:wN \@@_ln_div_ii:wwn \__int_value:w #1 } - { \exp_after:wN \@@_ln_div_ii:wwn \__int_value:w #1 } - { \exp_after:wN \@@_ln_div_vi:wwn \__int_value:w #1 } + { \exp_after:wN \@@_ln_div_ii:wwn \int_value:w #1 } + { \exp_after:wN \@@_ln_div_ii:wwn \int_value:w #1 } + { \exp_after:wN \@@_ln_div_ii:wwn \int_value:w #1 } + { \exp_after:wN \@@_ln_div_ii:wwn \int_value:w #1 } + { \exp_after:wN \@@_ln_div_vi:wwn \int_value:w #1 } } \cs_new:Npn \@@_ln_div_i:w #1; { \exp_after:wN \@@_div_significand_calc:wwnnnnnnn - \__int_value:w \__int_eval:w 999999 + 2 0000 0000 / #1 ; % Q1 + \int_value:w \@@_int_eval:w 999999 + 2 0000 0000 / #1 ; % Q1 } \cs_new:Npn \@@_ln_div_ii:wwn #1; #2;#3 % y; B1;B2 <- for k=1 { \exp_after:wN \@@_div_significand_pack:NNN - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \exp_after:wN \@@_div_significand_calc:wwnnnnnnn - \__int_value:w \__int_eval:w 999999 + #2 #3 / #1 ; % Q2 + \int_value:w \@@_int_eval:w 999999 + #2 #3 / #1 ; % Q2 #2 #3 ; } \cs_new:Npn \@@_ln_div_vi:wwn #1; #2;#3#4#5 #6#7#8#9 %y;F1;F2F3F4x1x2x3x4 { \exp_after:wN \@@_div_significand_pack:NNN - \__int_value:w \__int_eval:w 1000000 + #2 #3 / #1 ; % Q6 + \int_value:w \@@_int_eval:w 1000000 + #2 #3 / #1 ; % Q6 } % \end{macrocode} % We now have essentially @@ -396,12 +396,12 @@ \exp_after:wN \@@_ln_t_large:NNw \exp_after:wN + % <sign> \exp_after:wN #1 - \__int_value:w \__int_eval:w 9999 - #2 \exp_after:wN ; - \__int_value:w \__int_eval:w 9999 - #3 \exp_after:wN ; - \__int_value:w \__int_eval:w 9999 - #4 \exp_after:wN ; - \__int_value:w \__int_eval:w 9999 - #5 \exp_after:wN ; - \__int_value:w \__int_eval:w 9999 - #6 \exp_after:wN ; - \__int_value:w \__int_eval:w 1 0000 - #7 ; + \int_value:w \@@_int_eval:w 9999 - #2 \exp_after:wN ; + \int_value:w \@@_int_eval:w 9999 - #3 \exp_after:wN ; + \int_value:w \@@_int_eval:w 9999 - #4 \exp_after:wN ; + \int_value:w \@@_int_eval:w 9999 - #5 \exp_after:wN ; + \int_value:w \@@_int_eval:w 9999 - #6 \exp_after:wN ; + \int_value:w \@@_int_eval:w 1 0000 - #7 ; } % \end{macrocode} % @@ -418,29 +418,30 @@ \cs_new:Npn \@@_ln_t_large:NNw #1 #2 #3; #4; #5; #6; #7; #8; { \exp_after:wN \@@_ln_square_t_after:w - \__int_value:w \__int_eval:w 9999 0000 + #3*#3 + \int_value:w \@@_int_eval:w 9999 0000 + #3*#3 \exp_after:wN \@@_ln_square_t_pack:NNNNNw - \__int_value:w \__int_eval:w 9999 0000 + 2*#3*#4 + \int_value:w \@@_int_eval:w 9999 0000 + 2*#3*#4 \exp_after:wN \@@_ln_square_t_pack:NNNNNw - \__int_value:w \__int_eval:w 9999 0000 + 2*#3*#5 + #4*#4 + \int_value:w \@@_int_eval:w 9999 0000 + 2*#3*#5 + #4*#4 \exp_after:wN \@@_ln_square_t_pack:NNNNNw - \__int_value:w \__int_eval:w 9999 0000 + 2*#3*#6 + 2*#4*#5 + \int_value:w \@@_int_eval:w 9999 0000 + 2*#3*#6 + 2*#4*#5 \exp_after:wN \@@_ln_square_t_pack:NNNNNw - \__int_value:w \__int_eval:w 1 0000 0000 + 2*#3*#7 + 2*#4*#6 + #5*#5 + \int_value:w \@@_int_eval:w + 1 0000 0000 + 2*#3*#7 + 2*#4*#6 + #5*#5 + (2*#3*#8 + 2*#4*#7 + 2*#5*#6) / 1 0000 % ; ; ; \exp_after:wN \@@_ln_twice_t_after:w - \__int_value:w \__int_eval:w -1 + 2*#3 + \int_value:w \@@_int_eval:w -1 + 2*#3 \exp_after:wN \@@_ln_twice_t_pack:Nw - \__int_value:w \__int_eval:w 9999 + 2*#4 + \int_value:w \@@_int_eval:w 9999 + 2*#4 \exp_after:wN \@@_ln_twice_t_pack:Nw - \__int_value:w \__int_eval:w 9999 + 2*#5 + \int_value:w \@@_int_eval:w 9999 + 2*#5 \exp_after:wN \@@_ln_twice_t_pack:Nw - \__int_value:w \__int_eval:w 9999 + 2*#6 + \int_value:w \@@_int_eval:w 9999 + 2*#6 \exp_after:wN \@@_ln_twice_t_pack:Nw - \__int_value:w \__int_eval:w 9999 + 2*#7 + \int_value:w \@@_int_eval:w 9999 + 2*#7 \exp_after:wN \@@_ln_twice_t_pack:Nw - \__int_value:w \__int_eval:w 10000 + 2*#8 ; ; + \int_value:w \@@_int_eval:w 10000 + 2*#8 ; ; { \@@_ln_c:NwNw #1 } #2 } @@ -494,7 +495,7 @@ \@@_fixed_mul:wwn #3; { \exp_after:wN \@@_ln_Taylor_loop:www - \__int_value:w \__int_eval:w #1 - 2 ; + \int_value:w \@@_int_eval:w #1 - 2 ; } #3; } @@ -502,7 +503,7 @@ { \fi: \exp_after:wN \@@_fixed_mul:wwn - \exp_after:wN { \__int_value:w \__int_eval:w 10000 + #2 } #3; + \exp_after:wN { \int_value:w \@@_int_eval:w 10000 + #2 } #3; } % \end{macrocode} % \end{macro} @@ -556,16 +557,16 @@ \if_case:w #2 \exp_stop_f: 0 \@@_case_return:nw { \@@_fixed_to_float_o:Nw 2 } \or: - \exp_after:wN \@@_ln_exponent_one:ww \__int_value:w + \exp_after:wN \@@_ln_exponent_one:ww \int_value:w \else: \if_int_compare:w #2 > 0 \exp_stop_f: \exp_after:wN \@@_ln_exponent_small:NNww \exp_after:wN 0 - \exp_after:wN \@@_fixed_sub:wwn \__int_value:w + \exp_after:wN \@@_fixed_sub:wwn \int_value:w \else: \exp_after:wN \@@_ln_exponent_small:NNww \exp_after:wN 2 - \exp_after:wN \@@_fixed_add:wwn \__int_value:w - + \exp_after:wN \@@_fixed_add:wwn \int_value:w - \fi: \fi: #2; #1; @@ -648,7 +649,7 @@ \else: \exp_after:wN \@@_sanitize:Nw \exp_after:wN 0 - \__int_value:w #1 \__int_eval:w + \int_value:w #1 \@@_int_eval:w \if_int_compare:w #4 < 0 \exp_stop_f: \exp_after:wN \use_i:nn \else: @@ -698,7 +699,7 @@ ; #2#3#4 0000 0000 ; } \cs_new:Npn \@@_exp_Taylor_ii:ww #1; #2; - { \@@_exp_Taylor_loop:www 10 ; #1 ; #1 ; \s__stop } + { \@@_exp_Taylor_loop:www 10 ; #1 ; #1 ; \s_stop } \cs_new:Npn \@@_exp_Taylor_loop:www #1; #2; #3; { \if_int_compare:w #1 = 1 \exp_stop_f: @@ -709,11 +710,11 @@ \@@_fixed_mul:wwn #2 ; { \exp_after:wN \@@_exp_Taylor_loop:www - \__int_value:w \__int_eval:w #1 - 1 ; + \int_value:w \@@_int_eval:w #1 - 1 ; #2 ; } } -\cs_new:Npn \@@_exp_Taylor_break:Nww #1 #2; #3 \s__stop +\cs_new:Npn \@@_exp_Taylor_break:Nww #1 #2; #3 \s_stop { \@@_fixed_add_one:wN #2 ; } % \end{macrocode} % \end{macro} @@ -742,7 +743,7 @@ % current total. The loop is done by having the auxiliary for one % exponent call the auxiliary for the next exponent. The current % total is expressed by leaving the exponent behind in the input -% stream (we are currently within an \cs{__int_eval:w}), and keeping +% stream (we are currently within an \cs{@@_int_eval:w}), and keeping % track of a fixed point number, |#1| for the numbered auxiliaries. % Our usage of \cs{if_case:w} is somewhat dirty for optimization: % \TeX{} jumps to the appropriate case, but we then close the @@ -752,9 +753,9 @@ \cs_new:Npn \@@_exp_pos_large:NnnNwn #1#2#3 #4#5; #6 { \exp_after:wN \exp_after:wN - \cs:w @@_exp_large_ \__int_to_roman:w #6 :wN \exp_after:wN \cs_end: + \cs:w @@_exp_large_ \@@_int_to_roman:w #6 :wN \exp_after:wN \cs_end: \exp_after:wN \c_@@_one_fixed_tl - \__int_value:w #3 #4 \exp_stop_f: + \int_value:w #3 #4 \exp_stop_f: #5 00000 ; } \cs_new:Npn \@@_exp_large:w #1 \or: #2 \fi: @@ -989,7 +990,7 @@ \cs_new:Npn \@@_pow_normal_o:ww \s_@@ \@@_chk:w 1 #1#2#3; \s_@@ \@@_chk:w #4#5 { - \if_int_compare:w \__str_if_eq_x:nn { #2 #3 } + \if_int_compare:w \@@_str_if_eq_x:nn { #2 #3 } { 1 {1000} {0000} {0000} {0000} } = 0 \exp_stop_f: \if_int_compare:w #4 #1 = 32 \exp_stop_f: \exp_after:wN \@@_case_return_ii_o:ww @@ -1036,7 +1037,7 @@ { \exp_after:wN \@@_sanitize:Nw \exp_after:wN 0 - \__int_value:w + \int_value:w \if:w #1 \if_int_compare:w #3 > 0 \exp_stop_f: 0 \else: 2 \fi: \exp_after:wN \@@_pow_npos_aux:NNnww \exp_after:wN + @@ -1060,7 +1061,7 @@ \cs_new:Npn \@@_pow_npos_aux:NNnww #1#2#3#4#5; \s_@@ \@@_chk:w 1#6#7#8; { #1 - \__int_eval:w + \@@_int_eval:w \@@_ln_significand:NNNNnnnN #4#5 \@@_pow_exponent:wnN {#3} \@@_fixed_mul:wwn #8 {0000}{0000} ; @@ -1081,37 +1082,37 @@ \cs_new:Npn \@@_pow_exponent:Nwnnnnnw #1#2; #3#4#5#6#7#8; { %^^A todo: use that in ln. \exp_after:wN \@@_fixed_mul_after:wwn - \__int_value:w \__int_eval:w \c_@@_leading_shift_int + \int_value:w \@@_int_eval:w \c_@@_leading_shift_int \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int #1#2*23025 - #1 #3 \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int #1 #2*8509 - #1 #4 \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int #1 #2*2994 - #1 #5 \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int #1 #2*0456 - #1 #6 \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_trailing_shift_int + \int_value:w \@@_int_eval:w \c_@@_trailing_shift_int #1 #2*8401 - #1 #7 #1 ( #2*7991 - #8 ) / 1 0000 ; ; } \cs_new:Npn \@@_pow_B:wwN #1#2#3#4#5#6; #7; { \if_int_compare:w #7 < 0 \exp_stop_f: - \exp_after:wN \@@_pow_C_neg:w \__int_value:w - + \exp_after:wN \@@_pow_C_neg:w \int_value:w - \else: \if_int_compare:w #7 < 22 \exp_stop_f: - \exp_after:wN \@@_pow_C_pos:w \__int_value:w + \exp_after:wN \@@_pow_C_pos:w \int_value:w \else: - \exp_after:wN \@@_pow_C_overflow:w \__int_value:w + \exp_after:wN \@@_pow_C_overflow:w \int_value:w \fi: \fi: #7 \exp_after:wN ; - \__int_value:w \__int_eval:w 10 0000 + #1 \__int_eval_end: + \int_value:w \@@_int_eval:w 10 0000 + #1 \@@_int_eval_end: #2#3#4#5#6 0000 0000 0000 0000 0000 0000 ; %^^A todo: how many 0? } \cs_new:Npn \@@_pow_C_overflow:w #1; #2; #3 @@ -1133,11 +1134,11 @@ \exp_after:wN #2 \else: \if_meaning:w 0 #2 - \exp_after:wN \@@_pow_C_pos_loop:wN \__int_value:w + \exp_after:wN \@@_pow_C_pos_loop:wN \int_value:w \else: - \exp_after:wN \@@_pow_C_overflow:w \__int_value:w + \exp_after:wN \@@_pow_C_overflow:w \int_value:w \fi: - \__int_eval:w #1 - 1 \exp_after:wN ; + \@@_int_eval:w #1 - 1 \exp_after:wN ; \fi: } \cs_new:Npn \@@_pow_C_pack:w @@ -1162,7 +1163,7 @@ \if_case:w \@@_pow_neg_case:w #4 ; \exp_after:wN \@@_pow_neg_aux:wNN \or: - \if_int_compare:w \__int_eval:w #1 / 2 = 1 \exp_stop_f: + \if_int_compare:w \@@_int_eval:w #1 / 2 = 1 \exp_stop_f: \@@_invalid_operation_o:Nww ^ #3; #4; \exp:w \exp_end_continue_f:w \exp_after:wN \exp_after:wN @@ -1178,7 +1179,7 @@ \exp_after:wN \s_@@ \exp_after:wN \@@_chk:w \exp_after:wN #2 - \__int_value:w \__int_eval:w 2 - #3 \__int_eval_end: + \int_value:w \@@_int_eval:w 2 - #3 \@@_int_eval_end: } % \end{macrocode} % ^^A todo: is this \@@_exp_after_o:w necessary? Appropriate? diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx index f0716dd0f15..9187ab81a14 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3fp-extended.dtx Copyright (C) 2011-2017 The LaTeX3 Project +%% File: l3fp-extended.dtx Copyright (C) 2011-2018 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -38,7 +38,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -134,7 +134,7 @@ \cs_new:Npn \@@_fixed_add_one:wN #1#2; #3 { \exp_after:wN #3 \exp_after:wN - { \__int_value:w \__int_eval:w \c_@@_myriad_int + #1 } #2 ; + { \int_value:w \@@_int_eval:w \c_@@_myriad_int + #1 } #2 ; } % \end{macrocode} % \end{macro} @@ -150,9 +150,9 @@ \cs_new:Npn \@@_fixed_div_myriad:wn #1#2#3#4#5#6; { \exp_after:wN \@@_fixed_mul_after:wwn - \__int_value:w \__int_eval:w \c_@@_leading_shift_int + \int_value:w \@@_int_eval:w \c_@@_leading_shift_int \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_trailing_shift_int + \int_value:w \@@_int_eval:w \c_@@_trailing_shift_int + #1 ; {#2}{#3}{#4}{#5}; } % \end{macrocode} @@ -188,22 +188,22 @@ \cs_new:Npn \@@_fixed_mul_short:wwn #1#2#3#4#5#6; #7#8#9; { \exp_after:wN \@@_fixed_mul_after:wwn - \__int_value:w \__int_eval:w \c_@@_leading_shift_int + \int_value:w \@@_int_eval:w \c_@@_leading_shift_int + #1*#7 \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int + #1*#8 + #2*#7 \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int + #1*#9 + #2*#8 + #3*#7 \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int + #2*#9 + #3*#8 + #4*#7 \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int + #3*#9 + #4*#8 + #5*#7 \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_trailing_shift_int + \int_value:w \@@_int_eval:w \c_@@_trailing_shift_int + #4*#9 + #5*#8 + #6*#7 + ( #5*#9 + #6*#8 + #6*#9 / \c_@@_myriad_int ) / \c_@@_myriad_int ; ; @@ -268,7 +268,7 @@ { \exp_after:wN \@@_fixed_div_int_after:Nw \exp_after:wN #8 - \__int_value:w \__int_eval:w - 1 + \int_value:w \@@_int_eval:w - 1 \@@_fixed_div_int:wnN #1; {#7} \@@_fixed_div_int_auxi:wnn #2; {#7} \@@_fixed_div_int_auxi:wnn @@ -280,7 +280,7 @@ \cs_new:Npn \@@_fixed_div_int:wnN #1; #2 #3 { \exp_after:wN #3 - \__int_value:w \__int_eval:w #1 / #2 - 1 ; + \int_value:w \@@_int_eval:w #1 / #2 - 1 ; {#2} {#1} } @@ -288,9 +288,9 @@ { + #1 \exp_after:wN \@@_fixed_div_int_pack:Nw - \__int_value:w \__int_eval:w 9999 + \int_value:w \@@_int_eval:w 9999 \exp_after:wN \@@_fixed_div_int:wnN - \__int_value:w \__int_eval:w #3 - #1*#2 \__int_eval_end: + \int_value:w \@@_int_eval:w #3 - #1*#2 \@@_int_eval_end: } \cs_new:Npn \@@_fixed_div_int_auxii:wnn #1; #2 #3 { + #1 + 2 ; } \cs_new:Npn \@@_fixed_div_int_pack:Nw #1 #2; { + #1; {#2} } @@ -332,16 +332,16 @@ \cs_new:Npn \@@_fixed_add:Nnnnnwnn #1 #2#3#4#5 #6; #7#8 { \exp_after:wN \@@_fixed_add_after:NNNNNwn - \__int_value:w \__int_eval:w 9 9999 9998 + #2#3 #1 #7#8 + \int_value:w \@@_int_eval:w 9 9999 9998 + #2#3 #1 #7#8 \exp_after:wN \@@_fixed_add_pack:NNNNNwn - \__int_value:w \__int_eval:w 1 9999 9998 + #4#5 + \int_value:w \@@_int_eval:w 1 9999 9998 + #4#5 \@@_fixed_add:nnNnnnwn #6 #1 } \cs_new:Npn \@@_fixed_add:nnNnnnwn #1#2 #3 #4#5 #6#7 ; #8 { #3 #4#5 \exp_after:wN \@@_fixed_add_pack:NNNNNwn - \__int_value:w \__int_eval:w 2 0000 0000 #3 #6#7 + #1#2 ; {#8} ; + \int_value:w \@@_int_eval:w 2 0000 0000 #3 #6#7 + #1#2 ; {#8} ; } \cs_new:Npn \@@_fixed_add_pack:NNNNNwn #1 #2#3#4#5 #6; #7 { + #1 ; {#7} {#2#3#4#5} {#6} } @@ -401,21 +401,21 @@ \cs_new:Npn \@@_fixed_mul:wwn #1#2#3#4 #5; #6#7#8#9 { \exp_after:wN \@@_fixed_mul_after:wwn - \__int_value:w \__int_eval:w \c_@@_leading_shift_int + \int_value:w \@@_int_eval:w \c_@@_leading_shift_int \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int + #1*#6 \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int + #1*#7 + #2*#6 \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int + #1*#8 + #2*#7 + #3*#6 \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int + #1*#9 + #2*#8 + #3*#7 + #4*#6 \exp_after:wN \@@_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_trailing_shift_int + \int_value:w \@@_int_eval:w \c_@@_trailing_shift_int + #2*#9 + #3*#8 + #4*#7 + ( #3*#9 + #4*#8 + \@@_fixed_mul:nnnnnnnw #5 {#6}{#7} {#1}{#2} @@ -485,9 +485,9 @@ \cs_new:Npn \@@_fixed_mul_add:wwwn #1; #2; #3#4#5#6#7#8; { \exp_after:wN \@@_fixed_mul_after:wwn - \__int_value:w \__int_eval:w \c_@@_big_leading_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_leading_shift_int \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_big_middle_shift_int + #3 #4 + \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int + #3 #4 \@@_fixed_mul_add:Nwnnnwnnn + + #5 #6 ; #2 ; #1 ; #2 ; + + #7 #8 ; ; @@ -495,9 +495,9 @@ \cs_new:Npn \@@_fixed_mul_sub_back:wwwn #1; #2; #3#4#5#6#7#8; { \exp_after:wN \@@_fixed_mul_after:wwn - \__int_value:w \__int_eval:w \c_@@_big_leading_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_leading_shift_int \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_big_middle_shift_int + #3 #4 + \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int + #3 #4 \@@_fixed_mul_add:Nwnnnwnnn - + #5 #6 ; #2 ; #1 ; #2 ; - + #7 #8 ; ; @@ -505,9 +505,10 @@ \cs_new:Npn \@@_fixed_one_minus_mul:wwn #1; #2; { \exp_after:wN \@@_fixed_mul_after:wwn - \__int_value:w \__int_eval:w \c_@@_big_leading_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_leading_shift_int \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_big_middle_shift_int + 1 0000 0000 + \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int + + 1 0000 0000 \@@_fixed_mul_add:Nwnnnwnnn - ; #2 ; #1 ; #2 ; - ; ; @@ -537,13 +538,13 @@ { #1 #7*#3 \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_big_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int #1 #7*#4 #1 #8*#3 \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_big_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int #1 #7*#5 #1 #8*#4 #1 #9*#3 #2 \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_big_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int #1 \@@_fixed_mul_add:nnnnwnnnn {#7}{#8}{#9} } % \end{macrocode} @@ -575,7 +576,7 @@ { ( #1*#9 + #2*#8 + #3*#7 + #4*#6 ) \exp_after:wN \@@_pack_big:NNNNNNw - \__int_value:w \__int_eval:w \c_@@_big_trailing_shift_int + \int_value:w \@@_int_eval:w \c_@@_big_trailing_shift_int \@@_fixed_mul_add:nnnnwnnwN { #6 + #4*#7 + #3*#8 + #2*#9 + #1 } { #7 + #4*#8 + #3*#9 + #2 } @@ -631,7 +632,7 @@ \cs_new:Npn \@@_ep_to_fixed:wwn #1,#2 { \exp_after:wN \@@_ep_to_fixed_auxi:www - \__int_value:w \__int_eval:w 1 0000 0000 + #2 \exp_after:wN ; + \int_value:w \@@_int_eval:w 1 0000 0000 + #2 \exp_after:wN ; \exp:w \exp_end_continue_f:w \prg_replicate:nn { 4 - \int_max:nn {#1} { -32 } } { 0 } ; } @@ -672,10 +673,10 @@ \cs_new:Npn \@@_ep_to_ep:wwN #1,#2#3#4#5#6#7; #8 { \exp_after:wN #8 - \__int_value:w \__int_eval:w #1 + 4 + \int_value:w \@@_int_eval:w #1 + 4 \exp_after:wN \use_i:nn \exp_after:wN \@@_ep_to_ep_loop:N - \__int_value:w \__int_eval:w 1 0000 0000 + #2 \__int_eval_end: + \int_value:w \@@_int_eval:w 1 0000 0000 + #2 \@@_int_eval_end: #3#4#5#6#7 ; ; ! } \cs_new:Npn \@@_ep_to_ep_loop:N #1 @@ -756,7 +757,7 @@ \cs_new:Npn \@@_ep_mul_raw:wwwwN #1,#2; #3,#4; #5 { \@@_fixed_mul:wwn #2; #4; - { \exp_after:wN #5 \__int_value:w \__int_eval:w #1 + #3 , } + { \exp_after:wN #5 \int_value:w \@@_int_eval:w #1 + #3 , } } % \end{macrocode} % \end{macro} @@ -932,15 +933,15 @@ \cs_new:Npn \@@_ep_div_esti:wwwwn #1,#2#3; #4, { \exp_after:wN \@@_ep_div_estii:wwnnwwn - \__int_value:w \__int_eval:w 10 0000 0000 / ( #2 + 1 ) + \int_value:w \@@_int_eval:w 10 0000 0000 / ( #2 + 1 ) \exp_after:wN ; - \__int_value:w \__int_eval:w #4 - #1 + 1 , + \int_value:w \@@_int_eval:w #4 - #1 + 1 , {#2} #3; } \cs_new:Npn \@@_ep_div_estii:wwnnwwn #1; #2,#3#4#5; #6; #7 { \exp_after:wN \@@_ep_div_estiii:NNNNNwwwn - \__int_value:w \__int_eval:w 10 0000 0000 - 1750 + \int_value:w \@@_int_eval:w 10 0000 0000 - 1750 + #1 000 + (10 0000 0000 / #3 - #1) * (1000 - #4 / 10) ; {#3}{#4}#5; #6; { #7 #2, } } @@ -975,11 +976,11 @@ \cs_new:Npn \@@_ep_div_epsi:wnNNNNNn #1#2#3#4#5#6; { \exp_after:wN \@@_ep_div_epsii:wwnNNNNNn - \__int_value:w \__int_eval:w 1 9998 - #2 + \int_value:w \@@_int_eval:w 1 9998 - #2 \exp_after:wN \@@_ep_div_eps_pack:NNNNNw - \__int_value:w \__int_eval:w 1 9999 9998 - #3#4 + \int_value:w \@@_int_eval:w 1 9999 9998 - #3#4 \exp_after:wN \@@_ep_div_eps_pack:NNNNNw - \__int_value:w \__int_eval:w 2 0000 0000 - #5#6 ; ; + \int_value:w \@@_int_eval:w 2 0000 0000 - #5#6 ; ; } \cs_new:Npn \@@_ep_div_eps_pack:NNNNNw #1#2#3#4#5#6; { + #1 ; {#2#3#4#5} {#6} } @@ -1049,7 +1050,7 @@ \cs_new:Npn \@@_ep_isqrt_auxi:wwn #1, { \exp_after:wN \@@_ep_isqrt_auxii:wwnnnwn - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \int_if_odd:nTF {#1} { (1 - #1) / 2 , 535 , { 0 } { } } { 1 - #1 / 2 , 168 , { } { 0 } } @@ -1092,15 +1093,15 @@ \exp_after:wN \@@_ep_isqrt_estii:wwwnnwn \fi: \exp_after:wN \@@_ep_isqrt_esti:wwwnnwn - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w (#1 + 1 0050 0000 #4 / (#1 * #3)) / 2 , #1, #3, {#4} } \cs_new:Npn \@@_ep_isqrt_estii:wwwnnwn #1, #2, #3, #4#5 { \exp_after:wN \@@_ep_isqrt_estiii:NNNNNwwwn - \__int_value:w \__int_eval:w 1000 0000 + #2 * #2 #5 * 5 - \exp_after:wN , \__int_value:w \__int_eval:w 10000 + #2 ; + \int_value:w \@@_int_eval:w 1000 0000 + #2 * #2 #5 * 5 + \exp_after:wN , \int_value:w \@@_int_eval:w 10000 + #2 ; } \cs_new:Npn \@@_ep_isqrt_estiii:NNNNNwwwn 1#1#2#3#4#5#6, 1#7#8; #9; { @@ -1149,7 +1150,7 @@ % integer expression then convert the fixed point number. % \begin{macrocode} \cs_new:Npn \@@_ep_to_float_o:wwN #1, - { + \__int_eval:w #1 \@@_fixed_to_float_o:wN } + { + \@@_int_eval:w #1 \@@_fixed_to_float_o:wN } \cs_new:Npn \@@_ep_inv_to_float_o:wwN #1,#2; { \@@_ep_div:wwwwn 1,{1000}{0000}{0000}{0000}{0000}{0000}; #1,#2; @@ -1184,7 +1185,7 @@ % \begin{macro}[rEXP] % {\@@_fixed_to_float_o:wN, \@@_fixed_to_float_o:Nw} % \begin{syntax} -% \ldots{} \cs{__int_eval:w} \meta{exponent} \cs{@@_fixed_to_float_o:wN} \Arg{a_1} \Arg{a_2} \Arg{a_3} \Arg{a_4} \Arg{a_5} \Arg{a_6} |;| \meta{sign} +% \ldots{} \cs{@@_int_eval:w} \meta{exponent} \cs{@@_fixed_to_float_o:wN} \Arg{a_1} \Arg{a_2} \Arg{a_3} \Arg{a_4} \Arg{a_5} \Arg{a_6} |;| \meta{sign} % \end{syntax} % yields % \begin{quote} @@ -1198,18 +1199,19 @@ % %^^A todo: round properly when rounding to infinity: I need the sign. % \begin{macrocode} -\cs_new:Npn \@@_fixed_to_float_o:Nw #1#2; { \@@_fixed_to_float_o:wN #2; #1 } +\cs_new:Npn \@@_fixed_to_float_o:Nw #1#2; + { \@@_fixed_to_float_o:wN #2; #1 } \cs_new:Npn \@@_fixed_to_float_o:wN #1#2#3#4#5#6; #7 - { - + \__int_eval:w \c_@@_block_int % for the 8-digit-at-the-start thing. + { % for the 8-digit-at-the-start thing + + \@@_int_eval:w \c_@@_block_int \exp_after:wN \exp_after:wN \exp_after:wN \@@_fixed_to_loop:N \exp_after:wN \use_none:n - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w 1 0000 0000 + #1 \exp_after:wN \@@_use_none_stop_f:n - \__int_value:w 1#2 \exp_after:wN \@@_use_none_stop_f:n - \__int_value:w 1#3#4 \exp_after:wN \@@_use_none_stop_f:n - \__int_value:w 1#5#6 + \int_value:w 1#2 \exp_after:wN \@@_use_none_stop_f:n + \int_value:w 1#3#4 \exp_after:wN \@@_use_none_stop_f:n + \int_value:w 1#5#6 \exp_after:wN ; \exp_after:wN ; } @@ -1250,9 +1252,9 @@ \cs_new:Npn \@@_fixed_to_float_round_up:wnnnnw ; #1#2#3#4 ; { \exp_after:wN \@@_basics_pack_high:NNNNNw - \__int_value:w \__int_eval:w 1 #1#2 + \int_value:w \@@_int_eval:w 1 #1#2 \exp_after:wN \@@_basics_pack_low:NNNNNw - \__int_value:w \__int_eval:w 1 #3#4 + 1 ; + \int_value:w \@@_int_eval:w 1 #3#4 + 1 ; } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx index 77a092f8f00..e6821415089 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx @@ -38,7 +38,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -131,7 +131,7 @@ \if_int_compare:w \exp_after:wN \@@_compare_aux:wn \exp:w \exp_end_continue_f:w \@@_parse:n {#1} {#3} - = \__int_eval:w `#2 - `= \__int_eval_end: + = \@@_int_eval:w `#2 - `= \@@_int_eval_end: \prg_return_true: \else: \prg_return_false: @@ -182,7 +182,7 @@ \s_@@ \@@_chk:w #1 #2 #3; \s_@@ \@@_chk:w #4 #5 #6; { - \__int_value:w + \int_value:w \if_meaning:w 3 #1 \exp_after:wN \@@_compare_nan:w \fi: \if_meaning:w 3 #4 \exp_after:wN \@@_compare_nan:w \fi: \if_meaning:w 2 #5 - \fi: @@ -214,7 +214,7 @@ % Tuple and floating point numbers are not comparable so return $2$ in % mixed cases or when tuples have a different number of items. % Otherwise compare pairs of items with \cs{@@_compare_back_any:ww} -% and if any don't match return~$2$ (as \cs{__int_value:w} |02| +% and if any don't match return~$2$ (as \cs{int_value:w} |02| % \cs{exp_stop_f:}). % \begin{macrocode} \cs_new:Npn \@@_compare_back_tuple:ww #1; #2; { 2 } @@ -223,13 +223,14 @@ \s_@@_tuple \@@_tuple_chk:w #1; \s_@@_tuple \@@_tuple_chk:w #2; { - \int_compare:nNnTF { \@@_array_count:n {#1} } = { \@@_array_count:n {#2} } + \int_compare:nNnTF { \@@_array_count:n {#1} } = + { \@@_array_count:n {#2} } { - \__int_value:w 0 + \int_value:w 0 \@@_tuple_compare_back_loop:w - #1 { \s_@@ \__prg_break: } ; @ - #2 { \s_@@ \__prg_break: } ; - \__prg_break_point: + #1 { \s_@@ \prg_break: } ; @ + #2 { \s_@@ \prg_break: } ; + \prg_break_point: \exp_stop_f: } { 2 } @@ -241,7 +242,7 @@ \if_int_compare:w \@@_compare_back_any:ww #1 #2 ; #4 #5 ; = 0 \exp_stop_f: \else: - 2 \exp_after:wN \__prg_break: + 2 \exp_after:wN \prg_break: \fi: \@@_tuple_compare_back_loop:w #3 @ } @@ -256,7 +257,7 @@ % \Arg{expo_1} \meta{body_1} |;| % \Arg{expo_2} \meta{body_2} |;| % \end{quote} -% Within an \cs{__int_value:w} \ldots{} \cs{exp_stop_f:} construction, +% Within an \cs{int_value:w} \ldots{} \cs{exp_stop_f:} construction, % this expands to $0$ if the two numbers are equal, $-1$ if the first % is smaller, and $1$ if the first is bigger. First compare the % exponents: the larger one denotes the larger number. If they are @@ -398,11 +399,11 @@ % \begin{macrocode} \cs_new:Npn \@@_step:wwwN #1#2; #3#4; #5#6; #7 { - \@@_if_type_fp:NTwFw #1 { } \s_@@ \__prg_break: \q_stop - \@@_if_type_fp:NTwFw #3 { } \s_@@ \__prg_break: \q_stop - \@@_if_type_fp:NTwFw #5 { } \s_@@ \__prg_break: \q_stop + \@@_if_type_fp:NTwFw #1 { } \s_@@ \prg_break: \q_stop + \@@_if_type_fp:NTwFw #3 { } \s_@@ \prg_break: \q_stop + \@@_if_type_fp:NTwFw #5 { } \s_@@ \prg_break: \q_stop \use_i:nnnn { \@@_step_fp:wwwN #1#2; #3#4; #5#6; #7 } - \__prg_break_point: + \prg_break_point: \use:n { \@@_error:nfff { fp-step-tuple } { \fp_to_tl:n { #1#2 ; } } @@ -419,7 +420,10 @@ } { \token_if_eq_meaning:NNTF #2 0 - { \__kernel_msg_expandable_error:nnn { kernel } { zero-step } {#6} } + { + \__kernel_msg_expandable_error:nnn { kernel } + { zero-step } {#6} + } { \@@_error:nnfn { fp-bad-step } { } { \fp_to_tl:n { \s_@@ \@@_chk:w #2#3#4 ; } } {#6} @@ -457,17 +461,17 @@ % \begin{macrocode} \cs_new_protected:Npn \fp_step_inline:nnnn { - \int_gincr:N \g__prg_map_int + \int_gincr:N \g__kernel_prg_map_int \exp_args:NNc \@@_step:NNnnnn \cs_gset_protected:Npn - { __prg_map_ \int_use:N \g__prg_map_int :w } + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } } \cs_new_protected:Npn \fp_step_variable:nnnNn #1#2#3#4#5 { - \int_gincr:N \g__prg_map_int + \int_gincr:N \g__kernel_prg_map_int \exp_args:NNc \@@_step:NNnnnn \cs_gset_protected:Npx - { __prg_map_ \int_use:N \g__prg_map_int :w } + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } {#1} {#2} {#3} { \tl_set:Nn \exp_not:N #4 {##1} @@ -478,7 +482,7 @@ { #1 #2 ##1 {#6} \fp_step_function:nnnN {#3} {#4} {#5} #2 - \__prg_break_point:Nn \scan_stop: { \int_gdecr:N \g__prg_map_int } + \prg_break_point:Nn \scan_stop: { \int_gdecr:N \g__kernel_prg_map_int } } % \end{macrocode} % \end{macro} @@ -637,7 +641,8 @@ \cs_new:Npn \@@_|_o:ww { \@@_&_o:ww \else: } \cs_new:Npn \@@_|_tuple_o:ww { \@@_&_tuple_o:ww \else: } \cs_new:Npn \@@_tuple_|_o:ww #1; #2; { \@@_exp_after_tuple_o:w #1; } - \cs_new:Npn \@@_tuple_|_tuple_o:ww #1; #2; { \@@_exp_after_tuple_o:w #1; } + \cs_new:Npn \@@_tuple_|_tuple_o:ww #1; #2; + { \@@_exp_after_tuple_o:w #1; } \group_end: \cs_new:Npn \@@_and_return:wNw #1; \fi: #2; { \fi: \@@_exp_after_o:w #1; } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx index 41c22e977c7..9a0f8a233f6 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx @@ -38,7 +38,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -183,11 +183,11 @@ % already been found, and that we want to parse the next number. The % current status of the code may look as follows. % \begin{syntax} -% \cs{exp_after:wN} |\add:ww| \cs{__int_value:w} 12345 \cs{exp_after:wN} ; +% \cs{exp_after:wN} |\add:ww| \cs{int_value:w} 12345 \cs{exp_after:wN} ; % \cs{exp:w} |\operand:w| \meta{stuff} % \end{syntax} % One step of expansion expands \cs{exp_after:wN}, which triggers the -% primitive \cs{__int_value:w}, which reads the five digits we have +% primitive \cs{int_value:w}, which reads the five digits we have % already found, |12345|. This integer is unfinished, causing the % second \cs{exp_after:wN} to expand, and to trigger the construction % \cs{exp:w}, which expands |\operand:w|, defined to read @@ -195,13 +195,13 @@ % number, and a semicolon in the input stream. Once |\operand:w| is % done expanding, we obtain essentially % \begin{syntax} -% \cs{exp_after:wN} |\add:ww| \cs{__int_value:w} 12345 ; +% \cs{exp_after:wN} |\add:ww| \cs{int_value:w} 12345 ; % \cs{exp:w} \cs{exp_end:} 333444 ; % \end{syntax} % where in fact \cs{exp_after:wN} has already been expanded, -% \cs{__int_value:w} has already seen |12345|, and +% \cs{int_value:w} has already seen |12345|, and % \cs{exp:w} is still looking for a number. It finds -% \cs{exp_end:}, hence expands to nothing. Now, \cs{__int_value:w} sees +% \cs{exp_end:}, hence expands to nothing. Now, \cs{int_value:w} sees % the \texttt{;}, which cannot be part of a number. The expansion % stops, and we are left with % \begin{syntax} @@ -212,7 +212,7 @@ % % If we were to continue parsing the expression, then the following % number should also be cleaned up before the next use of a binary -% operation such as |\add:ww|. Just like \cs{__int_value:w} |12345| +% operation such as |\add:ww|. Just like \cs{int_value:w} |12345| % \cs{exp_after:wN}~|;| expanded what follows once, we need |\add:ww| % to do the calculation, and in the process to expand the following % once. This is also true in our real application: all the functions of @@ -521,7 +521,7 @@ % character code, testing if |`#1| lies in $[65,90]$ (uppercase letters) % or $[97,112]$ (lowercase letters) % \begin{verbatim} -% \if_int_compare:w \__int_eval:w +% \if_int_compare:w \__fp_int_eval:w % ( `#1 \if_int_compare:w `#1 > `Z - 32 \fi: ) / 26 = 3 \exp_stop_f: % is a letter % \else: @@ -651,8 +651,8 @@ % \@@_parse_digits_i:N , % \@@_parse_digits_:N % } -% These functions must be called within an \cs{__int_value:w} or -% \cs{__int_eval:w} construction. The first token which follows must +% These functions must be called within an \cs{int_value:w} or +% \cs{@@_int_eval:w} construction. The first token which follows must % be \texttt{f}-expanded prior to calling those functions. The % functions read tokens one by one, and output digits into the input % stream, until meeting a non-digit, or up to a number of digits equal @@ -791,7 +791,8 @@ } \cs_new:cpn { @@_exp_after_?_f:nw } #1#2 { - \__kernel_msg_expandable_error:nnn { kernel } { bad-variable } {#2} + \__kernel_msg_expandable_error:nnn { kernel } { bad-variable } + {#2} \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w #1 } %<*package> @@ -805,9 +806,15 @@ \str_if_eq:nnTF {##2} { \protect } { \cs_if_eq:NNTF ##2 #1 { \use_i:nn } { \use:n } - { \__kernel_msg_expandable_error:nnn { kernel } { fp-robust-cmd } } + { + \__kernel_msg_expandable_error:nnn { kernel } + { fp-robust-cmd } + } + } + { + \__kernel_msg_expandable_error:nnn { kernel } + { bad-variable } {##2} } - { \__kernel_msg_expandable_error:nnn { kernel } { bad-variable } {##2} } } } } @@ -824,8 +831,6 @@ % \@@_parse_one_register_int:www, % \@@_parse_one_register_mu:www, % \@@_parse_one_register_dim:ww, -% \@@_parse_one_register_wd:w, -% \@@_parse_one_register_wd:Nw, % } % This is called whenever~|#2| is a control sequence other than % \cs{scan_stop:} in meaning. We special-case \tn{wd}, \tn{ht}, \tn{dp} @@ -840,7 +845,7 @@ % registers, the decimal rounding provided by \TeX{} does not % accurately represent the binary value that it manipulates, so we % extract this binary value as a number of scaled points with -% \cs{__int_value:w} \cs{__dim_eval:w} \meta{decimal value} |pt|, and +% \cs{int_value:w} \cs{dim_to_decimal_in_sp:n} |{| \meta{decimal value} |pt| |}|, and % use an auxiliary of \cs{dim_to_fp:n}, which performs the % multiplication by $2^{-16}$, correctly rounded. % \begin{macrocode} @@ -849,12 +854,10 @@ \exp_after:wN \@@_parse_infix_after_operand:NwN \exp_after:wN #1 \exp:w \exp_end_continue_f:w - \if_meaning:w \box_wd:N #2 \@@_parse_one_register_wd:w \fi: - \if_meaning:w \box_ht:N #2 \@@_parse_one_register_wd:w \fi: - \if_meaning:w \box_dp:N #2 \@@_parse_one_register_wd:w \fi: + \@@_parse_one_register_special:N #2 \exp_after:wN \@@_parse_one_register_aux:Nw \exp_after:wN #2 - \__int_value:w + \int_value:w \exp_after:wN \@@_parse_exponent:N \exp:w \@@_parse_expand:w } @@ -884,16 +887,49 @@ \cs_new:Npn \@@_parse_one_register_dim:ww #1; #2; { \exp_after:wN \@@_from_dim_test:ww - \__int_value:w #2 \exp_after:wN , - \__int_value:w \__dim_eval:w #1 pt ; + \int_value:w #2 \exp_after:wN , + \int_value:w \dim_to_decimal_in_sp:n { #1 pt } ; } % \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \@@_parse_one_register_special:N, +% \@@_parse_one_register_math:NNw, +% \@@_parse_one_register_wd:w, +% \@@_parse_one_register_wd:Nw +% } % The \tn{wd}, \tn{dp}, \tn{ht} primitives expect an integer argument. % We abuse the exponent parser to find the integer argument: simply % include the exponent marker~|e|. Once that \enquote{exponent} is % found, use \cs{tex_the:D} to find the box dimension and then copy % what we did for dimensions. % \begin{macrocode} +\cs_new:Npn \@@_parse_one_register_special:N #1 + { + \if_meaning:w \box_wd:N #1 \@@_parse_one_register_wd:w \fi: + \if_meaning:w \box_ht:N #1 \@@_parse_one_register_wd:w \fi: + \if_meaning:w \box_dp:N #1 \@@_parse_one_register_wd:w \fi: + \if_meaning:w \infty #1 + \@@_parse_one_register_math:NNw \infty #1 + \fi: + \if_meaning:w \pi #1 + \@@_parse_one_register_math:NNw \pi #1 + \fi: + } +\cs_new:Npn \@@_parse_one_register_math:NNw + #1#2#3#4 \@@_parse_expand:w + { + #3 + \str_if_eq:nnTF {#1} {#2} + { + \__kernel_msg_expandable_error:nnn + { kernel } { fp-infty-pi } {#1} + \c_nan_fp + } + { #4 \@@_parse_expand:w } + } \cs_new:Npn \@@_parse_one_register_wd:w #1#2 \exp_after:wN #3#4 \@@_parse_expand:w { @@ -905,8 +941,7 @@ { \exp_after:wN \@@_from_dim_test:ww \exp_after:wN 0 \exp_after:wN , - \__int_value:w \__dim_eval:w - \exp_after:wN \use:n \exp_after:wN { \tex_the:D #1 #2 } ; + \int_value:w \dim_to_decimal_in_sp:n { #1 #2 } ; } % \end{macrocode} % \end{macro} @@ -926,7 +961,7 @@ \exp_after:wN #1 \exp:w \exp_end_continue_f:w \exp_after:wN \@@_sanitize:wN - \__int_value:w \__int_eval:w 0 \@@_parse_trim_zeros:N + \int_value:w \@@_int_eval:w 0 \@@_parse_trim_zeros:N } % \end{macrocode} % \end{macro} @@ -941,7 +976,7 @@ \cs_new:Npn \@@_parse_one_other:NN #1 #2 { \if_int_compare:w - \__int_eval:w + \@@_int_eval:w ( `#2 \if_int_compare:w `#2 > `Z - 32 \fi: ) / 26 = 3 \exp_stop_f: \exp_after:wN \@@_parse_word:Nw @@ -984,7 +1019,8 @@ { \cs_if_exist_use:cF { @@_parse_word_#2:N } { - \cs_if_exist_use:cF { @@_parse_caseless_ \str_fold_case:n {#2} :N } + \cs_if_exist_use:cF + { @@_parse_caseless_ \str_fold_case:n {#2} :N } { \__kernel_msg_expandable_error:nnn { kernel } { unknown-fp-word } {#2} @@ -1001,7 +1037,7 @@ \if_catcode:w \scan_stop: \exp_not:N #1 0 \else: - \__int_eval:w + \@@_int_eval:w ( `#1 \if_int_compare:w `#1 > `Z - 32 \fi: ) / 26 \fi: = 3 \exp_stop_f: @@ -1144,7 +1180,7 @@ \cs_new:Npn \@@_parse_zero: { \exp_after:wN ; \exp_after:wN 1 - \__int_value:w \@@_parse_exponent:N + \int_value:w \@@_parse_exponent:N } % \end{macrocode} % \end{macro} @@ -1156,11 +1192,11 @@ % and removed all leading zeros from the significand. It is followed % by a non-zero digit (with any catcode). The goal is to read up to % $16$ digits. But we can't do that all at once, because -% \cs{__int_value:w} (which allows us to collect digits and continue +% \cs{int_value:w} (which allows us to collect digits and continue % expanding) can only go up to $9$ digits. Hence we grab digits in % two steps of $8$ digits. Since |#1| is a digit, read seven more % digits using \cs{@@_parse_digits_vii:N}. The \texttt{small_leading} -% auxiliary leaves those digits in the \cs{__int_value:w}, and +% auxiliary leaves those digits in the \cs{int_value:w}, and % grabs some more, or stops if there are no more digits. Then the % \texttt{pack_leading} auxiliary puts the various parts in the % appropriate order for the processing further up. @@ -1168,9 +1204,9 @@ \cs_new:Npn \@@_parse_small:N #1 { \exp_after:wN \@@_parse_pack_leading:NNNNNww - \__int_value:w \__int_eval:w 1 \token_to_str:N #1 + \int_value:w \@@_int_eval:w 1 \token_to_str:N #1 \exp_after:wN \@@_parse_small_leading:wwNN - \__int_value:w 1 + \int_value:w 1 \exp_after:wN \@@_parse_digits_vii:N \exp:w \@@_parse_expand:w } @@ -1196,11 +1232,11 @@ #1 #2 \exp_after:wN \@@_parse_pack_trailing:NNNNNNww \exp_after:wN 0 - \__int_value:w \__int_eval:w 1 + \int_value:w \@@_int_eval:w 1 \if_int_compare:w 9 < 1 \token_to_str:N #4 \exp_stop_f: \token_to_str:N #4 \exp_after:wN \@@_parse_small_trailing:wwNN - \__int_value:w 1 + \int_value:w 1 \exp_after:wN \@@_parse_digits_vi:N \exp:w \else: @@ -1294,7 +1330,7 @@ \cs_new:Npn \@@_parse_large:N #1 { \exp_after:wN \@@_parse_large_leading:wwNN - \__int_value:w 1 \token_to_str:N #1 + \int_value:w 1 \token_to_str:N #1 \exp_after:wN \@@_parse_digits_vii:N \exp:w \@@_parse_expand:w } @@ -1320,19 +1356,19 @@ { + \c_@@_half_prec_int - #3 \exp_after:wN \@@_parse_pack_leading:NNNNNww - \__int_value:w \__int_eval:w 1 #1 + \int_value:w \@@_int_eval:w 1 #1 \if_int_compare:w 9 < 1 \token_to_str:N #4 \exp_stop_f: \exp_after:wN \@@_parse_large_trailing:wwNN - \__int_value:w 1 \token_to_str:N #4 + \int_value:w 1 \token_to_str:N #4 \exp_after:wN \@@_parse_digits_vi:N \exp:w \else: \if:w . \exp_not:N #4 \exp_after:wN \@@_parse_small_leading:wwNN - \__int_value:w 1 + \int_value:w 1 \cs:w @@_parse_digits_ - \__int_to_roman:w #3 + \@@_int_to_roman:w #3 :N \exp_after:wN \cs_end: \exp:w @@ -1340,7 +1376,7 @@ #2 \exp_after:wN \@@_parse_pack_trailing:NNNNNNww \exp_after:wN 0 - \__int_value:w 1 0000 0000 + \int_value:w 1 0000 0000 \@@_parse_exponent:Nw #4 \fi: \fi: @@ -1372,20 +1408,20 @@ \if_int_compare:w 9 < 1 \token_to_str:N #4 \exp_stop_f: \exp_after:wN \@@_parse_pack_trailing:NNNNNNww \exp_after:wN \c_@@_half_prec_int - \__int_value:w \__int_eval:w 1 #1 \token_to_str:N #4 + \int_value:w \@@_int_eval:w 1 #1 \token_to_str:N #4 \exp_after:wN \@@_parse_large_round:NN \exp_after:wN #4 \exp:w \else: \exp_after:wN \@@_parse_pack_trailing:NNNNNNww - \__int_value:w \__int_eval:w 7 - #3 \exp_stop_f: - \__int_value:w \__int_eval:w 1 #1 + \int_value:w \@@_int_eval:w 7 - #3 \exp_stop_f: + \int_value:w \@@_int_eval:w 1 #1 \if:w . \exp_not:N #4 \exp_after:wN \@@_parse_small_trailing:wwNN - \__int_value:w 1 + \int_value:w 1 \cs:w @@_parse_digits_ - \__int_to_roman:w #3 + \@@_int_to_roman:w #3 :N \exp_after:wN \cs_end: \exp:w @@ -1450,7 +1486,7 @@ \cs_new:Npn \@@_parse_round_after:wN #1; #2 { + #2 \exp_after:wN ; - \__int_value:w \__int_eval:w #1 + \@@_parse_exponent:N + \int_value:w \@@_int_eval:w #1 + \@@_parse_exponent:N } % \end{macrocode} % \end{macro} @@ -1478,9 +1514,9 @@ \exp_after:wN 0 \exp_after:wN #1 \exp_after:wN #2 - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \exp_after:wN \@@_parse_round_after:wN - \__int_value:w \__int_eval:w 0 * \__int_eval:w 0 + \int_value:w \@@_int_eval:w 0 * \@@_int_eval:w 0 \exp_after:wN \@@_parse_round_loop:N \exp:w \else: @@ -1519,9 +1555,9 @@ \exp_after:wN 0 \exp_after:wN #1 \exp_after:wN #2 - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \exp_after:wN \@@_parse_large_round_aux:wNN - \__int_value:w \__int_eval:w 1 + \int_value:w \@@_int_eval:w 1 \exp_after:wN \@@_parse_round_loop:N \else: %^^A could be dot, or e, or other \exp_after:wN \@@_parse_large_round_test:NN @@ -1544,9 +1580,9 @@ { + #2 \exp_after:wN \@@_parse_round_after:wN - \__int_value:w \__int_eval:w #1 + \int_value:w \@@_int_eval:w #1 \if:w . \exp_not:N #3 - + 0 * \__int_eval:w 0 + + 0 * \@@_int_eval:w 0 \exp_after:wN \@@_parse_round_loop:N \exp:w \exp_after:wN \@@_parse_expand:w \else: @@ -1591,19 +1627,19 @@ % This auxiliary is convenient to smuggle some material through % \cs{fi:} ending conditional processing. We place those \cs{fi:} % (argument~|#2|) at a very odd place because this allows us to insert -% \cs{__int_eval:w} \ldots{} there if needed. +% \cs{@@_int_eval:w} \ldots{} there if needed. % \begin{macrocode} \cs_new:Npn \@@_parse_exponent:Nw #1 #2 \@@_parse_expand:w { \exp_after:wN ; - \__int_value:w #2 \@@_parse_exponent:N #1 + \int_value:w #2 \@@_parse_exponent:N #1 } % \end{macrocode} % \end{macro} % % \begin{macro}[rEXP] % {\@@_parse_exponent:N, \@@_parse_exponent_aux:N} -% This function should be called within an \cs{__int_value:w} +% This function should be called within an \cs{int_value:w} % expansion (or within an integer expression). It leaves digits of the % exponent behind it in the input stream, and terminates the expansion % with a semicolon. If there is no~|e|, leave an exponent of~$0$. If @@ -1716,7 +1752,7 @@ \if_catcode:w \scan_stop: \exp_not:N #1 \if_meaning:w \scan_stop: #1 \if_int_compare:w - \__str_if_eq_x:nn { \s_@@ } { \exp_not:N #1 } + \@@_str_if_eq_x:nn { \s_@@ } { \exp_not:N #1 } = 0 \exp_stop_f: 0 \__kernel_msg_expandable_error:nnn @@ -1730,9 +1766,9 @@ \fi: \else: \if_int_compare:w - \__str_if_eq_x:nn { \__int_value:w #1 } { \tex_the:D #1 } + \@@_str_if_eq_x:nn { \int_value:w #1 } { \tex_the:D #1 } = 0 \exp_stop_f: - \__int_value:w #1 + \int_value:w #1 \else: 0 \__kernel_msg_expandable_error:nnn @@ -1870,7 +1906,7 @@ \exp_after:wN #1 \exp:w \exp_end_continue_f:w \exp_after:wN \@@_sanitize:wN - \__int_value:w \__int_eval:w 0 \@@_parse_strim_zeros:N + \int_value:w \@@_int_eval:w 0 \@@_parse_strim_zeros:N } % \end{macrocode} % \end{macro} @@ -2032,7 +2068,7 @@ { \exp_after:wN \@@_from_dim_test:ww \exp_after:wN 0 \exp_after:wN , - \__int_value:w \__dim_eval:w 1 #1 \exp_after:wN ; + \int_value:w \dim_to_decimal_in_sp:n { 1 #1 } \exp_after:wN ; \exp:w \exp_end_continue_f:w \@@_parse_infix:NN } } @@ -2224,7 +2260,7 @@ { \if_catcode:w \scan_stop: \exp_not:N #2 \if_int_compare:w - \__str_if_eq_x:nn { \s_@@_mark } { \exp_not:N #2 } + \@@_str_if_eq_x:nn { \s_@@_mark } { \exp_not:N #2 } = 0 \exp_stop_f: \exp_after:wN \exp_after:wN \exp_after:wN \@@_parse_infix_mark:NNN @@ -2234,7 +2270,7 @@ \fi: \else: \if_int_compare:w - \__int_eval:w + \@@_int_eval:w ( `#2 \if_int_compare:w `#2 > `Z - 32 \fi: ) / 26 = 3 \exp_stop_f: \exp_after:wN \exp_after:wN @@ -2563,7 +2599,8 @@ \cs_new:Npn \@@_parse_compare_auxi:NNNNNNN #1#2#3#4#5#6#7 { \if_case:w - \__int_eval:w \exp_after:wN ` \token_to_str:N #7 - `< \__int_eval_end: + \@@_int_eval:w \exp_after:wN ` \token_to_str:N #7 - `< + \@@_int_eval_end: \@@_parse_compare_auxii:NNNNN #2#2#4#5#6 \or: \@@_parse_compare_auxii:NNNNN #2#3#2#5#6 \or: \@@_parse_compare_auxii:NNNNN #2#3#4#2#6 @@ -2732,8 +2769,8 @@ \exp_after:wN { \exp:w \exp_end_continue_f:w \@@_tuple_map_loop_o:nw {#1} #2 - { \s_@@ \__prg_break: } ; - \__prg_break_point: + { \s_@@ \prg_break: } ; + \prg_break_point: \exp_after:wN } \exp_after:wN ; } \cs_new:Npn \@@_tuple_map_loop_o:nw #1#2#3 ; @@ -2759,9 +2796,9 @@ \exp_after:wN { \exp:w \exp_end_continue_f:w \@@_tuple_mapthread_loop_o:nw {#1} - #2 { \s_@@ \__prg_break: } ; @ - #3 { \s_@@ \__prg_break: } ; - \__prg_break_point: + #2 { \s_@@ \prg_break: } ; @ + #3 { \s_@@ \prg_break: } ; + \prg_break_point: \exp_after:wN } \exp_after:wN ; } \cs_new:Npn \@@_tuple_mapthread_loop_o:nw #1#2#3 ; #4 @ #5#6 ; @@ -2820,7 +2857,7 @@ { \exp_after:wN \@@_function_args:Nwn \exp_after:wN #2 - \__int_value:w #3 \exp_after:wN ; \exp_after:wN + \int_value:w #3 \exp_after:wN ; \exp_after:wN } \exp:w \@@_parse_operand:Nw \c_@@_prec_func_int \@@_parse_expand:w @@ -2913,6 +2950,8 @@ { #1~expects~between~#2~and~#3~arguments. } \__kernel_msg_new:nnn { kernel } { fp-bad-args } { Arguments~in~#1#2~are~invalid. } +\__kernel_msg_new:nnn { kernel } { fp-infty-pi } + { Math~command~#1 is~not~an~fp } %<*package> \cs_if_exist:cT { @unexpandable@protect } { diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx index 565c61dbcc8..20c90ce692d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx @@ -38,7 +38,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -71,10 +71,9 @@ % % \subsection{Engine support} % -% At present, \XeTeX{}, \pTeX{} and \upTeX{} do not provide random -% numbers, while \LuaTeX{} and \pdfTeX{} provide the primitive -% \cs{pdftex_uniformdeviate:D} (\tn{pdfuniformdeviate} in \pdfTeX{} and -% \tn{uniformdeviate} in \LuaTeX{}). We write the test twice simply in +% At present, \XeTeX{} does not provide random +% numbers, while \pdfTeX{}, \LuaTeX{}, \pTeX{} and \upTeX{} provide the primitive +% \cs{pdftex_uniformdeviate:D}. We write the test twice simply in % order to write the \texttt{false} branch first. % \begin{macrocode} \cs_if_exist:NF \pdftex_uniformdeviate:D @@ -87,6 +86,11 @@ \exp_after:wN \c_nan_fp } \cs_new_eq:NN \@@_randint_o:Nw \@@_rand_o:Nw + \cs_new:Npn \int_rand:nn #1#2 + { + \__kernel_msg_expandable_error:nn { kernel } { fp-no-random } + \int_eval:n {#1} + } } \cs_if_exist:NT \pdftex_uniformdeviate:D { @@ -109,11 +113,11 @@ % of \cs{int_rand:nn}. We also use variants of this number % rounded down to multiples of $10^4$ and $10^8$. % \begin{macrocode} -\cs_new:Npn \@@_rand_uniform: - { \pdftex_uniformdeviate:D \c_@@_rand_size_int } -\int_const:Nn \c_@@_rand_size_int { 268 435 456 } -\int_const:Nn \c_@@_rand_four_int { 268 430 000 } -\int_const:Nn \c_@@_rand_eight_int { 200 000 000 } + \cs_new:Npn \@@_rand_uniform: + { \pdftex_uniformdeviate:D \c_@@_rand_size_int } + \int_const:Nn \c_@@_rand_size_int { 268 435 456 } + \int_const:Nn \c_@@_rand_four_int { 268 430 000 } + \int_const:Nn \c_@@_rand_eight_int { 200 000 000 } % \end{macrocode} % \end{variable} % \end{macro} @@ -137,50 +141,50 @@ % characters from the input stream with \cs{use_i:nnn}, \cs{use_i:nn} % or nothing. % \begin{macrocode} -\cs_new:Npn \@@_rand_myriads:n #1 - { - \@@_rand_myriads_loop:nn #1 - { ? \use_i_delimit_by_q_stop:nw \@@_rand_myriads_last: } - { ? \use_none_delimit_by_q_stop:w } \q_stop - } -\cs_new:Npn \@@_rand_myriads_loop:nn #1#2 - { - \use_none:n #2 - \exp_after:wN \@@_rand_myriads_get:w - \__int_value:w \@@_rand_uniform: ; {#1}{#2} - } -\cs_new:Npn \@@_rand_myriads_get:w #1 ; - { - \if_int_compare:w #1 < \c_@@_rand_eight_int - \exp_after:wN \use_none:n - \__int_value:w \__int_eval:w - \c_@@_rand_eight_int + #1 \__int_eval_end: - \exp_after:wN \use_i:nnn - \else: - \if_int_compare:w #1 < \c_@@_rand_four_int - \exp_after:wN \use_none:nnnnn - \__int_value:w \__int_eval:w - \c_@@_rand_four_int + #1 \__int_eval_end: - \exp_after:wN \exp_after:wN \exp_after:wN \use_i:nn - \fi: - \fi: - \@@_rand_myriads_loop:nn - } -\cs_new:Npn \@@_rand_myriads_last: - { - \exp_after:wN \@@_rand_myriads_last:w - \__int_value:w \@@_rand_uniform: ; - } -\cs_new:Npn \@@_rand_myriads_last:w #1 ; - { - \if_int_compare:w #1 < \c_@@_rand_four_int - \exp_after:wN \use_none:nnnnn - \__int_value:w \__int_eval:w - \c_@@_rand_four_int + #1 \__int_eval_end: - \else: - \exp_after:wN \@@_rand_myriads_last: - \fi: - } + \cs_new:Npn \@@_rand_myriads:n #1 + { + \@@_rand_myriads_loop:nn #1 + { ? \use_i_delimit_by_q_stop:nw \@@_rand_myriads_last: } + { ? \use_none_delimit_by_q_stop:w } \q_stop + } + \cs_new:Npn \@@_rand_myriads_loop:nn #1#2 + { + \use_none:n #2 + \exp_after:wN \@@_rand_myriads_get:w + \int_value:w \@@_rand_uniform: ; {#1}{#2} + } + \cs_new:Npn \@@_rand_myriads_get:w #1 ; + { + \if_int_compare:w #1 < \c_@@_rand_eight_int + \exp_after:wN \use_none:n + \int_value:w \@@_int_eval:w + \c_@@_rand_eight_int + #1 \@@_int_eval_end: + \exp_after:wN \use_i:nnn + \else: + \if_int_compare:w #1 < \c_@@_rand_four_int + \exp_after:wN \use_none:nnnnn + \int_value:w \@@_int_eval:w + \c_@@_rand_four_int + #1 \@@_int_eval_end: + \exp_after:wN \exp_after:wN \exp_after:wN \use_i:nn + \fi: + \fi: + \@@_rand_myriads_loop:nn + } + \cs_new:Npn \@@_rand_myriads_last: + { + \exp_after:wN \@@_rand_myriads_last:w + \int_value:w \@@_rand_uniform: ; + } + \cs_new:Npn \@@_rand_myriads_last:w #1 ; + { + \if_int_compare:w #1 < \c_@@_rand_four_int + \exp_after:wN \use_none:nnnnn + \int_value:w \@@_int_eval:w + \c_@@_rand_four_int + #1 \@@_int_eval_end: + \else: + \exp_after:wN \@@_rand_myriads_last: + \fi: + } % \end{macrocode} % \end{macro} % \end{macro} @@ -192,18 +196,18 @@ % First we check that |random| was called without argument. Then get % four blocks of four digits. % \begin{macrocode} -\cs_new:Npn \@@_rand_o:Nw ? #1 @ - { - \tl_if_empty:nTF {#1} - { \@@_rand_o: } + \cs_new:Npn \@@_rand_o:Nw ? #1 @ { - \__kernel_msg_expandable_error:nnnnn - { kernel } { fp-num-args } { rand() } { 0 } { 0 } - \exp_after:wN \c_nan_fp + \tl_if_empty:nTF {#1} + { \@@_rand_o: } + { + \__kernel_msg_expandable_error:nnnnn + { kernel } { fp-num-args } { rand() } { 0 } { 0 } + \exp_after:wN \c_nan_fp + } } - } -\cs_new:Npn \@@_rand_o: - { \@@_parse_o:n { . \@@_rand_myriads:n { xxxx } } } + \cs_new:Npn \@@_rand_o: + { \@@_parse_o:n { . \@@_rand_myriads:n { xxxx } } } % \end{macrocode} % \end{macro} % \end{macro} @@ -244,89 +248,172 @@ % bound. The result is compared to the upper bound and the process % repeats if needed. % \begin{macrocode} -\cs_new:Npn \@@_randint_o:Nw ? - { - \@@_parse_function_one_two:nnw - { randint } - { \@@_randint_default:w \@@_randint_o:w } - } -\cs_new:Npn \@@_randint_default:w #1 { \exp_after:wN #1 \c_one_fp } -\cs_new:Npn \@@_randint_badarg:w \s_@@ \@@_chk:w #1#2#3; - { - \@@_int:wTF \s_@@ \@@_chk:w #1#2#3; + \cs_new:Npn \@@_randint_o:Nw ? { - \if_meaning:w 1 #1 - \if_int_compare:w - \use_i_delimit_by_q_stop:nw #3 \q_stop > \c_@@_prec_int - 1 \exp_stop_f: - \fi: + \@@_parse_function_one_two:nnw + { randint } + { \@@_randint_default:w \@@_randint_o:w } + } + \cs_new:Npn \@@_randint_default:w #1 { \exp_after:wN #1 \c_one_fp } + \cs_new:Npn \@@_randint_badarg:w \s_@@ \@@_chk:w #1#2#3; + { + \@@_int:wTF \s_@@ \@@_chk:w #1#2#3; + { + \if_meaning:w 1 #1 + \if_int_compare:w + \use_i_delimit_by_q_stop:nw #3 \q_stop > \c_@@_prec_int + 1 \exp_stop_f: + \fi: + \fi: + } + { 1 \exp_stop_f: } + } + \cs_new:Npn \@@_randint_o:w #1; #2; @ + { + \if_case:w + \@@_randint_badarg:w #1; + \@@_randint_badarg:w #2; + \fp_compare:nNnTF { #1; } > { #2; } { 1 } { 0 } \exp_stop_f: + \exp_after:wN \exp_after:wN \exp_after:wN \@@_randint_e:wnn + \@@_parse:n { #2; - #1; } { #1; } { #2; } + \or: + \@@_invalid_operation_tl_o:ff + { randint } { \@@_array_to_clist:n { #1; #2; } } + \exp:w \fi: + \exp_after:wN \exp_end: } - { 1 \exp_stop_f: } - } -\cs_new:Npn \@@_randint_o:w #1; #2; @ - { - \if_case:w - \@@_randint_badarg:w #1; - \@@_randint_badarg:w #2; - \fp_compare:nNnTF { #1; } > { #2; } { 1 } { 0 } \exp_stop_f: - \exp_after:wN \exp_after:wN \exp_after:wN \@@_randint_e:wnn - \@@_parse:n { #2; - #1; } { #1; } { #2; } - \or: - \@@_invalid_operation_tl_o:ff - { randint } { \@@_array_to_clist:n { #1; #2; } } - \exp:w - \fi: - \exp_after:wN \exp_end: - } -\cs_new:Npn \@@_randint_e:wnn #1; - { - \exp_after:wN \@@_randint_e:wwNnn - \__int_value:w \@@_rand_uniform: \exp_after:wN ; - \exp:w \exp_end_continue_f:w - \fp_compare:nNnTF { #1 ; } < \c_@@_rand_size_int - { \fp_to_int:n { #1 ; + 1 } ; \@@_randint_narrow_e:nnnn } - { \fp_to_int:n { floor(#1 ; * 1e-8 + 1) } ; \@@_randint_wide_e:nnnn } - } -\cs_new:Npn \@@_randint_e:wwNnn #1 ; #2 ; - { - \exp_after:wN \@@_randint_e:wwwNnn - \__int_value:w \int_mod:nn {#1} {#2} ; #1 ; #2 ; - } -\cs_new:Npn \@@_randint_e:wwwNnn #1 ; #2 ; #3 ; #4 - { - \int_compare:nNnTF { #2 - #1 + #3 } > \c_@@_rand_size_int + \cs_new:Npn \@@_randint_e:wnn #1; { \exp_after:wN \@@_randint_e:wwNnn - \__int_value:w \@@_rand_uniform: ; #3 ; #4 + \int_value:w \@@_rand_uniform: \exp_after:wN ; + \exp:w \exp_end_continue_f:w + \fp_compare:nNnTF { #1 ; } < \c_@@_rand_size_int + { \fp_to_int:n { #1 ; + 1 } ; \@@_randint_narrow_e:nnnn } + { + \fp_to_int:n { floor(#1 ; * 1e-8 + 1) } ; + \@@_randint_wide_e:nnnn + } } - { #4 {#1} {#3} } - } -\cs_new:Npn \@@_randint_narrow_e:nnnn #1#2#3#4 - { \@@_parse_o:n { #3 + #1 } \exp:w } -\cs_new:Npn \@@_randint_wide_e:nnnn #1#2#3#4 - { - \exp_after:wN \exp_after:wN - \exp_after:wN \@@_randint_wide_e:wnnn - \@@_parse:n { #3 + #1e8 + \@@_rand_myriads:n { xx } } - {#2} {#3} {#4} - } -\cs_new:Npn \@@_randint_wide_e:wnnn #1 ; #2#3#4 - { - \fp_compare:nNnTF { #1 ; } > {#4} + \cs_new:Npn \@@_randint_e:wwNnn #1 ; #2 ; { - \exp_after:wN \@@_randint_e:wwNnn - \__int_value:w \@@_rand_uniform: ; #2 ; - \@@_randint_wide_e:nnnn {#3} {#4} + \exp_after:wN \@@_randint_e:wwwNnn + \int_value:w \int_mod:nn {#1} {#2} ; #1 ; #2 ; + } + \cs_new:Npn \@@_randint_e:wwwNnn #1 ; #2 ; #3 ; #4 + { + \int_compare:nNnTF { #2 - #1 + #3 } > \c_@@_rand_size_int + { + \exp_after:wN \@@_randint_e:wwNnn + \int_value:w \@@_rand_uniform: ; #3 ; #4 + } + { #4 {#1} {#3} } + } + \cs_new:Npn \@@_randint_narrow_e:nnnn #1#2#3#4 + { \@@_parse_o:n { #3 + #1 } \exp:w } + \cs_new:Npn \@@_randint_wide_e:nnnn #1#2#3#4 + { + \exp_after:wN \exp_after:wN + \exp_after:wN \@@_randint_wide_e:wnnn + \@@_parse:n { #3 + #1e8 + \@@_rand_myriads:n { xx } } + {#2} {#3} {#4} + } + \cs_new:Npn \@@_randint_wide_e:wnnn #1 ; #2#3#4 + { + \fp_compare:nNnTF { #1 ; } > {#4} + { + \exp_after:wN \@@_randint_e:wwNnn + \int_value:w \@@_rand_uniform: ; #2 ; + \@@_randint_wide_e:nnnn {#3} {#4} + } + { \@@_exp_after_o:w #1 ; \exp:w } } - { \@@_exp_after_o:w #1 ; \exp:w } - } % \end{macrocode} % \end{macro} % \end{macro} % +% \begin{macro}{\int_rand:nn} +% \begin{macro}{\@@_randint:ww} +% \begin{macro}{\@@_randint_narrow:n} +% \begin{macro}{\@@_randint_narrow:nn} +% \begin{macro}{\@@_randint_narrow:nnn} +% Evaluate the argument and filter out the case where the lower +% bound~|#1| is more than the upper bound~|#2|. Then determine +% whether the range is narrower than \cs{c_@@_rand_size_int}; |#2-#1| +% may overflow for very large positive~|#2| and negative~|#1|. If the +% range is wide, use slower code from \pkg{l3fp}. If the range is +% narrow, call \cs{@@_randint_narrow:n} \Arg{choices} where +% \meta{choices} is the number of possible outcomes. +% +% One option then would be to reduce a random number modulo +% \meta{choices}, but the low-order bits of random numbers provided by +% the primitive have poor randomness: empirical tests indicate that +% taking random numbers modulo~$2$ gives only two possible sequences +% of bits depending on the seed's parity. Instead, fit in the output +% range $[0,\cs{c_@@_rand_size_int}-1]$ of the random number generator +% \meta{choices} equal-size intervals of maximum possible size +% (obtained using \cs{int_div_truncate:nn}). Given a random number, +% divide it by the size to determine which interval it falls into; if +% it is beyond \meta{choices}, try another random number. +% \begin{macrocode} + \cs_new:Npn \int_rand:nn #1#2 + { + \exp_after:wN \@@_randint:ww + \int_value:w \int_eval:n {#1} \exp_after:wN ; + \int_value:w \int_eval:n {#2} ; + } + \cs_new:Npn \@@_randint:ww #1; #2; + { + \int_compare:nNnTF {#1} > {#2} + { + \__kernel_msg_expandable_error:nnnn + { kernel } { randint-backward-range } {#1} {#2} + \@@_randint:ww #2; #1; + } + { + \int_compare:nNnTF {#1} > 0 + { \int_compare:nNnTF { #2 - #1 } < \c_@@_rand_size_int } + { \int_compare:nNnTF {#2} < { #1 + \c_@@_rand_size_int } } + { + \int_eval:n + { + #1 + + \exp_args:Nf \@@_randint_narrow:n + { \int_eval:n { #2 - #1 + 1 } } + } + } + { \fp_to_int:n { randint(#1,#2) } } + } + } + \cs_new:Npn \@@_randint_narrow:n #1 + { + \exp_args:Nf \@@_randint_narrow:nn + { \int_div_truncate:nn \c_@@_rand_size_int {#1} } {#1} + } + \cs_new:Npn \@@_randint_narrow:nn #1 + { + \exp_args:Nf \@@_randint_narrow:nnn + { + \int_div_truncate:nn + { \pdftex_uniformdeviate:D \c_@@_rand_size_int } {#1} + } + {#1} + } + \cs_new:Npn \@@_randint_narrow:nnn #1#2#3 + { + \int_compare:nNnTF {#1} < {#3} + {#1} + { \@@_randint_narrow:nn {#2} {#3} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % End the initial conditional that ensures these commands are only -% defined in \pdfTeX{} and \LuaTeX{}. +% defined in engines that support random numbers. % \begin{macrocode} } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx index 5636ff51d8a..da019daf60f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -166,7 +166,7 @@ % \meta{digit_1}.\meta{digit_2}$ to an integer rounds it towards zero % (truncates it), this function expands to |0\exp_stop_f:|, and otherwise % to |1\exp_stop_f:|. Typically used within the scope of an -% \cs{__int_eval:w}, to add~$1$ if needed, and thereby round +% \cs{@@_int_eval:w}, to add~$1$ if needed, and thereby round % correctly. The result depends on the rounding mode. % % It is very important that \meta{final sign} be the final sign of the @@ -272,7 +272,7 @@ % \meta{digit}.\meta{more digits}$ to an integer truncates, and to % |1\exp_stop_f:;| otherwise. The \meta{more digits} part must be a digit, % followed by something that does not overflow a \cs{int_use:N} -% \cs{__int_eval:w} construction. The only relevant information about +% \cs{@@_int_eval:w} construction. The only relevant information about % this piece is whether it is zero or not. % \begin{macrocode} \cs_new:Npn \@@_round_s:NNNw #1 #2 #3 #4; @@ -280,11 +280,11 @@ \exp_after:wN \@@_round:NNN \exp_after:wN #1 \exp_after:wN #2 - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \if_int_odd:w 0 \if_meaning:w 0 #3 1 \fi: \if_meaning:w 5 #3 1 \fi: \exp_stop_f: - \if_int_compare:w \__int_eval:w #4 > 0 \exp_stop_f: + \if_int_compare:w \@@_int_eval:w #4 > 0 \exp_stop_f: 1 + \fi: \fi: @@ -296,11 +296,11 @@ % % \begin{macro}[EXP]{\@@_round_digit:Nw} % \begin{syntax} -% \cs{__int_value:w} \cs{@@_round_digit:Nw} \meta{digit} \meta{intexpr} |;| +% \cs{int_value:w} \cs{@@_round_digit:Nw} \meta{digit} \meta{intexpr} |;| % \end{syntax} -% This function should always be called within an \cs{__int_value:w} -% or \cs{__int_eval:w} expansion; it may add an extra -% \cs{__int_eval:w}, which means that the integer or integer +% This function should always be called within an \cs{int_value:w} +% or \cs{@@_int_eval:w} expansion; it may add an extra +% \cs{@@_int_eval:w}, which means that the integer or integer % expression should not be ended with a synonym of \tn{relax}, but % with a semi-colon for instance. % \begin{macrocode} @@ -309,8 +309,8 @@ \if_int_odd:w \if_meaning:w 0 #1 1 \else: \if_meaning:w 5 #1 1 \else: 0 \fi: \fi: \exp_stop_f: - \if_int_compare:w \__int_eval:w #2 > 0 \exp_stop_f: - \__int_eval:w 1 + + \if_int_compare:w \@@_int_eval:w #2 > 0 \exp_stop_f: + \@@_int_eval:w 1 + \fi: \fi: #1 @@ -355,7 +355,8 @@ } \cs_new_eq:NN \@@_round_to_pinf_neg:NNN \@@_round_to_ninf:NNN \cs_new_eq:NN \@@_round_to_nearest_neg:NNN \@@_round_to_nearest:NNN -\cs_new_eq:NN \@@_round_to_nearest_ninf_neg:NNN \@@_round_to_nearest_pinf:NNN +\cs_new_eq:NN \@@_round_to_nearest_ninf_neg:NNN + \@@_round_to_nearest_pinf:NNN \cs_new:Npn \@@_round_to_nearest_zero_neg:NNN #1 #2 #3 { \if_int_compare:w #3 < \c_@@_five_int \else: @@ -363,7 +364,8 @@ \fi: 0 \exp_stop_f: } -\cs_new_eq:NN \@@_round_to_nearest_pinf_neg:NNN \@@_round_to_nearest_ninf:NNN +\cs_new_eq:NN \@@_round_to_nearest_pinf_neg:NNN + \@@_round_to_nearest_ninf:NNN \cs_new_eq:NN \@@_round_neg:NNN \@@_round_to_nearest_neg:NNN % \end{macrocode} % \end{macro} @@ -390,7 +392,7 @@ \cs_new:Npn \@@_round_aux_o:Nw #1#2 @ { \if_case:w - \__int_eval:w \@@_array_count:n {#2} \__int_eval_end: + \@@_int_eval:w \@@_array_count:n {#2} \@@_int_eval_end: \@@_round_no_arg_o:Nw #1 \exp:w \or: \@@_round:Nwn #1 #2 {0} \exp:w \or: \@@_round:Nww #1 #2 \exp:w @@ -494,7 +496,7 @@ \if_meaning:w 1 #2 \exp_after:wN \@@_round_normal:NwNNnw \exp_after:wN #1 - \__int_value:w #5 + \int_value:w #5 \else: \exp_after:wN \@@_exp_after_o:w \fi: @@ -508,25 +510,25 @@ \cs_new:Npn \@@_round_normal:NnnwNNnn #1#2#3#4; #5#6 { \exp_after:wN \@@_round_normal:NNwNnn - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \if_int_compare:w #2 > 0 \exp_stop_f: - 1 \__int_value:w #2 + 1 \int_value:w #2 \exp_after:wN \@@_round_pack:Nw - \__int_value:w \__int_eval:w 1#3 + + \int_value:w \@@_int_eval:w 1#3 + \else: \if_int_compare:w #3 > 0 \exp_stop_f: - 1 \__int_value:w #3 + + 1 \int_value:w #3 + \fi: \fi: \exp_after:wN #5 \exp_after:wN #6 \use_none:nnnnnnn #3 #1 - \__int_eval_end: + \@@_int_eval_end: 0000 0000 0000 0000 ; #6 } \cs_new:Npn \@@_round_pack:Nw #1 - { \if_meaning:w 2 #1 + 1 \fi: \__int_eval_end: } + { \if_meaning:w 2 #1 + 1 \fi: \@@_int_eval_end: } \cs_new:Npn \@@_round_normal:NNwNnn #1 #2 { \if_meaning:w 0 #2 @@ -551,7 +553,7 @@ \else: \exp_after:wN \@@_round_special_aux:Nw \exp_after:wN #4 - \__int_value:w \__int_eval:w 1 + \int_value:w \@@_int_eval:w 1 \if_meaning:w 1 #1 -#6 \else: +#5 \fi: \fi: ; diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx index 8548fa1654a..c98d5efd7d8 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx @@ -38,7 +38,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % \maketitle % % \begin{documentation} @@ -163,7 +163,7 @@ { #1 \@@_error:nnfn { fp-invalid } {##2} { \fp_to_tl:n { ##3; } } { } - \flag_raise:n { fp_invalid_operation } + \flag_raise_if_clear:n { fp_invalid_operation } ##1 } \exp_args:Nno \use:n @@ -172,7 +172,7 @@ #1 \@@_error:nffn { fp-invalid-ii } { \fp_to_tl:n { ##2; } } { \fp_to_tl:n { ##3; } } {##1} - \flag_raise:n { fp_invalid_operation } + \flag_raise_if_clear:n { fp_invalid_operation } \exp_after:wN \c_nan_fp } \exp_args:Nno \use:n @@ -180,7 +180,7 @@ { #1 \@@_error:nffn { fp-invalid } {##1} {##2} { } - \flag_raise:n { fp_invalid_operation } + \flag_raise_if_clear:n { fp_invalid_operation } \exp_after:wN \c_nan_fp } } @@ -213,7 +213,7 @@ { #1 \@@_error:nnfn { fp-zero-div } {##2} { \fp_to_tl:n { ##3; } } { } - \flag_raise:n { fp_division_by_zero } + \flag_raise_if_clear:n { fp_division_by_zero } \exp_after:wN ##1 } \exp_args:Nno \use:n @@ -222,7 +222,7 @@ #1 \@@_error:nffn { fp-zero-div-ii } { \fp_to_tl:n { ##3; } } { \fp_to_tl:n { ##4; } } {##2} - \flag_raise:n { fp_division_by_zero } + \flag_raise_if_clear:n { fp_division_by_zero } \exp_after:wN ##1 } } @@ -285,7 +285,7 @@ { \fp_to_tl:n { \s_@@ \@@_chk:w ##1##2##3; } } { \token_if_eq_meaning:NNF 0 ##2 { - } #4 } {#2} - \flag_raise:n { fp_#2 } + \flag_raise_if_clear:n { fp_#2 } #3 ##2 } } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx index 8d1d38f0180..223e28a1ba7 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx @@ -38,7 +38,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -363,7 +363,7 @@ \exp_after:wN #2 \exp_after:wN #3 \exp_after:wN #4 - \__int_value:w \__int_eval:w #5 + \int_value:w \@@_int_eval:w #5 \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \if_int_compare:w #7 > #1 0 1 \exp_stop_f: #1 \@@_trig_large:ww \@@_trigd_large:ww @@ -455,8 +455,8 @@ \cs_new:Npn \@@_trigd_large_auxi:nnnnwNNNN #1#2#3#4#5; #6#7#8#9 { \exp_after:wN \@@_trigd_large_auxii:wNw - \__int_value:w \__int_eval:w #1 + #2 - - (#1 + #2 - 4) / 9 * 9 \__int_eval_end: + \int_value:w \@@_int_eval:w #1 + #2 + - (#1 + #2 - 4) / 9 * 9 \@@_int_eval_end: #3; #4; #5{#6#7#8#9}; } @@ -464,8 +464,8 @@ { + (#1#2 - 4) / 9 * 2 \exp_after:wN \@@_trigd_large_auxiii:www - \__int_value:w \__int_eval:w #1#2 - - (#1#2 - 4) / 9 * 9 \__int_eval_end: #3 ; + \int_value:w \@@_int_eval:w #1#2 + - (#1#2 - 4) / 9 * 9 \@@_int_eval_end: #3 ; } \cs_new:Npn \@@_trigd_large_auxiii:www #1; #2; #3! { @@ -710,9 +710,9 @@ \cs_new:Npn \@@_trig_large:ww #1, #2#3#4#5#6; { \exp_after:wN \@@_trig_large_auxi:wwwwww - \__int_value:w \__int_eval:w (#1 - 32) / 64 \exp_after:wN , - \__int_value:w \__int_eval:w (#1 - 4) / 8 \exp_after:wN , - \__int_value:w #1 \@@_trig_inverse_two_pi: ; + \int_value:w \@@_int_eval:w (#1 - 32) / 64 \exp_after:wN , + \int_value:w \@@_int_eval:w (#1 - 4) / 8 \exp_after:wN , + \int_value:w #1 \@@_trig_inverse_two_pi: ; {#2}{#3}{#4}{#5} ; } \cs_new:Npn \@@_trig_large_auxi:wwwwww #1, #2, #3, #4! @@ -761,7 +761,7 @@ { \exp_after:wN \@@_use_i_until_s:nw \exp_after:wN \@@_trig_large_auxvii:w - \__int_value:w \__int_eval:w \c_@@_leading_shift_int + \int_value:w \@@_int_eval:w \c_@@_leading_shift_int \prg_replicate:nn { 13 } { \@@_trig_large_auxvi:wnnnnnnnn } + \c_@@_trailing_shift_int - \c_@@_middle_shift_int @@ -771,7 +771,7 @@ \cs_new:Npn \@@_trig_large_auxvi:wnnnnnnnn #1; #2#3#4#5#6#7#8#9 { \exp_after:wN \@@_trig_large_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int + #2*#9 + #3*#8 + #4*#7 + #5*#6 #1; {#2}{#3}{#4}{#5} {#7}{#8}{#9} } @@ -809,7 +809,7 @@ \cs_new:Npn \@@_trig_large_auxvii:w #1#2#3 { \exp_after:wN \@@_trig_large_auxviii:ww - \__int_value:w \__int_eval:w (#1#2#3 - 62) / 125 ; + \int_value:w \@@_int_eval:w (#1#2#3 - 62) / 125 ; #1#2#3 } \cs_new:Npn \@@_trig_large_auxviii:ww #1; @@ -827,7 +827,7 @@ { \exp_after:wN \@@_use_i_until_s:nw \exp_after:wN \@@_trig_large_auxxi:w - \__int_value:w \__int_eval:w \c_@@_leading_shift_int + \int_value:w \@@_int_eval:w \c_@@_leading_shift_int \prg_replicate:nn { 13 } { \@@_trig_large_auxx:wNNNNN } + \c_@@_trailing_shift_int - \c_@@_middle_shift_int @@ -836,14 +836,14 @@ \cs_new:Npn \@@_trig_large_auxx:wNNNNN #1; #2 #3#4#5#6 { \exp_after:wN \@@_trig_large_pack:NNNNNw - \__int_value:w \__int_eval:w \c_@@_middle_shift_int + \int_value:w \@@_int_eval:w \c_@@_middle_shift_int #2 8 * #3#4#5#6 #1; #2 } \cs_new:Npn \@@_trig_large_auxxi:w #1; { \exp_after:wN \@@_ep_mul_raw:wwwwN - \__int_value:w \__int_eval:w 0 \@@_ep_to_ep_loop:N #1 ; ; ! + \int_value:w \@@_int_eval:w 0 \@@_ep_to_ep_loop:N #1 ; ; ! 0,{7853}{9816}{3397}{4483}{0961}{5661}; \@@_trig_small:ww } @@ -890,8 +890,8 @@ { \exp_after:wN \@@_sin_series_aux_o:NNnwww \exp_after:wN #1 - \__int_value:w - \if_int_odd:w \__int_eval:w (#3 + 2) / 4 \__int_eval_end: + \int_value:w + \if_int_odd:w \@@_int_eval:w (#3 + 2) / 4 \@@_int_eval_end: #2 \else: \if_meaning:w #2 0 2 \else: 0 \fi: @@ -901,7 +901,7 @@ } \cs_new:Npn \@@_sin_series_aux_o:NNnwww #1#2#3 #4; #5,#6; { - \if_int_odd:w \__int_eval:w #3 / 2 \__int_eval_end: + \if_int_odd:w \@@_int_eval:w #3 / 2 \@@_int_eval_end: \exp_after:wN \use_i:nn \else: \exp_after:wN \use_ii:nn @@ -934,7 +934,7 @@ { \exp_after:wN \@@_sanitize:Nw \exp_after:wN #2 - \__int_value:w \__int_eval:w #1 + \int_value:w \@@_int_eval:w #1 } #2 } @@ -953,7 +953,7 @@ % $\tan\lvert x\rvert\geq 0$ coincide with those for which $\lfloor % (|#3| + 1) / 2\rfloor$ is odd. We also have to take into account % the original sign of $x$ to get the sign of the final result; it is -% straightforward to check that the first \cs{__int_value:w} expansion +% straightforward to check that the first \cs{int_value:w} expansion % produces $0$ for a positive final result, and $2$ otherwise. A % similar story holds for $\cot(x)$. % @@ -978,8 +978,8 @@ \@@_fixed_mul:wwn #4; #4; { \exp_after:wN \@@_tan_series_aux_o:Nnwww - \__int_value:w - \if_int_odd:w \__int_eval:w #3 / 2 \__int_eval_end: + \int_value:w + \if_int_odd:w \@@_int_eval:w #3 / 2 \@@_int_eval_end: \exp_after:wN \reverse_if:N \fi: \if_meaning:w #1#2 2 \else: 0 \fi: @@ -1004,7 +1004,7 @@ \@@_fixed_mul_sub_back:wwwn#3;{10000}{0000}{0000}{0000}{0000}{0000}; { \reverse_if:N \if_int_odd:w - \__int_eval:w (#2 - 1) / 2 \__int_eval_end: + \@@_int_eval:w (#2 - 1) / 2 \@@_int_eval_end: \exp_after:wN \@@_reverse_args:Nww \fi: \@@_ep_div:wwwwn 0, @@ -1013,7 +1013,7 @@ { \exp_after:wN \@@_sanitize:Nw \exp_after:wN #1 - \__int_value:w \__int_eval:w \@@_ep_to_float_o:wwN + \int_value:w \@@_int_eval:w \@@_ep_to_float_o:wwN } #1 } @@ -1170,7 +1170,7 @@ { \exp_after:wN \@@_atan_combine_o:NwwwwwN \exp_after:wN #2 - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \if_meaning:w 2 #5 7 - \fi: #3 \exp_after:wN ; \c_@@_one_fixed_tl {0000}{0000}{0000}{0000}{0000}{0000}; @@ -1217,9 +1217,9 @@ { \exp_after:wN \@@_atan_combine_o:NwwwwwN \exp_after:wN #1 - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \if_meaning:w 2 #4 - 7 - \__int_eval:w + 7 - \@@_int_eval:w \fi: \if_int_compare:w \@@_ep_compare:wwww #2,#3; #5,#6; > 0 \exp_stop_f: @@ -1249,8 +1249,9 @@ \cs_new:Npn \@@_atan_div:wnwwnw #1,#2#3; #4,#5#6; { \if_int_compare:w - \__int_eval:w 41421 * #5 < #2 000 - \if_case:w \__int_eval:w #4 - #1 \__int_eval_end: 00 \or: 0 \fi: + \@@_int_eval:w 41421 * #5 < #2 000 + \if_case:w \@@_int_eval:w #4 - #1 \@@_int_eval_end: + 00 \or: 0 \fi: \exp_stop_f: \exp_after:wN \@@_atan_near:wwwn \fi: @@ -1315,7 +1316,7 @@ \@@_rrot:www \@@_fixed_mul_sub_back:wwwn #2; #3; { \exp_after:wN \@@_atan_Taylor_loop:www - \__int_value:w \__int_eval:w #1 - 2 ; + \int_value:w \@@_int_eval:w #1 - 2 ; } #3; } @@ -1354,7 +1355,7 @@ { \exp_after:wN \@@_sanitize:Nw \exp_after:wN #1 - \__int_value:w \__int_eval:w + \int_value:w \@@_int_eval:w \if_meaning:w 0 #2 \exp_after:wN \use_i:nn \else: @@ -1365,7 +1366,7 @@ \@@_fixed_mul:wwn #3; #4; { \exp_after:wN \@@_atan_combine_aux:ww - \__int_value:w \__int_eval:w #2 / 2 ; #2; + \int_value:w \@@_int_eval:w #2 / 2 ; #2; } } { #7 \@@_fixed_to_float_o:wN \@@_fixed_to_float_rad_o:wN } @@ -1463,7 +1464,7 @@ \if_int_compare:w #5 < 1 \exp_stop_f: \exp_after:wN \@@_use_none_until_s:w \fi: - \if_int_compare:w \__int_eval:w #5 + #6#7 + #8#9 = 1000 0001 ~ + \if_int_compare:w \@@_int_eval:w #5 + #6#7 + #8#9 = 1000 0001 ~ \exp_after:wN \@@_use_none_until_s:w \fi: \@@_use_i:ww diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx index b02f20ae962..06a0754ab6c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx @@ -35,7 +35,7 @@ % % % \title{^^A -% The \textsf{l3fp} package: floating points^^A +% The \textsf{l3fp} package: Floating points^^A % } % % \author{^^A @@ -47,7 +47,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -102,7 +102,7 @@ % towards $+\infty$ if $t>0$ and towards $-\infty$ if $t<0$. And % \emph{(not yet)} modulo, and \enquote{quantize}. % \item Random numbers: $\mathop{rand}()$, $\mathop{randint}(m,n)$ in -% \pdfTeX{} and \LuaTeX{} engines. +% all engines except \XeTeX{}. % \item Constants: \texttt{pi}, \texttt{deg} (one degree in radians). % \item Dimensions, automatically expressed in points, \emph{e.g.}, % \texttt{pc} is~$12$. @@ -129,9 +129,12 @@ % \LaTeX{} can now compute: $ \frac{\sin (3.5)}{2} + 2\cdot 10^{-3} % = \ExplSyntaxOn \fp_to_decimal:n {sin(3.5)/2 + 2e-3} $. % \end{verbatim} -% But in all fairness, this module is mostly meant as an underlying tool -% for higher-level commands. For example, one could provide a function -% to typeset nicely the result of floating point computations. +% The operation \texttt{round} can be used to limit the result's +% precision. Adding $+0$ avoids the possibly undesirable output |-0|, +% replacing it by |+0|. However, the \pkg{l3fp} module is mostly meant +% as an underlying tool for higher-level commands. For example, one +% could provide a function to typeset nicely the result of floating +% point computations. % \begin{verbatim} % \documentclass{article} % \usepackage{xparse, siunitx} @@ -143,6 +146,8 @@ % \calcnum { 2 pi * sin ( 2.3 ^ 5 ) } % \end{document} % \end{verbatim} +% See the documentation of \pkg{siunitx} for various options of +% \cs{num}. % % \section{Creating and initialising floating point variables} % @@ -398,7 +403,7 @@ % This is experimental. % \end{function} % -% \begin{function}[EXP, pTF, updated = 2012-12-14, +% \begin{function}[EXP, pTF, updated = 2013-12-14, % tested = m3fp-logic001]{\fp_compare:n} % \begin{syntax} % \cs{fp_compare_p:n} \\ @@ -500,7 +505,7 @@ % \texttt{false}. % \end{function} % -% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003] +% \begin{function}[rEXP, added = 2012-08-16, updated = 2013-12-14, tested = m3fp-logic003] % {\fp_do_until:nn} % \begin{syntax} % \cs{fp_do_until:nn} \{ \meta{fpexpr_1} \meta{relation} \meta{fpexpr_2} \} \Arg{code} @@ -513,7 +518,7 @@ % \meta{relation} is \texttt{true}. % \end{function} % -% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003] +% \begin{function}[rEXP, added = 2012-08-16, updated = 2013-12-14, tested = m3fp-logic003] % {\fp_do_while:nn} % \begin{syntax} % \cs{fp_do_while:nn} \{ \meta{fpexpr_1} \meta{relation} \meta{fpexpr_2} \} \Arg{code} @@ -526,7 +531,7 @@ % is \texttt{false}. % \end{function} % -% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003] +% \begin{function}[rEXP, added = 2012-08-16, updated = 2013-12-14, tested = m3fp-logic003] % {\fp_until_do:nn} % \begin{syntax} % \cs{fp_until_do:nn} \{ \meta{fpexpr_1} \meta{relation} \meta{fpexpr_2} \} \Arg{code} @@ -539,7 +544,7 @@ % \texttt{true}. % \end{function} % -% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003] +% \begin{function}[rEXP, added = 2012-08-16, updated = 2013-12-14, tested = m3fp-logic003] % {\fp_while_do:nn} % \begin{syntax} % \cs{fp_while_do:nn} \{ \meta{fpexpr_1} \meta{relation} \meta{fpexpr_2} \} \Arg{code} @@ -637,7 +642,7 @@ % The value of the base of the natural logarithm, $\mathrm{e} = \exp(1)$. % \end{variable} % -% \begin{variable}[updated = 2012-05-08, updated = 2013-11-17]{\c_pi_fp} +% \begin{variable}[updated = 2013-11-17]{\c_pi_fp} % The value of~$\pi$. This can be input directly in a floating point % expression as~\texttt{pi}. % \end{variable} @@ -823,6 +828,11 @@ % preceded by any sign, but that sign is ignored. % \item Any unrecognizable string triggers an error, and produces a % \nan{}. +% \item Note that commands such as \tn{infty}, \tn{pi}, or \tn{sin} +% \emph{do not} work in floating point expressions. They may +% silently be interpreted as completely unexpected numbers, because +% integer constants (allowed in expressions) are commonly stored as +% mathematical characters. % \end{itemize} % % \subsection{Precedence of operators} @@ -1253,27 +1263,21 @@ % \cs{fp_eval:n} \{ |rand()| \} % \end{syntax} % Produces a pseudo-random floating-point number (multiple of -% $10^{-16}$) between $0$~included and $1$~excluded. Available in -% \pdfTeX{} and \LuaTeX{} engines only. +% $10^{-16}$) between $0$~included and $1$~excluded. This is not yet +% available in \XeTeX{}. The random seed can be queried using +% \cs{sys_rand_seed:} and set using \cs{sys_gset_rand_seed:n}. % \begin{texnote} % This is based on pseudo-random numbers provided by the engine's -% primitive \tn{pdfuniformdeviate} in \pdfTeX{} and -% \tn{uniformdeviate} in \LuaTeX{}. The underlying code in -% \pdfTeX{} and \LuaTeX{} is based on Metapost, which follows an -% additive scheme recommended in Section 3.6 of \enquote{The Art of -% Computer Programming, Volume~2}. +% primitive \tn{pdfuniformdeviate} in \pdfTeX{}, \pTeX{}, \upTeX{} +% and \tn{uniformdeviate} in \LuaTeX{}. The underlying code is +% based on Metapost, which follows an additive scheme recommended in +% Section 3.6 of \enquote{The Art of Computer Programming, +% Volume~2}. % % While we are more careful than \tn{uniformdeviate} to preserve % uniformity of the underlying stream of $28$-bit pseudo-random % integers, these pseudo-random numbers should of course not be % relied upon for serious numerical computations nor cryptography. -% -% The random seed can be queried using \tn{pdfrandomseed} and set -% using \tn{pdfsetrandomseed} (in \LuaTeX{} \tn{randomseed} and -% \tn{setrandomseed}). While a $32$-bit (signed) integer can be -% given as a seed, only the absolute value is used and any number -% beyond $2^{28}$ is divided by an appropriate power of~$2$. We -% recommend using an integer in $[0,2^{28}-1]$. % \end{texnote} % \end{function} % @@ -1366,9 +1370,7 @@ % \item Function to count items in a tuple (and to determine if something is a tuple). % \item Decide what exponent range to consider. % \item Support signalling \texttt{nan}. -% \item Modulo and remainder, and rounding functions |quantize|, -% |quantize0|, |quantize+|, |quantize-|, |quantize=|, |round=|. -% Should the modulo also be provided as (catcode 12) |%|? +% \item Modulo and remainder, and rounding function |quantize| (and its friends analogous to |trunc|, |ceil|, |floor|). % \item \cs{fp_format:nn} \Arg{fpexpr} \Arg{format}, but what should % \meta{format} be? More general pretty printing? % \item Add |and|, |or|, |xor|? Perhaps under the names \texttt{all}, diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx index 2d9deaf1210..58c13e5ec41 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -92,6 +92,17 @@ % \end{texnote} % \end{function} % +% \begin{function}[EXP, added = 2018-03-30]{\int_eval:w} +% \begin{syntax} +% \cs{int_eval:w} \Arg{integer expression} +% \end{syntax} +% Evaluates the \meta{integer expression} as described for +% \cs{int_eval:n}. The end of the expression is the first token +% encountered that cannot form part of such an expression. +% If that token is \cs{scan_stop:} it is removed, otherwise not. +% Spaces do \emph{not} terminate the expression. +% \end{function} +% % \begin{function}[EXP, updated = 2012-09-26]{\int_abs:n} % \begin{syntax} % \cs{int_abs:n} \Arg{integer expression} @@ -481,9 +492,11 @@ % % \section{Integer step functions} % -% \begin{function}[added = 2012-06-04, updated = 2014-05-30, rEXP] -% {\int_step_function:nnnN} +% \begin{function}[added = 2012-06-04, updated = 2018-04-22, rEXP] +% {\int_step_function:nN, \int_step_function:nnN, \int_step_function:nnnN} % \begin{syntax} +% \cs{int_step_function:nN} \Arg{final value} \meta{function} +% \cs{int_step_function:nnN} \Arg{initial value} \Arg{final value} \meta{function} % \cs{int_step_function:nnnN} \Arg{initial value} \Arg{step} \Arg{final value} \meta{function} % \end{syntax} % This function first evaluates the \meta{initial value}, \meta{step} @@ -508,11 +521,18 @@ % [I saw 4] \quad % [I saw 5] \quad % \end{quote} +% +% The functions \cs{int_step_function:nN} and \cs{int_step_function:nnN} +% both use a fixed \meta{step} of $1$, and in the case of +% \cs{int_step_function:nN} the \meta{initial value} is also fixed as +% $1$. These functions are provided as simple short-cuts for code clarity. % \end{function} % -% \begin{function}[added = 2012-06-04, updated = 2014-05-30] -% {\int_step_inline:nnnn} +% \begin{function}[added = 2012-06-04, updated = 2018-04-22] +% {\int_step_inline:nn, \int_step_inline:nnn, \int_step_inline:nnnn} % \begin{syntax} +% \cs{int_step_inline:nn} \Arg{final value} \Arg{code} +% \cs{int_step_inline:nnn} \Arg{initial value} \Arg{final value} \Arg{code} % \cs{int_step_inline:nnnn} \Arg{initial value} \Arg{step} \Arg{final value} \Arg{code} % \end{syntax} % This function first evaluates the \meta{initial value}, \meta{step} @@ -522,13 +542,19 @@ % \meta{value}), the \meta{code} is inserted into the input stream % with |#1| replaced by the current \meta{value}. Thus the % \meta{code} should define a function of one argument~(|#1|). +% +% The functions \cs{int_step_inline:nn} and \cs{int_step_inline:nnn} +% both use a fixed \meta{step} of $1$, and in the case of +% \cs{int_step_inline:nn} the \meta{initial value} is also fixed as +% $1$. These functions are provided as simple short-cuts for code clarity. % \end{function} % -% \begin{function}[added = 2012-06-04, updated = 2014-05-30] -% {\int_step_variable:nnnNn} +% \begin{function}[added = 2012-06-04, updated = 2018-04-22] +% {\int_step_variable:nnn, \int_step_variable:nnnn, \int_step_variable:nnnnn} % \begin{syntax} -% \cs{int_step_variable:nnnNn} \\ -% ~~\Arg{initial value} \Arg{step} \Arg{final value} \meta{tl~var} \Arg{code} +% \cs{int_step_variable:nNn} \Arg{final value} \meta{tl~var} \Arg{code} +% \cs{int_step_variable:nnNn} \Arg{initial value} \Arg{final value} \meta{tl~var} \Arg{code} +% \cs{int_step_variable:nnnNn} \Arg{initial value} \Arg{step} \Arg{final value} \meta{tl~var} \Arg{code} % \end{syntax} % This function first evaluates the \meta{initial value}, \meta{step} % and \meta{final value}, all of which should be integer expressions. @@ -537,6 +563,11 @@ % \meta{value}), the \meta{code} is inserted into the input stream, % with the \meta{tl~var} defined as the current \meta{value}. Thus % the \meta{code} should make use of the \meta{tl~var}. +% +% The functions \cs{int_step_variable:nNn} and \cs{int_step_variable:nnNn} +% both use a fixed \meta{step} of $1$, and in the case of +% \cs{int_step_variable:nNn} the \meta{initial value} is also fixed as +% $1$. These functions are provided as simple short-cuts for code clarity. % \end{function} % % \section{Formatting integers} @@ -753,6 +784,17 @@ % \cs{int_to_Base:nn}. % \end{function} % +% \section{Random integers} +% +% \begin{function}[EXP, added = 2016-12-06, updated = 2018-04-27]{\int_rand:nn} +% \begin{syntax} +% \cs{int_rand:nn} \Arg{intexpr_1} \Arg{intexpr_2} +% \end{syntax} +% Evaluates the two \meta{integer expressions} and produces a +% pseudo-random number between the two (with bounds included). This +% is not yet available in \XeTeX{}. +% \end{function} +% % \section{Viewing integers} % % \begin{function}{\int_show:N, \int_show:c} @@ -846,6 +888,38 @@ % code and so should only be used for short-term storage. % \end{variable} % +% \subsection{Direct number expansion} +% +% \begin{function}[EXP, added = 2018-03-27]{\int_value:w} +% \begin{syntax} +% \cs{int_value:w} \meta{integer} +% \cs{int_value:w} \meta{integer denotation} \meta{optional space} +% \end{syntax} +% Expands the following tokens until an \meta{integer} is formed, and +% leaves a normalized form (no leading sign except for negative +% numbers, no leading digit~|0| except for zero) in the input stream +% as category code $12$ (other) characters. The \meta{integer} can +% consist of any number of signs (with intervening spaces) followed +% by +% \begin{itemize} +% \item an integer variable (in fact, any \TeX{} register except +% \tn{toks}) or +% \item explicit digits (or by |'|\meta{octal digits} or |"|\meta{hexadecimal digits} or |`|\meta{character}). +% \end{itemize} +% In this last case expansion stops once a non-digit is found; if that is a +% space it is removed as in \texttt{f}-expansion, and so \cs{exp_stop_f:} +% may be employed as an end marker. Note that protected functions +% \emph{are} expanded by this process. +% +% This function requires exactly one expansion to produce a value, and so +% is suitable for use in cases where a number is required \enquote{directly}. +% In general, \cs{int_eval:n} is the preferred approach to generating +% numbers. +% \begin{texnote} +% This is the \TeX{} primitive \tn{number}. +% \end{texnote} +% \end{function} +% % \section{Primitive conditionals} % % \begin{function}[EXP]{\if_int_compare:w} @@ -898,86 +972,6 @@ % \end{texnote} % \end{function} % -% \section{Internal functions} -% -% \begin{function}[EXP]{\__int_value:w} -% \begin{syntax} -% \cs{__int_value:w} \meta{integer} -% \cs{__int_value:w} \meta{integer denotation} \meta{optional space} -% \end{syntax} -% Expands the following tokens until an \meta{integer} is formed, and -% leaves a normalized form (no leading sign except for negative -% numbers, no leading digit~|0| except for zero) in the input stream -% as category code $12$ (other) characters. The \meta{integer} can -% consist of any number of signs (with intervening spaces) followed -% by -% \begin{itemize} -% \item an integer variable (in fact, any \TeX{} register except -% \tn{toks}) or -% \item \cs{__int_eval:w} \meta{intexpr} \cs{__int_eval_end:} (or -% another \eTeX{} expression) or -% \item explicit digits (or by |'|\meta{octal digits} or |"|\meta{hexadecimal digits} or |`|\meta{character} -% \end{itemize} -% In this last case expansion stops once a non-digit is found; if that is a space it is removed as in \texttt{f}-expansion. -% Note that protected functions \emph{are} expanded by this process -% \begin{texnote} -% This is the \TeX{} primitive \tn{number}. -% \end{texnote} -% \end{function} -% -% \begin{function}[EXP]{\__int_to_roman:w} -% \begin{syntax} -% \cs{__int_to_roman:w} \meta{integer} -% \cs{__int_to_roman:w} \meta{integer denotation} \meta{optional space} -% \end{syntax} -% Converts an \meta{integer} to lower case Roman representation. The -% \meta{integer} is found as in \cs{__int_value:w} by expanding what -% follows exhaustively. One (optional) space is lost if the -% \meta{integer} is given by explicit digits. Note that this function -% produces a string of letters with category code~$12$. Negative -% \meta{integer} values result in no output, although the function -% does not terminate expansion until a suitable endpoint is found in -% the same way as for positive numbers. -% \begin{texnote} -% This is the \TeX{} primitive \tn{romannumeral} renamed. -% \end{texnote} -% \end{function} -% -% \begin{function}[EXP]{\__int_eval:w, \__int_eval_end:} -% \begin{syntax} -% \cs{__int_eval:w} \meta{intexpr} \cs{__int_eval_end:} -% \end{syntax} -% Evaluates \meta{integer expression} as described for \cs{int_eval:n}. -% The evaluation stops when an unexpandable token which is not a valid -% part of an integer is read or when \cs{__int_eval_end:} is -% reached. The latter is gobbled by the scanner mechanism: -% \cs{__int_eval_end:} itself is unexpandable but used correctly -% the entire construct is expandable. -% \begin{texnote} -% This is the \eTeX{} primitive \tn{numexpr}. -% \end{texnote} -% \end{function} -% -% \begin{function}[EXP]{\__int_eval:n} -% \begin{syntax} -% \cs{__int_eval:n} \Arg{intexpr} -% \end{syntax} -% By default this expands to \cs{__int_eval:w} \meta{intexpr} -% \cs{__int_eval_end:} but when debugging is enabled this expands to a -% more complicated construction that evaluates \meta{intexpr} with -% parentheses and within a brace group to detect early termination. -% \end{function} -% -% \begin{function}{\__prg_compare_error:, \__prg_compare_error:Nw} -% \begin{syntax} -% \cs{__prg_compare_error:} -% \cs{__prg_compare_error:Nw} \meta{token} -% \end{syntax} -% These are used within \cs{int_compare:nTF}, \cs{dim_compare:nTF} -% and so on to recover correctly if the \texttt{n}-type argument does not -% contain a properly-formed relation. -% \end{function} -% % \end{documentation} % % \begin{implementation} @@ -1008,7 +1002,7 @@ % Done in \pkg{l3basics}. % \end{macro} % -% \begin{macro}{\@@_value:w} +% \begin{macro}{\int_value:w} % \begin{macro}{\@@_eval:w} % \begin{macro}{\@@_eval_end:} % \begin{macro}{\if_int_odd:w} @@ -1016,7 +1010,7 @@ % Here are the remaining primitives for number comparisons and % expressions. % \begin{macrocode} -\cs_new_eq:NN \@@_value:w \tex_number:D +\cs_new_eq:NN \int_value:w \tex_number:D \cs_new_eq:NN \@@_eval:w \etex_numexpr:D \cs_new_eq:NN \@@_eval_end: \tex_relax:D \cs_new_eq:NN \if_int_odd:w \tex_ifodd:D @@ -1031,6 +1025,7 @@ % \subsection{Integer expressions} % % \begin{macro}{\int_eval:n} +% \begin{macro}{\int_eval:w} % Wrapper for \cs{@@_eval:w}: can be used in an integer expression % or directly in the input stream. % When debugging, use parentheses to catch early termination. @@ -1038,19 +1033,10 @@ \__kernel_patch_args:nNNpn { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_eval:n } } \cs_new:Npn \int_eval:n #1 - { \@@_value:w \@@_eval:w #1 \@@_eval_end: } + { \int_value:w \@@_eval:w #1 \@@_eval_end: } +\cs_new:Npn \int_eval:w { \int_value:w \@@_eval:w } % \end{macrocode} % \end{macro} -% -% \begin{macro}{\@@_eval:n} -% Only differ from \cs{int_eval:n} by the absence of \cs{@@_value:w}, -% so as to produce an internal integer rather than expanding into -% characters. This is for use in other modules. -% \begin{macrocode} -\__kernel_patch_args:nNNpn - { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \@@_eval:n } } -\cs_new:Npn \@@_eval:n #1 { \@@_eval:w #1 \@@_eval_end: } -% \end{macrocode} % \end{macro} % % \begin{macro}[EXP]{\int_abs:n} @@ -1069,8 +1055,8 @@ { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_abs:n } } \cs_new:Npn \int_abs:n #1 { - \@@_value:w \exp_after:wN \@@_abs:N - \@@_value:w \@@_eval:w #1 \@@_eval_end: + \int_value:w \exp_after:wN \@@_abs:N + \int_value:w \@@_eval:w #1 \@@_eval_end: \exp_stop_f: } \cs_new:Npn \@@_abs:N #1 @@ -1082,9 +1068,9 @@ } \cs_set:Npn \int_max:nn #1#2 { - \@@_value:w \exp_after:wN \@@_maxmin:wwN - \@@_value:w \@@_eval:w #1 \exp_after:wN ; - \@@_value:w \@@_eval:w #2 ; + \int_value:w \exp_after:wN \@@_maxmin:wwN + \int_value:w \@@_eval:w #1 \exp_after:wN ; + \int_value:w \@@_eval:w #2 ; > \exp_stop_f: } @@ -1095,9 +1081,9 @@ } \cs_set:Npn \int_min:nn #1#2 { - \@@_value:w \exp_after:wN \@@_maxmin:wwN - \@@_value:w \@@_eval:w #1 \exp_after:wN ; - \@@_value:w \@@_eval:w #2 ; + \int_value:w \exp_after:wN \@@_maxmin:wwN + \int_value:w \@@_eval:w #1 \exp_after:wN ; + \int_value:w \@@_eval:w #2 ; < \exp_stop_f: } @@ -1144,10 +1130,10 @@ } \cs_new:Npn \int_div_truncate:nn #1#2 { - \@@_value:w \@@_eval:w + \int_value:w \@@_eval:w \exp_after:wN \@@_div_truncate:NwNw - \@@_value:w \@@_eval:w #1 \exp_after:wN ; - \@@_value:w \@@_eval:w #2 ; + \int_value:w \@@_eval:w #1 \exp_after:wN ; + \int_value:w \@@_eval:w #2 ; \@@_eval_end: } \cs_new:Npn \@@_div_truncate:NwNw #1#2; #3#4; @@ -1167,7 +1153,7 @@ % For the sake of completeness: % \begin{macrocode} \cs_new:Npn \int_div_round:nn #1#2 - { \@@_value:w \@@_eval:w ( #1 ) / ( #2 ) \@@_eval_end: } + { \int_value:w \@@_eval:w ( #1 ) / ( #2 ) \@@_eval_end: } % \end{macrocode} % Finally there's the modulus operation. % \begin{macrocode} @@ -1178,9 +1164,9 @@ } \cs_new:Npn \int_mod:nn #1#2 { - \@@_value:w \@@_eval:w \exp_after:wN \@@_mod:ww - \@@_value:w \@@_eval:w #1 \exp_after:wN ; - \@@_value:w \@@_eval:w #2 ; + \int_value:w \@@_eval:w \exp_after:wN \@@_mod:ww + \int_value:w \@@_eval:w #1 \exp_after:wN ; + \int_value:w \@@_eval:w #2 ; \@@_eval_end: } \cs_new:Npn \@@_mod:ww #1; #2; @@ -1205,7 +1191,7 @@ %<*package> \cs_new_protected:Npn \int_new:N #1 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \cs:w newcount \cs_end: #1 } %</package> @@ -1215,7 +1201,7 @@ % % \begin{macro}{\int_const:Nn, \int_const:cn} % \begin{macro}{\@@_constdef:Nw} -% \begin{variable}{\c__max_constdef_int} +% \begin{variable}{\c_@@_max_constdef_int} % \UnitTested % As stated, most constants can be defined as \tn{chardef} or % \tn{mathchardef} but that's engine dependent. As a result, there is some @@ -1236,13 +1222,13 @@ \tex_global:D } { - \int_compare:nNnTF {#2} > \c__max_constdef_int + \int_compare:nNnTF {#2} > \c_@@_max_constdef_int { \int_new:N #1 \tex_global:D } { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \tex_global:D \@@_constdef:Nw } } @@ -1257,10 +1243,10 @@ \cs_if_exist:NTF \uptex_disablecjktoken:D { \cs_new_eq:NN \@@_constdef:Nw \uptex_kchardef:D } { \cs_new_eq:NN \@@_constdef:Nw \tex_chardef:D } - \@@_constdef:Nw \c__max_constdef_int 1114111 ~ + \@@_constdef:Nw \c_@@_max_constdef_int 1114111 ~ \else: \cs_new_eq:NN \@@_constdef:Nw \tex_mathchardef:D - \tex_mathchardef:D \c__max_constdef_int 32767 ~ + \tex_mathchardef:D \c_@@_max_constdef_int 32767 ~ \fi: % \end{macrocode} % \end{variable} @@ -1449,27 +1435,27 @@ % % \subsection{Integer expression conditionals} % -% \begin{macro}[EXP]{\__prg_compare_error:, \__prg_compare_error:Nw} +% \begin{macro}[EXP]{\@@_compare_error:, \@@_compare_error:Nw} % Those functions are used for comparison tests which use a simple % syntax where only one set of braces is required and additional % operators such as |!=| and |>=| are supported. The tests first % evaluate their left-hand side, with a trailing -% \cs{__prg_compare_error:}. This marker is normally not expanded, +% \cs{@@_compare_error:}. This marker is normally not expanded, % but if the relation symbol is missing from the test's argument, then % the marker inserts |=| (and itself) after triggering the relevant % \TeX{} error. If the first token which appears after evaluating and % removing the left-hand side is not a known relation symbol, then a -% judiciously placed \cs{__prg_compare_error:Nw} gets expanded, +% judiciously placed \cs{@@_compare_error:Nw} gets expanded, % cleaning up the end of the test and telling the user what the % problem was. % \begin{macrocode} -\cs_new_protected:Npn \__prg_compare_error: +\cs_new_protected:Npn \@@_compare_error: { \if_int_compare:w \c_zero \c_zero \fi: = - \__prg_compare_error: + \@@_compare_error: } -\cs_new:Npn \__prg_compare_error:Nw +\cs_new:Npn \@@_compare_error:Nw #1#2 \q_stop { { } @@ -1513,7 +1499,7 @@ % of the \TeX{} conditional is taken (because of \cs{reverse_if:N}), % immediately returning \texttt{false} as the result of the test. % There is no \TeX{} conditional waiting the first operand, so we add -% an \cs{if_false:} and expand by hand with \cs{@@_value:w}, thus +% an \cs{if_false:} and expand by hand with \cs{int_value:w}, thus % skipping \cs{prg_return_false:} on the first iteration. % % Before starting the loop, the first step is to make sure that there @@ -1521,7 +1507,7 @@ % left hand side of the (in)equality using \cs{@@_eval:w}. Since the % relation symbols |<|, |>|, |=| and |!| are not allowed in integer % expressions, they would terminate the expression. If the argument contains no -% relation symbol, \cs{__prg_compare_error:} is expanded, +% relation symbol, \cs{@@_compare_error:} is expanded, % inserting~|=| and itself after an error. In all cases, % \cs{@@_compare:w} receives as its argument an integer, a relation % symbol, and some more tokens. We then setup the loop, which is @@ -1531,11 +1517,11 @@ \prg_new_conditional:Npnn \int_compare:n #1 { p , T , F , TF } { \exp_after:wN \@@_compare:w - \@@_value:w \@@_eval:w #1 \__prg_compare_error: + \int_value:w \@@_eval:w #1 \@@_compare_error: } -\cs_new:Npn \@@_compare:w #1 \__prg_compare_error: +\cs_new:Npn \@@_compare:w #1 \@@_compare_error: { - \exp_after:wN \if_false: \@@_value:w + \exp_after:wN \if_false: \int_value:w \@@_compare:Nw #1 e { = nd_ } \q_stop } % \end{macrocode} @@ -1551,7 +1537,7 @@ % hence the test for that as a second token. If the relation symbol % is unknown, then the control sequence is turned by \TeX{} into % \cs{scan_stop:}, ignored thanks to \tn{unexpanded}, and -% \cs{__prg_compare_error:Nw} raises an error. +% \cs{@@_compare_error:Nw} raises an error. % \begin{macrocode} \cs_new:Npn \@@_compare:Nw #1#2 \q_stop { @@ -1561,14 +1547,14 @@ } \cs_new:Npn \@@_compare:NNw #1#2#3 \q_mark { - \etex_unexpanded:D + \__kernel_exp_not:w \use:c { @@_compare_ \token_to_str:N #1 \if_meaning:w = #2 = \fi: :NNw } - \__prg_compare_error:Nw #1 + \@@_compare_error:Nw #1 } % \end{macrocode} % When the last \meta{operand} is seen, \cs{@@_compare:NNw} receives @@ -1596,12 +1582,12 @@ {#2} \exp_stop_f: \prg_return_false: \exp_after:wN \use_none_delimit_by_q_stop:w \fi: - #1 #2 #3 \exp_after:wN \@@_compare:Nw \@@_value:w \@@_eval:w + #1 #2 #3 \exp_after:wN \@@_compare:Nw \int_value:w \@@_eval:w } % \end{macrocode} % The actual comparisons are then simple function calls, using the % relation as delimiter for a delimited argument and discarding -% \cs{__prg_compare_error:Nw} \meta{token} responsible for error +% \cs{@@_compare_error:Nw} \meta{token} responsible for error % detection. % \begin{macrocode} \cs_new:cpn { @@_compare_=:NNw } #1#2#3 = @@ -1649,7 +1635,7 @@ % \begin{macro}{\@@_case:nw, \@@_case_end:nw} % For integer cases, the first task to fully expand the check % condition. The over all idea is then much the same as for -% \cs{str_case:nn(TF)} as described in \pkg{l3basics}. +% \cs{tl_case:nn(TF)} as described in \pkg{l3tl}. % \begin{macrocode} \cs_new:Npn \int_case:nnTF #1 { @@ -1679,7 +1665,8 @@ { \@@_case_end:nw {#3} } { \@@_case:nw {#1} } } -\cs_new_eq:NN \@@_case_end:nw \__prg_case_end:nw +\cs_new:Npn \@@_case_end:nw #1#2#3 \q_mark #4#5 \q_stop + { \exp_end: #1 #4 } % \end{macrocode} % \end{macro} % \end{macro} @@ -1810,7 +1797,9 @@ % \subsection{Integer step functions} % % \begin{macro}{\int_step_function:nnnN} -% \begin{macro}{\@@_step:wwwN, \@@_step:NnnnN} +% \begin{macro}{\@@_step:wwwN, \@@_step:NwnnN} +% \begin{macro}{\int_step_function:nN} +% \begin{macro}{\int_step_function:nnN} % Before all else, evaluate the initial value, step, and final value. % Repeating a function by steps first needs a check on the direction % of the steps. After that, do the function for the start value then @@ -1820,70 +1809,96 @@ % \begin{macrocode} \__kernel_patch_args:nNNpn { - { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_step_function:nnnN } - { \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } \int_step_function:nnnN } - { \__kernel_chk_expr:nNnN {#3} \@@_eval:w { } \int_step_function:nnnN } + { + \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } + \int_step_function:nnnN + } + { + \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } + \int_step_function:nnnN + } + { + \__kernel_chk_expr:nNnN {#3} \@@_eval:w { } + \int_step_function:nnnN + } } \cs_new:Npn \int_step_function:nnnN #1#2#3 { \exp_after:wN \@@_step:wwwN - \@@_value:w \@@_eval:w #1 \exp_after:wN ; - \@@_value:w \@@_eval:w #2 \exp_after:wN ; - \@@_value:w \@@_eval:w #3 ; + \int_value:w \@@_eval:w #1 \exp_after:wN ; + \int_value:w \@@_eval:w #2 \exp_after:wN ; + \int_value:w \@@_eval:w #3 ; } \cs_new:Npn \@@_step:wwwN #1; #2; #3; #4 { \int_compare:nNnTF {#2} > \c_zero - { \@@_step:NnnnN > } + { \@@_step:NwnnN > } { \int_compare:nNnTF {#2} = \c_zero { - \__kernel_msg_expandable_error:nnn { kernel } { zero-step } {#4} - \use_none:nnnn + \__kernel_msg_expandable_error:nnn + { kernel } { zero-step } {#4} + \prg_break: } - { \@@_step:NnnnN < } + { \@@_step:NwnnN < } } - {#1} {#2} {#3} #4 + #1 ; {#2} {#3} #4 + \prg_break_point: } -\cs_new:Npn \@@_step:NnnnN #1#2#3#4#5 +\cs_new:Npn \@@_step:NwnnN #1#2 ; #3#4#5 { - \int_compare:nNnF {#2} #1 {#4} - { - #5 {#2} - \exp_args:NNf \@@_step:NnnnN - #1 { \int_eval:n { #2 + #3 } } {#3} {#4} #5 - } - } + \if_int_compare:w #2 #1 #4 \exp_stop_f: + \prg_break:n + \fi: + #5 {#2} + \exp_after:wN \@@_step:NwnnN + \exp_after:wN #1 + \int_value:w \@@_eval:w #2 + #3 ; {#3} {#4} #5 + } +\cs_new:Npn \int_step_function:nN + { \int_step_function:nnnN { 1 } { 1 } } +\cs_new:Npn \int_step_function:nnN #1 + { \int_step_function:nnnN {#1} { 1 } } % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} % -% \begin{macro}{\int_step_inline:nnnn} -% \begin{macro}{\int_step_variable:nnnNn} +% \begin{macro}{\int_step_inline:nn, \int_step_inline:nnn, \int_step_inline:nnnn} +% \begin{macro}{\int_step_variable:nNn, \int_step_variable:nnNn, \int_step_variable:nnnNn} % \UnitTested % \begin{macro}{\@@_step:NNnnnn} % The approach here is to build a function, with a global integer % required to make the nesting safe (as seen in other in line % functions), and map that function using \cs{int_step_function:nnnN}. -% We put a \cs{__prg_break_point:Nn} so that \texttt{map_break} -% functions from other modules correctly decrement \cs{g__prg_map_int} +% We put a \cs{prg_break_point:Nn} so that \texttt{map_break} +% functions from other modules correctly decrement \cs{g__kernel_prg_map_int} % before looking for their own break point. The first argument is % \cs{scan_stop:}, so that no breaking function recognizes this break % point as its own. % \begin{macrocode} +\cs_new_protected:Npn \int_step_inline:nn + { \int_step_inline:nnnn { 1 } { 1 } } +\cs_new_protected:Npn \int_step_inline:nnn #1 + { \int_step_inline:nnnn {#1} { 1 } } \cs_new_protected:Npn \int_step_inline:nnnn { - \int_gincr:N \g__prg_map_int + \int_gincr:N \g__kernel_prg_map_int \exp_args:NNc \@@_step:NNnnnn \cs_gset_protected:Npn - { __prg_map_ \int_use:N \g__prg_map_int :w } + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } } +\cs_new_protected:Npn \int_step_variable:nNn + { \int_step_variable:nnnNn { 1 } { 1 } } +\cs_new_protected:Npn \int_step_variable:nnNn #1 + { \int_step_variable:nnnNn {#1} { 1 } } \cs_new_protected:Npn \int_step_variable:nnnNn #1#2#3#4#5 { - \int_gincr:N \g__prg_map_int + \int_gincr:N \g__kernel_prg_map_int \exp_args:NNc \@@_step:NNnnnn \cs_gset_protected:Npx - { __prg_map_ \int_use:N \g__prg_map_int :w } + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } {#1}{#2}{#3} { \tl_set:Nn \exp_not:N #4 {##1} @@ -1894,7 +1909,7 @@ { #1 #2 ##1 {#6} \int_step_function:nnnN {#3} {#4} {#5} #2 - \__prg_break_point:Nn \scan_stop: { \int_gdecr:N \g__prg_map_int } + \prg_break_point:Nn \scan_stop: { \int_gdecr:N \g__kernel_prg_map_int } } % \end{macrocode} % \end{macro} @@ -2139,7 +2154,7 @@ \or: x \or: y \or: z - \else: \@@_value:w \@@_eval:w #1 \exp_after:wN \@@_eval_end: + \else: \int_value:w \@@_eval:w #1 \exp_after:wN \@@_eval_end: \fi: } \cs_new:Npn \@@_to_Letter:n #1 @@ -2172,7 +2187,7 @@ \or: X \or: Y \or: Z - \else: \@@_value:w \@@_eval:w #1 \exp_after:wN \@@_eval_end: + \else: \int_value:w \@@_eval:w #1 \exp_after:wN \@@_eval_end: \fi: } % \end{macrocode} @@ -2479,6 +2494,12 @@ % \end{macrocode} % \end{macro} % +%\subsection{Random integers} +% +% \begin{macro}{\int_rand:nn} +% Defined in \pkg{l3fp-random}. +% \end{macro} +% % \subsection{Constant integers} % % \begin{variable}{\c_zero} @@ -2590,15 +2611,22 @@ % \cs{c_minus_one} (as all deprecated commands) is made outer by % \cs{debug_deprecation_on:}. % \begin{macrocode} -%<package>\cs_gset_eq:NN \c__deprecation_minus_one \m@ne -%<initex>\int_const:Nn \c__deprecation_minus_one { -1 } -\cs_new_eq:NN \c_minus_one \c__deprecation_minus_one +%<package>\cs_gset_eq:NN \c_@@_minus_one \m@ne +%<initex>\int_const:Nn \c_@@_minus_one { -1 } +\cs_new_eq:NN \c_minus_one \c_@@_minus_one \__kernel_deprecation_code:nn - { \__deprecation_error:Nnn \c_minus_one { -1 } { 2018-12-31 } } - { \tex_let:D \c_minus_one \c__deprecation_minus_one } + { \__kernel_deprecation_error:Nnn \c_minus_one { -1 } { 2018-12-31 } } + { \tex_let:D \c_minus_one \c_@@_minus_one } % \end{macrocode} % \end{variable} % +% \begin{macro}[deprecated = 2019-12-31]{\@@_value:w} +% Made public. +% \begin{macrocode} +\cs_new_eq:NN \@@_value:w \int_value:w +% \end{macrocode} +% \end{macro} +% % \begin{macrocode} %</initex|package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx b/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx index 56128aa8e1c..9ccc892e28d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3intarray.dtx Copyright (C) 2017 The LaTeX3 Project +%% File: l3intarray.dtx Copyright (C) 2017-2018 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -30,7 +30,7 @@ % % % \title{^^A -% The \textsf{l3intarray} package: low-level arrays of small integers^^A +% The \textsf{l3intarray} package: fast global integer arrays^^A % } % % \author{^^A @@ -42,7 +42,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -50,66 +50,73 @@ % % \section{\pkg{l3intarray} documentation} % -% This module provides no user function: at present it is meant for -% kernel use only. -% -% It is a wrapper around the \tn{fontdimen} primitive, used to store -% arrays of integers (with a restricted range: absolute value at most -% $2^{30}-1$). In contrast to \pkg{l3seq} sequences the access to -% individual entries is done in constant time rather than linear time, -% but only integers can be stored. More precisely, the primitive -% \tn{fontdimen} stores dimensions but the \pkg{l3intarray} package -% transparently converts these from/to integers. Assignments are always -% global. -% -% While \LuaTeX{}'s memory is extensible, other engines can -% \enquote{only} deal with a bit less than $4\times 10^6$ entries in all -% \tn{fontdimen} arrays combined (with default \TeX{}Live settings). -% -% \subsection{Internal functions} -% -% \begin{function}{\__intarray_new:Nn} +% For applications requiring heavy use of integers, this module provides +% arrays which can be accessed in constant time (contrast \pkg{l3seq}, +% where access time is linear). These arrays have several important +% features +% \begin{itemize} +% \item The size of the array is fixed and must be given at +% point of initialisation +% \item The absolute value of each entry has maximum $2^{30}-1$ +% (\emph{i.e.}~one power lower than the usual \cs{c_max_int} +% ceiling of $2^{31}-1$) +% \end{itemize} +% The use of \texttt{intarray} data is therefore recommended for cases where +% the need for fast access is of paramount importance. +% +% \begin{function}[added = 2018-03-29]{\intarray_new:Nn} % \begin{syntax} -% \cs{__intarray_new:Nn} \meta{intarray~var} \Arg{size} +% \cs{intarray_new:Nn} \meta{intarray~var} \Arg{size} % \end{syntax} % Evaluates the integer expression \meta{size} and allocates an % \meta{integer array variable} with that number of (zero) entries. % \end{function} % -% \begin{function}[EXP]{\__intarray_count:N} +% \begin{function}[EXP, added = 2018-03-29]{\intarray_count:N} % \begin{syntax} -% \cs{__intarray_count:N} \meta{intarray~var} +% \cs{intarray_count:N} \meta{intarray~var} % \end{syntax} % Expands to the number of entries in the \meta{integer array variable}. % Contrarily to \cs{seq_count:N} this is performed in constant time. % \end{function} % -% \begin{function}{\__intarray_gset:Nnn, \__intarray_gset_fast:Nnn} +% \begin{function}[added = 2018-03-29]{\intarray_gset:Nnn} % \begin{syntax} -% \cs{__intarray_gset:Nnn} \meta{intarray~var} \Arg{position} \Arg{value} -% \cs{__intarray_gset_fast:Nnn} \meta{intarray~var} \Arg{position} \Arg{value} +% \cs{intarray_gset:Nnn} \meta{intarray~var} \Arg{position} \Arg{value} % \end{syntax} % Stores the result of evaluating the integer expression \meta{value} % into the \meta{integer array variable} at the (integer expression) -% \meta{position}. While \cs{__intarray_gset:Nnn} checks that the -% \meta{position} is between $1$ and the \cs{__intarray_count:N} and that -% the \meta{value}'s absolute value is at most $2^{30}-1$, the -% \enquote{fast} function performs no such bound check. -% Assignments are always global. +% \meta{position}. If the \meta{position} is not between $1$ and the +% \cs{intarray_count:N}, or the \meta{value}'s absolute value is +% bigger than $2^{30}-1$, an error occurs. Assignments are always +% global. % \end{function} % -% \begin{function}[EXP]{\__intarray_item:Nn, \__intarray_item_fast:Nn} +% \begin{function}[EXP, added = 2018-03-29]{\intarray_item:Nn} % \begin{syntax} -% \cs{__intarray_item:Nn} \meta{intarray~var} \Arg{position} -% \cs{__intarray_item_fast:Nn} \meta{intarray~var} \Arg{position} +% \cs{intarray_item:Nn} \meta{intarray~var} \Arg{position} % \end{syntax} % Expands to the integer entry stored at the (integer expression) -% \meta{position} in the \meta{integer array variable}. While -% \cs{__intarray_item:Nn} checks that the \meta{position} is between $1$ -% and the \cs{__intarray_count:N}, the \enquote{fast} function performs -% no such bound check. +% \meta{position} in the \meta{integer array variable}. If the +% \meta{position} is not between $1$ and the \cs{intarray_count:N}, an +% error occurs. % \end{function} % +% \subsection{Implementation notes} +% +% It is a wrapper around the \tn{fontdimen} primitive, used to store +% arrays of integers (with a restricted range: absolute value at most +% $2^{30}-1$). In contrast to \pkg{l3seq} sequences the access to +% individual entries is done in constant time rather than linear time, +% but only integers can be stored. More precisely, the primitive +% \tn{fontdimen} stores dimensions but the \pkg{l3intarray} package +% transparently converts these from/to integers. Assignments are always +% global. +% +% While \LuaTeX{}'s memory is extensible, other engines can +% \enquote{only} deal with a bit less than $4\times 10^6$ entries in all +% \tn{fontdimen} arrays combined (with default \TeX{}Live settings). +% % \end{documentation} % % \begin{implementation} @@ -126,6 +133,13 @@ % % \subsection{Allocating arrays} % +% \begin{variable}{\c_@@_sp_dim} +% Used to convert integers to dimensions fast. +% \begin{macrocode} +\dim_const:Nn \c_@@_sp_dim { 1 sp } +% \end{macrocode} +% \end{variable} +% % \begin{variable}{\g_@@_font_int} % Used to assign one font per array. % \begin{macrocode} @@ -133,7 +147,7 @@ % \end{macrocode} % \end{variable} % -% \begin{macro}{\@@_new:Nn} +% \begin{macro}{\intarray_new:Nn} % Declare |#1| to be a font (arbitrarily |cmr10| at a never-used % size). Store the array's size as the \tn{hyphenchar} of that font % and make sure enough \tn{fontdimen} are allocated, by setting the @@ -141,82 +155,120 @@ % It seems \LuaTeX{}'s |cmr10| has an extra \tn{fontdimen} parameter % number $8$ compared to other engines (for a math font we would % replace $8$ by $22$ or some such). +% Every \texttt{intarray} must be global; it's enough to run this +% check in \cs{intarray_new:Nn}. % \begin{macrocode} -\cs_new_protected:Npn \@@_new:Nn #1#2 +\__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN g #1 } { } +\cs_new_protected:Npn \intarray_new:Nn #1#2 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \int_gincr:N \g_@@_font_int - \tex_global:D \tex_font:D #1 = cmr10~at~ \g_@@_font_int sp \scan_stop: + \tex_global:D \tex_font:D #1 + = cmr10~at~ \g_@@_font_int \c_@@_sp_dim \scan_stop: \tex_hyphenchar:D #1 = \int_eval:n {#2} \scan_stop: \int_compare:nNnT { \tex_hyphenchar:D #1 } > 0 - { \tex_fontdimen:D \tex_hyphenchar:D #1 #1 = 0 sp \scan_stop: } - \int_step_inline:nnnn { 1 } { 1 } { 8 } - { \tex_fontdimen:D ##1 #1 = 0 sp \scan_stop: } + { \tex_fontdimen:D \tex_hyphenchar:D #1 #1 = \c_zero_dim } + \int_step_inline:nn { 8 } { \tex_fontdimen:D ##1 #1 = \c_zero_dim } } % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\@@_count:N} +% \begin{macro}[EXP]{\intarray_count:N} % Size of an array. % \begin{macrocode} -\cs_new:Npn \@@_count:N #1 { \tex_the:D \tex_hyphenchar:D #1 } +\cs_new:Npn \intarray_count:N #1 { \tex_the:D \tex_hyphenchar:D #1 } % \end{macrocode} % \end{macro} % % \subsection{Array items} % -% \begin{macro}{\@@_gset:Nnn, \@@_gset_fast:Nnn} -% \begin{macro}{\@@_gset_aux:Nnn} -% Set the appropriate \tn{fontdimen}. The slow version checks the -% position and value are within bounds. +% \begin{macro}[EXP]{\@@_bounds:NNnTF, \@@_bounds_error:NNn} +% The functions \cs{intarray_gset:Nnn} and \cs{intarray_item:Nn} share +% bounds checking. The |T| branch is used if |#3| is within bounds of +% the array |#2|. % \begin{macrocode} -\cs_new_protected:Npn \@@_gset_fast:Nnn #1#2#3 - { \tex_fontdimen:D \int_eval:n {#2} #1 = \int_eval:n {#3} sp \scan_stop: } -\cs_new_protected:Npn \@@_gset:Nnn #1#2#3 +\cs_new:Npn \@@_bounds:NNnTF #1#2#3#4#5 { - \exp_args:Nff \@@_gset_aux:Nnn #1 - { \int_eval:n {#2} } { \int_eval:n {#3} } + \if_int_compare:w 1 > #3 \exp_stop_f: + \@@_bounds_error:NNn #1 #2 {#3} + #5 + \else: + \if_int_compare:w #3 > \intarray_count:N #2 \exp_stop_f: + \@@_bounds_error:NNn #1 #2 {#3} + #5 + \else: + #4 + \fi: + \fi: } -\cs_new_protected:Npn \@@_gset_aux:Nnn #1#2#3 +\cs_new:Npn \@@_bounds_error:NNn #1#2#3 { - \int_compare:nTF { 1 <= #2 <= \@@_count:N #1 } - { - \int_compare:nTF { - \c_max_dim <= \int_abs:n {#3} <= \c_max_dim } - { \@@_gset_fast:Nnn #1 {#2} {#3} } - { - \__kernel_msg_error:nnxxxx { kernel } { overflow } - { \token_to_str:N #1 } {#2} {#3} - { \int_compare:nNnT {#3} < 0 { - } \__int_value:w \c_max_dim } - \@@_gset_fast:Nnn #1 {#2} - { \int_compare:nNnT {#3} < 0 { - } \c_max_dim } - } - } + #1 { kernel } { out-of-bounds } + { \token_to_str:N #2 } {#3} { \intarray_count:N #2 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intarray_gset:Nnn, \__kernel_intarray_gset:Nnn} +% \begin{macro}{\@@_gset:Nnn, \@@_gset_overflow:Nnn} +% Set the appropriate \tn{fontdimen}. The +% \cs{__kernel_intarray_gset:Nnn} function does not use +% \cs{int_eval:n}, namely its arguments must be suitable for +% \cs{int_value:w}. The user version checks the position and value +% are within bounds. +% \begin{macrocode} +\cs_new_protected:Npn \__kernel_intarray_gset:Nnn #1#2#3 + { \tex_fontdimen:D #2 #1 #3 \c_@@_sp_dim } +\cs_new_protected:Npn \intarray_gset:Nnn #1#2#3 + { + \exp_after:wN \@@_gset:Nww + \exp_after:wN #1 + \int_value:w \int_eval:n {#2} \exp_after:wN ; + \int_value:w \int_eval:n {#3} ; + } +\cs_new_protected:Npn \@@_gset:Nww #1#2 ; #3 ; + { + \@@_bounds:NNnTF \__kernel_msg_error:nnxxx #1 {#2} { - \__kernel_msg_error:nnxxx { kernel } { out-of-bounds } - { \token_to_str:N #1 } {#2} { \@@_count:N #1 } + \if_int_compare:w \int_abs:n {#3} > \c_max_dim + \exp_after:wN \@@_gset_overflow:NNnn + \fi: + \__kernel_intarray_gset:Nnn #1 {#2} {#3} } + { } + } +\cs_new_protected:Npn \@@_gset_overflow:NNnn #1#2#3#4 + { + \__kernel_msg_error:nnxxxx { kernel } { overflow } + { \token_to_str:N #2 } {#3} {#4} + { \int_value:w \int_compare:nNnT {#4} < 0 { - } \c_max_dim } + \__kernel_intarray_gset:Nnn #2 {#3} + { \int_value:w \int_compare:nNnT {#4} < 0 { - } \c_max_dim } } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\@@_item:Nn, \@@_item_fast:Nn} -% \begin{macro}{\@@_item_aux:Nn} -% Get the appropriate \tn{fontdimen} and perform bound checks if requested. +% \begin{macro}[EXP]{\intarray_item:Nn, \__kernel_intarray_item:Nn} +% \begin{macro}{\@@_item:Nn} +% Get the appropriate \tn{fontdimen} and perform bound checks. The +% \cs{__kernel_intarray_item:Nn} function omits bound checks and omits +% \cs{int_eval:n}, namely its argument must be a \TeX{} integer +% suitable for \cs{int_value:w}. % \begin{macrocode} -\cs_new:Npn \@@_item_fast:Nn #1#2 - { \__int_value:w \tex_fontdimen:D \int_eval:n {#2} #1 } -\cs_new:Npn \@@_item:Nn #1#2 - { \exp_args:Nf \@@_item_aux:Nn #1 { \int_eval:n {#2} } } -\cs_new:Npn \@@_item_aux:Nn #1#2 +\cs_new:Npn \__kernel_intarray_item:Nn #1#2 + { \int_value:w \tex_fontdimen:D #2 #1 } +\cs_new:Npn \intarray_item:Nn #1#2 { - \int_compare:nTF { 1 <= #2 <= \@@_count:N #1 } - { \@@_item_fast:Nn #1 {#2} } - { - \__kernel_msg_expandable_error:nnnnn { kernel } { out-of-bounds } - { \token_to_str:N #1 } {#2} { \@@_count:N #1 } - 0 - } + \exp_after:wN \@@_item:Nw + \exp_after:wN #1 + \int_value:w \int_eval:n {#2} ; + } +\cs_new:Npn \@@_item:Nw #1#2 ; + { + \@@_bounds:NNnTF \__kernel_msg_expandable_error:nnfff #1 {#2} + { \__kernel_intarray_item:Nn #1 {#2} } + { 0 } } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx b/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx new file mode 100644 index 00000000000..aa4e288b59d --- /dev/null +++ b/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx @@ -0,0 +1,481 @@ +% \iffalse meta-comment +% +%% File: l3kernel-functions.dtx Copyright (C) 2018 The LaTeX3 project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% This file is part of the "l3kernel bundle" (The Work in LPPL) +% and all files in that bundle must be distributed together. +% +% ----------------------------------------------------------------------- +% +% The development version of the bundle can be found at +% +% https://github.com/latex3/latex3 +% +% for those people who are interested. +% +%<*driver> +\documentclass[full,kernel]{l3doc} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% \title{^^A +% The \pkg{l3kernel-functions} package\\ Kernel-reserved functions^^A +% } +% +% \author{^^A +% The \LaTeX3 Project\thanks +% {^^A +% E-mail: +% \href{mailto:latex-team@latex-project.org} +% {latex-team@latex-project.org}^^A +% }^^A +% } +% +% \date{Released 2018-04-30} +% +% \maketitle +% +% \begin{documentation} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{Internal kernel functions} +% +% \begin{function}{\__kernel_chk_cs_exist:N, \__kernel_chk_cs_exist:c} +% \begin{syntax} +% \cs{__kernel_chk_cs_exist:N} \meta{cs} +% \end{syntax} +% This function is only created if debugging is enabled. It checks +% that \meta{cs} exists according to the criteria for +% \cs{cs_if_exist_p:N}, and if not raises a kernel-level error. +% \end{function} +% +% \begin{function}{\__kernel_chk_defined:NT} +% \begin{syntax} +% \cs{__kernel_chk_defined:NT} \meta{variable} \Arg{true code} +% \end{syntax} +% If \meta{variable} is not defined (according to +% \cs{cs_if_exist:NTF}), this triggers an error, otherwise the +% \meta{true code} is run. +% \end{function} +% +% \begin{function}{\__kernel_chk_expr:nNnN} +% \begin{syntax} +% \cs{__kernel_chk_expr:nNnN} \Arg{expr} \meta{eval} \Arg{convert} \meta{caller} +% \end{syntax} +% This function is only created if debugging is enabled. By default +% it is equivalent to \cs{use_i:nnnn}. When expression checking is +% enabled, it leaves in the input stream the result of \cs{tex_the:D} +% \meta{eval} \meta{expr} \cs{tex_relax:D} after checking that no +% token was left over. If any token was not taken as part of the +% expression, there is an error message displaying the result of the +% evaluation as well as the \meta{caller}. For instance \meta{eval} +% can be \cs{__int_eval:w} and \meta{caller} can be \cs{int_eval:n} or +% \cs{int_set:Nn}. The argument \meta{convert} is empty except for mu +% expressions where it is \cs{etex_mutoglue:D}, used for internal +% purposes. +% \end{function} +% +% \begin{function}{\__kernel_chk_var_exist:N} +% \begin{syntax} +% \cs{__kernel_chk_var_exist:N} \meta{var} +% \end{syntax} +% This function is only created if debugging is enabled. It checks +% that \meta{var} is defined according to the criteria for +% \cs{cs_if_exist_p:N}, and if not raises a kernel-level error. +% \end{function} +% +% \begin{function}{\__kernel_chk_var_scope:NN} +% \begin{syntax} +% \cs{__kernel_chk_var_scope:NN} \meta{scope} \meta{var} +% \end{syntax} +% Checks the \meta{var} has the correct \meta{scope}, and if not +% raises a kernel-level error. This function is only created if +% debugging is enabled. The \meta{scope} is a single letter |l|, |g|, +% |c| denoting local variables, global variables, or constants. More +% precisely, if the variable name starts with a letter and an +% underscore (normal \pkg{expl3} convention) the function checks that +% this single letter matches the \meta{scope}. Otherwise the function +% cannot know the scope \meta{var} the first time: instead, it defines +% |\__debug_chk_/|\meta{var name} to store that information for the +% next call. Thus, if a given \meta{var} is subject to assignments of +% different scopes a kernel error will result. +% \end{function} +% +% \begin{function}{\__kernel_chk_var_local:N, \__kernel_chk_var_global:N} +% \begin{syntax} +% \cs{__kernel_chk_var_local:N} \meta{var} +% \cs{__kernel_chk_var_global:N} \meta{var} +% \end{syntax} +% Applies \cs{__kernel_chk_var_exist:N} \meta{var}, and assuming that is +% true applies +% \cs{__kernel_chk_var_scope:NN} \meta{scope} \meta{var}, where +% \meta{scope} is |l| or~|g|. +% \end{function} +% +% \begin{function}{\__kernel_cs_parm_from_arg_count:nnF} +% \begin{syntax} +% \cs{__kernel_cs_parm_from_arg_count:nnF} \Arg{follow-on} \Arg{args} \Arg{false code} +% \end{syntax} +% Evaluates the number of \meta{args} and leaves the \meta{follow-on} code +% followed by a brace group containing the required number of primitive +% parameter markers (|#1|, \emph{etc}.). If the number of \meta{args} is outside +% the range $[0,9]$, the \meta{false code} is inserted \emph{instead} of +% the \meta{follow-on}. +% \end{function} +% +% \begin{function}{\__kernel_if_debug:TF} +% \begin{syntax} +% \cs{__kernel_if_debug:TF} \Arg{true code} \Arg{false code} +% \end{syntax} +% Runs the \meta{true code} if debugging is enabled, namely only in +% \LaTeXe{} package mode with one of the options +% \texttt{check-declarations}, \texttt{enable-debug}, or +% \texttt{log-functions}. Otherwise runs the \meta{false code}. The +% |T| and |F| variants are not provided for this low-level +% conditional. +% \end{function} +% +% \begin{function}{\__kernel_debug_log:x} +% \begin{syntax} +% \cs{__kernel_debug_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}. +% This function is only created if debugging is enabled. +% \end{function} +% +% \begin{function}[EXP]{\__kernel_exp_not:w} +% \begin{syntax} +% \cs{__kernel_exp_not:w} \meta{expandable tokens} \Arg{content} +% \end{syntax} +% Carries out expansion on the \meta{expandable tokens} before preventing +% further expansion of the \meta{content} as for \cs{exp_not:n}. Typically, +% the \meta{expandable tokens} will alter the nature of the \meta{content}, +% \emph{i.e.}~allow it to be generated in some way. +% \end{function} +% +% \begin{variable}{\l__kernel_expl_bool} +% A boolean which records the current code syntax status: \texttt{true} if +% currently inside a code environment. This variable should only be +% set by \cs{ExplSyntaxOn}/\cs{ExplSyntaxOff}. +% \end{variable} +% +% \begin{function}{\__kernel_file_missing:n} +% \begin{syntax} +% \cs{__kernel_file_missing:n} \Arg{name} +% \end{syntax} +% Expands the \meta{name} as per \cs{__kernel_file_name_sanitize:nN} then +% produces an error message indicating that that file was not found. +% \end{function} +% +% \begin{function}{\__kernel_file_name_sanitize:nN} +% \begin{syntax} +% \cs{__kernel_file_name_sanitize:nN} \Arg{name} \meta{str var} +% \end{syntax} +% For converting a \meta{name} to a string where active characters are treated +% as strings. +% \end{function} +% +% \begin{function}{\__kernel_file_input_push:n, \__kernel_file_input_pop:} +% \begin{syntax} +% \cs{__kernel_file_input_push:n} \Arg{name} +% \cs{__kernel_file_input_pop:} +% \end{syntax} +% Used to push and pop data from the internal file stack: needed only +% in package mode, where interfacing with the \LaTeXe{} kernel is necessary. +% \end{function} +% +% \begin{function}{\__kernel_ior_open:Nn, \__kernel_ior_open:No} +% \begin{syntax} +% \cs{__kernel_ior_open:Nn} \meta{stream} \Arg{file name} +% \end{syntax} +% This function has identical syntax to the public version. However, +% is does not take precautions against active characters in the +% \meta{file name}, and it does not attempt to add a \meta{path} to +% the \meta{file name}: it is therefore intended to be used by +% higher-level +% functions which have already fully expanded the \meta{file name} and which +% need to perform multiple open or close operations. See for example the +% implementation of \cs{file_get_full_name:nN}, +% \end{function} +% +% \begin{function}{\__kernel_iow_with:Nnn} +% \begin{syntax} +% \cs{__kernel_iow_with:Nnn} \meta{integer} \Arg{value} \Arg{code} +% \end{syntax} +% If the \meta{integer} is equal to the \meta{value} then this +% function simply runs the \meta{code}. Otherwise it saves the +% current value of the \meta{integer}, sets it to the \meta{value}, +% runs the \meta{code}, and restores the \meta{integer} to its former +% value. This is used to ensure that the \tn{newlinechar} is~$10$ +% when writing to a stream, which lets \cs{iow_newline:} work, and +% that \tn{errorcontextlines} is $-1$ when displaying a message. +% \end{function} +% +% \begin{function} +% {\__kernel_msg_new:nnnn, \__kernel_msg_new:nnn} +% \begin{syntax} +% \cs{__kernel_msg_new:nnnn} \Arg{module} \Arg{message} \Arg{text} \Arg{more text} +% \end{syntax} +% Creates a kernel \meta{message} for a given \meta{module}. +% The message is defined to first give \meta{text} and then +% \meta{more text} if the user requests it. If no \meta{more text} is +% available then a standard text is given instead. Within \meta{text} +% and \meta{more text} four parameters (|#1| to |#4|) can be used: +% these will be supplied and expanded at the time the message is used. +% An error is raised if the \meta{message} already exists. +% \end{function} +% +% \begin{function} +% {\__kernel_msg_set:nnnn, \__kernel_msg_set:nnn} +% \begin{syntax} +% \cs{__kernel_msg_set:nnnn} \Arg{module} \Arg{message} \Arg{text} \Arg{more text} +% \end{syntax} +% Sets up the text for a kernel \meta{message} for a given \meta{module}. +% The message is defined to first give \meta{text} and then +% \meta{more text} if the user requests it. If no \meta{more text} is +% available then a standard text is given instead. Within \meta{text} +% and \meta{more text} four parameters (|#1| to |#4|) can be used: +% these will be supplied and expanded at the time the message is used. +% \end{function} +% +% \begin{function} +% { +% \__kernel_msg_fatal:nnnnnn , +% \__kernel_msg_fatal:nnnnn , +% \__kernel_msg_fatal:nnnn , +% \__kernel_msg_fatal:nnn , +% \__kernel_msg_fatal:nn , +% \__kernel_msg_fatal:nnxxxx , +% \__kernel_msg_fatal:nnxxx , +% \__kernel_msg_fatal:nnxx , +% \__kernel_msg_fatal:nnx +% } +% \begin{syntax} +% \cs{__kernel_msg_fatal:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four} +% \end{syntax} +% Issues kernel \meta{module} error \meta{message}, passing \meta{arg one} +% to \meta{arg four} to the text-creating functions. After issuing a +% fatal error the \TeX{} run halts. Cannot be redirected. +% \end{function} +% +% \begin{function} +% { +% \__kernel_msg_error:nnnnnn , +% \__kernel_msg_error:nnnnn , +% \__kernel_msg_error:nnnn , +% \__kernel_msg_error:nnn , +% \__kernel_msg_error:nn , +% \__kernel_msg_error:nnxxxx , +% \__kernel_msg_error:nnxxx , +% \__kernel_msg_error:nnxx , +% \__kernel_msg_error:nnx +% } +% \begin{syntax} +% \cs{__kernel_msg_error:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four} +% \end{syntax} +% Issues kernel \meta{module} error \meta{message}, passing \meta{arg one} +% to +% \meta{arg four} to the text-creating functions. The error +% stops processing and issues the text at the terminal. After user input, +% the run continues. Cannot be redirected. +% \end{function} +% +% \begin{function} +% { +% \__kernel_msg_warning:nnnnnn , +% \__kernel_msg_warning:nnnnn , +% \__kernel_msg_warning:nnnn , +% \__kernel_msg_warning:nnn , +% \__kernel_msg_warning:nn , +% \__kernel_msg_warning:nnxxxx , +% \__kernel_msg_warning:nnxxx , +% \__kernel_msg_warning:nnxx , +% \__kernel_msg_warning:nnx +% } +% \begin{syntax} +% \cs{__kernel_msg_warning:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four} +% \end{syntax} +% Issues kernel \meta{module} warning \meta{message}, passing +% \meta{arg one} to +% \meta{arg four} to the text-creating functions. The warning text +% is added to the log file, but the \TeX{} run is not interrupted. +% \end{function} +% +% \begin{function} +% { +% \__kernel_msg_info:nnnnnn , +% \__kernel_msg_info:nnnnn , +% \__kernel_msg_info:nnnn , +% \__kernel_msg_info:nnn , +% \__kernel_msg_info:nn , +% \__kernel_msg_info:nnxxxx , +% \__kernel_msg_info:nnxxx , +% \__kernel_msg_info:nnxx , +% \__kernel_msg_info:nnx +% } +% \begin{syntax} +% \cs{__kernel_msg_info:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four} +% \end{syntax} +% Issues kernel \meta{module} information \meta{message}, passing +% \meta{arg one} to \meta{arg four} to the text-creating functions. +% The information text is added to the log file. +% \end{function} +% +% \begin{function}[EXP] +% { +% \__kernel_msg_expandable_error:nnnnnn, +% \__kernel_msg_expandable_error:nnnnn, +% \__kernel_msg_expandable_error:nnnn, +% \__kernel_msg_expandable_error:nnn, +% \__kernel_msg_expandable_error:nn, +% \__kernel_msg_expandable_error:nnffff, +% \__kernel_msg_expandable_error:nnfff, +% \__kernel_msg_expandable_error:nnff, +% \__kernel_msg_expandable_error:nnf, +% } +% \begin{syntax} +% \cs{__kernel_msg_expandable_error:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four} +% \end{syntax} +% Issues an error, passing \meta{arg one} to \meta{arg four} +% to the text-creating functions. The resulting string must +% be much shorter than a line, otherwise it is cropped. +% \end{function} +% +% \begin{function}{\__kernel_patch:nnNNpn} +% \begin{syntax} +% \cs{__kernel_patch:nnNNpn} \Arg{before} \Arg{after} +% \meta{definition} \meta{function} \meta{parameters} \Arg{code} +% \end{syntax} +% If debugging is not enabled, this function ignores the \meta{before} +% and \meta{after} code and performs the \meta{definition} with no +% patching. Otherwise it replaces \meta{code} by \meta{before} +% \meta{code} \meta{after} (which can involve |#1| and so on) in the +% \meta{definition} that follows. The \meta{definition} must start +% with \cs{cs_new:Npn} or \cs{cs_set:Npn} or \cs{cs_gset:Npn} or their +% \texttt{_protected} counterparts. Other cases can be added as +% needed. +% \end{function} +% +% \begin{function}{\__kernel_patch_conditional:nNNpnn} +% \begin{syntax} +% \cs{__kernel_patch_conditional:nNNpnn} \Arg{before} +% \meta{definition} \meta{conditional} \meta{parameters} \Arg{type} \Arg{code} +% \end{syntax} +% Similar to \cs{__kernel_patch:nnNNpn} for conditionals, namely +% \meta{definition} must be \cs{prg_new_conditional:Npnn} or its +% \texttt{_protected} counterpart. There is no \meta{after} code +% because that would interfere with the action of the conditional. +% \end{function} +% +% \begin{function} +% {\__kernel_patch_args:nNNpn, \__kernel_patch_conditional_args:nNNpnn} +% \begin{syntax} +% \cs{__kernel_patch_args:nNNpn} \Arg{arguments} +% \meta{definition} \meta{function} \meta{parameters} \Arg{code} +% \end{syntax} +% Like \cs{__kernel_patch:nnNNpn}, this tweaks the following +% definition, but from the \enquote{inside out} (and if debugging is +% not enabled, the \meta{arguments} are ignored). It replaces |#1|, +% |#2| and so on in the \meta{code} of the definition as indicated by +% the \meta{arguments}. More precisely, a temporary function is +% defined using the \meta{definition} with the \meta{parameters} and +% \meta{code}, then the result of expanding that function once in +% front of the \meta{arguments} is used instead of the \meta{code} +% when defining the actual function. For instance, +% \begin{quote} +% \cs{__kernel_patch_args:nNNpn} |{ { (#1) } }| \\ +% \cs{cs_new:Npn} \cs{int_eval:n} |#1| \\ +% ~~|{ \int_value:w \__int_eval:w #1 \__int_eval_end: }| +% \end{quote} +% would replace |#1| by |(#1)| in the definition of \cs{int_eval:n} when +% debugging is enabled. This fails if the \meta{code} contains~|##|. +% The \cs{__kernel_patch_conditional_args:nNNpnn} function is for use +% before \cs{prg_new_conditional:Npnn} or its \texttt{_protected} +% counterpart. +% \end{function} +% +% \begin{function} +% {\__kernel_patch_args:nnnNNpn, \__kernel_patch_conditional_args:nnnNNpnn} +% \begin{syntax} +% \cs{__kernel_patch_args:nnnNNpn} \Arg{before} \Arg{after} \Arg{arguments} +% \meta{definition} \meta{function} \meta{parameters} \Arg{code} +% \end{syntax} +% A combination of \cs{__kernel_patch:nnNNpn} and +% \cs{__kernel_patch_args:nNNpn}. +% \end{function} +% +% \begin{variable}{\g__kernel_prg_map_int} +% This integer is used by non-expandable mapping functions to track +% the level of nesting in force. The functions +% \cs[no-index]{\meta{type}_map_1:w}, +% \cs[no-index]{\meta{type}_map_2:w}, \emph{etc.}, labelled by +% \cs{g__kernel_prg_map_int} +% hold functions to be mapped over various list datatypes in inline +% and variable mappings. +% \end{variable} +% +% \begin{function}{\__kernel_register_show:N, \__kernel_register_show:c} +% \begin{syntax} +% \cs{__kernel_register_show:N} \meta{register} +% \end{syntax} +% Used to show the contents of a \TeX{} register at the terminal, formatted +% such that internal parts of the mechanism are not visible. +% \end{function} +% +% \begin{function} +% {\__kernel_register_log:N, \__kernel_register_log:c} +% \begin{syntax} +% \cs{__kernel_register_log:N} \meta{register} +% \end{syntax} +% Used to write the contents of a \TeX{} register to the log file in a +% form similar to \cs{__kernel_register_show:N}. +% \end{function} +% +% \begin{function}[EXP]{\__kernel_str_to_other:n} +% \begin{syntax} +% \cs{__kernel_str_to_other:n} \Arg{token list} +% \end{syntax} +% Converts the \meta{token list} to a \meta{other string}, where +% spaces have category code \enquote{other}. This function can be +% \texttt{f}-expanded without fear of losing a leading space, since +% spaces do not have category code $10$ in its result. It takes a +% time quadratic in the character count of the string. +% \end{function} +% +% \begin{function}[rEXP]{\__kernel_str_to_other_fast:n} +% \begin{syntax} +% \cs{__kernel_str_to_other_fast:n} \Arg{token list} +% \end{syntax} +% Same behaviour \cs{__kernel_str_to_other:n} but only restricted-expandable. +% It takes a time linear in the character count of the string. +% \end{function} +% +% \begin{function}[EXP]{\__kernel_tl_to_str:w} +% \begin{syntax} +% \cs{__kernel_tl_to_str:w} \meta{expandable tokens} \Arg{tokens} +% \end{syntax} +% Carries out expansion on the \meta{expandable tokens} before conversion of +% the \meta{tokens} to a string as describe for \cs{tl_to_str:n}. Typically, +% the \meta{expandable tokens} will alter the nature of the \meta{tokens}, +% \emph{i.e.}~allow it to be generated in some way. This function requires +% only a single expansion. +% \end{function} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx index 75dcff129dd..7b8c19097ba 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -118,7 +118,7 @@ % % \section{Creating keys} % -% \begin{function}[updated = 2015-11-07]{\keys_define:nn} +% \begin{function}[updated = 2017-11-14]{\keys_define:nn} % \begin{syntax} % \cs{keys_define:nn} \Arg{module} \Arg{keyval list} % \end{syntax} @@ -343,9 +343,9 @@ % \meta{key} .meta:n = \Arg{keyval list} % \end{syntax} % Makes \meta{key} a meta-key, which will set \meta{keyval list} in -% one go. If \meta{key} is given with a value at the time the key -% is used, then the value will be passed through to the subsidiary -% \meta{keys} for processing (as |#1|). +% one go. The \meta{keyval list} can refer as |#1| to the value given +% at the time the \meta{key} is used (or, if no value is given, the +% \meta{key}'s default value). % \end{function} % % \begin{function}[added = 2013-07-10]{.meta:nn} @@ -353,10 +353,10 @@ % \meta{key} .meta:nn = \Arg{path} \Arg{keyval list} % \end{syntax} % Makes \meta{key} a meta-key, which will set \meta{keyval list} in -% one go using the \meta{path} in place of the current one. -% If \meta{key} is given with a value at the time the key -% is used, then the value will be passed through to the subsidiary -% \meta{keys} for processing (as |#1|). +% one go using the \meta{path} in place of the current one. The +% \meta{keyval list} can refer as |#1| to the value given at the time +% the \meta{key} is used (or, if no value is given, the \meta{key}'s +% default value). % \end{function} % % \begin{function}[added = 2011-08-21]{.multichoice:} @@ -598,7 +598,7 @@ % % \section{Setting keys} % -% \begin{function}[updated = 2015-11-07] +% \begin{function}[updated = 2017-11-14] % {\keys_set:nn, \keys_set:nV, \keys_set:nv, \keys_set:no} % \begin{syntax} % \cs{keys_set:nn} \Arg{module} \Arg{keyval list} @@ -757,7 +757,7 @@ % % \section{Utility functions for keys} % -% \begin{function}[EXP, pTF, updated = 2015-11-07]{\keys_if_exist:nn} +% \begin{function}[EXP, pTF, updated = 2017-11-14]{\keys_if_exist:nn} % \begin{syntax} % \cs{keys_if_exist_p:nn} \Arg{module} \Arg{key} \\ % \cs{keys_if_exist:nnTF} \Arg{module} \Arg{key} \Arg{true code} \Arg{false code} @@ -766,7 +766,7 @@ % has been defined for \meta{key}. % \end{function} % -% \begin{function}[added = 2011-08-21,EXP,pTF, updated = 2015-11-07] +% \begin{function}[added = 2011-08-21,EXP,pTF, updated = 2017-11-14] % {\keys_if_choice_exist:nnn} % \begin{syntax} % \cs{keys_if_choice_exist_p:nnn} \Arg{module} \Arg{key} \Arg{choice} \\ @@ -913,9 +913,7 @@ % The main function starts off by normalising category codes in package mode. % That's relatively \enquote{expensive} so is skipped (hopefully) in format % mode. We then hand off to the parser. The use of \cs{q_mark} here prevents -% loss of braces from the key argument. This particular quark is chosen as -% it fits in with \cs{__tl_trim_spaces:nn} and allows a performance enhancement -% as the token can be carried through. Notice that by passing the two +% loss of braces from the key argument. Notice that by passing the two % processor commands along the input stack we avoid the need to track these % at all. % \begin{macrocode} @@ -1043,7 +1041,9 @@ \if_meaning:w \l_@@_key_tl \c_empty_tl \exp_after:wN \@@_split_tidy:w \else: - \exp_after:wN \@@_split_value:NNw \exp_after:wN #1 \exp_after:wN #2 + \exp_after:wN \@@_split_value:NNw + \exp_after:wN #1 + \exp_after:wN #2 \exp_after:wN \q_mark \fi: } @@ -1053,7 +1053,9 @@ \cs_set:Npx \@@_action: { \exp_not:N #1 { \exp_not:o \l_@@_key_tl } } \else: - \if:w \scan_stop: \etex_detokenize:D \exp_after:wN { \use_none:n #4 } + \if:w + \scan_stop: + \__kernel_tl_to_str:w \exp_after:wN { \use_none:n #4 } \scan_stop: \@@_def:Nn \l_@@_value_tl {#3} \cs_set:Npx \@@_action: @@ -1064,14 +1066,19 @@ } \else: \cs_set:Npn \@@_action: - { \__kernel_msg_error:nn { kernel } { misplaced-equals-sign } } + { + \__kernel_msg_error:nn { kernel } + { misplaced-equals-sign } + } \fi: \fi: \@@_action: } \cs_new_protected:Npn \@@_split_tidy:w #1 \q_stop { - \if:w \scan_stop: \etex_detokenize:D \exp_after:wN { \use_none:n #1 } + \if:w + \scan_stop: + \__kernel_tl_to_str:w \exp_after:wN { \use_none:n #1 } \scan_stop: \else: \exp_after:wN \@@_empty_key: @@ -1088,15 +1095,16 @@ % \begin{macro}{\@@_def:Nn} % \begin{macro}[EXP]{\@@_def_aux:n} % \begin{macro}[EXP]{\@@_def_aux:w} -% First trim spaces off, then potentially remove a set of braces. By using -% the internal interface |\__tl_trim_spaces:nn| we can take advantage of the -% fact it needs a leading |\q_mark| in this process. The |\exp_after:wN| -% removes the quark, the delimited argument deals with any braces. +% First remove the leading quark, then trim spaces off, and finally remove +% a set of braces. % \begin{macrocode} \cs_new_protected:Npn \@@_def:Nn #1#2 - { \tl_set:Nx #1 { \__tl_trim_spaces:nn {#2} \@@_def_aux:n } } + { + \tl_set:Nx #1 + { \tl_trim_spaces_apply:oN { \use_none:n #2 } \@@_def_aux:n } + } \cs_new:Npn \@@_def_aux:n #1 - { \exp_after:wN \@@_def_aux:w #1 \q_stop } + { \@@_def_aux:w #1 \q_stop } \cs_new:Npn \@@_def_aux:w #1 \q_stop { \exp_not:n {#1} } % \end{macrocode} % \end{macro} @@ -1295,7 +1303,7 @@ { \tl_if_empty:NF \l_@@_property_tl { - \__kernel_msg_error:nnxx { kernel } { property-unknown } + \__kernel_msg_error:nnxx { kernel } { key-property-unknown } { \l_@@_property_tl } { \l_keys_path_tl } } } @@ -1314,7 +1322,8 @@ \cs_new_protected:Npn \@@_property_find:n #1 { \tl_set:Nx \l_@@_property_tl { \@@_remove_spaces:n {#1} } - \exp_after:wN \@@_property_find:w \l_@@_property_tl . . \q_stop {#1} + \exp_after:wN \@@_property_find:w \l_@@_property_tl . . + \q_stop {#1} } \cs_new_protected:Npn \@@_property_find:w #1 . #2 . #3 \q_stop #4 { @@ -1373,18 +1382,15 @@ { \use:c { \c_@@_props_root_tl \l_@@_property_tl } } { \__kernel_msg_error:nnxx { kernel } - { property-requires-value } { \l_@@_property_tl } + { key-property-requires-value } { \l_@@_property_tl } { \l_keys_path_tl } } } { \use:c { \c_@@_props_root_tl \l_@@_property_tl } {#1} } } -\use:x - { - \cs_new:Npn \exp_not:N \__keys_define_code:w - ##1 \c_colon_str ##2 \exp_not:N \q_stop - } - { \tl_if_empty:nTF {#2} } +\exp_last_unbraced:NNNNo + \cs_new:Npn \__keys_define_code:w #1 \c_colon_str #2 \q_stop + { \tl_if_empty:nTF {#2} } % \end{macrocode} % \end{macro} % \end{macro} @@ -1454,7 +1460,10 @@ { \c_@@_type_root_tl \@@_parent:o \l_keys_path_tl } { \str_if_eq_x:nnTF - { \exp_not:v { \c_@@_type_root_tl \@@_parent:o \l_keys_path_tl } } + { + \exp_not:v + { \c_@@_type_root_tl \@@_parent:o \l_keys_path_tl } + } { choice } { \__kernel_msg_error:nnxx { kernel } { nested-choice-key } @@ -1466,7 +1475,8 @@ } \cs_new_protected:Npn \@@_choice_make_aux:N #1 { - \cs_set_nopar:cpn { \c_@@_type_root_tl \l_keys_path_tl } { choice } + \cs_set_nopar:cpn { \c_@@_type_root_tl \l_keys_path_tl } + { choice } \@@_cmd_set:nn { \l_keys_path_tl } { #1 {##1} } \@@_cmd_set:nn { \l_keys_path_tl / unknown } { @@ -1495,7 +1505,8 @@ \clist_map_inline:nn {#2} { \int_incr:N \l_keys_choice_int - \@@_cmd_set:nx { \l_keys_path_tl / \@@_remove_spaces:n {##1} } + \@@_cmd_set:nx + { \l_keys_path_tl / \@@_remove_spaces:n {##1} } { \tl_set:Nn \exp_not:N \l_keys_choice_tl {##1} \int_set:Nn \exp_not:N \l_keys_choice_int @@ -1658,7 +1669,8 @@ } } { - \__kernel_msg_error:nnx { kernel } { property-boolean-values-only } + \__kernel_msg_error:nnx { kernel } + { key-property-boolean-values-only } { .value_ #1 :n } } } @@ -2332,7 +2344,8 @@ } } { - \cs_if_exist:cTF { \c_@@_code_root_tl \l_@@_module_tl / unknown } + \cs_if_exist:cTF + { \c_@@_code_root_tl \l_@@_module_tl / unknown } { \cs:w \c_@@_code_root_tl \l_@@_module_tl / unknown \exp_after:wN \cs_end: \exp_after:wN { \l_keys_value_tl } @@ -2458,7 +2471,10 @@ \exp_args:Nnf \msg_show_item_unbraced:nn { code } { \exp_args:Nc \token_get_replacement_spec:N - { \c_@@_code_root_tl \@@_remove_spaces:n { #2 / #3 } } + { + \c_@@_code_root_tl + \@@_remove_spaces:n { #2 / #3 } + } } } } @@ -2480,15 +2496,6 @@ The~key~'#1'~only~accepts~predefined~values,~ and~'#2'~is~not~one~of~these. } -\__kernel_msg_new:nnnn { kernel } { key-no-property } - { No~property~given~in~definition~of~key~'#1'. } - { - \c__msg_coding_error_text_tl - Inside~\keys_define:nn each~key~name~ - needs~a~property: \\ \\ - \iow_indent:n { #1 .<property> } \\ \\ - LaTeX~did~not~find~a~'.'~to~indicate~the~start~of~a~property. - } \__kernel_msg_new:nnnn { kernel } { key-unknown } { The~key~'#1'~is~unknown~and~is~being~ignored. } { @@ -2501,26 +2508,6 @@ The~key~'#1'~cannot~be~defined~as~a~choice~as~the~parent~key~'#2'~is~ itself~a~choice. } -\__kernel_msg_new:nnnn { kernel } { property-boolean-values-only } - { The~property~'#1'~accepts~boolean~values~only. } - { - \c__msg_coding_error_text_tl - The~property~'#1'~only~accepts~the~values~'true'~and~'false'. - } -\__kernel_msg_new:nnnn { kernel } { property-requires-value } - { The~property~'#1'~requires~a~value. } - { - \c__msg_coding_error_text_tl - LaTeX~was~asked~to~set~property~'#1'~for~key~'#2'.\\ - No~value~was~given~for~the~property,~and~one~is~required. - } -\__kernel_msg_new:nnnn { kernel } { property-unknown } - { The~key~property~'#1'~is~unknown. } - { - \c__msg_coding_error_text_tl - LaTeX~has~been~asked~to~set~the~property~'#1'~for~key~'#2':~ - this~property~is~not~defined. - } \__kernel_msg_new:nnnn { kernel } { value-forbidden } { The~key~'#1'~does~not~take~a~value. } { diff --git a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx index d5179a174ce..77431db7558 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3luatex.dtx Copyright (C) 2010-2017 The LaTeX3 Project +%% File: l3luatex.dtx Copyright (C) 2010-2018 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -29,7 +29,7 @@ % \fi % % \title{^^A -% The \pkg{l3luatex} package\\LuaTeX-specific functions^^A +% The \pkg{l3luatex} package: \LuaTeX-specific functions^^A % } % % \author{^^A @@ -41,22 +41,20 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % % \begin{documentation} % -% \section{Breaking out to \Lua{}} -% % The \LuaTeX{} engine provides access to the \Lua{} programming language, % and with it access to the \enquote{internals} of \TeX{}. In order to use % this within the framework provided here, a family of functions is -% available. When used with \pdfTeX{} or \XeTeX{} these raise an +% available. When used with \pdfTeX{}, \pTeX{}, \upTeX{} or \XeTeX{} these raise an % error: use \cs{sys_if_engine_luatex:T} to avoid this. Details on using % \Lua{} with the \LuaTeX{} engine are given in the \LuaTeX{} manual. % -% \subsection{\TeX{} code interfaces} +% \section{Breaking out to \Lua{}} % % \begin{function}[EXP, added = 2015-06-29]{\lua_now_x:n, \lua_now:n} % \begin{syntax} @@ -123,10 +121,15 @@ % \end{texnote} % \end{function} % -% \subsection{Lua interfaces} +% \section{Lua interfaces} % % As well as interfaces for \TeX{}, there are a small number of Lua functions -% provided here. Currently these are intended for internal use only. +% provided here. +% +% \begin{function}{l3kernel} +% All public interfaces provided by the module are stored within the +% |l3kernel| table. +% \end{function} % % \begin{function}{l3kernel.charcat} % \begin{syntax} @@ -151,8 +154,12 @@ % |l3kernel.filemoddate||(|\meta{file}|)| % \end{syntax} % Returns the of the date/time of last modification of the \meta{file} in the -% format |D:|\meta{year}\meta{month}\meta{day}\meta{hour}\meta{minute}^^A -% \meta{second}\meta{offset}, where the latter may be |Z| (UTC) or +% format +% \begin{quote} +% |D:|\meta{year}\meta{month}\meta{day}\meta{hour}\meta{minute}^^A +% \meta{second}\meta{offset} +% \end{quote} +% where the latter may be |Z| (UTC) or % \meta{plus-minus}\meta{hours}|'|\meta{minutes}|'|. If the \meta{file} is % not found, nothing is returned with \emph{no error raised}. % \end{function} @@ -189,6 +196,26 @@ %<*tex> % \end{macrocode} % +% \begin{macrocode} +%<@@=luatex> +% \end{macrocode} +% +% \begin{macro}[EXP]{\@@_escape_x:n, \@@_now_x:n, \@@_shipout_x:n} +% Copies of primitives. +% \begin{macrocode} +\cs_new_eq:NN \@@_escape_x:n \luatex_luaescapestring:D +\cs_new_eq:NN \@@_now_x:n \luatex_directlua:D +\cs_new_eq:NN \@@_shipout_x:n \luatex_latelua:D +% \end{macrocode} +% \end{macro} +% +% These functions are set up in \pkg{l3str} for bootstrapping: we want to +% replace them with a \enquote{proper} version at this stage, so clean up. +% \begin{macrocode} +\cs_undefine:N \lua_escape_x:n +\cs_undefine:N \lua_now_x:n +% \end{macrocode} +% % \begin{macro}[EXP]{\lua_now_x:n, \lua_now:n} % \begin{macro}{\lua_shipout_x:n, \lua_shipout:n} % \begin{macro}[EXP]{\lua_escape_x:n, \lua_escape:n} @@ -196,17 +223,21 @@ % these have to be macros, we give them the same status in all cases. % When \LuaTeX{} is not in use, simply give an error message/ % \begin{macrocode} -\cs_new:Npn \lua_now_x:n #1 { \luatex_directlua:D {#1} } +\cs_new:Npn \lua_now_x:n #1 { \@@_now_x:n {#1} } \cs_new:Npn \lua_now:n #1 { \lua_now_x:n { \exp_not:n {#1} } } -\cs_new_protected:Npn \lua_shipout_x:n #1 { \luatex_latelua:D {#1} } +\cs_new_protected:Npn \lua_shipout_x:n #1 { \@@_shiphout_x:n {#1} } \cs_new_protected:Npn \lua_shipout:n #1 { \lua_shipout_x:n { \exp_not:n {#1} } } -\cs_new:Npn \lua_escape_x:n #1 { \luatex_luaescapestring:D {#1} } +\cs_new:Npn \lua_escape_x:n #1 { \@@_escape_x:n {#1} } \cs_new:Npn \lua_escape:n #1 { \lua_escape_x:n { \exp_not:n {#1} } } \sys_if_engine_luatex:F { \clist_map_inline:nn - { \lua_now_x:n , \lua_now:n , \lua_escape_x:n , \lua_escape:n } + { + \use_x:n , + \lua_escape_x:n , \lua_escape:n , + \lua_now_x:n , \lua_now:n + } { \cs_set:Npn #1 ##1 { @@ -292,7 +323,7 @@ local write = tex.write local utf8_char = unicode.utf8.char % \end{macrocode} % -% \begin{macro}{escapehex} +% \begin{macro}[int]{escapehex} % An internal auxiliary to convert a string to the matching hex escape. % This works on a byte basis: extension to handled UTF-8 input is % covered in \pkg{pdftexcmds} but is not currently required here. @@ -432,13 +463,17 @@ l3kernel.strcmp = strcmp %<*initex> % \end{macrocode} % +% \begin{macrocode} +%<@@=alloc> +% \end{macrocode} +% % A small amount of generic code is used by almost all \LuaTeX{} material so % needs to be loaded by the format. % \begin{macrocode} -attribute_count_name = "g__alloc_attribute_int" -bytecode_count_name = "g__alloc_bytecode_int" -chunkname_count_name = "g__alloc_chunkname_int" -whatsit_count_name = "g__alloc_whatsit_int" +attribute_count_name = "g_@@_attribute_int" +bytecode_count_name = "g_@@_bytecode_int" +chunkname_count_name = "g_@@_chunkname_int" +whatsit_count_name = "g_@@_whatsit_int" require("ltluatex") % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx index 2314178cf11..c73c38da8ab 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -524,174 +524,6 @@ % documentation for the latter should be consulted for full details. % \end{function} % -% \section{Kernel-specific functions} -% -% Messages from \LaTeX3 itself are handled by the general message system, -% but have their own functions. This allows some text to be pre-defined, -% and also ensures that serious errors can be handled properly. -% -% \begin{function}[added = 2017-12-17] -% {\__kernel_msg_new:nnnn, \__kernel_msg_new:nnn} -% \begin{syntax} -% \cs{__kernel_msg_new:nnnn} \Arg{module} \Arg{message} \Arg{text} \Arg{more text} -% \end{syntax} -% Creates a kernel \meta{message} for a given \meta{module}. -% The message is defined to first give \meta{text} and then -% \meta{more text} if the user requests it. If no \meta{more text} is -% available then a standard text is given instead. Within \meta{text} -% and \meta{more text} four parameters (|#1| to |#4|) can be used: -% these will be supplied and expanded at the time the message is used. -% An error is raised if the \meta{message} already exists. -% \end{function} -% -% \begin{function}[added = 2017-12-17] -% {\__kernel_msg_set:nnnn, \__kernel_msg_set:nnn} -% \begin{syntax} -% \cs{__kernel_msg_set:nnnn} \Arg{module} \Arg{message} \Arg{text} \Arg{more text} -% \end{syntax} -% Sets up the text for a kernel \meta{message} for a given \meta{module}. -% The message is defined to first give \meta{text} and then -% \meta{more text} if the user requests it. If no \meta{more text} is -% available then a standard text is given instead. Within \meta{text} -% and \meta{more text} four parameters (|#1| to |#4|) can be used: -% these will be supplied and expanded at the time the message is used. -% \end{function} -% -% \begin{function}[added = 2017-12-17] -% { -% \__kernel_msg_fatal:nnnnnn , -% \__kernel_msg_fatal:nnnnn , -% \__kernel_msg_fatal:nnnn , -% \__kernel_msg_fatal:nnn , -% \__kernel_msg_fatal:nn , -% \__kernel_msg_fatal:nnxxxx , -% \__kernel_msg_fatal:nnxxx , -% \__kernel_msg_fatal:nnxx , -% \__kernel_msg_fatal:nnx -% } -% \begin{syntax} -% \cs{__kernel_msg_fatal:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four} -% \end{syntax} -% Issues kernel \meta{module} error \meta{message}, passing \meta{arg one} -% to \meta{arg four} to the text-creating functions. After issuing a -% fatal error the \TeX{} run halts. Cannot be redirected. -% \end{function} -% -% \begin{function}[added = 2017-12-17] -% { -% \__kernel_msg_error:nnnnnn , -% \__kernel_msg_error:nnnnn , -% \__kernel_msg_error:nnnn , -% \__kernel_msg_error:nnn , -% \__kernel_msg_error:nn , -% \__kernel_msg_error:nnxxxx , -% \__kernel_msg_error:nnxxx , -% \__kernel_msg_error:nnxx , -% \__kernel_msg_error:nnx -% } -% \begin{syntax} -% \cs{__kernel_msg_error:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four} -% \end{syntax} -% Issues kernel \meta{module} error \meta{message}, passing \meta{arg one} -% to -% \meta{arg four} to the text-creating functions. The error -% stops processing and issues the text at the terminal. After user input, -% the run continues. Cannot be redirected. -% \end{function} -% -% \begin{function}[added = 2017-12-17] -% { -% \__kernel_msg_warning:nnnnnn , -% \__kernel_msg_warning:nnnnn , -% \__kernel_msg_warning:nnnn , -% \__kernel_msg_warning:nnn , -% \__kernel_msg_warning:nn , -% \__kernel_msg_warning:nnxxxx , -% \__kernel_msg_warning:nnxxx , -% \__kernel_msg_warning:nnxx , -% \__kernel_msg_warning:nnx -% } -% \begin{syntax} -% \cs{__kernel_msg_warning:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four} -% \end{syntax} -% Issues kernel \meta{module} warning \meta{message}, passing -% \meta{arg one} to -% \meta{arg four} to the text-creating functions. The warning text -% is added to the log file, but the \TeX{} run is not interrupted. -% \end{function} -% -% \begin{function}[added = 2017-12-17] -% { -% \__kernel_msg_info:nnnnnn , -% \__kernel_msg_info:nnnnn , -% \__kernel_msg_info:nnnn , -% \__kernel_msg_info:nnn , -% \__kernel_msg_info:nn , -% \__kernel_msg_info:nnxxxx , -% \__kernel_msg_info:nnxxx , -% \__kernel_msg_info:nnxx , -% \__kernel_msg_info:nnx -% } -% \begin{syntax} -% \cs{__kernel_msg_info:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four} -% \end{syntax} -% Issues kernel \meta{module} information \meta{message}, passing -% \meta{arg one} to \meta{arg four} to the text-creating functions. -% The information text is added to the log file. -% \end{function} -% -% \section{Expandable errors} -% -% In a few places, the \LaTeX3 kernel needs to produce errors in an -% expansion only context. This must be handled internally very -% differently from normal error messages, as none of the tools -% to print to the terminal or the log file are expandable. -% However, the interface is similar, with the important caveat that the -% message text and arguments are not expanded, and messages should be -% very short. -% -% \begin{function}[EXP, added = 2017-12-17] -% { -% \__kernel_msg_expandable_error:nnnnnn, -% \__kernel_msg_expandable_error:nnnnn, -% \__kernel_msg_expandable_error:nnnn, -% \__kernel_msg_expandable_error:nnn, -% \__kernel_msg_expandable_error:nn -% } -% \begin{syntax} -% \cs{__kernel_msg_expandable_error:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four} -% \end{syntax} -% Issues an error, passing \meta{arg one} to \meta{arg four} -% to the text-creating functions. The resulting string must -% be much shorter than a line, otherwise it is cropped. -% \end{function} -% -% \begin{function}[EXP, added = 2011-08-11, updated = 2011-08-13] -% {\__msg_expandable_error:n} -% \begin{syntax} -% \cs{__msg_expandable_error:n} \Arg{error message} -% \end{syntax} -% Issues an \enquote{Undefined error} message from \TeX{} itself, -% and prints the \meta{error message}. The \meta{error message} -% must be short: it is cropped at the end of one line. -% \begin{texnote} -% This function expands to an empty token list after two steps. -% Tokens inserted in response to \TeX{}'s prompt are read with -% the current category code setting, and inserted just after -% the place where the error message was issued. -% \end{texnote} -% \end{function} -% -% \section{Internal \pkg{l3msg} functions} -% -% \begin{variable}{\c__msg_coding_error_text_tl} -% The text -% \begin{verbatim} -% This is a coding error. -% \end{verbatim} -% used by kernel functions when erroneous programming input is encountered. -% \end{variable} -% % \end{documentation} % % \begin{implementation} @@ -747,13 +579,16 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\__chk_if_free_msg:nn} -% This auxiliary is similar to \cs{__chk_if_free_cs:N}, and is used when +% \begin{macro}{\@@_chk_if_free:nn} +% This auxiliary is similar to \cs{__kernel_chk_if_free_cs:N}, and is used when % defining messages with \cs{msg_new:nnnn}. % \begin{macrocode} \__kernel_patch:nnNNpn { } - { \__kernel_debug_log:x { Defining~message~ #1 / #2 ~\msg_line_context: } } -\cs_new_protected:Npn \__chk_if_free_msg:nn #1#2 + { + \__kernel_debug_log:x + { Defining~message~ #1 / #2 ~\msg_line_context: } + } +\cs_new_protected:Npn \@@_chk_free:nn #1#2 { \msg_if_exist:nnT {#1} {#2} { @@ -772,7 +607,7 @@ % \begin{macrocode} \cs_new_protected:Npn \msg_new:nnnn #1#2 { - \__chk_if_free_msg:nn {#1} {#2} + \@@_chk_free:nn {#1} {#2} \msg_gset:nnnn {#1} {#2} } \cs_new_protected:Npn \msg_new:nnn #1#2#3 @@ -932,7 +767,7 @@ % inserted by typing |I| in the command-line are inserted after % the message is entirely cleaned up. % -% The \cs{__iow_with:Nnn} auxiliary, defined in \pkg{l3file}, expects +% The \cs{__kernel_iow_with:Nnn} auxiliary, defined in \pkg{l3file}, expects % an \meta{integer variable}, an integer \meta{value}, and some % \meta{code}. It runs the \meta{code} after ensuring that the % \meta{integer variable} takes the given \meta{value}, then restores @@ -961,9 +796,9 @@ \iow_newline: ! } - \__iow_with:Nnn \tex_newlinechar:D { `\^^J } + \__kernel_iow_with:Nnn \tex_newlinechar:D { `\^^J } { - \__iow_with:Nnn \tex_errorcontextlines:D { -1 } + \__kernel_iow_with:Nnn \tex_errorcontextlines:D { -1 } { \group_begin: \cs_set_protected:Npn & @@ -1316,7 +1151,7 @@ % \msg_show:nnxx , % \msg_show:nnx % } -% \begin{macro}[aux]{\@@_show:n, \@@_show:w, \@@_show_dot:w, \@@_show:nn} +% \begin{macro}{\@@_show:n, \@@_show:w, \@@_show_dot:w, \@@_show:nn} % The \texttt{show} message type is used for \cs{seq_show:N} and % similar complicated data structures. Wrap the given text with a % trailing dot (important later) then pass it to \cs{@@_show:n}. If @@ -1353,9 +1188,9 @@ \tl_if_empty:nF {#1} { \exp_args:No \iow_term:n { \use_none:n #1 } } \tl_set:Nn \l_@@_internal_tl {#2} - \__iow_with:Nnn \tex_newlinechar:D { 10 } + \__kernel_iow_with:Nnn \tex_newlinechar:D { 10 } { - \__iow_with:Nnn \tex_errorcontextlines:D { -1 } + \__kernel_iow_with:Nnn \tex_errorcontextlines:D { -1 } { \etex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN { \exp_after:wN \l_@@_internal_tl } @@ -1400,8 +1235,8 @@ % \end{variable} % % \begin{variable}{\l_@@_hierarchy_seq} -% During redirection, split the message name into a sequence with -% items |{/module/submodule}|, |{/module}|, and |{}|. +% During redirection, split the message name into a sequence: +% |{/module/submodule}|, |{/module}|, and |{}|. % \begin{macrocode} \seq_new:N \l_@@_hierarchy_seq % \end{macrocode} @@ -1426,9 +1261,13 @@ % assignment to \cs{@@_use_code:} is similar to \cs{tl_set:Nn}. % The message is eventually produced with whatever \cs{l_@@_class_tl} % is when \cs{@@_use_code:} is called. +% Here is also a good place to suppress tracing output if the +% \pkg{trace} package is loaded since all (non-expandable) messages go +% through this auxiliary. % \begin{macrocode} \cs_new_protected:Npn \@@_use:nnnnnnn #1#2#3#4#5#6#7 { +%<package> \use:c { conditionally@traceoff } \msg_if_exist:nnTF {#2} {#3} { \@@_class_chk_exist:nT {#1} @@ -1446,12 +1285,14 @@ } } { \__kernel_msg_error:nnxx { kernel } { message-unknown } {#2} {#3} } +%<package> \use:c { conditionally@traceon } } \cs_new_protected:Npn \@@_use_code: { } % \end{macrocode} % The first check is for a individual message redirection. If this % applies then no further redirection is attempted. Otherwise, split -% the message name into \texttt{module/submodule/message} (with an +% the message name into \meta{module}, \meta{submodule} and \meta{message} +% (with an % arbitrary number of slashes), and store |{/module/submodule}|, % |{/module}| and |{}| into \cs{l_@@_hierarchy_seq}. We then % map through this sequence, applying the most specific redirection. @@ -1793,7 +1634,8 @@ } % \end{macrocode} % -% Messages for earlier kernel modules. +% Messages for earlier kernel modules plus a few for \pkg{l3keys} which +% cover coding errors. % \begin{macrocode} \__kernel_msg_new:nnnn { kernel } { bad-number-of-arguments } { Function~'#1'~cannot~be~defined~with~#2~arguments. } @@ -1885,6 +1727,8 @@ LaTeX~has~been~asked~to~define~'#1'~as~a~protected~predicate.~ Only~expandable~tests~can~have~a~predicate~version. } +\__kernel_msg_new:nnn { kernel } { randint-backward-range } + { Bounds~ordered~backwards~in~\int_rand:nn {#1}~{#2}. } \__kernel_msg_new:nnnn { kernel } { conditional-form-unknown } { Conditional~form~'#1'~for~function~'#2'~unknown. } { @@ -1892,6 +1736,35 @@ LaTeX~has~been~asked~to~define~the~conditional~form~'#1'~of~ the~function~'#2',~but~only~'TF',~'T',~'F',~and~'p'~forms~exist. } +\__kernel_msg_new:nnnn { kernel } { key-no-property } + { No~property~given~in~definition~of~key~'#1'. } + { + \c_@@_coding_error_text_tl + Inside~\keys_define:nn each~key~name~ + needs~a~property: \\ \\ + \iow_indent:n { #1 .<property> } \\ \\ + LaTeX~did~not~find~a~'.'~to~indicate~the~start~of~a~property. + } +\__kernel_msg_new:nnnn { kernel } { key-property-boolean-values-only } + { The~property~'#1'~accepts~boolean~values~only. } + { + \c_@@_coding_error_text_tl + The~property~'#1'~only~accepts~the~values~'true'~and~'false'. + } +\__kernel_msg_new:nnnn { kernel } { key-property-requires-value } + { The~property~'#1'~requires~a~value. } + { + \c_@@_coding_error_text_tl + LaTeX~was~asked~to~set~property~'#1'~for~key~'#2'.\\ + No~value~was~given~for~the~property,~and~one~is~required. + } +\__kernel_msg_new:nnnn { kernel } { key-property-unknown } + { The~key~property~'#1'~is~unknown. } + { + \c_@@_coding_error_text_tl + LaTeX~has~been~asked~to~set~the~property~'#1'~for~key~'#2':~ + this~property~is~not~defined. + } \__kernel_msg_new:nnnn { kernel } { scanmark-already-defined } { Scan~mark~#1~already~defined. } { @@ -1922,6 +1795,14 @@ with~a~signature~starting~with~'#1',~but~cannot~change~an~argument~ from~type~'#3'~to~type~'#4'. } +\__kernel_msg_new:nnnn { kernel } { invalid-exp-args } + { Invalid~variant~specifier~'#1'~in~'#2'. } + { + \c_@@_coding_error_text_tl + LaTeX~has~been~asked~to~create~an~\iow_char:N\\exp_args:N...~ + function~with~signature~'N#2'~but~'#1'~is~not~a~valid~argument~ + specifier. + } \__kernel_msg_new:nnn { kernel } { deprecated-variant } { Variant~form~'#1'~deprecated~for~base~form~'#2'.~ @@ -1941,7 +1822,7 @@ % In format mode the error is somewhat different. % \begin{macrocode} %<*package> -\bool_if:NTF \l@expl@enable@debug@bool +\__kernel_if_debug:TF { \__kernel_msg_new:nnnn { kernel } { debug } { The~debugging~option~'#1'~does~not~exist~\msg_line_context:. } @@ -1955,14 +1836,19 @@ { Inconsistent~local/global~assignment } { \c_@@_coding_error_text_tl - \if:w l #2 Local \else: Global \fi: \ + \if:w l #2 Local \else: Global \fi: \ % assignment~to~a~ - \if:w l #1 local \else: \if:w g #1 global \else: constant \fi: \fi: \ + \if:w l #1 local + \else: + \if:w g #1 global \else: constant \fi: + \fi: + \ % variable~'#3'. } \__kernel_msg_new:nnnn { kernel } { non-declared-variable } { The~variable~#1~has~not~been~declared~\msg_line_context:. } { + \c_@@_coding_error_text_tl Checking~is~active,~and~you~have~tried~do~so~something~like: \\ \ \ \tl_set:Nn ~ #1 ~ \{ ~ ... ~ \} \\ without~first~having: \\ @@ -2103,10 +1989,14 @@ % \__kernel_msg_expandable_error:nnnnn, % \__kernel_msg_expandable_error:nnnn, % \__kernel_msg_expandable_error:nnn, -% \__kernel_msg_expandable_error:nn +% \__kernel_msg_expandable_error:nn, +% \__kernel_msg_expandable_error:nnffff, +% \__kernel_msg_expandable_error:nnfff, +% \__kernel_msg_expandable_error:nnff, +% \__kernel_msg_expandable_error:nnf, % } % The command built from the csname -% |\c_@@_text_prefix_tl LaTeX / #1 / #2| +% \cs{c_@@_text_prefix_tl} |LaTeX / #1 / #2| % takes four arguments and builds the error text, which is fed to % \cs{@@_expandable_error:n}. % \begin{macrocode} @@ -2139,6 +2029,10 @@ \__kernel_msg_expandable_error:nnnnnn {#1} {#2} { } { } { } { } } +\cs_generate_variant:Nn \__kernel_msg_expandable_error:nnnnnn { nnffff } +\cs_generate_variant:Nn \__kernel_msg_expandable_error:nnnnn { nnfff } +\cs_generate_variant:Nn \__kernel_msg_expandable_error:nnnn { nnff } +\cs_generate_variant:Nn \__kernel_msg_expandable_error:nnn { nnf } % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx index 80e862d5d2f..576ba968f6d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -71,8 +71,8 @@ % \item[{\cs[no-index]{xetex_\ldots}}] Introduced by \XeTeX{}; % \item[{\cs[no-index]{luatex_\ldots}}] Introduced by \LuaTeX{}; % \item[{\cs[no-index]{utex_\ldots}}] Introduced by \XeTeX{} and \LuaTeX{}; -% \item[{\cs[no-index]{ptex_\ldots}}] Introduced by p\TeX{}; -% \item[{\cs[no-index]{uptex_\ldots}}] Introduced by up\TeX{}. +% \item[{\cs[no-index]{ptex_\ldots}}] Introduced by \pTeX{}; +% \item[{\cs[no-index]{uptex_\ldots}}] Introduced by \upTeX{}. % \end{itemize} % % \end{documentation} @@ -95,12 +95,6 @@ % names. In format mode, it also deletes all of the existing names (although % some do come back later). % -% \begin{macro}{\tex_undefined:D} -% This function does not exist at all, but is the name used by the -% plain \TeX{} format for an undefined function. So it should -% be marked here as \enquote{taken}. -% \end{macro} -% % The \tn{let} primitive is renamed by hand first as it is essential for % the entire process to follow. This also uses \tn{global}, as that way % we avoid leaving an unneeded csname in the hash table. @@ -141,406 +135,407 @@ % These are given modified new names, so that they may be entered % without catcode tricks. % \begin{macrocode} - \@@_primitive:NN \ \tex_space:D - \@@_primitive:NN \/ \tex_italiccorrection:D - \@@_primitive:NN \- \tex_hyphen:D + \@@_primitive:NN \ \tex_space:D + \@@_primitive:NN \/ \tex_italiccorrection:D + \@@_primitive:NN \- \tex_hyphen:D % \end{macrocode} % % Now all the other primitives. % \begin{macrocode} - \@@_primitive:NN \above \tex_above:D - \@@_primitive:NN \abovedisplayshortskip \tex_abovedisplayshortskip:D - \@@_primitive:NN \abovedisplayskip \tex_abovedisplayskip:D - \@@_primitive:NN \abovewithdelims \tex_abovewithdelims:D - \@@_primitive:NN \accent \tex_accent:D - \@@_primitive:NN \adjdemerits \tex_adjdemerits:D - \@@_primitive:NN \advance \tex_advance:D - \@@_primitive:NN \afterassignment \tex_afterassignment:D - \@@_primitive:NN \aftergroup \tex_aftergroup:D - \@@_primitive:NN \atop \tex_atop:D - \@@_primitive:NN \atopwithdelims \tex_atopwithdelims:D - \@@_primitive:NN \badness \tex_badness:D - \@@_primitive:NN \baselineskip \tex_baselineskip:D - \@@_primitive:NN \batchmode \tex_batchmode:D - \@@_primitive:NN \begingroup \tex_begingroup:D - \@@_primitive:NN \belowdisplayshortskip \tex_belowdisplayshortskip:D - \@@_primitive:NN \belowdisplayskip \tex_belowdisplayskip:D - \@@_primitive:NN \binoppenalty \tex_binoppenalty:D - \@@_primitive:NN \botmark \tex_botmark:D - \@@_primitive:NN \box \tex_box:D - \@@_primitive:NN \boxmaxdepth \tex_boxmaxdepth:D - \@@_primitive:NN \brokenpenalty \tex_brokenpenalty:D - \@@_primitive:NN \catcode \tex_catcode:D - \@@_primitive:NN \char \tex_char:D - \@@_primitive:NN \chardef \tex_chardef:D - \@@_primitive:NN \cleaders \tex_cleaders:D - \@@_primitive:NN \closein \tex_closein:D - \@@_primitive:NN \closeout \tex_closeout:D - \@@_primitive:NN \clubpenalty \tex_clubpenalty:D - \@@_primitive:NN \copy \tex_copy:D - \@@_primitive:NN \count \tex_count:D - \@@_primitive:NN \countdef \tex_countdef:D - \@@_primitive:NN \cr \tex_cr:D - \@@_primitive:NN \crcr \tex_crcr:D - \@@_primitive:NN \csname \tex_csname:D - \@@_primitive:NN \day \tex_day:D - \@@_primitive:NN \deadcycles \tex_deadcycles:D - \@@_primitive:NN \def \tex_def:D - \@@_primitive:NN \defaulthyphenchar \tex_defaulthyphenchar:D - \@@_primitive:NN \defaultskewchar \tex_defaultskewchar:D - \@@_primitive:NN \delcode \tex_delcode:D - \@@_primitive:NN \delimiter \tex_delimiter:D - \@@_primitive:NN \delimiterfactor \tex_delimiterfactor:D - \@@_primitive:NN \delimitershortfall \tex_delimitershortfall:D - \@@_primitive:NN \dimen \tex_dimen:D - \@@_primitive:NN \dimendef \tex_dimendef:D - \@@_primitive:NN \discretionary \tex_discretionary:D - \@@_primitive:NN \displayindent \tex_displayindent:D - \@@_primitive:NN \displaylimits \tex_displaylimits:D - \@@_primitive:NN \displaystyle \tex_displaystyle:D - \@@_primitive:NN \displaywidowpenalty \tex_displaywidowpenalty:D - \@@_primitive:NN \displaywidth \tex_displaywidth:D - \@@_primitive:NN \divide \tex_divide:D - \@@_primitive:NN \doublehyphendemerits \tex_doublehyphendemerits:D - \@@_primitive:NN \dp \tex_dp:D - \@@_primitive:NN \dump \tex_dump:D - \@@_primitive:NN \edef \tex_edef:D - \@@_primitive:NN \else \tex_else:D - \@@_primitive:NN \emergencystretch \tex_emergencystretch:D - \@@_primitive:NN \end \tex_end:D - \@@_primitive:NN \endcsname \tex_endcsname:D - \@@_primitive:NN \endgroup \tex_endgroup:D - \@@_primitive:NN \endinput \tex_endinput:D - \@@_primitive:NN \endlinechar \tex_endlinechar:D - \@@_primitive:NN \eqno \tex_eqno:D - \@@_primitive:NN \errhelp \tex_errhelp:D - \@@_primitive:NN \errmessage \tex_errmessage:D - \@@_primitive:NN \errorcontextlines \tex_errorcontextlines:D - \@@_primitive:NN \errorstopmode \tex_errorstopmode:D - \@@_primitive:NN \escapechar \tex_escapechar:D - \@@_primitive:NN \everycr \tex_everycr:D - \@@_primitive:NN \everydisplay \tex_everydisplay:D - \@@_primitive:NN \everyhbox \tex_everyhbox:D - \@@_primitive:NN \everyjob \tex_everyjob:D - \@@_primitive:NN \everymath \tex_everymath:D - \@@_primitive:NN \everypar \tex_everypar:D - \@@_primitive:NN \everyvbox \tex_everyvbox:D - \@@_primitive:NN \exhyphenpenalty \tex_exhyphenpenalty:D - \@@_primitive:NN \expandafter \tex_expandafter:D - \@@_primitive:NN \fam \tex_fam:D - \@@_primitive:NN \fi \tex_fi:D - \@@_primitive:NN \finalhyphendemerits \tex_finalhyphendemerits:D - \@@_primitive:NN \firstmark \tex_firstmark:D - \@@_primitive:NN \floatingpenalty \tex_floatingpenalty:D - \@@_primitive:NN \font \tex_font:D - \@@_primitive:NN \fontdimen \tex_fontdimen:D - \@@_primitive:NN \fontname \tex_fontname:D - \@@_primitive:NN \futurelet \tex_futurelet:D - \@@_primitive:NN \gdef \tex_gdef:D - \@@_primitive:NN \global \tex_global:D - \@@_primitive:NN \globaldefs \tex_globaldefs:D - \@@_primitive:NN \halign \tex_halign:D - \@@_primitive:NN \hangafter \tex_hangafter:D - \@@_primitive:NN \hangindent \tex_hangindent:D - \@@_primitive:NN \hbadness \tex_hbadness:D - \@@_primitive:NN \hbox \tex_hbox:D - \@@_primitive:NN \hfil \tex_hfil:D - \@@_primitive:NN \hfill \tex_hfill:D - \@@_primitive:NN \hfilneg \tex_hfilneg:D - \@@_primitive:NN \hfuzz \tex_hfuzz:D - \@@_primitive:NN \hoffset \tex_hoffset:D - \@@_primitive:NN \holdinginserts \tex_holdinginserts:D - \@@_primitive:NN \hrule \tex_hrule:D - \@@_primitive:NN \hsize \tex_hsize:D - \@@_primitive:NN \hskip \tex_hskip:D - \@@_primitive:NN \hss \tex_hss:D - \@@_primitive:NN \ht \tex_ht:D - \@@_primitive:NN \hyphenation \tex_hyphenation:D - \@@_primitive:NN \hyphenchar \tex_hyphenchar:D - \@@_primitive:NN \hyphenpenalty \tex_hyphenpenalty:D - \@@_primitive:NN \if \tex_if:D - \@@_primitive:NN \ifcase \tex_ifcase:D - \@@_primitive:NN \ifcat \tex_ifcat:D - \@@_primitive:NN \ifdim \tex_ifdim:D - \@@_primitive:NN \ifeof \tex_ifeof:D - \@@_primitive:NN \iffalse \tex_iffalse:D - \@@_primitive:NN \ifhbox \tex_ifhbox:D - \@@_primitive:NN \ifhmode \tex_ifhmode:D - \@@_primitive:NN \ifinner \tex_ifinner:D - \@@_primitive:NN \ifmmode \tex_ifmmode:D - \@@_primitive:NN \ifnum \tex_ifnum:D - \@@_primitive:NN \ifodd \tex_ifodd:D - \@@_primitive:NN \iftrue \tex_iftrue:D - \@@_primitive:NN \ifvbox \tex_ifvbox:D - \@@_primitive:NN \ifvmode \tex_ifvmode:D - \@@_primitive:NN \ifvoid \tex_ifvoid:D - \@@_primitive:NN \ifx \tex_ifx:D - \@@_primitive:NN \ignorespaces \tex_ignorespaces:D - \@@_primitive:NN \immediate \tex_immediate:D - \@@_primitive:NN \indent \tex_indent:D - \@@_primitive:NN \input \tex_input:D - \@@_primitive:NN \inputlineno \tex_inputlineno:D - \@@_primitive:NN \insert \tex_insert:D - \@@_primitive:NN \insertpenalties \tex_insertpenalties:D - \@@_primitive:NN \interlinepenalty \tex_interlinepenalty:D - \@@_primitive:NN \jobname \tex_jobname:D - \@@_primitive:NN \kern \tex_kern:D - \@@_primitive:NN \language \tex_language:D - \@@_primitive:NN \lastbox \tex_lastbox:D - \@@_primitive:NN \lastkern \tex_lastkern:D - \@@_primitive:NN \lastpenalty \tex_lastpenalty:D - \@@_primitive:NN \lastskip \tex_lastskip:D - \@@_primitive:NN \lccode \tex_lccode:D - \@@_primitive:NN \leaders \tex_leaders:D - \@@_primitive:NN \left \tex_left:D - \@@_primitive:NN \lefthyphenmin \tex_lefthyphenmin:D - \@@_primitive:NN \leftskip \tex_leftskip:D - \@@_primitive:NN \leqno \tex_leqno:D - \@@_primitive:NN \let \tex_let:D - \@@_primitive:NN \limits \tex_limits:D - \@@_primitive:NN \linepenalty \tex_linepenalty:D - \@@_primitive:NN \lineskip \tex_lineskip:D - \@@_primitive:NN \lineskiplimit \tex_lineskiplimit:D - \@@_primitive:NN \long \tex_long:D - \@@_primitive:NN \looseness \tex_looseness:D - \@@_primitive:NN \lower \tex_lower:D - \@@_primitive:NN \lowercase \tex_lowercase:D - \@@_primitive:NN \mag \tex_mag:D - \@@_primitive:NN \mark \tex_mark:D - \@@_primitive:NN \mathaccent \tex_mathaccent:D - \@@_primitive:NN \mathbin \tex_mathbin:D - \@@_primitive:NN \mathchar \tex_mathchar:D - \@@_primitive:NN \mathchardef \tex_mathchardef:D - \@@_primitive:NN \mathchoice \tex_mathchoice:D - \@@_primitive:NN \mathclose \tex_mathclose:D - \@@_primitive:NN \mathcode \tex_mathcode:D - \@@_primitive:NN \mathinner \tex_mathinner:D - \@@_primitive:NN \mathop \tex_mathop:D - \@@_primitive:NN \mathopen \tex_mathopen:D - \@@_primitive:NN \mathord \tex_mathord:D - \@@_primitive:NN \mathpunct \tex_mathpunct:D - \@@_primitive:NN \mathrel \tex_mathrel:D - \@@_primitive:NN \mathsurround \tex_mathsurround:D - \@@_primitive:NN \maxdeadcycles \tex_maxdeadcycles:D - \@@_primitive:NN \maxdepth \tex_maxdepth:D - \@@_primitive:NN \meaning \tex_meaning:D - \@@_primitive:NN \medmuskip \tex_medmuskip:D - \@@_primitive:NN \message \tex_message:D - \@@_primitive:NN \mkern \tex_mkern:D - \@@_primitive:NN \month \tex_month:D - \@@_primitive:NN \moveleft \tex_moveleft:D - \@@_primitive:NN \moveright \tex_moveright:D - \@@_primitive:NN \mskip \tex_mskip:D - \@@_primitive:NN \multiply \tex_multiply:D - \@@_primitive:NN \muskip \tex_muskip:D - \@@_primitive:NN \muskipdef \tex_muskipdef:D - \@@_primitive:NN \newlinechar \tex_newlinechar:D - \@@_primitive:NN \noalign \tex_noalign:D - \@@_primitive:NN \noboundary \tex_noboundary:D - \@@_primitive:NN \noexpand \tex_noexpand:D - \@@_primitive:NN \noindent \tex_noindent:D - \@@_primitive:NN \nolimits \tex_nolimits:D - \@@_primitive:NN \nonscript \tex_nonscript:D - \@@_primitive:NN \nonstopmode \tex_nonstopmode:D - \@@_primitive:NN \nulldelimiterspace \tex_nulldelimiterspace:D - \@@_primitive:NN \nullfont \tex_nullfont:D - \@@_primitive:NN \number \tex_number:D - \@@_primitive:NN \omit \tex_omit:D - \@@_primitive:NN \openin \tex_openin:D - \@@_primitive:NN \openout \tex_openout:D - \@@_primitive:NN \or \tex_or:D - \@@_primitive:NN \outer \tex_outer:D - \@@_primitive:NN \output \tex_output:D - \@@_primitive:NN \outputpenalty \tex_outputpenalty:D - \@@_primitive:NN \over \tex_over:D - \@@_primitive:NN \overfullrule \tex_overfullrule:D - \@@_primitive:NN \overline \tex_overline:D - \@@_primitive:NN \overwithdelims \tex_overwithdelims:D - \@@_primitive:NN \pagedepth \tex_pagedepth:D - \@@_primitive:NN \pagefilllstretch \tex_pagefilllstretch:D - \@@_primitive:NN \pagefillstretch \tex_pagefillstretch:D - \@@_primitive:NN \pagefilstretch \tex_pagefilstretch:D - \@@_primitive:NN \pagegoal \tex_pagegoal:D - \@@_primitive:NN \pageshrink \tex_pageshrink:D - \@@_primitive:NN \pagestretch \tex_pagestretch:D - \@@_primitive:NN \pagetotal \tex_pagetotal:D - \@@_primitive:NN \par \tex_par:D - \@@_primitive:NN \parfillskip \tex_parfillskip:D - \@@_primitive:NN \parindent \tex_parindent:D - \@@_primitive:NN \parshape \tex_parshape:D - \@@_primitive:NN \parskip \tex_parskip:D - \@@_primitive:NN \patterns \tex_patterns:D - \@@_primitive:NN \pausing \tex_pausing:D - \@@_primitive:NN \penalty \tex_penalty:D - \@@_primitive:NN \postdisplaypenalty \tex_postdisplaypenalty:D - \@@_primitive:NN \predisplaypenalty \tex_predisplaypenalty:D - \@@_primitive:NN \predisplaysize \tex_predisplaysize:D - \@@_primitive:NN \pretolerance \tex_pretolerance:D - \@@_primitive:NN \prevdepth \tex_prevdepth:D - \@@_primitive:NN \prevgraf \tex_prevgraf:D - \@@_primitive:NN \radical \tex_radical:D - \@@_primitive:NN \raise \tex_raise:D - \@@_primitive:NN \read \tex_read:D - \@@_primitive:NN \relax \tex_relax:D - \@@_primitive:NN \relpenalty \tex_relpenalty:D - \@@_primitive:NN \right \tex_right:D - \@@_primitive:NN \righthyphenmin \tex_righthyphenmin:D - \@@_primitive:NN \rightskip \tex_rightskip:D - \@@_primitive:NN \romannumeral \tex_romannumeral:D - \@@_primitive:NN \scriptfont \tex_scriptfont:D - \@@_primitive:NN \scriptscriptfont \tex_scriptscriptfont:D - \@@_primitive:NN \scriptscriptstyle \tex_scriptscriptstyle:D - \@@_primitive:NN \scriptspace \tex_scriptspace:D - \@@_primitive:NN \scriptstyle \tex_scriptstyle:D - \@@_primitive:NN \scrollmode \tex_scrollmode:D - \@@_primitive:NN \setbox \tex_setbox:D - \@@_primitive:NN \setlanguage \tex_setlanguage:D - \@@_primitive:NN \sfcode \tex_sfcode:D - \@@_primitive:NN \shipout \tex_shipout:D - \@@_primitive:NN \show \tex_show:D - \@@_primitive:NN \showbox \tex_showbox:D - \@@_primitive:NN \showboxbreadth \tex_showboxbreadth:D - \@@_primitive:NN \showboxdepth \tex_showboxdepth:D - \@@_primitive:NN \showlists \tex_showlists:D - \@@_primitive:NN \showthe \tex_showthe:D - \@@_primitive:NN \skewchar \tex_skewchar:D - \@@_primitive:NN \skip \tex_skip:D - \@@_primitive:NN \skipdef \tex_skipdef:D - \@@_primitive:NN \spacefactor \tex_spacefactor:D - \@@_primitive:NN \spaceskip \tex_spaceskip:D - \@@_primitive:NN \span \tex_span:D - \@@_primitive:NN \special \tex_special:D - \@@_primitive:NN \splitbotmark \tex_splitbotmark:D - \@@_primitive:NN \splitfirstmark \tex_splitfirstmark:D - \@@_primitive:NN \splitmaxdepth \tex_splitmaxdepth:D - \@@_primitive:NN \splittopskip \tex_splittopskip:D - \@@_primitive:NN \string \tex_string:D - \@@_primitive:NN \tabskip \tex_tabskip:D - \@@_primitive:NN \textfont \tex_textfont:D - \@@_primitive:NN \textstyle \tex_textstyle:D - \@@_primitive:NN \the \tex_the:D - \@@_primitive:NN \thickmuskip \tex_thickmuskip:D - \@@_primitive:NN \thinmuskip \tex_thinmuskip:D - \@@_primitive:NN \time \tex_time:D - \@@_primitive:NN \toks \tex_toks:D - \@@_primitive:NN \toksdef \tex_toksdef:D - \@@_primitive:NN \tolerance \tex_tolerance:D - \@@_primitive:NN \topmark \tex_topmark:D - \@@_primitive:NN \topskip \tex_topskip:D - \@@_primitive:NN \tracingcommands \tex_tracingcommands:D - \@@_primitive:NN \tracinglostchars \tex_tracinglostchars:D - \@@_primitive:NN \tracingmacros \tex_tracingmacros:D - \@@_primitive:NN \tracingonline \tex_tracingonline:D - \@@_primitive:NN \tracingoutput \tex_tracingoutput:D - \@@_primitive:NN \tracingpages \tex_tracingpages:D - \@@_primitive:NN \tracingparagraphs \tex_tracingparagraphs:D - \@@_primitive:NN \tracingrestores \tex_tracingrestores:D - \@@_primitive:NN \tracingstats \tex_tracingstats:D - \@@_primitive:NN \uccode \tex_uccode:D - \@@_primitive:NN \uchyph \tex_uchyph:D - \@@_primitive:NN \underline \tex_underline:D - \@@_primitive:NN \unhbox \tex_unhbox:D - \@@_primitive:NN \unhcopy \tex_unhcopy:D - \@@_primitive:NN \unkern \tex_unkern:D - \@@_primitive:NN \unpenalty \tex_unpenalty:D - \@@_primitive:NN \unskip \tex_unskip:D - \@@_primitive:NN \unvbox \tex_unvbox:D - \@@_primitive:NN \unvcopy \tex_unvcopy:D - \@@_primitive:NN \uppercase \tex_uppercase:D - \@@_primitive:NN \vadjust \tex_vadjust:D - \@@_primitive:NN \valign \tex_valign:D - \@@_primitive:NN \vbadness \tex_vbadness:D - \@@_primitive:NN \vbox \tex_vbox:D - \@@_primitive:NN \vcenter \tex_vcenter:D - \@@_primitive:NN \vfil \tex_vfil:D - \@@_primitive:NN \vfill \tex_vfill:D - \@@_primitive:NN \vfilneg \tex_vfilneg:D - \@@_primitive:NN \vfuzz \tex_vfuzz:D - \@@_primitive:NN \voffset \tex_voffset:D - \@@_primitive:NN \vrule \tex_vrule:D - \@@_primitive:NN \vsize \tex_vsize:D - \@@_primitive:NN \vskip \tex_vskip:D - \@@_primitive:NN \vsplit \tex_vsplit:D - \@@_primitive:NN \vss \tex_vss:D - \@@_primitive:NN \vtop \tex_vtop:D - \@@_primitive:NN \wd \tex_wd:D - \@@_primitive:NN \widowpenalty \tex_widowpenalty:D - \@@_primitive:NN \write \tex_write:D - \@@_primitive:NN \xdef \tex_xdef:D - \@@_primitive:NN \xleaders \tex_xleaders:D - \@@_primitive:NN \xspaceskip \tex_xspaceskip:D - \@@_primitive:NN \year \tex_year:D + \@@_primitive:NN \above \tex_above:D + \@@_primitive:NN \abovedisplayshortskip \tex_abovedisplayshortskip:D + \@@_primitive:NN \abovedisplayskip \tex_abovedisplayskip:D + \@@_primitive:NN \abovewithdelims \tex_abovewithdelims:D + \@@_primitive:NN \accent \tex_accent:D + \@@_primitive:NN \adjdemerits \tex_adjdemerits:D + \@@_primitive:NN \advance \tex_advance:D + \@@_primitive:NN \afterassignment \tex_afterassignment:D + \@@_primitive:NN \aftergroup \tex_aftergroup:D + \@@_primitive:NN \atop \tex_atop:D + \@@_primitive:NN \atopwithdelims \tex_atopwithdelims:D + \@@_primitive:NN \badness \tex_badness:D + \@@_primitive:NN \baselineskip \tex_baselineskip:D + \@@_primitive:NN \batchmode \tex_batchmode:D + \@@_primitive:NN \begingroup \tex_begingroup:D + \@@_primitive:NN \belowdisplayshortskip \tex_belowdisplayshortskip:D + \@@_primitive:NN \belowdisplayskip \tex_belowdisplayskip:D + \@@_primitive:NN \binoppenalty \tex_binoppenalty:D + \@@_primitive:NN \botmark \tex_botmark:D + \@@_primitive:NN \box \tex_box:D + \@@_primitive:NN \boxmaxdepth \tex_boxmaxdepth:D + \@@_primitive:NN \brokenpenalty \tex_brokenpenalty:D + \@@_primitive:NN \catcode \tex_catcode:D + \@@_primitive:NN \char \tex_char:D + \@@_primitive:NN \chardef \tex_chardef:D + \@@_primitive:NN \cleaders \tex_cleaders:D + \@@_primitive:NN \closein \tex_closein:D + \@@_primitive:NN \closeout \tex_closeout:D + \@@_primitive:NN \clubpenalty \tex_clubpenalty:D + \@@_primitive:NN \copy \tex_copy:D + \@@_primitive:NN \count \tex_count:D + \@@_primitive:NN \countdef \tex_countdef:D + \@@_primitive:NN \cr \tex_cr:D + \@@_primitive:NN \crcr \tex_crcr:D + \@@_primitive:NN \csname \tex_csname:D + \@@_primitive:NN \day \tex_day:D + \@@_primitive:NN \deadcycles \tex_deadcycles:D + \@@_primitive:NN \def \tex_def:D + \@@_primitive:NN \defaulthyphenchar \tex_defaulthyphenchar:D + \@@_primitive:NN \defaultskewchar \tex_defaultskewchar:D + \@@_primitive:NN \delcode \tex_delcode:D + \@@_primitive:NN \delimiter \tex_delimiter:D + \@@_primitive:NN \delimiterfactor \tex_delimiterfactor:D + \@@_primitive:NN \delimitershortfall \tex_delimitershortfall:D + \@@_primitive:NN \dimen \tex_dimen:D + \@@_primitive:NN \dimendef \tex_dimendef:D + \@@_primitive:NN \discretionary \tex_discretionary:D + \@@_primitive:NN \displayindent \tex_displayindent:D + \@@_primitive:NN \displaylimits \tex_displaylimits:D + \@@_primitive:NN \displaystyle \tex_displaystyle:D + \@@_primitive:NN \displaywidowpenalty \tex_displaywidowpenalty:D + \@@_primitive:NN \displaywidth \tex_displaywidth:D + \@@_primitive:NN \divide \tex_divide:D + \@@_primitive:NN \doublehyphendemerits \tex_doublehyphendemerits:D + \@@_primitive:NN \dp \tex_dp:D + \@@_primitive:NN \dump \tex_dump:D + \@@_primitive:NN \edef \tex_edef:D + \@@_primitive:NN \else \tex_else:D + \@@_primitive:NN \emergencystretch \tex_emergencystretch:D + \@@_primitive:NN \end \tex_end:D + \@@_primitive:NN \endcsname \tex_endcsname:D + \@@_primitive:NN \endgroup \tex_endgroup:D + \@@_primitive:NN \endinput \tex_endinput:D + \@@_primitive:NN \endlinechar \tex_endlinechar:D + \@@_primitive:NN \eqno \tex_eqno:D + \@@_primitive:NN \errhelp \tex_errhelp:D + \@@_primitive:NN \errmessage \tex_errmessage:D + \@@_primitive:NN \errorcontextlines \tex_errorcontextlines:D + \@@_primitive:NN \errorstopmode \tex_errorstopmode:D + \@@_primitive:NN \escapechar \tex_escapechar:D + \@@_primitive:NN \everycr \tex_everycr:D + \@@_primitive:NN \everydisplay \tex_everydisplay:D + \@@_primitive:NN \everyhbox \tex_everyhbox:D + \@@_primitive:NN \everyjob \tex_everyjob:D + \@@_primitive:NN \everymath \tex_everymath:D + \@@_primitive:NN \everypar \tex_everypar:D + \@@_primitive:NN \everyvbox \tex_everyvbox:D + \@@_primitive:NN \exhyphenpenalty \tex_exhyphenpenalty:D + \@@_primitive:NN \expandafter \tex_expandafter:D + \@@_primitive:NN \fam \tex_fam:D + \@@_primitive:NN \fi \tex_fi:D + \@@_primitive:NN \finalhyphendemerits \tex_finalhyphendemerits:D + \@@_primitive:NN \firstmark \tex_firstmark:D + \@@_primitive:NN \floatingpenalty \tex_floatingpenalty:D + \@@_primitive:NN \font \tex_font:D + \@@_primitive:NN \fontdimen \tex_fontdimen:D + \@@_primitive:NN \fontname \tex_fontname:D + \@@_primitive:NN \futurelet \tex_futurelet:D + \@@_primitive:NN \gdef \tex_gdef:D + \@@_primitive:NN \global \tex_global:D + \@@_primitive:NN \globaldefs \tex_globaldefs:D + \@@_primitive:NN \halign \tex_halign:D + \@@_primitive:NN \hangafter \tex_hangafter:D + \@@_primitive:NN \hangindent \tex_hangindent:D + \@@_primitive:NN \hbadness \tex_hbadness:D + \@@_primitive:NN \hbox \tex_hbox:D + \@@_primitive:NN \hfil \tex_hfil:D + \@@_primitive:NN \hfill \tex_hfill:D + \@@_primitive:NN \hfilneg \tex_hfilneg:D + \@@_primitive:NN \hfuzz \tex_hfuzz:D + \@@_primitive:NN \hoffset \tex_hoffset:D + \@@_primitive:NN \holdinginserts \tex_holdinginserts:D + \@@_primitive:NN \hrule \tex_hrule:D + \@@_primitive:NN \hsize \tex_hsize:D + \@@_primitive:NN \hskip \tex_hskip:D + \@@_primitive:NN \hss \tex_hss:D + \@@_primitive:NN \ht \tex_ht:D + \@@_primitive:NN \hyphenation \tex_hyphenation:D + \@@_primitive:NN \hyphenchar \tex_hyphenchar:D + \@@_primitive:NN \hyphenpenalty \tex_hyphenpenalty:D + \@@_primitive:NN \if \tex_if:D + \@@_primitive:NN \ifcase \tex_ifcase:D + \@@_primitive:NN \ifcat \tex_ifcat:D + \@@_primitive:NN \ifdim \tex_ifdim:D + \@@_primitive:NN \ifeof \tex_ifeof:D + \@@_primitive:NN \iffalse \tex_iffalse:D + \@@_primitive:NN \ifhbox \tex_ifhbox:D + \@@_primitive:NN \ifhmode \tex_ifhmode:D + \@@_primitive:NN \ifinner \tex_ifinner:D + \@@_primitive:NN \ifmmode \tex_ifmmode:D + \@@_primitive:NN \ifnum \tex_ifnum:D + \@@_primitive:NN \ifodd \tex_ifodd:D + \@@_primitive:NN \iftrue \tex_iftrue:D + \@@_primitive:NN \ifvbox \tex_ifvbox:D + \@@_primitive:NN \ifvmode \tex_ifvmode:D + \@@_primitive:NN \ifvoid \tex_ifvoid:D + \@@_primitive:NN \ifx \tex_ifx:D + \@@_primitive:NN \ignorespaces \tex_ignorespaces:D + \@@_primitive:NN \immediate \tex_immediate:D + \@@_primitive:NN \indent \tex_indent:D + \@@_primitive:NN \input \tex_input:D + \@@_primitive:NN \inputlineno \tex_inputlineno:D + \@@_primitive:NN \insert \tex_insert:D + \@@_primitive:NN \insertpenalties \tex_insertpenalties:D + \@@_primitive:NN \interlinepenalty \tex_interlinepenalty:D + \@@_primitive:NN \jobname \tex_jobname:D + \@@_primitive:NN \kern \tex_kern:D + \@@_primitive:NN \language \tex_language:D + \@@_primitive:NN \lastbox \tex_lastbox:D + \@@_primitive:NN \lastkern \tex_lastkern:D + \@@_primitive:NN \lastpenalty \tex_lastpenalty:D + \@@_primitive:NN \lastskip \tex_lastskip:D + \@@_primitive:NN \lccode \tex_lccode:D + \@@_primitive:NN \leaders \tex_leaders:D + \@@_primitive:NN \left \tex_left:D + \@@_primitive:NN \lefthyphenmin \tex_lefthyphenmin:D + \@@_primitive:NN \leftskip \tex_leftskip:D + \@@_primitive:NN \leqno \tex_leqno:D + \@@_primitive:NN \let \tex_let:D + \@@_primitive:NN \limits \tex_limits:D + \@@_primitive:NN \linepenalty \tex_linepenalty:D + \@@_primitive:NN \lineskip \tex_lineskip:D + \@@_primitive:NN \lineskiplimit \tex_lineskiplimit:D + \@@_primitive:NN \long \tex_long:D + \@@_primitive:NN \looseness \tex_looseness:D + \@@_primitive:NN \lower \tex_lower:D + \@@_primitive:NN \lowercase \tex_lowercase:D + \@@_primitive:NN \mag \tex_mag:D + \@@_primitive:NN \mark \tex_mark:D + \@@_primitive:NN \mathaccent \tex_mathaccent:D + \@@_primitive:NN \mathbin \tex_mathbin:D + \@@_primitive:NN \mathchar \tex_mathchar:D + \@@_primitive:NN \mathchardef \tex_mathchardef:D + \@@_primitive:NN \mathchoice \tex_mathchoice:D + \@@_primitive:NN \mathclose \tex_mathclose:D + \@@_primitive:NN \mathcode \tex_mathcode:D + \@@_primitive:NN \mathinner \tex_mathinner:D + \@@_primitive:NN \mathop \tex_mathop:D + \@@_primitive:NN \mathopen \tex_mathopen:D + \@@_primitive:NN \mathord \tex_mathord:D + \@@_primitive:NN \mathpunct \tex_mathpunct:D + \@@_primitive:NN \mathrel \tex_mathrel:D + \@@_primitive:NN \mathsurround \tex_mathsurround:D + \@@_primitive:NN \maxdeadcycles \tex_maxdeadcycles:D + \@@_primitive:NN \maxdepth \tex_maxdepth:D + \@@_primitive:NN \meaning \tex_meaning:D + \@@_primitive:NN \medmuskip \tex_medmuskip:D + \@@_primitive:NN \message \tex_message:D + \@@_primitive:NN \mkern \tex_mkern:D + \@@_primitive:NN \month \tex_month:D + \@@_primitive:NN \moveleft \tex_moveleft:D + \@@_primitive:NN \moveright \tex_moveright:D + \@@_primitive:NN \mskip \tex_mskip:D + \@@_primitive:NN \multiply \tex_multiply:D + \@@_primitive:NN \muskip \tex_muskip:D + \@@_primitive:NN \muskipdef \tex_muskipdef:D + \@@_primitive:NN \newlinechar \tex_newlinechar:D + \@@_primitive:NN \noalign \tex_noalign:D + \@@_primitive:NN \noboundary \tex_noboundary:D + \@@_primitive:NN \noexpand \tex_noexpand:D + \@@_primitive:NN \noindent \tex_noindent:D + \@@_primitive:NN \nolimits \tex_nolimits:D + \@@_primitive:NN \nonscript \tex_nonscript:D + \@@_primitive:NN \nonstopmode \tex_nonstopmode:D + \@@_primitive:NN \nulldelimiterspace \tex_nulldelimiterspace:D + \@@_primitive:NN \nullfont \tex_nullfont:D + \@@_primitive:NN \number \tex_number:D + \@@_primitive:NN \omit \tex_omit:D + \@@_primitive:NN \openin \tex_openin:D + \@@_primitive:NN \openout \tex_openout:D + \@@_primitive:NN \or \tex_or:D + \@@_primitive:NN \outer \tex_outer:D + \@@_primitive:NN \output \tex_output:D + \@@_primitive:NN \outputpenalty \tex_outputpenalty:D + \@@_primitive:NN \over \tex_over:D + \@@_primitive:NN \overfullrule \tex_overfullrule:D + \@@_primitive:NN \overline \tex_overline:D + \@@_primitive:NN \overwithdelims \tex_overwithdelims:D + \@@_primitive:NN \pagedepth \tex_pagedepth:D + \@@_primitive:NN \pagefilllstretch \tex_pagefilllstretch:D + \@@_primitive:NN \pagefillstretch \tex_pagefillstretch:D + \@@_primitive:NN \pagefilstretch \tex_pagefilstretch:D + \@@_primitive:NN \pagegoal \tex_pagegoal:D + \@@_primitive:NN \pageshrink \tex_pageshrink:D + \@@_primitive:NN \pagestretch \tex_pagestretch:D + \@@_primitive:NN \pagetotal \tex_pagetotal:D + \@@_primitive:NN \par \tex_par:D + \@@_primitive:NN \parfillskip \tex_parfillskip:D + \@@_primitive:NN \parindent \tex_parindent:D + \@@_primitive:NN \parshape \tex_parshape:D + \@@_primitive:NN \parskip \tex_parskip:D + \@@_primitive:NN \patterns \tex_patterns:D + \@@_primitive:NN \pausing \tex_pausing:D + \@@_primitive:NN \penalty \tex_penalty:D + \@@_primitive:NN \postdisplaypenalty \tex_postdisplaypenalty:D + \@@_primitive:NN \predisplaypenalty \tex_predisplaypenalty:D + \@@_primitive:NN \predisplaysize \tex_predisplaysize:D + \@@_primitive:NN \pretolerance \tex_pretolerance:D + \@@_primitive:NN \prevdepth \tex_prevdepth:D + \@@_primitive:NN \prevgraf \tex_prevgraf:D + \@@_primitive:NN \radical \tex_radical:D + \@@_primitive:NN \raise \tex_raise:D + \@@_primitive:NN \read \tex_read:D + \@@_primitive:NN \relax \tex_relax:D + \@@_primitive:NN \relpenalty \tex_relpenalty:D + \@@_primitive:NN \right \tex_right:D + \@@_primitive:NN \righthyphenmin \tex_righthyphenmin:D + \@@_primitive:NN \rightskip \tex_rightskip:D + \@@_primitive:NN \romannumeral \tex_romannumeral:D + \@@_primitive:NN \scriptfont \tex_scriptfont:D + \@@_primitive:NN \scriptscriptfont \tex_scriptscriptfont:D + \@@_primitive:NN \scriptscriptstyle \tex_scriptscriptstyle:D + \@@_primitive:NN \scriptspace \tex_scriptspace:D + \@@_primitive:NN \scriptstyle \tex_scriptstyle:D + \@@_primitive:NN \scrollmode \tex_scrollmode:D + \@@_primitive:NN \setbox \tex_setbox:D + \@@_primitive:NN \setlanguage \tex_setlanguage:D + \@@_primitive:NN \sfcode \tex_sfcode:D + \@@_primitive:NN \shipout \tex_shipout:D + \@@_primitive:NN \show \tex_show:D + \@@_primitive:NN \showbox \tex_showbox:D + \@@_primitive:NN \showboxbreadth \tex_showboxbreadth:D + \@@_primitive:NN \showboxdepth \tex_showboxdepth:D + \@@_primitive:NN \showlists \tex_showlists:D + \@@_primitive:NN \showthe \tex_showthe:D + \@@_primitive:NN \skewchar \tex_skewchar:D + \@@_primitive:NN \skip \tex_skip:D + \@@_primitive:NN \skipdef \tex_skipdef:D + \@@_primitive:NN \spacefactor \tex_spacefactor:D + \@@_primitive:NN \spaceskip \tex_spaceskip:D + \@@_primitive:NN \span \tex_span:D + \@@_primitive:NN \special \tex_special:D + \@@_primitive:NN \splitbotmark \tex_splitbotmark:D + \@@_primitive:NN \splitfirstmark \tex_splitfirstmark:D + \@@_primitive:NN \splitmaxdepth \tex_splitmaxdepth:D + \@@_primitive:NN \splittopskip \tex_splittopskip:D + \@@_primitive:NN \string \tex_string:D + \@@_primitive:NN \tabskip \tex_tabskip:D + \@@_primitive:NN \textfont \tex_textfont:D + \@@_primitive:NN \textstyle \tex_textstyle:D + \@@_primitive:NN \the \tex_the:D + \@@_primitive:NN \thickmuskip \tex_thickmuskip:D + \@@_primitive:NN \thinmuskip \tex_thinmuskip:D + \@@_primitive:NN \time \tex_time:D + \@@_primitive:NN \toks \tex_toks:D + \@@_primitive:NN \toksdef \tex_toksdef:D + \@@_primitive:NN \tolerance \tex_tolerance:D + \@@_primitive:NN \topmark \tex_topmark:D + \@@_primitive:NN \topskip \tex_topskip:D + \@@_primitive:NN \tracingcommands \tex_tracingcommands:D + \@@_primitive:NN \tracinglostchars \tex_tracinglostchars:D + \@@_primitive:NN \tracingmacros \tex_tracingmacros:D + \@@_primitive:NN \tracingonline \tex_tracingonline:D + \@@_primitive:NN \tracingoutput \tex_tracingoutput:D + \@@_primitive:NN \tracingpages \tex_tracingpages:D + \@@_primitive:NN \tracingparagraphs \tex_tracingparagraphs:D + \@@_primitive:NN \tracingrestores \tex_tracingrestores:D + \@@_primitive:NN \tracingstats \tex_tracingstats:D + \@@_primitive:NN \uccode \tex_uccode:D + \@@_primitive:NN \uchyph \tex_uchyph:D + \@@_primitive:NN \underline \tex_underline:D + \@@_primitive:NN \unhbox \tex_unhbox:D + \@@_primitive:NN \unhcopy \tex_unhcopy:D + \@@_primitive:NN \unkern \tex_unkern:D + \@@_primitive:NN \unpenalty \tex_unpenalty:D + \@@_primitive:NN \unskip \tex_unskip:D + \@@_primitive:NN \unvbox \tex_unvbox:D + \@@_primitive:NN \unvcopy \tex_unvcopy:D + \@@_primitive:NN \uppercase \tex_uppercase:D + \@@_primitive:NN \vadjust \tex_vadjust:D + \@@_primitive:NN \valign \tex_valign:D + \@@_primitive:NN \vbadness \tex_vbadness:D + \@@_primitive:NN \vbox \tex_vbox:D + \@@_primitive:NN \vcenter \tex_vcenter:D + \@@_primitive:NN \vfil \tex_vfil:D + \@@_primitive:NN \vfill \tex_vfill:D + \@@_primitive:NN \vfilneg \tex_vfilneg:D + \@@_primitive:NN \vfuzz \tex_vfuzz:D + \@@_primitive:NN \voffset \tex_voffset:D + \@@_primitive:NN \vrule \tex_vrule:D + \@@_primitive:NN \vsize \tex_vsize:D + \@@_primitive:NN \vskip \tex_vskip:D + \@@_primitive:NN \vsplit \tex_vsplit:D + \@@_primitive:NN \vss \tex_vss:D + \@@_primitive:NN \vtop \tex_vtop:D + \@@_primitive:NN \wd \tex_wd:D + \@@_primitive:NN \widowpenalty \tex_widowpenalty:D + \@@_primitive:NN \write \tex_write:D + \@@_primitive:NN \xdef \tex_xdef:D + \@@_primitive:NN \xleaders \tex_xleaders:D + \@@_primitive:NN \xspaceskip \tex_xspaceskip:D + \@@_primitive:NN \year \tex_year:D % \end{macrocode} % Since \LaTeX3 requires at least the \eTeX{} extensions, % we also rename the additional primitives. These are all % given the prefix | \etex_|. % \begin{macrocode} - \@@_primitive:NN \beginL \etex_beginL:D - \@@_primitive:NN \beginR \etex_beginR:D - \@@_primitive:NN \botmarks \etex_botmarks:D - \@@_primitive:NN \clubpenalties \etex_clubpenalties:D - \@@_primitive:NN \currentgrouplevel \etex_currentgrouplevel:D - \@@_primitive:NN \currentgrouptype \etex_currentgrouptype:D - \@@_primitive:NN \currentifbranch \etex_currentifbranch:D - \@@_primitive:NN \currentiflevel \etex_currentiflevel:D - \@@_primitive:NN \currentiftype \etex_currentiftype:D - \@@_primitive:NN \detokenize \etex_detokenize:D - \@@_primitive:NN \dimexpr \etex_dimexpr:D - \@@_primitive:NN \displaywidowpenalties \etex_displaywidowpenalties:D - \@@_primitive:NN \endL \etex_endL:D - \@@_primitive:NN \endR \etex_endR:D - \@@_primitive:NN \eTeXrevision \etex_eTeXrevision:D - \@@_primitive:NN \eTeXversion \etex_eTeXversion:D - \@@_primitive:NN \everyeof \etex_everyeof:D - \@@_primitive:NN \firstmarks \etex_firstmarks:D - \@@_primitive:NN \fontchardp \etex_fontchardp:D - \@@_primitive:NN \fontcharht \etex_fontcharht:D - \@@_primitive:NN \fontcharic \etex_fontcharic:D - \@@_primitive:NN \fontcharwd \etex_fontcharwd:D - \@@_primitive:NN \glueexpr \etex_glueexpr:D - \@@_primitive:NN \glueshrink \etex_glueshrink:D - \@@_primitive:NN \glueshrinkorder \etex_glueshrinkorder:D - \@@_primitive:NN \gluestretch \etex_gluestretch:D - \@@_primitive:NN \gluestretchorder \etex_gluestretchorder:D - \@@_primitive:NN \gluetomu \etex_gluetomu:D - \@@_primitive:NN \ifcsname \etex_ifcsname:D - \@@_primitive:NN \ifdefined \etex_ifdefined:D - \@@_primitive:NN \iffontchar \etex_iffontchar:D - \@@_primitive:NN \interactionmode \etex_interactionmode:D - \@@_primitive:NN \interlinepenalties \etex_interlinepenalties:D - \@@_primitive:NN \lastlinefit \etex_lastlinefit:D - \@@_primitive:NN \lastnodetype \etex_lastnodetype:D - \@@_primitive:NN \marks \etex_marks:D - \@@_primitive:NN \middle \etex_middle:D - \@@_primitive:NN \muexpr \etex_muexpr:D - \@@_primitive:NN \mutoglue \etex_mutoglue:D - \@@_primitive:NN \numexpr \etex_numexpr:D - \@@_primitive:NN \pagediscards \etex_pagediscards:D - \@@_primitive:NN \parshapedimen \etex_parshapedimen:D - \@@_primitive:NN \parshapeindent \etex_parshapeindent:D - \@@_primitive:NN \parshapelength \etex_parshapelength:D - \@@_primitive:NN \predisplaydirection \etex_predisplaydirection:D - \@@_primitive:NN \protected \etex_protected:D - \@@_primitive:NN \readline \etex_readline:D - \@@_primitive:NN \savinghyphcodes \etex_savinghyphcodes:D - \@@_primitive:NN \savingvdiscards \etex_savingvdiscards:D - \@@_primitive:NN \scantokens \etex_scantokens:D - \@@_primitive:NN \showgroups \etex_showgroups:D - \@@_primitive:NN \showifs \etex_showifs:D - \@@_primitive:NN \showtokens \etex_showtokens:D - \@@_primitive:NN \splitbotmarks \etex_splitbotmarks:D - \@@_primitive:NN \splitdiscards \etex_splitdiscards:D - \@@_primitive:NN \splitfirstmarks \etex_splitfirstmarks:D - \@@_primitive:NN \TeXXeTstate \etex_TeXXeTstate:D - \@@_primitive:NN \topmarks \etex_topmarks:D - \@@_primitive:NN \tracingassigns \etex_tracingassigns:D - \@@_primitive:NN \tracinggroups \etex_tracinggroups:D - \@@_primitive:NN \tracingifs \etex_tracingifs:D - \@@_primitive:NN \tracingnesting \etex_tracingnesting:D - \@@_primitive:NN \tracingscantokens \etex_tracingscantokens:D - \@@_primitive:NN \unexpanded \etex_unexpanded:D - \@@_primitive:NN \unless \etex_unless:D - \@@_primitive:NN \widowpenalties \etex_widowpenalties:D + \@@_primitive:NN \beginL \etex_beginL:D + \@@_primitive:NN \beginR \etex_beginR:D + \@@_primitive:NN \botmarks \etex_botmarks:D + \@@_primitive:NN \clubpenalties \etex_clubpenalties:D + \@@_primitive:NN \currentgrouplevel \etex_currentgrouplevel:D + \@@_primitive:NN \currentgrouptype \etex_currentgrouptype:D + \@@_primitive:NN \currentifbranch \etex_currentifbranch:D + \@@_primitive:NN \currentiflevel \etex_currentiflevel:D + \@@_primitive:NN \currentiftype \etex_currentiftype:D + \@@_primitive:NN \detokenize \etex_detokenize:D + \@@_primitive:NN \dimexpr \etex_dimexpr:D + \@@_primitive:NN \displaywidowpenalties + \etex_displaywidowpenalties:D + \@@_primitive:NN \endL \etex_endL:D + \@@_primitive:NN \endR \etex_endR:D + \@@_primitive:NN \eTeXrevision \etex_eTeXrevision:D + \@@_primitive:NN \eTeXversion \etex_eTeXversion:D + \@@_primitive:NN \everyeof \etex_everyeof:D + \@@_primitive:NN \firstmarks \etex_firstmarks:D + \@@_primitive:NN \fontchardp \etex_fontchardp:D + \@@_primitive:NN \fontcharht \etex_fontcharht:D + \@@_primitive:NN \fontcharic \etex_fontcharic:D + \@@_primitive:NN \fontcharwd \etex_fontcharwd:D + \@@_primitive:NN \glueexpr \etex_glueexpr:D + \@@_primitive:NN \glueshrink \etex_glueshrink:D + \@@_primitive:NN \glueshrinkorder \etex_glueshrinkorder:D + \@@_primitive:NN \gluestretch \etex_gluestretch:D + \@@_primitive:NN \gluestretchorder \etex_gluestretchorder:D + \@@_primitive:NN \gluetomu \etex_gluetomu:D + \@@_primitive:NN \ifcsname \etex_ifcsname:D + \@@_primitive:NN \ifdefined \etex_ifdefined:D + \@@_primitive:NN \iffontchar \etex_iffontchar:D + \@@_primitive:NN \interactionmode \etex_interactionmode:D + \@@_primitive:NN \interlinepenalties \etex_interlinepenalties:D + \@@_primitive:NN \lastlinefit \etex_lastlinefit:D + \@@_primitive:NN \lastnodetype \etex_lastnodetype:D + \@@_primitive:NN \marks \etex_marks:D + \@@_primitive:NN \middle \etex_middle:D + \@@_primitive:NN \muexpr \etex_muexpr:D + \@@_primitive:NN \mutoglue \etex_mutoglue:D + \@@_primitive:NN \numexpr \etex_numexpr:D + \@@_primitive:NN \pagediscards \etex_pagediscards:D + \@@_primitive:NN \parshapedimen \etex_parshapedimen:D + \@@_primitive:NN \parshapeindent \etex_parshapeindent:D + \@@_primitive:NN \parshapelength \etex_parshapelength:D + \@@_primitive:NN \predisplaydirection \etex_predisplaydirection:D + \@@_primitive:NN \protected \etex_protected:D + \@@_primitive:NN \readline \etex_readline:D + \@@_primitive:NN \savinghyphcodes \etex_savinghyphcodes:D + \@@_primitive:NN \savingvdiscards \etex_savingvdiscards:D + \@@_primitive:NN \scantokens \etex_scantokens:D + \@@_primitive:NN \showgroups \etex_showgroups:D + \@@_primitive:NN \showifs \etex_showifs:D + \@@_primitive:NN \showtokens \etex_showtokens:D + \@@_primitive:NN \splitbotmarks \etex_splitbotmarks:D + \@@_primitive:NN \splitdiscards \etex_splitdiscards:D + \@@_primitive:NN \splitfirstmarks \etex_splitfirstmarks:D + \@@_primitive:NN \TeXXeTstate \etex_TeXXeTstate:D + \@@_primitive:NN \topmarks \etex_topmarks:D + \@@_primitive:NN \tracingassigns \etex_tracingassigns:D + \@@_primitive:NN \tracinggroups \etex_tracinggroups:D + \@@_primitive:NN \tracingifs \etex_tracingifs:D + \@@_primitive:NN \tracingnesting \etex_tracingnesting:D + \@@_primitive:NN \tracingscantokens \etex_tracingscantokens:D + \@@_primitive:NN \unexpanded \etex_unexpanded:D + \@@_primitive:NN \unless \etex_unless:D + \@@_primitive:NN \widowpenalties \etex_widowpenalties:D % \end{macrocode} % The newer primitives are more complex: there are an awful lot of them, % and we don't use them all at the moment. So the following is selective, @@ -551,134 +546,139 @@ % are not related to PDF output. These ones related to PDF output or only % work in PDF mode. % \begin{macrocode} - \@@_primitive:NN \pdfannot \pdftex_pdfannot:D - \@@_primitive:NN \pdfcatalog \pdftex_pdfcatalog:D - \@@_primitive:NN \pdfcompresslevel \pdftex_pdfcompresslevel:D - \@@_primitive:NN \pdfcolorstack \pdftex_pdfcolorstack:D - \@@_primitive:NN \pdfcolorstackinit \pdftex_pdfcolorstackinit:D - \@@_primitive:NN \pdfcreationdate \pdftex_pdfcreationdate:D - \@@_primitive:NN \pdfdecimaldigits \pdftex_pdfdecimaldigits:D - \@@_primitive:NN \pdfdest \pdftex_pdfdest:D - \@@_primitive:NN \pdfdestmargin \pdftex_pdfdestmargin:D - \@@_primitive:NN \pdfendlink \pdftex_pdfendlink:D - \@@_primitive:NN \pdfendthread \pdftex_pdfendthread:D - \@@_primitive:NN \pdffontattr \pdftex_pdffontattr:D - \@@_primitive:NN \pdffontname \pdftex_pdffontname:D - \@@_primitive:NN \pdffontobjnum \pdftex_pdffontobjnum:D - \@@_primitive:NN \pdfgamma \pdftex_pdfgamma:D - \@@_primitive:NN \pdfimageapplygamma \pdftex_pdfimageapplygamma:D - \@@_primitive:NN \pdfimagegamma \pdftex_pdfimagegamma:D - \@@_primitive:NN \pdfgentounicode \pdftex_pdfgentounicode:D - \@@_primitive:NN \pdfglyphtounicode \pdftex_pdfglyphtounicode:D - \@@_primitive:NN \pdfhorigin \pdftex_pdfhorigin:D - \@@_primitive:NN \pdfimagehicolor \pdftex_pdfimagehicolor:D - \@@_primitive:NN \pdfimageresolution \pdftex_pdfimageresolution:D - \@@_primitive:NN \pdfincludechars \pdftex_pdfincludechars:D - \@@_primitive:NN \pdfinclusioncopyfonts \pdftex_pdfinclusioncopyfonts:D - \@@_primitive:NN \pdfinclusionerrorlevel \pdftex_pdfinclusionerrorlevel:D - \@@_primitive:NN \pdfinfo \pdftex_pdfinfo:D - \@@_primitive:NN \pdflastannot \pdftex_pdflastannot:D - \@@_primitive:NN \pdflastlink \pdftex_pdflastlink:D - \@@_primitive:NN \pdflastobj \pdftex_pdflastobj:D - \@@_primitive:NN \pdflastxform \pdftex_pdflastxform:D - \@@_primitive:NN \pdflastximage \pdftex_pdflastximage:D - \@@_primitive:NN \pdflastximagecolordepth \pdftex_pdflastximagecolordepth:D - \@@_primitive:NN \pdflastximagepages \pdftex_pdflastximagepages:D - \@@_primitive:NN \pdflinkmargin \pdftex_pdflinkmargin:D - \@@_primitive:NN \pdfliteral \pdftex_pdfliteral:D - \@@_primitive:NN \pdfminorversion \pdftex_pdfminorversion:D - \@@_primitive:NN \pdfnames \pdftex_pdfnames:D - \@@_primitive:NN \pdfobj \pdftex_pdfobj:D - \@@_primitive:NN \pdfobjcompresslevel \pdftex_pdfobjcompresslevel:D - \@@_primitive:NN \pdfoutline \pdftex_pdfoutline:D - \@@_primitive:NN \pdfoutput \pdftex_pdfoutput:D - \@@_primitive:NN \pdfpageattr \pdftex_pdfpageattr:D - \@@_primitive:NN \pdfpagebox \pdftex_pdfpagebox:D - \@@_primitive:NN \pdfpageref \pdftex_pdfpageref:D - \@@_primitive:NN \pdfpageresources \pdftex_pdfpageresources:D - \@@_primitive:NN \pdfpagesattr \pdftex_pdfpagesattr:D - \@@_primitive:NN \pdfrefobj \pdftex_pdfrefobj:D - \@@_primitive:NN \pdfrefxform \pdftex_pdfrefxform:D - \@@_primitive:NN \pdfrefximage \pdftex_pdfrefximage:D - \@@_primitive:NN \pdfrestore \pdftex_pdfrestore:D - \@@_primitive:NN \pdfretval \pdftex_pdfretval:D - \@@_primitive:NN \pdfsave \pdftex_pdfsave:D - \@@_primitive:NN \pdfsetmatrix \pdftex_pdfsetmatrix:D - \@@_primitive:NN \pdfstartlink \pdftex_pdfstartlink:D - \@@_primitive:NN \pdfstartthread \pdftex_pdfstartthread:D - \@@_primitive:NN \pdfsuppressptexinfo \pdftex_pdfsuppressptexinfo:D - \@@_primitive:NN \pdfthread \pdftex_pdfthread:D - \@@_primitive:NN \pdfthreadmargin \pdftex_pdfthreadmargin:D - \@@_primitive:NN \pdftrailer \pdftex_pdftrailer:D - \@@_primitive:NN \pdfuniqueresname \pdftex_pdfuniqueresname:D - \@@_primitive:NN \pdfvorigin \pdftex_pdfvorigin:D - \@@_primitive:NN \pdfxform \pdftex_pdfxform:D - \@@_primitive:NN \pdfxformattr \pdftex_pdfxformattr:D - \@@_primitive:NN \pdfxformname \pdftex_pdfxformname:D - \@@_primitive:NN \pdfxformresources \pdftex_pdfxformresources:D - \@@_primitive:NN \pdfximage \pdftex_pdfximage:D - \@@_primitive:NN \pdfximagebbox \pdftex_pdfximagebbox:D + \@@_primitive:NN \pdfannot \pdftex_pdfannot:D + \@@_primitive:NN \pdfcatalog \pdftex_pdfcatalog:D + \@@_primitive:NN \pdfcompresslevel \pdftex_pdfcompresslevel:D + \@@_primitive:NN \pdfcolorstack \pdftex_pdfcolorstack:D + \@@_primitive:NN \pdfcolorstackinit \pdftex_pdfcolorstackinit:D + \@@_primitive:NN \pdfcreationdate \pdftex_pdfcreationdate:D + \@@_primitive:NN \pdfdecimaldigits \pdftex_pdfdecimaldigits:D + \@@_primitive:NN \pdfdest \pdftex_pdfdest:D + \@@_primitive:NN \pdfdestmargin \pdftex_pdfdestmargin:D + \@@_primitive:NN \pdfendlink \pdftex_pdfendlink:D + \@@_primitive:NN \pdfendthread \pdftex_pdfendthread:D + \@@_primitive:NN \pdffontattr \pdftex_pdffontattr:D + \@@_primitive:NN \pdffontname \pdftex_pdffontname:D + \@@_primitive:NN \pdffontobjnum \pdftex_pdffontobjnum:D + \@@_primitive:NN \pdfgamma \pdftex_pdfgamma:D + \@@_primitive:NN \pdfimageapplygamma \pdftex_pdfimageapplygamma:D + \@@_primitive:NN \pdfimagegamma \pdftex_pdfimagegamma:D + \@@_primitive:NN \pdfgentounicode \pdftex_pdfgentounicode:D + \@@_primitive:NN \pdfglyphtounicode \pdftex_pdfglyphtounicode:D + \@@_primitive:NN \pdfhorigin \pdftex_pdfhorigin:D + \@@_primitive:NN \pdfimagehicolor \pdftex_pdfimagehicolor:D + \@@_primitive:NN \pdfimageresolution \pdftex_pdfimageresolution:D + \@@_primitive:NN \pdfincludechars \pdftex_pdfincludechars:D + \@@_primitive:NN \pdfinclusioncopyfonts + \pdftex_pdfinclusioncopyfonts:D + \@@_primitive:NN \pdfinclusionerrorlevel + \pdftex_pdfinclusionerrorlevel:D + \@@_primitive:NN \pdfinfo \pdftex_pdfinfo:D + \@@_primitive:NN \pdflastannot \pdftex_pdflastannot:D + \@@_primitive:NN \pdflastlink \pfdftex_pdflastlink:D + \@@_primitive:NN \pdflastobj \pdftex_pdflastobj:D + \@@_primitive:NN \pdflastxform \pdftex_pdflastxform:D + \@@_primitive:NN \pdflastximage \pdftex_pdflastximage:D + \@@_primitive:NN \pdflastximagecolordepth + \pdftex_pdflastximagecolordepth:D + \@@_primitive:NN \pdflastximagepages \pdftex_pdflastximagepages:D + \@@_primitive:NN \pdflinkmargin \pdftex_pdflinkmargin:D + \@@_primitive:NN \pdfliteral \pdftex_pdfliteral:D + \@@_primitive:NN \pdfminorversion \pdftex_pdfminorversion:D + \@@_primitive:NN \pdfnames \pdftex_pdfnames:D + \@@_primitive:NN \pdfobj \pdftex_pdfobj:D + \@@_primitive:NN \pdfobjcompresslevel + \pdftex_pdfobjcompresslevel:D + \@@_primitive:NN \pdfoutline \pdftex_pdfoutline:D + \@@_primitive:NN \pdfoutput \pdftex_pdfoutput:D + \@@_primitive:NN \pdfpageattr \pdftex_pdfpageattr:D + \@@_primitive:NN \pdfpagebox \pdftex_pdfpagebox:D + \@@_primitive:NN \pdfpageref \pdftex_pdfpageref:D + \@@_primitive:NN \pdfpageresources \pdftex_pdfpageresources:D + \@@_primitive:NN \pdfpagesattr \pdftex_pdfpagesattr:D + \@@_primitive:NN \pdfrefobj \pdftex_pdfrefobj:D + \@@_primitive:NN \pdfrefxform \pdftex_pdfrefxform:D + \@@_primitive:NN \pdfrefximage \pdftex_pdfrefximage:D + \@@_primitive:NN \pdfrestore \pdftex_pdfrestore:D + \@@_primitive:NN \pdfretval \pdftex_pdfretval:D + \@@_primitive:NN \pdfsave \pdftex_pdfsave:D + \@@_primitive:NN \pdfsetmatrix \pdftex_pdfsetmatrix:D + \@@_primitive:NN \pdfstartlink \pdftex_pdfstartlink:D + \@@_primitive:NN \pdfstartthread \pdftex_pdfstartthread:D + \@@_primitive:NN \pdfsuppressptexinfo + \pdftex_pdfsuppressptexinfo:D + \@@_primitive:NN \pdfthread \pdftex_pdfthread:D + \@@_primitive:NN \pdfthreadmargin \pdftex_pdfthreadmargin:D + \@@_primitive:NN \pdftrailer \pdftex_pdftrailer:D + \@@_primitive:NN \pdfuniqueresname \pdftex_pdfuniqueresname:D + \@@_primitive:NN \pdfvorigin \pdftex_pdfvorigin:D + \@@_primitive:NN \pdfxform \pdftex_pdfxform:D + \@@_primitive:NN \pdfxformattr \pdftex_pdfxformattr:D + \@@_primitive:NN \pdfxformname \pdftex_pdfxformname:D + \@@_primitive:NN \pdfxformresources \pdftex_pdfxformresources:D + \@@_primitive:NN \pdfximage \pdftex_pdfximage:D + \@@_primitive:NN \pdfximagebbox \pdftex_pdfximagebbox:D % \end{macrocode} % While these are not. % \begin{macrocode} - \@@_primitive:NN \ifpdfabsdim \pdftex_ifabsdim:D - \@@_primitive:NN \ifpdfabsnum \pdftex_ifabsnum:D - \@@_primitive:NN \ifpdfprimitive \pdftex_ifprimitive:D - \@@_primitive:NN \pdfadjustspacing \pdftex_adjustspacing:D - \@@_primitive:NN \pdfcopyfont \pdftex_copyfont:D - \@@_primitive:NN \pdfdraftmode \pdftex_draftmode:D - \@@_primitive:NN \pdfeachlinedepth \pdftex_eachlinedepth:D - \@@_primitive:NN \pdfeachlineheight \pdftex_eachlineheight:D - \@@_primitive:NN \pdffilemoddate \pdftex_filemoddate:D - \@@_primitive:NN \pdffilesize \pdftex_filesize:D - \@@_primitive:NN \pdffirstlineheight \pdftex_firstlineheight:D - \@@_primitive:NN \pdffontexpand \pdftex_fontexpand:D - \@@_primitive:NN \pdffontsize \pdftex_fontsize:D - \@@_primitive:NN \pdfignoreddimen \pdftex_ignoreddimen:D - \@@_primitive:NN \pdfinsertht \pdftex_insertht:D - \@@_primitive:NN \pdflastlinedepth \pdftex_lastlinedepth:D - \@@_primitive:NN \pdflastxpos \pdftex_lastxpos:D - \@@_primitive:NN \pdflastypos \pdftex_lastypos:D - \@@_primitive:NN \pdfmapfile \pdftex_mapfile:D - \@@_primitive:NN \pdfmapline \pdftex_mapline:D - \@@_primitive:NN \pdfmdfivesum \pdftex_mdfivesum:D - \@@_primitive:NN \pdfnoligatures \pdftex_noligatures:D - \@@_primitive:NN \pdfnormaldeviate \pdftex_normaldeviate:D - \@@_primitive:NN \pdfpageheight \pdftex_pageheight:D - \@@_primitive:NN \pdfpagewidth \pdftex_pagewidth:D - \@@_primitive:NN \pdfpkmode \pdftex_pkmode:D - \@@_primitive:NN \pdfpkresolution \pdftex_pkresolution:D - \@@_primitive:NN \pdfprimitive \pdftex_primitive:D - \@@_primitive:NN \pdfprotrudechars \pdftex_protrudechars:D - \@@_primitive:NN \pdfpxdimen \pdftex_pxdimen:D - \@@_primitive:NN \pdfrandomseed \pdftex_randomseed:D - \@@_primitive:NN \pdfsavepos \pdftex_savepos:D - \@@_primitive:NN \pdfstrcmp \pdftex_strcmp:D - \@@_primitive:NN \pdfsetrandomseed \pdftex_setrandomseed:D - \@@_primitive:NN \pdfshellescape \pdftex_shellescape:D - \@@_primitive:NN \pdftracingfonts \pdftex_tracingfonts:D - \@@_primitive:NN \pdfuniformdeviate \pdftex_uniformdeviate:D + \@@_primitive:NN \ifpdfabsdim \pdftex_ifabsdim:D + \@@_primitive:NN \ifpdfabsnum \pdftex_ifabsnum:D + \@@_primitive:NN \ifpdfprimitive \pdftex_ifprimitive:D + \@@_primitive:NN \pdfadjustspacing \pdftex_adjustspacing:D + \@@_primitive:NN \pdfcopyfont \pdftex_copyfont:D + \@@_primitive:NN \pdfdraftmode \pdftex_draftmode:D + \@@_primitive:NN \pdfeachlinedepth \pdftex_eachlinedepth:D + \@@_primitive:NN \pdfeachlineheight \pdftex_eachlineheight:D + \@@_primitive:NN \pdffilemoddate \pdftex_filemoddate:D + \@@_primitive:NN \pdffilesize \pdftex_filesize:D + \@@_primitive:NN \pdffirstlineheigh \pdftex_firstlineheight:D + \@@_primitive:NN \pdffontexpand \pdftex_fontexpand:D + \@@_primitive:NN \pdffontsize \pdftex_fontsize:D + \@@_primitive:NN \pdfignoreddimen \pdftex_ignoreddimen:D + \@@_primitive:NN \pdfinsertht \pdftex_insertht:D + \@@_primitive:NN \pdflastlinedepth \pdftex_lastlinedepth:D + \@@_primitive:NN \pdflastxpos \pdftex_lastxpos:D + \@@_primitive:NN \pdflastypos \pdftex_lastypos:D + \@@_primitive:NN \pdfmapfile \pdftex_mapfile:D + \@@_primitive:NN \pdfmapline \pdftex_mapline:D + \@@_primitive:NN \pdfmdfivesum \pdftex_mdfivesum:D + \@@_primitive:NN \pdfnoligatures \pdftex_noligatures:D + \@@_primitive:NN \pdfnormaldeviate \pdftex_normaldeviate:D + \@@_primitive:NN \pdfpageheight \pdftex_pageheight:D + \@@_primitive:NN \pdfpagewidth \pdftex_pagewidth:D + \@@_primitive:NN \pdfpkmode \pdftex_pkmode:D + \@@_primitive:NN \pdfpkresolution \pdftex_pkresolution:D + \@@_primitive:NN \pdfprimitive \pdftex_primitive:D + \@@_primitive:NN \pdfprotrudechars \pdftex_protrudechars:D + \@@_primitive:NN \pdfpxdimen \pdftex_pxdimen:D + \@@_primitive:NN \pdfrandomseed \pdftex_randomseed:D + \@@_primitive:NN \pdfsavepos \pdftex_savepos:D + \@@_primitive:NN \pdfstrcmp \pdftex_strcmp:D + \@@_primitive:NN \pdfsetrandomseed \pdftex_setrandomseed:D + \@@_primitive:NN \pdfshellescape \pdftex_shellescape:D + \@@_primitive:NN \pdftracingfonts \pdftex_tracingfonts:D + \@@_primitive:NN \pdfuniformdeviate \pdftex_uniformdeviate:D % \end{macrocode} % The version primitives are not related to PDF mode but are related to % \pdfTeX{} so retain the full prefix. % \begin{macrocode} - \@@_primitive:NN \pdftexbanner \pdftex_pdftexbanner:D - \@@_primitive:NN \pdftexrevision \pdftex_pdftexrevision:D - \@@_primitive:NN \pdftexversion \pdftex_pdftexversion:D + \@@_primitive:NN \pdftexbanner \pdftex_pdftexbanner:D + \@@_primitive:NN \pdftexrevision \pdftex_pdftexrevision:D + \@@_primitive:NN \pdftexversion \pdftex_pdftexversion:D % \end{macrocode} % These ones appear in \pdfTeX{} but don't have |pdf| in the name at all. % (\tn{synctex} is odd as it's really not from \pdfTeX{} but from SyncTeX!) % \begin{macrocode} - \@@_primitive:NN \efcode \pdftex_efcode:D - \@@_primitive:NN \ifincsname \pdftex_ifincsname:D - \@@_primitive:NN \leftmarginkern \pdftex_leftmarginkern:D - \@@_primitive:NN \letterspacefont \pdftex_letterspacefont:D - \@@_primitive:NN \lpcode \pdftex_lpcode:D - \@@_primitive:NN \quitvmode \pdftex_quitvmode:D - \@@_primitive:NN \rightmarginkern \pdftex_rightmarginkern:D - \@@_primitive:NN \rpcode \pdftex_rpcode:D - \@@_primitive:NN \synctex \pdftex_synctex:D - \@@_primitive:NN \tagcode \pdftex_tagcode:D + \@@_primitive:NN \efcode \pdftex_efcode:D + \@@_primitive:NN \ifincsname \pdftex_ifincsname:D + \@@_primitive:NN \leftmarginkern \pdftex_leftmarginkern:D + \@@_primitive:NN \letterspacefont \pdftex_letterspacefont:D + \@@_primitive:NN \lpcode \pdftex_lpcode:D + \@@_primitive:NN \quitvmode \pdftex_quitvmode:D + \@@_primitive:NN \rightmarginkern \pdftex_rightmarginkern:D + \@@_primitive:NN \rpcode \pdftex_rpcode:D + \@@_primitive:NN \synctex \pdftex_synctex:D + \@@_primitive:NN \tagcode \pdftex_tagcode:D % \end{macrocode} % Post \pdfTeX{} primitive availability gets more complex. Both \XeTeX{} and % \LuaTeX{} have varying names for some primitives from \pdfTeX{}. Particularly @@ -708,210 +708,236 @@ % into the \enquote{base} name. A few cross-compatibility names which lack % the |pdf| of the original are handled later. % \begin{macrocode} - \@@_primitive:NN \suppressfontnotfounderror \xetex_suppressfontnotfounderror:D - \@@_primitive:NN \XeTeXcharclass \xetex_charclass:D - \@@_primitive:NN \XeTeXcharglyph \xetex_charglyph:D - \@@_primitive:NN \XeTeXcountfeatures \xetex_countfeatures:D - \@@_primitive:NN \XeTeXcountglyphs \xetex_countglyphs:D - \@@_primitive:NN \XeTeXcountselectors \xetex_countselectors:D - \@@_primitive:NN \XeTeXcountvariations \xetex_countvariations:D - \@@_primitive:NN \XeTeXdefaultencoding \xetex_defaultencoding:D - \@@_primitive:NN \XeTeXdashbreakstate \xetex_dashbreakstate:D - \@@_primitive:NN \XeTeXfeaturecode \xetex_featurecode:D - \@@_primitive:NN \XeTeXfeaturename \xetex_featurename:D - \@@_primitive:NN \XeTeXfindfeaturebyname \xetex_findfeaturebyname:D - \@@_primitive:NN \XeTeXfindselectorbyname \xetex_findselectorbyname:D - \@@_primitive:NN \XeTeXfindvariationbyname \xetex_findvariationbyname:D - \@@_primitive:NN \XeTeXfirstfontchar \xetex_firstfontchar:D - \@@_primitive:NN \XeTeXfonttype \xetex_fonttype:D - \@@_primitive:NN \XeTeXgenerateactualtext \xetex_generateactualtext:D - \@@_primitive:NN \XeTeXglyph \xetex_glyph:D - \@@_primitive:NN \XeTeXglyphbounds \xetex_glyphbounds:D - \@@_primitive:NN \XeTeXglyphindex \xetex_glyphindex:D - \@@_primitive:NN \XeTeXglyphname \xetex_glyphname:D - \@@_primitive:NN \XeTeXinputencoding \xetex_inputencoding:D - \@@_primitive:NN \XeTeXinputnormalization \xetex_inputnormalization:D - \@@_primitive:NN \XeTeXinterchartokenstate \xetex_interchartokenstate:D - \@@_primitive:NN \XeTeXinterchartoks \xetex_interchartoks:D - \@@_primitive:NN \XeTeXisdefaultselector \xetex_isdefaultselector:D - \@@_primitive:NN \XeTeXisexclusivefeature \xetex_isexclusivefeature:D - \@@_primitive:NN \XeTeXlastfontchar \xetex_lastfontchar:D - \@@_primitive:NN \XeTeXlinebreakskip \xetex_linebreakskip:D - \@@_primitive:NN \XeTeXlinebreaklocale \xetex_linebreaklocale:D - \@@_primitive:NN \XeTeXlinebreakpenalty \xetex_linebreakpenalty:D - \@@_primitive:NN \XeTeXOTcountfeatures \xetex_OTcountfeatures:D - \@@_primitive:NN \XeTeXOTcountlanguages \xetex_OTcountlanguages:D - \@@_primitive:NN \XeTeXOTcountscripts \xetex_OTcountscripts:D - \@@_primitive:NN \XeTeXOTfeaturetag \xetex_OTfeaturetag:D - \@@_primitive:NN \XeTeXOTlanguagetag \xetex_OTlanguagetag:D - \@@_primitive:NN \XeTeXOTscripttag \xetex_OTscripttag:D - \@@_primitive:NN \XeTeXpdffile \xetex_pdffile:D - \@@_primitive:NN \XeTeXpdfpagecount \xetex_pdfpagecount:D - \@@_primitive:NN \XeTeXpicfile \xetex_picfile:D - \@@_primitive:NN \XeTeXselectorname \xetex_selectorname:D - \@@_primitive:NN \XeTeXtracingfonts \xetex_tracingfonts:D - \@@_primitive:NN \XeTeXupwardsmode \xetex_upwardsmode:D - \@@_primitive:NN \XeTeXuseglyphmetrics \xetex_useglyphmetrics:D - \@@_primitive:NN \XeTeXvariation \xetex_variation:D - \@@_primitive:NN \XeTeXvariationdefault \xetex_variationdefault:D - \@@_primitive:NN \XeTeXvariationmax \xetex_variationmax:D - \@@_primitive:NN \XeTeXvariationmin \xetex_variationmin:D - \@@_primitive:NN \XeTeXvariationname \xetex_variationname:D + \@@_primitive:NN \suppressfontnotfounderror + \xetex_suppressfontnotfounderror:D + \@@_primitive:NN \XeTeXcharclass \xetex_charclass:D + \@@_primitive:NN \XeTeXcharglyph \xetex_charglyph:D + \@@_primitive:NN \XeTeXcountfeatures \xetex_countfeatures:D + \@@_primitive:NN \XeTeXcountglyphs \xetex_countglyphs:D + \@@_primitive:NN \XeTeXcountselectors \xetex_countselectors:D + \@@_primitive:NN \XeTeXcountvariations \xetex_countvariations:D + \@@_primitive:NN \XeTeXdefaultencoding \xetex_defaultencoding:D + \@@_primitive:NN \XeTeXdashbreakstate \xetex_dashbreakstate:D + \@@_primitive:NN \XeTeXfeaturecode \xetex_featurecode:D + \@@_primitive:NN \XeTeXfeaturename \xetex_featurename:D + \@@_primitive:NN \XeTeXfindfeaturebyname + \xetex_findfeaturebyname:D + \@@_primitive:NN \XeTeXfindselectorbyname + \xetex_findselectorbyname:D + \@@_primitive:NN \XeTeXfindvariationbyname + \xetex_findvariationbyname:D + \@@_primitive:NN \XeTeXfirstfontchar \xetex_firstfontchar:D + \@@_primitive:NN \XeTeXfonttype \xetex_fonttype:D + \@@_primitive:NN \XeTeXgenerateactualtext + \xetex_generateactualtext:D + \@@_primitive:NN \XeTeXglyph \xetex_glyph:D + \@@_primitive:NN \XeTeXglyphbounds \xetex_glyphbounds:D + \@@_primitive:NN \XeTeXglyphindex \xetex_glyphindex:D + \@@_primitive:NN \XeTeXglyphname \xetex_glyphname:D + \@@_primitive:NN \XeTeXinputencoding \xetex_inputencoding:D + \@@_primitive:NN \XeTeXinputnormalization + \xetex_inputnormalization:D + \@@_primitive:NN \XeTeXinterchartokenstate + \xetex_interchartokenstate:D + \@@_primitive:NN \XeTeXinterchartoks \xetex_interchartoks:D + \@@_primitive:NN \XeTeXisdefaultselector + \xetex_isdefaultselector:D + \@@_primitive:NN \XeTeXisexclusivefeature + \xetex_isexclusivefeature:D + \@@_primitive:NN \XeTeXlastfontchar \xetex_lastfontchar:D + \@@_primitive:NN \XeTeXlinebreakskip \xetex_linebreakskip:D + \@@_primitive:NN \XeTeXlinebreaklocale \xetex_linebreaklocale:D + \@@_primitive:NN \XeTeXlinebreakpenalty \xetex_linebreakpenalty:D + \@@_primitive:NN \XeTeXOTcountfeatures \xetex_OTcountfeatures:D + \@@_primitive:NN \XeTeXOTcountlanguages \xetex_OTcountlanguages:D + \@@_primitive:NN \XeTeXOTcountscripts \xetex_OTcountscripts:D + \@@_primitive:NN \XeTeXOTfeaturetag \xetex_OTfeaturetag:D + \@@_primitive:NN \XeTeXOTlanguagetag \xetex_OTlanguagetag:D + \@@_primitive:NN \XeTeXOTscripttag \xetex_OTscripttag:D + \@@_primitive:NN \XeTeXpdffile \xetex_pdffile:D + \@@_primitive:NN \XeTeXpdfpagecount \xetex_pdfpagecount:D + \@@_primitive:NN \XeTeXpicfile \xetex_picfile:D + \@@_primitive:NN \XeTeXselectorname \xetex_selectorname:D + \@@_primitive:NN \XeTeXtracingfonts \xetex_tracingfonts:D + \@@_primitive:NN \XeTeXupwardsmode \xetex_upwardsmode:D + \@@_primitive:NN \XeTeXuseglyphmetrics \xetex_useglyphmetrics:D + \@@_primitive:NN \XeTeXvariation \xetex_variation:D + \@@_primitive:NN \XeTeXvariationdefault \xetex_variationdefault:D + \@@_primitive:NN \XeTeXvariationmax \xetex_variationmax:D + \@@_primitive:NN \XeTeXvariationmin \xetex_variationmin:D + \@@_primitive:NN \XeTeXvariationname \xetex_variationname:D % \end{macrocode} % The version primitives retain |XeTeX|. % \begin{macrocode} - \@@_primitive:NN \XeTeXrevision \xetex_XeTeXrevision:D - \@@_primitive:NN \XeTeXversion \xetex_XeTeXversion:D + \@@_primitive:NN \XeTeXrevision \xetex_XeTeXrevision:D + \@@_primitive:NN \XeTeXversion \xetex_XeTeXversion:D % \end{macrocode} % Primitives from \pdfTeX{} that \XeTeX{} renames: also helps with % \LuaTeX{}. % \begin{macrocode} - \@@_primitive:NN \mdfivesum \pdftex_mdfivesum:D - \@@_primitive:NN \ifprimitive \pdftex_ifprimitive:D - \@@_primitive:NN \primitive \pdftex_primitive:D - \@@_primitive:NN \shellescape \pdftex_shellescape:D + \@@_primitive:NN \mdfivesum \pdftex_mdfivesum:D + \@@_primitive:NN \ifprimitive \pdftex_ifprimitive:D + \@@_primitive:NN \primitive \pdftex_primitive:D + \@@_primitive:NN \shellescape \pdftex_shellescape:D % \end{macrocode} % Primitives from \LuaTeX{}, some of which have been ported back to % \XeTeX{}. Notice that \tn{expanded} was intended for \pdfTeX{}~1.50 but % as that was not released we call this a \LuaTeX{} primitive. % \begin{macrocode} - \@@_primitive:NN \alignmark \luatex_alignmark:D - \@@_primitive:NN \aligntab \luatex_aligntab:D - \@@_primitive:NN \attribute \luatex_attribute:D - \@@_primitive:NN \attributedef \luatex_attributedef:D - \@@_primitive:NN \automaticdiscretionary \luatex_automaticdiscretionary:D - \@@_primitive:NN \automatichyphenmode \luatex_automatichyphenmode:D - \@@_primitive:NN \automatichyphenpenalty \luatex_automatichyphenpenalty:D - \@@_primitive:NN \begincsname \luatex_begincsname:D - \@@_primitive:NN \breakafterdirmode \luatex_breakafterdirmode:D - \@@_primitive:NN \catcodetable \luatex_catcodetable:D - \@@_primitive:NN \clearmarks \luatex_clearmarks:D - \@@_primitive:NN \crampeddisplaystyle \luatex_crampeddisplaystyle:D - \@@_primitive:NN \crampedscriptscriptstyle \luatex_crampedscriptscriptstyle:D - \@@_primitive:NN \crampedscriptstyle \luatex_crampedscriptstyle:D - \@@_primitive:NN \crampedtextstyle \luatex_crampedtextstyle:D - \@@_primitive:NN \directlua \luatex_directlua:D - \@@_primitive:NN \dviextension \luatex_dviextension:D - \@@_primitive:NN \dvifeedback \luatex_dvifeedback:D - \@@_primitive:NN \dvivariable \luatex_dvivariable:D - \@@_primitive:NN \etoksapp \luatex_etoksapp:D - \@@_primitive:NN \etokspre \luatex_etokspre:D - \@@_primitive:NN \explicithyphenpenalty \luatex_explicithyphenpenalty:D - \@@_primitive:NN \expanded \luatex_expanded:D - \@@_primitive:NN \explicitdiscretionary \luatex_explicitdiscretionary:D - \@@_primitive:NN \firstvalidlanguage \luatex_firstvalidlanguage:D - \@@_primitive:NN \fontid \luatex_fontid:D - \@@_primitive:NN \formatname \luatex_formatname:D - \@@_primitive:NN \hjcode \luatex_hjcode:D - \@@_primitive:NN \hpack \luatex_hpack:D - \@@_primitive:NN \hyphenationbounds \luatex_hyphenationbounds:D - \@@_primitive:NN \hyphenationmin \luatex_hyphenationmin:D - \@@_primitive:NN \hyphenpenaltymode \luatex_hyphenpenaltymode:D - \@@_primitive:NN \gleaders \luatex_gleaders:D - \@@_primitive:NN \initcatcodetable \luatex_initcatcodetable:D - \@@_primitive:NN \lastnamedcs \luatex_lastnamedcs:D - \@@_primitive:NN \latelua \luatex_latelua:D - \@@_primitive:NN \letcharcode \luatex_letcharcode:D - \@@_primitive:NN \luaescapestring \luatex_luaescapestring:D - \@@_primitive:NN \luafunction \luatex_luafunction:D - \@@_primitive:NN \luatexbanner \luatex_luatexbanner:D - \@@_primitive:NN \luatexrevision \luatex_luatexrevision:D - \@@_primitive:NN \luatexversion \luatex_luatexversion:D - \@@_primitive:NN \mathdelimitersmode \luatex_mathdelimitersmode:D - \@@_primitive:NN \mathdisplayskipmode \luatex_mathdisplayskipmode:D - \@@_primitive:NN \matheqnogapstep \luatex_matheqnogapstep:D - \@@_primitive:NN \mathnolimitsmode \luatex_mathnolimitsmode:D - \@@_primitive:NN \mathoption \luatex_mathoption:D - \@@_primitive:NN \mathpenaltiesmode \luatex_mathpenaltiesmode:D - \@@_primitive:NN \mathrulesfam \luatex_mathrulesfam:D - \@@_primitive:NN \mathscriptsmode \luatex_mathscriptsmode:D - \@@_primitive:NN \mathscriptboxmode \luatex_mathscriptboxmode:D - \@@_primitive:NN \mathstyle \luatex_mathstyle:D - \@@_primitive:NN \mathsurroundmode \luatex_mathsurroundmode:D - \@@_primitive:NN \mathsurroundskip \luatex_mathsurroundskip:D - \@@_primitive:NN \nohrule \luatex_nohrule:D - \@@_primitive:NN \nokerns \luatex_nokerns:D - \@@_primitive:NN \noligs \luatex_noligs:D - \@@_primitive:NN \nospaces \luatex_nospaces:D - \@@_primitive:NN \novrule \luatex_novrule:D - \@@_primitive:NN \outputbox \luatex_outputbox:D - \@@_primitive:NN \pagebottomoffset \luatex_pagebottomoffset:D - \@@_primitive:NN \pageleftoffset \luatex_pageleftoffset:D - \@@_primitive:NN \pagerightoffset \luatex_pagerightoffset:D - \@@_primitive:NN \pagetopoffset \luatex_pagetopoffset:D - \@@_primitive:NN \pdfextension \luatex_pdfextension:D - \@@_primitive:NN \pdffeedback \luatex_pdffeedback:D - \@@_primitive:NN \pdfvariable \luatex_pdfvariable:D - \@@_primitive:NN \postexhyphenchar \luatex_postexhyphenchar:D - \@@_primitive:NN \posthyphenchar \luatex_posthyphenchar:D - \@@_primitive:NN \prebinoppenalty \luatex_prebinoppenalty:D - \@@_primitive:NN \predisplaygapfactor \luatex_predisplaygapfactor:D - \@@_primitive:NN \preexhyphenchar \luatex_preexhyphenchar:D - \@@_primitive:NN \prehyphenchar \luatex_prehyphenchar:D - \@@_primitive:NN \prerelpenalty \luatex_prerelpenalty:D - \@@_primitive:NN \savecatcodetable \luatex_savecatcodetable:D - \@@_primitive:NN \scantextokens \luatex_scantextokens:D - \@@_primitive:NN \setfontid \luatex_setfontid:D - \@@_primitive:NN \shapemode \luatex_shapemode:D - \@@_primitive:NN \suppressifcsnameerror \luatex_suppressifcsnameerror:D - \@@_primitive:NN \suppresslongerror \luatex_suppresslongerror:D - \@@_primitive:NN \suppressmathparerror \luatex_suppressmathparerror:D - \@@_primitive:NN \suppressoutererror \luatex_suppressoutererror:D - \@@_primitive:NN \suppressprimitiveerror \luatex_suppressprimitiveerror:D - \@@_primitive:NN \toksapp \luatex_toksapp:D - \@@_primitive:NN \tokspre \luatex_tokspre:D - \@@_primitive:NN \tpack \luatex_tpack:D - \@@_primitive:NN \vpack \luatex_vpack:D + \@@_primitive:NN \alignmark \luatex_alignmark:D + \@@_primitive:NN \aligntab \luatex_aligntab:D + \@@_primitive:NN \attribute \luatex_attribute:D + \@@_primitive:NN \attributedef \luatex_attributedef:D + \@@_primitive:NN \automaticdiscretionary + \luatex_automaticdiscretionary:D + \@@_primitive:NN \automatichyphenmode + \luatex_automatichyphenmode:D + \@@_primitive:NN \automatichyphenpenalty + \luatex_automatichyphenpenalty:D + \@@_primitive:NN \begincsname \luatex_begincsname:D + \@@_primitive:NN \breakafterdirmode \luatex_breakafterdirmode:D + \@@_primitive:NN \catcodetable \luatex_catcodetable:D + \@@_primitive:NN \clearmarks \luatex_clearmarks:D + \@@_primitive:NN \crampeddisplaystyle + \luatex_crampeddisplaystyle:D + \@@_primitive:NN \crampedscriptscriptstyle + \luatex_crampedscriptscriptstyle:D + \@@_primitive:NN \crampedscriptstyle \luatex_crampedscriptstyle:D + \@@_primitive:NN \crampedtextstyle \luatex_crampedtextstyle:D + \@@_primitive:NN \directlua \luatex_directlua:D + \@@_primitive:NN \dviextension \luatex_dviextension:D + \@@_primitive:NN \dvifeedback \luatex_dvifeedback:D + \@@_primitive:NN \dvivariable \luatex_dvivariable:D + \@@_primitive:NN \etoksapp \luatex_etoksapp:D + \@@_primitive:NN \etokspre \luatex_etokspre:D + \@@_primitive:NN \explicithyphenpenalty + \luatex_explicithyphenpenalty:D + \@@_primitive:NN \expanded \luatex_expanded:D + \@@_primitive:NN \explicitdiscretionary + \luatex_explicitdiscretionary:D + \@@_primitive:NN \firstvalidlanguage \luatex_firstvalidlanguage:D + \@@_primitive:NN \fontid \luatex_fontid:D + \@@_primitive:NN \formatname \luatex_formatname:D + \@@_primitive:NN \hjcode \luatex_hjcode:D + \@@_primitive:NN \hpack \luatex_hpack:D + \@@_primitive:NN \hyphenationbounds \luatex_hyphenationbounds:D + \@@_primitive:NN \hyphenationmin \luatex_hyphenationmin:D + \@@_primitive:NN \hyphenpenaltymode \luatex_hyphenpenaltymode:D + \@@_primitive:NN \gleaders \luatex_gleaders:D + \@@_primitive:NN \initcatcodetable \luatex_initcatcodetable:D + \@@_primitive:NN \lastnamedcs \luatex_lastnamedcs:D + \@@_primitive:NN \latelua \luatex_latelua:D + \@@_primitive:NN \letcharcode \luatex_letcharcode:D + \@@_primitive:NN \luaescapestring \luatex_luaescapestring:D + \@@_primitive:NN \luafunction \luatex_luafunction:D + \@@_primitive:NN \luatexbanner \luatex_luatexbanner:D + \@@_primitive:NN \luatexrevision \luatex_luatexrevision:D + \@@_primitive:NN \luatexversion \luatex_luatexversion:D + \@@_primitive:NN \mathdelimitersmode \luatex_mathdelimitersmode:D + \@@_primitive:NN \mathdisplayskipmode + \luatex_mathdisplayskipmode:D + \@@_primitive:NN \matheqnogapstep \luatex_matheqnogapstep:D + \@@_primitive:NN \mathnolimitsmode \luatex_mathnolimitsmode:D + \@@_primitive:NN \mathoption \luatex_mathoption:D + \@@_primitive:NN \mathpenaltiesmode \luatex_mathpenaltiesmode:D + \@@_primitive:NN \mathrulesfam \luatex_mathrulesfam:D + \@@_primitive:NN \mathscriptsmode \luatex_mathscriptsmode:D + \@@_primitive:NN \mathscriptboxmode \luatex_mathscriptboxmode:D + \@@_primitive:NN \mathstyle \luatex_mathstyle:D + \@@_primitive:NN \mathsurroundmode \luatex_mathsurroundmode:D + \@@_primitive:NN \mathsurroundskip \luatex_mathsurroundskip:D + \@@_primitive:NN \nohrule \luatex_nohrule:D + \@@_primitive:NN \nokerns \luatex_nokerns:D + \@@_primitive:NN \noligs \luatex_noligs:D + \@@_primitive:NN \nospaces \luatex_nospaces:D + \@@_primitive:NN \novrule \luatex_novrule:D + \@@_primitive:NN \outputbox \luatex_outputbox:D + \@@_primitive:NN \pagebottomoffset \luatex_pagebottomoffset:D + \@@_primitive:NN \pageleftoffset \luatex_pageleftoffset:D + \@@_primitive:NN \pagerightoffset \luatex_pagerightoffset:D + \@@_primitive:NN \pagetopoffset \luatex_pagetopoffset:D + \@@_primitive:NN \pdfextension \luatex_pdfextension:D + \@@_primitive:NN \pdffeedback \luatex_pdffeedback:D + \@@_primitive:NN \pdfvariable \luatex_pdfvariable:D + \@@_primitive:NN \postexhyphenchar \luatex_postexhyphenchar:D + \@@_primitive:NN \posthyphenchar \luatex_posthyphenchar:D + \@@_primitive:NN \prebinoppenalty \luatex_prebinoppenalty:D + \@@_primitive:NN \predisplaygapfactor + \luatex_predisplaygapfactor:D + \@@_primitive:NN \preexhyphenchar \luatex_preexhyphenchar:D + \@@_primitive:NN \prehyphenchar \luatex_prehyphenchar:D + \@@_primitive:NN \prerelpenalty \luatex_prerelpenalty:D + \@@_primitive:NN \savecatcodetable \luatex_savecatcodetable:D + \@@_primitive:NN \scantextokens \luatex_scantextokens:D + \@@_primitive:NN \setfontid \luatex_setfontid:D + \@@_primitive:NN \shapemode \luatex_shapemode:D + \@@_primitive:NN \suppressifcsnameerror + \luatex_suppressifcsnameerror:D + \@@_primitive:NN \suppresslongerror \luatex_suppresslongerror:D + \@@_primitive:NN \suppressmathparerror + \luatex_suppressmathparerror:D + \@@_primitive:NN \suppressoutererror \luatex_suppressoutererror:D + \@@_primitive:NN \suppressprimitiveerror + \luatex_suppressprimitiveerror:D + \@@_primitive:NN \toksapp \luatex_toksapp:D + \@@_primitive:NN \tokspre \luatex_tokspre:D + \@@_primitive:NN \tpack \luatex_tpack:D + \@@_primitive:NN \vpack \luatex_vpack:D % \end{macrocode} % Slightly more awkward are the directional primitives in \LuaTeX{}. These % come from Omega/Aleph, but we do not support those engines and % so it seems most sensible to treat them as \LuaTeX{} primitives for prefix % purposes. One here is \enquote{new} but fits into the general set. % \begin{macrocode} - \@@_primitive:NN \bodydir \luatex_bodydir:D - \@@_primitive:NN \boxdir \luatex_boxdir:D - \@@_primitive:NN \leftghost \luatex_leftghost:D - \@@_primitive:NN \linedir \luatex_linedir:D - \@@_primitive:NN \localbrokenpenalty \luatex_localbrokenpenalty:D - \@@_primitive:NN \localinterlinepenalty \luatex_localinterlinepenalty:D - \@@_primitive:NN \localleftbox \luatex_localleftbox:D - \@@_primitive:NN \localrightbox \luatex_localrightbox:D - \@@_primitive:NN \mathdir \luatex_mathdir:D - \@@_primitive:NN \pagedir \luatex_pagedir:D - \@@_primitive:NN \pardir \luatex_pardir:D - \@@_primitive:NN \rightghost \luatex_rightghost:D - \@@_primitive:NN \textdir \luatex_textdir:D + \@@_primitive:NN \bodydir \luatex_bodydir:D + \@@_primitive:NN \boxdir \luatex_boxdir:D + \@@_primitive:NN \leftghost \luatex_leftghost:D + \@@_primitive:NN \linedir \luatex_linedir:D + \@@_primitive:NN \localbrokenpenalty \luatex_localbrokenpenalty:D + \@@_primitive:NN \localinterlinepenalty + \luatex_localinterlinepenalty:D + \@@_primitive:NN \localleftbox \luatex_localleftbox:D + \@@_primitive:NN \localrightbox \luatex_localrightbox:D + \@@_primitive:NN \mathdir \luatex_mathdir:D + \@@_primitive:NN \pagedir \luatex_pagedir:D + \@@_primitive:NN \pardir \luatex_pardir:D + \@@_primitive:NN \rightghost \luatex_rightghost:D + \@@_primitive:NN \textdir \luatex_textdir:D % \end{macrocode} % Primitives from \pdfTeX{} that \LuaTeX{} renames. % \begin{macrocode} - \@@_primitive:NN \adjustspacing \pdftex_adjustspacing:D - \@@_primitive:NN \copyfont \pdftex_copyfont:D - \@@_primitive:NN \draftmode \pdftex_draftmode:D - \@@_primitive:NN \expandglyphsinfont \pdftex_fontexpand:D - \@@_primitive:NN \ifabsdim \pdftex_ifabsdim:D - \@@_primitive:NN \ifabsnum \pdftex_ifabsnum:D - \@@_primitive:NN \ignoreligaturesinfont \pdftex_ignoreligaturesinfont:D - \@@_primitive:NN \insertht \pdftex_insertht:D - \@@_primitive:NN \lastsavedboxresourceindex \pdftex_pdflastxform:D - \@@_primitive:NN \lastsavedimageresourceindex \pdftex_pdflastximage:D - \@@_primitive:NN \lastsavedimageresourcepages \pdftex_pdflastximagepages:D - \@@_primitive:NN \lastxpos \pdftex_lastxpos:D - \@@_primitive:NN \lastypos \pdftex_lastypos:D - \@@_primitive:NN \normaldeviate \pdftex_normaldeviate:D - \@@_primitive:NN \outputmode \pdftex_pdfoutput:D - \@@_primitive:NN \pageheight \pdftex_pageheight:D - \@@_primitive:NN \pagewidth \pdftex_pagewith:D - \@@_primitive:NN \protrudechars \pdftex_protrudechars:D - \@@_primitive:NN \pxdimen \pdftex_pxdimen:D - \@@_primitive:NN \randomseed \pdftex_randomseed:D - \@@_primitive:NN \useboxresource \pdftex_pdfrefxform:D - \@@_primitive:NN \useimageresource \pdftex_pdfrefximage:D - \@@_primitive:NN \savepos \pdftex_savepos:D - \@@_primitive:NN \saveboxresource \pdftex_pdfxform:D - \@@_primitive:NN \saveimageresource \pdftex_pdfximage:D - \@@_primitive:NN \setrandomseed \pdftex_setrandomseed:D - \@@_primitive:NN \tracingfonts \pdftex_tracingfonts:D - \@@_primitive:NN \uniformdeviate \pdftex_uniformdeviate:D + \@@_primitive:NN \adjustspacing \pdftex_adjustspacing:D + \@@_primitive:NN \copyfont \pdftex_copyfont:D + \@@_primitive:NN \draftmode \pdftex_draftmode:D + \@@_primitive:NN \expandglyphsinfont \pdftex_fontexpand:D + \@@_primitive:NN \ifabsdim \pdftex_ifabsdim:D + \@@_primitive:NN \ifabsnum \pdftex_ifabsnum:D + \@@_primitive:NN \ignoreligaturesinfont + \pdftex_ignoreligaturesinfont:D + \@@_primitive:NN \insertht \pdftex_insertht:D + \@@_primitive:NN \lastsavedboxresourceindex + \pdftex_pdflastxform:D + \@@_primitive:NN \lastsavedimageresourceindex + \pdftex_pdflastximage:D + \@@_primitive:NN \lastsavedimageresourcepages + \pdftex_pdflastximagepages:D + \@@_primitive:NN \lastxpos \pdftex_lastxpos:D + \@@_primitive:NN \lastypos \pdftex_lastypos:D + \@@_primitive:NN \normaldeviate \pdftex_normaldeviate:D + \@@_primitive:NN \outputmode \pdftex_pdfoutput:D + \@@_primitive:NN \pageheight \pdftex_pageheight:D + \@@_primitive:NN \pagewidth \pdftex_pagewith:D + \@@_primitive:NN \protrudechars \pdftex_protrudechars:D + \@@_primitive:NN \pxdimen \pdftex_pxdimen:D + \@@_primitive:NN \randomseed \pdftex_randomseed:D + \@@_primitive:NN \useboxresource \pdftex_pdfrefxform:D + \@@_primitive:NN \useimageresource \pdftex_pdfrefximage:D + \@@_primitive:NN \savepos \pdftex_savepos:D + \@@_primitive:NN \saveboxresource \pdftex_pdfxform:D + \@@_primitive:NN \saveimageresource \pdftex_pdfximage:D + \@@_primitive:NN \setrandomseed \pdftex_setrandomseed:D + \@@_primitive:NN \tracingfonts \pdftex_tracingfonts:D + \@@_primitive:NN \uniformdeviate \pdftex_uniformdeviate:D % \end{macrocode} % The set of Unicode math primitives were introduced by \XeTeX{} and \LuaTeX{} % in a somewhat complex fashion: a few first as |\XeTeX...| which were then @@ -921,201 +947,225 @@ % and drop |\U(math)| from the names. Where there is a related \TeX{}90 % primitive or where it really seems required we keep the |math| part of the name. % \begin{macrocode} - \@@_primitive:NN \Uchar \utex_char:D - \@@_primitive:NN \Ucharcat \utex_charcat:D - \@@_primitive:NN \Udelcode \utex_delcode:D - \@@_primitive:NN \Udelcodenum \utex_delcodenum:D - \@@_primitive:NN \Udelimiter \utex_delimiter:D - \@@_primitive:NN \Udelimiterover \utex_delimiterover:D - \@@_primitive:NN \Udelimiterunder \utex_delimiterunder:D - \@@_primitive:NN \Uhextensible \utex_hextensible:D - \@@_primitive:NN \Umathaccent \utex_mathaccent:D - \@@_primitive:NN \Umathaxis \utex_mathaxis:D - \@@_primitive:NN \Umathbinbinspacing \utex_binbinspacing:D - \@@_primitive:NN \Umathbinclosespacing \utex_binclosespacing:D - \@@_primitive:NN \Umathbininnerspacing \utex_bininnerspacing:D - \@@_primitive:NN \Umathbinopenspacing \utex_binopenspacing:D - \@@_primitive:NN \Umathbinopspacing \utex_binopspacing:D - \@@_primitive:NN \Umathbinordspacing \utex_binordspacing:D - \@@_primitive:NN \Umathbinpunctspacing \utex_binpunctspacing:D - \@@_primitive:NN \Umathbinrelspacing \utex_binrelspacing:D - \@@_primitive:NN \Umathchar \utex_mathchar:D - \@@_primitive:NN \Umathcharclass \utex_mathcharclass:D - \@@_primitive:NN \Umathchardef \utex_mathchardef:D - \@@_primitive:NN \Umathcharfam \utex_mathcharfam:D - \@@_primitive:NN \Umathcharnum \utex_mathcharnum:D - \@@_primitive:NN \Umathcharnumdef \utex_mathcharnumdef:D - \@@_primitive:NN \Umathcharslot \utex_mathcharslot:D - \@@_primitive:NN \Umathclosebinspacing \utex_closebinspacing:D - \@@_primitive:NN \Umathcloseclosespacing \utex_closeclosespacing:D - \@@_primitive:NN \Umathcloseinnerspacing \utex_closeinnerspacing:D - \@@_primitive:NN \Umathcloseopenspacing \utex_closeopenspacing:D - \@@_primitive:NN \Umathcloseopspacing \utex_closeopspacing:D - \@@_primitive:NN \Umathcloseordspacing \utex_closeordspacing:D - \@@_primitive:NN \Umathclosepunctspacing \utex_closepunctspacing:D - \@@_primitive:NN \Umathcloserelspacing \utex_closerelspacing:D - \@@_primitive:NN \Umathcode \utex_mathcode:D - \@@_primitive:NN \Umathcodenum \utex_mathcodenum:D - \@@_primitive:NN \Umathconnectoroverlapmin \utex_connectoroverlapmin:D - \@@_primitive:NN \Umathfractiondelsize \utex_fractiondelsize:D - \@@_primitive:NN \Umathfractiondenomdown \utex_fractiondenomdown:D - \@@_primitive:NN \Umathfractiondenomvgap \utex_fractiondenomvgap:D - \@@_primitive:NN \Umathfractionnumup \utex_fractionnumup:D - \@@_primitive:NN \Umathfractionnumvgap \utex_fractionnumvgap:D - \@@_primitive:NN \Umathfractionrule \utex_fractionrule:D - \@@_primitive:NN \Umathinnerbinspacing \utex_innerbinspacing:D - \@@_primitive:NN \Umathinnerclosespacing \utex_innerclosespacing:D - \@@_primitive:NN \Umathinnerinnerspacing \utex_innerinnerspacing:D - \@@_primitive:NN \Umathinneropenspacing \utex_inneropenspacing:D - \@@_primitive:NN \Umathinneropspacing \utex_inneropspacing:D - \@@_primitive:NN \Umathinnerordspacing \utex_innerordspacing:D - \@@_primitive:NN \Umathinnerpunctspacing \utex_innerpunctspacing:D - \@@_primitive:NN \Umathinnerrelspacing \utex_innerrelspacing:D - \@@_primitive:NN \Umathlimitabovebgap \utex_limitabovebgap:D - \@@_primitive:NN \Umathlimitabovekern \utex_limitabovekern:D - \@@_primitive:NN \Umathlimitabovevgap \utex_limitabovevgap:D - \@@_primitive:NN \Umathlimitbelowbgap \utex_limitbelowbgap:D - \@@_primitive:NN \Umathlimitbelowkern \utex_limitbelowkern:D - \@@_primitive:NN \Umathlimitbelowvgap \utex_limitbelowvgap:D - \@@_primitive:NN \Umathnolimitsubfactor \utex_nolimitsubfactor:D - \@@_primitive:NN \Umathnolimitsupfactor \utex_nolimitsupfactor:D - \@@_primitive:NN \Umathopbinspacing \utex_opbinspacing:D - \@@_primitive:NN \Umathopclosespacing \utex_opclosespacing:D - \@@_primitive:NN \Umathopenbinspacing \utex_openbinspacing:D - \@@_primitive:NN \Umathopenclosespacing \utex_openclosespacing:D - \@@_primitive:NN \Umathopeninnerspacing \utex_openinnerspacing:D - \@@_primitive:NN \Umathopenopenspacing \utex_openopenspacing:D - \@@_primitive:NN \Umathopenopspacing \utex_openopspacing:D - \@@_primitive:NN \Umathopenordspacing \utex_openordspacing:D - \@@_primitive:NN \Umathopenpunctspacing \utex_openpunctspacing:D - \@@_primitive:NN \Umathopenrelspacing \utex_openrelspacing:D - \@@_primitive:NN \Umathoperatorsize \utex_operatorsize:D - \@@_primitive:NN \Umathopinnerspacing \utex_opinnerspacing:D - \@@_primitive:NN \Umathopopenspacing \utex_opopenspacing:D - \@@_primitive:NN \Umathopopspacing \utex_opopspacing:D - \@@_primitive:NN \Umathopordspacing \utex_opordspacing:D - \@@_primitive:NN \Umathoppunctspacing \utex_oppunctspacing:D - \@@_primitive:NN \Umathoprelspacing \utex_oprelspacing:D - \@@_primitive:NN \Umathordbinspacing \utex_ordbinspacing:D - \@@_primitive:NN \Umathordclosespacing \utex_ordclosespacing:D - \@@_primitive:NN \Umathordinnerspacing \utex_ordinnerspacing:D - \@@_primitive:NN \Umathordopenspacing \utex_ordopenspacing:D - \@@_primitive:NN \Umathordopspacing \utex_ordopspacing:D - \@@_primitive:NN \Umathordordspacing \utex_ordordspacing:D - \@@_primitive:NN \Umathordpunctspacing \utex_ordpunctspacing:D - \@@_primitive:NN \Umathordrelspacing \utex_ordrelspacing:D - \@@_primitive:NN \Umathoverbarkern \utex_overbarkern:D - \@@_primitive:NN \Umathoverbarrule \utex_overbarrule:D - \@@_primitive:NN \Umathoverbarvgap \utex_overbarvgap:D - \@@_primitive:NN \Umathoverdelimiterbgap \utex_overdelimiterbgap:D - \@@_primitive:NN \Umathoverdelimitervgap \utex_overdelimitervgap:D - \@@_primitive:NN \Umathpunctbinspacing \utex_punctbinspacing:D - \@@_primitive:NN \Umathpunctclosespacing \utex_punctclosespacing:D - \@@_primitive:NN \Umathpunctinnerspacing \utex_punctinnerspacing:D - \@@_primitive:NN \Umathpunctopenspacing \utex_punctopenspacing:D - \@@_primitive:NN \Umathpunctopspacing \utex_punctopspacing:D - \@@_primitive:NN \Umathpunctordspacing \utex_punctordspacing:D - \@@_primitive:NN \Umathpunctpunctspacing \utex_punctpunctspacing:D - \@@_primitive:NN \Umathpunctrelspacing \utex_punctrelspacing:D - \@@_primitive:NN \Umathquad \utex_quad:D - \@@_primitive:NN \Umathradicaldegreeafter \utex_radicaldegreeafter:D - \@@_primitive:NN \Umathradicaldegreebefore \utex_radicaldegreebefore:D - \@@_primitive:NN \Umathradicaldegreeraise \utex_radicaldegreeraise:D - \@@_primitive:NN \Umathradicalkern \utex_radicalkern:D - \@@_primitive:NN \Umathradicalrule \utex_radicalrule:D - \@@_primitive:NN \Umathradicalvgap \utex_radicalvgap:D - \@@_primitive:NN \Umathrelbinspacing \utex_relbinspacing:D - \@@_primitive:NN \Umathrelclosespacing \utex_relclosespacing:D - \@@_primitive:NN \Umathrelinnerspacing \utex_relinnerspacing:D - \@@_primitive:NN \Umathrelopenspacing \utex_relopenspacing:D - \@@_primitive:NN \Umathrelopspacing \utex_relopspacing:D - \@@_primitive:NN \Umathrelordspacing \utex_relordspacing:D - \@@_primitive:NN \Umathrelpunctspacing \utex_relpunctspacing:D - \@@_primitive:NN \Umathrelrelspacing \utex_relrelspacing:D - \@@_primitive:NN \Umathskewedfractionhgap \utex_skewedfractionhgap:D - \@@_primitive:NN \Umathskewedfractionvgap \utex_skewedfractionvgap:D - \@@_primitive:NN \Umathspaceafterscript \utex_spaceafterscript:D - \@@_primitive:NN \Umathstackdenomdown \utex_stackdenomdown:D - \@@_primitive:NN \Umathstacknumup \utex_stacknumup:D - \@@_primitive:NN \Umathstackvgap \utex_stackvgap:D - \@@_primitive:NN \Umathsubshiftdown \utex_subshiftdown:D - \@@_primitive:NN \Umathsubshiftdrop \utex_subshiftdrop:D - \@@_primitive:NN \Umathsubsupshiftdown \utex_subsupshiftdown:D - \@@_primitive:NN \Umathsubsupvgap \utex_subsupvgap:D - \@@_primitive:NN \Umathsubtopmax \utex_subtopmax:D - \@@_primitive:NN \Umathsupbottommin \utex_supbottommin:D - \@@_primitive:NN \Umathsupshiftdrop \utex_supshiftdrop:D - \@@_primitive:NN \Umathsupshiftup \utex_supshiftup:D - \@@_primitive:NN \Umathsupsubbottommax \utex_supsubbottommax:D - \@@_primitive:NN \Umathunderbarkern \utex_underbarkern:D - \@@_primitive:NN \Umathunderbarrule \utex_underbarrule:D - \@@_primitive:NN \Umathunderbarvgap \utex_underbarvgap:D - \@@_primitive:NN \Umathunderdelimiterbgap \utex_underdelimiterbgap:D - \@@_primitive:NN \Umathunderdelimitervgap \utex_underdelimitervgap:D - \@@_primitive:NN \Unosubscript \utex_Unosubscript:D - \@@_primitive:NN \Unosuperscript \utex_Unosuperscript:D - \@@_primitive:NN \Uoverdelimiter \utex_overdelimiter:D - \@@_primitive:NN \Uradical \utex_radical:D - \@@_primitive:NN \Uroot \utex_root:D - \@@_primitive:NN \Uskewed \utex_skewed:D - \@@_primitive:NN \Uskewedwithdelims \utex_skewedwithdelims:D - \@@_primitive:NN \Ustack \utex_stack:D - \@@_primitive:NN \Ustartdisplaymath \utex_startdisplaymath:D - \@@_primitive:NN \Ustartmath \utex_startmath:D - \@@_primitive:NN \Ustopdisplaymath \utex_stopdisplaymath:D - \@@_primitive:NN \Ustopmath \utex_stopmath:D - \@@_primitive:NN \Usubscript \utex_subscript:D - \@@_primitive:NN \Usuperscript \utex_superscript:D - \@@_primitive:NN \Uunderdelimiter \utex_underdelimiter:D - \@@_primitive:NN \Uvextensible \utex_vextensible:D + \@@_primitive:NN \Uchar \utex_char:D + \@@_primitive:NN \Ucharcat \utex_charcat:D + \@@_primitive:NN \Udelcode \utex_delcode:D + \@@_primitive:NN \Udelcodenum \utex_delcodenum:D + \@@_primitive:NN \Udelimiter \utex_delimiter:D + \@@_primitive:NN \Udelimiterover \utex_delimiterover:D + \@@_primitive:NN \Udelimiterunder \utex_delimiterunder:D + \@@_primitive:NN \Uhextensible \utex_hextensible:D + \@@_primitive:NN \Umathaccent \utex_mathaccent:D + \@@_primitive:NN \Umathaxis \utex_mathaxis:D + \@@_primitive:NN \Umathbinbinspacing \utex_binbinspacing:D + \@@_primitive:NN \Umathbinclosespacing \utex_binclosespacing:D + \@@_primitive:NN \Umathbininnerspacing \utex_bininnerspacing:D + \@@_primitive:NN \Umathbinopenspacing \utex_binopenspacing:D + \@@_primitive:NN \Umathbinopspacing \utex_binopspacing:D + \@@_primitive:NN \Umathbinordspacing \utex_binordspacing:D + \@@_primitive:NN \Umathbinpunctspacing \utex_binpunctspacing:D + \@@_primitive:NN \Umathbinrelspacing \utex_binrelspacing:D + \@@_primitive:NN \Umathchar \utex_mathchar:D + \@@_primitive:NN \Umathcharclass \utex_mathcharclass:D + \@@_primitive:NN \Umathchardef \utex_mathchardef:D + \@@_primitive:NN \Umathcharfam \utex_mathcharfam:D + \@@_primitive:NN \Umathcharnum \utex_mathcharnum:D + \@@_primitive:NN \Umathcharnumdef \utex_mathcharnumdef:D + \@@_primitive:NN \Umathcharslot \utex_mathcharslot:D + \@@_primitive:NN \Umathclosebinspacing \utex_closebinspacing:D + \@@_primitive:NN \Umathcloseclosespacing + \utex_closeclosespacing:D + \@@_primitive:NN \Umathcloseinnerspacing + \utex_closeinnerspacing:D + \@@_primitive:NN \Umathcloseopenspacing \utex_closeopenspacing:D + \@@_primitive:NN \Umathcloseopspacing \utex_closeopspacing:D + \@@_primitive:NN \Umathcloseordspacing \utex_closeordspacing:D + \@@_primitive:NN \Umathclosepunctspacing + \utex_closepunctspacing:D + \@@_primitive:NN \Umathcloserelspacing \utex_closerelspacing:D + \@@_primitive:NN \Umathcode \utex_mathcode:D + \@@_primitive:NN \Umathcodenum \utex_mathcodenum:D + \@@_primitive:NN \Umathconnectoroverlapmin + \utex_connectoroverlapmin:D + \@@_primitive:NN \Umathfractiondelsize \utex_fractiondelsize:D + \@@_primitive:NN \Umathfractiondenomdown + \utex_fractiondenomdown:D + \@@_primitive:NN \Umathfractiondenomvgap + \utex_fractiondenomvgap:D + \@@_primitive:NN \Umathfractionnumup \utex_fractionnumup:D + \@@_primitive:NN \Umathfractionnumvgap \utex_fractionnumvgap:D + \@@_primitive:NN \Umathfractionrule \utex_fractionrule:D + \@@_primitive:NN \Umathinnerbinspacing \utex_innerbinspacing:D + \@@_primitive:NN \Umathinnerclosespacing + \utex_innerclosespacing:D + \@@_primitive:NN \Umathinnerinnerspacing + \utex_innerinnerspacing:D + \@@_primitive:NN \Umathinneropenspacing \utex_inneropenspacing:D + \@@_primitive:NN \Umathinneropspacing \utex_inneropspacing:D + \@@_primitive:NN \Umathinnerordspacing \utex_innerordspacing:D + \@@_primitive:NN \Umathinnerpunctspacing + \utex_innerpunctspacing:D + \@@_primitive:NN \Umathinnerrelspacing \utex_innerrelspacing:D + \@@_primitive:NN \Umathlimitabovebgap \utex_limitabovebgap:D + \@@_primitive:NN \Umathlimitabovekern \utex_limitabovekern:D + \@@_primitive:NN \Umathlimitabovevgap \utex_limitabovevgap:D + \@@_primitive:NN \Umathlimitbelowbgap \utex_limitbelowbgap:D + \@@_primitive:NN \Umathlimitbelowkern \utex_limitbelowkern:D + \@@_primitive:NN \Umathlimitbelowvgap \utex_limitbelowvgap:D + \@@_primitive:NN \Umathnolimitsubfactor \utex_nolimitsubfactor:D + \@@_primitive:NN \Umathnolimitsupfactor \utex_nolimitsupfactor:D + \@@_primitive:NN \Umathopbinspacing \utex_opbinspacing:D + \@@_primitive:NN \Umathopclosespacing \utex_opclosespacing:D + \@@_primitive:NN \Umathopenbinspacing \utex_openbinspacing:D + \@@_primitive:NN \Umathopenclosespacing \utex_openclosespacing:D + \@@_primitive:NN \Umathopeninnerspacing \utex_openinnerspacing:D + \@@_primitive:NN \Umathopenopenspacing \utex_openopenspacing:D + \@@_primitive:NN \Umathopenopspacing \utex_openopspacing:D + \@@_primitive:NN \Umathopenordspacing \utex_openordspacing:D + \@@_primitive:NN \Umathopenpunctspacing \utex_openpunctspacing:D + \@@_primitive:NN \Umathopenrelspacing \utex_openrelspacing:D + \@@_primitive:NN \Umathoperatorsize \utex_operatorsize:D + \@@_primitive:NN \Umathopinnerspacing \utex_opinnerspacing:D + \@@_primitive:NN \Umathopopenspacing \utex_opopenspacing:D + \@@_primitive:NN \Umathopopspacing \utex_opopspacing:D + \@@_primitive:NN \Umathopordspacing \utex_opordspacing:D + \@@_primitive:NN \Umathoppunctspacing \utex_oppunctspacing:D + \@@_primitive:NN \Umathoprelspacing \utex_oprelspacing:D + \@@_primitive:NN \Umathordbinspacing \utex_ordbinspacing:D + \@@_primitive:NN \Umathordclosespacing \utex_ordclosespacing:D + \@@_primitive:NN \Umathordinnerspacing \utex_ordinnerspacing:D + \@@_primitive:NN \Umathordopenspacing \utex_ordopenspacing:D + \@@_primitive:NN \Umathordopspacing \utex_ordopspacing:D + \@@_primitive:NN \Umathordordspacing \utex_ordordspacing:D + \@@_primitive:NN \Umathordpunctspacing \utex_ordpunctspacing:D + \@@_primitive:NN \Umathordrelspacing \utex_ordrelspacing:D + \@@_primitive:NN \Umathoverbarkern \utex_overbarkern:D + \@@_primitive:NN \Umathoverbarrule \utex_overbarrule:D + \@@_primitive:NN \Umathoverbarvgap \utex_overbarvgap:D + \@@_primitive:NN \Umathoverdelimiterbgap + \utex_overdelimiterbgap:D + \@@_primitive:NN \Umathoverdelimitervgap + \utex_overdelimitervgap:D + \@@_primitive:NN \Umathpunctbinspacing \utex_punctbinspacing:D + \@@_primitive:NN \Umathpunctclosespacing + \utex_punctclosespacing:D + \@@_primitive:NN \Umathpunctinnerspacing + \utex_punctinnerspacing:D + \@@_primitive:NN \Umathpunctopenspacing \utex_punctopenspacing:D + \@@_primitive:NN \Umathpunctopspacing \utex_punctopspacing:D + \@@_primitive:NN \Umathpunctordspacing \utex_punctordspacing:D + \@@_primitive:NN \Umathpunctpunctspacing\utex_punctpunctspacing:D + \@@_primitive:NN \Umathpunctrelspacing \utex_punctrelspacing:D + \@@_primitive:NN \Umathquad \utex_quad:D + \@@_primitive:NN \Umathradicaldegreeafter + \utex_radicaldegreeafter:D + \@@_primitive:NN \Umathradicaldegreebefore + \utex_radicaldegreebefore:D + \@@_primitive:NN \Umathradicaldegreeraise + \utex_radicaldegreeraise:D + \@@_primitive:NN \Umathradicalkern \utex_radicalkern:D + \@@_primitive:NN \Umathradicalrule \utex_radicalrule:D + \@@_primitive:NN \Umathradicalvgap \utex_radicalvgap:D + \@@_primitive:NN \Umathrelbinspacing \utex_relbinspacing:D + \@@_primitive:NN \Umathrelclosespacing \utex_relclosespacing:D + \@@_primitive:NN \Umathrelinnerspacing \utex_relinnerspacing:D + \@@_primitive:NN \Umathrelopenspacing \utex_relopenspacing:D + \@@_primitive:NN \Umathrelopspacing \utex_relopspacing:D + \@@_primitive:NN \Umathrelordspacing \utex_relordspacing:D + \@@_primitive:NN \Umathrelpunctspacing \utex_relpunctspacing:D + \@@_primitive:NN \Umathrelrelspacing \utex_relrelspacing:D + \@@_primitive:NN \Umathskewedfractionhgap + \utex_skewedfractionhgap:D + \@@_primitive:NN \Umathskewedfractionvgap + \utex_skewedfractionvgap:D + \@@_primitive:NN \Umathspaceafterscript \utex_spaceafterscript:D + \@@_primitive:NN \Umathstackdenomdown \utex_stackdenomdown:D + \@@_primitive:NN \Umathstacknumup \utex_stacknumup:D + \@@_primitive:NN \Umathstackvgap \utex_stackvgap:D + \@@_primitive:NN \Umathsubshiftdown \utex_subshiftdown:D + \@@_primitive:NN \Umathsubshiftdrop \utex_subshiftdrop:D + \@@_primitive:NN \Umathsubsupshiftdown \utex_subsupshiftdown:D + \@@_primitive:NN \Umathsubsupvgap \utex_subsupvgap:D + \@@_primitive:NN \Umathsubtopmax \utex_subtopmax:D + \@@_primitive:NN \Umathsupbottommin \utex_supbottommin:D + \@@_primitive:NN \Umathsupshiftdrop \utex_supshiftdrop:D + \@@_primitive:NN \Umathsupshiftup \utex_supshiftup:D + \@@_primitive:NN \Umathsupsubbottommax \utex_supsubbottommax:D + \@@_primitive:NN \Umathunderbarkern \utex_underbarkern:D + \@@_primitive:NN \Umathunderbarrule \utex_underbarrule:D + \@@_primitive:NN \Umathunderbarvgap \utex_underbarvgap:D + \@@_primitive:NN \Umathunderdelimiterbgap + \utex_underdelimiterbgap:D + \@@_primitive:NN \Umathunderdelimitervgap + \utex_underdelimitervgap:D + \@@_primitive:NN \Unosubscript \utex_nosubscript:D + \@@_primitive:NN \Unosuperscript \utex_nosuperscript:D + \@@_primitive:NN \Uoverdelimiter \utex_overdelimiter:D + \@@_primitive:NN \Uradical \utex_radical:D + \@@_primitive:NN \Uroot \utex_root:D + \@@_primitive:NN \Uskewed \utex_skewed:D + \@@_primitive:NN \Uskewedwithdelims \utex_skewedwithdelims:D + \@@_primitive:NN \Ustack \utex_stack:D + \@@_primitive:NN \Ustartdisplaymath \utex_startdisplaymath:D + \@@_primitive:NN \Ustartmath \utex_startmath:D + \@@_primitive:NN \Ustopdisplaymath \utex_stopdisplaymath:D + \@@_primitive:NN \Ustopmath \utex_stopmath:D + \@@_primitive:NN \Usubscript \utex_subscript:D + \@@_primitive:NN \Usuperscript \utex_superscript:D + \@@_primitive:NN \Uunderdelimiter \utex_underdelimiter:D + \@@_primitive:NN \Uvextensible \utex_vextensible:D % \end{macrocode} -% Primitives from p\TeX{}. +% Primitives from \pTeX{}. % \begin{macrocode} - \@@_primitive:NN \autospacing \ptex_autospacing:D - \@@_primitive:NN \autoxspacing \ptex_autoxspacing:D - \@@_primitive:NN \dtou \ptex_dtou:D - \@@_primitive:NN \euc \ptex_euc:D - \@@_primitive:NN \ifdbox \ptex_ifdbox:D - \@@_primitive:NN \ifddir \ptex_ifddir:D - \@@_primitive:NN \ifmdir \ptex_ifmdir:D - \@@_primitive:NN \iftbox \ptex_iftbox:D - \@@_primitive:NN \iftdir \ptex_iftdir:D - \@@_primitive:NN \ifybox \ptex_ifybox:D - \@@_primitive:NN \ifydir \ptex_ifydir:D - \@@_primitive:NN \inhibitglue \ptex_inhibitglue:D - \@@_primitive:NN \inhibitxspcode \ptex_inhibitxspcode:D - \@@_primitive:NN \jcharwidowpenalty \ptex_jcharwidowpenalty:D - \@@_primitive:NN \jfam \ptex_jfam:D - \@@_primitive:NN \jfont \ptex_jfont:D - \@@_primitive:NN \jis \ptex_jis:D - \@@_primitive:NN \kanjiskip \ptex_kanjiskip:D - \@@_primitive:NN \kansuji \ptex_kansuji:D - \@@_primitive:NN \kansujichar \ptex_kansujichar:D - \@@_primitive:NN \kcatcode \ptex_kcatcode:D - \@@_primitive:NN \kuten \ptex_kuten:D - \@@_primitive:NN \noautospacing \ptex_noautospacing:D - \@@_primitive:NN \noautoxspacing \ptex_noautoxspacing:D - \@@_primitive:NN \postbreakpenalty \ptex_postbreakpenalty:D - \@@_primitive:NN \prebreakpenalty \ptex_prebreakpenalty:D - \@@_primitive:NN \showmode \ptex_showmode:D - \@@_primitive:NN \sjis \ptex_sjis:D - \@@_primitive:NN \tate \ptex_tate:D - \@@_primitive:NN \tbaselineshift \ptex_tbaselineshift:D - \@@_primitive:NN \tfont \ptex_tfont:D - \@@_primitive:NN \xkanjiskip \ptex_xkanjiskip:D - \@@_primitive:NN \xspcode \ptex_xspcode:D - \@@_primitive:NN \ybaselineshift \ptex_ybaselineshift:D - \@@_primitive:NN \yoko \ptex_yoko:D + \@@_primitive:NN \autospacing \ptex_autospacing:D + \@@_primitive:NN \autoxspacing \ptex_autoxspacing:D + \@@_primitive:NN \dtou \ptex_dtou:D + \@@_primitive:NN \epTeXinputencoding \ptex_inputencoding:D + \@@_primitive:NN \epTeXversion \ptex_epTeXversion:D + \@@_primitive:NN \euc \ptex_euc:D + \@@_primitive:NN \ifdbox \ptex_ifdbox:D + \@@_primitive:NN \ifddir \ptex_ifddir:D + \@@_primitive:NN \ifmdir \ptex_ifmdir:D + \@@_primitive:NN \iftbox \ptex_iftbox:D + \@@_primitive:NN \iftdir \ptex_iftdir:D + \@@_primitive:NN \ifybox \ptex_ifybox:D + \@@_primitive:NN \ifydir \ptex_ifydir:D + \@@_primitive:NN \inhibitglue \ptex_inhibitglue:D + \@@_primitive:NN \inhibitxspcode \ptex_inhibitxspcode:D + \@@_primitive:NN \jcharwidowpenalty \ptex_jcharwidowpenalty:D + \@@_primitive:NN \jfam \ptex_jfam:D + \@@_primitive:NN \jfont \ptex_jfont:D + \@@_primitive:NN \jis \ptex_jis:D + \@@_primitive:NN \kanjiskip \ptex_kanjiskip:D + \@@_primitive:NN \kansuji \ptex_kansuji:D + \@@_primitive:NN \kansujichar \ptex_kansujichar:D + \@@_primitive:NN \kcatcode \ptex_kcatcode:D + \@@_primitive:NN \kuten \ptex_kuten:D + \@@_primitive:NN \noautospacing \ptex_noautospacing:D + \@@_primitive:NN \noautoxspacing \ptex_noautoxspacing:D + \@@_primitive:NN \postbreakpenalty \ptex_postbreakpenalty:D + \@@_primitive:NN \prebreakpenalty \ptex_prebreakpenalty:D + \@@_primitive:NN \ptexversion \ptex_ptexversion:D + \@@_primitive:NN \showmode \ptex_showmode:D + \@@_primitive:NN \sjis \ptex_sjis:D + \@@_primitive:NN \tate \ptex_tate:D + \@@_primitive:NN \tbaselineshift \ptex_tbaselineshift:D + \@@_primitive:NN \tfont \ptex_tfont:D + \@@_primitive:NN \xkanjiskip \ptex_xkanjiskip:D + \@@_primitive:NN \xspcode \ptex_xspcode:D + \@@_primitive:NN \ybaselineshift \ptex_ybaselineshift:D + \@@_primitive:NN \yoko \ptex_yoko:D % \end{macrocode} -% Primitives from up\TeX{}. +% Primitives from \upTeX{}. % \begin{macrocode} - \@@_primitive:NN \disablecjktoken \uptex_disablecjktoken:D - \@@_primitive:NN \enablecjktoken \uptex_enablecjktoken:D - \@@_primitive:NN \forcecjktoken \uptex_forcecjktoken:D - \@@_primitive:NN \kchar \uptex_kchar:D - \@@_primitive:NN \kchardef \uptex_kchardef:D - \@@_primitive:NN \kuten \uptex_kuten:D - \@@_primitive:NN \ucs \uptex_ucs:D + \@@_primitive:NN \disablecjktoken \uptex_disablecjktoken:D + \@@_primitive:NN \enablecjktoken \uptex_enablecjktoken:D + \@@_primitive:NN \forcecjktoken \uptex_forcecjktoken:D + \@@_primitive:NN \kchar \uptex_kchar:D + \@@_primitive:NN \kchardef \uptex_kchardef:D + \@@_primitive:NN \kuten \uptex_kuten:D + \@@_primitive:NN \ucs \uptex_ucs:D + \@@_primitive:NN \uptexversion \uptex_uptexversion:D % \end{macrocode} % End of the \enquote{just the names} part of the source. % \begin{macrocode} @@ -1186,7 +1236,7 @@ % this simply as \tn{tracingfonts}, but that is overwritten by % the \LaTeXe{} kernel. So any spurious definition has to be removed, then % the real version saved either from the \pdfTeX{} name or from \LuaTeX{}. -% In the latter case, we leave \tn{@@@@tracingfonts} available: this might +% In the latter case, we leave \tn{@@tracingfonts} available: this might % be useful and almost all \LaTeXe{} users will have \pkg{expl3} loaded by % \pkg{fontspec}. (We follow the usual kernel convention that |@@| is used % for saved primitives.) @@ -1207,60 +1257,65 @@ % that get the right names anyway so are missing here! % \begin{macrocode} \etex_ifdefined:D \luatexsuppressfontnotfounderror - \tex_let:D \luatex_alignmark:D \luatexalignmark - \tex_let:D \luatex_aligntab:D \luatexaligntab - \tex_let:D \luatex_attribute:D \luatexattribute - \tex_let:D \luatex_attributedef:D \luatexattributedef - \tex_let:D \luatex_catcodetable:D \luatexcatcodetable - \tex_let:D \luatex_clearmarks:D \luatexclearmarks - \tex_let:D \luatex_crampeddisplaystyle:D \luatexcrampeddisplaystyle - \tex_let:D \luatex_crampedscriptscriptstyle:D \luatexcrampedscriptscriptstyle - \tex_let:D \luatex_crampedscriptstyle:D \luatexcrampedscriptstyle - \tex_let:D \luatex_crampedtextstyle:D \luatexcrampedtextstyle - \tex_let:D \luatex_fontid:D \luatexfontid - \tex_let:D \luatex_formatname:D \luatexformatname - \tex_let:D \luatex_gleaders:D \luatexgleaders - \tex_let:D \luatex_initcatcodetable:D \luatexinitcatcodetable - \tex_let:D \luatex_latelua:D \luatexlatelua - \tex_let:D \luatex_luaescapestring:D \luatexluaescapestring - \tex_let:D \luatex_luafunction:D \luatexluafunction - \tex_let:D \luatex_mathstyle:D \luatexmathstyle - \tex_let:D \luatex_nokerns:D \luatexnokerns - \tex_let:D \luatex_noligs:D \luatexnoligs - \tex_let:D \luatex_outputbox:D \luatexoutputbox - \tex_let:D \luatex_pageleftoffset:D \luatexpageleftoffset - \tex_let:D \luatex_pagetopoffset:D \luatexpagetopoffset - \tex_let:D \luatex_postexhyphenchar:D \luatexpostexhyphenchar - \tex_let:D \luatex_posthyphenchar:D \luatexposthyphenchar - \tex_let:D \luatex_preexhyphenchar:D \luatexpreexhyphenchar - \tex_let:D \luatex_prehyphenchar:D \luatexprehyphenchar - \tex_let:D \luatex_savecatcodetable:D \luatexsavecatcodetable - \tex_let:D \luatex_scantextokens:D \luatexscantextokens - \tex_let:D \luatex_suppressifcsnameerror:D \luatexsuppressifcsnameerror - \tex_let:D \luatex_suppresslongerror:D \luatexsuppresslongerror - \tex_let:D \luatex_suppressmathparerror:D \luatexsuppressmathparerror - \tex_let:D \luatex_suppressoutererror:D \luatexsuppressoutererror - \tex_let:D \utex_char:D \luatexUchar - \tex_let:D \xetex_suppressfontnotfounderror:D \luatexsuppressfontnotfounderror + \tex_let:D \luatex_alignmark:D \luatexalignmark + \tex_let:D \luatex_aligntab:D \luatexaligntab + \tex_let:D \luatex_attribute:D \luatexattribute + \tex_let:D \luatex_attributedef:D \luatexattributedef + \tex_let:D \luatex_catcodetable:D \luatexcatcodetable + \tex_let:D \luatex_clearmarks:D \luatexclearmarks + \tex_let:D \luatex_crampeddisplaystyle:D \luatexcrampeddisplaystyle + \tex_let:D \luatex_crampedscriptscriptstyle:D + \luatexcrampedscriptscriptstyle + \tex_let:D \luatex_crampedscriptstyle:D \luatexcrampedscriptstyle + \tex_let:D \luatex_crampedtextstyle:D \luatexcrampedtextstyle + \tex_let:D \luatex_fontid:D \luatexfontid + \tex_let:D \luatex_formatname:D \luatexformatname + \tex_let:D \luatex_gleaders:D \luatexgleaders + \tex_let:D \luatex_initcatcodetable:D \luatexinitcatcodetable + \tex_let:D \luatex_latelua:D \luatexlatelua + \tex_let:D \luatex_luaescapestring:D \luatexluaescapestring + \tex_let:D \luatex_luafunction:D \luatexluafunction + \tex_let:D \luatex_mathstyle:D \luatexmathstyle + \tex_let:D \luatex_nokerns:D \luatexnokerns + \tex_let:D \luatex_noligs:D \luatexnoligs + \tex_let:D \luatex_outputbox:D \luatexoutputbox + \tex_let:D \luatex_pageleftoffset:D \luatexpageleftoffset + \tex_let:D \luatex_pagetopoffset:D \luatexpagetopoffset + \tex_let:D \luatex_postexhyphenchar:D \luatexpostexhyphenchar + \tex_let:D \luatex_posthyphenchar:D \luatexposthyphenchar + \tex_let:D \luatex_preexhyphenchar:D \luatexpreexhyphenchar + \tex_let:D \luatex_prehyphenchar:D \luatexprehyphenchar + \tex_let:D \luatex_savecatcodetable:D \luatexsavecatcodetable + \tex_let:D \luatex_scantextokens:D \luatexscantextokens + \tex_let:D \luatex_suppressifcsnameerror:D + \luatexsuppressifcsnameerror + \tex_let:D \luatex_suppresslongerror:D \luatexsuppresslongerror + \tex_let:D \luatex_suppressmathparerror:D + \luatexsuppressmathparerror + \tex_let:D \luatex_suppressoutererror:D \luatexsuppressoutererror + \tex_let:D \utex_char:D \luatexUchar + \tex_let:D \xetex_suppressfontnotfounderror:D + \luatexsuppressfontnotfounderror % \end{macrocode} % Which also covers those slightly odd ones. % \begin{macrocode} - \tex_let:D \luatex_bodydir:D \luatexbodydir - \tex_let:D \luatex_boxdir:D \luatexboxdir - \tex_let:D \luatex_leftghost:D \luatexleftghost - \tex_let:D \luatex_localbrokenpenalty:D \luatexlocalbrokenpenalty - \tex_let:D \luatex_localinterlinepenalty:D \luatexlocalinterlinepenalty - \tex_let:D \luatex_localleftbox:D \luatexlocalleftbox - \tex_let:D \luatex_localrightbox:D \luatexlocalrightbox - \tex_let:D \luatex_mathdir:D \luatexmathdir - \tex_let:D \luatex_pagebottomoffset:D \luatexpagebottomoffset - \tex_let:D \luatex_pagedir:D \luatexpagedir - \tex_let:D \pdftex_pageheight:D \luatexpageheight - \tex_let:D \luatex_pagerightoffset:D \luatexpagerightoffset - \tex_let:D \pdftex_pagewidth:D \luatexpagewidth - \tex_let:D \luatex_pardir:D \luatexpardir - \tex_let:D \luatex_rightghost:D \luatexrightghost - \tex_let:D \luatex_textdir:D \luatextextdir + \tex_let:D \luatex_bodydir:D \luatexbodydir + \tex_let:D \luatex_boxdir:D \luatexboxdir + \tex_let:D \luatex_leftghost:D \luatexleftghost + \tex_let:D \luatex_localbrokenpenalty:D \luatexlocalbrokenpenalty + \tex_let:D \luatex_localinterlinepenalty:D + \luatexlocalinterlinepenalty + \tex_let:D \luatex_localleftbox:D \luatexlocalleftbox + \tex_let:D \luatex_localrightbox:D \luatexlocalrightbox + \tex_let:D \luatex_mathdir:D \luatexmathdir + \tex_let:D \luatex_pagebottomoffset:D \luatexpagebottomoffset + \tex_let:D \luatex_pagedir:D \luatexpagedir + \tex_let:D \pdftex_pageheight:D \luatexpageheight + \tex_let:D \luatex_pagerightoffset:D \luatexpagerightoffset + \tex_let:D \pdftex_pagewidth:D \luatexpagewidth + \tex_let:D \luatex_pardir:D \luatexpardir + \tex_let:D \luatex_rightghost:D \luatexrightghost + \tex_let:D \luatex_textdir:D \luatextextdir \tex_fi:D % \end{macrocode} % Only \pdfTeX{} and \LuaTeX{} define \tn{pdfmapfile} and \tn{pdfmapline}: @@ -1306,10 +1361,10 @@ %</initex|package> % \end{macrocode} % -% For Con\TeX{}t, two tests are needed. Both Mark~II and Mark~IV move several +% For \ConTeXt{}, two tests are needed. Both Mark~II and Mark~IV move several % primitives: these are all covered by the first test, again using \cs{end} % as a marker. For Mark~IV, a few more primitives are moved: they are -% implemented using some Lua code in the current Con\TeX{}t. +% implemented using some Lua code in the current \ConTeXt{}. % \begin{macrocode} %<*package> \etex_ifdefined:D \normalend diff --git a/Master/texmf-dist/source/latex/l3kernel/l3oldmodules.dtx b/Master/texmf-dist/source/latex/l3kernel/l3oldmodules.dtx index 169ee512dd8..77e3c46c775 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3oldmodules.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3oldmodules.dtx @@ -42,7 +42,7 @@ % } % % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx index 73a8774db53..74accffcc5c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -654,79 +654,89 @@ % branches according to the result. % \end{function} % -% \section{Internal programming functions} +% \section{Nestable recursions and mappings} % -% \begin{function}[updated = 2011-08-11, EXP] -% {\group_align_safe_begin:, \group_align_safe_end:} -% \begin{syntax} -% \cs{group_align_safe_begin:} -% \ldots -% \cs{group_align_safe_end:} -% \end{syntax} -% These functions are used to enclose material in a \TeX{} alignment -% environment within a specially-constructed group. This group is -% designed in such a way that it does not add brace groups to the -% output but does act as a group for the |&| token inside -% \tn{halign}. This is necessary to allow grabbing of tokens -% for testing purposes, as \TeX{} uses group level to determine the -% effect of alignment tokens. Without the special grouping, the use of -% a function such as \cs{peek_after:Nw} would result in a forbidden -% comparison of the internal \tn{endtemplate} token, yielding a -% fatal error. Each \cs{group_align_safe_begin:} must be matched by a -% \cs{group_align_safe_end:}, although this does not have to occur -% within the same function. -% \end{function} +% There are a number of places where recursion or mapping constructs are used in +% \pkg{expl3}. At a low-level, these typically require insertion of tokens +% at the end of the content to allow \enquote{clean up}. To support such +% mappings in a nestable form, the following functions are provided. % -% \begin{function}[EXP]{\__prg_break_point:Nn} +% \begin{function}[EXP, added = 2018-03-26]{\prg_break_point:Nn} % \begin{syntax} -% \cs{__prg_break_point:Nn} \cs[no-index]{\meta{type}_map_break:} \Arg{code} +% \cs{prg_break_point:Nn} \cs[no-index]{\meta{type}_map_break:} \Arg{code} % \end{syntax} % Used to mark the end of a recursion or mapping: the functions -% \cs[no-index]{\meta{type}_map_break:} and \cs[no-index]{\meta{type}_map_break:n} use -% this to break out of the loop. After the loop ends, the -% \meta{code} is inserted into the input stream. This occurs even -% if the break functions are \emph{not} applied: -% \cs{__prg_break_point:Nn} is functionally-equivalent in these cases +% \cs[no-index]{\meta{type}_map_break:} and +% \cs[no-index]{\meta{type}_map_break:n} use this to break out of the loop +% (see \cs{prg_map_break:Nn} for how to set these up). +% After the loop ends, the \meta{code} is inserted into the input stream. This +% occurs even if the break functions are \emph{not} applied: +% \cs{prg_break_point:Nn} is functionally-equivalent in these cases % to \cs{use_ii:nn}. % \end{function} % -% \begin{function}[EXP]{\__prg_map_break:Nn} +% \begin{function}[EXP, added = 2018-03-26]{\prg_map_break:Nn} % \begin{syntax} -% \cs{__prg_map_break:Nn} \cs[no-index]{\meta{type}_map_break:} \Arg{user code} +% \cs{prg_map_break:Nn} \cs[no-index]{\meta{type}_map_break:} \Arg{user code} % \ldots{} -% \cs{__prg_break_point:Nn} \cs[no-index]{\meta{type}_map_break:} \Arg{ending code} +% \cs{prg_break_point:Nn} \cs[no-index]{\meta{type}_map_break:} \Arg{ending code} % \end{syntax} % Breaks a recursion in mapping contexts, inserting in the input % stream the \meta{user code} after the \meta{ending code} for the % loop. The function breaks loops, inserting their \meta{ending -% code}, until reaching a loop with the same \meta{type} as its -% first argument. This \cs[no-index]{\meta{type}_map_break:} argument is simply -% used as a recognizable marker for the \meta{type}. +% code}, until reaching a loop with the same \meta{type} as its +% first argument. This \cs[no-index]{\meta{type}_map_break:} argument +% must be defined; it is simply used as a recognizable marker for the \meta{type}. +% +% For types with mappings defined in the kernel, +% \cs[no-index]{\meta{type}_map_break:} and \cs[no-index]{\meta{type}_map_break:n} +% are defined as \cs{prg_map_break:Nn} \cs[no-index]{\meta{type}_map_break:} |{}| +% and the same with |{}| omitted. % \end{function} % -% \begin{variable}{\g__prg_map_int} -% This integer is used by non-expandable mapping functions to track -% the level of nesting in force. The functions \cs{__prg_map_1:w}, -% \cs{__prg_map_2:w}, \emph{etc.}, labelled by \cs{g__prg_map_int} -% hold functions to be mapped over various list datatypes in inline -% and variable mappings. -% \end{variable} +% \subsection{Simple mappings} +% +% In addition to the more complex mappings above, non-nestable mappings are +% used in a number of locations and support is provided for these. % -% \begin{function}[EXP]{\__prg_break_point:} +% \begin{function}[EXP, added = 2018-03-27]{\prg_break_point:} % This copy of \cs{prg_do_nothing:} is used to mark the end of a fast -% short-term recursion: the function \cs{__prg_break:n} uses this to +% short-term recursion: the function \cs{prg_break:n} uses this to % break out of the loop. % \end{function} % -% \begin{function}[EXP]{\__prg_break:, \__prg_break:n} +% \begin{function}[EXP, added = 2018-03-27]{\prg_break:, \prg_break:n} % \begin{syntax} -% \cs{__prg_break:n} \Arg{code} \ldots{} \cs{__prg_break_point:} +% \cs{prg_break:n} \Arg{code} \ldots{} \cs{prg_break_point:} % \end{syntax} % Breaks a recursion which has no \meta{ending code} and which is not % a user-breakable mapping (see for instance \cs{prop_get:Nn}), and % inserts the \meta{code} in the input stream. % \end{function} % +% \section{Internal programming functions} +% +% \begin{function}[updated = 2011-08-11, EXP] +% {\group_align_safe_begin:, \group_align_safe_end:} +% \begin{syntax} +% \cs{group_align_safe_begin:} +% \ldots +% \cs{group_align_safe_end:} +% \end{syntax} +% These functions are used to enclose material in a \TeX{} alignment +% environment within a specially-constructed group. This group is +% designed in such a way that it does not add brace groups to the +% output but does act as a group for the |&| token inside +% \tn{halign}. This is necessary to allow grabbing of tokens +% for testing purposes, as \TeX{} uses group level to determine the +% effect of alignment tokens. Without the special grouping, the use of +% a function such as \cs{peek_after:Nw} would result in a forbidden +% comparison of the internal \tn{endtemplate} token, yielding a +% fatal error. Each \cs{group_align_safe_begin:} must be matched by a +% \cs{group_align_safe_end:}, although this does not have to occur +% within the same function. +% \end{function} +% % \end{documentation} % % \begin{implementation} @@ -909,7 +919,7 @@ \cs_generate_variant:Nn \bool_log:N { c } \cs_new_protected:Npn \@@_show:NN #1#2 { - \__kernel_check_defined:NT #2 + \__kernel_chk_defined:NT #2 { \exp_args:Nx #1 { \token_to_str:N #2 = \@@_to_str:n {#2} } } } % \end{macrocode} @@ -1068,19 +1078,19 @@ \cs_new:cpn { @@_(:Nw } #1#2 { \exp_after:wN \@@_choose:NNN \exp_after:wN #1 - \__int_value:w \@@_get_next:NN \use_i:nnnn + \int_value:w \@@_get_next:NN \use_i:nnnn } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_p:Nw} % If what follows GetNext is neither |!| nor |(|, evaluate the -% predicate using the primitive \cs{__int_value:w}. The canonical +% predicate using the primitive \cs{int_value:w}. The canonical % \texttt{true} and \texttt{false} values have numerical values $1$ % and $0$ respectively. Look for And, Or or Close afterwards. % \begin{macrocode} \cs_new:cpn { @@_p:Nw } #1 - { \exp_after:wN \@@_choose:NNN \exp_after:wN #1 \__int_value:w } + { \exp_after:wN \@@_choose:NNN \exp_after:wN #1 \int_value:w } % \end{macrocode} % \end{macro} % @@ -1386,7 +1396,7 @@ { \exp:w \exp_after:wN \@@_replicate_first:N - \__int_value:w \__int_eval:n {#1} + \int_value:w \int_eval:n {#1} \cs_end: } \cs_new:Npn \@@_replicate:N #1 @@ -1436,7 +1446,8 @@ \cs_new:cpn { @@_replicate_first_6:n } #1 { \exp_end: #1#1#1#1#1#1 } \cs_new:cpn { @@_replicate_first_7:n } #1 { \exp_end: #1#1#1#1#1#1#1 } \cs_new:cpn { @@_replicate_first_8:n } #1 { \exp_end: #1#1#1#1#1#1#1#1 } -\cs_new:cpn { @@_replicate_first_9:n } #1 { \exp_end: #1#1#1#1#1#1#1#1#1 } +\cs_new:cpn { @@_replicate_first_9:n } #1 + { \exp_end: #1#1#1#1#1#1#1#1#1 } % \end{macrocode} % \end{macro} % \end{macro} @@ -1522,27 +1533,68 @@ %<@@=prg> % \end{macrocode} % -% \begin{variable}{\g_@@_map_int} +% \begin{variable}{\g__kernel_prg_map_int} % A nesting counter for mapping. % \begin{macrocode} -\int_new:N \g_@@_map_int +\int_new:N \g__kernel_prg_map_int % \end{macrocode} % \end{variable} % -% \begin{macro}{\@@_break_point:Nn} -% \begin{macro}{\@@_map_break:Nn} +% \begin{macro}{\prg_break_point:Nn} +% \begin{macro}{\prg_map_break:Nn} % These are defined in \pkg{l3basics}, as they are needed % \enquote{early}. This is just a reminder that is the case! % \end{macro} % \end{macro} % -% \begin{macro}{\@@_break_point:} -% \begin{macro}{\@@_break:, \@@_break:n} +% \begin{macro}{\prg_break_point:} +% \begin{macro}{\prg_break:, \prg_break:n} % Also done in \pkg{l3basics} as in format mode these are needed within % \pkg{l3alloc}. % \end{macro} % \end{macro} % +% \subsection{Deprecated functions} +% +% \begin{macro}[deprecated = 2019-12-31]{\@@_break_point:Nn} +% \begin{macro}[deprecated = 2019-12-31]{\@@_break_point:} +% \begin{macro}[deprecated = 2019-12-31]{\@@_map_break:Nn} +% \begin{macro}[deprecated = 2019-12-31]{\@@_break:} +% \begin{macro}[deprecated = 2019-12-31]{\@@_break:n} +% Made public, but used by a few third-parties. It's not possible to +% perfectly support a mixture of \cs{@@_map_break:Nn} and +% \cs{prg_map_break:Nn} because they use different delimiters. The +% following code only breaks if someone tries to break from two +% \enquote{old-style} \cs{@@_map_break:Nn} \ldots{} +% \cs{@@_break_point:Nn} mappings in one go. Basically, the +% \cs{@@_map_break:Nn} converts a single \cs{@@_break_point:Nn} to +% \cs{prg_break_point:Nn}, and that delimiter had better be the right +% one. Then we call \cs{prg_map_break:Nn} which may end up breaking +% intermediate looks in the (unbraced) argument |#1|. It is essential +% to define the |break_point| functions before the corresponding +% |break| functions: otherwise \cs{debug_on:n} |{deprecation}| +% \cs{debug_off:n} |{deprecation}| would break when trying to restore +% the definitions because they would involve deprecated commands whose +% definition has not yet been restored. +% \begin{macrocode} +\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break_point:Nn } +\cs_new:Npn \@@_break_point:Nn { \prg_break_point:Nn } +\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break_point: } +\cs_new:Npn \@@_break_point: { \prg_break_point: } +\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_map_break:Nn } +\cs_new:Npn \@@_map_break:Nn #1 \@@_break_point:Nn + { \prg_map_break:Nn #1 \prg_break_point:Nn } +\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break: } +\cs_new:Npn \@@_break: #1 \@@_break_point: { } +\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break:n } +\cs_new:Npn \@@_break:n #1#2 \@@_break_point: {#1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % \begin{macrocode} %</initex|package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx index edbb4ce3815..0ce5f6b2b20 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3prop.dtx Copyright (C) 1990-2017 The LaTeX3 Project +%% File: l3prop.dtx Copyright (C) 1990-2018 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -447,16 +447,41 @@ % A permanently-empty property list used for internal comparisons. % \end{variable} % -% \section{Internal property list functions} +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3prop} implementation} +% +% \TestFiles{m3prop001, m3prop002, m3prop003, m3prop004, m3show001} +% +% \begin{macrocode} +%<*initex|package> +% \end{macrocode} +% +% \begin{macrocode} +%<@@=prop> +% \end{macrocode} +% +% A property list is a macro whose top-level expansion is of the form +% \begin{quote} +% \cs{s_@@} +% \cs{@@_pair:wn} \meta{key_1} \cs{s_@@} \Arg{value_1} \\ +% \ldots{} \\ +% \cs{@@_pair:wn} \meta{key_n} \cs{s_@@} \Arg{value_n} \\ +% \end{quote} +% where \cs{s_@@} is a scan mark +% (equal to \cs{scan_stop:}), and \cs{@@_pair:wn} can be used to map +% through the property list. % -% \begin{variable}{\s__prop} +% \begin{variable}{\s_@@} % The internal token used at the beginning of property lists. This is -% also used after each \meta{key} (see \cs{__prop_pair:wn}). +% also used after each \meta{key} (see \cs{@@_pair:wn}). % \end{variable} % -% \begin{variable}{\__prop_pair:wn} +% \begin{variable}{\@@_pair:wn} % \begin{syntax} -% \cs{__prop_pair:wn} \meta{key} \cs{s__prop} \Arg{item} +% \cs{@@_pair:wn} \meta{key} \cs{s_@@} \Arg{item} % \end{syntax} % The internal token used to begin each key--value pair in the % property list. If expanded outside of a mapping or manipulation @@ -464,14 +489,14 @@ % set globally. % \end{variable} % -% \begin{variable}{\l__prop_internal_tl} +% \begin{variable}{\l_@@_internal_tl} % Token list used to store new key--value pairs to be inserted by % functions of the \cs{prop_put:Nnn} family. % \end{variable} % -% \begin{function}[updated = 2013-01-08]{\__prop_split:NnTF} +% \begin{function}[updated = 2013-01-08]{\@@_split:NnTF} % \begin{syntax} -% \cs{__prop_split:NnTF} \meta{property list} \Arg{key} \Arg{true code} \Arg{false code} +% \cs{@@_split:NnTF} \meta{property list} \Arg{key} \Arg{true code} \Arg{false code} % \end{syntax} % Splits the \meta{property list} at the \meta{key}, giving three % token lists: the \meta{extract} of \meta{property list} before the @@ -495,38 +520,11 @@ % The \meta{key} comparison takes place as described for \cs{str_if_eq:nn}. % \end{function} % -% \end{documentation} -% -% \begin{implementation} -% -% \section{\pkg{l3prop} implementation} -% -% \TestFiles{m3prop001, m3prop002, m3prop003, m3prop004, m3show001} -% -% \begin{macrocode} -%<*initex|package> -% \end{macrocode} -% -% \begin{macrocode} -%<@@=prop> -% \end{macrocode} -% -% A property list is a macro whose top-level expansion is of the form -% \begin{quote} -% \cs{s_@@} -% \cs{@@_pair:wn} \meta{key_1} \cs{s_@@} \Arg{value_1} \\ -% \ldots{} \\ -% \cs{@@_pair:wn} \meta{key_n} \cs{s_@@} \Arg{value_n} \\ -% \end{quote} -% where \cs{s_@@} is a scan mark -% (equal to \cs{scan_stop:}), and \cs{@@_pair:wn} can be used to map -% through the property list. -% % \begin{macro}{\s_@@} % A private scan mark is used as a marker after each key, and at the % very beginning of the property list. % \begin{macrocode} -\__scan_new:N \s_@@ +\scan_new:N \s_@@ % \end{macrocode} % \end{macro} % @@ -561,7 +559,7 @@ % \begin{macrocode} \cs_new_protected:Npn \prop_new:N #1 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \cs_gset_eq:NN #1 \c_empty_prop } \cs_generate_variant:Nn \prop_new:N { c } @@ -634,14 +632,15 @@ % \@@_from_keyval:n, % \@@_from_keyval_loop:w, % \@@_from_keyval_split:Nw, +% \@@_from_keyval_key:n, % \@@_from_keyval_key:w, +% \@@_from_keyval_value:n, % \@@_from_keyval_value:w % } % Loop through items separated by commas, with \cs{q_mark} to avoid % losing braces. After checking for termination, split the item at % the first then at the second |=| (which ought to be the first of the -% trailing~|=|). At both splits, trim spaces (the internal -% \cs{__tl_trim_spaces:nn} expects the \cs{q_mark} we give it) and +% trailing~|=|). At both splits, trim spaces and % call \cs{@@_from_keyval_key:w}, then \cs{@@_from_keyval_value:w}, % followed by the trimmed material, \cs{q_nil}, the subsequent part of % the item, and the trailing |=|'s and \cs{q_stop}. After finding the @@ -670,20 +669,24 @@ \cs_new:Npn \@@_from_keyval_loop:w #1 , { \quark_if_recursion_tail_stop:o { \use_none:n #1 } - \@@_from_keyval_split:Nw \@@_from_keyval_key:w + \@@_from_keyval_split:Nw \@@_from_keyval_key:n #1 = = \q_stop { \use_none:n #1 } \@@_from_keyval_loop:w \q_mark } \cs_new:Npn \@@_from_keyval_split:Nw #1#2 = { - \__tl_trim_spaces:nn {#2} - { \exp_last_unbraced:No #1 } \q_nil + \tl_trim_spaces_apply:oN { \use_none:n #2 } #1 + \q_nil } +\cs_new:Npn \@@_from_keyval_key:n #1 + { \@@_from_keyval_key:w #1 } \cs_new:Npn \@@_from_keyval_key:w #1 \q_nil #2 \q_stop { - \@@_from_keyval_split:Nw \@@_from_keyval_value:w + \@@_from_keyval_split:Nw \@@_from_keyval_value:n \q_mark #2 \q_stop {#1} } +\cs_new:Npn \@@_from_keyval_value:n #1 + { \@@_from_keyval_value:w #1 } \cs_new:Npn \@@_from_keyval_value:w #1 \q_nil #2 \q_stop #3#4 { \tl_if_empty:nF { #3 #1 #2 } @@ -694,8 +697,9 @@ \s_@@ { \exp_not:n {#1} } } { - \exp_args:Nnno \__kernel_msg_expandable_error:nnn - { kernel } { prop-keyval } {#4} + \__kernel_msg_expandable_error:nnf + { kernel } { prop-keyval } + { \exp_after:wN \exp_stop_f: #4 } } } } @@ -853,12 +857,12 @@ { \exp_last_unbraced:Noo \@@_item_Nn:nwwn { \tl_to_str:n {#2} } #1 \@@_pair:wn \tl_to_str:n {#2} \s_@@ { } - \__prg_break_point: + \prg_break_point: } \cs_new:Npn \@@_item_Nn:nwwn #1#2 \@@_pair:wn #3 \s_@@ #4 { \str_if_eq_x:nnTF {#1} {#3} - { \__prg_break:n { \exp_not:n {#4} } } + { \prg_break:n { \exp_not:n {#4} } } { \@@_item_Nn:nwwn {#1} } } \cs_generate_variant:Nn \prop_item:Nn { c } @@ -1050,7 +1054,7 @@ \exp_last_unbraced:Noo \@@_if_in:nwwn { \tl_to_str:n {#2} } #1 \@@_pair:wn \tl_to_str:n {#2} \s_@@ { } \q_recursion_tail - \__prg_break_point: + \prg_break_point: } \cs_new:Npn \@@_if_in:nwwn #1#2 \@@_pair:wn #3 \s_@@ #4 { @@ -1065,7 +1069,7 @@ \else: \prg_return_true: \fi: - \__prg_break: + \prg_break: } \prg_generate_conditional_variant:Nnn \prop_if_in:Nn { NV , No , c , cV , co } { p , T , F , TF } @@ -1106,24 +1110,22 @@ % \prop_map_function:cN, \prop_map_function:cc % } % \begin{macro}{\@@_map_function:Nwwn} -% The fastest way to do a recursion here is to use an -% \cs{if_meaning:w} test: the keys are strings, and thus cannot match -% the marker \cs{q_recursion_tail}. A special case to note is when -% the key~|#3| is empty: then \cs{q_recursion_tail} is compared to -% \cs{exp_after:wN}, also different. Note that |#2|~is empty, except -% at the first iteration, where it is \cs{s_@@}. +% The argument delimited by \cs{@@_pair:wn} is empty except at the end +% of the loop where it is \cs{prg_break:}. No need for any quark +% test. % \begin{macrocode} \cs_new:Npn \prop_map_function:NN #1#2 { - \exp_last_unbraced:NNo \@@_map_function:Nwwn #2 #1 - \@@_pair:wn \q_recursion_tail \s_@@ { } - \__prg_break_point:Nn \prop_map_break: { } + \exp_after:wN \use_i_ii:nnn + \exp_after:wN \@@_map_function:Nwwn + \exp_after:wN #2 + #1 + \prg_break: \@@_pair:wn \s_@@ { } \prg_break_point: + \prg_break_point:Nn \prop_map_break: { } } \cs_new:Npn \@@_map_function:Nwwn #1#2 \@@_pair:wn #3 \s_@@ #4 { - \if_meaning:w \q_recursion_tail #3 - \exp_after:wN \prop_map_break: - \fi: + #2 #1 {#3} {#4} \@@_map_function:Nwwn #1 } @@ -1145,15 +1147,15 @@ \cs_new_protected:Npn \prop_map_inline:Nn #1#2 { \cs_gset_eq:cN - { __prg_map_ \int_use:N \g__prg_map_int :wn } \@@_pair:wn - \int_gincr:N \g__prg_map_int + { @@_map_ \int_use:N \g__kernel_prg_map_int :wn } \@@_pair:wn + \int_gincr:N \g__kernel_prg_map_int \cs_gset_protected:Npn \@@_pair:wn ##1 \s_@@ ##2 {#2} #1 - \__prg_break_point:Nn \prop_map_break: + \prg_break_point:Nn \prop_map_break: { - \int_gdecr:N \g__prg_map_int + \int_gdecr:N \g__kernel_prg_map_int \cs_gset_eq:Nc \@@_pair:wn - { __prg_map_ \int_use:N \g__prg_map_int :wn } + { @@_map_ \int_use:N \g__kernel_prg_map_int :wn } } } \cs_generate_variant:Nn \prop_map_inline:Nn { c } @@ -1162,12 +1164,12 @@ % % \begin{macro}[tested = m3prop003]{\prop_map_break:} % \begin{macro}[tested = m3prop003]{\prop_map_break:n} -% The break statements are based on the general \cs{__prg_map_break:Nn}. +% The break statements are based on the general \cs{prg_map_break:Nn}. % \begin{macrocode} \cs_new:Npn \prop_map_break: - { \__prg_map_break:Nn \prop_map_break: { } } + { \prg_map_break:Nn \prop_map_break: { } } \cs_new:Npn \prop_map_break:n - { \__prg_map_break:Nn \prop_map_break: } + { \prg_map_break:Nn \prop_map_break: } % \end{macrocode} % \end{macro} % \end{macro} @@ -1176,7 +1178,7 @@ % % \begin{macro}[tested = m3show001] % {\prop_show:N, \prop_show:c, \prop_log:N, \prop_log:c} -% Apply the general \cs{__kernel_check_defined:NT} and +% Apply the general \cs{__kernel_chk_defined:NT} and % \cs{msg_show:nnnnnn}. Contrarily to sequences and comma lists, % we use \cs{msg_show_item:nn} to format both the key and the value % for each pair. @@ -1187,7 +1189,7 @@ \cs_generate_variant:Nn \prop_log:N { c } \cs_new_protected:Npn \@@_show:NN #1#2 { - \__kernel_check_defined:NT #2 + \__kernel_chk_defined:NT #2 { #1 { LaTeX/kernel } { show-prop } { \token_to_str:N #2 } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx index f4ee8b13118..b42d4ebc67a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx @@ -41,21 +41,17 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % % \begin{documentation} % -% \section{Introduction to quarks and scan marks} -% % Two special types of constants in \LaTeX3 are \enquote{quarks} and % \enquote{scan marks}. By convention all constants of type quark -% start out with |\q_|, and scan marks start with |\s_|. Scan marks are -% for internal use by the kernel: they are not intended for more general -% use. +% start out with |\q_|, and scan marks start with |\s_|. % -% \subsection{Quarks} +% \section{Quarks} % % Quarks are control sequences that expand to themselves and should % therefore \emph{never} be executed directly in the code. @@ -247,6 +243,21 @@ % ended. % \end{function} % +% +% \begin{function}[added = 2018-04-10] +% { +% \quark_if_recursion_tail_break:NN, +% \quark_if_recursion_tail_break:nN +% } +% \begin{syntax} +% \cs{quark_if_recursion_tail_break:nN} \Arg{token list} \cs[no-index]{\meta{type}_map_break:} +% \end{syntax} +% Tests if \meta{token list} contains only \cs{q_recursion_tail}, and +% if so terminates the recursion using \cs[no-index]{\meta{type}_map_break:}. +% The recursion end should be marked by \cs{prg_break_point:Nn} +% \cs[no-index]{\meta{type}_map_break:}. +% \end{function} +% % \section{An example of recursion with quarks} % \label{sec:l3quark:quark-example} % @@ -297,23 +308,6 @@ % mapping function cannot be nested, since the second map would overwrite % the definition of |\__my_map_dbl_fn:nn|. % -% -% \section{Internal quark functions} -% -% \begin{function} -% { -% \__quark_if_recursion_tail_break:NN, -% \__quark_if_recursion_tail_break:nN -% } -% \begin{syntax} -% \cs{__quark_if_recursion_tail_break:nN} \Arg{token list} \cs[no-index]{\meta{type}_map_break:} -% \end{syntax} -% Tests if \meta{token list} contains only \cs{q_recursion_tail}, and -% if so terminates the recursion using \cs[no-index]{\meta{type}_map_break:}. -% The recursion end should be marked by \cs{prg_break_point:Nn} -% \cs[no-index]{\meta{type}_map_break:}. -% \end{function} -% % \section{Scan marks} % % Scan marks are control sequences set equal to \cs{scan_stop:}, @@ -327,30 +321,26 @@ % This allows to skip to that point if the end of the instructions % should not be performed (see \pkg{l3regex}). % -% The scan marks system is only for internal use by the kernel team in -% a small number of very specific places. These functions should not be -% used more generally. -% -% \begin{function}{\__scan_new:N} +% \begin{function}[added = 2018-04-01]{\scan_new:N} % \begin{syntax} -% \cs{__scan_new:N} \meta{scan mark} +% \cs{scan_new:N} \meta{scan mark} % \end{syntax} % Creates a new \meta{scan mark} which is set equal to \cs{scan_stop:}. % The \meta{scan mark} is defined globally, and an error message % is raised if the name was already taken by another scan mark. % \end{function} % -% \begin{variable}{\s__stop} +% \begin{variable}[added = 2018-04-01]{\s_stop} % Used at the end of a set of instructions, as a marker -% that can be jumped to using \cs{__use_none_delimit_by_s__stop:w}. +% that can be jumped to using \cs{use_none_delimit_by_s_stop:w}. % \end{variable} % -% \begin{function}{\__use_none_delimit_by_s__stop:w} +% \begin{function}[added = 2018-04-01]{\use_none_delimit_by_s_stop:w} % \begin{syntax} -% \cs{__use_none_delimit_by_s__stop:w} \meta{tokens} \cs{s__stop} +% \cs{use_none_delimit_by_s_stop:w} \meta{tokens} \cs{s_stop} % \end{syntax} -% Removes the \meta{tokens} and \cs{s__stop} from the input stream. -% This leads to a low-level \TeX{} error if \cs{s__stop} is absent. +% Removes the \meta{tokens} and \cs{s_stop} from the input stream. +% This leads to a low-level \TeX{} error if \cs{s_stop} is absent. % \end{function} % % \end{documentation} @@ -378,7 +368,7 @@ \__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN q #1 } { } \cs_new_protected:Npn \quark_new:N #1 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \cs_gset_nopar:Npn #1 {#1} } % \end{macrocode} @@ -473,24 +463,23 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\__quark_if_recursion_tail_break:NN} -% \begin{macro}{\__quark_if_recursion_tail_break:nN} -% Analogs of the \cs[index=quark_if_recursion_tail_stop:n] +% \begin{macro}{\quark_if_recursion_tail_break:NN} +% \begin{macro}{\quark_if_recursion_tail_break:nN} +% Analogues of the \cs[index=quark_if_recursion_tail_stop:n] % {quark_if_recursion_tail_stop\ldots{}} functions. % Break the mapping using |#2|. % \begin{macrocode} -\cs_new:Npn \__quark_if_recursion_tail_break:NN #1#2 +\cs_new:Npn \quark_if_recursion_tail_break:NN #1#2 { \if_meaning:w \q_recursion_tail #1 \exp_after:wN #2 \fi: } -\cs_new:Npn \__quark_if_recursion_tail_break:nN #1#2 +\cs_new:Npn \quark_if_recursion_tail_break:nN #1#2 { - \tl_if_empty:oTF + \tl_if_empty:oT { \@@_if_recursion_tail:w {} #1 {} ?! \q_recursion_tail ??! } {#2} - { } } % \end{macrocode} % \end{macro} @@ -533,6 +522,7 @@ % \begin{macro}[pTF]{\quark_if_no_value:n} % \UnitTested % \begin{macro}{\@@_if_nil:w, \@@_if_no_value:w} +% \begin{macro}[EXP]{\@@_if_empty_return:o} % Let us explain |\quark_if_nil:n(TF)|. Expanding \cs{@@_if_nil:w} % once is safe thanks to the trailing \cs{q_nil} |??!|. The result of % expanding once is empty if and only if both delimited arguments |#1| @@ -546,35 +536,38 @@ % |{}\q_nil| |{}?| |!\q_nil|~|??!|, hence |#3|~is delimited by the % final~|?!|, and the test returns \texttt{true} as wanted. In the % second case, the result is not empty since the first~|?!| in the -% definition of \cs{quark_if_nil:n} stop~|#3|. +% definition of \cs{quark_if_nil:n} stop~|#3|. The auxiliary here +% is the same as \cs{__tl_if_empty_return:o}, with the same comments +% applying. % \begin{macrocode} \prg_new_conditional:Npnn \quark_if_nil:n #1 { p, T , F , TF } { - \__tl_if_empty_return:o + \@@_if_empty_return:o { \@@_if_nil:w {} #1 {} ? ! \q_nil ? ? ! } } \cs_new:Npn \@@_if_nil:w #1 \q_nil #2 ? #3 ? ! { #1 #2 } \prg_new_conditional:Npnn \quark_if_no_value:n #1 { p, T , F , TF } { - \__tl_if_empty_return:o + \@@_if_empty_return:o { \@@_if_no_value:w {} #1 {} ? ! \q_no_value ? ? ! } } \cs_new:Npn \@@_if_no_value:w #1 \q_no_value #2 ? #3 ? ! { #1 #2 } \prg_generate_conditional_variant:Nnn \quark_if_nil:n { V , o } { p , TF , T , F } +\cs_new:Npn \@@_if_empty_return:o #1 + { + \exp_after:wN \if_meaning:w \exp_after:wN \q_nil + \__kernel_tl_to_str:w \exp_after:wN {#1} \q_nil + \prg_return_true: + \else: + \prg_return_false: + \fi: + } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} -% -% \begin{variable}{\q__tl_act_mark, \q__tl_act_stop} -% These private quarks are needed by \pkg{l3tl}, but that is loaded -% before the quark module, hence their definition is deferred. -% \begin{macrocode} -\quark_new:N \q__tl_act_mark -\quark_new:N \q__tl_act_stop -% \end{macrocode} -% \end{variable} +% \end{macro} % % \subsection{Scan marks} % @@ -590,12 +583,13 @@ % \end{macrocode} % \end{variable} % -% \begin{macro}{\@@_new:N} +% \begin{macro}{\scan_new:N} % \UnitTested % Check whether the variable is already a scan mark, % then declare it to be equal to \cs{scan_stop:} globally. % \begin{macrocode} -\cs_new_protected:Npn \@@_new:N #1 +\__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN s #1 } { } +\cs_new_protected:Npn \scan_new:N #1 { \tl_if_in:NnTF \g_@@_marks_tl { #1 } { @@ -610,31 +604,23 @@ % \end{macrocode} % \end{macro} % -% \begin{variable}{\s__stop} +% \begin{variable}{\s_stop} % \UnitTested % We only declare one scan mark here, more can be defined % by specific modules. % \begin{macrocode} -\@@_new:N \s__stop +\scan_new:N \s_stop % \end{macrocode} % \end{variable} % -% \begin{macro}{\__use_none_delimit_by_s__stop:w} +% \begin{macro}{\use_none_delimit_by_s_stop:w} % \UnitTested % Similar to \cs{use_none_delimit_by_q_stop:w}. % \begin{macrocode} -\cs_new:Npn \__use_none_delimit_by_s__stop:w #1 \s__stop { } +\cs_new:Npn \use_none_delimit_by_s_stop:w #1 \s_stop { } % \end{macrocode} % \end{macro} % -% \begin{variable}{\s__seq} -% This private scan mark is needed by \pkg{l3seq}, but that is loaded -% before the quark module, hence its definition is deferred. -% \begin{macrocode} -\__scan_new:N \s__seq -% \end{macrocode} -% \end{variable} -% % \begin{macrocode} %</initex|package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx index c693af6f7d2..0c0434054d7 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx @@ -29,7 +29,7 @@ % \fi % % \title{^^A -% The \textsf{l3regex} package: regular expressions in \TeX{}^^A +% The \textsf{l3regex} package: Regular expressions in \TeX{}^^A % } % % \author{^^A @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -50,8 +50,6 @@ % {\begin{itemize}\def\\{\char`\\}\def\makelabel##1{\hss\llap{\ttfamily##1}}} % {\end{itemize}} % -% \section{Regular expressions} -% % The \pkg{l3regex} package provides regular expression testing, % extraction of submatches, splitting, and replacement, all acting % on token lists. The syntax of regular expressions is mostly a subset @@ -96,7 +94,7 @@ % giving us access to the name of the environment when doing % replacements. % -% \subsection{Syntax of regular expressions} +% \section{Syntax of regular expressions} % % We start with a few examples, and encourage the reader to apply % \cs{regex_show:n} to these regular expressions. @@ -203,7 +201,8 @@ % equivalent to |[\^^J\^^K\^^L\^^M]|. Note that |\^^K| is a vertical space, % but not a space, for compatibility with Perl. % \item[\\w] Any word character, \emph{i.e.}, -% alpha-numerics and underscore, equivalent to |[A-Za-z0-9\_]|. +% alphanumerics and underscore, equivalent to the explicit +% class |[A-Za-z0-9\_]|. % \item[\\D] Any token not matched by |\d|. % \item[\\H] Any token not matched by |\h|. % \item[\\N] Any token other than the |\n| character (hex 0A). @@ -381,7 +380,7 @@ % true match is |{acbc3}|, with first submatch |{bc}|, but |\K| resets % the beginning of the match to the last position where it appears. % -% \subsection{Syntax of the replacement text} +% \section{Syntax of the replacement text} % % Most of the features described in regular expressions do not make % sense within the replacement text. Backslash introduces various @@ -456,7 +455,7 @@ % \end{verbatim} % results in \cs{l_my_tl} holding |first,\emph{second},first,first|. % -% \subsection{Pre-compiling regular expressions} +% \section{Pre-compiling regular expressions} % % If a regular expression is to be used several times, % it is better to compile it once rather than doing it @@ -509,7 +508,7 @@ % the second branch is not anchored to the beginning of the match. % \end{function} % -% \subsection{Matching} +% \section{Matching} % % All regular expression functions are available in both |:n| and |:N| % variants. The former require a \enquote{standard} regular expression, @@ -551,9 +550,9 @@ % results in \cs{l_foo_int} taking the value $5$. % \end{function} % -% \subsection{Submatch extraction} +% \section{Submatch extraction} % -% \begin{function}[TF, added = 2017-05-26] +% \begin{function}[noTF, added = 2017-05-26] % {\regex_extract_once:nnN, \regex_extract_once:NnN} % \begin{syntax} % \cs{regex_extract_once:nnN} \Arg{regex} \Arg{token list} \meta{seq~var} @@ -584,7 +583,7 @@ % functions such as \cs{regex_replace_once:nnN}. % \end{function} % -% \begin{function}[TF, added = 2017-05-26] +% \begin{function}[noTF, added = 2017-05-26] % {\regex_extract_all:nnN, \regex_extract_all:NnN} % \begin{syntax} % \cs{regex_extract_all:nnN} \Arg{regex} \Arg{token list} \meta{seq~var} @@ -608,7 +607,7 @@ % and the \texttt{true} branch is left in the input stream. % \end{function} % -% \begin{function}[TF, added = 2017-05-26]{\regex_split:nnN, \regex_split:NnN} +% \begin{function}[noTF, added = 2017-05-26]{\regex_split:nnN, \regex_split:NnN} % \begin{syntax} % \cs{regex_split:nnN} \Arg{regular expression} \Arg{token list} \meta{seq~var} % \cs{regex_split:nnNTF} \Arg{regular expression} \Arg{token list} \meta{seq~var} \Arg{true code} \Arg{false code} @@ -634,9 +633,9 @@ % is left in the input stream. % \end{function} % -% \subsection{Replacement} +% \section{Replacement} % -% \begin{function}[TF, added = 2017-05-26] +% \begin{function}[noTF, added = 2017-05-26] % {\regex_replace_once:nnN,\regex_replace_once:NnN} % \begin{syntax} % \cs{regex_replace_once:nnN} \Arg{regular expression} \Arg{replacement} \meta{tl~var} @@ -649,7 +648,7 @@ % first capturing group, |\2| of the second, \emph{etc.} % \end{function} % -% \begin{function}[TF, added = 2017-05-26] +% \begin{function}[noTF, added = 2017-05-26] % {\regex_replace_all:nnN, \regex_replace_all:NnN} % \begin{syntax} % \cs{regex_replace_all:nnN} \Arg{regular expression} \Arg{replacement} \meta{tl~var} @@ -663,7 +662,7 @@ % locally to \meta{tl~var}. % \end{function} % -% \subsection{Constants and variables} +% \section{Constants and variables} % % \begin{variable}[added = 2017-12-11]{\l_tmpa_regex, \l_tmpb_regex} % Scratch regex for local assignment. These are never used by @@ -679,7 +678,7 @@ % code and so should only be used for short-term storage. % \end{variable} % -% \subsection{Bugs, misfeatures, future work, and other possibilities} +% \section{Bugs, misfeatures, future work, and other possibilities} % % The following need to be done now. % \begin{itemize} @@ -716,7 +715,7 @@ % \item If possible, when a state is reused by the same thread, kill % other subthreads. % \item Use an array rather than \cs{l__regex_balance_tl} -% to build \cs{__regex_replacement_balance_one_match:n}. +% to build the function \cs{__regex_replacement_balance_one_match:n}. % \item Reduce the number of epsilon-transitions in alternatives. % \item Optimize simple strings: use less states (|abcade| should give % two states, for |abc| and |ade|). [Does that really make sense?] @@ -744,7 +743,7 @@ % \item Conditional subpatterns with look ahead/behind: \enquote{if % what follows is [\ldots{}], then [\ldots{}]}. % \item |(*..)| and |(?..)| sequences to set some options. -% \item UTF-8 mode for pdf\TeX{}. +% \item UTF-8 mode for \pdfTeX{}. % \item Newline conventions are not done. % In particular, we should have an option for |.| not to match newlines. % Also, |\A| should differ from |^|, and |\Z|, |\z| and |$| should @@ -798,7 +797,7 @@ % \item Comments: \TeX{} already has its own system for comments. % \item |\Q...\E| escaping: this would require to read the argument % verbatim, which is not in the scope of this module. -% \item |\C| single byte in UTF-8 mode: Xe\TeX{} and Lua\TeX{} serve +% \item |\C| single byte in UTF-8 mode: \XeTeX{} and \LuaTeX{} serve % us characters directly, and splitting those into bytes is tricky, % encoding dependent, and most likely not useful anyways. % \end{itemize} @@ -869,8 +868,7 @@ % \tn{toks} registers, by accessing them directly by number rather than % tying them to control sequence using the \tn{newtoks} allocation % functions. Specifically, these arrays and \tn{toks} are used as -% follows. When compiling, \tn{toks} registers are used under the hood -% by functions from the \pkg{l3tl-build} module. When building, +% follows. When building, % \tn{toks}\meta{state} holds the tests and actions to perform in the % \meta{state} of the \textsc{nfa}. When matching, % \begin{itemize} @@ -917,6 +915,15 @@ % % \subsection{Helpers} % +% \begin{macro} +% {\@@_int_eval:w} +% Access the primitive: performance is key here, so we do not use +% the slower route \emph{via} \cs{int_eval:n}. +% \begin{macrocode} +\cs_new_eq:NN \@@_int_eval:w \etex_numexpr:D +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@@_standard_escapechar:} % Make the \tn{escapechar} into the standard backslash. % \begin{macrocode} @@ -936,7 +943,7 @@ % Empty a \tn{toks} or set it to a value, given its number. % \begin{macrocode} \cs_new_protected:Npn \@@_toks_clear:N #1 - { \tex_toks:D #1 { } } + { \@@_toks_set:Nn #1 { } } \cs_new_eq:NN \@@_toks_set:Nn \tex_toks:D \cs_new_protected:Npn \@@_toks_set:No #1 { \@@_toks_set:Nn #1 \exp_after:wN } @@ -1029,6 +1036,14 @@ % \end{macrocode} % \end{variable} % +% \begin{variable}{\l_@@_build_tl} +% This temporary variable is specifically for use with the |tl_build| +% machinery. +% \begin{macrocode} +\tl_new:N \l_@@_build_tl +% \end{macrocode} +% \end{variable} +% % \begin{variable}{\c_@@_no_match_regex} % This regular expression matches nothing, but is still a valid % regular expression. We could use a failing assertion, but I went for @@ -1050,9 +1065,9 @@ % registers. We also store the balance of begin-group/end-group % characters into \cs{g_@@_balance_intarray}. % \begin{macrocode} -\__intarray_new:Nn \g_@@_charcode_intarray { 65536 } -\__intarray_new:Nn \g_@@_catcode_intarray { 65536 } -\__intarray_new:Nn \g_@@_balance_intarray { 65536 } +\intarray_new:Nn \g_@@_charcode_intarray { 65536 } +\intarray_new:Nn \g_@@_catcode_intarray { 65536 } +\intarray_new:Nn \g_@@_balance_intarray { 65536 } % \end{macrocode} % \end{variable} % @@ -1200,12 +1215,14 @@ \if_int_compare:w \l_@@_curr_char_int > `Z \exp_stop_f: \if_int_compare:w \l_@@_curr_char_int > `z \exp_stop_f: \else: \if_int_compare:w \l_@@_curr_char_int < `a \exp_stop_f: \else: - \int_sub:Nn \l_@@_case_changed_char_int { \c_@@_ascii_lower_int } + \int_sub:Nn \l_@@_case_changed_char_int + { \c_@@_ascii_lower_int } \fi: \fi: \else: \if_int_compare:w \l_@@_curr_char_int < `A \exp_stop_f: \else: - \int_add:Nn \l_@@_case_changed_char_int { \c_@@_ascii_lower_int } + \int_add:Nn \l_@@_case_changed_char_int + { \c_@@_ascii_lower_int } \fi: \fi: } @@ -1243,7 +1260,7 @@ } \cs_new_protected:Npn \@@_item_catcode:nT #1 { - \if_int_odd:w \__int_eval:n { #1 / \@@_item_catcode: } + \if_int_odd:w \int_eval:n { #1 / \@@_item_catcode: } \exp_stop_f: \exp_after:wN \use:n \else: \exp_after:wN \use_none:n @@ -1273,7 +1290,8 @@ { \tl_set:Nx \l_@@_internal_a_tl { \scan_stop: \@@_curr_cs_to_str: \scan_stop: } - \tl_if_in:noTF { \scan_stop: #1 \scan_stop: } \l_@@_internal_a_tl + \tl_if_in:noTF { \scan_stop: #1 \scan_stop: } + \l_@@_internal_a_tl { \@@_break_true:w } { } } { } @@ -1300,12 +1318,14 @@ \@@_single_match: \@@_disable_submatches: \@@_build_for_cs:n {#1} - \bool_set_eq:NN \l_@@_saved_success_bool \g_@@_success_bool + \bool_set_eq:NN \l_@@_saved_success_bool + \g_@@_success_bool \exp_args:NV \@@_match:n \l_@@_cs_name_tl \if_meaning:w \c_true_bool \g_@@_success_bool \group_insert_after:N \@@_break_true:w \fi: - \bool_gset_eq:NN \g_@@_success_bool \l_@@_saved_success_bool + \bool_gset_eq:NN \g_@@_success_bool + \l_@@_saved_success_bool \group_end: } } @@ -1444,42 +1464,41 @@ % character, then fed to \meta{inline~3}. The result is then left in the % input stream. Spaces are ignored unless escaped. % -% The conversion is mostly done within an \texttt{x}-expanding -% assignment, except for the |\x| escape sequence, which is not amenable -% to that in general. For this, we use the general framework of -% \cs{__tl_build:Nw}. +% The conversion is done within an \texttt{x}-expanding assignment. % % \begin{macro}{\@@_escape_use:nnnn} -% The result is built in \cs{l_@@_internal_a_tl}, which is then -% left in the input stream. Go through |#4| once, applying |#1|, +% The result is built in \cs{l_@@_internal_a_tl}, which is then left +% in the input stream. Tracing code is added as appropriate inside +% this token list. Go through |#4| once, applying |#1|, % |#2|, or |#3| as relevant to each character (after de-escaping -% it). Note that we cannot replace \cs{tl_set:Nx} and -% \cs{__tl_build_one:o} by a single call to \cs{__tl_build_one:x}, because -% the \texttt{x}-expanding assignment may be interrupted by |\x|. +% it). % \begin{macrocode} \__kernel_patch:nnNNpn { \@@_trace_push:nnN { regex } { 1 } \@@_escape_use:nnnn - \__tl_build:Nw \l_@@_internal_a_tl - \__tl_build_one:n { \@@_trace_pop:nnN { regex } { 1 } \@@_escape_use:nnnn } - \use_none:nn + \group_begin: + \tl_set:Nx \l_@@_internal_a_tl + { \@@_trace_pop:nnN { regex } { 1 } \@@_escape_use:nnnn } + \use_none:nnn } { } \cs_new_protected:Npn \@@_escape_use:nnnn #1#2#3#4 { - \__tl_build:Nw \l_@@_internal_a_tl + \group_begin: + \tl_clear:N \l_@@_internal_a_tl \cs_set:Npn \@@_escape_unescaped:N ##1 { #1 } \cs_set:Npn \@@_escape_escaped:N ##1 { #2 } \cs_set:Npn \@@_escape_raw:N ##1 { #3 } \@@_standard_escapechar: - \tl_gset:Nx \g_@@_internal_tl { \__str_to_other_fast:n {#4} } - \tl_set:Nx \l_@@_internal_b_tl + \tl_gset:Nx \g_@@_internal_tl + { \__kernel_str_to_other_fast:n {#4} } + \tl_put_right:Nx \l_@@_internal_a_tl { \exp_after:wN \@@_escape_loop:N \g_@@_internal_tl - { break } \__prg_break_point: + { break } \prg_break_point: } - \__tl_build_one:o \l_@@_internal_b_tl - \__tl_build_end: + \exp_after:wN + \group_end: \l_@@_internal_a_tl } % \end{macrocode} @@ -1532,12 +1551,11 @@ % backslash. Spaces are ignored, and |\a|, |\e|, |\f|, |\n|, |\r|, % |\t| take their meaning here. % \begin{macrocode} -\cs_new_eq:NN \@@_escape_break:w \__prg_break: +\cs_new_eq:NN \@@_escape_break:w \prg_break: \cs_new:cpn { @@_escape_/break:w } { - \if_false: { \fi: } - \__kernel_msg_error:nn { kernel } { trailing-backslash } - \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi: + \__kernel_msg_expandable_error:nn { kernel } { trailing-backslash } + \prg_break: } \cs_new:cpn { @@_escape_~:w } { } \cs_new:cpx { @@_escape_/a:w } @@ -1567,17 +1585,14 @@ \cs_new:cpn { @@_escape_/x:w } \@@_escape_loop:N { \exp_after:wN \@@_escape_x_end:w - \__int_value:w "0 \@@_escape_x_test:N + \int_value:w "0 \@@_escape_x_test:N } \cs_new:Npn \@@_escape_x_end:w #1 ; { \int_compare:nNnTF {#1} > \c_max_char_int { - \if_false: { \fi: } - \__tl_build_one:o \l_@@_internal_b_tl - \__kernel_msg_error:nnx { kernel } { x-overflow } {#1} - \tl_set:Nx \l_@@_internal_b_tl - { \if_false: } \fi: + \__kernel_msg_expandable_error:nnff { kernel } { x-overflow } + {#1} { \int_to_Hex:n {#1} } } { \exp_last_unbraced:Nf \@@_escape_raw:N @@ -1662,11 +1677,8 @@ } \cs_new:Npn \@@_escape_x_loop_error:n #1 { - \if_false: { \fi: } - \__tl_build_one:o \l_@@_internal_b_tl - \__kernel_msg_error:nnx { kernel } { x-missing-rbrace } {#1} - \tl_set:Nx \l_@@_internal_b_tl - { \if_false: } \fi: \@@_escape_loop:N #1 + \__kernel_msg_expandable_error:nnn { kernel } { x-missing-rbrace } {#1} + \@@_escape_loop:N #1 } % \end{macrocode} % \end{macro} @@ -1682,7 +1694,7 @@ #1 \prg_return_true: \else: \if_case:w - \__int_eval:n { \exp_after:wN ` \token_to_str:N #1 - `a } + \int_eval:n { \exp_after:wN ` \token_to_str:N #1 - `a } A \or: B \or: C @@ -2097,7 +2109,8 @@ \if_int_compare:w \l_@@_mode_int = \c_@@_catcode_mode_int \int_set_eq:NN \l_@@_mode_int \c_@@_outer_mode_int \else: - \if_int_compare:w \l_@@_mode_int = \c_@@_catcode_in_class_mode_int + \if_int_compare:w \l_@@_mode_int = + \c_@@_catcode_in_class_mode_int \int_set_eq:NN \l_@@_mode_int \c_@@_class_mode_int \fi: \fi: @@ -2117,13 +2130,16 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_compile:w { - \__tl_build_x:Nw \l_@@_internal_regex + \group_begin: + \tl_build_begin:N \l_@@_build_tl \int_zero:N \l_@@_group_level_int - \int_set_eq:NN \l_@@_default_catcodes_int \c_@@_all_catcodes_int + \int_set_eq:NN \l_@@_default_catcodes_int + \c_@@_all_catcodes_int \int_set_eq:NN \l_@@_catcodes_int \l_@@_default_catcodes_int \cs_set:Npn \@@_item_equal:n { \@@_item_caseful_equal:n } \cs_set:Npn \@@_item_range:nn { \@@_item_caseful_range:nn } - \__tl_build_one:n { \@@_branch:n { \if_false: } \fi: } + \tl_build_put_right:Nn \l_@@_build_tl + { \@@_branch:n { \if_false: } \fi: } } \cs_new_protected:Npn \@@_compile_end: { @@ -2140,17 +2156,23 @@ \prg_replicate:nn { \l_@@_group_level_int } { - \__tl_build_one:n + \tl_build_put_right:Nn \l_@@_build_tl { \if_false: { \fi: } \if_false: { \fi: } { 1 } { 0 } \c_true_bool } - \__tl_build_end: - \__tl_build_one:o \l_@@_internal_regex + \tl_build_end:N \l_@@_build_tl + \exp_args:NNNo + \group_end: + \tl_build_put_right:Nn \l_@@_build_tl + { \l_@@_build_tl } } \fi: - \__tl_build_one:n { \if_false: { \fi: } } - \__tl_build_end: + \tl_build_put_right:Nn \l_@@_build_tl { \if_false: { \fi: } } + \tl_build_end:N \l_@@_build_tl + \exp_args:NNNx + \group_end: + \tl_set:Nn \l_@@_internal_regex { \l_@@_build_tl } } % \end{macrocode} % \end{macro} @@ -2219,7 +2241,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_compile_one:x} +% \begin{macro}{\@@_compile_one:n} % This is used after finding one \enquote{test}, such as |\d|, or a % raw character. If that followed a catcode test (\emph{e.g.}, |\cL|), % then restore the mode. If we are not in a class, then the test is @@ -2227,17 +2249,18 @@ % search for quantifiers. In any case, insert the test, possibly % together with a catcode test if appropriate. % \begin{macrocode} -\cs_new_protected:Npn \@@_compile_one:x #1 +\cs_new_protected:Npn \@@_compile_one:n #1 { \@@_mode_quit_c: \@@_if_in_class:TF { } { - \__tl_build_one:n + \tl_build_put_right:Nn \l_@@_build_tl { \@@_class:NnnnN \c_true_bool { \if_false: } \fi: } } - \__tl_build_one:x + \tl_build_put_right:Nx \l_@@_build_tl { - \if_int_compare:w \l_@@_catcodes_int < \c_@@_all_catcodes_int + \if_int_compare:w \l_@@_catcodes_int < + \c_@@_all_catcodes_int \@@_item_catcode:nT { \int_use:N \l_@@_catcodes_int } { \exp_not:N \exp_not:n {#1} } \else: @@ -2292,7 +2315,10 @@ % whatever characters were grabbed are left raw). % \begin{macrocode} \cs_new_protected:Npn \@@_compile_quantifier_none: - { \__tl_build_one:n { \if_false: { \fi: } { 1 } { 0 } \c_false_bool } } + { + \tl_build_put_right:Nn \l_@@_build_tl + { \if_false: { \fi: } { 1 } { 0 } \c_false_bool } + } \cs_new_protected:Npn \@@_compile_quantifier_abort:xNN #1#2#3 { \@@_compile_quantifier_none: @@ -2315,9 +2341,13 @@ \cs_new_protected:Npn \@@_compile_quantifier_lazyness:nnNN #1#2#3#4 { \str_if_eq:nnTF { #3 #4 } { \@@_compile_special:N ? } - { \__tl_build_one:n { \if_false: { \fi: } { #1 } { #2 } \c_true_bool } } { - \__tl_build_one:n { \if_false: { \fi: } { #1 } { #2 } \c_false_bool } + \tl_build_put_right:Nn \l_@@_build_tl + { \if_false: { \fi: } { #1 } { #2 } \c_true_bool } + } + { + \tl_build_put_right:Nn \l_@@_build_tl + { \if_false: { \fi: } { #1 } { #2 } \c_false_bool } #3 #4 } } @@ -2408,7 +2438,8 @@ \str_if_eq_x:nnTF { #1 #2 } { \@@_compile_special:N \c_right_brace_str } { - \if_int_compare:w \l_@@_internal_a_int > \l_@@_internal_b_int + \if_int_compare:w \l_@@_internal_a_int > + \l_@@_internal_b_int \__kernel_msg_error:nnxx { kernel } { backwards-quantifier } { \int_use:N \l_@@_internal_a_int } { \int_use:N \l_@@_internal_b_int } @@ -2461,14 +2492,14 @@ \str_if_eq:nnTF {#2#3} { \@@_compile_special:N - } { \@@_compile_range:Nw #1 } { - \@@_compile_one:x - { \@@_item_equal:n { \__int_value:w `#1 ~ } } + \@@_compile_one:n + { \@@_item_equal:n { \int_value:w `#1 } } #2 #3 } } { - \@@_compile_one:x - { \@@_item_equal:n { \__int_value:w `#1 ~ } } + \@@_compile_one:n + { \@@_item_equal:n { \int_value:w `#1 } } #2 #3 } } @@ -2504,24 +2535,24 @@ \if_int_compare:w `#1 > `#3 \exp_stop_f: \__kernel_msg_error:nnxx { kernel } { range-backwards } {#1} {#3} \else: - \__tl_build_one:x + \tl_build_put_right:Nx \l_@@_build_tl { \if_int_compare:w `#1 = `#3 \exp_stop_f: \@@_item_equal:n \else: - \@@_item_range:nn { \__int_value:w `#1 ~ } + \@@_item_range:nn { \int_value:w `#1 } \fi: - { \__int_value:w `#3 ~ } + { \int_value:w `#3 } } \fi: } { \__kernel_msg_warning:nnxx { kernel } { range-missing-end } {#1} { \c_backslash_str #3 } - \__tl_build_one:x + \tl_build_put_right:Nx \l_@@_build_tl { - \@@_item_equal:n { \__int_value:w `#1 ~ } - \@@_item_equal:n { \__int_value:w `- ~ } + \@@_item_equal:n { \int_value:w `#1 \exp_stop_f: } + \@@_item_equal:n { \int_value:w `- \exp_stop_f: } } #2#3 } @@ -2540,7 +2571,7 @@ { \exp_not:N \@@_if_in_class:TF { \@@_compile_raw:N . } - { \@@_compile_one:x \exp_not:c { @@_prop_.: } } + { \@@_compile_one:n \exp_not:c { @@_prop_.: } } } \cs_new_protected:cpn { @@_prop_.: } { @@ -2568,10 +2599,10 @@ \cs_set_protected:Npn \@@_tmp:w #1#2 { \cs_new_protected:cpx { @@_compile_/#1: } - { \@@_compile_one:x \exp_not:c { @@_prop_#1: } } + { \@@_compile_one:n \exp_not:c { @@_prop_#1: } } \cs_new_protected:cpx { @@_compile_/#2: } { - \@@_compile_one:x + \@@_compile_one:n { \@@_item_reverse:n \exp_not:c { @@_prop_#1: } } } } @@ -2581,7 +2612,7 @@ \@@_tmp:w v V \@@_tmp:w w W \cs_new_protected:cpn { @@_compile_/N: } - { \@@_compile_one:x \@@_prop_N: } + { \@@_compile_one:n \@@_prop_N: } % \end{macrocode} % \end{macro} % @@ -2602,7 +2633,7 @@ { \@@_if_in_class_or_catcode:TF {#2} { - \__tl_build_one:n + \tl_build_put_right:Nn \l_@@_build_tl { \@@_assertion:Nn \c_true_bool { \@@_anchor:N #1 } } } } @@ -2639,7 +2670,7 @@ \@@_if_in_class_or_catcode:TF { \@@_compile_raw_error:N b } { - \__tl_build_one:n + \tl_build_put_right:Nn \l_@@_build_tl { \@@_assertion:Nn \c_true_bool { \@@_b_test: } } } } @@ -2648,7 +2679,7 @@ \@@_if_in_class_or_catcode:TF { \@@_compile_raw_error:N B } { - \__tl_build_one:n + \tl_build_put_right:Nn \l_@@_build_tl { \@@_assertion:Nn \c_false_bool { \@@_b_test: } } } } @@ -2668,8 +2699,9 @@ { \@@_if_in_class:TF { - \if_int_compare:w \l_@@_mode_int > \c_@@_catcode_in_class_mode_int - \__tl_build_one:n { \if_false: { \fi: } } + \if_int_compare:w \l_@@_mode_int > + \c_@@_catcode_in_class_mode_int + \tl_build_put_right:Nn \l_@@_build_tl { \if_false: { \fi: } } \fi: \tex_advance:D \l_@@_mode_int - 15 \exp_stop_f: \tex_divide:D \l_@@_mode_int 13 \exp_stop_f: @@ -2733,7 +2765,7 @@ \cs_new_protected:Npn \@@_compile_class_catcode:w #1; { \if_int_compare:w \l_@@_mode_int = \c_@@_catcode_mode_int - \__tl_build_one:n + \tl_build_put_right:Nn \l_@@_build_tl { \@@_class:NnnnN \c_true_bool { \if_false: } \fi: } \fi: \int_set_eq:NN \l_@@_catcodes_int \l_@@_default_catcodes_int @@ -2752,14 +2784,14 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_compile_class:TFNN #1#2#3#4 { - \l_@@_mode_int = \__int_value:w \l_@@_mode_int 3 \exp_stop_f: + \l_@@_mode_int = \int_value:w \l_@@_mode_int 3 \exp_stop_f: \str_if_eq:nnTF { #3 #4 } { \@@_compile_special:N ^ } { - \__tl_build_one:n { #2 { \if_false: } \fi: } + \tl_build_put_right:Nn \l_@@_build_tl { #2 { \if_false: } \fi: } \@@_compile_class:NN } { - \__tl_build_one:n { #1 { \if_false: } \fi: } + \tl_build_put_right:Nn \l_@@_build_tl { #1 { \if_false: } \fi: } \@@_compile_class:NN #3 #4 } } @@ -2794,8 +2826,14 @@ \str_case:nn { #2 } { : { \@@_compile_class_posix:NNNNw } - = { \__kernel_msg_warning:nnx { kernel } { posix-unsupported } { = } } - . { \__kernel_msg_warning:nnx { kernel } { posix-unsupported } { . } } + = { + \__kernel_msg_warning:nnx { kernel } + { posix-unsupported } { = } + } + . { + \__kernel_msg_warning:nnx { kernel } + { posix-unsupported } { . } + } } } \@@_compile_raw:N [ #1 #2 @@ -2827,7 +2865,7 @@ { \cs_if_exist:cTF { @@_posix_ \l_@@_internal_a_tl : } { - \@@_compile_one:x + \@@_compile_one:n { \bool_if:NF \l_@@_internal_bool \@@_item_reverse:n \exp_not:c { @@_posix_ \l_@@_internal_a_tl : } @@ -2857,9 +2895,9 @@ % % \begin{macro}{\@@_compile_group_begin:N, \@@_compile_group_end:} % The contents of a regex group are turned into compiled code in -% \cs{l_@@_internal_regex}, which ends up with items of the form +% \cs{l_@@_build_tl}, which ends up with items of the form % \cs{@@_branch:n} \Arg{concatenation}. This construction is done -% using \pkg{l3tl-build} within a \TeX{} group, which automatically +% using \cs[no-index]{tl_build_\ldots{}} functions within a \TeX{} group, which automatically % makes sure that options (case-sensitivity and default catcode) are % reset at the end of the group. The argument |#1| is % \cs{@@_group:nnnN} or a variant thereof. A small subtlety to @@ -2870,20 +2908,24 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_compile_group_begin:N #1 { - \__tl_build_one:n { #1 { \if_false: } \fi: } + \tl_build_put_right:Nn \l_@@_build_tl { #1 { \if_false: } \fi: } \@@_mode_quit_c: - \__tl_build:Nw \l_@@_internal_regex + \group_begin: + \tl_build_begin:N \l_@@_build_tl \int_set_eq:NN \l_@@_default_catcodes_int \l_@@_catcodes_int \int_incr:N \l_@@_group_level_int - \__tl_build_one:n { \@@_branch:n { \if_false: } \fi: } + \tl_build_put_right:Nn \l_@@_build_tl + { \@@_branch:n { \if_false: } \fi: } } \cs_new_protected:Npn \@@_compile_group_end: { \if_int_compare:w \l_@@_group_level_int > 0 \exp_stop_f: - \__tl_build_one:n { \if_false: { \fi: } } - \__tl_build_end: + \tl_build_put_right:Nn \l_@@_build_tl { \if_false: { \fi: } } + \tl_build_end:N \l_@@_build_tl + \exp_args:NNNx + \group_end: + \tl_build_put_right:Nn \l_@@_build_tl { \l_@@_build_tl } \int_set_eq:NN \l_@@_catcodes_int \l_@@_default_catcodes_int - \__tl_build_one:o \l_@@_internal_regex \exp_after:wN \@@_compile_quantifier:w \else: \__kernel_msg_warning:nn { kernel } { extra-rparen } @@ -2894,14 +2936,23 @@ % \end{macro} % % \begin{macro}{\@@_compile_(:} -% In a class, parentheses are not special. Outside, check for a |?|, -% denoting special groups, and run the code for the corresponding -% special group. +% In a class, parentheses are not special. In a catcode test inside a +% class, a left parenthesis gives an error, to catch |[a\cL(bcd)e]|. +% Otherwise check for a |?|, denoting special groups, and run the code +% for the corresponding special group. % \begin{macrocode} \cs_new_protected:cpn { @@_compile_(: } { \@@_if_in_class:TF { \@@_compile_raw:N ( } - { \@@_compile_lparen:w } + { + \if_int_compare:w \l_@@_mode_int = + \c_@@_catcode_in_class_mode_int + \__kernel_msg_error:nn { kernel } { c-lparen-in-class } + \exp_after:wN \@@_compile_raw:N \exp_after:wN ( + \else: + \exp_after:wN \@@_compile_lparen:w + \fi: + } } \cs_new_protected:Npn \@@_compile_lparen:w #1#2#3#4 { @@ -2932,7 +2983,7 @@ { \@@_if_in_class:TF { \@@_compile_raw:N | } { - \__tl_build_one:n + \tl_build_put_right:Nn \l_@@_build_tl { \if_false: { \fi: } \@@_branch:n { \if_false: } \fi: } } } @@ -2973,8 +3024,10 @@ { \str_if_eq:nnTF { #1 #2 } { \@@_compile_special:N ) } { - \cs_set:Npn \@@_item_equal:n { \@@_item_caseless_equal:n } - \cs_set:Npn \@@_item_range:nn { \@@_item_caseless_range:nn } + \cs_set:Npn \@@_item_equal:n + { \@@_item_caseless_equal:n } + \cs_set:Npn \@@_item_range:nn + { \@@_item_caseless_range:nn } } { \__kernel_msg_warning:nnx { kernel } { unknown-option } { (?i #2 } @@ -2989,8 +3042,10 @@ \str_if_eq:nnTF { #1 #2 #3 #4 } { \@@_compile_raw:N i \@@_compile_special:N ) } { - \cs_set:Npn \@@_item_equal:n { \@@_item_caseful_equal:n } - \cs_set:Npn \@@_item_range:nn { \@@_item_caseful_range:nn } + \cs_set:Npn \@@_item_equal:n + { \@@_item_caseful_equal:n } + \cs_set:Npn \@@_item_range:nn + { \@@_item_caseful_range:nn } } { \__kernel_msg_warning:nnx { kernel } { unknown-option } { (?-#2#4 } @@ -3019,7 +3074,8 @@ { \int_if_exist:cTF { c_@@_catcode_#2_int } { - \int_set_eq:Nc \l_@@_catcodes_int { c_@@_catcode_#2_int } + \int_set_eq:Nc \l_@@_catcodes_int + { c_@@_catcode_#2_int } \l_@@_mode_int = \if_case:w \l_@@_mode_int \c_@@_catcode_mode_int @@ -3112,7 +3168,7 @@ } \cs_new_protected:Npn \@@_compile_c_lbrack_add:N #1 { - \if_int_odd:w \__int_eval:n { \l_@@_catcodes_int / #1 } + \if_int_odd:w \int_eval:n { \l_@@_catcodes_int / #1 } \exp_stop_f: \else: \int_add:Nn \l_@@_catcodes_int {#1} \fi: @@ -3176,11 +3232,14 @@ \exp_after:wN \@@_compile_cs_aux:Nn \l_@@_internal_regex \q_nil \q_nil \q_recursion_stop } - \exp_args:Nx \@@_compile_one:x + \exp_args:Nx \@@_compile_one:n { \flag_if_raised:nTF { @@_cs } { \@@_item_cs:n { \exp_not:o \l_@@_internal_regex } } - { \@@_item_exact_cs:n { \tl_tail:N \l_@@_internal_a_tl } } + { + \@@_item_exact_cs:n + { \tl_tail:N \l_@@_internal_a_tl } + } } } \cs_new:Npn \@@_compile_cs_aux:Nn #1#2 @@ -3193,7 +3252,7 @@ \@@_compile_cs_aux:Nn } { - \quark_if_nil:NF #1 { \flag_raise:n { @@_cs } } + \quark_if_nil:NF #1 { \flag_raise_if_clear:n { @@_cs } } \use_none_delimit_by_q_recursion_stop:w } } @@ -3215,7 +3274,7 @@ { \quark_if_nil:NF #1 { - \flag_raise:n { @@_cs } + \flag_raise_if_clear:n { @@_cs } \use_i_delimit_by_q_recursion_stop:nw } \use_none_delimit_by_q_recursion_stop:w @@ -3245,7 +3304,8 @@ \@@_if_in_class_or_catcode:TF { \@@_compile_raw_error:N u #1 #2 } { - \str_if_eq_x:nnTF {#1#2} { \@@_compile_special:N \c_left_brace_str } + \str_if_eq_x:nnTF {#1#2} + { \@@_compile_special:N \c_left_brace_str } { \tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi: \@@_compile_u_loop:NN @@ -3305,8 +3365,11 @@ \cs_new_protected:Npn \@@_compile_u_in_cs: { \tl_gset:Nx \g_@@_internal_tl - { \exp_args:No \__str_to_other_fast:n { \l_@@_internal_a_tl } } - \__tl_build_one:x + { + \exp_args:No \__kernel_str_to_other_fast:n + { \l_@@_internal_a_tl } + } + \tl_build_put_right:Nx \l_@@_build_tl { \tl_map_function:NN \g_@@_internal_tl \@@_compile_u_in_cs_aux:n @@ -3315,7 +3378,7 @@ \cs_new:Npn \@@_compile_u_in_cs_aux:n #1 { \@@_class:NnnnN \c_true_bool - { \@@_item_caseful_equal:n { \__int_value:w `#1 } } + { \@@_item_caseful_equal:n { \int_value:w `#1 } } { 1 } { 0 } \c_false_bool } % \end{macrocode} @@ -3329,16 +3392,17 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_compile_u_not_cs: { - \exp_args:No \__tl_analysis_map_inline:nn { \l_@@_internal_a_tl } + \tl_analysis_map_inline:Nn \l_@@_internal_a_tl { - \__tl_build_one:n + \tl_build_put_right:Nx \l_@@_build_tl { \@@_class:NnnnN \c_true_bool { - \if_int_compare:w "##2 = 0 \exp_stop_f: - \@@_item_exact_cs:n { \exp_after:wN \cs_to_str:N ##1 } + \if_int_compare:w "##3 = 0 \exp_stop_f: + \@@_item_exact_cs:n + { \exp_after:wN \cs_to_str:N ##1 } \else: - \@@_item_exact:nn { \__int_value:w "##2 } { ##3 } + \@@_item_exact:nn { \int_value:w "##3 } { ##2 } \fi: } { 1 } { 0 } \c_false_bool @@ -3359,7 +3423,7 @@ \cs_new_protected:cpn { @@_compile_/K: } { \int_compare:nNnTF \l_@@_mode_int = \c_@@_outer_mode_int - { \__tl_build_one:n { \@@_command_K: } } + { \tl_build_put_right:Nn \l_@@_build_tl { \@@_command_K: } } { \@@_compile_raw_error:N K } } % \end{macrocode} @@ -3368,19 +3432,22 @@ % \subsubsection{Showing regexes} % % \begin{macro}{\@@_show:N} -% Within a \cs{__tl_build:Nw} \ldots{} \cs{__tl_build_end:} group, we +% Within a group and within \cs{tl_build_begin:N} \ldots{} \cs{tl_build_end:N} we % redefine all the function that can appear in a compiled regex, then % run the regex. The result stored in \cs{l_@@_internal_a_tl} is then % meant to be shown. % \begin{macrocode} \cs_new_protected:Npn \@@_show:N #1 { - \__tl_build:Nw \l_@@_internal_a_tl + \group_begin: + \tl_build_begin:N \l_@@_build_tl \cs_set_protected:Npn \@@_branch:n { - \seq_pop_right:NN \l_@@_show_prefix_seq \l_@@_internal_a_tl + \seq_pop_right:NN \l_@@_show_prefix_seq + \l_@@_internal_a_tl \@@_show_one:n { +-branch } - \seq_put_right:No \l_@@_show_prefix_seq \l_@@_internal_a_tl + \seq_put_right:No \l_@@_show_prefix_seq + \l_@@_internal_a_tl \use:n } \cs_set_protected:Npn \@@_group:nnnN @@ -3393,13 +3460,19 @@ \cs_set_protected:Npn \@@_command_K: { \@@_show_one:n { reset~match~start~(\iow_char:N\\K) } } \cs_set_protected:Npn \@@_assertion:Nn ##1##2 - { \@@_show_one:n { \bool_if:NF ##1 { negative~ } assertion:~##2 } } + { + \@@_show_one:n + { \bool_if:NF ##1 { negative~ } assertion:~##2 } + } \cs_set:Npn \@@_b_test: { word~boundary } \cs_set_eq:NN \@@_anchor:N \@@_show_anchor_to_str:N \cs_set_protected:Npn \@@_item_caseful_equal:n ##1 { \@@_show_one:n { char~code~\int_eval:n{##1} } } \cs_set_protected:Npn \@@_item_caseful_range:nn ##1##2 - { \@@_show_one:n { range~[\int_eval:n{##1}, \int_eval:n{##2}] } } + { + \@@_show_one:n + { range~[\int_eval:n{##1}, \int_eval:n{##2}] } + } \cs_set_protected:Npn \@@_item_caseless_equal:n ##1 { \@@_show_one:n { char~code~\int_eval:n{##1}~(caseless) } } \cs_set_protected:Npn \@@_item_caseless_range:nn ##1##2 @@ -3422,7 +3495,10 @@ \seq_clear:N \l_@@_show_prefix_seq \@@_show_push:n { ~ } \cs_if_exist_use:N #1 - \__tl_build_end: + \tl_build_end:N \l_@@_build_tl + \exp_args:NNNo + \group_end: + \tl_set:Nn \l_@@_internal_a_tl { \l_@@_build_tl } } % \end{macrocode} % \end{macro} @@ -3434,7 +3510,7 @@ \cs_new_protected:Npn \@@_show_one:n #1 { \int_incr:N \l_@@_show_lines_int - \__tl_build_one:x + \tl_build_put_right:Nx \l_@@_build_tl { \exp_not:N \iow_newline: \seq_map_function:NN \l_@@_show_prefix_seq \use:n @@ -3495,42 +3571,39 @@ % \begin{macrocode} \cs_set:Npn \@@_show_class:NnnnN #1#2#3#4#5 { - \__tl_build:Nw \l_@@_internal_a_tl + \group_begin: + \tl_build_begin:N \l_@@_build_tl \int_zero:N \l_@@_show_lines_int \@@_show_push:n {~} #2 - \exp_last_unbraced:Nf - \int_case:nnF { \l_@@_show_lines_int } + \int_compare:nTF { \l_@@_show_lines_int = 0 } { - {0} + \group_end: + \@@_show_one:n { \bool_if:NTF #1 { Fail } { Pass } } + } + { + \bool_if:nTF + { #1 && \int_compare_p:n { \l_@@_show_lines_int = 1 } } { - \__tl_build_end: - \@@_show_one:n { \bool_if:NTF #1 { Fail } { Pass } } + \group_end: + #2 + \tl_build_put_right:Nn \l_@@_build_tl + { \@@_msg_repeated:nnN {#3} {#4} #5 } } - {1} { - \__tl_build_end: - \bool_if:NTF #1 - { - #2 - \__tl_build_one:n { \@@_msg_repeated:nnN {#3} {#4} #5 } - } + \tl_build_end:N \l_@@_build_tl + \exp_args:NNNo + \group_end: + \tl_set:Nn \l_@@_internal_a_tl \l_@@_build_tl + \@@_show_one:n { - \@@_show_one:n - { Don't~match~\@@_msg_repeated:nnN {#3} {#4} #5 } - \__tl_build_one:o \l_@@_internal_a_tl + \bool_if:NTF #1 { Match } { Don't~match } + \@@_msg_repeated:nnN {#3} {#4} #5 } + \tl_build_put_right:Nx \l_@@_build_tl + { \exp_not:o \l_@@_internal_a_tl } } } - { - \__tl_build_end: - \@@_show_one:n - { - \bool_if:NTF #1 { M } { Don't~m } atch - \@@_msg_repeated:nnN {#3} {#4} #5 - } - \__tl_build_one:o \l_@@_internal_a_tl - } } % \end{macrocode} % \end{macro} @@ -4011,8 +4084,8 @@ { \int_use:N \l_@@_capturing_group_int } { \int_use:N \l_@@_capturing_group_int } #1 - { ?? \__prg_break:n } { } - \__prg_break_point: + { ?? \prg_break:n } { } + \prg_break_point: } } \cs_new_protected:Npn \@@_group_resetting_loop:nnNn #1#2#3#4 @@ -4109,7 +4182,7 @@ \l_@@_right_state_int \l_@@_max_state_int \int_set_eq:NN \l_@@_internal_a_int \l_@@_left_state_int \int_set_eq:NN \l_@@_internal_b_int \l_@@_max_state_int - \if_int_compare:w \__int_eval:n {#1} > 1 \exp_stop_f: + \if_int_compare:w \int_eval:n {#1} > 1 \exp_stop_f: \int_set:Nn \l_@@_internal_c_int { ( #1 - 1 ) @@ -4295,7 +4368,10 @@ \@@_action_submatch:n { 0< } \bool_set_true:N \l_@@_fresh_thread_bool \@@_action_free:n - { \int_eval:n { \l_@@_right_state_int - \l_@@_left_state_int } } + { + \int_eval:n + { \l_@@_right_state_int - \l_@@_left_state_int } + } \bool_set_false:N \l_@@_fresh_thread_bool } } @@ -4459,8 +4535,8 @@ % threads to be considered in the next step, more precisely the % states in which these threads are. % \begin{macrocode} -\__intarray_new:Nn \g_@@_state_active_intarray { 65536 } -\__intarray_new:Nn \g_@@_thread_state_intarray { 65536 } +\intarray_new:Nn \g_@@_state_active_intarray { 65536 } +\intarray_new:Nn \g_@@_thread_state_intarray { 65536 } % \end{macrocode} % \end{variable} % @@ -4545,8 +4621,8 @@ \int_set:Nn \l_@@_curr_pos_int { 2 * \l_@@_max_state_int } \@@_query_set:nnn { } { -1 } { -2 } \int_set_eq:NN \l_@@_min_pos_int \l_@@_curr_pos_int - \__tl_analysis_map_inline:nn {#1} - { \@@_query_set:nnn {##1} {"##2} {##3} } + \tl_analysis_map_inline:nn {#1} + { \@@_query_set:nnn {##1} {"##3} {##2} } \int_set_eq:NN \l_@@_max_pos_int \l_@@_curr_pos_int \@@_query_set:nnn { } { -1 } { -2 } \@@_match_init: @@ -4558,9 +4634,12 @@ \cs_new_protected:Npn \@@_match_init: { \bool_gset_false:N \g_@@_success_bool - \int_step_inline:nnnn - \l_@@_min_state_int { 1 } { \l_@@_max_state_int - 1 } - { \__intarray_gset_fast:Nnn \g_@@_state_active_intarray {##1} { 1 } } + \int_step_inline:nnn + \l_@@_min_state_int { \l_@@_max_state_int - 1 } + { + \__kernel_intarray_gset:Nnn + \g_@@_state_active_intarray {##1} { 1 } + } \int_set_eq:NN \l_@@_min_active_int \l_@@_max_state_int \int_zero:N \l_@@_step_int \int_set_eq:NN \l_@@_success_pos_int \l_@@_min_pos_int @@ -4591,7 +4670,10 @@ { \if_meaning:w \c_true_bool \l_@@_empty_success_bool \cs_set:Npn \@@_if_two_empty_matches:F - { \int_compare:nNnF \l_@@_start_pos_int = \l_@@_curr_pos_int } + { + \int_compare:nNnF + \l_@@_start_pos_int = \l_@@_curr_pos_int + } \else: \cs_set_eq:NN \@@_if_two_empty_matches:F \use:n \fi: @@ -4618,7 +4700,11 @@ \cs_new_protected:Npn \@@_single_match: { \tl_set:Nn \l_@@_every_match_tl - { \bool_gset_eq:NN \g_@@_success_bool \l_@@_match_success_bool } + { + \bool_gset_eq:NN + \g_@@_success_bool + \l_@@_match_success_bool + } } \cs_new_protected:Npn \@@_multi_match:n #1 { @@ -4658,14 +4744,13 @@ \use:x { \int_set_eq:NN \l_@@_max_active_int \l_@@_min_active_int - \int_step_function:nnnN + \int_step_function:nnN { \l_@@_min_active_int } - { 1 } { \l_@@_max_active_int - 1 } \@@_match_one_active:n } - \__prg_break_point: - \bool_set_false:N \l_@@_fresh_thread_bool %^^A was arg of break_point:n + \prg_break_point: + \bool_set_false:N \l_@@_fresh_thread_bool \if_int_compare:w \l_@@_max_active_int > \l_@@_min_active_int \if_int_compare:w \l_@@_curr_pos_int < \l_@@_max_pos_int \exp_after:wN \exp_after:wN \exp_after:wN \@@_match_loop: @@ -4675,7 +4760,7 @@ \cs_new:Npn \@@_match_one_active:n #1 { \@@_use_state_and_submatches:nn - { \__intarray_item_fast:Nn \g_@@_thread_state_intarray {#1} } + { \__kernel_intarray_item:Nn \g_@@_thread_state_intarray {#1} } { \@@_toks_use:w #1 } } % \end{macrocode} @@ -4691,11 +4776,11 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_query_set:nnn #1#2#3 { - \__intarray_gset_fast:Nnn \g_@@_charcode_intarray + \__kernel_intarray_gset:Nnn \g_@@_charcode_intarray { \l_@@_curr_pos_int } {#3} - \__intarray_gset_fast:Nnn \g_@@_catcode_intarray + \__kernel_intarray_gset:Nnn \g_@@_catcode_intarray { \l_@@_curr_pos_int } {#2} - \__intarray_gset_fast:Nnn \g_@@_balance_intarray + \__kernel_intarray_gset:Nnn \g_@@_balance_intarray { \l_@@_curr_pos_int } { \l_@@_balance_int } \@@_toks_set:Nn \l_@@_curr_pos_int {#1} \int_incr:N \l_@@_curr_pos_int @@ -4714,10 +4799,10 @@ \cs_new_protected:Npn \@@_query_get: { \l_@@_curr_char_int - = \__intarray_item_fast:Nn \g_@@_charcode_intarray + = \__kernel_intarray_item:Nn \g_@@_charcode_intarray { \l_@@_curr_pos_int } \scan_stop: \l_@@_curr_catcode_int - = \__intarray_item_fast:Nn \g_@@_catcode_intarray + = \__kernel_intarray_item:Nn \g_@@_catcode_intarray { \l_@@_curr_pos_int } \scan_stop: } % \end{macrocode} @@ -4734,15 +4819,19 @@ % point will be terminated. % \begin{macrocode} \__kernel_patch:nnNNpn - { \@@_trace:nnx { regex } { 2 } { state~\int_use:N \l_@@_curr_state_int } } + { + \@@_trace:nnx { regex } { 2 } + { state~\int_use:N \l_@@_curr_state_int } + } { } \cs_new_protected:Npn \@@_use_state: { - \__intarray_gset_fast:Nnn \g_@@_state_active_intarray + \__kernel_intarray_gset:Nnn \g_@@_state_active_intarray { \l_@@_curr_state_int } { \l_@@_step_int } \@@_toks_use:w \l_@@_curr_state_int - \__intarray_gset_fast:Nnn \g_@@_state_active_intarray - { \l_@@_curr_state_int } { \l_@@_step_int + 1 } + \__kernel_intarray_gset:Nnn \g_@@_state_active_intarray + { \l_@@_curr_state_int } + { \int_eval:n { \l_@@_step_int + 1 } } } % \end{macrocode} % \end{macro} @@ -4757,7 +4846,7 @@ { \int_set:Nn \l_@@_curr_state_int {#1} \if_int_compare:w - \__intarray_item_fast:Nn \g_@@_state_active_intarray + \__kernel_intarray_item:Nn \g_@@_state_active_intarray { \l_@@_curr_state_int } < \l_@@_step_int \tl_set:Nn \l_@@_curr_submatches_prop {#2} @@ -4814,7 +4903,7 @@ \exp_not:n { \if_int_compare:w - \__intarray_item_fast:Nn \g_@@_state_active_intarray + \__kernel_intarray_item:Nn \g_@@_state_active_intarray { \l_@@_curr_state_int } #1 \exp_after:wN \@@_use_state: @@ -4838,8 +4927,8 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_action_cost:n #1 { - \exp_args:No \@@_store_state:n - { \__int_value:w \__int_eval:n { \l_@@_curr_state_int + #1 } } + \exp_args:Nx \@@_store_state:n + { \int_eval:n { \l_@@_curr_state_int + #1 } } } % \end{macrocode} % \end{macro} @@ -4853,7 +4942,7 @@ \cs_new_protected:Npn \@@_store_state:n #1 { \@@_store_submatches: - \__intarray_gset_fast:Nnn \g_@@_thread_state_intarray + \__kernel_intarray_gset:Nnn \g_@@_thread_state_intarray { \l_@@_max_active_int } {#1} \int_incr:N \l_@@_max_active_int } @@ -4898,7 +4987,7 @@ % empty match. Then mark that there was a successful match; it is % empty if it is \enquote{fresh}; and we store the current position % and submatches. The current step is then interrupted with -% \cs{__prg_break:}, and only paths with higher precedence are +% \cs{prg_break:}, and only paths with higher precedence are % pursued further. The values stored here may be overwritten by a % later success of a path with higher precedence. % \begin{macrocode} @@ -4912,7 +5001,7 @@ \int_set_eq:NN \l_@@_success_pos_int \l_@@_curr_pos_int \prop_set_eq:NN \l_@@_success_submatches_prop \l_@@_curr_submatches_prop - \__prg_break: + \prg_break: } } % \end{macrocode} @@ -4983,8 +5072,8 @@ \cs_new:Npn \@@_replacement_do_one_match:n #1 { \@@_query_range:nn - { \__intarray_item_fast:Nn \g_@@_submatch_prev_intarray {#1} } - { \__intarray_item_fast:Nn \g_@@_submatch_begin_intarray {#1} } + { \__kernel_intarray_item:Nn \g_@@_submatch_prev_intarray {#1} } + { \__kernel_intarray_item:Nn \g_@@_submatch_begin_intarray {#1} } } % \end{macrocode} % \end{macro} @@ -5020,19 +5109,19 @@ \cs_new:Npn \@@_query_range:nn #1#2 { \exp_after:wN \@@_query_range_loop:ww - \__int_value:w \__int_eval:w #1 \exp_after:wN ; - \__int_value:w \__int_eval:w #2 ; - \__prg_break_point: + \int_value:w \@@_int_eval:w #1 \exp_after:wN ; + \int_value:w \@@_int_eval:w #2 ; + \prg_break_point: } \cs_new:Npn \@@_query_range_loop:ww #1 ; #2 ; { \if_int_compare:w #1 < #2 \exp_stop_f: \else: - \exp_after:wN \__prg_break: + \exp_after:wN \prg_break: \fi: \@@_toks_use:w #1 \exp_stop_f: \exp_after:wN \@@_query_range_loop:ww - \__int_value:w \__int_eval:w #1 + 1 ; #2 ; + \int_value:w \@@_int_eval:w #1 + 1 ; #2 ; } % \end{macrocode} % \end{macro} @@ -5044,13 +5133,13 @@ \cs_new:Npn \@@_query_submatch:n #1 { \@@_query_range:nn - { \__intarray_item_fast:Nn \g_@@_submatch_begin_intarray {#1} } - { \__intarray_item_fast:Nn \g_@@_submatch_end_intarray {#1} } + { \__kernel_intarray_item:Nn \g_@@_submatch_begin_intarray {#1} } + { \__kernel_intarray_item:Nn \g_@@_submatch_end_intarray {#1} } } % \end{macrocode} % \end{macro} % -% \begin{macro}[rEXP]{\@@_submatch_balance:n} +% \begin{macro}{\@@_submatch_balance:n} % Every user function must result in a balanced token list (unbalanced % token lists cannot be stored by TeX). When we unpacked the query, we % kept track of the brace balance, hence the contribution from a given @@ -5061,22 +5150,36 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_submatch_balance:n #1 { - \__int_eval:n + \int_eval:n { \int_compare:nNnTF - { \__intarray_item_fast:Nn \g_@@_submatch_end_intarray {#1} } = 0 + { + \__kernel_intarray_item:Nn + \g_@@_submatch_end_intarray {#1} + } + = 0 { 0 } { - \__intarray_item_fast:Nn \g_@@_balance_intarray - { \__intarray_item_fast:Nn \g_@@_submatch_end_intarray {#1} } + \__kernel_intarray_item:Nn \g_@@_balance_intarray + { + \__kernel_intarray_item:Nn + \g_@@_submatch_end_intarray {#1} + } } - \int_compare:nNnTF - { \__intarray_item_fast:Nn \g_@@_submatch_begin_intarray {#1} } = 0 + { + \__kernel_intarray_item:Nn + \g_@@_submatch_begin_intarray {#1} + } + = 0 { 0 } { - \__intarray_item_fast:Nn \g_@@_balance_intarray - { \__intarray_item_fast:Nn \g_@@_submatch_begin_intarray {#1} } + \__kernel_intarray_item:Nn \g_@@_balance_intarray + { + \__kernel_intarray_item:Nn + \g_@@_submatch_begin_intarray {#1} + } } } } @@ -5087,8 +5190,7 @@ % % \begin{macro}{\@@_replacement:n} % \begin{macro}{\@@_replacement_aux:n} -% The replacement text is built incrementally by abusing \tn{toks} -% within a group (see \pkg{l3tl-build}). We keep track in +% The replacement text is built incrementally. We keep track in % \cs{l_@@_balance_int} of the balance of explicit begin- and % end-group tokens and we store in \cs{l_@@_balance_tl} some % code to compute the brace balance from submatches (see its @@ -5103,7 +5205,8 @@ { \@@_trace_pop:nnN { regex } { 1 } \@@_replacement:n } \cs_new_protected:Npn \@@_replacement:n #1 { - \__tl_build:Nw \l_@@_internal_a_tl + \group_begin: + \tl_build_begin:N \l_@@_build_tl \int_zero:N \l_@@_balance_int \tl_clear:N \l_@@_balance_tl \@@_escape_use:nnnn @@ -5122,7 +5225,7 @@ \if_int_compare:w \l_@@_replacement_csnames_int > 0 \exp_stop_f: \__kernel_msg_error:nnx { kernel } { replacement-missing-rbrace } { \int_use:N \l_@@_replacement_csnames_int } - \__tl_build_one:x + \tl_build_put_right:Nx \l_@@_build_tl { \prg_replicate:nn \l_@@_replacement_csnames_int \cs_end: } \fi: \seq_if_empty:NF \l_@@_replacement_category_seq @@ -5137,16 +5240,24 @@ \l_@@_balance_tl - \@@_submatch_balance:n {##1} } - \__tl_build_end: - \exp_args:No \@@_replacement_aux:n \l_@@_internal_a_tl + \tl_build_end:N \l_@@_build_tl + \exp_args:NNo + \group_end: + \@@_replacement_aux:n \l_@@_build_tl } \cs_new_protected:Npn \@@_replacement_aux:n #1 { \cs_set:Npn \@@_replacement_do_one_match:n ##1 { \@@_query_range:nn - { \__intarray_item_fast:Nn \g_@@_submatch_prev_intarray {##1} } - { \__intarray_item_fast:Nn \g_@@_submatch_begin_intarray {##1} } + { + \__kernel_intarray_item:Nn + \g_@@_submatch_prev_intarray {##1} + } + { + \__kernel_intarray_item:Nn + \g_@@_submatch_begin_intarray {##1} + } #1 } } @@ -5156,7 +5267,7 @@ % % \begin{macro}{\@@_replacement_normal:n} % Most characters are simply sent to the output by -% \cs{__tl_build_one:n}, unless a particular category code has been +% \cs{tl_build_put_right:Nn}, unless a particular category code has been % requested: then \cs{@@_replacement_c_A:w} or a similar auxiliary is % called. One exception is right parentheses, which restore the % category code in place before the group started. Note that the @@ -5167,7 +5278,7 @@ \cs_new_protected:Npn \@@_replacement_normal:n #1 { \tl_if_empty:NTF \l_@@_replacement_category_tl - { \__tl_build_one:n {#1} } + { \tl_build_put_right:Nn \l_@@_build_tl {#1} } { % ( \token_if_eq_charcode:NNTF #1 ) { @@ -5175,7 +5286,11 @@ \l_@@_replacement_category_tl } { - \use:c { @@_replacement_c_ \l_@@_replacement_category_tl :w } + \use:c + { + @@_replacement_c_ + \l_@@_replacement_category_tl :w + } \@@_replacement_normal:n {#1} } } @@ -5212,17 +5327,21 @@ % Unless the submatch appears inside a |\c{...}| or |\u{...}| % construction, it must be taken into account in the brace balance. % Later on, |##1| will be replaced by a pointer to the $0$-th submatch for a -% given match. We cannot use \cs{int_eval:n} because it is -% expandable, and would be expanded too early (short of adding -% \cs{exp_not:N}, making the code messy again). +% given match. There is an \cs{exp_not:N} here as at the point-of-use +% of \cs{l_@@_balance_tl} there is an \texttt{x}-type expansion which is needed +% to get |##1| in correctly. % \begin{macrocode} \cs_new_protected:Npn \@@_replacement_put_submatch:n #1 { \if_int_compare:w #1 < \l_@@_capturing_group_int - \__tl_build_one:n { \@@_query_submatch:n { #1 + ##1 } } + \tl_build_put_right:Nn \l_@@_build_tl + { \@@_query_submatch:n { \int_eval:n { #1 + ##1 } } } \if_int_compare:w \l_@@_replacement_csnames_int = 0 \exp_stop_f: \tl_put_right:Nn \l_@@_balance_tl - { + \@@_submatch_balance:n { \__int_eval:n { #1+##1 } } } + { + + \@@_submatch_balance:n + { \exp_not:N \int_eval:n { #1 + ##1 } } + } \fi: \fi: } @@ -5237,7 +5356,9 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_replacement_g:w #1#2 { - \str_if_eq_x:nnTF { #1#2 } { \@@_replacement_normal:n \c_left_brace_str } + \str_if_eq_x:nnTF + { #1#2 } + { \@@_replacement_normal:n \c_left_brace_str } { \l_@@_internal_a_int = \@@_replacement_g_digits:NN } { \@@_replacement_error:NNN g #1 #2 } } @@ -5308,9 +5429,11 @@ \cs_new_protected:Npn \@@_replacement_cu_aux:Nw #1 { \if_case:w \l_@@_replacement_csnames_int - \__tl_build_one:n { \exp_not:n { \exp_after:wN #1 \cs:w } } + \tl_build_put_right:Nn \l_@@_build_tl + { \exp_not:n { \exp_after:wN #1 \cs:w } } \else: - \__tl_build_one:n { \exp_not:n { \exp_after:wN \tl_to_str:V \cs:w } } + \tl_build_put_right:Nn \l_@@_build_tl + { \exp_not:n { \exp_after:wN \tl_to_str:V \cs:w } } \fi: \int_incr:N \l_@@_replacement_csnames_int } @@ -5324,7 +5447,9 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_replacement_u:w #1#2 { - \str_if_eq_x:nnTF { #1#2 } { \@@_replacement_normal:n \c_left_brace_str } + \str_if_eq_x:nnTF + { #1#2 } + { \@@_replacement_normal:n \c_left_brace_str } { \@@_replacement_cu_aux:Nw \exp_not:V } { \@@_replacement_error:NNN u #1#2 } } @@ -5339,7 +5464,7 @@ \cs_new_protected:Npn \@@_replacement_rbrace:N #1 { \if_int_compare:w \l_@@_replacement_csnames_int > 0 \exp_stop_f: - \__tl_build_one:n \cs_end: + \tl_build_put_right:Nn \l_@@_build_tl { \cs_end: } \int_decr:N \l_@@_replacement_csnames_int \else: \@@_replacement_normal:n {#1} @@ -5370,7 +5495,11 @@ #2 #3 } { - \str_if_eq:nnTF { #2 #3 } { \@@_replacement_normal:n ( } % ) + \str_if_eq:nnTF + { #2#3 } + { + \@@_replacement_normal:n ( % ) + } { \seq_push:NV \l_@@_replacement_category_seq \l_@@_replacement_category_tl @@ -5416,7 +5545,7 @@ \cs_new_protected:Npn \@@_replacement_char:nNN #1#2#3 { \tex_lccode:D 0 = `#3 \scan_stop: - \tex_lowercase:D { \__tl_build_one:n {#1} } + \tex_lowercase:D { \tl_build_put_right:Nn \l_@@_build_tl {#1} } } % \end{macrocode} % \end{macro} @@ -5460,7 +5589,10 @@ % character, we prepare for two \texttt{x}-expansions. % \begin{macrocode} \cs_new_protected:Npn \@@_replacement_c_C:w #1#2 - { \__tl_build_one:n { \exp_not:N \exp_not:N \exp_not:c {#2} } } + { + \tl_build_put_right:Nn \l_@@_build_tl + { \exp_not:N \exp_not:N \exp_not:c {#2} } + } % \end{macrocode} % \end{macro} % @@ -5546,7 +5678,7 @@ \__kernel_msg_error:nn { kernel } { replacement-null-space } \fi: \tex_lccode:D `\ = `#2 \scan_stop: - \tex_lowercase:D { \__tl_build_one:n {~} } + \tex_lowercase:D { \tl_build_put_right:Nn \l_@@_build_tl {~} } } % \end{macrocode} % \end{macro} @@ -5650,7 +5782,7 @@ } \cs_new_protected:Npn \regex_show:N #1 { - \__kernel_check_defined:NT #1 + \__kernel_chk_defined:NT #1 { \@@_show:N #1 \msg_show:nnxxxx { LaTeX / kernel } { show-regex } @@ -5691,15 +5823,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro} -% { -% \regex_extract_once:nnN, \regex_extract_once:NnN, -% \regex_extract_all:nnN, \regex_extract_all:NnN, -% \regex_replace_once:nnN, \regex_replace_once:NnN, -% \regex_replace_all:nnN, \regex_replace_all:NnN, -% \regex_split:nnN, \regex_split:NnN -% } -% \begin{macro}[TF] +% \begin{macro}[noTF] % { % \regex_extract_once:nnN, \regex_extract_once:NnN, % \regex_extract_all:nnN, \regex_extract_all:NnN, @@ -5735,7 +5859,6 @@ \@@_tmp:w \@@_split:nnN \regex_split:nnN \regex_split:NnN % \end{macrocode} % \end{macro} -% \end{macro} % % \subsubsection{Variables and helpers for user functions} % @@ -5777,9 +5900,9 @@ % \begin{variable}{\g_@@_submatch_prev_intarray, \g_@@_submatch_begin_intarray, \g_@@_submatch_end_intarray} % Hold the place where the match attempt begun and the end-points of each submatch. % \begin{macrocode} -\__intarray_new:Nn \g_@@_submatch_prev_intarray { 65536 } -\__intarray_new:Nn \g_@@_submatch_begin_intarray { 65536 } -\__intarray_new:Nn \g_@@_submatch_end_intarray { 65536 } +\intarray_new:Nn \g_@@_submatch_prev_intarray { 65536 } +\intarray_new:Nn \g_@@_submatch_begin_intarray { 65536 } +\intarray_new:Nn \g_@@_submatch_end_intarray { 65536 } % \end{macrocode} % \end{variable} % @@ -5883,17 +6006,18 @@ \group_begin: \@@_multi_match:n { - \if_int_compare:w \l_@@_start_pos_int < \l_@@_success_pos_int + \if_int_compare:w + \l_@@_start_pos_int < \l_@@_success_pos_int \@@_extract: - \__intarray_gset_fast:Nnn \g_@@_submatch_prev_intarray + \__kernel_intarray_gset:Nnn \g_@@_submatch_prev_intarray { \l_@@_zeroth_submatch_int } { 0 } - \__intarray_gset_fast:Nnn \g_@@_submatch_end_intarray + \__kernel_intarray_gset:Nnn \g_@@_submatch_end_intarray { \l_@@_zeroth_submatch_int } { - \__intarray_item_fast:Nn \g_@@_submatch_begin_intarray + \__kernel_intarray_item:Nn \g_@@_submatch_begin_intarray { \l_@@_zeroth_submatch_int } } - \__intarray_gset_fast:Nnn \g_@@_submatch_begin_intarray + \__kernel_intarray_gset:Nnn \g_@@_submatch_begin_intarray { \l_@@_zeroth_submatch_int } { \l_@@_start_pos_int } \fi: @@ -5901,12 +6025,12 @@ #1 \@@_match:n {#2} %<assert>\assert_int:n { \l_@@_curr_pos_int = \l_@@_max_pos_int } - \__intarray_gset_fast:Nnn \g_@@_submatch_prev_intarray + \__kernel_intarray_gset:Nnn \g_@@_submatch_prev_intarray { \l_@@_submatch_int } { 0 } - \__intarray_gset_fast:Nnn \g_@@_submatch_end_intarray + \__kernel_intarray_gset:Nnn \g_@@_submatch_end_intarray { \l_@@_submatch_int } { \l_@@_max_pos_int } - \__intarray_gset_fast:Nnn \g_@@_submatch_begin_intarray + \__kernel_intarray_gset:Nnn \g_@@_submatch_begin_intarray { \l_@@_submatch_int } { \l_@@_start_pos_int } \int_incr:N \l_@@_submatch_int @@ -5925,39 +6049,36 @@ % from \cs{l_@@_min_submatch_int} to % \cs{l_@@_submatch_int} (exclusive). Extract the relevant ranges % into \cs{l_@@_internal_a_tl}. We detect unbalanced results using -% the two flags \texttt{@@_begin} and \texttt{@@_end}, raised +% the two flags \texttt{__regex_begin} and \texttt{__regex_end}, raised % whenever we see too many begin-group or end-group tokens in a -% submatch. We disable \cs{__seq_item:n} to prevent two -% \texttt{x}-expansions. +% submatch. % \begin{macrocode} \cs_new_protected:Npn \@@_group_end_extract_seq:N #1 { - \cs_set_eq:NN \__seq_item:n \scan_stop: \flag_clear:n { @@_begin } \flag_clear:n { @@_end } - \tl_set:Nx \l_@@_internal_a_tl + \seq_set_from_function:NnN \l_@@_internal_seq { - \s__seq - \int_step_function:nnnN - { \l_@@_min_submatch_int } - { 1 } + \int_step_function:nnN { \l_@@_min_submatch_int } { \l_@@_submatch_int - 1 } - \@@_extract_seq_aux:n } + \@@_extract_seq_aux:n \int_compare:nNnF - { \flag_height:n { @@_begin } + \flag_height:n { @@_end } } - = 0 + { + \flag_height:n { @@_begin } + + \flag_height:n { @@_end } + } + = 0 { \__kernel_msg_error:nnxxx { kernel } { result-unbalanced } { splitting~or~extracting~submatches } { \flag_height:n { @@_end } } { \flag_height:n { @@_begin } } } - \use:x - { - \group_end: - \tl_set:Nn \exp_not:N #1 { \l_@@_internal_a_tl } - } + \seq_set_map:NNn \l_@@_internal_seq \l_@@_internal_seq {##1} + \exp_args:NNNo + \group_end: + \tl_set:Nn #1 { \l_@@_internal_seq } } % \end{macrocode} % \end{macro} @@ -5970,11 +6091,8 @@ % \begin{macrocode} \cs_new:Npn \@@_extract_seq_aux:n #1 { - \__seq_item:n - { - \exp_after:wN \@@_extract_seq_aux:ww - \__int_value:w \@@_submatch_balance:n {#1} ; #1; - } + \exp_after:wN \@@_extract_seq_aux:ww + \int_value:w \@@_submatch_balance:n {#1} ; #1; } \cs_new:Npn \@@_extract_seq_aux:ww #1; #2; { @@ -6010,31 +6128,34 @@ \int_set_eq:NN \l_@@_zeroth_submatch_int \l_@@_submatch_int \prg_replicate:nn \l_@@_capturing_group_int { - \__intarray_gset_fast:Nnn \g_@@_submatch_begin_intarray + \__kernel_intarray_gset:Nnn \g_@@_submatch_begin_intarray { \l_@@_submatch_int } { 0 } - \__intarray_gset_fast:Nnn \g_@@_submatch_end_intarray + \__kernel_intarray_gset:Nnn \g_@@_submatch_end_intarray { \l_@@_submatch_int } { 0 } - \__intarray_gset_fast:Nnn \g_@@_submatch_prev_intarray + \__kernel_intarray_gset:Nnn \g_@@_submatch_prev_intarray { \l_@@_submatch_int } { 0 } \int_incr:N \l_@@_submatch_int } \prop_map_inline:Nn \l_@@_success_submatches_prop { \if_int_compare:w ##1 - 1 \exp_stop_f: - \exp_after:wN \@@_extract_e:wn \__int_value:w + \exp_after:wN \@@_extract_e:wn \int_value:w \else: - \exp_after:wN \@@_extract_b:wn \__int_value:w + \exp_after:wN \@@_extract_b:wn \int_value:w \fi: - \__int_eval:w \l_@@_zeroth_submatch_int + ##1 {##2} + \@@_int_eval:w \l_@@_zeroth_submatch_int + ##1 {##2} } - \__intarray_gset_fast:Nnn \g_@@_submatch_prev_intarray + \__kernel_intarray_gset:Nnn \g_@@_submatch_prev_intarray { \l_@@_zeroth_submatch_int } { \l_@@_start_pos_int } \fi: } \cs_new_protected:Npn \@@_extract_b:wn #1 < #2 - { \__intarray_gset_fast:Nnn \g_@@_submatch_begin_intarray {#1} {#2} } + { + \__kernel_intarray_gset:Nnn + \g_@@_submatch_begin_intarray {#1} {#2} + } \cs_new_protected:Npn \@@_extract_e:wn #1 > #2 - { \__intarray_gset_fast:Nnn \g_@@_submatch_end_intarray {#1} {#2} } + { \__kernel_intarray_gset:Nnn \g_@@_submatch_end_intarray {#1} {#2} } % \end{macrocode} % \end{macro} % @@ -6072,10 +6193,11 @@ } \tl_set:Nx \l_@@_internal_a_tl { - \@@_replacement_do_one_match:n { \l_@@_zeroth_submatch_int } + \@@_replacement_do_one_match:n + { \l_@@_zeroth_submatch_int } \@@_query_range:nn { - \__intarray_item_fast:Nn \g_@@_submatch_end_intarray + \__kernel_intarray_item:Nn \g_@@_submatch_end_intarray { \l_@@_zeroth_submatch_int } } { \l_@@_max_pos_int } @@ -6170,26 +6292,20 @@ % % Messages for the preparsing phase. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { trailing-backslash } - { Trailing~escape~character~'\iow_char:N\\'. } - { - A~regular~expression~or~its~replacement~text~ends~with~ - the~escape~character~'\iow_char:N\\'.~It~will~be~ignored. - } -\__kernel_msg_new:nnnn { kernel } { x-missing-rbrace } - { Missing~closing~brace~in~'\iow_char:N\\x'~hexadecimal~sequence. } +\use:x { - You~wrote~something~like~ - '\iow_char:N\\x\{...#1'.~ - The~closing~brace~is~missing. - } -\__kernel_msg_new:nnnn { kernel } { x-overflow } - { Character~code~'#1'~too~large~in~'\iow_char:N\\x'~hexadecimal~sequence. } - { - You~wrote~something~like~ - '\iow_char:N\\x\{\int_to_Hex:n{#1}\}'.~ - The~character~code~#1~is~larger~than~ - the~maximum~value~\int_use:N \c_max_char_int. + \__kernel_msg_new:nnn { kernel } { trailing-backslash } + { Trailing~escape~char~'\iow_char:N\\'~in~regex~or~replacement. } + \__kernel_msg_new:nnn { kernel } { x-missing-rbrace } + { + Missing~brace~'\iow_char:N\}'~in~regex~ + '...\iow_char:N\\x\iow_char:N\{...##1'. + } + \__kernel_msg_new:nnn { kernel } { x-overflow } + { + Character~code~##1~too~large~in~ + \iow_char:N\\x\iow_char:N\{##2\iow_char:N\}~regex. + } } % \end{macrocode} % @@ -6294,6 +6410,12 @@ control~sequence~or~the~next~group~to~be~made~of~control~sequences.~ It~only~makes~sense~to~follow~it~by~'.'~or~by~a~group. } +\__kernel_msg_new:nnnn { kernel } { c-lparen-in-class } + { Catcode~test~cannot~apply~to~group~in~character~class } + { + Construction~such~as~'\iow_char:N\\cL(abc)'~are~not~allowed~inside~a~ + class~'[...]'~because~classes~do~not~match~multiple~characters~at~once. + } \__kernel_msg_new:nnnn { kernel } { c-missing-rbrace } { Missing~right~brace~inserted~for~'\iow_char:N\\c'~escape. } { @@ -6334,7 +6456,8 @@ \str_if_eq_x:nnTF { } {#2} { reached~the~end~of~the~string~ } { encountered~an~escaped~alphanumeric~character '\iow_char:N\\#2'~ } - when~parsing~the~argument~of~an~'\iow_char:N\\u\iow_char:N\{...\}'~escape. + when~parsing~the~argument~of~an~ + '\iow_char:N\\u\iow_char:N\{...\}'~escape. } % \end{macrocode} % @@ -6467,7 +6590,8 @@ { Missing~right~parenthesis~inserted~in~replacement~text. } { There~ \int_compare:nTF { #1 = 1 } { was } { were } ~ #1~ - missing~right~\int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } . + missing~right~ + \int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } . } % \end{macrocode} % @@ -6518,7 +6642,7 @@ % typically~1. If the module's current tracing level is less than % |#2| show nothing, otherwise write |#3| to the terminal. % \begin{macrocode} -\__kernel_debug:TF +\__kernel_if_debug:TF { \cs_new_protected:Npn \@@_trace_push:nnN #1#2#3 { \@@_trace:nnx {#1} {#2} { entering~ \token_to_str:N #3 } } @@ -6547,13 +6671,12 @@ % stored in \tn{toks} from $0$ to \cs{l_@@_max_state_int} % (excluded). % \begin{macrocode} -\__kernel_debug:TF +\__kernel_if_debug:TF { \cs_new_protected:Npn \@@_trace_states:n #1 { - \int_step_inline:nnnn + \int_step_inline:nnn \l_@@_min_state_int - { 1 } { \l_@@_max_state_int - 1 } { \@@_trace:nnx { regex } {#1} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx index 95dddce8afa..0a8c475fd57 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3seq.dtx Copyright (C) 1990-2017 The LaTeX3 Project +%% File: l3seq.dtx Copyright (C) 1990-2018 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -855,40 +855,6 @@ % Writes the entries in the \meta{sequence} in the log file. % \end{function} % -% \section{Internal sequence functions} -% -% \begin{variable}{\s__seq} -% This scan mark (equal to \cs{scan_stop:}) marks the beginning of a -% sequence variable. -% \end{variable} -% -% \begin{function}[EXP]{\__seq_item:n} -% \begin{syntax} -% \cs{__seq_item:n} \Arg{item} -% \end{syntax} -% The internal token used to begin each sequence entry. If expanded -% outside of a mapping or manipulation function, an error is -% raised. The definition should always be set globally. -% \end{function} -% -% \begin{function}{\__seq_push_item_def:n, \__seq_push_item_def:x} -% \begin{syntax} -% \cs{__seq_push_item_def:n} \Arg{code} -% \end{syntax} -% Saves the definition of \cs{__seq_item:n} and redefines it to -% accept one parameter and expand to \meta{code}. This function -% should always be balanced by use of \cs{__seq_pop_item_def:}. -% \end{function} -% -% \begin{function}{\__seq_pop_item_def:} -% \begin{syntax} -% \cs{__seq_pop_item_def:} -% \end{syntax} -% Restores the definition of \cs{__seq_item:n} most recently saved by -% \cs{__seq_push_item_def:n}. This function should always be used in -% a balanced pair with \cs{__seq_push_item_def:n}. -% \end{function} -% % \end{documentation} % % \begin{implementation} @@ -913,10 +879,40 @@ % \meta{item_1} \cs{seq_elt_end:} \ldots \cs{seq_elt:w} \meta{item_n} % \cs{seq_elt_end:}}. This allowed rapid searching using a delimited % function, but was not suitable for items containing |{|, |}| and |#| -% tokens, and also lead to the loss of surrounding braces around items. +% tokens, and also lead to the loss of surrounding braces around items +% +% \begin{function}[EXP]{\@@_item:n} +% \begin{syntax} +% \cs{@@_item:n} \Arg{item} +% \end{syntax} +% The internal token used to begin each sequence entry. If expanded +% outside of a mapping or manipulation function, an error is +% raised. The definition should always be set globally. +% \end{function} +% +% \begin{function}{\@@_push_item_def:n, \@@_push_item_def:x} +% \begin{syntax} +% \cs{@@_push_item_def:n} \Arg{code} +% \end{syntax} +% Saves the definition of \cs{@@_item:n} and redefines it to +% accept one parameter and expand to \meta{code}. This function +% should always be balanced by use of \cs{@@_pop_item_def:}. +% \end{function} +% +% \begin{function}{\@@_pop_item_def:} +% \begin{syntax} +% \cs{@@_pop_item_def:} +% \end{syntax} +% Restores the definition of \cs{@@_item:n} most recently saved by +% \cs{@@_push_item_def:n}. This function should always be used in +% a balanced pair with \cs{@@_push_item_def:n}. +% \end{function} % % \begin{variable}{\s_@@} -% The variable is defined in the \pkg{l3quark} module, loaded later. +% This private scan mark. +% \begin{macrocode} +\scan_new:N \s_@@ +% \end{macrocode} % \end{variable} % % \begin{macro}{\@@_item:n} @@ -962,7 +958,7 @@ % \begin{macrocode} \cs_new_protected:Npn \seq_new:N #1 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \cs_gset_eq:NN #1 \c_empty_seq } \cs_generate_variant:Nn \seq_new:N { c } @@ -1451,10 +1447,10 @@ #1 \group_end: \prg_return_false: - \__prg_break_point: + \prg_break_point: } \cs_new:Npn \@@_if_in: - { \__prg_break:n { \group_end: \prg_return_true: } } + { \prg_break:n { \group_end: \prg_return_true: } } \prg_generate_conditional_variant:Nnn \seq_if_in:Nn { NV , Nv , No , Nx , c , cV , cv , co , cx } { T , F , TF } % \end{macrocode} @@ -1542,30 +1538,29 @@ % % \begin{macro}{\seq_get_right:NN, \seq_get_right:cN} % \UnitTested -% \begin{macro}{\@@_get_right_loop:nn} -% First remove \cs{s_@@} and prepend \cs{q_no_value}, then take two -% arguments at a time. Before the right-hand end of the sequence, -% this is a brace group followed by \cs{@@_item:n}, both removed by -% \cs{use_none:nn}. At the end of the sequence, the two question -% marks are taken by \cs{use_none:nn}, and the assignment is placed -% before the right-most item. In the next iteration, -% \cs{@@_get_right_loop:nn} receives two empty arguments, and -% \cs{use_none:nn} stops the loop. +% \begin{macro}[EXP]{\@@_get_right_loop:nw, \@@_get_right_end:NnN} +% First remove \cs{s_@@} and prepend \cs{q_no_value}. The first +% argument of \cs{@@_get_right_loop:nw} is the last item found, and +% the second argument is empty until the end of the loop, where it is +% code that applies \cs{exp_not:n} to the last item and ends the loop. % \begin{macrocode} \cs_new_protected:Npn \seq_get_right:NN #1#2 { - \exp_after:wN \use_i_ii:nnn - \exp_after:wN \@@_get_right_loop:nn - \exp_after:wN \q_no_value - #1 - { ?? \tl_set:Nn #2 } - { } { } + \tl_set:Nx #2 + { + \exp_after:wN \use_i_ii:nnn + \exp_after:wN \@@_get_right_loop:nw + \exp_after:wN \q_no_value + #1 + \@@_get_right_end:NnN \@@_item:n + } } -\cs_new_protected:Npn \@@_get_right_loop:nn #1#2 +\cs_new:Npn \@@_get_right_loop:nw #1#2 \@@_item:n { - \use_none:nn #2 {#1} - \@@_get_right_loop:nn + #2 \use_none:n {#1} + \@@_get_right_loop:nw } +\cs_new:Npn \@@_get_right_end:NnN #1#2#3 { \exp_not:n {#2} } \cs_generate_variant:Nn \seq_get_right:NN { c } % \end{macrocode} % \end{macro} @@ -1646,18 +1641,26 @@ % \begin{macro}[TF]{\seq_gpop_right:NN, \seq_gpop_right:cN} % More or less the same for popping. % \begin{macrocode} -\prg_new_protected_conditional:Npnn \seq_pop_left:NN #1#2 { T , F , TF } +\prg_new_protected_conditional:Npnn \seq_pop_left:NN #1#2 + { T , F , TF } { \@@_pop_TF:NNNN \@@_pop_left:NNN \tl_set:Nn #1 #2 } -\prg_new_protected_conditional:Npnn \seq_gpop_left:NN #1#2 { T , F , TF } +\prg_new_protected_conditional:Npnn \seq_gpop_left:NN #1#2 + { T , F , TF } { \@@_pop_TF:NNNN \@@_pop_left:NNN \tl_gset:Nn #1 #2 } -\prg_new_protected_conditional:Npnn \seq_pop_right:NN #1#2 { T , F , TF } +\prg_new_protected_conditional:Npnn \seq_pop_right:NN #1#2 + { T , F , TF } { \@@_pop_TF:NNNN \@@_pop_right:NNN \tl_set:Nx #1 #2 } -\prg_new_protected_conditional:Npnn \seq_gpop_right:NN #1#2 { T , F , TF } +\prg_new_protected_conditional:Npnn \seq_gpop_right:NN #1#2 + { T , F , TF } { \@@_pop_TF:NNNN \@@_pop_right:NNN \tl_gset:Nx #1 #2 } -\prg_generate_conditional_variant:Nnn \seq_pop_left:NN { c } { T , F , TF } -\prg_generate_conditional_variant:Nnn \seq_gpop_left:NN { c } { T , F , TF } -\prg_generate_conditional_variant:Nnn \seq_pop_right:NN { c } { T , F , TF } -\prg_generate_conditional_variant:Nnn \seq_gpop_right:NN { c } { T , F , TF } +\prg_generate_conditional_variant:Nnn \seq_pop_left:NN { c } + { T , F , TF } +\prg_generate_conditional_variant:Nnn \seq_gpop_left:NN { c } + { T , F , TF } +\prg_generate_conditional_variant:Nnn \seq_pop_right:NN { c } + { T , F , TF } +\prg_generate_conditional_variant:Nnn \seq_gpop_right:NN { c } + { T , F , TF } % \end{macrocode} % \end{macro} % \end{macro} @@ -1665,21 +1668,21 @@ % \end{macro} % % \begin{macro}{\seq_item:Nn, \seq_item:cn} -% \begin{macro}{\@@_item:wNn, \@@_item:nN, \@@_item:nnn} +% \begin{macro}{\@@_item:wNn, \@@_item:nN, \@@_item:nwn} % The idea here is to find the offset of the item from the left, then use % a loop to grab the correct item. If the resulting offset is too large, -% then the stop code |{ ? \__prg_break: } { }| is used by the auxiliary, -% terminating the loop and returning nothing at all. +% then the argument delimited by \cs{@@_item:n} is \cs{prg_break:} instead +% of being empty, terminating the loop and returning nothing at all. % \begin{macrocode} \cs_new:Npn \seq_item:Nn #1 { \exp_after:wN \@@_item:wNn #1 \q_stop #1 } \cs_new:Npn \@@_item:wNn \s_@@ #1 \q_stop #2#3 { - \exp_args:Nf \@@_item:nnn + \exp_args:Nf \@@_item:nwn { \exp_args:Nf \@@_item:nN { \int_eval:n {#3} } #2 } #1 - { ? \__prg_break: } { } - \__prg_break_point: + \prg_break: \@@_item:n { } + \prg_break_point: } \cs_new:Npn \@@_item:nN #1#2 { @@ -1687,12 +1690,12 @@ { \int_eval:n { \seq_count:N #2 + 1 + #1 } } {#1} } -\cs_new:Npn \@@_item:nnn #1#2#3 +\cs_new:Npn \@@_item:nwn #1#2 \@@_item:n #3 { - \use_none:n #2 + #2 \int_compare:nNnTF {#1} = 1 - { \__prg_break:n { \exp_not:n {#3} } } - { \exp_args:Nf \@@_item:nnn { \int_eval:n { #1 - 1 } } } + { \prg_break:n { \exp_not:n {#3} } } + { \exp_args:Nf \@@_item:nwn { \int_eval:n { #1 - 1 } } } } \cs_generate_variant:Nn \seq_item:Nn { c } % \end{macrocode} @@ -1705,14 +1708,14 @@ % \UnitTested % \begin{macro}{\seq_map_break:n} % \UnitTested -% To break a function, the special token \cs{__prg_break_point:Nn} is +% To break a function, the special token \cs{prg_break_point:Nn} is % used to find the end of the code. Any ending code is then inserted % before the return value of \cs{seq_map_break:n} is inserted. % \begin{macrocode} \cs_new:Npn \seq_map_break: - { \__prg_map_break:Nn \seq_map_break: { } } + { \prg_map_break:Nn \seq_map_break: { } } \cs_new:Npn \seq_map_break:n - { \__prg_map_break:Nn \seq_map_break: } + { \prg_map_break:Nn \seq_map_break: } % \end{macrocode} % \end{macro} % \end{macro} @@ -1721,26 +1724,26 @@ % \UnitTested % \begin{macro}[rEXP]{\@@_map_function:NNn} % The idea here is to apply the code of |#2| to each item in the -% sequence without altering the definition of \cs{@@_item:n}. This -% is done as by noting that every odd token in the sequence must be -% \cs{@@_item:n}, which can be gobbled by \cs{use_none:n}. At the end of -% the loop, |#2| is instead |? \seq_map_break:|, which therefore breaks the -% loop without needing to do a (relatively-expensive) quark test. +% sequence without altering the definition of \cs{@@_item:n}. The +% argument delimited by \cs{@@_item:n} is almost always empty, except +% at the end of the loop where it is \cs{prg_break:}. This allows to +% break the loop without needing to do a (relatively-expensive) quark +% test. % \begin{macrocode} \cs_new:Npn \seq_map_function:NN #1#2 { \exp_after:wN \use_i_ii:nnn - \exp_after:wN \@@_map_function:NNn + \exp_after:wN \@@_map_function:Nw \exp_after:wN #2 #1 - { ? \seq_map_break: } { } - \__prg_break_point:Nn \seq_map_break: { } + \prg_break: \@@_item:n { } \prg_break_point: + \prg_break_point:Nn \seq_map_break: { } } -\cs_new:Npn \@@_map_function:NNn #1#2#3 +\cs_new:Npn \@@_map_function:Nw #1#2 \@@_item:n #3 { - \use_none:n #2 + #2 #1 {#3} - \@@_map_function:NNn #1 + \@@_map_function:Nw #1 } \cs_generate_variant:Nn \seq_map_function:NN { c } % \end{macrocode} @@ -1766,15 +1769,15 @@ } \cs_new_protected:Npn \@@_push_item_def: { - \int_gincr:N \g__prg_map_int - \cs_gset_eq:cN { __prg_map_ \int_use:N \g__prg_map_int :w } + \int_gincr:N \g__kernel_prg_map_int + \cs_gset_eq:cN { @@_map_ \int_use:N \g__kernel_prg_map_int :w } \@@_item:n } \cs_new_protected:Npn \@@_pop_item_def: { \cs_gset_eq:Nc \@@_item:n - { __prg_map_ \int_use:N \g__prg_map_int :w } - \int_gdecr:N \g__prg_map_int + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } + \int_gdecr:N \g__kernel_prg_map_int } % \end{macrocode} % \end{macro} @@ -1791,7 +1794,7 @@ { \@@_push_item_def:n {#2} #1 - \__prg_break_point:Nn \seq_map_break: { \@@_pop_item_def: } + \prg_break_point:Nn \seq_map_break: { \@@_pop_item_def: } } \cs_generate_variant:Nn \seq_map_inline:Nn { c } % \end{macrocode} @@ -1815,7 +1818,7 @@ \exp_not:n {#3} } #1 - \__prg_break_point:Nn \seq_map_break: { \@@_pop_item_def: } + \prg_break_point:Nn \seq_map_break: { \@@_pop_item_def: } } \cs_generate_variant:Nn \seq_map_variable:NNn { Nc } \cs_generate_variant:Nn \seq_map_variable:NNn { c , cc } @@ -1823,20 +1826,37 @@ % \end{macro} % % \begin{macro}{\seq_count:N, \seq_count:c} -% \begin{macro}{\@@_count:n} -% Counting the items in a sequence is done using the same approach as for -% other count functions: turn each entry into a \texttt{+1} then use -% integer evaluation to actually do the mathematics. +% \begin{macro}{\@@_count:w, \@@_count_end:w} +% Since counting the items in a sequence is quite common, we optimize +% it by grabbing $8$~items at a time and correspondingly adding $8$ to +% an integer expression. At the end of the loop, |#9| is +% \cs{@@_count_end:w} instead of being empty. It removes |8+| and +% instead places the number of \cs{@@_item:n} that \cs{@@_count:w} +% grabbed before reaching the end of the sequence. % \begin{macrocode} \cs_new:Npn \seq_count:N #1 { \int_eval:n { - 0 - \seq_map_function:NN #1 \@@_count:n + \exp_after:wN \use_i:nn + \exp_after:wN \@@_count:w + #1 + \@@_count_end:w \@@_item:n 7 + \@@_count_end:w \@@_item:n 6 + \@@_count_end:w \@@_item:n 5 + \@@_count_end:w \@@_item:n 4 + \@@_count_end:w \@@_item:n 3 + \@@_count_end:w \@@_item:n 2 + \@@_count_end:w \@@_item:n 1 + \@@_count_end:w \@@_item:n 0 + \prg_break_point: } } -\cs_new:Npn \@@_count:n #1 { + 1 } +\cs_new:Npn \@@_count:w + #1 \@@_item:n #2 \@@_item:n #3 \@@_item:n #4 \@@_item:n + #5 \@@_item:n #6 \@@_item:n #7 \@@_item:n #8 #9 \@@_item:n + { #9 8 + \@@_count:w } +\cs_new:Npn \@@_count_end:w 8 + \@@_count:w #1#2 \prg_break_point: {#1} \cs_generate_variant:Nn \seq_count:N { c } % \end{macrocode} % \end{macro} @@ -1983,7 +2003,7 @@ \cs_generate_variant:Nn \seq_log:N { c } \cs_new_protected:Npn \@@_show:NN #1#2 { - \__kernel_check_defined:NT #2 + \__kernel_chk_defined:NT #2 { #1 { LaTeX/kernel } { show-seq } { \token_to_str:N #2 } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx index 250f71b65ce..4dd819ce073 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx @@ -42,7 +42,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -1042,33 +1042,6 @@ % \end{texnote} % \end{function} % -% \section{Internal functions} -% -% \begin{function}[EXP]{\__dim_eval:w, \__dim_eval_end:} -% \begin{syntax} -% \cs{__dim_eval:w} \meta{dimexpr} \cs{__dim_eval_end:} -% \end{syntax} -% Evaluates \meta{dimension expression} as described for \cs{dim_eval:n}. -% The evaluation stops when an unexpandable token which is not a valid -% part of a dimension is read or when \cs{__dim_eval_end:} is -% reached. The latter is gobbled by the scanner mechanism: -% \cs{__dim_eval_end:} itself is unexpandable but used correctly -% the entire construct is expandable. -% \begin{texnote} -% This is the \eTeX{} primitive \tn{dimexpr}. -% \end{texnote} -% \end{function} -% -% \begin{function}[EXP]{\__dim_eval:n} -% \begin{syntax} -% \cs{__dim_eval:n} \Arg{dimexpr} -% \end{syntax} -% By default this expands to \cs{__dim_eval:w} \meta{dimexpr} -% \cs{__dim_eval_end:} but when debugging is enabled this expands to a -% more complicated construction that evaluates \meta{dimexpr} with -% parentheses and within a brace group to detect early termination. -% \end{function} -% % \end{documentation} % % \begin{implementation} @@ -1106,7 +1079,7 @@ %<*package> \cs_new_protected:Npn \dim_new:N #1 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \cs:w newdimen \cs_end: #1 } %</package> @@ -1244,7 +1217,10 @@ { \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: \scan_stop: } \@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \dim_gadd:Nn #1#2 - { \tex_global:D \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: \scan_stop: } + { + \tex_global:D \tex_advance:D #1 by + \@@_eval:w #2 \@@_eval_end: \scan_stop: + } \cs_generate_variant:Nn \dim_add:Nn { c } \cs_generate_variant:Nn \dim_gadd:Nn { c } \@@_tmp:w \__kernel_chk_var_local:N @@ -1252,7 +1228,10 @@ { \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: \scan_stop: } \@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \dim_gsub:Nn #1#2 - { \tex_global:D \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: \scan_stop: } + { + \tex_global:D \tex_advance:D #1 by + -\@@_eval:w #2 \@@_eval_end: \scan_stop: + } \cs_generate_variant:Nn \dim_sub:Nn { c } \cs_generate_variant:Nn \dim_gsub:Nn { c } % \end{macrocode} @@ -1328,13 +1307,13 @@ % \begin{macro}{\@@_ratio:n} % With dimension expressions, something like |10 pt * ( 5 pt / 10 pt )| does % not work. Instead, the ratio part needs to be converted to an integer -% expression. Using \cs{__int_value:w} forces everything into |sp|, avoiding +% expression. Using \cs{int_value:w} forces everything into |sp|, avoiding % any decimal parts. % \begin{macrocode} \cs_new:Npn \dim_ratio:nn #1#2 { \@@_ratio:n {#1} / \@@_ratio:n {#2} } \cs_new:Npn \@@_ratio:n #1 - { \__int_value:w \@@_eval:w (#1) \@@_eval_end: } + { \int_value:w \@@_eval:w (#1) \@@_eval_end: } % \end{macrocode} % \end{macro} % \end{macro} @@ -1367,10 +1346,11 @@ % \@@_compare_<:w, % \@@_compare_>:w % } +% \begin{macro}{\@@_compare_error:} % This code is adapted from the \cs{int_compare:nTF} function. First % make sure that there is at least one relation operator, by % evaluating a dimension expression with a trailing -% \cs{__prg_compare_error:}. Just like for integers, the looping +% \cs{@@_compare_error:}. Just like for integers, the looping % auxiliary \cs{@@_compare:wNN} closes a primitive conditional and % opens a new one. It is actually easier to grab a dimension operand % than an integer one, because once evaluated, dimensions all end with @@ -1381,9 +1361,9 @@ \prg_new_conditional:Npnn \dim_compare:n #1 { p , T , F , TF } { \exp_after:wN \@@_compare:w - \dim_use:N \@@_eval:w #1 \__prg_compare_error: + \dim_use:N \@@_eval:w #1 \@@_compare_error: } -\cs_new:Npn \@@_compare:w #1 \__prg_compare_error: +\cs_new:Npn \@@_compare:w #1 \@@_compare_error: { \exp_after:wN \if_false: \exp:w \exp_end_continue_f:w \@@_compare:wNN #1 ? { = \@@_compare_end:w \else: } \q_stop @@ -1412,10 +1392,17 @@ #1 \reverse_if:N #2 > #3 = { #1 #2 < #3 } \cs_new:Npn \@@_compare_end:w #1 \prg_return_false: #2 \q_stop { #1 \prg_return_false: \else: \prg_return_true: \fi: } +\cs_new_protected:Npn \@@_compare_error: + { + \if_int_compare:w \c_zero \c_zero \fi: + = + \@@_compare_error: + } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}[EXP, noTF]{\dim_case:nn} % \begin{macro}{\@@_case:nnTF} @@ -1452,7 +1439,8 @@ { \@@_case_end:nw {#3} } { \@@_case:nw {#1} } } -\cs_new_eq:NN \@@_case_end:nw \__prg_case_end:nw +\cs_new:Npn \@@_case_end:nw #1#2#3 \q_mark #4#5 \q_stop + { \exp_end: #1 #4 } % \end{macrocode} % \end{macro} % \end{macro} @@ -1555,9 +1543,18 @@ % \begin{macrocode} \__kernel_patch_args:nNNpn { - { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \dim_step_function:nnnN } - { \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } \dim_step_function:nnnN } - { \__kernel_chk_expr:nNnN {#3} \@@_eval:w { } \dim_step_function:nnnN } + { + \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } + \dim_step_function:nnnN + } + { + \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } + \dim_step_function:nnnN + } + { + \__kernel_chk_expr:nNnN {#3} \@@_eval:w { } + \dim_step_function:nnnN + } } \cs_new:Npn \dim_step_function:nnnN #1#2#3 { @@ -1599,25 +1596,25 @@ % The approach here is to build a function, with a global integer % required to make the nesting safe (as seen in other in line % functions), and map that function using \cs{dim_step_function:nnnN}. -% We put a \cs{__prg_break_point:Nn} so that \texttt{map_break} -% functions from other modules correctly decrement \cs{g__prg_map_int} +% We put a \cs{prg_break_point:Nn} so that \texttt{map_break} +% functions from other modules correctly decrement \cs{g__kernel_prg_map_int} % before looking for their own break point. The first argument is % \cs{scan_stop:}, so that no breaking function recognizes this break % point as its own. % \begin{macrocode} \cs_new_protected:Npn \dim_step_inline:nnnn { - \int_gincr:N \g__prg_map_int + \int_gincr:N \g__kernel_prg_map_int \exp_args:NNc \@@_step:NNnnnn \cs_gset_protected:Npn - { __prg_map_ \int_use:N \g__prg_map_int :w } + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } } \cs_new_protected:Npn \dim_step_variable:nnnNn #1#2#3#4#5 { - \int_gincr:N \g__prg_map_int + \int_gincr:N \g__kernel_prg_map_int \exp_args:NNc \@@_step:NNnnnn \cs_gset_protected:Npx - { __prg_map_ \int_use:N \g__prg_map_int :w } + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } {#1}{#2}{#3} { \tl_set:Nn \exp_not:N #4 {##1} @@ -1628,7 +1625,7 @@ { #1 #2 ##1 {#6} \dim_step_function:nnnN {#3} {#4} {#5} #2 - \__prg_break_point:Nn \scan_stop: { \int_gdecr:N \g__prg_map_int } + \prg_break_point:Nn \scan_stop: { \int_gdecr:N \g__kernel_prg_map_int } } % \end{macrocode} % \end{macro} @@ -1647,18 +1644,6 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_eval:n} -% Evaluating a dimension expression expandably. This is for use in -% other modules, to avoid having to patch many commands. The only -% difference with \cs{dim_eval:n} is the lack of \cs{dim_use:N}, to -% produce an internal dimension rather than expand it into characters. -% \begin{macrocode} -\__kernel_patch_args:nNNpn - { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \@@_eval:n } } -\cs_new:Npn \@@_eval:n #1 { \@@_eval:w #1 \@@_eval_end: } -% \end{macrocode} -% \end{macro} -% % \begin{macro}{\dim_use:N, \dim_use:c} % Accessing a \meta{dim}. % \begin{macrocode} @@ -1702,7 +1687,7 @@ % \end{macro} % % \begin{macro}[EXP]{\dim_to_decimal_in_bp:n} -% Conversion to big points is done using a scaling inside \cs{__dim_eval:w} +% Conversion to big points is done using a scaling inside \cs{@@_eval:w} % as \eTeX{} does that using $64$-bit precision. Here, $800/803$ is the % integer fraction for $72/72.27$. This is a common case so is hand-coded % for accuracy (and speed). @@ -1717,9 +1702,14 @@ % off-scale. % \begin{macrocode} \__kernel_patch_args:nNNpn - { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \dim_to_decimal_in_sp:n } } + { + { + \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } + \dim_to_decimal_in_sp:n + } + } \cs_new:Npn \dim_to_decimal_in_sp:n #1 - { \int_eval:n { \@@_eval:w #1 \@@_eval_end: } } + { \int_value:w \@@_eval:w #1 \@@_eval_end: } % \end{macrocode} % \end{macro} % @@ -1799,13 +1789,17 @@ % % \subsection{Creating and initialising \texttt{skip} variables} % +% \begin{macrocode} +%<@@=skip> +% \end{macrocode} +% % \begin{macro}{\skip_new:N, \skip_new:c} % Allocation of a new internal registers. % \begin{macrocode} %<*package> \cs_new_protected:Npn \skip_new:N #1 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \cs:w newskip \cs_end: #1 } %</package> @@ -1948,19 +1942,15 @@ % \begin{macrocode} \prg_new_conditional:Npnn \skip_if_eq:nn #1#2 { p , T , F , TF } { - \if_int_compare:w - \__str_if_eq_x:nn { \skip_eval:n { #1 } } { \skip_eval:n { #2 } } - = 0 \exp_stop_f: - \prg_return_true: - \else: - \prg_return_false: - \fi: + \str_if_eq_x:nnTF { \skip_eval:n { #1 } } { \skip_eval:n { #2 } } + { \prg_return_true: } + { \prg_return_false: } } % \end{macrocode} % \end{macro} % % \begin{macro}[EXP,pTF]{\skip_if_finite:n} -% \begin{macro}[EXP]{\__skip_if_finite:wwNw} +% \begin{macro}[EXP]{\@@_if_finite:wwNw} % With \eTeX{}, we have an easy access to the order of infinities of % the stretch and shrink components of a skip. However, to access % both, we either need to evaluate the expression twice, or evaluate @@ -1980,11 +1970,11 @@ } \prg_new_conditional:Npnn \skip_if_finite:n ##1 { p , T , F , TF } { - \exp_after:wN \__skip_if_finite:wwNw + \exp_after:wN \@@_if_finite:wwNw \skip_use:N \etex_glueexpr:D ##1 ; \prg_return_false: #1 ; \prg_return_true: \q_stop } - \cs_new:Npn \__skip_if_finite:wwNw ##1 #1 ##2 ; ##3 ##4 \q_stop {##3} + \cs_new:Npn \@@_if_finite:wwNw ##1 #1 ##2 ; ##3 ##4 \q_stop {##3} } \exp_args:No \@@_tmp:w { \tl_to_str:n { fil } } % \end{macrocode} @@ -2020,12 +2010,22 @@ % \begin{macrocode} \cs_new_eq:NN \skip_horizontal:N \tex_hskip:D \__kernel_patch_args:nNNpn - { { \__kernel_chk_expr:nNnN {#1} \etex_glueexpr:D { } \skip_horizontal:n } } + { + { + \__kernel_chk_expr:nNnN {#1} \etex_glueexpr:D { } + \skip_horizontal:n + } + } \cs_new:Npn \skip_horizontal:n #1 { \skip_horizontal:N \etex_glueexpr:D #1 \scan_stop: } \cs_new_eq:NN \skip_vertical:N \tex_vskip:D \__kernel_patch_args:nNNpn - { { \__kernel_chk_expr:nNnN {#1} \etex_glueexpr:D { } \skip_vertical:n } } + { + { + \__kernel_chk_expr:nNnN {#1} \etex_glueexpr:D { } + \skip_vertical:n + } + } \cs_new:Npn \skip_vertical:n #1 { \skip_vertical:N \etex_glueexpr:D #1 \scan_stop: } \cs_generate_variant:Nn \skip_horizontal:N { c } @@ -2097,7 +2097,7 @@ %<*package> \cs_new_protected:Npn \muskip_new:N #1 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \cs:w newmuskip \cs_end: #1 } %</package> diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx index 10569020f22..45982d61328 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -81,7 +81,7 @@ % % \begin{texnote} % The current implementation is limited to sorting approximately -% $20000$ items ($40000$ in Lua\TeX{}), depending on what other +% $20000$ items ($40000$ in \LuaTeX{}), depending on what other % packages are loaded. % % Internally, the code from \pkg{l3sort} stores items in \tn{toks} @@ -91,6 +91,18 @@ % previously allocated \tn{toks} register is not a problem. % \end{texnote} % +% \begin{function}[added = 2017-02-06]{\sort_return_same:, \sort_return_swapped:} +% \begin{syntax} +% \cs{seq_sort:Nn} \meta{seq~var} +% ~~|{| \ldots{} \cs{sort_return_same:} or \cs{sort_return_swapped:} \ldots{} |}| +% \end{syntax} +% Indicates whether to keep the order or swap the order of two items +% that are compared in the sorting code. Only one of the +% \cs[no-index]{sort_return_\ldots{}} functions should be used by the +% code, according to the results of some tests on the items |#1| and +% |#2| to be compared. +% \end{function} +% % \end{documentation} % % \begin{implementation} @@ -107,6 +119,20 @@ % % \subsection{Variables} % +% \begin{variable}{\g_@@_internal_seq, \g_@@_internal_tl} +% Sorting happens in a group; the result is stored in those global +% variables before being copied outside the group to the proper +% places. For seq and tl this is more efficient than using \cs{use:x} +% (or some \cs{exp_args:NNNx}) to smuggle the definition outside the +% group since \TeX{} does not need to re-read tokens. For clist we +% don't gain anything since the result is converted from seq to clist +% anyways. +% \begin{macrocode} +\seq_new:N \g_@@_internal_seq +\tl_new:N \g_@@_internal_tl +% \end{macrocode} +% \end{variable} +% % \begin{variable} % { % \l_@@_length_int, \l_@@_min_int, \l_@@_top_int, \l_@@_max_int, @@ -232,7 +258,7 @@ % for \tn{loctoks} every time a sorting function is called, as % \pkg{etex} or \pkg{elocalloc} could be loaded. % -% In Con\TeX{}t MkIV the range is from +% In \ConTeXt{} MkIV the range is from % $|\c_syst_last_allocated_toks|+1$ to \cs{c_max_register_int}, and in % MkII it is from $|\lastallocatedtoks|+1$ to \cs{c_max_register_int}. % In all these cases, call \cs{@@_shrink_range:}. The \LaTeX3 format @@ -303,163 +329,124 @@ % % \subsection{Protected user commands} % -% \begin{macro}{\@@_main:NNNnNn} +% \begin{macro}{\@@_main:NNNn} % Sorting happens in three steps. First store items in \tn{toks} % registers ranging from \cs{l_@@_min_int} to $\cs{l_@@_top_int}-1$, -% while checking that the list is not too -% long. If we reach the maximum length, all further -% items are entirely ignored after raising an error. -% Secondly, sort the array of \tn{toks} registers, -% using the user-defined sorting function, |#6|. -% Finally, unpack the \tn{toks} registers (now sorted) -% into a variable of the right type, by \texttt{x}-expanding -% the code in |#4|, specific to each type of list. +% while checking that the list is not too long. If we reach the +% maximum length, that's an error; exit the group. Secondly, sort the +% array of \tn{toks} registers, using the user-defined sorting +% function: \cs{@@_level:} calls \cs{@@_compare:nn} as needed. +% Finally, unpack the \tn{toks} registers (now sorted) into the target +% tl, or into \cs{g_@@_internal_seq} for seq and clist. This is done +% by \cs{@@_seq:NNNNn} and \cs{@@_tl:NNn}. % \begin{macrocode} -\cs_new_protected:Npn \@@_main:NNNnNn #1#2#3#4#5#6 +\cs_new_protected:Npn \@@_main:NNNn #1#2#3#4 { - \group_begin: -%<package> \@@_disable_toksdef: - \@@_compute_range: - \int_set_eq:NN \l_@@_top_int \l_@@_min_int - #2 #5 - { - \if_int_compare:w \l_@@_top_int = \l_@@_max_int - \@@_too_long_error:NNw #3 #5 - \fi: - \tex_toks:D \l_@@_top_int {##1} - \int_incr:N \l_@@_top_int - } - \int_set:Nn \l_@@_length_int - { \l_@@_top_int - \l_@@_min_int } - \cs_set:Npn \@@_compare:nn ##1 ##2 { #6 } - \int_set:Nn \l_@@_block_int { 1 } - \@@_level: - \use:x - { - \group_end: - #1 \exp_not:N #5 {#4} - } +%<package> \@@_disable_toksdef: + \@@_compute_range: + \int_set_eq:NN \l_@@_top_int \l_@@_min_int + #1 #3 + { + \if_int_compare:w \l_@@_top_int = \l_@@_max_int + \@@_too_long_error:NNw #2 #3 + \fi: + \tex_toks:D \l_@@_top_int {##1} + \int_incr:N \l_@@_top_int + } + \int_set:Nn \l_@@_length_int + { \l_@@_top_int - \l_@@_min_int } + \cs_set:Npn \@@_compare:nn ##1 ##2 {#4} + \int_set:Nn \l_@@_block_int { 1 } + \@@_level: } % \end{macrocode} % \end{macro} % -% \begin{macro}{\seq_sort:Nn, \seq_gsort:Nn} -% The first argument to \cs{@@_main:NNNnNn} is the final -% assignment function used, either \cs{tl_set:Nn} or -% \cs{tl_gset:Nn} to control local versus global results. -% The second argument is what mapping function is used when storing -% items to \tn{toks} registers, and the third breaks away from the -% loop. The fourth is used to build back the correct kind of list -% from the contents of the \tn{toks} registers, including the leading -% \cs{s__seq}. Fifth and sixth -% arguments are the variable to sort, and the sorting method -% as inline code. +% \begin{macro}{\tl_sort:Nn, \tl_sort:cn, \tl_gsort:Nn, \tl_gsort:cn} +% \begin{macro}{\@@_tl:NNn} +% \begin{macro}[EXP]{\@@_tl_toks:w} +% Call the main sorting function then unpack \tn{toks} registers +% outside the group into the target token list. The unpacking is done +% by \cs{@@_tl_toks:w}; registers are numbered from \cs{l_@@_min_int} +% to $\cs{l_@@_top_int}-1$. For expansion behaviour we need a couple +% of primitives. The \cs{tl_gclear:N} reduces memory usage. The +% \cs{prg_break_point:} is used by \cs{@@_main:NNNn} when the list is +% too long. % \begin{macrocode} -\cs_new_protected:Npn \seq_sort:Nn +\cs_new_protected:Npn \tl_sort:Nn { \@@_tl:NNn \tl_set_eq:NN } +\cs_generate_variant:Nn \tl_sort:Nn { c } +\cs_new_protected:Npn \tl_gsort:Nn { \@@_tl:NNn \tl_gset_eq:NN } +\cs_generate_variant:Nn \tl_gsort:Nn { c } +\cs_new_protected:Npn \@@_tl:NNn #1#2#3 { - \@@_main:NNNnNn \tl_set:Nn - \seq_map_inline:Nn \seq_map_break:n - { \s__seq \@@_toks:NN \exp_not:N \__seq_item:n } + \group_begin: + \@@_main:NNNn \tl_map_inline:Nn \tl_map_break:n #2 {#3} + \tl_gset:Nx \g_@@_internal_tl + { \@@_tl_toks:w \l_@@_min_int ; } + \group_end: + #1 #2 \g_@@_internal_tl + \tl_gclear:N \g_@@_internal_tl + \prg_break_point: } -\cs_generate_variant:Nn \seq_sort:Nn { c } -\cs_new_protected:Npn \seq_gsort:Nn +\cs_new:Npn \@@_tl_toks:w #1 ; { - \@@_main:NNNnNn \tl_gset:Nn - \seq_map_inline:Nn \seq_map_break:n - { \s__seq \@@_toks:NN \exp_not:N \__seq_item:n } + \if_int_compare:w #1 < \l_@@_top_int + { \tex_the:D \tex_toks:D #1 } + \exp_after:wN \@@_tl_toks:w + \int_value:w \int_eval:n { #1 + 1 } \exp_after:wN ; + \fi: } -\cs_generate_variant:Nn \seq_gsort:Nn { c } % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} % -% \begin{macro}{\tl_sort:Nn, \tl_sort:cn, \tl_gsort:Nn, \tl_gsort:cn} -% Again, use \cs{tl_set:Nn} or \cs{tl_gset:Nn} to control -% the scope of the assignment. Mapping through the token -% list is done with \cs{tl_map_inline:Nn}, and producing -% the token list is very similar to sequences, removing -% \cs{__seq_item:n}. +% \begin{macro}{\seq_sort:Nn, \seq_sort:cn, \seq_gsort:Nn, \seq_gsort:cn} +% \begin{macro}{\clist_sort:Nn, \clist_sort:cn, \clist_gsort:Nn, \clist_gsort:cn} +% \begin{macro}{\@@_seq:NNNNn} +% Use the same general framework for seq and clist. Apply the general +% sorting code, then unpack \tn{toks} into \cs{g_@@_internal_seq}. +% Outside the group copy or convert (for clist) the data to the target +% variable. The \cs{seq_gclear:N} reduces memory usage. The +% \cs{prg_break_point:} is used by \cs{@@_main:NNNn} when the list is +% too long. % \begin{macrocode} -\cs_new_protected:Npn \tl_sort:Nn +\cs_new_protected:Npn \seq_sort:Nn + { \@@_seq:NNNNn \seq_map_inline:Nn \seq_map_break:n \seq_set_eq:NN } +\cs_generate_variant:Nn \seq_sort:Nn { c } +\cs_new_protected:Npn \seq_gsort:Nn + { \@@_seq:NNNNn \seq_map_inline:Nn \seq_map_break:n \seq_gset_eq:NN } +\cs_generate_variant:Nn \seq_gsort:Nn { c } +\cs_new_protected:Npn \clist_sort:Nn { - \@@_main:NNNnNn \tl_set:Nn - \tl_map_inline:Nn \tl_map_break:n - { \@@_toks:NN \prg_do_nothing: \prg_do_nothing: } + \@@_seq:NNNNn \clist_map_inline:Nn \clist_map_break:n + \clist_set_from_seq:NN } -\cs_generate_variant:Nn \tl_sort:Nn { c } -\cs_new_protected:Npn \tl_gsort:Nn +\cs_generate_variant:Nn \clist_sort:Nn { c } +\cs_new_protected:Npn \clist_gsort:Nn { - \@@_main:NNNnNn \tl_gset:Nn - \tl_map_inline:Nn \tl_map_break:n - { \@@_toks:NN \prg_do_nothing: \prg_do_nothing: } + \@@_seq:NNNNn \clist_map_inline:Nn \clist_map_break:n + \clist_gset_from_seq:NN } -\cs_generate_variant:Nn \tl_gsort:Nn { c } -% \end{macrocode} -% \end{macro} -% -% \begin{macro} -% {\clist_sort:Nn, \clist_sort:cn, \clist_gsort:Nn, \clist_gsort:cn} -% \begin{macro}{\@@_clist:NNn} -% The case of empty comma-lists is a little bit special as usual, -% and filtered out: there is nothing to sort in that case. -% Otherwise, the input is done with \cs{clist_map_inline:Nn}, -% and the output requires some more elaborate processing than -% for sequences and token lists. The first comma must be removed. -% An item must be wrapped in an extra set of braces if it contains -% either the space or the comma characters. This is taken care of -% by \cs{clist_wrap_item:n}, but \cs{@@_toks:NN} would simply -% feed \cs{tex_the:D} \cs{tex_toks:D} \meta{number} as an -% argument to that function; hence we need to expand this argument -% once to unpack the register. -% \begin{macrocode} -\cs_new_protected:Npn \clist_sort:Nn - { \@@_clist:NNn \tl_set:Nn } -\cs_new_protected:Npn \clist_gsort:Nn - { \@@_clist:NNn \tl_gset:Nn } -\cs_generate_variant:Nn \clist_sort:Nn { c } \cs_generate_variant:Nn \clist_gsort:Nn { c } -\cs_new_protected:Npn \@@_clist:NNn #1#2#3 +\cs_new_protected:Npn \@@_seq:NNNNn #1#2#3#4#5 { - \clist_if_empty:NF #2 - { - \@@_main:NNNnNn #1 - \clist_map_inline:Nn \clist_map_break:n - { - \exp_last_unbraced:Nf \use_none:n - { \@@_toks:NN \exp_args:No \__clist_wrap_item:n } - } - #2 {#3} - } + \group_begin: + \@@_main:NNNn #1 #2 #4 {#5} + \seq_gset_from_inline_x:Nnn \g_@@_internal_seq + { + \int_step_function:nnN + { \l_@@_min_int } { \l_@@_top_int - 1 } + } + { \tex_the:D \tex_toks:D ##1 } + \group_end: + #3 #4 \g_@@_internal_seq + \seq_gclear:N \g_@@_internal_seq + \prg_break_point: } % \end{macrocode} % \end{macro} % \end{macro} -% -% \begin{macro}{\@@_toks:NN, \@@_toks:NNw} -% Unpack the various \tn{toks} registers, from \cs{l_@@_min_int} to -% $\cs{l_@@_top_int}-1$. The functions |#1| and |#2| allow us to treat -% the three data structures in a unified way: -% \begin{itemize} -% \item for sequences, they are \cs{exp_not:N} \cs{__seq_item:n}, -% expanding to the \cs{__seq_item:n} separator, as expected; -% \item for token lists, they expand to nothing; -% \item for comma lists, they expand to \cs{exp_args:No} -% \cs{clist_wrap_item:n}, taking care of unpacking the register -% before letting the undocumented internal \pkg{clist} function -% \cs{clist_wrap_item:n} do the work of putting a comma and possibly -% braces. -% \end{itemize} -% \begin{macrocode} -\cs_new:Npn \@@_toks:NN #1#2 - { \@@_toks:NNw #1 #2 \l_@@_min_int ; } -\cs_new:Npn \@@_toks:NNw #1#2#3 ; - { - \if_int_compare:w #3 < \l_@@_top_int - #1 #2 { \tex_the:D \tex_toks:D #3 } - \exp_after:wN \@@_toks:NNw \exp_after:wN #1 \exp_after:wN #2 - \__int_value:w \__int_eval:w #3 + 1 \exp_after:wN ; - \fi: - } -% \end{macrocode} % \end{macro} % % \subsection{Merge sort} @@ -579,9 +566,17 @@ % once. If neither is called, \cs{@@_return_none_error:} is called. % \begin{macrocode} \cs_new_protected:Npn \sort_return_same: #1 \@@_return_mark:N - { #1 \@@_return_mark:N \@@_return_two_error:w \@@_return_same: } + { + #1 + \@@_return_mark:N + \@@_return_two_error:w \@@_return_same: + } \cs_new_protected:Npn \sort_return_swapped: #1 \@@_return_mark:N - { #1 \@@_return_mark:N \@@_return_two_error:w \@@_return_swapped: } + { + #1 + \@@_return_mark:N + \@@_return_two_error:w \@@_return_swapped: + } \cs_new_protected:Npn \@@_return_mark:N #1 { } \cs_new_protected:Npn \@@_return_none_error: { @@ -827,11 +822,11 @@ % each item. The \texttt{prepare} auxiliary receives the conditional % as~|#1|, the prepared token list so far as~|#2|, the next prepared % item as~|#3|, and the item after that as~|#4|. The loop ends -% when~|#4| contains \cs{__prg_break_point:}, then the +% when~|#4| contains \cs{prg_break_point:}, then the % \texttt{prepare_end} auxiliary finds the prepared token list % as~|#4|. The scene is then set up for \cs{@@_quick_split:NnNn}, % which sorts the prepared list and perform the post action placed -% after \cs{q_mark}, namely removing the trailing \cs{s__stop} and +% after \cs{q_mark}, namely removing the trailing \cs{s_stop} and % \cs{q_stop} and leaving \cs{exp_stop_f:} to stop % \texttt{f}-expansion. % \begin{macrocode} @@ -843,23 +838,23 @@ { \@@_quick_prepare:Nnnn #2 { } { } #1 - { \__prg_break_point: \@@_quick_prepare_end:NNNnw } + { \prg_break_point: \@@_quick_prepare_end:NNNnw } \q_stop } } } \cs_new:Npn \@@_quick_prepare:Nnnn #1#2#3#4 { - \__prg_break: #4 \__prg_break_point: + \prg_break: #4 \prg_break_point: \@@_quick_prepare:Nnnn #1 { #2 #3 } { #1 {#4} } } \cs_new:Npn \@@_quick_prepare_end:NNNnw #1#2#3#4#5 \q_stop { \@@_quick_split:NnNn #4 \@@_quick_end:nnTFNn { } \q_mark { \@@_quick_cleanup:w \exp_stop_f: } - \s__stop \q_stop + \s_stop \q_stop } -\cs_new:Npn \@@_quick_cleanup:w #1 \s__stop \q_stop {#1} +\cs_new:Npn \@@_quick_cleanup:w #1 \s_stop \q_stop {#1} % \end{macrocode} % \end{macro} % \end{macro} @@ -895,31 +890,36 @@ % \begin{macrocode} \cs_new:Npn \@@_quick_split:NnNn #1#2#3#4 { - #3 {#2} {#4} \@@_quick_only_ii:NnnnnNn \@@_quick_only_i:NnnnnNn + #3 {#2} {#4} \@@_quick_only_ii:NnnnnNn + \@@_quick_only_i:NnnnnNn \@@_quick_single_end:nnnwnw { #3 {#4} } { } { } {#2} } \cs_new:Npn \@@_quick_only_i:NnnnnNn #1#2#3#4#5#6#7 { - #6 {#5} {#7} \@@_quick_split_ii:NnnnnNn \@@_quick_only_i:NnnnnNn + #6 {#5} {#7} \@@_quick_split_ii:NnnnnNn + \@@_quick_only_i:NnnnnNn \@@_quick_only_i_end:nnnwnw { #6 {#7} } { #3 #2 } { } {#5} } \cs_new:Npn \@@_quick_only_ii:NnnnnNn #1#2#3#4#5#6#7 { - #6 {#5} {#7} \@@_quick_only_ii:NnnnnNn \@@_quick_split_i:NnnnnNn + #6 {#5} {#7} \@@_quick_only_ii:NnnnnNn + \@@_quick_split_i:NnnnnNn \@@_quick_only_ii_end:nnnwnw { #6 {#7} } { } { #4 #2 } {#5} } \cs_new:Npn \@@_quick_split_i:NnnnnNn #1#2#3#4#5#6#7 { - #6 {#5} {#7} \@@_quick_split_ii:NnnnnNn \@@_quick_split_i:NnnnnNn + #6 {#5} {#7} \@@_quick_split_ii:NnnnnNn + \@@_quick_split_i:NnnnnNn \@@_quick_split_end:nnnwnw { #6 {#7} } { #3 #2 } {#4} {#5} } \cs_new:Npn \@@_quick_split_ii:NnnnnNn #1#2#3#4#5#6#7 { - #6 {#5} {#7} \@@_quick_split_ii:NnnnnNn \@@_quick_split_i:NnnnnNn + #6 {#5} {#7} \@@_quick_split_ii:NnnnnNn + \@@_quick_split_i:NnnnnNn \@@_quick_split_end:nnnwnw { #6 {#7} } {#3} { #4 #2 } {#5} } @@ -989,14 +989,14 @@ % \begin{macro}{\@@_error:} % Bailing out of the sorting code is a bit tricky. It may not be safe % to use a delimited argument, so instead we redefine many -% \pkg{l3sort} commands to be trivial, with \cs{@@_level:} getting rid -% of the final assignment. This error recovery won't work in a group. +% \pkg{l3sort} commands to be trivial, with \cs{@@_level:} jumping to +% the break point. This error recovery won't work in a group. % \begin{macrocode} \cs_new_protected:Npn \@@_error: { \cs_set_eq:NN \@@_merge_blocks_aux: \prg_do_nothing: \cs_set_eq:NN \@@_merge_blocks: \prg_do_nothing: - \cs_set_protected:Npn \@@_level: \use:x ##1 { \group_end: } + \cs_set_protected:Npn \@@_level: { \group_end: \prg_break: } } % \end{macrocode} % \end{macro} @@ -1022,7 +1022,8 @@ { Allocation~of~\iow_char:N\\toks~registers~impossible~while~sorting. } { The~comparison~code~used~for~sorting~a~list~has~attempted~to~ - define~#1~as~a~new~\iow_char:N\\toks~register~using~\iow_char:N\\newtoks~ + define~#1~as~a~new~\iow_char:N\\toks~register~using~ + \iow_char:N\\newtoks~ or~a~similar~command.~The~list~will~not~be~sorted. } %</package> @@ -1048,7 +1049,7 @@ { TeX~has~#2~toks~registers~still~available:~ this~only~allows~to~sort~with~up~to~#3~ - items.~All~extra~items~will~be~deleted. + items.~The~list~will~not~be~sorted. } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx index 245be5a85ce..4cf93f4d10b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx @@ -29,7 +29,7 @@ % \fi % % \title{^^A -% The \pkg{l3str} package\\Strings^^A +% The \pkg{l3str} package: Strings^^A % } % % \author{^^A @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -203,7 +203,7 @@ % var} are not automatically converted to a string. % \end{function} % -% \subsection{Modifying string variables} +% \section{Modifying string variables} % % \begin{function}[added = 2017-10-08] % { @@ -269,7 +269,7 @@ % results in \cs{l_tmpa_str} containing \texttt{abcd}. % \end{function} % -% \subsection{String conditionals} +% \section{String conditionals} % % \begin{function}[EXP, pTF, added = 2015-09-18] % {\str_if_exist:N, \str_if_exist:c} @@ -799,70 +799,6 @@ % code and so should only be used for short-term storage. % \end{variable} % -% \subsection{Internal string functions} -% -% \begin{function}[EXP]{\__str_if_eq_x:nn} -% \begin{syntax} -% \cs{__str_if_eq_x:nn} \Arg{tl_1} \Arg{tl_2} -% \end{syntax} -% Compares the full expansion of two \meta{token lists} on a character by -% character basis, and is \texttt{true} if the two lists contain the same -% characters in the same order. Leaves |0| in the input stream if the -% condition is true, and |+1| or |-1| otherwise. -% \end{function} -% -% \begin{function}{\__str_if_eq_x_return:nn} -% \begin{syntax} -% \cs{__str_if_eq_x_return:nn} \Arg{tl_1} \Arg{tl_2} -% \end{syntax} -% Compares the full expansion of two \meta{token lists} on a character by -% character basis, and is \texttt{true} if the two lists contain the same -% characters in the same order. Either \cs{prg_return_true:} or -% \cs{prg_return_false:} is then left in the input stream. This is a version -% of \cs{str_if_eq_x:nnTF} coded for speed. -% \end{function} -% -% \begin{function}[EXP]{\__str_to_other:n} -% \begin{syntax} -% \cs{__str_to_other:n} \Arg{token list} -% \end{syntax} -% Converts the \meta{token list} to a \meta{other string}, where -% spaces have category code \enquote{other}. This function can be -% \texttt{f}-expanded without fear of losing a leading space, since -% spaces do not have category code $10$ in its result. It takes a -% time quadratic in the character count of the string. -% \end{function} -% -% \begin{function}[rEXP]{\__str_to_other_fast:n} -% \begin{syntax} -% \cs{__str_to_other_fast:n} \Arg{token list} -% \end{syntax} -% Same behaviour \cs{__str_to_other:n} but only restricted-expandable. -% It takes a time linear in the character count of the string. -% It is used for \cs{iow_wrap:nnnN}. -% \end{function} -% -% \begin{function}[EXP]{\__str_count:n} -% \begin{syntax} -% \cs{__str_count:n} \Arg{other string} -% \end{syntax} -% This function expects an argument that is entirely made of -% characters with category \enquote{other}, as produced by -% \cs{__str_to_other:n}. It leaves in the input stream the number of -% character tokens in the \meta{other string}, faster than the -% analogous \cs{str_count:n} function. -% \end{function} -% -% \begin{function}[EXP]{\__str_range:nnn} -% \begin{syntax} -% \cs{__str_range:nnn} \Arg{other string} \Arg{start index} \Arg{end index} -% \end{syntax} -% Identical to \cs{str_range:nnn} except that the first argument is -% expected to be entirely made of characters with category -% \enquote{other}, as produced by \cs{__str_to_other:n}, and the -% result is also an \meta{other string}. -% \end{function} -% % \end{documentation} % % \begin{implementation} @@ -955,8 +891,11 @@ \tl_if_blank:nF {#1} { \cs_new_protected:cpx { str_ #1 :Nn } ##1##2 - { \exp_not:c { tl_ #1 :Nx } ##1 { \exp_not:N \tl_to_str:n {##2} } } - \exp_args:Nc \cs_generate_variant:Nn { str_ #1 :Nn } { Nx , cn , cx } + { + \exp_not:c { tl_ #1 :Nx } ##1 + { \exp_not:N \tl_to_str:n {##2} } + } + \cs_generate_variant:cn { str_ #1 :Nn } { Nx , cn , cx } \@@_tmp:n } } @@ -1079,10 +1018,14 @@ % } % More copy-paste! % \begin{macrocode} -\prg_new_eq_conditional:NNn \str_if_exist:N \tl_if_exist:N { p , T , F , TF } -\prg_new_eq_conditional:NNn \str_if_exist:c \tl_if_exist:c { p , T , F , TF } -\prg_new_eq_conditional:NNn \str_if_empty:N \tl_if_empty:N { p , T , F , TF } -\prg_new_eq_conditional:NNn \str_if_empty:c \tl_if_empty:c { p , T , F , TF } +\prg_new_eq_conditional:NNn \str_if_exist:N \tl_if_exist:N + { p , T , F , TF } +\prg_new_eq_conditional:NNn \str_if_exist:c \tl_if_exist:c + { p , T , F , TF } +\prg_new_eq_conditional:NNn \str_if_empty:N \tl_if_empty:N + { p , T , F , TF } +\prg_new_eq_conditional:NNn \str_if_empty:c \tl_if_empty:c + { p , T , F , TF } % \end{macrocode} % \end{macro} % @@ -1093,9 +1036,8 @@ % is that we do not \emph{always} use the primitive, the correct approach % is to wrap up in a function with defined behaviour. That's done by % providing a wrapper and then redefining in the \LuaTeX{} case. Note that -% the necessary Lua code is covered in \pkg{l3boostrap}: long-term this may -% need to go into a separate Lua file, but at present it's somewhere that -% spaces are not skipped for ease-of-input. The need to detokenize and force +% the necessary Lua code is loaded in \pkg{l3boostrap}. +% The need to detokenize and force % expansion of input arises from the case where a |#| token is used in the % input, \emph{e.g.}~|\__str_if_eq_x:nn {#} { \tl_to_str:n {#} }|, which % otherwise would fail as \cs{luatex_luaescapestring:D} does not double @@ -1104,9 +1046,11 @@ \cs_new:Npn \@@_if_eq_x:nn #1#2 { \pdftex_strcmp:D {#1} {#2} } \cs_if_exist:NT \luatex_luatexversion:D { + \cs_set_eq:NN \lua_escape_x:n \luatex_luaescapestring:D + \cs_set_eq:NN \lua_now_x:n \luatex_directlua:D \cs_set:Npn \@@_if_eq_x:nn #1#2 { - \luatex_directlua:D + \lua_now_x:n { l3kernel.strcmp ( @@ -1117,34 +1061,14 @@ } \cs_new:Npn \@@_escape_x:n #1 { - \luatex_luaescapestring:D - { - \etex_detokenize:D \exp_after:wN { \luatex_expanded:D {#1} } - } + \lua_escape_x:n + { \__kernel_tl_to_str:w \use_x:n { {#1} } } } } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\@@_if_eq_x_return:nn} -% It turns out that we often need to compare a token list -% with the result of applying some function to it, and -% return with \cs{prg_return_true/false:}. This test is -% similar to \cs{str_if_eq:nnTF} (see \pkg{l3str}), -% but is hard-coded for speed. -% \begin{macrocode} -\cs_new:Npn \@@_if_eq_x_return:nn #1 #2 - { - \if_int_compare:w \@@_if_eq_x:nn {#1} {#2} = 0 \exp_stop_f: - \prg_return_true: - \else: - \prg_return_false: - \fi: - } -% \end{macrocode} -% \end{macro} -% % \begin{macro}[pTF, EXP] % { % \str_if_eq:nn, \str_if_eq:Vn, \str_if_eq:on, \str_if_eq:nV, @@ -1180,7 +1104,8 @@ % \begin{macrocode} \prg_new_conditional:Npnn \str_if_eq:NN #1#2 { p , TF , T , F } { - \if_int_compare:w \@@_if_eq_x:nn { \tl_to_str:N #1 } { \tl_to_str:N #2 } + \if_int_compare:w + \@@_if_eq_x:nn { \tl_to_str:N #1 } { \tl_to_str:N #2 } = 0 \exp_stop_f: \prg_return_true: \else: \prg_return_false: \fi: } \prg_generate_conditional_variant:Nnn \str_if_eq:NN @@ -1278,7 +1203,8 @@ { \@@_case_end:nw {#3} } { \@@_case_x:nw {#1} } } -\cs_new_eq:NN \@@_case_end:nw \__prg_case_end:nw +\cs_new:Npn \@@_case_end:nw #1#2#3 \q_mark #4#5 \q_stop + { \exp_end: #1 #4 } % \end{macrocode} % \end{macro} % \end{macro} @@ -1299,7 +1225,7 @@ % The inline and variable mappings are similar to the usual token list % mappings but start out by turning the argument to an ``other % string''. Doing the same for the expandable function mapping would -% require \cs{@@_to_other:n}, quadratic in the string length. To deal +% require \cs{__kernel_str_to_other:n}, quadratic in the string length. To deal % with spaces in that case, \cs{@@_map_function:w} replaces the % following space by a braced space and a further call to itself. % These are received by \cs{@@_map_function:Nn}, which passes @@ -1317,9 +1243,9 @@ { \exp_after:wN \@@_map_function:w \exp_after:wN \@@_map_function:Nn \exp_after:wN #2 - \etex_detokenize:D {#1} + \__kernel_tl_to_str:w {#1} \q_recursion_tail ? ~ - \__prg_break_point:Nn \str_map_break: { } + \prg_break_point:Nn \str_map_break: { } } \cs_new:Npn \str_map_function:NN { \exp_args:No \str_map_function:nN } @@ -1335,24 +1261,25 @@ \cs_generate_variant:Nn \str_map_function:NN { c } \cs_new_protected:Npn \str_map_inline:nn #1#2 { - \int_gincr:N \g__prg_map_int + \int_gincr:N \g__kernel_prg_map_int \cs_gset_protected:cpn - { __prg_map_ \int_use:N \g__prg_map_int :w } ##1 {#2} + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1 {#2} \use:x { \exp_not:N \@@_map_inline:NN - \exp_not:c { __prg_map_ \int_use:N \g__prg_map_int :w } - \@@_to_other_fast:n {#1} + \exp_not:c { @@_map_ \int_use:N \g__kernel_prg_map_int :w } + \__kernel_str_to_other_fast:n {#1} } \q_recursion_tail - \__prg_break_point:Nn \str_map_break: { \int_gdecr:N \g__prg_map_int } + \prg_break_point:Nn \str_map_break: + { \int_gdecr:N \g__kernel_prg_map_int } } \cs_new_protected:Npn \str_map_inline:Nn { \exp_args:No \str_map_inline:nn } \cs_generate_variant:Nn \str_map_inline:Nn { c } \cs_new:Npn \@@_map_inline:NN #1#2 { - \__quark_if_recursion_tail_break:NN #2 \str_map_break: + \quark_if_recursion_tail_break:NN #2 \str_map_break: \exp_args:No #1 { \token_to_str:N #2 } \@@_map_inline:NN #1 } @@ -1361,25 +1288,25 @@ \use:x { \exp_not:n { \@@_map_variable:NnN #2 {#3} } - \@@_to_other_fast:n {#1} + \__kernel_str_to_other_fast:n {#1} } \q_recursion_tail - \__prg_break_point:Nn \str_map_break: { } + \prg_break_point:Nn \str_map_break: { } } \cs_new_protected:Npn \str_map_variable:NNn { \exp_args:No \str_map_variable:nNn } \cs_new_protected:Npn \@@_map_variable:NnN #1#2#3 { - \__quark_if_recursion_tail_break:NN #3 \str_map_break: + \quark_if_recursion_tail_break:NN #3 \str_map_break: \str_set:Nn #1 {#3} \use:n {#2} \@@_map_variable:NnN #1 {#2} } \cs_generate_variant:Nn \str_map_variable:NNn { c } \cs_new:Npn \str_map_break: - { \__prg_map_break:Nn \str_map_break: { } } + { \prg_map_break:Nn \str_map_break: { } } \cs_new:Npn \str_map_break:n - { \__prg_map_break:Nn \str_map_break: } + { \prg_map_break:Nn \str_map_break: } % \end{macrocode} % \end{macro} % \end{macro} @@ -1394,7 +1321,7 @@ % % \subsection{Accessing specific characters in a string} % -% \begin{macro}[EXP]{\@@_to_other:n} +% \begin{macro}[EXP]{\__kernel_str_to_other:n} % \begin{macro}[EXP]{\@@_to_other_loop:w, \@@_to_other_end:w} % First apply \cs{tl_to_str:n}, then replace all spaces by % \enquote{other} spaces, $8$ at a time, storing the converted part of @@ -1405,7 +1332,7 @@ % the result between \cs{q_mark} and the first |A| (well, there is % also the need to remove a space). % \begin{macrocode} -\cs_new:Npn \@@_to_other:n #1 +\cs_new:Npn \__kernel_str_to_other:n #1 { \exp_after:wN \@@_to_other_loop:w \tl_to_str:n {#1} ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ \q_mark \q_stop @@ -1432,13 +1359,13 @@ % \end{macro} % \end{macro} % -% \begin{macro}[rEXP]{\@@_to_other_fast:n} -% \begin{macro}[rEXP]{\@@_to_other_fast_loop:w, \@@_to_other_fast_end:w} -% The difference with \cs{@@_to_other:n} is that the converted part is +% \begin{macro}[rEXP]{\__kernel_str_to_other_fast:n} +% \begin{macro}[rEXP]{\__kernel_str_to_other_fast_loop:w, \@@_to_other_fast_end:w} +% The difference with \cs{__kernel_str_to_other:n} is that the converted part is % left in the input stream, making these commands only % restricted-expandable. % \begin{macrocode} -\cs_new:Npn \@@_to_other_fast:n #1 +\cs_new:Npn \__kernel_str_to_other_fast:n #1 { \exp_after:wN \@@_to_other_fast_loop:w \tl_to_str:n {#1} ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ \q_stop @@ -1491,17 +1418,16 @@ \exp_args:Nf \tl_to_str:n { \exp_args:Nf \@@_item:nn - { \@@_to_other:n {#1} } {#2} + { \__kernel_str_to_other:n {#1} } {#2} } } \cs_new:Npn \str_item_ignore_spaces:nn #1 { \exp_args:No \@@_item:nn { \tl_to_str:n {#1} } } -\__kernel_patch_args:nNNpn { {#1} { \__int_eval:n {#2} } } \cs_new:Npn \@@_item:nn #1#2 { \exp_after:wN \@@_item:w - \__int_value:w \__int_eval:w #2 \exp_after:wN ; - \__int_value:w \@@_count:n {#1} ; + \int_value:w \int_eval:n {#2} \exp_after:wN ; + \int_value:w \@@_count:n {#1} ; #1 \q_stop } \cs_new:Npn \@@_item:w #1; #2; @@ -1513,7 +1439,7 @@ { \exp_after:wN \use_i_delimit_by_q_stop:nw \exp:w \exp_after:wN \@@_skip_exp_end:w - \__int_value:w \__int_eval:w #1 + #2 ; + \int_value:w \int_eval:n { #1 + #2 } ; } } { @@ -1552,12 +1478,15 @@ \exp_after:wN \@@_skip_loop:wNNNNNNNN \else: \exp_after:wN \@@_skip_end:w - \__int_value:w \__int_eval:w + \int_value:w \int_eval:w \fi: #1 ; } \cs_new:Npn \@@_skip_loop:wNNNNNNNN #1; #2#3#4#5#6#7#8#9 - { \exp_after:wN \@@_skip_exp_end:w \__int_value:w \__int_eval:w #1 - 8 ; } + { + \exp_after:wN \@@_skip_exp_end:w + \int_value:w \int_eval:n { #1 - 8 } ; + } \cs_new:Npn \@@_skip_end:w #1 ; { \exp_after:wN \@@_skip_end:NNNNNNNN @@ -1588,19 +1517,17 @@ \exp_args:Nf \tl_to_str:n { \exp_args:Nf \@@_range:nnn - { \@@_to_other:n {#1} } {#2} {#3} + { \__kernel_str_to_other:n {#1} } {#2} {#3} } } \cs_new:Npn \str_range_ignore_spaces:nnn #1 { \exp_args:No \@@_range:nnn { \tl_to_str:n {#1} } } -\__kernel_patch_args:nNNpn - { {#1} { \__int_eval:n {#2} } { \__int_eval:n {#3} } } \cs_new:Npn \@@_range:nnn #1#2#3 { \exp_after:wN \@@_range:w - \__int_value:w \@@_count:n {#1} \exp_after:wN ; - \__int_value:w \__int_eval:w #2 - 1 \exp_after:wN ; - \__int_value:w \__int_eval:w #3 ; + \int_value:w \@@_count:n {#1} \exp_after:wN ; + \int_value:w \int_eval:n { (#2) - 1 } \exp_after:wN ; + \int_value:w \int_eval:n {#3} ; #1 \q_stop } \cs_new:Npn \@@_range:w #1; #2; #3; @@ -1612,7 +1539,7 @@ \cs_new:Npn \@@_range:nnw #1#2 { \exp_after:wN \@@_collect_delimit_by_q_stop:w - \__int_value:w \__int_eval:w #2 - #1 \exp_after:wN ; + \int_value:w \int_eval:n { #2 - #1 } \exp_after:wN ; \exp:w \@@_skip_exp_end:w #1 ; } % \end{macrocode} @@ -1678,14 +1605,15 @@ \cs_new:Npn \@@_collect_loop:wnNNNNNNN #1; #2 #3#4#5#6#7#8#9 { \exp_after:wN \@@_collect_loop:wn - \__int_value:w \__int_eval:w #1 - 7 ; + \int_value:w \int_eval:n { #1 - 7 } ; { #2 #3#4#5#6#7#8#9 } } \cs_new:Npn \@@_collect_end:wn #1 ; { \exp_after:wN \@@_collect_end:nnnnnnnnw - \if_case:w \if_int_compare:w #1 > 0 \exp_stop_f: #1 \else: 0 \fi: \exp_stop_f: - \or: \or: \or: \or: \or: \or: \fi: + \if_case:w \if_int_compare:w #1 > 0 \exp_stop_f: + #1 \else: 0 \fi: \exp_stop_f: + \or: \or: \or: \or: \or: \or: \fi: } \cs_new:Npn \@@_collect_end:nnnnnnnnw #1#2#3#4#5#6#7#8 #9 \q_stop { #1#2#3#4#5#6#7#8 } @@ -1733,7 +1661,7 @@ % \begin{macro}[EXP]{\@@_count:n} % \begin{macro}[EXP]{\@@_count_aux:n, \@@_count_loop:NNNNNNNNN} % To count characters in a string we could first escape all spaces -% using \cs{@@_to_other:n}, then pass the result to \cs{tl_count:n}. +% using \cs{__kernel_str_to_other:n}, then pass the result to \cs{tl_count:n}. % However, the escaping step would be quadratic in the number of % characters in the string, and we can do better. Namely, sum the % number of spaces (\cs{str_count_spaces:n}) and the result of @@ -1881,8 +1809,6 @@ % \begin{macro}[EXP]{\@@_change_case_loop:nw} % \begin{macro}[EXP]{\@@_change_case_space:n} % \begin{macro}[EXP]{\@@_change_case_char:nN} -% \begin{macro} -% {\@@_lookup_lower:N, \@@_lookup_upper:N, \@@_lookup_fold:N} % Case changing for programmatic reasons is done by first detokenizing % input then doing a simple loop that only has to worry about spaces % and everything else. The output is detokenized to allow data sharing @@ -1907,7 +1833,8 @@ \cs_new:Npn \@@_change_case_output:nw #1#2 \@@_change_case_result:n #3 { #2 \@@_change_case_result:n { #3 #1 } } \cs_generate_variant:Nn \@@_change_case_output:nw { f } -\cs_new:Npn \@@_change_case_end:wn #1 \@@_change_case_result:n #2 { #2 } +\cs_new:Npn \@@_change_case_end:wn #1 \@@_change_case_result:n #2 + { \tl_to_str:n {#2} } \cs_new:Npn \@@_change_case_loop:nw #1#2 \q_recursion_stop { \tl_if_head_is_space:nTF {#2} @@ -1915,8 +1842,8 @@ { \@@_change_case_char:nN } {#1} #2 \q_recursion_stop } -\use:x - { \cs_new:Npn \exp_not:N \@@_change_case_space:n ##1 \c_space_tl } +\exp_last_unbraced:NNNNo + \cs_new:Npn \@@_change_case_space:n #1 \c_space_tl { \@@_change_case_output:nw { ~ } \@@_change_case_loop:nw {#1} @@ -1925,41 +1852,11 @@ { \quark_if_recursion_tail_stop_do:Nn #2 { \@@_change_case_end:wn } - \cs_if_exist:cTF { c__unicode_ #1 _ #2 _tl } - { - \@@_change_case_output:fw - { \tl_to_str:c { c__unicode_ #1 _ #2 _tl } } - } - { \@@_change_case_char_aux:nN {#1} #2 } + \@@_change_case_output:fw + { \use:c { char_ #1 _case:N } #2 } \@@_change_case_loop:nw {#1} } % \end{macrocode} -% For Unicode engines there's a look up to see if the current character -% has a valid one-to-one case change mapping. That's not needed for $8$-bit -% engines: as they don't have \cs{utex_char:D} all of the changes they can -% make are hard-coded and so already picked up above. -% \begin{macrocode} -\cs_if_exist:NTF \utex_char:D - { - \cs_new:Npn \@@_change_case_char_aux:nN #1#2 - { - \int_compare:nNnTF { \use:c { __str_lookup_ #1 :N } #2 } = { 0 } - { \@@_change_case_output:nw {#2} } - { - \@@_change_case_output:fw - { \utex_char:D \use:c { __str_lookup_ #1 :N } #2 ~ } - } - } - \cs_new_protected:Npn \@@_lookup_lower:N #1 { \tex_lccode:D `#1 } - \cs_new_protected:Npn \@@_lookup_upper:N #1 { \tex_uccode:D `#1 } - \cs_new_eq:NN \@@_lookup_fold:N \@@_lookup_lower:N - } - { - \cs_new:Npn \@@_change_case_char_aux:nN #1#2 - { \@@_change_case_output:nw {#2} } - } -% \end{macrocode} -% \end{macro} % \end{macro} % \end{macro} % \end{macro} @@ -2024,213 +1921,6 @@ % \end{macrocode} % \end{macro} % -% \subsection{Unicode data for case changing} -% -% \begin{macrocode} -%<@@=unicode> -% \end{macrocode} -% -% Case changing both for strings and \enquote{text} requires data from -% the Unicode Consortium. Some of this is build in to the format (as -% \tn{lccode} and \tn{uccode} values) but this covers only the simple -% one-to-one situations and does not fully handle for example case folding. -% -% The data required for cross-module manipulations is loaded here: currently -% this means for |str| and |tl| functions. As such, the prefix used is not -% |str| but rather |unicode|. For performance (as the entire data set must -% be read during each run) and as this code comes somewhat early in the -% load process, there is quite a bit of low-level code here. -% -% As only the data needs to remain at the end of this process, everything -% is set up inside a group. -% \begin{macrocode} -\group_begin: -% \end{macrocode} -% A read stream is needed. The I/O module is not yet in place \emph{and} -% we do not want to use up a stream. We therefore use a known free one in -% format mode or look for the next free one in package mode (covers plain, -% \LaTeXe{} and Con\TeX{}t MkII and MkIV). -% \begin{macrocode} -%<*initex> - \tex_chardef:D \g_@@_data_ior = 0 \scan_stop: -%</initex> -%<*package> - \tex_chardef:D \g_@@_data_ior - \etex_numexpr:D - \cs_if_exist:NTF \lastallocatedread - { \lastallocatedread } - { - \cs_if_exist:NTF \c_syst_last_allocated_read - { \c_syst_last_allocated_read } - { \tex_count:D 16 ~ } - } - + 1 - \scan_stop: -%</package> -% \end{macrocode} -% Set up to read each file. As they use C-style comments, there is a need to -% deal with |#|. At the same time, spaces are important so they need to be -% picked up as they are important. Beyond that, the current category code -% scheme works fine. With no I/O loop available, hard-code one that works -% quickly. -% \begin{macrocode} - \cs_set_protected:Npn \@@_map_inline:n #1 - { - \group_begin: - \tex_catcode:D `\# = 12 \scan_stop: - \tex_catcode:D `\ = 10 \scan_stop: - \tex_openin:D \g_@@_data_ior = #1 \scan_stop: - \cs_if_exist:NT \utex_char:D - { \@@_map_loop: } - \tex_closein:D \g_@@_data_ior - \group_end: - } - \cs_set_protected:Npn \@@_map_loop: - { - \tex_ifeof:D \g_@@_data_ior - \exp_after:wN \use_none:n - \else: - \exp_after:wN \use:n - \fi: - { - \tex_read:D \g_@@_data_ior to \l_@@_tmp_tl - \if_meaning:w \c_empty_tl \l_@@_tmp_tl - \else: - \exp_after:wN \@@_parse:w \l_@@_tmp_tl \q_stop - \fi: - \@@_map_loop: - } - } -% \end{macrocode} -% The lead-off parser for each line is common for all of the files. If -% the line starts with a |#| it's a comment. There's one special comment -% line to look out for in \texttt{SpecialCasing.txt} as we want to ignore -% everything after it. As this line does not appear in any other sources -% and the test is quite quick (there are relatively few comment lines), it -% can be present in all of the passes. -% \begin{macrocode} - \cs_set_protected:Npn \@@_parse:w #1#2 \q_stop - { - \reverse_if:N \if:w \c_hash_str #1 - \@@_parse_auxi:w #1#2 \q_stop - \else: - \if_int_compare:w \__str_if_eq_x:nn - { \exp_not:n {#2} } { ~Conditional~Mappings~ } = 0 \exp_stop_f: - \cs_set_protected:Npn \@@_parse:w ##1 \q_stop { } - \fi: - \fi: - } -% \end{macrocode} -% Storing each exception is always done in the same way: create a constant -% token list which expands to exactly the mapping. These have the -% category codes \enquote{now} (so should be letters) but are later detokenized -% for string use. -% \begin{macrocode} - \cs_set_protected:Npn \@@_store:nnnnn #1#2#3#4#5 - { - \tl_const:cx { c_@@_ #2 _ \utex_char:D "#1 _tl } - { - \utex_char:D "#3 ~ - \utex_char:D "#4 ~ - \tl_if_blank:nF {#5} - { \utex_char:D "#5 } - } - } -% \end{macrocode} -% Parse the main Unicode data file for title case exceptions (the one-to-one -% lower and upper case mappings it contains are all be covered by the \TeX{} -% data). -% \begin{macrocode} - \cs_set_protected:Npn \@@_parse_auxi:w - #1 ; #2 ; #3 ; #4 ; #5 ; #6 ; #7 ; #8 ; #9 ; - { \@@_parse_auxii:w #1 ; } - \cs_set_protected:Npn \@@_parse_auxii:w - #1 ; #2 ; #3 ; #4 ; #5 ; #6 ; #7 \q_stop - { - \tl_if_blank:nF {#7} - { - \if_int_compare:w \__str_if_eq_x:nn { #5 ~ } {#7} = 0 \exp_stop_f: - \else: - \tl_const:cx - { c_@@_mixed_ \utex_char:D "#1 _tl } - { \utex_char:D "#7 } - \fi: - } - } - \@@_map_inline:n { UnicodeData.txt } -% \end{macrocode} -% The set up for case folding is in two parts. For the basic (core) mappings, -% folding is the same as lower casing in most positions so only store -% the differences. For the more complex foldings, always store the result, -% splitting up the two or three code points in the input as required. -% \begin{macrocode} - \cs_set_protected:Npn \@@_parse_auxi:w #1 ;~ #2 ;~ #3 ; #4 \q_stop - { - \if_int_compare:w \__str_if_eq_x:nn {#2} { C } = 0 \exp_stop_f: - \if_int_compare:w \tex_lccode:D "#1 = "#3 \scan_stop: - \else: - \tl_const:cx - { c_@@_fold_ \utex_char:D "#1 _tl } - { \utex_char:D "#3 ~ } - \fi: - \else: - \if_int_compare:w \__str_if_eq_x:nn {#2} { F } = 0 \exp_stop_f: - \@@_parse_auxii:w #1 ~ #3 ~ \q_stop - \fi: - \fi: - } - \cs_set_protected:Npn \@@_parse_auxii:w #1 ~ #2 ~ #3 ~ #4 \q_stop - { \@@_store:nnnnn {#1} { fold } {#2} {#3} {#4} } - \@@_map_inline:n { CaseFolding.txt } -% \end{macrocode} -% For upper and lower casing special situations, there is a bit more to -% do as we also have title casing to consider. -% \begin{macrocode} - \cs_set_protected:Npn \@@_parse_auxi:w #1 ;~ #2 ;~ #3 ;~ #4 ; #5 \q_stop - { - \use:n { \@@_parse_auxii:w #1 ~ lower ~ #2 ~ } ~ \q_stop - \use:n { \@@_parse_auxii:w #1 ~ upper ~ #4 ~ } ~ \q_stop - \if_int_compare:w \__str_if_eq_x:nn {#3} {#4} = 0 \exp_stop_f: - \else: - \use:n { \@@_parse_auxii:w #1 ~ mixed ~ #3 ~ } ~ \q_stop - \fi: - } - \cs_set_protected:Npn \@@_parse_auxii:w #1 ~ #2 ~ #3 ~ #4 ~ #5 \q_stop - { - \tl_if_empty:nF {#4} - { \@@_store:nnnnn {#1} {#2} {#3} {#4} {#5} } - } - \@@_map_inline:n { SpecialCasing.txt } -% \end{macrocode} -% For the $8$-bit engines, the above does nothing but there is some set -% up needed. There is no expandable character generator primitive so some -% alternative is needed. As we've not used up hash space for the above, we -% can go for the fast approach here of one name per letter. Keeping folding -% and lower casing separate makes the use later a bit easier. -% \begin{macrocode} - \cs_if_exist:NF \utex_char:D - { - \cs_set_protected:Npn \@@_tmp:NN #1#2 - { - \if_meaning:w \q_recursion_tail #2 - \exp_after:wN \use_none_delimit_by_q_recursion_stop:w - \fi: - \tl_const:cn { c_@@_fold_ #1 _tl } {#2} - \tl_const:cn { c_@@_lower_ #1 _tl } {#2} - \tl_const:cn { c_@@_upper_ #2 _tl } {#1} - \@@_tmp:NN - } - \@@_tmp:NN - AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz - ? \q_recursion_tail \q_recursion_stop - } -% \end{macrocode} -% -% All done: tidy up. -% \begin{macrocode} -\group_end: -% \end{macrocode} -% % \begin{macrocode} %</initex|package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx index 01842fa73f4..21a8aed75c5 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3sys.dtx Copyright (C) 2015-2017 The LaTeX3 Project +%% File: l3sys.dtx Copyright (C) 2015-2018 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -29,7 +29,7 @@ % \fi % % \title{^^A -% The \pkg{l3sys} package\\System/runtime functions^^A +% The \pkg{l3sys} package: System/runtime functions^^A % } % % \author{^^A @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -134,6 +134,10 @@ %<*initex|package> % \end{macrocode} % +% \begin{macrocode} +%<@@=sys> +% \end{macrocode} +% % \subsection{The name of the job} % % \begin{variable}{\c_sys_jobname_str} @@ -178,6 +182,29 @@ % % \subsection{Detecting the engine} % +% \begin{macro}{\@@_const:nn} +% Set the |T|, |F|, |TF|, |p| forms of |#1| to be constants equal to +% the result of evaluating the boolean expression~|#2|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_const:nn #1#2 + { + \bool_if:nTF {#2} + { + \cs_new_eq:cN { #1 :T } \use:n + \cs_new_eq:cN { #1 :F } \use_none:n + \cs_new_eq:cN { #1 :TF } \use_i:nn + \cs_new_eq:cN { #1 _p: } \c_true_bool + } + { + \cs_new_eq:cN { #1 :T } \use_none:n + \cs_new_eq:cN { #1 :F } \use:n + \cs_new_eq:cN { #1 :TF } \use_ii:nn + \cs_new_eq:cN { #1 _p: } \c_false_bool + } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[pTF, EXP] % { % \sys_if_engine_luatex:, @@ -193,56 +220,24 @@ % or |-kanji-internal=euc| effective makes it more like \pTeX{}. In those % cases we therefore report \pTeX{} rather than \upTeX{}. % \begin{macrocode} -\clist_map_inline:nn { lua , pdf , p , up , xe } - { - \cs_new_eq:cN { sys_if_engine_ #1 tex:T } \use_none:n - \cs_new_eq:cN { sys_if_engine_ #1 tex:F } \use:n - \cs_new_eq:cN { sys_if_engine_ #1 tex:TF } \use_ii:nn - \cs_new_eq:cN { sys_if_engine_ #1 tex_p: } \c_false_bool - } -\cs_if_exist:NT \luatex_luatexversion:D +\str_const:Nx \c_sys_engine_str { - \cs_gset_eq:NN \sys_if_engine_luatex:T \use:n - \cs_gset_eq:NN \sys_if_engine_luatex:F \use_none:n - \cs_gset_eq:NN \sys_if_engine_luatex:TF \use_i:nn - \cs_gset_eq:NN \sys_if_engine_luatex_p: \c_true_bool - \str_const:Nn \c_sys_engine_str { luatex } - } -\cs_if_exist:NT \pdftex_pdftexversion:D - { - \cs_gset_eq:NN \sys_if_engine_pdftex:T \use:n - \cs_gset_eq:NN \sys_if_engine_pdftex:F \use_none:n - \cs_gset_eq:NN \sys_if_engine_pdftex:TF \use_i:nn - \cs_gset_eq:NN \sys_if_engine_pdftex_p: \c_true_bool - \str_const:Nn \c_sys_engine_str { pdftex } - } -\cs_if_exist:NT \ptex_kanjiskip:D - { - \bool_lazy_and:nnTF - { \cs_if_exist_p:N \uptex_disablecjktoken:D } - { \int_compare_p:nNn { \ptex_jis:D "2121 } = { "3000 } } - { - \cs_gset_eq:NN \sys_if_engine_uptex:T \use:n - \cs_gset_eq:NN \sys_if_engine_uptex:F \use_none:n - \cs_gset_eq:NN \sys_if_engine_uptex:TF \use_i:nn - \cs_gset_eq:NN \sys_if_engine_uptex_p: \c_true_bool - \str_const:Nn \c_sys_engine_str { uptex } - } + \cs_if_exist:NT \luatex_luatexversion:D { luatex } + \cs_if_exist:NT \pdftex_pdftexversion:D { pdftex } + \cs_if_exist:NT \ptex_kanjiskip:D { - \cs_gset_eq:NN \sys_if_engine_ptex:T \use:n - \cs_gset_eq:NN \sys_if_engine_ptex:F \use_none:n - \cs_gset_eq:NN \sys_if_engine_ptex:TF \use_i:nn - \cs_gset_eq:NN \sys_if_engine_ptex_p: \c_true_bool - \str_const:Nn \c_sys_engine_str { ptex } + \bool_lazy_and:nnTF + { \cs_if_exist_p:N \uptex_disablecjktoken:D } + { \int_compare_p:nNn { \ptex_jis:D "2121 } = { "3000 } } + { uptex } + { ptex } } + \cs_if_exist:NT \xetex_XeTeXversion:D { xetex } } -\cs_if_exist:NT \xetex_XeTeXversion:D +\tl_map_inline:nn { { luatex } { pdftex } { ptex } { uptex } { xetex } } { - \cs_gset_eq:NN \sys_if_engine_xetex:T \use:n - \cs_gset_eq:NN \sys_if_engine_xetex:F \use_none:n - \cs_gset_eq:NN \sys_if_engine_xetex:TF \use_i:nn - \cs_gset_eq:NN \sys_if_engine_xetex_p: \c_true_bool - \str_const:Nn \c_sys_engine_str { xetex } + \@@_const:nn { sys_if_engine_ #1 } + { \str_if_eq_x_p:nn \c_sys_engine_str {#1} } } % \end{macrocode} % \end{variable} @@ -258,30 +253,17 @@ % \begin{variable}{\c_sys_output_str} % This is a simple enough concept: the two views here are complementary. % \begin{macrocode} -\int_compare:nNnTF - { \cs_if_exist_use:NF \pdftex_pdfoutput:D { 0 } } > { 0 } - { - \cs_new_eq:NN \sys_if_output_dvi:T \use_none:n - \cs_new_eq:NN \sys_if_output_dvi:F \use:n - \cs_new_eq:NN \sys_if_output_dvi:TF \use_ii:nn - \cs_new_eq:NN \sys_if_output_dvi_p: \c_false_bool - \cs_new_eq:NN \sys_if_output_pdf:T \use:n - \cs_new_eq:NN \sys_if_output_pdf:F \use_none:n - \cs_new_eq:NN \sys_if_output_pdf:TF \use_i:nn - \cs_new_eq:NN \sys_if_output_pdf_p: \c_true_bool - \str_const:Nn \c_sys_output_str { pdf } - } +\str_const:Nx \c_sys_output_str { - \cs_new_eq:NN \sys_if_output_dvi:T \use:n - \cs_new_eq:NN \sys_if_output_dvi:F \use_none:n - \cs_new_eq:NN \sys_if_output_dvi:TF \use_i:nn - \cs_new_eq:NN \sys_if_output_dvi_p: \c_true_bool - \cs_new_eq:NN \sys_if_output_pdf:T \use_none:n - \cs_new_eq:NN \sys_if_output_pdf:F \use:n - \cs_new_eq:NN \sys_if_output_pdf:TF \use_ii:nn - \cs_new_eq:NN \sys_if_output_pdf_p: \c_false_bool - \str_const:Nn \c_sys_output_str { dvi } + \int_compare:nNnTF + { \cs_if_exist_use:NF \pdftex_pdfoutput:D { 0 } } > { 0 } + { pdf } + { dvi } } +\@@_const:nn { sys_if_output_dvi } + { \str_if_eq_x_p:nn \c_sys_output_str { dvi } } +\@@_const:nn { sys_if_output_pdf } + { \str_if_eq_x_p:nn \c_sys_output_str { pdf } } % \end{macrocode} % \end{variable} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx index 60cd85b5478..435a77498f7 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3tl-analysis.dtx Copyright (C) 2011-2017 The LaTeX3 Project% +%% File: l3tl-analysis.dtx Copyright (C) 2011-2018 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -30,7 +30,7 @@ % % % \title{^^A -% The \textsf{l3tl-analysis} package: analysing token lists^^A +% The \textsf{l3tl-analysis} package: Analysing token lists^^A % } % % \author{^^A @@ -42,7 +42,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -55,9 +55,9 @@ % debugging function, very similar to the \cs{ShowTokens} macro from the % \pkg{ted} package. % -% \begin{function}[added = 2017-05-26]{\tl_show_analysis:N, \tl_show_analysis:n} +% \begin{function}[added = 2018-04-09]{\tl_analysis_show:N, \tl_analysis_show:n} % \begin{syntax} -% \cs{tl_show_analysis:n} \Arg{token list} +% \cs{tl_analysis_show:n} \Arg{token list} % \end{syntax} % Displays to the terminal the detailed decomposition of the % \meta{token list} into tokens, showing the category code of each @@ -65,22 +65,10 @@ % characters, and the value of registers. % \end{function} % -% \end{documentation} -% -% \begin{implementation} -% -% \section{\pkg{l3tl-analysis} implementation} -% -% \subsection{Internal functions} -% -% \begin{variable}{\s__tl} -% The format used to store token lists internally uses the scan mark -% \cs{s__tl} as a delimiter. -% \end{variable} -% -% \begin{function}{\__tl_analysis_map_inline:nn} +% \begin{function}[added = 2018-04-09] +% {\tl_analysis_map_inline:nn, \tl_analysis_map_inline:Nn} % \begin{syntax} -% \cs{__tl_analysis_map_inline:nn} \Arg{token list} \Arg{inline function} +% \cs{tl_analysis_map_inline:nn} \Arg{token list} \Arg{inline function} % \end{syntax} % Applies the \meta{inline function} to each individual \meta{token} % in the \meta{token list}. The \meta{inline function} receives three @@ -89,20 +77,33 @@ % \item \meta{tokens}, which both \texttt{o}-expand and % \texttt{x}-expand to the \meta{token}. The detailed form of % \meta{token} may change in later releases. +% \item \meta{char code}, a decimal representation of the character +% code of the token, $-1$ if it is a control sequence (with +% \meta{catcode} $0$). % \item \meta{catcode}, a capital hexadecimal digit which denotes % the category code of the \meta{token} (0: control sequence, 1: % begin-group, 2: end-group, 3: math shift, 4: alignment tab, 6: % parameter, 7: superscript, 8: subscript, A: space, B: letter, % C:other, D:active). -% \item \meta{char code}, a decimal representation of the character -% code of the token, $-1$ if it is a control sequence (with -% \meta{catcode} $0$). % \end{itemize} % \end{function} % -% For optimizations in \pkg{l3regex} (when matching control sequences), -% it may be useful to provide a \cs{__tl_analysis_from_str_map_inline:nn} -% function, perhaps named \cs{__str_analysis_map_inline:nn}. +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3tl-analysis} implementation} +% +% \begin{macrocode} +%<@@=tl> +% \end{macrocode} +% +% \subsection{Internal functions} +% +% \begin{variable}{\s_@@} +% The format used to store token lists internally uses the scan mark +% \cs{s_@@} as a delimiter. +% \end{variable} % % \subsection{Internal format} % @@ -123,7 +124,7 @@ % regexes are catcode-agnostic. The internal format thus takes the form % of a succession of items of the form % \begin{quote} -% \meta{tokens} \cs{s__tl} \meta{catcode} \meta{char code} \cs{s__tl} +% \meta{tokens} \cs{s_@@} \meta{catcode} \meta{char code} \cs{s_@@} % \end{quote} % The \meta{tokens} \texttt{o}- \emph{and} \texttt{x}-expand to the % original token in the token list or to the cluster of tokens @@ -134,7 +135,7 @@ % % Using delimited arguments lets us build the \meta{tokens} % progressively when doing an encoding conversion in \pkg{l3str-convert}. On the -% other hand, the delimiter \cs{s__tl} may not appear unbraced in +% other hand, the delimiter \cs{s_@@} may not appear unbraced in % \meta{tokens}. This is not a problem because we are careful to wrap % control sequences in braces (as an argument to \cs{exp_not:n}) when % converting from a general token list to the internal format. @@ -144,15 +145,15 @@ % it is the following. % \begin{itemize} % \item A control sequence |\cs| becomes |\exp_not:n { \cs }| -% \cs{s__tl} $0$ $-1$ \cs{s__tl}. +% \cs{s_@@} $0$ $-1$ \cs{s_@@}. % \item A begin-group character |{| becomes \cs{exp_after:wN} |{| -% \cs{if_false:} |}| \cs{fi:} \cs{s__tl} $1$ \meta{char code} -% \cs{s__tl}. +% \cs{if_false:} |}| \cs{fi:} \cs{s_@@} $1$ \meta{char code} +% \cs{s_@@}. % \item An end-group character |}| becomes \cs{if_false:} |{| \cs{fi:} -% |}| \cs{s__tl} $2$ \meta{char code} \cs{s__tl}. +% |}| \cs{s_@@} $2$ \meta{char code} \cs{s_@@}. % \item A character with any other category code becomes -% \cs{exp_not:n} \Arg{character} \cs{s__tl} \meta{hex catcode} -% \meta{char code} \cs{s__tl}. +% \cs{exp_not:n} \Arg{character} \cs{s_@@} \meta{hex catcode} +% \meta{char code} \cs{s_@@}. % \end{itemize} % % ^^A todo: ask LuaTeX list for an \ifx\undefined <active char> @@ -162,133 +163,121 @@ %<*initex|package> % \end{macrocode} % -% \begin{macrocode} -%<@@=tl_analysis> -% \end{macrocode} -% % \subsection{Variables and helper functions} % -% \begin{variable}{\s__tl} -% The scan mark \cs{s__tl} is used as a delimiter in the internal +% \begin{variable}{\s_@@} +% The scan mark \cs{s_@@} is used as a delimiter in the internal % format. This is more practical than using a quark, because we would % then need to control expansion much more carefully: compare -% \cs{__int_value:w} |`#1| \cs{s__tl} with \cs{__int_value:w} |`#1| +% \cs{int_value:w} |`#1| \cs{s_@@} with \cs{int_value:w} |`#1| % \cs{exp_stop_f:} \cs{exp_not:N} \cs{q_mark} to extract a character % code followed by the delimiter in an \texttt{x}-expansion. % \begin{macrocode} -\__scan_new:N \s__tl -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_@@_internal_tl} -% This token list variable is used to hand the argument of -% \cs{tl_show_analysis:n} to \cs{tl_show_analysis:N}. -% \begin{macrocode} -\tl_new:N \l_@@_internal_tl +\scan_new:N \s_@@ % \end{macrocode} % \end{variable} % -% \begin{variable}{\l_@@_token} -% \begin{variable}{\l_@@_char_token} +% \begin{variable}{\l_@@_analysis_token} +% \begin{variable}{\l_@@_analysis_char_token} % The tokens in the token list are probed with the \TeX{} primitive -% \tn{futurelet}. We use \cs{l_@@_token} in that +% \tn{futurelet}. We use \cs{l_@@_analysis_token} in that % construction. In some cases, we convert the following token to a % string before probing it: then the token variable used is -% \cs{l_@@_char_token}. +% \cs{l_@@_analysis_char_token}. % \begin{macrocode} -\cs_new_eq:NN \l_@@_token ? -\cs_new_eq:NN \l_@@_char_token ? +\cs_new_eq:NN \l_@@_analysis_token ? +\cs_new_eq:NN \l_@@_analysis_char_token ? % \end{macrocode} % \end{variable} % \end{variable} % -% \begin{variable}{\l_@@_normal_int} +% \begin{variable}{\l_@@_analysis_normal_int} % The number of normal (\texttt{N}-type argument) tokens since the % last special token. % \begin{macrocode} -\int_new:N \l_@@_normal_int +\int_new:N \l_@@_analysis_normal_int % \end{macrocode} % \end{variable} % -% \begin{variable}{\l_@@_index_int} +% \begin{variable}{\l_@@_analysis_index_int} % During the first pass, this is the index in the array being built. % During the second pass, it is equal to the maximum index in the % array from the first pass. % \begin{macrocode} -\int_new:N \l_@@_index_int +\int_new:N \l_@@_analysis_index_int % \end{macrocode} % \end{variable} % -% \begin{variable}{\l_@@_nesting_int} +% \begin{variable}{\l_@@_analysis_nesting_int} % Nesting depth of explicit begin-group and end-group characters % during the first pass. This lets us detect the end of the token list % without a reserved end-marker. % \begin{macrocode} -\int_new:N \l_@@_nesting_int +\int_new:N \l_@@_analysis_nesting_int % \end{macrocode} % \end{variable} % -% \begin{variable}{\l_@@_type_int} +% \begin{variable}{\l_@@_analysis_type_int} % When encountering special characters, we record their \enquote{type} % in this integer. % \begin{macrocode} -\int_new:N \l_@@_type_int +\int_new:N \l_@@_analysis_type_int % \end{macrocode} % \end{variable} % -% \begin{variable}{\g_@@_result_tl} +% \begin{variable}{\g_@@_analysis_result_tl} % The result of the conversion is stored in this token list, with a % succession of items of the form % \begin{quote} -% \meta{tokens} \cs{s__tl} \meta{catcode} \meta{char code} \cs{s__tl} +% \meta{tokens} \cs{s_@@} \meta{catcode} \meta{char code} \cs{s_@@} % \end{quote} % \begin{macrocode} -\tl_new:N \g_@@_result_tl +\tl_new:N \g_@@_analysis_result_tl % \end{macrocode} % \end{variable} % -% \begin{macro}[EXP]{\@@_extract_charcode:} -% \begin{macro}[EXP]{\@@_extract_charcode_aux:w} +% \begin{macro}[EXP]{\@@_analysis_extract_charcode:} +% \begin{macro}[EXP]{\@@_analysis_extract_charcode_aux:w} % Extracting the character code from the meaning of -% \cs{l_@@_token}. This has no error checking, and should +% \cs{l_@@_analysis_token}. This has no error checking, and should % only be assumed to work for begin-group and end-group character % tokens. It produces a number in the form |`|\meta{char}. % \begin{macrocode} -\cs_new:Npn \@@_extract_charcode: +\cs_new:Npn \@@_analysis_extract_charcode: { - \exp_after:wN \@@_extract_charcode_aux:w - \token_to_meaning:N \l_@@_token + \exp_after:wN \@@_analysis_extract_charcode_aux:w + \token_to_meaning:N \l_@@_analysis_token } -\cs_new:Npn \@@_extract_charcode_aux:w #1 ~ #2 ~ { ` } +\cs_new:Npn \@@_analysis_extract_charcode_aux:w #1 ~ #2 ~ { ` } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\@@_cs_space_count:NN} -% \begin{macro}[EXP]{\@@_cs_space_count:w} -% \begin{macro}[EXP]{\@@_cs_space_count_end:w} +% \begin{macro}[EXP]{\@@_analysis_cs_space_count:NN} +% \begin{macro}[EXP]{\@@_analysis_cs_space_count:w} +% \begin{macro}[EXP]{\@@_analysis_cs_space_count_end:w} % Counts the number of spaces in the string representation of its % second argument, as well as the number of characters following the % last space in that representation, and feeds the two numbers as % semicolon-delimited arguments to the first argument. When this % function is used, the escape character is printable and non-space. % \begin{macrocode} -\cs_new:Npn \@@_cs_space_count:NN #1 #2 +\cs_new:Npn \@@_analysis_cs_space_count:NN #1 #2 { \exp_after:wN #1 - \__int_value:w \__int_eval:w 0 - \exp_after:wN \@@_cs_space_count:w + \int_value:w \int_eval:w 0 + \exp_after:wN \@@_analysis_cs_space_count:w \token_to_str:N #2 - \fi: \@@_cs_space_count_end:w ; ~ ! + \fi: \@@_analysis_cs_space_count_end:w ; ~ ! } -\cs_new:Npn \@@_cs_space_count:w #1 ~ +\cs_new:Npn \@@_analysis_cs_space_count:w #1 ~ { \if_false: #1 #1 \fi: + 1 - \@@_cs_space_count:w + \@@_analysis_cs_space_count:w } -\cs_new:Npn \@@_cs_space_count_end:w ; #1 \fi: #2 ! - { \exp_after:wN ; \__int_value:w \str_count_ignore_spaces:n {#1} ; } +\cs_new:Npn \@@_analysis_cs_space_count_end:w ; #1 \fi: #2 ! + { \exp_after:wN ; \int_value:w \str_count_ignore_spaces:n {#1} ; } % \end{macrocode} % \end{macro} % \end{macro} @@ -298,10 +287,10 @@ % % Our goal is to produce a token list of the form roughly % \begin{quote} -% \meta{token 1} \cs{s__tl} \meta{catcode 1} \meta{char code 1} \cs{s__tl} \\ -% \meta{token 2} \cs{s__tl} \meta{catcode 2} \meta{char code 2} \cs{s__tl} \\ +% \meta{token 1} \cs{s@__} \meta{catcode 1} \meta{char code 1} \cs{s@__} \\ +% \meta{token 2} \cs{s_@@} \meta{catcode 2} \meta{char code 2} \cs{s_@@} \\ % \ldots{} -% \meta{token N} \cs{s__tl} \meta{catcode N} \meta{char code N} \cs{s__tl} +% \meta{token N} \cs{s_@@} \meta{catcode N} \meta{char code N} \cs{s_@@} % \end{quote} % Most but not all tokens can be grabbed as an undelimited % (\texttt{N}-type) argument by \TeX{}. The plan is to have a two pass @@ -346,18 +335,18 @@ % % The second pass is a simple exercise in expandable loops. % -% \begin{macro}{\@@:n} +% \begin{macro}{\@@_analysis:n} % Everything is done within a group, and all definitions are % local. We use \cs{group_align_safe_begin/end:} to avoid problems in -% case \cs{@@:n} is used within an alignment and its argument +% case \cs{@@_analysis:n} is used within an alignment and its argument % contains alignment tab tokens. % \begin{macrocode} -\cs_new_protected:Npn \@@:n #1 +\cs_new_protected:Npn \@@_analysis:n #1 { \group_begin: \group_align_safe_begin: - \@@_a:n {#1} - \@@_b:n {#1} + \@@_analysis_a:n {#1} + \@@_analysis_b:n {#1} \group_align_safe_end: \group_end: } @@ -366,7 +355,7 @@ % % \subsection{Disabling active characters} % -% \begin{macro}{\@@_disable:n} +% \begin{macro}{\@@_analysis_disable:n} % Active characters can cause problems later on in the processing, so % we provide a way to disable them, by setting them to % \texttt{undefined}. Since Unicode contains too many characters to @@ -376,14 +365,16 @@ % \begin{macrocode} \group_begin: \char_set_catcode_active:N \^^@ - \cs_new_protected:Npn \@@_disable:n #1 + \cs_new_protected:Npn \@@_analysis_disable:n #1 { \tex_lccode:D 0 = #1 \exp_stop_f: \tex_lowercase:D { \tex_let:D ^^@ } \tex_undefined:D } - \cs_if_exist:NT \ptex_kanjiskip:D + \bool_lazy_or:nnT + { \sys_if_engine_ptex_p: } + { \sys_if_engine_uptex_p: } { - \cs_gset_protected:Npn \@@_disable:n #1 + \cs_gset_protected:Npn \@@_analysis_disable:n #1 { \if_int_compare:w 256 > #1 \exp_stop_f: \tex_lccode:D 0 = #1 \exp_stop_f: @@ -431,37 +422,37 @@ % \cs{str_tail:n} \Arg{token} is non-empty, because the % escape character is printable. % -% \begin{macro}{\@@_a:n} +% \begin{macro}{\@@_analysis_a:n} % We read tokens one by one using \tn{futurelet}. % While performing the loop, we keep track of the number of % true begin-group characters minus the number of -% true end-group characters in \cs{l_@@_nesting_int}. +% true end-group characters in \cs{l_@@_analysis_nesting_int}. % This reaches $-1$ when we read the closing brace. % \begin{macrocode} -\cs_new_protected:Npn \@@_a:n #1 +\cs_new_protected:Npn \@@_analysis_a:n #1 { - \@@_disable:n { 32 } + \@@_analysis_disable:n { 32 } \int_set:Nn \tex_escapechar:D { 92 } - \int_zero:N \l_@@_normal_int - \int_zero:N \l_@@_index_int - \int_zero:N \l_@@_nesting_int - \if_false: { \fi: \@@_a_loop:w #1 } - \int_decr:N \l_@@_index_int + \int_zero:N \l_@@_analysis_normal_int + \int_zero:N \l_@@_analysis_index_int + \int_zero:N \l_@@_analysis_nesting_int + \if_false: { \fi: \@@_analysis_a_loop:w #1 } + \int_decr:N \l_@@_analysis_index_int } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_a_loop:w} +% \begin{macro}{\@@_analysis_a_loop:w} % Read one character and check its type. % \begin{macrocode} -\cs_new_protected:Npn \@@_a_loop:w - { \tex_futurelet:D \l_@@_token \@@_a_type:w } +\cs_new_protected:Npn \@@_analysis_a_loop:w + { \tex_futurelet:D \l_@@_analysis_token \@@_analysis_a_type:w } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_a_type:w} -% At this point, \cs{l_@@_token} holds the meaning -% of the following token. We store in \cs{l_@@_type_int} +% \begin{macro}{\@@_analysis_a_type:w} +% At this point, \cs{l_@@_analysis_token} holds the meaning +% of the following token. We store in \cs{l_@@_analysis_type_int} % information about the meaning of the token ahead: % \begin{itemize} % \item 0 space token; @@ -473,19 +464,19 @@ % character changes the nesting level ($2$ is used only here, % and is irrelevant later). Then call the auxiliary for each case. % Note that nesting conditionals here is safe because we only skip -% over \cs{l_@@_token} if it matches with one of the +% over \cs{l_@@_analysis_token} if it matches with one of the % character tokens (hence is not a primitive conditional). % \begin{macrocode} -\cs_new_protected:Npn \@@_a_type:w +\cs_new_protected:Npn \@@_analysis_a_type:w { - \l_@@_type_int = - \if_meaning:w \l_@@_token \c_space_token + \l_@@_analysis_type_int = + \if_meaning:w \l_@@_analysis_token \c_space_token 0 \else: - \if_catcode:w \exp_not:N \l_@@_token \c_group_begin_token + \if_catcode:w \exp_not:N \l_@@_analysis_token \c_group_begin_token 1 \else: - \if_catcode:w \exp_not:N \l_@@_token \c_group_end_token + \if_catcode:w \exp_not:N \l_@@_analysis_token \c_group_end_token - 1 \else: 2 @@ -493,26 +484,26 @@ \fi: \fi: \exp_stop_f: - \if_case:w \l_@@_type_int - \exp_after:wN \@@_a_space:w - \or: \exp_after:wN \@@_a_bgroup:w - \or: \exp_after:wN \@@_a_safe:N - \else: \exp_after:wN \@@_a_egroup:w + \if_case:w \l_@@_analysis_type_int + \exp_after:wN \@@_analysis_a_space:w + \or: \exp_after:wN \@@_analysis_a_bgroup:w + \or: \exp_after:wN \@@_analysis_a_safe:N + \else: \exp_after:wN \@@_analysis_a_egroup:w \fi: } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_a_space:w} -% \begin{macro}{\@@_a_space_test:w} +% \begin{macro}{\@@_analysis_a_space:w} +% \begin{macro}{\@@_analysis_a_space_test:w} % In this branch, the following token's meaning is a blank space. % Apply \tn{string} to that token: a true blank space gives a space, a % control sequence gives a result starting with the escape character, % an active character gives something else than a space since we -% disabled the space. We grab as \cs{l_@@_char_token} the first +% disabled the space. We grab as \cs{l_@@_analysis_char_token} the first % character of the string representation then test it in -% \cs{@@_a_space_test:w}. -% Also, since \cs{@@_a_store:} expects the special token to be +% \cs{@@_analysis_a_space_test:w}. +% Also, since \cs{@@_analysis_a_store:} expects the special token to be % stored in the relevant \tn{toks} register, we do that. The extra % \cs{exp_not:n} is unnecessary of course, but it makes the treatment % of all tokens more homogeneous. @@ -526,30 +517,30 @@ % so that the second pass does not need to test the meaning of tokens, % only strings. % \begin{macrocode} -\cs_new_protected:Npn \@@_a_space:w +\cs_new_protected:Npn \@@_analysis_a_space:w { - \tex_afterassignment:D \@@_a_space_test:w + \tex_afterassignment:D \@@_analysis_a_space_test:w \exp_after:wN \cs_set_eq:NN - \exp_after:wN \l_@@_char_token + \exp_after:wN \l_@@_analysis_char_token \token_to_str:N } -\cs_new_protected:Npn \@@_a_space_test:w +\cs_new_protected:Npn \@@_analysis_a_space_test:w { - \if_meaning:w \l_@@_char_token \c_space_token - \tex_toks:D \l_@@_index_int { \exp_not:n { ~ } } - \@@_a_store: + \if_meaning:w \l_@@_analysis_char_token \c_space_token + \tex_toks:D \l_@@_analysis_index_int { \exp_not:n { ~ } } + \@@_analysis_a_store: \else: - \int_incr:N \l_@@_normal_int + \int_incr:N \l_@@_analysis_normal_int \fi: - \@@_a_loop:w + \@@_analysis_a_loop:w } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}{\@@_a_bgroup:w, \@@_a_egroup:w} +% \begin{macro}{\@@_analysis_a_bgroup:w, \@@_analysis_a_egroup:w} % \begin{macro} -% {\@@_a_group:nw, \@@_a_group_aux:w, \@@_a_group_auxii:w, \@@_a_group_test:w} +% {\@@_analysis_a_group:nw, \@@_analysis_a_group_aux:w, \@@_analysis_a_group_auxii:w, \@@_analysis_a_group_test:w} % The token is most likely a true character token with catcode $1$ or % $2$, but it might be a control sequence, or an active character. % Optimizing for the first case, we store in a toks register some code @@ -561,60 +552,60 @@ % active character with that character code and re-test: if the % following token has become undefined we can in fact safely grab it. % We are finally ready to turn what follows to a string and test it. -% This is one place where we need \cs{l_@@_char_token} to be a -% separate control sequence from \cs{l_@@_token}, to compare them. +% This is one place where we need \cs{l_@@_analysis_char_token} to be a +% separate control sequence from \cs{l_@@_analysis_token}, to compare them. % \begin{macrocode} \group_begin: \char_set_catcode_group_begin:N \^^@ % { - \cs_new_protected:Npn \@@_a_bgroup:w - { \@@_a_group:nw { \exp_after:wN ^^@ \if_false: } \fi: } } + \cs_new_protected:Npn \@@_analysis_a_bgroup:w + { \@@_analysis_a_group:nw { \exp_after:wN ^^@ \if_false: } \fi: } } \char_set_catcode_group_end:N \^^@ - \cs_new_protected:Npn \@@_a_egroup:w - { \@@_a_group:nw { \if_false: { \fi: ^^@ } } % } + \cs_new_protected:Npn \@@_analysis_a_egroup:w + { \@@_analysis_a_group:nw { \if_false: { \fi: ^^@ } } % } \group_end: -\cs_new_protected:Npn \@@_a_group:nw #1 +\cs_new_protected:Npn \@@_analysis_a_group:nw #1 { - \tex_lccode:D 0 = \@@_extract_charcode: \scan_stop: - \tex_lowercase:D { \tex_toks:D \l_@@_index_int {#1} } + \tex_lccode:D 0 = \@@_analysis_extract_charcode: \scan_stop: + \tex_lowercase:D { \tex_toks:D \l_@@_analysis_index_int {#1} } \if_int_compare:w \tex_lccode:D 0 = \tex_escapechar:D \int_set:Nn \tex_escapechar:D { 139 - \tex_escapechar:D } \fi: - \@@_disable:n { \tex_lccode:D 0 } - \tex_futurelet:D \l_@@_token \@@_a_group_aux:w + \@@_analysis_disable:n { \tex_lccode:D 0 } + \tex_futurelet:D \l_@@_analysis_token \@@_analysis_a_group_aux:w } -\cs_new_protected:Npn \@@_a_group_aux:w +\cs_new_protected:Npn \@@_analysis_a_group_aux:w { - \if_meaning:w \l_@@_token \tex_undefined:D - \exp_after:wN \@@_a_safe:N + \if_meaning:w \l_@@_analysis_token \tex_undefined:D + \exp_after:wN \@@_analysis_a_safe:N \else: - \exp_after:wN \@@_a_group_auxii:w + \exp_after:wN \@@_analysis_a_group_auxii:w \fi: } -\cs_new_protected:Npn \@@_a_group_auxii:w +\cs_new_protected:Npn \@@_analysis_a_group_auxii:w { - \tex_afterassignment:D \@@_a_group_test:w + \tex_afterassignment:D \@@_analysis_a_group_test:w \exp_after:wN \cs_set_eq:NN - \exp_after:wN \l_@@_char_token + \exp_after:wN \l_@@_analysis_char_token \token_to_str:N } -\cs_new_protected:Npn \@@_a_group_test:w +\cs_new_protected:Npn \@@_analysis_a_group_test:w { - \if_charcode:w \l_@@_token \l_@@_char_token - \@@_a_store: + \if_charcode:w \l_@@_analysis_token \l_@@_analysis_char_token + \@@_analysis_a_store: \else: - \int_incr:N \l_@@_normal_int + \int_incr:N \l_@@_analysis_normal_int \fi: - \@@_a_loop:w + \@@_analysis_a_loop:w } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}{\@@_a_store:} +% \begin{macro}{\@@_analysis_a_store:} % This function is called each time we meet a special token; -% at this point, the \tn{toks} register \cs{l_@@_index_int} +% at this point, the \tn{toks} register \cs{l_@@_analysis_index_int} % holds a token list which expands to the given special token. -% Also, the value of \cs{l_@@_type_int} indicates which case +% Also, the value of \cs{l_@@_analysis_type_int} indicates which case % we are in: % \begin{itemize} % \item -1 end-group character; @@ -634,31 +625,32 @@ % \item 2 space begin-group character. % \end{itemize} % This has the property that non-space characters correspond to odd -% values of \cs{l_@@_type_int}. The number of normal tokens until +% values of \cs{l_@@_analysis_type_int}. The number of normal tokens until % here and the type of special token are packed into a \tn{skip} % register. Finally, we check whether we reached the last closing % brace, in which case we stop by disabling the looping function % (locally). % \begin{macrocode} -\cs_new_protected:Npn \@@_a_store: +\cs_new_protected:Npn \@@_analysis_a_store: { - \tex_advance:D \l_@@_nesting_int \l_@@_type_int + \tex_advance:D \l_@@_analysis_nesting_int \l_@@_analysis_type_int \if_int_compare:w \tex_lccode:D 0 = `\ \exp_stop_f: - \tex_advance:D \l_@@_type_int \l_@@_type_int + \tex_advance:D \l_@@_analysis_type_int \l_@@_analysis_type_int \fi: - \tex_skip:D \l_@@_index_int - = \l_@@_normal_int sp plus \l_@@_type_int sp \scan_stop: - \int_incr:N \l_@@_index_int - \int_zero:N \l_@@_normal_int - \if_int_compare:w \l_@@_nesting_int = -1 \exp_stop_f: - \cs_set_eq:NN \@@_a_loop:w \scan_stop: + \tex_skip:D \l_@@_analysis_index_int + = \l_@@_analysis_normal_int sp + plus \l_@@_analysis_type_int sp \scan_stop: + \int_incr:N \l_@@_analysis_index_int + \int_zero:N \l_@@_analysis_normal_int + \if_int_compare:w \l_@@_analysis_nesting_int = -1 \exp_stop_f: + \cs_set_eq:NN \@@_analysis_a_loop:w \scan_stop: \fi: } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_a_safe:N} -% \begin{macro}{\@@_a_cs:ww} +% \begin{macro}{\@@_analysis_a_safe:N} +% \begin{macro}{\@@_analysis_a_cs:ww} % This should be the simplest case: since the upcoming token is safe, % we can simply grab it in a second pass. If the token is a single % character (including space), the \cs{if_charcode:w} test yields @@ -672,12 +664,12 @@ % if the control sequence name contains no space, count that token % as a number of normal tokens equal to its string length. If the % control sequence contains spaces, they should be registered as -% special characters by increasing \cs{l_@@_index_int} +% special characters by increasing \cs{l_@@_analysis_index_int} % (no need to carefully count character between each space), and % all characters after the last space should be counted in the % following sequence of \enquote{normal} tokens. % \begin{macrocode} -\cs_new_protected:Npn \@@_a_safe:N #1 +\cs_new_protected:Npn \@@_analysis_a_safe:N #1 { \if_charcode:w \scan_stop: @@ -688,22 +680,22 @@ \exp_after:wN \use_ii:nn \fi: { - \@@_disable:n { `#1 } - \int_incr:N \l_@@_normal_int + \@@_analysis_disable:n { `#1 } + \int_incr:N \l_@@_analysis_normal_int } - { \@@_cs_space_count:NN \@@_a_cs:ww #1 } - \@@_a_loop:w + { \@@_analysis_cs_space_count:NN \@@_analysis_a_cs:ww #1 } + \@@_analysis_a_loop:w } -\cs_new_protected:Npn \@@_a_cs:ww #1; #2; +\cs_new_protected:Npn \@@_analysis_a_cs:ww #1; #2; { \if_int_compare:w #1 > 0 \exp_stop_f: - \tex_skip:D \l_@@_index_int - = \__int_eval:w \l_@@_normal_int + 1 sp \scan_stop: - \tex_advance:D \l_@@_index_int #1 \exp_stop_f: + \tex_skip:D \l_@@_analysis_index_int + = \int_eval:n { \l_@@_analysis_normal_int + 1 } sp \exp_stop_f: + \tex_advance:D \l_@@_analysis_index_int #1 \exp_stop_f: \else: \tex_advance:D \fi: - \l_@@_normal_int #2 \exp_stop_f: + \l_@@_analysis_normal_int #2 \exp_stop_f: } % \end{macrocode} % \end{macro} @@ -715,61 +707,61 @@ % All the necessary information is stored in \tn{skip} % and \tn{toks} registers. % -% \begin{macro}{\@@_b:n} -% \begin{macro}[EXP]{\@@_b_loop:w} +% \begin{macro}{\@@_analysis_b:n} +% \begin{macro}[EXP]{\@@_analysis_b_loop:w} % Start the loop with the index $0$. No need for an end-marker: % the loop stops by itself when the last index is read. % We repeatedly oscillate between reading long stretches % of normal tokens, and reading special tokens. % \begin{macrocode} -\cs_new_protected:Npn \@@_b:n #1 +\cs_new_protected:Npn \@@_analysis_b:n #1 { - \tl_gset:Nx \g_@@_result_tl + \tl_gset:Nx \g_@@_analysis_result_tl { - \@@_b_loop:w 0; #1 - \__prg_break_point: + \@@_analysis_b_loop:w 0; #1 + \prg_break_point: } } -\cs_new:Npn \@@_b_loop:w #1; +\cs_new:Npn \@@_analysis_b_loop:w #1; { - \exp_after:wN \@@_b_normals:ww - \__int_value:w \tex_skip:D #1 ; #1 ; + \exp_after:wN \@@_analysis_b_normals:ww + \int_value:w \tex_skip:D #1 ; #1 ; } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\@@_b_normals:ww} -% \begin{macro}[EXP]{\@@_b_normal:wwN} +% \begin{macro}[EXP]{\@@_analysis_b_normals:ww} +% \begin{macro}[EXP]{\@@_analysis_b_normal:wwN} % The first argument is the number of normal tokens which remain % to be read, and the second argument is the index in the array % produced in the first step. % A character's string representation is always one character long, % while a control sequence is always longer (we have set the escape % character to a printable value). In both cases, we leave -% \cs{exp_not:n} \Arg{token} \cs{s__tl} in the input stream +% \cs{exp_not:n} \Arg{token} \cs{s_@@} in the input stream % (after \texttt{x}-expansion). Here, \cs{exp_not:n} is used % rather than \cs{exp_not:N} because |#3| could be -% a macro parameter character or could be \cs{s__tl} +% a macro parameter character or could be \cs{s_@@} % (which must be hidden behind braces in the result). % \begin{macrocode} -\cs_new:Npn \@@_b_normals:ww #1; +\cs_new:Npn \@@_analysis_b_normals:ww #1; { \if_int_compare:w #1 = 0 \exp_stop_f: - \@@_b_special:w + \@@_analysis_b_special:w \fi: - \@@_b_normal:wwN #1; + \@@_analysis_b_normal:wwN #1; } -\cs_new:Npn \@@_b_normal:wwN #1; #2; #3 +\cs_new:Npn \@@_analysis_b_normal:wwN #1; #2; #3 { - \exp_not:n { \exp_not:n { #3 } } \s__tl + \exp_not:n { \exp_not:n { #3 } } \s_@@ \if_charcode:w \scan_stop: \exp_after:wN \use_none:n \token_to_str:N #3 \prg_do_nothing: \scan_stop: - \exp_after:wN \@@_b_char:Nww + \exp_after:wN \@@_analysis_b_char:Nww \else: - \exp_after:wN \@@_b_cs:Nww + \exp_after:wN \@@_analysis_b_cs:Nww \fi: #3 #1; #2; } @@ -777,13 +769,13 @@ % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\@@_b_char:Nww} +% \begin{macro}[EXP]{\@@_analysis_b_char:Nww} % If the normal token we grab is a character, leave -% \meta{catcode} \meta{charcode} followed by \cs{s__tl} -% in the input stream, and call \cs{@@_b_normals:ww} +% \meta{catcode} \meta{charcode} followed by \cs{s_@@} +% in the input stream, and call \cs{@@_analysis_b_normals:ww} % with its first argument decremented. % \begin{macrocode} -\cs_new:Npx \@@_b_char:Nww #1 +\cs_new:Npx \@@_analysis_b_char:Nww #1 { \exp_not:N \if_meaning:w #1 \exp_not:N \tex_undefined:D \token_to_str:N D \exp_not:N \else: @@ -791,53 +783,57 @@ \token_to_str:N C \exp_not:N \else: \exp_not:N \if_catcode:w #1 \c_catcode_letter_token \token_to_str:N B \exp_not:N \else: - \exp_not:N \if_catcode:w #1 \c_math_toggle_token 3 \exp_not:N \else: - \exp_not:N \if_catcode:w #1 \c_alignment_token 4 \exp_not:N \else: - \exp_not:N \if_catcode:w #1 \c_math_superscript_token 7 \exp_not:N \else: - \exp_not:N \if_catcode:w #1 \c_math_subscript_token 8 \exp_not:N \else: + \exp_not:N \if_catcode:w #1 \c_math_toggle_token 3 + \exp_not:N \else: + \exp_not:N \if_catcode:w #1 \c_alignment_token 4 + \exp_not:N \else: + \exp_not:N \if_catcode:w #1 \c_math_superscript_token 7 + \exp_not:N \else: + \exp_not:N \if_catcode:w #1 \c_math_subscript_token 8 + \exp_not:N \else: \exp_not:N \if_catcode:w #1 \c_space_token \token_to_str:N A \exp_not:N \else: 6 \exp_not:n { \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: } - \exp_not:N \__int_value:w `#1 \s__tl - \exp_not:N \exp_after:wN \exp_not:N \@@_b_normals:ww - \exp_not:N \__int_value:w \exp_not:N \__int_eval:w - 1 + + \exp_not:N \int_value:w `#1 \s_@@ + \exp_not:N \exp_after:wN \exp_not:N \@@_analysis_b_normals:ww + \exp_not:N \int_value:w \exp_not:N \int_eval:w - 1 + } % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\@@_b_cs:Nww} -% \begin{macro}[EXP]{\@@_b_cs_test:ww} +% \begin{macro}[EXP]{\@@_analysis_b_cs:Nww} +% \begin{macro}[EXP]{\@@_analysis_b_cs_test:ww} % If the token we grab is a control sequence, leave % |0 -1| (as category code and character code) in the input stream, -% followed by \cs{s__tl}, -% and call \cs{@@_b_normals:ww} with updated arguments. +% followed by \cs{s_@@}, +% and call \cs{@@_analysis_b_normals:ww} with updated arguments. % \begin{macrocode} -\cs_new:Npn \@@_b_cs:Nww #1 +\cs_new:Npn \@@_analysis_b_cs:Nww #1 { - 0 -1 \s__tl - \@@_cs_space_count:NN \@@_b_cs_test:ww #1 + 0 -1 \s_@@ + \@@_analysis_cs_space_count:NN \@@_analysis_b_cs_test:ww #1 } -\cs_new:Npn \@@_b_cs_test:ww #1 ; #2 ; #3 ; #4 ; +\cs_new:Npn \@@_analysis_b_cs_test:ww #1 ; #2 ; #3 ; #4 ; { - \exp_after:wN \@@_b_normals:ww - \__int_value:w \__int_eval:w + \exp_after:wN \@@_analysis_b_normals:ww + \int_value:w \int_eval:w \if_int_compare:w #1 = 0 \exp_stop_f: #3 \else: - \tex_skip:D \__int_eval:w #4 + #1 \__int_eval_end: + \tex_skip:D \int_eval:n { #4 + #1 } \exp_stop_f: \fi: - #2 \exp_after:wN ; - \__int_value:w \__int_eval:w #4 + #1 ; + \int_value:w \int_eval:n { #4 + #1 } ; } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\@@_b_special:w} -% \begin{macro}[EXP]{\@@_b_special_char:wN} -% \begin{macro}[EXP]{\@@_b_special_space:w} +% \begin{macro}[EXP]{\@@_analysis_b_special:w} +% \begin{macro}[EXP]{\@@_analysis_b_special_char:wN} +% \begin{macro}[EXP]{\@@_analysis_b_special_space:w} % Here, |#1| is the current index in the array built in the first pass. % Check now whether we reached the end (we shouldn't keep the trailing % end-group character that marked the end of the token list in the @@ -845,18 +841,18 @@ % Unpack the \tn{toks} register: when \texttt{x}-expanding again, % we will get the special token. % Then leave the category code in the input stream, followed by -% the character code, and call \cs{@@_b_loop:w} with the next index. +% the character code, and call \cs{@@_analysis_b_loop:w} with the next index. % \begin{macrocode} \group_begin: \char_set_catcode_other:N A - \cs_new:Npn \@@_b_special:w - \fi: \@@_b_normal:wwN 0 ; #1 ; + \cs_new:Npn \@@_analysis_b_special:w + \fi: \@@_analysis_b_normal:wwN 0 ; #1 ; { \fi: - \if_int_compare:w #1 = \l_@@_index_int - \exp_after:wN \__prg_break: + \if_int_compare:w #1 = \l_@@_analysis_index_int + \exp_after:wN \prg_break: \fi: - \tex_the:D \tex_toks:D #1 \s__tl + \tex_the:D \tex_toks:D #1 \s_@@ \if_case:w \etex_gluestretch:D \tex_skip:D #1 \exp_stop_f: \token_to_str:N A \or: 1 @@ -864,23 +860,23 @@ \else: 2 \fi: \if_int_odd:w \etex_gluestretch:D \tex_skip:D #1 \exp_stop_f: - \exp_after:wN \@@_b_special_char:wN \__int_value:w + \exp_after:wN \@@_analysis_b_special_char:wN \int_value:w \else: - \exp_after:wN \@@_b_special_space:w \__int_value:w + \exp_after:wN \@@_analysis_b_special_space:w \int_value:w \fi: - \__int_eval:w 1 + #1 \exp_after:wN ; + \int_eval:n { 1 + #1 } \exp_after:wN ; \token_to_str:N } \group_end: -\cs_new:Npn \@@_b_special_char:wN #1 ; #2 +\cs_new:Npn \@@_analysis_b_special_char:wN #1 ; #2 { - \__int_value:w `#2 \s__tl - \@@_b_loop:w #1 ; + \int_value:w `#2 \s_@@ + \@@_analysis_b_loop:w #1 ; } -\cs_new:Npn \@@_b_special_space:w #1 ; ~ +\cs_new:Npn \@@_analysis_b_special_space:w #1 ; ~ { - 32 \s__tl - \@@_b_loop:w #1 ; + 32 \s_@@ + \@@_analysis_b_loop:w #1 ; } % \end{macrocode} % \end{macro} @@ -889,11 +885,12 @@ % % \subsection{Mapping through the analysis} % -% \begin{macro}{\@@_map_inline:nn} -% \begin{macro}{\@@_map_inline_aux:Nn} +% \begin{macro}{\tl_analysis_map_inline:nn, \tl_analysis_map_inline:Nn} +% \begin{macro}{\@@_analysis_map_inline_aux:Nn} +% \begin{macro}{\@@_analysis_map_inline_aux:nnn} % First obtain the analysis of the token list into -% \cs{g_@@_result_tl}. To allow nested mappings, increase the -% nesting depth \cs{g__prg_map_int} (shared between all modules), then +% \cs{g_@@_analysis_result_tl}. To allow nested mappings, increase the +% nesting depth \cs{g__kernel_prg_map_int} (shared between all modules), then % define the looping macro, which has a name specific to that nesting % depth. That looping grabs the \meta{tokens}, \meta{catcode} and % \meta{char code}; it checks for the end of the loop with @@ -902,57 +899,65 @@ % |#2|, and loops by calling itself. When the loop ends, remember to % decrease the nesting depth. % \begin{macrocode} -\cs_new_protected:Npn \@@_map_inline:nn #1 +\cs_new_protected:Npn \tl_analysis_map_inline:nn #1 { - \@@:n {#1} - \int_gincr:N \g__prg_map_int - \exp_args:Nc \@@_map_inline_aux:Nn - { @@_map_inline_ \int_use:N \g__prg_map_int :wNw } + \@@_analysis:n {#1} + \int_gincr:N \g__kernel_prg_map_int + \exp_args:Nc \@@_analysis_map_inline_aux:Nn + { @@_analysis_map_inline_ \int_use:N \g__kernel_prg_map_int :wNw } } -\cs_new_protected:Npn \@@_map_inline_aux:Nn #1#2 +\cs_new_protected:Npn \tl_analysis_map_inline:Nn #1 + { \exp_args:No \tl_analysis_map_inline:nn #1 } +\cs_new_protected:Npn \@@_analysis_map_inline_aux:Nn #1#2 { - \cs_gset_protected:Npn #1 ##1 \s__tl ##2 ##3 \s__tl + \cs_gset_protected:Npn #1 ##1 \s_@@ ##2 ##3 \s_@@ { \use_none:n ##2 + \@@_analysis_map_inline_aux:nnn {##1} {##3} {##2} + } + \cs_gset_protected:Npn \@@_analysis_map_inline_aux:nnn ##1##2##3 + { #2 #1 } \exp_after:wN #1 - \g_@@_result_tl - \s__tl { ? \tl_map_break: } \s__tl - \__prg_break_point:Nn \tl_map_break: { \int_gdecr:N \g__prg_map_int } + \g_@@_analysis_result_tl + \s_@@ { ? \tl_map_break: } \s_@@ + \prg_break_point:Nn \tl_map_break: + { \int_gdecr:N \g__kernel_prg_map_int } } % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % \subsection{Showing the results} % -% \begin{macro}{\tl_show_analysis:N, \tl_show_analysis:n} -% Add to \cs{@@:n} a third pass to display tokens to the terminal. +% \begin{macro}{\tl_analysis_show:N, \tl_analysis_show:n} +% Add to \cs{@@_analysis:n} a third pass to display tokens to the terminal. % If the token list variable is not defined, throw the same error % as \cs{tl_show:N} by simply calling that function. % \begin{macrocode} -\cs_new_protected:Npn \tl_show_analysis:N #1 +\cs_new_protected:Npn \tl_analysis_show:N #1 { \tl_if_exist:NTF #1 { - \exp_args:No \@@:n {#1} + \exp_args:No \@@_analysis:n {#1} \msg_show:nnxxxx { LaTeX / kernel } { show-tl-analysis } - { \token_to_str:N #1 } { \@@_show: } { } { } + { \token_to_str:N #1 } { \@@_analysis_show: } { } { } } { \tl_show:N #1 } } -\cs_new_protected:Npn \tl_show_analysis:n #1 +\cs_new_protected:Npn \tl_analysis_show:n #1 { - \@@:n {#1} + \@@_analysis:n {#1} \msg_show:nnxxxx { LaTeX / kernel } { show-tl-analysis } - { } { \@@_show: } { } { } + { } { \@@_analysis_show: } { } { } } % \end{macrocode} % \end{macro} % -% \begin{macro}[rEXP]{\@@_show:, \@@_show_loop:wNw} +% \begin{macro}[rEXP]{\@@_analysis_show:, \@@_analysis_show_loop:wNw} % Here, |#1| \texttt{o}- and \texttt{x}-expands to the token; % |#2| is the category code (one uppercase hexadecimal digit), % $0$ for control sequences; @@ -961,40 +966,40 @@ % the meaning may overflow one line, and we want to truncate % it. Those cases are thus separated out. % \begin{macrocode} -\cs_new:Npn \@@_show: +\cs_new:Npn \@@_analysis_show: { - \exp_after:wN \@@_show_loop:wNw \g_@@_result_tl - \s__tl { ? \__prg_break: } \s__tl - \__prg_break_point: + \exp_after:wN \@@_analysis_show_loop:wNw \g_@@_analysis_result_tl + \s_@@ { ? \prg_break: } \s_@@ + \prg_break_point: } -\cs_new:Npn \@@_show_loop:wNw #1 \s__tl #2 #3 \s__tl +\cs_new:Npn \@@_analysis_show_loop:wNw #1 \s_@@ #2 #3 \s_@@ { \use_none:n #2 \iow_newline: > \use:nn { ~ } { ~ } \if_int_compare:w "#2 = 0 \exp_stop_f: - \exp_after:wN \@@_show_cs:n + \exp_after:wN \@@_analysis_show_cs:n \else: \if_int_compare:w "#2 = 13 \exp_stop_f: \exp_after:wN \exp_after:wN - \exp_after:wN \@@_show_active:n + \exp_after:wN \@@_analysis_show_active:n \else: \exp_after:wN \exp_after:wN - \exp_after:wN \@@_show_normal:n + \exp_after:wN \@@_analysis_show_normal:n \fi: \fi: {#1} - \@@_show_loop:wNw + \@@_analysis_show_loop:wNw } % \end{macrocode} % \end{macro} % -% \begin{macro}[rEXP]{\@@_show_normal:n} +% \begin{macro}[rEXP]{\@@_analysis_show_normal:n} % Non-active characters are a simple matter of printing % the character, and its meaning. Our test suite checks that % begin-group and end-group characters do not mess up % \TeX{}'s alignment status. % \begin{macrocode} -\cs_new:Npn \@@_show_normal:n #1 +\cs_new:Npn \@@_analysis_show_normal:n #1 { \exp_after:wN \token_to_str:N #1 ~ ( \exp_after:wN \token_to_meaning:N #1 ) @@ -1002,48 +1007,48 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\@@_show_value:N} +% \begin{macro}[EXP]{\@@_analysis_show_value:N} % This expands to the value of |#1| if it has any. % \begin{macrocode} -\cs_new:Npn \@@_show_value:N #1 +\cs_new:Npn \@@_analysis_show_value:N #1 { \token_if_expandable:NF #1 { - \token_if_chardef:NTF #1 \__prg_break: { } - \token_if_mathchardef:NTF #1 \__prg_break: { } - \token_if_dim_register:NTF #1 \__prg_break: { } - \token_if_int_register:NTF #1 \__prg_break: { } - \token_if_skip_register:NTF #1 \__prg_break: { } - \token_if_toks_register:NTF #1 \__prg_break: { } + \token_if_chardef:NTF #1 \prg_break: { } + \token_if_mathchardef:NTF #1 \prg_break: { } + \token_if_dim_register:NTF #1 \prg_break: { } + \token_if_int_register:NTF #1 \prg_break: { } + \token_if_skip_register:NTF #1 \prg_break: { } + \token_if_toks_register:NTF #1 \prg_break: { } \use_none:nnn - \__prg_break_point: + \prg_break_point: \use:n { \exp_after:wN = \tex_the:D #1 } } } % \end{macrocode} % \end{macro} % -% \begin{macro}[rEXP]{\@@_show_cs:n} -% \begin{macro}[rEXP]{\@@_show_active:n} -% \begin{macro}[rEXP]{\@@_show_long:nn} -% \begin{macro}[rEXP]{\@@_show_long_aux:nnnn} +% \begin{macro}[rEXP]{\@@_analysis_show_cs:n} +% \begin{macro}[rEXP]{\@@_analysis_show_active:n} +% \begin{macro}[rEXP]{\@@_analysis_show_long:nn} +% \begin{macro}[rEXP]{\@@_analysis_show_long_aux:nnnn} % Control sequences and active characters are printed in the same way, % making sure not to go beyond the \cs{l_iow_line_count_int}. In case % of an overflow, we replace the last characters by -% \cs{c_@@_show_etc_str}. +% \cs{c_@@_analysis_show_etc_str}. % \begin{macrocode} -\cs_new:Npn \@@_show_cs:n #1 - { \exp_args:No \@@_show_long:nn {#1} { control~sequence= } } -\cs_new:Npn \@@_show_active:n #1 - { \exp_args:No \@@_show_long:nn {#1} { active~character= } } -\cs_new:Npn \@@_show_long:nn #1 +\cs_new:Npn \@@_analysis_show_cs:n #1 + { \exp_args:No \@@_analysis_show_long:nn {#1} { control~sequence= } } +\cs_new:Npn \@@_analysis_show_active:n #1 + { \exp_args:No \@@_analysis_show_long:nn {#1} { active~character= } } +\cs_new:Npn \@@_analysis_show_long:nn #1 { - \@@_show_long_aux:oofn + \@@_analysis_show_long_aux:oofn { \token_to_str:N #1 } { \token_to_meaning:N #1 } - { \@@_show_value:N #1 } + { \@@_analysis_show_value:N #1 } } -\cs_new:Npn \@@_show_long_aux:nnnn #1#2#3#4 +\cs_new:Npn \@@_analysis_show_long_aux:nnnn #1#2#3#4 { \int_compare:nNnTF { \str_count:n { #1 ~ ( #4 #2 #3 ) } } @@ -1052,13 +1057,13 @@ \str_range:nnn { #1 ~ ( #4 #2 #3 ) } { 1 } { \l_iow_line_count_int - 3 - - \str_count:N \c_@@_show_etc_str + - \str_count:N \c_@@_analysis_show_etc_str } - \c_@@_show_etc_str + \c_@@_analysis_show_etc_str } { #1 ~ ( #4 #2 #3 ) } } -\cs_generate_variant:Nn \@@_show_long_aux:nnnn { oof } +\cs_generate_variant:Nn \@@_analysis_show_long_aux:nnnn { oof } % \end{macrocode} % \end{macro} % \end{macro} @@ -1067,12 +1072,12 @@ % % \subsection{Messages} % -% \begin{variable}{\c_@@_show_etc_str} +% \begin{variable}{\c_@@_analysis_show_etc_str} % When a control sequence (or active character) % and its meaning are too long to fit in one line % of the terminal, the end is replaced by this token list. % \begin{macrocode} -\tl_const:Nx \c_@@_show_etc_str % ( +\tl_const:Nx \c_@@_analysis_show_etc_str % ( { \token_to_str:N \ETC.) } % \end{macrocode} % \end{variable} @@ -1087,6 +1092,23 @@ } % \end{macrocode} % +% \subsection{Deprecated functions} +% +% \begin{macro}[deprecated = 2019-12-31] +% {\tl_show_analysis:N, \tl_show_analysis:n} +% Simple renames. +% \begin{macrocode} +\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } + { \tl_analysis_show:N } +\cs_new_protected:Npn \tl_show_analysis:N #1 + { \tl_analysis_show:N #1 } +\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } + { \tl_analysis_show:n } +\cs_new_protected:Npn \tl_show_analysis:n #1 + { \tl_analysis_show:n {#1} } +% \end{macrocode} +% \end{macro} +% % \begin{macrocode} %</initex|package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl-build.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl-build.dtx deleted file mode 100644 index 15cc7029cc3..00000000000 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl-build.dtx +++ /dev/null @@ -1,280 +0,0 @@ -% \iffalse meta-comment -% -%% File: l3tl-build.dtx Copyright (C) 2011-2017 The LaTeX3 Project -% -% It may be distributed and/or modified under the conditions of the -% LaTeX Project Public License (LPPL), either version 1.3c of this -% license or (at your option) any later version. The latest version -% of this license is in the file -% -% https://www.latex-project.org/lppl.txt -% -% This file is part of the "l3kernel bundle" (The Work in LPPL) -% and all files in that bundle must be distributed together. -% -% ----------------------------------------------------------------------- -% -% The development version of the bundle can be found at -% -% https://github.com/latex3/latex3 -% -% for those people who are interested. -% -%<*driver> -\documentclass[full,kernel]{l3doc} -\begin{document} - \DocInput{\jobname.dtx} -\end{document} -%</driver> -% \fi -% -% -% \title{^^A -% The \textsf{l3tl-build} package: building token lists^^A -% } -% -% \author{^^A -% The \LaTeX3 Project\thanks -% {^^A -% E-mail: -% \href{mailto:latex-team@latex-project.org} -% {latex-team@latex-project.org}^^A -% }^^A -% } -% -% \date{Released 2018/03/05} -% -% \maketitle -% -% \begin{documentation} -% -% \section{\pkg{l3tl-build} documentation} -% -% This module provides no user function: it is meant for kernel use -% only. -% -% There are two main ways of building token lists from individual -% tokens. Either in one go within an \texttt{x}-expanding assignment, or -% by repeatedly using \cs{tl_put_right:Nn}. The first method takes a -% linear time, but only allows expandable operations. The second method -% takes a time quadratic in the length of the token list, but allows -% expandable and non-expandable operations. -% -% The goal of this module is to provide functions to build a token list -% piece by piece in linear time, while allowing non-expandable -% operations. This is achieved by abusing \tn{toks}: adding some tokens -% to the token list is done by storing them in a free token register -% (time $O(1)$ for each such operation). Those token registers are only -% put together at the end, within an \texttt{x}-expanding assignment, -% which takes a linear time.\footnote{If we run out of token registers, -% then the currently filled-up \tn{toks} are put together in a -% temporary token list, and cleared, and we ultimately use -% \cs{tl_put_right:Nx} to put those chunks together. Hence the true -% asymptotic is quadratic, with a very small constant.} Of course, -% all this must be done in a group: we can't go and clobber the values -% of legitimate \tn{toks} used by \LaTeXe{}. -% -% Since none of the current applications need the ability to insert -% material on the left of the token list, I have not implemented -% that. This could be done for instance by using odd-numbered \tn{toks} -% for the left part, and even-numbered \tn{toks} for the right part. -% -% \subsection{Internal functions} -% -% \begin{function} -% { -% \__tl_build:Nw, \__tl_gbuild:Nw, -% \__tl_build_x:Nw, \__tl_gbuild_x:Nw -% } -% \begin{syntax} -% \cs{__tl_build:Nw} \meta{tl~var} \texttt{\ldots{}} -% \cs{__tl_build_one:n} \Arg{tokens_1} \texttt{\ldots{}} -% \cs{__tl_build_one:n} \Arg{tokens_2} \texttt{\ldots{}} -% \ldots{} -% \cs{__tl_build_end:} -% \end{syntax} -% Defines the \meta{tl~var} to contain the contents of \meta{tokens1} -% followed by \meta{tokens2}, \emph{etc.} This is built in such a way -% to be more efficient than repeatedly using \cs{tl_put_right:Nn}. The -% code in \enquote{\texttt{\ldots{}}} does not need to be -% expandable. The commands \cs{__tl_build:Nw} and \cs{__tl_build_end:} -% start and end a group. The assignment to the \meta{tl~var} occurs -% just after the end of that group, using \cs{tl_set:Nn}, -% \cs{tl_gset:Nn}, \cs{tl_set:Nx}, or \cs{tl_gset:Nx}. -% \end{function} -% -% \begin{function}{\__tl_build_one:n, \__tl_build_one:o, \__tl_build_one:x} -% \begin{syntax} -% \cs{__tl_build_one:n} \Arg{tokens} -% \end{syntax} -% This function may only be used within the scope of a -% \cs{__tl_build:Nw} function. It adds the \meta{tokens} on the -% right of the current token list. -% \end{function} -% -% \begin{function}{\__tl_build_end:} -% Ends the scope started by \cs{__tl_build:Nw}, and performs the -% relevant assignment. -% \end{function} -% -% \end{documentation} -% -% \begin{implementation} -% -% \section{\pkg{l3tl-build} implementation} -% -% \begin{macrocode} -%<*initex|package> -% \end{macrocode} -% -% \begin{macrocode} -%<@@=tl_build> -% \end{macrocode} -% -% \subsection{Variables and helper functions} -% -% \begin{variable}{\l_@@_start_index_int, \l_@@_index_int} -% Integers pointing to the starting index (currently always starts at -% zero), and the current index. The corresponding \tn{toks} are -% accessed directly by number. -% \begin{macrocode} -\int_new:N \l_@@_start_index_int -\int_new:N \l_@@_index_int -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_@@_result_tl} -% The resulting token list is normally built in one go by unpacking -% all \tn{toks} in some range. In the rare cases where there are too -% many \cs{@@_one:n} commands, leading to the depletion of -% registers, the contents of the current set of \tn{toks} is unpacked -% into \cs{l_@@_result_tl}. This prevents overflow from -% affecting the end-user (beyond an obvious performance hit). -% \begin{macrocode} -\tl_new:N \l_@@_result_tl -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\@@_unpack:} -% \begin{macro}[EXP]{\@@_unpack_loop:w} -% The various pieces of the token list are built in \tn{toks} from the -% \texttt{start_index} (inclusive) to the (current) \texttt{index} -% (excluded). Those \tn{toks} are unpacked and stored in order in the -% \texttt{result} token list. Optimizations would be possible here, -% for instance, unpacking $10$ \tn{toks} at a time with a macro -% expanding to |\the\toks#10...\the\toks#19|, but this should be kept -% for much later. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unpack: - { - \tl_put_right:Nx \l_@@_result_tl - { - \exp_after:wN \@@_unpack_loop:w - \int_use:N \l_@@_start_index_int ; - \__prg_break_point: - } - } -\cs_new:Npn \@@_unpack_loop:w #1 ; - { - \if_int_compare:w #1 = \l_@@_index_int - \exp_after:wN \__prg_break: - \fi: - \tex_the:D \tex_toks:D #1 \exp_stop_f: - \exp_after:wN \@@_unpack_loop:w - \int_use:N \__int_eval:w #1 + 1 ; - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \subsection{Building the token list} -% -% \begin{macro} -% { -% \@@:Nw , \@@_x:Nw , -% \__tl_gbuild:Nw , \__tl_gbuild_x:Nw -% } -% \begin{macro}{\@@_aux:NNw} -% Similar to what is done for coffins: redefine some command, here -% \cs{@@_end_aux:n} to hold the relevant assignment (see -% \cs{@@_end:} for details). Then initialize the start index and -% the current index at zero, and empty the \texttt{result} token list. -% \begin{macrocode} -\cs_new_protected:Npn \@@:Nw - { \@@_aux:NNw \tl_set:Nn } -\cs_new_protected:Npn \@@_x:Nw - { \@@_aux:NNw \tl_set:Nx } -\cs_new_protected:Npn \__tl_gbuild:Nw - { \@@_aux:NNw \tl_gset:Nn } -\cs_new_protected:Npn \__tl_gbuild_x:Nw - { \@@_aux:NNw \tl_gset:Nx } -\cs_new_protected:Npn \@@_aux:NNw #1#2 - { - \group_begin: - \cs_set:Npn \@@_end_assignment:n - { \group_end: #1 #2 } - \int_zero:N \l_@@_start_index_int - \int_zero:N \l_@@_index_int - \tl_clear:N \l_@@_result_tl - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_end:} -% \begin{macro}{\@@_end_assignment:n} -% When we are done building a token list, unpack all \tn{toks} into -% the \texttt{result} token list, and expand this list before closing -% the group. The \cs{@@_end_assignment:n} function is defined by -% \cs{@@_aux:NNw} to end the group and hold the relevant -% assignment. Its value outside is irrelevant, but just in case, we -% set it to a function which would clean up the contents of -% \cs{l_@@_result_tl}. -% \begin{macrocode} -\cs_new_protected:Npn \@@_end: - { - \@@_unpack: - \exp_args:No - \@@_end_assignment:n \l_@@_result_tl - } -\cs_new_eq:NN \@@_end_assignment:n \use_none:n -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_one:n, \@@_one:o, \@@_one:x} -% Store the tokens in a free \tn{toks}, then move the pointer to the -% next one. If we overflow, unpack the current \tn{toks}, and reset -% the current index, preparing to fill more \tn{toks}. This could be -% optimized by avoiding to read |#1|, using \tn{afterassignment}. -% \begin{macrocode} -\cs_new_protected:Npn \@@_one:n #1 - { - \tex_toks:D \l_@@_index_int {#1} - \int_incr:N \l_@@_index_int - \if_int_compare:w \l_@@_index_int > \c_max_register_int - \@@_unpack: - \l_@@_index_int \l_@@_start_index_int - \fi: - } -\cs_new_protected:Npn \@@_one:o #1 - { - \tex_toks:D \l_@@_index_int \exp_after:wN {#1} - \int_incr:N \l_@@_index_int - \if_int_compare:w \l_@@_index_int > \c_max_register_int - \@@_unpack: - \l_@@_index_int \l_@@_start_index_int - \fi: - } -\cs_new_protected:Npn \@@_one:x #1 - { \use:x { \@@_one:n {#1} } } -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -%</initex|package> -% \end{macrocode} -% -% \end{implementation} -% -% \PrintIndex diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx index a655fe18ea3..61505a3337c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -316,8 +316,7 @@ % (character code $32$ or $9$) at the end of every line. % Otherwise, spaces (and tabs) are retained at both ends of the % single-line string, as if it appeared in the middle of a line -% read from a file. Only the case of a single line is supported in -% \LuaTeX{} because of a bug in this engine. +% read from a file. % \end{texnote} % \end{function} % @@ -346,8 +345,7 @@ % (character code $32$ or $9$) at the end of every line. % Otherwise, spaces (and tabs) are retained at both ends of the % single-line string, as if it appeared in the middle of a line -% read from a file. Only the case of a single line is supported in -% \LuaTeX{} because of a bug in this engine. +% read from a file. % \end{texnote} % \end{function} % @@ -621,7 +619,10 @@ % resulting character tokens in the input stream. A \meta{string} % is a series of tokens with category code $12$ (other) with the exception % of spaces, which retain category code $10$ (space). +% This function requires only a single expansion. +% Its argument \emph{must} be braced. % \begin{texnote} +% This is the \eTeX{} primitive \tn{detokenize}. % Converting a \meta{token list} to a \meta{string} yields a % concatenation of the string representations of every token in the % \meta{token list}. @@ -754,7 +755,7 @@ % \end{function} % % \begin{function}[added = 2011-07-09, updated = 2012-06-25, EXP] -% {\tl_trim_spaces:n} +% {\tl_trim_spaces:n, \tl_trim_spaces:o} % \begin{syntax} % \cs{tl_trim_spaces:n} \Arg{token list} % \end{syntax} @@ -769,6 +770,17 @@ % \end{texnote} % \end{function} % +% \begin{function}[added = 2018-04-12, EXP] +% {\tl_trim_spaces_apply:nN, \tl_trim_spaces_apply:oN} +% \begin{syntax} +% \cs{tl_trim_spaces_apply:nN} \Arg{token list} \meta{function} +% \end{syntax} +% Removes any leading and trailing explicit space characters (explicit +% tokens with character code~$32$ and category code~$10$) from the +% \meta{token list} and passes the result to the \meta{function} as an +% \texttt{n}-type argument. +% \end{function} +% % \begin{function}[added = 2011-07-09] % { % \tl_trim_spaces:N, \tl_trim_spaces:c, @@ -1079,22 +1091,6 @@ % code and so should only be used for short-term storage. % \end{variable} % -% \section{Internal functions} -% -% \begin{function}{\__tl_trim_spaces:nn} -% \begin{syntax} -% \cs{__tl_trim_spaces:nn} |{ \q_mark| \meta{token list} |}| \Arg{continuation} -% \end{syntax} -% This function removes all leading and trailing explicit space -% characters from the \meta{token list}, and expands to the -% \meta{continuation}, followed by a brace group containing -% \cs{use_none:n} \cs{q_mark} \meta{trimmed token list}. For -% instance, \cs{tl_trim_spaces:n} is implemented by taking the -% \meta{continuation} to be \cs{exp_not:o}, and the \texttt{o}-type -% expansion removes the \cs{q_mark}. This function is also used in -% \pkg{l3clist} and \pkg{l3candidates}. -% \end{function} -% % \end{documentation} % % \begin{implementation} @@ -1121,7 +1117,7 @@ % \begin{macrocode} \cs_new_protected:Npn \tl_new:N #1 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \cs_gset_eq:NN #1 \c_empty_tl } \cs_generate_variant:Nn \tl_new:N { c } @@ -1134,13 +1130,13 @@ \__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN c #1 } { } \cs_new_protected:Npn \tl_const:Nn #1#2 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \cs_gset_nopar:Npx #1 { \exp_not:n {#2} } } \__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN c #1 } { } \cs_new_protected:Npn \tl_const:Nx #1#2 { - \__chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #1 \cs_gset_nopar:Npx #1 {#2} } \cs_generate_variant:Nn \tl_const:Nn { c } @@ -1183,23 +1179,25 @@ % For setting token list variables equal to each other. When checking % is turned on, make sure both variables exist. % \begin{macrocode} -\tex_ifodd:D \l@expl@enable@debug@bool - \cs_new_protected:Npn \tl_set_eq:NN #1#2 - { - \__kernel_chk_var_local:N #1 - \__kernel_chk_var_exist:N #2 - \cs_set_eq:NN #1 #2 - } - \cs_new_protected:Npn \tl_gset_eq:NN #1#2 - { - \__kernel_chk_var_global:N #1 - \__kernel_chk_var_exist:N #2 - \cs_gset_eq:NN #1 #2 - } -\else: - \cs_new_eq:NN \tl_set_eq:NN \cs_set_eq:NN - \cs_new_eq:NN \tl_gset_eq:NN \cs_gset_eq:NN -\fi: +\__kernel_if_debug:TF + { + \cs_new_protected:Npn \tl_set_eq:NN #1#2 + { + \__kernel_chk_var_local:N #1 + \__kernel_chk_var_exist:N #2 + \cs_set_eq:NN #1 #2 + } + \cs_new_protected:Npn \tl_gset_eq:NN #1#2 + { + \__kernel_chk_var_global:N #1 + \__kernel_chk_var_exist:N #2 + \cs_gset_eq:NN #1 #2 + } + } + { + \cs_new_eq:NN \tl_set_eq:NN \cs_set_eq:NN + \cs_new_eq:NN \tl_gset_eq:NN \cs_gset_eq:NN + } \cs_generate_variant:Nn \tl_set_eq:NN { cN, Nc, cc } \cs_generate_variant:Nn \tl_gset_eq:NN { cN, Nc, cc } % \end{macrocode} @@ -1491,7 +1489,8 @@ } { \group_begin: - \exp_args:No \etex_everyeof:D { \c_@@_rescan_marker_tl \exp_not:N } + \exp_args:No \etex_everyeof:D + { \c_@@_rescan_marker_tl \exp_not:N } \int_compare:nNnT \tex_endlinechar:D = { 32 } { \int_set:Nn \tex_endlinechar:D { -1 } } \tex_newlinechar:D \tex_endlinechar:D @@ -1636,7 +1635,7 @@ \int_compare:nNnT { \char_value_catcode:n - { \exp_last_unbraced:Nf ` \str_head:n {#2} ~ } + { \exp_last_unbraced:Nf ` { \str_head:n {#2} } ~ } } = { 10 } { ~ } \exp_after:wN \@@_rescan:w @@ -1783,9 +1782,12 @@ } % \end{macrocode} % The auxiliary \cs{@@_replace_auxii:nNNNnn} receives the following -% arguments: \Arg{delimiter} -% \meta{function} \meta{assignment} \meta{tl~var} \Arg{pattern} -% \Arg{replacement}. All of its work is done between +% arguments: +% \begin{quote} +% \Arg{delimiter} \meta{function} \meta{assignment} \\ +% \meta{tl~var} \Arg{pattern} \Arg{replacement} +% \end{quote} +% All of its work is done between % \cs{group_align_safe_begin:} and \cs{group_align_safe_end:} to avoid % issues in alignments. It does the actual replacement within % |#3|~|#4|~|{...}|, an \texttt{x}-expanding \meta{assignment}~|#3| to @@ -1960,13 +1962,11 @@ % The test for emptiness is based on \cs{tl_if_empty:nTF}, but % the expansion is hard-coded for efficiency, as this auxiliary % function is used in many places. -% Note that this works because \cs{etex_detokenize:D} expands tokens -% that follow until reading a catcode $1$ (begin-group) token. % \begin{macrocode} \cs_new:Npn \@@_if_empty_return:o #1 { \exp_after:wN \if_meaning:w \exp_after:wN \q_nil - \etex_detokenize:D \exp_after:wN {#1} \q_nil + \__kernel_tl_to_str:w \exp_after:wN {#1} \q_nil \prg_return_true: \else: \prg_return_false: @@ -2067,23 +2067,20 @@ % up to be expandable and to check the value exactly. The question % mark prevents the auxiliary from losing braces. % \begin{macrocode} -\use:x +\cs_set_protected:Npn \@@_tmp:w #1 { - \prg_new_conditional:Npnn \exp_not:N \tl_if_novalue:n ##1 + \prg_new_conditional:Npnn \tl_if_novalue:n ##1 { p , T , F , TF } { - \exp_not:N \str_if_eq:onTF - { - \exp_not:N \@@_if_novalue:w ? ##1 { } - \c_novalue_tl - } - { ? { } \c_novalue_tl } - { \exp_not:N \prg_return_true: } - { \exp_not:N \prg_return_false: } + \str_if_eq:onTF + { \@@_if_novalue:w ? ##1 { } #1 } + { ? { } #1 } + { \prg_return_true: } + { \prg_return_false: } } - \cs_new:Npn \exp_not:N \@@_if_novalue:w ##1 \c_novalue_tl - {##1} + \cs_new:Npn \@@_if_novalue:w ##1 #1 {##1} } +\exp_args:No \@@_tmp:w { \c_novalue_tl } % \end{macrocode} % \end{macro} % \end{macro} @@ -2112,15 +2109,15 @@ % |#1| has a single item, the token is~|^| and the catcode test % yields \texttt{true}. Otherwise, it is one of the characters % resulting from \cs{tl_to_str:n}, and the catcode test yields -% \texttt{false}. Note that \cs{if_catcode:w} takes care of the -% expansions, and that \cs{tl_to_str:n} (the \tn{detokenize} -% primitive) actually expands tokens until finding a begin-group -% token. +% \texttt{false}. Note that \cs{if_catcode:w} and +% \cs{__kernel_tl_to_str:w} are primitives that take care of +% expansion. % \begin{macrocode} \prg_new_conditional:Npnn \tl_if_single:n #1 { p , T , F , TF } { \if_catcode:w ^ \exp_after:wN \@@_if_single:nnw - \tl_to_str:n \exp_after:wN { \use_none:nn #1 ?? } ^ ? \q_stop + \__kernel_tl_to_str:w + \exp_after:wN { \use_none:nn #1 ?? } ^ ? \q_stop \prg_return_true: \else: \prg_return_false: @@ -2134,7 +2131,6 @@ % \begin{macro}[EXP, noTF]{\tl_case:Nn, \tl_case:cn} % \begin{macro}[EXP]{\@@_case:nnTF} % \begin{macro}[EXP]{\@@_case:Nw} -% \begin{macro}[EXP]{\__prg_case_end:nw} % \begin{macro}[EXP]{\@@_case_end:nw} % The aim here is to allow the case statement to be evaluated % using a known number of expansion steps (two), and without @@ -2187,15 +2183,13 @@ % the first \cs{q_mark} and so |#4| is the \texttt{false} code (the % \texttt{true} code is mopped up by |#3|). % \begin{macrocode} -\cs_new:Npn \__prg_case_end:nw #1#2#3 \q_mark #4#5 \q_stop +\cs_new:Npn \@@_case_end:nw #1#2#3 \q_mark #4#5 \q_stop { \exp_end: #1 #4 } -\cs_new_eq:NN \@@_case_end:nw \__prg_case_end:nw % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} % % \subsection{Mapping to token lists} % @@ -2210,13 +2204,13 @@ { \@@_map_function:Nn #2 #1 \q_recursion_tail - \__prg_break_point:Nn \tl_map_break: { } + \prg_break_point:Nn \tl_map_break: { } } \cs_new:Npn \tl_map_function:NN { \exp_args:No \tl_map_function:nN } \cs_new:Npn \@@_map_function:Nn #1#2 { - \__quark_if_recursion_tail_break:nN {#2} \tl_map_break: + \quark_if_recursion_tail_break:nN {#2} \tl_map_break: #1 {#2} \@@_map_function:Nn #1 } \cs_generate_variant:Nn \tl_map_function:NN { c } @@ -2228,19 +2222,20 @@ % \begin{macro}{\tl_map_inline:nn} % \begin{macro}{\tl_map_inline:Nn, \tl_map_inline:cn} % The inline functions are straight forward by now. We use a little -% trick with the counter \cs{g__prg_map_int} to make +% trick with the counter \cs{g__kernel_prg_map_int} to make % them nestable. We can also make use of \cs{@@_map_function:Nn} % from before. % \begin{macrocode} \cs_new_protected:Npn \tl_map_inline:nn #1#2 { - \int_gincr:N \g__prg_map_int + \int_gincr:N \g__kernel_prg_map_int \cs_gset_protected:cpn - { __prg_map_ \int_use:N \g__prg_map_int :w } ##1 {#2} + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1 {#2} \exp_args:Nc \@@_map_function:Nn - { __prg_map_ \int_use:N \g__prg_map_int :w } + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } #1 \q_recursion_tail - \__prg_break_point:Nn \tl_map_break: { \int_gdecr:N \g__prg_map_int } + \prg_break_point:Nn \tl_map_break: + { \int_gdecr:N \g__kernel_prg_map_int } } \cs_new_protected:Npn \tl_map_inline:Nn { \exp_args:No \tl_map_inline:nn } @@ -2260,14 +2255,14 @@ { \@@_map_variable:Nnn #2 {#3} #1 \q_recursion_tail - \__prg_break_point:Nn \tl_map_break: { } + \prg_break_point:Nn \tl_map_break: { } } \cs_new_protected:Npn \tl_map_variable:NNn { \exp_args:No \tl_map_variable:nNn } \cs_new_protected:Npn \@@_map_variable:Nnn #1#2#3 { \tl_set:Nn #1 {#3} - \__quark_if_recursion_tail_break:NN #1 \tl_map_break: + \quark_if_recursion_tail_break:NN #1 \tl_map_break: \use:n {#2} \@@_map_variable:Nnn #1 {#2} } @@ -2279,12 +2274,12 @@ % % \begin{macro}{\tl_map_break:} % \begin{macro}{\tl_map_break:n} -% The break statements use the general \cs{__prg_map_break:Nn}. +% The break statements use the general \cs{prg_map_break:Nn}. % \begin{macrocode} \cs_new:Npn \tl_map_break: - { \__prg_map_break:Nn \tl_map_break: { } } + { \prg_map_break:Nn \tl_map_break: { } } \cs_new:Npn \tl_map_break:n - { \__prg_map_break:Nn \tl_map_break: } + { \prg_map_break:Nn \tl_map_break: } % \end{macrocode} % \end{macro} % \end{macro} @@ -2302,7 +2297,7 @@ % These functions return the replacement text of a token list as a % string. % \begin{macrocode} -\cs_new:Npn \tl_to_str:N #1 { \etex_detokenize:D \exp_after:wN {#1} } +\cs_new:Npn \tl_to_str:N #1 { \__kernel_tl_to_str:w \exp_after:wN {#1} } \cs_generate_variant:Nn \tl_to_str:N { c } % \end{macrocode} % \end{macro} @@ -2381,6 +2376,7 @@ % \end{macro} % % \begin{macro}{\tl_trim_spaces:n, \tl_trim_spaces:o} +% \begin{macro}{\tl_trim_spaces_apply:nN, \tl_trim_spaces_apply:oN} % \begin{macro} % { % \tl_trim_spaces:N, \tl_trim_spaces:c, @@ -2397,6 +2393,9 @@ \cs_new:Npn \tl_trim_spaces:n #1 { \@@_trim_spaces:nn { \q_mark #1 } \exp_not:o } \cs_generate_variant:Nn \tl_trim_spaces:n { o } +\cs_new:Npn \tl_trim_spaces_apply:nN #1#2 + { \@@_trim_spaces:nn { \q_mark #1 } { \exp_args:No #2 } } +\cs_generate_variant:Nn \tl_trim_spaces_apply:nN { o } \cs_new_protected:Npn \tl_trim_spaces:N #1 { \tl_set:Nx #1 { \exp_args:No \tl_trim_spaces:n {#1} } } \cs_new_protected:Npn \tl_gtrim_spaces:N #1 @@ -2469,6 +2468,7 @@ % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro} % {\tl_sort:Nn, \tl_sort:cn, \tl_gsort:Nn, \tl_gsort:cn, \tl_sort:nN} @@ -2478,12 +2478,16 @@ % \subsection{Token by token changes} % % \begin{variable}{\q_@@_act_mark, \q_@@_act_stop} -% The \cs{tl_act} functions may be applied to any token list. +% The \cs[no-index]{@@_act_\ldots{}} functions may be applied to any token list. % Hence, we use two private quarks, to allow any token, even quarks, % in the token list. % Only \cs{q_@@_act_mark} and \cs{q_@@_act_stop} may not appear -% in the token lists manipulated by \cs{@@_act:NNNnn} functions. The quarks -% are effectively defined in \pkg{l3quark}. +% in the token lists manipulated by \cs{@@_act:NNNnn} functions. +% No quark module yet, so do things by hand. +% \begin{macrocode} +\cs_new_nopar:Npn \q_@@_act_mark { \q_@@_act_mark } +\cs_new_nopar:Npn \q_@@_act_stop { \q_@@_act_stop } +% \end{macrocode} % \end{variable} % % \begin{macro}[EXP]{\@@_act:NNNnn} @@ -2588,7 +2592,7 @@ % \begin{macrocode} \cs_new:Npn \tl_reverse:n #1 { - \etex_unexpanded:D \exp_after:wN + \__kernel_exp_not:w \exp_after:wN { \exp:w \@@_act:NNNnn @@ -2645,7 +2649,7 @@ % \begin{macrocode} \cs_new:Npn \tl_head:n #1 { - \etex_unexpanded:D + \__kernel_exp_not:w \if_false: { \fi: \@@_head_auxi:nw #1 { } \q_stop } } \cs_new:Npn \@@_head_auxi:nw #1#2 \q_stop @@ -2656,7 +2660,7 @@ \cs_new:Npn \@@_head_auxii:n #1 { \exp_after:wN \if_meaning:w \exp_after:wN \q_nil - \tl_to_str:n \exp_after:wN { \use_none:n #1 } \q_nil + \__kernel_tl_to_str:w \exp_after:wN { \use_none:n #1 } \q_nil \exp_after:wN \use_i:nn \else: \exp_after:wN \use_ii:nn @@ -2685,7 +2689,7 @@ % \begin{macrocode} \cs_new:Npn \tl_tail:n #1 { - \etex_unexpanded:D + \__kernel_exp_not:w \tl_if_blank:nTF {#1} { { } } { \exp_after:wN { \use_none:n #1 } } @@ -2928,7 +2932,7 @@ { \exp_args:Nf \@@_item_aux:nn { \int_eval:n {#2} } {#1} } #1 \q_recursion_tail - \__prg_break_point: + \prg_break_point: } \cs_new:Npn \@@_item_aux:nn #1#2 { @@ -2938,9 +2942,9 @@ } \cs_new:Npn \@@_item:nn #1#2 { - \__quark_if_recursion_tail_break:nN {#2} \__prg_break: + \quark_if_recursion_tail_break:nN {#2} \prg_break: \int_compare:nNnTF {#1} = 1 - { \__prg_break:n { \exp_not:n {#2} } } + { \prg_break:n { \exp_not:n {#2} } } { \exp_args:Nf \@@_item:nn { \int_eval:n { #1 - 1 } } } } \cs_new:Npn \tl_item:Nn { \exp_args:No \tl_item:nn } @@ -2961,7 +2965,7 @@ \cs_generate_variant:Nn \tl_log:N { c } \cs_new_protected:Npn \@@_show:NN #1#2 { - \__kernel_check_defined:NT #2 + \__kernel_chk_defined:NT #2 { \exp_args:Nx #1 { \token_to_str:N #2 = \exp_not:o {#2} } } } % \end{macrocode} @@ -2980,7 +2984,7 @@ % of all these manipulations is displayed to the terminal using % \cs{etex_showtokens:D} and an odd \cs{exp_after:wN} which expand the % closing brace to improve the output slightly. The calls to -% \cs{__iow_with:Nnn} ensure that the \tn{newlinechar} is set to~$10$ +% \cs{__kernel_iow_with:Nnn} ensure that the \tn{newlinechar} is set to~$10$ % so that the \cs{iow_newline:} inserted by the line-wrapping code % are correctly recognized by \TeX{}, and that \tn{errorcontextlines} % is $-1$ to avoid printing irrelevant context. @@ -2990,9 +2994,9 @@ \cs_new_protected:Npn \@@_show:n #1 { \tl_set:Nf \l_@@_internal_a_tl { \@@_show:w #1 \q_stop } - \__iow_with:Nnn \tex_newlinechar:D { 10 } + \__kernel_iow_with:Nnn \tex_newlinechar:D { 10 } { - \__iow_with:Nnn \tex_errorcontextlines:D { -1 } + \__kernel_iow_with:Nnn \tex_errorcontextlines:D { -1 } { \etex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN { \exp_after:wN \l_@@_internal_a_tl } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx index 5bf97da8f8a..cc091b65559 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx @@ -12,7 +12,6 @@ % This file is part of the "l3kernel bundle" (The Work in LPPL) % and all files in that bundle must be distributed together. % -%=[] % ----------------------------------------------------------------------- % % The development version of the bundle can be found at @@ -42,7 +41,7 @@ % }^^A % } % -% \date{Released 2018/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -122,7 +121,8 @@ % be an active character. % \end{function} % -% \begin{function}[EXP, added = 2015-09-09]{\char_generate:nn} +% \begin{function}[EXP, added = 2015-09-09, updated = 2018-04-19] +% {\char_generate:nn} % \begin{syntax} % \cs{char_generate:nn} \Arg{charcode} \Arg{catcode} % \end{syntax} @@ -139,12 +139,14 @@ % \item $8$ (math subscript) % \item $11$ (letter) % \item $12$ (other) +% \item $13$ (active) (not \XeTeX{}) % \end{itemize} % and other values raise an error. % % The \meta{charcode} may be any one valid for the engine in use. Note % however that for \XeTeX{} releases prior to 0.99992 only the 8-bit -% range ($0$ to $255$) is accepted due to engine limitations. +% range ($0$ to $255$) is accepted due to engine limitations. Note also +% that \XeTeX{} cannot currently generate active character tokens. % \end{function} % % \begin{variable}[added = 2011-09-05]{\c_catcode_other_space_tl} @@ -443,6 +445,10 @@ % as |macro|s. % \begin{texnote} % This is the \TeX{} primitive \tn{meaning}. +% The \meta{token} can thus be an explicit space tokens or an +% explicit begin-group or end-group character token (|{|~or~|}| when +% normal \TeX{} category codes apply) even though these are not +% valid \texttt{N}-type arguments. % \end{texnote} % \end{function} % @@ -457,6 +463,10 @@ % \meta{token}). This function requires only a single expansion. % \begin{texnote} % \cs{token_to_str:N} is the \TeX{} primitive \tn{string} renamed. +% The \meta{token} can thus be an explicit space tokens or an +% explicit begin-group or end-group character token (|{|~or~|}| when +% normal \TeX{} category codes apply) even though these are not +% valid \texttt{N}-type arguments. % \end{texnote} % \end{function} % @@ -1019,9 +1029,9 @@ % expandable) results in an internal token, displayed (temporarily) % as \cs{notexpanded: \meta{token}}, whose shape coincides with the % \meta{token} and whose meaning differs from \tn{relax}. -% \item An |\outer endtemplate:| (expanding to another internal token, -% |end of alignment template|) can be encountered when peeking ahead -% at the next token. +% \item An |\outer endtemplate:| can be encountered when peeking ahead +% at the next token; this expands to another internal token, +% |end of alignment template|. % \item Tricky programming might access a frozen |\endwrite|. % \item Some frozen tokens can only be accessed in interactive % sessions: |\cr|, |\right|, |\endgroup|, |\fi|, |\inaccessible|. @@ -1095,19 +1105,6 @@ % single tokens \enquote{N-type}, as they are suitable to be used as an % argument for a function with the signature~\texttt{:N}. % -% \section{Internal functions} -% -% \begin{function}[EXP, added = 2016-03-25]{\__char_generate:nn} -% \begin{syntax} -% \cs{__char_generate:nn} \Arg{charcode} \Arg{catcode} -% \end{syntax} -% This function is identical in operation to the public -% \cs{char_generate:nn} but omits various sanity tests. In particular, this -% means it is used in certain places where engine variations need to be -% accounted for by the kernel. The \meta{catcode} must give an explicit -% integer when expanded (and must not absorb a space for instance). -% \end{function} -% % \end{documentation} % % \begin{implementation} @@ -1130,9 +1127,9 @@ % Simple wrappers around the primitives. % \begin{macrocode} \cs_new_protected:Npn \char_set_catcode:nn #1#2 - { \tex_catcode:D \__int_eval:n {#1} = \__int_eval:n {#2} } + { \tex_catcode:D \int_eval:n {#1} = \int_eval:n {#2} \exp_stop_f: } \cs_new:Npn \char_value_catcode:n #1 - { \tex_the:D \tex_catcode:D \__int_eval:n {#1} } + { \tex_the:D \tex_catcode:D \int_eval:n {#1} \exp_stop_f: } \cs_new_protected:Npn \char_show_value_catcode:n #1 { \exp_args:Nf \tl_show:n { \char_value_catcode:n {#1} } } % \end{macrocode} @@ -1265,27 +1262,27 @@ % Pretty repetitive, but necessary! % \begin{macrocode} \cs_new_protected:Npn \char_set_mathcode:nn #1#2 - { \tex_mathcode:D \__int_eval:n {#1} = \__int_eval:n {#2} } + { \tex_mathcode:D \int_eval:n {#1} = \int_eval:n {#2} \exp_stop_f: } \cs_new:Npn \char_value_mathcode:n #1 - { \tex_the:D \tex_mathcode:D \__int_eval:n {#1} } + { \tex_the:D \tex_mathcode:D \int_eval:n {#1} \exp_stop_f: } \cs_new_protected:Npn \char_show_value_mathcode:n #1 { \exp_args:Nf \tl_show:n { \char_value_mathcode:n {#1} } } \cs_new_protected:Npn \char_set_lccode:nn #1#2 - { \tex_lccode:D \__int_eval:n {#1} = \__int_eval:n {#2} } + { \tex_lccode:D \int_eval:n {#1} = \int_eval:n {#2} \exp_stop_f: } \cs_new:Npn \char_value_lccode:n #1 - { \tex_the:D \tex_lccode:D \__int_eval:n {#1} } + { \tex_the:D \tex_lccode:D \int_eval:n {#1} \exp_stop_f: } \cs_new_protected:Npn \char_show_value_lccode:n #1 { \exp_args:Nf \tl_show:n { \char_value_lccode:n {#1} } } \cs_new_protected:Npn \char_set_uccode:nn #1#2 - { \tex_uccode:D \__int_eval:n {#1} = \__int_eval:n {#2} } + { \tex_uccode:D \int_eval:n {#1} = \int_eval:n {#2} \exp_stop_f: } \cs_new:Npn \char_value_uccode:n #1 - { \tex_the:D \tex_uccode:D \__int_eval:n {#1} } + { \tex_the:D \tex_uccode:D \int_eval:n {#1} \exp_stop_f: } \cs_new_protected:Npn \char_show_value_uccode:n #1 { \exp_args:Nf \tl_show:n { \char_value_uccode:n {#1} } } \cs_new_protected:Npn \char_set_sfcode:nn #1#2 - { \tex_sfcode:D \__int_eval:n {#1} = \__int_eval:n {#2} } + { \tex_sfcode:D \int_eval:n {#1} = \int_eval:n {#2} \exp_stop_f: } \cs_new:Npn \char_value_sfcode:n #1 - { \tex_the:D \tex_sfcode:D \__int_eval:n {#1} } + { \tex_the:D \tex_sfcode:D \int_eval:n {#1} \exp_stop_f: } \cs_new_protected:Npn \char_show_value_sfcode:n #1 { \exp_args:Nf \tl_show:n { \char_value_sfcode:n {#1} } } % \end{macrocode} @@ -1355,12 +1352,18 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_int_to_roman:w} +% For efficiency in 8-bit engines, we use the faster primitive approach +% to making roman numerals. +% \begin{macrocode} +\cs_new_eq:NN \@@_int_to_roman:w \tex_romannumeral:D +% \end{macrocode} +% \end{macro} +% % \begin{macro}[EXP]{\char_generate:nn} -% \begin{macro}[EXP]{\__char_generate:nn} % \begin{macro}[EXP]{\@@_generate_aux:nn} -% \begin{macro}[EXP]{\@@_generate_aux:nnw} +% \begin{macro}[EXP]{\@@_generate_aux:nnw, \@@_generate_auxii:nnw} % \begin{variable}{\l_@@_tmp_tl} -% \begin{variable}{\c_@@_max_int} % \begin{macro}[EXP]{\@@_generate_invalid_catcode:} % The aim here is to generate characters of (broadly) arbitrary category % code. Where possible, that is done using engine support (\XeTeX{}, @@ -1368,57 +1371,43 @@ % the interface layer, turn the two arguments into integers up-front so % this is only done once. % \begin{macrocode} -\__kernel_patch_args:nNNpn { { \__int_eval:n {#1} } { \__int_eval:n {#2} } } \cs_new:Npn \char_generate:nn #1#2 { \exp:w \exp_after:wN \@@_generate_aux:w - \__int_value:w \__int_eval:w #1 \exp_after:wN ; - \__int_value:w \__int_eval:w #2 ; - } -\cs_new:Npn \__char_generate:nn #1#2 - { - \exp:w \exp_after:wN - \@@_generate_aux:nnw \exp_after:wN - { \__int_value:w \__int_eval:w #1 } {#2} \exp_end: + \int_value:w \int_eval:n {#1} \exp_after:wN ; + \int_value:w \int_eval:n {#2} ; } % \end{macrocode} % Before doing any actual conversion, first some special case filtering. -% The \tn{Ucharcat} primitive cannot make active chars, so that is turned -% off here: if the primitive gets altered then the code is already in -% place for 8-bit engines and will kick in for \LuaTeX{} too. Spaces -% are also banned here as \LuaTeX{} emulation only makes normal (charcode -% $32$ spaces. However, |^^@| is filtered out separately as that can't be +% Spaces are out here as \LuaTeX{} emulation only makes normal (charcode +% $32$ spaces). However, |^^@| is filtered out separately as that can't be % done with macro emulation either, so is flagged up separately. That % done, hand off to the engine-dependent part. % \begin{macrocode} \cs_new:Npn \@@_generate_aux:w #1 ; #2 ; { - \if_int_compare:w #2 = 13 \exp_stop_f: - \__kernel_msg_expandable_error:nn { kernel } { char-active } + \if_int_compare:w #2 = 10 \exp_stop_f: + \if_int_compare:w #1 = 0 \exp_stop_f: + \__kernel_msg_expandable_error:nn { kernel } { char-null-space } + \else: + \__kernel_msg_expandable_error:nn { kernel } { char-space } + \fi: \else: - \if_int_compare:w #2 = 10 \exp_stop_f: - \if_int_compare:w #1 = 0 \exp_stop_f: - \__kernel_msg_expandable_error:nn { kernel } { char-null-space } - \else: - \__kernel_msg_expandable_error:nn { kernel } { char-space } - \fi: + \if_int_odd:w 0 + \if_int_compare:w #2 < 1 \exp_stop_f: 1 \fi: + \if_int_compare:w #2 = 5 \exp_stop_f: 1 \fi: + \if_int_compare:w #2 = 9 \exp_stop_f: 1 \fi: + \if_int_compare:w #2 > 13 \exp_stop_f: 1 \fi: \exp_stop_f: + \__kernel_msg_expandable_error:nn { kernel } + { char-invalid-catcode } \else: \if_int_odd:w 0 - \if_int_compare:w #2 < 1 \exp_stop_f: 1 \fi: - \if_int_compare:w #2 = 5 \exp_stop_f: 1 \fi: - \if_int_compare:w #2 = 9 \exp_stop_f: 1 \fi: - \if_int_compare:w #2 > 13 \exp_stop_f: 1 \fi: \exp_stop_f: + \if_int_compare:w #1 < 0 \exp_stop_f: 1 \fi: + \if_int_compare:w #1 > \c_max_char_int 1 \fi: \exp_stop_f: \__kernel_msg_expandable_error:nn { kernel } - { char-invalid-catcode } + { char-out-of-range } \else: - \if_int_odd:w 0 - \if_int_compare:w #1 < 0 \exp_stop_f: 1 \fi: - \if_int_compare:w #1 > \c_@@_max_int 1 \fi: \exp_stop_f: - \__kernel_msg_expandable_error:nn { kernel } - { char-out-of-range } - \else: - \@@_generate_aux:nnw {#1} {#2} - \fi: + \@@_generate_aux:nnw {#1} {#2} \fi: \fi: \fi: @@ -1432,6 +1421,9 @@ % out here using a primitive-based boolean expression for speed. % The final level is the basic definition at the engine level: the arguments % here are integers so there is no need to worry about them too much. +% At present \XeTeX{} cannot generate active characters so we filter that: +% at some future stage that may change: the slightly odd ordering of +% auxiliaries reflects that. % \begin{macrocode} \group_begin: %<*package> @@ -1440,16 +1432,15 @@ %</package> \char_set_catcode_other:n { 0 } \if_int_odd:w 0 - \cs_if_exist:NT \luatex_directlua:D { 1 } - \cs_if_exist:NT \utex_charcat:D { 1 } \exp_stop_f: - \int_const:Nn \c_@@_max_int { 1114111 } - \cs_if_exist:NTF \luatex_directlua:D + \sys_if_engine_luatex:T { 1 } + \sys_if_engine_xetex:T { 1 } \exp_stop_f: + \sys_if_engine_luatex:TF { \cs_new:Npn \@@_generate_aux:nnw #1#2#3 \exp_end: { #3 - \exp_after:wN \exp_end: - \luatex_directlua:D { l3kernel.charcat(#1, #2) } + \exp_after:wN \exp_after:wN \exp_after:wN \exp_end: + \lua_now_x:n { l3kernel.charcat(#1, #2) } } } { @@ -1457,7 +1448,18 @@ { #3 \exp_after:wN \exp_end: - \utex_charcat:D #1 ~ #2 ~ + \utex_charcat:D #1 \exp_stop_f: #2 \exp_stop_f: + } + \cs_new_eq:NN \@@_generate_auxii:nnw \@@_generate_aux:nnw + \cs_gset:Npn \@@_generate_aux:nnw #1#2#3 \exp_end: + { + #3 + \if_int_compare:w #2 = 13 \exp_stop_f: + \__kernel_msg_expandable_error:nn { kernel } { char-active } + \else: + \@@_generate_auxii:nnw {#1} {#2} + \fi: + \exp_end: } } \else: @@ -1472,7 +1474,6 @@ % To get open/close braces into the list, they are set up using |\if_false:| % pairing and are then |x|-type expanded together into the desired form. % \begin{macrocode} - \int_const:Nn \c_@@_max_int { 255 } \tl_set:Nn \l_@@_tmp_tl { \exp_not:N \or: } \char_set_catcode_group_begin:n { 0 } % { \tl_put_right:Nn \l_@@_tmp_tl { ^^@ \if_false: } } @@ -1493,7 +1494,7 @@ \tl_put_right:Nn \l_@@_tmp_tl { \or: - \etex_unexpanded:D \exp_after:wN + \__kernel_exp_not:w \exp_after:wN { \exp_after:wN ^^@ \exp_after:wN } } \tl_put_right:Nn \l_@@_tmp_tl { \or: } @@ -1533,20 +1534,20 @@ \exp_args:Nx \tex_lowercase:D { \tl_const:Nn - \exp_not:c { c_@@_ \__int_to_roman:w #1 _tl } + \exp_not:c { c_@@_ \@@_int_to_roman:w #1 _tl } { \exp_not:o \l_@@_tmp_tl } } } %<*package> - \int_step_function:nnnN { 0 } { 1 } { 11 } \@@_tmp:n + \int_step_function:nnN { 0 } { 11 } \@@_tmp:n \group_begin: \tl_replace_once:Nnn \l_@@_tmp_tl { ^^@ } { \ERROR } \@@_tmp:n { 12 } \group_end: - \int_step_function:nnnN { 13 } { 1 } { 255 } \@@_tmp:n + \int_step_function:nnN { 13 } { 255 } \@@_tmp:n %</package> %<*initex> - \int_step_function:nnnN { 0 } { 1 } { 255 } \@@_tmp:n + \int_step_function:nnN { 0 } { 255 } \@@_tmp:n %</initex> \cs_new:Npn \@@_generate_aux:nnw #1#2#3 \exp_end: { @@ -1556,7 +1557,7 @@ \exp_after:wN \exp_after:wN \if_case:w #2 \exp_last_unbraced:Nv \exp_stop_f: - { c_@@_ \__int_to_roman:w #1 _tl } + { c_@@_ \@@_int_to_roman:w #1 _tl } \fi: } \fi: @@ -1564,8 +1565,6 @@ % \end{macrocode} % \end{macro} % \end{variable} -% \end{variable} -% \end{macro} % \end{macro} % \end{macro} % \end{macro} @@ -1609,12 +1608,12 @@ % \emph{work} with \cs{cs_new_eq:NN} but that's not really a great idea to % show off: we want people to stick to the defined interfaces and that % includes us.) So that these few odd names go into the log when appropriate -% there is a need to hand-apply the \cs{__chk_if_free_cs:N} check. +% there is a need to hand-apply the \cs{__kernel_chk_if_free_cs:N} check. % \begin{macrocode} \group_begin: - \__chk_if_free_cs:N \c_group_begin_token + \__kernel_chk_if_free_cs:N \c_group_begin_token \tex_global:D \tex_let:D \c_group_begin_token { - \__chk_if_free_cs:N \c_group_end_token + \__kernel_chk_if_free_cs:N \c_group_end_token \tex_global:D \tex_let:D \c_group_end_token } \char_set_catcode_math_toggle:N \* \cs_new_eq:NN \c_math_toggle_token * @@ -1624,7 +1623,7 @@ \cs_new_eq:NN \c_math_superscript_token ^ \char_set_catcode_math_subscript:N \* \cs_new_eq:NN \c_math_subscript_token * - \__chk_if_free_cs:N \c_space_token + \__kernel_chk_if_free_cs:N \c_space_token \use:n { \tex_global:D \tex_let:D \c_space_token = ~ } ~ \cs_new_eq:NN \c_catcode_letter_token a \cs_new_eq:NN \c_catcode_other_token 1 @@ -1860,11 +1859,9 @@ ##1 \tl_to_str:n { ma } ##2 \c_colon_str ##3 \exp_not:N \q_stop } { - \if_int_compare:w \__str_if_eq_x:nn { #2 } { cro } = 0 \exp_stop_f: - \prg_return_true: - \else: - \prg_return_false: - \fi: + \str_if_eq_x:nnTF { #2 } { cro } + { \prg_return_true: } + { \prg_return_false: } } % \end{macrocode} % \end{macro} @@ -1964,7 +1961,7 @@ % function cannot be defined on the fly because tests must remain % expandable): instead the first argument of the auxiliary (plus the % delimiter to avoid complications with trailing spaces) is compared -% using \cs{__str_if_eq_x_return:nn} to the result of applying +% using \cs{str_if_eq_x:nnTF} to the result of applying % \cs{token_to_str:N} to a control sequence. Second, the % \tn{meaning} of primitives such as \tn{dimen} or \tn{dimendef} % starts in the same way as registers such as @@ -2012,7 +2009,7 @@ \exp_not:N \prg_return_false: \exp_not:N \else: } - \exp_not:N \__str_if_eq_x_return:nn + \exp_not:N \str_if_eq_x:nnTF { \exp_not:N \exp_after:wN \exp_not:c { @@_delimit_by_ #2 :w } @@ -2020,6 +2017,8 @@ ? \tl_to_str:n {#2} \exp_not:N \q_stop } { \exp_not:n {#3} } + { \exp_not:N \prg_return_true: } + { \exp_not:N \prg_return_false: } \cs_if_exist:cT { tex_ #2 :D } { \exp_not:N \fi: diff --git a/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx b/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx new file mode 100644 index 00000000000..3006d953d6d --- /dev/null +++ b/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx @@ -0,0 +1,238 @@ +% \iffalse meta-comment +% +%% File: l3unicode.dtx Copyright (C) 2018 The LaTeX3 Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% This file is part of the "l3kernel bundle" (The Work in LPPL) +% and all files in that bundle must be distributed together. +% +% ----------------------------------------------------------------------- +% +% The development version of the bundle can be found at +% +% https://github.com/latex3/latex3 +% +% for those people who are interested. +% +%<*driver> +\documentclass[full,kernel]{l3doc} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% \title{^^A +% The \pkg{l3unicode} package: Unicode support functions^^A +% } +% +% \author{^^A +% The \LaTeX3 Project\thanks +% {^^A +% E-mail: +% \href{mailto:latex-team@latex-project.org} +% {latex-team@latex-project.org}^^A +% }^^A +% } +% +% \date{Released 2018-04-30} +% +% \maketitle +% +% \begin{documentation} +% +% This module provides Unicode-specific functions along with loading data +% from a range of Unicode Consortium files. At present, it provides no +% public functions. +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3unicode} implementation} +% +% \begin{macrocode} +%<*initex|package> +% \end{macrocode} +% +% \begin{macrocode} +%<@@=char> +% \end{macrocode} +% +% Case changing both for strings and \enquote{text} requires data from +% the Unicode Consortium. Some of this is build in to the format (as +% \tn{lccode} and \tn{uccode} values) but this covers only the simple +% one-to-one situations and does not fully handle for example case folding. +% +% As only the data needs to remain at the end of this process, everything +% is set up inside a group. The only thing that is outside is creating a +% stream: they are global anyway and it is best to force a stream for +% all engines. +% \begin{macrocode} +\ior_new:N \g_@@_data_ior +\bool_lazy_or:nnTF { \sys_if_engine_luatex_p: } { \sys_if_engine_xetex_p: } + { + \group_begin: +% \end{macrocode} +% Set up a private copy of the char-generation primitive. +% \begin{macrocode} + \cs_set_eq:NN \@@_generate:w \utex_char:D +% \end{macrocode} +% Parse the main Unicode data file for title case exceptions (the one-to-one +% lower and upper case mappings it contains are all be covered by the \TeX{} +% data). There are no comments in the main data file so this can be done using +% a standard mapping and no checks. +% \begin{macrocode} + \ior_open:Nn \g_@@_data_ior { UnicodeData.txt } + \cs_set_protected:Npn \@@_data_auxi:w + #1 ; #2 ; #3 ; #4 ; #5 ; #6 ; #7 ; #8 ; #9 ; + { \@@_data_auxii:w #1 ; } + \cs_set_protected:Npn \@@_data_auxii:w + #1 ; #2 ; #3 ; #4 ; #5 ; #6 ; #7 \q_stop + { + \tl_if_blank:nF {#7} + { + \str_if_eq:nnF {#5} {#7} + { + \tl_const:cx + { c_@@_mixed_case_ \@@_generate:w "#1 _tl } + { \@@_generate:w "#7 } + } + } + } + \ior_map_inline:Nn \g_@@_data_ior + { + \tl_if_blank:nF {#1} + { \@@_data_auxi:w #1 \q_stop } + } + \ior_close:N \g_@@_data_ior +% \end{macrocode} +% The other data files all use C-style comments so we have to worry about +% |#| tokens (and reading as strings). The set up for case folding is in two +% parts. For the basic (core) mappings, folding is the same as lower casing in +% most positions so only store the differences. For the more complex foldings, +% always store the result, splitting up the two or three code points in the input +% as required. +% \begin{macrocode} + \ior_open:Nn \g_@@_data_ior { CaseFolding.txt } + \cs_set_protected:Npn \@@_data_auxi:w #1 ;~ #2 ;~ #3 ; #4 \q_stop + { + \str_if_eq:nnTF {#2} { C } + { + \int_compare:nNnF + { \char_value_lccode:n {"#1} } = {"#3} + { + \tl_const:cx + { c_@@_fold_case_ \@@_generate:w "#1 _tl } + { \@@_generate:w "#3 } + } + } + { + \str_if_eq:nnT {#2} { F } + { \@@_data_auxii:w #1 ~ #3 ~ \q_stop } + } + } + \cs_set_protected:Npn \@@_data_auxii:w #1 ~ #2 ~ #3 ~ #4 \q_stop + { + \tl_const:cx { c_@@_fold_case_ \@@_generate:w "#1 _tl } + { + \@@_generate:w "#2 \exp_stop_f: + \@@_generate:w "#3 \exp_stop_f: + \tl_if_blank:nF {#4} + { \@@_generate:w "#4 } + } + } + \ior_str_map_inline:Nn \g_@@_data_ior + { + \tl_if_blank:nF {#1} + { + \str_if_eq_x:nnF { \tl_head:n {#1} } { \c_hash_str } + { \@@_data_auxi:w #1 \q_stop } + } + } + \ior_close:N \g_@@_data_ior +% \end{macrocode} +% For upper and lower casing special situations, there is a bit more to +% do as we also have title casing to consider, plus we need to stop part-way +% through the file. +% \begin{macrocode} + \ior_open:Nn \g_@@_data_ior { SpecialCasing.txt } + \cs_set_protected:Npn \@@_data_auxi:w + #1 ;~ #2 ;~ #3 ;~ #4 ; #5 \q_stop + { + \use:n { \@@_data_auxii:w #1 ~ lower ~ #2 ~ } ~ \q_stop + \use:n { \@@_data_auxii:w #1 ~ upper ~ #4 ~ } ~ \q_stop + \str_if_eq:nnF {#3} {#4} + { \use:n { \@@_data_auxii:w #1 ~ mixed ~ #3 ~ } ~ \q_stop } + } + \cs_set_protected:Npn \@@_data_auxii:w + #1 ~ #2 ~ #3 ~ #4 ~ #5 \q_stop + { + \tl_if_empty:nF {#4} + { + \tl_const:cx { c_@@_ #2 _case_ \@@_generate:w "#1 _tl } + { + \@@_generate:w "#3 \exp_stop_f: + \@@_generate:w "#4 \exp_stop_f: + \tl_if_blank:nF {#5} + { \@@_generate:w "#5 } + } + } + } + \ior_str_map_inline:Nn \g_@@_data_ior + { + \tl_if_blank:nF {#1} + { + \str_if_eq_x:nnTF { \tl_head:n {#1} } { \c_hash_str } + { + \str_if_eq_x:nnT + {#1} + { \c_hash_str \c_space_tl Conditional~Mappings } + { \ior_map_break: } + } + { \@@_data_auxi:w #1 \q_stop } + } + } + \ior_close:N \g_@@_data_ior + \group_end: + } +% \end{macrocode} +% For the $8$-bit engines, the above is skipped but there is still some +% set up required. As case changing can only be applied to bytes, and +% they have to be in the ASCII range, we define a series of data stores +% to represent them, and the data are used such that only these are +% ever case-changed. We do open and close one file to force allocation of +% a read: this keeps all engines in line. +% \begin{macrocode} + { + \group_begin: + \cs_set_protected:Npn \@@_tmp:NN #1#2 + { + \quark_if_recursion_tail_stop:N #2 + \tl_const:cn { c_@@_upper_case_ #2 _tl } {#1} + \tl_const:cn { c_@@_lower_case_ #1 _tl } {#2} + \tl_const:cn { c_@@_fold_case_ #1 _tl } {#2} + \@@_tmp:NN + } + \@@_tmp:NN + AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz + ? \q_recursion_tail \q_recursion_stop + \ior_open:Nn \g_@@_data_ior { UnicodeData.txt } + \ior_close:N \g_@@_data_ior + \group_end: + } +% \end{macrocode} +% +% \begin{macrocode} +%</initex|package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex |