summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/doc/latex/unravel/README34
-rw-r--r--Master/texmf-dist/doc/latex/unravel/README.md36
-rw-r--r--Master/texmf-dist/doc/latex/unravel/unravel.pdfbin674252 -> 692725 bytes
-rw-r--r--Master/texmf-dist/source/latex/unravel/unravel.dtx1929
-rw-r--r--Master/texmf-dist/tex/latex/unravel/unravel.sty1030
5 files changed, 1841 insertions, 1188 deletions
diff --git a/Master/texmf-dist/doc/latex/unravel/README b/Master/texmf-dist/doc/latex/unravel/README
deleted file mode 100644
index b2dce6d2cc1..00000000000
--- a/Master/texmf-dist/doc/latex/unravel/README
+++ /dev/null
@@ -1,34 +0,0 @@
-----------------------------------------------------------------
-unravel --- Watching TeX digest tokens
-E-mail: blflatex@gmail.com
-Released under the LaTeX Project Public License v1.3c or later
-See http://www.latex-project.org/lppl.txt
-----------------------------------------------------------------
-
-The unravel LaTeX package provides tools to explore TeX code,
-performing expansion and assignments step by step.
-
-TeX is a strange beast. Its eyes read files, making characters
-into tokens. Its mouth then chews tokens, expanding them if
-possible, namely, expanding user-defined macros, or conditionals,
-etc. When meeting a so called ``unexpandable'' token, TeX's
-stomach comes into play, performing assignments, or moving boxes
-around, eventually typesetting the result thanks to its great
-line- and page-breaking algorithms.
-
-All of this is interleaved, and difficult to follow. Of course,
-one can always use \tracingall, but the result is... messy.
-This package is an attempt to replicate how TeX digests tokens,
-and to make the process easier to follow. Namely,
-\unravel{\some\tokens} will let you go through expansions and
-assignments performed by TeX upon seeing of ``\some\tokens'',
-step by step.
-
-Some parts of TeX are not covered. In particular, category codes
-are fixed for the whole argument of \unravel when it is read.
-
-This package requires up-to-date versions of the l3kernel,
-l3packages, and l3experimental bundles.
-
-The package is extracted by running "pdflatex unravel.ins".
-For documentation, run "pdflatex unravel.dtx" twice. \ No newline at end of file
diff --git a/Master/texmf-dist/doc/latex/unravel/README.md b/Master/texmf-dist/doc/latex/unravel/README.md
new file mode 100644
index 00000000000..bc25d285c38
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/unravel/README.md
@@ -0,0 +1,36 @@
+unravel: Watching TeX digest tokens
+====================================================
+* E-mail: blflatex@gmail.com
+* Released under the LaTeX Project Public License v1.3c or later
+ See http://www.latex-project.org/lppl.txt
+
+The `unravel` LaTeX package provides tools to explore TeX code,
+performing expansion and assignments step by step.
+
+TeX is a strange beast. Its eyes read files, making characters
+into tokens. Its mouth then chews tokens, expanding them if
+possible, namely, expanding user-defined macros, or conditionals,
+etc. When meeting a so called 'unexpandable' token, TeX's
+stomach comes into play, performing assignments, or moving boxes
+around, eventually typesetting the result thanks to its great
+line- and page-breaking algorithms.
+
+All of this is interleaved, and difficult to follow. Of course,
+one can always use `\tracingall`, but the result is... messy.
+This package is an attempt to replicate how TeX digests tokens,
+and to make the process easier to follow. Namely,
+`\unravel{\some\tokens}` will let you go through expansions and
+assignments performed by TeX upon seeing of `\some\tokens`,
+step by step.
+
+Some parts of TeX are not covered. In particular, category codes
+are fixed for the whole argument of `\unravel` when it is read.
+
+This package requires up-to-date versions of the `l3kernel`,
+`l3packages` and `l3experimental` bundles.
+
+The package is extracted by running `pdflatex unravel.ins`.
+For the documentation, run `pdflatex unravel.dtx` twice.
+
+This is work in progress, all suggestions/comments/bug reports
+are welcome! See https://github.com/blefloch/latex-unravel/
diff --git a/Master/texmf-dist/doc/latex/unravel/unravel.pdf b/Master/texmf-dist/doc/latex/unravel/unravel.pdf
index 19a0e4fe3f1..a8af7eaff51 100644
--- a/Master/texmf-dist/doc/latex/unravel/unravel.pdf
+++ b/Master/texmf-dist/doc/latex/unravel/unravel.pdf
Binary files differ
diff --git a/Master/texmf-dist/source/latex/unravel/unravel.dtx b/Master/texmf-dist/source/latex/unravel/unravel.dtx
index 1cd40dc4382..87170f4286c 100644
--- a/Master/texmf-dist/source/latex/unravel/unravel.dtx
+++ b/Master/texmf-dist/source/latex/unravel/unravel.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: unravel.dtx Copyright (C) 2013 Bruno Le Floch
+%% File: unravel.dtx Copyright (C) 2013, 2015 Bruno Le Floch
%%
%% It may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -23,9 +23,9 @@
%
% \title{The \textsf{unravel} package: \\
% watching TeX digest tokens\thanks{This
-% file has version number 0.0a, last revised 2013/07/28.}}
+% file has version number 0.1, last revised 2015/09/22.}}
% \author{Bruno Le Floch}
-% \date{2013/07/28}
+% \date{2015/09/22}
%
% \maketitle
% \tableofcontents
@@ -38,18 +38,53 @@
% This is done by letting the user step through the execution of some
% \TeX{} code, going through the details of nested expansions,
% performing assignments, as well as some simple typesetting commands.
+% To use this package, one should normally run \TeX{} in a terminal.
+%
+% \begin{function}{\unravel}
+% \begin{syntax}
+% \cs{unravel} \oarg{key-value list} \marg{code}
+% \end{syntax}
+% This command shows in the terminal the steps performed by \TeX{}
+% when running the \meta{code}. By default, it pauses to let the
+% user read the description of every step: simply press |<return>| to
+% proceed. Typing |s|\meta{integer} instead will go forward
+% \meta{integer} steps somewhat silently. In the future it will be
+% possible to use a negative \meta{integer} to go back a few steps.
+% Typing |h| gives a list of various other possibilities.
+% The available \meta{key-value} options are described in
+% Section~\ref{sec:options}.
+% \end{function}
+%
+% \begin{function}{\unravelsetup}
+% \begin{syntax}
+% \cs{unravelsetup} \marg{options}
+% \end{syntax}
+% Sets \meta{options} that apply to all subsequent \cs{unravel}. See
+% options in Section~\ref{sec:options}.
+% \end{function}
+%
+% \begin{function}{\unravel:nn}
+% \begin{syntax}
+% \cs{unravel:nn} \Arg{options} \Arg{code}
+% \end{syntax}
+% See \cs{unravel}.
+% \end{function}
+%
+% \begin{function}{\unravel_setup:n}
+% \begin{syntax}
+% \cs{unravel_setup:n} \Arg{options}
+% \end{syntax}
+% See \cs{unravelsetup}.
+% \end{function}
+%
% The \pkg{unravel} package is currently based on the behaviour of
-% \pdfTeX{}, but it should work in the \XeTeX{} and \LuaTeX{} engines as
-% long as none of the primitives specific to those engines is used. Any
+% \pdfTeX{}, but it should work in all engines supported by \pkg{expl3}
+% (\pdfTeX{}, \XeTeX{}, \LuaTeX{}, ep\TeX{}, eup\TeX{}) as long as none
+% of the primitives specific to those engines is used. Any
% difference between how \pkg{unravel} and (pdf)\TeX{} process a given
% piece of code, unless described in the section~\ref{sec:differences},
-% should be reported to Bruno Le Floch \texttt{<blflatex@gmail.com>}.
-%
-% The only public command is \cs{unravel}, used as \cs{unravel}
-% \Arg{some tokens}. It will show on the terminal the various steps
-% that \TeX{} performs, waiting for input from the user at each step.
-% As a result, \pkg{unravel} can only be used meaningfully when \TeX{}
-% is run in a terminal.
+% should be reported on the issue tracker
+% (\url{https://github.com/blefloch/latex-unravel/issues}).
%
% As a simple example, one can run \LaTeX{} on the following file.
% \begin{verbatim}
@@ -120,34 +155,76 @@
% |\unravel{\lipsum[1-30]}|, which also takes $20000$ step, takes
% $8$~minutes to complete.
%
+% \subsection{Options}
+% \label{sec:options}
+%
+% \begin{function}{explicit-prompt}
+% Boolean option (default \texttt{false}) determining whether to give
+% an explicit prompt. If \texttt{true}, the text ``|Your input=|''
+% will appear at the beginning of lines where user input is expected.
+% \end{function}
+%
+% \begin{function}{internal-debug}
+% Boolean option (default \texttt{false}) used to debug \pkg{unravel}
+% itself.
+% \end{function}
+%
+% \begin{function}{machine}
+% Option which takes no value and makes \pkg{unravel} produce an
+% output that is somewhat more suitable for automatic processing. In
+% particular, it sets |max-action|, |max-output|, |max-input| to very
+% large values, and |number-steps| to \texttt{false}.
+% \end{function}
+%
+% \begin{function}{max-action, max-output, max-input}
+% Integer options (defaults $50$, $300$, $300$) determining the
+% maximum number of characters displayed for the action, the output
+% part, and the input part.
+% \end{function}
+%
+% \begin{function}{number-steps}
+% Boolean option (default \texttt{true}) determining whether to
+% number steps.
+% \end{function}
+%
+% \begin{function}{welcome-message}
+% Boolean option (default \texttt{true}) determining whether to
+% display the welcome message.
+% \end{function}
+%
% \subsection{Differences between \pkg{unravel} and \TeX{}'s processing}
% \label{sec:differences}
%
+% Bugs are listed at \url{https://github.com/blefloch/latex-unravel/issues}.
+%
+% Differences.
% \begin{itemize}
-% \item Alignments (\tn{halign}, \tn{valign}, \tn{noalign}, \tn{omit},
-% \tn{span}, \tn{cr}, \tn{crcr},~|&|) are not implemented.
-% \item Math mode is not implemented, but might be.
-% \item Some other primitives are not implemented (but they should claim
-% so).
-% \item For \pkg{unravel}, category codes are fixed when a file is read,
+% \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
+% all primitives specific to engines other than \pdfTeX{}.
+% This list is sadly incomplete!
+% \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
% one go, and the result must be balanced.
% \item Explicit begin-group and end-group characters other than the
-% usual left and right braces will either make \pkg{unravel} choke or
-% will be replaced by the usual left and right braces.
-% \item \tn{endinput} is ignored, as it is not possible to implement it
-% in a way similar to \TeX{}'s, and as it is most often used at the
-% very end of files, in a redundant way.
-% \item Negative signs and glue probably mix in wrong ways (this is a
-% fixable bug, please tell me if it affects you).
+% usual left and right braces may make \pkg{unravel} choke, or may be
+% silently replaced by the usual left and right braces.
+% \item \tn{endinput} is ignored with a warning, as it is very difficult
+% to implement it in a way similar to \TeX{}'s, and as it is most
+% often used at the very end of files, in a redundant way.
+% \item \tn{outer} is not supported.
% \end{itemize}
%
% \subsection{Future perhaps}
%
% \begin{itemize}
-% \item Allow users to change some settings.
+% \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}).
% \end{itemize}
@@ -166,26 +243,495 @@
% \end{macrocode}
%
% \begin{macrocode}
-\RequirePackage{expl3}[2013/07/01]
-\RequirePackage{l3str}[2013/04/24]
-\RequirePackage{gtl}[2013/07/28]
+\RequirePackage{expl3,xparse}[2015/09/11]
+\RequirePackage{gtl}[2015/09/21]
\ProvidesExplPackage
- {unravel} {2013/07/28} {0.0a} {Watching TeX digest tokens}
+ {unravel} {2015/09/22} {0.1} {Watching TeX digest tokens}
+% \end{macrocode}
+%
+% 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} }
% \end{macrocode}
%
% \begin{macrocode}
%<@@=unravel>
% \end{macrocode}
%
+% \subsection{Primitives, variants, and helpers}
+%
+% \subsubsection{Renamed primitives}
+%
+% \begin{macro}
+% {
+% \@@_currentgrouptype:, \@@_everyeof:w, \@@_everypar:w,
+% \@@_set_escapechar:n, \@@_nullfont:,
+% \@@_hbox:w, \@@_the:w,
+% }
+% Copy primitives which are used multiple times, to avoid littering
+% the code with |:D| commands. Primitives are left as |:D| in the
+% code when that is clearer (typically when testing the meaning of
+% a token against that of a primitive).
+% \begin{macrocode}
+\cs_new_eq:NN \@@_currentgrouptype: \etex_currentgrouptype:D
+\cs_new_protected_nopar:Npn \@@_set_escapechar:n
+ { \int_set:Nn \tex_escapechar:D }
+\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 \@@_nullfont: \tex_nullfont:D
+\cs_new_eq:NN \@@_the:w \tex_the:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\c_@@_prompt_ior, \c_@@_noprompt_ior}
+% These are not quite primitives, but are very low-level
+% |ior| streams to prompt the user explicitly or not.
+% \begin{macrocode}
+\cs_new_eq:NN \c_@@_prompt_ior \c_sixteen
+\cs_new_eq:NN \c_@@_noprompt_ior \c_minus_one
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Variants}
+%
+% 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 \ior_get_str:NN { Nc }
+\cs_generate_variant:Nn \gtl_if_empty:NTF { c }
+\cs_generate_variant:Nn \gtl_to_str:N { c }
+\cs_generate_variant:Nn \gtl_gpop_left:NN { c }
+\cs_generate_variant:Nn \gtl_get_left:NN { c }
+\cs_generate_variant:Nn \gtl_gset:Nn { c }
+\cs_generate_variant:Nn \gtl_gconcat:NNN { ccc , cNc }
+\cs_generate_variant:Nn \gtl_gclear:N { c }
+\cs_generate_variant:Nn \gtl_gclear_new:N { c }
+% \end{macrocode}
+%
+% \subsubsection{Miscellanous helpers}
+%
+% \begin{macro}[aux]{\@@_tmp:w}
+% Temporary function used to define other functions.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_tmp:w { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_tl_gset_input:Nnn, \@@_tl_gset_input:Nno}
+% \begin{macro}[aux]{\@@_tl_gset_input_aux:wN}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_tl_gset_input:Nnn #1#2#3
+ {
+ \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_generate_variant:Nn \@@_tl_gset_input:Nnn { Nno }
+\use:x
+ {
+ \cs_new_protected:Npn \exp_not:N \@@_tl_gset_input_aux:wN
+ ##1 \token_to_str:N @ @ ##2
+ } { \tl_gset:No #2 {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{String helpers}
+%
+% \begin{macro}[int]{\@@_strip_escape:w}
+% \begin{macro}[aux]{\@@_strip_escape_aux:N, \@@_strip_escape_aux:w}
+% This is based on the 2013-07-19 (and earlier) version of
+% \cs{cs_to_str:N}. There are three cases. If the escape character
+% is printable, the charcode test is false, and
+% \cs{@@_strip_escape_aux:N} removes one character. If the escape
+% character is a space, the charcode test is true, and if there is no
+% escape charcter, the test is unfinished after |\token_to_str:N \ |.
+% In both of those cases, \cs{@@_strip_escape_aux:w} inserts
+% |-\__int_value:w \fi: \c_zero|. If the escape character was a
+% space, the test was true, and \cs{__int_value:w} converts
+% \cs{c_zero} to~|0|, hence the leading roman numeral expansion
+% removes a space from what follows (it is important that what follows
+% cannot start with a digit). Otherwise, the test takes~|-| as its
+% second operand, is false, and the roman numeral expansion only sees
+% \cs{c_zero}, thus does not remove anything from what follows.
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_strip_escape:w
+ {
+ \tex_romannumeral:D
+ \if_charcode:w \token_to_str:N \ \@@_strip_escape_aux:w \fi:
+ \@@_strip_escape_aux:N
+ }
+\cs_new:Npn \@@_strip_escape_aux:N #1 { \c_zero }
+\cs_new:Npn \@@_strip_escape_aux:w #1#2
+ { - \__int_value:w #1 \c_zero }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% ^^A todo: change approach: this abuses future l3obj.
+% \begin{macro}[int,EXP]{\@@_to_str:n}
+% \begin{macro}[aux,EXP]
+% {\@@_to_str_auxi:w, \@@_to_str_auxii:w, \@@_gtl_to_str:n}
+% Use the type-appropriate conversion to string.
+% This unavoidably uses an internal function of \pkg{gtl}.
+% \begin{macrocode}
+\cs_new:Npn \@@_to_str:n #1
+ {
+ \tl_if_head_eq_meaning:nNTF {#1} \scan_stop:
+ { \@@_to_str_auxi:w #1 ? \q_stop }
+ { \tl_to_str:n }
+ {#1}
+ }
+\cs_set:Npn \@@_tmp:w #1
+ {
+ \cs_new:Npn \@@_to_str_auxi:w ##1##2 \q_stop
+ {
+ \exp_after:wN \@@_to_str_auxii:w \token_to_str:N ##1 \q_mark
+ #1 tl \q_mark \q_stop
+ }
+ \cs_new:Npn \@@_to_str_auxii:w ##1 #1 ##2 \q_mark ##3 \q_stop
+ { \cs_if_exist_use:cF { @@_ ##2 _to_str:n } { \tl_to_str:n } }
+ }
+\exp_args:No \@@_tmp:w { \tl_to_str:n { s__ } }
+\cs_new:Npn \@@_gtl_to_str:n #1 { \__gtl_to_str:w #1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_str_truncate_left:nn}
+% \begin{macro}[aux]{\@@_str_truncate_left_aux:nnn}
+% Truncate the string |#1| to a maximum of |#2| characters. If it is
+% longer, replace some characters on the left of the string by
+% |(123~more~chars)~| with the appropriate number instead of~|123|.
+% In any reasonable case, $25$ is big enough to fit this extra text.
+% \begin{macrocode}
+\cs_new:Npn \@@_str_truncate_left:nn #1#2
+ {
+ \exp_args:Nf \@@_str_truncate_left_aux:nnn
+ { \str_count:n {#1} } {#1} {#2}
+ }
+\cs_new:Npn \@@_str_truncate_left_aux:nnn #1#2#3
+ {
+ \int_compare:nNnTF {#1} > {#3}
+ {
+ ( \int_eval:n { #1 - #3 + 25 } ~ more~chars ) ~
+ \str_range:nnn {#2} { #1 - #3 + 26 } {#1}
+ }
+ { \tl_to_str:n {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_str_truncate_right:nn}
+% \begin{macro}[aux]{\@@_str_truncate_right_aux:nnn}
+% Truncate the string |#1| to a maximum of |#2| characters. If it is
+% longer, replace some characters on the right of the string by
+% |~(123~more~chars)| with the appropriate number instead of~|123|.
+% In any reasonable case, $25$ is big enough to fit this extra text.
+% \begin{macrocode}
+\cs_new:Npn \@@_str_truncate_right:nn #1#2
+ {
+ \exp_args:Nf \@@_str_truncate_right_aux:nnn
+ { \str_count:n {#1} } {#1} {#2}
+ }
+\cs_new:Npn \@@_str_truncate_right_aux:nnn #1#2#3
+ {
+ \int_compare:nNnTF {#1} > {#3}
+ {
+ \str_range:nnn {#2} { 1 } { #3 - 25 } ~
+ ( \int_eval:n { #1 - #3 + 25 } ~ more~chars )
+ }
+ { \tl_to_str:n {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Helpers for control flow}
+%
+% \begin{macro}[int,EXP]{\@@_exit:w, \@@_exit_point:}
+% Jump to the very end of this instance of \cs{unravel}.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_exit_point: \prg_do_nothing:
+\cs_new:Npn \@@_exit:w #1 \@@_exit_point: { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int,EXP]{\@@_break:w, \@@_break_point:}
+% Useful to jump out of complicated conditionals.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_break_point: \prg_do_nothing:
+\cs_new:Npn \@@_break:w #1 \@@_break_point: { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_cmd_if_internal:TF}
+% Test whether the \cs{l_@@_head_cmd_int} denotes an ``internal''
+% command, between |min_internal| and |max_internal| (see
+% Section~\ref{sec:numeric-codes}).
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_cmd_if_internal: { TF }
+ {
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int < { \@@_tex_use:n { min_internal } }
+ { \prg_return_false: }
+ {
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int
+ > { \@@_tex_use:n { max_internal } }
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Helpers concerning tokens}
+%
+% \begin{macro}[int]{\@@_token_to_char:N}
+% \begin{macro}[int]{\@@_meaning_to_char:n, \@@_meaning_to_char:o}
+% \begin{macro}[aux]
+% {\@@_meaning_to_char_auxi:w, \@@_meaning_to_char_auxii:w}
+% From the meaning of a character token (with arbitrary character
+% code, except active), extract the character itself (with string
+% category codes). This is somewhat robust against wrong input.
+% \begin{macrocode}
+\cs_new:Npn \@@_meaning_to_char:n #1
+ { \@@_meaning_to_char_auxi:w #1 \q_mark ~ {} ~ \q_mark \q_stop }
+\cs_new:Npn \@@_meaning_to_char_auxi:w #1 ~ #2 ~ #3 \q_mark #4 \q_stop
+ { \@@_meaning_to_char_auxii:w #3 ~ #3 ~ \q_stop }
+\cs_new:Npn \@@_meaning_to_char_auxii:w #1 ~ #2 ~ #3 \q_stop
+ { \tl_if_empty:nTF {#2} { ~ } {#2} }
+\cs_generate_variant:Nn \@@_meaning_to_char:n { o }
+\cs_new:Npn \@@_token_to_char:N #1
+ { \@@_meaning_to_char:o { \token_to_meaning:N #1 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int,EXP,pTF]{\@@_token_if_expandable:N}
+% We need to cook up our own version of \cs{token_if_expandable:NTF}
+% because the \pkg{expl3} one does not think that |undefined| is
+% expandable.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_token_if_expandable:N #1
+ { p , T , F , TF }
+ {
+ \exp_after:wN \if_meaning:w \exp_not:N #1 #1
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int,EXP,pTF]{\@@_token_if_protected:N}
+% Returns \texttt{true} if the token is either not expandable or is a
+% protected macro.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_token_if_protected:N #1
+ { p , T , F , TF }
+ {
+ \@@_token_if_expandable:NTF #1
+ {
+ \token_if_protected_macro:NTF #1
+ { \prg_return_true: }
+ {
+ \token_if_protected_long_macro:NTF #1
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ }
+ { \prg_return_true: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int,TF]{\@@_token_if_definable:N}
+% Within a group, set the escape character to a non-space value
+% (backslash). Convert the token to a string with
+% \cs{token_to_str:N}. The result is multiple characters if the
+% token is a control sequence, and a single character otherwise (even
+% for explicit catcode~$6$ character tokens which would be doubled if
+% we used \cs{tl_to_str:n} instead of \cs{token_to_str:N}). Thus
+% \cs{str_tail:n} gives a non-empty result exactly for control
+% sequences. Those are definable (technically, not always:
+% |\expandafter\font\csname\endcsname=cmr10|
+% |\expandafter\def\the\csname\endcsname{}|). For characters, there
+% remains to determine if |#1| is an active character. One option
+% would be to build the active character with that character code and
+% compare them using a delimited-argument test, but that needlessly
+% pollutes the hash table in \XeTeX{} (and \LuaTeX{}?) if the
+% character was in fact not active. Instead, use the \tn{lowercase}
+% primitive to convert the character to a fixed character code~|Z|.
+% Compare with an active~|Z|. In all cases, remember to end the
+% group.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_active:n { `Z }
+ \prg_new_protected_conditional:Npnn \@@_token_if_definable:N #1
+ { TF }
+ {
+ \group_begin:
+ \@@_set_escapechar:n { 92 }
+ \tl_set:Nx \l_@@_tmpa_tl
+ { \exp_args:No \str_tail:n { \token_to_str:N #1 } }
+ \tl_if_empty:NTF \l_@@_tmpa_tl
+ {
+ \exp_args:Nx \char_set_lccode:nn
+ { ` \str_head:n {#1} } { `Z }
+ \tex_lowercase:D { \tl_if_eq:nnTF {#1} } { Z }
+ { \group_end: \prg_return_true: }
+ { \group_end: \prg_return_false: }
+ }
+ { \group_end: \prg_return_true: }
+ }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int,TF]{\@@_gtl_if_head_is_definable:N}
+% Tests if a generalized token list is a single control sequence or a
+% single active character. First test that it is single, then filter
+% out the case of (explicit) begin-group, end-group, and blank space
+% characters: those are neither control sequences nor active. Then
+% feed the single normal token to a first auxiliary.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_gtl_if_head_is_definable:N #1
+ { TF , F }
+ {
+ \gtl_if_single_token:NTF #1
+ {
+ \gtl_if_head_is_N_type:NTF #1
+ {
+ \exp_last_unbraced:Nx \@@_token_if_definable:NTF
+ { \gtl_head:N #1 }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Helpers for previous input}
+%
+% \begin{macro}[int]
+% {
+% \@@_prev_input_silent:n,
+% \@@_prev_input_silent:V,
+% \@@_prev_input_silent:x
+% }
+% \begin{macro}[int]
+% {
+% \@@_prev_input:n,
+% \@@_prev_input:V,
+% \@@_prev_input:x
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_prev_input_silent:n #1
+ {
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_prev_input_tl
+ \tl_put_right:Nn \l_@@_prev_input_tl {#1}
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_prev_input_tl
+ }
+\cs_generate_variant:Nn \@@_prev_input_silent:n { V , x }
+\cs_new_protected:Npn \@@_prev_input:n #1
+ {
+ \@@_prev_input_silent:n {#1}
+ \@@_print_action:x { \tl_to_str:n {#1} }
+ }
+\cs_generate_variant:Nn \@@_prev_input:n { V , x }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_prev_input_gtl:N}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_prev_input_gtl:N #1
+ {
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_prev_input_gtl
+ \gtl_concat:NNN \l_@@_prev_input_gtl \l_@@_prev_input_gtl #1
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_prev_input_gtl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_prev_input_join_get:nN}
+% \begin{macro}[aux]{\@@_join_get_aux:NNN}
+% Pops \cs{g_@@_prev_input_seq} 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
+ {
+ \int_case:nnF {#1}
+ {
+ { 2 } { \@@_join_get_aux:NNN \skip_eval:n \etex_glueexpr:D }
+ { 3 } { \@@_join_get_aux:NNN \muskip_eval:n \etex_muexpr:D }
+ }
+ {
+ \msg_error:nnn { unravel } { internal } { join-factor }
+ \@@_join_get_aux:NNN \use:n \prg_do_nothing:
+ }
+ }
+\cs_new_protected:Npn \@@_join_get_aux:NNN #1#2#3
+ {
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \tl_set:Nx #3 { #1 { \l_@@_tmpa_tl #2 \l_@@_head_tl } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \subsection{Variables}
%
% \subsubsection{User interaction}
%
-% \begin{variable}
-% {\g_@@_prompt_ior, \g_@@_prompt_before_tl, \l_@@_prompt_tmpa_int}
+% \begin{variable}{\g_@@_before_print_state_tl, \g_@@_before_prompt_tl}
+% Code to run before printing the state or before the prompt.
+% \begin{macrocode}
+\tl_new:N \g_@@_before_print_state_tl
+\tl_new:N \g_@@_before_prompt_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_prompt_tmpa_int}
% \begin{macrocode}
-\ior_new:N \g_@@_prompt_ior
-\tl_new:N \g_@@_prompt_before_tl
\int_new:N \l_@@_prompt_tmpa_int
% \end{macrocode}
% \end{variable}
@@ -199,10 +745,29 @@
% \end{macrocode}
% \end{variable}
%
-% \begin{variable}{\l_@@_debug_bool}
-% If true, debug-mode. Activated by \cs{UnravelDebug}
-% \begin{macrocode}
-\bool_new:N \l_@@_debug_bool
+% \begin{variable}
+% {
+% \g_@@_default_explicit_prompt_bool , \g_@@_explicit_prompt_bool ,
+% \g_@@_default_internal_debug_bool , \g_@@_internal_debug_bool ,
+% \g_@@_default_number_steps_bool , \g_@@_number_steps_bool ,
+% \g_@@_default_welcome_message_bool , \g_@@_welcome_message_bool ,
+% }
+% Variables for the options |explicit-prompt|,
+% |internal-debug|, |number-steps|. The
+% \texttt{default_} booleans store the default value of these
+% options, and are affected by \cs{unravelsetup} or
+% \cs{unravel_setup:n}.
+% \begin{macrocode}
+\bool_new:N \g_@@_default_explicit_prompt_bool
+\bool_new:N \g_@@_default_internal_debug_bool
+\bool_new:N \g_@@_default_number_steps_bool
+\bool_gset_true:N \g_@@_default_number_steps_bool
+\bool_new:N \g_@@_default_welcome_message_bool
+\bool_gset_true:N \g_@@_default_welcome_message_bool
+\bool_new:N \g_@@_explicit_prompt_bool
+\bool_new:N \g_@@_internal_debug_bool
+\bool_new:N \g_@@_number_steps_bool
+\bool_new:N \g_@@_welcome_message_bool
% \end{macrocode}
% \end{variable}
%
@@ -223,28 +788,29 @@
% \end{macrocode}
% \end{variable}
%
-% ^^A todo: let the user fix those numbers.
% \begin{variable}
% {
+% \g_@@_default_max_action_int,
+% \g_@@_default_max_output_int,
+% \g_@@_default_max_input_int,
% \g_@@_max_action_int,
% \g_@@_max_output_int,
-% \g_@@_max_prev_int,
% \g_@@_max_input_int
% }
% Maximum length of various pieces of what is shown on the terminal.
% \begin{macrocode}
+\int_new:N \g_@@_default_max_action_int
+\int_new:N \g_@@_default_max_output_int
+\int_new:N \g_@@_default_max_input_int
+\int_gset:Nn \g_@@_default_max_action_int { 50 }
+\int_gset:Nn \g_@@_default_max_output_int { 300 }
+\int_gset:Nn \g_@@_default_max_input_int { 300 }
\int_new:N \g_@@_max_action_int
\int_new:N \g_@@_max_output_int
-\int_new:N \g_@@_max_prev_int
\int_new:N \g_@@_max_input_int
-\int_gset:Nn \g_@@_max_action_int { 50 }
-\int_gset:Nn \g_@@_max_output_int { 300 }
-\int_gset:Nn \g_@@_max_prev_int { 300 }
-\int_gset:Nn \g_@@_max_input_int { 300 }
% \end{macrocode}
% \end{variable}
%
-% ^^A todo: doc, and let user decide
% \begin{variable}{\g_@@_speedup_macros_bool}
% If this boolean is true, speed up macros which have a simple
% parameter text. This may not be safe if very weird macros appear.
@@ -287,7 +853,12 @@
%
% \begin{variable}
% {\g_@@_prev_input_seq, \l_@@_prev_input_tl, \l_@@_prev_input_gtl}
-% ^^A todo: comment
+% The different levels of expansion are stored in
+% \cs{g_@@_prev_input_seq}, with the innermost at the end of the
+% sequence (otherwise the sequence would have to be reversed for
+% display). When adding material to the last level of expansion,
+% \cs{l_@@_prev_input_tl} or \cs{l_@@_prev_input_gtl} are used to
+% temporarily store the last level of expansion.
% \begin{macrocode}
\seq_new:N \g_@@_prev_input_seq
\tl_new:N \l_@@_prev_input_tl
@@ -331,10 +902,12 @@
% \end{variable}
%
% \begin{variable}
-% {\l_@@_tmpa_tl, \l_@@_tmpb_gtl, \g_@@_tmpc_tl, \l_@@_tmpa_seq}
-% Temporary storage.
+% {\l_@@_tmpa_tl, \l_@@_tmpb_gtl, \g_@@_tmpc_tl, \l_@@_tmpa_seq, \l_@@_unused_gtl}
+% Temporary storage. The \cs{l_@@_unused_gtl} is only used once,
+% to ignore some unwanted tokens.
% \begin{macrocode}
\tl_new:N \l_@@_tmpa_tl
+\gtl_new:N \l_@@_unused_gtl
\gtl_new:N \l_@@_tmpb_gtl
\tl_new:N \g_@@_tmpc_tl
\seq_new:N \l_@@_tmpa_seq
@@ -382,9 +955,9 @@
% Used to determine if a macro has simple parameters or not.
% \begin{macrocode}
\group_begin:
- \char_set_lccode:nn { `* } { `# }
- \tex_lowercase:D
- { \tl_const:Nn \c_@@_parameters_tl { ^*1*2*3*4*5*6*7*8*9 } }
+ \cs_set:Npx \@@_tmp:w #1 { \c_hash_str #1 }
+ \tl_const:Nx \c_@@_parameters_tl
+ { ^ \tl_map_function:nN { 123456789 } \@@_tmp:w }
\group_end:
% \end{macrocode}
% \end{variable}
@@ -407,28 +980,6 @@
% \end{macrocode}
% \end{variable}
%
-% \begin{variable}
-% {
-% \c_@@_plus_tl, \c_@@_minus_tl, \c_@@_times_tl, \c_@@_over_tl,
-% \c_@@_lq_tl, \c_@@_rq_tl, \c_@@_dq_tl, \c_@@_lp_tl, \c_@@_rp_tl,
-% \c_@@_eq_tl, \c_@@_comma_tl, \c_@@_point_tl,
-% }
-% \begin{macrocode}
-\tl_const:Nn \c_@@_plus_tl { + }
-\tl_const:Nn \c_@@_minus_tl { - }
-\tl_const:Nn \c_@@_times_tl { * }
-\tl_const:Nn \c_@@_over_tl { / }
-\tl_const:Nn \c_@@_lq_tl { ` }
-\tl_const:Nn \c_@@_rq_tl { ' }
-\tl_const:Nn \c_@@_dq_tl { " }
-\tl_const:Nn \c_@@_lp_tl { ( }
-\tl_const:Nn \c_@@_rp_tl { ) }
-\tl_const:Nn \c_@@_eq_tl { = }
-\tl_const:Nn \c_@@_comma_tl { , }
-\tl_const:Nn \c_@@_point_tl { . }
-% \end{macrocode}
-% \end{variable}
-%
% \begin{variable}{\g_@@_if_limit_tl}
% \begin{variable}{\g_@@_if_limit_int}
% \begin{variable}{\g_@@_if_depth_int}
@@ -472,317 +1023,37 @@
%
% \subsubsection{Constants}
%
-% \begin{variable}{\c_@@_frozen_relax_gtl}
-% \TeX{}'s |frozen_relax|, inserted by \cs{@@_insert_relax:}.
-% \begin{macrocode}
-\gtl_const:Nx \c_@@_frozen_relax_gtl { \if_int_compare:w 0 = 0 \fi: }
-% \end{macrocode}
-% \end{variable}
-%
-% \subsection{Variants and helper functions}
-%
-% 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 \ior_get_str:NN { Nc }
-\cs_generate_variant:Nn \gtl_if_empty:NTF { c }
-\cs_generate_variant:Nn \gtl_to_str:N { c }
-\cs_generate_variant:Nn \gtl_gpop_left:NN { c }
-\cs_generate_variant:Nn \gtl_get_left:NN { c }
-\cs_generate_variant:Nn \gtl_gset:Nn { c }
-\cs_generate_variant:Nn \gtl_gconcat:NNN { ccc , cNc }
-\cs_generate_variant:Nn \gtl_gclear:N { c }
-% \end{macrocode}
-%
-% \begin{macro}[aux]{\@@_tl_gset_input:Nnn, \@@_tl_gset_input:Nno}
-% \begin{macro}[aux]{\@@_tl_gset_input_aux:wN}
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_tl_gset_input:Nnn #1#2#3
- {
- \group_begin:
- \etex_everyeof:D \exp_after:wN { \token_to_str:N @ @ #1 }
- #2
- \tl_gclear:N #1
- \str_if_eq_x:nnF
- { \token_to_meaning:N \tex_input:D }
- { \token_to_str:N \input }
- { \msg_unravel:nnx { unravel } { internal } { input-prim } }
- \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 \etex_everyeof:D
- }
-\cs_generate_variant:Nn \@@_tl_gset_input:Nnn { Nno }
-\use:x
- {
- \cs_new_protected:Npn \exp_not:N \@@_tl_gset_input_aux:wN
- ##1 \token_to_str:N @ @ ##2
- } { \tl_gset:No #2 {#1} }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_cs_case:NnF}
-% Currently, \texttt{expl3} does not provide a case statement for the
-% meaning of control sequences. However, \cs{tl_case:NnF} in fact
-% does precisely this.
-% \begin{macrocode}
-\cs_new_eq:NN \@@_cs_case:NnF \tl_case:NnF
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_strip_escape:w}
-% \begin{macro}[aux]{\@@_strip_escape_aux:N, \@@_strip_escape_aux:w}
-% This is based on the 2013-07-19 (and earlier) version of
-% \cs{cs_to_str:N}. There are three cases. If the escape character
-% is printable, the charcode test is false, and
-% \cs{@@_strip_escape_aux:N} removes one character. If the escape
-% character is a space, the charcode test is true, and if there is no
-% escape charcter, the test is unfinished after |\token_to_str:N \ |.
-% In both of those cases, \cs{@@_strip_escape_aux:w} inserts
-% |-\__int_value:w \fi: \c_zero|. If the escape character was a
-% space, the test was true, and \cs{__int_value:w} converts
-% \cs{c_zero} to~|0|, hence the leading roman numeral expansion
-% removes a space from what follows (it is important that what follows
-% cannot start with a digit). Otherwise, the test takes~|-| as its
-% second operand, is false, and the roman numeral expansion only sees
-% \cs{c_zero}, thus does not remove anything from what follows.
-% \begin{macrocode}
-\cs_new_nopar:Npn \@@_strip_escape:w
- {
- \tex_romannumeral:D
- \if_charcode:w \token_to_str:N \ \@@_strip_escape_aux:w \fi:
- \@@_strip_escape_aux:N
- }
-\cs_new:Npn \@@_strip_escape_aux:N #1 { \c_zero }
-\cs_new:Npn \@@_strip_escape_aux:w #1#2
- { - \__int_value:w #1 \c_zero }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_token_to_char:N}
-% \begin{macro}[int]{\@@_meaning_to_char:n, \@@_meaning_to_char:o}
-% \begin{macro}[aux]
-% {\@@_meaning_to_char_auxi:w, \@@_meaning_to_char_auxii:w}
-% From the meaning of a character token (with arbitrary character
-% code, except active), extract the character itself (with string
-% category codes). This is somewhat robust against wrong input.
-% \begin{macrocode}
-\cs_new:Npn \@@_meaning_to_char:n #1
- { \@@_meaning_to_char_auxi:w #1 \q_mark ~ {} ~ \q_mark \q_stop }
-\cs_new:Npn \@@_meaning_to_char_auxi:w #1 ~ #2 ~ #3 \q_mark #4 \q_stop
- { \@@_meaning_to_char_auxii:w #3 ~ #3 ~ \q_stop }
-\cs_new:Npn \@@_meaning_to_char_auxii:w #1 ~ #2 ~ #3 \q_stop
- { \tl_if_empty:nTF {#2} { ~ } {#2} }
-\cs_generate_variant:Nn \@@_meaning_to_char:n { o }
-\cs_new:Npn \@@_token_to_char:N #1
- { \@@_meaning_to_char:o { \token_to_meaning:N #1 } }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% ^^A this abuses future l3obj.
-% \begin{macro}[int,EXP]{\@@_to_str:n}
-% \begin{macro}[aux,EXP]{\@@_to_str_auxi:w, \@@_to_str_auxii:w}
-% Use the type-appropriate conversion to string.
-% \begin{macrocode}
-\cs_new:Npn \@@_to_str:n #1
- {
- \tl_if_head_eq_meaning:nNTF {#1} \scan_stop:
- { \@@_to_str_auxi:w #1 ? \q_stop }
- { \tl_to_str:n }
- {#1}
- }
-\cs_set:Npn \@@_tmp:w #1
- {
- \cs_new:Npn \@@_to_str_auxi:w ##1##2 \q_stop
- {
- \exp_after:wN \@@_to_str_auxii:w \token_to_str:N ##1 \q_mark
- #1 tl \q_mark \q_stop
- }
- \cs_new:Npn \@@_to_str_auxii:w ##1 #1 ##2 \q_mark ##3 \q_stop
- { \cs_if_exist_use:cF { ##2 _to_str:n } { \tl_to_str:n } }
- }
-\exp_args:No \@@_tmp:w { \tl_to_str:n { s__ } }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[int]
-% {
-% \@@_prev_input_silent:n,
-% \@@_prev_input_silent:V,
-% \@@_prev_input_silent:x
-% }
-% \begin{macro}[int]
+% \begin{variable}
% {
-% \@@_prev_input:n,
-% \@@_prev_input:V,
-% \@@_prev_input:x
+% \c_@@_plus_tl, \c_@@_minus_tl, \c_@@_times_tl, \c_@@_over_tl,
+% \c_@@_lq_tl, \c_@@_rq_tl, \c_@@_dq_tl, \c_@@_lp_tl, \c_@@_rp_tl,
+% \c_@@_eq_tl, \c_@@_comma_tl, \c_@@_point_tl,
% }
% \begin{macrocode}
-\cs_new_protected:Npn \@@_prev_input_silent:n #1
- {
- \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_prev_input_tl
- \tl_put_right:Nn \l_@@_prev_input_tl {#1}
- \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_prev_input_tl
- }
-\cs_generate_variant:Nn \@@_prev_input_silent:n { V , x }
-\cs_new_protected:Npn \@@_prev_input:n #1
- {
- \@@_prev_input_silent:n {#1}
- \@@_print_action:x { \tl_to_str:n {#1} }
- }
-\cs_generate_variant:Nn \@@_prev_input:n { V , x }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_prev_input_gtl:N}
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_prev_input_gtl:N #1
- {
- \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_prev_input_gtl
- \gtl_concat:NNN \l_@@_prev_input_gtl \l_@@_prev_input_gtl #1
- \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_prev_input_gtl
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int,EXP,pTF]{\@@_token_if_expandable:N}
-% We need to cook up our own version of \cs{token_if_expandable:NTF}
-% because the \texttt{expl3} one does not think that |undefined| is
-% expandable.
-% \begin{macrocode}
-\prg_new_conditional:Npnn \@@_token_if_expandable:N #1
- { p , T , F , TF }
- {
- \exp_after:wN \if_meaning:w \exp_not:N #1 #1
- \prg_return_false:
- \else:
- \prg_return_true:
- \fi:
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int,EXP,pTF]{\@@_token_if_protected:N}
-% Returns \texttt{true} if the token is either not expandable or is a
-% protected macro.
-% \begin{macrocode}
-\prg_new_conditional:Npnn \@@_token_if_protected:N #1
- { p , T , F , TF }
- {
- \@@_token_if_expandable:NTF #1
- {
- \token_if_protected_macro:NTF #1
- { \prg_return_true: }
- {
- \token_if_protected_long_macro:NTF #1
- { \prg_return_true: }
- { \prg_return_false: }
- }
- }
- { \prg_return_true: }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int,EXP]{\@@_exit:w, \@@_exit_point:}
-% Jump to the very end of this instance of \cs{unravel}.
-% \begin{macrocode}
-\cs_new_eq:NN \@@_exit_point: \prg_do_nothing:
-\cs_new:Npn \@@_exit:w #1 \@@_exit_point: { }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int,EXP]{\@@_break:w, \@@_break_point:}
-% Useful to jump out of complicated conditionals.
-% \begin{macrocode}
-\cs_new_eq:NN \@@_break_point: \prg_do_nothing:
-\cs_new:Npn \@@_break:w #1 \@@_break_point: { }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int,TF]{\@@_token_if_definable:N}
-% Within a group, set the escape character to a non-zero non-space
-% value (backslash): if the result of converting the token to a string
-% is longer than a single token (false branch), the token was a
-% control sequence and the test is \texttt{true} (note that we did not
-% use \cs{tl_to_str:n}, as this would fail on explicit macro parameter
-% characters). Otherwise, the token was an explicit character, active
-% or not. Use \tn{lowercase} to convert the character to a fixed
-% character code~|Z|. Compare with an active~|Z|. In all three
-% outcomes, remember to end the group.
-% \begin{macrocode}
-\group_begin:
- \char_set_catcode_active:n { `Z }
- \prg_new_protected_conditional:Npnn \@@_token_if_definable:N #1
- { TF }
- {
- \group_begin:
- \int_set:Nn \tex_escapechar:D { 92 }
- \exp_args:No \tl_if_single:nTF { \token_to_str:N #1 }
- {
- \exp_args:Nx \char_set_lccode:nn
- { ` \str_head:n {#1} } { `Z }
- \tex_lowercase:D { \tl_if_eq:nnTF {#1} } { Z }
- { \group_end: \prg_return_true: }
- { \group_end: \prg_return_false: }
- }
- { \group_end: \prg_return_true: }
- }
-\group_end:
+\tl_const:Nn \c_@@_plus_tl { + }
+\tl_const:Nn \c_@@_minus_tl { - }
+\tl_const:Nn \c_@@_times_tl { * }
+\tl_const:Nn \c_@@_over_tl { / }
+\tl_const:Nn \c_@@_lq_tl { ` }
+\tl_const:Nn \c_@@_rq_tl { ' }
+\tl_const:Nn \c_@@_dq_tl { " }
+\tl_const:Nn \c_@@_lp_tl { ( }
+\tl_const:Nn \c_@@_rp_tl { ) }
+\tl_const:Nn \c_@@_eq_tl { = }
+\tl_const:Nn \c_@@_comma_tl { , }
+\tl_const:Nn \c_@@_point_tl { . }
% \end{macrocode}
-% \end{macro}
+% \end{variable}
%
-% \begin{macro}[int,TF]{\@@_gtl_if_head_is_definable:N}
-% Tests if a generalized token list is a single control sequence or a
-% single active character. First test that it is single, then filter
-% out the case of (explicit) begin-group, end-group, and blank space
-% characters: those are neither control sequences nor active. Then
-% feed the single normal token to a first auxiliary.
+% \begin{variable}{\c_@@_frozen_relax_gtl}
+% \TeX{}'s |frozen_relax|, inserted by \cs{@@_insert_relax:}.
% \begin{macrocode}
-\prg_new_protected_conditional:Npnn \@@_gtl_if_head_is_definable:N #1
- { TF , F }
- {
- \gtl_if_single_token:NTF #1
- {
- \gtl_if_head_is_N_type:NTF #1
- {
- \exp_last_unbraced:Nx \@@_token_if_definable:NTF
- { \gtl_head:N #1 }
- { \prg_return_true: }
- { \prg_return_false: }
- }
- { \prg_return_false: }
- }
- { \prg_return_false: }
- }
+\gtl_const:Nx \c_@@_frozen_relax_gtl { \if_int_compare:w 0 = 0 \fi: }
% \end{macrocode}
-% \end{macro}
+% \end{variable}
%
% \subsection{Numeric codes}
+% \label{sec:numeric-codes}
%
% First we define some numeric codes, following Section~15 of the \TeX{}
% web code, then we associate a command code to each \TeX{} primitive,
@@ -1253,7 +1524,7 @@
\@@_tex_primitive:nnn { lefthyphenmin } { assign_int } { 51 }
\@@_tex_primitive:nnn { righthyphenmin } { assign_int } { 52 }
\@@_tex_primitive:nnn { holdinginserts } { assign_int } { 53 }
-\@@_tex_primitive:nnn { errorcontegtlines } { assign_int } { 54 }
+\@@_tex_primitive:nnn { errorcontextlines } { assign_int } { 54 }
\@@_tex_primitive:nnn { pdfoutput } { assign_int } { 55 }
\@@_tex_primitive:nnn { pdfcompresslevel } { assign_int } { 56 }
\@@_tex_primitive:nnn { pdfdecimaldigits } { assign_int } { 57 }
@@ -1662,10 +1933,9 @@
% \end{macro}
% \end{macro}
%
-% ^^A todo: should we worry about call vs long_call etc.?
% \begin{macro}[aux]{\@@_set_cmd_aux_macro:}
-% The token is a macro. For now we do not test if the macro is
-% long/outer.
+% The token is a macro. There is no need to determine whether the
+% macro is long/outer.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_set_cmd_aux_macro:
{
@@ -1847,7 +2117,7 @@
% \end{macrocode}
% \end{macro}
%
-% ^^A todo: "timeit" to know if \@@_input_split: is beneficial.
+% ^^A todo: profiling to know if \@@_input_split: is beneficial.
%
% \begin{macro}[int]{\@@_input_split:}
% If the input is completely flat, and is a token list starting with
@@ -1894,6 +2164,8 @@
\cs_new_protected:Npn \@@_input_split_auxiii:w
#1 \@@_input_split_end:
{
+ \gtl_gclear_new:c
+ { g_@@_input_ \int_use:N \g_@@_input_tmpa_int _gtl }
\gtl_gset:cn
{ g_@@_input_ \int_use:N \g_@@_input_tmpa_int _gtl } {#1}
\int_gdecr:N \g_@@_input_tmpa_int
@@ -1906,8 +2178,8 @@
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_input_gset:n
{
- \int_gset_eq:NN \g_@@_input_int \c_one
- \gtl_gset:cn { g_@@_input_1_gtl }
+ \int_gzero:N \g_@@_input_int
+ \@@_back_input:n
}
% \end{macrocode}
% \end{macro}
@@ -2043,11 +2315,14 @@
% \end{macro}
%
% \begin{macro}[int]{\@@_back_input:n, \@@_back_input:x}
-% Insert a token list back into the input.
+% Insert a token list back into the input. Use \cs{gtl_gclear_new:c}
+% to define the gtl variable if necessary: this happens whenever a
+% new largest value of \cs{g_@@_input_int} is reached.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_back_input:n
{
\int_gincr:N \g_@@_input_int
+ \gtl_gclear_new:c { g_@@_input_ \int_use:N \g_@@_input_int _gtl }
\gtl_gset:cn { g_@@_input_ \int_use:N \g_@@_input_int _gtl }
}
\cs_generate_variant:Nn \@@_back_input:n { x , V , o }
@@ -2147,21 +2422,20 @@
% \@@_macro_replacement:N
% }
% \begin{macrocode}
-\group_begin:
- \char_set_lccode:nn { `. } { `: }
- \tex_lowercase:D
- {
- \cs_new:Npn \@@_macro_split_do:NN #1
- {
- \exp_after:wN \@@_macro_split_do:wN
- \token_to_meaning:N #1 \q_mark { } . -> \q_mark \use_none:nnnn
- \q_stop
- }
- \cs_new:Npn \@@_macro_split_do:wN
- #1 . #2 -> #3 \q_mark #4 #5 \q_stop #6
- { #4 #6 {#1} {#2} {#3} }
- }
-\group_end:
+\use:x
+ {
+ \exp_not:n { \cs_new:Npn \@@_macro_split_do:NN #1 }
+ {
+ \exp_not:n { \exp_after:wN \@@_macro_split_do:wN }
+ \exp_not:n { \token_to_meaning:N #1 \q_mark { } }
+ \tl_to_str:n { : } \exp_not:n { -> \q_mark \use_none:nnnn }
+ \exp_not:N \q_stop
+ }
+ \exp_not:n { \cs_new:Npn \@@_macro_split_do:wN }
+ \exp_not:n {#1} \tl_to_str:n { : } \exp_not:n { #2 -> }
+ \exp_not:n { #3 \q_mark #4 #5 \q_stop #6 }
+ { \exp_not:n { #4 #6 {#1} {#2} {#3} } }
+ }
\cs_new:Npn \@@_macro_prefix:N #1
{ \@@_macro_split_do:NN #1 \use_i:nnn }
\cs_new:Npn \@@_macro_parameter:N #1
@@ -2172,13 +2446,13 @@
% \end{macro}
%
% ^^A todo: redoc
-% ^^A todo: estimate how far the macro has touched the input.
% \begin{macro}[int]{\@@_macro_call:}
% \begin{macro}[aux]
% {
% \@@_macro_call_safe:,
% \@@_macro_call_quick:,
-% \@@_macro_call_quick_loop:NN
+% \@@_macro_call_quick_loop:NNN,
+% \@@_macro_call_quick_runaway:Nw,
% }
% Macros are simply expanded once. We cannot determine precisely
% which tokens a macro will need for its parameters, but we know that
@@ -2206,17 +2480,23 @@
}
\cs_new_protected_nopar:Npn \@@_macro_call_quick:
{
- \exp_after:wN \@@_macro_call_quick_loop:NN \l_@@_tmpa_tl
+ \exp_after:wN \@@_macro_call_quick_loop:NNN \l_@@_tmpa_tl
{ ? \use_none_delimit_by_q_stop:w } \q_stop
}
-\cs_new_protected_nopar:Npn \@@_macro_call_quick_loop:NN #1#2
+\cs_new_protected:Npn \@@_macro_call_quick_loop:NNN #1#2#3
{
\use_none:n #2
\@@_input_gpop_item:NF \l_@@_tmpa_tl
- { \msg_error:nn { unravel } { runaway-macro-parameter } }
+ { \@@_macro_call_quick_runaway:Nw #3 }
\tl_put_right:Nx \l_@@_head_tl
{ { \exp_not:V \l_@@_tmpa_tl } }
- \@@_macro_call_quick_loop:NN
+ \@@_macro_call_quick_loop:NNN
+ #3
+ }
+\cs_new_protected:Npn \@@_macro_call_quick_runaway:Nw #1#2 \q_stop
+ {
+ \msg_error:nnxx { unravel } { runaway-macro-parameter }
+ { \tl_to_str:N \l_@@_head_tl } { \tl_to_str:n {#1} }
}
% \end{macrocode}
% \end{macro}
@@ -2233,7 +2513,7 @@
\cs_new_protected_nopar:Npn \@@_expand:
{
\@@_set_action_text:
- \bool_if:NT \l_@@_debug_bool
+ \bool_if:NT \g_@@_internal_debug_bool
{
\@@_set_cmd:
\iow_term:x { Exp:~\int_use:N \l_@@_head_cmd_int }
@@ -2250,7 +2530,8 @@
% and call the function implementing that expansion. If we do not
% recognize the meaning then it is probably an unknown primitive. If
% we recognize the meaning but there is no corresponding function,
-% then we probably have not implemented it yet.
+% then we probably have not implemented it yet, so dump it in the
+% output as is.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_expand_nonmacro:
{
@@ -2513,7 +2794,7 @@
}
{
\msg_error:nn { unravel } { missing-font-id }
- \@@_prev_input:n { \tex_nullfont:D }
+ \@@_prev_input:n { \@@_nullfont: }
\@@_back_error:
}
}
@@ -2549,7 +2830,7 @@
% \end{macro}
%
% ^^A todo: redoc
-% ^^A todo: rename: all other scan functions do get_x_next themselves.
+% ^^A todo: rename this function because all other scan functions do get_x_next themselves.
% \begin{macro}[aux]{\@@_scan_something_internal:n}
% \begin{macro}[aux]{\@@_scan_something_aux:nwn}
% Receives an (explicit) \enquote{level} argument:
@@ -2582,7 +2863,10 @@
% 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
-% token, its meaning).
+% token, its meaning). Use |=>| rather than |=| because the value
+% displayed is the value used, not the actual value (this matters in
+% constructions such as |\parindent=\parskip| where a skip or a dimen
+% is downgraded to a dimen or an int).
% \begin{macrocode}
\cs_new_protected:Npn \@@_scan_something_internal:n #1
{
@@ -2611,7 +2895,7 @@
\@@_prev_input_silent:V \l_@@_tmpa_tl
\@@_set_action_text:
\@@_set_action_text:x
- { \g_@@_action_text_str = ~ \tl_to_str:N \l_@@_tmpa_tl }
+ { \g_@@_action_text_str \use:n { ~ => ~ } \tl_to_str:N \l_@@_tmpa_tl }
\int_compare:nNnF {#3} > { 3 } { \@@_print_action: }
\int_gset:Nn \g_@@_val_level_int {#1}
}
@@ -2624,7 +2908,7 @@
% This expands to a digit (the level generated by whatever token is
% the current |head|), followed by some code to fetch necessary
% operands. In most cases, this can be done by simply looking at the
-% |cmd| integer, but for |last_item| and |register|, the level of the
+% |cmd| integer, but for |last_item|, |set_aux| and |register|, the level of the
% token depends on the |char| integer. When the token is not allowed
% after \tn{the} (or at any other position where
% \cs{@@_scan_something_internal:n} is called), the resulting level
@@ -2646,7 +2930,7 @@
{ 76 } { 3 } % assign_mu_glue
{ 77 } { 1 \@@_scan_font_dimen: } % assign_font_dimen
{ 78 } { 0 \@@_scan_font_int: } % assign_font_int
- { 79 } { 0 } % set_aux
+ { 79 } { \@@_thing_set_aux: } % set_aux
{ 80 } { 0 } % set_prev_graf
{ 81 } { 1 } % set_page_dimen
{ 82 } { 0 } % set_page_int
@@ -2660,6 +2944,8 @@
}
{ 8 }
}
+\cs_new_nopar:Npn \@@_thing_set_aux:
+ { \int_compare:nNnTF \l_@@_head_char_int = { 1 } { 1 } { 0 } }
\cs_new_nopar:Npn \@@_thing_last_item:
{
\int_compare:nNnTF \l_@@_head_char_int < { 26 }
@@ -2737,7 +3023,7 @@
{ 2 } \skip_eval:n
{ 3 } \muskip_eval:n
}
- { \tex_the:D }
+ { \@@_the:w }
}
% \end{macrocode}
% \end{macro}
@@ -2842,7 +3128,6 @@
% \end{macrocode}
% \end{macro}
%
-% ^^A todo: |\let\a b \ifnum`\a=`b wrong!\fi|
% \begin{macro}[aux]{\@@_scan_int:}
% \begin{macro}[aux]
% {\@@_scan_int_char:, \@@_scan_int_lq:, \@@_scan_int_explicit:n}
@@ -2851,16 +3136,9 @@
{
\@@_scan_signs:
\@@_set_cmd:
- \int_compare:nNnTF
- \l_@@_head_cmd_int < { \@@_tex_use:n { min_internal } }
+ \@@_cmd_if_internal:TF
+ { \@@_scan_something_internal:n { 0 } }
{ \@@_scan_int_char: }
- {
- \int_compare:nNnTF
- \l_@@_head_cmd_int
- > { \@@_tex_use:n { max_internal } }
- { \@@_scan_int_char: }
- { \@@_scan_something_internal:n { 0 } }
- }
}
\cs_new_protected_nopar:Npn \@@_scan_int_char:
{
@@ -2922,61 +3200,56 @@
% \begin{macro}[int]{\@@_scan_normal_dimen:}
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_scan_normal_dimen:
- { \@@_scan_dimen:NN \c_false_bool \c_false_bool }
+ { \@@_scan_dimen:nN { 2 } \c_false_bool }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[int]{\@@_scan_dimen:NN}
-% Quoth |tex.web|. ``\emph{|mu| is |true| if the finite units must be
-% `mu', while |mu| is |false| if `mu' units are disallowed; |inf| is
-% |true| if the infinite units `fil', `fill', `filll' are
-% permitted.}'' The function here has the same first two parameters
-% as \TeX{}'s |scan_dimen|, but omits the third, as the shortcut is
-% provided as a separate function, \cs{@@_scan_dimen_unit:NN}.
+% \begin{macro}[int]{\@@_scan_dimen:nN}
+% The first argument is $2$ if the unit may not be |mu| and $3$ if
+% the unit must be |mu| (or |fil|). The second argument is
+% \cs{c_true_bool} if |fil|, |fill|, |filll| are permitted, and is
+% otherwise |false|. These arguments are similar to those of
+% \TeX{}'s own |scan_dimen| procedure, in which |mu| is |bool(#1=3)|
+% 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_dimen_unit:nN}.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_scan_dimen:NN #1#2
+\cs_new_protected:Npn \@@_scan_dimen:nN #1#2
{
\@@_scan_signs:
\seq_gput_right:Nn \g_@@_prev_input_seq { }
\@@_set_cmd:
- \int_compare:nNnTF
- \l_@@_head_cmd_int < { \@@_tex_use:n { min_internal } }
- { \@@_scan_dimen_char:NN #1#2 }
+ \@@_cmd_if_internal:TF
{
- \int_compare:nNnTF
- \l_@@_head_cmd_int
- > { \@@_tex_use:n { max_internal } }
- { \@@_scan_dimen_char:NN #1#2 }
+ \int_compare:nNnTF {#1} = { 3 }
{
- \bool_if:NTF #1
+ \@@_scan_something_internal:n { 3 }
+ \int_case:nnF \g_@@_val_level_int
{
- \@@_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
- }
+ { 0 } { \@@_scan_dim_unit:nN {#1} #2 }
+ { 3 } { }
}
{
- \@@_scan_something_internal:n { 2 }
- \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 } }
- }
- { }
+ \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_dimen_char:nN {#1} #2 }
\seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
\@@_prev_input_silent:V \l_@@_head_tl
}
-\cs_new_protected:Npn \@@_scan_dimen_char:NN #1#2
+\cs_new_protected:Npn \@@_scan_dimen_char:nN #1#2
{
\tl_if_eq:NNT \l_@@_head_tl \c_@@_comma_tl
{ \tl_set_eq:NN \l_@@_head_tl \c_@@_point_tl }
@@ -3004,9 +3277,9 @@
\@@_scan_int:
}
}
- \@@_scan_dim_unit:NN #1#2
+ \@@_scan_dim_unit:nN {#1} #2
}
-\cs_new_protected:Npn \@@_scan_dim_unit:NN #1#2
+\cs_new_protected:Npn \@@_scan_dim_unit:nN #1#2
{
\bool_if:NT #2
{
@@ -3018,35 +3291,16 @@
}
\@@_get_x_non_blank:
\@@_set_cmd:
- \int_compare:nNnTF
- \l_@@_head_cmd_int < { \@@_tex_use:n { min_internal } }
- { \@@_back_input: }
+ \@@_cmd_if_internal:TF
{
- \int_compare:nNnTF
- \l_@@_head_cmd_int
- > { \@@_tex_use:n { max_internal } }
- { \@@_back_input: }
- {
- \seq_gput_right:Nn \g_@@_prev_input_seq { }
- \bool_if:NTF #1
- { \@@_scan_something_internal:n { 3 } }
- { \@@_scan_something_internal:n { 2 } }
- \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
- \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
- \tl_set:Nx \l_@@_tmpa_tl
- {
- \bool_if:NTF #1 \muskip_eval:n \skip_eval:n
- {
- \l_@@_tmpa_tl
- \bool_if:NTF #1 \etex_muexpr:D \etex_glueexpr:D
- \l_@@_head_tl
- }
- }
- \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_tmpa_tl
- \@@_break:w
- }
+ \seq_gput_right:Nn \g_@@_prev_input_seq { }
+ \@@_scan_something_internal:n {#1}
+ \@@_prev_input_join_get:nN {#1} \l_@@_tmpa_tl
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \@@_break:w
}
- \bool_if:NT #1
+ { \@@_back_input: }
+ \int_compare:nNnT {#1} = { 3 }
{
\@@_scan_keyword:nT { mM uU } { \@@_break:w }
\msg_error:nn { unravel } { missing-mudim }
@@ -3099,52 +3353,38 @@
% \end{macrocode}
% \end{macro}
%
-% ^^A todo: this is wrong for signs.
% \begin{macro}[int]{\@@_scan_glue:n}
% \begin{macrocode}
\cs_new_protected:Npn \@@_scan_glue:n #1
{
- \int_compare:nNnTF {#1} = { 2 }
- { \@@_scan_glue_aux:nN {#1} \c_false_bool }
- { \@@_scan_glue_aux:nN {#1} \c_true_bool }
- }
-\cs_new_protected:Npn \@@_scan_glue_aux:nN #1#2
- {
+ \seq_gput_right:Nn \g_@@_prev_input_seq { }
\@@_scan_signs:
\seq_gput_right:Nn \g_@@_prev_input_seq { }
\@@_set_cmd:
- \int_compare:nNnTF
- \l_@@_head_cmd_int < { \@@_tex_use:n { min_internal } }
- { \@@_back_input: \@@_scan_dimen:NN #2 \c_false_bool }
+ \@@_cmd_if_internal:TF
{
- \int_compare:nNnTF
- \l_@@_head_cmd_int
- > { \@@_tex_use:n { max_internal } }
+ \@@_scan_something_internal:n {#1}
+ \int_case:nnF \g_@@_val_level_int
{
- \@@_back_input:
- \@@_scan_dimen:NN #2 \c_false_bool
+ { 0 } { \@@_scan_dimen:nN {#1} \c_false_bool }
+ {#1} { \@@_break:w }
}
{
- \@@_scan_something_internal:n {#1}
- \int_case:nnF \g_@@_val_level_int
- {
- { 0 } { \@@_scan_dimen:NN #2 \c_false_bool }
- { 1 } { \bool_if:NT #2 { \msg_error: } } % ^^A todo: ??
- }
- {
- \int_compare:nNnF \g_@@_val_level_int = {#1}
- { \msg_error:nn { unravel } { incompatible-units } }
- \@@_break:w
- }
+ \int_compare:nNnF { \g_@@_val_level_int + #1 } = 3
+ { \msg_error:nn { unravel } { incompatible-units } }
}
}
+ { \@@_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_dimen:NN #2 \c_true_bool }
+ { \@@_scan_dimen:nN {#1} \c_true_bool }
\@@_scan_keyword:nT { mM iI nN uU sS }
- { \@@_scan_dimen:NN #2 \c_true_bool }
+ { \@@_scan_dimen:nN {#1} \c_true_bool }
\@@_break_point:
- \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
- \@@_prev_input_silent:V \l_@@_head_tl
+ \@@_prev_input_join_get:nN {#1} \l_@@_tmpa_tl
+ \@@_prev_input_silent:V \l_@@_tmpa_tl
}
% \end{macrocode}
% \end{macro}
@@ -3379,7 +3619,7 @@
% \end{macrocode}
% \end{macro}
%
-% ^^A todo: catch runaway expand/get_x_next.
+% ^^A todo: catch runaway expand/get_x_next. (get_next too, probably)
%
% \begin{macro}[aux]{\@@_scan_alt_rule:}
% \begin{macrocode}
@@ -3452,11 +3692,12 @@
{
\bool_if:NTF #1
{
- \@@_cs_case:NnF \l_@@_head_token
+ \int_case:nnTF \l_@@_head_cmd_int
{
- \tex_hrule:D { \@@_do_leaders_rule: }
- \tex_vrule:D { \@@_do_leaders_rule: }
+ { \@@_tex_use:n { hrule } } { }
+ { \@@_tex_use:n { vrule } } { }
}
+ { \@@_do_leaders_rule: }
{ \@@_do_box_error: }
}
{ \@@_do_box_error: }
@@ -3576,7 +3817,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_do_box_explicit:N #1
{
- \token_if_eq_meaning:NNTF \l_@@_head_token \tex_hbox:D
+ \token_if_eq_meaning:NNTF \l_@@_head_token \@@_hbox:w
{ \@@_box_hook:N \tex_everyhbox:D }
{ \@@_box_hook:N \tex_everyvbox:D }
% ^^A todo: TeX calls |normal_paragraph| here.
@@ -3617,7 +3858,7 @@
\@@_print_action:
\@@_back_input:o {##1}
\@@_set_action_text:x
- { \token_to_meaning:N #1 \tl_to_str:o {##1} }
+ { \token_to_meaning:N #1 = \tl_to_str:o {##1} }
\tl_if_empty:oF {##1} { \@@_print_action: }
}
}
@@ -3662,26 +3903,18 @@
%
% \begin{macro}[aux]{\@@_char:n, \@@_char:V, \@@_char:x}
% \begin{macrocode}
-\group_begin:
- \char_set_catcode_other:n { 0 }
- \cs_new_protected:Npn \@@_char:n #1
- {
- \tex_char:D #1 \scan_stop:
- \@@_charcode_if_safe:nTF {#1}
- {
- \group_begin:
- \char_set_lccode:nn { 0 } {#1}
- \tex_lowercase:D
- { \group_end: \tl_set:Nn \l_@@_tmpa_tl { ^^@ } }
- }
- {
- \tl_set:Nx \l_@@_tmpa_tl
- { \exp_not:N \char \int_eval:n {#1} ~ }
- }
- \gtl_gput_right:NV \g_@@_output_gtl \l_@@_tmpa_tl
- \@@_print_action:x { \tl_to_str:N \l_@@_tmpa_tl }
- }
-\group_end:
+\cs_new_protected:Npn \@@_char:n #1
+ {
+ \tex_char:D #1 \scan_stop:
+ \@@_charcode_if_safe:nTF {#1}
+ { \tl_set:Nx \l_@@_tmpa_tl { \char_generate:nn {#1} { 12 } } }
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ { \exp_not:N \char \int_eval:n {#1} ~ }
+ }
+ \gtl_gput_right:NV \g_@@_output_gtl \l_@@_tmpa_tl
+ \@@_print_action:x { \tl_to_str:N \l_@@_tmpa_tl }
+ }
\cs_generate_variant:Nn \@@_char:n { V , x }
% \end{macrocode}
% \end{macro}
@@ -3689,21 +3922,16 @@
% \begin{macro}[aux]
% {\@@_char_in_mmode:n, \@@_char_in_mmode:V, \@@_char_in_mmode:x}
% \begin{macrocode}
-\group_begin:
- \char_set_catcode_other:n { 0 }
- \cs_new_protected:Npn \@@_char_in_mmode:n #1
- {
- \int_compare:nNnTF { \tex_mathcode:D #1 } = { "8000 }
- { % math active
- \group_begin:
- \char_set_lccode:nn { 0 } { \l_@@_tmpa_tl }
- \tex_lowercase:D
- { \group_end: \gtl_set:Nn \l_@@_head_gtl { ^^@ } }
- \@@_back_input:
- }
- { \@@_char:n {#1} }
- }
-\group_end:
+\cs_new_protected:Npn \@@_char_in_mmode:n #1
+ {
+ \int_compare:nNnTF { \tex_mathcode:D #1 } = { "8000 }
+ { % math active
+ \gtl_set:Nx \l_@@_head_gtl
+ { \char_generate:nn {#1} { 12 } }
+ \@@_back_input:
+ }
+ { \@@_char:n {#1} }
+ }
\cs_generate_variant:Nn \@@_char_in_mmode:n { V , x }
% \end{macrocode}
% \end{macro}
@@ -3731,10 +3959,10 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_new_graf:N #1
{
- \tl_set:NV \l_@@_tmpa_tl \tex_everypar:D
- \tex_everypar:D { }
+ \tl_set:NV \l_@@_tmpa_tl \@@_everypar:w
+ \@@_everypar:w { }
\bool_if:NTF #1 { \tex_indent:D } { \tex_noindent:D }
- \exp_args:NV \tex_everypar:D \l_@@_tmpa_tl
+ \exp_args:NV \@@_everypar:w \l_@@_tmpa_tl
\@@_back_input:V \l_@@_tmpa_tl
\@@_print_action:x
{
@@ -3778,7 +4006,6 @@
% ^^A todo: implement \@@_end_align_group:
% ^^A todo: implement \@@_end_no_align_group: (start = \@@_end_graf:)
% ^^A todo: implement \@@_end_output_group:
-% ^^A todo: implement \@@_end_math_group:
% ^^A todo: implement \@@_end_disc_group:
% ^^A todo: implement \@@_end_math_choice_group:
%
@@ -3788,7 +4015,7 @@
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_handle_left_brace:
{
- \int_case:nnF \etex_currentgrouptype:D
+ \int_case:nnF \@@_currentgrouptype:
{
{ 1 } { \@@_end_simple_group: } % simple
{ 2 } { \@@_end_box_group: } % hbox
@@ -3798,7 +4025,7 @@
{ 6 } { \@@_end_align_group: } % align
{ 7 } { \@@_end_no_align_group: } % no_align
{ 8 } { \@@_end_output_group: } % output
- { 9 } { \@@_end_math_group: } % math
+ { 9 } { \@@_end_simple_group: } % math
{ 10 } { \@@_end_disc_group: } % disc
{ 11 } { \@@_end_graf: \@@_end_simple_group: } % insert
{ 12 } { \@@_end_graf: \@@_end_simple_group: } % vcenter
@@ -3860,14 +4087,14 @@
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_off_save:
{
- \int_compare:nNnTF \etex_currentgrouptype:D = { 0 }
+ \int_compare:nNnTF \@@_currentgrouptype: = { 0 }
{ % bottom-level
\msg_error:nnx { unravel } { extra-close }
{ \token_to_meaning:N \l_@@_head_token }
}
{
\@@_back_input:
- \int_case:nnF \etex_currentgrouptype:D
+ \int_case:nnF \@@_currentgrouptype:
{
{ 14 } % semi_simple_group
{ \gtl_set:Nn \l_@@_head_gtl { \group_end: } }
@@ -3887,9 +4114,6 @@
%
% \subsection{Modes}
% ^^A todo: implement \aftergroup and things happening at end-group
-% ^^A todo: implement \@@_after_math:
-% ^^A todo: implement \@@_goto_inner_math:
-% ^^A todo: implement \@@_goto_display_math:
% ^^A todo: implement \@@_scan_math:
%
% \begin{macro}[int]
@@ -3937,6 +4161,56 @@
% \end{macrocode}
% \end{macro}
%
+% ^^A todo: should push_math be provided?
+% \begin{macro}[aux]{\@@_goto_inner_math:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_goto_inner_math:
+ {
+ \@@_box_hook:N \tex_everymath:D
+ $ % $
+ \@@_box_hook_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_goto_display_math:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_goto_display_math:
+ {
+ \@@_box_hook:N \tex_everydisplay:D
+ $ $
+ \@@_box_hook_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_after_math:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_after_math:
+ {
+ \mode_if_inner:TF
+ {
+ \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl
+ $ % $
+ }
+ {
+ \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl
+ \@@_get_x_next:
+ \token_if_eq_catcode:NNF
+ \l_@@_head_token \c_math_toggle_token
+ {
+ \@@_back_input:
+ \tl_set:Nn \l_@@_head_tl { $ } % $
+ \msg_error:nn { unravel } { missing-dollar }
+ }
+ \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl
+ $ $
+ }
+ \@@_print_action:
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{One step}
%
% \begin{macro}[int]{\@@_do_step:}
@@ -3946,7 +4220,7 @@
\cs_new_protected_nopar:Npn \@@_do_step:
{
\@@_set_action_text:
- \bool_if:NT \l_@@_debug_bool
+ \bool_if:NT \g_@@_internal_debug_bool
{ \iow_term:x { Cmd:~\int_use:N \l_@@_head_cmd_int } }
\cs_if_exist_use:cF
{ @@_cmd_ \int_use:N \l_@@_head_cmd_int : }
@@ -3968,7 +4242,7 @@
% \item |relax=0| for \tn{relax}.
% \item |begin-group_char=1| for begin-group characters (catcode~$1$).
% \item |end-group_char=2| for end-group characters (catcode~$2$).
-% \item |math_char=3| for math shift (math toggle in \texttt{expl3})
+% \item |math_char=3| for math shift (math toggle in \pkg{expl3})
% characters (catcode~$3$).
% \item |tab_mark=4| for \tn{span}
% \item |alignment_char=4| for alignment tab characters (catcode~$4$).
@@ -4019,18 +4293,23 @@
\mode_if_math:TF
{
\int_compare:nNnTF
- \etex_currentgrouplevel:D = { 15 } % math_shift_group
+ \@@_currentgrouptype: = { 15 } % math_shift_group
{ \@@_after_math: }
{ \@@_off_save: }
}
{
+ \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl
\@@_get_next:
\token_if_eq_catcode:NNTF
\l_@@_head_token \c_math_toggle_token
{
\mode_if_inner:TF
{ \@@_back_input: \@@_goto_inner_math: }
- { \@@_goto_display_math: }
+ {
+ \gtl_gput_right:NV
+ \g_@@_output_gtl \l_@@_head_tl
+ \@@_goto_display_math:
+ }
}
{ \@@_back_input: \@@_goto_inner_math: }
}
@@ -4050,6 +4329,8 @@
{ \l_@@_head_token \@@_print_action: }
% \end{macrocode}
%
+% ^^A todo: wrong: needs to collect subsup before output (otherwise b{}^2{}_3)
+% ^^A todo: wrong: mathcode "8000 is not recognized.
% \begin{macrocode}
\@@_new_tex_cmd:nn { superscript_char } % 7
{ \@@_mode_math:n { \@@_sub_sup: } }
@@ -4059,10 +4340,45 @@
{
\seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
\@@_print_action:
- \@@_scan_math:
- \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
- \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl
- \tl_use:N \l_@@_head_tl \scan_stop:
+ \@@_get_x_non_relax:
+ \@@_set_cmd:
+ \int_case:nnTF \l_@@_head_cmd_int
+ {
+ { \@@_tex_use:n { the_char } }
+ { \@@_prev_input:V \l_@@_head_tl }
+ { \@@_tex_use:n { other_char } }
+ { \@@_prev_input:V \l_@@_head_tl }
+ { \@@_tex_use:n { char_given } }
+ { \@@_prev_input:V \l_@@_head_tl }
+ { \@@_tex_use:n { char_num } }
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_int:
+ }
+ { \@@_tex_use:n { math_char_num } }
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_int:
+ }
+ { \@@_tex_use:n { math_given } }
+ { \@@_prev_input:V \l_@@_head_tl }
+ { \@@_tex_use:n { delim_num } }
+ { \@@_prev_input:V \l_@@_head_tl \@@_scan_int: }
+ }
+ {
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl
+ \tl_use:N \l_@@_head_tl \scan_stop:
+ }
+ {
+ \@@_back_input:
+ \@@_scan_left_brace:
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl
+ \gtl_gconcat:NNN \g_@@_output_gtl
+ \g_@@_output_gtl \c_group_begin_gtl
+ \tl_use:N \l_@@_head_tl \c_group_begin_token
+ }
\@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
}
% \end{macrocode}
@@ -4135,7 +4451,7 @@
\@@_back_input:
\@@_back_input:n
{
- \tex_hbox:D to \tex_hsize:D { }
+ \@@_hbox:w to \tex_hsize:D { }
\tex_vfill:D
\tex_penalty:D - '10000000000 ~
}
@@ -4431,8 +4747,8 @@
\seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
\@@_print_action:
\token_if_eq_meaning:NNTF \l_@@_head_token \tex_kern:D
- { \@@_scan_dimen:NN \c_true_bool \c_false_bool }
- { \@@_scan_dimen:NN \c_false_bool \c_false_bool }
+ { \@@_scan_dimen:nN { 2 } \c_false_bool }
+ { \@@_scan_dimen:nN { 3 } \c_false_bool }
\seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
\tl_use:N \l_@@_head_tl \scan_stop:
\@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
@@ -4579,7 +4895,7 @@
{
\int_compare:nNnT \l_@@_head_char_int = { 1 } % indent
{
- \tex_hbox:D width \tex_parindent:D { }
+ \@@_hbox:w width \tex_parindent:D { }
\gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl
}
\@@_print_action:
@@ -5267,7 +5583,6 @@
%
% \subsubsection{Assignments}
%
-% ^^A todo: introduce \@@_tmp:w
% Quoting \texttt{tex.web}: ``Every prefix, and every command code that
% might or might not be prefixed, calls the action procedure
% |prefixed_command|. This routine accumulates a sequence of prefixes
@@ -5351,7 +5666,6 @@
% \end{macro}
%
% \begin{macro}[int]{\@@_assign_token:n}
-% ^^A todo: wrong printed value for \count123=123\count\count123=987.
% \begin{macrocode}
\cs_new_protected:Npn \@@_assign_token:n #1
{
@@ -5364,7 +5678,6 @@
% \end{macro}
%
% \begin{macro}[int]{\@@_assign_register:}
-% ^^A todo: wrong printed value for \count123=123\count\count123=987.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_assign_register:
{
@@ -5460,7 +5773,7 @@
{ \@@_scan_font_int: } { \@@_scan_int: }
}
\@@_prefixed_new:nn { set_aux } % 79
- { % prevdepth = 1, spacefactor = 0
+ { % prevdepth = 1, spacefactor = 102
\int_compare:nNnTF \l_@@_head_char_int = \c_one
{ \@@_assign_value:nn { } { \@@_scan_normal_dimen: } }
{ \@@_assign_value:nn { } { \@@_scan_int: } }
@@ -5669,33 +5982,46 @@
}
% \end{macrocode}
%
-% ^^A todo: the implementation of |set_interaction| looks fishy
% \begin{macrocode}
\@@_prefixed_new:nn { set_interaction } % 100
{
\seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
- \tl_put_right:NV \l_@@_head_tl \l_@@_tmpa_tl
+ \tl_put_left:NV \l_@@_head_tl \l_@@_tmpa_tl
\tl_use:N \l_@@_head_tl \scan_stop:
\@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
}
% \end{macrocode}
%
+% ^^A todo: print the temporary nullfont assignment?
% \begin{macrocode}
\@@_prefixed_new:nn { letterspace_font } % 101
{
- % ^^A todo...
- % new_letterspaced_font(a);
- \msg_error:nnx { unravel } { not-implemented } { letterspace-font }
- \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
- \@@_omit_after_assignment:w
+ \@@_prev_input_silent:V \l_@@_head_tl
+ \@@_set_action_text:x { \tl_to_str:N \l_@@_head_tl }
+ \@@_scan_r_token:
+ \@@_print_action:x
+ { \g_@@_action_text_str \tl_to_str:N \l_@@_defined_tl }
+ \exp_after:wN \cs_set_eq:NN \l_@@_defined_tl \@@_nullfont:
+ \@@_scan_optional_equals:
+ \@@_scan_font_ident:
+ \@@_scan_int:
+ \@@_assign_token:n { }
}
+% \end{macrocode}
+%
+% ^^A todo: print the temporary nullfont assignment?
+% \begin{macrocode}
\@@_prefixed_new:nn { pdf_copy_font } % 102
{
- % ^^A todo...
- % make_font_copy(a);
- \msg_error:nnx { unravel } { not-implemented } { pdf-copy-font }
- \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
- \@@_omit_after_assignment:w
+ \@@_prev_input_silent:V \l_@@_head_tl
+ \@@_set_action_text:x { \tl_to_str:N \l_@@_head_tl }
+ \@@_scan_r_token:
+ \@@_print_action:x
+ { \g_@@_action_text_str \tl_to_str:N \l_@@_defined_tl }
+ \exp_after:wN \cs_set_eq:NN \l_@@_defined_tl \@@_nullfont:
+ \@@_scan_optional_equals:
+ \@@_scan_font_ident:
+ \@@_assign_token:n { }
}
% \end{macrocode}
%
@@ -5952,15 +6278,13 @@
% \end{macrocode}
% \end{macro}
%
-% ^^A todo: document that this often fails.
-% ^^A todo: better \endinput? Document current behaviour (ignored).
-% \begin{macro}[aux]{\@@_scantokens:, \@@_input:}
+% \begin{macro}[aux]{\@@_endinput:, \@@_scantokens:, \@@_input:}
% \begin{macrocode}
\@@_new_tex_expandable:nn { input } % 106
{
\int_case:nnF \l_@@_head_char_int
{
- { 1 } { \@@_print_action: } % \endinput
+ { 1 } { \@@_endinput: } % \endinput
{ 2 } { \@@_scantokens: } % \scantokens
}
{ % 0=\input
@@ -5968,6 +6292,11 @@
{ \@@_insert_relax: } { \@@_input: }
}
}
+\cs_new_protected_nopar:Npn \@@_endinput:
+ {
+ \msg_warning:nn { unravel } { endinput-ignored }
+ \@@_print_action:
+ }
\cs_new_protected_nopar:Npn \@@_scantokens:
{
\seq_gput_right:Nn \g_@@_prev_input_seq { }
@@ -5990,7 +6319,6 @@
% \end{macrocode}
% \end{macro}
%
-% ^^A todo: this wrongly accepts things let to characters.
% \begin{macro}[aux]{\@@_csname_loop:}
% \begin{macrocode}
\@@_new_tex_expandable:nn { cs_name } % 109
@@ -6215,7 +6543,7 @@
\fi:
\int_incr:N \l_@@_if_nesting_int
\fi:
- \@@_input_gpop:N \l_@@_tmpa_gtl
+ \@@_input_gpop:N \l_@@_unused_gtl
\int_compare:nNnTF \l_@@_if_nesting_int = \c_zero
{ \@@_pass_text: }
{ \@@_pass_text_nested: }
@@ -6463,7 +6791,7 @@
{
\seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
\@@_print_action:
- \bool_if:NT \l_@@_debug_bool { \iow_term:n { {\ifcase level~#1} } }
+ \bool_if:NT \g_@@_internal_debug_bool { \iow_term:n { {\ifcase level~#1} } }
\@@_scan_int:
\seq_get_right:NN \g_@@_prev_input_seq \l_@@_head_tl
\tl_set:Nx \l_@@_head_tl { \tl_tail:N \l_@@_head_tl }
@@ -6602,7 +6930,7 @@
\cs_new_protected:Npn \@@_set_action_text:x #1
{
\group_begin:
- \int_set:Nn \tex_escapechar:D { 92 }
+ \@@_set_escapechar:n { 92 }
\str_gset:Nx \g_@@_action_text_str {#1}
\group_end:
}
@@ -6628,7 +6956,8 @@
\cs_new_protected:Npn \@@_print_state:
{
\group_begin:
- \int_set:Nn \tex_escapechar:D { 92 }
+ \@@_set_escapechar:n { 92 }
+ \tl_use:N \g_@@_before_print_state_tl
\int_compare:nNnT \g_@@_noise_int > \c_zero
{
\exp_args:Nx \@@_print_state_output:n
@@ -6647,83 +6976,39 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[int]{\@@_print_state_output:n}
+% \begin{macro}[aux]{\@@_print_state_output:n}
+% Unless empty, print |#1| with each line starting with \verb*+<|~+.
+% The \cs{@@_str_truncate_left:nn} function trims |#1| if needed, to
+% fit in a maximum of \cs{g_@@_max_output_int} characters.
% \begin{macrocode}
\cs_new_protected:Npn \@@_print_state_output:n #1
{
\tl_if_empty:nF {#1}
{
- \int_set:Nn \l_@@_print_int { \str_count:n {#1} }
\@@_print_message:nn { <| ~ }
- {
- \int_compare:nNnTF
- \l_@@_print_int > \g_@@_max_output_int
- {
- (
- \int_eval:n
- {
- \l_@@_print_int
- - \g_@@_max_output_int + 14
- } ~
- chars
- )~
- ...
- \str_substr:nnn {#1}
- { \l_@@_print_int - \g_@@_max_output_int + 15 }
- { \l_@@_print_int }
- }
- {#1}
- }
+ { \@@_str_truncate_left:nn {#1} { \g_@@_max_output_int } }
}
}
% \end{macrocode}
% \end{macro}
%
-% ^^A todo: use \cs{g_@@_max_prev_int}
% \begin{macro}[aux]{\@@_print_state_prev:n}
+% Never trim~|#1|.
% \begin{macrocode}
\cs_new_protected:Npn \@@_print_state_prev:n #1
- {
- % \int_set:Nn \l_@@_print_int { \str_count:n {#1} }
- \@@_print_message:nn { || ~ } {#1}
- % {
- % \int_compare:nNnTF \l_@@_print_int > \g_@@_max_prev_int
- % {
- % (
- % \int_eval:n
- % { \l_@@_print_int - \g_@@_max_prev_int + 14 } ~
- % chars
- % )~
- % ...
- % \str_substr:nnn {#1}
- % { \l_@@_print_int - \g_@@_max_prev_int + 15 }
- % { \l_@@_print_int }
- % }
- % {#1}
- % }
- }
+ { \@@_print_message:nn { || ~ } {#1} }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[aux]{\@@_print_state_input:n}
+% Print |#1| with each line starting with \verb*+|>~+. The
+% \cs{@@_str_truncate_right:nn} function trims |#1| if needed, to fit
+% in a maximum of \cs{g_@@_max_input_int} characters.
% \begin{macrocode}
\cs_new_protected:Npn \@@_print_state_input:n #1
{
- \int_set:Nn \l_@@_print_int { \str_count:n {#1} }
\@@_print_message:nn { |> ~ }
- {
- \int_compare:nNnTF \l_@@_print_int > \g_@@_max_input_int
- {
- \str_substr:nnn {#1} { 1 } { \g_@@_max_input_int - 14 }
- ...~
- (
- \int_eval:n
- { \l_@@_print_int - \g_@@_max_input_int + 14 } ~
- chars
- )
- }
- {#1}
- }
+ { \@@_str_truncate_right:nn {#1} { \g_@@_max_input_int } }
}
% \end{macrocode}
% \end{macro}
@@ -6751,21 +7036,20 @@
\cs_new_protected:Npn \@@_print_action:
{
\int_gincr:N \g_@@_step_int
- \@@_print_message:nn { }
+ \@@_print:x
{
- % \\
- [=====~ Step~ \int_use:N \g_@@_step_int \ =====]~
+ [=====
+ \bool_if:NT \g_@@_number_steps_bool
+ { ~ Step ~ \int_use:N \g_@@_step_int \ }
+ =====]~
\int_compare:nNnTF
{ \str_count:N \g_@@_action_text_str }
> { \g_@@_max_action_int }
{
- \str_substr:Nnn \g_@@_action_text_str
+ \str_range:Nnn \g_@@_action_text_str
{ 1 } { \g_@@_max_action_int - 3 } ...
}
{ \g_@@_action_text_str }
- % \\
- % \ \ < \int_use:N \g_@@_input_int > % ^^A todo: remove
- % \ < \seq_count:N \g_@@_prev_input_seq > % ^^A todo: remove
}
\@@_print_state:
}
@@ -6812,7 +7096,7 @@
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 \tex_the:D \l_@@_defined_tl
+ = \exp_after:wN \@@_the:w \l_@@_defined_tl
}
\@@_omit_after_assignment:w
}
@@ -6820,21 +7104,25 @@
% \end{macro}
%
% \begin{macro}[int]{\@@_print_welcome:}
-% Welcoming message.
+% Welcome message.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_print_welcome:
{
\@@_print_message:nn { }
{
- \\
- ========~ Welcome~ to~ the~ unravel~ package~ ========\\
- \iow_indent:n
+ \bool_if:NTF \g_@@_welcome_message_bool
{
- "<|"~ denotes~ the~ output~ to~ TeX's~ stomach. \\
- "||"~ denotes~ tokens~ waiting~ to~ be~ used. \\
- "|>"~ denotes~ tokens~ that~ we~ will~ act~ on. \\
- Press~<enter>~to~continue;~'h'~<enter>~for~help. \\
+ \\
+ ========~ Welcome~ to~ the~ unravel~ package~ ========\\
+ \iow_indent:n
+ {
+ "<|"~ denotes~ the~ output~ to~ TeX's~ stomach. \\
+ "||"~ denotes~ tokens~ waiting~ to~ be~ used. \\
+ "|>"~ denotes~ tokens~ that~ we~ will~ act~ on. \\
+ Press~<enter>~to~continue;~'h'~<enter>~for~help. \\
+ }
}
+ { [=====~Start~=====] }
}
\@@_print_state:
}
@@ -6845,13 +7133,7 @@
% Final message.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_print_outcome:
- {
- % \int_gset_eq:NN \g_@@_max_input_int \c_max_int
- % \int_gset_eq:NN \g_@@_max_prev_int \c_max_int
- % \int_gset_eq:NN \g_@@_max_output_int \c_max_int
- % \@@_print_state:
- \@@_print_message:nn { } { [=====~The~end!~=====] \\ }
- }
+ { \@@_print:n { [=====~End~=====] } }
% \end{macrocode}
% \end{macro}
%
@@ -6865,18 +7147,23 @@
\int_compare:nNnF \g_@@_nonstop_int > \c_zero
{
\group_begin:
- \int_set_eq:NN \tex_escapechar:D \c_minus_one
+ \@@_set_escapechar:n { -1 }
\int_set_eq:NN \tex_endlinechar:D \c_minus_one
- \tl_use:N \g_@@_prompt_before_tl
- \tl_gclear:N \g_@@_prompt_before_tl
+ \tl_use:N \g_@@_before_prompt_tl
\@@_prompt_aux:
\group_end:
}
}
\cs_new_protected_nopar:Npn \@@_prompt_aux:
{
- \ior_get_str:Nc \g_@@_prompt_ior { Your~input }
- \exp_args:Nv \@@_prompt_treat:n { Your~input }
+ \int_compare:nNnT { \etex_interactionmode:D } = { 3 }
+ {
+ \bool_if:NTF \g_@@_explicit_prompt_bool
+ { \ior_get_str:Nc \c_@@_prompt_ior }
+ { \ior_get_str:Nc \c_@@_noprompt_ior }
+ { Your~input }
+ \exp_args:Nv \@@_prompt_treat:n { Your~input }
+ }
}
\cs_new_protected:Npn \@@_prompt_treat:n #1
{
@@ -6908,6 +7195,9 @@
{ \tl_gclear:N \g_@@_tmpc_tl }
\group_insert_after:N \g_@@_tmpc_tl
}
+ { | } { \@@_prompt_scan_int:nn {#1}
+ \@@_prompt_vert:n }
+ { a } { \@@_prompt_all: }
}
{ \@@_prompt_help: }
}
@@ -6915,7 +7205,9 @@
\cs_new_protected:Npn \@@_prompt_scan_int:nn #1
{
\tex_afterassignment:D \@@_prompt_scan_int_after:wn
- \l_@@_prompt_tmpa_int = 0 \use_none:n #1 \scan_stop:
+ \l_@@_prompt_tmpa_int =
+ \tl_if_head_eq_charcode:fNF { \use_none:n #1 } - { 0 }
+ \use_ii:nn #1 \scan_stop:
}
\cs_new_protected:Npn \@@_prompt_scan_int_after:wn #1 \scan_stop: #2
{
@@ -6925,87 +7217,222 @@
\cs_new_protected:Npn \@@_prompt_help:
{
\@@_print:n { "m":~meaning~of~first~token }
- \@@_print:n { "q":~semi-quiet }
- \@@_print:n { "x":~exit~this~instance~of~unravel }
- \@@_print:n { "X":~try~harder~to~exit }
+ \@@_print:n { "q":~semi-quiet~(same~as~"o1") }
+ \@@_print:n { "x"/"X":~exit~this~instance~of~unravel/TeX }
\@@_print:n { "s<num>":~do~<num>~steps~silently }
\@@_print:n
- { "o<num>":~0~=>~only~log~not~online,~1~=>~both,~-1~=>~neither.}
- \@@_print:n { "C<code>":~run~some~code~immediately }
+ { "o<num>":~1~=>~log~and~terminal,~0~=>~only~log,~-1~=>~neither.}
+ \@@_print:n { "C<code>":~run~some~expl3~code~immediately }
+ \@@_print:n { "|<num>":~silent~steps~until~<num>~fewer~"||" }
+ \@@_print:n { "a":~print~state~again,~without~truncating }
\@@_prompt_aux:
}
\cs_new_protected:Npn \@@_prompt_silent_steps:n #1
{
+ \int_compare:nNnF {#1} < \c_zero
+ {
+ \int_gset_eq:NN \g_@@_noise_int \c_minus_one
+ \tl_gset:Nn \g_@@_before_prompt_tl
+ {
+ \int_gset_eq:NN \g_@@_noise_int \c_one
+ \tl_gclear:N \g_@@_before_prompt_tl
+ }
+ \int_gset:Nn \g_@@_nonstop_int {#1}
+ }
+ }
+\cs_new_protected:Npn \@@_prompt_vert:n #1
+ {
+ \int_compare:nNnTF {#1} < { 0 }
+ { \@@_prompt_vert:Nn > {#1} }
+ { \@@_prompt_vert:Nn < {#1} }
+ }
+\cs_new_protected:Npn \@@_prompt_vert:Nn #1#2
+ {
\int_gset_eq:NN \g_@@_noise_int \c_minus_one
- \tl_gset:Nn \g_@@_prompt_before_tl
- { \int_gset_eq:NN \g_@@_noise_int \c_one }
- \int_gset:Nn \g_@@_nonstop_int {#1}
+ \tl_gset:Nf \g_@@_before_print_state_tl
+ {
+ \exp_args:NNf \exp_stop_f: \int_compare:nNnTF
+ { \int_eval:n { \seq_count:N \g_@@_prev_input_seq - #2 } }
+ #1 { \seq_count:N \g_@@_prev_input_seq }
+ {
+ \int_gset:Nn \g_@@_nonstop_int
+ { \int_max:nn { \g_@@_nonstop_int } { 2 } }
+ }
+ {
+ \int_gset_eq:NN \g_@@_noise_int \c_one
+ \tl_gclear:N \g_@@_before_print_state_tl
+ }
+ }
}
+\cs_new_protected_nopar:Npn \@@_prompt_all:
+ {
+ \tl_gset:Nx \g_@@_tmpc_tl
+ {
+ \exp_not:n
+ {
+ \tl_gclear:N \g_@@_tmpc_tl
+ \int_gset_eq:NN \g_@@_max_output_int \c_max_int
+ \int_gset_eq:NN \g_@@_max_input_int \c_max_int
+ \@@_print_state:
+ }
+ \@@_prompt_all_aux:N \g_@@_max_output_int
+ \@@_prompt_all_aux:N \g_@@_max_input_int
+ }
+ \group_insert_after:N \g_@@_tmpc_tl
+ }
+\cs_new:Npn \@@_prompt_all_aux:N #1
+ { \exp_not:n { \int_gset:Nn #1 } { \int_use:N #1 } }
% \end{macrocode}
% \end{macro}
%
+% ^^A todo: I suspect a bug if given 'a' twice in a row
+%
+% \subsection{Keys}
+%
+% Each key needs to be defined twice: for its default setting and for
+% its setting applying to a single \cs{unravel}. This is due to the
+% fact that we cannot use grouping to keep settings local to a single
+% \cs{unravel} since the \meta{code} argument of \cs{unravel} may open
+% or close groups.
+% \begin{macrocode}
+\keys_define:nn { unravel/defaults }
+ {
+ explicit-prompt .bool_gset:N = \g_@@_default_explicit_prompt_bool ,
+ internal-debug .bool_gset:N = \g_@@_default_internal_debug_bool ,
+ max-action .int_gset:N = \g_@@_default_max_action_int ,
+ max-output .int_gset:N = \g_@@_default_max_output_int ,
+ max-input .int_gset:N = \g_@@_default_max_input_int ,
+ number-steps .bool_gset:N = \g_@@_default_number_steps_bool ,
+ welcome-message .bool_gset:N = \g_@@_default_welcome_message_bool ,
+ }
+\keys_define:nn { unravel }
+ {
+ explicit-prompt .bool_gset:N = \g_@@_explicit_prompt_bool ,
+ internal-debug .bool_gset:N = \g_@@_internal_debug_bool ,
+ max-action .int_gset:N = \g_@@_max_action_int ,
+ max-output .int_gset:N = \g_@@_max_output_int ,
+ max-input .int_gset:N = \g_@@_max_input_int ,
+ number-steps .bool_gset:N = \g_@@_number_steps_bool ,
+ welcome-message .bool_gset:N = \g_@@_welcome_message_bool ,
+ }
+% \end{macrocode}
+%
+% The |machine| option is somewhat special so it is clearer to define
+% it separately. The code is identical for |unravel/defaults| and
+% |unravel| keys. To be sure of which options are set, use |.meta:nn|
+% and give the path explicitly.
+% \begin{macrocode}
+\tl_map_inline:nn { { /defaults } { } }
+ {
+ \keys_define:nn { unravel #1 }
+ {
+ machine .meta:nn =
+ { unravel #1 }
+ {
+ explicit-prompt = false ,
+ internal-debug = false ,
+ max-action = \c_max_int ,
+ max-output = \c_max_int ,
+ max-input = \c_max_int ,
+ number-steps = false ,
+ welcome-message = false ,
+ } ,
+ }
+ }
+% \end{macrocode}
+%
% \subsection{Main command}
%
% \begin{macro}{\unravel}
-% Simply call an underlying internal command.
+% Simply call an underlying code-level command.
+% \begin{macrocode}
+\NewDocumentCommand \unravel { O { } m } { \unravel:nn {#1} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\unravelsetup}
+% Simply call an underlying code-level command.
% \begin{macrocode}
-\cs_new_protected:Npn \unravel #1 { \@@_unravel:n {#1} }
+\NewDocumentCommand \unravelsetup { m } { \unravel_setup:n {#1} }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\UnravelDebug}
-% Turn on debugging mode.
+% \begin{macro}{\unravel_setup:n}
+% Set keys, updating both default values and current values.
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \UnravelDebug
+\cs_new_protected:Npn \unravel_setup:n #1
{
- \bool_set_true:N \l_@@_debug_bool
+ \keys_set:nn { unravel/defaults } {#1}
+ \keys_set:nn { unravel } {#1}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[int]{\@@_unravel:n}
-% Welcome the user, then initialize the input, output and step. Until
-% the input is exhausted, print the current status and do one step.
+% \begin{macro}[int]{\unravel:nn}
+% Initialize and setup keys. Initialize and setup other variables
+% including the input. Welcome the user. Then comes the main loop:
+% until the input is exhausted, print the current status and do one
+% step. The main loop is exited by skipping to the first
+% \cs{@@_exit_point:}, while some abort procedures jump to the second
+% (and last) one instead. If the main loop finished correctly, print
+% its outcome and finally test that everything is all right.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_unravel:n #1
+\cs_new_protected:Npn \unravel:nn #1#2
+ {
+ \@@_init_key_vars:
+ \keys_set:nn { unravel } {#1}
+ \@@_init_vars:
+ \@@_input_gset:n {#2}
+ \@@_print_welcome:
+ \@@_main_loop:
+ \@@_exit_point:
+ \@@_print_outcome:
+ \@@_final_test:
+ \@@_exit_point:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_init_key_vars:}
+% Give variables that are affected by keys their default values (also
+% controlled by keys).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_init_key_vars:
+ {
+ \bool_gset_eq:NN \g_@@_explicit_prompt_bool \g_@@_default_explicit_prompt_bool
+ \bool_gset_eq:NN \g_@@_internal_debug_bool \g_@@_default_internal_debug_bool
+ \bool_gset_eq:NN \g_@@_number_steps_bool \g_@@_default_number_steps_bool
+ \bool_gset_eq:NN \g_@@_welcome_message_bool \g_@@_default_welcome_message_bool
+ \int_gset_eq:NN \g_@@_max_action_int \g_@@_default_max_action_int
+ \int_gset_eq:NN \g_@@_max_output_int \g_@@_default_max_output_int
+ \int_gset_eq:NN \g_@@_max_input_int \g_@@_default_max_input_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_init_vars:}
+% Give initial values to variables used during the processing. These
+% have no reason to be modified by the user: neither directly nor
+% through keys.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_init_vars:
{
- \int_gzero:N \g_@@_step_int
- \@@_input_gset:n {#1}
\seq_gclear:N \g_@@_prev_input_seq
\gtl_gclear:N \g_@@_output_gtl
+ \int_gzero:N \g_@@_step_int
\tl_gclear:N \g_@@_if_limit_tl
\int_gzero:N \g_@@_if_limit_int
\int_gzero:N \g_@@_if_depth_int
\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
- \cs_gset_eq:NN \g_@@_prompt_ior \c_minus_one % ^^A todo:?
- \@@_print_welcome:
- \@@_main_loop:
- \@@_exit_point:
- \@@_print_outcome:
- \bool_if:nTF
- {
- \tl_if_empty_p:N \g_@@_if_limit_tl
- && \int_compare_p:nNn \g_@@_if_limit_int = \c_zero
- && \int_compare_p:nNn \g_@@_if_depth_int = \c_zero
- && \seq_if_empty_p:N \g_@@_prev_input_seq
- }
- { \@@_input_if_empty:TF { } { \@@_bad_finish: } }
- { \@@_bad_finish: }
- \@@_exit_point:
- }
-\cs_new_protected_nopar:Npn \@@_bad_finish:
- {
- \msg_error:nnx { unravel } { internal }
- { the-last-unravel-finished-badly }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\@@_main_loop:}
-% Loop forever, getting a token and performing the corresponding
-% command.
+% Loop forever, getting the next token (with expansion) and
+% performing the corresponding command.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_main_loop:
{
@@ -7017,6 +7444,31 @@
% \end{macrocode}
% \end{macro}
%
+% ^^A todo: improve error message
+% \begin{macro}[aux]{\@@_final_test:, \@@_final_bad:}
+% Make sure that the \cs{unravel} finished correctly. The error
+% message is a bit primitive.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_final_test:
+ {
+ \bool_if:nTF
+ {
+ \tl_if_empty_p:N \g_@@_if_limit_tl
+ && \int_compare_p:nNn \g_@@_if_limit_int = \c_zero
+ && \int_compare_p:nNn \g_@@_if_depth_int = \c_zero
+ && \seq_if_empty_p:N \g_@@_prev_input_seq
+ }
+ { \@@_input_if_empty:TF { } { \@@_final_bad: } }
+ { \@@_final_bad: }
+ }
+\cs_new_protected_nopar:Npn \@@_final_bad:
+ {
+ \msg_error:nnx { unravel } { internal }
+ { the-last-unravel-finished-badly }
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{Messages}
%
% \begin{macrocode}
@@ -7077,14 +7529,21 @@
{ Missing~\iow_char:N\\endcsname~inserted. }
\msg_new:nnn { unravel } { runaway-if }
{ Runaway~\iow_char:N\\if... }
+\msg_new:nnn { unravel } { runaway-macro-parameter }
+ {
+ Runaway~macro~parameter~\# #2~after \\\\
+ \iow_indent:n {#1}
+ }
\msg_new:nnn { unravel } { extra-or }
{ Extra~\iow_char:N\\or. }
\msg_new:nnn { unravel } { missing-equals }
{ Missing~equals~for~\iow_char:N\\ifnum~or~\iow_char:N\\ifdim. }
\msg_new:nnn { unravel } { internal }
- { Internal~error:~'#1'.~\ Please report. }
+ { Internal~error:~'#1'.~\ Please~report. }
\msg_new:nnn { unravel } { not-implemented }
{ The~following~feature~is~not~implemented:~'#1'. }
+\msg_new:nnn { unravel } { endinput-ignored }
+ { The~primitive~\iow_char:N\\endinput~was~ignored. }
% \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 1665ce3acf4..630584380a7 100644
--- a/Master/texmf-dist/tex/latex/unravel/unravel.sty
+++ b/Master/texmf-dist/tex/latex/unravel/unravel.sty
@@ -11,7 +11,7 @@
%% Communicate any suggestions for changing this package
%% to Bruno Le Floch (blflatex@gmail.com).
%%
-%% File: unravel.dtx Copyright (C) 2013 Bruno Le Floch
+%% File: unravel.dtx Copyright (C) 2013, 2015 Bruno Le Floch
%%
%% It may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -21,80 +21,21 @@
%% http://www.latex-project.org/lppl.txt
%%
%% -----------------------------------------------------------------------
-\RequirePackage{expl3}[2013/07/01]
-\RequirePackage{l3str}[2013/04/24]
-\RequirePackage{gtl}[2013/07/28]
+\RequirePackage{expl3,xparse}[2015/09/11]
+\RequirePackage{gtl}[2015/09/21]
\ProvidesExplPackage
- {unravel} {2013/07/28} {0.0a} {Watching TeX digest tokens}
-\ior_new:N \g__unravel_prompt_ior
-\tl_new:N \g__unravel_prompt_before_tl
-\int_new:N \l__unravel_prompt_tmpa_int
-\int_new:N \g__unravel_nonstop_int
-\int_new:N \g__unravel_noise_int
-\int_gset_eq:NN \g__unravel_noise_int \c_one
-\bool_new:N \l__unravel_debug_bool
-\int_new:N \g__unravel_step_int
-\str_new:N \g__unravel_action_text_str
-\int_new:N \g__unravel_max_action_int
-\int_new:N \g__unravel_max_output_int
-\int_new:N \g__unravel_max_prev_int
-\int_new:N \g__unravel_max_input_int
-\int_gset:Nn \g__unravel_max_action_int { 50 }
-\int_gset:Nn \g__unravel_max_output_int { 300 }
-\int_gset:Nn \g__unravel_max_prev_int { 300 }
-\int_gset:Nn \g__unravel_max_input_int { 300 }
-\bool_new:N \g__unravel_speedup_macros_bool
-\bool_gset_true:N \g__unravel_speedup_macros_bool
-\int_new:N \l__unravel_print_int
-\int_new:N \g__unravel_input_int
-\int_new:N \g__unravel_input_tmpa_int
-\tl_new:N \l__unravel_input_tmpa_tl
-\seq_new:N \g__unravel_prev_input_seq
-\tl_new:N \l__unravel_prev_input_tl
-\gtl_new:N \l__unravel_prev_input_gtl
-\gtl_new:N \g__unravel_output_gtl
-\gtl_new:N \l__unravel_head_gtl
-\tl_new:N \l__unravel_head_tl
-\token_new:Nn \l__unravel_head_token { ? }
-\int_new:N \l__unravel_head_cmd_int
-\int_new:N \l__unravel_head_char_int
-\tl_new:N \l__unravel_head_meaning_tl
-\tl_new:N \l__unravel_tmpa_tl
-\gtl_new:N \l__unravel_tmpb_gtl
-\tl_new:N \g__unravel_tmpc_tl
-\seq_new:N \l__unravel_tmpa_seq
-\tl_new:N \l__unravel_defined_tl
-\tl_new:N \l__unravel_defining_tl
-\cs_new_eq:NN \__unravel_inaccessible:w ?
-\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
-\group_begin:
- \char_set_lccode:nn { `* } { `# }
- \tex_lowercase:D
- { \tl_const:Nn \c__unravel_parameters_tl { ^*1*2*3*4*5*6*7*8*9 } }
-\group_end:
-\int_new:N \g__unravel_val_level_int
-\tl_const:Nn \c__unravel_plus_tl { + }
-\tl_const:Nn \c__unravel_minus_tl { - }
-\tl_const:Nn \c__unravel_times_tl { * }
-\tl_const:Nn \c__unravel_over_tl { / }
-\tl_const:Nn \c__unravel_lq_tl { ` }
-\tl_const:Nn \c__unravel_rq_tl { ' }
-\tl_const:Nn \c__unravel_dq_tl { " }
-\tl_const:Nn \c__unravel_lp_tl { ( }
-\tl_const:Nn \c__unravel_rp_tl { ) }
-\tl_const:Nn \c__unravel_eq_tl { = }
-\tl_const:Nn \c__unravel_comma_tl { , }
-\tl_const:Nn \c__unravel_point_tl { . }
-\tl_new:N \g__unravel_if_limit_tl
-\int_new:N \g__unravel_if_limit_int
-\int_new:N \g__unravel_if_depth_int
-\int_new:N \l__unravel_if_nesting_int
-\seq_new:N \l__unravel_leaders_box_seq
-\int_new:N \g__unravel_ends_int
-\int_gset:Nn \g__unravel_ends_int { 3 }
-\gtl_const:Nx \c__unravel_frozen_relax_gtl { \if_int_compare:w 0 = 0 \fi: }
+ {unravel} {2015/09/22} {0.1} {Watching TeX digest tokens}
+\cs_if_exist:NF \str_range:nnn { \RequirePackage{l3str} }
+\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_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 }
@@ -121,21 +62,19 @@
\cs_generate_variant:Nn \gtl_gset:Nn { c }
\cs_generate_variant:Nn \gtl_gconcat:NNN { ccc , cNc }
\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
{
\group_begin:
- \etex_everyeof:D \exp_after:wN { \token_to_str:N @ @ #1 }
+ \__unravel_everyeof:w \exp_after:wN { \token_to_str:N @ @ #1 }
#2
\tl_gclear:N #1
- \str_if_eq_x:nnF
- { \token_to_meaning:N \tex_input:D }
- { \token_to_str:N \input }
- { \msg_unravel:nnx { unravel } { internal } { input-prim } }
\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 \etex_everyeof:D
+ \tl_gput_right:NV #1 \__unravel_everyeof:w
}
\cs_generate_variant:Nn \__unravel_tl_gset_input:Nnn { Nno }
\use:x
@@ -143,7 +82,6 @@
\cs_new_protected:Npn \exp_not:N \__unravel_tl_gset_input_aux:wN
##1 \token_to_str:N @ @ ##2
} { \tl_gset:No #2 {#1} }
-\cs_new_eq:NN \__unravel_cs_case:NnF \tl_case:NnF
\cs_new_nopar:Npn \__unravel_strip_escape:w
{
\tex_romannumeral:D
@@ -153,15 +91,6 @@
\cs_new:Npn \__unravel_strip_escape_aux:N #1 { \c_zero }
\cs_new:Npn \__unravel_strip_escape_aux:w #1#2
{ - \__int_value:w #1 \c_zero }
-\cs_new:Npn \__unravel_meaning_to_char:n #1
- { \__unravel_meaning_to_char_auxi:w #1 \q_mark ~ {} ~ \q_mark \q_stop }
-\cs_new:Npn \__unravel_meaning_to_char_auxi:w #1 ~ #2 ~ #3 \q_mark #4 \q_stop
- { \__unravel_meaning_to_char_auxii:w #3 ~ #3 ~ \q_stop }
-\cs_new:Npn \__unravel_meaning_to_char_auxii:w #1 ~ #2 ~ #3 \q_stop
- { \tl_if_empty:nTF {#2} { ~ } {#2} }
-\cs_generate_variant:Nn \__unravel_meaning_to_char:n { o }
-\cs_new:Npn \__unravel_token_to_char:N #1
- { \__unravel_meaning_to_char:o { \token_to_meaning:N #1 } }
\cs_new:Npn \__unravel_to_str:n #1
{
\tl_if_head_eq_meaning:nNTF {#1} \scan_stop:
@@ -177,28 +106,64 @@
#1 tl \q_mark \q_stop
}
\cs_new:Npn \__unravel_to_str_auxii:w ##1 #1 ##2 \q_mark ##3 \q_stop
- { \cs_if_exist_use:cF { ##2 _to_str:n } { \tl_to_str:n } }
+ { \cs_if_exist_use:cF { __unravel_ ##2 _to_str:n } { \tl_to_str:n } }
}
\exp_args:No \__unravel_tmp:w { \tl_to_str:n { s__ } }
-\cs_new_protected:Npn \__unravel_prev_input_silent:n #1
+\cs_new:Npn \__unravel_gtl_to_str:n #1 { \__gtl_to_str:w #1 }
+\cs_new:Npn \__unravel_str_truncate_left:nn #1#2
{
- \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_prev_input_tl
- \tl_put_right:Nn \l__unravel_prev_input_tl {#1}
- \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_prev_input_tl
+ \exp_args:Nf \__unravel_str_truncate_left_aux:nnn
+ { \str_count:n {#1} } {#1} {#2}
}
-\cs_generate_variant:Nn \__unravel_prev_input_silent:n { V , x }
-\cs_new_protected:Npn \__unravel_prev_input:n #1
+\cs_new:Npn \__unravel_str_truncate_left_aux:nnn #1#2#3
{
- \__unravel_prev_input_silent:n {#1}
- \__unravel_print_action:x { \tl_to_str:n {#1} }
+ \int_compare:nNnTF {#1} > {#3}
+ {
+ ( \int_eval:n { #1 - #3 + 25 } ~ more~chars ) ~
+ \str_range:nnn {#2} { #1 - #3 + 26 } {#1}
+ }
+ { \tl_to_str:n {#2} }
}
-\cs_generate_variant:Nn \__unravel_prev_input:n { V , x }
-\cs_new_protected:Npn \__unravel_prev_input_gtl:N #1
+\cs_new:Npn \__unravel_str_truncate_right:nn #1#2
{
- \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_prev_input_gtl
- \gtl_concat:NNN \l__unravel_prev_input_gtl \l__unravel_prev_input_gtl #1
- \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_prev_input_gtl
+ \exp_args:Nf \__unravel_str_truncate_right_aux:nnn
+ { \str_count:n {#1} } {#1} {#2}
+ }
+\cs_new:Npn \__unravel_str_truncate_right_aux:nnn #1#2#3
+ {
+ \int_compare:nNnTF {#1} > {#3}
+ {
+ \str_range:nnn {#2} { 1 } { #3 - 25 } ~
+ ( \int_eval:n { #1 - #3 + 25 } ~ more~chars )
+ }
+ { \tl_to_str:n {#2} }
+ }
+\cs_new_eq:NN \__unravel_exit_point: \prg_do_nothing:
+\cs_new:Npn \__unravel_exit:w #1 \__unravel_exit_point: { }
+\cs_new_eq:NN \__unravel_break_point: \prg_do_nothing:
+\cs_new:Npn \__unravel_break:w #1 \__unravel_break_point: { }
+\prg_new_conditional:Npnn \__unravel_cmd_if_internal: { TF }
+ {
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int < { \__unravel_tex_use:n { min_internal } }
+ { \prg_return_false: }
+ {
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int
+ > { \__unravel_tex_use:n { max_internal } }
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
}
+\cs_new:Npn \__unravel_meaning_to_char:n #1
+ { \__unravel_meaning_to_char_auxi:w #1 \q_mark ~ {} ~ \q_mark \q_stop }
+\cs_new:Npn \__unravel_meaning_to_char_auxi:w #1 ~ #2 ~ #3 \q_mark #4 \q_stop
+ { \__unravel_meaning_to_char_auxii:w #3 ~ #3 ~ \q_stop }
+\cs_new:Npn \__unravel_meaning_to_char_auxii:w #1 ~ #2 ~ #3 \q_stop
+ { \tl_if_empty:nTF {#2} { ~ } {#2} }
+\cs_generate_variant:Nn \__unravel_meaning_to_char:n { o }
+\cs_new:Npn \__unravel_token_to_char:N #1
+ { \__unravel_meaning_to_char:o { \token_to_meaning:N #1 } }
\prg_new_conditional:Npnn \__unravel_token_if_expandable:N #1
{ p , T , F , TF }
{
@@ -223,18 +188,16 @@
}
{ \prg_return_true: }
}
-\cs_new_eq:NN \__unravel_exit_point: \prg_do_nothing:
-\cs_new:Npn \__unravel_exit:w #1 \__unravel_exit_point: { }
-\cs_new_eq:NN \__unravel_break_point: \prg_do_nothing:
-\cs_new:Npn \__unravel_break:w #1 \__unravel_break_point: { }
\group_begin:
\char_set_catcode_active:n { `Z }
\prg_new_protected_conditional:Npnn \__unravel_token_if_definable:N #1
{ TF }
{
\group_begin:
- \int_set:Nn \tex_escapechar:D { 92 }
- \exp_args:No \tl_if_single:nTF { \token_to_str:N #1 }
+ \__unravel_set_escapechar:n { 92 }
+ \tl_set:Nx \l__unravel_tmpa_tl
+ { \exp_args:No \str_tail:n { \token_to_str:N #1 } }
+ \tl_if_empty:NTF \l__unravel_tmpa_tl
{
\exp_args:Nx \char_set_lccode:nn
{ ` \str_head:n {#1} } { `Z }
@@ -261,6 +224,123 @@
}
{ \prg_return_false: }
}
+\cs_new_protected:Npn \__unravel_prev_input_silent:n #1
+ {
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_prev_input_tl
+ \tl_put_right:Nn \l__unravel_prev_input_tl {#1}
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_prev_input_tl
+ }
+\cs_generate_variant:Nn \__unravel_prev_input_silent:n { V , x }
+\cs_new_protected:Npn \__unravel_prev_input:n #1
+ {
+ \__unravel_prev_input_silent:n {#1}
+ \__unravel_print_action:x { \tl_to_str:n {#1} }
+ }
+\cs_generate_variant:Nn \__unravel_prev_input:n { V , x }
+\cs_new_protected:Npn \__unravel_prev_input_gtl:N #1
+ {
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_prev_input_gtl
+ \gtl_concat:NNN \l__unravel_prev_input_gtl \l__unravel_prev_input_gtl #1
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_prev_input_gtl
+ }
+\cs_new_protected:Npn \__unravel_prev_input_join_get:nN #1
+ {
+ \int_case:nnF {#1}
+ {
+ { 2 } { \__unravel_join_get_aux:NNN \skip_eval:n \etex_glueexpr:D }
+ { 3 } { \__unravel_join_get_aux:NNN \muskip_eval:n \etex_muexpr:D }
+ }
+ {
+ \msg_error:nnn { unravel } { internal } { join-factor }
+ \__unravel_join_get_aux:NNN \use:n \prg_do_nothing:
+ }
+ }
+\cs_new_protected:Npn \__unravel_join_get_aux:NNN #1#2#3
+ {
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \tl_set:Nx #3 { #1 { \l__unravel_tmpa_tl #2 \l__unravel_head_tl } }
+ }
+\tl_new:N \g__unravel_before_print_state_tl
+\tl_new:N \g__unravel_before_prompt_tl
+\int_new:N \l__unravel_prompt_tmpa_int
+\int_new:N \g__unravel_nonstop_int
+\int_new:N \g__unravel_noise_int
+\int_gset_eq:NN \g__unravel_noise_int \c_one
+\bool_new:N \g__unravel_default_explicit_prompt_bool
+\bool_new:N \g__unravel_default_internal_debug_bool
+\bool_new:N \g__unravel_default_number_steps_bool
+\bool_gset_true:N \g__unravel_default_number_steps_bool
+\bool_new:N \g__unravel_default_welcome_message_bool
+\bool_gset_true:N \g__unravel_default_welcome_message_bool
+\bool_new:N \g__unravel_explicit_prompt_bool
+\bool_new:N \g__unravel_internal_debug_bool
+\bool_new:N \g__unravel_number_steps_bool
+\bool_new:N \g__unravel_welcome_message_bool
+\int_new:N \g__unravel_step_int
+\str_new:N \g__unravel_action_text_str
+\int_new:N \g__unravel_default_max_action_int
+\int_new:N \g__unravel_default_max_output_int
+\int_new:N \g__unravel_default_max_input_int
+\int_gset:Nn \g__unravel_default_max_action_int { 50 }
+\int_gset:Nn \g__unravel_default_max_output_int { 300 }
+\int_gset:Nn \g__unravel_default_max_input_int { 300 }
+\int_new:N \g__unravel_max_action_int
+\int_new:N \g__unravel_max_output_int
+\int_new:N \g__unravel_max_input_int
+\bool_new:N \g__unravel_speedup_macros_bool
+\bool_gset_true:N \g__unravel_speedup_macros_bool
+\int_new:N \l__unravel_print_int
+\int_new:N \g__unravel_input_int
+\int_new:N \g__unravel_input_tmpa_int
+\tl_new:N \l__unravel_input_tmpa_tl
+\seq_new:N \g__unravel_prev_input_seq
+\tl_new:N \l__unravel_prev_input_tl
+\gtl_new:N \l__unravel_prev_input_gtl
+\gtl_new:N \g__unravel_output_gtl
+\gtl_new:N \l__unravel_head_gtl
+\tl_new:N \l__unravel_head_tl
+\token_new:Nn \l__unravel_head_token { ? }
+\int_new:N \l__unravel_head_cmd_int
+\int_new:N \l__unravel_head_char_int
+\tl_new:N \l__unravel_head_meaning_tl
+\tl_new:N \l__unravel_tmpa_tl
+\gtl_new:N \l__unravel_unused_gtl
+\gtl_new:N \l__unravel_tmpb_gtl
+\tl_new:N \g__unravel_tmpc_tl
+\seq_new:N \l__unravel_tmpa_seq
+\tl_new:N \l__unravel_defined_tl
+\tl_new:N \l__unravel_defining_tl
+\cs_new_eq:NN \__unravel_inaccessible:w ?
+\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
+\group_begin:
+ \cs_set:Npx \__unravel_tmp:w #1 { \c_hash_str #1 }
+ \tl_const:Nx \c__unravel_parameters_tl
+ { ^ \tl_map_function:nN { 123456789 } \__unravel_tmp:w }
+\group_end:
+\int_new:N \g__unravel_val_level_int
+\tl_new:N \g__unravel_if_limit_tl
+\int_new:N \g__unravel_if_limit_int
+\int_new:N \g__unravel_if_depth_int
+\int_new:N \l__unravel_if_nesting_int
+\seq_new:N \l__unravel_leaders_box_seq
+\int_new:N \g__unravel_ends_int
+\int_gset:Nn \g__unravel_ends_int { 3 }
+\tl_const:Nn \c__unravel_plus_tl { + }
+\tl_const:Nn \c__unravel_minus_tl { - }
+\tl_const:Nn \c__unravel_times_tl { * }
+\tl_const:Nn \c__unravel_over_tl { / }
+\tl_const:Nn \c__unravel_lq_tl { ` }
+\tl_const:Nn \c__unravel_rq_tl { ' }
+\tl_const:Nn \c__unravel_dq_tl { " }
+\tl_const:Nn \c__unravel_lp_tl { ( }
+\tl_const:Nn \c__unravel_rp_tl { ) }
+\tl_const:Nn \c__unravel_eq_tl { = }
+\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: }
\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 } }
@@ -683,7 +763,7 @@
\__unravel_tex_primitive:nnn { lefthyphenmin } { assign_int } { 51 }
\__unravel_tex_primitive:nnn { righthyphenmin } { assign_int } { 52 }
\__unravel_tex_primitive:nnn { holdinginserts } { assign_int } { 53 }
-\__unravel_tex_primitive:nnn { errorcontegtlines } { assign_int } { 54 }
+\__unravel_tex_primitive:nnn { errorcontextlines } { assign_int } { 54 }
\__unravel_tex_primitive:nnn { pdfoutput } { assign_int } { 55 }
\__unravel_tex_primitive:nnn { pdfcompresslevel } { assign_int } { 56 }
\__unravel_tex_primitive:nnn { pdfdecimaldigits } { assign_int } { 57 }
@@ -1158,14 +1238,16 @@
\cs_new_protected:Npn \__unravel_input_split_auxiii:w
#1 \__unravel_input_split_end:
{
+ \gtl_gclear_new:c
+ { g__unravel_input_ \int_use:N \g__unravel_input_tmpa_int _gtl }
\gtl_gset:cn
{ g__unravel_input_ \int_use:N \g__unravel_input_tmpa_int _gtl } {#1}
\int_gdecr:N \g__unravel_input_tmpa_int
}
\cs_new_protected_nopar:Npn \__unravel_input_gset:n
{
- \int_gset_eq:NN \g__unravel_input_int \c_one
- \gtl_gset:cn { g__unravel_input_1_gtl }
+ \int_gzero:N \g__unravel_input_int
+ \__unravel_back_input:n
}
\cs_new_protected:Npn \__unravel_input_get:N #1
{
@@ -1262,6 +1344,7 @@
\cs_new_protected_nopar:Npn \__unravel_back_input:n
{
\int_gincr:N \g__unravel_input_int
+ \gtl_gclear_new:c { g__unravel_input_ \int_use:N \g__unravel_input_int _gtl }
\gtl_gset:cn { g__unravel_input_ \int_use:N \g__unravel_input_int _gtl }
}
\cs_generate_variant:Nn \__unravel_back_input:n { x , V , o }
@@ -1308,21 +1391,20 @@
\msg_error:nn { unravel } { missing-dollar }
\__unravel_print_action:
}
-\group_begin:
- \char_set_lccode:nn { `. } { `: }
- \tex_lowercase:D
- {
- \cs_new:Npn \__unravel_macro_split_do:NN #1
- {
- \exp_after:wN \__unravel_macro_split_do:wN
- \token_to_meaning:N #1 \q_mark { } . -> \q_mark \use_none:nnnn
- \q_stop
- }
- \cs_new:Npn \__unravel_macro_split_do:wN
- #1 . #2 -> #3 \q_mark #4 #5 \q_stop #6
- { #4 #6 {#1} {#2} {#3} }
- }
-\group_end:
+\use:x
+ {
+ \exp_not:n { \cs_new:Npn \__unravel_macro_split_do:NN #1 }
+ {
+ \exp_not:n { \exp_after:wN \__unravel_macro_split_do:wN }
+ \exp_not:n { \token_to_meaning:N #1 \q_mark { } }
+ \tl_to_str:n { : } \exp_not:n { -> \q_mark \use_none:nnnn }
+ \exp_not:N \q_stop
+ }
+ \exp_not:n { \cs_new:Npn \__unravel_macro_split_do:wN }
+ \exp_not:n {#1} \tl_to_str:n { : } \exp_not:n { #2 -> }
+ \exp_not:n { #3 \q_mark #4 #5 \q_stop #6 }
+ { \exp_not:n { #4 #6 {#1} {#2} {#3} } }
+ }
\cs_new:Npn \__unravel_macro_prefix:N #1
{ \__unravel_macro_split_do:NN #1 \use_i:nnn }
\cs_new:Npn \__unravel_macro_parameter:N #1
@@ -1349,22 +1431,28 @@
}
\cs_new_protected_nopar:Npn \__unravel_macro_call_quick:
{
- \exp_after:wN \__unravel_macro_call_quick_loop:NN \l__unravel_tmpa_tl
+ \exp_after:wN \__unravel_macro_call_quick_loop:NNN \l__unravel_tmpa_tl
{ ? \use_none_delimit_by_q_stop:w } \q_stop
}
-\cs_new_protected_nopar:Npn \__unravel_macro_call_quick_loop:NN #1#2
+\cs_new_protected:Npn \__unravel_macro_call_quick_loop:NNN #1#2#3
{
\use_none:n #2
\__unravel_input_gpop_item:NF \l__unravel_tmpa_tl
- { \msg_error:nn { unravel } { runaway-macro-parameter } }
+ { \__unravel_macro_call_quick_runaway:Nw #3 }
\tl_put_right:Nx \l__unravel_head_tl
{ { \exp_not:V \l__unravel_tmpa_tl } }
- \__unravel_macro_call_quick_loop:NN
+ \__unravel_macro_call_quick_loop:NNN
+ #3
+ }
+\cs_new_protected:Npn \__unravel_macro_call_quick_runaway:Nw #1#2 \q_stop
+ {
+ \msg_error:nnxx { unravel } { runaway-macro-parameter }
+ { \tl_to_str:N \l__unravel_head_tl } { \tl_to_str:n {#1} }
}
\cs_new_protected_nopar:Npn \__unravel_expand:
{
\__unravel_set_action_text:
- \bool_if:NT \l__unravel_debug_bool
+ \bool_if:NT \g__unravel_internal_debug_bool
{
\__unravel_set_cmd:
\iow_term:x { Exp:~\int_use:N \l__unravel_head_cmd_int }
@@ -1527,7 +1615,7 @@
}
{
\msg_error:nn { unravel } { missing-font-id }
- \__unravel_prev_input:n { \tex_nullfont:D }
+ \__unravel_prev_input:n { \__unravel_nullfont: }
\__unravel_back_error:
}
}
@@ -1573,7 +1661,7 @@
\__unravel_prev_input_silent:V \l__unravel_tmpa_tl
\__unravel_set_action_text:
\__unravel_set_action_text:x
- { \g__unravel_action_text_str = ~ \tl_to_str:N \l__unravel_tmpa_tl }
+ { \g__unravel_action_text_str \use:n { ~ => ~ } \tl_to_str:N \l__unravel_tmpa_tl }
\int_compare:nNnF {#3} > { 3 } { \__unravel_print_action: }
\int_gset:Nn \g__unravel_val_level_int {#1}
}
@@ -1592,7 +1680,7 @@
{ 76 } { 3 } % assign_mu_glue
{ 77 } { 1 \__unravel_scan_font_dimen: } % assign_font_dimen
{ 78 } { 0 \__unravel_scan_font_int: } % assign_font_int
- { 79 } { 0 } % set_aux
+ { 79 } { \__unravel_thing_set_aux: } % set_aux
{ 80 } { 0 } % set_prev_graf
{ 81 } { 1 } % set_page_dimen
{ 82 } { 0 } % set_page_int
@@ -1606,6 +1694,8 @@
}
{ 8 }
}
+\cs_new_nopar:Npn \__unravel_thing_set_aux:
+ { \int_compare:nNnTF \l__unravel_head_char_int = { 1 } { 1 } { 0 } }
\cs_new_nopar:Npn \__unravel_thing_last_item:
{
\int_compare:nNnTF \l__unravel_head_char_int < { 26 }
@@ -1669,7 +1759,7 @@
{ 2 } \skip_eval:n
{ 3 } \muskip_eval:n
}
- { \tex_the:D }
+ { \__unravel_the:w }
}
\cs_new_protected:Npn \__unravel_scan_expr:N #1
{ \__unravel_scan_expr_aux:NN #1 \c_false_bool }
@@ -1760,16 +1850,9 @@
{
\__unravel_scan_signs:
\__unravel_set_cmd:
- \int_compare:nNnTF
- \l__unravel_head_cmd_int < { \__unravel_tex_use:n { min_internal } }
+ \__unravel_cmd_if_internal:TF
+ { \__unravel_scan_something_internal:n { 0 } }
{ \__unravel_scan_int_char: }
- {
- \int_compare:nNnTF
- \l__unravel_head_cmd_int
- > { \__unravel_tex_use:n { max_internal } }
- { \__unravel_scan_int_char: }
- { \__unravel_scan_something_internal:n { 0 } }
- }
}
\cs_new_protected_nopar:Npn \__unravel_scan_int_char:
{
@@ -1825,50 +1908,43 @@
}
}
\cs_new_protected_nopar:Npn \__unravel_scan_normal_dimen:
- { \__unravel_scan_dimen:NN \c_false_bool \c_false_bool }
-\cs_new_protected:Npn \__unravel_scan_dimen:NN #1#2
+ { \__unravel_scan_dimen:nN { 2 } \c_false_bool }
+\cs_new_protected:Npn \__unravel_scan_dimen:nN #1#2
{
\__unravel_scan_signs:
\seq_gput_right:Nn \g__unravel_prev_input_seq { }
\__unravel_set_cmd:
- \int_compare:nNnTF
- \l__unravel_head_cmd_int < { \__unravel_tex_use:n { min_internal } }
- { \__unravel_scan_dimen_char:NN #1#2 }
+ \__unravel_cmd_if_internal:TF
{
- \int_compare:nNnTF
- \l__unravel_head_cmd_int
- > { \__unravel_tex_use:n { max_internal } }
- { \__unravel_scan_dimen_char:NN #1#2 }
+ \int_compare:nNnTF {#1} = { 3 }
{
- \bool_if:NTF #1
+ \__unravel_scan_something_internal:n { 3 }
+ \int_case:nnF \g__unravel_val_level_int
{
- \__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
- }
+ { 0 } { \__unravel_scan_dim_unit:nN {#1} #2 }
+ { 3 } { }
}
{
- \__unravel_scan_something_internal:n { 2 }
- \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 } }
- }
- { }
+ \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_dimen_char:nN {#1} #2 }
\seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
\__unravel_prev_input_silent:V \l__unravel_head_tl
}
-\cs_new_protected:Npn \__unravel_scan_dimen_char:NN #1#2
+\cs_new_protected:Npn \__unravel_scan_dimen_char:nN #1#2
{
\tl_if_eq:NNT \l__unravel_head_tl \c__unravel_comma_tl
{ \tl_set_eq:NN \l__unravel_head_tl \c__unravel_point_tl }
@@ -1896,9 +1972,9 @@
\__unravel_scan_int:
}
}
- \__unravel_scan_dim_unit:NN #1#2
+ \__unravel_scan_dim_unit:nN {#1} #2
}
-\cs_new_protected:Npn \__unravel_scan_dim_unit:NN #1#2
+\cs_new_protected:Npn \__unravel_scan_dim_unit:nN #1#2
{
\bool_if:NT #2
{
@@ -1910,35 +1986,16 @@
}
\__unravel_get_x_non_blank:
\__unravel_set_cmd:
- \int_compare:nNnTF
- \l__unravel_head_cmd_int < { \__unravel_tex_use:n { min_internal } }
- { \__unravel_back_input: }
+ \__unravel_cmd_if_internal:TF
{
- \int_compare:nNnTF
- \l__unravel_head_cmd_int
- > { \__unravel_tex_use:n { max_internal } }
- { \__unravel_back_input: }
- {
- \seq_gput_right:Nn \g__unravel_prev_input_seq { }
- \bool_if:NTF #1
- { \__unravel_scan_something_internal:n { 3 } }
- { \__unravel_scan_something_internal:n { 2 } }
- \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
- \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
- \tl_set:Nx \l__unravel_tmpa_tl
- {
- \bool_if:NTF #1 \muskip_eval:n \skip_eval:n
- {
- \l__unravel_tmpa_tl
- \bool_if:NTF #1 \etex_muexpr:D \etex_glueexpr:D
- \l__unravel_head_tl
- }
- }
- \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_tmpa_tl
- \__unravel_break:w
- }
+ \seq_gput_right:Nn \g__unravel_prev_input_seq { }
+ \__unravel_scan_something_internal:n {#1}
+ \__unravel_prev_input_join_get:nN {#1} \l__unravel_tmpa_tl
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \__unravel_break:w
}
- \bool_if:NT #1
+ { \__unravel_back_input: }
+ \int_compare:nNnT {#1} = { 3 }
{
\__unravel_scan_keyword:nT { mM uU } { \__unravel_break:w }
\msg_error:nn { unravel } { missing-mudim }
@@ -1985,47 +2042,34 @@
{ \__unravel_scan_glue:n { 3 } }
\cs_new_protected:Npn \__unravel_scan_glue:n #1
{
- \int_compare:nNnTF {#1} = { 2 }
- { \__unravel_scan_glue_aux:nN {#1} \c_false_bool }
- { \__unravel_scan_glue_aux:nN {#1} \c_true_bool }
- }
-\cs_new_protected:Npn \__unravel_scan_glue_aux:nN #1#2
- {
+ \seq_gput_right:Nn \g__unravel_prev_input_seq { }
\__unravel_scan_signs:
\seq_gput_right:Nn \g__unravel_prev_input_seq { }
\__unravel_set_cmd:
- \int_compare:nNnTF
- \l__unravel_head_cmd_int < { \__unravel_tex_use:n { min_internal } }
- { \__unravel_back_input: \__unravel_scan_dimen:NN #2 \c_false_bool }
+ \__unravel_cmd_if_internal:TF
{
- \int_compare:nNnTF
- \l__unravel_head_cmd_int
- > { \__unravel_tex_use:n { max_internal } }
+ \__unravel_scan_something_internal:n {#1}
+ \int_case:nnF \g__unravel_val_level_int
{
- \__unravel_back_input:
- \__unravel_scan_dimen:NN #2 \c_false_bool
+ { 0 } { \__unravel_scan_dimen:nN {#1} \c_false_bool }
+ {#1} { \__unravel_break:w }
}
{
- \__unravel_scan_something_internal:n {#1}
- \int_case:nnF \g__unravel_val_level_int
- {
- { 0 } { \__unravel_scan_dimen:NN #2 \c_false_bool }
- { 1 } { \bool_if:NT #2 { \msg_error: } } % ^^A todo: ??
- }
- {
- \int_compare:nNnF \g__unravel_val_level_int = {#1}
- { \msg_error:nn { unravel } { incompatible-units } }
- \__unravel_break:w
- }
+ \int_compare:nNnF { \g__unravel_val_level_int + #1 } = 3
+ { \msg_error:nn { unravel } { incompatible-units } }
}
}
+ { \__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_dimen:NN #2 \c_true_bool }
+ { \__unravel_scan_dimen:nN {#1} \c_true_bool }
\__unravel_scan_keyword:nT { mM iI nN uU sS }
- { \__unravel_scan_dimen:NN #2 \c_true_bool }
+ { \__unravel_scan_dimen:nN {#1} \c_true_bool }
\__unravel_break_point:
- \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
- \__unravel_prev_input_silent:V \l__unravel_head_tl
+ \__unravel_prev_input_join_get:nN {#1} \l__unravel_tmpa_tl
+ \__unravel_prev_input_silent:V \l__unravel_tmpa_tl
}
\cs_new_protected_nopar:Npn \__unravel_scan_file_name:
{
@@ -2235,11 +2279,12 @@
{
\bool_if:NTF #1
{
- \__unravel_cs_case:NnF \l__unravel_head_token
+ \int_case:nnTF \l__unravel_head_cmd_int
{
- \tex_hrule:D { \__unravel_do_leaders_rule: }
- \tex_vrule:D { \__unravel_do_leaders_rule: }
+ { \__unravel_tex_use:n { hrule } } { }
+ { \__unravel_tex_use:n { vrule } } { }
}
+ { \__unravel_do_leaders_rule: }
{ \__unravel_do_box_error: }
}
{ \__unravel_do_box_error: }
@@ -2304,7 +2349,7 @@
}
\cs_new_protected:Npn \__unravel_do_box_explicit:N #1
{
- \token_if_eq_meaning:NNTF \l__unravel_head_token \tex_hbox:D
+ \token_if_eq_meaning:NNTF \l__unravel_head_token \__unravel_hbox:w
{ \__unravel_box_hook:N \tex_everyhbox:D }
{ \__unravel_box_hook:N \tex_everyvbox:D }
% ^^A todo: TeX calls |normal_paragraph| here.
@@ -2339,7 +2384,7 @@
\__unravel_print_action:
\__unravel_back_input:o {##1}
\__unravel_set_action_text:x
- { \token_to_meaning:N #1 \tl_to_str:o {##1} }
+ { \token_to_meaning:N #1 = \tl_to_str:o {##1} }
\tl_if_empty:oF {##1} { \__unravel_print_action: }
}
}
@@ -2363,42 +2408,29 @@
{ \prg_return_true: }
{ \prg_return_false: }
}
-\group_begin:
- \char_set_catcode_other:n { 0 }
- \cs_new_protected:Npn \__unravel_char:n #1
- {
- \tex_char:D #1 \scan_stop:
- \__unravel_charcode_if_safe:nTF {#1}
- {
- \group_begin:
- \char_set_lccode:nn { 0 } {#1}
- \tex_lowercase:D
- { \group_end: \tl_set:Nn \l__unravel_tmpa_tl { ^^@ } }
- }
- {
- \tl_set:Nx \l__unravel_tmpa_tl
- { \exp_not:N \char \int_eval:n {#1} ~ }
- }
- \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_tmpa_tl
- \__unravel_print_action:x { \tl_to_str:N \l__unravel_tmpa_tl }
- }
-\group_end:
+\cs_new_protected:Npn \__unravel_char:n #1
+ {
+ \tex_char:D #1 \scan_stop:
+ \__unravel_charcode_if_safe:nTF {#1}
+ { \tl_set:Nx \l__unravel_tmpa_tl { \char_generate:nn {#1} { 12 } } }
+ {
+ \tl_set:Nx \l__unravel_tmpa_tl
+ { \exp_not:N \char \int_eval:n {#1} ~ }
+ }
+ \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_tmpa_tl
+ \__unravel_print_action:x { \tl_to_str:N \l__unravel_tmpa_tl }
+ }
\cs_generate_variant:Nn \__unravel_char:n { V , x }
-\group_begin:
- \char_set_catcode_other:n { 0 }
- \cs_new_protected:Npn \__unravel_char_in_mmode:n #1
- {
- \int_compare:nNnTF { \tex_mathcode:D #1 } = { "8000 }
- { % math active
- \group_begin:
- \char_set_lccode:nn { 0 } { \l__unravel_tmpa_tl }
- \tex_lowercase:D
- { \group_end: \gtl_set:Nn \l__unravel_head_gtl { ^^@ } }
- \__unravel_back_input:
- }
- { \__unravel_char:n {#1} }
- }
-\group_end:
+\cs_new_protected:Npn \__unravel_char_in_mmode:n #1
+ {
+ \int_compare:nNnTF { \tex_mathcode:D #1 } = { "8000 }
+ { % math active
+ \gtl_set:Nx \l__unravel_head_gtl
+ { \char_generate:nn {#1} { 12 } }
+ \__unravel_back_input:
+ }
+ { \__unravel_char:n {#1} }
+ }
\cs_generate_variant:Nn \__unravel_char_in_mmode:n { V , x }
\cs_new_protected:Npn \__unravel_mathchar:n #1
{
@@ -2411,10 +2443,10 @@
\cs_generate_variant:Nn \__unravel_mathchar:n { x }
\cs_new_protected:Npn \__unravel_new_graf:N #1
{
- \tl_set:NV \l__unravel_tmpa_tl \tex_everypar:D
- \tex_everypar:D { }
+ \tl_set:NV \l__unravel_tmpa_tl \__unravel_everypar:w
+ \__unravel_everypar:w { }
\bool_if:NTF #1 { \tex_indent:D } { \tex_noindent:D }
- \exp_args:NV \tex_everypar:D \l__unravel_tmpa_tl
+ \exp_args:NV \__unravel_everypar:w \l__unravel_tmpa_tl
\__unravel_back_input:V \l__unravel_tmpa_tl
\__unravel_print_action:x
{
@@ -2435,7 +2467,7 @@
}
\cs_new_protected_nopar:Npn \__unravel_handle_left_brace:
{
- \int_case:nnF \etex_currentgrouptype:D
+ \int_case:nnF \__unravel_currentgrouptype:
{
{ 1 } { \__unravel_end_simple_group: } % simple
{ 2 } { \__unravel_end_box_group: } % hbox
@@ -2445,7 +2477,7 @@
{ 6 } { \__unravel_end_align_group: } % align
{ 7 } { \__unravel_end_no_align_group: } % no_align
{ 8 } { \__unravel_end_output_group: } % output
- { 9 } { \__unravel_end_math_group: } % math
+ { 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
@@ -2487,14 +2519,14 @@
}
\cs_new_protected_nopar:Npn \__unravel_off_save:
{
- \int_compare:nNnTF \etex_currentgrouptype:D = { 0 }
+ \int_compare:nNnTF \__unravel_currentgrouptype: = { 0 }
{ % bottom-level
\msg_error:nnx { unravel } { extra-close }
{ \token_to_meaning:N \l__unravel_head_token }
}
{
\__unravel_back_input:
- \int_case:nnF \etex_currentgrouptype:D
+ \int_case:nnF \__unravel_currentgrouptype:
{
{ 14 } % semi_simple_group
{ \gtl_set:Nn \l__unravel_head_gtl { \group_end: } }
@@ -2542,10 +2574,44 @@
\__unravel_back_input:
}
}
+\cs_new_protected_nopar:Npn \__unravel_goto_inner_math:
+ {
+ \__unravel_box_hook:N \tex_everymath:D
+ $ % $
+ \__unravel_box_hook_end:
+ }
+\cs_new_protected_nopar:Npn \__unravel_goto_display_math:
+ {
+ \__unravel_box_hook:N \tex_everydisplay:D
+ $ $
+ \__unravel_box_hook_end:
+ }
+\cs_new_protected_nopar:Npn \__unravel_after_math:
+ {
+ \mode_if_inner:TF
+ {
+ \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl
+ $ % $
+ }
+ {
+ \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl
+ \__unravel_get_x_next:
+ \token_if_eq_catcode:NNF
+ \l__unravel_head_token \c_math_toggle_token
+ {
+ \__unravel_back_input:
+ \tl_set:Nn \l__unravel_head_tl { $ } % $
+ \msg_error:nn { unravel } { missing-dollar }
+ }
+ \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl
+ $ $
+ }
+ \__unravel_print_action:
+ }
\cs_new_protected_nopar:Npn \__unravel_do_step:
{
\__unravel_set_action_text:
- \bool_if:NT \l__unravel_debug_bool
+ \bool_if:NT \g__unravel_internal_debug_bool
{ \iow_term:x { Cmd:~\int_use:N \l__unravel_head_cmd_int } }
\cs_if_exist_use:cF
{ __unravel_cmd_ \int_use:N \l__unravel_head_cmd_int : }
@@ -2569,18 +2635,23 @@
\mode_if_math:TF
{
\int_compare:nNnTF
- \etex_currentgrouplevel:D = { 15 } % math_shift_group
+ \__unravel_currentgrouptype: = { 15 } % math_shift_group
{ \__unravel_after_math: }
{ \__unravel_off_save: }
}
{
+ \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl
\__unravel_get_next:
\token_if_eq_catcode:NNTF
\l__unravel_head_token \c_math_toggle_token
{
\mode_if_inner:TF
{ \__unravel_back_input: \__unravel_goto_inner_math: }
- { \__unravel_goto_display_math: }
+ {
+ \gtl_gput_right:NV
+ \g__unravel_output_gtl \l__unravel_head_tl
+ \__unravel_goto_display_math:
+ }
}
{ \__unravel_back_input: \__unravel_goto_inner_math: }
}
@@ -2600,10 +2671,45 @@
{
\seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
\__unravel_print_action:
- \__unravel_scan_math:
- \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
- \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl
- \tl_use:N \l__unravel_head_tl \scan_stop:
+ \__unravel_get_x_non_relax:
+ \__unravel_set_cmd:
+ \int_case:nnTF \l__unravel_head_cmd_int
+ {
+ { \__unravel_tex_use:n { the_char } }
+ { \__unravel_prev_input:V \l__unravel_head_tl }
+ { \__unravel_tex_use:n { other_char } }
+ { \__unravel_prev_input:V \l__unravel_head_tl }
+ { \__unravel_tex_use:n { char_given } }
+ { \__unravel_prev_input:V \l__unravel_head_tl }
+ { \__unravel_tex_use:n { char_num } }
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_int:
+ }
+ { \__unravel_tex_use:n { math_char_num } }
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_int:
+ }
+ { \__unravel_tex_use:n { math_given } }
+ { \__unravel_prev_input:V \l__unravel_head_tl }
+ { \__unravel_tex_use:n { delim_num } }
+ { \__unravel_prev_input:V \l__unravel_head_tl \__unravel_scan_int: }
+ }
+ {
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl
+ \tl_use:N \l__unravel_head_tl \scan_stop:
+ }
+ {
+ \__unravel_back_input:
+ \__unravel_scan_left_brace:
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl
+ \gtl_gconcat:NNN \g__unravel_output_gtl
+ \g__unravel_output_gtl \c_group_begin_gtl
+ \tl_use:N \l__unravel_head_tl \c_group_begin_token
+ }
\__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl }
}
\__unravel_new_tex_cmd:nn { endv } % 9
@@ -2657,7 +2763,7 @@
\__unravel_back_input:
\__unravel_back_input:n
{
- \tex_hbox:D to \tex_hsize:D { }
+ \__unravel_hbox:w to \tex_hsize:D { }
\tex_vfill:D
\tex_penalty:D - '10000000000 ~
}
@@ -2823,8 +2929,8 @@
\seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
\__unravel_print_action:
\token_if_eq_meaning:NNTF \l__unravel_head_token \tex_kern:D
- { \__unravel_scan_dimen:NN \c_true_bool \c_false_bool }
- { \__unravel_scan_dimen:NN \c_false_bool \c_false_bool }
+ { \__unravel_scan_dimen:nN { 2 } \c_false_bool }
+ { \__unravel_scan_dimen:nN { 3 } \c_false_bool }
\seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
\tl_use:N \l__unravel_head_tl \scan_stop:
\__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl }
@@ -2908,7 +3014,7 @@
{
\int_compare:nNnT \l__unravel_head_char_int = { 1 } % indent
{
- \tex_hbox:D width \tex_parindent:D { }
+ \__unravel_hbox:w width \tex_parindent:D { }
\gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl
}
\__unravel_print_action:
@@ -3563,7 +3669,7 @@
{ \__unravel_scan_font_int: } { \__unravel_scan_int: }
}
\__unravel_prefixed_new:nn { set_aux } % 79
- { % prevdepth = 1, spacefactor = 0
+ { % prevdepth = 1, spacefactor = 102
\int_compare:nNnTF \l__unravel_head_char_int = \c_one
{ \__unravel_assign_value:nn { } { \__unravel_scan_normal_dimen: } }
{ \__unravel_assign_value:nn { } { \__unravel_scan_int: } }
@@ -3737,25 +3843,34 @@
\__unravel_prefixed_new:nn { set_interaction } % 100
{
\seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
- \tl_put_right:NV \l__unravel_head_tl \l__unravel_tmpa_tl
+ \tl_put_left:NV \l__unravel_head_tl \l__unravel_tmpa_tl
\tl_use:N \l__unravel_head_tl \scan_stop:
\__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl }
}
\__unravel_prefixed_new:nn { letterspace_font } % 101
{
- % ^^A todo...
- % new_letterspaced_font(a);
- \msg_error:nnx { unravel } { not-implemented } { letterspace-font }
- \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
- \__unravel_omit_after_assignment:w
+ \__unravel_prev_input_silent:V \l__unravel_head_tl
+ \__unravel_set_action_text:x { \tl_to_str:N \l__unravel_head_tl }
+ \__unravel_scan_r_token:
+ \__unravel_print_action:x
+ { \g__unravel_action_text_str \tl_to_str:N \l__unravel_defined_tl }
+ \exp_after:wN \cs_set_eq:NN \l__unravel_defined_tl \__unravel_nullfont:
+ \__unravel_scan_optional_equals:
+ \__unravel_scan_font_ident:
+ \__unravel_scan_int:
+ \__unravel_assign_token:n { }
}
\__unravel_prefixed_new:nn { pdf_copy_font } % 102
{
- % ^^A todo...
- % make_font_copy(a);
- \msg_error:nnx { unravel } { not-implemented } { pdf-copy-font }
- \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
- \__unravel_omit_after_assignment:w
+ \__unravel_prev_input_silent:V \l__unravel_head_tl
+ \__unravel_set_action_text:x { \tl_to_str:N \l__unravel_head_tl }
+ \__unravel_scan_r_token:
+ \__unravel_print_action:x
+ { \g__unravel_action_text_str \tl_to_str:N \l__unravel_defined_tl }
+ \exp_after:wN \cs_set_eq:NN \l__unravel_defined_tl \__unravel_nullfont:
+ \__unravel_scan_optional_equals:
+ \__unravel_scan_font_ident:
+ \__unravel_assign_token:n { }
}
\__unravel_prefixed_new:nn { register } % 89
{ \__unravel_do_register:N \c_zero }
@@ -3938,7 +4053,7 @@
{
\int_case:nnF \l__unravel_head_char_int
{
- { 1 } { \__unravel_print_action: } % \endinput
+ { 1 } { \__unravel_endinput: } % \endinput
{ 2 } { \__unravel_scantokens: } % \scantokens
}
{ % 0=\input
@@ -3946,6 +4061,11 @@
{ \__unravel_insert_relax: } { \__unravel_input: }
}
}
+\cs_new_protected_nopar:Npn \__unravel_endinput:
+ {
+ \msg_warning:nn { unravel } { endinput-ignored }
+ \__unravel_print_action:
+ }
\cs_new_protected_nopar:Npn \__unravel_scantokens:
{
\seq_gput_right:Nn \g__unravel_prev_input_seq { }
@@ -4142,7 +4262,7 @@
\fi:
\int_incr:N \l__unravel_if_nesting_int
\fi:
- \__unravel_input_gpop:N \l__unravel_tmpa_gtl
+ \__unravel_input_gpop:N \l__unravel_unused_gtl
\int_compare:nNnTF \l__unravel_if_nesting_int = \c_zero
{ \__unravel_pass_text: }
{ \__unravel_pass_text_nested: }
@@ -4334,7 +4454,7 @@
{
\seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
\__unravel_print_action:
- \bool_if:NT \l__unravel_debug_bool { \iow_term:n { {\ifcase level~#1} } }
+ \bool_if:NT \g__unravel_internal_debug_bool { \iow_term:n { {\ifcase level~#1} } }
\__unravel_scan_int:
\seq_get_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
\tl_set:Nx \l__unravel_head_tl { \tl_tail:N \l__unravel_head_tl }
@@ -4433,7 +4553,7 @@
\cs_new_protected:Npn \__unravel_set_action_text:x #1
{
\group_begin:
- \int_set:Nn \tex_escapechar:D { 92 }
+ \__unravel_set_escapechar:n { 92 }
\str_gset:Nx \g__unravel_action_text_str {#1}
\group_end:
}
@@ -4449,7 +4569,8 @@
\cs_new_protected:Npn \__unravel_print_state:
{
\group_begin:
- \int_set:Nn \tex_escapechar:D { 92 }
+ \__unravel_set_escapechar:n { 92 }
+ \tl_use:N \g__unravel_before_print_state_tl
\int_compare:nNnT \g__unravel_noise_int > \c_zero
{
\exp_args:Nx \__unravel_print_state_output:n
@@ -4469,66 +4590,16 @@
{
\tl_if_empty:nF {#1}
{
- \int_set:Nn \l__unravel_print_int { \str_count:n {#1} }
\__unravel_print_message:nn { <| ~ }
- {
- \int_compare:nNnTF
- \l__unravel_print_int > \g__unravel_max_output_int
- {
- (
- \int_eval:n
- {
- \l__unravel_print_int
- - \g__unravel_max_output_int + 14
- } ~
- chars
- )~
- ...
- \str_substr:nnn {#1}
- { \l__unravel_print_int - \g__unravel_max_output_int + 15 }
- { \l__unravel_print_int }
- }
- {#1}
- }
+ { \__unravel_str_truncate_left:nn {#1} { \g__unravel_max_output_int } }
}
}
\cs_new_protected:Npn \__unravel_print_state_prev:n #1
- {
- % \int_set:Nn \l__unravel_print_int { \str_count:n {#1} }
- \__unravel_print_message:nn { || ~ } {#1}
- % {
- % \int_compare:nNnTF \l__unravel_print_int > \g__unravel_max_prev_int
- % {
- % (
- % \int_eval:n
- % { \l__unravel_print_int - \g__unravel_max_prev_int + 14 } ~
- % chars
- % )~
- % ...
- % \str_substr:nnn {#1}
- % { \l__unravel_print_int - \g__unravel_max_prev_int + 15 }
- % { \l__unravel_print_int }
- % }
- % {#1}
- % }
- }
+ { \__unravel_print_message:nn { || ~ } {#1} }
\cs_new_protected:Npn \__unravel_print_state_input:n #1
{
- \int_set:Nn \l__unravel_print_int { \str_count:n {#1} }
\__unravel_print_message:nn { |> ~ }
- {
- \int_compare:nNnTF \l__unravel_print_int > \g__unravel_max_input_int
- {
- \str_substr:nnn {#1} { 1 } { \g__unravel_max_input_int - 14 }
- ...~
- (
- \int_eval:n
- { \l__unravel_print_int - \g__unravel_max_input_int + 14 } ~
- chars
- )
- }
- {#1}
- }
+ { \__unravel_str_truncate_right:nn {#1} { \g__unravel_max_input_int } }
}
\cs_new_protected:Npn \__unravel_print_meaning:
{
@@ -4546,21 +4617,20 @@
\cs_new_protected:Npn \__unravel_print_action:
{
\int_gincr:N \g__unravel_step_int
- \__unravel_print_message:nn { }
+ \__unravel_print:x
{
- % \\
- [=====~ Step~ \int_use:N \g__unravel_step_int \ =====]~
+ [=====
+ \bool_if:NT \g__unravel_number_steps_bool
+ { ~ Step ~ \int_use:N \g__unravel_step_int \ }
+ =====]~
\int_compare:nNnTF
{ \str_count:N \g__unravel_action_text_str }
> { \g__unravel_max_action_int }
{
- \str_substr:Nnn \g__unravel_action_text_str
+ \str_range:Nnn \g__unravel_action_text_str
{ 1 } { \g__unravel_max_action_int - 3 } ...
}
{ \g__unravel_action_text_str }
- % \\
- % \ \ < \int_use:N \g__unravel_input_int > % ^^A todo: remove
- % \ < \seq_count:N \g__unravel_prev_input_seq > % ^^A todo: remove
}
\__unravel_print_state:
}
@@ -4592,7 +4662,7 @@
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 \tex_the:D \l__unravel_defined_tl
+ = \exp_after:wN \__unravel_the:w \l__unravel_defined_tl
}
\__unravel_omit_after_assignment:w
}
@@ -4600,44 +4670,47 @@
{
\__unravel_print_message:nn { }
{
- \\
- ========~ Welcome~ to~ the~ unravel~ package~ ========\\
- \iow_indent:n
+ \bool_if:NTF \g__unravel_welcome_message_bool
{
- "<|"~ denotes~ the~ output~ to~ TeX's~ stomach. \\
- "||"~ denotes~ tokens~ waiting~ to~ be~ used. \\
- "|>"~ denotes~ tokens~ that~ we~ will~ act~ on. \\
- Press~<enter>~to~continue;~'h'~<enter>~for~help. \\
+ \\
+ ========~ Welcome~ to~ the~ unravel~ package~ ========\\
+ \iow_indent:n
+ {
+ "<|"~ denotes~ the~ output~ to~ TeX's~ stomach. \\
+ "||"~ denotes~ tokens~ waiting~ to~ be~ used. \\
+ "|>"~ denotes~ tokens~ that~ we~ will~ act~ on. \\
+ Press~<enter>~to~continue;~'h'~<enter>~for~help. \\
+ }
}
+ { [=====~Start~=====] }
}
\__unravel_print_state:
}
\cs_new_protected_nopar:Npn \__unravel_print_outcome:
- {
- % \int_gset_eq:NN \g__unravel_max_input_int \c_max_int
- % \int_gset_eq:NN \g__unravel_max_prev_int \c_max_int
- % \int_gset_eq:NN \g__unravel_max_output_int \c_max_int
- % \__unravel_print_state:
- \__unravel_print_message:nn { } { [=====~The~end!~=====] \\ }
- }
+ { \__unravel_print:n { [=====~End~=====] } }
\cs_new_protected_nopar:Npn \__unravel_prompt:
{
\int_gdecr:N \g__unravel_nonstop_int
\int_compare:nNnF \g__unravel_nonstop_int > \c_zero
{
\group_begin:
- \int_set_eq:NN \tex_escapechar:D \c_minus_one
+ \__unravel_set_escapechar:n { -1 }
\int_set_eq:NN \tex_endlinechar:D \c_minus_one
- \tl_use:N \g__unravel_prompt_before_tl
- \tl_gclear:N \g__unravel_prompt_before_tl
+ \tl_use:N \g__unravel_before_prompt_tl
\__unravel_prompt_aux:
\group_end:
}
}
\cs_new_protected_nopar:Npn \__unravel_prompt_aux:
{
- \ior_get_str:Nc \g__unravel_prompt_ior { Your~input }
- \exp_args:Nv \__unravel_prompt_treat:n { Your~input }
+ \int_compare:nNnT { \etex_interactionmode:D } = { 3 }
+ {
+ \bool_if:NTF \g__unravel_explicit_prompt_bool
+ { \ior_get_str:Nc \c__unravel_prompt_ior }
+ { \ior_get_str:Nc \c__unravel_noprompt_ior }
+ { Your~input }
+ \exp_args:Nv \__unravel_prompt_treat:n { Your~input }
+ }
}
\cs_new_protected:Npn \__unravel_prompt_treat:n #1
{
@@ -4669,6 +4742,9 @@
{ \tl_gclear:N \g__unravel_tmpc_tl }
\group_insert_after:N \g__unravel_tmpc_tl
}
+ { | } { \__unravel_prompt_scan_int:nn {#1}
+ \__unravel_prompt_vert:n }
+ { a } { \__unravel_prompt_all: }
}
{ \__unravel_prompt_help: }
}
@@ -4676,7 +4752,9 @@
\cs_new_protected:Npn \__unravel_prompt_scan_int:nn #1
{
\tex_afterassignment:D \__unravel_prompt_scan_int_after:wn
- \l__unravel_prompt_tmpa_int = 0 \use_none:n #1 \scan_stop:
+ \l__unravel_prompt_tmpa_int =
+ \tl_if_head_eq_charcode:fNF { \use_none:n #1 } - { 0 }
+ \use_ii:nn #1 \scan_stop:
}
\cs_new_protected:Npn \__unravel_prompt_scan_int_after:wn #1 \scan_stop: #2
{
@@ -4686,44 +4764,159 @@
\cs_new_protected:Npn \__unravel_prompt_help:
{
\__unravel_print:n { "m":~meaning~of~first~token }
- \__unravel_print:n { "q":~semi-quiet }
- \__unravel_print:n { "x":~exit~this~instance~of~unravel }
- \__unravel_print:n { "X":~try~harder~to~exit }
+ \__unravel_print:n { "q":~semi-quiet~(same~as~"o1") }
+ \__unravel_print:n { "x"/"X":~exit~this~instance~of~unravel/TeX }
\__unravel_print:n { "s<num>":~do~<num>~steps~silently }
\__unravel_print:n
- { "o<num>":~0~=>~only~log~not~online,~1~=>~both,~-1~=>~neither.}
- \__unravel_print:n { "C<code>":~run~some~code~immediately }
+ { "o<num>":~1~=>~log~and~terminal,~0~=>~only~log,~-1~=>~neither.}
+ \__unravel_print:n { "C<code>":~run~some~expl3~code~immediately }
+ \__unravel_print:n { "|<num>":~silent~steps~until~<num>~fewer~"||" }
+ \__unravel_print:n { "a":~print~state~again,~without~truncating }
\__unravel_prompt_aux:
}
\cs_new_protected:Npn \__unravel_prompt_silent_steps:n #1
{
+ \int_compare:nNnF {#1} < \c_zero
+ {
+ \int_gset_eq:NN \g__unravel_noise_int \c_minus_one
+ \tl_gset:Nn \g__unravel_before_prompt_tl
+ {
+ \int_gset_eq:NN \g__unravel_noise_int \c_one
+ \tl_gclear:N \g__unravel_before_prompt_tl
+ }
+ \int_gset:Nn \g__unravel_nonstop_int {#1}
+ }
+ }
+\cs_new_protected:Npn \__unravel_prompt_vert:n #1
+ {
+ \int_compare:nNnTF {#1} < { 0 }
+ { \__unravel_prompt_vert:Nn > {#1} }
+ { \__unravel_prompt_vert:Nn < {#1} }
+ }
+\cs_new_protected:Npn \__unravel_prompt_vert:Nn #1#2
+ {
\int_gset_eq:NN \g__unravel_noise_int \c_minus_one
- \tl_gset:Nn \g__unravel_prompt_before_tl
- { \int_gset_eq:NN \g__unravel_noise_int \c_one }
- \int_gset:Nn \g__unravel_nonstop_int {#1}
+ \tl_gset:Nf \g__unravel_before_print_state_tl
+ {
+ \exp_args:NNf \exp_stop_f: \int_compare:nNnTF
+ { \int_eval:n { \seq_count:N \g__unravel_prev_input_seq - #2 } }
+ #1 { \seq_count:N \g__unravel_prev_input_seq }
+ {
+ \int_gset:Nn \g__unravel_nonstop_int
+ { \int_max:nn { \g__unravel_nonstop_int } { 2 } }
+ }
+ {
+ \int_gset_eq:NN \g__unravel_noise_int \c_one
+ \tl_gclear:N \g__unravel_before_print_state_tl
+ }
+ }
}
-\cs_new_protected:Npn \unravel #1 { \__unravel_unravel:n {#1} }
-\cs_new_protected_nopar:Npn \UnravelDebug
+\cs_new_protected_nopar:Npn \__unravel_prompt_all:
{
- \bool_set_true:N \l__unravel_debug_bool
+ \tl_gset:Nx \g__unravel_tmpc_tl
+ {
+ \exp_not:n
+ {
+ \tl_gclear:N \g__unravel_tmpc_tl
+ \int_gset_eq:NN \g__unravel_max_output_int \c_max_int
+ \int_gset_eq:NN \g__unravel_max_input_int \c_max_int
+ \__unravel_print_state:
+ }
+ \__unravel_prompt_all_aux:N \g__unravel_max_output_int
+ \__unravel_prompt_all_aux:N \g__unravel_max_input_int
+ }
+ \group_insert_after:N \g__unravel_tmpc_tl
}
-\cs_new_protected:Npn \__unravel_unravel:n #1
+\cs_new:Npn \__unravel_prompt_all_aux:N #1
+ { \exp_not:n { \int_gset:Nn #1 } { \int_use:N #1 } }
+\keys_define:nn { unravel/defaults }
+ {
+ explicit-prompt .bool_gset:N = \g__unravel_default_explicit_prompt_bool ,
+ internal-debug .bool_gset:N = \g__unravel_default_internal_debug_bool ,
+ max-action .int_gset:N = \g__unravel_default_max_action_int ,
+ max-output .int_gset:N = \g__unravel_default_max_output_int ,
+ max-input .int_gset:N = \g__unravel_default_max_input_int ,
+ number-steps .bool_gset:N = \g__unravel_default_number_steps_bool ,
+ welcome-message .bool_gset:N = \g__unravel_default_welcome_message_bool ,
+ }
+\keys_define:nn { unravel }
+ {
+ explicit-prompt .bool_gset:N = \g__unravel_explicit_prompt_bool ,
+ internal-debug .bool_gset:N = \g__unravel_internal_debug_bool ,
+ max-action .int_gset:N = \g__unravel_max_action_int ,
+ max-output .int_gset:N = \g__unravel_max_output_int ,
+ max-input .int_gset:N = \g__unravel_max_input_int ,
+ number-steps .bool_gset:N = \g__unravel_number_steps_bool ,
+ welcome-message .bool_gset:N = \g__unravel_welcome_message_bool ,
+ }
+\tl_map_inline:nn { { /defaults } { } }
+ {
+ \keys_define:nn { unravel #1 }
+ {
+ machine .meta:nn =
+ { unravel #1 }
+ {
+ explicit-prompt = false ,
+ internal-debug = false ,
+ max-action = \c_max_int ,
+ max-output = \c_max_int ,
+ max-input = \c_max_int ,
+ number-steps = false ,
+ welcome-message = false ,
+ } ,
+ }
+ }
+\NewDocumentCommand \unravel { O { } m } { \unravel:nn {#1} {#2} }
+\NewDocumentCommand \unravelsetup { m } { \unravel_setup:n {#1} }
+\cs_new_protected:Npn \unravel_setup:n #1
+ {
+ \keys_set:nn { unravel/defaults } {#1}
+ \keys_set:nn { unravel } {#1}
+ }
+\cs_new_protected:Npn \unravel:nn #1#2
+ {
+ \__unravel_init_key_vars:
+ \keys_set:nn { unravel } {#1}
+ \__unravel_init_vars:
+ \__unravel_input_gset:n {#2}
+ \__unravel_print_welcome:
+ \__unravel_main_loop:
+ \__unravel_exit_point:
+ \__unravel_print_outcome:
+ \__unravel_final_test:
+ \__unravel_exit_point:
+ }
+\cs_new_protected_nopar:Npn \__unravel_init_key_vars:
+ {
+ \bool_gset_eq:NN \g__unravel_explicit_prompt_bool \g__unravel_default_explicit_prompt_bool
+ \bool_gset_eq:NN \g__unravel_internal_debug_bool \g__unravel_default_internal_debug_bool
+ \bool_gset_eq:NN \g__unravel_number_steps_bool \g__unravel_default_number_steps_bool
+ \bool_gset_eq:NN \g__unravel_welcome_message_bool \g__unravel_default_welcome_message_bool
+ \int_gset_eq:NN \g__unravel_max_action_int \g__unravel_default_max_action_int
+ \int_gset_eq:NN \g__unravel_max_output_int \g__unravel_default_max_output_int
+ \int_gset_eq:NN \g__unravel_max_input_int \g__unravel_default_max_input_int
+ }
+\cs_new_protected_nopar:Npn \__unravel_init_vars:
{
- \int_gzero:N \g__unravel_step_int
- \__unravel_input_gset:n {#1}
\seq_gclear:N \g__unravel_prev_input_seq
\gtl_gclear:N \g__unravel_output_gtl
+ \int_gzero:N \g__unravel_step_int
\tl_gclear:N \g__unravel_if_limit_tl
\int_gzero:N \g__unravel_if_limit_int
\int_gzero:N \g__unravel_if_depth_int
\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
- \cs_gset_eq:NN \g__unravel_prompt_ior \c_minus_one % ^^A todo:?
- \__unravel_print_welcome:
+ }
+\cs_new_protected_nopar:Npn \__unravel_main_loop:
+ {
+ \__unravel_get_x_next:
+ \__unravel_set_cmd:
+ \__unravel_do_step:
\__unravel_main_loop:
- \__unravel_exit_point:
- \__unravel_print_outcome:
+ }
+\cs_new_protected_nopar:Npn \__unravel_final_test:
+ {
\bool_if:nTF
{
\tl_if_empty_p:N \g__unravel_if_limit_tl
@@ -4731,22 +4924,14 @@
&& \int_compare_p:nNn \g__unravel_if_depth_int = \c_zero
&& \seq_if_empty_p:N \g__unravel_prev_input_seq
}
- { \__unravel_input_if_empty:TF { } { \__unravel_bad_finish: } }
- { \__unravel_bad_finish: }
- \__unravel_exit_point:
+ { \__unravel_input_if_empty:TF { } { \__unravel_final_bad: } }
+ { \__unravel_final_bad: }
}
-\cs_new_protected_nopar:Npn \__unravel_bad_finish:
+\cs_new_protected_nopar:Npn \__unravel_final_bad:
{
\msg_error:nnx { unravel } { internal }
{ the-last-unravel-finished-badly }
}
-\cs_new_protected_nopar:Npn \__unravel_main_loop:
- {
- \__unravel_get_x_next:
- \__unravel_set_cmd:
- \__unravel_do_step:
- \__unravel_main_loop:
- }
\msg_new:nnn { unravel } { unknown-primitive }
{ Internal~error:~the~primitive~'#1'~is~not~known. }
\msg_new:nnn { unravel } { extra-fi-or-else }
@@ -4804,14 +4989,21 @@
{ Missing~\iow_char:N\\endcsname~inserted. }
\msg_new:nnn { unravel } { runaway-if }
{ Runaway~\iow_char:N\\if... }
+\msg_new:nnn { unravel } { runaway-macro-parameter }
+ {
+ Runaway~macro~parameter~\# #2~after \\\\
+ \iow_indent:n {#1}
+ }
\msg_new:nnn { unravel } { extra-or }
{ Extra~\iow_char:N\\or. }
\msg_new:nnn { unravel } { missing-equals }
{ Missing~equals~for~\iow_char:N\\ifnum~or~\iow_char:N\\ifdim. }
\msg_new:nnn { unravel } { internal }
- { Internal~error:~'#1'.~\ Please report. }
+ { Internal~error:~'#1'.~\ Please~report. }
\msg_new:nnn { unravel } { not-implemented }
{ The~following~feature~is~not~implemented:~'#1'. }
+\msg_new:nnn { unravel } { endinput-ignored }
+ { The~primitive~\iow_char:N\\endinput~was~ignored. }
%%
%%
%% End of file `unravel.sty'.