From ee7abbf3326590ad80cbd11ae7756c9238f7dab8 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Sun, 17 Nov 2019 03:01:57 +0000 Subject: CTAN sync 201911170301 --- macros/latex/contrib/unravel/unravel.dtx | 270 ++++++++++++++++++++----------- macros/latex/contrib/unravel/unravel.pdf | Bin 689310 -> 692007 bytes 2 files changed, 176 insertions(+), 94 deletions(-) (limited to 'macros/latex/contrib/unravel') diff --git a/macros/latex/contrib/unravel/unravel.dtx b/macros/latex/contrib/unravel/unravel.dtx index cd7e87a4bf..1b205fb31b 100644 --- a/macros/latex/contrib/unravel/unravel.dtx +++ b/macros/latex/contrib/unravel/unravel.dtx @@ -23,9 +23,9 @@ % % \title{The \textsf{unravel} package: \\ % watching TeX digest tokens\thanks{This -% file has version number 0.2g, last revised 2019/03/23.}} +% file has version number 0.2h, last revised 2019/11/15.}} % \author{Bruno Le Floch} -% \date{2019/03/23} +% \date{2019/11/15} % % \maketitle % \tableofcontents @@ -213,6 +213,24 @@ % neither if the option is negative. % \end{function} % +% \begin{function}{prompt-input} +% Comma-delimited list option (empty by default) whose items are used +% one by one as if the user typed them at the prompt. Since the +% key-value list is itself comma-delimited, the value here must be +% wrapped in braces. For instance, |prompt-input = {s10, m, u\def}| +% skips $10$ steps, shows the first token's meaning, then continues +% silently until the first token is~|\def|, and any subsequent prompt +% is treated normally with user interaction. This can be useful when +% repeatedly debugging complicated code when the issue is known to lie +% quite late in the code. +% +% As for any |clist|, spaces are discarded around each comma and empty +% entries are removed, then for each item one pair of braces is +% removed (if any is present); to get an empty item use an empty brace +% group, such as in |prompt-input = {s10, {}, x}|. Category codes are +% those in effect when the |prompt-input| option is read. +% \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|, @@ -246,17 +264,14 @@ % \tn{lastpenalty}, \tn{lastskip}, \tn{currentiflevel} and % \tn{currentiftype} may have wrong values. Perhaps % \tn{currentgrouplevel} and \tn{currentgrouptype} too. -% \item Tokens passed to \tn{afterassignment} are not yet kept after -% \pkg{unravel} is done even if there has been no assignment. +% \item Setting \tn{globaldefs} to a non-zero value may cause problems. % \item Tokens passed to \tn{aftergroup} are lost when \pkg{unravel} is % done. -% \item In \XeTeX{}, characters beyond the basic multilingual plane may -% break \pkg{unravel} (not tested). % \item For \pkg{unravel}, category codes are fixed when a file is read % using \tn{input}, % while \TeX{} only fixes category codes when the corresponding % characters are converted to tokens. Similarly, the argument of -% \tn{scantokens} is converted to the new category code r\'egime in +% \tn{scantokens} is converted to the new category code regime in % one go, and the result must be balanced. % \item Explicit begin-group and end-group characters other than the % usual left and right braces may make \pkg{unravel} choke, or may be @@ -273,10 +288,7 @@ % \subsection{Future perhaps} % % \begin{itemize} -% \item Allow users to change some settings globally/for one |\unravel|. % \item Allow to replay steps that have already been run. -% \item Fix the display for \tn{if} and \tn{ifcat} (remove extraneous -% \cs{exp_not:N}). % \item Use the |file-error| fatal error message: first implement % \cs{@@_file_if_exist:nTF} and use it to determine whether % \tn{input} will throw a fatal error in \tn{batchmode} and @@ -545,7 +557,7 @@ {% \csname @@_setup_restore:\endcsname \ProvidesExplPackage - {unravel} {2019/03/23} {0.2g} {Watching TeX digest tokens}% + {unravel} {2019/11/15} {0.2h} {Watching TeX digest tokens}% \csname @@_setup_unravel:\endcsname }% % \end{macrocode} @@ -870,16 +882,11 @@ % % \subsubsection{Helpers for control flow} % -% \begin{macro}[EXP]{\@@_exit:w, \@@_exit_error:w, \@@_exit_hard:w, \@@_exit_point:} +% \begin{macro}[EXP]{\@@_exit:w, \@@_exit_hard: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: \cs_new:Npn \@@_exit:w #1 \@@_exit_point: { } -\cs_new:Npn \@@_exit_error:w #1 \@@_exit_point: #2 \@@_final_bad: - { - \@@_error:nnnnn { runaway-unravel } { } { } { } { } - #2 - } \cs_new:Npn \@@_exit_hard:w #1 \@@_exit_point: #2 \@@_exit_point: { } % \end{macrocode} % \end{macro} @@ -1151,31 +1158,31 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_prev_input_join_get:nN} -% \begin{macro}{\@@_join_get_aux:NNN} +% \begin{macro}{\@@_prev_input_join_get:nnN} +% \begin{macro}{\@@_join_get_aux:NNnN} % Pops the previous-input sequence twice to get some value in % \cs{l_@@_head_tl} and some sign or decimal number in % \cs{l_@@_tmpa_tl}. Combines them into a value, using % the appropriate evaluation function, determined based % on~|#1|. % \begin{macrocode} -\cs_new_protected:Npn \@@_prev_input_join_get:nN #1 +\cs_new_protected:Npn \@@_prev_input_join_get:nnN #1 { \int_case:nnF {#1} { - { 2 } { \@@_join_get_aux:NNN \skip_eval:n \tex_glueexpr:D } - { 3 } { \@@_join_get_aux:NNN \muskip_eval:n \tex_muexpr:D } + { 2 } { \@@_join_get_aux:NNnN \skip_eval:n \tex_glueexpr:D } + { 3 } { \@@_join_get_aux:NNnN \muskip_eval:n \tex_muexpr:D } } { \@@_error:nnnnn { internal } { join-factor } { } { } { } - \@@_join_get_aux:NNN \use:n \prg_do_nothing: + \@@_join_get_aux:NNnN \use:n \prg_do_nothing: } } -\cs_new_protected:Npn \@@_join_get_aux:NNN #1#2#3 +\cs_new_protected:Npn \@@_join_get_aux:NNnN #1#2#3#4 { \@@_prev_input_gpop:N \l_@@_head_tl \@@_prev_input_gpop:N \l_@@_tmpa_tl - \tl_set:Nx #3 { #1 { \l_@@_tmpa_tl #2 \l_@@_head_tl } } + \tl_set:Nx #4 { #1 { \l_@@_tmpa_tl #2 \l_@@_head_tl #3 } } } % \end{macrocode} % \end{macro} @@ -1212,6 +1219,7 @@ % \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_prompt_input_clist , \g_@@_prompt_input_clist , % \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 , @@ -1227,6 +1235,7 @@ \bool_new:N \g_@@_default_internal_debug_bool \bool_new:N \g_@@_default_number_steps_bool \int_new:N \g_@@_default_online_int +\clist_new:N \g_@@_default_prompt_input_clist \bool_new:N \g_@@_default_trace_assigns_bool \bool_new:N \g_@@_default_trace_expansion_bool \bool_new:N \g_@@_default_trace_other_bool @@ -1241,6 +1250,7 @@ \bool_new:N \g_@@_internal_debug_bool \bool_new:N \g_@@_number_steps_bool \int_new:N \g_@@_online_int +\clist_new:N \g_@@_prompt_input_clist \bool_new:N \g_@@_trace_assigns_bool \bool_new:N \g_@@_trace_expansion_bool \bool_new:N \g_@@_trace_other_bool @@ -2289,11 +2299,10 @@ \@@_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 } - } + { \@@_tex_primitive:nnn { directlua } { convert } { 33 } } +\@@_tex_primitive:nnn { expanded } { convert } { 34 } +\sys_if_engine_luatex:T + { \@@_tex_primitive:nnn { luaescapestring } { convert } { 35 } } \sys_if_engine_xetex:T { \@@_tex_primitive:nnn { Ucharcat } { convert } { 40 } @@ -2329,8 +2338,11 @@ % % \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 +% If the input is empty, insert a frozen \tn{relax} (the alternative +% would be either to grab a token in the input stream after +% \cs{unravel}, which is tough, or simply produce an error and exit; +% perhaps this should be configurable). +% Then remove the first token in the input, and store it in % \cs{l_@@_head_gtl}. Set \cs{l_@@_head_token} equal in meaning to % that first token. Then set \cs{l_@@_head_tl} to contain the token, % unless it is a begin-group or end-group character, in which case @@ -2339,20 +2351,22 @@ \cs_new_protected:Npn \@@_get_next: { \@@_input_if_empty:TF - { \@@_exit_error:w } { - \@@_input_gpop:N \l_@@_head_gtl - \gtl_head_do:NN \l_@@_head_gtl \@@_get_next_aux:w - \gtl_if_tl:NTF \l_@@_head_gtl - { - \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 } + \@@_error:nnnnn { runaway-unravel } { } { } { } { } + \@@_back_input_gtl:N \c_@@_frozen_relax_gtl } + { } + \@@_input_gpop:N \l_@@_head_gtl + \gtl_head_do:NN \l_@@_head_gtl \@@_get_next_aux:w + \gtl_if_tl:NTF \l_@@_head_gtl + { + \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:Npn \@@_get_next_aux:w { \cs_set_eq:NN \l_@@_head_token } @@ -2582,7 +2596,7 @@ % sequence is \tn{nullfont} or similar (note that we do not search for % \verb*|select font|, as the code to trim the escape character from % the meaning may have removed the leading~|s|). Otherwise, we expect -% the \tn{meaning} to be \tn{char} or \tn{mathchar} followed by +% the \tn{meaning} to be \tn{char} or \tn{mathchar} or similar followed by % |"|~and an uppercase hexadecimal number, or one of \tn{count}, % \tn{dimen}, \tn{skip}, \tn{muskip} or \tn{toks} followed by a % decimal number. @@ -2610,7 +2624,7 @@ % 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 |kchar| in up\TeX{}), +% first part to be |char| or~|mathchar| (or |kchar| or |omathchar| in (u)p\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 @@ -2646,6 +2660,7 @@ { char } { \@@_set_cmd_aux_given:n { char_given } } { kchar } { \@@_set_cmd_aux_given:n { char_given } } { mathchar } { \@@_set_cmd_aux_given:n { math_given } } + { omathchar } { \@@_set_cmd_aux_given:n { math_given } } } { \@@_set_cmd_aux_primitive:nTF {#1} @@ -3784,7 +3799,6 @@ % \end{macrocode} % \end{macro} % -% ^^A todo: comment % \begin{macro}{\@@_scan_expr:N} % \begin{macro}{\@@_scan_expr_aux:NN, \@@_scan_factor:N} % \begin{macrocode} @@ -3974,6 +3988,10 @@ % and |inf| is |#2|. The third argument of this procedure is omitted % here, as the corresponding shortcut is provided as a separate % function, \cs{@@_scan_dim_unit:nN}. +% +% Ideally, \cs{@@_scan_inf_unit_loop:} would produce an \pkg{unravel} +% error when reaching the third ``L'', rather than letting TeX produce +% the error later on. % \begin{macrocode} \cs_new_protected:Npn \@@_scan_dimen:nN #1#2 { @@ -4038,11 +4056,14 @@ { \@@_prev_input_gpush: \@@_scan_something_internal:n {#1} - \@@_prev_input_join_get:nN {#1} \l_@@_tmpa_tl + \int_compare:nNnTF \g_@@_val_level_int = { 0 } + { \@@_prev_input_join_get:nnN {#1} { sp } \l_@@_tmpa_tl } + { \@@_prev_input_join_get:nnN {#1} { } \l_@@_tmpa_tl } \@@_prev_input_gpush:N \l_@@_tmpa_tl - \@@_break:w + \exp_after:wN \use_none:n \@@_break:w } - { \@@_back_input: } + { } + \@@_back_input: \int_compare:nNnT {#1} = { 3 } { \@@_scan_keyword:nT { mMuU } { \@@_break:w } @@ -4069,6 +4090,7 @@ \@@_tex_error:nV { missing-pt } \l_@@_head_tl \@@_prev_input:n { pt } \@@_break_point: + \@@_skip_optional_space: } \cs_new_protected:Npn \@@_scan_inf_unit_loop: { \@@_scan_keyword:nT { lL } { \@@_scan_inf_unit_loop: } } @@ -4119,7 +4141,7 @@ { \@@_break:w } } { \@@_back_input: \@@_scan_dimen:nN {#1} \c_false_bool } - \@@_prev_input_join_get:nN {#1} \l_@@_tmpa_tl + \@@_prev_input_join_get:nnN {#1} { } \l_@@_tmpa_tl \@@_prev_input_gpush: \@@_prev_input_gpush:N \l_@@_tmpa_tl \@@_scan_keyword:nT { pPlLuUsS } @@ -4127,7 +4149,7 @@ \@@_scan_keyword:nT { mMiInNuUsS } { \@@_scan_dimen:nN {#1} \c_true_bool } \@@_break_point: - \@@_prev_input_join_get:nN {#1} \l_@@_tmpa_tl + \@@_prev_input_join_get:nnN {#1} { } \l_@@_tmpa_tl \@@_prev_input_silent:V \l_@@_tmpa_tl } % \end{macrocode} @@ -4185,7 +4207,6 @@ % \end{macrocode} % \end{macro} % -% ^^A todo: hash doubling is wrong % \begin{macro}{\@@_scan_toks_to_str:} % \begin{macrocode} \cs_new_protected:Npn \@@_scan_toks_to_str: @@ -4359,8 +4380,6 @@ % \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:Npn \@@_scan_alt_rule: @@ -4686,6 +4705,7 @@ % \end{macro} % % \begin{macro}{\@@_mathchar:n, \@@_mathchar:x} +% ^^A todo: \omathchar support % \begin{macrocode} \cs_new_protected:Npn \@@_mathchar:n #1 { @@ -4970,29 +4990,18 @@ % \end{macrocode} % \end{macro} % -% \subsection{One 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:Npn \@@_do_step: - { - \@@_set_action_text: - \bool_if:NT \g_@@_internal_debug_bool - { \@@_exp_args:Nx \iow_term:n { Cmd:~\int_to_arabic:n { \l_@@_head_cmd_int } } } - \cs_if_exist_use:cF - { @@_cmd_ \int_use:N \l_@@_head_cmd_int : } - { \@@_error:nxxxx { internal } { unknown-command } { } { } { } } - } -% \end{macrocode} -% \end{macro} -% % \subsection{Commands} % % We will implement commands in order of their command codes (some of % the more elaborate commands call auxiliaries defined in other -% sections). +% sections). Some cases are forbidden. +% +% \begin{macro}{\@@_forbidden_case:} +% \begin{macrocode} +\cs_new_protected:Npn \@@_forbidden_case: + { \@@_tex_error:nV { forbidden-case } \l_@@_head_tl } +% \end{macrocode} +% \end{macro} % % \subsubsection{Characters: from 0 to 15} % @@ -5395,8 +5404,6 @@ } % \end{macrocode} % -% ^^A todo: implement \@@_forbidden_case: -% % \begin{macro}{\@@_do_move:} % Scan a dimension and a box, and perform the shift, printing the % appropriate action. @@ -7023,8 +7030,8 @@ % \tn{pdffilemoddate}, \tn{pdffilesize}, \tn{pdfmdfivesum}, % \tn{pdffiledump}, \tn{pdfmatch}, \tn{pdflastmatch}, % \tn{pdfuniformdeviate}, \tn{pdfnormaldeviate}, \tn{pdfinsertht}, -% \tn{pdfximagebbox}, \tn{jobname}, and in -% \LuaTeX{} \tn{directlua}, \tn{expanded}, \tn{luaescapestring}. +% \tn{pdfximagebbox}, \tn{jobname}, \tn{expanded}, and in +% \LuaTeX{} \tn{directlua}, \tn{luaescapestring}, and in \XeTeX{} \tn{Ucharcat}. % \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}, @@ -7378,7 +7385,8 @@ \cs_if_eq:NNTF #1 \@@_get_token_xdef: { \tl_put_right:NV \l_@@_defining_tl \l_@@_head_tl - \@@_prev_input:V \l_@@_head_tl + \@@_prev_input_silent:x { \l_@@_head_tl } + \@@_print_action: } { \cs_if_eq:NNTF #1 \@@_get_token_x: @@ -7624,7 +7632,7 @@ \@@_print_expansion:x { \g_@@_action_text_str = false ~ - => ~ skipped ~ to ~ \iow_char:N\\fi + => ~ skip ~ to ~ \tl_to_str:N \l_@@_head_tl } } \cs_new_protected:Npn \@@_cond_false_loop:n #1 @@ -7671,7 +7679,6 @@ % \end{macrocode} % \end{macro} % -% ^^A todo: fix interaction with noexpand and active chars (what interaction?) % \begin{macro}{\@@_test_two_chars:nn, \@@_test_two_chars_get:n, \@@_test_two_chars_gtl:N} % \begin{macrocode} \cs_new_protected:Npn \@@_test_two_chars:nn #1 @@ -7710,7 +7717,10 @@ \gtl_if_head_is_group_begin:NTF #1 { \c_group_begin_token } { \gtl_if_head_is_group_end:NTF #1 { \c_group_end_token } - { \exp_not:N \exp_not:N \gtl_head_do:NN #1 \exp_not:N } + { + \exp_not:N \exp_not:N + \exp_not:f { \gtl_head_do:NN #1 \exp_stop_f: } + } } } } @@ -7872,10 +7882,9 @@ \@@_set_action_text:x { \g_@@_action_text_str \c_space_tl - => ~ skipped ~ to ~ \tl_to_str:N \l_@@_head_tl + => ~ skip ~ to ~ \tl_to_str:N \l_@@_head_tl } } - % ^^A todo: in the terminal output the token itself is missing. \@@_print_expansion: \@@_cond_pop: } @@ -8222,13 +8231,28 @@ } \cs_new_protected:Npn \@@_prompt_aux: { - \int_compare:nNnT { \tex_interactionmode:D } = { 3 } + \clist_if_empty:NTF \g_@@_prompt_input_clist { - \bool_if:NTF \g_@@_explicit_prompt_bool - { \@@_ior_str_get:Nc \c_@@_prompt_ior } - { \@@_ior_str_get:Nc \c_@@_noprompt_ior } - { Your~input } - \exp_args:Nv \@@_prompt_treat:n { Your~input } + \int_compare:nNnT { \tex_interactionmode:D } = { 3 } + { + \bool_if:NTF \g_@@_explicit_prompt_bool + { \@@_ior_str_get:Nc \c_@@_prompt_ior } + { \@@_ior_str_get:Nc \c_@@_noprompt_ior } + { Your~input } + \exp_args:Nv \@@_prompt_treat:n { Your~input } + } + } + { + \clist_gpop:NN \g_@@_prompt_input_clist \l_@@_tmpa_tl + \group_begin: + \@@_set_escapechar:n { 92 } + \@@_print:x + { + \bool_if:NT \g_@@_explicit_prompt_bool { Your~input= } + \tl_to_str:N \l_@@_tmpa_tl + } + \group_end: + \exp_args:NV \@@_prompt_treat:n \l_@@_tmpa_tl } } \cs_new_protected:Npn \@@_prompt_treat:n #1 @@ -8248,7 +8272,11 @@ \group_end: \@@_exit_hard:w } - { X } { \tex_batchmode:D \tex_end:D } + { X } + { + \tex_batchmode:D + \tex_read:D -1 to \l_@@_tmpa_tl + } { s } { \@@_prompt_scan_int:nn {#1} \@@_prompt_silent_steps:n } { o } { \@@_prompt_scan_int:nn {#1} @@ -8379,6 +8407,7 @@ { \exp_not:N \@@:nn \tl_to_str:N \g_@@_until_tl } } { + \int_gzero:N \g_@@_nonstop_int \int_gset:Nn \g_@@_online_int { 1 } \tl_gclear:N \g_@@_before_print_state_tl } @@ -8483,6 +8512,7 @@ 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 , + prompt-input .clist_gset:N = \g_@@_default_prompt_input_clist , 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 , @@ -8497,6 +8527,7 @@ 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 , + prompt-input .clist_gset:N = \g_@@_prompt_input_clist , 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 , @@ -8589,6 +8620,7 @@ \@@_exit_point: \@@_print_outcome: \@@_final_test: + \@@_final_after_assignment: \@@_exit_point: } \cs_new_protected:Npn \unravel_get:nnN #1#2#3 @@ -8609,6 +8641,7 @@ \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 + \clist_gset_eq:NN \g_@@_prompt_input_clist \g_@@_default_prompt_input_clist \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 @@ -8669,6 +8702,22 @@ % \end{macrocode} % \end{macro} % +% \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:Npn \@@_do_step: + { + \@@_set_action_text: + \bool_if:NT \g_@@_internal_debug_bool + { \@@_exp_args:Nx \iow_term:n { Cmd:~\int_to_arabic:n { \l_@@_head_cmd_int } } } + \cs_if_exist_use:cF + { @@_cmd_ \int_use:N \l_@@_head_cmd_int : } + { \@@_error:nxxxx { internal } { unknown-command } { } { } { } } + } +% \end{macrocode} +% \end{macro} +% % ^^A todo: improve error message % \begin{macro}{\@@_final_test:, \@@_final_bad:} % Make sure that the \cs{unravel} finished correctly. The error @@ -8694,6 +8743,17 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_final_after_assignment:} +% Salvage any remaining \tn{afterassignment} token. +% \begin{macrocode} +\cs_new_protected:Npn \@@_final_after_assignment: + { + \gtl_if_empty:NF \g_@@_after_assignment_gtl + { \gtl_head_do:NN \g_@@_after_assignment_gtl \tex_afterassignment:D } + } +% \end{macrocode} +% \end{macro} +% % \subsection{Messages} % % \begin{macrocode} @@ -8745,12 +8805,14 @@ \msg_new:nnn { unravel } { bad-unless } { \iow_char:N\\unless~not~followed~by~conditional. } \msg_new:nnn { unravel } { runaway-if } - { Runaway~\iow_char:N\\if... } + { Runaway~\iow_char:N\\if...~Exiting~\iow_char:N\\unravel } \msg_new:nnn { unravel } { runaway-macro-parameter } { Runaway~macro~parameter~\# #2~after \\\\ \iow_indent:n {#1} } +\msg_new:nnn { unravel } { runaway-text } + { Runaway~braced~argument~for~TeX~primitive.~Exiting~\iow_char:N\\unravel } \msg_new:nnn { unravel } { extra-or } { Extra~\iow_char:N\\or. } \msg_new:nnn { unravel } { missing-equals } @@ -8779,12 +8841,32 @@ { TeX~provides~no~further~help~for~this~error. } { TeX's~advice~is:\\\\ \iow_indent:n {#3} } } -\msg_new:nnn { unravel } { runaway-unravel } - { Runaway~\iow_char:N\\unravel } +\msg_new:nnnn { unravel } { runaway-unravel } + { Runaway~\iow_char:N\\unravel,~so~\iow_char:N\\relax~inserted. } + { + Some~TeX~command~expects~input~beyond~the~end~of~ + the~argument~of~\iow_char:N\\unravel. + } % \end{macrocode} % % Some error messages from \TeX{} itself. % \begin{macrocode} +\@@_tex_msg_new:nnn { forbidden-case } + { + You~can't~use~`\exp_after:wN \token_to_str:N \l_@@_head_tl'~in~ + \mode_if_vertical:TF { vertical } + { + \mode_if_horizontal:TF { horizontal } + { \mode_if_math:TF { math } { no } } + } ~ mode. + } + { + Sorry,~but~I'm~not~programmed~to~handle~this~case;~ + I'll~just~pretend~that~you~didn't~ask~for~it.~ + If~you're~in~the~wrong~mode,~you~might~be~able~to~ + return~to~the~right~one~by~typing~`I\iow_char:N\}'~or~ + `I\iow_char:N\$'~or~`I\iow_char:N\\par'. + } \@@_tex_msg_new:nnn { incompatible-mag } { Incompatible~magnification~ diff --git a/macros/latex/contrib/unravel/unravel.pdf b/macros/latex/contrib/unravel/unravel.pdf index df3f7437be..b8f069b2bb 100644 Binary files a/macros/latex/contrib/unravel/unravel.pdf and b/macros/latex/contrib/unravel/unravel.pdf differ -- cgit v1.2.3