From b9f09946a8fe2f81468fb7bf624e3f8ce2d26888 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 30 Sep 2015 21:17:21 +0000 Subject: unravel (30sep15) git-svn-id: svn://tug.org/texlive/trunk@38506 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/unravel/unravel.pdf | Bin 692725 -> 709793 bytes Master/texmf-dist/source/latex/unravel/unravel.dtx | 893 ++++++++++++++++----- Master/texmf-dist/tex/latex/unravel/unravel.sty | 627 +++++++++++---- 3 files changed, 1177 insertions(+), 343 deletions(-) diff --git a/Master/texmf-dist/doc/latex/unravel/unravel.pdf b/Master/texmf-dist/doc/latex/unravel/unravel.pdf index a8af7eaff51..3dda4e56617 100644 Binary files a/Master/texmf-dist/doc/latex/unravel/unravel.pdf and b/Master/texmf-dist/doc/latex/unravel/unravel.pdf differ diff --git a/Master/texmf-dist/source/latex/unravel/unravel.dtx b/Master/texmf-dist/source/latex/unravel/unravel.dtx index 87170f4286c..328b20512ed 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.1, last revised 2015/09/22.}} +% file has version number 0.2, last revised 2015/09/30.}} % \author{Bruno Le Floch} -% \date{2015/09/22} +% \date{2015/09/30} % % \maketitle % \tableofcontents @@ -202,9 +202,21 @@ % \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 -% \cs{pdfprimitive}, \cs{aftergroup}, \cs{discretionary}, as well as +% \tn{pdfprimitive}, \tn{discretionary}, as well as % all primitives specific to engines other than \pdfTeX{}. -% This list is sadly incomplete! +% This list may sadly be incomplete! +% \item \tn{aftergroup} is only partially implemented. +% \item \tn{everyhbox}, \tn{everyvbox}, \tn{everymath}, +% \tn{everydisplay}, \tn{lastkern}, \tn{lastnodetype}, +% \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 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 @@ -227,6 +239,16 @@ % \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 +% \tn{nonstopmode}. +% \item Use the |interwoven-preambles| fatal error message once +% alignments are implemented. +% \item Look at all places where \TeX{}'s procedure |prepare_mag| is +% called. +% \item Find out why so many input levels are used (see the log of the +% |unravel003| testfile for instance) % \end{itemize} % % \end{documentation} @@ -243,21 +265,251 @@ % \end{macrocode} % % \begin{macrocode} -\RequirePackage{expl3,xparse}[2015/09/11] -\RequirePackage{gtl}[2015/09/21] -\ProvidesExplPackage - {unravel} {2015/09/22} {0.1} {Watching TeX digest tokens} +%<@@=unravel> +% \end{macrocode} +% +% Catcode settings. In a group, set |\c| to be a synonym of |\catcode| +% for short, set the catcode of space to be 10 (using |\fam| to avoid +% needing a space or an equal sign to separate the two integer +% arguments of |\catcode|) and that of |%| to be 14 (using |\fam| again +% to avoid needing the digit 7 to have catcode other: we need the digit +% 5 anyway in two steps). Then make |-|, |6|, |7|, |8|, |9| other (we +% must assume that |0| through |5| are already other), and make |:|, +% |_|, |h|, |j|, |k|, |q|, |s|, |w|, |x|, |y|, |z| letters (other +% lowercase letters already need to be letters in the rest of the +% code). Make sure there is no |\endlinechar|. We are finally ready +% to safely test whether the package has already been loaded and bail +% out in case it has. Expanding |\fi| before ending the group ensures +% that the whole line has been read by \TeX{} before restoring earlier +% catcodes. +% \begin{macrocode} +\begingroup\let\c\catcode\fam32\c\fam10\advance\fam5\c\fam14\c45 12 % +\c54 12\c55 12\c56 12\c57 12\c58 11\c95 11\c104 11\c106 11\c107 11 % +\c113 11\c115 11\c119 11\c120 11\c121 11\c122 11\endlinechar-1 % +\expandafter\ifx\csname unravel\endcsname\relax +\else\endinput\expandafter\endgroup\fi +% \end{macrocode} +% +% Set |T| and |X| to be letters for an error message. Set up braces +% and |#| for definitions, |=| for nicer character code assignments, +% |>| for integer comparison, |+| for integer expressions. +% \begin{macrocode} +\c84 11\c88 11\c35 6\c123 1\c125 2\c62 12\c61 12\c43 12 % +% \end{macrocode} +% +% If \eTeX{}'s \tn{numexpr} or \tn{protected} are not available, bail +% out with an error. +% \begin{macrocode} +\expandafter\ifx\csname numexpr\endcsname\relax +\errmessage{unravel requires \numexpr from eTeX} +\endinput\expandafter\endgroup\fi +\expandafter\ifx\csname protected\endcsname\relax +\errmessage{unravel requires \protected from eTeX} +\endinput\expandafter\endgroup\fi +% \end{macrocode} +% +% If \pkg{unravel} is loaded within a group, bail out because +% \pkg{expl3} would not be loaded properly. +% \begin{macrocode} +\expandafter\ifx\csname currentgrouplevel\endcsname\relax\else +\ifnum\currentgrouplevel>1 \errmessage{unravel loaded in a group} +\endinput\expandafter\expandafter\expandafter\endgroup\fi\fi +% \end{macrocode} +% +% Make spaces ignored and make |~| a space, to prettify code. +% \begin{macrocode} +\catcode 32 = 9 \relax +\catcode 126 = 10 \relax +% \end{macrocode} +% +% \begin{variable}{\l_@@_setup_restore_tl} +% This token list variable will contain code to restore category +% codes to their value when the package was loaded. +% \begin{macrocode} +\gdef \l_@@_setup_restore_tl { } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[int]{\@@_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. +% \begin{macrocode} +\protected \gdef \@@_setup_restore: + { + \l_@@_setup_restore_tl + \def \l_@@_setup_restore_tl { } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_setup_save:} +% \begin{macro}[aux, 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}, +% \tn{newlinechar}. +% \begin{macrocode} +\protected \gdef \@@_setup_save: + { + \edef \l_@@_setup_restore_tl + { + \@@_setup_save_aux:w 0 = + \endlinechar = \the \endlinechar + \escapechar = \the \escapechar + \newlinechar = \the \newlinechar + \relax + } + } +\long \gdef \@@_setup_save_aux:w #1 = + { + \catcode #1 = \the \catcode #1 ~ + \ifnum 255 > #1 ~ + \expandafter \@@_setup_save_aux:w + \the \numexpr #1 + 1 \expandafter = + \fi + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int]{\@@_setup_catcodes:nnn} +% This sets all characters from |#1| to |#2| (inclusive) to have +% catcode |#3|. +% \begin{macrocode} +\protected \long \gdef \@@_setup_catcodes:nnn #1 #2 #3 + { + \ifnum #1 > #2 ~ \else + \catcode #1 = #3 ~ + \expandafter \@@_setup_catcodes:nnn \expandafter + { \the \numexpr #1 + 1 } {#2} {#3} + \fi + } % \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_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). +% \begin{macrocode} +\protected \gdef \@@_setup_latexe: + { + \@@_setup_save: + \@@_setup_catcodes:nnn {0} {8} {15} + \catcode 9 = 10 ~ + \catcode 10 = 12 ~ + \catcode 11 = 15 ~ + \catcode 12 = 13 ~ + \catcode 13 = 5 ~ + \@@_setup_catcodes:nnn {14} {31} {15} + \catcode 32 = 10 ~ + \catcode 33 = 12 ~ + \catcode 34 = 12 ~ + \catcode 35 = 6 ~ + \catcode 36 = 3 ~ + \catcode 37 = 14 ~ + \catcode 38 = 4 ~ + \@@_setup_catcodes:nnn {39} {63} {12} + \@@_setup_catcodes:nnn {64} {90} {11} + \catcode 91 = 12 ~ + \catcode 92 = 0 ~ + \catcode 93 = 12 ~ + \catcode 94 = 7 ~ + \catcode 95 = 8 ~ + \catcode 96 = 12 ~ + \@@_setup_catcodes:nnn {97} {122} {11} + \catcode 123 = 1 ~ + \catcode 124 = 12 ~ + \catcode 125 = 2 ~ + \catcode 126 = 13 ~ + \catcode 127 = 15 ~ + \@@_setup_catcodes:nnn {128} {255} {12} + \endlinechar = 13 ~ + \escapechar = 92 ~ + \newlinechar = 10 ~ + } +% \end{macrocode} +% \end{macro} % +% \begin{macro}[int]{\@@_setup_unravel:} +% Catcodes for \pkg{unravel} (in particular, |@| is other, |:| and +% |_| are letters, spaces are ignored, |~| is a space). +% \begin{macrocode} +\protected \gdef \@@_setup_unravel: + { + \@@_setup_save: + \@@_setup_catcodes:nnn {0} {8} {15} + \catcode 9 = 9 ~ + \catcode 10 = 12 ~ + \catcode 11 = 15 ~ + \catcode 12 = 13 ~ + \catcode 13 = 5 ~ + \@@_setup_catcodes:nnn {14} {31} {15} + \catcode 32 = 9 ~ + \catcode 33 = 12 ~ + \catcode 34 = 12 ~ + \catcode 35 = 6 ~ + \catcode 36 = 3 ~ + \catcode 37 = 14 ~ + \catcode 38 = 4 ~ + \@@_setup_catcodes:nnn {39} {57} {12} + \catcode 58 = 11 ~ + \@@_setup_catcodes:nnn {59} {64} {12} + \@@_setup_catcodes:nnn {65} {90} {11} + \catcode 91 = 12 ~ + \catcode 92 = 0 ~ + \catcode 93 = 12 ~ + \catcode 94 = 7 ~ + \catcode 95 = 11 ~ + \catcode 96 = 12 ~ + \@@_setup_catcodes:nnn {97} {122} {11} + \catcode 123 = 1 ~ + \catcode 124 = 12 ~ + \catcode 125 = 2 ~ + \catcode 126 = 10 ~ + \catcode 127 = 15 ~ + \@@_setup_catcodes:nnn {128} {255} {12} + \escapechar = 92 ~ + \endlinechar = 32 ~ + \newlinechar = 10 ~ + } +% \end{macrocode} +% \end{macro} +% +% End the group where all catcodes where changed, but expand +% \cs{@@_setup_latexe:} to sanitize catcodes again outside the +% group. The catcodes are saved. +% \begin{macrocode} +\expandafter \endgroup \@@_setup_latexe: +% \end{macrocode} +% +% Load a few dependencies: \pkg{expl3}, \pkg{xparse}, \pkg{gtl}. % Load \pkg{l3str} if \pkg{expl3} is too old and does not define % \cs{str_range:nnn}. Otherwise loading \pkg{l3str} would give % an error. % \begin{macrocode} -\cs_if_exist:NF \str_range:nnn { \RequirePackage{l3str} } +\RequirePackage{expl3,xparse}[2015/09/11] +\RequirePackage{gtl}[2015/09/21] +\csname cs_if_exist:cF\endcsname{str_range:nnn}{\RequirePackage{l3str}} % \end{macrocode} % +% Before loading \pkg{unravel}, restore catcodes, so that the implicit +% \cs{ExplSyntaxOn} in \cs{ProvidesExplPackage} picks up the correct +% catcodes to restore when \cs{ExplSyntaxOff} is run at the end of the +% package. The place where catcodes are restored are beyond +% \pkg{unravel}'s reach, which is why we cannot bypass \pkg{expl3} and +% simply restore the catcodes once everything is done. To avoid issues +% with crazy catcodes, make \TeX{} read the arguments of +% \cs{ProvidesExplPackage} before restoring catcodes. Then immediately +% go to the catcodes we want. % \begin{macrocode} -%<@@=unravel> +\csname use:n\endcsname + {% + \csname @@_setup_restore:\endcsname + \ProvidesExplPackage + {unravel} {2015/09/30} {0.2} {Watching TeX digest tokens}% + \csname @@_setup_unravel:\endcsname + }% % \end{macrocode} % % \subsection{Primitives, variants, and helpers} @@ -281,6 +533,7 @@ \cs_new_eq:NN \@@_everyeof:w \etex_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 \cs_new_eq:NN \@@_nullfont: \tex_nullfont:D \cs_new_eq:NN \@@_the:w \tex_the:D % \end{macrocode} @@ -299,24 +552,15 @@ % % Variants that we need. % \begin{macrocode} -\cs_if_exist:NF \exp_last_unbraced:NNn - { \cs_new_eq:NN \exp_last_unbraced:NNn \use:nnn } -\cs_generate_variant:Nn \exp_last_unbraced:NNn { NNv } \cs_generate_variant:Nn \str_head:n { f } \cs_generate_variant:Nn \tl_to_str:n { o } \cs_generate_variant:Nn \tl_if_head_eq_meaning:nNT { V } -\cs_generate_variant:Nn \tl_if_head_is_space:nTF { o } -\cs_generate_variant:Nn \tl_if_head_is_space:nT { V } -\cs_generate_variant:Nn \tl_if_head_is_N_type:nTF { o } \cs_generate_variant:Nn \tl_if_in:nnF { nV } \cs_generate_variant:Nn \tl_if_in:nnTF { nV } -\cs_generate_variant:Nn \tl_if_eq:nnT { V } \cs_generate_variant:Nn \tl_if_in:NnTF { No , NV } \cs_generate_variant:Nn \tl_if_single_token:nT { V } \cs_generate_variant:Nn \tl_gset_rescan:Nnn { Nnx } -\cs_generate_variant:Nn \gtl_gput_left:Nn { Nx , NV , No } -\cs_generate_variant:Nn \gtl_gput_right:Nn { Nx , NV } -\cs_generate_variant:Nn \gtl_put_right:Nn { NV } +\cs_generate_variant:Nn \gtl_gput_right:Nn { NV } \cs_generate_variant:Nn \ior_get_str:NN { Nc } \cs_generate_variant:Nn \gtl_if_empty:NTF { c } \cs_generate_variant:Nn \gtl_to_str:N { c } @@ -337,31 +581,97 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[aux]{\@@_tl_gset_input:Nnn, \@@_tl_gset_input:Nno} -% \begin{macro}[aux]{\@@_tl_gset_input_aux:wN} +% \begin{macro}[aux]{\@@_file_get:nN} +% \begin{macro}[aux]{\@@_file_get_aux:wN} % \begin{macrocode} -\cs_new_protected:Npn \@@_tl_gset_input:Nnn #1#2#3 +\cs_set_protected:Npn \@@_tmp:w #1 { - \group_begin: - \@@_everyeof:w \exp_after:wN { \token_to_str:N @ @ #1 } - #2 - \tl_gclear:N #1 - \exp_after:wN \@@_tl_gset_input_aux:wN - \exp_after:wN \prg_do_nothing: - \tex_input:D \tl_to_str:n {#3} \scan_stop: - \group_end: - \tl_gput_right:NV #1 \@@_everyeof:w + \cs_new_protected:Npn \@@_file_get:nN ##1##2 + { + \group_begin: + \@@_everyeof:w { #1 ##2 } + \exp_after:wN \@@_file_get_aux:wN + \exp_after:wN \prg_do_nothing: + \tex_input:D ##1 \scan_stop: + } + \cs_new_protected:Npn \@@_file_get_aux:wN ##1 #1 ##2 + { + \group_end: + \tl_set:Nx ##2 + { \exp_not:o {##1} \exp_not:V \@@_everyeof:w } + } } -\cs_generate_variant:Nn \@@_tl_gset_input:Nnn { Nno } -\use:x +\exp_args:No \@@_tmp:w { \token_to_str:N : : } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int, EXP]{\@@_tl_first_int:N} +% \begin{macro}[aux, 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 +% \meta{number} within the whole \tn{read} \meta{number} |to| +% \meta{cs} construction. The auxiliary initially has itself as a +% first argument, and once a first digit is found it has +% \cs{use_none_delimit_by_q_stop:w}. That first argument is used +% whenever what follows is not a digit, hence initially we loop, +% while after the first digit is found any non-digit stops the +% recursion. If no integer is found, $0$ is left in the token list. +% The surrounding \cs{int_eval:n} lets us dump digits in the input +% stream while keeping the function fully expandable. +% \begin{macrocode} +\cs_new:Npn \@@_tl_first_int:N #1 { - \cs_new_protected:Npn \exp_not:N \@@_tl_gset_input_aux:wN - ##1 \token_to_str:N @ @ ##2 - } { \tl_gset:No #2 {#1} } + \int_eval:n + { + \exp_after:wN \@@_tl_first_int_aux:Nn + \exp_after:wN \@@_tl_first_int_aux:Nn + #1 ? 0 ? \q_stop + } + } +\cs_new:Npn \@@_tl_first_int_aux:Nn #1#2 + { + \tl_if_single:nT {#2} + { + \token_if_eq_catcode:NNT + #2 + { + \if_int_compare:w 1 < 1 #2 \exp_stop_f: + #2 + \exp_after:wN \use_i_ii:nnn + \exp_after:wN \@@_tl_first_int_aux:Nn + \exp_after:wN \use_none_delimit_by_q_stop:w + \fi: + } + } + #1 + } % \end{macrocode} % \end{macro} % \end{macro} % +% \begin{macro}[int]{\@@_prepare_mag:} +% Used whenever \TeX{} needs the value of \tn{mag}. ^^A todo: move +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_prepare_mag: + { + \int_compare:nNnT { \g_@@_mag_set_int } > { 0 } + { + \int_compare:nNnF { \@@_mag: } = { \g_@@_mag_set_int } + { + \@@_tex_error:nn { incompatible-mag } { } + \int_gset_eq:NN \@@_mag: \g_@@_mag_set_int + } + } + \int_compare:nF { 1 <= \@@_mag: <= 32768 } + { + \@@_tex_error:nV { illegal-mag } \l_@@_head_tl + \int_gset:Nn \@@_mag: { 1000 } + } + \int_gset_eq:NN \g_@@_mag_set_int \@@_mag: + } +% \end{macrocode} +% \end{macro} +% % \subsubsection{String helpers} % % \begin{macro}[int]{\@@_strip_escape:w} @@ -951,6 +1261,14 @@ % \end{macrocode} % \end{variable} % +% \begin{variable}{\l_@@_after_group_gtl} +% Tokens to insert after the current group ends. This variable must +% be emptied at the beginning of every group. +% \begin{macrocode} +\gtl_new:N \l_@@_after_group_gtl +% \end{macrocode} +% \end{variable} +% % \begin{variable}{\c_@@_parameters_tl} % Used to determine if a macro has simple parameters or not. % \begin{macrocode} @@ -1052,6 +1370,19 @@ % \end{macrocode} % \end{variable} % +% \subsubsection{\TeX{} parameters} +% +% \begin{variable}{\g_@@_mag_set_int} +% The first time \TeX{} uses the value of \tn{mag}, it stores it in a +% global parameter |mag_set| (initially $0$ to denote not being set). +% Any time \TeX{} needs the value of \tn{mag}, it checks that the +% value matches |mag_set|. This is done in \pkg{unravel} by +% \cs{@@_prepare_mag:}, storing |mag_set| in \cs{g_@@_mag_set_int}. +% \begin{macrocode} +\int_new:N \g_@@_mag_set_int +% \end{macrocode} +% \end{variable} +% % \subsection{Numeric codes} % \label{sec:numeric-codes} % @@ -2516,7 +2847,7 @@ \bool_if:NT \g_@@_internal_debug_bool { \@@_set_cmd: - \iow_term:x { Exp:~\int_use:N \l_@@_head_cmd_int } + \iow_term:x { Exp:~\int_to_arabic:n { \l_@@_head_cmd_int } } } \token_if_macro:NTF \l_@@_head_token { \@@_macro_call: } @@ -2769,6 +3100,21 @@ % \end{macro} % \end{macro} % +% \begin{macro}[aux]{\@@_scan_to:} +% Used when |to| is mandatory: after \tn{read} or \tn{readline} and +% after \tn{vsplit}. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_scan_to: + { + \@@_scan_keyword:nF { tToO } + { + \msg_error:nn { unravel } { missing-to } + \@@_prev_input:n { to } + } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[aux]{\@@_scan_font_ident:} % Find a font identifier. % \begin{macrocode} @@ -2794,8 +3140,8 @@ } { \msg_error:nn { unravel } { missing-font-id } + \@@_back_input: \@@_prev_input:n { \@@_nullfont: } - \@@_back_error: } } % \end{macrocode} @@ -2859,7 +3205,7 @@ % performed after placing the current token in a new level of % |prev_input| and telling the user about it. Once done with this % step, \cs{l_@@_head_tl} contains the tokens found. Convert them to -% the wanted level with \cs{@@_thing_use:nN} (at this stage, \TeX{} +% the wanted level with \cs{@@_thing_use_get:nnNN} (at this stage, \TeX{} % may complain about a missing number or incompatible glue units), and % place the result in |prev_input|. Finally, tell the user the tokens % that have been found and their value (and, if there was a single @@ -2880,7 +3226,11 @@ { \int_compare:nNnTF { ( #1 + \c_two ) / \c_four } > { ( #3 + \c_two ) / \c_four } - { \@@_back_input: } + { + \@@_back_input: + \msg_error:nn { unravel } { missing-something } + \tl_clear:N \l_@@_tmpa_tl + } { \tl_if_empty:nF {#2} { @@ -2889,9 +3239,8 @@ #2 \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl } + \@@_thing_use_get:nnNN {#1} {#3} \l_@@_head_tl \l_@@_tmpa_tl } - \tl_set:Nx \l_@@_tmpa_tl - { \@@_thing_use:nnN {#1} {#3} \l_@@_head_tl } \@@_prev_input_silent:V \l_@@_tmpa_tl \@@_set_action_text: \@@_set_action_text:x @@ -2937,9 +3286,9 @@ { 83 } { 1 \@@_scan_int: } % set_box_dimen { 84 } { 0 \@@_scan_int: } % set_shape { 85 } { 0 \@@_scan_int: } % def_code - { 86 } { 4 \@@_scan_font_ident: } % def_family - { 87 } { 4 \@@_scan_font_ident: } % set_font - { 88 } { 4 \@@_scan_font_ident: } % def_font + { 86 } { 4 \@@_scan_int: } % def_family + { 87 } { 4 } % set_font + { 88 } { 4 } % def_font { 89 } { \@@_thing_register: } % register } { 8 } @@ -3009,21 +3358,45 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[aux,EXP]{\@@_thing_use:nnN} -% Given a level~|#1|, call a function to convert the token list~|#2| -% to the correct level. This step may trigger \TeX{} errors, which -% should precisely match the expected ones. +% \begin{macro}[aux]{\@@_thing_use_get:nnNN} +% Given a level found~|#1| and a target level~|#2| (with |#1| in +% $[0,3]$ or |#1| and |#2| in $[4,5]$), turn the token list |#3| into +% the desired level, and store the result in |#4|. This step may +% trigger \TeX{} errors, which should precisely match the expected +% ones. % \begin{macrocode} -\cs_new:Npn \@@_thing_use:nnN #1#2 +\cs_new_protected:Npn \@@_thing_use_get:nnNN #1#2#3#4 { - \int_case:nnF { \int_min:nn {#1} {#2} } + \int_compare:nNnTF {#2} < { 3 } + { + \int_compare:nNnT {#1} = { 3 } + { \@@_tex_error:nV { incompatible-units } #3 } + \tl_set:Nx #4 + { + \int_case:nn { \int_min:nn {#1} {#2} } + { + { 0 } \int_eval:n + { 1 } \dim_eval:n + { 2 } \skip_eval:n + } + { \int_compare:nNnT {#1} = { 3 } \etex_mutoglue:D #3 } + } + } { - { 0 } \int_eval:n - { 1 } \dim_eval:n - { 2 } \skip_eval:n - { 3 } \muskip_eval:n + \int_compare:nNnTF {#2} = { 3 } + { + \int_case:nnF {#1} + { + { 0 } { \tl_set:Nx #4 { \int_eval:n {#3} } } + { 3 } { \tl_set:Nx #4 { \muskip_eval:n {#3} } } + } + { + \@@_tex_error:nV { incompatible-units } #3 + \tl_set:Nx #4 { \muskip_eval:n { \etex_gluetomu:D #3 } } + } + } + { \tl_set:Nx #4 { \@@_the:w #3 } } } - { \@@_the:w } } % \end{macrocode} % \end{macro} @@ -3222,28 +3595,10 @@ \@@_cmd_if_internal:TF { \int_compare:nNnTF {#1} = { 3 } - { - \@@_scan_something_internal:n { 3 } - \int_case:nnF \g_@@_val_level_int - { - { 0 } { \@@_scan_dim_unit:nN {#1} #2 } - { 3 } { } - } - { - \msg_error:nn { unravel } { incompatible-units } - % ^^A todo: error recovery - } - } - { - \@@_scan_something_internal:n { 1 } - \int_case:nnF \g_@@_val_level_int - { - { 0 } { \@@_scan_dim_unit:nN {#1} #2 } - { 3 } % ^^A todo: error recovery - { \msg_error:nn { unravel } { incompatible-units } } - } - { } - } + { \@@_scan_something_internal:n { 3 } } + { \@@_scan_something_internal:n { 1 } } + \int_compare:nNnT \g_@@_val_level_int = { 0 } + { \@@_scan_dim_unit:nN {#1} #2 } } { \@@_scan_dimen_char:nN {#1} #2 } \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl @@ -3283,7 +3638,7 @@ { \bool_if:NT #2 { - \@@_scan_keyword:nT { fF iI lL } + \@@_scan_keyword:nT { fFiIlL } { \@@_scan_inf_unit_loop: \@@_break:w @@ -3302,25 +3657,26 @@ { \@@_back_input: } \int_compare:nNnT {#1} = { 3 } { - \@@_scan_keyword:nT { mM uU } { \@@_break:w } + \@@_scan_keyword:nT { mMuU } { \@@_break:w } \msg_error:nn { unravel } { missing-mudim } \@@_break:w } - \@@_scan_keyword:nT { eE mM } { \@@_break:w } - \@@_scan_keyword:nT { eE xX } { \@@_break:w } - \@@_scan_keyword:nT { pP xX } { \@@_break:w } - \@@_scan_keyword:n { tT rR uU eE } - \@@_scan_keyword:nT { pP tT } { \@@_break:w } - \@@_scan_keyword:nT { iI nN } { \@@_break:w } - \@@_scan_keyword:nT { pP cC } { \@@_break:w } - \@@_scan_keyword:nT { cC mM } { \@@_break:w } - \@@_scan_keyword:nT { mM mM } { \@@_break:w } - \@@_scan_keyword:nT { bB pP } { \@@_break:w } - \@@_scan_keyword:nT { dD dD } { \@@_break:w } - \@@_scan_keyword:nT { cC cC } { \@@_break:w } - \@@_scan_keyword:nT { nN dD } { \@@_break:w } - \@@_scan_keyword:nT { nN cC } { \@@_break:w } - \@@_scan_keyword:nT { sS pP } { \@@_break:w } + \@@_scan_keyword:nT { eEmM } { \@@_break:w } + \@@_scan_keyword:nT { eExX } { \@@_break:w } + \@@_scan_keyword:nT { pPxX } { \@@_break:w } + \@@_scan_keyword:nT { tTrRuUeE } + { \@@_prepare_mag: } + \@@_scan_keyword:nT { pPtT } { \@@_break:w } + \@@_scan_keyword:nT { iInN } { \@@_break:w } + \@@_scan_keyword:nT { pPcC } { \@@_break:w } + \@@_scan_keyword:nT { cCmM } { \@@_break:w } + \@@_scan_keyword:nT { mMmM } { \@@_break:w } + \@@_scan_keyword:nT { bBpP } { \@@_break:w } + \@@_scan_keyword:nT { dDdD } { \@@_break:w } + \@@_scan_keyword:nT { cCcC } { \@@_break:w } + \@@_scan_keyword:nT { nNdD } { \@@_break:w } + \@@_scan_keyword:nT { nNcC } { \@@_break:w } + \@@_scan_keyword:nT { sSpP } { \@@_break:w } \@@_break_point: } \cs_new_protected_nopar:Npn \@@_scan_inf_unit_loop: @@ -3367,20 +3723,17 @@ \int_case:nnF \g_@@_val_level_int { { 0 } { \@@_scan_dimen:nN {#1} \c_false_bool } - {#1} { \@@_break:w } - } - { - \int_compare:nNnF { \g_@@_val_level_int + #1 } = 3 - { \msg_error:nn { unravel } { incompatible-units } } + { 1 } { } } + { \@@_break:w } } { \@@_back_input: \@@_scan_dimen:nN {#1} \c_false_bool } \@@_prev_input_join_get:nN {#1} \l_@@_tmpa_tl \seq_gput_right:Nn \g_@@_prev_input_seq { } \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_tmpa_tl - \@@_scan_keyword:nT { pP lL uU sS } + \@@_scan_keyword:nT { pPlLuUsS } { \@@_scan_dimen:nN {#1} \c_true_bool } - \@@_scan_keyword:nT { mM iI nN uU sS } + \@@_scan_keyword:nT { mMiInNuUsS } { \@@_scan_dimen:nN {#1} \c_true_bool } \@@_break_point: \@@_prev_input_join_get:nN {#1} \l_@@_tmpa_tl @@ -3654,9 +4007,9 @@ % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_scan_spec: { - \@@_scan_keyword:nTF { tT oO } { \@@_scan_normal_dimen: } + \@@_scan_keyword:nTF { tToO } { \@@_scan_normal_dimen: } { - \@@_scan_keyword:nT { sS pP rR eE aA dD } + \@@_scan_keyword:nT { sSpPrReEaAdD } { \@@_scan_normal_dimen: } } \@@_scan_left_brace: @@ -3742,11 +4095,7 @@ { 3 } % vsplit { \@@_scan_int: - \@@_scan_keyword:nF { tT oO } - { - \msg_error:nn { unravel } { missing-to } - \@@_prev_input:n { to } - } + \@@_scan_to: \@@_scan_normal_dimen: } } @@ -3760,14 +4109,18 @@ % For leaders, we need to fetch a glue. In all cases, retrieve the % box construction (such as |\raise3pt\vsplit7to5em|). Finally, let % \TeX{} run the code and print what we have done. +% In the case of \tn{shipout}, check that \tn{mag} has a value +% between $1$ and $32768$. % \begin{macrocode} \cs_new_protected:Npn \@@_do_simple_box:N #1 { \bool_if:NTF #1 { \@@_do_leaders_fetch_skip: } { \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl + \tl_if_head_eq_meaning:VNT \l_@@_head_tl \tex_shipout:D + { \@@_prepare_mag: } \tl_use:N \l_@@_head_tl \scan_stop: - \gtl_put_right:NV \g_@@_output_gtl \l_@@_head_tl + \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl \@@_print_action:x { \tl_to_str:N \l_@@_head_tl } } } @@ -3812,8 +4165,8 @@ % is such that all that material is collected and put into the input % that we will study. % We must remember to find a glue for leaders, and for this -% we use a stack of booleans: the top is true if the innermost box is -% part of leaders. +% we use a stack of letters |v|, |h| for vertical/horizontal +% leaders, and |Z| for normal boxes. % \begin{macrocode} \cs_new_protected:Npn \@@_do_box_explicit:N #1 { @@ -3838,6 +4191,10 @@ % % \begin{macro}[aux]{\@@_box_hook:N} % \begin{macro}[aux]{\@@_box_hook:w, \@@_box_hook_end:} +% Used to capture the contents of an \tn{everyhbox} or similar, +% without altering \tn{everyhbox} too much (just add one token at the +% start). The various \texttt{o}-expansions remove +% \cs{prg_do_nothing:}, used to avoid losing braces. % \begin{macrocode} \cs_new_protected:Npn \@@_box_hook:N #1 { @@ -3855,6 +4212,7 @@ { \exp_args:No #1 {##1} \cs_gset_eq:NN \@@_box_hook:w \prg_do_nothing: + \gtl_clear:N \l_@@_after_group_gtl \@@_print_action: \@@_back_input:o {##1} \@@_set_action_text:x @@ -4009,30 +4367,35 @@ % ^^A todo: implement \@@_end_disc_group: % ^^A todo: implement \@@_end_math_choice_group: % -% \begin{macro}[aux]{\@@_handle_left_brace:} +% \begin{macro}[aux]{\@@_handle_right_brace:} % When an end-group character is sensed, the result depends on the % current group type. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_handle_left_brace: +\cs_new_protected_nopar:Npn \@@_handle_right_brace: { - \int_case:nnF \@@_currentgrouptype: + \int_compare:nTF { 1 <= \@@_currentgrouptype: <= 13 } { - { 1 } { \@@_end_simple_group: } % simple - { 2 } { \@@_end_box_group: } % hbox - { 3 } { \@@_end_box_group: } % adjusted_hbox - { 4 } { \@@_end_graf: \@@_end_box_group: } % vbox - { 5 } { \@@_end_graf: \@@_end_box_group: } % vtop - { 6 } { \@@_end_align_group: } % align - { 7 } { \@@_end_no_align_group: } % no_align - { 8 } { \@@_end_output_group: } % output - { 9 } { \@@_end_simple_group: } % math - { 10 } { \@@_end_disc_group: } % disc - { 11 } { \@@_end_graf: \@@_end_simple_group: } % insert - { 12 } { \@@_end_graf: \@@_end_simple_group: } % vcenter - { 13 } { \@@_end_math_choice_group: } % math_choice + \gtl_gconcat:NNN \g_@@_output_gtl + \g_@@_output_gtl \c_group_end_gtl + \@@_back_input_gtl:N \l_@@_after_group_gtl + \int_case:nn \@@_currentgrouptype: + { + { 1 } { \@@_end_simple_group: } % simple + { 2 } { \@@_end_box_group: } % hbox + { 3 } { \@@_end_box_group: } % adjusted_hbox + { 4 } { \@@_end_graf: \@@_end_box_group: } % vbox + { 5 } { \@@_end_graf: \@@_end_box_group: } % vtop + { 6 } { \@@_end_align_group: } % align + { 7 } { \@@_end_no_align_group: } % no_align + { 8 } { \@@_end_output_group: } % output + { 9 } { \@@_end_simple_group: } % math + { 10 } { \@@_end_disc_group: } % disc + { 11 } { \@@_end_graf: \@@_end_simple_group: } % insert + { 12 } { \@@_end_graf: \@@_end_simple_group: } % vcenter + { 13 } { \@@_end_math_choice_group: } % math_choice + } } { % bottom_level, semi_simple, math_shift, math_left - \@@_back_input: \l_@@_head_token \@@_print_action: } @@ -4047,8 +4410,6 @@ \cs_new_protected_nopar:Npn \@@_end_simple_group: { \l_@@_head_token - \gtl_gconcat:NNN \g_@@_output_gtl - \g_@@_output_gtl \c_group_end_gtl \@@_print_action: } % \end{macrocode} @@ -4062,13 +4423,17 @@ \cs_new_protected_nopar:Npn \@@_end_box_group: { \seq_pop:NN \l_@@_leaders_box_seq \l_@@_tmpa_tl - \str_if_eq_x:nnTF \l_@@_tmpa_tl { Z } + \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 } { \@@_end_simple_group: } { \@@_get_x_non_relax: \@@_set_cmd: \int_compare:nNnTF \l_@@_head_cmd_int - = { \@@_tex_use:n { \l_@@_tmpa_tl skip } } + = { \@@_tex_use:n { #1 skip } } { \tl_put_left:Nn \l_@@_head_tl { \c_group_end_token } \@@_do_append_glue: @@ -4191,6 +4556,7 @@ \mode_if_inner:TF { \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl + \@@_back_input_gtl:N \l_@@_after_group_gtl $ % $ } { @@ -4204,6 +4570,7 @@ \msg_error:nn { unravel } { missing-dollar } } \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl + \@@_back_input_gtl:N \l_@@_after_group_gtl $ $ } \@@_print_action: @@ -4221,7 +4588,7 @@ { \@@_set_action_text: \bool_if:NT \g_@@_internal_debug_bool - { \iow_term:x { Cmd:~\int_use:N \l_@@_head_cmd_int } } + { \iow_term:x { Cmd:~\int_to_arabic:n { \l_@@_head_cmd_int } } } \cs_if_exist_use:cF { @@_cmd_ \int_use:N \l_@@_head_cmd_int : } { \msg_error:nnx { unravel } { internal } { unknown-command } } @@ -4267,7 +4634,7 @@ % \end{macrocode} % % Begin-group characters are sent to the output, as their grouping -% behaviour may affect the scope of font changes, for instance. The are +% behaviour may affect the scope of font changes, for instance. They are % also performed. % \begin{macrocode} \@@_new_tex_cmd:nn { begin-group_char } % 1 @@ -4276,12 +4643,13 @@ \g_@@_output_gtl \c_group_begin_gtl \@@_print_action: \l_@@_head_token + \gtl_clear:N \l_@@_after_group_gtl } % \end{macrocode} % % \begin{macrocode} \@@_new_tex_cmd:nn { end-group_char } % 2 - { \@@_handle_left_brace: } + { \@@_handle_right_brace: } % \end{macrocode} % % Math shift characters quit vertical mode, and start math mode. @@ -4436,6 +4804,7 @@ } % \end{macrocode} % +% ^^A todo: \dump only at bottom-level (\currentgrouptype=0) % \begin{macrocode} \@@_new_tex_cmd:nn { stop } % 14 { @@ -4865,9 +5234,33 @@ } % \end{macrocode} % +% Save the next token at the end of \cs{l_@@_after_group_gtl}, unless +% we are at the bottom group level, in which case, the token is ignored +% completely. % \begin{macrocode} \@@_new_tex_cmd:nn { after_group } % 41 - { \msg_error:nnx { unravel } { not-implemented } { aftergroup } } + { + \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_head_tl + \@@_get_next: + \int_compare:nNnTF \@@_currentgrouptype: = \c_zero + { + \@@_print_action:x + { + Aftergroup~(level~0~=>~dropped):~ + \tl_to_str:N \l_@@_tmpa_tl + \gtl_to_str:N \l_@@_head_gtl + } + } + { + \gtl_concat:NNN \l_@@_after_group_gtl + \l_@@_after_group_gtl \l_@@_head_gtl + \@@_print_action:x + { + Aftergroup:~\tl_to_str:N \l_@@_tmpa_tl + \gtl_to_str:N \l_@@_head_gtl + } + } + } % \end{macrocode} % % See \cs{@@_do_append_glue:}. @@ -5124,19 +5517,20 @@ } % \end{macrocode} % -% ^^A todo: take \aftergroup into account % \begin{macrocode} \@@_new_tex_cmd:nn { begin_group } % 61 { \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl - \@@_print_action: \l_@@_head_token + \gtl_clear:N \l_@@_after_group_gtl + \@@_print_action: } \@@_new_tex_cmd:nn { end_group } % 62 { \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl - \@@_print_action: + \@@_back_input_gtl:N \l_@@_after_group_gtl \l_@@_head_token + \@@_print_action: } % \end{macrocode} % @@ -5245,24 +5639,24 @@ } { 6 } % pdfliteral { - \@@_scan_keyword:nF { dD iI rR eE cC tT } - { \@@_scan_keyword:n { pP aA gG eE } } + \@@_scan_keyword:nF { dDiIrReEcCtT } + { \@@_scan_keyword:n { pPaAgGeE } } \@@_scan_pdf_ext_toks: } { 7 } % pdfobj { \@@_scan_keyword:nTF - { rR eE sS eE rR vV eE oO bB jJ nN uU mM } + { rReEsSeErRvVeEoObBjJnNuUmM } { \@@_skip_optional_space: } { - \@@_scan_keyword:nF { uU sS eE oO bB jJ nN uU mM } + \@@_scan_keyword:nF { uUsSeEoObBjJnNuUmM } { \@@_scan_int: } - \@@_scan_keyword:nT { sS tT rR eE aA mM } + \@@_scan_keyword:nT { sStTrReEaAmM } { - \@@_scan_keyword:nT { aA tT tT rR } + \@@_scan_keyword:nT { aAtTtTrR } { \@@_scan_pdf_ext_toks: } } - \@@_scan_keyword:n { fF iI lL eE } + \@@_scan_keyword:n { fFiIlLeE } \@@_scan_pdf_ext_toks: } } @@ -5270,9 +5664,9 @@ { \@@_scan_int: } { 9 } % pdfxform { - \@@_scan_keyword:nT { aA tT tT rR } + \@@_scan_keyword:nT { aAtTtTrR } { \@@_scan_pdf_ext_toks: } - \@@_scan_keyword:nTF { rR eE sS oO uU rR cC eE sS } + \@@_scan_keyword:nTF { rReEsSoOuUrRcCeEsS } { \@@_scan_pdf_ext_toks: } \@@_scan_int: } @@ -5285,10 +5679,10 @@ { 13 } % pdfannot { \@@_scan_keyword:nTF - { rR eE sS eE rR vV eE oO bB jJ nN uU mM } + { rReEsSeErRvVeEoObBjJnNuUmM } { \@@_scan_optional_space: } { - \@@_scan_keyword:nT { uU sS eE oO bB jJ nN uU mM } + \@@_scan_keyword:nT { uUsSeEoObBjJnNuUmM } { \@@_scan_int: } \@@_scan_alt_rule: \@@_scan_pdf_ext_toks: @@ -5310,10 +5704,10 @@ } { 16 } % pdfoutline { - \@@_scan_keyword:nT { aA tT tT rR } + \@@_scan_keyword:nT { aAtTtTrR } { \@@_scan_pdf_ext_toks: } \@@_scan_action: - \@@_scan_keyword:nT { cC oO uU nN tT } + \@@_scan_keyword:nT { cCoOuUnNtT } { \@@_scan_int: } \@@_scan_pdf_ext_toks: } @@ -5332,7 +5726,7 @@ { 23 } % pdfcatalog { \@@_scan_pdf_ext_toks: - \@@_scan_keyword:n { oO pP eE nN aA cC tT iI oO nN } + \@@_scan_keyword:n { oOpPeEnNaAcCtTiIoOnN } { \@@_scan_action: } } { 24 } % pdfnames @@ -5422,7 +5816,7 @@ \cs_new_protected_nopar:Npn \@@_scan_rule_attr: { \@@_scan_alt_rule: - \@@_scan_keyword:nT { aA tT tT rR } + \@@_scan_keyword:nT { aAtTtTrR } { \@@_scan_pdf_ext_toks: } } % \end{macrocode} @@ -5839,7 +6233,7 @@ \@@_scan_keyword:nTF { aAtT } { \@@_scan_normal_dimen: } { - \@@_scan_keyword:nT { sS cC aA lL eE dD } + \@@_scan_keyword:nT { sScCaAlLeEdD } { \@@_scan_int: } } \bool_gset_false:N \g_@@_name_in_progress_bool @@ -5910,21 +6304,55 @@ } % \end{macrocode} % +% \begin{macro}[aux, EXP]{\@@_read_to_cs_safe:nTF, \@@_read_to_cs_safe:fTF} +% After \tn{read} or \tn{readline}, find an int, the mandatory +% keyword |to|, and an assignable token. The \tn{read} and +% \tn{readline} primitives throw a fatal error in \tn{nonstopmode} +% and in \tn{batchmode} when trying to read from a stream that is +% outside $[0,15]$ or that is not open (according to \tn{ifeof}). We +% detect this situation using \cs{@@_read_to_cs_safe:nTF} after +% grabbing all arguments of the primitives. If reading is unsafe, +% let the user know that \TeX{} would have thrown a fatal error. % \begin{macrocode} \@@_prefixed_new:nn { read_to_cs } % 96 { - \@@_prev_input:V \l_@@_head_tl + \@@_prev_input_silent:V \l_@@_head_tl \@@_print_action:x { \tl_to_str:N \l_@@_head_tl } \@@_scan_int: - \@@_scan_keyword:nF { tToO } + \@@_scan_to: + \@@_scan_r_token: + \seq_get_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl + \@@_read_to_cs_safe:fTF + { \@@_tl_first_int:N \l_@@_tmpa_tl } + { \@@_assign_token:n { } } { - \msg_error:nn { unravel } { missing-to } - \@@_prev_input:n { to } + \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl + \@@_tex_fatal_error:nV { cannot-read } \l_@@_head_tl + } + } +\prg_new_conditional:Npnn \@@_read_to_cs_safe:n #1 { TF } + { + \int_compare:nNnTF { \etex_interactionmode:D } > { 1 } + { \prg_return_true: } + { + \int_compare:nNnTF {#1} < { 0 } + { \prg_return_false: } + { + \int_compare:nNnTF {#1} > { 15 } + { \prg_return_false: } + { + \tex_ifeof:D #1 \exp_stop_f: + \prg_return_false: + \else: + \prg_return_true: + \fi: + } + } } - \@@_scan_r_token: - \@@_assign_token:n { } } +\cs_generate_variant:Nn \@@_read_to_cs_safe:nTF { f } % \end{macrocode} +% \end{macro} % % \begin{macrocode} \@@_prefixed_new:nn { def } % 97 @@ -6312,8 +6740,8 @@ \@@_scan_file_name: \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl \tl_set:Nx \l_@@_tmpa_tl { \tl_tail:N \l_@@_head_tl } - \@@_tl_gset_input:Nno \g_@@_tmpc_tl { } \l_@@_tmpa_tl - \@@_back_input:V \g_@@_tmpc_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 } } % \end{macrocode} @@ -6380,7 +6808,7 @@ { 23 } \@@_scan_pdf_ext_toks: { 24 } { - \@@_scan_keyword:n { fF iI lL eE } + \@@_scan_keyword:n { fFiIlLeE } \@@_scan_pdf_ext_toks: } { 25 } \@@_scan_pdffiledump: @@ -6402,23 +6830,23 @@ { \@@_scan_int: \@@_scan_int: } \cs_new_protected_nopar:Npn \@@_scan_pdfcolorstackinit: { - \@@_scan_keyword:nTF { pP aA gG eE } + \@@_scan_keyword:nTF { pPaAgGeE } { \bool_set_true:N \l_@@_tmpa_bool } { \bool_set_false:N \l_@@_tmpb_bool } - \@@_scan_keyword:nF { dD iI rR eE cC tT } - { \@@_scan_keyword:n { pP aA gG eE } } + \@@_scan_keyword:nF { dDiIrReEcCtT } + { \@@_scan_keyword:n { pPaAgGeE } } \@@_scan_toks_to_str: } \cs_new_protected_nopar:Npn \@@_scan_pdffiledump: { - \@@_scan_keyword:nT { oO fF fF sS eE tT } \@@_scan_int: - \@@_scan_keyword:nT { lL eE nN gG tT hH } \@@_scan_int: + \@@_scan_keyword:nT { oOfFfFsSeEtT } \@@_scan_int: + \@@_scan_keyword:nT { lLeEnNgGtThH } \@@_scan_int: \@@_scan_pdf_ext_toks: } \cs_new_protected_nopar:Npn \@@_scan_pdfmatch: { - \@@_scan_keyword:n { iI cC aA sS eE } - \@@_scan_keyword:nT { sS uU bB cC oO uU nN tT } + \@@_scan_keyword:n { iIcCaAsSeE } + \@@_scan_keyword:nT { sSuUbBcCoOuUnNtT } { \@@_scan_int: } \@@_scan_pdf_ext_toks: \@@_scan_pdf_ext_toks: @@ -7040,7 +7468,7 @@ { [===== \bool_if:NT \g_@@_number_steps_bool - { ~ Step ~ \int_use:N \g_@@_step_int \ } + { ~ Step ~ \int_to_arabic:n { \g_@@_step_int } ~ } =====]~ \int_compare:nNnTF { \str_count:N \g_@@_action_text_str } @@ -7091,12 +7519,15 @@ \cs_new_protected_nopar:Npn \@@_print_assigned_register: { \@@_after_assignment: % ^^A todo: simplify - \@@_print_action:x + \exp_args:Nx \@@_print_action:x { - Set~ \exp_after:wN \token_to_str:N \l_@@_defined_tl - \tl_if_single:NT \l_@@_defined_tl - { ( \exp_after:wN \token_to_meaning:N \l_@@_defined_tl ) } - = \exp_after:wN \@@_the:w \l_@@_defined_tl + \exp_not:n + { + Set~ \exp_after:wN \token_to_str:N \l_@@_defined_tl + \tl_if_single:NT \l_@@_defined_tl + { ( \exp_after:wN \token_to_meaning:N \l_@@_defined_tl ) } + } + = \exp_not:N \tl_to_str:n { \@@_the:w \l_@@_defined_tl } } \@@_omit_after_assignment:w } @@ -7287,6 +7718,50 @@ % % ^^A todo: I suspect a bug if given 'a' twice in a row % +% \subsubsection{Errors} +% +% \begin{macro}[int]{\@@_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} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_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} +\cs_new_protected:Npn \@@_tex_error:nn #1#2 + { + \msg_error:nnxxx { unravel } { tex-error } + { \tl_to_str:n {#2} } + { \use:c { @@_tex_msg_error_#1: } } + { \use:c { @@_tex_msg_help_#1: } } + } +\cs_generate_variant:Nn \@@_tex_error:nn { nV } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_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. +% \begin{macrocode} +\cs_new_protected:Npn \@@_tex_fatal_error:nn #1#2 + { + \msg_error:nnxxx { unravel } { tex-fatal } + { \tl_to_str:n {#2} } + { \use:c { @@_tex_msg_error_#1: } } + { \use:c { @@_tex_msg_help_#1: } } + } +\cs_generate_variant:Nn \@@_tex_fatal_error:nn { nV } +% \end{macrocode} +% \end{macro} +% % \subsection{Keys} % % Each key needs to be defined twice: for its default setting and for @@ -7426,6 +7901,7 @@ \gtl_gclear:N \g_@@_after_assignment_gtl \bool_gset_true:N \g_@@_set_box_allowed_bool \bool_gset_false:N \g_@@_name_in_progress_bool + \gtl_clear:N \l_@@_after_group_gtl } % \end{macrocode} % \end{macro} @@ -7486,8 +7962,6 @@ { Missing~font~identifier.~\iow_char:N\\nullfont~inserted. } \msg_new:nnn { unravel } { missing-rparen } { Missing~right~parenthesis~inserted~for~expression. } -\msg_new:nnn { unravel } { incompatible-units } - { Mu~glue/dimen~used~as~a~normal~glue/dimen~or~vice-versa. } \msg_new:nnn { unravel } { missing-mudim } { Missing~mu~unit. } \msg_new:nnn { unravel } { missing-cs } @@ -7544,6 +8018,63 @@ { The~following~feature~is~not~implemented:~'#1'. } \msg_new:nnn { unravel } { endinput-ignored } { The~primitive~\iow_char:N\\endinput~was~ignored. } +\msg_new:nnn { unravel } { missing-something } + { Something~is~missing,~sorry! } +\msg_new:nnnn { unravel } { tex-error } + { TeX~sees~"#1"~and~throws~an~error:\\\\ \iow_indent:n {#2} } + { + \tl_if_empty:nTF {#3} + { TeX~provides~no~further~help~for~this~error. } + { TeX's~advice~is:\\\\ \iow_indent:n {#3} } + } +\msg_new:nnnn { unravel } { tex-fatal } + { TeX~sees~"#1"~and~throws~a~fatal~error:\\\\ \iow_indent:n {#2} } + { + \tl_if_empty:nTF {#3} + { TeX~provides~no~further~help~for~this~error. } + { TeX's~advice~is:\\\\ \iow_indent:n {#3} } + } +% \end{macrocode} +% +% Some error messages from \TeX{} itself. +% \begin{macrocode} +\@@_tex_msg_new:nnn { incompatible-mag } + { + Incompatible~magnification~ + ( \int_to_arabic:n { \@@_mag: } ); \\ + \ the~previous~value~will~be~retained + } + { + I~can~handle~only~one~magnification~ratio~per~job.~So~I've\\ + reverted~to~the~magnification~you~used~earlier~on~this~run. + } +\@@_tex_msg_new:nnn { illegal-mag } + { + Illegal~magnification~has~been~changed~to~1000~ + ( \int_to_arabic:n { \@@_mag: } ) + } + { The~magnification~ratio~must~be~between~1~and~32768. } +\@@_tex_msg_new:nnn { incompatible-units } + { Incompatible~glue~units } + { I'm~going~to~assume~that~1mu=1pt~when~they're~mixed. } +% \end{macrocode} +% +% Fatal \TeX{} error messages. +% \begin{macrocode} +\@@_tex_msg_new:nnn { cannot-read } + { ***~(cannot~\iow_char:N\\read~from~terminal~in~nonstop~modes) } + { } +\@@_tex_msg_new:nnn { file-error } + { ***~(job~aborted,~file~error~in~nonstop~mode) } + { } +\@@_tex_msg_new:nnn { interwoven-preambles } + { (interwoven~alignment~preambles~are~not~allowed) } + { } +% \end{macrocode} +% +% Restore catcodes to their original values. +% \begin{macrocode} +\@@_setup_restore: % \end{macrocode} % % \begin{macrocode} diff --git a/Master/texmf-dist/tex/latex/unravel/unravel.sty b/Master/texmf-dist/tex/latex/unravel/unravel.sty index 630584380a7..9d051e10e64 100644 --- a/Master/texmf-dist/tex/latex/unravel/unravel.sty +++ b/Master/texmf-dist/tex/latex/unravel/unravel.sty @@ -21,39 +21,161 @@ %% http://www.latex-project.org/lppl.txt %% %% ----------------------------------------------------------------------- +\begingroup\let\c\catcode\fam32\c\fam10\advance\fam5\c\fam14\c45 12 % +\c54 12\c55 12\c56 12\c57 12\c58 11\c95 11\c104 11\c106 11\c107 11 % +\c113 11\c115 11\c119 11\c120 11\c121 11\c122 11\endlinechar-1 % +\expandafter\ifx\csname unravel\endcsname\relax +\else\endinput\expandafter\endgroup\fi +\c84 11\c88 11\c35 6\c123 1\c125 2\c62 12\c61 12\c43 12 % +\expandafter\ifx\csname numexpr\endcsname\relax +\errmessage{unravel requires \numexpr from eTeX} +\endinput\expandafter\endgroup\fi +\expandafter\ifx\csname protected\endcsname\relax +\errmessage{unravel requires \protected from eTeX} +\endinput\expandafter\endgroup\fi +\expandafter\ifx\csname currentgrouplevel\endcsname\relax\else +\ifnum\currentgrouplevel>1 \errmessage{unravel loaded in a group} +\endinput\expandafter\expandafter\expandafter\endgroup\fi\fi +\catcode 32 = 9 \relax +\catcode 126 = 10 \relax +\gdef \l__unravel_setup_restore_tl { } +\protected \gdef \__unravel_setup_restore: + { + \l__unravel_setup_restore_tl + \def \l__unravel_setup_restore_tl { } + } +\protected \gdef \__unravel_setup_save: + { + \edef \l__unravel_setup_restore_tl + { + \__unravel_setup_save_aux:w 0 = + \endlinechar = \the \endlinechar + \escapechar = \the \escapechar + \newlinechar = \the \newlinechar + \relax + } + } +\long \gdef \__unravel_setup_save_aux:w #1 = + { + \catcode #1 = \the \catcode #1 ~ + \ifnum 255 > #1 ~ + \expandafter \__unravel_setup_save_aux:w + \the \numexpr #1 + 1 \expandafter = + \fi + } +\protected \long \gdef \__unravel_setup_catcodes:nnn #1 #2 #3 + { + \ifnum #1 > #2 ~ \else + \catcode #1 = #3 ~ + \expandafter \__unravel_setup_catcodes:nnn \expandafter + { \the \numexpr #1 + 1 } {#2} {#3} + \fi + } +\protected \gdef \__unravel_setup_latexe: + { + \__unravel_setup_save: + \__unravel_setup_catcodes:nnn {0} {8} {15} + \catcode 9 = 10 ~ + \catcode 10 = 12 ~ + \catcode 11 = 15 ~ + \catcode 12 = 13 ~ + \catcode 13 = 5 ~ + \__unravel_setup_catcodes:nnn {14} {31} {15} + \catcode 32 = 10 ~ + \catcode 33 = 12 ~ + \catcode 34 = 12 ~ + \catcode 35 = 6 ~ + \catcode 36 = 3 ~ + \catcode 37 = 14 ~ + \catcode 38 = 4 ~ + \__unravel_setup_catcodes:nnn {39} {63} {12} + \__unravel_setup_catcodes:nnn {64} {90} {11} + \catcode 91 = 12 ~ + \catcode 92 = 0 ~ + \catcode 93 = 12 ~ + \catcode 94 = 7 ~ + \catcode 95 = 8 ~ + \catcode 96 = 12 ~ + \__unravel_setup_catcodes:nnn {97} {122} {11} + \catcode 123 = 1 ~ + \catcode 124 = 12 ~ + \catcode 125 = 2 ~ + \catcode 126 = 13 ~ + \catcode 127 = 15 ~ + \__unravel_setup_catcodes:nnn {128} {255} {12} + \endlinechar = 13 ~ + \escapechar = 92 ~ + \newlinechar = 10 ~ + } +\protected \gdef \__unravel_setup_unravel: + { + \__unravel_setup_save: + \__unravel_setup_catcodes:nnn {0} {8} {15} + \catcode 9 = 9 ~ + \catcode 10 = 12 ~ + \catcode 11 = 15 ~ + \catcode 12 = 13 ~ + \catcode 13 = 5 ~ + \__unravel_setup_catcodes:nnn {14} {31} {15} + \catcode 32 = 9 ~ + \catcode 33 = 12 ~ + \catcode 34 = 12 ~ + \catcode 35 = 6 ~ + \catcode 36 = 3 ~ + \catcode 37 = 14 ~ + \catcode 38 = 4 ~ + \__unravel_setup_catcodes:nnn {39} {57} {12} + \catcode 58 = 11 ~ + \__unravel_setup_catcodes:nnn {59} {64} {12} + \__unravel_setup_catcodes:nnn {65} {90} {11} + \catcode 91 = 12 ~ + \catcode 92 = 0 ~ + \catcode 93 = 12 ~ + \catcode 94 = 7 ~ + \catcode 95 = 11 ~ + \catcode 96 = 12 ~ + \__unravel_setup_catcodes:nnn {97} {122} {11} + \catcode 123 = 1 ~ + \catcode 124 = 12 ~ + \catcode 125 = 2 ~ + \catcode 126 = 10 ~ + \catcode 127 = 15 ~ + \__unravel_setup_catcodes:nnn {128} {255} {12} + \escapechar = 92 ~ + \endlinechar = 32 ~ + \newlinechar = 10 ~ + } +\expandafter \endgroup \__unravel_setup_latexe: \RequirePackage{expl3,xparse}[2015/09/11] \RequirePackage{gtl}[2015/09/21] -\ProvidesExplPackage - {unravel} {2015/09/22} {0.1} {Watching TeX digest tokens} -\cs_if_exist:NF \str_range:nnn { \RequirePackage{l3str} } +\csname cs_if_exist:cF\endcsname{str_range:nnn}{\RequirePackage{l3str}} +\csname use:n\endcsname + {% + \csname __unravel_setup_restore:\endcsname + \ProvidesExplPackage + {unravel} {2015/09/30} {0.2} {Watching TeX digest tokens}% + \csname __unravel_setup_unravel:\endcsname + }% \cs_new_eq:NN \__unravel_currentgrouptype: \etex_currentgrouptype:D \cs_new_protected_nopar:Npn \__unravel_set_escapechar:n { \int_set:Nn \tex_escapechar:D } \cs_new_eq:NN \__unravel_everyeof:w \etex_everyeof:D \cs_new_eq:NN \__unravel_everypar:w \tex_everypar:D \cs_new_eq:NN \__unravel_hbox:w \tex_hbox:D +\cs_new_eq:NN \__unravel_mag: \tex_mag:D \cs_new_eq:NN \__unravel_nullfont: \tex_nullfont:D \cs_new_eq:NN \__unravel_the:w \tex_the:D \cs_new_eq:NN \c__unravel_prompt_ior \c_sixteen \cs_new_eq:NN \c__unravel_noprompt_ior \c_minus_one -\cs_if_exist:NF \exp_last_unbraced:NNn - { \cs_new_eq:NN \exp_last_unbraced:NNn \use:nnn } -\cs_generate_variant:Nn \exp_last_unbraced:NNn { NNv } \cs_generate_variant:Nn \str_head:n { f } \cs_generate_variant:Nn \tl_to_str:n { o } \cs_generate_variant:Nn \tl_if_head_eq_meaning:nNT { V } -\cs_generate_variant:Nn \tl_if_head_is_space:nTF { o } -\cs_generate_variant:Nn \tl_if_head_is_space:nT { V } -\cs_generate_variant:Nn \tl_if_head_is_N_type:nTF { o } \cs_generate_variant:Nn \tl_if_in:nnF { nV } \cs_generate_variant:Nn \tl_if_in:nnTF { nV } -\cs_generate_variant:Nn \tl_if_eq:nnT { V } \cs_generate_variant:Nn \tl_if_in:NnTF { No , NV } \cs_generate_variant:Nn \tl_if_single_token:nT { V } \cs_generate_variant:Nn \tl_gset_rescan:Nnn { Nnx } -\cs_generate_variant:Nn \gtl_gput_left:Nn { Nx , NV , No } -\cs_generate_variant:Nn \gtl_gput_right:Nn { Nx , NV } -\cs_generate_variant:Nn \gtl_put_right:Nn { NV } +\cs_generate_variant:Nn \gtl_gput_right:Nn { NV } \cs_generate_variant:Nn \ior_get_str:NN { Nc } \cs_generate_variant:Nn \gtl_if_empty:NTF { c } \cs_generate_variant:Nn \gtl_to_str:N { c } @@ -64,24 +186,66 @@ \cs_generate_variant:Nn \gtl_gclear:N { c } \cs_generate_variant:Nn \gtl_gclear_new:N { c } \cs_new_protected_nopar:Npn \__unravel_tmp:w { } -\cs_new_protected:Npn \__unravel_tl_gset_input:Nnn #1#2#3 +\cs_set_protected:Npn \__unravel_tmp:w #1 { - \group_begin: - \__unravel_everyeof:w \exp_after:wN { \token_to_str:N @ @ #1 } - #2 - \tl_gclear:N #1 - \exp_after:wN \__unravel_tl_gset_input_aux:wN - \exp_after:wN \prg_do_nothing: - \tex_input:D \tl_to_str:n {#3} \scan_stop: - \group_end: - \tl_gput_right:NV #1 \__unravel_everyeof:w + \cs_new_protected:Npn \__unravel_file_get:nN ##1##2 + { + \group_begin: + \__unravel_everyeof:w { #1 ##2 } + \exp_after:wN \__unravel_file_get_aux:wN + \exp_after:wN \prg_do_nothing: + \tex_input:D ##1 \scan_stop: + } + \cs_new_protected:Npn \__unravel_file_get_aux:wN ##1 #1 ##2 + { + \group_end: + \tl_set:Nx ##2 + { \exp_not:o {##1} \exp_not:V \__unravel_everyeof:w } + } } -\cs_generate_variant:Nn \__unravel_tl_gset_input:Nnn { Nno } -\use:x +\exp_args:No \__unravel_tmp:w { \token_to_str:N : : } +\cs_new:Npn \__unravel_tl_first_int:N #1 + { + \int_eval:n + { + \exp_after:wN \__unravel_tl_first_int_aux:Nn + \exp_after:wN \__unravel_tl_first_int_aux:Nn + #1 ? 0 ? \q_stop + } + } +\cs_new:Npn \__unravel_tl_first_int_aux:Nn #1#2 + { + \tl_if_single:nT {#2} + { + \token_if_eq_catcode:NNT + #2 + { + \if_int_compare:w 1 < 1 #2 \exp_stop_f: + #2 + \exp_after:wN \use_i_ii:nnn + \exp_after:wN \__unravel_tl_first_int_aux:Nn + \exp_after:wN \use_none_delimit_by_q_stop:w + \fi: + } + } + #1 + } +\cs_new_protected_nopar:Npn \__unravel_prepare_mag: { - \cs_new_protected:Npn \exp_not:N \__unravel_tl_gset_input_aux:wN - ##1 \token_to_str:N @ @ ##2 - } { \tl_gset:No #2 {#1} } + \int_compare:nNnT { \g__unravel_mag_set_int } > { 0 } + { + \int_compare:nNnF { \__unravel_mag: } = { \g__unravel_mag_set_int } + { + \__unravel_tex_error:nn { incompatible-mag } { } + \int_gset_eq:NN \__unravel_mag: \g__unravel_mag_set_int + } + } + \int_compare:nF { 1 <= \__unravel_mag: <= 32768 } + { + \__unravel_tex_error:nV { illegal-mag } \l__unravel_head_tl + \int_gset:Nn \__unravel_mag: { 1000 } + } + \int_gset_eq:NN \g__unravel_mag_set_int \__unravel_mag: + } \cs_new_nopar:Npn \__unravel_strip_escape:w { \tex_romannumeral:D @@ -315,6 +479,7 @@ \gtl_new:N \g__unravel_after_assignment_gtl \bool_new:N \g__unravel_set_box_allowed_bool \bool_new:N \g__unravel_name_in_progress_bool +\gtl_new:N \l__unravel_after_group_gtl \group_begin: \cs_set:Npx \__unravel_tmp:w #1 { \c_hash_str #1 } \tl_const:Nx \c__unravel_parameters_tl @@ -341,6 +506,7 @@ \tl_const:Nn \c__unravel_comma_tl { , } \tl_const:Nn \c__unravel_point_tl { . } \gtl_const:Nx \c__unravel_frozen_relax_gtl { \if_int_compare:w 0 = 0 \fi: } +\int_new:N \g__unravel_mag_set_int \cs_new_protected:Npn \__unravel_tex_const:nn #1#2 { \int_const:cn { c__unravel_tex_#1_int } {#2} } \cs_new:Npn \__unravel_tex_use:n #1 { \int_use:c { c__unravel_tex_#1_int } } @@ -1455,7 +1621,7 @@ \bool_if:NT \g__unravel_internal_debug_bool { \__unravel_set_cmd: - \iow_term:x { Exp:~\int_use:N \l__unravel_head_cmd_int } + \iow_term:x { Exp:~\int_to_arabic:n { \l__unravel_head_cmd_int } } } \token_if_macro:NTF \l__unravel_head_token { \__unravel_macro_call: } @@ -1593,6 +1759,14 @@ \__unravel_back_input_gtl:N \l__unravel_tmpb_gtl \prg_return_false: } +\cs_new_protected_nopar:Npn \__unravel_scan_to: + { + \__unravel_scan_keyword:nF { tToO } + { + \msg_error:nn { unravel } { missing-to } + \__unravel_prev_input:n { to } + } + } \cs_new_protected_nopar:Npn \__unravel_scan_font_ident: { \__unravel_get_x_non_blank: @@ -1615,8 +1789,8 @@ } { \msg_error:nn { unravel } { missing-font-id } + \__unravel_back_input: \__unravel_prev_input:n { \__unravel_nullfont: } - \__unravel_back_error: } } \cs_new_protected_nopar:Npn \__unravel_scan_font_int: @@ -1646,7 +1820,11 @@ { \int_compare:nNnTF { ( #1 + \c_two ) / \c_four } > { ( #3 + \c_two ) / \c_four } - { \__unravel_back_input: } + { + \__unravel_back_input: + \msg_error:nn { unravel } { missing-something } + \tl_clear:N \l__unravel_tmpa_tl + } { \tl_if_empty:nF {#2} { @@ -1655,9 +1833,8 @@ #2 \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl } + \__unravel_thing_use_get:nnNN {#1} {#3} \l__unravel_head_tl \l__unravel_tmpa_tl } - \tl_set:Nx \l__unravel_tmpa_tl - { \__unravel_thing_use:nnN {#1} {#3} \l__unravel_head_tl } \__unravel_prev_input_silent:V \l__unravel_tmpa_tl \__unravel_set_action_text: \__unravel_set_action_text:x @@ -1687,9 +1864,9 @@ { 83 } { 1 \__unravel_scan_int: } % set_box_dimen { 84 } { 0 \__unravel_scan_int: } % set_shape { 85 } { 0 \__unravel_scan_int: } % def_code - { 86 } { 4 \__unravel_scan_font_ident: } % def_family - { 87 } { 4 \__unravel_scan_font_ident: } % set_font - { 88 } { 4 \__unravel_scan_font_ident: } % def_font + { 86 } { 4 \__unravel_scan_int: } % def_family + { 87 } { 4 } % set_font + { 88 } { 4 } % def_font { 89 } { \__unravel_thing_register: } % register } { 8 } @@ -1750,16 +1927,38 @@ \int_compare:nNnT \l__unravel_head_char_int = \c_zero { \__unravel_scan_int: } } -\cs_new:Npn \__unravel_thing_use:nnN #1#2 +\cs_new_protected:Npn \__unravel_thing_use_get:nnNN #1#2#3#4 { - \int_case:nnF { \int_min:nn {#1} {#2} } + \int_compare:nNnTF {#2} < { 3 } + { + \int_compare:nNnT {#1} = { 3 } + { \__unravel_tex_error:nV { incompatible-units } #3 } + \tl_set:Nx #4 + { + \int_case:nn { \int_min:nn {#1} {#2} } + { + { 0 } \int_eval:n + { 1 } \dim_eval:n + { 2 } \skip_eval:n + } + { \int_compare:nNnT {#1} = { 3 } \etex_mutoglue:D #3 } + } + } { - { 0 } \int_eval:n - { 1 } \dim_eval:n - { 2 } \skip_eval:n - { 3 } \muskip_eval:n + \int_compare:nNnTF {#2} = { 3 } + { + \int_case:nnF {#1} + { + { 0 } { \tl_set:Nx #4 { \int_eval:n {#3} } } + { 3 } { \tl_set:Nx #4 { \muskip_eval:n {#3} } } + } + { + \__unravel_tex_error:nV { incompatible-units } #3 + \tl_set:Nx #4 { \muskip_eval:n { \etex_gluetomu:D #3 } } + } + } + { \tl_set:Nx #4 { \__unravel_the:w #3 } } } - { \__unravel_the:w } } \cs_new_protected:Npn \__unravel_scan_expr:N #1 { \__unravel_scan_expr_aux:NN #1 \c_false_bool } @@ -1917,28 +2116,10 @@ \__unravel_cmd_if_internal:TF { \int_compare:nNnTF {#1} = { 3 } - { - \__unravel_scan_something_internal:n { 3 } - \int_case:nnF \g__unravel_val_level_int - { - { 0 } { \__unravel_scan_dim_unit:nN {#1} #2 } - { 3 } { } - } - { - \msg_error:nn { unravel } { incompatible-units } - % ^^A todo: error recovery - } - } - { - \__unravel_scan_something_internal:n { 1 } - \int_case:nnF \g__unravel_val_level_int - { - { 0 } { \__unravel_scan_dim_unit:nN {#1} #2 } - { 3 } % ^^A todo: error recovery - { \msg_error:nn { unravel } { incompatible-units } } - } - { } - } + { \__unravel_scan_something_internal:n { 3 } } + { \__unravel_scan_something_internal:n { 1 } } + \int_compare:nNnT \g__unravel_val_level_int = { 0 } + { \__unravel_scan_dim_unit:nN {#1} #2 } } { \__unravel_scan_dimen_char:nN {#1} #2 } \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl @@ -1978,7 +2159,7 @@ { \bool_if:NT #2 { - \__unravel_scan_keyword:nT { fF iI lL } + \__unravel_scan_keyword:nT { fFiIlL } { \__unravel_scan_inf_unit_loop: \__unravel_break:w @@ -1997,25 +2178,26 @@ { \__unravel_back_input: } \int_compare:nNnT {#1} = { 3 } { - \__unravel_scan_keyword:nT { mM uU } { \__unravel_break:w } + \__unravel_scan_keyword:nT { mMuU } { \__unravel_break:w } \msg_error:nn { unravel } { missing-mudim } \__unravel_break:w } - \__unravel_scan_keyword:nT { eE mM } { \__unravel_break:w } - \__unravel_scan_keyword:nT { eE xX } { \__unravel_break:w } - \__unravel_scan_keyword:nT { pP xX } { \__unravel_break:w } - \__unravel_scan_keyword:n { tT rR uU eE } - \__unravel_scan_keyword:nT { pP tT } { \__unravel_break:w } - \__unravel_scan_keyword:nT { iI nN } { \__unravel_break:w } - \__unravel_scan_keyword:nT { pP cC } { \__unravel_break:w } - \__unravel_scan_keyword:nT { cC mM } { \__unravel_break:w } - \__unravel_scan_keyword:nT { mM mM } { \__unravel_break:w } - \__unravel_scan_keyword:nT { bB pP } { \__unravel_break:w } - \__unravel_scan_keyword:nT { dD dD } { \__unravel_break:w } - \__unravel_scan_keyword:nT { cC cC } { \__unravel_break:w } - \__unravel_scan_keyword:nT { nN dD } { \__unravel_break:w } - \__unravel_scan_keyword:nT { nN cC } { \__unravel_break:w } - \__unravel_scan_keyword:nT { sS pP } { \__unravel_break:w } + \__unravel_scan_keyword:nT { eEmM } { \__unravel_break:w } + \__unravel_scan_keyword:nT { eExX } { \__unravel_break:w } + \__unravel_scan_keyword:nT { pPxX } { \__unravel_break:w } + \__unravel_scan_keyword:nT { tTrRuUeE } + { \__unravel_prepare_mag: } + \__unravel_scan_keyword:nT { pPtT } { \__unravel_break:w } + \__unravel_scan_keyword:nT { iInN } { \__unravel_break:w } + \__unravel_scan_keyword:nT { pPcC } { \__unravel_break:w } + \__unravel_scan_keyword:nT { cCmM } { \__unravel_break:w } + \__unravel_scan_keyword:nT { mMmM } { \__unravel_break:w } + \__unravel_scan_keyword:nT { bBpP } { \__unravel_break:w } + \__unravel_scan_keyword:nT { dDdD } { \__unravel_break:w } + \__unravel_scan_keyword:nT { cCcC } { \__unravel_break:w } + \__unravel_scan_keyword:nT { nNdD } { \__unravel_break:w } + \__unravel_scan_keyword:nT { nNcC } { \__unravel_break:w } + \__unravel_scan_keyword:nT { sSpP } { \__unravel_break:w } \__unravel_break_point: } \cs_new_protected_nopar:Npn \__unravel_scan_inf_unit_loop: @@ -2052,20 +2234,17 @@ \int_case:nnF \g__unravel_val_level_int { { 0 } { \__unravel_scan_dimen:nN {#1} \c_false_bool } - {#1} { \__unravel_break:w } - } - { - \int_compare:nNnF { \g__unravel_val_level_int + #1 } = 3 - { \msg_error:nn { unravel } { incompatible-units } } + { 1 } { } } + { \__unravel_break:w } } { \__unravel_back_input: \__unravel_scan_dimen:nN {#1} \c_false_bool } \__unravel_prev_input_join_get:nN {#1} \l__unravel_tmpa_tl \seq_gput_right:Nn \g__unravel_prev_input_seq { } \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_tmpa_tl - \__unravel_scan_keyword:nT { pP lL uU sS } + \__unravel_scan_keyword:nT { pPlLuUsS } { \__unravel_scan_dimen:nN {#1} \c_true_bool } - \__unravel_scan_keyword:nT { mM iI nN uU sS } + \__unravel_scan_keyword:nT { mMiInNuUsS } { \__unravel_scan_dimen:nN {#1} \c_true_bool } \__unravel_break_point: \__unravel_prev_input_join_get:nN {#1} \l__unravel_tmpa_tl @@ -2262,9 +2441,9 @@ } \cs_new_protected_nopar:Npn \__unravel_scan_spec: { - \__unravel_scan_keyword:nTF { tT oO } { \__unravel_scan_normal_dimen: } + \__unravel_scan_keyword:nTF { tToO } { \__unravel_scan_normal_dimen: } { - \__unravel_scan_keyword:nT { sS pP rR eE aA dD } + \__unravel_scan_keyword:nT { sSpPrReEaAdD } { \__unravel_scan_normal_dimen: } } \__unravel_scan_left_brace: @@ -2308,11 +2487,7 @@ { 3 } % vsplit { \__unravel_scan_int: - \__unravel_scan_keyword:nF { tT oO } - { - \msg_error:nn { unravel } { missing-to } - \__unravel_prev_input:n { to } - } + \__unravel_scan_to: \__unravel_scan_normal_dimen: } } @@ -2324,8 +2499,10 @@ \bool_if:NTF #1 { \__unravel_do_leaders_fetch_skip: } { \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl + \tl_if_head_eq_meaning:VNT \l__unravel_head_tl \tex_shipout:D + { \__unravel_prepare_mag: } \tl_use:N \l__unravel_head_tl \scan_stop: - \gtl_put_right:NV \g__unravel_output_gtl \l__unravel_head_tl + \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl \__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl } } } @@ -2381,6 +2558,7 @@ { \exp_args:No #1 {##1} \cs_gset_eq:NN \__unravel_box_hook:w \prg_do_nothing: + \gtl_clear:N \l__unravel_after_group_gtl \__unravel_print_action: \__unravel_back_input:o {##1} \__unravel_set_action_text:x @@ -2465,26 +2643,31 @@ \cs_new_protected_nopar:Npn \__unravel_build_page: { } -\cs_new_protected_nopar:Npn \__unravel_handle_left_brace: +\cs_new_protected_nopar:Npn \__unravel_handle_right_brace: { - \int_case:nnF \__unravel_currentgrouptype: + \int_compare:nTF { 1 <= \__unravel_currentgrouptype: <= 13 } { - { 1 } { \__unravel_end_simple_group: } % simple - { 2 } { \__unravel_end_box_group: } % hbox - { 3 } { \__unravel_end_box_group: } % adjusted_hbox - { 4 } { \__unravel_end_graf: \__unravel_end_box_group: } % vbox - { 5 } { \__unravel_end_graf: \__unravel_end_box_group: } % vtop - { 6 } { \__unravel_end_align_group: } % align - { 7 } { \__unravel_end_no_align_group: } % no_align - { 8 } { \__unravel_end_output_group: } % output - { 9 } { \__unravel_end_simple_group: } % math - { 10 } { \__unravel_end_disc_group: } % disc - { 11 } { \__unravel_end_graf: \__unravel_end_simple_group: } % insert - { 12 } { \__unravel_end_graf: \__unravel_end_simple_group: } % vcenter - { 13 } { \__unravel_end_math_choice_group: } % math_choice + \gtl_gconcat:NNN \g__unravel_output_gtl + \g__unravel_output_gtl \c_group_end_gtl + \__unravel_back_input_gtl:N \l__unravel_after_group_gtl + \int_case:nn \__unravel_currentgrouptype: + { + { 1 } { \__unravel_end_simple_group: } % simple + { 2 } { \__unravel_end_box_group: } % hbox + { 3 } { \__unravel_end_box_group: } % adjusted_hbox + { 4 } { \__unravel_end_graf: \__unravel_end_box_group: } % vbox + { 5 } { \__unravel_end_graf: \__unravel_end_box_group: } % vtop + { 6 } { \__unravel_end_align_group: } % align + { 7 } { \__unravel_end_no_align_group: } % no_align + { 8 } { \__unravel_end_output_group: } % output + { 9 } { \__unravel_end_simple_group: } % math + { 10 } { \__unravel_end_disc_group: } % disc + { 11 } { \__unravel_end_graf: \__unravel_end_simple_group: } % insert + { 12 } { \__unravel_end_graf: \__unravel_end_simple_group: } % vcenter + { 13 } { \__unravel_end_math_choice_group: } % math_choice + } } { % bottom_level, semi_simple, math_shift, math_left - \__unravel_back_input: \l__unravel_head_token \__unravel_print_action: } @@ -2492,20 +2675,22 @@ \cs_new_protected_nopar:Npn \__unravel_end_simple_group: { \l__unravel_head_token - \gtl_gconcat:NNN \g__unravel_output_gtl - \g__unravel_output_gtl \c_group_end_gtl \__unravel_print_action: } \cs_new_protected_nopar:Npn \__unravel_end_box_group: { \seq_pop:NN \l__unravel_leaders_box_seq \l__unravel_tmpa_tl - \str_if_eq_x:nnTF \l__unravel_tmpa_tl { Z } + \exp_args:No \__unravel_end_box_group_aux:n { \l__unravel_tmpa_tl } + } +\cs_new_protected:Npn \__unravel_end_box_group_aux:n #1 + { + \str_if_eq_x:nnTF {#1} { Z } { \__unravel_end_simple_group: } { \__unravel_get_x_non_relax: \__unravel_set_cmd: \int_compare:nNnTF \l__unravel_head_cmd_int - = { \__unravel_tex_use:n { \l__unravel_tmpa_tl skip } } + = { \__unravel_tex_use:n { #1 skip } } { \tl_put_left:Nn \l__unravel_head_tl { \c_group_end_token } \__unravel_do_append_glue: @@ -2591,6 +2776,7 @@ \mode_if_inner:TF { \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl + \__unravel_back_input_gtl:N \l__unravel_after_group_gtl $ % $ } { @@ -2604,6 +2790,7 @@ \msg_error:nn { unravel } { missing-dollar } } \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl + \__unravel_back_input_gtl:N \l__unravel_after_group_gtl $ $ } \__unravel_print_action: @@ -2612,7 +2799,7 @@ { \__unravel_set_action_text: \bool_if:NT \g__unravel_internal_debug_bool - { \iow_term:x { Cmd:~\int_use:N \l__unravel_head_cmd_int } } + { \iow_term:x { Cmd:~\int_to_arabic:n { \l__unravel_head_cmd_int } } } \cs_if_exist_use:cF { __unravel_cmd_ \int_use:N \l__unravel_head_cmd_int : } { \msg_error:nnx { unravel } { internal } { unknown-command } } @@ -2625,9 +2812,10 @@ \g__unravel_output_gtl \c_group_begin_gtl \__unravel_print_action: \l__unravel_head_token + \gtl_clear:N \l__unravel_after_group_gtl } \__unravel_new_tex_cmd:nn { end-group_char } % 2 - { \__unravel_handle_left_brace: } + { \__unravel_handle_right_brace: } \__unravel_new_tex_cmd:nn { math_char } % 3 { \__unravel_mode_non_vertical:n @@ -2993,7 +3181,28 @@ } } \__unravel_new_tex_cmd:nn { after_group } % 41 - { \msg_error:nnx { unravel } { not-implemented } { aftergroup } } + { + \tl_set_eq:NN \l__unravel_tmpa_tl \l__unravel_head_tl + \__unravel_get_next: + \int_compare:nNnTF \__unravel_currentgrouptype: = \c_zero + { + \__unravel_print_action:x + { + Aftergroup~(level~0~=>~dropped):~ + \tl_to_str:N \l__unravel_tmpa_tl + \gtl_to_str:N \l__unravel_head_gtl + } + } + { + \gtl_concat:NNN \l__unravel_after_group_gtl + \l__unravel_after_group_gtl \l__unravel_head_gtl + \__unravel_print_action:x + { + Aftergroup:~\tl_to_str:N \l__unravel_tmpa_tl + \gtl_to_str:N \l__unravel_head_gtl + } + } + } \__unravel_new_tex_cmd:nn { break_penalty } % 42 { \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl @@ -3147,14 +3356,16 @@ \__unravel_new_tex_cmd:nn { begin_group } % 61 { \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl - \__unravel_print_action: \l__unravel_head_token + \gtl_clear:N \l__unravel_after_group_gtl + \__unravel_print_action: } \__unravel_new_tex_cmd:nn { end_group } % 62 { \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl - \__unravel_print_action: + \__unravel_back_input_gtl:N \l__unravel_after_group_gtl \l__unravel_head_token + \__unravel_print_action: } \__unravel_new_tex_cmd:nn { omit } % 63 { \msg_error:nn { unravel } { not-implemented } { omit } } @@ -3229,24 +3440,24 @@ } { 6 } % pdfliteral { - \__unravel_scan_keyword:nF { dD iI rR eE cC tT } - { \__unravel_scan_keyword:n { pP aA gG eE } } + \__unravel_scan_keyword:nF { dDiIrReEcCtT } + { \__unravel_scan_keyword:n { pPaAgGeE } } \__unravel_scan_pdf_ext_toks: } { 7 } % pdfobj { \__unravel_scan_keyword:nTF - { rR eE sS eE rR vV eE oO bB jJ nN uU mM } + { rReEsSeErRvVeEoObBjJnNuUmM } { \__unravel_skip_optional_space: } { - \__unravel_scan_keyword:nF { uU sS eE oO bB jJ nN uU mM } + \__unravel_scan_keyword:nF { uUsSeEoObBjJnNuUmM } { \__unravel_scan_int: } - \__unravel_scan_keyword:nT { sS tT rR eE aA mM } + \__unravel_scan_keyword:nT { sStTrReEaAmM } { - \__unravel_scan_keyword:nT { aA tT tT rR } + \__unravel_scan_keyword:nT { aAtTtTrR } { \__unravel_scan_pdf_ext_toks: } } - \__unravel_scan_keyword:n { fF iI lL eE } + \__unravel_scan_keyword:n { fFiIlLeE } \__unravel_scan_pdf_ext_toks: } } @@ -3254,9 +3465,9 @@ { \__unravel_scan_int: } { 9 } % pdfxform { - \__unravel_scan_keyword:nT { aA tT tT rR } + \__unravel_scan_keyword:nT { aAtTtTrR } { \__unravel_scan_pdf_ext_toks: } - \__unravel_scan_keyword:nTF { rR eE sS oO uU rR cC eE sS } + \__unravel_scan_keyword:nTF { rReEsSoOuUrRcCeEsS } { \__unravel_scan_pdf_ext_toks: } \__unravel_scan_int: } @@ -3269,10 +3480,10 @@ { 13 } % pdfannot { \__unravel_scan_keyword:nTF - { rR eE sS eE rR vV eE oO bB jJ nN uU mM } + { rReEsSeErRvVeEoObBjJnNuUmM } { \__unravel_scan_optional_space: } { - \__unravel_scan_keyword:nT { uU sS eE oO bB jJ nN uU mM } + \__unravel_scan_keyword:nT { uUsSeEoObBjJnNuUmM } { \__unravel_scan_int: } \__unravel_scan_alt_rule: \__unravel_scan_pdf_ext_toks: @@ -3294,10 +3505,10 @@ } { 16 } % pdfoutline { - \__unravel_scan_keyword:nT { aA tT tT rR } + \__unravel_scan_keyword:nT { aAtTtTrR } { \__unravel_scan_pdf_ext_toks: } \__unravel_scan_action: - \__unravel_scan_keyword:nT { cC oO uU nN tT } + \__unravel_scan_keyword:nT { cCoOuUnNtT } { \__unravel_scan_int: } \__unravel_scan_pdf_ext_toks: } @@ -3316,7 +3527,7 @@ { 23 } % pdfcatalog { \__unravel_scan_pdf_ext_toks: - \__unravel_scan_keyword:n { oO pP eE nN aA cC tT iI oO nN } + \__unravel_scan_keyword:n { oOpPeEnNaAcCtTiIoOnN } { \__unravel_scan_action: } } { 24 } % pdfnames @@ -3396,7 +3607,7 @@ \cs_new_protected_nopar:Npn \__unravel_scan_rule_attr: { \__unravel_scan_alt_rule: - \__unravel_scan_keyword:nT { aA tT tT rR } + \__unravel_scan_keyword:nT { aAtTtTrR } { \__unravel_scan_pdf_ext_toks: } } \cs_new_protected_nopar:Npn \__unravel_scan_action: @@ -3729,7 +3940,7 @@ \__unravel_scan_keyword:nTF { aAtT } { \__unravel_scan_normal_dimen: } { - \__unravel_scan_keyword:nT { sS cC aA lL eE dD } + \__unravel_scan_keyword:nT { sScCaAlLeEdD } { \__unravel_scan_int: } } \bool_gset_false:N \g__unravel_name_in_progress_bool @@ -3788,17 +3999,41 @@ } \__unravel_prefixed_new:nn { read_to_cs } % 96 { - \__unravel_prev_input:V \l__unravel_head_tl + \__unravel_prev_input_silent:V \l__unravel_head_tl \__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl } \__unravel_scan_int: - \__unravel_scan_keyword:nF { tToO } + \__unravel_scan_to: + \__unravel_scan_r_token: + \seq_get_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl + \__unravel_read_to_cs_safe:fTF + { \__unravel_tl_first_int:N \l__unravel_tmpa_tl } + { \__unravel_assign_token:n { } } { - \msg_error:nn { unravel } { missing-to } - \__unravel_prev_input:n { to } + \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl + \__unravel_tex_fatal_error:nV { cannot-read } \l__unravel_head_tl + } + } +\prg_new_conditional:Npnn \__unravel_read_to_cs_safe:n #1 { TF } + { + \int_compare:nNnTF { \etex_interactionmode:D } > { 1 } + { \prg_return_true: } + { + \int_compare:nNnTF {#1} < { 0 } + { \prg_return_false: } + { + \int_compare:nNnTF {#1} > { 15 } + { \prg_return_false: } + { + \tex_ifeof:D #1 \exp_stop_f: + \prg_return_false: + \else: + \prg_return_true: + \fi: + } + } } - \__unravel_scan_r_token: - \__unravel_assign_token:n { } } +\cs_generate_variant:Nn \__unravel_read_to_cs_safe:nTF { f } \__unravel_prefixed_new:nn { def } % 97 { \seq_get_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl @@ -4081,8 +4316,8 @@ \__unravel_scan_file_name: \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl \tl_set:Nx \l__unravel_tmpa_tl { \tl_tail:N \l__unravel_head_tl } - \__unravel_tl_gset_input:Nno \g__unravel_tmpc_tl { } \l__unravel_tmpa_tl - \__unravel_back_input:V \g__unravel_tmpc_tl + \__unravel_file_get:nN \l__unravel_tmpa_tl \l__unravel_tmpa_tl + \__unravel_back_input:V \l__unravel_tmpa_tl \__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl } } \__unravel_new_tex_expandable:nn { cs_name } % 109 @@ -4140,7 +4375,7 @@ { 23 } \__unravel_scan_pdf_ext_toks: { 24 } { - \__unravel_scan_keyword:n { fF iI lL eE } + \__unravel_scan_keyword:n { fFiIlLeE } \__unravel_scan_pdf_ext_toks: } { 25 } \__unravel_scan_pdffiledump: @@ -4162,23 +4397,23 @@ { \__unravel_scan_int: \__unravel_scan_int: } \cs_new_protected_nopar:Npn \__unravel_scan_pdfcolorstackinit: { - \__unravel_scan_keyword:nTF { pP aA gG eE } + \__unravel_scan_keyword:nTF { pPaAgGeE } { \bool_set_true:N \l__unravel_tmpa_bool } { \bool_set_false:N \l__unravel_tmpb_bool } - \__unravel_scan_keyword:nF { dD iI rR eE cC tT } - { \__unravel_scan_keyword:n { pP aA gG eE } } + \__unravel_scan_keyword:nF { dDiIrReEcCtT } + { \__unravel_scan_keyword:n { pPaAgGeE } } \__unravel_scan_toks_to_str: } \cs_new_protected_nopar:Npn \__unravel_scan_pdffiledump: { - \__unravel_scan_keyword:nT { oO fF fF sS eE tT } \__unravel_scan_int: - \__unravel_scan_keyword:nT { lL eE nN gG tT hH } \__unravel_scan_int: + \__unravel_scan_keyword:nT { oOfFfFsSeEtT } \__unravel_scan_int: + \__unravel_scan_keyword:nT { lLeEnNgGtThH } \__unravel_scan_int: \__unravel_scan_pdf_ext_toks: } \cs_new_protected_nopar:Npn \__unravel_scan_pdfmatch: { - \__unravel_scan_keyword:n { iI cC aA sS eE } - \__unravel_scan_keyword:nT { sS uU bB cC oO uU nN tT } + \__unravel_scan_keyword:n { iIcCaAsSeE } + \__unravel_scan_keyword:nT { sSuUbBcCoOuUnNtT } { \__unravel_scan_int: } \__unravel_scan_pdf_ext_toks: \__unravel_scan_pdf_ext_toks: @@ -4621,7 +4856,7 @@ { [===== \bool_if:NT \g__unravel_number_steps_bool - { ~ Step ~ \int_use:N \g__unravel_step_int \ } + { ~ Step ~ \int_to_arabic:n { \g__unravel_step_int } ~ } =====]~ \int_compare:nNnTF { \str_count:N \g__unravel_action_text_str } @@ -4657,12 +4892,15 @@ \cs_new_protected_nopar:Npn \__unravel_print_assigned_register: { \__unravel_after_assignment: % ^^A todo: simplify - \__unravel_print_action:x + \exp_args:Nx \__unravel_print_action:x { - Set~ \exp_after:wN \token_to_str:N \l__unravel_defined_tl - \tl_if_single:NT \l__unravel_defined_tl - { ( \exp_after:wN \token_to_meaning:N \l__unravel_defined_tl ) } - = \exp_after:wN \__unravel_the:w \l__unravel_defined_tl + \exp_not:n + { + Set~ \exp_after:wN \token_to_str:N \l__unravel_defined_tl + \tl_if_single:NT \l__unravel_defined_tl + { ( \exp_after:wN \token_to_meaning:N \l__unravel_defined_tl ) } + } + = \exp_not:N \tl_to_str:n { \__unravel_the:w \l__unravel_defined_tl } } \__unravel_omit_after_assignment:w } @@ -4829,6 +5067,27 @@ } \cs_new:Npn \__unravel_prompt_all_aux:N #1 { \exp_not:n { \int_gset:Nn #1 } { \int_use:N #1 } } +\cs_new_protected:Npn \__unravel_tex_msg_new:nnn #1#2#3 + { + \cs_new_nopar:cpn { __unravel_tex_msg_error_#1: } {#2} + \cs_new_nopar:cpn { __unravel_tex_msg_help_#1: } {#3} + } +\cs_new_protected:Npn \__unravel_tex_error:nn #1#2 + { + \msg_error:nnxxx { unravel } { tex-error } + { \tl_to_str:n {#2} } + { \use:c { __unravel_tex_msg_error_#1: } } + { \use:c { __unravel_tex_msg_help_#1: } } + } +\cs_generate_variant:Nn \__unravel_tex_error:nn { nV } +\cs_new_protected:Npn \__unravel_tex_fatal_error:nn #1#2 + { + \msg_error:nnxxx { unravel } { tex-fatal } + { \tl_to_str:n {#2} } + { \use:c { __unravel_tex_msg_error_#1: } } + { \use:c { __unravel_tex_msg_help_#1: } } + } +\cs_generate_variant:Nn \__unravel_tex_fatal_error:nn { nV } \keys_define:nn { unravel/defaults } { explicit-prompt .bool_gset:N = \g__unravel_default_explicit_prompt_bool , @@ -4907,6 +5166,7 @@ \gtl_gclear:N \g__unravel_after_assignment_gtl \bool_gset_true:N \g__unravel_set_box_allowed_bool \bool_gset_false:N \g__unravel_name_in_progress_bool + \gtl_clear:N \l__unravel_after_group_gtl } \cs_new_protected_nopar:Npn \__unravel_main_loop: { @@ -4946,8 +5206,6 @@ { Missing~font~identifier.~\iow_char:N\\nullfont~inserted. } \msg_new:nnn { unravel } { missing-rparen } { Missing~right~parenthesis~inserted~for~expression. } -\msg_new:nnn { unravel } { incompatible-units } - { Mu~glue/dimen~used~as~a~normal~glue/dimen~or~vice-versa. } \msg_new:nnn { unravel } { missing-mudim } { Missing~mu~unit. } \msg_new:nnn { unravel } { missing-cs } @@ -5004,6 +5262,51 @@ { The~following~feature~is~not~implemented:~'#1'. } \msg_new:nnn { unravel } { endinput-ignored } { The~primitive~\iow_char:N\\endinput~was~ignored. } +\msg_new:nnn { unravel } { missing-something } + { Something~is~missing,~sorry! } +\msg_new:nnnn { unravel } { tex-error } + { TeX~sees~"#1"~and~throws~an~error:\\\\ \iow_indent:n {#2} } + { + \tl_if_empty:nTF {#3} + { TeX~provides~no~further~help~for~this~error. } + { TeX's~advice~is:\\\\ \iow_indent:n {#3} } + } +\msg_new:nnnn { unravel } { tex-fatal } + { TeX~sees~"#1"~and~throws~a~fatal~error:\\\\ \iow_indent:n {#2} } + { + \tl_if_empty:nTF {#3} + { TeX~provides~no~further~help~for~this~error. } + { TeX's~advice~is:\\\\ \iow_indent:n {#3} } + } +\__unravel_tex_msg_new:nnn { incompatible-mag } + { + Incompatible~magnification~ + ( \int_to_arabic:n { \__unravel_mag: } ); \\ + \ the~previous~value~will~be~retained + } + { + I~can~handle~only~one~magnification~ratio~per~job.~So~I've\\ + reverted~to~the~magnification~you~used~earlier~on~this~run. + } +\__unravel_tex_msg_new:nnn { illegal-mag } + { + Illegal~magnification~has~been~changed~to~1000~ + ( \int_to_arabic:n { \__unravel_mag: } ) + } + { The~magnification~ratio~must~be~between~1~and~32768. } +\__unravel_tex_msg_new:nnn { incompatible-units } + { Incompatible~glue~units } + { I'm~going~to~assume~that~1mu=1pt~when~they're~mixed. } +\__unravel_tex_msg_new:nnn { cannot-read } + { ***~(cannot~\iow_char:N\\read~from~terminal~in~nonstop~modes) } + { } +\__unravel_tex_msg_new:nnn { file-error } + { ***~(job~aborted,~file~error~in~nonstop~mode) } + { } +\__unravel_tex_msg_new:nnn { interwoven-preambles } + { (interwoven~alignment~preambles~are~not~allowed) } + { } +\__unravel_setup_restore: %% %% %% End of file `unravel.sty'. -- cgit v1.2.3