diff options
author | Karl Berry <karl@freefriends.org> | 2018-12-28 21:32:14 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2018-12-28 21:32:14 +0000 |
commit | c15aab665004d0395cdf322d9bcb64b36a9a3902 (patch) | |
tree | f8201611324eafb46e053256f94a0a8c0b9bd1cc /Master/texmf-dist/source/latex/unravel | |
parent | b93e30db8606f12389976318678d926f36a32f02 (diff) |
unravel (28dec18)
git-svn-id: svn://tug.org/texlive/trunk@49515 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/unravel')
-rw-r--r-- | Master/texmf-dist/source/latex/unravel/unravel.dtx | 1496 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/unravel/unravel.ins | 2 |
2 files changed, 979 insertions, 519 deletions
diff --git a/Master/texmf-dist/source/latex/unravel/unravel.dtx b/Master/texmf-dist/source/latex/unravel/unravel.dtx index 6572f1ed1ea..8c3b8c23a9f 100644 --- a/Master/texmf-dist/source/latex/unravel/unravel.dtx +++ b/Master/texmf-dist/source/latex/unravel/unravel.dtx @@ -23,9 +23,9 @@ % % \title{The \textsf{unravel} package: \\ % watching TeX digest tokens\thanks{This -% file has version number 0.2e, last revised 2018/04/04.}} +% file has version number 0.2f, last revised 2018/12/28.}} % \author{Bruno Le Floch} -% \date{2018/04/04} +% \date{2018/12/28} % % \maketitle % \tableofcontents @@ -40,6 +40,8 @@ % performing assignments, as well as some simple typesetting commands. % To use this package, one should normally run \TeX{} in a terminal. % +% \subsection{Commands} +% % \begin{function}{\unravel} % \begin{syntax} % \cs{unravel} \oarg{key-value list} \marg{code} @@ -70,6 +72,15 @@ % See \cs{unravel}. % \end{function} % +% \begin{function}{\unravel_get:nnN} +% \begin{syntax} +% \cs{unravel_get:nnN} \Arg{options} \Arg{code} \meta{tl var} +% \end{syntax} +% Performs \cs{unravel:nn} with the \meta{options} and \meta{code} +% then saves the output into the \meta{tl var}. The option +% |mute| is useful in this case. +% \end{function} +% % \begin{function}{\unravel_setup:n} % \begin{syntax} % \cs{unravel_setup:n} \Arg{options} @@ -77,6 +88,8 @@ % See \cs{unravelsetup}. % \end{function} % +% \subsection{Examples} +% % The \pkg{unravel} package is currently based on the behaviour of % \pdfTeX{}, but it should work in all engines supported by \pkg{expl3} % (\pdfTeX{}, \XeTeX{}, \LuaTeX{}, ep\TeX{}, eup\TeX{}) as long as none @@ -132,7 +145,7 @@ % % Given all the work that \pkg{unravel} has to do to emulate \TeX{}, it % is not fast on very large pieces of code. For instance, running it on -% |\documentclass{article}| takes about one minute on my machine, and +% |\documentclass{article}| takes about thirty seconds on my machine, and % finishes after somewhat less than $21000$ steps. % \begin{verbatim} % \RequirePackage{unravel} @@ -148,11 +161,12 @@ % would if your file ended just after |\documentclass{article}|. After % running the above through \pdfTeX{}, one can check that the result is % identical to that without \pkg{unravel}. Note that -% \cs{unravel}|{\usepackage{lipsum}\relax}|, despite taking as many steps -% to complete, is much slower, because \tn{newcommand} uses +% \cs{unravel}|{\usepackage{lipsum}\relax}|, despite taking roughly as many steps +% to complete, is ten times slower, because \tn{newcommand} uses % delimited arguments, which prevent some optimizations that % \pkg{unravel} can otherwise obtain. For comparison, -% |\unravel{\lipsum[1-30]}| also takes $20000$ step. +% |\unravel{\lipsum[1-30]}| also takes $20000$ step and is ten times +% faster than loading the package. % % \subsection{Options} % \label{sec:options} @@ -181,11 +195,31 @@ % part, and the input part. % \end{function} % +% \begin{function}{mute} +% Make none of the steps produce any output, by setting +% |trace-assigns|, |trace-expansion|, |trace-other|, |welcome-message| +% to \texttt{false}. This is only useful with \cs{unravel_get:nnN} or +% when other options change some of these settings. +% \end{function} +% % \begin{function}{number-steps} % Boolean option (default \texttt{true}) determining whether to % number steps. % \end{function} % +% \begin{function}{online} +% Integer option determining where to write the output: terminal and +% log if the option is positive, log only if the option is zero, +% neither if the option is negative. +% \end{function} +% +% \begin{function}{trace-assigns, trace-expansion, trace-other} +% Boolean options (default \texttt{true}) controlling what steps +% produce any output at all. The keys |trace-assigns|, +% |trace-expansion|, |trace-other| control tracing of different types +% of steps. +% \end{function} +% % \begin{function}{welcome-message} % Boolean option (default \texttt{true}) determining whether to % display the welcome message. @@ -198,6 +232,8 @@ % % Differences. % \begin{itemize} +% \item Kerning between letters of a word is omitted, which can lead to +% incorrect widths. % \item Some primitives are not implemented yet: alignments % (\tn{halign}, \tn{valign}, \tn{noalign}, \tn{omit}, \tn{span}, % \tn{cr}, \tn{crcr},~|&|), many math mode primitives, and @@ -229,6 +265,9 @@ % to implement it in a way similar to \TeX{}'s, and as it is most % often used at the very end of files, in a redundant way. % \item \tn{outer} is not supported. +% \item \cs{unravel} cannot be nested. +% \item Control sequences of the form \cs{notexpanded:\ldots{}} are +% reserved for use by \pkg{unravel}. % \end{itemize} % % \subsection{Future perhaps} @@ -329,7 +368,7 @@ % \end{macrocode} % \end{variable} % -% \begin{macro}[int]{\@@_setup_restore:} +% \begin{macro}{\@@_setup_restore:} % Use the token list to restore catcodes to their former values, then % empty the list since there is no catcode to restore anymore. This % mechanism cannot be nested. @@ -342,7 +381,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_setup_save:} +% \begin{macro}{\@@_setup_save:} % \begin{macro}[EXP]{\@@_setup_save_aux:n} % This saves into \cs{l_@@_setup_restore_tl} the current catcodes % (from $0$ to $255$ only), \tn{endlinechar}, \tn{escapechar}, @@ -371,7 +410,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_setup_catcodes:nnn} +% \begin{macro}{\@@_setup_catcodes:nnn} % This sets all characters from |#1| to |#2| (inclusive) to have % catcode |#3|. % \begin{macrocode} @@ -386,7 +425,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_setup_latexe:} +% \begin{macro}{\@@_setup_latexe:} % This saves the catcodes and related parameters, then sets them to % the value they normally have in a \LaTeXe{} package (in particular, % |@| is a letter). @@ -430,7 +469,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_setup_unravel:} +% \begin{macro}{\@@_setup_unravel:} % Catcodes for \pkg{unravel} (in particular, |@| is other, |:| and % |_| are letters, spaces are ignored, |~| is a space). % \begin{macrocode} @@ -488,7 +527,7 @@ % an error. % \begin{macrocode} \RequirePackage{expl3,xparse}[2018/02/21] -\RequirePackage{gtl}[2018/04/04] +\RequirePackage{gtl}[2018/12/28] \csname cs_if_exist:cF\endcsname{str_range:nnn}{\RequirePackage{l3str}} % \end{macrocode} % @@ -506,7 +545,7 @@ {% \csname @@_setup_restore:\endcsname \ProvidesExplPackage - {unravel} {2018/04/04} {0.2e} {Watching TeX digest tokens}% + {unravel} {2018/12/28} {0.2f} {Watching TeX digest tokens}% \csname @@_setup_unravel:\endcsname }% % \end{macrocode} @@ -526,10 +565,10 @@ % code when that is clearer (typically when testing the meaning of % a token against that of a primitive). % \begin{macrocode} -\cs_new_eq:NN \@@_currentgrouptype: \etex_currentgrouptype:D -\cs_new_protected_nopar:Npn \@@_set_escapechar:n +\cs_new_eq:NN \@@_currentgrouptype: \tex_currentgrouptype:D +\cs_new_protected:Npn \@@_set_escapechar:n { \int_set:Nn \tex_escapechar:D } -\cs_new_eq:NN \@@_everyeof:w \etex_everyeof:D +\cs_new_eq:NN \@@_everyeof:w \tex_everyeof:D \cs_new_eq:NN \@@_everypar:w \tex_everypar:D \cs_new_eq:NN \@@_hbox:w \tex_hbox:D \cs_new_eq:NN \@@_mag: \tex_mag:D @@ -539,12 +578,25 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_special_relax:} +% A special marker slightly different from \tn{relax} (its +% \tn{meaning} is \tn{relax} but it differs from \tn{relax} according +% to \tn{ifx}). In the right-hand side of our assignment, +% \cs{@@_special_relax:} could be replaced by any other expandable +% command. +% \begin{macrocode} +\exp_after:wN \cs_new_eq:NN + \exp_after:wN \@@_special_relax: + \exp_not:N \@@_special_relax: +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\c_@@_prompt_ior, \c_@@_noprompt_ior} % These are not quite primitives, but are very low-level % |ior| streams to prompt the user explicitly or not. % \begin{macrocode} -\cs_new_eq:NN \c_@@_prompt_ior \c_sixteen -\cs_new_eq:NN \c_@@_noprompt_ior \c_minus_one +\int_const:Nn \c_@@_prompt_ior { 16 } +\int_const:Nn \c_@@_noprompt_ior { -1 } % \end{macrocode} % \end{macro} % @@ -555,10 +607,8 @@ \cs_generate_variant:Nn \seq_push:Nn { Nf } \cs_generate_variant:Nn \str_head:n { f } \cs_generate_variant:Nn \tl_to_str:n { o } +\cs_generate_variant:Nn \tl_if_eq:nnTF { o } \cs_generate_variant:Nn \tl_if_head_eq_meaning:nNT { V } -\cs_generate_variant:Nn \tl_if_in:nnF { nV } -\cs_generate_variant:Nn \tl_if_in:nnTF { nV } -\cs_generate_variant:Nn \tl_if_in:NnTF { No , NV } \cs_generate_variant:Nn \tl_if_single_token:nT { V } \cs_generate_variant:Nn \gtl_gput_right:Nn { NV } \cs_generate_variant:Nn \ior_str_get:NN { Nc } @@ -572,6 +622,20 @@ \cs_generate_variant:Nn \gtl_gclear_new:N { c } % \end{macrocode} % +% \begin{macro}{\@@_tl_if_in:ooTF} +% Analogue of \cs{tl_if_in:ooTF} but with an extra group because that +% function redefines an auxiliary that may appear in the code being +% debugged (see Github issue |#27|). +% \begin{macrocode} +\cs_new_protected:Npn \@@_tl_if_in:ooTF #1#2#3#4 + { + \group_begin: + \exp_args:Noo \tl_if_in:nnTF {#1} {#2} + { \group_end: #3 } { \group_end: #4 } + } +% \end{macrocode} +% \end{macro} +% % \begin{variable}{\l_@@_exp_tl} % \begin{macro}{\@@_exp_args:Nx, \@@_exp_args:NNx} % Low-level because \cs{exp_args:Nx} redefines an internal @@ -597,7 +661,7 @@ % \begin{macro}{\@@_tmp:w} % Temporary function used to define other functions. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_tmp:w { } +\cs_new_protected:Npn \@@_tmp:w { } % \end{macrocode} % \end{macro} % @@ -626,7 +690,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int, EXP]{\@@_tl_first_int:N} +% \begin{macro}[EXP]{\@@_tl_first_int:N} % \begin{macro}[EXP]{\@@_tl_first_int_aux:Nn} % Function that finds an explicit number in a token list. This is % used for instance when implementing \tn{read}, to find the stream @@ -669,10 +733,10 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_prepare_mag:} +% \begin{macro}{\@@_prepare_mag:} % Used whenever \TeX{} needs the value of \tn{mag}. ^^A todo: move % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_prepare_mag: +\cs_new_protected:Npn \@@_prepare_mag: { \int_compare:nNnT { \g_@@_mag_set_int } > { 0 } { @@ -694,7 +758,7 @@ % % \subsubsection{String helpers} % -% \begin{macro}[int]{\@@_strip_escape:w} +% \begin{macro}{\@@_strip_escape:w} % \begin{macro}{\@@_strip_escape_aux:N, \@@_strip_escape_aux:w} % This is based on the 2013-07-19 (and earlier) version of % \cs{cs_to_str:N}. There are three cases. If the escape character @@ -703,29 +767,29 @@ % character is a space, the charcode test is true, and if there is no % escape charcter, the test is unfinished after |\token_to_str:N \ |. % In both of those cases, \cs{@@_strip_escape_aux:w} inserts -% |-\@@_number:w \fi: \c_zero|. If the escape character was a +% |-\@@_number:w \fi: \c_zero_int|. If the escape character was a % space, the test was true, and \cs{int_value:w} converts -% \cs{c_zero} to~|0|, hence the leading roman numeral expansion +% \cs{c_zero_int} to~|0|, hence the leading roman numeral expansion % removes a space from what follows (it is important that what follows % cannot start with a digit). Otherwise, the test takes~|-| as its % second operand, is false, and the roman numeral expansion only sees -% \cs{c_zero}, thus does not remove anything from what follows. +% \cs{c_zero_int}, thus does not remove anything from what follows. % \begin{macrocode} -\cs_new_nopar:Npn \@@_strip_escape:w +\cs_new:Npn \@@_strip_escape:w { \tex_romannumeral:D \if_charcode:w \token_to_str:N \ \@@_strip_escape_aux:w \fi: \@@_strip_escape_aux:N } -\cs_new:Npn \@@_strip_escape_aux:N #1 { \c_zero } +\cs_new:Npn \@@_strip_escape_aux:N #1 { \c_zero_int } \cs_new:Npn \@@_strip_escape_aux:w #1#2 - { - \@@_number:w #1 \c_zero } + { - \@@_number:w #1 \c_zero_int } % \end{macrocode} % \end{macro} % \end{macro} % % ^^A todo: change approach: this abuses future l3obj. -% \begin{macro}[int,EXP]{\@@_to_str:n} +% \begin{macro}[EXP]{\@@_to_str:n} % \begin{macro}[EXP] % {\@@_to_str_auxi:w, \@@_to_str_auxii:w, \@@_gtl_to_str:n} % Use the type-appropriate conversion to string. @@ -753,7 +817,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_str_truncate_left:nn} +% \begin{macro}{\@@_str_truncate_left:nn} % \begin{macro}{\@@_str_truncate_left_aux:nnn} % Truncate the string |#1| to a maximum of |#2| characters. If it is % longer, replace some characters on the left of the string by @@ -778,7 +842,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_str_truncate_right:nn} +% \begin{macro}{\@@_str_truncate_right:nn} % \begin{macro}{\@@_str_truncate_right_aux:nnn} % Truncate the string |#1| to a maximum of |#2| characters. If it is % longer, replace some characters on the right of the string by @@ -805,7 +869,7 @@ % % \subsubsection{Helpers for control flow} % -% \begin{macro}[int,EXP]{\@@_exit:w, \@@_exit_point:} +% \begin{macro}[EXP]{\@@_exit:w, \@@_exit_point:} % Jump to the very end of this instance of \cs{unravel}. % \begin{macrocode} \cs_new_eq:NN \@@_exit_point: \prg_do_nothing: @@ -813,7 +877,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int,EXP]{\@@_break:w, \@@_break_point:} +% \begin{macro}[EXP]{\@@_break:w, \@@_break_point:} % Useful to jump out of complicated conditionals. % \begin{macrocode} \cs_new_eq:NN \@@_break_point: \prg_do_nothing: @@ -821,7 +885,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_cmd_if_internal:TF} +% \begin{macro}{\@@_cmd_if_internal:TF} % Test whether the \cs{l_@@_head_cmd_int} denotes an ``internal'' % command, between |min_internal| and |max_internal| (see % Section~\ref{sec:numeric-codes}). @@ -844,8 +908,8 @@ % % \subsubsection{Helpers concerning tokens} % -% \begin{macro}[int]{\@@_token_to_char:N} -% \begin{macro}[int]{\@@_meaning_to_char:n, \@@_meaning_to_char:o} +% \begin{macro}{\@@_token_to_char:N} +% \begin{macro}{\@@_meaning_to_char:n, \@@_meaning_to_char:o} % \begin{macro} % {\@@_meaning_to_char_auxi:w, \@@_meaning_to_char_auxii:w} % From the meaning of a character token (with arbitrary character @@ -866,7 +930,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int,EXP,pTF]{\@@_token_if_expandable:N} +% \begin{macro}[EXP,pTF]{\@@_token_if_expandable:N} % We need to cook up our own version of \cs{token_if_expandable:NTF} % because the \pkg{expl3} one does not think that |undefined| is % expandable. @@ -883,7 +947,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int,EXP,pTF]{\@@_token_if_protected:N} +% \begin{macro}[EXP,pTF]{\@@_token_if_protected:N} % Returns \texttt{true} if the token is either not expandable or is a % protected macro. % \begin{macrocode} @@ -905,24 +969,41 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int,TF]{\@@_token_if_definable:N} +% \begin{macro}[TF]{\@@_token_if_active_char:N} +% Lowercase the token after setting its \tn{lccode} (more precisely +% the \tn{lccode} of the first character in its string representation) +% to a known value, then compare the result with that active +% character. +% \begin{macrocode} +\group_begin: + \char_set_catcode_active:n { `Z } + \prg_new_protected_conditional:Npnn \@@_token_if_active_char:N #1 + { TF } + { + \group_begin: + \@@_exp_args:Nx \char_set_lccode:nn + { ` \exp_args:No \str_head:n { \token_to_str:N #1 } } + { ` Z } + \tex_lowercase:D { \tl_if_eq:nnTF {#1} } { Z } + { \group_end: \prg_return_true: } + { \group_end: \prg_return_false: } + } +\group_end: +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[TF]{\@@_token_if_definable:N} % Within a group, set the escape character to a non-space value % (backslash). Convert the token to a string with -% \cs{token_to_str:N}. The result is multiple characters if the -% token is a control sequence, and a single character otherwise (even -% for explicit catcode~$6$ character tokens which would be doubled if -% we used \cs{tl_to_str:n} instead of \cs{token_to_str:N}). Thus +% \cs{token_to_str:N}. The result is multiple characters if the token +% is a control sequence, and a single character otherwise (even for +% explicit catcode~$6$ character tokens which would be doubled if we +% used \cs{tl_to_str:n} instead of \cs{token_to_str:N}). Thus % \cs{str_tail:n} gives a non-empty result exactly for control % sequences. Those are definable (technically, not always: % |\expandafter\font\csname\endcsname=cmr10| -% |\expandafter\def\the\csname\endcsname{}|). For characters, there -% remains to determine if |#1| is an active character. One option -% would be to build the active character with that character code and -% compare them using a delimited-argument test, but that needlessly -% pollutes the hash table in \XeTeX{} (and \LuaTeX{}?) if the -% character was in fact not active. Instead, use the \tn{lowercase} -% primitive to convert the character to a fixed character code~|Z|. -% Compare with an active~|Z|. In all cases, remember to end the +% |\expandafter\def\the\csname\endcsname{}|). For characters just +% check for active characters. In both cases remember to end the % group. % \begin{macrocode} \group_begin: @@ -936,9 +1017,7 @@ { \exp_args:No \str_tail:n { \token_to_str:N #1 } } \tl_if_empty:NTF \l_@@_tmpa_tl { - \exp_args:Nx \char_set_lccode:nn - { ` \str_head:n {#1} } { `Z } - \tex_lowercase:D { \tl_if_eq:nnTF {#1} } { Z } + \@@_token_if_active_char:NTF #1 { \group_end: \prg_return_true: } { \group_end: \prg_return_false: } } @@ -948,7 +1027,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int,TF]{\@@_gtl_if_head_is_definable:N} +% \begin{macro}[TF]{\@@_gtl_if_head_is_definable:N} % Tests if a generalized token list is a single control sequence or a % single active character. First test that it is single, then filter % out the case of (explicit) begin-group, end-group, and blank space @@ -977,7 +1056,7 @@ % % \begin{macro}[EXP]{\@@_prev_input_count:, \@@_prev_input_count_aux:n} % \begin{macrocode} -\cs_new_nopar:Npn \@@_prev_input_count: +\cs_new:Npn \@@_prev_input_count: { \int_eval:n { @@ -1003,30 +1082,30 @@ % } % ^^A todo: doc and add optional sanity checking % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_prev_input_get:N +\cs_new_protected:Npn \@@_prev_input_get:N { \seq_get_right:NN \g_@@_prev_input_seq } -\cs_new_protected_nopar:Npn \@@_prev_input_gpush: +\cs_new_protected:Npn \@@_prev_input_gpush: { \seq_gput_right:Nn \g_@@_prev_input_seq { } } -\cs_new_protected_nopar:Npn \@@_prev_input_gpush:N +\cs_new_protected:Npn \@@_prev_input_gpush:N { \seq_gput_right:NV \g_@@_prev_input_seq } -\cs_new_protected_nopar:Npn \@@_prev_input_gpop:N +\cs_new_protected:Npn \@@_prev_input_gpop:N { \seq_gpop_right:NN \g_@@_prev_input_seq } -\cs_new_protected_nopar:Npn \@@_prev_input_gpush_gtl: +\cs_new_protected:Npn \@@_prev_input_gpush_gtl: { \seq_gput_right:NV \g_@@_prev_input_seq \c_empty_gtl } -\cs_new_protected_nopar:Npn \@@_prev_input_gpush_gtl:N +\cs_new_protected:Npn \@@_prev_input_gpush_gtl:N { \seq_gput_right:NV \g_@@_prev_input_seq } -\cs_new_protected_nopar:Npn \@@_prev_input_gpop_gtl:N +\cs_new_protected:Npn \@@_prev_input_gpop_gtl:N { \seq_gpop_right:NN \g_@@_prev_input_seq } % \end{macrocode} % \end{macro} % -% \begin{macro}[int] +% \begin{macro} % { % \@@_prev_input_silent:n, % \@@_prev_input_silent:V, % \@@_prev_input_silent:x % } -% \begin{macro}[int] +% \begin{macro} % { % \@@_prev_input:n, % \@@_prev_input:V, @@ -1054,7 +1133,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_prev_input_gtl:N} +% \begin{macro}{\@@_prev_input_gtl:N} % \begin{macrocode} \cs_new_protected:Npn \@@_prev_input_gtl:N #1 { @@ -1065,7 +1144,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_prev_input_join_get:nN} +% \begin{macro}{\@@_prev_input_join_get:nN} % \begin{macro}{\@@_join_get_aux:NNN} % Pops the previous-input sequence twice to get some value in % \cs{l_@@_head_tl} and some sign or decimal number in @@ -1077,8 +1156,8 @@ { \int_case:nnF {#1} { - { 2 } { \@@_join_get_aux:NNN \skip_eval:n \etex_glueexpr:D } - { 3 } { \@@_join_get_aux:NNN \muskip_eval:n \etex_muexpr:D } + { 2 } { \@@_join_get_aux:NNN \skip_eval:n \tex_glueexpr:D } + { 3 } { \@@_join_get_aux:NNN \muskip_eval:n \tex_muexpr:D } } { \@@_error:nnnnn { internal } { join-factor } { } { } { } @@ -1113,12 +1192,10 @@ % \end{macrocode} % \end{variable} % -% \begin{variable}{\g_@@_nonstop_int, \g_@@_noise_int} +% \begin{variable}{\g_@@_nonstop_int} % The number of prompts to skip. % \begin{macrocode} \int_new:N \g_@@_nonstop_int -\int_new:N \g_@@_noise_int -\int_gset_eq:NN \g_@@_noise_int \c_one % \end{macrocode} % \end{variable} % @@ -1127,23 +1204,39 @@ % \g_@@_default_explicit_prompt_bool , \g_@@_explicit_prompt_bool , % \g_@@_default_internal_debug_bool , \g_@@_internal_debug_bool , % \g_@@_default_number_steps_bool , \g_@@_number_steps_bool , +% \g_@@_default_online_int , \g_@@_online_int , +% \g_@@_default_trace_assigns_bool , \g_@@_trace_assigns_bool , +% \g_@@_default_trace_expansion_bool , \g_@@_trace_expansion_bool , +% \g_@@_default_trace_other_bool , \g_@@_trace_other_bool , % \g_@@_default_welcome_message_bool , \g_@@_welcome_message_bool , % } % Variables for the options |explicit-prompt|, -% |internal-debug|, |number-steps|. The -% \texttt{default_} booleans store the default value of these +% |internal-debug|, |number-steps|, and so on. The +% \texttt{default_} booleans/integers store the default value of these % options, and are affected by \cs{unravelsetup} or % \cs{unravel_setup:n}. % \begin{macrocode} \bool_new:N \g_@@_default_explicit_prompt_bool \bool_new:N \g_@@_default_internal_debug_bool \bool_new:N \g_@@_default_number_steps_bool -\bool_gset_true:N \g_@@_default_number_steps_bool +\int_new:N \g_@@_default_online_int +\bool_new:N \g_@@_default_trace_assigns_bool +\bool_new:N \g_@@_default_trace_expansion_bool +\bool_new:N \g_@@_default_trace_other_bool \bool_new:N \g_@@_default_welcome_message_bool +\bool_gset_true:N \g_@@_default_number_steps_bool +\int_gset:Nn \g_@@_default_online_int { 1 } +\bool_gset_true:N \g_@@_default_trace_assigns_bool +\bool_gset_true:N \g_@@_default_trace_expansion_bool +\bool_gset_true:N \g_@@_default_trace_other_bool \bool_gset_true:N \g_@@_default_welcome_message_bool \bool_new:N \g_@@_explicit_prompt_bool \bool_new:N \g_@@_internal_debug_bool \bool_new:N \g_@@_number_steps_bool +\int_new:N \g_@@_online_int +\bool_new:N \g_@@_trace_assigns_bool +\bool_new:N \g_@@_trace_expansion_bool +\bool_new:N \g_@@_trace_other_bool \bool_new:N \g_@@_welcome_message_bool % \end{macrocode} % \end{variable} @@ -1278,8 +1371,15 @@ % \end{macrocode} % \end{variable} % -% \begin{variable} -% {\l_@@_tmpa_tl, \l_@@_tmpb_gtl, \g_@@_tmpc_tl, \l_@@_tmpa_seq, \l_@@_unused_gtl} +% \begin{variable}{\l_@@_argi_tl, \l_@@_argii_tl} +% Token list variables used to store first/second arguments. +% \begin{macrocode} +\tl_new:N \l_@@_argi_tl +\tl_new:N \l_@@_argii_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_tmpa_tl, \l_@@_tmpb_gtl, \g_@@_tmpc_tl, \l_@@_tmpa_seq, \l_@@_unused_gtl, \l_@@_tmpb_token} % Temporary storage. The \cs{l_@@_unused_gtl} is only used once, % to ignore some unwanted tokens. % \begin{macrocode} @@ -1288,6 +1388,7 @@ \gtl_new:N \l_@@_tmpb_gtl \tl_new:N \g_@@_tmpc_tl \seq_new:N \l_@@_tmpa_seq +\cs_new_eq:NN \l_@@_tmpb_token ? % \end{macrocode} % \end{variable} % @@ -1306,7 +1407,7 @@ % \end{macrocode} % \end{variable} % -% \begin{macro}[int]{\@@_inaccessible:w} +% \begin{macro}{\@@_inaccessible:w} % \begin{macrocode} \cs_new_eq:NN \@@_inaccessible:w ? % \end{macrocode} @@ -1458,8 +1559,8 @@ % and a character code, to decide what action to perform upon seeing % them. % -% \begin{macro}[int]{\@@_tex_const:nn} -% \begin{macro}[int,EXP]{\@@_tex_use:n} +% \begin{macro}{\@@_tex_const:nn} +% \begin{macro}[EXP]{\@@_tex_use:n} % \begin{macrocode} \cs_new_protected:Npn \@@_tex_const:nn #1#2 { \int_const:cn { c_@@_tex_#1_int } {#2} } @@ -1468,7 +1569,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_tex_primitive:nnn} +% \begin{macro}{\@@_tex_primitive:nnn} % \begin{macrocode} \cs_new_protected:Npn \@@_tex_primitive:nnn #1#2#3 { @@ -1478,11 +1579,11 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_new_tex_cmd:nn, \@@_new_eq_tex_cmd:nn} +% \begin{macro}{\@@_new_tex_cmd:nn, \@@_new_eq_tex_cmd:nn} % \begin{macrocode} \cs_new_protected:Npn \@@_new_tex_cmd:nn #1#2 { - \cs_new_protected_nopar:cpn + \cs_new_protected:cpn { @@_cmd_ \@@_tex_use:n {#1} : } {#2} } \cs_new_protected:Npn \@@_new_eq_tex_cmd:nn #1#2 @@ -1494,11 +1595,11 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_new_tex_expandable:nn} +% \begin{macro}{\@@_new_tex_expandable:nn} % \begin{macrocode} \cs_new_protected:Npn \@@_new_tex_expandable:nn #1#2 { - \cs_new_protected_nopar:cpn + \cs_new_protected:cpn { @@_expandable_ \@@_tex_use:n {#1} : } {#2} } % \end{macrocode} @@ -1644,7 +1745,17 @@ % \item |def_code| and |def_family| is shifted by |cat_code_base=3983|. % \item In \TeX{}, |inputlineno.char=3| and |badness.char=4|. % \end{itemize} +% A special case for \LuaTeX{} deals with the fact that the +% \cs{@@_special_relax:} has a strange meaning \enquote{[unknown command +% code! (0, 1)]}. For instance \tn{expandafter} \tn{show} \tn{noexpand} +% \tn{undefined} shows this. % \begin{macrocode} +\sys_if_engine_luatex:T + { + \@@_tex_primitive:nnn + { \exp_after:wN \use_none:n \token_to_meaning:N \@@_special_relax: } + { relax } { 1 } + } \@@_tex_primitive:nnn { relax } { relax } { 256 } \@@_tex_primitive:nnn { span } { tab_mark } { 256 } \@@_tex_primitive:nnn { cr } { car_ret } { 257 } @@ -2153,7 +2264,8 @@ \@@_tex_primitive:nnn { pdfescapename } { convert } { 14 } \@@_tex_primitive:nnn { leftmarginkern } { convert } { 15 } \@@_tex_primitive:nnn { rightmarginkern } { convert } { 16 } -\@@_tex_primitive:nnn { pdfstrcmp } { convert } { 17 } +\@@_tex_primitive:nnn + { \sys_if_engine_xetex:F { pdf } strcmp } { convert } { 17 } \@@_tex_primitive:nnn { pdfcolorstackinit } { convert } { 18 } \@@_tex_primitive:nnn { pdfescapehex } { convert } { 19 } \@@_tex_primitive:nnn { pdfunescapehex } { convert } { 20 } @@ -2169,6 +2281,16 @@ \@@_tex_primitive:nnn { pdfinsertht } { convert } { 30 } \@@_tex_primitive:nnn { pdfximagebbox } { convert } { 31 } \@@_tex_primitive:nnn { jobname } { convert } { 32 } +\sys_if_engine_luatex:T + { + \@@_tex_primitive:nnn { directlua } { convert } { 33 } + \@@_tex_primitive:nnn { expanded } { convert } { 34 } + \@@_tex_primitive:nnn { luaescapestring } { convert } { 35 } + } +\sys_if_engine_xetex:T + { + \@@_tex_primitive:nnn { Ucharcat } { convert } { 40 } + } \@@_tex_primitive:nnn { the } { the } { 0 } \@@_tex_primitive:nnn { unexpanded } { the } { 1 } \@@_tex_primitive:nnn { detokenize } { the } { 5 } @@ -2198,7 +2320,7 @@ % \cs{l_@@_head_cmd_int} and \cs{l_@@_head_char_int} from % \cs{l_@@_head_token}. % -% \begin{macro}[int]{\@@_get_next:} +% \begin{macro}{\@@_get_next:} % \begin{macro}{\@@_get_next_aux:w} % If the input is empty, forcefully exit. Otherwise, % remove the first token in the input, and store it in @@ -2207,7 +2329,7 @@ % unless it is a begin-group or end-group character, in which case % this token list is emptied. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_get_next: +\cs_new_protected:Npn \@@_get_next: { \@@_input_if_empty:TF { \@@_exit:w } @@ -2218,22 +2340,113 @@ { \tl_set:Nx \l_@@_head_tl { \gtl_head:N \l_@@_head_gtl } + \token_if_eq_meaning:NNT + \l_@@_head_token \@@_special_relax: + \@@_get_next_notexpanded: } { \tl_clear:N \l_@@_head_tl } } } -\cs_new_protected_nopar:Npn \@@_get_next_aux:w +\cs_new_protected:Npn \@@_get_next_aux:w { \cs_set_eq:NN \l_@@_head_token } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_get_token:} +% \begin{macro}{\@@_get_next_notexpanded:} +% \begin{macro}{\@@_notexpanded_test:w, \@@_notexpanded_expand:nN, \@@_notexpanded_expand:NN} +% At this point we have likely encountered a special \tn{relax} marker +% that we use to mark cases where \tn{noexpand} acts on a control +% sequence or an active character. To make sure of that check the +% control sequence has the form \cs{notexpanded:\ldots{}}. Since we +% don't know the escape character we must use \cs{cs_to_str:N}, but +% that function is not meant for active characters and has a runaway +% argument if its argument is a space (active since we know its +% meaning is the special \tn{relax}). To avoid the runaway we include +% an arbitrary delimiter~|Z|. If the token in \cs{l_@@_head_tl} is +% not \cs{notexpanded:\ldots{}} we do nothing. Otherwise +% \cs{@@_notexpanded_expand:n} reconstructs the token that was hit +% with \tn{noexpand} (an active character if the argument is a single +% character) and do the job of \cs{@@_get_next:}, setting +% \cs{l_@@_head_token} to the special \tn{relax} marker for expandable +% commands, as \tn{noexpand} would. +% \begin{macrocode} +\cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_new_protected:Npn \@@_get_next_notexpanded: + { + \tl_if_eq:onTF { \l_@@_head_tl } { \@@_unravel_marker: } + { \@@_get_next_marker: } + { + \@@_exp_args:NNx \use:nn \@@_notexpanded_test:w + { \scan_stop: \exp_after:wN \cs_to_str:N \l_@@_head_tl Z } + \q_mark \@@_notexpanded_expand:n + #1 Z \q_mark \use_none:n + \q_stop + } + } + \cs_new_protected:Npn \@@_notexpanded_test:w + ##1 #1 ##2 Z \q_mark ##3##4 \q_stop + { ##3 {##2} } + } +\exp_args:Nx \@@_tmp:w { \scan_stop: \tl_to_str:n { notexpanded: } } +\group_begin: + \char_set_catcode_active:n { 0 } + \cs_new_protected:Npn \@@_notexpanded_expand:n #1 + { + \@@_exp_args:Nx \tl_if_empty:nTF { \str_tail:n {#1} } + { + \group_begin: + \char_set_lccode:nn { 0 } { `#1 } + \tex_lowercase:D + { + \group_end: + \@@_notexpanded_expand:N ^^@ + } + } + { + \group_begin: \exp_args:NNc \group_end: + \@@_notexpanded_expand:N { \use_none:n #1 } + } + } +\group_end: +\cs_new_protected:Npn \@@_notexpanded_expand:N #1 + { + \gtl_set:Nn \l_@@_head_gtl {#1} + \tl_set:Nn \l_@@_head_tl {#1} + \cs_set_eq:NN \l_@@_head_token \@@_special_relax: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_get_next_marker:} +% This is used to deal with nested unravel. +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_next_marker: + { + \@@_get_next: + \tl_if_eq:onTF \l_@@_head_tl { \@@:nn } + { \@@_error:nxxxx { nested-unravel } { } { } { } { } } + { \@@_error:nxxxx { internal } { marker~unknown } { } { } { } } + \@@_input_gpop_item:NF \l_@@_argi_tl + { \@@_error:nxxxx { internal } { marker~1 } { } { } { } } + \@@_input_gpop_item:NF \l_@@_argii_tl + { \@@_error:nxxxx { internal } { marker~2 } { } { } { } } + \exp_args:Nno \keys_set:nn { unravel } \l_@@_argi_tl + \@@_exp_args:Nx \@@_back_input:n + { \exp_not:N \exp_not:n { \exp_not:o \l_@@_argii_tl } } + \@@_get_next: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_get_token:} % Call \cs{@@_get_next:} to set \cs{l_@@_head_gtl}, \cs{l_@@_head_tl} % and \cs{l_@@_head_token}, then call \cs{@@_set_cmd:} to set % \cs{l_@@_head_cmd_int} and \cs{l_@@_head_char_int}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_get_token: +\cs_new_protected:Npn \@@_get_token: { \@@_get_next: \@@_set_cmd: @@ -2241,7 +2454,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_set_cmd:} +% \begin{macro}{\@@_set_cmd:} % After the call to \cs{@@_get_next:}, we find the command code % \cs{l_@@_head_cmd_int} and the character code % \cs{l_@@_head_char_int}, based only on \cs{l_@@_head_token}. First @@ -2252,7 +2465,7 @@ % (\emph{e.g.}, an expandable \XeTeX{} or \LuaTeX{} primitive % perhaps). Otherwise, it can be a control sequence or a character. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_set_cmd: +\cs_new_protected:Npn \@@_set_cmd: { \@@_set_cmd_aux_meaning: \@@_set_cmd_aux_primitive:oTF { \l_@@_head_meaning_tl } @@ -2282,7 +2495,7 @@ % for macros, for marks, and for that character too. For any % primitive except \tn{nullfont}, this leaves the primitive's name. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_set_cmd_aux_meaning: +\cs_new_protected:Npn \@@_set_cmd_aux_meaning: { \tl_set:Nx \l_@@_head_meaning_tl { @@ -2335,7 +2548,7 @@ % The token is a macro. There is no need to determine whether the % macro is long/outer. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_set_cmd_aux_macro: +\cs_new_protected:Npn \@@_set_cmd_aux_macro: { \int_set:Nn \l_@@_head_cmd_int { \@@_tex_use:n { call } } \int_zero:N \l_@@_head_char_int @@ -2347,7 +2560,7 @@ % Complain about an unknown primitive, and consider it as if it were % \tn{relax}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_set_cmd_aux_unknown: +\cs_new_protected:Npn \@@_set_cmd_aux_unknown: { \exp_last_unbraced:NV \@@_set_cmd_aux_primitive:nn \c_@@_tex_relax_tl @@ -2367,9 +2580,9 @@ % \tn{dimen}, \tn{skip}, \tn{muskip} or \tn{toks} followed by a % decimal number. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_set_cmd_aux_cs: +\cs_new_protected:Npn \@@_set_cmd_aux_cs: { - \tl_if_in:NoTF \l_@@_head_meaning_tl + \@@_tl_if_in:ooTF \l_@@_head_meaning_tl { \tl_to_str:n { elect~font } } { \exp_last_unbraced:NV \@@_set_cmd_aux_primitive:nn @@ -2390,8 +2603,9 @@ % Insert \cs{q_mark} before the first non-letter (in fact, anything % less than~|A|) in the \tn{meaning} by looping one character at a % time (skipping spaces, but there should be none). We expect the -% first part to be |char| or~|mathchar|, or one of |count|, |dimen|, -% |skip|, |muskip|, or |toks|. In the first two cases, the command is +% first part to be |char| or~|mathchar| (or |kchar| in up\TeX{}), +% or one of |count|, |dimen|, +% |skip|, |muskip|, or |toks|. In the first two (three) cases, the command is % |char_given| or |math_given|. It is otherwise identical to the % corresponding primitive (\tn{count} \emph{etc.}). We then keep % track of the associated number (part after \cs{q_mark}) in @@ -2400,7 +2614,7 @@ % \cs{q_mark} is inserted at their end, and is followed by~|+0|, so % nothing breaks. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_set_cmd_aux_numeric: +\cs_new_protected:Npn \@@_set_cmd_aux_numeric: { \tl_set:Nx \l_@@_tmpa_tl { @@ -2423,6 +2637,7 @@ \str_case:nnF {#1} { { char } { \@@_set_cmd_aux_given:n { char_given } } + { kchar } { \@@_set_cmd_aux_given:n { char_given } } { mathchar } { \@@_set_cmd_aux_given:n { math_given } } } { @@ -2452,7 +2667,7 @@ % the character code, there is a need to expand % \cs{@@_token_to_char:N} before placing~|`|. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_set_cmd_aux_char: +\cs_new_protected:Npn \@@_set_cmd_aux_char: { \tl_set:Nx \l_@@_head_meaning_tl { \token_to_meaning:N \l_@@_head_token } @@ -2476,10 +2691,10 @@ % % \subsubsection{Elementary operations} % -% \begin{macro}[int,rEXP]{\@@_input_to_str:} +% \begin{macro}[rEXP]{\@@_input_to_str:} % Map \cs{gtl_to_str:c} through the input stack. % \begin{macrocode} -\cs_new_nopar:Npn \@@_input_to_str: +\cs_new:Npn \@@_input_to_str: { \int_step_function:nnnN \g_@@_input_int { -1 } { 1 } \@@_input_to_str_aux:n @@ -2489,7 +2704,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_input_if_empty:TF} +% \begin{macro}{\@@_input_if_empty:TF} % If the input stack is empty, the input contains no token. % Otherwise, check the top of the stack for tokens: if there are, then % the input is non-empty, and if there are none, then we get rid of @@ -2497,7 +2712,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_input_if_empty:TF { - \int_compare:nNnTF \g_@@_input_int = \c_zero + \int_compare:nNnTF \g_@@_input_int = 0 { \use_i:nn } { \gtl_if_empty:cTF @@ -2517,14 +2732,14 @@ % % ^^A todo: profiling to know if \@@_input_split: is beneficial. % -% \begin{macro}[int]{\@@_input_split:} +% \begin{macro}{\@@_input_split:} % If the input is completely flat, and is a token list starting with % an |N|-type token, try to unflatten it by splitting at each % occurence of that first character % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_input_split: +\cs_new_protected:Npn \@@_input_split: { - \int_compare:nNnT \g_@@_input_int = \c_one + \int_compare:nNnT \g_@@_input_int = 1 { \exp_args:Nc \@@_input_split_aux:N { g_@@_input_1_gtl } @@ -2559,7 +2774,7 @@ \l_@@_input_tmpa_tl \@@_input_split_end: } } -\cs_new_nopar:Npn \@@_input_split_end: { } +\cs_new:Npn \@@_input_split_end: { } \cs_new_protected:Npn \@@_input_split_auxiii:w #1 \@@_input_split_end: { @@ -2572,10 +2787,10 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_input_gset:n} +% \begin{macro}{\@@_input_gset:n} % At first, all of the input is in the same~\texttt{gtl}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_input_gset:n +\cs_new_protected:Npn \@@_input_gset:n { \int_gzero:N \g_@@_input_int \@@_back_input:n @@ -2583,7 +2798,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_input_get:N} +% \begin{macro}{\@@_input_get:N} % \begin{macrocode} \cs_new_protected:Npn \@@_input_get:N #1 { @@ -2597,7 +2812,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_input_gpop:N} +% \begin{macro}{\@@_input_gpop:N} % Call \cs{@@_input_if_empty:TF} to remove empty levels from the input % stack, then extract the first token from the left-most non-empty % level. @@ -2618,7 +2833,7 @@ % Merge the top two levels of input. This requires, but does not % check, that \cs{g_@@_input_int} is at least~$2$. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_input_merge: +\cs_new_protected:Npn \@@_input_merge: { \int_gdecr:N \g_@@_input_int \gtl_gconcat:ccc @@ -2631,7 +2846,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int,TF]{\@@_input_gpop_item:N} +% \begin{macro}[TF]{\@@_input_gpop_item:N} % \begin{macro}{\@@_input_gpop_item_aux:NN} % If there is no input, we cannot pop an item. Othewise, try to pop % from the top of the input stack. If this succeeds, or if this @@ -2642,7 +2857,7 @@ % \begin{macrocode} \prg_new_protected_conditional:Npnn \@@_input_gpop_item:N #1 { F } { - \int_compare:nNnTF \g_@@_input_int = \c_zero + \int_compare:nNnTF \g_@@_input_int = 0 { \prg_return_false: } { \exp_args:Nc \@@_input_gpop_item_aux:NN @@ -2654,10 +2869,10 @@ \gtl_gpop_left_item:NNTF #1#2 { \prg_return_true: } { - \int_compare:nNnTF { \gtl_extra_end:N #1 } > \c_zero + \int_compare:nNnTF { \gtl_extra_end:N #1 } > 0 { \prg_return_false: } { - \int_compare:nNnTF \g_@@_input_int = \c_one + \int_compare:nNnTF \g_@@_input_int = 1 { \prg_return_false: } { \@@_input_merge: @@ -2675,13 +2890,13 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_input_gpop_tl:N} +% \begin{macro}{\@@_input_gpop_tl:N} % \begin{macrocode} \cs_new_protected:Npn \@@_input_gpop_tl:N #1 { \tl_clear:N #1 \@@_input_gpop_tl_aux:N #1 } \cs_new_protected:Npn \@@_input_gpop_tl_aux:N #1 { - \int_compare:nNnF \g_@@_input_int = \c_zero + \int_compare:nNnF \g_@@_input_int = 0 { \exp_args:Nc \@@_input_gpop_tl_aux:NN { g_@@_input_ \int_use:N \g_@@_input_int _gtl } #1 @@ -2697,8 +2912,8 @@ \@@_input_gpop_tl_aux:N #2 } { - \int_compare:nNnTF \g_@@_input_int > \c_one - { \int_compare:nNnTF { \gtl_extra_end:N #1 } > \c_zero } + \int_compare:nNnTF \g_@@_input_int > 1 + { \int_compare:nNnTF { \gtl_extra_end:N #1 } > 0 } { \use_i:nn } { \tl_put_right:Nx #2 { \gtl_left_tl:N #1 } @@ -2713,12 +2928,12 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_back_input:n, \@@_back_input:x} +% \begin{macro}{\@@_back_input:n, \@@_back_input:x} % Insert a token list back into the input. Use \cs{gtl_gclear_new:c} % to define the gtl variable if necessary: this happens whenever a % new largest value of \cs{g_@@_input_int} is reached. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_back_input:n +\cs_new_protected:Npn \@@_back_input:n { \int_gincr:N \g_@@_input_int \gtl_gclear_new:c { g_@@_input_ \int_use:N \g_@@_input_int _gtl } @@ -2730,7 +2945,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_back_input_gtl:N} +% \begin{macro}{\@@_back_input_gtl:N} % Insert a generalized token list back into the input. % \begin{macrocode} \cs_new_protected:Npn \@@_back_input_gtl:N #1 @@ -2747,25 +2962,25 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_back_input:} +% \begin{macro}{\@@_back_input:} % Insert the last token read back into the input stream. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_back_input: +\cs_new_protected:Npn \@@_back_input: { \@@_back_input_gtl:N \l_@@_head_gtl } % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_back_input_tl_o:} +% \begin{macro}{\@@_back_input_tl_o:} % Insert the \cs{l_@@_head_tl} (may or may not be the last token read) % back into the input stream, after expanding it once. Then print % some diagnostic information. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_back_input_tl_o: +\cs_new_protected:Npn \@@_back_input_tl_o: { \tl_set:Nx \l_@@_tmpa_tl { \exp_args:NV \exp_not:o \l_@@_head_tl } \@@_back_input:V \l_@@_tmpa_tl - \@@_print_done:x + \@@_print_expansion:x { \tl_to_str:N \l_@@_head_tl = \tl_to_str:N \l_@@_tmpa_tl } } % \end{macrocode} @@ -2773,13 +2988,13 @@ % % \subsubsection{Insert token for error recovery} % -% \begin{macro}[int]{\@@_insert_relax:} +% \begin{macro}{\@@_insert_relax:} % This function inserts \TeX{}'s |frozen_relax|. It is called when a % conditional is not done finding its condition, but hits the % corresponding \tn{fi} or \tn{or} or \tn{else}, or when \tn{input} % appears while \cs{g_@@_name_in_progress_bool} is \texttt{true}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_insert_relax: +\cs_new_protected:Npn \@@_insert_relax: { \@@_back_input: \gtl_set_eq:NN \l_@@_head_gtl \c_@@_frozen_relax_gtl @@ -2789,9 +3004,9 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_insert_group_begin_error:} +% \begin{macro}{\@@_insert_group_begin_error:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_insert_group_begin_error: +\cs_new_protected:Npn \@@_insert_group_begin_error: { \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_head_tl \@@_back_input: @@ -2803,9 +3018,9 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_insert_dollar_error:} +% \begin{macro}{\@@_insert_dollar_error:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_insert_dollar_error: +\cs_new_protected:Npn \@@_insert_dollar_error: { \@@_back_input: \@@_back_input:n { $ } % $ @@ -2848,7 +3063,7 @@ % \end{macro} % % ^^A todo: redoc -% \begin{macro}[int]{\@@_macro_call:} +% \begin{macro}{\@@_macro_call:} % \begin{macro} % { % \@@_macro_call_safe:, @@ -2862,25 +3077,25 @@ % extracting the longest balanced prefix in the input and working with % that. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_macro_call: +\cs_new_protected:Npn \@@_macro_call: { \bool_if:NTF \g_@@_speedup_macros_bool { \tl_set:Nx \l_@@_tmpa_tl {^ \exp_after:wN \@@_macro_parameter:N \l_@@_head_tl } - \tl_if_in:NVTF \c_@@_parameters_tl \l_@@_tmpa_tl + \@@_tl_if_in:ooTF \c_@@_parameters_tl \l_@@_tmpa_tl { \@@_macro_call_quick: } { \@@_macro_call_safe: } } { \@@_macro_call_safe: } \exp_args:NV \@@_back_input:o \l_@@_head_tl - \@@_print_done:x { \g_@@_action_text_str } + \@@_print_expansion: } -\cs_new_protected_nopar:Npn \@@_macro_call_safe: +\cs_new_protected:Npn \@@_macro_call_safe: { \@@_input_gpop_tl:N \l_@@_tmpa_tl \tl_put_right:NV \l_@@_head_tl \l_@@_tmpa_tl } -\cs_new_protected_nopar:Npn \@@_macro_call_quick: +\cs_new_protected:Npn \@@_macro_call_quick: { \exp_after:wN \@@_macro_call_quick_loop:NNN \l_@@_tmpa_tl { ? \use_none_delimit_by_q_stop:w } \q_stop @@ -2906,13 +3121,28 @@ % % \subsection{Expand next token} % -% \begin{macro}[int]{\@@_expand:} -% This is similar to \cs{@@_do_step:}, but operates on expandable -% tokens rather than (non-expandable) commands. We mimick \TeX{}'s -% structure, distinguishing macros from other commands (not quite sure -% why). +% \begin{macro}{\@@_expand_do:N} +% The argument is a command that will almost always be run to continue +% a loop whose aim is to find the next non-expandable token, for +% various purposes. The only case where we will end up grabbing the +% argument is to suppress the loop by \cs{@@_noexpand:N}. +% \begin{itemize} +% \item \cs{@@_get_x_next:} when \TeX{} is looking for the first +% non-expandable token in the main loop or when looking for numbers, +% optional spaces etc. +% \item \cs{@@_get_x_or_protected:} at the start of an alignment cell. +% \item \cs{@@_get_token_xdef:} in the replacement text of \tn{edef} +% and \tn{xdef}. +% \item \cs{@@_get_token_x:} in the argument of \tn{message} and the +% like. +% \item \cs{prg_do_nothing:} in \cs{@@_expandafter:} namely after +% \tn{expandafter}. +% \end{itemize} +% We mimick \TeX{}'s structure, distinguishing macros from other +% commands because we find macro arguments very differently from +% primitives. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_expand: +\cs_new_protected:Npn \@@_expand_do:N { \@@_set_action_text: \bool_if:NT \g_@@_internal_debug_bool @@ -2927,15 +3157,16 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_expand_nonmacro:} +% \begin{macro}{\@@_expand_nonmacro:} % The token is a primitive. We find its (cleaned-up) \tn{meaning}, % and call the function implementing that expansion. If we do not -% recognize the meaning then it is probably an unknown primitive. If -% we recognize the meaning but there is no corresponding function, -% then we probably have not implemented it yet, so dump it in the -% output as is. +% recognize the meaning then it is probably an unknown primitive. +% Then do something similar to what we do for macros: get all tokens +% that are not too unlikely to appear in the arguments of the +% primitive and expand the resulting token list once before putting it +% back into the input stream. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_expand_nonmacro: +\cs_new_protected:Npn \@@_expand_nonmacro: { \@@_set_cmd_aux_meaning: \@@_set_cmd_aux_primitive:oTF { \l_@@_head_meaning_tl } @@ -2947,42 +3178,65 @@ { \@@_error:nxxxx { unknown-primitive } { \l_@@_head_meaning_tl } { } { } { } - \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl - \@@_print_action: + \@@_input_gpop_tl:N \l_@@_tmpa_tl + \tl_put_right:NV \l_@@_head_tl \l_@@_tmpa_tl + \exp_args:NV \@@_back_input:o \l_@@_head_tl + \@@_print_expansion: } } % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_get_x_next:} +% \begin{macro}{\@@_get_x_next:} % Get a token. If it is expandable, then expand it, and repeat. This -% function does not set the |cmd| and |char| integers. +% function does not set the |cmd| and |char| integers. It is the +% basis of all routines that look for keywords, numbers, equal signs, +% filenames, optional spaces etc (in the language of \LaTeX3 these are +% situations where \TeX{} \enquote{\texttt{f}-expands}). It is also +% the basis of the \cs{@@_main_loop:}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_get_x_next: +\cs_new_protected:Npn \@@_get_x_next: { \@@_get_next: \@@_token_if_expandable:NT \l_@@_head_token - { - \@@_expand: - \@@_get_x_next: - } + { \@@_expand_do:N \@@_get_x_next: } } % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_get_x_or_protected:} +% \begin{macro}{\@@_get_x_or_protected:} % Get a token. If it is expandable, but not protected, then expand % it, and repeat. This function does not set the |cmd| and |char| -% integers. +% integers. This function is not used at present: it will be used at +% the start of alignment cells. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_get_x_or_protected: +\cs_new_protected:Npn \@@_get_x_or_protected: { \@@_get_next: \@@_token_if_protected:NF \l_@@_head_token - { - \@@_expand: - \@@_get_x_or_protected: - } + { \@@_expand_do:N \@@_get_x_or_protected: } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_get_token_xdef:, \@@_get_token_x:} +% These are similar to \cs{@@_get_x_next:}, for use when reading the +% replacement text of \tn{edef}/\tn{xdef} or the argument of a +% primitive like \tn{message} that should be expanded as we read +% tokens. Loop until finding a non-expandable token (or protected +% macro). +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_token_xdef: + { + \@@_get_next: + \@@_token_if_protected:NF \l_@@_head_token + { \@@_expand_do:N \@@_get_token_xdef: } + } +\cs_new_protected:Npn \@@_get_token_x: + { + \@@_get_next: + \@@_token_if_protected:NF \l_@@_head_token + { \@@_expand_do:N \@@_get_token_x: } } % \end{macrocode} % \end{macro} @@ -2995,7 +3249,7 @@ % \begin{macro}{\@@_get_x_non_blank:} % This function does not set the |cmd| and |char| integers. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_get_x_non_blank: +\cs_new_protected:Npn \@@_get_x_non_blank: { \@@_get_x_next: \token_if_eq_catcode:NNT \l_@@_head_token \c_space_token @@ -3007,14 +3261,18 @@ % \begin{macro}{\@@_get_x_non_relax:} % This function does not set the |cmd| and |char| integers. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_get_x_non_relax: +\cs_new_protected:Npn \@@_get_x_non_relax: { \@@_get_x_next: - \token_if_eq_meaning:NNT \l_@@_head_token \scan_stop: + \token_if_eq_meaning:NNTF \l_@@_head_token \scan_stop: { \@@_get_x_non_relax: } { - \token_if_eq_catcode:NNT \l_@@_head_token \c_space_token + \token_if_eq_meaning:NNTF \l_@@_head_token \@@_special_relax: { \@@_get_x_non_relax: } + { + \token_if_eq_catcode:NNT \l_@@_head_token \c_space_token + { \@@_get_x_non_relax: } + } } } % \end{macrocode} @@ -3022,7 +3280,7 @@ % % \begin{macro}{\@@_skip_optional_space:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_skip_optional_space: +\cs_new_protected:Npn \@@_skip_optional_space: { \@@_get_x_next: \token_if_eq_catcode:NNF \l_@@_head_token \c_space_token @@ -3037,7 +3295,7 @@ % as \cs{@@_scan_something_internal:n} leaves raw numbers in % the previous-input sequence. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_optional_equals: +\cs_new_protected:Npn \@@_scan_optional_equals: { \@@_get_x_non_blank: \tl_if_eq:NNTF \l_@@_head_tl \c_@@_eq_tl @@ -3050,12 +3308,12 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_scan_left_brace:} +% \begin{macro}{\@@_scan_left_brace:} % The presence of \tn{relax} is allowed before a begin-group token. % If there is no begin-group token, insert one, produce an error, and % scan that begin-group using \cs{@@_get_next:}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_left_brace: +\cs_new_protected:Npn \@@_scan_left_brace: { \@@_get_x_non_relax: \token_if_eq_catcode:NNF \l_@@_head_token \c_group_begin_token @@ -3067,8 +3325,8 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_scan_keyword:n} -% \begin{macro}[int,TF]{\@@_scan_keyword:n} +% \begin{macro}{\@@_scan_keyword:n} +% \begin{macro}[TF]{\@@_scan_keyword:n} % \begin{macro} % { % \@@_scan_keyword_loop:NNN, @@ -3145,24 +3403,24 @@ \@@_gtl_if_head_is_definable:NTF \l_@@_head_gtl { \prg_return_false: } { - \str_if_eq_x:nnTF + \str_if_eq:eeTF { \str_head:f { \gtl_to_str:N \l_@@_head_gtl } } {#1} { \prg_return_true: } { - \str_if_eq_x:nnTF + \str_if_eq:eeTF { \str_head:f { \gtl_to_str:N \l_@@_head_gtl } } {#2} { \prg_return_true: } { \prg_return_false: } } } } -\cs_new_protected_nopar:Npn \@@_scan_keyword_true: +\cs_new_protected:Npn \@@_scan_keyword_true: { \@@_prev_input_gpop_gtl:N \l_@@_tmpb_gtl \@@_prev_input:x { \gtl_to_str:N \l_@@_tmpb_gtl } \prg_return_true: } -\cs_new_protected_nopar:Npn \@@_scan_keyword_false:w +\cs_new_protected:Npn \@@_scan_keyword_false:w #1 \q_recursion_stop { \@@_back_input: @@ -3179,7 +3437,7 @@ % Used when |to| is mandatory: after \tn{read} or \tn{readline} and % after \tn{vsplit}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_to: +\cs_new_protected:Npn \@@_scan_to: { \@@_scan_keyword:nF { tToO } { @@ -3193,7 +3451,7 @@ % \begin{macro}{\@@_scan_font_ident:} % Find a font identifier. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_font_ident: +\cs_new_protected:Npn \@@_scan_font_ident: { \@@_get_x_non_blank: \@@_set_cmd: @@ -3226,7 +3484,7 @@ % Find operands for one of \tn{hyphenchar}'s friends (command code % |assign_font_int=78|). % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_font_int: +\cs_new_protected:Npn \@@_scan_font_int: { \int_case:nnF \l_@@_head_char_int { @@ -3242,7 +3500,7 @@ % \begin{macro}{\@@_scan_font_dimen:} % Find operands for \tn{fontdimen}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_font_dimen: +\cs_new_protected:Npn \@@_scan_font_dimen: { \@@_scan_int: \@@_scan_font_ident: @@ -3316,7 +3574,7 @@ \int_compare:nNnT {#1} = { 8 } { \@@_tex_error:nV { the-cannot } \l_@@_head_tl - \@@_scan_something_internal_auxii:Vn \c_zero { 0 } + \@@_scan_something_internal_auxii:nn 0 { 0 } \@@_break:w } \tl_if_empty:nF {#2} @@ -3359,7 +3617,7 @@ % is~$8$, large enough so that the main function knows it is % forbidden. % \begin{macrocode} -\cs_new_nopar:Npn \@@_thing_case: +\cs_new:Npn \@@_thing_case: { \int_case:nnF \l_@@_head_cmd_int { @@ -3390,9 +3648,9 @@ } { 8 } } -\cs_new_nopar:Npn \@@_thing_set_aux: +\cs_new:Npn \@@_thing_set_aux: { \int_compare:nNnTF \l_@@_head_char_int = { 1 } { 1 } { 0 } } -\cs_new_nopar:Npn \@@_thing_last_item: +\cs_new:Npn \@@_thing_last_item: { \int_compare:nNnTF \l_@@_head_char_int < { 26 } { @@ -3435,10 +3693,10 @@ { } } } -\cs_new_nopar:Npn \@@_thing_register: +\cs_new:Npn \@@_thing_register: { \int_eval:n { \l_@@_head_char_int / 1 000 000 - 1 } - \int_compare:nNnT { \tl_tail:V \l_@@_head_char_int } = \c_zero + \int_compare:nNnT { \tl_tail:V \l_@@_head_char_int } = 0 { \@@_scan_int: } } % \end{macrocode} @@ -3449,7 +3707,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_scan_toks_register: { - \int_compare:nNnT \l_@@_head_char_int = \c_zero + \int_compare:nNnT \l_@@_head_char_int = 0 { \@@_scan_int: } } % \end{macrocode} @@ -3474,7 +3732,7 @@ { 1 } \dim_eval:n { 2 } \skip_eval:n } - { \int_compare:nNnT {#1} = { 3 } \etex_mutoglue:D #3 } + { \int_compare:nNnT {#1} = { 3 } \tex_mutoglue:D #3 } } } { @@ -3485,7 +3743,7 @@ } { \@@_tex_error:nV { incompatible-units } #3 - \tl_set:Nx #4 { \muskip_eval:n { \etex_gluetomu:D #3 } } + \tl_set:Nx #4 { \muskip_eval:n { \tex_gluetomu:D #3 } } } } } @@ -3573,7 +3831,7 @@ % Skips blanks, scans signs, and places them to the right of the last % item of \cs{@@_prev_input:n}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_signs: +\cs_new_protected:Npn \@@_scan_signs: { \@@_get_x_non_blank: \tl_if_eq:NNTF \l_@@_head_tl \c_@@_plus_tl @@ -3596,7 +3854,7 @@ % \begin{macro} % {\@@_scan_int_char:, \@@_scan_int_lq:, \@@_scan_int_explicit:n} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_int: +\cs_new_protected:Npn \@@_scan_int: { \@@_scan_signs: \@@_set_cmd: @@ -3604,7 +3862,7 @@ { \@@_scan_something_internal:n { 0 } } { \@@_scan_int_char: } } -\cs_new_protected_nopar:Npn \@@_scan_int_char: +\cs_new_protected:Npn \@@_scan_int_char: { \tl_case:NnF \l_@@_head_tl { @@ -3624,7 +3882,7 @@ } { \@@_scan_int_explicit:Nn \c_false_bool { } } } -\cs_new_protected_nopar:Npn \@@_scan_int_lq: +\cs_new_protected:Npn \@@_scan_int_lq: { \@@_get_next: \@@_gtl_if_head_is_definable:NF \l_@@_head_gtl @@ -3641,7 +3899,7 @@ } \cs_new_protected:Npn \@@_scan_int_explicit:Nn #1#2 { - \if_int_compare:w \c_one + \if_int_compare:w 1 < #2 1 \exp_after:wN \exp_not:N \l_@@_head_tl \exp_stop_f: \exp_after:wN \use_i:nn \else: @@ -3666,14 +3924,14 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_scan_normal_dimen:} +% \begin{macro}{\@@_scan_normal_dimen:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_normal_dimen: +\cs_new_protected:Npn \@@_scan_normal_dimen: { \@@_scan_dimen:nN { 2 } \c_false_bool } % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_scan_dimen:nN} +% \begin{macro}{\@@_scan_dimen:nN} % The first argument is $2$ if the unit may not be |mu| and $3$ if % the unit must be |mu| (or |fil|). The second argument is % \cs{c_true_bool} if |fil|, |fill|, |filll| are permitted, and is @@ -3710,7 +3968,7 @@ \@@_scan_decimal_loop: } { - \tl_if_in:nVTF { 0123456789 } \l_@@_head_tl + \@@_tl_if_in:ooTF { 0123456789 } \l_@@_head_tl { \@@_back_input: \@@_scan_int: @@ -3778,14 +4036,14 @@ \@@_prev_input:n { pt } \@@_break_point: } -\cs_new_protected_nopar:Npn \@@_scan_inf_unit_loop: +\cs_new_protected:Npn \@@_scan_inf_unit_loop: { \@@_scan_keyword:nT { lL } { \@@_scan_inf_unit_loop: } } -\cs_new_protected_nopar:Npn \@@_scan_decimal_loop: +\cs_new_protected:Npn \@@_scan_decimal_loop: { \@@_get_x_next: \tl_if_empty:NTF \l_@@_head_tl { \use_ii:nn } - { \tl_if_in:nVTF { 0123456789 } \l_@@_head_tl } + { \@@_tl_if_in:ooTF { 0123456789 } \l_@@_head_tl } { \@@_prev_input:V \l_@@_head_tl \@@_scan_decimal_loop: @@ -3799,16 +4057,16 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_scan_normal_glue:, \@@_scan_mu_glue:} +% \begin{macro}{\@@_scan_normal_glue:, \@@_scan_mu_glue:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_normal_glue: +\cs_new_protected:Npn \@@_scan_normal_glue: { \@@_scan_glue:n { 2 } } -\cs_new_protected_nopar:Npn \@@_scan_mu_glue: +\cs_new_protected:Npn \@@_scan_mu_glue: { \@@_scan_glue:n { 3 } } % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_scan_glue:n} +% \begin{macro}{\@@_scan_glue:n} % \begin{macrocode} \cs_new_protected:Npn \@@_scan_glue:n #1 { @@ -3842,10 +4100,10 @@ % \end{macro} % % ^^A todo: allow \input".. .." -% \begin{macro}[int]{\@@_scan_file_name:} +% \begin{macro}{\@@_scan_file_name:} % ^^A todo: area_delimiter and ext_delimiter ?? % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_file_name: +\cs_new_protected:Npn \@@_scan_file_name: { \bool_gset_true:N \g_@@_name_in_progress_bool \@@_get_x_non_blank: @@ -3853,7 +4111,7 @@ \bool_gset_false:N \g_@@_name_in_progress_bool \@@_prev_input_silent:n { ~ } } -\cs_new_protected_nopar:Npn \@@_scan_file_name_loop: +\cs_new_protected:Npn \@@_scan_file_name_loop: { \@@_gtl_if_head_is_definable:NTF \l_@@_head_gtl { \@@_back_input: } @@ -3871,12 +4129,12 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_scan_r_token:} +% \begin{macro}{\@@_scan_r_token:} % This is analogous to \TeX{}'s |get_r_token|. We store in % \cs{l_@@_defined_tl} the token which we found, as this is what will % be defined by the next assignment. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_r_token: +\cs_new_protected:Npn \@@_scan_r_token: { \bool_do_while:nn { \tl_if_eq_p:NN \l_@@_head_tl \c_space_tl } @@ -3907,8 +4165,25 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_scan_pdf_ext_toks:} +% \begin{macrocode} +\cs_new_protected:Npn \@@_scan_pdf_ext_toks: + { + \@@_prev_input_gpush: + \@@_scan_toks:NN \c_false_bool \c_true_bool + \@@_prev_input_gpop:N \l_@@_tmpa_tl + \@@_prev_input_silent:x + { { \exp_not:N \exp_not:n \exp_not:V \l_@@_tmpa_tl } } + } +% \end{macrocode} +% \end{macro} +% % ^^A todo: provide separate functions for defs (avoid hash doubling). % \begin{macro}{\@@_scan_toks:NN} +% The boolean |#1| is true if we are making a definition (then we +% start by scanning the parameter text), false if we are simply +% scanning a general text. The boolean |#2| is true if we need to +% expand, false otherwise (for instance for \tn{lowercase}). % \begin{macrocode} \cs_new_protected:Npn \@@_scan_toks:NN #1#2 { @@ -3928,14 +4203,14 @@ % input, stop looping, and put what we collected into % \cs{l_@@_defining_tl} and into the |prev_input|. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_param: +\cs_new_protected:Npn \@@_scan_param: { \tl_clear:N \l_@@_tmpa_tl \@@_scan_param_aux: \tl_put_right:NV \l_@@_defining_tl \l_@@_tmpa_tl \@@_prev_input_silent:V \l_@@_tmpa_tl } -\cs_new_protected_nopar:Npn \@@_scan_param_aux: +\cs_new_protected:Npn \@@_scan_param_aux: { \@@_get_next: \tl_concat:NNN \l_@@_tmpa_tl @@ -3948,9 +4223,14 @@ % \end{macro} % % \begin{macro}{\@@_scan_group_n:N} +% The boolean |#1| is true if we are making a definition, false +% otherwise. In both cases put the open brace back and grab the first +% item. The only difference is that when making a definition we store +% the data into \cs{l_@@_defining_tl} as well. % \begin{macrocode} \cs_new_protected:Npn \@@_scan_group_n:N #1 { + \gtl_set_eq:NN \l_@@_head_gtl \c_group_begin_gtl \@@_back_input: \@@_input_gpop_item:NF \l_@@_head_tl { @@ -3966,6 +4246,8 @@ % \end{macro} % % \begin{macro}{\@@_scan_group_x:N} +% The boolean |#1| is true if we are making a definition, false +% otherwise. % \begin{macrocode} \cs_new_protected:Npn \@@_scan_group_x:N #1 { @@ -3990,10 +4272,12 @@ % \end{macro} % % \begin{macro}{\@@_scan_group_xdef:n} +% This is to scan the replacement text of an \tn{edef} or \tn{xdef}. +% The integer |#1| counts the brace balance. % \begin{macrocode} \cs_new_protected:Npn \@@_scan_group_xdef:n #1 { - \@@_get_token_x:N \c_true_bool + \@@_get_token_xdef: \tl_if_empty:NTF \l_@@_head_tl { \gtl_if_head_is_group_begin:NTF \l_@@_head_gtl @@ -4005,7 +4289,7 @@ { \@@_prev_input_silent:V \c_right_brace_str \tl_put_right:Nn \l_@@_defining_tl { \if_false: { \fi: } } - \int_compare:nNnF {#1} = \c_one + \int_compare:nNnF {#1} = 1 { \@@_scan_group_xdef:f { \int_eval:n { #1 - 1 } } } } } @@ -4024,14 +4308,14 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_scan_group_x:n #1 { - \@@_get_token_x:N \c_false_bool + \@@_get_token_x: \@@_prev_input_gtl:N \l_@@_head_gtl \tl_if_empty:NTF \l_@@_head_tl { \gtl_if_head_is_group_begin:NTF \l_@@_head_gtl { \@@_scan_group_x:f { \int_eval:n { #1 + 1 } } } { - \int_compare:nNnF {#1} = \c_one + \int_compare:nNnF {#1} = 1 { \@@_scan_group_x:f { \int_eval:n { #1 - 1 } } } } } @@ -4041,41 +4325,11 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_get_token_x:N} -% \begin{macrocode} -\cs_new_protected:Npn \@@_get_token_x:N #1 - { - \@@_get_next: - \@@_token_if_protected:NF \l_@@_head_token - { - \@@_set_cmd: - \int_compare:nNnTF - \l_@@_head_cmd_int = { \@@_tex_use:n { the } } - { - \@@_get_the: - \bool_if:NTF #1 - { - \tl_put_right:NV \l_@@_defining_tl \l_@@_head_tl - \@@_prev_input:V \l_@@_head_tl - } - { - \@@_exp_args:NNx \gtl_set:Nn \l_@@_tmpb_gtl { \l_@@_head_tl } - \@@_prev_input_gtl:N \l_@@_tmpb_gtl - \@@_print_action: - } - } - { \@@_expand: } - \@@_get_token_x:N #1 - } - } -% \end{macrocode} -% \end{macro} -% % ^^A todo: catch runaway expand/get_x_next. (get_next too, probably) % % \begin{macro}{\@@_scan_alt_rule:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_alt_rule: +\cs_new_protected:Npn \@@_scan_alt_rule: { \@@_scan_keyword:nTF { wWiIdDtThH } { @@ -4104,7 +4358,7 @@ % Some \TeX{} primitives accept the keywords |to| and |spread|, % followed by a dimension. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_spec: +\cs_new_protected:Npn \@@_scan_spec: { \@@_scan_keyword:nTF { tToO } { \@@_scan_normal_dimen: } { @@ -4165,7 +4419,7 @@ % \TeX{} does), there is no need to remove the after assignment token % here. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_do_box_error: +\cs_new_protected:Npn \@@_do_box_error: { \@@_back_input: \@@_error:nnnnn { missing-box } { } { } { } { } @@ -4228,7 +4482,7 @@ % % \begin{macro}{\@@_do_leaders_fetch_skip:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_do_leaders_fetch_skip: +\cs_new_protected:Npn \@@_do_leaders_fetch_skip: { \@@_get_x_non_relax: \@@_set_cmd: @@ -4298,7 +4552,7 @@ \cs_new_protected:Npn \@@_box_hook:N #1 { \tl_set:NV \l_@@_tmpa_tl #1 - \str_if_eq_x:nnF + \str_if_eq:eeF { \tl_head:N \l_@@_tmpa_tl } { \exp_not:N \@@_box_hook:w } { \@@_exp_args:Nx #1 @@ -4330,7 +4584,7 @@ % |heigh| and |width| keywords, we are in the same situation as after % finding a box. Fetch the required skip accordingly. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_do_leaders_rule: +\cs_new_protected:Npn \@@_do_leaders_rule: { \@@_prev_input:V \l_@@_head_tl \@@_scan_alt_rule: @@ -4341,7 +4595,7 @@ % % \subsection{Paragraphs} % -% \begin{macro}[int,TF]{\@@_charcode_if_safe:n} +% \begin{macro}[TF]{\@@_charcode_if_safe:n} % \begin{macrocode} \prg_new_protected_conditional:Npnn \@@_charcode_if_safe:n #1 { TF } { @@ -4412,7 +4666,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_new_graf:N} +% \begin{macro}{\@@_new_graf:N} % The argument is a boolean, indicating whether the paragraph should % be indented. We have much less work to do here than \TeX{} itself. % Our only task is to correctly position the \tn{everypar} tokens in @@ -4435,17 +4689,17 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_end_graf:} +% \begin{macro}{\@@_end_graf:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_end_graf: +\cs_new_protected:Npn \@@_end_graf: { \mode_if_horizontal:T { \@@_normal_paragraph: } } % \end{macrocode} % \end{macro} % % ^^A todo: Do we need to do more? -% \begin{macro}[int]{\@@_normal_paragraph:} +% \begin{macro}{\@@_normal_paragraph:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_normal_paragraph: +\cs_new_protected:Npn \@@_normal_paragraph: { \tex_par:D \gtl_gput_right:Nn \g_@@_output_gtl { \par } @@ -4455,9 +4709,9 @@ % \end{macro} % % ^^A todo: do something to the \output routine? -% \begin{macro}[int]{\@@_build_page:} +% \begin{macro}{\@@_build_page:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_build_page: +\cs_new_protected:Npn \@@_build_page: { } % \end{macrocode} @@ -4475,7 +4729,7 @@ % When an end-group character is sensed, the result depends on the % current group type. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_handle_right_brace: +\cs_new_protected:Npn \@@_handle_right_brace: { \int_compare:nTF { 1 <= \@@_currentgrouptype: <= 13 } { @@ -4511,7 +4765,7 @@ % This command is used to simply end a group, when there are no % specific operations to perform. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_end_simple_group: +\cs_new_protected:Npn \@@_end_simple_group: { \l_@@_head_token \@@_print_action: @@ -4524,14 +4778,14 @@ % \tn{hbox}) can either be simple, or can mean that we need to find a % skip for a \tn{leaders}/\tn{cleaders}/\tn{xleaders} construction. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_end_box_group: +\cs_new_protected:Npn \@@_end_box_group: { \seq_pop:NN \l_@@_leaders_box_seq \l_@@_tmpa_tl \exp_args:No \@@_end_box_group_aux:n { \l_@@_tmpa_tl } } \cs_new_protected:Npn \@@_end_box_group_aux:n #1 { - \str_if_eq_x:nnTF {#1} { Z } + \str_if_eq:eeTF {#1} { Z } { \@@_end_simple_group: } { \@@_get_x_non_relax: @@ -4554,7 +4808,7 @@ % % \begin{macro}{\@@_off_save:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_off_save: +\cs_new_protected:Npn \@@_off_save: { \int_compare:nNnTF \@@_currentgrouptype: = { 0 } { % bottom-level @@ -4585,7 +4839,7 @@ % ^^A todo: implement \aftergroup and things happening at end-group % ^^A todo: implement \@@_scan_math: % -% \begin{macro}[int] +% \begin{macro} % {\@@_mode_math:n, \@@_mode_non_math:n, \@@_mode_vertical:n} % \begin{macrocode} \cs_new_protected:Npn \@@_mode_math:n #1 @@ -4610,7 +4864,7 @@ % \begin{macro}{\@@_head_for_vmode:} % See \TeX{}'s |head_for_vmode|. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_head_for_vmode: +\cs_new_protected:Npn \@@_head_for_vmode: { \mode_if_inner:TF { @@ -4633,7 +4887,7 @@ % ^^A todo: should push_math be provided? % \begin{macro}{\@@_goto_inner_math:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_goto_inner_math: +\cs_new_protected:Npn \@@_goto_inner_math: { \@@_box_hook:N \tex_everymath:D $ % $ @@ -4644,7 +4898,7 @@ % % \begin{macro}{\@@_goto_display_math:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_goto_display_math: +\cs_new_protected:Npn \@@_goto_display_math: { \@@_box_hook:N \tex_everydisplay:D $ $ @@ -4655,7 +4909,7 @@ % % \begin{macro}{\@@_after_math:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_after_math: +\cs_new_protected:Npn \@@_after_math: { \mode_if_inner:TF { @@ -4684,11 +4938,11 @@ % % \subsection{One step} % -% \begin{macro}[int]{\@@_do_step:} +% \begin{macro}{\@@_do_step:} % Perform the action if the corresponding command exists. If that % command does not exist, complain, and leave the token in the output. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_do_step: +\cs_new_protected:Npn \@@_do_step: { \@@_set_action_text: \bool_if:NT \g_@@_internal_debug_bool @@ -4734,7 +4988,18 @@ % \tn{relax} does nothing. % \begin{macrocode} \@@_new_tex_cmd:nn { relax } % 0 - { \@@_print_action: } + { + \token_if_eq_meaning:NNT \l_@@_head_token \@@_special_relax: + { + \exp_after:wN \@@_token_if_expandable:NTF \l_@@_head_tl + { + \@@_set_action_text:x + { \iow_char:N \\notexpanded: \g_@@_action_text_str } + } + { } + } + \@@_print_action: + } % \end{macrocode} % % Begin-group characters are sent to the output, as their grouping @@ -4808,7 +5073,7 @@ { \@@_mode_math:n { \@@_sub_sup: } } \@@_new_tex_cmd:nn { subscript_char } % 8 { \@@_mode_math:n { \@@_sub_sup: } } -\cs_new_protected_nopar:Npn \@@_sub_sup: +\cs_new_protected:Npn \@@_sub_sup: { \@@_prev_input_gpush:N \l_@@_head_tl \@@_print_action: @@ -4919,7 +5184,7 @@ { % ^^A todo: unless its_all_over \int_gdecr:N \g_@@_ends_int - \int_compare:nNnTF \g_@@_ends_int > \c_zero + \int_compare:nNnTF \g_@@_ends_int > 0 { \@@_back_input: \@@_back_input:n @@ -5024,7 +5289,7 @@ { \@@_prev_input_gpush:N \l_@@_head_tl \@@_print_action: - \int_compare:nNnF \l_@@_head_char_int = \c_zero + \int_compare:nNnF \l_@@_head_char_int = 0 { \@@_scan_int: } \@@_prev_input_gpush: \@@_scan_toks:NN \c_false_bool \c_true_bool @@ -5057,7 +5322,13 @@ { % show \@@_get_next: \@@_prev_input_gpop:N \l_@@_tmpa_tl - \gtl_head_do:NN \l_@@_head_gtl \l_@@_tmpa_tl + \token_if_eq_meaning:NNTF + \l_@@_head_token \@@_special_relax: + { + \exp_after:wN \exp_after:wN \exp_after:wN \l_@@_tmpa_tl + \exp_after:wN \exp_not:N \l_@@_head_tl + } + { \gtl_head_do:NN \l_@@_head_gtl \l_@@_tmpa_tl } } { 2 } { % showthe @@ -5065,13 +5336,13 @@ \@@_scan_something_internal:n { 5 } \@@_prev_input_gpop:N \l_@@_head_tl \@@_exp_args:Nx \use:n - { \etex_showtokens:D { \tl_tail:N \l_@@_head_tl } } + { \tex_showtokens:D { \tl_tail:N \l_@@_head_tl } } } } { % no operand for showlists, showgroups, showifs - \int_compare:nNnT \l_@@_head_char_int = \c_one % showbox + \int_compare:nNnT \l_@@_head_char_int = 1 % showbox { \@@_scan_int: } - \int_compare:nNnT \l_@@_head_char_int = \c_five % showtokens + \int_compare:nNnT \l_@@_head_char_int = 5 % showtokens { \@@_scan_toks:NN \c_false_bool \c_false_bool } \@@_prev_input_gpop:N \l_@@_head_tl \tl_use:N \l_@@_head_tl \scan_stop: @@ -5096,7 +5367,7 @@ % Scan a dimension and a box, and perform the shift, printing the % appropriate action. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_do_move: +\cs_new_protected:Npn \@@_do_move: { \@@_prev_input_gpush:N \l_@@_head_tl \@@_print_action: @@ -5126,7 +5397,7 @@ % % \begin{macro}{\@@_do_unpackage:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_do_unpackage: +\cs_new_protected:Npn \@@_do_unpackage: { \@@_prev_input_gpush:N \l_@@_head_tl \@@_print_action: @@ -5174,7 +5445,7 @@ % glue (\cs{l_@@_head_char_int} is $4$ or~$5$), then call the % primitive with that operand, and print the whole thing as an action. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_do_append_glue: +\cs_new_protected:Npn \@@_do_append_glue: { \int_compare:nNnTF \l_@@_head_char_int < { 4 } { \tl_use:N \l_@@_head_tl \@@_print_action: } @@ -5215,7 +5486,7 @@ % See \cs{@@_do_append_glue:}. This function is used for the % primitives \tn{kern} and \tn{mkern} only. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_do_append_kern: +\cs_new_protected:Npn \@@_do_append_kern: { \@@_prev_input_gpush:N \l_@@_head_tl \@@_print_action: @@ -5289,7 +5560,7 @@ { \@@_mode_non_vertical:n { \@@_do_rule: } } \@@_new_tex_cmd:nn { hrule } % 36 { \@@_mode_vertical:n { \@@_do_rule: } } -\cs_new_protected_nopar:Npn \@@_do_rule: +\cs_new_protected:Npn \@@_do_rule: { \@@_prev_input_gpush:N \l_@@_head_tl \@@_print_action: @@ -5347,7 +5618,7 @@ { \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_head_tl \@@_get_next: - \int_compare:nNnTF \@@_currentgrouptype: = \c_zero + \int_compare:nNnTF \@@_currentgrouptype: = 0 { \@@_print_action:x { @@ -5411,7 +5682,7 @@ % % \begin{macro}{\@@_do_accent:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_do_accent: +\cs_new_protected:Npn \@@_do_accent: { \@@_prev_input_gpush:N \l_@@_head_tl \@@_print_action: @@ -5450,7 +5721,7 @@ % \TeX{} will complain if \cs{l_@@_head_tl} happens to start with % \tn{accent} (the user used \tn{accent} in math mode). % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_do_math_accent: +\cs_new_protected:Npn \@@_do_math_accent: { \@@_prev_input_gpush:N \l_@@_head_tl \@@_print_action: @@ -5715,9 +5986,9 @@ % \subsubsection{Extensions} % ^^A todo: move this section. % -% \begin{macro}[int]{\@@_scan_extension_operands:} +% \begin{macro}{\@@_scan_extension_operands:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_extension_operands: +\cs_new_protected:Npn \@@_scan_extension_operands: { \int_case:nnF \l_@@_head_char_int { @@ -5897,7 +6168,7 @@ % % \begin{macro}{\@@_scan_pdfcolorstack_operands:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_pdfcolorstack_operands: +\cs_new_protected:Npn \@@_scan_pdfcolorstack_operands: { \@@_scan_int: \@@_scan_keyword:nF { sSeEtT } @@ -5920,7 +6191,7 @@ % % \begin{macro}{\@@_scan_rule_attr:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_rule_attr: +\cs_new_protected:Npn \@@_scan_rule_attr: { \@@_scan_alt_rule: \@@_scan_keyword:nT { aAtTtTrR } @@ -5929,9 +6200,9 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_scan_action:} +% \begin{macro}{\@@_scan_action:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_action: +\cs_new_protected:Npn \@@_scan_action: { \@@_scan_keyword:nTF { uUsSeErR } { \@@_scan_pdf_ext_toks: } @@ -5971,7 +6242,7 @@ % \begin{macro}{\@@_scan_image:} % Used by \tn{pdfximage}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_image: +\cs_new_protected:Npn \@@_scan_image: { \@@_scan_rule_attr: \@@_scan_keyword:nTF { nNaAmMeEdD } @@ -5987,9 +6258,9 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_scan_immediate_operands:} +% \begin{macro}{\@@_scan_immediate_operands:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_immediate_operands: +\cs_new_protected:Npn \@@_scan_immediate_operands: { \@@_get_x_next: \@@_set_cmd: @@ -6011,12 +6282,12 @@ } { \@@_scan_immediate_operands_bad: } } -\cs_new_protected_nopar:Npn \@@_scan_immediate_operands_aux: +\cs_new_protected:Npn \@@_scan_immediate_operands_aux: { \@@_prev_input:V \l_@@_head_tl \@@_scan_extension_operands: } -\cs_new_protected_nopar:Npn \@@_scan_immediate_operands_bad: +\cs_new_protected:Npn \@@_scan_immediate_operands_bad: { \@@_back_input: \@@_prev_input_gpop:N \l_@@_head_tl @@ -6029,7 +6300,7 @@ % % \begin{macro}{\@@_scan_pdfdest_operands:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scan_pdfdest_operands: +\cs_new_protected:Npn \@@_scan_pdfdest_operands: { \@@_scan_keyword:nTF { nNuUmM } { \@@_scan_int: } @@ -6089,7 +6360,7 @@ % We define all those commands in one go, from % |max_non_prefixed_command+1=71| to |max_command=102|. % \begin{macrocode} -\cs_set_protected_nopar:Npn \@@_tmp:w +\cs_set_protected:Npn \@@_tmp:w { \@@_prev_input_gpush: \@@_prefixed_command: @@ -6101,11 +6372,11 @@ { \cs_new_eq:cN { @@_cmd_#1: } \@@_tmp:w } % \end{macrocode} % -% \begin{macro}[int]{\@@_prefixed_command:} +% \begin{macro}{\@@_prefixed_command:} % Accumulated prefix codes so far are stored as the last item of % the previous-input sequence. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_prefixed_command: +\cs_new_protected:Npn \@@_prefixed_command: { \int_while_do:nNnn \l_@@_head_cmd_int = { \@@_tex_use:n { prefix } } @@ -6144,28 +6415,28 @@ % \begin{macro}{\@@_after_assignment:} % \begin{macro}{\@@_omit_after_assignment:w} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_after_assignment: +\cs_new_protected:Npn \@@_after_assignment: { \@@_back_input_gtl:N \g_@@_after_assignment_gtl \gtl_gclear:N \g_@@_after_assignment_gtl } -\cs_new_protected_nopar:Npn \@@_omit_after_assignment:w +\cs_new_protected:Npn \@@_omit_after_assignment:w #1 \@@_after_assignment: { } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_prefixed_new:nn} +% \begin{macro}{\@@_prefixed_new:nn} % \begin{macrocode} \cs_new_protected:Npn \@@_prefixed_new:nn #1#2 { - \cs_new_protected_nopar:cpn + \cs_new_protected:cpn { @@_prefixed_ \@@_tex_use:n {#1} : } {#2} } % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_assign_token:n} +% \begin{macro}{\@@_assign_token:n} % \begin{macrocode} \cs_new_protected:Npn \@@_assign_token:n #1 { @@ -6177,9 +6448,9 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_assign_register:} +% \begin{macro}{\@@_assign_register:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_assign_register: +\cs_new_protected:Npn \@@_assign_register: { \@@_prev_input_gpop:N \l_@@_head_tl \tl_use:N \l_@@_head_tl \scan_stop: @@ -6188,7 +6459,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_assign_value:nn} +% \begin{macro}{\@@_assign_value:nn} % \begin{macrocode} \cs_new_protected:Npn \@@_assign_value:nn #1#2 { @@ -6212,7 +6483,7 @@ % \begin{macrocode} \@@_prefixed_new:nn { toks_register } % 71 { - \int_compare:nNnT \l_@@_head_char_int = \c_zero + \int_compare:nNnT \l_@@_head_char_int = 0 { % \toks \@@_prev_input_gpush:N \l_@@_head_tl \@@_print_action: @@ -6223,7 +6494,7 @@ } \@@_prefixed_new:nn { assign_toks } % 72 { \@@_assign_toks: } -\cs_new_protected_nopar:Npn \@@_assign_toks: +\cs_new_protected:Npn \@@_assign_toks: { \@@_prev_input_silent:V \l_@@_head_tl \@@_print_action: @@ -6235,7 +6506,7 @@ \l_@@_head_cmd_int = { \@@_tex_use:n { toks_register } } { \@@_prev_input:V \l_@@_head_tl - \int_compare:nNnT \l_@@_head_char_int = \c_zero + \int_compare:nNnT \l_@@_head_char_int = 0 { \@@_scan_int: } } { @@ -6274,7 +6545,7 @@ } \@@_prefixed_new:nn { set_aux } % 79 { % prevdepth = 1, spacefactor = 102 - \int_compare:nNnTF \l_@@_head_char_int = \c_one + \int_compare:nNnTF \l_@@_head_char_int = 1 { \@@_assign_value:nn { } { \@@_scan_normal_dimen: } } { \@@_assign_value:nn { } { \@@_scan_int: } } } @@ -6299,7 +6570,7 @@ \prg_replicate:nn { \tl_if_head_eq_meaning:VNT - \l_@@_defined_tl \tex_parshape:D { \c_two * } + \l_@@_defined_tl \tex_parshape:D { 2 * } \tl_tail:N \l_@@_defined_tl } { \@@_scan_int: } @@ -6438,7 +6709,7 @@ } \prg_new_conditional:Npnn \@@_read_to_cs_safe:n #1 { TF } { - \int_compare:nNnTF { \etex_interactionmode:D } > { 1 } + \int_compare:nNnTF { \tex_interactionmode:D } > { 1 } { \prg_return_true: } { \int_compare:nNnTF {#1} < { 0 } @@ -6467,7 +6738,7 @@ \tl_set:NV \l_@@_defining_tl \l_@@_tmpa_tl \tl_put_right:NV \l_@@_defining_tl \l_@@_head_tl \@@_prev_input_gpush:N \l_@@_head_tl - \int_compare:nNnTF \l_@@_head_char_int < \c_two + \int_compare:nNnTF \l_@@_head_char_int < 2 { % def/gdef \@@_scan_r_token: \tl_put_right:NV \l_@@_defining_tl \l_@@_defined_tl @@ -6522,7 +6793,7 @@ \@@_prev_input_gpop:N \l_@@_tmpa_tl \tl_put_left:NV \l_@@_head_tl \l_@@_tmpa_tl \tl_use:N \l_@@_head_tl \scan_stop: - \@@_print_action:x { \tl_to_str:N \l_@@_head_tl } + \@@_print_assignment:x { \tl_to_str:N \l_@@_head_tl } } % \end{macrocode} % @@ -6563,13 +6834,13 @@ % \tn{muskip}, and commands with a built-in number). % \begin{macrocode} \@@_prefixed_new:nn { register } % 89 - { \@@_do_register:N \c_zero } + { \@@_do_register:N 0 } \@@_prefixed_new:nn { advance } % 90 - { \@@_do_operation:N \c_one } + { \@@_do_operation:N 1 } \@@_prefixed_new:nn { multiply } % 91 - { \@@_do_operation:N \c_two } + { \@@_do_operation:N 2 } \@@_prefixed_new:nn { divide } % 92 - { \@@_do_operation:N \c_three } + { \@@_do_operation:N 3 } % \end{macrocode} % % \begin{macro}{\@@_do_operation:N, \@@_do_operation_fail:w} @@ -6605,7 +6876,7 @@ } } } -\cs_new_protected_nopar:Npn \@@_do_operation_fail:w +\cs_new_protected:Npn \@@_do_operation_fail:w { \@@_error:nnnnn { after-advance } { } { } { } { } \@@_prev_input_gpop:N \l_@@_tmpa_tl @@ -6623,17 +6894,17 @@ } \cs_new_protected:Npn \@@_do_register_aux:Nn #1#2 { - \int_compare:nNnTF { \tl_tail:n {#2} } = \c_zero + \int_compare:nNnTF { \tl_tail:n {#2} } = 0 { \@@_prev_input_gpush:N \l_@@_head_tl - \@@_print_action: + \@@_print_assignment: \@@_scan_int: \@@_prev_input_gpop:N \l_@@_head_tl \@@_prev_input_silent:V \l_@@_head_tl } { \@@_prev_input_silent:V \l_@@_head_tl - \@@_print_action: + \@@_print_assignment: } \tl_set_eq:NN \l_@@_defined_tl \l_@@_head_tl \exp_args:NNf \@@_do_register_set:Nn #1 @@ -6646,7 +6917,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_do_register_set:Nn #1#2 { - \int_compare:nNnTF {#1} = \c_zero + \int_compare:nNnTF {#1} = 0 { % truly register command \@@_scan_optional_equals: } @@ -6654,7 +6925,7 @@ \@@_scan_keyword:nF { bByY } { \@@_prev_input_silent:n { by } } } - \int_compare:nNnTF {#1} < \c_two + \int_compare:nNnTF {#1} < 2 { \int_case:nnF {#2} { @@ -6673,7 +6944,7 @@ % % The following is used for instance when making accents. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_do_assignments: +\cs_new_protected:Npn \@@_do_assignments: { \@@_get_x_non_relax: \@@_set_cmd: @@ -6718,7 +6989,8 @@ % \tn{pdffilemoddate}, \tn{pdffilesize}, \tn{pdfmdfivesum}, % \tn{pdffiledump}, \tn{pdfmatch}, \tn{pdflastmatch}, % \tn{pdfuniformdeviate}, \tn{pdfnormaldeviate}, \tn{pdfinsertht}, -% \tn{pdfximagebbox}, and \tn{jobname}. +% \tn{pdfximagebbox}, \tn{jobname}, and in +% \LuaTeX{} \tn{directlua}, \tn{expanded}, \tn{luaescapestring}. % \item |the=111| for \tn{the}, \tn{unexpanded}, and \tn{detokenize}. % \item |top_bot_mark=112| \tn{topmark}, \tn{firstmark}, \tn{botmark}, % \tn{splitfirstmark}, \tn{splitbotmark}, \tn{topmarks}, @@ -6731,7 +7003,7 @@ % Let \TeX{} trigger an error. % \begin{macrocode} \@@_new_tex_expandable:nn { undefined_cs } % 103 - { \tl_use:N \l_@@_head_tl \@@_print_action: } + { \tl_use:N \l_@@_head_tl \@@_print_expansion: } % \end{macrocode} % % \begin{macro}{\@@_expandafter:, \@@_unless:, \@@_unless_bad:} @@ -6741,26 +7013,26 @@ \token_if_eq_meaning:NNTF \l_@@_head_token \tex_expandafter:D { \@@_expandafter: } { \@@_unless: } } -\cs_new_protected_nopar:Npn \@@_expandafter: +\cs_new_protected:Npn \@@_expandafter: { \gtl_set_eq:NN \l_@@_tmpb_gtl \l_@@_head_gtl \@@_get_next: \gtl_concat:NNN \l_@@_head_gtl \l_@@_tmpb_gtl \l_@@_head_gtl \@@_prev_input_gpush_gtl:N \l_@@_head_gtl - \@@_print_action:x { \gtl_to_str:N \l_@@_head_gtl } + \@@_print_expansion:x { \gtl_to_str:N \l_@@_head_gtl } \@@_get_next: \@@_token_if_expandable:NTF \l_@@_head_token - { \@@_expand: } + { \@@_expand_do:N \prg_do_nothing: } { \@@_back_input: } \@@_prev_input_gpop:N \l_@@_head_gtl \@@_set_action_text:x { back_input: ~ \gtl_to_str:N \l_@@_head_gtl } \gtl_pop_left:N \l_@@_head_gtl \@@_back_input: - \@@_print_action: + \@@_print_expansion: } -\cs_new_protected_nopar:Npn \@@_unless: +\cs_new_protected:Npn \@@_unless: { \@@_get_token: \int_compare:nNnTF @@ -6776,7 +7048,7 @@ } { \@@_unless_bad: } } -\cs_new_protected_nopar:Npn \@@_unless_bad: +\cs_new_protected:Npn \@@_unless_bad: { \@@_error:nnnnn { bad-unless } { } { } { } { } \@@_back_input: @@ -6784,30 +7056,72 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_noexpand:, \@@_pdfprimitive:} +% \begin{macro}{\@@_noexpand:N, \@@_noexpand_after:, \@@_pdfprimitive:} +% Currently not fully implemented. +% +% The argument of \cs{@@_noexpand:N} is \cs{prg_do_nothing:} when +% \tn{noexpand} is hit by \tn{expandafter}; otherwise it is one of +% various loop commands (\cs{@@_get_x_next:}, +% \cs{@@_get_x_or_protected:}, \cs{@@_get_token_xdef:}, +% \cs{@@_get_token_x:}) that would call \cs{@@_get_next:} and possibly +% expand the token more. For these cases we simply stop after +% \cs{@@_get_next:} and if the token is expandable we pretend its +% meaning is \tn{relax}. +% +% The case of \tn{expandafter} (so \cs{prg_do_nothing:}) is tougher. +% Do nothing if the next token is an explicit non-active character +% (begin-group and end-group characters are detected by +% \cs{l_@@_head_tl}, the rest by testing if the token is definable). +% Otherwise the token must be marked with \cs{notexpanded:} (even if +% the token is currently a non-expandable primitive, as its meaning +% can be changed by the code skipped over by \tn{expandafter}). That +% \cs{notexpanded:} marker should be removed if the token is taken as +% the argument of a macro, but we fail to do that. We set the +% \cs{notexpanded:\ldots{}} command to be a special \tn{relax} marker +% to make it quickly recognizable in \cs{@@_get_next:}. This is +% incidentally the same meaning used by \TeX{} for expandable commands. % \begin{macrocode} \@@_new_tex_expandable:nn { no_expand } % 105 { \token_if_eq_meaning:NNTF \l_@@_head_token \tex_noexpand:D - { \@@_noexpand: } + { \@@_noexpand:N } { \@@_pdfprimitive: } } -\cs_new_protected_nopar:Npn \@@_noexpand: +\cs_new_protected:Npn \@@_noexpand:N #1 { \@@_get_token: - \@@_back_input: - \@@_token_if_expandable:NT \l_@@_head_token + \cs_if_eq:NNTF #1 \prg_do_nothing: { - \cs_gset_protected_nopar:Npx \@@_get_next: + \tl_if_empty:NTF \l_@@_head_tl + { \@@_back_input: } { - \cs_gset_protected_nopar:Npn \@@_get_next: - { \exp_not:o { \@@_get_next: } } - \exp_not:o { \@@_get_next: } - \exp_not:n { \cs_set_eq:NN \l_@@_head_token \tex_relax:D } + \exp_after:wN \@@_token_if_definable:NTF \l_@@_head_tl + { \@@_noexpand_after: } + { \@@_back_input: } } } + { + \@@_back_input: + \@@_get_next: + \@@_token_if_expandable:NT \l_@@_head_token + { \cs_set_eq:NN \l_@@_head_token \@@_special_relax: } + } } -\cs_new_protected_nopar:Npn \@@_pdfprimitive: +\cs_new_protected:Npn \@@_noexpand_after: + { + \group_begin: + \@@_set_escapechar:n { 92 } + \exp_args:NNc + \group_end: + \@@_noexpand_after:N + { notexpanded: \exp_after:wN \token_to_str:N \l_@@_head_tl } + } +\cs_new_protected:Npn \@@_noexpand_after:N #1 + { + \cs_gset_eq:NN #1 \@@_special_relax: + \@@_back_input:n {#1} + } +\cs_new_protected:Npn \@@_pdfprimitive: { \@@_not_implemented:n { pdfprimitive } } % \end{macrocode} % \end{macro} @@ -6826,23 +7140,23 @@ { \@@_insert_relax: } { \@@_input: } } } -\cs_new_protected_nopar:Npn \@@_endinput: +\cs_new_protected:Npn \@@_endinput: { \group_begin: \msg_warning:nn { unravel } { endinput-ignored } \group_end: - \@@_print_action: + \@@_print_expansion: } -\cs_new_protected_nopar:Npn \@@_scantokens: +\cs_new_protected:Npn \@@_scantokens: { \@@_prev_input_gpush: \@@_scan_toks:NN \c_false_bool \c_false_bool \@@_prev_input_gpop:N \l_@@_tmpa_tl \tl_set_rescan:Nno \l_@@_head_tl { } \l_@@_tmpa_tl \@@_back_input:V \l_@@_head_tl - \@@_print_action:x { \tl_to_str:N \l_@@_tmpa_tl } + \@@_print_expansion:x { \tl_to_str:N \l_@@_tmpa_tl } } -\cs_new_protected_nopar:Npn \@@_input: +\cs_new_protected:Npn \@@_input: { \@@_prev_input_gpush:N \l_@@_head_tl \@@_scan_file_name: @@ -6850,7 +7164,7 @@ \tl_set:Nx \l_@@_tmpa_tl { \tl_tail:N \l_@@_head_tl } \@@_file_get:nN \l_@@_tmpa_tl \l_@@_tmpa_tl \@@_back_input:V \l_@@_tmpa_tl - \@@_print_action:x { \tl_to_str:N \l_@@_head_tl } + \@@_print_expansion:x { \tl_to_str:N \l_@@_head_tl } } % \end{macrocode} % \end{macro} @@ -6860,13 +7174,13 @@ \@@_new_tex_expandable:nn { cs_name } % 109 { \@@_prev_input_gpush:N \l_@@_head_tl - \@@_print_action: + \@@_print_expansion: \@@_csname_loop: \@@_prev_input_silent:V \l_@@_head_tl \@@_prev_input_gpop:N \l_@@_head_tl \@@_back_input_tl_o: } -\cs_new_protected_nopar:Npn \@@_csname_loop: +\cs_new_protected:Npn \@@_csname_loop: { \@@_get_x_next: \@@_gtl_if_head_is_definable:NTF \l_@@_head_gtl @@ -6891,13 +7205,13 @@ \@@_new_tex_expandable:nn { convert } % 110 { \@@_prev_input_gpush:N \l_@@_head_tl - \@@_print_action: + \@@_print_expansion: \int_case:nn \l_@@_head_char_int { 0 \@@_scan_int: 1 \@@_scan_int: - 2 { \@@_get_next: \@@_prev_input:V \l_@@_head_tl } - 3 { \@@_get_next: \@@_prev_input:V \l_@@_head_tl } + 2 \@@_convert_string: + 3 \@@_convert_meaning: 4 \@@_scan_font_ident: 8 \@@_scan_font_ident: 9 \@@_scan_font_ident: @@ -6925,18 +7239,41 @@ { 28 } \@@_scan_int: { 30 } \@@_scan_int: { 31 } \@@_scan_pdfximagebbox: + { 33 } \@@_scan_directlua: + { 34 } \@@_scan_pdf_ext_toks: + { 35 } \@@_scan_pdf_ext_toks: + { 40 } + { + \@@_scan_int: + \@@_prev_input_silent:n { ~ } + \@@_scan_int: + } } \@@_prev_input_gpop:N \l_@@_head_tl \@@_back_input_tl_o: } -\cs_new_protected_nopar:Npn \@@_scan_pdfstrcmp: +\cs_new_protected:Npn \@@_convert_string: + { + \@@_get_next: + \tl_if_empty:NTF \l_@@_head_tl + { \@@_prev_input:x { \gtl_to_str:N \l_@@_head_gtl } } + { \@@_prev_input:V \l_@@_head_tl } + } +\cs_new_protected:Npn \@@_convert_meaning: + { + \@@_get_next: + \tl_if_empty:NTF \l_@@_head_tl + { \@@_prev_input:n { \l_@@_head_token } } + { \@@_prev_input:V \l_@@_head_tl } + } +\cs_new_protected:Npn \@@_scan_pdfstrcmp: { \@@_scan_toks_to_str: \@@_scan_toks_to_str: } -\cs_new_protected_nopar:Npn \@@_scan_pdfximagebbox: +\cs_new_protected:Npn \@@_scan_pdfximagebbox: { \@@_scan_int: \@@_scan_int: } -\cs_new_protected_nopar:Npn \@@_scan_pdfcolorstackinit: +\cs_new_protected:Npn \@@_scan_pdfcolorstackinit: { \@@_scan_keyword:nTF { pPaAgGeE } { \bool_set_true:N \l_@@_tmpa_bool } @@ -6945,13 +7282,13 @@ { \@@_scan_keyword:n { pPaAgGeE } } \@@_scan_toks_to_str: } -\cs_new_protected_nopar:Npn \@@_scan_pdffiledump: +\cs_new_protected:Npn \@@_scan_pdffiledump: { \@@_scan_keyword:nT { oOfFfFsSeEtT } \@@_scan_int: \@@_scan_keyword:nT { lLeEnNgGtThH } \@@_scan_int: \@@_scan_pdf_ext_toks: } -\cs_new_protected_nopar:Npn \@@_scan_pdfmatch: +\cs_new_protected:Npn \@@_scan_pdfmatch: { \@@_scan_keyword:n { iIcCaAsSeE } \@@_scan_keyword:nT { sSuUbBcCoOuUnNtT } @@ -6959,21 +7296,33 @@ \@@_scan_pdf_ext_toks: \@@_scan_pdf_ext_toks: } +\sys_if_engine_luatex:T + { + \cs_new_protected:Npn \@@_scan_directlua: + { + \@@_get_x_non_relax: + \token_if_eq_catcode:NNTF \l_@@_head_token \c_group_begin_token + { \@@_back_input: } + { + \@@_scan_int: + \@@_get_x_non_relax: + } + \@@_scan_pdf_ext_toks: + } + } % \end{macrocode} % -% \begin{macro}{\@@_get_the:} +% \begin{macro}{\@@_get_the:N} +% |#1| is \cs{@@_get_token_xdef:} in \tn{edef} or \tn{xdef}, +% \cs{@@_get_token_x:} in \tn{message} and the like, and can be other +% commands. % \begin{macrocode} \@@_new_tex_expandable:nn { the } % 111 - { - \@@_get_the: - \tl_set:Nx \l_@@_tmpa_tl { \exp_args:NV \exp_not:o \l_@@_head_tl } - \@@_back_input:V \l_@@_tmpa_tl - \@@_print_action: - } -\cs_new_protected_nopar:Npn \@@_get_the: + { \@@_get_the:N } +\cs_new_protected:Npn \@@_get_the:N #1 { \@@_prev_input_gpush:N \l_@@_head_tl - \@@_print_action: + \@@_print_expansion: \int_if_odd:nTF \l_@@_head_char_int { % \unexpanded, \detokenize \@@_scan_toks:NN \c_false_bool \c_false_bool @@ -6992,6 +7341,24 @@ \tl_set:Nx \l_@@_head_tl { \exp_not:N \exp_not:n { \tl_tail:N \l_@@_head_tl } } } + \cs_if_eq:NNTF #1 \@@_get_token_xdef: + { + \tl_put_right:NV \l_@@_defining_tl \l_@@_head_tl + \@@_prev_input:V \l_@@_head_tl + } + { + \cs_if_eq:NNTF #1 \@@_get_token_x: + { + \@@_exp_args:NNx \gtl_set:Nn \l_@@_tmpb_gtl { \l_@@_head_tl } + \@@_prev_input_gtl:N \l_@@_tmpb_gtl + } + { + \tl_set:Nx \l_@@_tmpa_tl { \exp_args:NV \exp_not:o \l_@@_head_tl } + \@@_back_input:V \l_@@_tmpa_tl + } + \@@_print_expansion: + } + #1 } % \end{macrocode} % \end{macro} @@ -7013,30 +7380,30 @@ % \subsubsection{Conditionals} % % ^^A todo: simply use \cs{@@_input_gpop:N} right away. -% \begin{macro}[int]{\@@_pass_text:} +% \begin{macro}{\@@_pass_text:} % \begin{macro}{\@@_pass_text_done:w} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_pass_text: +\cs_new_protected:Npn \@@_pass_text: { \@@_input_if_empty:TF { \@@_pass_text_empty: } { \@@_input_get:N \l_@@_tmpb_gtl \if_true: - \if_case:w \gtl_head_do:NN \l_@@_tmpb_gtl \c_one + \if_case:w \gtl_head_do:NN \l_@@_tmpb_gtl \c_one_int \exp_after:wN \@@_pass_text_done:w \fi: \@@_input_gpop:N \l_@@_tmpb_gtl \exp_after:wN \@@_pass_text: \else: \use:c { fi: } - \int_set_eq:NN \l_@@_if_nesting_int \c_one + \int_set:Nn \l_@@_if_nesting_int { 1 } \@@_input_gpop:N \l_@@_tmpb_gtl \exp_after:wN \@@_pass_text_nested: \fi: } } -\cs_new_protected_nopar:Npn \@@_pass_text_done:w +\cs_new_protected:Npn \@@_pass_text_done:w { \@@_get_next: \token_if_eq_meaning:NNT \l_@@_head_token \fi: { \if_true: } @@ -7063,7 +7430,7 @@ % \cs{fi:}, the nesting integer is decremented before removing most % \cs{fi:}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_pass_text_nested: +\cs_new_protected:Npn \@@_pass_text_nested: { \@@_input_if_empty:TF { \@@_pass_text_empty: } @@ -7080,7 +7447,7 @@ \int_incr:N \l_@@_if_nesting_int \fi: \@@_input_gpop:N \l_@@_unused_gtl - \int_compare:nNnTF \l_@@_if_nesting_int = \c_zero + \int_compare:nNnTF \l_@@_if_nesting_int = 0 { \@@_pass_text: } { \@@_pass_text_nested: } } @@ -7090,7 +7457,7 @@ % % \begin{macro}{\@@_pass_text_empty:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_pass_text_empty: +\cs_new_protected:Npn \@@_pass_text_empty: { \@@_error:nnnnn { runaway-if } { } { } { } { } \@@_exit:w @@ -7098,7 +7465,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_cond_push:, \@@_cond_pop:} +% \begin{macro}{\@@_cond_push:, \@@_cond_pop:} % \begin{macrocode} \cs_new_protected:Npn \@@_cond_push: { @@ -7107,7 +7474,7 @@ \int_gincr:N \g_@@_if_depth_int \int_gzero:N \g_@@_if_limit_int } -\cs_new_protected_nopar:Npn \@@_cond_pop: +\cs_new_protected:Npn \@@_cond_pop: { \int_gset:Nn \g_@@_if_limit_int { \tl_head:N \g_@@_if_limit_tl } @@ -7126,7 +7493,7 @@ { \int_gset:Nn \g_@@_if_limit_int {#1} } { \tl_clear:N \l_@@_tmpa_tl - \prg_replicate:nn { \g_@@_if_depth_int - #2 - \c_one } + \prg_replicate:nn { \g_@@_if_depth_int - #2 - 1 } { \tl_put_right:Nx \l_@@_tmpa_tl { { \tl_head:N \g_@@_if_limit_tl } } @@ -7160,7 +7527,7 @@ } { \@@_prev_input_gpush:N \l_@@_head_tl - \@@_print_action: + \@@_print_expansion: \int_case:nn \l_@@_head_char_int { { 0 } { \@@_test_two_chars: } % if @@ -7208,7 +7575,7 @@ \cs_new_protected:Npn \@@_cond_true:n #1 { \@@_change_if_limit:nn { 3 } {#1} % wait for else/fi - \@@_print_action:x { \g_@@_action_text_str = true } + \@@_print_expansion:x { \g_@@_action_text_str = true } } % \end{macrocode} % \end{macro} @@ -7220,7 +7587,11 @@ { \@@_cond_false_loop:n {#1} \@@_cond_false_common: - \@@_print_action:x { \g_@@_action_text_str = false } + \@@_print_expansion:x + { + \g_@@_action_text_str = false ~ + => ~ skipped ~ to ~ \iow_char:N\\fi + } } \cs_new_protected:Npn \@@_cond_false_loop:n #1 { @@ -7239,7 +7610,7 @@ \@@_cond_false_loop:n {#1} } } -\cs_new_protected_nopar:Npn \@@_cond_false_common: +\cs_new_protected:Npn \@@_cond_false_common: { \token_if_eq_meaning:NNTF \l_@@_head_token \fi: { \@@_cond_pop: } @@ -7254,7 +7625,7 @@ { #1 \@@_get_x_non_blank: - \tl_if_in:nVF { < = > } \l_@@_head_tl + \@@_tl_if_in:ooTF { < = > } \l_@@_head_tl { } { \@@_error:nnnnn { missing-equals } { } { } { } { } \@@_back_input: @@ -7270,14 +7641,14 @@ % ^^A todo: fix non-brace begin-group and end-group tokens % \begin{macro}{\@@_test_two_chars:, \@@_test_two_chars_aux:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_test_two_chars: +\cs_new_protected:Npn \@@_test_two_chars: { \@@_test_two_chars_aux: \@@_prev_input:V \l_@@_head_tl \@@_test_two_chars_aux: \@@_prev_input:V \l_@@_head_tl } -\cs_new_protected_nopar:Npn \@@_test_two_chars_aux: +\cs_new_protected:Npn \@@_test_two_chars_aux: { \@@_get_x_next: \gtl_if_tl:NF \l_@@_head_gtl @@ -7293,31 +7664,63 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_test_ifx:n, \@@_test_ifx_aux:w} +% \begin{macro}{\@@_test_ifx:n, \@@_test_ifx_str:NN, \@@_test_ifx_aux:NNN, \@@_test_ifx_aux:w} +% The token equal to \tn{ifx} is pushed as a previous input to show an +% action nicely, then retrieved as \cs{l_@@_tmpa_tl} after getting the +% next two tokens as |tmpb| and |head|. Then we call +% \cs{l_@@_tmpa_tl} followed by these two tokens. A previous +% implementation made sure to get these tokens from unpacking the +% |gtl|, presumably (I should have documented, now I might be missing +% something) to deal nicely with the master counter in case these +% tokens are braces. On the other hand we must take care of tokens +% affected by \tn{noexpand} and whose current definition is +% expandable, in which case the trustworthy \tn{meaning} is that of +% the \cs{l_@@_head_token} or \cs{l_@@_tmpb_token} rather than that of +% the token in \cs{l_@@_head_gtl} or \cs{l_@@_tmpb_gtl}. % \begin{macrocode} \cs_new_protected:Npn \@@_test_ifx:n #1 { \@@_prev_input_gpush:N \l_@@_head_tl - \@@_print_action: + \@@_print_expansion: \@@_get_next: \gtl_set_eq:NN \l_@@_tmpb_gtl \l_@@_head_gtl + \cs_set_eq:NN \l_@@_tmpb_token \l_@@_head_token \@@_get_next: \@@_prev_input_gpop:N \l_@@_tmpa_tl \@@_set_action_text:x { Compare:~ \tl_to_str:N \l_@@_tmpa_tl - \gtl_to_str:N \l_@@_tmpb_gtl - \gtl_to_str:N \l_@@_head_gtl + \@@_test_ifx_str:NN \l_@@_tmpb_token \l_@@_tmpb_gtl + \@@_test_ifx_str:NN \l_@@_head_token \l_@@_head_gtl } - \gtl_head_do:NN \l_@@_tmpb_gtl \@@_test_ifx_aux:w + \@@_test_ifx_aux:NNN \l_@@_tmpb_token \l_@@_tmpb_gtl + \@@_test_ifx_aux:w \exp_after:wN \@@_cond_true:n \else: \exp_after:wN \@@_cond_false:n \fi: {#1} } -\cs_new_nopar:Npn \@@_test_ifx_aux:w - { \gtl_head_do:NN \l_@@_head_gtl \l_@@_tmpa_tl } +\cs_new:Npn \@@_test_ifx_str:NN #1#2 + { + \token_if_eq_meaning:NNT #1 \@@_special_relax: + { \iow_char:N \\notexpanded: } + \gtl_to_str:N #2 + } +\cs_new_protected:Npn \@@_test_ifx_aux:NNN #1#2#3 + { + \token_if_eq_meaning:NNTF #1 \@@_special_relax: + { + \gtl_head_do:NN #2 \@@_token_if_expandable:NTF + { #3 #1 } { \gtl_head_do:NN #2 #3 } + } + { \gtl_head_do:NN #2 #3 } + } +\cs_new:Npn \@@_test_ifx_aux:w + { + \@@_test_ifx_aux:NNN \l_@@_head_token \l_@@_head_gtl + \l_@@_tmpa_tl + } % \end{macrocode} % \end{macro} % @@ -7326,7 +7729,7 @@ \cs_new_protected:Npn \@@_test_case:n #1 { \@@_prev_input_gpush:N \l_@@_head_tl - \@@_print_action: + \@@_print_expansion: \bool_if:NT \g_@@_internal_debug_bool { \iow_term:n { {\ifcase level~#1} } } \@@_scan_int: \@@_prev_input_get:N \l_@@_head_tl @@ -7334,11 +7737,11 @@ % ^^A does text_case_aux use prev_input_seq? \exp_args:No \@@_test_case_aux:nn { \l_@@_head_tl } {#1} \@@_prev_input_gpop:N \l_@@_head_tl - \@@_print_action:x { \tl_to_str:N \l_@@_head_tl } + \@@_print_expansion:x { \tl_to_str:N \l_@@_head_tl } } \cs_new_protected:Npn \@@_test_case_aux:nn #1#2 { - \int_compare:nNnTF {#1} = \c_zero + \int_compare:nNnTF {#1} = 0 { \@@_change_if_limit:nn { 4 } {#2} } { \@@_pass_text: @@ -7363,7 +7766,7 @@ % % \begin{macro}{\@@_test_ifdefined:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_test_ifdefined: +\cs_new_protected:Npn \@@_test_ifdefined: { \@@_input_if_empty:TF { \@@_pass_text_empty: } @@ -7387,7 +7790,7 @@ % % \begin{macro}{\@@_test_ifcsname:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_test_ifcsname: +\cs_new_protected:Npn \@@_test_ifcsname: { \@@_csname_loop: \@@_prev_input:V \l_@@_head_tl @@ -7400,9 +7803,9 @@ { \int_compare:nNnTF \l_@@_head_char_int > \g_@@_if_limit_int { - \int_compare:nNnTF \g_@@_if_limit_int = \c_zero + \int_compare:nNnTF \g_@@_if_limit_int = 0 { - \int_compare:nNnTF \g_@@_if_depth_int = \c_zero + \int_compare:nNnTF \g_@@_if_depth_int = 0 { \@@_error:nnnnn { extra-fi-or-else } { } { } { } { } } { \@@_insert_relax: } } @@ -7410,7 +7813,7 @@ } { \@@_set_action_text: - \int_compare:nNnF \l_@@_head_char_int = \c_two + \int_compare:nNnF \l_@@_head_char_int = 2 { \@@_fi_or_else_loop: \@@_set_action_text:x @@ -7419,14 +7822,14 @@ => ~ skipped ~ to ~ \tl_to_str:N \l_@@_head_tl } } - % ^^A todo: in this print_action the token itself is missing. - \@@_print_action: + % ^^A todo: in the terminal output the token itself is missing. + \@@_print_expansion: \@@_cond_pop: } } -\cs_new_protected_nopar:Npn \@@_fi_or_else_loop: +\cs_new_protected:Npn \@@_fi_or_else_loop: { - \int_compare:nNnF \l_@@_head_char_int = \c_two + \int_compare:nNnF \l_@@_head_char_int = 2 { \@@_pass_text: \@@_set_cmd: @@ -7464,7 +7867,7 @@ % \end{variable} % \end{macro} % -% \begin{macro}[int]{\@@_print:n, \@@_print:x} +% \begin{macro}{\@@_print:n, \@@_print:x, \@@_log:n} % \begin{macrocode} \cs_new_protected:Npn \@@_print:n #1 { @@ -7474,20 +7877,34 @@ } \cs_new_protected:Npn \@@_print:x { \@@_exp_args:Nx \@@_print:n } +\cs_new_protected:Npn \@@_log:n #1 + { + \tl_set:Nn \l_@@_print_tl {#1} + \@@_print_normalize_null: + \@@_exp_args:Nx \iow_log:n { \l_@@_print_tl } + } % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_print_message:nn} +% \begin{macro}{\@@_print_message:nn} % The message to be printed should come already detokenized, as~|#2|. % It will be wrapped to 80 characters per line, with~|#1| before each -% line. +% line. The message is properly suppressed (or sent only to the log) +% according to \cs{g_@@_online_int}. % \begin{macrocode} \cs_new_protected:Npn \@@_print_message:nn #1 #2 - { \iow_wrap:nnnN { #1 #2 } { #1 } { } \@@_print:n } + { + \int_compare:nNnF \g_@@_online_int < 0 + { + \int_compare:nNnTF \g_@@_online_int = 0 + { \iow_wrap:nnnN { #1 #2 } { #1 } { } \@@_log:n } + { \iow_wrap:nnnN { #1 #2 } { #1 } { } \@@_print:n } + } + } % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_set_action_text:x} +% \begin{macro}{\@@_set_action_text:x} % \begin{macrocode} \cs_new_protected:Npn \@@_set_action_text:x #1 { @@ -7499,35 +7916,34 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_set_action_text:} +% \begin{macro}{\@@_set_action_text:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_set_action_text: +\cs_new_protected:Npn \@@_set_action_text: { \@@_set_action_text:x { \tl_to_str:N \l_@@_head_tl \tl_if_single_token:VT \l_@@_head_tl - { = ~ \exp_after:wN \token_to_meaning:N \l_@@_head_tl } + { = ~ \token_to_meaning:N \l_@@_head_token } } } % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_print_state:} +% \begin{macro}{\@@_print_state:} % \begin{macrocode} \cs_new_protected:Npn \@@_print_state: { \group_begin: \@@_set_escapechar:n { 92 } \tl_use:N \g_@@_before_print_state_tl - \int_compare:nNnT \g_@@_noise_int > \c_zero + \int_compare:nNnT \g_@@_online_int > 0 { \@@_print_state_output: \@@_print_state_prev: \@@_print_state_input: } \group_end: - \@@_prompt: } % \end{macrocode} % \end{macro} @@ -7537,7 +7953,7 @@ % The \cs{@@_str_truncate_left:nn} function trims |#1| if needed, to % fit in a maximum of \cs{g_@@_max_output_int} characters. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_print_state_output: +\cs_new_protected:Npn \@@_print_state_output: { \@@_exp_args:Nx \@@_print_state_output:n { \gtl_to_str:N \g_@@_output_gtl } @@ -7556,7 +7972,7 @@ % \begin{macro}{\@@_print_state_prev:} % Never trim~|##1|. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_print_state_prev: +\cs_new_protected:Npn \@@_print_state_prev: { \seq_set_map:NNn \l_@@_tmpa_seq \g_@@_prev_input_seq { \@@_to_str:n {##1} } @@ -7578,7 +7994,7 @@ % \cs{@@_str_truncate_right:nn} function trims |#1| if needed, to fit % in a maximum of \cs{g_@@_max_input_int} characters. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_print_state_input: +\cs_new_protected:Npn \@@_print_state_input: { \@@_exp_args:Nx \@@_print_state_input:n { \@@_input_to_str: } @@ -7609,67 +8025,75 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_print_action:, \@@_print_action:x} +% \begin{macro}{\@@_print_action:, \@@_print_action:x, \@@_print_assignment:, \@@_print_assignment:x, \@@_print_expansion:, \@@_print_expansion:x, \@@_print_action_aux:N} +% Some of these commands are currently synonyms but we may decide to +% make some options act differently on them. % \begin{macrocode} \cs_new_protected:Npn \@@_print_action: - { - \int_gincr:N \g_@@_step_int - \@@_print:x - { - [===== - \bool_if:NT \g_@@_number_steps_bool - { ~ Step ~ \int_to_arabic:n { \g_@@_step_int } ~ } - =====]~ - \int_compare:nNnTF - { \str_count:N \g_@@_action_text_str } - > { \g_@@_max_action_int } - { - \str_range:Nnn \g_@@_action_text_str - { 1 } { \g_@@_max_action_int - 3 } ... - } - { \g_@@_action_text_str } - } - \@@_print_state: - } + { \@@_print_action_aux:N \g_@@_trace_other_bool } \cs_new_protected:Npn \@@_print_action:x #1 { \@@_set_action_text:x {#1} \@@_print_action: } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[int]{\@@_print_gtl_action:N} -% \begin{macrocode} -\cs_new_protected:Npn \@@_print_gtl_action:N #1 +\cs_new_protected:Npn \@@_print_assignment: + { \@@_print_action_aux:N \g_@@_trace_assigns_bool } +\cs_new_protected:Npn \@@_print_assignment:x #1 { - \@@_print_action:x { \gtl_to_str:N #1 } + \@@_set_action_text:x {#1} + \@@_print_assignment: + } +\cs_new_protected:Npn \@@_print_expansion: + { \@@_print_action_aux:N \g_@@_trace_expansion_bool } +\cs_new_protected:Npn \@@_print_expansion:x #1 + { + \@@_set_action_text:x {#1} + \@@_print_expansion: + } +\cs_new_protected:Npn \@@_print_action_aux:N #1 + { + \int_gdecr:N \g_@@_nonstop_int + \int_gincr:N \g_@@_step_int + \bool_if:NT #1 + { + \@@_print:x + { + [===== + \bool_if:NT \g_@@_number_steps_bool + { ~ Step ~ \int_to_arabic:n { \g_@@_step_int } ~ } + =====]~ + \int_compare:nNnTF + { \str_count:N \g_@@_action_text_str } + > { \g_@@_max_action_int } + { + \str_range:Nnn \g_@@_action_text_str + { 1 } { \g_@@_max_action_int - 3 } ... + } + { \g_@@_action_text_str } + } + \@@_print_state: + \@@_prompt: + } } % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_print_done:x} -% \begin{macrocode} -\cs_new_eq:NN \@@_print_done:x \@@_print_action:x -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[int]{\@@_print_assigned_token:, \@@_print_assigned_register:} +% \begin{macro}{\@@_print_assigned_token:, \@@_print_assigned_register:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_print_assigned_token: +\cs_new_protected:Npn \@@_print_assigned_token: { \@@_after_assignment: % ^^A todo: simplify - \@@_print_action:x + \@@_print_assignment:x { Set~ \exp_after:wN \token_to_str:N \l_@@_defined_tl = \exp_after:wN \token_to_meaning:N \l_@@_defined_tl } \@@_omit_after_assignment:w } -\cs_new_protected_nopar:Npn \@@_print_assigned_register: +\cs_new_protected:Npn \@@_print_assigned_register: { \@@_after_assignment: % ^^A todo: simplify - \@@_exp_args:Nx \@@_print_action:x + \@@_exp_args:Nx \@@_print_assignment:x { \exp_not:n { @@ -7684,10 +8108,10 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_print_welcome:} +% \begin{macro}{\@@_print_welcome:} % Welcome message. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_print_welcome: +\cs_new_protected:Npn \@@_print_welcome: { \@@_print_message:nn { } { @@ -7706,38 +8130,38 @@ { [=====~Start~=====] } } \@@_print_state: + \@@_prompt: } % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_print_outcome:} +% \begin{macro}{\@@_print_outcome:} % Final message. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_print_outcome: - { \@@_print:n { [=====~End~=====] } } +\cs_new_protected:Npn \@@_print_outcome: + { \@@_print_message:nn { } { [=====~End~=====] } } % \end{macrocode} % \end{macro} % % \subsubsection{Prompt} % -% \begin{macro}[int]{\@@_prompt:} +% \begin{macro}{\@@_prompt:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_prompt: +\cs_new_protected:Npn \@@_prompt: { - \int_gdecr:N \g_@@_nonstop_int - \int_compare:nNnF \g_@@_nonstop_int > \c_zero + \int_compare:nNnF \g_@@_nonstop_int > 0 { \group_begin: \@@_set_escapechar:n { -1 } - \int_set_eq:NN \tex_endlinechar:D \c_minus_one + \int_set:Nn \tex_endlinechar:D { -1 } \tl_use:N \g_@@_before_prompt_tl \@@_prompt_aux: \group_end: } } -\cs_new_protected_nopar:Npn \@@_prompt_aux: +\cs_new_protected:Npn \@@_prompt_aux: { - \int_compare:nNnT { \etex_interactionmode:D } = { 3 } + \int_compare:nNnT { \tex_interactionmode:D } = { 3 } { \bool_if:NTF \g_@@_explicit_prompt_bool { \ior_str_get:Nc \c_@@_prompt_ior } @@ -7755,7 +8179,7 @@ { m } { \@@_print_meaning: \@@_prompt_aux: } { q } { - \int_gset_eq:NN \g_@@_noise_int \c_minus_one + \int_gset:Nn \g_@@_online_int { -1 } \int_gzero:N \g_@@_nonstop_int } { x } @@ -7767,7 +8191,7 @@ { s } { \@@_prompt_scan_int:nn {#1} \@@_prompt_silent_steps:n } { o } { \@@_prompt_scan_int:nn {#1} - { \int_gset:Nn \g_@@_noise_int } } + { \int_gset:Nn \g_@@_online_int } } { C } { \@@_exp_args:Nx \use:n @@ -7801,7 +8225,7 @@ \cs_new_protected:Npn \@@_prompt_help: { \@@_print:n { "m":~meaning~of~first~token } - \@@_print:n { "q":~semi-quiet~(same~as~"o1") } + \@@_print:n { "q":~semi-quiet~(same~as~"o-1") } \@@_print:n { "x"/"X":~exit~this~instance~of~unravel/TeX } \@@_print:n { "s<num>":~do~<num>~steps~silently } \@@_print:n @@ -7813,12 +8237,12 @@ } \cs_new_protected:Npn \@@_prompt_silent_steps:n #1 { - \int_compare:nNnF {#1} < \c_zero + \int_compare:nNnF {#1} < 0 { - \int_gset_eq:NN \g_@@_noise_int \c_minus_one + \int_gset:Nn \g_@@_online_int { -1 } \tl_gset:Nn \g_@@_before_prompt_tl { - \int_gset_eq:NN \g_@@_noise_int \c_one + \int_gset:Nn \g_@@_online_int { 1 } \tl_gclear:N \g_@@_before_prompt_tl } \int_gset:Nn \g_@@_nonstop_int {#1} @@ -7832,7 +8256,7 @@ } \cs_new_protected:Npn \@@_prompt_vert:Nn #1#2 { - \int_gset_eq:NN \g_@@_noise_int \c_minus_one + \int_gset:Nn \g_@@_online_int { -1 } \tl_gset:Nf \g_@@_before_print_state_tl { \exp_args:NNf \exp_stop_f: \int_compare:nNnTF @@ -7843,12 +8267,12 @@ { \int_max:nn { \g_@@_nonstop_int } { 2 } } } { - \int_gset_eq:NN \g_@@_noise_int \c_one + \int_gset:Nn \g_@@_online_int { 1 } \tl_gclear:N \g_@@_before_print_state_tl } } } -\cs_new_protected_nopar:Npn \@@_prompt_all: +\cs_new_protected:Npn \@@_prompt_all: { \tl_gset:Nx \g_@@_tmpc_tl { @@ -7858,6 +8282,8 @@ \int_gset_eq:NN \g_@@_max_output_int \c_max_int \int_gset_eq:NN \g_@@_max_input_int \c_max_int \@@_print_state: + \int_gdecr:N \g_@@_nonstop_int + \@@_prompt: } \@@_prompt_all_aux:N \g_@@_max_output_int \@@_prompt_all_aux:N \g_@@_max_input_int @@ -7880,7 +8306,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_error:nnnnn, \@@_error:nxxxx} +% \begin{macro}{\@@_error:nnnnn, \@@_error:nxxxx} % Errors within a group to make sure that none of the \pkg{l3msg} % variables (or others) that may be currently in use in the code being % debugged are modified. @@ -7900,18 +8326,18 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_tex_msg_new:nnn} +% \begin{macro}{\@@_tex_msg_new:nnn} % This stores a \TeX{} error message. % \begin{macrocode} \cs_new_protected:Npn \@@_tex_msg_new:nnn #1#2#3 { - \cs_new_nopar:cpn { @@_tex_msg_error_#1: } {#2} - \cs_new_nopar:cpn { @@_tex_msg_help_#1: } {#3} + \cs_new:cpn { @@_tex_msg_error_#1: } {#2} + \cs_new:cpn { @@_tex_msg_help_#1: } {#3} } % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_tex_error:nn, \@@_tex_error:nV} +% \begin{macro}{\@@_tex_error:nn, \@@_tex_error:nV} % Throw the |tex-error| message, with arguments: |#2| which triggered % the error, \TeX{}'s error message, and \TeX{}'s help text. % \begin{macrocode} @@ -7928,7 +8354,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_tex_fatal_error:nn, \@@_tex_fatal_error:nV} +% \begin{macro}{\@@_tex_fatal_error:nn, \@@_tex_fatal_error:nV} % Throw the |tex-fatal| error message, with arguments: |#2| which % triggered the fatal error, \TeX{}'s error message, and \TeX{}'s % help text. @@ -7961,6 +8387,10 @@ max-output .int_gset:N = \g_@@_default_max_output_int , max-input .int_gset:N = \g_@@_default_max_input_int , number-steps .bool_gset:N = \g_@@_default_number_steps_bool , + online .int_gset:N = \g_@@_default_online_int , + trace-assigns .bool_gset:N = \g_@@_default_trace_assign_bool , + trace-expansion .bool_gset:N = \g_@@_default_trace_expansion_bool , + trace-other .bool_gset:N = \g_@@_default_trace_other_bool , welcome-message .bool_gset:N = \g_@@_default_welcome_message_bool , } \keys_define:nn { unravel } @@ -7971,14 +8401,18 @@ max-output .int_gset:N = \g_@@_max_output_int , max-input .int_gset:N = \g_@@_max_input_int , number-steps .bool_gset:N = \g_@@_number_steps_bool , + online .int_gset:N = \g_@@_online_int , + trace-assigns .bool_gset:N = \g_@@_trace_assigns_bool , + trace-expansion .bool_gset:N = \g_@@_trace_expansion_bool , + trace-other .bool_gset:N = \g_@@_trace_other_bool , welcome-message .bool_gset:N = \g_@@_welcome_message_bool , } % \end{macrocode} % -% The |machine| option is somewhat special so it is clearer to define -% it separately. The code is identical for |unravel/defaults| and -% |unravel| keys. To be sure of which options are set, use |.meta:nn| -% and give the path explicitly. +% The |machine| and |trace| options are somewhat special so it is +% clearer to define them separately. The code is identical for +% |unravel/defaults| and |unravel| keys. To be sure of which options +% are set, use |.meta:nn| and give the path explicitly. % \begin{macrocode} \tl_map_inline:nn { { /defaults } { } } { @@ -7995,6 +8429,15 @@ number-steps = false , welcome-message = false , } , + mute .meta:nn = + { unravel #1 } + { + trace-assigns = false , + trace-expansion = false , + trace-other = false , + welcome-message = false , + online = -1 , + } } } % \end{macrocode} @@ -8004,7 +8447,7 @@ % \begin{macro}{\unravel} % Simply call an underlying code-level command. % \begin{macrocode} -\NewDocumentCommand \unravel { O { } m } { \unravel:nn {#1} {#2} } +\NewDocumentCommand \unravel { O { } +m } { \unravel:nn {#1} {#2} } % \end{macrocode} % \end{macro} % @@ -8026,7 +8469,10 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\unravel:nn} +% \begin{macro}{\unravel:nn, \@@:nn, \@@_unravel_marker:} +% The command starts with \cs{@@_unravel_marker:} to detect nesting of +% \tn{unravel} in \tn{unravel} and avoid re-initializing important +% variables. % Initialize and setup keys. Initialize and setup other variables % including the input. Welcome the user. Then comes the main loop: % until the input is exhausted, print the current status and do one @@ -8035,7 +8481,9 @@ % (and last) one instead. If the main loop finished correctly, print % its outcome and finally test that everything is all right. % \begin{macrocode} -\cs_new_protected:Npn \unravel:nn #1#2 +\cs_new_protected:Npn \unravel:nn { \@@_unravel_marker: \@@:nn } +\cs_new_eq:NN \@@_unravel_marker: \@@_special_relax: +\cs_new_protected:Npn \@@:nn #1#2 { \@@_init_key_vars: \keys_set:nn { unravel } {#1} @@ -8048,6 +8496,11 @@ \@@_final_test: \@@_exit_point: } +\cs_new_protected:Npn \unravel_get:nnN #1#2#3 + { + \unravel:nn {#1} {#2} + \tl_set:Nx #3 { \gtl_left_tl:N \g_@@_output_gtl } + } % \end{macrocode} % \end{macro} % @@ -8055,15 +8508,20 @@ % Give variables that are affected by keys their default values (also % controlled by keys). % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_init_key_vars: +\cs_new_protected:Npn \@@_init_key_vars: { \bool_gset_eq:NN \g_@@_explicit_prompt_bool \g_@@_default_explicit_prompt_bool \bool_gset_eq:NN \g_@@_internal_debug_bool \g_@@_default_internal_debug_bool \bool_gset_eq:NN \g_@@_number_steps_bool \g_@@_default_number_steps_bool + \int_gset_eq:NN \g_@@_online_int \g_@@_default_online_int + \bool_gset_eq:NN \g_@@_trace_assigns_bool \g_@@_default_trace_assigns_bool + \bool_gset_eq:NN \g_@@_trace_expansion_bool \g_@@_default_trace_expansion_bool + \bool_gset_eq:NN \g_@@_trace_other_bool \g_@@_default_trace_other_bool \bool_gset_eq:NN \g_@@_welcome_message_bool \g_@@_default_welcome_message_bool \int_gset_eq:NN \g_@@_max_action_int \g_@@_default_max_action_int \int_gset_eq:NN \g_@@_max_output_int \g_@@_default_max_output_int \int_gset_eq:NN \g_@@_max_input_int \g_@@_default_max_input_int + \int_gzero:N \g_@@_nonstop_int } % \end{macrocode} % \end{macro} @@ -8073,7 +8531,7 @@ % have no reason to be modified by the user: neither directly nor % through keys. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_init_vars: +\cs_new_protected:Npn \@@_init_vars: { \seq_gclear:N \g_@@_prev_input_seq \gtl_gclear:N \g_@@_output_gtl @@ -8089,11 +8547,11 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_main_loop:} +% \begin{macro}{\@@_main_loop:} % Loop forever, getting the next token (with expansion) and % performing the corresponding command. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_main_loop: +\cs_new_protected:Npn \@@_main_loop: { \@@_get_x_next: \@@_set_cmd: @@ -8108,19 +8566,19 @@ % Make sure that the \cs{unravel} finished correctly. The error % message is a bit primitive. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_final_test: +\cs_new_protected:Npn \@@_final_test: { \bool_if:nTF { \tl_if_empty_p:N \g_@@_if_limit_tl - && \int_compare_p:nNn \g_@@_if_limit_int = \c_zero - && \int_compare_p:nNn \g_@@_if_depth_int = \c_zero + && \int_compare_p:nNn \g_@@_if_limit_int = 0 + && \int_compare_p:nNn \g_@@_if_depth_int = 0 && \seq_if_empty_p:N \g_@@_prev_input_seq } { \@@_input_if_empty:TF { } { \@@_final_bad: } } { \@@_final_bad: } } -\cs_new_protected_nopar:Npn \@@_final_bad: +\cs_new_protected:Npn \@@_final_bad: { \@@_error:nnnnn { internal } { the-last-unravel-finished-badly } { } { } { } @@ -8197,6 +8655,8 @@ { The~primitive~\iow_char:N\\endinput~was~ignored. } \msg_new:nnn { unravel } { missing-something } { Something~is~missing,~sorry! } +\msg_new:nnn { unravel } { nested-unravel } + { The~\iow_char:N\\unravel~command~may~not~be~nested. } \msg_new:nnnn { unravel } { tex-error } { TeX~sees~"#1"~and~throws~an~error:\\\\ \iow_indent:n {#2} } { diff --git a/Master/texmf-dist/source/latex/unravel/unravel.ins b/Master/texmf-dist/source/latex/unravel/unravel.ins index 81a35f7019f..46180f9dea1 100644 --- a/Master/texmf-dist/source/latex/unravel/unravel.ins +++ b/Master/texmf-dist/source/latex/unravel/unravel.ins @@ -6,7 +6,7 @@ Do not distribute a modified version of this file. Communicate any suggestions for changing this package -to Bruno Le Floch (blflatex@gmail.com). +to Bruno Le Floch (blflatex+unravel@gmail.com). \endpreamble % stop docstrip adding \endinput |