summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2013-07-29 22:39:06 +0000
committerKarl Berry <karl@freefriends.org>2013-07-29 22:39:06 +0000
commit61aff27e54e84c0be9a312b82a413847a527c580 (patch)
tree2f134ca286a522f8cd44ed8de040a6c9365c8d8e /Master
parent81ad2a9f387b54bdad66ad8e98714b742d059445 (diff)
unravel (29jul13)
git-svn-id: svn://tug.org/texlive/trunk@31307 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/doc/latex/unravel/README34
-rw-r--r--Master/texmf-dist/doc/latex/unravel/unravel.pdfbin0 -> 674252 bytes
-rw-r--r--Master/texmf-dist/source/latex/unravel/unravel.dtx7096
-rw-r--r--Master/texmf-dist/source/latex/unravel/unravel.ins23
-rw-r--r--Master/texmf-dist/tex/latex/unravel/unravel.sty4817
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rw-r--r--Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/unravel.tlpsrc0
8 files changed, 11972 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/unravel/README b/Master/texmf-dist/doc/latex/unravel/README
new file mode 100644
index 00000000000..b2dce6d2cc1
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/unravel/README
@@ -0,0 +1,34 @@
+----------------------------------------------------------------
+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/unravel.pdf b/Master/texmf-dist/doc/latex/unravel/unravel.pdf
new file mode 100644
index 00000000000..19a0e4fe3f1
--- /dev/null
+++ 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
new file mode 100644
index 00000000000..1cd40dc4382
--- /dev/null
+++ b/Master/texmf-dist/source/latex/unravel/unravel.dtx
@@ -0,0 +1,7096 @@
+% \iffalse
+%% File: unravel.dtx Copyright (C) 2013 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
+%% license or (at your option) any later version. The latest version
+%% of this license is in the file
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver>
+%\fi
+%\iffalse
+\documentclass[full]{l3doc}
+\usepackage{unravel}
+\begin{document}
+ \DocInput{unravel.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{The \textsf{unravel} package: \\
+% watching TeX digest tokens\thanks{This
+% file has version number 0.0a, last revised 2013/07/28.}}
+% \author{Bruno Le Floch}
+% \date{2013/07/28}
+%
+% \maketitle
+% \tableofcontents
+%
+% \begin{documentation}
+%
+% \section{\pkg{unravel} documentation}
+%
+% The aim of this \LaTeX{} package is to help debug complicated macros.
+% 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.
+% 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
+% 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.
+%
+% As a simple example, one can run \LaTeX{} on the following file.
+% \begin{verbatim}
+% \documentclass{article}
+% \usepackage{unravel}
+% \unravel
+% {
+% \title{My title}
+% \author{Me}
+% \date{\today}
+% }
+% \begin{document}
+% \maketitle
+% \end{document}
+% \end{verbatim}
+%
+% A more elaborate example is to understand how \tn{newcommand} works.
+% \begin{verbatim}
+% \documentclass{article}
+% \usepackage{unravel}
+% \begin{document}
+% \unravel
+% {
+% \newcommand*{\foo}[1]{bar(#1)}
+% \foo{3}
+% }
+% \end{document}
+% \end{verbatim}
+%
+% The \pkg{unravel} package understands deeply nested expansions as can
+% be seen for instance by unravelling functions from \pkg{l3fp}, such as
+% with the following code (given the current default settings, this code
+% runs for roughly 2000 steps: you can type |s1980| as a response to the
+% prompt, then press ``enter'' a few times to see the last few steps of
+% expansion).
+% \begin{verbatim}
+% \documentclass{article}
+% \usepackage{unravel}
+% \begin{document}
+% \ExplSyntaxOn
+% \unravel { \fp_eval:n { 3.45 * 2 pi } }
+% \ExplSyntaxOff
+% \end{document}
+% \end{verbatim}
+%
+% Given all the work that \pkg{unravel} has to do to emulate \TeX{}, it
+% is not fast on very large pieces of code. For instance, running it on
+% |\documentclass{article}| takes about ten minutes on my machine, and
+% finishes after slightly more than $20000$ steps.
+% \begin{verbatim}
+% \RequirePackage{unravel}
+% \unravel{\documentclass{article}\relax}
+% \usepackage{lipsum}
+% \begin{document}
+% \lipsum
+% \end{document}
+% \end{verbatim}
+% The \tn{relax} command is needed after |\documentclass{article}|
+% because this command tries to look for an optional argument:
+% \cs{unravel} would not find any token, and would give up, as \TeX{}
+% would if your file ended just after |\documentclass{article}|. After
+% running the above through \pdfTeX{}, one can check that the result is
+% identical to that without \pkg{unravel}. Note that
+% \cs{unravel}|\usepackage{lipsum}\relax|, despite taking as many steps
+% to complete, is four times slower, because \tn{newcommand} uses
+% delimited arguments, which prevent some optimizations that
+% \pkg{unravel} can otherwise obtain. For comparison,
+% |\unravel{\lipsum[1-30]}|, which also takes $20000$ step, takes
+% $8$~minutes to complete.
+%
+% \subsection{Differences between \pkg{unravel} and \TeX{}'s processing}
+% \label{sec: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,
+% 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).
+% \end{itemize}
+%
+% \subsection{Future perhaps}
+%
+% \begin{itemize}
+% \item Allow users to change some settings.
+% \item Fix the display for \tn{if} and \tn{ifcat} (remove extraneous
+% \cs{exp_not:N}).
+% \end{itemize}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{unravel} implementation}
+%
+% Some support packages are loaded first, then we declare the package's
+% name, date, version, and purpose.
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\RequirePackage{expl3}[2013/07/01]
+\RequirePackage{l3str}[2013/04/24]
+\RequirePackage{gtl}[2013/07/28]
+\ProvidesExplPackage
+ {unravel} {2013/07/28} {0.0a} {Watching TeX digest tokens}
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=unravel>
+% \end{macrocode}
+%
+% \subsection{Variables}
+%
+% \subsubsection{User interaction}
+%
+% \begin{variable}
+% {\g_@@_prompt_ior, \g_@@_prompt_before_tl, \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}
+%
+% \begin{variable}{\g_@@_nonstop_int, \g_@@_noise_int}
+% The number of prompts to skip.
+% \begin{macrocode}
+\int_new:N \g_@@_nonstop_int
+\int_new:N \g_@@_noise_int
+\int_gset_eq:NN \g_@@_noise_int \c_one
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_debug_bool}
+% If true, debug-mode. Activated by \cs{UnravelDebug}
+% \begin{macrocode}
+\bool_new:N \l_@@_debug_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_step_int}
+% Current expansion step.
+% \begin{macrocode}
+\int_new:N \g_@@_step_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_action_text_str}
+% Text describing the action, displayed at each step. This should
+% only be altered through \cs{@@_set_action_text:x}, which sets the
+% escape character as appropriate before converting the argument to a
+% string.
+% \begin{macrocode}
+\str_new:N \g_@@_action_text_str
+% \end{macrocode}
+% \end{variable}
+%
+% ^^A todo: let the user fix those numbers.
+% \begin{variable}
+% {
+% \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_@@_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.
+% \begin{macrocode}
+\bool_new:N \g_@@_speedup_macros_bool
+\bool_gset_true:N \g_@@_speedup_macros_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_print_int}
+% The length of one piece of the terminal output.
+% \begin{macrocode}
+\int_new:N \l_@@_print_int
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Working with tokens}
+%
+% \begin{variable}{\g_@@_input_int}
+% The user input, at each stage of expansion, is stored in multiple
+% \texttt{gtl} variables, from |\g_@@_input_|\meta{n}|_gtl| to
+% \cs{g_@@_input_1_gtl}. The split between variables is akin to
+% \TeX{}'s input stack, and allows us to manipulate smaller token
+% lists, speeding up processing. The total number \meta{n} of lists
+% is \cs{g_@@_input_int}. The highest numbered \texttt{gtl}
+% represents input that comes to the left of lower numbered ones.
+% \begin{macrocode}
+\int_new:N \g_@@_input_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_input_tmpa_int}
+% \begin{variable}{\l_@@_input_tmpa_tl}
+% \begin{macrocode}
+\int_new:N \g_@@_input_tmpa_int
+\tl_new:N \l_@@_input_tmpa_tl
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}
+% {\g_@@_prev_input_seq, \l_@@_prev_input_tl, \l_@@_prev_input_gtl}
+% ^^A todo: comment
+% \begin{macrocode}
+\seq_new:N \g_@@_prev_input_seq
+\tl_new:N \l_@@_prev_input_tl
+\gtl_new:N \l_@@_prev_input_gtl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_output_gtl}
+% Material that is ``typeset'' or otherwise sent further down \TeX{}'s
+% digestion.
+% \begin{macrocode}
+\gtl_new:N \g_@@_output_gtl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \l_@@_head_gtl,
+% \l_@@_head_tl,
+% \l_@@_head_token,
+% \l_@@_head_cmd_int,
+% \l_@@_head_char_int
+% }
+% First token in the input, as a generalized token list (general case)
+% or as a token list whenever this is possible. Also, a token set
+% equal to it, and its command code and character code, following
+% \TeX{}.
+% \begin{macrocode}
+\gtl_new:N \l_@@_head_gtl
+\tl_new:N \l_@@_head_tl
+\token_new:Nn \l_@@_head_token { ? }
+\int_new:N \l_@@_head_cmd_int
+\int_new:N \l_@@_head_char_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_head_meaning_tl}
+% \begin{macrocode}
+\tl_new:N \l_@@_head_meaning_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\l_@@_tmpa_tl, \l_@@_tmpb_gtl, \g_@@_tmpc_tl, \l_@@_tmpa_seq}
+% Temporary storage.
+% \begin{macrocode}
+\tl_new:N \l_@@_tmpa_tl
+\gtl_new:N \l_@@_tmpb_gtl
+\tl_new:N \g_@@_tmpc_tl
+\seq_new:N \l_@@_tmpa_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_defined_tl, \l_@@_defining_tl}
+% The token that is defined by the prefixed command (such as
+% \tn{chardef} or \tn{futurelet}), and the code to define it. We do
+% not use the \cs{g_@@_prev_input_seq} to store that code: rather,
+% this sequence contains a string representation of the code, which is
+% not suitable for the definition. This is safe, as definitions
+% cannot be nested. This is needed for expanding assignments, as
+% expansion should be shown to the user, but then later should not be
+% performed again when defining.
+% \begin{macrocode}
+\tl_new:N \l_@@_defined_tl
+\tl_new:N \l_@@_defining_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[int]{\@@_inaccessible:w}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_inaccessible:w ?
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}
+% {
+% \g_@@_after_assignment_gtl,
+% \g_@@_set_box_allowed_bool,
+% \g_@@_name_in_progress_bool
+% }
+% Global variables keeping track of the state of \TeX{}. Token to
+% insert after the next assignment. Is \tn{setbox} currently allowed?
+% Should \tn{input} expand?
+% \begin{macrocode}
+\gtl_new:N \g_@@_after_assignment_gtl
+\bool_new:N \g_@@_set_box_allowed_bool
+\bool_new:N \g_@@_name_in_progress_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_parameters_tl}
+% 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 } }
+\group_end:
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Numbers and conditionals}
+%
+% \begin{variable}{\g_@@_val_level_int}
+% See \TeX{}'s |cur_val_level| variable. This is set by
+% \cs{@@_scan_something_internal:n} to
+% \begin{itemize}
+% \item $0$ for integer values,
+% \item $1$ for dimension values,
+% \item $2$ for glue values,
+% \item $3$ for mu glue values,
+% \item $4$ for font identifiers,
+% \item $5$ for token lists.
+% \end{itemize}
+% \begin{macrocode}
+\int_new:N \g_@@_val_level_int
+% \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}
+% Stack for what \TeX{} calls |if_limit|, and its depth.
+% \begin{macrocode}
+\tl_new:N \g_@@_if_limit_tl
+\int_new:N \g_@@_if_limit_int
+\int_new:N \g_@@_if_depth_int
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_if_nesting_int}
+% \begin{macrocode}
+\int_new:N \l_@@_if_nesting_int
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Boxes and groups}
+%
+% \begin{variable}{\l_@@_leaders_box_seq}
+% A stack of letters: the first token in the token list is |h|~if the
+% innermost explicit box (created with \tn{vtop}, \tn{vbox}, or
+% \tn{hbox}) appears in a horizontal (or math) mode leaders
+% construction; it is |v|~if the innermost explicit box appears in a
+% vertical mode leaders construction; it is |Z|~otherwise.
+% \begin{macrocode}
+\seq_new:N \l_@@_leaders_box_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_ends_int}
+% Number of times \tn{end} will be put back into the input in case
+% there remains to ship some pages.
+% \begin{macrocode}
+\int_new:N \g_@@_ends_int
+\int_gset:Nn \g_@@_ends_int { 3 }
+% \end{macrocode}
+% \end{variable}
+%
+% \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]
+% {
+% \@@_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,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:
+% \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}
+%
+% \subsection{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,
+% and a character code, to decide what action to perform upon seeing
+% them.
+%
+% \begin{macro}[int]{\@@_tex_const:nn}
+% \begin{macro}[int,EXP]{\@@_tex_use:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_tex_const:nn #1#2
+ { \int_const:cn { c_@@_tex_#1_int } {#2} }
+\cs_new:Npn \@@_tex_use:n #1 { \int_use:c { c_@@_tex_#1_int } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_tex_primitive:nnn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_tex_primitive:nnn #1#2#3
+ {
+ \tl_const:cx { c_@@_tex_#1_tl }
+ { { \@@_tex_use:n {#2} } {#3} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_new_tex_cmd:nn, \@@_new_eq_tex_cmd:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_new_tex_cmd:nn #1#2
+ {
+ \cs_new_protected_nopar:cpn
+ { @@_cmd_ \@@_tex_use:n {#1} : } {#2}
+ }
+\cs_new_protected:Npn \@@_new_eq_tex_cmd:nn #1#2
+ {
+ \cs_new_eq:cc
+ { @@_cmd_ \@@_tex_use:n {#1} : }
+ { @@_cmd_ \@@_tex_use:n {#2} : }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_new_tex_expandable:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_new_tex_expandable:nn #1#2
+ {
+ \cs_new_protected_nopar:cpn
+ { @@_expandable_ \@@_tex_use:n {#1} : } {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% Contrarily to \TeX{}, all macros are |call|, no |long_call| and the
+% like.
+% \begin{macrocode}
+\@@_tex_const:nn { relax } { 0 }
+\@@_tex_const:nn { begin-group_char } { 1 }
+\@@_tex_const:nn { end-group_char } { 2 }
+\@@_tex_const:nn { math_char } { 3 }
+\@@_tex_const:nn { tab_mark } { 4 }
+\@@_tex_const:nn { alignment_char } { 4 }
+\@@_tex_const:nn { car_ret } { 5 }
+\@@_tex_const:nn { macro_char } { 6 }
+\@@_tex_const:nn { superscript_char } { 7 }
+\@@_tex_const:nn { subscript_char } { 8 }
+\@@_tex_const:nn { endv } { 9 }
+\@@_tex_const:nn { blank_char } { 10 }
+\@@_tex_const:nn { the_char } { 11 }
+\@@_tex_const:nn { other_char } { 12 }
+\@@_tex_const:nn { par_end } { 13 }
+\@@_tex_const:nn { stop } { 14 }
+\@@_tex_const:nn { delim_num } { 15 }
+\@@_tex_const:nn { max_char_code } { 15 }
+\@@_tex_const:nn { char_num } { 16 }
+\@@_tex_const:nn { math_char_num } { 17 }
+\@@_tex_const:nn { mark } { 18 }
+\@@_tex_const:nn { xray } { 19 }
+\@@_tex_const:nn { make_box } { 20 }
+\@@_tex_const:nn { hmove } { 21 }
+\@@_tex_const:nn { vmove } { 22 }
+\@@_tex_const:nn { un_hbox } { 23 }
+\@@_tex_const:nn { un_vbox } { 24 }
+\@@_tex_const:nn { remove_item } { 25 }
+\@@_tex_const:nn { hskip } { 26 }
+\@@_tex_const:nn { vskip } { 27 }
+\@@_tex_const:nn { mskip } { 28 }
+\@@_tex_const:nn { kern } { 29 }
+\@@_tex_const:nn { mkern } { 30 }
+\@@_tex_const:nn { leader_ship } { 31 }
+\@@_tex_const:nn { halign } { 32 }
+\@@_tex_const:nn { valign } { 33 }
+\@@_tex_const:nn { no_align } { 34 }
+\@@_tex_const:nn { vrule } { 35 }
+\@@_tex_const:nn { hrule } { 36 }
+\@@_tex_const:nn { insert } { 37 }
+\@@_tex_const:nn { vadjust } { 38 }
+\@@_tex_const:nn { ignore_spaces } { 39 }
+\@@_tex_const:nn { after_assignment } { 40 }
+\@@_tex_const:nn { after_group } { 41 }
+\@@_tex_const:nn { break_penalty } { 42 }
+\@@_tex_const:nn { start_par } { 43 }
+\@@_tex_const:nn { ital_corr } { 44 }
+\@@_tex_const:nn { accent } { 45 }
+\@@_tex_const:nn { math_accent } { 46 }
+\@@_tex_const:nn { discretionary } { 47 }
+\@@_tex_const:nn { eq_no } { 48 }
+\@@_tex_const:nn { left_right } { 49 }
+\@@_tex_const:nn { math_comp } { 50 }
+\@@_tex_const:nn { limit_switch } { 51 }
+\@@_tex_const:nn { above } { 52 }
+\@@_tex_const:nn { math_style } { 53 }
+\@@_tex_const:nn { math_choice } { 54 }
+\@@_tex_const:nn { non_script } { 55 }
+\@@_tex_const:nn { vcenter } { 56 }
+\@@_tex_const:nn { case_shift } { 57 }
+\@@_tex_const:nn { message } { 58 }
+\@@_tex_const:nn { extension } { 59 }
+\@@_tex_const:nn { in_stream } { 60 }
+\@@_tex_const:nn { begin_group } { 61 }
+\@@_tex_const:nn { end_group } { 62 }
+\@@_tex_const:nn { omit } { 63 }
+\@@_tex_const:nn { ex_space } { 64 }
+\@@_tex_const:nn { no_boundary } { 65 }
+\@@_tex_const:nn { radical } { 66 }
+\@@_tex_const:nn { end_cs_name } { 67 }
+\@@_tex_const:nn { min_internal } { 68 }
+\@@_tex_const:nn { char_given } { 68 }
+\@@_tex_const:nn { math_given } { 69 }
+\@@_tex_const:nn { last_item } { 70 }
+\@@_tex_const:nn { max_non_prefixed_command } { 70 }
+\@@_tex_const:nn { toks_register } { 71 }
+\@@_tex_const:nn { assign_toks } { 72 }
+\@@_tex_const:nn { assign_int } { 73 }
+\@@_tex_const:nn { assign_dimen } { 74 }
+\@@_tex_const:nn { assign_glue } { 75 }
+\@@_tex_const:nn { assign_mu_glue } { 76 }
+\@@_tex_const:nn { assign_font_dimen } { 77 }
+\@@_tex_const:nn { assign_font_int } { 78 }
+\@@_tex_const:nn { set_aux } { 79 }
+\@@_tex_const:nn { set_prev_graf } { 80 }
+\@@_tex_const:nn { set_page_dimen } { 81 }
+\@@_tex_const:nn { set_page_int } { 82 }
+\@@_tex_const:nn { set_box_dimen } { 83 }
+\@@_tex_const:nn { set_shape } { 84 }
+\@@_tex_const:nn { def_code } { 85 }
+\@@_tex_const:nn { def_family } { 86 }
+\@@_tex_const:nn { set_font } { 87 }
+\@@_tex_const:nn { def_font } { 88 }
+\@@_tex_const:nn { register } { 89 }
+\@@_tex_const:nn { max_internal } { 89 }
+\@@_tex_const:nn { advance } { 90 }
+\@@_tex_const:nn { multiply } { 91 }
+\@@_tex_const:nn { divide } { 92 }
+\@@_tex_const:nn { prefix } { 93 }
+\@@_tex_const:nn { let } { 94 }
+\@@_tex_const:nn { shorthand_def } { 95 }
+\@@_tex_const:nn { read_to_cs } { 96 }
+\@@_tex_const:nn { def } { 97 }
+\@@_tex_const:nn { set_box } { 98 }
+\@@_tex_const:nn { hyph_data } { 99 }
+\@@_tex_const:nn { set_interaction } { 100 }
+\@@_tex_const:nn { letterspace_font } { 101 }
+\@@_tex_const:nn { pdf_copy_font } { 102 }
+\@@_tex_const:nn { max_command } { 102 }
+\@@_tex_const:nn { undefined_cs } { 103 }
+\@@_tex_const:nn { expand_after } { 104 }
+\@@_tex_const:nn { no_expand } { 105 }
+\@@_tex_const:nn { input } { 106 }
+\@@_tex_const:nn { if_test } { 107 }
+\@@_tex_const:nn { fi_or_else } { 108 }
+\@@_tex_const:nn { cs_name } { 109 }
+\@@_tex_const:nn { convert } { 110 }
+\@@_tex_const:nn { the } { 111 }
+\@@_tex_const:nn { top_bot_mark } { 112 }
+\@@_tex_const:nn { call } { 113 }
+\@@_tex_const:nn { end_template } { 117 }
+% \end{macrocode}
+% So far we've implemented properly [71,104]; [107,113].
+%
+% A few minor differences with pdf\TeX{}'s internal numbers are as
+% follows.
+% \begin{itemize}
+% \item |case_shift| is shifted by |3983|.
+% \item |assign_toks| is shifted by |local_base=3412|.
+% \item |assign_int| is shifted by |int_base=5263|.
+% \item |assign_dimen| is shifted by |dimen_base=5830|.
+% \item |assign_glue| and |assign_mu_glue| are shifted by
+% |glue_base=2882|.
+% \item |set_shape| is shifted (in \eTeX{}) by |local_base|.
+% \item |def_code| and |def_family| is shifted by |cat_code_base=3983|.
+% \item In \TeX{}, |inputlineno.char=3| and |badness.char=4|.
+% \end{itemize}
+% \begin{macrocode}
+\@@_tex_primitive:nnn { relax } { relax } { 256 }
+\@@_tex_primitive:nnn { span } { tab_mark } { 256 }
+\@@_tex_primitive:nnn { cr } { car_ret } { 257 }
+\@@_tex_primitive:nnn { crcr } { car_ret } { 258 }
+\@@_tex_primitive:nnn { par } { par_end } { 256 }
+\@@_tex_primitive:nnn { end } { stop } { 0 }
+\@@_tex_primitive:nnn { dump } { stop } { 1 }
+\@@_tex_primitive:nnn { delimiter } { delim_num } { 0 }
+\@@_tex_primitive:nnn { char } { char_num } { 0 }
+\@@_tex_primitive:nnn { mathchar } { math_char_num } { 0 }
+\@@_tex_primitive:nnn { mark } { mark } { 0 }
+\@@_tex_primitive:nnn { marks } { mark } { 5 }
+\@@_tex_primitive:nnn { show } { xray } { 0 }
+\@@_tex_primitive:nnn { showbox } { xray } { 1 }
+\@@_tex_primitive:nnn { showthe } { xray } { 2 }
+\@@_tex_primitive:nnn { showlists } { xray } { 3 }
+\@@_tex_primitive:nnn { showgroups } { xray } { 4 }
+\@@_tex_primitive:nnn { showtokens } { xray } { 5 }
+\@@_tex_primitive:nnn { showifs } { xray } { 6 }
+\@@_tex_primitive:nnn { box } { make_box } { 0 }
+\@@_tex_primitive:nnn { copy } { make_box } { 1 }
+\@@_tex_primitive:nnn { lastbox } { make_box } { 2 }
+\@@_tex_primitive:nnn { vsplit } { make_box } { 3 }
+\@@_tex_primitive:nnn { vtop } { make_box } { 4 }
+\@@_tex_primitive:nnn { vbox } { make_box } { 5 }
+\@@_tex_primitive:nnn { hbox } { make_box } { 106 }
+\@@_tex_primitive:nnn { moveright } { hmove } { 0 }
+\@@_tex_primitive:nnn { moveleft } { hmove } { 1 }
+\@@_tex_primitive:nnn { lower } { vmove } { 0 }
+\@@_tex_primitive:nnn { raise } { vmove } { 1 }
+\@@_tex_primitive:nnn { unhbox } { un_hbox } { 0 }
+\@@_tex_primitive:nnn { unhcopy } { un_hbox } { 1 }
+\@@_tex_primitive:nnn { unvbox } { un_vbox } { 0 }
+\@@_tex_primitive:nnn { unvcopy } { un_vbox } { 1 }
+\@@_tex_primitive:nnn { pagediscards } { un_vbox } { 2 }
+\@@_tex_primitive:nnn { splitdiscards } { un_vbox } { 3 }
+\@@_tex_primitive:nnn { unpenalty } { remove_item } { 12 }
+\@@_tex_primitive:nnn { unkern } { remove_item } { 11 }
+\@@_tex_primitive:nnn { unskip } { remove_item } { 10 }
+\@@_tex_primitive:nnn { hfil } { hskip } { 0 }
+\@@_tex_primitive:nnn { hfill } { hskip } { 1 }
+\@@_tex_primitive:nnn { hss } { hskip } { 2 }
+\@@_tex_primitive:nnn { hfilneg } { hskip } { 3 }
+\@@_tex_primitive:nnn { hskip } { hskip } { 4 }
+\@@_tex_primitive:nnn { vfil } { vskip } { 0 }
+\@@_tex_primitive:nnn { vfill } { vskip } { 1 }
+\@@_tex_primitive:nnn { vss } { vskip } { 2 }
+\@@_tex_primitive:nnn { vfilneg } { vskip } { 3 }
+\@@_tex_primitive:nnn { vskip } { vskip } { 4 }
+\@@_tex_primitive:nnn { mskip } { mskip } { 5 }
+\@@_tex_primitive:nnn { kern } { kern } { 1 }
+\@@_tex_primitive:nnn { mkern } { mkern } { 99 }
+\@@_tex_primitive:nnn { shipout } { leader_ship } { 99 }
+\@@_tex_primitive:nnn { leaders } { leader_ship } { 100 }
+\@@_tex_primitive:nnn { cleaders } { leader_ship } { 101 }
+\@@_tex_primitive:nnn { xleaders } { leader_ship } { 102 }
+\@@_tex_primitive:nnn { halign } { halign } { 0 }
+\@@_tex_primitive:nnn { valign } { valign } { 0 }
+\@@_tex_primitive:nnn { beginL } { valign } { 4 }
+\@@_tex_primitive:nnn { endL } { valign } { 5 }
+\@@_tex_primitive:nnn { beginR } { valign } { 8 }
+\@@_tex_primitive:nnn { endR } { valign } { 9 }
+\@@_tex_primitive:nnn { noalign } { no_align } { 0 }
+\@@_tex_primitive:nnn { vrule } { vrule } { 0 }
+\@@_tex_primitive:nnn { hrule } { hrule } { 0 }
+\@@_tex_primitive:nnn { insert } { insert } { 0 }
+\@@_tex_primitive:nnn { vadjust } { vadjust } { 0 }
+\@@_tex_primitive:nnn { ignorespaces } { ignore_spaces } { 0 }
+\@@_tex_primitive:nnn { afterassignment } { after_assignment } { 0 }
+\@@_tex_primitive:nnn { aftergroup } { after_group } { 0 }
+\@@_tex_primitive:nnn { penalty } { break_penalty } { 0 }
+\@@_tex_primitive:nnn { indent } { start_par } { 1 }
+\@@_tex_primitive:nnn { noindent } { start_par } { 0 }
+\@@_tex_primitive:nnn { quitvmode } { start_par } { 2 }
+\@@_tex_primitive:nnn { / } { ital_corr } { 0 }
+\@@_tex_primitive:nnn { accent } { accent } { 0 }
+\@@_tex_primitive:nnn { mathaccent } { math_accent } { 0 }
+\@@_tex_primitive:nnn { - } { discretionary } { 1 }
+\@@_tex_primitive:nnn { discretionary } { discretionary } { 0 }
+\@@_tex_primitive:nnn { eqno } { eq_no } { 0 }
+\@@_tex_primitive:nnn { leqno } { eq_no } { 1 }
+\@@_tex_primitive:nnn { left } { left_right } { 30 }
+\@@_tex_primitive:nnn { right } { left_right } { 31 }
+\@@_tex_primitive:nnn { middle } { left_right } { 17 }
+\@@_tex_primitive:nnn { mathord } { math_comp } { 16 }
+\@@_tex_primitive:nnn { mathop } { math_comp } { 17 }
+\@@_tex_primitive:nnn { mathbin } { math_comp } { 18 }
+\@@_tex_primitive:nnn { mathrel } { math_comp } { 19 }
+\@@_tex_primitive:nnn { mathopen } { math_comp } { 20 }
+\@@_tex_primitive:nnn { mathclose } { math_comp } { 21 }
+\@@_tex_primitive:nnn { mathpunct } { math_comp } { 22 }
+\@@_tex_primitive:nnn { mathinner } { math_comp } { 23 }
+\@@_tex_primitive:nnn { underline } { math_comp } { 26 }
+\@@_tex_primitive:nnn { overline } { math_comp } { 27 }
+\@@_tex_primitive:nnn { displaylimits } { limit_switch } { 0 }
+\@@_tex_primitive:nnn { limits } { limit_switch } { 1 }
+\@@_tex_primitive:nnn { nolimits } { limit_switch } { 2 }
+\@@_tex_primitive:nnn { above } { above } { 0 }
+\@@_tex_primitive:nnn { over } { above } { 1 }
+\@@_tex_primitive:nnn { atop } { above } { 2 }
+\@@_tex_primitive:nnn { abovewithdelims } { above } { 3 }
+\@@_tex_primitive:nnn { overwithdelims } { above } { 4 }
+\@@_tex_primitive:nnn { atopwithdelims } { above } { 5 }
+\@@_tex_primitive:nnn { displaystyle } { math_style } { 0 }
+\@@_tex_primitive:nnn { textstyle } { math_style } { 2 }
+\@@_tex_primitive:nnn { scriptstyle } { math_style } { 4 }
+\@@_tex_primitive:nnn { scriptscriptstyle } { math_style } { 6 }
+\@@_tex_primitive:nnn { mathchoice } { math_choice } { 0 }
+\@@_tex_primitive:nnn { nonscript } { non_script } { 0 }
+\@@_tex_primitive:nnn { vcenter } { vcenter } { 0 }
+\@@_tex_primitive:nnn { lowercase } { case_shift } { 256 }
+\@@_tex_primitive:nnn { uppercase } { case_shift } { 512 }
+\@@_tex_primitive:nnn { message } { message } { 0 }
+\@@_tex_primitive:nnn { errmessage } { message } { 1 }
+\@@_tex_primitive:nnn { openout } { extension } { 0 }
+\@@_tex_primitive:nnn { write } { extension } { 1 }
+\@@_tex_primitive:nnn { closeout } { extension } { 2 }
+\@@_tex_primitive:nnn { special } { extension } { 3 }
+\@@_tex_primitive:nnn { immediate } { extension } { 4 }
+\@@_tex_primitive:nnn { setlanguage } { extension } { 5 }
+\@@_tex_primitive:nnn { pdfliteral } { extension } { 6 }
+\@@_tex_primitive:nnn { pdfobj } { extension } { 7 }
+\@@_tex_primitive:nnn { pdfrefobj } { extension } { 8 }
+\@@_tex_primitive:nnn { pdfxform } { extension } { 9 }
+\@@_tex_primitive:nnn { pdfrefxform } { extension } { 10 }
+\@@_tex_primitive:nnn { pdfximage } { extension } { 11 }
+\@@_tex_primitive:nnn { pdfrefximage } { extension } { 12 }
+\@@_tex_primitive:nnn { pdfannot } { extension } { 13 }
+\@@_tex_primitive:nnn { pdfstartlink } { extension } { 14 }
+\@@_tex_primitive:nnn { pdfendlink } { extension } { 15 }
+\@@_tex_primitive:nnn { pdfoutline } { extension } { 16 }
+\@@_tex_primitive:nnn { pdfdest } { extension } { 17 }
+\@@_tex_primitive:nnn { pdfthread } { extension } { 18 }
+\@@_tex_primitive:nnn { pdfstartthread } { extension } { 19 }
+\@@_tex_primitive:nnn { pdfendthread } { extension } { 20 }
+\@@_tex_primitive:nnn { pdfsavepos } { extension } { 21 }
+\@@_tex_primitive:nnn { pdfinfo } { extension } { 22 }
+\@@_tex_primitive:nnn { pdfcatalog } { extension } { 23 }
+\@@_tex_primitive:nnn { pdfnames } { extension } { 24 }
+\@@_tex_primitive:nnn { pdffontattr } { extension } { 25 }
+\@@_tex_primitive:nnn { pdfincludechars } { extension } { 26 }
+\@@_tex_primitive:nnn { pdfmapfile } { extension } { 27 }
+\@@_tex_primitive:nnn { pdfmapline } { extension } { 28 }
+\@@_tex_primitive:nnn { pdftrailer } { extension } { 29 }
+\@@_tex_primitive:nnn { pdfresettimer } { extension } { 30 }
+\@@_tex_primitive:nnn { pdffontexpand } { extension } { 31 }
+\@@_tex_primitive:nnn { pdfsetrandomseed } { extension } { 32 }
+\@@_tex_primitive:nnn { pdfsnaprefpoint } { extension } { 33 }
+\@@_tex_primitive:nnn { pdfsnapy } { extension } { 34 }
+\@@_tex_primitive:nnn { pdfsnapycomp } { extension } { 35 }
+\@@_tex_primitive:nnn { pdfglyphtounicode } { extension } { 36 }
+\@@_tex_primitive:nnn { pdfcolorstack } { extension } { 37 }
+\@@_tex_primitive:nnn { pdfsetmatrix } { extension } { 38 }
+\@@_tex_primitive:nnn { pdfsave } { extension } { 39 }
+\@@_tex_primitive:nnn { pdfrestore } { extension } { 40 }
+\@@_tex_primitive:nnn { pdfnobuiltintounicode } { extension } { 41 }
+\@@_tex_primitive:nnn { openin } { in_stream } { 1 }
+\@@_tex_primitive:nnn { closein } { in_stream } { 0 }
+\@@_tex_primitive:nnn { begingroup } { begin_group } { 0 }
+\@@_tex_primitive:nnn { endgroup } { end_group } { 0 }
+\@@_tex_primitive:nnn { omit } { omit } { 0 }
+\@@_tex_primitive:nnn { ~ } { ex_space } { 0 }
+\@@_tex_primitive:nnn { noboundary } { no_boundary } { 0 }
+\@@_tex_primitive:nnn { radical } { radical } { 0 }
+\@@_tex_primitive:nnn { endcsname } { end_cs_name } { 0 }
+\@@_tex_primitive:nnn { lastpenalty } { last_item } { 0 }
+\@@_tex_primitive:nnn { lastkern } { last_item } { 1 }
+\@@_tex_primitive:nnn { lastskip } { last_item } { 2 }
+\@@_tex_primitive:nnn { lastnodetype } { last_item } { 3 }
+\@@_tex_primitive:nnn { inputlineno } { last_item } { 4 }
+\@@_tex_primitive:nnn { badness } { last_item } { 5 }
+\@@_tex_primitive:nnn { pdftexversion } { last_item } { 6 }
+\@@_tex_primitive:nnn { pdflastobj } { last_item } { 7 }
+\@@_tex_primitive:nnn { pdflastxform } { last_item } { 8 }
+\@@_tex_primitive:nnn { pdflastximage } { last_item } { 9 }
+\@@_tex_primitive:nnn { pdflastximagepages } { last_item } { 10 }
+\@@_tex_primitive:nnn { pdflastannot } { last_item } { 11 }
+\@@_tex_primitive:nnn { pdflastxpos } { last_item } { 12 }
+\@@_tex_primitive:nnn { pdflastypos } { last_item } { 13 }
+\@@_tex_primitive:nnn { pdfretval } { last_item } { 14 }
+\@@_tex_primitive:nnn { pdflastximagecolordepth } { last_item } { 15 }
+\@@_tex_primitive:nnn { pdfelapsedtime } { last_item } { 16 }
+\@@_tex_primitive:nnn { pdfshellescape } { last_item } { 17 }
+\@@_tex_primitive:nnn { pdfrandomseed } { last_item } { 18 }
+\@@_tex_primitive:nnn { pdflastlink } { last_item } { 19 }
+\@@_tex_primitive:nnn { eTeXversion } { last_item } { 20 }
+\@@_tex_primitive:nnn { currentgrouplevel } { last_item } { 21 }
+\@@_tex_primitive:nnn { currentgrouptype } { last_item } { 22 }
+\@@_tex_primitive:nnn { currentiflevel } { last_item } { 23 }
+\@@_tex_primitive:nnn { currentiftype } { last_item } { 24 }
+\@@_tex_primitive:nnn { currentifbranch } { last_item } { 25 }
+\@@_tex_primitive:nnn { gluestretchorder } { last_item } { 26 }
+\@@_tex_primitive:nnn { glueshrinkorder } { last_item } { 27 }
+\@@_tex_primitive:nnn { fontcharwd } { last_item } { 28 }
+\@@_tex_primitive:nnn { fontcharht } { last_item } { 29 }
+\@@_tex_primitive:nnn { fontchardp } { last_item } { 30 }
+\@@_tex_primitive:nnn { fontcharic } { last_item } { 31 }
+\@@_tex_primitive:nnn { parshapelength } { last_item } { 32 }
+\@@_tex_primitive:nnn { parshapeindent } { last_item } { 33 }
+\@@_tex_primitive:nnn { parshapedimen } { last_item } { 34 }
+\@@_tex_primitive:nnn { gluestretch } { last_item } { 35 }
+\@@_tex_primitive:nnn { glueshrink } { last_item } { 36 }
+\@@_tex_primitive:nnn { mutoglue } { last_item } { 37 }
+\@@_tex_primitive:nnn { gluetomu } { last_item } { 38 }
+\@@_tex_primitive:nnn { numexpr } { last_item } { 39 }
+\@@_tex_primitive:nnn { dimexpr } { last_item } { 40 }
+\@@_tex_primitive:nnn { glueexpr } { last_item } { 41 }
+\@@_tex_primitive:nnn { muexpr } { last_item } { 42 }
+\@@_tex_primitive:nnn { toks } { toks_register } { 0 }
+\@@_tex_primitive:nnn { output } { assign_toks } { 1 }
+\@@_tex_primitive:nnn { everypar } { assign_toks } { 2 }
+\@@_tex_primitive:nnn { everymath } { assign_toks } { 3 }
+\@@_tex_primitive:nnn { everydisplay } { assign_toks } { 4 }
+\@@_tex_primitive:nnn { everyhbox } { assign_toks } { 5 }
+\@@_tex_primitive:nnn { everyvbox } { assign_toks } { 6 }
+\@@_tex_primitive:nnn { everyjob } { assign_toks } { 7 }
+\@@_tex_primitive:nnn { everycr } { assign_toks } { 8 }
+\@@_tex_primitive:nnn { errhelp } { assign_toks } { 9 }
+\@@_tex_primitive:nnn { pdfpagesattr } { assign_toks } { 10 }
+\@@_tex_primitive:nnn { pdfpageattr } { assign_toks } { 11 }
+\@@_tex_primitive:nnn { pdfpageresources } { assign_toks } { 12 }
+\@@_tex_primitive:nnn { pdfpkmode } { assign_toks } { 13 }
+\@@_tex_primitive:nnn { everyeof } { assign_toks } { 14 }
+\@@_tex_primitive:nnn { pretolerance } { assign_int } { 0 }
+\@@_tex_primitive:nnn { tolerance } { assign_int } { 1 }
+\@@_tex_primitive:nnn { linepenalty } { assign_int } { 2 }
+\@@_tex_primitive:nnn { hyphenpenalty } { assign_int } { 3 }
+\@@_tex_primitive:nnn { exhyphenpenalty } { assign_int } { 4 }
+\@@_tex_primitive:nnn { clubpenalty } { assign_int } { 5 }
+\@@_tex_primitive:nnn { widowpenalty } { assign_int } { 6 }
+\@@_tex_primitive:nnn { displaywidowpenalty } { assign_int } { 7 }
+\@@_tex_primitive:nnn { brokenpenalty } { assign_int } { 8 }
+\@@_tex_primitive:nnn { binoppenalty } { assign_int } { 9 }
+\@@_tex_primitive:nnn { relpenalty } { assign_int } { 10 }
+\@@_tex_primitive:nnn { predisplaypenalty } { assign_int } { 11 }
+\@@_tex_primitive:nnn { postdisplaypenalty } { assign_int } { 12 }
+\@@_tex_primitive:nnn { interlinepenalty } { assign_int } { 13 }
+\@@_tex_primitive:nnn { doublehyphendemerits } { assign_int } { 14 }
+\@@_tex_primitive:nnn { finalhyphendemerits } { assign_int } { 15 }
+\@@_tex_primitive:nnn { adjdemerits } { assign_int } { 16 }
+\@@_tex_primitive:nnn { mag } { assign_int } { 17 }
+\@@_tex_primitive:nnn { delimiterfactor } { assign_int } { 18 }
+\@@_tex_primitive:nnn { looseness } { assign_int } { 19 }
+\@@_tex_primitive:nnn { time } { assign_int } { 20 }
+\@@_tex_primitive:nnn { day } { assign_int } { 21 }
+\@@_tex_primitive:nnn { month } { assign_int } { 22 }
+\@@_tex_primitive:nnn { year } { assign_int } { 23 }
+\@@_tex_primitive:nnn { showboxbreadth } { assign_int } { 24 }
+\@@_tex_primitive:nnn { showboxdepth } { assign_int } { 25 }
+\@@_tex_primitive:nnn { hbadness } { assign_int } { 26 }
+\@@_tex_primitive:nnn { vbadness } { assign_int } { 27 }
+\@@_tex_primitive:nnn { pausing } { assign_int } { 28 }
+\@@_tex_primitive:nnn { tracingonline } { assign_int } { 29 }
+\@@_tex_primitive:nnn { tracingmacros } { assign_int } { 30 }
+\@@_tex_primitive:nnn { tracingstats } { assign_int } { 31 }
+\@@_tex_primitive:nnn { tracingparagraphs } { assign_int } { 32 }
+\@@_tex_primitive:nnn { tracingpages } { assign_int } { 33 }
+\@@_tex_primitive:nnn { tracingoutput } { assign_int } { 34 }
+\@@_tex_primitive:nnn { tracinglostchars } { assign_int } { 35 }
+\@@_tex_primitive:nnn { tracingcommands } { assign_int } { 36 }
+\@@_tex_primitive:nnn { tracingrestores } { assign_int } { 37 }
+\@@_tex_primitive:nnn { uchyph } { assign_int } { 38 }
+\@@_tex_primitive:nnn { outputpenalty } { assign_int } { 39 }
+\@@_tex_primitive:nnn { maxdeadcycles } { assign_int } { 40 }
+\@@_tex_primitive:nnn { hangafter } { assign_int } { 41 }
+\@@_tex_primitive:nnn { floatingpenalty } { assign_int } { 42 }
+\@@_tex_primitive:nnn { globaldefs } { assign_int } { 43 }
+\@@_tex_primitive:nnn { fam } { assign_int } { 44 }
+\@@_tex_primitive:nnn { escapechar } { assign_int } { 45 }
+\@@_tex_primitive:nnn { defaulthyphenchar } { assign_int } { 46 }
+\@@_tex_primitive:nnn { defaultskewchar } { assign_int } { 47 }
+\@@_tex_primitive:nnn { endlinechar } { assign_int } { 48 }
+\@@_tex_primitive:nnn { newlinechar } { assign_int } { 49 }
+\@@_tex_primitive:nnn { language } { assign_int } { 50 }
+\@@_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 { pdfoutput } { assign_int } { 55 }
+\@@_tex_primitive:nnn { pdfcompresslevel } { assign_int } { 56 }
+\@@_tex_primitive:nnn { pdfdecimaldigits } { assign_int } { 57 }
+\@@_tex_primitive:nnn { pdfmovechars } { assign_int } { 58 }
+\@@_tex_primitive:nnn { pdfimageresolution } { assign_int } { 59 }
+\@@_tex_primitive:nnn { pdfpkresolution } { assign_int } { 60 }
+\@@_tex_primitive:nnn { pdfuniqueresname } { assign_int } { 61 }
+\@@_tex_primitive:nnn
+ { pdfoptionalwaysusepdfpagebox } { assign_int } { 62 }
+\@@_tex_primitive:nnn
+ { pdfoptionpdfinclusionerrorlevel } { assign_int } { 63 }
+\@@_tex_primitive:nnn
+ { pdfoptionpdfminorversion } { assign_int } { 64 }
+\@@_tex_primitive:nnn { pdfminorversion } { assign_int } { 64 }
+\@@_tex_primitive:nnn { pdfforcepagebox } { assign_int } { 65 }
+\@@_tex_primitive:nnn { pdfpagebox } { assign_int } { 66 }
+\@@_tex_primitive:nnn
+ { pdfinclusionerrorlevel } { assign_int } { 67 }
+\@@_tex_primitive:nnn { pdfgamma } { assign_int } { 68 }
+\@@_tex_primitive:nnn { pdfimagegamma } { assign_int } { 69 }
+\@@_tex_primitive:nnn { pdfimagehicolor } { assign_int } { 70 }
+\@@_tex_primitive:nnn { pdfimageapplygamma } { assign_int } { 71 }
+\@@_tex_primitive:nnn { pdfadjustspacing } { assign_int } { 72 }
+\@@_tex_primitive:nnn { pdfprotrudechars } { assign_int } { 73 }
+\@@_tex_primitive:nnn { pdftracingfonts } { assign_int } { 74 }
+\@@_tex_primitive:nnn { pdfobjcompresslevel } { assign_int } { 75 }
+\@@_tex_primitive:nnn
+ { pdfadjustinterwordglue } { assign_int } { 76 }
+\@@_tex_primitive:nnn { pdfprependkern } { assign_int } { 77 }
+\@@_tex_primitive:nnn { pdfappendkern } { assign_int } { 78 }
+\@@_tex_primitive:nnn { pdfgentounicode } { assign_int } { 79 }
+\@@_tex_primitive:nnn { pdfdraftmode } { assign_int } { 80 }
+\@@_tex_primitive:nnn { pdfinclusioncopyfonts } { assign_int } { 81 }
+\@@_tex_primitive:nnn { tracingassigns } { assign_int } { 82 }
+\@@_tex_primitive:nnn { tracinggroups } { assign_int } { 83 }
+\@@_tex_primitive:nnn { tracingifs } { assign_int } { 84 }
+\@@_tex_primitive:nnn { tracingscantokens } { assign_int } { 85 }
+\@@_tex_primitive:nnn { tracingnesting } { assign_int } { 86 }
+\@@_tex_primitive:nnn { predisplaydirection } { assign_int } { 87 }
+\@@_tex_primitive:nnn { lastlinefit } { assign_int } { 88 }
+\@@_tex_primitive:nnn { savingvdiscards } { assign_int } { 89 }
+\@@_tex_primitive:nnn { savinghyphcodes } { assign_int } { 90 }
+\@@_tex_primitive:nnn { TeXXeTstate } { assign_int } { 91 }
+\@@_tex_primitive:nnn { parindent } { assign_dimen } { 0 }
+\@@_tex_primitive:nnn { mathsurround } { assign_dimen } { 1 }
+\@@_tex_primitive:nnn { lineskiplimit } { assign_dimen } { 2 }
+\@@_tex_primitive:nnn { hsize } { assign_dimen } { 3 }
+\@@_tex_primitive:nnn { vsize } { assign_dimen } { 4 }
+\@@_tex_primitive:nnn { maxdepth } { assign_dimen } { 5 }
+\@@_tex_primitive:nnn { splitmaxdepth } { assign_dimen } { 6 }
+\@@_tex_primitive:nnn { boxmaxdepth } { assign_dimen } { 7 }
+\@@_tex_primitive:nnn { hfuzz } { assign_dimen } { 8 }
+\@@_tex_primitive:nnn { vfuzz } { assign_dimen } { 9 }
+\@@_tex_primitive:nnn { delimitershortfall } { assign_dimen } { 10 }
+\@@_tex_primitive:nnn { nulldelimiterspace } { assign_dimen } { 11 }
+\@@_tex_primitive:nnn { scriptspace } { assign_dimen } { 12 }
+\@@_tex_primitive:nnn { predisplaysize } { assign_dimen } { 13 }
+\@@_tex_primitive:nnn { displaywidth } { assign_dimen } { 14 }
+\@@_tex_primitive:nnn { displayindent } { assign_dimen } { 15 }
+\@@_tex_primitive:nnn { overfullrule } { assign_dimen } { 16 }
+\@@_tex_primitive:nnn { hangindent } { assign_dimen } { 17 }
+\@@_tex_primitive:nnn { hoffset } { assign_dimen } { 18 }
+\@@_tex_primitive:nnn { voffset } { assign_dimen } { 19 }
+\@@_tex_primitive:nnn { emergencystretch } { assign_dimen } { 20 }
+\@@_tex_primitive:nnn { pdfhorigin } { assign_dimen } { 21 }
+\@@_tex_primitive:nnn { pdfvorigin } { assign_dimen } { 22 }
+\@@_tex_primitive:nnn { pdfpagewidth } { assign_dimen } { 23 }
+\@@_tex_primitive:nnn { pdfpageheight } { assign_dimen } { 24 }
+\@@_tex_primitive:nnn { pdflinkmargin } { assign_dimen } { 25 }
+\@@_tex_primitive:nnn { pdfdestmargin } { assign_dimen } { 26 }
+\@@_tex_primitive:nnn { pdfthreadmargin } { assign_dimen } { 27 }
+\@@_tex_primitive:nnn { pdffirstlineheight } { assign_dimen } { 28 }
+\@@_tex_primitive:nnn { pdflastlinedepth } { assign_dimen } { 29 }
+\@@_tex_primitive:nnn { pdfeachlineheight } { assign_dimen } { 30 }
+\@@_tex_primitive:nnn { pdfeachlinedepth } { assign_dimen } { 31 }
+\@@_tex_primitive:nnn { pdfignoreddimen } { assign_dimen } { 32 }
+\@@_tex_primitive:nnn { pdfpxdimen } { assign_dimen } { 33 }
+\@@_tex_primitive:nnn { lineskip } { assign_glue } { 0 }
+\@@_tex_primitive:nnn { baselineskip } { assign_glue } { 1 }
+\@@_tex_primitive:nnn { parskip } { assign_glue } { 2 }
+\@@_tex_primitive:nnn { abovedisplayskip } { assign_glue } { 3 }
+\@@_tex_primitive:nnn { belowdisplayskip } { assign_glue } { 4 }
+\@@_tex_primitive:nnn { abovedisplayshortskip } { assign_glue } { 5 }
+\@@_tex_primitive:nnn { belowdisplayshortskip } { assign_glue } { 6 }
+\@@_tex_primitive:nnn { leftskip } { assign_glue } { 7 }
+\@@_tex_primitive:nnn { rightskip } { assign_glue } { 8 }
+\@@_tex_primitive:nnn { topskip } { assign_glue } { 9 }
+\@@_tex_primitive:nnn { splittopskip } { assign_glue } { 10 }
+\@@_tex_primitive:nnn { tabskip } { assign_glue } { 11 }
+\@@_tex_primitive:nnn { spaceskip } { assign_glue } { 12 }
+\@@_tex_primitive:nnn { xspaceskip } { assign_glue } { 13 }
+\@@_tex_primitive:nnn { parfillskip } { assign_glue } { 14 }
+\@@_tex_primitive:nnn { thinmuskip } { assign_mu_glue } { 15 }
+\@@_tex_primitive:nnn { medmuskip } { assign_mu_glue } { 16 }
+\@@_tex_primitive:nnn { thickmuskip } { assign_mu_glue } { 17 }
+\@@_tex_primitive:nnn { fontdimen } { assign_font_dimen } { 0 }
+\@@_tex_primitive:nnn { hyphenchar } { assign_font_int } { 0 }
+\@@_tex_primitive:nnn { skewchar } { assign_font_int } { 1 }
+\@@_tex_primitive:nnn { lpcode } { assign_font_int } { 2 }
+\@@_tex_primitive:nnn { rpcode } { assign_font_int } { 3 }
+\@@_tex_primitive:nnn { efcode } { assign_font_int } { 4 }
+\@@_tex_primitive:nnn { tagcode } { assign_font_int } { 5 }
+\@@_tex_primitive:nnn { pdfnoligatures } { assign_font_int } { 6 }
+\@@_tex_primitive:nnn { knbscode } { assign_font_int } { 7 }
+\@@_tex_primitive:nnn { stbscode } { assign_font_int } { 8 }
+\@@_tex_primitive:nnn { shbscode } { assign_font_int } { 9 }
+\@@_tex_primitive:nnn { knbccode } { assign_font_int } { 10 }
+\@@_tex_primitive:nnn { knaccode } { assign_font_int } { 11 }
+\@@_tex_primitive:nnn { spacefactor } { set_aux } { 102 }
+\@@_tex_primitive:nnn { prevdepth } { set_aux } { 1 }
+\@@_tex_primitive:nnn { prevgraf } { set_prev_graf } { 0 }
+\@@_tex_primitive:nnn { pagegoal } { set_page_dimen } { 0 }
+\@@_tex_primitive:nnn { pagetotal } { set_page_dimen } { 1 }
+\@@_tex_primitive:nnn { pagestretch } { set_page_dimen } { 2 }
+\@@_tex_primitive:nnn { pagefilstretch } { set_page_dimen } { 3 }
+\@@_tex_primitive:nnn { pagefillstretch } { set_page_dimen } { 4 }
+\@@_tex_primitive:nnn { pagefilllstretch } { set_page_dimen } { 5 }
+\@@_tex_primitive:nnn { pageshrink } { set_page_dimen } { 6 }
+\@@_tex_primitive:nnn { pagedepth } { set_page_dimen } { 7 }
+\@@_tex_primitive:nnn { deadcycles } { set_page_int } { 0 }
+\@@_tex_primitive:nnn { insertpenalties } { set_page_int } { 1 }
+\@@_tex_primitive:nnn { interactionmode } { set_page_int } { 2 }
+\@@_tex_primitive:nnn { wd } { set_box_dimen } { 1 }
+\@@_tex_primitive:nnn { dp } { set_box_dimen } { 2 }
+\@@_tex_primitive:nnn { ht } { set_box_dimen } { 3 }
+\@@_tex_primitive:nnn { parshape } { set_shape } { 0 }
+\@@_tex_primitive:nnn { interlinepenalties } { set_shape } { 1 }
+\@@_tex_primitive:nnn { clubpenalties } { set_shape } { 2 }
+\@@_tex_primitive:nnn { widowpenalties } { set_shape } { 3 }
+\@@_tex_primitive:nnn { displaywidowpenalties } { set_shape } { 4 }
+\@@_tex_primitive:nnn { catcode } { def_code } { 0 }
+\@@_tex_primitive:nnn { lccode } { def_code } { 256 }
+\@@_tex_primitive:nnn { uccode } { def_code } { 512 }
+\@@_tex_primitive:nnn { sfcode } { def_code } { 768 }
+\@@_tex_primitive:nnn { mathcode } { def_code } { 1024 }
+\@@_tex_primitive:nnn { delcode } { def_code } { 1591 }
+\@@_tex_primitive:nnn { textfont } { def_family } { -48 }
+\@@_tex_primitive:nnn { scriptfont } { def_family } { -32 }
+\@@_tex_primitive:nnn { scriptscriptfont } { def_family } { -16 }
+\@@_tex_primitive:nnn { nullfont } { set_font } { 0 }
+\@@_tex_primitive:nnn { font } { def_font } { 0 }
+\@@_tex_primitive:nnn { count } { register } { 1 000 000 }
+\@@_tex_primitive:nnn { dimen } { register } { 2 000 000 }
+\@@_tex_primitive:nnn { skip } { register } { 3 000 000 }
+\@@_tex_primitive:nnn { muskip } { register } { 4 000 000 }
+\@@_tex_primitive:nnn { advance } { advance } { 0 }
+\@@_tex_primitive:nnn { multiply } { multiply } { 0 }
+\@@_tex_primitive:nnn { divide } { divide } { 0 }
+\@@_tex_primitive:nnn { long } { prefix } { 1 }
+\@@_tex_primitive:nnn { outer } { prefix } { 2 }
+\@@_tex_primitive:nnn { global } { prefix } { 4 }
+\@@_tex_primitive:nnn { protected } { prefix } { 8 }
+\@@_tex_primitive:nnn { let } { let } { 0 }
+\@@_tex_primitive:nnn { futurelet } { let } { 1 }
+\@@_tex_primitive:nnn { chardef } { shorthand_def } { 0 }
+\@@_tex_primitive:nnn { mathchardef } { shorthand_def } { 1 }
+\@@_tex_primitive:nnn { countdef } { shorthand_def } { 2 }
+\@@_tex_primitive:nnn { dimendef } { shorthand_def } { 3 }
+\@@_tex_primitive:nnn { skipdef } { shorthand_def } { 4 }
+\@@_tex_primitive:nnn { muskipdef } { shorthand_def } { 5 }
+\@@_tex_primitive:nnn { toksdef } { shorthand_def } { 6 }
+\@@_tex_primitive:nnn { read } { read_to_cs } { 0 }
+\@@_tex_primitive:nnn { readline } { read_to_cs } { 1 }
+\@@_tex_primitive:nnn { def } { def } { 0 }
+\@@_tex_primitive:nnn { gdef } { def } { 1 }
+\@@_tex_primitive:nnn { edef } { def } { 2 }
+\@@_tex_primitive:nnn { xdef } { def } { 3 }
+\@@_tex_primitive:nnn { setbox } { set_box } { 0 }
+\@@_tex_primitive:nnn { hyphenation } { hyph_data } { 0 }
+\@@_tex_primitive:nnn { patterns } { hyph_data } { 1 }
+\@@_tex_primitive:nnn { batchmode } { set_interaction } { 0 }
+\@@_tex_primitive:nnn { nonstopmode } { set_interaction } { 1 }
+\@@_tex_primitive:nnn { scrollmode } { set_interaction } { 2 }
+\@@_tex_primitive:nnn { errorstopmode } { set_interaction } { 3 }
+\@@_tex_primitive:nnn { letterspacefont } { letterspace_font } { 0 }
+\@@_tex_primitive:nnn { pdfcopyfont } { pdf_copy_font } { 0 }
+\@@_tex_primitive:nnn { undefined } { undefined_cs } { 0 }
+\@@_tex_primitive:nnn { ndefined } { undefined_cs } { 0 }
+\@@_tex_primitive:nnn { expandafter } { expand_after } { 0 }
+\@@_tex_primitive:nnn { unless } { expand_after } { 1 }
+\@@_tex_primitive:nnn { pdfprimitive } { no_expand } { 1 }
+\@@_tex_primitive:nnn { noexpand } { no_expand } { 0 }
+\@@_tex_primitive:nnn { input } { input } { 0 }
+\@@_tex_primitive:nnn { endinput } { input } { 1 }
+\@@_tex_primitive:nnn { scantokens } { input } { 2 }
+\@@_tex_primitive:nnn { if } { if_test } { 0 }
+\@@_tex_primitive:nnn { ifcat } { if_test } { 1 }
+\@@_tex_primitive:nnn { ifnum } { if_test } { 2 }
+\@@_tex_primitive:nnn { ifdim } { if_test } { 3 }
+\@@_tex_primitive:nnn { ifodd } { if_test } { 4 }
+\@@_tex_primitive:nnn { ifvmode } { if_test } { 5 }
+\@@_tex_primitive:nnn { ifhmode } { if_test } { 6 }
+\@@_tex_primitive:nnn { ifmmode } { if_test } { 7 }
+\@@_tex_primitive:nnn { ifinner } { if_test } { 8 }
+\@@_tex_primitive:nnn { ifvoid } { if_test } { 9 }
+\@@_tex_primitive:nnn { ifhbox } { if_test } { 10 }
+\@@_tex_primitive:nnn { ifvbox } { if_test } { 11 }
+\@@_tex_primitive:nnn { ifx } { if_test } { 12 }
+\@@_tex_primitive:nnn { ifeof } { if_test } { 13 }
+\@@_tex_primitive:nnn { iftrue } { if_test } { 14 }
+\@@_tex_primitive:nnn { iffalse } { if_test } { 15 }
+\@@_tex_primitive:nnn { ifcase } { if_test } { 16 }
+\@@_tex_primitive:nnn { ifdefined } { if_test } { 17 }
+\@@_tex_primitive:nnn { ifcsname } { if_test } { 18 }
+\@@_tex_primitive:nnn { iffontchar } { if_test } { 19 }
+\@@_tex_primitive:nnn { ifincsname } { if_test } { 20 }
+\@@_tex_primitive:nnn { ifpdfprimitive } { if_test } { 21 }
+\@@_tex_primitive:nnn { ifpdfabsnum } { if_test } { 22 }
+\@@_tex_primitive:nnn { ifpdfabsdim } { if_test } { 23 }
+\@@_tex_primitive:nnn { fi } { fi_or_else } { 2 }
+\@@_tex_primitive:nnn { else } { fi_or_else } { 3 }
+\@@_tex_primitive:nnn { or } { fi_or_else } { 4 }
+\@@_tex_primitive:nnn { csname } { cs_name } { 0 }
+\@@_tex_primitive:nnn { number } { convert } { 0 }
+\@@_tex_primitive:nnn { romannumeral } { convert } { 1 }
+\@@_tex_primitive:nnn { string } { convert } { 2 }
+\@@_tex_primitive:nnn { meaning } { convert } { 3 }
+\@@_tex_primitive:nnn { fontname } { convert } { 4 }
+\@@_tex_primitive:nnn { eTeXrevision } { convert } { 5 }
+\@@_tex_primitive:nnn { pdftexrevision } { convert } { 6 }
+\@@_tex_primitive:nnn { pdftexbanner } { convert } { 7 }
+\@@_tex_primitive:nnn { pdffontname } { convert } { 8 }
+\@@_tex_primitive:nnn { pdffontobjnum } { convert } { 9 }
+\@@_tex_primitive:nnn { pdffontsize } { convert } { 10 }
+\@@_tex_primitive:nnn { pdfpageref } { convert } { 11 }
+\@@_tex_primitive:nnn { pdfxformname } { convert } { 12 }
+\@@_tex_primitive:nnn { pdfescapestring } { convert } { 13 }
+\@@_tex_primitive:nnn { pdfescapename } { convert } { 14 }
+\@@_tex_primitive:nnn { leftmarginkern } { convert } { 15 }
+\@@_tex_primitive:nnn { rightmarginkern } { convert } { 16 }
+\@@_tex_primitive:nnn { pdfstrcmp } { convert } { 17 }
+\@@_tex_primitive:nnn { pdfcolorstackinit } { convert } { 18 }
+\@@_tex_primitive:nnn { pdfescapehex } { convert } { 19 }
+\@@_tex_primitive:nnn { pdfunescapehex } { convert } { 20 }
+\@@_tex_primitive:nnn { pdfcreationdate } { convert } { 21 }
+\@@_tex_primitive:nnn { pdffilemoddate } { convert } { 22 }
+\@@_tex_primitive:nnn { pdffilesize } { convert } { 23 }
+\@@_tex_primitive:nnn { pdfmdfivesum } { convert } { 24 }
+\@@_tex_primitive:nnn { pdffiledump } { convert } { 25 }
+\@@_tex_primitive:nnn { pdfmatch } { convert } { 26 }
+\@@_tex_primitive:nnn { pdflastmatch } { convert } { 27 }
+\@@_tex_primitive:nnn { pdfuniformdeviate } { convert } { 28 }
+\@@_tex_primitive:nnn { pdfnormaldeviate } { convert } { 29 }
+\@@_tex_primitive:nnn { pdfinsertht } { convert } { 30 }
+\@@_tex_primitive:nnn { pdfximagebbox } { convert } { 31 }
+\@@_tex_primitive:nnn { jobname } { convert } { 32 }
+\@@_tex_primitive:nnn { the } { the } { 0 }
+\@@_tex_primitive:nnn { unexpanded } { the } { 1 }
+\@@_tex_primitive:nnn { detokenize } { the } { 5 }
+\@@_tex_primitive:nnn { topmark } { top_bot_mark } { 0 }
+\@@_tex_primitive:nnn { firstmark } { top_bot_mark } { 1 }
+\@@_tex_primitive:nnn { botmark } { top_bot_mark } { 2 }
+\@@_tex_primitive:nnn { splitfirstmark } { top_bot_mark } { 3 }
+\@@_tex_primitive:nnn { splitbotmark } { top_bot_mark } { 4 }
+\@@_tex_primitive:nnn { topmarks } { top_bot_mark } { 5 }
+\@@_tex_primitive:nnn { firstmarks } { top_bot_mark } { 6 }
+\@@_tex_primitive:nnn { botmarks } { top_bot_mark } { 7 }
+\@@_tex_primitive:nnn { splitfirstmarks } { top_bot_mark } { 8 }
+\@@_tex_primitive:nnn { splitbotmarks } { top_bot_mark } { 9 }
+% \end{macrocode}
+%
+% \subsection{Get next token}
+%
+% We define here two functions which fetch the next token in the token
+% list.
+% \begin{itemize}
+% \item \cs{@@_get_next:} sets \cs{l_@@_head_gtl}, \cs{l_@@_head_token},
+% and if possible \cs{l_@@_head_tl} (otherwise it is cleared).
+% \item \cs{@@_get_token:} additionally sets \cs{l_@@_head_cmd_int} and
+% \cs{l_@@_head_char_int}.
+% \end{itemize}
+% The latter is based on \cs{@@_set_cmd:} which derives the
+% \cs{l_@@_head_cmd_int} and \cs{l_@@_head_char_int} from
+% \cs{l_@@_head_token}.
+%
+% \begin{macro}[int]{\@@_get_next:}
+% \begin{macro}[aux]{\@@_get_next_aux:w}
+% If the input is empty, forcefully exit. Otherwise,
+% remove the first token in the input, and store it in
+% \cs{l_@@_head_gtl}. Set \cs{l_@@_head_token} equal in meaning to
+% that first token. Then set \cs{l_@@_head_tl} to contain the token,
+% unless it is a begin-group or end-group character, in which case
+% this token list is emptied.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_get_next:
+ {
+ \@@_input_if_empty:TF
+ { \@@_exit:w }
+ {
+ \@@_input_gpop:N \l_@@_head_gtl
+ \gtl_head_do:NN \l_@@_head_gtl \@@_get_next_aux:w
+ \gtl_if_tl:NTF \l_@@_head_gtl
+ {
+ \tl_set:Nx \l_@@_head_tl
+ { \gtl_head:N \l_@@_head_gtl }
+ }
+ { \tl_clear:N \l_@@_head_tl }
+ }
+ }
+\cs_new_protected_nopar:Npn \@@_get_next_aux:w
+ { \cs_set_eq:NN \l_@@_head_token }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_get_token:}
+% Call \cs{@@_get_next:} to set \cs{l_@@_head_gtl}, \cs{l_@@_head_tl}
+% and \cs{l_@@_head_token}, then call \cs{@@_set_cmd:} to set
+% \cs{l_@@_head_cmd_int} and \cs{l_@@_head_char_int}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_get_token:
+ {
+ \@@_get_next:
+ \@@_set_cmd:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_set_cmd:}
+% After the call to \cs{@@_get_next:}, we find the command code
+% \cs{l_@@_head_cmd_int} and the character code
+% \cs{l_@@_head_char_int}, based only on \cs{l_@@_head_token}. First
+% set \cs{l_@@_head_meaning_tl} from the \tn{meaning} of the first
+% token. If the corresponding primitive exists, use the information
+% to set the two integers. If the token is expandable, it can either
+% be a macro or be a primitive that we somehow do not know
+% (\emph{e.g.}, an expandable \XeTeX{} or \LuaTeX{} primitive
+% perhaps). Otherwise, it can be a control sequence or a character.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_set_cmd:
+ {
+ \@@_set_cmd_aux_meaning:
+ \@@_set_cmd_aux_primitive:oTF { \l_@@_head_meaning_tl }
+ { }
+ {
+ \@@_token_if_expandable:NTF \l_@@_head_token
+ {
+ \token_if_macro:NTF \l_@@_head_token
+ { \@@_set_cmd_aux_macro: }
+ { \@@_set_cmd_aux_unknown: }
+ }
+ {
+ \token_if_cs:NTF \l_@@_head_token
+ { \@@_set_cmd_aux_cs: }
+ { \@@_set_cmd_aux_char: }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_set_cmd_aux_meaning:}
+% \begin{macro}[aux,EXP]{\@@_set_cmd_aux_meaning:w}
+% Remove the leading escape character (\cs{@@_strip_escape:w} takes
+% care of special cases there) from the \tn{meaning} of the first
+% token, then remove anything after the first~|:|, which is present
+% for macros, for marks, and for that character too. For any
+% primitive except \tn{nullfont}, this leaves the primitive's name.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_set_cmd_aux_meaning:
+ {
+ \tl_set:Nx \l_@@_head_meaning_tl
+ {
+ \exp_after:wN \@@_strip_escape:w
+ \token_to_meaning:N \l_@@_head_token
+ \tl_to_str:n { : }
+ }
+ \tl_set:Nx \l_@@_head_meaning_tl
+ {
+ \exp_after:wN \@@_set_cmd_aux_meaning:w
+ \l_@@_head_meaning_tl \q_stop
+ }
+ }
+\use:x
+ {
+ \cs_new:Npn \exp_not:N \@@_set_cmd_aux_meaning:w
+ ##1 \token_to_str:N : ##2 \exp_not:N \q_stop {##1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]
+% {\@@_set_cmd_aux_primitive:nTF, \@@_set_cmd_aux_primitive:oTF}
+% \begin{macro}[aux]{\@@_set_cmd_aux_primitive:nn}
+% Test if there is any information about the given (cleaned-up)
+% \tn{meaning}. If there is, use that as the command and character
+% integers.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_cmd_aux_primitive:nTF #1#2
+ {
+ \cs_if_exist:cTF { c_@@_tex_#1_tl }
+ {
+ \exp_last_unbraced:Nv \@@_set_cmd_aux_primitive:nn
+ { c_@@_tex_#1_tl }
+ #2
+ }
+ }
+\cs_generate_variant:Nn \@@_set_cmd_aux_primitive:nTF { o }
+\cs_new_protected:Npn \@@_set_cmd_aux_primitive:nn #1#2
+ {
+ \int_set:Nn \l_@@_head_cmd_int {#1}
+ \int_set:Nn \l_@@_head_char_int {#2}
+ }
+% \end{macrocode}
+% \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.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_set_cmd_aux_macro:
+ {
+ \int_set:Nn \l_@@_head_cmd_int { \@@_tex_use:n { call } }
+ \int_zero:N \l_@@_head_char_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_set_cmd_aux_unknown:}
+% Complain about an unknown primitive, and consider it as if it were
+% \tn{relax}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_set_cmd_aux_unknown:
+ {
+ \exp_last_unbraced:NV \@@_set_cmd_aux_primitive:nn
+ \c_@@_tex_relax_tl
+ \msg_error:nnx { unravel } { unknown-primitive }
+ { \l_@@_head_meaning_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_set_cmd_aux_cs:}
+% If the \tn{meaning} contains \verb*|elect font|, the control
+% sequence is \tn{nullfont} or similar (note that we do not search for
+% \verb*|select font|, as the code to trim the escape character from
+% the meaning may have removed the leading~|s|). Otherwise, we expect
+% the \tn{meaning} to be \tn{char} or \tn{mathchar} followed by
+% |"|~and an uppercase hexadecimal number, or one of \tn{count},
+% \tn{dimen}, \tn{skip}, \tn{muskip} or \tn{toks} followed by a
+% decimal number.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_set_cmd_aux_cs:
+ {
+ \tl_if_in:NoTF \l_@@_head_meaning_tl
+ { \tl_to_str:n { elect~font } }
+ {
+ \exp_last_unbraced:NV \@@_set_cmd_aux_primitive:nn
+ \c_@@_tex_nullfont_tl
+ }
+ { \@@_set_cmd_aux_numeric: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]
+% {
+% \@@_set_cmd_aux_numeric:,
+% \@@_set_cmd_aux_numeric:w,
+% \@@_set_cmd_aux_given:n
+% }
+% \begin{macro}[aux,rEXP]{\@@_set_cmd_aux_numeric:N}
+% Insert \cs{q_mark} before the first non-letter (in fact, anything
+% less than~|A|) in the \tn{meaning} by looping one character at a
+% time (skipping spaces, but there should be none). We expect the
+% first part to be |char| or~|mathchar|, or one of |count|, |dimen|,
+% |skip|, |muskip|, or |toks|. In the first two cases, the command is
+% |char_given| or |math_given|. It is otherwise identical to the
+% corresponding primitive (\tn{count} \emph{etc.}). We then keep
+% track of the associated number (part after \cs{q_mark}) in
+% \cs{l_@@_head_char_int}. For unknown non-expandable primitives,
+% assuming that their meaning consists solely of letters, the
+% \cs{q_mark} is inserted at their end, and is followed by~|+0|, so
+% nothing breaks.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_set_cmd_aux_numeric:
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ \exp_after:wN \@@_set_cmd_aux_numeric:N
+ \l_@@_head_meaning_tl + 0
+ }
+ \exp_after:wN \@@_set_cmd_aux_numeric:w
+ \l_@@_tmpa_tl \q_stop
+ }
+\cs_new:Npn \@@_set_cmd_aux_numeric:N #1
+ {
+ \if_int_compare:w `#1 < `A \exp_stop_f:
+ \exp_not:N \q_mark
+ \exp_after:wN \use_i:nn
+ \fi:
+ #1 \@@_set_cmd_aux_numeric:N
+ }
+\cs_new_protected:Npn \@@_set_cmd_aux_numeric:w #1 \q_mark #2 \q_stop
+ {
+ \str_case:nnF {#1}
+ {
+ { char } { \@@_set_cmd_aux_given:n { char_given } }
+ { mathchar } { \@@_set_cmd_aux_given:n { math_given } }
+ }
+ {
+ \@@_set_cmd_aux_primitive:nTF {#1}
+ { }
+ { \@@_set_cmd_aux_unknown: }
+ \int_add:Nn \l_@@_head_char_int { 100 000 }
+ }
+ \int_add:Nn \l_@@_head_char_int {#2}
+ }
+\cs_new_protected:Npn \@@_set_cmd_aux_given:n #1
+ {
+ \int_set:Nn \l_@@_head_cmd_int { \@@_tex_use:n {#1} }
+ \int_zero:N \l_@@_head_char_int
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_set_cmd_aux_char:}
+% \begin{macro}[aux]{\@@_set_cmd_aux_char:w}
+% At this point, the \tn{meaning} token list has been shortened by the
+% code meant to remove the escape character. We thus set it again to
+% the \tn{meaning} of the leading token. The command is then the
+% first word (delimited by a space) of the \tn{meaning}, followed by
+% |_char|, except for category other, where we use |other_char|. For
+% the character code, there is a need to expand
+% \cs{@@_token_to_char:N} before placing~|`|.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_set_cmd_aux_char:
+ {
+ \tl_set:Nx \l_@@_head_meaning_tl
+ { \token_to_meaning:N \l_@@_head_token }
+ \token_if_eq_catcode:NNT \l_@@_head_token \c_catcode_other_token
+ { \tl_set:Nn \l_@@_head_meaning_tl { other~ } }
+ \exp_after:wN \@@_set_cmd_aux_char:w
+ \l_@@_head_meaning_tl \q_stop
+ \exp_args:NNx \int_set:Nn \l_@@_head_char_int
+ { ` \@@_token_to_char:N \l_@@_head_token }
+ }
+\cs_new_protected:Npn \@@_set_cmd_aux_char:w #1 ~ #2 \q_stop
+ {
+ \int_set:Nn \l_@@_head_cmd_int
+ { \@@_tex_use:n { #1_char } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Manipulating the input}
+%
+% \subsubsection{Elementary operations}
+%
+% \begin{macro}[int,rEXP]{\@@_input_to_str:}
+% Map \cs{gtl_to_str:c} through the input stack.
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_input_to_str:
+ {
+ \int_step_function:nnnN \g_@@_input_int { -1 } { 1 }
+ \@@_input_to_str_aux:n
+ }
+\cs_new:Npn \@@_input_to_str_aux:n #1
+ { \gtl_to_str:c { g_@@_input_#1_gtl } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_input_if_empty:TF}
+% If the input stack is empty, the input contains no token.
+% Otherwise, check the top of the stack for tokens: if there are, then
+% the input is non-empty, and if there are none, then we get rid of
+% the top of stack and loop.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_input_if_empty:TF
+ {
+ \int_compare:nNnTF \g_@@_input_int = \c_zero
+ { \use_i:nn }
+ {
+ \gtl_if_empty:cTF
+ { g_@@_input_ \int_use:N \g_@@_input_int _gtl }
+ {
+ \int_gdecr:N \g_@@_input_int
+ \@@_input_if_empty:TF
+ }
+ {
+ \@@_input_split:
+ \use_ii:nn
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: "timeit" 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
+% an |N|-type token, try to unflatten it by splitting at each
+% occurence of that first character
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_input_split:
+ {
+ \int_compare:nNnT \g_@@_input_int = \c_one
+ {
+ \exp_args:Nc \@@_input_split_aux:N
+ { g_@@_input_1_gtl }
+ }
+ }
+\cs_new_protected:Npn \@@_input_split_aux:N #1
+ {
+ \gtl_if_tl:NT #1
+ {
+ \gtl_if_head_is_N_type:NT #1
+ {
+ \tl_set:Nx \l_@@_input_tmpa_tl { \gtl_left_tl:N #1 }
+ \exp_last_unbraced:Nx \@@_input_split_auxii:N
+ { \tl_head:N \l_@@_input_tmpa_tl }
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_input_split_auxii:N #1
+ {
+ \token_if_parameter:NF #1
+ {
+ \tl_replace_all:Nnn \l_@@_input_tmpa_tl {#1}
+ { \@@_input_split_end: \@@_input_split_auxiii:w #1 }
+ \group_begin:
+ \cs_set:Npn \@@_input_split_auxiii:w
+ ##1 \@@_input_split_end: { + 1 }
+ \int_gset:Nn \g_@@_input_int
+ { 0 \l_@@_input_tmpa_tl \@@_input_split_end: }
+ \group_end:
+ \int_gset_eq:NN \g_@@_input_tmpa_int \g_@@_input_int
+ \l_@@_input_tmpa_tl \@@_input_split_end:
+ }
+ }
+\cs_new_nopar:Npn \@@_input_split_end: { }
+\cs_new_protected:Npn \@@_input_split_auxiii:w
+ #1 \@@_input_split_end:
+ {
+ \gtl_gset:cn
+ { g_@@_input_ \int_use:N \g_@@_input_tmpa_int _gtl } {#1}
+ \int_gdecr:N \g_@@_input_tmpa_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_input_gset:n}
+% At first, all of the input is in the same~\texttt{gtl}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_input_gset:n
+ {
+ \int_gset_eq:NN \g_@@_input_int \c_one
+ \gtl_gset:cn { g_@@_input_1_gtl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_input_get:N}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_input_get:N #1
+ {
+ \@@_input_if_empty:TF
+ { \gtl_set:Nn #1 { \q_no_value } }
+ {
+ \gtl_get_left:cN
+ { g_@@_input_ \int_use:N \g_@@_input_int _gtl } #1
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_input_gpop:N}
+% Call \cs{@@_input_if_empty:TF} to remove empty levels from the input
+% stack, then extract the first token from the left-most non-empty
+% level.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_input_gpop:N #1
+ {
+ \@@_input_if_empty:TF
+ { \gtl_set:Nn #1 { \q_no_value } }
+ {
+ \gtl_gpop_left:cN
+ { g_@@_input_ \int_use:N \g_@@_input_int _gtl } #1
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_input_merge:}
+% Merge the top two levels of input. This requires, but does not
+% check, that \cs{g_@@_input_int} is at least~$2$.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_input_merge:
+ {
+ \int_gdecr:N \g_@@_input_int
+ \gtl_gconcat:ccc
+ { g_@@_input_ \int_use:N \g_@@_input_int _gtl }
+ { g_@@_input_ \int_eval:n { \g_@@_input_int + 1 } _gtl }
+ { g_@@_input_ \int_use:N \g_@@_input_int _gtl }
+ \gtl_gclear:c
+ { g_@@_input_ \int_eval:n { \g_@@_input_int + 1 } _gtl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int,TF]{\@@_input_gpop_item:N}
+% \begin{macro}[aux]{\@@_input_gpop_item_aux:NN}
+% If there is no input, we cannot pop an item. Othewise, try to pop
+% from the top of the input stack. If this succeeds, or if this
+% failed and the top of stack has extra end-group characters, or if
+% the input stack contains only the top-most item, then the answer
+% given by \cs{gtl_gpop_left_item:NNTF} is the correct one, which we
+% return. Otherwise, merge the top two levels and repeat.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_input_gpop_item:N #1 { F }
+ {
+ \int_compare:nNnTF \g_@@_input_int = \c_zero
+ { \prg_return_false: }
+ {
+ \exp_args:Nc \@@_input_gpop_item_aux:NN
+ { g_@@_input_ \int_use:N \g_@@_input_int _gtl } #1
+ }
+ }
+\cs_new_protected:Npn \@@_input_gpop_item_aux:NN #1#2
+ {
+ \gtl_gpop_left_item:NNTF #1#2
+ { \prg_return_true: }
+ {
+ \int_compare:nNnTF { \gtl_extra_end:N #1 } > \c_zero
+ { \prg_return_false: }
+ {
+ \int_compare:nNnTF \g_@@_input_int = \c_one
+ { \prg_return_false: }
+ {
+ \@@_input_merge:
+ \exp_args:Nc \@@_input_gpop_item_aux:NN
+ {
+ g_@@_input_
+ \int_use:N \g_@@_input_int _gtl
+ }
+ #2
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_input_gpop_tl:N}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_input_gpop_tl:N #1
+ { \tl_clear:N #1 \@@_input_gpop_tl_aux:N #1 }
+\cs_new_protected:Npn \@@_input_gpop_tl_aux:N #1
+ {
+ \int_compare:nNnF \g_@@_input_int = \c_zero
+ {
+ \exp_args:Nc \@@_input_gpop_tl_aux:NN
+ { g_@@_input_ \int_use:N \g_@@_input_int _gtl } #1
+ }
+ }
+\cs_new_protected:Npn \@@_input_gpop_tl_aux:NN #1#2
+ {
+ \gtl_if_tl:NTF #1
+ {
+ \tl_put_right:Nx #2 { \gtl_left_tl:N #1 }
+ \gtl_gclear:N #1
+ \int_gdecr:N \g_@@_input_int
+ \@@_input_gpop_tl_aux:N #2
+ }
+ {
+ \int_compare:nNnTF \g_@@_input_int > \c_one
+ { \int_compare:nNnTF { \gtl_extra_end:N #1 } > \c_zero }
+ { \use_i:nn }
+ {
+ \tl_put_right:Nx #2 { \gtl_left_tl:N #1 }
+ \gtl_gpop_left_tl:N #1
+ }
+ {
+ \@@_input_merge:
+ \@@_input_gpop_tl_aux:N #2
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_back_input:n, \@@_back_input:x}
+% Insert a token list back into the input.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_back_input:n
+ {
+ \int_gincr:N \g_@@_input_int
+ \gtl_gset:cn { g_@@_input_ \int_use:N \g_@@_input_int _gtl }
+ }
+\cs_generate_variant:Nn \@@_back_input:n { x , V , o }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_back_input_gtl:N}
+% Insert a generalized token list back into the input.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_back_input_gtl:N #1
+ {
+ \gtl_if_tl:NTF #1
+ { \@@_back_input:x { \gtl_left_tl:N #1 } }
+ {
+ \gtl_gconcat:cNc
+ { g_@@_input_ \int_use:N \g_@@_input_int _gtl }
+ #1
+ { g_@@_input_ \int_use:N \g_@@_input_int _gtl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_back_input:}
+% Insert the last token read back into the input stream.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_back_input:
+ { \@@_back_input_gtl:N \l_@@_head_gtl }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_back_input_tl_o:}
+% Insert the \cs{l_@@_head_tl} (may or may not be the last token read)
+% back into the input stream, after expanding it once. Then print
+% some diagnostic information.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_back_input_tl_o:
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ { \exp_args:NV \exp_not:o \l_@@_head_tl }
+ \@@_back_input:V \l_@@_tmpa_tl
+ \@@_print_done:x
+ { \tl_to_str:N \l_@@_head_tl = \tl_to_str:N \l_@@_tmpa_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Insert token for error recovery}
+%
+% \begin{macro}[int]{\@@_insert_relax:}
+% This function inserts \TeX{}'s |frozen_relax|. It is called when a
+% conditional is not done finding its condition, but hits the
+% corresponding \tn{fi} or \tn{or} or \tn{else}, or when \tn{input}
+% appears while \cs{g_@@_name_in_progress_bool} is \texttt{true}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_insert_relax:
+ {
+ \@@_back_input:
+ \gtl_set_eq:NN \l_@@_head_gtl \c_@@_frozen_relax_gtl
+ \@@_back_input:
+ \@@_print_action:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_insert_group_begin_error:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_insert_group_begin_error:
+ {
+ \msg_error:nn { unravel } { missing-lbrace }
+ \@@_back_input:
+ \gtl_set_eq:NN \l_@@_head_gtl \c_group_begin_gtl
+ \@@_back_input:
+ \@@_print_action:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_insert_dollar_error:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_insert_dollar_error:
+ {
+ \@@_back_input:
+ \@@_back_input:n { $ } % $
+ \msg_error:nn { unravel } { missing-dollar }
+ \@@_print_action:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Macro calls}
+%
+% \begin{macro}[aux,EXP]
+% {
+% \@@_macro_prefix:N,
+% \@@_macro_parameter:N,
+% \@@_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:
+\cs_new:Npn \@@_macro_prefix:N #1
+ { \@@_macro_split_do:NN #1 \use_i:nnn }
+\cs_new:Npn \@@_macro_parameter:N #1
+ { \@@_macro_split_do:NN #1 \use_ii:nnn }
+\cs_new:Npn \@@_macro_replacement:N #1
+ { \@@_macro_split_do:NN #1 \use_iii:nnn }
+% \end{macrocode}
+% \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
+% }
+% Macros are simply expanded once. We cannot determine precisely
+% which tokens a macro will need for its parameters, but we know that
+% it must form a balanced token list. Thus we can be safe by
+% extracting the longest balanced prefix in the input and working with
+% that.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_macro_call:
+ {
+ \bool_if:NTF \g_@@_speedup_macros_bool
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ {^ \exp_after:wN \@@_macro_parameter:N \l_@@_head_tl }
+ \tl_if_in:NVTF \c_@@_parameters_tl \l_@@_tmpa_tl
+ { \@@_macro_call_quick: } { \@@_macro_call_safe: }
+ }
+ { \@@_macro_call_safe: }
+ \exp_args:NV \@@_back_input:o \l_@@_head_tl
+ \@@_print_done:x { \g_@@_action_text_str }
+ }
+\cs_new_protected_nopar:Npn \@@_macro_call_safe:
+ {
+ \@@_input_gpop_tl:N \l_@@_tmpa_tl
+ \tl_put_right:NV \l_@@_head_tl \l_@@_tmpa_tl
+ }
+\cs_new_protected_nopar:Npn \@@_macro_call_quick:
+ {
+ \exp_after:wN \@@_macro_call_quick_loop:NN \l_@@_tmpa_tl
+ { ? \use_none_delimit_by_q_stop:w } \q_stop
+ }
+\cs_new_protected_nopar:Npn \@@_macro_call_quick_loop:NN #1#2
+ {
+ \use_none:n #2
+ \@@_input_gpop_item:NF \l_@@_tmpa_tl
+ { \msg_error:nn { unravel } { runaway-macro-parameter } }
+ \tl_put_right:Nx \l_@@_head_tl
+ { { \exp_not:V \l_@@_tmpa_tl } }
+ \@@_macro_call_quick_loop:NN
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Expand next token}
+%
+% \begin{macro}[int]{\@@_expand:}
+% This is similar to \cs{@@_do_step:}, but operates on expandable
+% tokens rather than (non-expandable) commands. We mimick \TeX{}'s
+% structure, distinguishing macros from other commands (not quite sure
+% why).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_expand:
+ {
+ \@@_set_action_text:
+ \bool_if:NT \l_@@_debug_bool
+ {
+ \@@_set_cmd:
+ \iow_term:x { Exp:~\int_use:N \l_@@_head_cmd_int }
+ }
+ \token_if_macro:NTF \l_@@_head_token
+ { \@@_macro_call: }
+ { \@@_expand_nonmacro: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_expand_nonmacro:}
+% The token is a primitive. We find its (cleaned-up) \tn{meaning},
+% and call the function implementing that expansion. If we do not
+% recognize the meaning then it is probably an unknown primitive. If
+% we recognize the meaning but there is no corresponding function,
+% then we probably have not implemented it yet.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_expand_nonmacro:
+ {
+ \@@_set_cmd_aux_meaning:
+ \@@_set_cmd_aux_primitive:oTF { \l_@@_head_meaning_tl }
+ {
+ \cs_if_exist_use:cF
+ { @@_expandable_ \int_use:N \l_@@_head_cmd_int : }
+ { \msg_error:nnx { unravel } { internal } { expandable } }
+ }
+ {
+ \msg_error:nnx { unravel } { unknown-primitive }
+ { \l_@@_head_meaning_tl }
+ \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl
+ \@@_print_action:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_get_x_next:}
+% Get a token. If it is expandable, then expand it, and repeat. This
+% function does not set the |cmd| and |char| integers.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_get_x_next:
+ {
+ \@@_get_next:
+ \@@_token_if_expandable:NT \l_@@_head_token
+ {
+ \@@_expand:
+ \@@_get_x_next:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_get_x_or_protected:}
+% Get a token. If it is expandable, but not protected, then expand
+% it, and repeat. This function does not set the |cmd| and |char|
+% integers.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_get_x_or_protected:
+ {
+ \@@_get_next:
+ \@@_token_if_protected:NF \l_@@_head_token
+ {
+ \@@_expand:
+ \@@_get_x_or_protected:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Basic scanning subroutines}
+%
+% ^^A todo: implement |test_no_ligatures|?
+% ^^A todo: implement |get_tag_code|?
+%
+% \begin{macro}[aux]{\@@_get_x_non_blank:}
+% This function does not set the |cmd| and |char| integers.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_get_x_non_blank:
+ {
+ \@@_get_x_next:
+ \token_if_eq_catcode:NNT \l_@@_head_token \c_space_token
+ { \@@_get_x_non_blank: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_get_x_non_relax:}
+% This function does not set the |cmd| and |char| integers.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_get_x_non_relax:
+ {
+ \@@_get_x_next:
+ \token_if_eq_meaning:NNT \l_@@_head_token \scan_stop:
+ { \@@_get_x_non_relax: }
+ {
+ \token_if_eq_catcode:NNT \l_@@_head_token \c_space_token
+ { \@@_get_x_non_relax: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_skip_optional_space:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_skip_optional_space:
+ {
+ \@@_get_x_next:
+ \token_if_eq_catcode:NNF \l_@@_head_token \c_space_token
+ { \@@_back_input: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_optional_equals:}
+% See \TeX{}'s |scan_optional_equals|. In all cases we forcefully
+% insert an equal sign in the output, because this sign is required,
+% as \cs{@@_scan_something_internal:n} leaves raw numbers in
+% \cs{g_@@_prev_input_seq}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_optional_equals:
+ {
+ \@@_get_x_non_blank:
+ \tl_if_eq:NNTF \l_@@_head_tl \c_@@_eq_tl
+ { \@@_prev_input:n { = } }
+ {
+ \@@_prev_input_silent:n { = }
+ \@@_back_input:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_scan_left_brace:}
+% The presence of \tn{relax} is allowed before a begin-group
+% character.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_left_brace:
+ {
+ \@@_get_x_non_relax:
+ \token_if_eq_catcode:NNF \l_@@_head_token \c_group_begin_token
+ { \@@_insert_group_begin_error: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_scan_keyword:n}
+% \begin{macro}[int,TF]{\@@_scan_keyword:n}
+% \begin{macro}[aux]
+% {
+% \@@_scan_keyword_loop:NNN,
+% \@@_scan_keyword_test:NNTF,
+% \@@_scan_keyword_true:,
+% \@@_scan_keyword_false:w
+% }
+%
+% The details of how \TeX{} looks for keywords are quite tricky to get
+% right, in particular with respect to expansion, case-insensitivity,
+% and spaces. We get rid of the case issue by requiring the keyword
+% to be given in both cases, intertwined: for instance,
+% \cs{@@_scan_keyword:n} |{| |pPtT| |}|. Then loop through pairs of
+% letters (which should be matching lowercase and uppercase letters).
+% The looping auxiliary takes three arguments, the first of which is a
+% boolean, \texttt{true} if spaces are allowed (no letter of the
+% keyword has been found yet). At each iteration, get a token, with
+% expansion, and test whether it is a non-active character equal (in
+% character code) to either letter of the pair: this happens if the
+% token is not ``definable'' (neither a control sequence nor an active
+% character) and it has the right string representation\ldots{} well,
+% it could also be doubled (macro parameter character), hence we look
+% at the first character only; spaces become an empty string, but this
+% works out because no keyword contains a space. So, at each
+% iteration, if the token is the correct non-active character, add it
+% to \cs{g_@@_prev_input_seq} (as a generalized token list since
+% keywords may match begin-group or end-group characters), and
+% otherwise break with \cs{@@_scan_keyword_false:w}, unless we are
+% still at the beginning of the keyword and the token is a space.
+% When the loop reaches the end of the keyword letter pairs, complain
+% if there were an odd number of letters, and otherwise conclude the
+% loop with \cs{@@_scan_keyword_true:}, which stores the keyword,
+% converted to a string. Note that \TeX{}'s skipping of leading
+% spaces here must be intertwined with the search for keyword, as is
+% shown by the (plain \TeX{}) example
+% \begin{verbatim}
+% \lccode32=`f \lowercase{\def\fspace{ }}
+% \skip0=1pt plus 1 \fspace il\relax
+% \message{\the\skip0} % => 1pt plus 1fil
+% \end{verbatim}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scan_keyword:n #1
+ { \@@_scan_keyword:nTF {#1} { } { } }
+\prg_new_protected_conditional:Npnn \@@_scan_keyword:n #1
+ { T , F , TF }
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \c_empty_gtl
+ \@@_scan_keyword_loop:NNN \c_true_bool
+ #1 \q_recursion_tail \q_recursion_tail \q_recursion_stop
+ }
+\cs_new_protected:Npn \@@_scan_keyword_loop:NNN #1#2#3
+ {
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ { \@@_scan_keyword_true: }
+ \quark_if_recursion_tail_stop_do:nn {#3}
+ { \msg_error:nnx { unravel } { internal } { odd-keyword-length } }
+ \@@_get_x_next:
+ \@@_scan_keyword_test:NNTF #2#3
+ {
+ \@@_prev_input_gtl:N \l_@@_head_gtl
+ \@@_scan_keyword_loop:NNN \c_false_bool
+ }
+ {
+ \token_if_eq_catcode:NNF \l_@@_head_token \c_space_token
+ { \@@_scan_keyword_false:w }
+ \bool_if:NF #1
+ { \@@_scan_keyword_false:w }
+ \@@_scan_keyword_loop:NNN #1#2#3
+ }
+ }
+\prg_new_protected_conditional:Npnn \@@_scan_keyword_test:NN #1#2
+ { TF }
+ {
+ \@@_gtl_if_head_is_definable:NTF \l_@@_head_gtl
+ { \prg_return_false: }
+ {
+ \str_if_eq_x:nnTF
+ { \str_head:f { \gtl_to_str:N \l_@@_head_gtl } } {#1}
+ { \prg_return_true: }
+ {
+ \str_if_eq_x:nnTF
+ { \str_head:f { \gtl_to_str:N \l_@@_head_gtl } } {#2}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \@@_scan_keyword_true:
+ {
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpb_gtl
+ \@@_prev_input:x { \gtl_to_str:N \l_@@_tmpb_gtl }
+ \prg_return_true:
+ }
+\cs_new_protected_nopar:Npn \@@_scan_keyword_false:w
+ #1 \q_recursion_stop
+ {
+ \@@_back_input:
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpb_gtl
+ \@@_back_input_gtl:N \l_@@_tmpb_gtl
+ \prg_return_false:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_font_ident:}
+% Find a font identifier.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_font_ident:
+ {
+ \@@_get_x_non_blank:
+ \@@_set_cmd:
+ \int_case:nnF \l_@@_head_cmd_int
+ {
+ { \@@_tex_use:n { def_font } }
+ { \@@_prev_input:V \l_@@_head_tl }
+ { \@@_tex_use:n { letterspace_font } }
+ { \@@_prev_input:V \l_@@_head_tl }
+ { \@@_tex_use:n { pdf_copy_font } }
+ { \@@_prev_input:V \l_@@_head_tl }
+ { \@@_tex_use:n { set_font } }
+ { \@@_prev_input:V \l_@@_head_tl }
+ { \@@_tex_use:n { def_family } }
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_int:
+ }
+ }
+ {
+ \msg_error:nn { unravel } { missing-font-id }
+ \@@_prev_input:n { \tex_nullfont:D }
+ \@@_back_error:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_font_int:}
+% Find operands for one of \tn{hyphenchar}'s friends (command code
+% |assign_font_int=78|).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_font_int:
+ {
+ \int_case:nnF \l_@@_head_char_int
+ {
+ { 0 } { \@@_scan_font_ident: }
+ { 1 } { \@@_scan_font_ident: }
+ { 6 } { \@@_scan_font_ident: }
+ }
+ { \@@_scan_font_ident: \@@_scan_int: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_font_dimen:}
+% Find operands for \tn{fontdimen}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_font_dimen:
+ {
+ \@@_scan_int:
+ \@@_scan_font_ident:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: redoc
+% ^^A todo: rename: 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:
+% \begin{itemize}
+% \item |int_val=0| for integer values;
+% \item |dimen_val=1| for dimension values;
+% \item |glue_val=2| for glue specifications;
+% \item |mu_val=3| for math glue specifications;
+% \item |ident_val=4| for font identifiers (this never happens);
+% \item |tok_val=5| for token lists.
+% \end{itemize}
+% Scans something internal, and places its value, converted to the
+% given level, to the right of the last item of
+% \cs{g_@@_prev_input_seq}, then sets \cs{g_@@_val_level_int} to the
+% found level (level before conversion, so this may be higher than
+% requested). Get in one go the information about what level is
+% produced by the given token once it has received all its operands
+% (head of \cs{l_@@_tmpa_tl}), and about what to do to find those
+% operands (tail of \cs{l_@@_tmpa_tl}). If the first token is not
+% between |min_internal=68| and |max_internal=89|, this step claims a
+% level of~$8$. If the level that will be produced is $4$ or~$5$, but
+% the argument~|#1| is not, or if the level is~$8$ (exercise: check
+% that the conditional indeed checks for this case, given that \eTeX{}
+% rounds ``to nearest, ties away from zero''), then complain.
+% Otherwise, fetch arguments if there are any: the scanning is
+% performed after placing the current token in a new level of
+% |prev_input| and telling the user about it. Once done with this
+% step, \cs{l_@@_head_tl} contains the tokens found. Convert them to
+% the wanted level with \cs{@@_thing_use:nN} (at this stage, \TeX{}
+% 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).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scan_something_internal:n #1
+ {
+ \@@_set_cmd:
+ \@@_set_action_text:
+ \tl_set:Nf \l_@@_tmpa_tl { \@@_thing_case: }
+ \exp_after:wN \@@_scan_something_aux:nwn
+ \l_@@_tmpa_tl \q_stop {#1}
+ }
+\cs_new_protected:Npn \@@_scan_something_aux:nwn #1#2 \q_stop #3
+ {
+ \int_compare:nNnTF
+ { ( #1 + \c_two ) / \c_four } > { ( #3 + \c_two ) / \c_four }
+ { \@@_back_input: }
+ {
+ \tl_if_empty:nF {#2}
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ #2
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ }
+ }
+ \tl_set:Nx \l_@@_tmpa_tl
+ { \@@_thing_use:nnN {#1} {#3} \l_@@_head_tl }
+ \@@_prev_input_silent:V \l_@@_tmpa_tl
+ \@@_set_action_text:
+ \@@_set_action_text:x
+ { \g_@@_action_text_str = ~ \tl_to_str:N \l_@@_tmpa_tl }
+ \int_compare:nNnF {#3} > { 3 } { \@@_print_action: }
+ \int_gset:Nn \g_@@_val_level_int {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux, EXP]
+% {\@@_thing_case:, \@@_thing_last_item:, \@@_thing_register:}
+% 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
+% 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
+% is~$8$, large enough so that the main function knows it is
+% forbidden.
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_thing_case:
+ {
+ \int_case:nnF \l_@@_head_cmd_int
+ {
+ { 68 } { 0 } % char_given
+ { 69 } { 0 } % math_given
+ { 70 } { \@@_thing_last_item: } % last_item
+ { 71 } { 5 \@@_scan_toks_register: } % toks_register
+ { 72 } { 5 } % assign_toks
+ { 73 } { 0 } % assign_int
+ { 74 } { 1 } % assign_dimen
+ { 75 } { 2 } % assign_glue
+ { 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
+ { 80 } { 0 } % set_prev_graf
+ { 81 } { 1 } % set_page_dimen
+ { 82 } { 0 } % set_page_int
+ { 83 } { 1 \@@_scan_int: } % set_box_dimen
+ { 84 } { 0 \@@_scan_int: } % set_shape
+ { 85 } { 0 \@@_scan_int: } % def_code
+ { 86 } { 4 \@@_scan_font_ident: } % def_family
+ { 87 } { 4 \@@_scan_font_ident: } % set_font
+ { 88 } { 4 \@@_scan_font_ident: } % def_font
+ { 89 } { \@@_thing_register: } % register
+ }
+ { 8 }
+ }
+\cs_new_nopar:Npn \@@_thing_last_item:
+ {
+ \int_compare:nNnTF \l_@@_head_char_int < { 26 }
+ {
+ \int_case:nnF \l_@@_head_char_int
+ {
+ { 1 } { 1 } % lastkern
+ { 2 } { 2 } % lastskip
+ }
+ { 0 } % other integer parameters
+ }
+ {
+ \int_case:nnF \l_@@_head_char_int
+ {
+ { 26 } { 0 \@@_scan_normal_glue: } % gluestretchorder
+ { 27 } { 0 \@@_scan_normal_glue: } % glueshrinkorder
+ { 28 } % fontcharwd
+ { 1 \@@_scan_font_ident: \@@_scan_int: }
+ { 29 } % fontcharht
+ { 1 \@@_scan_font_ident: \@@_scan_int: }
+ { 30 } % fontchardp
+ { 1 \@@_scan_font_ident: \@@_scan_int: }
+ { 31 } % fontcharic
+ { 1 \@@_scan_font_ident: \@@_scan_int: }
+ { 32 } { 1 \@@_scan_int: } % parshapelength
+ { 33 } { 1 \@@_scan_int: } % parshapeindent
+ { 34 } { 1 \@@_scan_int: } % parshapedimen
+ { 35 } { 1 \@@_scan_normal_glue: } % gluestretch
+ { 36 } { 1 \@@_scan_normal_glue: } % glueshrink
+ { 37 } { 2 \@@_scan_mu_glue: } % mutoglue
+ { 38 } { 3 \@@_scan_normal_glue: } % gluetomu
+ { 39 } % numepr
+ { 0 \@@_scan_expr:N \@@_scan_int: }
+ { 40 } % dimexpr
+ { 1 \@@_scan_expr:N \@@_scan_normal_dimen: }
+ { 41 } % glueexpr
+ { 2 \@@_scan_expr:N \@@_scan_normal_glue: }
+ { 42 } % muexpr
+ { 3 \@@_scan_expr:N \@@_scan_mu_glue: }
+ }
+ { }
+ }
+ }
+\cs_new_nopar:Npn \@@_thing_register:
+ {
+ \int_eval:n { \l_@@_head_char_int / 1 000 000 - 1 }
+ \int_compare:nNnT { \tl_tail:V \l_@@_head_char_int } = \c_zero
+ { \@@_scan_int: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_toks_register:}
+% A case where getting operands is not completely trivial.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scan_toks_register:
+ {
+ \int_compare:nNnT \l_@@_head_char_int = \c_zero
+ { \@@_scan_int: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux,EXP]{\@@_thing_use:nnN}
+% Given a level~|#1|, call a function to convert the token list~|#2|
+% to the correct level. This step may trigger \TeX{} errors, which
+% should precisely match the expected ones.
+% \begin{macrocode}
+\cs_new:Npn \@@_thing_use:nnN #1#2
+ {
+ \int_case:nnF { \int_min:nn {#1} {#2} }
+ {
+ { 0 } \int_eval:n
+ { 1 } \dim_eval:n
+ { 2 } \skip_eval:n
+ { 3 } \muskip_eval:n
+ }
+ { \tex_the:D }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: comment
+% \begin{macro}[aux]{\@@_scan_expr:N}
+% \begin{macro}[aux]{\@@_scan_expr_aux:NN, \@@_scan_factor:N}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scan_expr:N #1
+ { \@@_scan_expr_aux:NN #1 \c_false_bool }
+\cs_new_protected:Npn \@@_scan_expr_aux:NN #1#2
+ {
+ \@@_get_x_non_blank:
+ \@@_scan_factor:N #1
+ \@@_scan_expr_op:NN #1#2
+ }
+\cs_new_protected:Npn \@@_scan_expr_op:NN #1#2
+ {
+ \@@_get_x_non_blank:
+ \tl_case:NnF \l_@@_head_tl
+ {
+ \c_@@_plus_tl
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_expr_aux:NN #1#2
+ }
+ \c_@@_minus_tl
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_expr_aux:NN #1#2
+ }
+ \c_@@_times_tl
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_get_x_non_blank:
+ \@@_scan_factor:N \@@_scan_int:
+ \@@_scan_expr_op:NN #1#2
+ }
+ \c_@@_over_tl
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_get_x_non_blank:
+ \@@_scan_factor:N \@@_scan_int:
+ \@@_scan_expr_op:NN #1#2
+ }
+ \c_@@_rp_tl
+ {
+ \bool_if:NTF #2
+ { \@@_prev_input:V \l_@@_head_tl }
+ { \@@_back_input: }
+ }
+ }
+ {
+ \bool_if:NTF #2
+ {
+ \msg_error:nn { unravel } { missing-rparen }
+ \@@_back_input:
+ \@@_prev_input:V \c_@@_rp_tl
+ }
+ {
+ \token_if_eq_meaning:NNF \l_@@_head_token \scan_stop:
+ { \@@_back_input: }
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_scan_factor:N #1
+ {
+ \tl_if_eq:NNTF \l_@@_head_tl \c_@@_lp_tl
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_expr_aux:NN #1 \c_true_bool
+ }
+ {
+ \@@_back_input:
+ #1
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_signs:}
+% Skips blanks, scans signs, and places them to the right of the last
+% item of \cs{@@_prev_input:n}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_signs:
+ {
+ \@@_get_x_non_blank:
+ \tl_if_eq:NNTF \l_@@_head_tl \c_@@_plus_tl
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_signs:
+ }
+ {
+ \tl_if_eq:NNT \l_@@_head_tl \c_@@_minus_tl
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_signs:
+ }
+ }
+ }
+% \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}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_int:
+ {
+ \@@_scan_signs:
+ \@@_set_cmd:
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int < { \@@_tex_use:n { min_internal } }
+ { \@@_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:
+ {
+ \tl_case:NnF \l_@@_head_tl
+ {
+ \c_@@_lq_tl { \@@_scan_int_lq: }
+ \c_@@_rq_tl
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_get_x_next:
+ \@@_scan_int_explicit:n { ' }
+ }
+ \c_@@_dq_tl
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_get_x_next:
+ \@@_scan_int_explicit:n { " }
+ }
+ }
+ { \@@_scan_int_explicit:n { } }
+ }
+\cs_new_protected_nopar:Npn \@@_scan_int_lq:
+ {
+ \@@_get_next:
+ \@@_gtl_if_head_is_definable:NF \l_@@_head_gtl
+ {
+ \tl_set:Nx \l_@@_head_tl
+ { \@@_token_to_char:N \l_@@_head_token }
+ }
+ \tl_set:Nx \l_@@_tmpa_tl
+ { \int_eval:n { \exp_after:wN ` \l_@@_head_tl } }
+ \@@_prev_input_silent:V \l_@@_tmpa_tl
+ \@@_print_action:x
+ { ` \gtl_to_str:N \l_@@_head_gtl = \l_@@_tmpa_tl }
+ \@@_skip_optional_space:
+ }
+\cs_new_protected:Npn \@@_scan_int_explicit:n #1
+ {
+ \if_int_compare:w \c_one
+ < #1 1 \exp_after:wN \exp_not:N \l_@@_head_tl \exp_stop_f:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_get_x_next:
+ \@@_scan_int_explicit:n {#1}
+ }
+ {
+ \token_if_eq_catcode:NNF \l_@@_head_token \c_space_token
+ { \@@_back_input: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \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 }
+% \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{macrocode}
+\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 }
+ {
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int
+ > { \@@_tex_use:n { max_internal } }
+ { \@@_scan_dimen_char:NN #1#2 }
+ {
+ \bool_if:NTF #1
+ {
+ \@@_scan_something_internal:n { 3 }
+ \int_case:nnF \g_@@_val_level_int
+ {
+ { 0 } { \@@_scan_dim_unit:NN #1 #2 }
+ { 3 } { }
+ }
+ {
+ \msg_error:nn { unravel } { incompatible-units }
+ % ^^A todo: error recovery
+ }
+ }
+ {
+ \@@_scan_something_internal:n { 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 } }
+ }
+ { }
+ }
+ }
+ }
+ \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
+ {
+ \tl_if_eq:NNT \l_@@_head_tl \c_@@_comma_tl
+ { \tl_set_eq:NN \l_@@_head_tl \c_@@_point_tl }
+ \tl_if_eq:NNTF \l_@@_head_tl \c_@@_point_tl
+ {
+ \@@_prev_input:n { . }
+ \@@_scan_decimal_loop:
+ }
+ {
+ \tl_if_in:nVTF { 0123456789 } \l_@@_head_tl
+ {
+ \@@_back_input:
+ \@@_scan_int:
+ \tl_if_eq:NNT \l_@@_head_tl \c_@@_comma_tl
+ { \tl_set_eq:NN \l_@@_head_tl \c_@@_point_tl }
+ \tl_if_eq:NNT \l_@@_head_tl \c_@@_point_tl
+ {
+ \@@_input_gpop:N \l_@@_tmpb_gtl
+ \@@_prev_input:n { . }
+ \@@_scan_decimal_loop:
+ }
+ }
+ {
+ \@@_back_input:
+ \@@_scan_int:
+ }
+ }
+ \@@_scan_dim_unit:NN #1#2
+ }
+\cs_new_protected:Npn \@@_scan_dim_unit:NN #1#2
+ {
+ \bool_if:NT #2
+ {
+ \@@_scan_keyword:nT { fF iI lL }
+ {
+ \@@_scan_inf_unit_loop:
+ \@@_break:w
+ }
+ }
+ \@@_get_x_non_blank:
+ \@@_set_cmd:
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int < { \@@_tex_use:n { min_internal } }
+ { \@@_back_input: }
+ {
+ \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
+ }
+ }
+ \bool_if:NT #1
+ {
+ \@@_scan_keyword:nT { mM uU } { \@@_break:w }
+ \msg_error:nn { unravel } { missing-mudim }
+ \@@_break:w
+ }
+ \@@_scan_keyword:nT { eE mM } { \@@_break:w }
+ \@@_scan_keyword:nT { eE xX } { \@@_break:w }
+ \@@_scan_keyword:nT { pP xX } { \@@_break:w }
+ \@@_scan_keyword:n { tT rR uU eE }
+ \@@_scan_keyword:nT { pP tT } { \@@_break:w }
+ \@@_scan_keyword:nT { iI nN } { \@@_break:w }
+ \@@_scan_keyword:nT { pP cC } { \@@_break:w }
+ \@@_scan_keyword:nT { cC mM } { \@@_break:w }
+ \@@_scan_keyword:nT { mM mM } { \@@_break:w }
+ \@@_scan_keyword:nT { bB pP } { \@@_break:w }
+ \@@_scan_keyword:nT { dD dD } { \@@_break:w }
+ \@@_scan_keyword:nT { cC cC } { \@@_break:w }
+ \@@_scan_keyword:nT { nN dD } { \@@_break:w }
+ \@@_scan_keyword:nT { nN cC } { \@@_break:w }
+ \@@_scan_keyword:nT { sS pP } { \@@_break:w }
+ \@@_break_point:
+ }
+\cs_new_protected_nopar:Npn \@@_scan_inf_unit_loop:
+ { \@@_scan_keyword:nT { lL } { \@@_scan_inf_unit_loop: } }
+\cs_new_protected_nopar:Npn \@@_scan_decimal_loop:
+ {
+ \@@_get_x_next:
+ \tl_if_empty:NTF \l_@@_head_tl
+ { \use_ii:nn }
+ { \tl_if_in:nVTF { 0123456789 } \l_@@_head_tl }
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_decimal_loop:
+ }
+ {
+ \token_if_eq_catcode:NNF \l_@@_head_token \c_space_token
+ { \@@_back_input: }
+ \@@_prev_input_silent:n { ~ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_scan_normal_glue:, \@@_scan_mu_glue:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_normal_glue:
+ { \@@_scan_glue:n { 2 } }
+\cs_new_protected_nopar:Npn \@@_scan_mu_glue:
+ { \@@_scan_glue:n { 3 } }
+% \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
+ {
+ \@@_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 }
+ {
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int
+ > { \@@_tex_use:n { max_internal } }
+ {
+ \@@_back_input:
+ \@@_scan_dimen:NN #2 \c_false_bool
+ }
+ {
+ \@@_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
+ }
+ }
+ }
+ \@@_scan_keyword:nT { pP lL uU sS }
+ { \@@_scan_dimen:NN #2 \c_true_bool }
+ \@@_scan_keyword:nT { mM iI nN uU sS }
+ { \@@_scan_dimen:NN #2 \c_true_bool }
+ \@@_break_point:
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_prev_input_silent:V \l_@@_head_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: allow \input".. .."
+% \begin{macro}[int]{\@@_scan_file_name:}
+% ^^A todo: area_delimiter and ext_delimiter ??
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_file_name:
+ {
+ \bool_gset_true:N \g_@@_name_in_progress_bool
+ \@@_get_x_non_blank:
+ \@@_scan_file_name_loop:
+ \bool_gset_false:N \g_@@_name_in_progress_bool
+ \@@_prev_input_silent:n { ~ }
+ }
+\cs_new_protected_nopar:Npn \@@_scan_file_name_loop:
+ {
+ \@@_gtl_if_head_is_definable:NTF \l_@@_head_gtl
+ { \@@_back_input: }
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ { \@@_token_to_char:N \l_@@_head_token }
+ \tl_if_eq:NNF \l_@@_tmpa_tl \c_space_tl
+ {
+ \@@_prev_input_silent:V \l_@@_tmpa_tl
+ \@@_get_x_next:
+ \@@_scan_file_name_loop:
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_scan_r_token:}
+% This is analogous to \TeX{}'s |get_r_token|. We store in
+% \cs{l_@@_defined_tl} the token which we found, as this is what will
+% be defined by the next assignment.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_r_token:
+ {
+ \bool_do_while:nn
+ { \tl_if_eq_p:NN \l_@@_head_tl \c_space_tl }
+ { \@@_get_next: }
+ \@@_gtl_if_head_is_definable:NF \l_@@_head_gtl
+ {
+ \msg_error:nn { unravel } { missing-cs }
+ \@@_back_input:
+ \tl_set:Nn \l_@@_head_tl { \@@_inaccessible:w }
+ }
+ \@@_prev_input_silent:V \l_@@_head_tl
+ \tl_set_eq:NN \l_@@_defined_tl \l_@@_head_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: hash doubling is wrong
+% \begin{macro}[aux]{\@@_scan_toks_to_str:}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scan_toks_to_str:
+ {
+ \seq_gput_right:Nn \g_@@_prev_input_seq { }
+ \@@_scan_toks:NN \c_false_bool \c_true_bool
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \@@_prev_input_silent:x
+ { { \exp_after:wN \tl_to_str:n \l_@@_tmpa_tl } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: provide separate functions for defs (avoid hash doubling).
+% \begin{macro}[aux]{\@@_scan_toks:NN}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scan_toks:NN #1#2
+ {
+ \bool_if:NT #1 { \@@_scan_param: }
+ \@@_scan_left_brace:
+ \bool_if:NTF #2
+ { \@@_scan_group_x:N #1 }
+ { \@@_scan_group_n:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_param:}
+% \begin{macro}[aux]{\@@_scan_param_aux:}
+% Collect the parameter text into \cs{l_@@_tmpa_tl}, and when seeing
+% either a begin-group or an end-group character, put it back into the
+% input, stop looping, and put what we collected into
+% \cs{l_@@_defining_tl} and into the |prev_input|.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_param:
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ \@@_scan_param_aux:
+ \tl_put_right:NV \l_@@_defining_tl \l_@@_tmpa_tl
+ \@@_prev_input_silent:V \l_@@_tmpa_tl
+ }
+\cs_new_protected_nopar:Npn \@@_scan_param_aux:
+ {
+ \@@_get_next:
+ \tl_concat:NNN \l_@@_tmpa_tl
+ \l_@@_tmpa_tl \l_@@_head_tl
+ \tl_if_empty:NTF \l_@@_head_tl
+ { \@@_back_input: } { \@@_scan_param_aux: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_group_n:N}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scan_group_n:N #1
+ {
+ \@@_back_input:
+ \@@_input_gpop_item:NF \l_@@_head_tl
+ {
+ \msg_error:nn { unravel } { runaway-text }
+ \@@_exit:w
+ }
+ \tl_set:Nx \l_@@_head_tl { { \exp_not:V \l_@@_head_tl } }
+ \bool_if:NT #1
+ { \tl_put_right:NV \l_@@_defining_tl \l_@@_head_tl }
+ \@@_prev_input_silent:V \l_@@_head_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_group_x:N}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scan_group_x:N #1
+ {
+ \@@_input_gpop_tl:N \l_@@_head_tl
+ \@@_back_input:V \l_@@_head_tl
+ \bool_if:NTF #1
+ {
+ \@@_prev_input_silent:V \c_left_brace_str
+ \tl_put_right:Nn \l_@@_defining_tl { { \if_false: } \fi: }
+ \@@_scan_group_xdef:n { 1 }
+ }
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \c_empty_gtl
+ \@@_prev_input_gtl:N \l_@@_head_gtl
+ \@@_scan_group_x:n { 1 }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpb_gtl
+ \@@_prev_input_silent:x
+ { \gtl_left_tl:N \l_@@_tmpb_gtl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_group_xdef:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scan_group_xdef:n #1
+ {
+ \@@_get_token_x:N \c_true_bool
+ \tl_if_empty:NTF \l_@@_head_tl
+ {
+ \gtl_if_head_is_group_begin:NTF \l_@@_head_gtl
+ {
+ \@@_prev_input_silent:V \c_left_brace_str
+ \tl_put_right:Nn \l_@@_defining_tl { { \if_false: } \fi: }
+ \@@_scan_group_xdef:f { \int_eval:n { #1 + 1 } }
+ }
+ {
+ \@@_prev_input_silent:V \c_right_brace_str
+ \tl_put_right:Nn \l_@@_defining_tl { \if_false: { \fi: } }
+ \int_compare:nNnF {#1} = \c_one
+ { \@@_scan_group_xdef:f { \int_eval:n { #1 - 1 } } }
+ }
+ }
+ {
+ \@@_prev_input_silent:V \l_@@_head_tl
+ \tl_put_right:Nx \l_@@_defining_tl
+ { \exp_not:N \exp_not:N \exp_not:V \l_@@_head_tl }
+ \@@_scan_group_xdef:n {#1}
+ }
+ }
+\cs_generate_variant:Nn \@@_scan_group_xdef:n { f }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_group_x:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scan_group_x:n #1
+ {
+ \@@_get_token_x:N \c_false_bool
+ \@@_prev_input_gtl:N \l_@@_head_gtl
+ \tl_if_empty:NTF \l_@@_head_tl
+ {
+ \gtl_if_head_is_group_begin:NTF \l_@@_head_gtl
+ { \@@_scan_group_x:f { \int_eval:n { #1 + 1 } } }
+ {
+ \int_compare:nNnF {#1} = \c_one
+ { \@@_scan_group_x:f { \int_eval:n { #1 - 1 } } }
+ }
+ }
+ { \@@_scan_group_x:n {#1} }
+ }
+\cs_generate_variant:Nn \@@_scan_group_x:n { f }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_get_token_x:N}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_get_token_x:N #1
+ {
+ \@@_get_next:
+ \@@_token_if_protected:NF \l_@@_head_token
+ {
+ \@@_set_cmd:
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int = { \@@_tex_use:n { the } }
+ {
+ \@@_get_the:
+ \bool_if:NTF #1
+ {
+ \tl_put_right:NV \l_@@_defining_tl \l_@@_head_tl
+ \@@_prev_input:V \l_@@_head_tl
+ }
+ {
+ \gtl_set:Nx \l_@@_tmpb_gtl { \l_@@_head_tl }
+ \@@_prev_input_gtl:N \l_@@_tmpb_gtl
+ \@@_print_action:
+ }
+ }
+ { \@@_expand: }
+ \@@_get_token_x:N #1
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: catch runaway expand/get_x_next.
+%
+% \begin{macro}[aux]{\@@_scan_alt_rule:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_alt_rule:
+ {
+ \@@_scan_keyword:nTF { wWiIdDtThH }
+ {
+ \@@_scan_normal_dimen:
+ \@@_scan_alt_rule:
+ }
+ {
+ \@@_scan_keyword:nTF { hHeEiIgGhHtT }
+ {
+ \@@_scan_normal_dimen:
+ \@@_scan_alt_rule:
+ }
+ {
+ \@@_scan_keyword:nT { dDeEpPtThH }
+ {
+ \@@_scan_normal_dimen:
+ \@@_scan_alt_rule:
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_spec:}
+% Some \TeX{} primitives accept the keywords |to| and |spread|,
+% followed by a dimension.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_spec:
+ {
+ \@@_scan_keyword:nTF { tT oO } { \@@_scan_normal_dimen: }
+ {
+ \@@_scan_keyword:nT { sS pP rR eE aA dD }
+ { \@@_scan_normal_dimen: }
+ }
+ \@@_scan_left_brace:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Working with boxes}
+%
+% \begin{macro}[aux]{\@@_do_box:N}
+% When this procedure is called, the last item in
+% \cs{g_@@_prev_input_seq} is
+% \begin{itemize}
+% \item empty if the box is meant to be put in the input stream,
+% \item \tn{setbox}\meta{int} if it is meant to be stored somewhere,
+% \item \tn{moveright}\meta{dim}, \tn{moveleft}\meta{dim},
+% \tn{lower}\meta{dim}, \tn{raise}\meta{dim} if it is meant to be
+% shifted,
+% \item \tn{leaders} or \tn{cleaders} or \tn{xleaders}, in which case
+% the argument is \cs{c_true_bool} (otherwise \cs{c_false_bool}).
+% \end{itemize}
+% If a |make_box| command follows, we fetch the operands. If leaders
+% are followed by a rule, then this is also ok. In all other cases,
+% call \cs{@@_do_box_error:} to clean up.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_do_box:N #1
+ {
+ \@@_get_x_non_relax:
+ \@@_set_cmd:
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int = { \@@_tex_use:n { make_box } }
+ { \@@_do_begin_box:N #1 }
+ {
+ \bool_if:NTF #1
+ {
+ \@@_cs_case:NnF \l_@@_head_token
+ {
+ \tex_hrule:D { \@@_do_leaders_rule: }
+ \tex_vrule:D { \@@_do_leaders_rule: }
+ }
+ { \@@_do_box_error: }
+ }
+ { \@@_do_box_error: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_do_box_error:}
+% Put the (non-|make_box|) command back into the input and complain.
+% Then recover by throwing away the action (last item of
+% \cs{g_@@_prev_input_seq}). For some reason (this appears to be what
+% \TeX{} does), there is no need to remove the after assignment token
+% here.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_do_box_error:
+ {
+ \@@_back_input:
+ \msg_error:nn { unravel } { missing-box }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_do_begin_box:N}
+% We have just found a |make_box| command and placed it into the last
+% item of \cs{g_@@_prev_input_seq}. If it is ``simple''
+% (\tn{box}\meta{int}, \tn{copy}\meta{int}, \tn{lastbox},
+% \tn{vsplit}\meta{int} \texttt{to} \meta{dim}) then we grab its
+% operands, then call \cs{@@_do_simple_box:N} to finish up. If it is
+% \tn{vtop} or \tn{vbox} or \tn{hbox}, we need to work harder.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_do_begin_box:N #1
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \int_case:nnTF \l_@@_head_char_int
+ {
+ { 0 } { \@@_scan_int: } % box
+ { 1 } { \@@_scan_int: } % copy
+ { 2 } { } % lastbox
+ { 3 } % vsplit
+ {
+ \@@_scan_int:
+ \@@_scan_keyword:nF { tT oO }
+ {
+ \msg_error:nn { unravel } { missing-to }
+ \@@_prev_input:n { to }
+ }
+ \@@_scan_normal_dimen:
+ }
+ }
+ { \@@_do_simple_box:N #1 }
+ { \@@_do_box_explicit:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_do_simple_box:N}
+% For leaders, we need to fetch a glue. In all cases, retrieve the
+% box construction (such as |\raise3pt\vsplit7to5em|). Finally, let
+% \TeX{} run the code and print what we have done.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_do_simple_box:N #1
+ {
+ \bool_if:NTF #1 { \@@_do_leaders_fetch_skip: }
+ {
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \tl_use:N \l_@@_head_tl \scan_stop:
+ \gtl_put_right:NV \g_@@_output_gtl \l_@@_head_tl
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_do_leaders_fetch_skip:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_do_leaders_fetch_skip:
+ {
+ \@@_get_x_non_relax:
+ \@@_set_cmd:
+ \int_compare:nNnTF \l_@@_head_cmd_int
+ = { \@@_tex_use:n { \mode_if_vertical:TF { vskip } { hskip } } }
+ {
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \tl_put_left:NV \l_@@_head_tl \l_@@_tmpa_tl
+ \@@_do_append_glue:
+ }
+ {
+ \@@_back_input:
+ \msg_error:nn { unravel } { improper-leaders }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: less intrusive hooking into \everyhbox/\everyvbox?
+% \begin{macro}[aux]{\@@_do_box_explicit:N}
+% At this point, the last item in \cs{g_@@_prev_input_seq} is
+% typically |\setbox0\hbox| or |\raise 3pt\hbox|. Scan for keywords
+% |to| and |spread| and a left brace. Install a hook in
+% \tn{everyhbox} or \tn{everyvbox} (whichever \TeX{} is going to
+% insert in the box). We then retrieve all the material that led to
+% the current box into \cs{l_@@_head_tl} in order to print it, then
+% let \TeX{} perform the box operation (here we need to provide the
+% begin-group token, as it was scanned but not placed in
+% \cs{g_@@_prev_input_seq}). \TeX{} inserts \tn{everyhbox} or
+% \tn{everyvbox} just after the begin-group token, and the hook we did
+% is such that all that material is collected and put into the input
+% that we will study.
+% We must remember to find a glue for leaders, and for this
+% we use a stack of booleans: the top is true if the innermost box is
+% part of leaders.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_do_box_explicit:N #1
+ {
+ \token_if_eq_meaning:NNTF \l_@@_head_token \tex_hbox:D
+ { \@@_box_hook:N \tex_everyhbox:D }
+ { \@@_box_hook:N \tex_everyvbox:D }
+ % ^^A todo: TeX calls |normal_paragraph| here.
+ \@@_scan_spec:
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_set_action_text:x
+ { \tl_to_str:N \l_@@_head_tl \iow_char:N \{ }
+ \seq_push:Nx \l_@@_leaders_box_seq
+ { \bool_if:NTF #1 { \mode_if_vertical:TF { v } { h } } { Z } }
+ \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 \@@_box_hook_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_box_hook:N}
+% \begin{macro}[aux]{\@@_box_hook:w, \@@_box_hook_end:}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_box_hook:N #1
+ {
+ \tl_set:NV \l_@@_tmpa_tl #1
+ \str_if_eq_x:nnF
+ { \tl_head:N \l_@@_tmpa_tl } { \exp_not:N \@@_box_hook:w }
+ {
+ \exp_args:Nx #1
+ {
+ \exp_not:n { \@@_box_hook:w \prg_do_nothing: }
+ \exp_not:V #1
+ }
+ }
+ \cs_gset_protected:Npn \@@_box_hook:w ##1 \@@_box_hook_end:
+ {
+ \exp_args:No #1 {##1}
+ \cs_gset_eq:NN \@@_box_hook:w \prg_do_nothing:
+ \@@_print_action:
+ \@@_back_input:o {##1}
+ \@@_set_action_text:x
+ { \token_to_meaning:N #1 \tl_to_str:o {##1} }
+ \tl_if_empty:oF {##1} { \@@_print_action: }
+ }
+ }
+\cs_new_eq:NN \@@_box_hook:w \prg_do_nothing:
+\cs_new_eq:NN \@@_box_hook_end: \prg_do_nothing:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_do_leaders_rule:}
+% After finding a |vrule| or |hrule| command and looking for |depth|,
+% |heigh| and |width| keywords, we are in the same situation as after
+% finding a box. Fetch the required skip accordingly.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_do_leaders_rule:
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_alt_rule:
+ \@@_do_leaders_fetch_skip:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Paragraphs}
+%
+% \begin{macro}[int,TF]{\@@_charcode_if_safe:n}
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_charcode_if_safe:n #1 { TF }
+ {
+ \bool_if:nTF
+ {
+ \int_compare_p:n { #1 = `! }
+ || \int_compare_p:n { `' <= #1 <= `[ }
+ || \int_compare_p:n { #1 = `] }
+ || \int_compare_p:n { ` ` <= #1 <= `z }
+ }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \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_generate_variant:Nn \@@_char:n { V , x }
+% \end{macrocode}
+% \end{macro}
+%
+% \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_generate_variant:Nn \@@_char_in_mmode:n { V , x }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_mathchar:n, \@@_mathchar:x}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_mathchar:n #1
+ {
+ \tex_mathchar:D #1 \scan_stop:
+ \tl_set:Nx \l_@@_tmpa_tl
+ { \exp_not:N \mathchar \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 \@@_mathchar:n { x }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_new_graf:N}
+% The argument is a boolean, indicating whether the paragraph should
+% be indented. We have much less work to do here than \TeX{} itself.
+% Our only task is to correctly position the \tn{everypar} tokens in
+% the input that we will read, rather than letting \TeX{} run the code
+% right away.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_new_graf:N #1
+ {
+ \tl_set:NV \l_@@_tmpa_tl \tex_everypar:D
+ \tex_everypar:D { }
+ \bool_if:NTF #1 { \tex_indent:D } { \tex_noindent:D }
+ \exp_args:NV \tex_everypar:D \l_@@_tmpa_tl
+ \@@_back_input:V \l_@@_tmpa_tl
+ \@@_print_action:x
+ {
+ \g_@@_action_text_str \c_space_tl : ~
+ \token_to_str:N \everypar = { \tl_to_str:N \l_@@_tmpa_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_end_graf:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_end_graf:
+ { \mode_if_horizontal:T { \@@_normal_paragraph: } }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: Do we need to do more?
+% \begin{macro}[int]{\@@_normal_paragraph:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_normal_paragraph:
+ {
+ \tex_par:D
+ \gtl_gput_right:Nn \g_@@_output_gtl { \par }
+ \@@_print_action:x { Paragraph~end. }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: do something to the \output routine?
+% \begin{macro}[int]{\@@_build_page:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_build_page:
+ {
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Groups}
+%
+% ^^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:
+%
+% \begin{macro}[aux]{\@@_handle_left_brace:}
+% When an end-group character is sensed, the result depends on the
+% current group type.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_handle_left_brace:
+ {
+ \int_case:nnF \etex_currentgrouptype:D
+ {
+ { 1 } { \@@_end_simple_group: } % simple
+ { 2 } { \@@_end_box_group: } % hbox
+ { 3 } { \@@_end_box_group: } % adjusted_hbox
+ { 4 } { \@@_end_graf: \@@_end_box_group: } % vbox
+ { 5 } { \@@_end_graf: \@@_end_box_group: } % vtop
+ { 6 } { \@@_end_align_group: } % align
+ { 7 } { \@@_end_no_align_group: } % no_align
+ { 8 } { \@@_end_output_group: } % output
+ { 9 } { \@@_end_math_group: } % math
+ { 10 } { \@@_end_disc_group: } % disc
+ { 11 } { \@@_end_graf: \@@_end_simple_group: } % insert
+ { 12 } { \@@_end_graf: \@@_end_simple_group: } % vcenter
+ { 13 } { \@@_end_math_choice_group: } % math_choice
+ }
+ { % bottom_level, semi_simple, math_shift, math_left
+ \@@_back_input:
+ \l_@@_head_token
+ \@@_print_action:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_end_simple_group:}
+% This command is used to simply end a group, when there are no
+% specific operations to perform.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_end_simple_group:
+ {
+ \l_@@_head_token
+ \gtl_gconcat:NNN \g_@@_output_gtl
+ \g_@@_output_gtl \c_group_end_gtl
+ \@@_print_action:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_end_box_group:}
+% The end of an explicit box (generated by \tn{vtop}, \tn{vbox}, or
+% \tn{hbox}) can either be simple, or can mean that we need to find a
+% skip for a \tn{leaders}/\tn{cleaders}/\tn{xleaders} construction.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_end_box_group:
+ {
+ \seq_pop:NN \l_@@_leaders_box_seq \l_@@_tmpa_tl
+ \str_if_eq_x:nnTF \l_@@_tmpa_tl { Z }
+ { \@@_end_simple_group: }
+ {
+ \@@_get_x_non_relax:
+ \@@_set_cmd:
+ \int_compare:nNnTF \l_@@_head_cmd_int
+ = { \@@_tex_use:n { \l_@@_tmpa_tl skip } }
+ {
+ \tl_put_left:Nn \l_@@_head_tl { \c_group_end_token }
+ \@@_do_append_glue:
+ }
+ {
+ \@@_back_input:
+ \c_group_end_token \group_begin: \group_end:
+ \@@_print_action:
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_off_save:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_off_save:
+ {
+ \int_compare:nNnTF \etex_currentgrouptype:D = { 0 }
+ { % bottom-level
+ \msg_error:nnx { unravel } { extra-close }
+ { \token_to_meaning:N \l_@@_head_token }
+ }
+ {
+ \@@_back_input:
+ \int_case:nnF \etex_currentgrouptype:D
+ {
+ { 14 } % semi_simple_group
+ { \gtl_set:Nn \l_@@_head_gtl { \group_end: } }
+ { 15 } % math_shift_group
+ { \gtl_set:Nn \l_@@_head_gtl { $ } } % $
+ { 16 } % math_left_group
+ { \gtl_set:Nn \l_@@_head_gtl { \tex_right:D . } }
+ }
+ { \gtl_set_eq:NN \l_@@_head_gtl \c_group_end_gtl }
+ \@@_back_input:
+ \msg_error:nnx { unravel } { off-save }
+ { \gtl_to_str:N \l_@@_head_gtl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \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]
+% {\@@_mode_math:n, \@@_mode_non_math:n, \@@_mode_vertical:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_mode_math:n #1
+ { \mode_if_math:TF {#1} { \@@_insert_dollar_error: } }
+\cs_new_protected:Npn \@@_mode_non_math:n #1
+ { \mode_if_math:TF { \@@_insert_dollar_error: } {#1} }
+\cs_new_protected:Npn \@@_mode_vertical:n #1
+ {
+ \mode_if_math:TF
+ { \@@_insert_dollar_error: }
+ { \mode_if_horizontal:TF { \@@_head_for_vmode: } {#1} }
+ }
+\cs_new_protected:Npn \@@_mode_non_vertical:n #1
+ {
+ \mode_if_vertical:TF
+ { \@@_back_input: \@@_new_graf:N \c_true_bool }
+ {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_head_for_vmode:}
+% See \TeX{}'s |head_for_vmode|.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_head_for_vmode:
+ {
+ \mode_if_inner:TF
+ {
+ \token_if_eq_meaning:NNTF \l_@@_head_token \tex_hrule:D
+ {
+ \msg_error:nn { unravel } { hrule-bad-mode }
+ \@@_print_action:
+ }
+ { \@@_off_save: }
+ }
+ {
+ \@@_back_input:
+ \gtl_set:Nn \l_@@_head_gtl { \par }
+ \@@_back_input:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{One step}
+%
+% \begin{macro}[int]{\@@_do_step:}
+% Perform the action if the corresponding command exists. If that
+% command does not exist, complain, and leave the token in the output.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_do_step:
+ {
+ \@@_set_action_text:
+ \bool_if:NT \l_@@_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 : }
+ { \msg_error:nnx { unravel } { internal } { unknown-command } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Commands}
+%
+% We will implement commands in order of their command codes (some of
+% the more elaborate commands call auxiliaries defined in other
+% sections).
+%
+% \subsubsection{Characters: from 0 to 15}
+%
+% This section is about command codes in the range $[0, 15]$.
+% \begin{itemize}
+% \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})
+% characters (catcode~$3$).
+% \item |tab_mark=4| for \tn{span}
+% \item |alignment_char=4| for alignment tab characters (catcode~$4$).
+% \item |car_ret=5| for \tn{cr} and \tn{crcr}.
+% \item |macro_char=6| for macro parameter characters (catcode~$6$).
+% \item |superscript_char=7| for superscript characters (catcode~$7$).
+% \item |subscript_char=8| for subscript characters (catcode~$8$).
+% \item |endv=9| for |?|.
+% \item |blank_char=10| for blank spaces (catcode~$10$).
+% \item |the_char=11| for letters (catcode~$11$).
+% \item |other_char=12| for other characters (catcode~$12$).
+% \item |par_end=13| for \tn{par}.
+% \item |stop=14| for \tn{end} and \tn{dump}.
+% \item |delim_num=15| for \tn{delimiter}.
+% \end{itemize}
+% Not implemented at all: |endv|.
+%
+% \tn{relax} does nothing.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { relax } % 0
+ { \@@_print_action: }
+% \end{macrocode}
+%
+% Begin-group characters are sent to the output, as their grouping
+% behaviour may affect the scope of font changes, for instance. The are
+% also performed.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { begin-group_char } % 1
+ {
+ \gtl_gconcat:NNN \g_@@_output_gtl
+ \g_@@_output_gtl \c_group_begin_gtl
+ \@@_print_action:
+ \l_@@_head_token
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { end-group_char } % 2
+ { \@@_handle_left_brace: }
+% \end{macrocode}
+%
+% Math shift characters quit vertical mode, and start math mode.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { math_char } % 3
+ {
+ \@@_mode_non_vertical:n
+ {
+ \mode_if_math:TF
+ {
+ \int_compare:nNnTF
+ \etex_currentgrouplevel:D = { 15 } % math_shift_group
+ { \@@_after_math: }
+ { \@@_off_save: }
+ }
+ {
+ \@@_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: }
+ }
+ { \@@_back_input: \@@_goto_inner_math: }
+ }
+ }
+ }
+% \end{macrocode}
+%
+% Some commands are errors when they reach \TeX{}'s stomach. Among
+% others, |tab_mark=alignment_char|, |car_ret| and |macro_char|. We let
+% \TeX{} insert the proper error.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { alignment_char } % 4
+ { \l_@@_head_token \@@_print_action: }
+\@@_new_tex_cmd:nn { car_ret } % 5
+ { \l_@@_head_token \@@_print_action: }
+\@@_new_tex_cmd:nn { macro_char } % 6
+ { \l_@@_head_token \@@_print_action: }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { superscript_char } % 7
+ { \@@_mode_math:n { \@@_sub_sup: } }
+\@@_new_tex_cmd:nn { subscript_char } % 8
+ { \@@_mode_math:n { \@@_sub_sup: } }
+\cs_new_protected_nopar:Npn \@@_sub_sup:
+ {
+ \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:
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { endv } % 9
+ { \msg_error:nn { unravel } { not-implemented } { alignments } }
+% \end{macrocode}
+%
+% Blank spaces are ignored in vertical and math modes in the same way as
+% \tn{relax} is in all modes. In horizontal mode, add them to the
+% output.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { blank_char } % 10
+ {
+ \mode_if_horizontal:T
+ {
+ \gtl_gput_right:Nn \g_@@_output_gtl { ~ }
+ \l_@@_head_token
+ }
+ \@@_print_action:
+ }
+% \end{macrocode}
+%
+% Letters and other characters leave vertical mode.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { the_char } % 11
+ {
+ \@@_mode_non_vertical:n
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ { ` \@@_token_to_char:N \l_@@_head_token }
+ \mode_if_math:TF
+ { \@@_char_in_mmode:V \l_@@_tmpa_tl }
+ { \@@_char:V \l_@@_tmpa_tl }
+ }
+ }
+\@@_new_eq_tex_cmd:nn { other_char } { the_char } % 12
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { par_end } % 13
+ {
+ \@@_mode_non_math:n
+ {
+ \mode_if_vertical:TF
+ { \@@_normal_paragraph: }
+ {
+ % if align_state<0 then off_save;
+ \@@_end_graf:
+ \mode_if_vertical:T
+ { \mode_if_inner:F { \@@_build_page: } }
+ }
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { stop } % 14
+ {
+ \@@_mode_vertical:n
+ {
+ \mode_if_inner:TF
+ { \@@_forbidden_case: }
+ {
+ % ^^A todo: unless its_all_over
+ \int_gdecr:N \g_@@_ends_int
+ \int_compare:nNnTF \g_@@_ends_int > \c_zero
+ {
+ \@@_back_input:
+ \@@_back_input:n
+ {
+ \tex_hbox:D to \tex_hsize:D { }
+ \tex_vfill:D
+ \tex_penalty:D - '10000000000 ~
+ }
+ \@@_build_page:
+ \@@_print_action:x { End~everything! }
+ }
+ {
+ \@@_print_outcome:
+ \l_@@_head_token
+ }
+ }
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { delim_num } % 15
+ {
+ \@@_mode_math:n
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_int:
+ \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 }
+ }
+ }
+% \end{macrocode}
+%
+% \subsubsection{Boxes: from 16 to 31}
+%
+% \begin{itemize}
+% \item |char_num=16| for \tn{char}
+% \item |math_char_num=17| for \tn{mathchar}
+% \item |mark=18| for \tn{mark} and \tn{marks}
+% \item |xray=19| for \tn{show}, \tn{showbox}, \tn{showthe},
+% \tn{showlists}, \tn{showgroups}, \tn{showtokens}, \tn{showifs}.
+% \item |make_box=20| for \tn{box}, \tn{copy}, \tn{lastbox},
+% \tn{vsplit}, \tn{vtop}, \tn{vbox}, and \tn{hbox}~(106).
+% \item |hmove=21| for \tn{moveright} and \tn{moveleft}.
+% \item |vmove=22| for \tn{lower} and \tn{raise}.
+% \item |un_hbox=23| for \tn{unhbox} and \tn{unhcopy}.
+% \item |unvbox=24| for \tn{unvbox}, \tn{unvcopy}, \tn{pagediscards},
+% and \tn{splitdiscards}.
+% \item |remove_item=25| for \tn{unpenalty}~(12), \tn{unkern}~(11),
+% \tn{unskip}~(10).
+% \item |hskip=26| for \tn{hfil}, \tn{hfill}, \tn{hss}, \tn{hfilneg},
+% \tn{hskip}.
+% \item |vskip=27| for \tn{vfil}, \tn{vfill}, \tn{vss}, \tn{vfilneg},
+% \tn{vskip}.
+% \item |mskip=28| for \tn{mskip}~(5).
+% \item |kern=29| for \tn{kern}~(1).
+% \item |mkern=30| for \tn{mkern}~(99).
+% \item |leader_ship=31| for \tn{shipout}~(99), \tn{leaders}~(100),
+% \tn{cleaders}~(101), \tn{xleaders}~(102).
+% \end{itemize}
+%
+% \tn{char} leaves vertical mode, then scans an integer operand, then
+% calls \cs{@@_char_in_mmode:n} or \cs{@@_char:n} depending on the mode.
+% See implementation of |the_char| and |other_char|.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { char_num } % 16
+ {
+ \@@_mode_non_vertical:n
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_int:
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \mode_if_math:TF
+ { \@@_char_in_mmode:x { \tl_tail:N \l_@@_head_tl } }
+ { \@@_char:x { \tl_tail:N \l_@@_head_tl } }
+ }
+ }
+% \end{macrocode}
+%
+% Only allowed in math mode, \tn{mathchar} reads an integer operand, and
+% calls \cs{@@_mathchar:n}, which places the corresponding math
+% character in the \cs{g_@@_output_gtl}, and in the actual output.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { math_char_num } % 17
+ {
+ \@@_mode_math:n
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_int:
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_mathchar:x { \tl_tail:N \l_@@_head_tl }
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { mark } % 18
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \int_compare:nNnF \l_@@_head_char_int = \c_zero
+ { \@@_scan_int: }
+ \seq_gput_right:Nn \g_@@_prev_input_seq { }
+ \@@_scan_toks:NN \c_false_bool \c_true_bool
+ \seq_gpop_right:Nn \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:x
+ { \tl_to_str:N \l_@@_head_tl \tl_to_str:N \l_@@_tmpa_tl }
+ \tl_put_right:Nx \l_@@_head_tl
+ { { \exp_not:N \exp_not:n \exp_not:V \l_@@_tmpa_tl } }
+ \tl_use:N \l_@@_head_tl
+ }
+% \end{macrocode}
+%
+% We now implement the primitives \tn{show}, \tn{showbox}, \tn{showthe},
+% \tn{showlists}, \tn{showgroups}, \tn{showtokens} and \tn{showifs}.
+% Those with no operand are sent to \TeX{} after printing the action.
+% Those with operands print first, then scan their operands, then are
+% sent to \TeX{}. The case of \tn{show} is a bit special, as its
+% operand is a single token, which cannot easily be put into the
+% \cs{g_@@_prev_input_seq} in general. Since no expansion can occur,
+% simply grab the token and show it.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { xray } % 19
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \int_case:nnF \l_@@_head_char_int
+ {
+ { 0 }
+ { % show
+ \@@_get_next:
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \gtl_head_do:NN \l_@@_head_gtl \l_@@_tmpa_tl
+ }
+ { 2 }
+ { % showthe
+ \@@_get_x_next:
+ \@@_scan_something_internal:n { 5 }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \exp_args:Nx \etex_showtokens:D
+ { \tl_tail:N \l_@@_head_tl }
+ }
+ }
+ { % no operand for showlists, showgroups, showifs
+ \int_compare:nNnT \l_@@_head_char_int = \c_one % showbox
+ { \@@_scan_int: }
+ \int_compare:nNnT \l_@@_head_char_int = \c_five % showtokens
+ { \@@_scan_toks:NN \c_false_bool \c_false_bool }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \tl_use:N \l_@@_head_tl \scan_stop:
+ }
+ }
+% \end{macrocode}
+%
+% |make_box=20| for \tn{box}, \tn{copy}, \tn{lastbox},
+% \tn{vsplit}, \tn{vtop}, \tn{vbox}, and \tn{hbox}~(106).
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { make_box } % 20
+ {
+ \seq_gput_right:Nn \g_@@_prev_input_seq { }
+ \@@_back_input:
+ \@@_do_box:N \c_false_bool
+ }
+% \end{macrocode}
+%
+% ^^A todo: implement \@@_forbidden_case:
+%
+% \begin{macro}[aux]{\@@_do_move:}
+% Scan a dimension and a box, and perform the shift, printing the
+% appropriate action.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_do_move:
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_normal_dimen:
+ \@@_do_box:N \c_false_bool
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% |hmove=21| for \tn{moveright} and \tn{moveleft}.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { hmove } % 21
+ {
+ \mode_if_vertical:TF
+ { \@@_do_move: } { \@@_forbidden_case: }
+ }
+% \end{macrocode}
+%
+% |vmove=22| for \tn{lower} and \tn{raise}.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { vmove } % 22
+ {
+ \mode_if_vertical:TF
+ { \@@_forbidden_case: } { \@@_do_move: }
+ }
+% \end{macrocode}
+%
+% \begin{macro}[aux]{\@@_do_unpackage:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_do_unpackage:
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_int:
+ \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 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% |un_hbox=23| for \tn{unhbox} and \tn{unhcopy}.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { un_hbox } % 23
+ { \@@_mode_non_vertical:n { \@@_do_unpackage: } }
+% \end{macrocode}
+%
+% |unvbox=24| for \tn{unvbox}, \tn{unvcopy}, \tn{pagediscards}, and
+% \tn{splitdiscards}. The latter two take no operands, so we just let
+% \TeX{} do its thing, then we show the action.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { un_vbox } % 24
+ {
+ \@@_mode_vertical:n
+ {
+ \int_compare:nNnTF \l_@@_head_char_int > { 1 }
+ { \l_@@_head_token \@@_print_action: }
+ { \@@_do_unpackage: }
+ }
+ }
+% \end{macrocode}
+%
+% |remove_item=25| for \tn{unpenalty}~(12), \tn{unkern}~(11),
+% \tn{unskip}~(10). Those commands only act on \TeX{}'s box/glue data
+% structures, which \pkg{unravel} does not (and cannot) care about.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { remove_item } % 25
+ { \l_@@_head_token \@@_print_action: }
+% \end{macrocode}
+%
+% \begin{macro}[aux]{\@@_do_append_glue:}
+% For \tn{hfil}, \tn{hfill}, \tn{hss}, \tn{hfilneg} and their vertical
+% analogs, simply call the primitive then print the action. For
+% \tn{hskip}, \tn{vskip} and \tn{mskip}, read a normal glue or a mu
+% glue (\cs{l_@@_head_char_int} is $4$ or~$5$), then call the
+% primitive with that operand, and print the whole thing as an action.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_do_append_glue:
+ {
+ \int_compare:nNnTF \l_@@_head_char_int < { 4 }
+ { \tl_use:N \l_@@_head_tl \@@_print_action: }
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \exp_args:Nf \@@_scan_glue:n
+ { \int_eval:n { \l_@@_head_char_int - 2 } }
+ \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 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% |hskip=26| for \tn{hfil}, \tn{hfill}, \tn{hss}, \tn{hfilneg},
+% \tn{hskip}.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { hskip } % 26
+ { \@@_mode_non_vertical:n { \@@_do_append_glue: } }
+% \end{macrocode}
+%
+% |vskip=27| for \tn{vfil}, \tn{vfill}, \tn{vss}, \tn{vfilneg},
+% \tn{vskip}.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { vskip } % 27
+ { \@@_mode_vertical:n { \@@_do_append_glue: } }
+% \end{macrocode}
+%
+% |mskip=28| for \tn{mskip}~(5).
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { mskip } % 28
+ { \@@_mode_math:n { \@@_do_append_glue: } }
+% \end{macrocode}
+%
+% \begin{macro}[aux]{\@@_do_append_kern:}
+% See \cs{@@_do_append_glue:}. This function is used for the
+% primitives \tn{kern} and \tn{mkern} only.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_do_append_kern:
+ {
+ \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 }
+ \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 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% |kern=29| for \tn{kern}~(1).
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { kern } % 29
+ { \@@_do_append_kern: }
+% \end{macrocode}
+%
+% |mkern=30| for \tn{mkern}~(99).
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { mkern } % 30
+ { \@@_mode_math:n { \@@_do_append_kern: } }
+% \end{macrocode}
+%
+% |leader_ship=31| for \tn{shipout}~(99), \tn{leaders}~(100),
+% \tn{cleaders}~(101), \tn{xleaders}~(102).
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { leader_ship } % 31
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_do_box:N \c_true_bool
+ }
+% \end{macrocode}
+%
+% \subsubsection{From 32 to 47}
+%
+% ^^A todo: implement \@@_begin_insert_or_adjust:
+%
+% \begin{itemize}
+% \item |halign=32|
+% \item |valign=33|
+% \item |no_align=34|
+% \item |vrule=35|
+% \item |hrule=36|
+% \item |insert=37|
+% \item |vadjust=38|
+% \item |ignore_spaces=39|
+% \item |after_assignment=40|
+% \item |after_group=41|
+% \item |break_penalty=42|
+% \item |start_par=43|
+% \item |ital_corr=44|
+% \item |accent=45|
+% \item |math_accent=46|
+% \item |discretionary=47|
+% \end{itemize}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { halign } % 32
+ { \msg_fatal:nnx { unravel } { not-implemented } { halign } }
+\@@_new_tex_cmd:nn { valign } % 33
+ { \msg_fatal:nnx { unravel } { not-implemented } { valign } }
+\@@_new_tex_cmd:nn { no_align } % 34
+ { \msg_fatal:nnx { unravel } { not-implemented } { noalign } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { vrule } % 35
+ { \@@_mode_non_vertical:n { \@@_do_rule: } }
+\@@_new_tex_cmd:nn { hrule } % 36
+ { \@@_mode_vertical:n { \@@_do_rule: } }
+\cs_new_protected_nopar:Npn \@@_do_rule:
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_alt_rule:
+ \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 }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { insert } % 37
+ { \@@_begin_insert_or_adjust: }
+\@@_new_tex_cmd:nn { vadjust } % 38
+ {
+ \mode_if_vertical:TF
+ { \@@_forbidden_case: } { \@@_begin_insert_or_adjust: }
+ }
+% \end{macrocode}
+%
+% ^^A todo: implement the internal \pdfprimitive business.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { ignore_spaces } % 39
+ {
+ \token_if_eq_meaning:NNTF \l_@@_head_token \tex_ignorespaces:D
+ {
+ \@@_get_x_non_blank:
+ \@@_set_cmd:
+ \@@_do_step:
+ }
+ { \msg_error:nn { unravel } { not-implemented } { pdfprimitive } }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { after_assignment } % 40
+ {
+ \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_head_tl
+ \@@_get_next:
+ \gtl_gset_eq:NN \g_@@_after_assignment_gtl \l_@@_head_gtl
+ \@@_print_action:x
+ {
+ Afterassignment:~\tl_to_str:N \l_@@_tmpa_tl
+ \gtl_to_str:N \l_@@_head_gtl
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { after_group } % 41
+ { \msg_error:nnx { unravel } { not-implemented } { aftergroup } }
+% \end{macrocode}
+%
+% See \cs{@@_do_append_glue:}.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { break_penalty } % 42
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_int:
+ \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 }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { start_par } % 43
+ {
+ \mode_if_vertical:TF
+ {
+ \token_if_eq_meaning:NNTF \l_@@_head_token \tex_noindent:D
+ { \@@_new_graf:N \c_false_bool }
+ { \@@_new_graf:N \c_true_bool }
+ }
+ {
+ \int_compare:nNnT \l_@@_head_char_int = { 1 } % indent
+ {
+ \tex_hbox:D width \tex_parindent:D { }
+ \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl
+ }
+ \@@_print_action:
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { ital_corr } % 44
+ {
+ \mode_if_vertical:TF { \@@_forbidden_case: }
+ { \l_@@_head_token \@@_print_action: }
+ }
+% \end{macrocode}
+%
+% \begin{macro}[aux]{\@@_do_accent:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_do_accent:
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_int:
+ \@@_do_assignments:
+ \bool_if:nTF
+ {
+ \token_if_eq_catcode_p:NN
+ \l_@@_head_token \c_catcode_letter_token
+ ||
+ \token_if_eq_catcode_p:NN
+ \l_@@_head_token \c_catcode_other_token
+ ||
+ \int_compare_p:nNn
+ \l_@@_head_cmd_int = { \@@_tex_use:n { char_given } }
+ }
+ { \@@_prev_input:V \l_@@_head_tl }
+ {
+ \token_if_eq_meaning:NNTF \l_@@_head_token \tex_char:D
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_int:
+ }
+ { \@@_break:w }
+ }
+ \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:
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
+ \@@_break_point:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_do_math_accent:}
+% \TeX{} will complain if \cs{l_@@_head_tl} happens to start with
+% \tn{accent} (the user used \tn{accent} in math mode).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_do_math_accent:
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_int:
+ \@@_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:
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { accent } % 45
+ {
+ \@@_mode_non_vertical:n
+ {
+ \mode_if_math:TF
+ { \@@_do_math_accent: } { \@@_do_accent: }
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { math_accent } % 46
+ { \@@_mode_math:n { \@@_do_math_accent: } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { discretionary } % 47
+ { \msg_error:nnx { unravel } { not-implemented } { discretionary } }
+% \end{macrocode}
+%
+% \subsubsection{Maths: from 48 to 56}
+%
+% \begin{itemize}
+% \item |eq_no=48|
+% \item |left_right=49|
+% \item |math_comp=50|
+% \item |limit_switch=51|
+% \item |above=52|
+% \item |math_style=53|
+% \item |math_choice=54|
+% \item |non_script=55|
+% \item |vcenter=56|
+% \end{itemize}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { eq_no } % 48
+ { \msg_error:nnx { unravel } { not-implemented } { eqno } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { left_right } % 49
+ { \msg_error:nnx { unravel } { not-implemented } { left/right } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { math_comp } % 50
+ { \msg_error:nnx { unravel } { not-implemented } { math~comp } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { limit_switch } % 51
+ { \msg_error:nnx { unravel } { not-implemented } { limits } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { above } % 52
+ { \msg_error:nnx { unravel } { not-implemented } { above } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { math_style } % 53
+ { \msg_error:nnx { unravel } { not-implemented } { math~style } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { math_choice } % 54
+ { \msg_error:nnx { unravel } { not-implemented } { math~choice } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { non_script } % 55
+ { \msg_error:nnx { unravel } { not-implemented } { non~script } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { vcenter } % 56
+ { \msg_error:nnx { unravel } { not-implemented } { vcenter } }
+% \end{macrocode}
+%
+% \subsubsection{From 57 to 70}
+%
+% \begin{itemize}
+% \item |case_shift=57|
+% \item |message=58|
+% \item |extension=59|
+% \item |in_stream=60|
+% \item |begin_group=61|
+% \item |end_group=62|
+% \item |omit=63|
+% \item |ex_space=64|
+% \item |no_boundary=65|
+% \item |radical=66|
+% \item |end_cs_name=67|
+% \item |char_given=68|
+% \item |math_given=69|
+% \item |last_item=70|
+% \end{itemize}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { case_shift } % 57
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_scan_toks:NN \c_false_bool \c_false_bool
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \exp_after:wN \@@_case_shift:Nn \l_@@_tmpa_tl
+ }
+\cs_new_protected:Npn \@@_case_shift:Nn #1#2
+ {
+ #1 { \@@_back_input:n {#2} }
+ \@@_print_action:x
+ { \token_to_meaning:N #1 ~ \tl_to_str:n { {#2} } }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { message } % 58
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_toks_to_str:
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \tl_use:N \l_@@_head_tl
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
+ }
+% \end{macrocode}
+%
+% Extensions are implemented in a later section.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { extension } % 59
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_extension_operands:
+ \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 }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { in_stream } % 60
+ {
+ \seq_put_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \token_if_eq_meaning:NNTF \l_@@_head_token \tex_openin:D
+ {
+ \@@_scan_int:
+ \@@_scan_optional_equals:
+ \@@_scan_file_name:
+ }
+ { \@@_scan_int: }
+ \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 }
+ }
+% \end{macrocode}
+%
+% ^^A todo: take \aftergroup into account
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { begin_group } % 61
+ {
+ \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl
+ \@@_print_action:
+ \l_@@_head_token
+ }
+\@@_new_tex_cmd:nn { end_group } % 62
+ {
+ \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl
+ \@@_print_action:
+ \l_@@_head_token
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { omit } % 63
+ { \msg_error:nn { unravel } { not-implemented } { omit } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { ex_space } % 64
+ {
+ \@@_mode_non_vertical:n
+ { \l_@@_head_token \@@_print_action: }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { no_boundary } % 65
+ {
+ \@@_mode_non_vertical:n
+ { \l_@@_head_token \@@_print_action: }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { radical } % 66
+ {
+ \@@_mode_math:n
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_int:
+ \@@_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:
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
+ }
+ }
+% \end{macrocode}
+%
+% Let \TeX{} cause the error.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { end_cs_name } % 67
+ { \l_@@_head_token \@@_print_action: }
+% \end{macrocode}
+%
+% See |the_char| and |other_char|.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { char_given } % 68
+ {
+ \@@_mode_non_vertical:n
+ {
+ \mode_if_math:TF
+ { \@@_char_in_mmode:V \l_@@_head_char_int }
+ { \@@_char:V \l_@@_head_char_int }
+ }
+ }
+% \end{macrocode}
+%
+% See |math_char_num|.
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { math_given } % 69
+ {
+ \@@_mode_math:n
+ { \@@_mathchar:x { \int_use:N \l_@@_head_char_int } }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_cmd:nn { last_item } % 70
+ { \@@_forbidden_case: }
+% \end{macrocode}
+%
+% \subsubsection{Extensions}
+% ^^A todo: move this section.
+%
+% \begin{macro}[int]{\@@_scan_extension_operands:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_extension_operands:
+ {
+ \int_case:nnF \l_@@_head_char_int
+ {
+ { 0 } % openout
+ {
+ \@@_scan_int:
+ \@@_scan_optional_equals:
+ \@@_scan_file_name:
+ }
+ { 1 } % write
+ {
+ \@@_scan_int:
+ \@@_scan_toks:NN \c_false_bool \c_false_bool
+ }
+ { 2 } % closeout
+ { \@@_scan_int: }
+ { 3 } % special
+ { \@@_scan_toks_to_str: }
+ { 4 } % immediate
+ { \@@_scan_immediate_operands: }
+ { 5 } % setlanguage
+ {
+ \mode_if_horizontal:TF
+ { \@@_scan_int: }
+ { \msg_error:nn { unravel } { invalid-mode } }
+ }
+ { 6 } % pdfliteral
+ {
+ \@@_scan_keyword:nF { dD iI rR eE cC tT }
+ { \@@_scan_keyword:n { pP aA gG eE } }
+ \@@_scan_pdf_ext_toks:
+ }
+ { 7 } % pdfobj
+ {
+ \@@_scan_keyword:nTF
+ { rR eE sS eE rR vV eE oO bB jJ nN uU mM }
+ { \@@_skip_optional_space: }
+ {
+ \@@_scan_keyword:nF { uU sS eE oO bB jJ nN uU mM }
+ { \@@_scan_int: }
+ \@@_scan_keyword:nT { sS tT rR eE aA mM }
+ {
+ \@@_scan_keyword:nT { aA tT tT rR }
+ { \@@_scan_pdf_ext_toks: }
+ }
+ \@@_scan_keyword:n { fF iI lL eE }
+ \@@_scan_pdf_ext_toks:
+ }
+ }
+ { 8 } % pdfrefobj
+ { \@@_scan_int: }
+ { 9 } % pdfxform
+ {
+ \@@_scan_keyword:nT { aA tT tT rR }
+ { \@@_scan_pdf_ext_toks: }
+ \@@_scan_keyword:nTF { rR eE sS oO uU rR cC eE sS }
+ { \@@_scan_pdf_ext_toks: }
+ \@@_scan_int:
+ }
+ { 10 } % pdfrefxform
+ { \@@_scan_int: }
+ { 11 } % pdfximage
+ { \@@_scan_image: }
+ { 12 } % pdfrefximage
+ { \@@_scan_int: }
+ { 13 } % pdfannot
+ {
+ \@@_scan_keyword:nTF
+ { rR eE sS eE rR vV eE oO bB jJ nN uU mM }
+ { \@@_scan_optional_space: }
+ {
+ \@@_scan_keyword:nT { uU sS eE oO bB jJ nN uU mM }
+ { \@@_scan_int: }
+ \@@_scan_alt_rule:
+ \@@_scan_pdf_ext_toks:
+ }
+ }
+ { 14 } % pdfstartlink
+ {
+ \mode_if_vertical:TF
+ { \msg_error:nn { unravel } { invalid-mode } }
+ {
+ \@@_scan_rule_attr:
+ \@@_scan_action:
+ }
+ }
+ { 15 } % pdfendlink
+ {
+ \mode_if_vertical:T
+ { \msg_error:nn { unravel } { invalid-mode } }
+ }
+ { 16 } % pdfoutline
+ {
+ \@@_scan_keyword:nT { aA tT tT rR }
+ { \@@_scan_pdf_ext_toks: }
+ \@@_scan_action:
+ \@@_scan_keyword:nT { cC oO uU nN tT }
+ { \@@_scan_int: }
+ \@@_scan_pdf_ext_toks:
+ }
+ { 17 } % pdfdest
+ { \@@_scan_pdfdest_operands: }
+ { 18 } % pdfthread
+ { \@@_scan_rule_attr: \@@_scan_thread_id: }
+ { 19 } % pdfstartthread
+ { \@@_scan_rule_attr: \@@_scan_thread_id: }
+ { 20 } % pdfendthread
+ { }
+ { 21 } % pdfsavepos
+ { }
+ { 22 } % pdfinfo
+ { \@@_scan_pdf_ext_toks: }
+ { 23 } % pdfcatalog
+ {
+ \@@_scan_pdf_ext_toks:
+ \@@_scan_keyword:n { oO pP eE nN aA cC tT iI oO nN }
+ { \@@_scan_action: }
+ }
+ { 24 } % pdfnames
+ { \@@_scan_pdf_ext_toks: }
+ { 25 } % pdffontattr
+ {
+ \@@_scan_font_ident:
+ \@@_scan_pdf_ext_toks:
+ }
+ { 26 } % pdfincludechars
+ {
+ \@@_scan_font_ident:
+ \@@_scan_pdf_ext_toks:
+ }
+ { 27 } % pdfmapfile
+ { \@@_scan_pdf_ext_toks: }
+ { 28 } % pdfmapline
+ { \@@_scan_pdf_ext_toks: }
+ { 29 } % pdftrailer
+ { \@@_scan_pdf_ext_toks: }
+ { 30 } % pdfresettimer
+ { }
+ { 31 } % pdffontexpand
+ {
+ \@@_scan_font_ident:
+ \@@_scan_optional_equals:
+ \@@_scan_int:
+ \@@_scan_int:
+ \@@_scan_int:
+ \@@_scan_keyword:nT { aAuUtToOeExXpPaAnNdD }
+ { \@@_skip_optional_space: }
+ }
+ { 32 } % pdfsetrandomseed
+ { \@@_scan_int: }
+ { 33 } % pdfsnaprefpoint
+ { }
+ { 34 } % pdfsnapy
+ { \@@_scan_normal_glue: }
+ { 35 } % pdfsnapycomp
+ { \@@_scan_int: }
+ { 36 } % pdfglyphtounicode
+ {
+ \@@_scan_pdf_ext_toks:
+ \@@_scan_pdf_ext_toks:
+ }
+ { 37 } % pdfcolorstack
+ { \@@_scan_pdfcolorstack_operands: }
+ { 38 } % pdfsetmatrix
+ { \@@_scan_pdf_ext_toks: }
+ { 39 } % pdfsave
+ { }
+ { 40 } % pdfrestore
+ { }
+ { 41 } % pdfnobuiltintounicode
+ { \@@_scan_font_ident: }
+ }
+ { } % no other cases.
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_pdfcolorstack_operands:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_pdfcolorstack_operands:
+ {
+ \@@_scan_int:
+ \@@_scan_keyword:nF { sSeEtT }
+ {
+ \@@_scan_keyword:nF { pPuUsShH }
+ {
+ \@@_scan_keyword:nF { pPoOpP }
+ {
+ \@@_scan_keyword:nF { cCuUrRrReEnNtT }
+ {
+ \msg_error:nn { unravel }
+ { color-stack-action-missing }
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_rule_attr:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_rule_attr:
+ {
+ \@@_scan_alt_rule:
+ \@@_scan_keyword:nT { aA tT tT rR }
+ { \@@_scan_pdf_ext_toks: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_scan_action:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_action:
+ {
+ \@@_scan_keyword:nTF { uUsSeErR }
+ { \@@_scan_pdf_ext_toks: }
+ {
+ \@@_scan_keyword:nF { gGoOtToO }
+ {
+ \@@_scan_keyword:nF { tThHrReEaAdD }
+ { \msg_error:nn { unravel } { action-type-missing } }
+ }
+ }
+ \@@_scan_keyword:nT { fFiIlLeE }
+ { \@@_scan_pdf_ext_toks: }
+ \@@_scan_keyword:nTF { pPaAgGeE }
+ {
+ \@@_scan_int:
+ \@@_scan_pdf_ext_toks:
+ }
+ {
+ \@@_scan_keyword:nTF { nNaAmMeE }
+ { \@@_scan_pdf_ext_toks: }
+ {
+ \@@_scan_keyword:nTF { nNuUmM }
+ { \@@_scan_int: }
+ { \msg_error:nn { unravel } { identifier-type-missing } }
+ }
+ }
+ \@@_scan_keyword:nTF { nNeEwWwWiInNdDoOwW }
+ { \@@_skip_optional_space: }
+ {
+ \@@_scan_keyword:nT { nNoOnNeEwWwWiInNdDoOwW }
+ { \@@_skip_optional_space: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_image:}
+% Used by \tn{pdfximage}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_image:
+ {
+ \@@_scan_rule_attr:
+ \@@_scan_keyword:nTF { nNaAmMeEdD }
+ { \@@_scan_pdf_ext_toks: }
+ {
+ \@@_scan_keyword:nT { pPaAgGeE }
+ { \@@_scan_int: }
+ }
+ \@@_scan_keyword:nT { cCoOlLoOrRsSpPaAcCeE }
+ { \@@_scan_int: }
+ \@@_scan_pdf_ext_toks:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_scan_immediate_operands:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_immediate_operands:
+ {
+ \@@_get_x_next:
+ \@@_set_cmd:
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int = { \@@_tex_use:n { extension } }
+ {
+ \int_compare:nNnTF
+ \l_@@_head_char_int < { 3 } % openout, write, closeout
+ { \@@_scan_immediate_operands_aux: }
+ {
+ \int_case:nnF \l_@@_head_char_int
+ {
+ { 7 } { \@@_scan_extension_operands_aux: } % pdfobj
+ { 9 } { \@@_scan_extension_operands_aux: } % pdfxform
+ { 11 } { \@@_scan_extension_operands_aux: } %pdfximage
+ }
+ { \@@_scan_immediate_operands_bad: }
+ }
+ }
+ { \@@_scan_immediate_operands_bad: }
+ }
+\cs_new_protected_nopar:Npn \@@_scan_immediate_operands_aux:
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_extension_operands:
+ }
+\cs_new_protected_nopar:Npn \@@_scan_immediate_operands_bad:
+ {
+ \@@_back_input:
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl ignored }
+ \seq_gput_right:Nn \g_@@_prev_input_seq { }
+ }
+
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_scan_pdfdest_operands:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scan_pdfdest_operands:
+ {
+ \@@_scan_keyword:nTF { nNuUmM }
+ { \@@_scan_int: }
+ {
+ \@@_scan_keyword:nTF { nNaAmMeE }
+ { \@@_scan_pdf_ext_toks: }
+ { \msg_error:nn { unravel } { identifier-type-missing } }
+ }
+ \@@_scan_keyword:nTF { xXyYzZ }
+ {
+ \@@_scan_keyword:nT { zZoOoOmM }
+ { \@@_scan_int: }
+ }
+ {
+ \@@_scan_keyword:nF { fFiItTbBhH }
+ {
+ \@@_scan_keyword:nF { fFiItTbBvV }
+ {
+ \@@_scan_keyword:nF { fFiItTbB }
+ {
+ \@@_scan_keyword:nF { fFiItThHhH }
+ {
+ \@@_scan_keyword:nF { fFiItTvV }
+ {
+ \@@_scan_keyword:nTF
+ { fFiItTrR }
+ {
+ \@@_skip_optional_space:
+ \@@_scan_alt_rule:
+ \use_none:n
+ }
+ {
+ \@@_scan_keyword:nF
+ { fFiItT }
+ {
+ \msg_error:nn { unravel }
+ {
+ destination-type-missing
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ \@@_skip_optional_space:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \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
+% until coming to a non-prefix, then it carries out the command.''
+% We define all those commands in one go, from
+% |max_non_prefixed_command+1=71| to |max_command=102|.
+% \begin{macrocode}
+\cs_set_protected_nopar:Npn \@@_tmp:w
+ {
+ \seq_gput_right:Nn \g_@@_prev_input_seq { }
+ \@@_prefixed_command:
+ }
+\int_step_inline:nnnn
+ { \@@_tex_use:n { max_non_prefixed_command } + 1 }
+ { 1 }
+ { \@@_tex_use:n { max_command } }
+ { \cs_new_eq:cN { @@_cmd_#1: } \@@_tmp:w }
+% \end{macrocode}
+%
+% \begin{macro}[int]{\@@_prefixed_command:}
+% Accumulated prefix codes so far are stored as the last item of
+% \cs{g_@@_prev_input_seq}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_prefixed_command:
+ {
+ \int_while_do:nNnn
+ \l_@@_head_cmd_int = { \@@_tex_use:n { prefix } }
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_get_x_non_relax:
+ \@@_set_cmd:
+ \int_compare:nNnF \l_@@_head_cmd_int
+ > { \@@_tex_use:n { max_non_prefixed_command } }
+ {
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \msg_error:nnxx { unravel } { erroneous-prefixes }
+ { \tl_to_str:N \l_@@_tmpa_tl }
+ { \tl_to_str:N l_@@_head_tl }
+ \@@_back_input:
+ \@@_omit_after_assignment:w
+ }
+ }
+ % ^^A todo: Discard non-\global prefixes if they are irrelevant
+ % ^^A todo: Adjust for the setting of \globaldefs
+ \cs_if_exist_use:cF
+ { @@_prefixed_ \int_use:N \l_@@_head_cmd_int : }
+ {
+ \msg_error:nnx { unravel } { internal } { prefixed }
+ \@@_omit_after_assignment:w
+ }
+ \@@_after_assignment:
+ }
+% \end{macrocode}
+% \end{macro}
+% We now need to implement prefixed commands, for command codes in the
+% range $[71,102]$, with the exception of |prefix=93|, which would have
+% been collected by the \cs{@@_prefixed_command:} loop.
+%
+% \begin{macro}[aux]{\@@_after_assignment:}
+% \begin{macro}[aux]{\@@_omit_after_assignment:w}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_after_assignment:
+ {
+ \@@_back_input_gtl:N \g_@@_after_assignment_gtl
+ \gtl_gclear:N \g_@@_after_assignment_gtl
+ }
+\cs_new_protected_nopar:Npn \@@_omit_after_assignment:w
+ #1 \@@_after_assignment: { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_prefixed_new:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_prefixed_new:nn #1#2
+ {
+ \cs_new_protected_nopar:cpn
+ { @@_prefixed_ \@@_tex_use:n {#1} : } {#2}
+ }
+% \end{macrocode}
+% \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
+ {
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ #1
+ \tl_use:N \l_@@_head_tl \scan_stop:
+ \@@_print_assigned_token:
+ }
+% \end{macrocode}
+% \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:
+ {
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \tl_use:N \l_@@_head_tl \scan_stop:
+ \@@_print_assigned_register:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_assign_value:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_assign_value:nn #1#2
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
+ #1
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ }
+ \@@_prev_input:V \l_@@_head_tl
+ \tl_set_eq:NN \l_@@_defined_tl \l_@@_head_tl
+ \@@_scan_optional_equals:
+ #2
+ \@@_assign_register:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_assign_toks:}
+% \begin{macrocode}
+\@@_prefixed_new:nn { toks_register } % 71
+ {
+ \int_compare:nNnT \l_@@_head_char_int = \c_zero
+ { % \toks
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_int:
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ }
+ \@@_assign_toks:
+ }
+\@@_prefixed_new:nn { assign_toks } % 72
+ { \@@_assign_toks: }
+\cs_new_protected_nopar:Npn \@@_assign_toks:
+ {
+ \@@_prev_input_silent:V \l_@@_head_tl
+ \@@_print_action:
+ \tl_set_eq:NN \l_@@_defined_tl \l_@@_head_tl
+ \@@_scan_optional_equals:
+ \@@_get_x_non_relax:
+ \@@_set_cmd:
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int = { \@@_tex_use:n { toks_register } }
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \int_compare:nNnT \l_@@_head_char_int = \c_zero
+ { \@@_scan_int: }
+ }
+ {
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int = { \@@_tex_use:n { assign_toks } }
+ { \@@_prev_input:V \l_@@_head_tl }
+ {
+ \@@_back_input:
+ \@@_scan_toks:NN \c_false_bool \c_false_bool
+ }
+ }
+ \@@_assign_register:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\@@_prefixed_new:nn { assign_int } % 73
+ { \@@_assign_value:nn { } { \@@_scan_int: } }
+\@@_prefixed_new:nn { assign_dimen } % 74
+ { \@@_assign_value:nn { } { \@@_scan_normal_dimen: } }
+\@@_prefixed_new:nn { assign_glue } % 75
+ { \@@_assign_value:nn { } { \@@_scan_normal_glue: } }
+\@@_prefixed_new:nn { assign_mu_glue } % 76
+ { \@@_assign_value:nn { } { \@@_scan_mu_glue: } }
+\@@_prefixed_new:nn { assign_font_dimen } % 77
+ {
+ \@@_assign_value:nn
+ { \@@_scan_int: \@@_scan_font_ident: }
+ { \@@_scan_normal_dimen: }
+ }
+\@@_prefixed_new:nn { assign_font_int } % 78
+ {
+ \@@_assign_value:nn
+ { \@@_scan_font_int: } { \@@_scan_int: }
+ }
+\@@_prefixed_new:nn { set_aux } % 79
+ { % prevdepth = 1, spacefactor = 0
+ \int_compare:nNnTF \l_@@_head_char_int = \c_one
+ { \@@_assign_value:nn { } { \@@_scan_normal_dimen: } }
+ { \@@_assign_value:nn { } { \@@_scan_int: } }
+ }
+\@@_prefixed_new:nn { set_prev_graf } % 80
+ { \@@_assign_value:nn { } { \@@_scan_int: } }
+\@@_prefixed_new:nn { set_page_dimen } % 81
+ { \@@_assign_value:nn { } { \@@_scan_normal_dimen: } }
+\@@_prefixed_new:nn { set_page_int } % 82
+ { \@@_assign_value:nn { } { \@@_scan_int: } }
+\@@_prefixed_new:nn { set_box_dimen } % 83
+ {
+ \@@_assign_value:nn
+ { \@@_scan_int: } { \@@_scan_normal_dimen: }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_prefixed_new:nn { set_shape } % 84
+ {
+ \@@_assign_value:nn { \@@_scan_int: }
+ {
+ \prg_replicate:nn
+ {
+ \tl_if_head_eq_meaning:VNT
+ \l_@@_defined_tl \tex_parshape:D { \c_two * }
+ \tl_tail:N \l_@@_defined_tl
+ }
+ { \@@_scan_int: }
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_prefixed_new:nn { def_code } % 85
+ {
+ \@@_assign_value:nn
+ { \@@_scan_int: } { \@@_scan_int: }
+ }
+\@@_prefixed_new:nn { def_family } % 86
+ {
+ \@@_assign_value:nn
+ { \@@_scan_int: } { \@@_scan_font_ident: }
+ }
+\@@_prefixed_new:nn { set_font } % 87
+ {
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \tl_put_left:NV \l_@@_head_tl \l_@@_tmpa_tl
+ \tl_use:N \l_@@_head_tl \scan_stop:
+ \gtl_gput_right:NV \g_@@_output_gtl \l_@@_head_tl
+ \@@_print_action:
+ }
+\@@_prefixed_new:nn { def_font } % 88
+ {
+ \@@_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 }
+ \@@_scan_optional_equals:
+ \@@_scan_file_name:
+ \bool_gset_true:N \g_@@_name_in_progress_bool
+ \@@_scan_keyword:nTF { aAtT }
+ { \@@_scan_normal_dimen: }
+ {
+ \@@_scan_keyword:nT { sS cC aA lL eE dD }
+ { \@@_scan_int: }
+ }
+ \bool_gset_false:N \g_@@_name_in_progress_bool
+ \@@_assign_token:n { }
+ }
+% \end{macrocode}
+%
+% |register=89|, |advance=90|, |multiply=91|, |divide=92| are
+% implemented elsewhere. |prefix=93| is never needed (see explanation
+% above).
+%
+% |let|, |futurelet|
+% \begin{macrocode}
+\@@_prefixed_new:nn { let } % 94
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \token_if_eq_meaning:NNTF \l_@@_head_token \tex_let:D
+ { % |let|
+ \@@_scan_r_token:
+ \seq_get_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \@@_print_action:x { \tl_to_str:N \l_@@_tmpa_tl }
+ \@@_get_next:
+ \bool_while_do:nn
+ { \token_if_eq_catcode_p:NN \l_@@_head_token \c_space_token }
+ { \@@_get_next: }
+ \tl_if_eq:NNT \l_@@_head_tl \c_@@_eq_tl
+ { \@@_get_next: }
+ \token_if_eq_catcode:NNT \l_@@_head_token \c_space_token
+ { \@@_get_next: }
+ }
+ { % |futurelet|
+ \@@_scan_r_token:
+ \seq_get_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \@@_print_action:x { \tl_to_str:N \l_@@_tmpa_tl }
+ \@@_get_next:
+ \gtl_set_eq:NN \l_@@_tmpb_gtl \l_@@_head_gtl
+ \@@_get_next:
+ \@@_back_input:
+ \gtl_set_eq:NN \l_@@_head_gtl \l_@@_tmpb_gtl
+ \@@_back_input:
+ }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \tl_put_right:Nn \l_@@_tmpa_tl { = ~ \l_@@_head_token }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \use:x
+ {
+ \exp_not:V \l_@@_head_tl
+ \tex_let:D \tl_tail:N \l_@@_tmpa_tl
+ }
+ \@@_print_assigned_token:
+ }
+% \end{macrocode}
+%
+% ^^A todo: print the temporary relax assignment?
+% \begin{macrocode}
+\@@_prefixed_new:nn { shorthand_def } % 95
+ {
+ \@@_prev_input_silent:V \l_@@_head_tl
+ \tl_set:Nx \l_@@_prev_action_tl
+ { \tl_to_str:N \l_@@_head_tl }
+ \@@_scan_r_token:
+ \@@_print_action:x
+ { \l_@@_prev_action_tl \tl_to_str:N \l_@@_defined_tl }
+ \exp_after:wN \cs_set_eq:NN \l_@@_defined_tl \scan_stop:
+ \@@_scan_optional_equals:
+ \@@_scan_int:
+ \@@_assign_token:n { }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_prefixed_new:nn { read_to_cs } % 96
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
+ \@@_scan_int:
+ \@@_scan_keyword:nF { tToO }
+ {
+ \msg_error:nn { unravel } { missing-to }
+ \@@_prev_input:n { to }
+ }
+ \@@_scan_r_token:
+ \@@_assign_token:n { }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_prefixed_new:nn { def } % 97
+ {
+ \seq_get_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \tl_set:NV \l_@@_defining_tl \l_@@_tmpa_tl
+ \tl_put_right:NV \l_@@_defining_tl \l_@@_head_tl
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \int_compare:nNnTF \l_@@_head_char_int < \c_two
+ { % def/gdef
+ \@@_scan_r_token:
+ \tl_put_right:NV \l_@@_defining_tl \l_@@_defined_tl
+ \@@_scan_toks:NN \c_true_bool \c_false_bool
+ }
+ { % edef/xdef
+ \@@_scan_r_token:
+ \tl_put_right:NV \l_@@_defining_tl \l_@@_defined_tl
+ \@@_scan_toks:NN \c_true_bool \c_true_bool
+ }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_assign_token:n
+ { \tl_set_eq:NN \l_@@_head_tl \l_@@_defining_tl }
+ }
+% \end{macrocode}
+%
+% \tn{setbox} is a bit special: directly put it in
+% \cs{g_@@_prev_input_seq} with the prefixes; the box code will take
+% care of things, and expects a single item containing what it needs to
+% do.
+% \begin{macrocode}
+\@@_prefixed_new:nn { set_box } % 98
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_int:
+ \@@_scan_optional_equals:
+ \bool_if:NTF \g_@@_set_box_allowed_bool
+ { \@@_do_box:N \c_false_bool }
+ {
+ \msg_error:nn { unravel } { improper-setbox }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \@@_omit_after_assignment:w
+ }
+ }
+% \end{macrocode}
+%
+% ^^A todo: \hyphenation{...{...}...} recovers weirdly (no nesting).
+% \tn{hyphenation} and \tn{patterns}
+% \begin{macrocode}
+\@@_prefixed_new:nn { hyph_data } % 99
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_scan_toks:NN \c_false_bool \c_false_bool
+ \@@_assign_token:n { }
+ }
+% \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_use:N \l_@@_head_tl \scan_stop:
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
+ }
+% \end{macrocode}
+%
+% \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
+ }
+\@@_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
+ }
+% \end{macrocode}
+%
+% Changes to numeric registers (\tn{count}, \tn{dimen}, \tn{skip},
+% \tn{muskip}, and commands with a built-in number).
+% \begin{macrocode}
+\@@_prefixed_new:nn { register } % 89
+ { \@@_do_register:N \c_zero }
+\@@_prefixed_new:nn { advance } % 90
+ { \@@_do_operation:N \c_one }
+\@@_prefixed_new:nn { multiply } % 91
+ { \@@_do_operation:N \c_two }
+\@@_prefixed_new:nn { divide } % 92
+ { \@@_do_operation:N \c_three }
+% \end{macrocode}
+%
+% \begin{macro}[aux]{\@@_do_operation:N, \@@_do_operation_fail:w}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_do_operation:N #1
+ {
+ \@@_prev_input_silent:V \l_@@_head_tl
+ \@@_print_action:
+ \@@_get_x_next:
+ \@@_set_cmd:
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int > { \@@_tex_use:n { assign_mu_glue } }
+ {
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int = { \@@_tex_use:n { register } }
+ { \@@_do_register:N #1 }
+ { \@@_do_operation_fail:w }
+ }
+ {
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int < { \@@_tex_use:n { assign_int } }
+ { \@@_do_operation_fail:w }
+ {
+ \@@_prev_input:V \l_@@_head_tl
+ \exp_args:NNf \@@_do_register_set:Nn #1
+ {
+ \int_eval:n
+ {
+ \l_@@_head_cmd_int
+ - \@@_tex_use:n { assign_toks }
+ }
+ }
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \@@_do_operation_fail:w
+ {
+ \msg_error:nn { unravel } { after-advance }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \@@_omit_after_assignment:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_do_register:N, \@@_do_register_aux:Nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_do_register:N #1
+ {
+ \exp_args:NNV \@@_do_register_aux:Nn #1
+ \l_@@_head_char_int
+ }
+\cs_new_protected:Npn \@@_do_register_aux:Nn #1#2
+ {
+ \int_compare:nNnTF { \tl_tail:n {#2} } = \c_zero
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_scan_int:
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_prev_input_silent:V \l_@@_head_tl
+ }
+ {
+ \@@_prev_input_silent:V \l_@@_head_tl
+ \@@_print_action:
+ }
+ \tl_set_eq:NN \l_@@_defined_tl \l_@@_head_tl
+ \exp_args:NNf \@@_do_register_set:Nn #1
+ { \int_eval:n { #2 / 1 000 000 } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_do_register_set:Nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_do_register_set:Nn #1#2
+ {
+ \int_compare:nNnTF {#1} = \c_zero
+ { % truly register command
+ \@@_scan_optional_equals:
+ }
+ { % \advance, \multiply, \divide
+ \@@_scan_keyword:nF { bByY }
+ { \@@_prev_input_silent:n { by } }
+ }
+ \int_compare:nNnTF {#1} < \c_two
+ {
+ \int_case:nnF {#2}
+ {
+ { 1 } { \@@_scan_int: } % count
+ { 2 } { \@@_scan_normal_dimen: } % dim
+ { 3 } { \@@_scan_normal_glue: } % glue
+ { 4 } { \@@_scan_mu_glue: } % muglue
+ }
+ { \msg_error:nnx { unravel } { internal } { do-reg=#2 } }
+ }
+ { \@@_scan_int: }
+ \@@_assign_register:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% The following is used for instance when making accents.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_do_assignments:
+ {
+ \@@_get_x_non_relax:
+ \@@_set_cmd:
+ \int_compare:nNnT
+ \l_@@_head_cmd_int
+ > { \@@_tex_use:n { max_non_prefixed_command } }
+ {
+ \bool_gset_false:N \g_@@_set_box_allowed_bool
+ \seq_gput_right:Nn \g_@@_prev_input_seq { }
+ \@@_prefixed_command:
+ \bool_gset_true:N \g_@@_set_box_allowed_bool
+ \@@_do_assignments:
+ }
+ }
+% \end{macrocode}
+%
+% \subsection{Expandable primitives}
+%
+% This section implements expandable primitives, which have the
+% following command codes:
+% \begin{itemize}
+% \item |undefined_cs=103| for undefined control sequences (not quite a
+% primitive).
+% \item |expand_after=104| for \tn{expandafter} and \tn{unless}.
+% \item |no_expand=105| for \tn{noexpand} and \tn{pdfprimitive}.
+% \item |input=106| for \tn{input}, \tn{endinput} and \tn{scantokens}.
+% \item |if_test=107| for the conditionals, \tn{if}, \tn{ifcat},
+% \tn{ifnum}, \tn{ifdim}, \tn{ifodd}, \tn{ifvmode}, \tn{ifhmode},
+% \tn{ifmmode}, \tn{ifinner}, \tn{ifvoid}, \tn{ifhbox}, \tn{ifvbox},
+% \tn{ifx}, \tn{ifeof}, \tn{iftrue}, \tn{iffalse}, \tn{ifcase},
+% \tn{ifdefined}, \tn{ifcsname}, \tn{iffontchar}, \tn{ifincsname},
+% \tn{ifpdfprimitive}, \tn{ifpdfabsnum}, and \tn{ifpdfabsdim}.
+% \item |fi_or_else=108| for \tn{fi}, \tn{else} and \tn{or}.
+% \item |cs_name=109| for \tn{csname}.
+% \item |convert=110| for \tn{number}, \tn{romannumeral}, \tn{string},
+% \tn{meaning}, \tn{fontname}, \tn{eTeXrevision}, \tn{pdftexrevision},
+% \tn{pdftexbanner}, \tn{pdffontname}, \tn{pdffontobjnum},
+% \tn{pdffontsize}, \tn{pdfpageref}, \tn{pdfxformname},
+% \tn{pdfescapestring}, \tn{pdfescapename}, \tn{leftmarginkern},
+% \tn{rightmarginkern}, \tn{pdfstrcmp}, \tn{pdfcolorstackinit},
+% \tn{pdfescapehex}, \tn{pdfunescapehex}, \tn{pdfcreationdate},
+% \tn{pdffilemoddate}, \tn{pdffilesize}, \tn{pdfmdfivesum},
+% \tn{pdffiledump}, \tn{pdfmatch}, \tn{pdflastmatch},
+% \tn{pdfuniformdeviate}, \tn{pdfnormaldeviate}, \tn{pdfinsertht},
+% \tn{pdfximagebbox}, and \tn{jobname}.
+% \item |the=111| for \tn{the}, \tn{unexpanded}, and \tn{detokenize}.
+% \item |top_bot_mark=112| \tn{topmark}, \tn{firstmark}, \tn{botmark},
+% \tn{splitfirstmark}, \tn{splitbotmark}, \tn{topmarks},
+% \tn{firstmarks}, \tn{botmarks}, \tn{splitfirstmarks}, and
+% \tn{splitbotmarks}.
+% \item |call=113| for macro calls, implemented by \cs{@@_macro_call:}.
+% \item |end_template=117| for \TeX{}'s end template.
+% \end{itemize}
+%
+% Let \TeX{} trigger an error.
+% \begin{macrocode}
+\@@_new_tex_expandable:nn { undefined_cs } % 103
+ { \tl_use:N \l_@@_head_tl \@@_print_action: }
+% \end{macrocode}
+%
+% \begin{macro}[aux]{\@@_expandafter:, \@@_unless:, \@@_unless_bad:}
+% \begin{macrocode}
+\@@_new_tex_expandable:nn { expand_after } % 104
+ {
+ \token_if_eq_meaning:NNTF \l_@@_head_token \tex_expandafter:D
+ { \@@_expandafter: } { \@@_unless: }
+ }
+\cs_new_protected_nopar:Npn \@@_expandafter:
+ {
+ \gtl_set_eq:NN \l_@@_tmpb_gtl \l_@@_head_gtl
+ \@@_get_next:
+ \gtl_concat:NNN \l_@@_head_gtl
+ \l_@@_tmpb_gtl \l_@@_head_gtl
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_gtl
+ \@@_print_action:x { \gtl_to_str:N \l_@@_head_gtl }
+ \@@_get_next:
+ \@@_token_if_expandable:NTF \l_@@_head_token
+ { \@@_expand: }
+ { \@@_back_input: }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_gtl
+ \@@_set_action_text:x
+ { back_input: ~ \gtl_to_str:N \l_@@_head_gtl }
+ \gtl_pop_left:N \l_@@_head_gtl
+ \@@_back_input:
+ \@@_print_action:
+ }
+\cs_new_protected_nopar:Npn \@@_unless:
+ {
+ \@@_get_token:
+ \int_compare:nNnTF
+ \l_@@_head_cmd_int = { \@@_tex_use:n { if_test } }
+ {
+ \token_if_eq_meaning:NNTF \l_@@_head_token \tex_ifcase:D
+ { \@@_unless_bad: }
+ {
+ \tl_put_left:Nn \l_@@_head_tl { \reverse_if:N }
+ % \int_add:Nn \l_@@_head_char_int { 32 }
+ \@@_expand_nonmacro:
+ }
+ }
+ { \@@_unless_bad: }
+ }
+\cs_new_protected_nopar:Npn \@@_unless_bad:
+ {
+ \msg_error:nn { unravel } { bad-unless }
+ \@@_back_input:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_noexpand:, \@@_pdfprimitive:}
+% \begin{macrocode}
+\@@_new_tex_expandable:nn { no_expand } % 105
+ {
+ \token_if_eq_meaning:NNTF \l_@@_head_token \tex_noexpand:D
+ { \@@_noexpand: }
+ { \@@_pdfprimitive: }
+ }
+\cs_new_protected_nopar:Npn \@@_noexpand:
+ {
+ \@@_get_token:
+ \@@_back_input:
+ \@@_token_if_expandable:NT \l_@@_head_token
+ {
+ \cs_gset_protected_nopar:Npx \@@_get_next:
+ {
+ \cs_gset_protected_nopar:Npn \@@_get_next:
+ { \exp_not:o { \@@_get_next: } }
+ \exp_not:o { \@@_get_next: }
+ \exp_not:n { \cs_set_eq:NN \l_@@_head_token \tex_relax:D }
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \@@_pdfprimitive:
+ { \msg_error:nnx { unravel } { not-implemented } { pdfprimitive } }
+% \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{macrocode}
+\@@_new_tex_expandable:nn { input } % 106
+ {
+ \int_case:nnF \l_@@_head_char_int
+ {
+ { 1 } { \@@_print_action: } % \endinput
+ { 2 } { \@@_scantokens: } % \scantokens
+ }
+ { % 0=\input
+ \bool_if:NTF \g_@@_name_in_progress_bool
+ { \@@_insert_relax: } { \@@_input: }
+ }
+ }
+\cs_new_protected_nopar:Npn \@@_scantokens:
+ {
+ \seq_gput_right:Nn \g_@@_prev_input_seq { }
+ \@@_scan_toks:NN \c_false_bool \c_false_bool
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \tl_set_rescan:Nno \l_@@_head_tl { } \l_@@_tmpa_tl
+ \@@_back_input:V \l_@@_head_tl
+ \@@_print_action:x { \tl_to_str:N \l_@@_tmpa_tl }
+ }
+\cs_new_protected_nopar:Npn \@@_input:
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_scan_file_name:
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \tl_set:Nx \l_@@_tmpa_tl { \tl_tail:N \l_@@_head_tl }
+ \@@_tl_gset_input:Nno \g_@@_tmpc_tl { } \l_@@_tmpa_tl
+ \@@_back_input:V \g_@@_tmpc_tl
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
+ }
+% \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
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_csname_loop:
+ \@@_prev_input:V \l_@@_head_tl
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_back_input_tl_o:
+ }
+\cs_new_protected_nopar:Npn \@@_csname_loop:
+ {
+ \@@_get_x_next:
+ \token_if_cs:NTF \l_@@_head_token
+ {
+ \cs_if_eq:NNF \l_@@_head_token \tex_endcsname:D
+ {
+ \msg_error:nn { unravel } { missing-endcsname }
+ \@@_back_input:
+ \tl_set:Nn \l_@@_head_tl { \tex_endcsname:D }
+ }
+ }
+ {
+ \@@_prev_input_silent:x
+ { \@@_token_to_char:N \l_@@_head_token }
+ \@@_csname_loop:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\@@_new_tex_expandable:nn { convert } % 110
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \int_case:nn \l_@@_head_char_int
+ {
+ 0 \@@_scan_int:
+ 1 \@@_scan_int:
+ 2 { \@@_get_next: \@@_prev_input:V \l_@@_head_tl }
+ 3 { \@@_get_next: \@@_prev_input:V \l_@@_head_tl }
+ 4 \@@_scan_font_ident:
+ 8 \@@_scan_font_ident:
+ 9 \@@_scan_font_ident:
+ { 10 } \@@_scan_font_ident:
+ { 11 } \@@_scan_int:
+ { 12 } \@@_scan_int:
+ { 13 } \@@_scan_pdf_ext_toks:
+ { 14 } \@@_scan_pdf_ext_toks:
+ { 15 } \@@_scan_int:
+ { 16 } \@@_scan_int:
+ { 17 } \@@_scan_pdfstrcmp:
+ { 18 } \@@_scan_pdfcolorstackinit:
+ { 19 } \@@_scan_pdf_ext_toks:
+ { 20 } \@@_scan_pdf_ext_toks:
+ { 22 } \@@_scan_pdf_ext_toks:
+ { 23 } \@@_scan_pdf_ext_toks:
+ { 24 }
+ {
+ \@@_scan_keyword:n { fF iI lL eE }
+ \@@_scan_pdf_ext_toks:
+ }
+ { 25 } \@@_scan_pdffiledump:
+ { 26 } \@@_scan_pdfmatch:
+ { 27 } \@@_scan_int:
+ { 28 } \@@_scan_int:
+ { 30 } \@@_scan_int:
+ { 31 } \@@_scan_pdfximagebbox:
+ }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_back_input_tl_o:
+ }
+\cs_new_protected_nopar:Npn \@@_scan_pdfstrcmp:
+ {
+ \@@_scan_toks_to_str:
+ \@@_scan_toks_to_str:
+ }
+\cs_new_protected_nopar:Npn \@@_scan_pdfximagebbox:
+ { \@@_scan_int: \@@_scan_int: }
+\cs_new_protected_nopar:Npn \@@_scan_pdfcolorstackinit:
+ {
+ \@@_scan_keyword:nTF { pP aA gG eE }
+ { \bool_set_true:N \l_@@_tmpa_bool }
+ { \bool_set_false:N \l_@@_tmpb_bool }
+ \@@_scan_keyword:nF { dD iI rR eE cC tT }
+ { \@@_scan_keyword:n { pP aA gG eE } }
+ \@@_scan_toks_to_str:
+ }
+\cs_new_protected_nopar:Npn \@@_scan_pdffiledump:
+ {
+ \@@_scan_keyword:nT { oO fF fF sS eE tT } \@@_scan_int:
+ \@@_scan_keyword:nT { lL eE nN gG tT hH } \@@_scan_int:
+ \@@_scan_pdf_ext_toks:
+ }
+\cs_new_protected_nopar:Npn \@@_scan_pdfmatch:
+ {
+ \@@_scan_keyword:n { iI cC aA sS eE }
+ \@@_scan_keyword:nT { sS uU bB cC oO uU nN tT }
+ { \@@_scan_int: }
+ \@@_scan_pdf_ext_toks:
+ \@@_scan_pdf_ext_toks:
+ }
+% \end{macrocode}
+%
+% \begin{macro}[aux]{\@@_get_the:}
+% \begin{macrocode}
+\@@_new_tex_expandable:nn { the } % 111
+ {
+ \@@_get_the:
+ \tl_set:Nx \l_@@_tmpa_tl { \exp_args:NV \exp_not:o \l_@@_head_tl }
+ \@@_back_input:V \l_@@_tmpa_tl
+ \@@_print_action:
+ }
+\cs_new_protected_nopar:Npn \@@_get_the:
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \int_if_odd:nTF \l_@@_head_char_int
+ { % \unexpanded, \detokenize
+ \@@_scan_toks:NN \c_false_bool \c_false_bool
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_set_action_text:x { \tl_to_str:N \l_@@_head_tl }
+ }
+ { % \the
+ \@@_get_x_next:
+ \@@_scan_something_internal:n { 5 }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_set_action_text:x
+ {
+ \tl_head:N \l_@@_head_tl
+ => \tl_tail:N \l_@@_head_tl
+ }
+ \tl_set:Nx \l_@@_head_tl
+ { \exp_not:N \exp_not:n { \tl_tail:N \l_@@_head_tl } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\@@_new_tex_expandable:nn { top_bot_mark } % 112
+ { \@@_back_input_tl_o: }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_new_tex_expandable:nn { end_template } % 117
+ {
+ \msg_error:nn { unravel } { not-implemented } { end-template }
+ \@@_back_input_tl_o:
+ }
+% \end{macrocode}
+%
+%
+% \subsubsection{Conditionals}
+%
+% ^^A todo: simply use \cs{@@_input_gpop:N} right away.
+% \begin{macro}[int]{\@@_pass_text:}
+% \begin{macro}[aux]{\@@_pass_text_done:w}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_pass_text:
+ {
+ \@@_input_if_empty:TF
+ { \@@_pass_text_empty: }
+ {
+ \@@_input_get:N \l_@@_tmpb_gtl
+ \if_true:
+ \if_case:w \gtl_head_do:NN \l_@@_tmpb_gtl \c_one
+ \exp_after:wN \@@_pass_text_done:w
+ \fi:
+ \@@_input_gpop:N \l_@@_tmpb_gtl
+ \exp_after:wN \@@_pass_text:
+ \else:
+ \use:c { fi: }
+ \int_set_eq:NN \l_@@_if_nesting_int \c_one
+ \@@_input_gpop:N \l_@@_tmpb_gtl
+ \exp_after:wN \@@_pass_text_nested:
+ \fi:
+ }
+ }
+\cs_new_protected_nopar:Npn \@@_pass_text_done:w
+ {
+ \@@_get_next:
+ \token_if_eq_meaning:NNT \l_@@_head_token \fi: { \if_true: }
+ \else:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_pass_text_nested:}
+% Again, if there is no more input we are in trouble. The
+% construction otherwise essentially results in
+% \begin{quote}
+% \cs{if_true:} \cs{if_true:} \cs{else:} \meta{head} \\
+% \cs{int_decr:N} \cs{l_@@_if_nesting_int} \cs{use_none:nnnnn} \cs{fi:} \\
+% \cs{use_none:nnn} \cs{fi:} \\
+% \cs{int_incr:N} \cs{l_@@_if_nesting_int} \cs{fi:}
+% \end{quote}
+% If the \meta{head} is a primitive |\if...|, then the \cs{if_true:}
+% \cs{else:} ends with the second \cs{fi:}, and the nesting integer is
+% incremented before appropriately closing the \cs{if_true:}. If it
+% is a normal token or \tn{or} or \tn{else}, \cs{use_none:nnn} cleans
+% up, leaving the appropriate number of \cs{fi:}. Finally, if it is
+% \cs{fi:}, the nesting integer is decremented before removing most
+% \cs{fi:}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_pass_text_nested:
+ {
+ \@@_input_if_empty:TF
+ { \@@_pass_text_empty: }
+ {
+ \@@_input_get:N \l_@@_tmpb_gtl
+ \if_true:
+ \if_true:
+ \gtl_head_do:NN \l_@@_tmpb_gtl \else:
+ \int_decr:N \l_@@_if_nesting_int
+ \use_none:nnnnn
+ \fi:
+ \use_none:nnn
+ \fi:
+ \int_incr:N \l_@@_if_nesting_int
+ \fi:
+ \@@_input_gpop:N \l_@@_tmpa_gtl
+ \int_compare:nNnTF \l_@@_if_nesting_int = \c_zero
+ { \@@_pass_text: }
+ { \@@_pass_text_nested: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_pass_text_empty:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_pass_text_empty:
+ {
+ \msg_error:nn { unravel } { runaway-if }
+ \@@_exit:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_cond_push:, \@@_cond_pop:}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cond_push:
+ {
+ \tl_gput_left:Nx \g_@@_if_limit_tl
+ { { \int_use:N \g_@@_if_limit_int } }
+ \int_gincr:N \g_@@_if_depth_int
+ \int_gzero:N \g_@@_if_limit_int
+ }
+\cs_new_protected_nopar:Npn \@@_cond_pop:
+ {
+ \int_gset:Nn \g_@@_if_limit_int
+ { \tl_head:N \g_@@_if_limit_tl }
+ \tl_gset:Nx \g_@@_if_limit_tl
+ { \tl_tail:N \g_@@_if_limit_tl }
+ \int_gdecr:N \g_@@_if_depth_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_change_if_limit:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_change_if_limit:nn #1#2
+ {
+ \int_compare:nNnTF {#2} = \g_@@_if_depth_int
+ { \int_gset:Nn \g_@@_if_limit_int {#1} }
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ \prg_replicate:nn { \g_@@_if_depth_int - #2 - \c_one }
+ {
+ \tl_put_right:Nx \l_@@_tmpa_tl
+ { { \tl_head:N \g_@@_if_limit_tl } }
+ \tl_gset:Nx \g_@@_if_limit_tl
+ { \tl_tail:N \g_@@_if_limit_tl }
+ }
+ \tl_gset:Nx \g_@@_if_limit_tl
+ { \l_@@_tmpa_tl {#1} \tl_tail:N \g_@@_if_limit_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\@@_new_tex_expandable:nn { if_test } % 107
+ {
+ \@@_cond_push:
+ \exp_args:NV \@@_cond_aux:n \g_@@_if_depth_int
+ }
+% \end{macrocode}
+%
+% \begin{macro}[aux]{\@@_cond_aux:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cond_aux:n #1
+ {
+ \int_case:nnF \l_@@_head_char_int
+ {
+ { 12 } { \@@_test_ifx:n {#1} }
+ { 16 } { \@@_test_case:n {#1} }
+ { 21 } { \@@_test_pdfprimitive:n {#1} } % ^^A todo and \unless
+ }
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \int_case:nn \l_@@_head_char_int
+ {
+ { 0 } { \@@_test_two_chars: } % if
+ { 1 } { \@@_test_two_chars: } % ifcat
+ { 2 } % ifnum
+ { \@@_test_two_vals:N \@@_scan_int: }
+ { 3 } % ifdim
+ { \@@_test_two_vals:N \@@_scan_normal_dimen: }
+ { 4 } { \@@_scan_int: } % ifodd
+ % { 5 } { } % ifvmode
+ % { 6 } { } % ifhmode
+ % { 7 } { } % ifmmode
+ % { 8 } { } % ifinner
+ { 9 } { \@@_scan_int: } % ifvoid
+ { 10 } { \@@_scan_int: } % ifhbox
+ { 11 } { \@@_scan_int: } % ifvbox
+ { 13 } { \@@_scan_int: } % ifeof
+ % { 14 } { } % iftrue
+ % { 15 } { } % iffalse
+ { 17 } { \@@_test_ifdefined: } % ifdefined
+ { 18 } { \@@_test_ifcsname: } % ifcsname
+ { 19 } % iffontchar
+ { \@@_scan_font_ident: \@@_scan_int: }
+ % { 20 } { } % ifincsname % ^^A todo: something?
+ { 22 } % ifpdfabsnum
+ { \@@_test_two_vals:N \@@_scan_int: }
+ { 23 } % ifpdfabsdim
+ { \@@_test_two_vals:N \@@_scan_normal_dimen: }
+ }
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_set_action_text:x { \tl_to_str:N \l_@@_head_tl }
+ \l_@@_head_tl \scan_stop:
+ \exp_after:wN \@@_cond_true:n
+ \else:
+ \exp_after:wN \@@_cond_false:n
+ \fi:
+ {#1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_cond_true:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cond_true:n #1
+ {
+ \@@_change_if_limit:nn { 3 } {#1} % wait for else/fi
+ \@@_print_action:x { \g_@@_action_text_str = true }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]
+% {\@@_cond_false:n, \@@_cond_false_loop:n, \@@_cond_false_common:}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cond_false:n #1
+ {
+ \@@_cond_false_loop:n {#1}
+ \@@_cond_false_common:
+ \@@_print_action:x { \g_@@_action_text_str = false }
+ }
+\cs_new_protected:Npn \@@_cond_false_loop:n #1
+ {
+ \@@_pass_text:
+ \int_compare:nNnTF \g_@@_if_depth_int = {#1}
+ {
+ \token_if_eq_meaning:NNT \l_@@_head_token \or:
+ {
+ \msg_error:nn { unravel } { extra-or }
+ \@@_cond_false_loop:n {#1}
+ }
+ }
+ {
+ \token_if_eq_meaning:NNT \l_@@_head_token \fi:
+ { \@@_cond_pop: }
+ \@@_cond_false_loop:n {#1}
+ }
+ }
+\cs_new_protected_nopar:Npn \@@_cond_false_common:
+ {
+ \token_if_eq_meaning:NNTF \l_@@_head_token \fi:
+ { \@@_cond_pop: }
+ { \int_gset:Nn \g_@@_if_limit_int { 2 } } % wait for fi
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_test_two_vals:N}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_test_two_vals:N #1
+ {
+ #1
+ \@@_get_x_non_blank:
+ \tl_if_in:nVF { < = > } \l_@@_head_tl
+ {
+ \msg_error:nn { unravel } { missing-equals }
+ \@@_back_input:
+ \tl_set:Nn \l_@@_head_tl { = }
+ }
+ \@@_prev_input:V \l_@@_head_tl
+ #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: fix interaction with noexpand and active chars
+% ^^A todo: fix non-brace begin-group and end-group tokens
+% \begin{macro}[aux]{\@@_test_two_chars:, \@@_test_two_chars_aux:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_test_two_chars:
+ {
+ \@@_test_two_chars_aux:
+ \@@_prev_input:V \l_@@_head_tl
+ \@@_test_two_chars_aux:
+ \@@_prev_input:V \l_@@_head_tl
+ }
+\cs_new_protected_nopar:Npn \@@_test_two_chars_aux:
+ {
+ \@@_get_x_next:
+ \gtl_if_tl:NF \l_@@_head_gtl
+ {
+ \tl_set:Nx \l_@@_head_tl
+ {
+ \gtl_if_head_is_group_begin:NTF \l_@@_head_gtl
+ { \c_group_begin_token } { \c_group_end_token }
+ }
+ }
+ \tl_put_left:Nn \l_@@_head_tl { \exp_not:N } % ^^A todo: prettify.
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_test_ifx:n, \@@_test_ifx_aux:w}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_test_ifx:n #1
+ {
+ \seq_gput_right:NV \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:
+ \@@_get_next:
+ \gtl_set_eq:NN \l_@@_tmpb_gtl \l_@@_head_gtl
+ \@@_get_next:
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_tmpa_tl
+ \@@_set_action_text:x
+ {
+ Compare:~ \tl_to_str:N \l_@@_tmpa_tl
+ \gtl_to_str:N \l_@@_tmpb_gtl
+ \gtl_to_str:N \l_@@_head_gtl
+ }
+ \gtl_head_do:NN \l_@@_tmpb_gtl \@@_test_ifx_aux:w
+ \exp_after:wN \@@_cond_true:n
+ \else:
+ \exp_after:wN \@@_cond_false:n
+ \fi:
+ {#1}
+ }
+\cs_new_nopar:Npn \@@_test_ifx_aux:w
+ { \gtl_head_do:NN \l_@@_head_gtl \l_@@_tmpa_tl }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_test_case:n, \@@_test_case_aux:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_test_case:n #1
+ {
+ \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} } }
+ \@@_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 }
+ % ^^A does text_case_aux use prev_input_seq?
+ \exp_args:No \@@_test_case_aux:nn { \l_@@_head_tl } {#1}
+ \seq_gpop_right:NN \g_@@_prev_input_seq \l_@@_head_tl
+ \@@_print_action:x { \tl_to_str:N \l_@@_head_tl }
+ }
+\cs_new_protected:Npn \@@_test_case_aux:nn #1#2
+ {
+ \int_compare:nNnTF {#1} = \c_zero
+ { \@@_change_if_limit:nn { 4 } {#2} }
+ {
+ \@@_pass_text:
+ \int_compare:nNnTF \g_@@_if_depth_int = {#2}
+ {
+ \token_if_eq_meaning:NNTF \l_@@_head_token \or:
+ {
+ \exp_args:Nf \@@_test_case_aux:nn
+ { \int_eval:n { #1 - 1 } } {#2}
+ }
+ { \@@_cond_false_common: }
+ }
+ {
+ \token_if_eq_meaning:NNT \l_@@_head_token \fi:
+ { \@@_cond_pop: }
+ \@@_test_case_aux:nn {#1} {#2}
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_test_ifdefined:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_test_ifdefined:
+ {
+ \@@_input_if_empty:TF
+ { \@@_pass_text_empty: }
+ {
+ \@@_input_gpop:N \l_@@_tmpb_gtl
+ \@@_set_action_text:x
+ {
+ Conditional:~ \tl_to_str:N \l_@@_head_tl
+ \gtl_to_str:N \l_@@_tmpb_gtl
+ }
+ \@@_prev_input:x
+ {
+ \gtl_if_tl:NTF \l_@@_tmpb_gtl
+ { \gtl_head:N \l_@@_tmpb_gtl }
+ { \gtl_to_str:N \l_@@_tmpb_gtl }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_test_ifcsname:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_test_ifcsname:
+ {
+ \@@_csname_loop:
+ \@@_prev_input:V \l_@@_head_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\@@_new_tex_expandable:nn { fi_or_else } % 108
+ {
+ \int_compare:nNnTF \l_@@_head_char_int > \g_@@_if_limit_int
+ {
+ \int_compare:nNnTF \g_@@_if_limit_int = \c_zero
+ {
+ \int_compare:nNnTF \g_@@_if_depth_int = \c_zero
+ { \msg_error:nn { unravel } { extra-fi-or-else } }
+ { \@@_insert_relax: }
+ }
+ { \msg_error:nn { unravel } { extra-fi-or-else } }
+ }
+ {
+ \@@_set_action_text:
+ \int_compare:nNnF \l_@@_head_char_int = \c_two
+ {
+ \@@_fi_or_else_loop:
+ \@@_set_action_text:x
+ {
+ \g_@@_action_text_str \c_space_tl
+ => ~ skipped ~ to ~ \tl_to_str:N \l_@@_head_tl
+ }
+ }
+ % ^^A todo: in this print_action the token itself is missing.
+ \@@_print_action:
+ \@@_cond_pop:
+ }
+ }
+\cs_new_protected_nopar:Npn \@@_fi_or_else_loop:
+ {
+ \int_compare:nNnF \l_@@_head_char_int = \c_two
+ {
+ \@@_pass_text:
+ \@@_set_cmd:
+ \@@_fi_or_else_loop:
+ }
+ }
+% \end{macrocode}
+%
+% \subsection{User interaction}
+%
+% ^^A Not implemented yet: non-hash-doubling version.
+%
+% \subsubsection{Print}
+%
+% Let us start with the procedure which prints to the terminal: this
+% will help me test the code while I'm writing it.
+%
+% \begin{macro}[int]{\@@_print:n, \@@_print:x}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_print:n \iow_term:n
+\cs_generate_variant:Nn \@@_print:n { x }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_print_message:nn}
+% The message to be printed should come already detokenized, as~|#2|.
+% It will be wrapped to 80 characters per line, with~|#1| before each
+% line.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_message:nn #1 #2
+ { \iow_wrap:nnnN { #1 #2 } { #1 } { } \@@_print:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_set_action_text:x}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_action_text:x #1
+ {
+ \group_begin:
+ \int_set:Nn \tex_escapechar:D { 92 }
+ \str_gset:Nx \g_@@_action_text_str {#1}
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_set_action_text:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_set_action_text:
+ {
+ \@@_set_action_text:x
+ {
+ \tl_to_str:N \l_@@_head_tl
+ \tl_if_single_token:VT \l_@@_head_tl
+ { = ~ \exp_after:wN \token_to_meaning:N \l_@@_head_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_print_state:}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_state:
+ {
+ \group_begin:
+ \int_set:Nn \tex_escapechar:D { 92 }
+ \int_compare:nNnT \g_@@_noise_int > \c_zero
+ {
+ \exp_args:Nx \@@_print_state_output:n
+ { \gtl_to_str:N \g_@@_output_gtl }
+ \seq_set_map:NNn \l_@@_tmpa_seq \g_@@_prev_input_seq
+ { \@@_to_str:n {##1} }
+ \seq_remove_all:Nn \l_@@_tmpa_seq { }
+ \exp_args:Nx \@@_print_state_prev:n
+ { \seq_use:Nn \l_@@_tmpa_seq { \\ } }
+ \exp_args:Nx \@@_print_state_input:n
+ { \@@_input_to_str: }
+ }
+ \group_end:
+ \@@_prompt:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_print_state_output:n}
+% \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}
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: use \cs{g_@@_max_prev_int}
+% \begin{macro}[aux]{\@@_print_state_prev:n}
+% \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}
+ % }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_print_state_input:n}
+% \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}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_print_meaning:}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_meaning:
+ {
+ \@@_input_if_empty:TF
+ { \@@_print_message:nn { } { Empty~input! } }
+ {
+ \@@_input_get:N \l_@@_tmpb_gtl
+ \@@_print_message:nn { }
+ {
+ \gtl_head_do:NN \l_@@_tmpb_gtl \token_to_str:N
+ = \gtl_head_do:NN \l_@@_tmpb_gtl \token_to_meaning:N
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_print_action:, \@@_print_action:x}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_action:
+ {
+ \int_gincr:N \g_@@_step_int
+ \@@_print_message:nn { }
+ {
+ % \\
+ [=====~ 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
+ { 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:
+ }
+\cs_new_protected:Npn \@@_print_action:x #1
+ {
+ \@@_set_action_text:x {#1}
+ \@@_print_action:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_print_gtl_action:N}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_gtl_action:N #1
+ {
+ \@@_print_action:x { \gtl_to_str:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_print_done:x}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_print_done:x \@@_print_action:x
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_print_assigned_token:, \@@_print_assigned_register:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_print_assigned_token:
+ {
+ \@@_after_assignment: % ^^A todo: simplify
+ \@@_print_action:x
+ {
+ Set~ \exp_after:wN \token_to_str:N \l_@@_defined_tl
+ = \exp_after:wN \token_to_meaning:N \l_@@_defined_tl
+ }
+ \@@_omit_after_assignment:w
+ }
+\cs_new_protected_nopar:Npn \@@_print_assigned_register:
+ {
+ \@@_after_assignment: % ^^A todo: simplify
+ \@@_print_action:x
+ {
+ Set~ \exp_after:wN \token_to_str:N \l_@@_defined_tl
+ \tl_if_single:NT \l_@@_defined_tl
+ { ( \exp_after:wN \token_to_meaning:N \l_@@_defined_tl ) }
+ = \exp_after:wN \tex_the:D \l_@@_defined_tl
+ }
+ \@@_omit_after_assignment:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_print_welcome:}
+% Welcoming message.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_print_welcome:
+ {
+ \@@_print_message:nn { }
+ {
+ \\
+ ========~ 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. \\
+ }
+ }
+ \@@_print_state:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_print_outcome:}
+% 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!~=====] \\ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Prompt}
+%
+% \begin{macro}[int]{\@@_prompt:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_prompt:
+ {
+ \int_gdecr:N \g_@@_nonstop_int
+ \int_compare:nNnF \g_@@_nonstop_int > \c_zero
+ {
+ \group_begin:
+ \int_set_eq:NN \tex_escapechar:D \c_minus_one
+ \int_set_eq:NN \tex_endlinechar:D \c_minus_one
+ \tl_use:N \g_@@_prompt_before_tl
+ \tl_gclear:N \g_@@_prompt_before_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 }
+ }
+\cs_new_protected:Npn \@@_prompt_treat:n #1
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \exp_args:Nx \str_case:nnF { \tl_head:n {#1} }
+ {
+ { m } { \@@_print_meaning: \@@_prompt_aux: }
+ { q }
+ {
+ \int_gset_eq:NN \g_@@_noise_int \c_minus_one
+ \int_gzero:N \g_@@_nonstop_int
+ }
+ { x }
+ {
+ \group_end:
+ \exp_after:wN \@@_exit:w \@@_exit:w
+ }
+ { X } { \tex_batchmode:D \tex_end:D }
+ { s } { \@@_prompt_scan_int:nn {#1}
+ \@@_prompt_silent_steps:n }
+ { o } { \@@_prompt_scan_int:nn {#1}
+ { \int_gset:Nn \g_@@_noise_int } }
+ { C }
+ {
+ \tl_gset_rescan:Nnx \g_@@_tmpc_tl
+ { \ExplSyntaxOn } { \tl_tail:n {#1} }
+ \tl_gput_left:Nn \g_@@_tmpc_tl
+ { \tl_gclear:N \g_@@_tmpc_tl }
+ \group_insert_after:N \g_@@_tmpc_tl
+ }
+ }
+ { \@@_prompt_help: }
+ }
+ }
+\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:
+ }
+\cs_new_protected:Npn \@@_prompt_scan_int_after:wn #1 \scan_stop: #2
+ {
+ #2 \l_@@_prompt_tmpa_int
+ \tl_if_blank:nF {#1} { \@@_prompt_treat:n {#1} }
+ }
+\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 { "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 }
+ \@@_prompt_aux:
+ }
+\cs_new_protected:Npn \@@_prompt_silent_steps:n #1
+ {
+ \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}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Main command}
+%
+% \begin{macro}{\unravel}
+% Simply call an underlying internal command.
+% \begin{macrocode}
+\cs_new_protected:Npn \unravel #1 { \@@_unravel:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\UnravelDebug}
+% Turn on debugging mode.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \UnravelDebug
+ {
+ \bool_set_true:N \l_@@_debug_bool
+ }
+% \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{macrocode}
+\cs_new_protected:Npn \@@_unravel:n #1
+ {
+ \int_gzero:N \g_@@_step_int
+ \@@_input_gset:n {#1}
+ \seq_gclear:N \g_@@_prev_input_seq
+ \gtl_gclear:N \g_@@_output_gtl
+ \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.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_main_loop:
+ {
+ \@@_get_x_next:
+ \@@_set_cmd:
+ \@@_do_step:
+ \@@_main_loop:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% \begin{macrocode}
+\msg_new:nnn { unravel } { unknown-primitive }
+ { Internal~error:~the~primitive~'#1'~is~not~known. }
+\msg_new:nnn { unravel } { extra-fi-or-else }
+ { Extra~fi,~or,~or~else. }
+\msg_new:nnn { unravel } { missing-lbrace }
+ { Missing~left~brace~inserted. }
+\msg_new:nnn { unravel } { missing-dollar }
+ { Missing~dollar~inserted. }
+\msg_new:nnn { unravel } { unknown-expandable }
+ { Internal~error:~the~expandable~command~'#1'~is~not~known. }
+\msg_new:nnn { unravel } { missing-font-id }
+ { Missing~font~identifier.~\iow_char:N\\nullfont~inserted. }
+\msg_new:nnn { unravel } { missing-rparen }
+ { Missing~right~parenthesis~inserted~for~expression. }
+\msg_new:nnn { unravel } { incompatible-units }
+ { Mu~glue/dimen~used~as~a~normal~glue/dimen~or~vice-versa. }
+\msg_new:nnn { unravel } { missing-mudim }
+ { Missing~mu~unit. }
+\msg_new:nnn { unravel } { missing-cs }
+ { Missing~control~sequence.~\iow_char:N\\inaccessible~inserted. }
+\msg_new:nnn { unravel } { missing-box }
+ { Missing~box~inserted. }
+\msg_new:nnn { unravel } { missing-to }
+ { Missing~keyword~'to'~inserted. }
+\msg_new:nnn { unravel } { improper-leaders }
+ { Leaders~not~followed~by~proper~glue. }
+\msg_new:nnn { unravel } { extra-close }
+ { Extra~right~brace~or~\iow_char:N\\endgroup. }
+\msg_new:nnn { unravel } { off-save }
+ { Something~is~wrong~with~groups. }
+\msg_new:nnn { unravel } { hrule-bad-mode }
+ { \iow_char\\hrule~used~in~wrong~mode. }
+\msg_new:nnn { unravel } { invalid-mode }
+ { Invalid~mode~for~this~command. }
+\msg_new:nnn { unravel } { color-stack-action-missing }
+ { Missing~color~stack~action. }
+\msg_new:nnn { unravel } { action-type-missing }
+ { Missing~action~type. }
+\msg_new:nnn { unravel } { identifier-type-missing }
+ { Missing~identifier~type. }
+\msg_new:nnn { unravel } { destination-type-missing }
+ { Missing~destination~type. }
+\msg_new:nnn { unravel } { erroneous-prefixes }
+ { Prefixes~appplied~to~non-assignment~command. }
+\msg_new:nnn { unravel } { improper-setbox }
+ { \iow_char:N\\setbox~while~fetching~base~of~an~accent. }
+\msg_new:nnn { unravel } { after-advance }
+ {
+ Missing~register~after~\iow_char:N\\advance,~
+ \iow_char:N\\multiply,~or~\iow_char:N\\divide.
+ }
+\msg_new:nnn { unravel } { bad-unless }
+ { \iow_char:N\\unless~not~followed~by~conditional. }
+\msg_new:nnn { unravel } { missing-endcsname }
+ { Missing~\iow_char:N\\endcsname~inserted. }
+\msg_new:nnn { unravel } { runaway-if }
+ { Runaway~\iow_char:N\\if... }
+\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. }
+\msg_new:nnn { unravel } { not-implemented }
+ { The~following~feature~is~not~implemented:~'#1'. }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/unravel/unravel.ins b/Master/texmf-dist/source/latex/unravel/unravel.ins
new file mode 100644
index 00000000000..81a35f7019f
--- /dev/null
+++ b/Master/texmf-dist/source/latex/unravel/unravel.ins
@@ -0,0 +1,23 @@
+\input l3docstrip.tex
+\askforoverwritefalse
+
+\preamble
+
+Do not distribute a modified version of this file.
+
+Communicate any suggestions for changing this package
+to Bruno Le Floch (blflatex@gmail.com).
+
+\endpreamble
+% stop docstrip adding \endinput
+\postamble
+\endpostamble
+
+\keepsilent
+
+% the package
+\generate{%
+ \file{unravel.sty} {\from{unravel.dtx} {package}}%
+}
+
+\endbatchfile
diff --git a/Master/texmf-dist/tex/latex/unravel/unravel.sty b/Master/texmf-dist/tex/latex/unravel/unravel.sty
new file mode 100644
index 00000000000..1665ce3acf4
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/unravel/unravel.sty
@@ -0,0 +1,4817 @@
+%%
+%% This is file `unravel.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% unravel.dtx (with options: `package')
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% Communicate any suggestions for changing this package
+%% to Bruno Le Floch (blflatex@gmail.com).
+%%
+%% File: unravel.dtx Copyright (C) 2013 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
+%% license or (at your option) any later version. The latest version
+%% of this license is in the file
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{expl3}[2013/07/01]
+\RequirePackage{l3str}[2013/04/24]
+\RequirePackage{gtl}[2013/07/28]
+\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: }
+\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_new_protected:Npn \__unravel_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 \__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
+ }
+\cs_generate_variant:Nn \__unravel_tl_gset_input:Nnn { Nno }
+\use:x
+ {
+ \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
+ \if_charcode:w \token_to_str:N \ \__unravel_strip_escape_aux:w \fi:
+ \__unravel_strip_escape_aux:N
+ }
+\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:
+ { \__unravel_to_str_auxi:w #1 ? \q_stop }
+ { \tl_to_str:n }
+ {#1}
+ }
+\cs_set:Npn \__unravel_tmp:w #1
+ {
+ \cs_new:Npn \__unravel_to_str_auxi:w ##1##2 \q_stop
+ {
+ \exp_after:wN \__unravel_to_str_auxii:w \token_to_str:N ##1 \q_mark
+ #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 } }
+ }
+\exp_args:No \__unravel_tmp:w { \tl_to_str:n { s__ } }
+\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
+ }
+\prg_new_conditional:Npnn \__unravel_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:
+ }
+\prg_new_conditional:Npnn \__unravel_token_if_protected:N #1
+ { p , T , F , TF }
+ {
+ \__unravel_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: }
+ }
+\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 }
+ {
+ \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:
+\prg_new_protected_conditional:Npnn \__unravel_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 \__unravel_token_if_definable:NTF
+ { \gtl_head:N #1 }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+\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 } }
+\cs_new_protected:Npn \__unravel_tex_primitive:nnn #1#2#3
+ {
+ \tl_const:cx { c__unravel_tex_#1_tl }
+ { { \__unravel_tex_use:n {#2} } {#3} }
+ }
+\cs_new_protected:Npn \__unravel_new_tex_cmd:nn #1#2
+ {
+ \cs_new_protected_nopar:cpn
+ { __unravel_cmd_ \__unravel_tex_use:n {#1} : } {#2}
+ }
+\cs_new_protected:Npn \__unravel_new_eq_tex_cmd:nn #1#2
+ {
+ \cs_new_eq:cc
+ { __unravel_cmd_ \__unravel_tex_use:n {#1} : }
+ { __unravel_cmd_ \__unravel_tex_use:n {#2} : }
+ }
+\cs_new_protected:Npn \__unravel_new_tex_expandable:nn #1#2
+ {
+ \cs_new_protected_nopar:cpn
+ { __unravel_expandable_ \__unravel_tex_use:n {#1} : } {#2}
+ }
+\__unravel_tex_const:nn { relax } { 0 }
+\__unravel_tex_const:nn { begin-group_char } { 1 }
+\__unravel_tex_const:nn { end-group_char } { 2 }
+\__unravel_tex_const:nn { math_char } { 3 }
+\__unravel_tex_const:nn { tab_mark } { 4 }
+\__unravel_tex_const:nn { alignment_char } { 4 }
+\__unravel_tex_const:nn { car_ret } { 5 }
+\__unravel_tex_const:nn { macro_char } { 6 }
+\__unravel_tex_const:nn { superscript_char } { 7 }
+\__unravel_tex_const:nn { subscript_char } { 8 }
+\__unravel_tex_const:nn { endv } { 9 }
+\__unravel_tex_const:nn { blank_char } { 10 }
+\__unravel_tex_const:nn { the_char } { 11 }
+\__unravel_tex_const:nn { other_char } { 12 }
+\__unravel_tex_const:nn { par_end } { 13 }
+\__unravel_tex_const:nn { stop } { 14 }
+\__unravel_tex_const:nn { delim_num } { 15 }
+\__unravel_tex_const:nn { max_char_code } { 15 }
+\__unravel_tex_const:nn { char_num } { 16 }
+\__unravel_tex_const:nn { math_char_num } { 17 }
+\__unravel_tex_const:nn { mark } { 18 }
+\__unravel_tex_const:nn { xray } { 19 }
+\__unravel_tex_const:nn { make_box } { 20 }
+\__unravel_tex_const:nn { hmove } { 21 }
+\__unravel_tex_const:nn { vmove } { 22 }
+\__unravel_tex_const:nn { un_hbox } { 23 }
+\__unravel_tex_const:nn { un_vbox } { 24 }
+\__unravel_tex_const:nn { remove_item } { 25 }
+\__unravel_tex_const:nn { hskip } { 26 }
+\__unravel_tex_const:nn { vskip } { 27 }
+\__unravel_tex_const:nn { mskip } { 28 }
+\__unravel_tex_const:nn { kern } { 29 }
+\__unravel_tex_const:nn { mkern } { 30 }
+\__unravel_tex_const:nn { leader_ship } { 31 }
+\__unravel_tex_const:nn { halign } { 32 }
+\__unravel_tex_const:nn { valign } { 33 }
+\__unravel_tex_const:nn { no_align } { 34 }
+\__unravel_tex_const:nn { vrule } { 35 }
+\__unravel_tex_const:nn { hrule } { 36 }
+\__unravel_tex_const:nn { insert } { 37 }
+\__unravel_tex_const:nn { vadjust } { 38 }
+\__unravel_tex_const:nn { ignore_spaces } { 39 }
+\__unravel_tex_const:nn { after_assignment } { 40 }
+\__unravel_tex_const:nn { after_group } { 41 }
+\__unravel_tex_const:nn { break_penalty } { 42 }
+\__unravel_tex_const:nn { start_par } { 43 }
+\__unravel_tex_const:nn { ital_corr } { 44 }
+\__unravel_tex_const:nn { accent } { 45 }
+\__unravel_tex_const:nn { math_accent } { 46 }
+\__unravel_tex_const:nn { discretionary } { 47 }
+\__unravel_tex_const:nn { eq_no } { 48 }
+\__unravel_tex_const:nn { left_right } { 49 }
+\__unravel_tex_const:nn { math_comp } { 50 }
+\__unravel_tex_const:nn { limit_switch } { 51 }
+\__unravel_tex_const:nn { above } { 52 }
+\__unravel_tex_const:nn { math_style } { 53 }
+\__unravel_tex_const:nn { math_choice } { 54 }
+\__unravel_tex_const:nn { non_script } { 55 }
+\__unravel_tex_const:nn { vcenter } { 56 }
+\__unravel_tex_const:nn { case_shift } { 57 }
+\__unravel_tex_const:nn { message } { 58 }
+\__unravel_tex_const:nn { extension } { 59 }
+\__unravel_tex_const:nn { in_stream } { 60 }
+\__unravel_tex_const:nn { begin_group } { 61 }
+\__unravel_tex_const:nn { end_group } { 62 }
+\__unravel_tex_const:nn { omit } { 63 }
+\__unravel_tex_const:nn { ex_space } { 64 }
+\__unravel_tex_const:nn { no_boundary } { 65 }
+\__unravel_tex_const:nn { radical } { 66 }
+\__unravel_tex_const:nn { end_cs_name } { 67 }
+\__unravel_tex_const:nn { min_internal } { 68 }
+\__unravel_tex_const:nn { char_given } { 68 }
+\__unravel_tex_const:nn { math_given } { 69 }
+\__unravel_tex_const:nn { last_item } { 70 }
+\__unravel_tex_const:nn { max_non_prefixed_command } { 70 }
+\__unravel_tex_const:nn { toks_register } { 71 }
+\__unravel_tex_const:nn { assign_toks } { 72 }
+\__unravel_tex_const:nn { assign_int } { 73 }
+\__unravel_tex_const:nn { assign_dimen } { 74 }
+\__unravel_tex_const:nn { assign_glue } { 75 }
+\__unravel_tex_const:nn { assign_mu_glue } { 76 }
+\__unravel_tex_const:nn { assign_font_dimen } { 77 }
+\__unravel_tex_const:nn { assign_font_int } { 78 }
+\__unravel_tex_const:nn { set_aux } { 79 }
+\__unravel_tex_const:nn { set_prev_graf } { 80 }
+\__unravel_tex_const:nn { set_page_dimen } { 81 }
+\__unravel_tex_const:nn { set_page_int } { 82 }
+\__unravel_tex_const:nn { set_box_dimen } { 83 }
+\__unravel_tex_const:nn { set_shape } { 84 }
+\__unravel_tex_const:nn { def_code } { 85 }
+\__unravel_tex_const:nn { def_family } { 86 }
+\__unravel_tex_const:nn { set_font } { 87 }
+\__unravel_tex_const:nn { def_font } { 88 }
+\__unravel_tex_const:nn { register } { 89 }
+\__unravel_tex_const:nn { max_internal } { 89 }
+\__unravel_tex_const:nn { advance } { 90 }
+\__unravel_tex_const:nn { multiply } { 91 }
+\__unravel_tex_const:nn { divide } { 92 }
+\__unravel_tex_const:nn { prefix } { 93 }
+\__unravel_tex_const:nn { let } { 94 }
+\__unravel_tex_const:nn { shorthand_def } { 95 }
+\__unravel_tex_const:nn { read_to_cs } { 96 }
+\__unravel_tex_const:nn { def } { 97 }
+\__unravel_tex_const:nn { set_box } { 98 }
+\__unravel_tex_const:nn { hyph_data } { 99 }
+\__unravel_tex_const:nn { set_interaction } { 100 }
+\__unravel_tex_const:nn { letterspace_font } { 101 }
+\__unravel_tex_const:nn { pdf_copy_font } { 102 }
+\__unravel_tex_const:nn { max_command } { 102 }
+\__unravel_tex_const:nn { undefined_cs } { 103 }
+\__unravel_tex_const:nn { expand_after } { 104 }
+\__unravel_tex_const:nn { no_expand } { 105 }
+\__unravel_tex_const:nn { input } { 106 }
+\__unravel_tex_const:nn { if_test } { 107 }
+\__unravel_tex_const:nn { fi_or_else } { 108 }
+\__unravel_tex_const:nn { cs_name } { 109 }
+\__unravel_tex_const:nn { convert } { 110 }
+\__unravel_tex_const:nn { the } { 111 }
+\__unravel_tex_const:nn { top_bot_mark } { 112 }
+\__unravel_tex_const:nn { call } { 113 }
+\__unravel_tex_const:nn { end_template } { 117 }
+\__unravel_tex_primitive:nnn { relax } { relax } { 256 }
+\__unravel_tex_primitive:nnn { span } { tab_mark } { 256 }
+\__unravel_tex_primitive:nnn { cr } { car_ret } { 257 }
+\__unravel_tex_primitive:nnn { crcr } { car_ret } { 258 }
+\__unravel_tex_primitive:nnn { par } { par_end } { 256 }
+\__unravel_tex_primitive:nnn { end } { stop } { 0 }
+\__unravel_tex_primitive:nnn { dump } { stop } { 1 }
+\__unravel_tex_primitive:nnn { delimiter } { delim_num } { 0 }
+\__unravel_tex_primitive:nnn { char } { char_num } { 0 }
+\__unravel_tex_primitive:nnn { mathchar } { math_char_num } { 0 }
+\__unravel_tex_primitive:nnn { mark } { mark } { 0 }
+\__unravel_tex_primitive:nnn { marks } { mark } { 5 }
+\__unravel_tex_primitive:nnn { show } { xray } { 0 }
+\__unravel_tex_primitive:nnn { showbox } { xray } { 1 }
+\__unravel_tex_primitive:nnn { showthe } { xray } { 2 }
+\__unravel_tex_primitive:nnn { showlists } { xray } { 3 }
+\__unravel_tex_primitive:nnn { showgroups } { xray } { 4 }
+\__unravel_tex_primitive:nnn { showtokens } { xray } { 5 }
+\__unravel_tex_primitive:nnn { showifs } { xray } { 6 }
+\__unravel_tex_primitive:nnn { box } { make_box } { 0 }
+\__unravel_tex_primitive:nnn { copy } { make_box } { 1 }
+\__unravel_tex_primitive:nnn { lastbox } { make_box } { 2 }
+\__unravel_tex_primitive:nnn { vsplit } { make_box } { 3 }
+\__unravel_tex_primitive:nnn { vtop } { make_box } { 4 }
+\__unravel_tex_primitive:nnn { vbox } { make_box } { 5 }
+\__unravel_tex_primitive:nnn { hbox } { make_box } { 106 }
+\__unravel_tex_primitive:nnn { moveright } { hmove } { 0 }
+\__unravel_tex_primitive:nnn { moveleft } { hmove } { 1 }
+\__unravel_tex_primitive:nnn { lower } { vmove } { 0 }
+\__unravel_tex_primitive:nnn { raise } { vmove } { 1 }
+\__unravel_tex_primitive:nnn { unhbox } { un_hbox } { 0 }
+\__unravel_tex_primitive:nnn { unhcopy } { un_hbox } { 1 }
+\__unravel_tex_primitive:nnn { unvbox } { un_vbox } { 0 }
+\__unravel_tex_primitive:nnn { unvcopy } { un_vbox } { 1 }
+\__unravel_tex_primitive:nnn { pagediscards } { un_vbox } { 2 }
+\__unravel_tex_primitive:nnn { splitdiscards } { un_vbox } { 3 }
+\__unravel_tex_primitive:nnn { unpenalty } { remove_item } { 12 }
+\__unravel_tex_primitive:nnn { unkern } { remove_item } { 11 }
+\__unravel_tex_primitive:nnn { unskip } { remove_item } { 10 }
+\__unravel_tex_primitive:nnn { hfil } { hskip } { 0 }
+\__unravel_tex_primitive:nnn { hfill } { hskip } { 1 }
+\__unravel_tex_primitive:nnn { hss } { hskip } { 2 }
+\__unravel_tex_primitive:nnn { hfilneg } { hskip } { 3 }
+\__unravel_tex_primitive:nnn { hskip } { hskip } { 4 }
+\__unravel_tex_primitive:nnn { vfil } { vskip } { 0 }
+\__unravel_tex_primitive:nnn { vfill } { vskip } { 1 }
+\__unravel_tex_primitive:nnn { vss } { vskip } { 2 }
+\__unravel_tex_primitive:nnn { vfilneg } { vskip } { 3 }
+\__unravel_tex_primitive:nnn { vskip } { vskip } { 4 }
+\__unravel_tex_primitive:nnn { mskip } { mskip } { 5 }
+\__unravel_tex_primitive:nnn { kern } { kern } { 1 }
+\__unravel_tex_primitive:nnn { mkern } { mkern } { 99 }
+\__unravel_tex_primitive:nnn { shipout } { leader_ship } { 99 }
+\__unravel_tex_primitive:nnn { leaders } { leader_ship } { 100 }
+\__unravel_tex_primitive:nnn { cleaders } { leader_ship } { 101 }
+\__unravel_tex_primitive:nnn { xleaders } { leader_ship } { 102 }
+\__unravel_tex_primitive:nnn { halign } { halign } { 0 }
+\__unravel_tex_primitive:nnn { valign } { valign } { 0 }
+\__unravel_tex_primitive:nnn { beginL } { valign } { 4 }
+\__unravel_tex_primitive:nnn { endL } { valign } { 5 }
+\__unravel_tex_primitive:nnn { beginR } { valign } { 8 }
+\__unravel_tex_primitive:nnn { endR } { valign } { 9 }
+\__unravel_tex_primitive:nnn { noalign } { no_align } { 0 }
+\__unravel_tex_primitive:nnn { vrule } { vrule } { 0 }
+\__unravel_tex_primitive:nnn { hrule } { hrule } { 0 }
+\__unravel_tex_primitive:nnn { insert } { insert } { 0 }
+\__unravel_tex_primitive:nnn { vadjust } { vadjust } { 0 }
+\__unravel_tex_primitive:nnn { ignorespaces } { ignore_spaces } { 0 }
+\__unravel_tex_primitive:nnn { afterassignment } { after_assignment } { 0 }
+\__unravel_tex_primitive:nnn { aftergroup } { after_group } { 0 }
+\__unravel_tex_primitive:nnn { penalty } { break_penalty } { 0 }
+\__unravel_tex_primitive:nnn { indent } { start_par } { 1 }
+\__unravel_tex_primitive:nnn { noindent } { start_par } { 0 }
+\__unravel_tex_primitive:nnn { quitvmode } { start_par } { 2 }
+\__unravel_tex_primitive:nnn { / } { ital_corr } { 0 }
+\__unravel_tex_primitive:nnn { accent } { accent } { 0 }
+\__unravel_tex_primitive:nnn { mathaccent } { math_accent } { 0 }
+\__unravel_tex_primitive:nnn { - } { discretionary } { 1 }
+\__unravel_tex_primitive:nnn { discretionary } { discretionary } { 0 }
+\__unravel_tex_primitive:nnn { eqno } { eq_no } { 0 }
+\__unravel_tex_primitive:nnn { leqno } { eq_no } { 1 }
+\__unravel_tex_primitive:nnn { left } { left_right } { 30 }
+\__unravel_tex_primitive:nnn { right } { left_right } { 31 }
+\__unravel_tex_primitive:nnn { middle } { left_right } { 17 }
+\__unravel_tex_primitive:nnn { mathord } { math_comp } { 16 }
+\__unravel_tex_primitive:nnn { mathop } { math_comp } { 17 }
+\__unravel_tex_primitive:nnn { mathbin } { math_comp } { 18 }
+\__unravel_tex_primitive:nnn { mathrel } { math_comp } { 19 }
+\__unravel_tex_primitive:nnn { mathopen } { math_comp } { 20 }
+\__unravel_tex_primitive:nnn { mathclose } { math_comp } { 21 }
+\__unravel_tex_primitive:nnn { mathpunct } { math_comp } { 22 }
+\__unravel_tex_primitive:nnn { mathinner } { math_comp } { 23 }
+\__unravel_tex_primitive:nnn { underline } { math_comp } { 26 }
+\__unravel_tex_primitive:nnn { overline } { math_comp } { 27 }
+\__unravel_tex_primitive:nnn { displaylimits } { limit_switch } { 0 }
+\__unravel_tex_primitive:nnn { limits } { limit_switch } { 1 }
+\__unravel_tex_primitive:nnn { nolimits } { limit_switch } { 2 }
+\__unravel_tex_primitive:nnn { above } { above } { 0 }
+\__unravel_tex_primitive:nnn { over } { above } { 1 }
+\__unravel_tex_primitive:nnn { atop } { above } { 2 }
+\__unravel_tex_primitive:nnn { abovewithdelims } { above } { 3 }
+\__unravel_tex_primitive:nnn { overwithdelims } { above } { 4 }
+\__unravel_tex_primitive:nnn { atopwithdelims } { above } { 5 }
+\__unravel_tex_primitive:nnn { displaystyle } { math_style } { 0 }
+\__unravel_tex_primitive:nnn { textstyle } { math_style } { 2 }
+\__unravel_tex_primitive:nnn { scriptstyle } { math_style } { 4 }
+\__unravel_tex_primitive:nnn { scriptscriptstyle } { math_style } { 6 }
+\__unravel_tex_primitive:nnn { mathchoice } { math_choice } { 0 }
+\__unravel_tex_primitive:nnn { nonscript } { non_script } { 0 }
+\__unravel_tex_primitive:nnn { vcenter } { vcenter } { 0 }
+\__unravel_tex_primitive:nnn { lowercase } { case_shift } { 256 }
+\__unravel_tex_primitive:nnn { uppercase } { case_shift } { 512 }
+\__unravel_tex_primitive:nnn { message } { message } { 0 }
+\__unravel_tex_primitive:nnn { errmessage } { message } { 1 }
+\__unravel_tex_primitive:nnn { openout } { extension } { 0 }
+\__unravel_tex_primitive:nnn { write } { extension } { 1 }
+\__unravel_tex_primitive:nnn { closeout } { extension } { 2 }
+\__unravel_tex_primitive:nnn { special } { extension } { 3 }
+\__unravel_tex_primitive:nnn { immediate } { extension } { 4 }
+\__unravel_tex_primitive:nnn { setlanguage } { extension } { 5 }
+\__unravel_tex_primitive:nnn { pdfliteral } { extension } { 6 }
+\__unravel_tex_primitive:nnn { pdfobj } { extension } { 7 }
+\__unravel_tex_primitive:nnn { pdfrefobj } { extension } { 8 }
+\__unravel_tex_primitive:nnn { pdfxform } { extension } { 9 }
+\__unravel_tex_primitive:nnn { pdfrefxform } { extension } { 10 }
+\__unravel_tex_primitive:nnn { pdfximage } { extension } { 11 }
+\__unravel_tex_primitive:nnn { pdfrefximage } { extension } { 12 }
+\__unravel_tex_primitive:nnn { pdfannot } { extension } { 13 }
+\__unravel_tex_primitive:nnn { pdfstartlink } { extension } { 14 }
+\__unravel_tex_primitive:nnn { pdfendlink } { extension } { 15 }
+\__unravel_tex_primitive:nnn { pdfoutline } { extension } { 16 }
+\__unravel_tex_primitive:nnn { pdfdest } { extension } { 17 }
+\__unravel_tex_primitive:nnn { pdfthread } { extension } { 18 }
+\__unravel_tex_primitive:nnn { pdfstartthread } { extension } { 19 }
+\__unravel_tex_primitive:nnn { pdfendthread } { extension } { 20 }
+\__unravel_tex_primitive:nnn { pdfsavepos } { extension } { 21 }
+\__unravel_tex_primitive:nnn { pdfinfo } { extension } { 22 }
+\__unravel_tex_primitive:nnn { pdfcatalog } { extension } { 23 }
+\__unravel_tex_primitive:nnn { pdfnames } { extension } { 24 }
+\__unravel_tex_primitive:nnn { pdffontattr } { extension } { 25 }
+\__unravel_tex_primitive:nnn { pdfincludechars } { extension } { 26 }
+\__unravel_tex_primitive:nnn { pdfmapfile } { extension } { 27 }
+\__unravel_tex_primitive:nnn { pdfmapline } { extension } { 28 }
+\__unravel_tex_primitive:nnn { pdftrailer } { extension } { 29 }
+\__unravel_tex_primitive:nnn { pdfresettimer } { extension } { 30 }
+\__unravel_tex_primitive:nnn { pdffontexpand } { extension } { 31 }
+\__unravel_tex_primitive:nnn { pdfsetrandomseed } { extension } { 32 }
+\__unravel_tex_primitive:nnn { pdfsnaprefpoint } { extension } { 33 }
+\__unravel_tex_primitive:nnn { pdfsnapy } { extension } { 34 }
+\__unravel_tex_primitive:nnn { pdfsnapycomp } { extension } { 35 }
+\__unravel_tex_primitive:nnn { pdfglyphtounicode } { extension } { 36 }
+\__unravel_tex_primitive:nnn { pdfcolorstack } { extension } { 37 }
+\__unravel_tex_primitive:nnn { pdfsetmatrix } { extension } { 38 }
+\__unravel_tex_primitive:nnn { pdfsave } { extension } { 39 }
+\__unravel_tex_primitive:nnn { pdfrestore } { extension } { 40 }
+\__unravel_tex_primitive:nnn { pdfnobuiltintounicode } { extension } { 41 }
+\__unravel_tex_primitive:nnn { openin } { in_stream } { 1 }
+\__unravel_tex_primitive:nnn { closein } { in_stream } { 0 }
+\__unravel_tex_primitive:nnn { begingroup } { begin_group } { 0 }
+\__unravel_tex_primitive:nnn { endgroup } { end_group } { 0 }
+\__unravel_tex_primitive:nnn { omit } { omit } { 0 }
+\__unravel_tex_primitive:nnn { ~ } { ex_space } { 0 }
+\__unravel_tex_primitive:nnn { noboundary } { no_boundary } { 0 }
+\__unravel_tex_primitive:nnn { radical } { radical } { 0 }
+\__unravel_tex_primitive:nnn { endcsname } { end_cs_name } { 0 }
+\__unravel_tex_primitive:nnn { lastpenalty } { last_item } { 0 }
+\__unravel_tex_primitive:nnn { lastkern } { last_item } { 1 }
+\__unravel_tex_primitive:nnn { lastskip } { last_item } { 2 }
+\__unravel_tex_primitive:nnn { lastnodetype } { last_item } { 3 }
+\__unravel_tex_primitive:nnn { inputlineno } { last_item } { 4 }
+\__unravel_tex_primitive:nnn { badness } { last_item } { 5 }
+\__unravel_tex_primitive:nnn { pdftexversion } { last_item } { 6 }
+\__unravel_tex_primitive:nnn { pdflastobj } { last_item } { 7 }
+\__unravel_tex_primitive:nnn { pdflastxform } { last_item } { 8 }
+\__unravel_tex_primitive:nnn { pdflastximage } { last_item } { 9 }
+\__unravel_tex_primitive:nnn { pdflastximagepages } { last_item } { 10 }
+\__unravel_tex_primitive:nnn { pdflastannot } { last_item } { 11 }
+\__unravel_tex_primitive:nnn { pdflastxpos } { last_item } { 12 }
+\__unravel_tex_primitive:nnn { pdflastypos } { last_item } { 13 }
+\__unravel_tex_primitive:nnn { pdfretval } { last_item } { 14 }
+\__unravel_tex_primitive:nnn { pdflastximagecolordepth } { last_item } { 15 }
+\__unravel_tex_primitive:nnn { pdfelapsedtime } { last_item } { 16 }
+\__unravel_tex_primitive:nnn { pdfshellescape } { last_item } { 17 }
+\__unravel_tex_primitive:nnn { pdfrandomseed } { last_item } { 18 }
+\__unravel_tex_primitive:nnn { pdflastlink } { last_item } { 19 }
+\__unravel_tex_primitive:nnn { eTeXversion } { last_item } { 20 }
+\__unravel_tex_primitive:nnn { currentgrouplevel } { last_item } { 21 }
+\__unravel_tex_primitive:nnn { currentgrouptype } { last_item } { 22 }
+\__unravel_tex_primitive:nnn { currentiflevel } { last_item } { 23 }
+\__unravel_tex_primitive:nnn { currentiftype } { last_item } { 24 }
+\__unravel_tex_primitive:nnn { currentifbranch } { last_item } { 25 }
+\__unravel_tex_primitive:nnn { gluestretchorder } { last_item } { 26 }
+\__unravel_tex_primitive:nnn { glueshrinkorder } { last_item } { 27 }
+\__unravel_tex_primitive:nnn { fontcharwd } { last_item } { 28 }
+\__unravel_tex_primitive:nnn { fontcharht } { last_item } { 29 }
+\__unravel_tex_primitive:nnn { fontchardp } { last_item } { 30 }
+\__unravel_tex_primitive:nnn { fontcharic } { last_item } { 31 }
+\__unravel_tex_primitive:nnn { parshapelength } { last_item } { 32 }
+\__unravel_tex_primitive:nnn { parshapeindent } { last_item } { 33 }
+\__unravel_tex_primitive:nnn { parshapedimen } { last_item } { 34 }
+\__unravel_tex_primitive:nnn { gluestretch } { last_item } { 35 }
+\__unravel_tex_primitive:nnn { glueshrink } { last_item } { 36 }
+\__unravel_tex_primitive:nnn { mutoglue } { last_item } { 37 }
+\__unravel_tex_primitive:nnn { gluetomu } { last_item } { 38 }
+\__unravel_tex_primitive:nnn { numexpr } { last_item } { 39 }
+\__unravel_tex_primitive:nnn { dimexpr } { last_item } { 40 }
+\__unravel_tex_primitive:nnn { glueexpr } { last_item } { 41 }
+\__unravel_tex_primitive:nnn { muexpr } { last_item } { 42 }
+\__unravel_tex_primitive:nnn { toks } { toks_register } { 0 }
+\__unravel_tex_primitive:nnn { output } { assign_toks } { 1 }
+\__unravel_tex_primitive:nnn { everypar } { assign_toks } { 2 }
+\__unravel_tex_primitive:nnn { everymath } { assign_toks } { 3 }
+\__unravel_tex_primitive:nnn { everydisplay } { assign_toks } { 4 }
+\__unravel_tex_primitive:nnn { everyhbox } { assign_toks } { 5 }
+\__unravel_tex_primitive:nnn { everyvbox } { assign_toks } { 6 }
+\__unravel_tex_primitive:nnn { everyjob } { assign_toks } { 7 }
+\__unravel_tex_primitive:nnn { everycr } { assign_toks } { 8 }
+\__unravel_tex_primitive:nnn { errhelp } { assign_toks } { 9 }
+\__unravel_tex_primitive:nnn { pdfpagesattr } { assign_toks } { 10 }
+\__unravel_tex_primitive:nnn { pdfpageattr } { assign_toks } { 11 }
+\__unravel_tex_primitive:nnn { pdfpageresources } { assign_toks } { 12 }
+\__unravel_tex_primitive:nnn { pdfpkmode } { assign_toks } { 13 }
+\__unravel_tex_primitive:nnn { everyeof } { assign_toks } { 14 }
+\__unravel_tex_primitive:nnn { pretolerance } { assign_int } { 0 }
+\__unravel_tex_primitive:nnn { tolerance } { assign_int } { 1 }
+\__unravel_tex_primitive:nnn { linepenalty } { assign_int } { 2 }
+\__unravel_tex_primitive:nnn { hyphenpenalty } { assign_int } { 3 }
+\__unravel_tex_primitive:nnn { exhyphenpenalty } { assign_int } { 4 }
+\__unravel_tex_primitive:nnn { clubpenalty } { assign_int } { 5 }
+\__unravel_tex_primitive:nnn { widowpenalty } { assign_int } { 6 }
+\__unravel_tex_primitive:nnn { displaywidowpenalty } { assign_int } { 7 }
+\__unravel_tex_primitive:nnn { brokenpenalty } { assign_int } { 8 }
+\__unravel_tex_primitive:nnn { binoppenalty } { assign_int } { 9 }
+\__unravel_tex_primitive:nnn { relpenalty } { assign_int } { 10 }
+\__unravel_tex_primitive:nnn { predisplaypenalty } { assign_int } { 11 }
+\__unravel_tex_primitive:nnn { postdisplaypenalty } { assign_int } { 12 }
+\__unravel_tex_primitive:nnn { interlinepenalty } { assign_int } { 13 }
+\__unravel_tex_primitive:nnn { doublehyphendemerits } { assign_int } { 14 }
+\__unravel_tex_primitive:nnn { finalhyphendemerits } { assign_int } { 15 }
+\__unravel_tex_primitive:nnn { adjdemerits } { assign_int } { 16 }
+\__unravel_tex_primitive:nnn { mag } { assign_int } { 17 }
+\__unravel_tex_primitive:nnn { delimiterfactor } { assign_int } { 18 }
+\__unravel_tex_primitive:nnn { looseness } { assign_int } { 19 }
+\__unravel_tex_primitive:nnn { time } { assign_int } { 20 }
+\__unravel_tex_primitive:nnn { day } { assign_int } { 21 }
+\__unravel_tex_primitive:nnn { month } { assign_int } { 22 }
+\__unravel_tex_primitive:nnn { year } { assign_int } { 23 }
+\__unravel_tex_primitive:nnn { showboxbreadth } { assign_int } { 24 }
+\__unravel_tex_primitive:nnn { showboxdepth } { assign_int } { 25 }
+\__unravel_tex_primitive:nnn { hbadness } { assign_int } { 26 }
+\__unravel_tex_primitive:nnn { vbadness } { assign_int } { 27 }
+\__unravel_tex_primitive:nnn { pausing } { assign_int } { 28 }
+\__unravel_tex_primitive:nnn { tracingonline } { assign_int } { 29 }
+\__unravel_tex_primitive:nnn { tracingmacros } { assign_int } { 30 }
+\__unravel_tex_primitive:nnn { tracingstats } { assign_int } { 31 }
+\__unravel_tex_primitive:nnn { tracingparagraphs } { assign_int } { 32 }
+\__unravel_tex_primitive:nnn { tracingpages } { assign_int } { 33 }
+\__unravel_tex_primitive:nnn { tracingoutput } { assign_int } { 34 }
+\__unravel_tex_primitive:nnn { tracinglostchars } { assign_int } { 35 }
+\__unravel_tex_primitive:nnn { tracingcommands } { assign_int } { 36 }
+\__unravel_tex_primitive:nnn { tracingrestores } { assign_int } { 37 }
+\__unravel_tex_primitive:nnn { uchyph } { assign_int } { 38 }
+\__unravel_tex_primitive:nnn { outputpenalty } { assign_int } { 39 }
+\__unravel_tex_primitive:nnn { maxdeadcycles } { assign_int } { 40 }
+\__unravel_tex_primitive:nnn { hangafter } { assign_int } { 41 }
+\__unravel_tex_primitive:nnn { floatingpenalty } { assign_int } { 42 }
+\__unravel_tex_primitive:nnn { globaldefs } { assign_int } { 43 }
+\__unravel_tex_primitive:nnn { fam } { assign_int } { 44 }
+\__unravel_tex_primitive:nnn { escapechar } { assign_int } { 45 }
+\__unravel_tex_primitive:nnn { defaulthyphenchar } { assign_int } { 46 }
+\__unravel_tex_primitive:nnn { defaultskewchar } { assign_int } { 47 }
+\__unravel_tex_primitive:nnn { endlinechar } { assign_int } { 48 }
+\__unravel_tex_primitive:nnn { newlinechar } { assign_int } { 49 }
+\__unravel_tex_primitive:nnn { language } { assign_int } { 50 }
+\__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 { pdfoutput } { assign_int } { 55 }
+\__unravel_tex_primitive:nnn { pdfcompresslevel } { assign_int } { 56 }
+\__unravel_tex_primitive:nnn { pdfdecimaldigits } { assign_int } { 57 }
+\__unravel_tex_primitive:nnn { pdfmovechars } { assign_int } { 58 }
+\__unravel_tex_primitive:nnn { pdfimageresolution } { assign_int } { 59 }
+\__unravel_tex_primitive:nnn { pdfpkresolution } { assign_int } { 60 }
+\__unravel_tex_primitive:nnn { pdfuniqueresname } { assign_int } { 61 }
+\__unravel_tex_primitive:nnn
+ { pdfoptionalwaysusepdfpagebox } { assign_int } { 62 }
+\__unravel_tex_primitive:nnn
+ { pdfoptionpdfinclusionerrorlevel } { assign_int } { 63 }
+\__unravel_tex_primitive:nnn
+ { pdfoptionpdfminorversion } { assign_int } { 64 }
+\__unravel_tex_primitive:nnn { pdfminorversion } { assign_int } { 64 }
+\__unravel_tex_primitive:nnn { pdfforcepagebox } { assign_int } { 65 }
+\__unravel_tex_primitive:nnn { pdfpagebox } { assign_int } { 66 }
+\__unravel_tex_primitive:nnn
+ { pdfinclusionerrorlevel } { assign_int } { 67 }
+\__unravel_tex_primitive:nnn { pdfgamma } { assign_int } { 68 }
+\__unravel_tex_primitive:nnn { pdfimagegamma } { assign_int } { 69 }
+\__unravel_tex_primitive:nnn { pdfimagehicolor } { assign_int } { 70 }
+\__unravel_tex_primitive:nnn { pdfimageapplygamma } { assign_int } { 71 }
+\__unravel_tex_primitive:nnn { pdfadjustspacing } { assign_int } { 72 }
+\__unravel_tex_primitive:nnn { pdfprotrudechars } { assign_int } { 73 }
+\__unravel_tex_primitive:nnn { pdftracingfonts } { assign_int } { 74 }
+\__unravel_tex_primitive:nnn { pdfobjcompresslevel } { assign_int } { 75 }
+\__unravel_tex_primitive:nnn
+ { pdfadjustinterwordglue } { assign_int } { 76 }
+\__unravel_tex_primitive:nnn { pdfprependkern } { assign_int } { 77 }
+\__unravel_tex_primitive:nnn { pdfappendkern } { assign_int } { 78 }
+\__unravel_tex_primitive:nnn { pdfgentounicode } { assign_int } { 79 }
+\__unravel_tex_primitive:nnn { pdfdraftmode } { assign_int } { 80 }
+\__unravel_tex_primitive:nnn { pdfinclusioncopyfonts } { assign_int } { 81 }
+\__unravel_tex_primitive:nnn { tracingassigns } { assign_int } { 82 }
+\__unravel_tex_primitive:nnn { tracinggroups } { assign_int } { 83 }
+\__unravel_tex_primitive:nnn { tracingifs } { assign_int } { 84 }
+\__unravel_tex_primitive:nnn { tracingscantokens } { assign_int } { 85 }
+\__unravel_tex_primitive:nnn { tracingnesting } { assign_int } { 86 }
+\__unravel_tex_primitive:nnn { predisplaydirection } { assign_int } { 87 }
+\__unravel_tex_primitive:nnn { lastlinefit } { assign_int } { 88 }
+\__unravel_tex_primitive:nnn { savingvdiscards } { assign_int } { 89 }
+\__unravel_tex_primitive:nnn { savinghyphcodes } { assign_int } { 90 }
+\__unravel_tex_primitive:nnn { TeXXeTstate } { assign_int } { 91 }
+\__unravel_tex_primitive:nnn { parindent } { assign_dimen } { 0 }
+\__unravel_tex_primitive:nnn { mathsurround } { assign_dimen } { 1 }
+\__unravel_tex_primitive:nnn { lineskiplimit } { assign_dimen } { 2 }
+\__unravel_tex_primitive:nnn { hsize } { assign_dimen } { 3 }
+\__unravel_tex_primitive:nnn { vsize } { assign_dimen } { 4 }
+\__unravel_tex_primitive:nnn { maxdepth } { assign_dimen } { 5 }
+\__unravel_tex_primitive:nnn { splitmaxdepth } { assign_dimen } { 6 }
+\__unravel_tex_primitive:nnn { boxmaxdepth } { assign_dimen } { 7 }
+\__unravel_tex_primitive:nnn { hfuzz } { assign_dimen } { 8 }
+\__unravel_tex_primitive:nnn { vfuzz } { assign_dimen } { 9 }
+\__unravel_tex_primitive:nnn { delimitershortfall } { assign_dimen } { 10 }
+\__unravel_tex_primitive:nnn { nulldelimiterspace } { assign_dimen } { 11 }
+\__unravel_tex_primitive:nnn { scriptspace } { assign_dimen } { 12 }
+\__unravel_tex_primitive:nnn { predisplaysize } { assign_dimen } { 13 }
+\__unravel_tex_primitive:nnn { displaywidth } { assign_dimen } { 14 }
+\__unravel_tex_primitive:nnn { displayindent } { assign_dimen } { 15 }
+\__unravel_tex_primitive:nnn { overfullrule } { assign_dimen } { 16 }
+\__unravel_tex_primitive:nnn { hangindent } { assign_dimen } { 17 }
+\__unravel_tex_primitive:nnn { hoffset } { assign_dimen } { 18 }
+\__unravel_tex_primitive:nnn { voffset } { assign_dimen } { 19 }
+\__unravel_tex_primitive:nnn { emergencystretch } { assign_dimen } { 20 }
+\__unravel_tex_primitive:nnn { pdfhorigin } { assign_dimen } { 21 }
+\__unravel_tex_primitive:nnn { pdfvorigin } { assign_dimen } { 22 }
+\__unravel_tex_primitive:nnn { pdfpagewidth } { assign_dimen } { 23 }
+\__unravel_tex_primitive:nnn { pdfpageheight } { assign_dimen } { 24 }
+\__unravel_tex_primitive:nnn { pdflinkmargin } { assign_dimen } { 25 }
+\__unravel_tex_primitive:nnn { pdfdestmargin } { assign_dimen } { 26 }
+\__unravel_tex_primitive:nnn { pdfthreadmargin } { assign_dimen } { 27 }
+\__unravel_tex_primitive:nnn { pdffirstlineheight } { assign_dimen } { 28 }
+\__unravel_tex_primitive:nnn { pdflastlinedepth } { assign_dimen } { 29 }
+\__unravel_tex_primitive:nnn { pdfeachlineheight } { assign_dimen } { 30 }
+\__unravel_tex_primitive:nnn { pdfeachlinedepth } { assign_dimen } { 31 }
+\__unravel_tex_primitive:nnn { pdfignoreddimen } { assign_dimen } { 32 }
+\__unravel_tex_primitive:nnn { pdfpxdimen } { assign_dimen } { 33 }
+\__unravel_tex_primitive:nnn { lineskip } { assign_glue } { 0 }
+\__unravel_tex_primitive:nnn { baselineskip } { assign_glue } { 1 }
+\__unravel_tex_primitive:nnn { parskip } { assign_glue } { 2 }
+\__unravel_tex_primitive:nnn { abovedisplayskip } { assign_glue } { 3 }
+\__unravel_tex_primitive:nnn { belowdisplayskip } { assign_glue } { 4 }
+\__unravel_tex_primitive:nnn { abovedisplayshortskip } { assign_glue } { 5 }
+\__unravel_tex_primitive:nnn { belowdisplayshortskip } { assign_glue } { 6 }
+\__unravel_tex_primitive:nnn { leftskip } { assign_glue } { 7 }
+\__unravel_tex_primitive:nnn { rightskip } { assign_glue } { 8 }
+\__unravel_tex_primitive:nnn { topskip } { assign_glue } { 9 }
+\__unravel_tex_primitive:nnn { splittopskip } { assign_glue } { 10 }
+\__unravel_tex_primitive:nnn { tabskip } { assign_glue } { 11 }
+\__unravel_tex_primitive:nnn { spaceskip } { assign_glue } { 12 }
+\__unravel_tex_primitive:nnn { xspaceskip } { assign_glue } { 13 }
+\__unravel_tex_primitive:nnn { parfillskip } { assign_glue } { 14 }
+\__unravel_tex_primitive:nnn { thinmuskip } { assign_mu_glue } { 15 }
+\__unravel_tex_primitive:nnn { medmuskip } { assign_mu_glue } { 16 }
+\__unravel_tex_primitive:nnn { thickmuskip } { assign_mu_glue } { 17 }
+\__unravel_tex_primitive:nnn { fontdimen } { assign_font_dimen } { 0 }
+\__unravel_tex_primitive:nnn { hyphenchar } { assign_font_int } { 0 }
+\__unravel_tex_primitive:nnn { skewchar } { assign_font_int } { 1 }
+\__unravel_tex_primitive:nnn { lpcode } { assign_font_int } { 2 }
+\__unravel_tex_primitive:nnn { rpcode } { assign_font_int } { 3 }
+\__unravel_tex_primitive:nnn { efcode } { assign_font_int } { 4 }
+\__unravel_tex_primitive:nnn { tagcode } { assign_font_int } { 5 }
+\__unravel_tex_primitive:nnn { pdfnoligatures } { assign_font_int } { 6 }
+\__unravel_tex_primitive:nnn { knbscode } { assign_font_int } { 7 }
+\__unravel_tex_primitive:nnn { stbscode } { assign_font_int } { 8 }
+\__unravel_tex_primitive:nnn { shbscode } { assign_font_int } { 9 }
+\__unravel_tex_primitive:nnn { knbccode } { assign_font_int } { 10 }
+\__unravel_tex_primitive:nnn { knaccode } { assign_font_int } { 11 }
+\__unravel_tex_primitive:nnn { spacefactor } { set_aux } { 102 }
+\__unravel_tex_primitive:nnn { prevdepth } { set_aux } { 1 }
+\__unravel_tex_primitive:nnn { prevgraf } { set_prev_graf } { 0 }
+\__unravel_tex_primitive:nnn { pagegoal } { set_page_dimen } { 0 }
+\__unravel_tex_primitive:nnn { pagetotal } { set_page_dimen } { 1 }
+\__unravel_tex_primitive:nnn { pagestretch } { set_page_dimen } { 2 }
+\__unravel_tex_primitive:nnn { pagefilstretch } { set_page_dimen } { 3 }
+\__unravel_tex_primitive:nnn { pagefillstretch } { set_page_dimen } { 4 }
+\__unravel_tex_primitive:nnn { pagefilllstretch } { set_page_dimen } { 5 }
+\__unravel_tex_primitive:nnn { pageshrink } { set_page_dimen } { 6 }
+\__unravel_tex_primitive:nnn { pagedepth } { set_page_dimen } { 7 }
+\__unravel_tex_primitive:nnn { deadcycles } { set_page_int } { 0 }
+\__unravel_tex_primitive:nnn { insertpenalties } { set_page_int } { 1 }
+\__unravel_tex_primitive:nnn { interactionmode } { set_page_int } { 2 }
+\__unravel_tex_primitive:nnn { wd } { set_box_dimen } { 1 }
+\__unravel_tex_primitive:nnn { dp } { set_box_dimen } { 2 }
+\__unravel_tex_primitive:nnn { ht } { set_box_dimen } { 3 }
+\__unravel_tex_primitive:nnn { parshape } { set_shape } { 0 }
+\__unravel_tex_primitive:nnn { interlinepenalties } { set_shape } { 1 }
+\__unravel_tex_primitive:nnn { clubpenalties } { set_shape } { 2 }
+\__unravel_tex_primitive:nnn { widowpenalties } { set_shape } { 3 }
+\__unravel_tex_primitive:nnn { displaywidowpenalties } { set_shape } { 4 }
+\__unravel_tex_primitive:nnn { catcode } { def_code } { 0 }
+\__unravel_tex_primitive:nnn { lccode } { def_code } { 256 }
+\__unravel_tex_primitive:nnn { uccode } { def_code } { 512 }
+\__unravel_tex_primitive:nnn { sfcode } { def_code } { 768 }
+\__unravel_tex_primitive:nnn { mathcode } { def_code } { 1024 }
+\__unravel_tex_primitive:nnn { delcode } { def_code } { 1591 }
+\__unravel_tex_primitive:nnn { textfont } { def_family } { -48 }
+\__unravel_tex_primitive:nnn { scriptfont } { def_family } { -32 }
+\__unravel_tex_primitive:nnn { scriptscriptfont } { def_family } { -16 }
+\__unravel_tex_primitive:nnn { nullfont } { set_font } { 0 }
+\__unravel_tex_primitive:nnn { font } { def_font } { 0 }
+\__unravel_tex_primitive:nnn { count } { register } { 1 000 000 }
+\__unravel_tex_primitive:nnn { dimen } { register } { 2 000 000 }
+\__unravel_tex_primitive:nnn { skip } { register } { 3 000 000 }
+\__unravel_tex_primitive:nnn { muskip } { register } { 4 000 000 }
+\__unravel_tex_primitive:nnn { advance } { advance } { 0 }
+\__unravel_tex_primitive:nnn { multiply } { multiply } { 0 }
+\__unravel_tex_primitive:nnn { divide } { divide } { 0 }
+\__unravel_tex_primitive:nnn { long } { prefix } { 1 }
+\__unravel_tex_primitive:nnn { outer } { prefix } { 2 }
+\__unravel_tex_primitive:nnn { global } { prefix } { 4 }
+\__unravel_tex_primitive:nnn { protected } { prefix } { 8 }
+\__unravel_tex_primitive:nnn { let } { let } { 0 }
+\__unravel_tex_primitive:nnn { futurelet } { let } { 1 }
+\__unravel_tex_primitive:nnn { chardef } { shorthand_def } { 0 }
+\__unravel_tex_primitive:nnn { mathchardef } { shorthand_def } { 1 }
+\__unravel_tex_primitive:nnn { countdef } { shorthand_def } { 2 }
+\__unravel_tex_primitive:nnn { dimendef } { shorthand_def } { 3 }
+\__unravel_tex_primitive:nnn { skipdef } { shorthand_def } { 4 }
+\__unravel_tex_primitive:nnn { muskipdef } { shorthand_def } { 5 }
+\__unravel_tex_primitive:nnn { toksdef } { shorthand_def } { 6 }
+\__unravel_tex_primitive:nnn { read } { read_to_cs } { 0 }
+\__unravel_tex_primitive:nnn { readline } { read_to_cs } { 1 }
+\__unravel_tex_primitive:nnn { def } { def } { 0 }
+\__unravel_tex_primitive:nnn { gdef } { def } { 1 }
+\__unravel_tex_primitive:nnn { edef } { def } { 2 }
+\__unravel_tex_primitive:nnn { xdef } { def } { 3 }
+\__unravel_tex_primitive:nnn { setbox } { set_box } { 0 }
+\__unravel_tex_primitive:nnn { hyphenation } { hyph_data } { 0 }
+\__unravel_tex_primitive:nnn { patterns } { hyph_data } { 1 }
+\__unravel_tex_primitive:nnn { batchmode } { set_interaction } { 0 }
+\__unravel_tex_primitive:nnn { nonstopmode } { set_interaction } { 1 }
+\__unravel_tex_primitive:nnn { scrollmode } { set_interaction } { 2 }
+\__unravel_tex_primitive:nnn { errorstopmode } { set_interaction } { 3 }
+\__unravel_tex_primitive:nnn { letterspacefont } { letterspace_font } { 0 }
+\__unravel_tex_primitive:nnn { pdfcopyfont } { pdf_copy_font } { 0 }
+\__unravel_tex_primitive:nnn { undefined } { undefined_cs } { 0 }
+\__unravel_tex_primitive:nnn { ndefined } { undefined_cs } { 0 }
+\__unravel_tex_primitive:nnn { expandafter } { expand_after } { 0 }
+\__unravel_tex_primitive:nnn { unless } { expand_after } { 1 }
+\__unravel_tex_primitive:nnn { pdfprimitive } { no_expand } { 1 }
+\__unravel_tex_primitive:nnn { noexpand } { no_expand } { 0 }
+\__unravel_tex_primitive:nnn { input } { input } { 0 }
+\__unravel_tex_primitive:nnn { endinput } { input } { 1 }
+\__unravel_tex_primitive:nnn { scantokens } { input } { 2 }
+\__unravel_tex_primitive:nnn { if } { if_test } { 0 }
+\__unravel_tex_primitive:nnn { ifcat } { if_test } { 1 }
+\__unravel_tex_primitive:nnn { ifnum } { if_test } { 2 }
+\__unravel_tex_primitive:nnn { ifdim } { if_test } { 3 }
+\__unravel_tex_primitive:nnn { ifodd } { if_test } { 4 }
+\__unravel_tex_primitive:nnn { ifvmode } { if_test } { 5 }
+\__unravel_tex_primitive:nnn { ifhmode } { if_test } { 6 }
+\__unravel_tex_primitive:nnn { ifmmode } { if_test } { 7 }
+\__unravel_tex_primitive:nnn { ifinner } { if_test } { 8 }
+\__unravel_tex_primitive:nnn { ifvoid } { if_test } { 9 }
+\__unravel_tex_primitive:nnn { ifhbox } { if_test } { 10 }
+\__unravel_tex_primitive:nnn { ifvbox } { if_test } { 11 }
+\__unravel_tex_primitive:nnn { ifx } { if_test } { 12 }
+\__unravel_tex_primitive:nnn { ifeof } { if_test } { 13 }
+\__unravel_tex_primitive:nnn { iftrue } { if_test } { 14 }
+\__unravel_tex_primitive:nnn { iffalse } { if_test } { 15 }
+\__unravel_tex_primitive:nnn { ifcase } { if_test } { 16 }
+\__unravel_tex_primitive:nnn { ifdefined } { if_test } { 17 }
+\__unravel_tex_primitive:nnn { ifcsname } { if_test } { 18 }
+\__unravel_tex_primitive:nnn { iffontchar } { if_test } { 19 }
+\__unravel_tex_primitive:nnn { ifincsname } { if_test } { 20 }
+\__unravel_tex_primitive:nnn { ifpdfprimitive } { if_test } { 21 }
+\__unravel_tex_primitive:nnn { ifpdfabsnum } { if_test } { 22 }
+\__unravel_tex_primitive:nnn { ifpdfabsdim } { if_test } { 23 }
+\__unravel_tex_primitive:nnn { fi } { fi_or_else } { 2 }
+\__unravel_tex_primitive:nnn { else } { fi_or_else } { 3 }
+\__unravel_tex_primitive:nnn { or } { fi_or_else } { 4 }
+\__unravel_tex_primitive:nnn { csname } { cs_name } { 0 }
+\__unravel_tex_primitive:nnn { number } { convert } { 0 }
+\__unravel_tex_primitive:nnn { romannumeral } { convert } { 1 }
+\__unravel_tex_primitive:nnn { string } { convert } { 2 }
+\__unravel_tex_primitive:nnn { meaning } { convert } { 3 }
+\__unravel_tex_primitive:nnn { fontname } { convert } { 4 }
+\__unravel_tex_primitive:nnn { eTeXrevision } { convert } { 5 }
+\__unravel_tex_primitive:nnn { pdftexrevision } { convert } { 6 }
+\__unravel_tex_primitive:nnn { pdftexbanner } { convert } { 7 }
+\__unravel_tex_primitive:nnn { pdffontname } { convert } { 8 }
+\__unravel_tex_primitive:nnn { pdffontobjnum } { convert } { 9 }
+\__unravel_tex_primitive:nnn { pdffontsize } { convert } { 10 }
+\__unravel_tex_primitive:nnn { pdfpageref } { convert } { 11 }
+\__unravel_tex_primitive:nnn { pdfxformname } { convert } { 12 }
+\__unravel_tex_primitive:nnn { pdfescapestring } { convert } { 13 }
+\__unravel_tex_primitive:nnn { pdfescapename } { convert } { 14 }
+\__unravel_tex_primitive:nnn { leftmarginkern } { convert } { 15 }
+\__unravel_tex_primitive:nnn { rightmarginkern } { convert } { 16 }
+\__unravel_tex_primitive:nnn { pdfstrcmp } { convert } { 17 }
+\__unravel_tex_primitive:nnn { pdfcolorstackinit } { convert } { 18 }
+\__unravel_tex_primitive:nnn { pdfescapehex } { convert } { 19 }
+\__unravel_tex_primitive:nnn { pdfunescapehex } { convert } { 20 }
+\__unravel_tex_primitive:nnn { pdfcreationdate } { convert } { 21 }
+\__unravel_tex_primitive:nnn { pdffilemoddate } { convert } { 22 }
+\__unravel_tex_primitive:nnn { pdffilesize } { convert } { 23 }
+\__unravel_tex_primitive:nnn { pdfmdfivesum } { convert } { 24 }
+\__unravel_tex_primitive:nnn { pdffiledump } { convert } { 25 }
+\__unravel_tex_primitive:nnn { pdfmatch } { convert } { 26 }
+\__unravel_tex_primitive:nnn { pdflastmatch } { convert } { 27 }
+\__unravel_tex_primitive:nnn { pdfuniformdeviate } { convert } { 28 }
+\__unravel_tex_primitive:nnn { pdfnormaldeviate } { convert } { 29 }
+\__unravel_tex_primitive:nnn { pdfinsertht } { convert } { 30 }
+\__unravel_tex_primitive:nnn { pdfximagebbox } { convert } { 31 }
+\__unravel_tex_primitive:nnn { jobname } { convert } { 32 }
+\__unravel_tex_primitive:nnn { the } { the } { 0 }
+\__unravel_tex_primitive:nnn { unexpanded } { the } { 1 }
+\__unravel_tex_primitive:nnn { detokenize } { the } { 5 }
+\__unravel_tex_primitive:nnn { topmark } { top_bot_mark } { 0 }
+\__unravel_tex_primitive:nnn { firstmark } { top_bot_mark } { 1 }
+\__unravel_tex_primitive:nnn { botmark } { top_bot_mark } { 2 }
+\__unravel_tex_primitive:nnn { splitfirstmark } { top_bot_mark } { 3 }
+\__unravel_tex_primitive:nnn { splitbotmark } { top_bot_mark } { 4 }
+\__unravel_tex_primitive:nnn { topmarks } { top_bot_mark } { 5 }
+\__unravel_tex_primitive:nnn { firstmarks } { top_bot_mark } { 6 }
+\__unravel_tex_primitive:nnn { botmarks } { top_bot_mark } { 7 }
+\__unravel_tex_primitive:nnn { splitfirstmarks } { top_bot_mark } { 8 }
+\__unravel_tex_primitive:nnn { splitbotmarks } { top_bot_mark } { 9 }
+\cs_new_protected_nopar:Npn \__unravel_get_next:
+ {
+ \__unravel_input_if_empty:TF
+ { \__unravel_exit:w }
+ {
+ \__unravel_input_gpop:N \l__unravel_head_gtl
+ \gtl_head_do:NN \l__unravel_head_gtl \__unravel_get_next_aux:w
+ \gtl_if_tl:NTF \l__unravel_head_gtl
+ {
+ \tl_set:Nx \l__unravel_head_tl
+ { \gtl_head:N \l__unravel_head_gtl }
+ }
+ { \tl_clear:N \l__unravel_head_tl }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_get_next_aux:w
+ { \cs_set_eq:NN \l__unravel_head_token }
+\cs_new_protected_nopar:Npn \__unravel_get_token:
+ {
+ \__unravel_get_next:
+ \__unravel_set_cmd:
+ }
+\cs_new_protected_nopar:Npn \__unravel_set_cmd:
+ {
+ \__unravel_set_cmd_aux_meaning:
+ \__unravel_set_cmd_aux_primitive:oTF { \l__unravel_head_meaning_tl }
+ { }
+ {
+ \__unravel_token_if_expandable:NTF \l__unravel_head_token
+ {
+ \token_if_macro:NTF \l__unravel_head_token
+ { \__unravel_set_cmd_aux_macro: }
+ { \__unravel_set_cmd_aux_unknown: }
+ }
+ {
+ \token_if_cs:NTF \l__unravel_head_token
+ { \__unravel_set_cmd_aux_cs: }
+ { \__unravel_set_cmd_aux_char: }
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_set_cmd_aux_meaning:
+ {
+ \tl_set:Nx \l__unravel_head_meaning_tl
+ {
+ \exp_after:wN \__unravel_strip_escape:w
+ \token_to_meaning:N \l__unravel_head_token
+ \tl_to_str:n { : }
+ }
+ \tl_set:Nx \l__unravel_head_meaning_tl
+ {
+ \exp_after:wN \__unravel_set_cmd_aux_meaning:w
+ \l__unravel_head_meaning_tl \q_stop
+ }
+ }
+\use:x
+ {
+ \cs_new:Npn \exp_not:N \__unravel_set_cmd_aux_meaning:w
+ ##1 \token_to_str:N : ##2 \exp_not:N \q_stop {##1}
+ }
+\cs_new_protected:Npn \__unravel_set_cmd_aux_primitive:nTF #1#2
+ {
+ \cs_if_exist:cTF { c__unravel_tex_#1_tl }
+ {
+ \exp_last_unbraced:Nv \__unravel_set_cmd_aux_primitive:nn
+ { c__unravel_tex_#1_tl }
+ #2
+ }
+ }
+\cs_generate_variant:Nn \__unravel_set_cmd_aux_primitive:nTF { o }
+\cs_new_protected:Npn \__unravel_set_cmd_aux_primitive:nn #1#2
+ {
+ \int_set:Nn \l__unravel_head_cmd_int {#1}
+ \int_set:Nn \l__unravel_head_char_int {#2}
+ }
+\cs_new_protected_nopar:Npn \__unravel_set_cmd_aux_macro:
+ {
+ \int_set:Nn \l__unravel_head_cmd_int { \__unravel_tex_use:n { call } }
+ \int_zero:N \l__unravel_head_char_int
+ }
+\cs_new_protected_nopar:Npn \__unravel_set_cmd_aux_unknown:
+ {
+ \exp_last_unbraced:NV \__unravel_set_cmd_aux_primitive:nn
+ \c__unravel_tex_relax_tl
+ \msg_error:nnx { unravel } { unknown-primitive }
+ { \l__unravel_head_meaning_tl }
+ }
+\cs_new_protected_nopar:Npn \__unravel_set_cmd_aux_cs:
+ {
+ \tl_if_in:NoTF \l__unravel_head_meaning_tl
+ { \tl_to_str:n { elect~font } }
+ {
+ \exp_last_unbraced:NV \__unravel_set_cmd_aux_primitive:nn
+ \c__unravel_tex_nullfont_tl
+ }
+ { \__unravel_set_cmd_aux_numeric: }
+ }
+\cs_new_protected_nopar:Npn \__unravel_set_cmd_aux_numeric:
+ {
+ \tl_set:Nx \l__unravel_tmpa_tl
+ {
+ \exp_after:wN \__unravel_set_cmd_aux_numeric:N
+ \l__unravel_head_meaning_tl + 0
+ }
+ \exp_after:wN \__unravel_set_cmd_aux_numeric:w
+ \l__unravel_tmpa_tl \q_stop
+ }
+\cs_new:Npn \__unravel_set_cmd_aux_numeric:N #1
+ {
+ \if_int_compare:w `#1 < `A \exp_stop_f:
+ \exp_not:N \q_mark
+ \exp_after:wN \use_i:nn
+ \fi:
+ #1 \__unravel_set_cmd_aux_numeric:N
+ }
+\cs_new_protected:Npn \__unravel_set_cmd_aux_numeric:w #1 \q_mark #2 \q_stop
+ {
+ \str_case:nnF {#1}
+ {
+ { char } { \__unravel_set_cmd_aux_given:n { char_given } }
+ { mathchar } { \__unravel_set_cmd_aux_given:n { math_given } }
+ }
+ {
+ \__unravel_set_cmd_aux_primitive:nTF {#1}
+ { }
+ { \__unravel_set_cmd_aux_unknown: }
+ \int_add:Nn \l__unravel_head_char_int { 100 000 }
+ }
+ \int_add:Nn \l__unravel_head_char_int {#2}
+ }
+\cs_new_protected:Npn \__unravel_set_cmd_aux_given:n #1
+ {
+ \int_set:Nn \l__unravel_head_cmd_int { \__unravel_tex_use:n {#1} }
+ \int_zero:N \l__unravel_head_char_int
+ }
+\cs_new_protected_nopar:Npn \__unravel_set_cmd_aux_char:
+ {
+ \tl_set:Nx \l__unravel_head_meaning_tl
+ { \token_to_meaning:N \l__unravel_head_token }
+ \token_if_eq_catcode:NNT \l__unravel_head_token \c_catcode_other_token
+ { \tl_set:Nn \l__unravel_head_meaning_tl { other~ } }
+ \exp_after:wN \__unravel_set_cmd_aux_char:w
+ \l__unravel_head_meaning_tl \q_stop
+ \exp_args:NNx \int_set:Nn \l__unravel_head_char_int
+ { ` \__unravel_token_to_char:N \l__unravel_head_token }
+ }
+\cs_new_protected:Npn \__unravel_set_cmd_aux_char:w #1 ~ #2 \q_stop
+ {
+ \int_set:Nn \l__unravel_head_cmd_int
+ { \__unravel_tex_use:n { #1_char } }
+ }
+\cs_new_nopar:Npn \__unravel_input_to_str:
+ {
+ \int_step_function:nnnN \g__unravel_input_int { -1 } { 1 }
+ \__unravel_input_to_str_aux:n
+ }
+\cs_new:Npn \__unravel_input_to_str_aux:n #1
+ { \gtl_to_str:c { g__unravel_input_#1_gtl } }
+\cs_new_protected:Npn \__unravel_input_if_empty:TF
+ {
+ \int_compare:nNnTF \g__unravel_input_int = \c_zero
+ { \use_i:nn }
+ {
+ \gtl_if_empty:cTF
+ { g__unravel_input_ \int_use:N \g__unravel_input_int _gtl }
+ {
+ \int_gdecr:N \g__unravel_input_int
+ \__unravel_input_if_empty:TF
+ }
+ {
+ \__unravel_input_split:
+ \use_ii:nn
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_input_split:
+ {
+ \int_compare:nNnT \g__unravel_input_int = \c_one
+ {
+ \exp_args:Nc \__unravel_input_split_aux:N
+ { g__unravel_input_1_gtl }
+ }
+ }
+\cs_new_protected:Npn \__unravel_input_split_aux:N #1
+ {
+ \gtl_if_tl:NT #1
+ {
+ \gtl_if_head_is_N_type:NT #1
+ {
+ \tl_set:Nx \l__unravel_input_tmpa_tl { \gtl_left_tl:N #1 }
+ \exp_last_unbraced:Nx \__unravel_input_split_auxii:N
+ { \tl_head:N \l__unravel_input_tmpa_tl }
+ }
+ }
+ }
+\cs_new_protected:Npn \__unravel_input_split_auxii:N #1
+ {
+ \token_if_parameter:NF #1
+ {
+ \tl_replace_all:Nnn \l__unravel_input_tmpa_tl {#1}
+ { \__unravel_input_split_end: \__unravel_input_split_auxiii:w #1 }
+ \group_begin:
+ \cs_set:Npn \__unravel_input_split_auxiii:w
+ ##1 \__unravel_input_split_end: { + 1 }
+ \int_gset:Nn \g__unravel_input_int
+ { 0 \l__unravel_input_tmpa_tl \__unravel_input_split_end: }
+ \group_end:
+ \int_gset_eq:NN \g__unravel_input_tmpa_int \g__unravel_input_int
+ \l__unravel_input_tmpa_tl \__unravel_input_split_end:
+ }
+ }
+\cs_new_nopar:Npn \__unravel_input_split_end: { }
+\cs_new_protected:Npn \__unravel_input_split_auxiii:w
+ #1 \__unravel_input_split_end:
+ {
+ \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 }
+ }
+\cs_new_protected:Npn \__unravel_input_get:N #1
+ {
+ \__unravel_input_if_empty:TF
+ { \gtl_set:Nn #1 { \q_no_value } }
+ {
+ \gtl_get_left:cN
+ { g__unravel_input_ \int_use:N \g__unravel_input_int _gtl } #1
+ }
+ }
+\cs_new_protected:Npn \__unravel_input_gpop:N #1
+ {
+ \__unravel_input_if_empty:TF
+ { \gtl_set:Nn #1 { \q_no_value } }
+ {
+ \gtl_gpop_left:cN
+ { g__unravel_input_ \int_use:N \g__unravel_input_int _gtl } #1
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_input_merge:
+ {
+ \int_gdecr:N \g__unravel_input_int
+ \gtl_gconcat:ccc
+ { g__unravel_input_ \int_use:N \g__unravel_input_int _gtl }
+ { g__unravel_input_ \int_eval:n { \g__unravel_input_int + 1 } _gtl }
+ { g__unravel_input_ \int_use:N \g__unravel_input_int _gtl }
+ \gtl_gclear:c
+ { g__unravel_input_ \int_eval:n { \g__unravel_input_int + 1 } _gtl }
+ }
+\prg_new_protected_conditional:Npnn \__unravel_input_gpop_item:N #1 { F }
+ {
+ \int_compare:nNnTF \g__unravel_input_int = \c_zero
+ { \prg_return_false: }
+ {
+ \exp_args:Nc \__unravel_input_gpop_item_aux:NN
+ { g__unravel_input_ \int_use:N \g__unravel_input_int _gtl } #1
+ }
+ }
+\cs_new_protected:Npn \__unravel_input_gpop_item_aux:NN #1#2
+ {
+ \gtl_gpop_left_item:NNTF #1#2
+ { \prg_return_true: }
+ {
+ \int_compare:nNnTF { \gtl_extra_end:N #1 } > \c_zero
+ { \prg_return_false: }
+ {
+ \int_compare:nNnTF \g__unravel_input_int = \c_one
+ { \prg_return_false: }
+ {
+ \__unravel_input_merge:
+ \exp_args:Nc \__unravel_input_gpop_item_aux:NN
+ {
+ g__unravel_input_
+ \int_use:N \g__unravel_input_int _gtl
+ }
+ #2
+ }
+ }
+ }
+ }
+\cs_new_protected:Npn \__unravel_input_gpop_tl:N #1
+ { \tl_clear:N #1 \__unravel_input_gpop_tl_aux:N #1 }
+\cs_new_protected:Npn \__unravel_input_gpop_tl_aux:N #1
+ {
+ \int_compare:nNnF \g__unravel_input_int = \c_zero
+ {
+ \exp_args:Nc \__unravel_input_gpop_tl_aux:NN
+ { g__unravel_input_ \int_use:N \g__unravel_input_int _gtl } #1
+ }
+ }
+\cs_new_protected:Npn \__unravel_input_gpop_tl_aux:NN #1#2
+ {
+ \gtl_if_tl:NTF #1
+ {
+ \tl_put_right:Nx #2 { \gtl_left_tl:N #1 }
+ \gtl_gclear:N #1
+ \int_gdecr:N \g__unravel_input_int
+ \__unravel_input_gpop_tl_aux:N #2
+ }
+ {
+ \int_compare:nNnTF \g__unravel_input_int > \c_one
+ { \int_compare:nNnTF { \gtl_extra_end:N #1 } > \c_zero }
+ { \use_i:nn }
+ {
+ \tl_put_right:Nx #2 { \gtl_left_tl:N #1 }
+ \gtl_gpop_left_tl:N #1
+ }
+ {
+ \__unravel_input_merge:
+ \__unravel_input_gpop_tl_aux:N #2
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_back_input:n
+ {
+ \int_gincr:N \g__unravel_input_int
+ \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 }
+\cs_new_protected:Npn \__unravel_back_input_gtl:N #1
+ {
+ \gtl_if_tl:NTF #1
+ { \__unravel_back_input:x { \gtl_left_tl:N #1 } }
+ {
+ \gtl_gconcat:cNc
+ { g__unravel_input_ \int_use:N \g__unravel_input_int _gtl }
+ #1
+ { g__unravel_input_ \int_use:N \g__unravel_input_int _gtl }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_back_input:
+ { \__unravel_back_input_gtl:N \l__unravel_head_gtl }
+\cs_new_protected_nopar:Npn \__unravel_back_input_tl_o:
+ {
+ \tl_set:Nx \l__unravel_tmpa_tl
+ { \exp_args:NV \exp_not:o \l__unravel_head_tl }
+ \__unravel_back_input:V \l__unravel_tmpa_tl
+ \__unravel_print_done:x
+ { \tl_to_str:N \l__unravel_head_tl = \tl_to_str:N \l__unravel_tmpa_tl }
+ }
+\cs_new_protected_nopar:Npn \__unravel_insert_relax:
+ {
+ \__unravel_back_input:
+ \gtl_set_eq:NN \l__unravel_head_gtl \c__unravel_frozen_relax_gtl
+ \__unravel_back_input:
+ \__unravel_print_action:
+ }
+\cs_new_protected_nopar:Npn \__unravel_insert_group_begin_error:
+ {
+ \msg_error:nn { unravel } { missing-lbrace }
+ \__unravel_back_input:
+ \gtl_set_eq:NN \l__unravel_head_gtl \c_group_begin_gtl
+ \__unravel_back_input:
+ \__unravel_print_action:
+ }
+\cs_new_protected_nopar:Npn \__unravel_insert_dollar_error:
+ {
+ \__unravel_back_input:
+ \__unravel_back_input:n { $ } % $
+ \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:
+\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
+ { \__unravel_macro_split_do:NN #1 \use_ii:nnn }
+\cs_new:Npn \__unravel_macro_replacement:N #1
+ { \__unravel_macro_split_do:NN #1 \use_iii:nnn }
+\cs_new_protected_nopar:Npn \__unravel_macro_call:
+ {
+ \bool_if:NTF \g__unravel_speedup_macros_bool
+ {
+ \tl_set:Nx \l__unravel_tmpa_tl
+ {^ \exp_after:wN \__unravel_macro_parameter:N \l__unravel_head_tl }
+ \tl_if_in:NVTF \c__unravel_parameters_tl \l__unravel_tmpa_tl
+ { \__unravel_macro_call_quick: } { \__unravel_macro_call_safe: }
+ }
+ { \__unravel_macro_call_safe: }
+ \exp_args:NV \__unravel_back_input:o \l__unravel_head_tl
+ \__unravel_print_done:x { \g__unravel_action_text_str }
+ }
+\cs_new_protected_nopar:Npn \__unravel_macro_call_safe:
+ {
+ \__unravel_input_gpop_tl:N \l__unravel_tmpa_tl
+ \tl_put_right:NV \l__unravel_head_tl \l__unravel_tmpa_tl
+ }
+\cs_new_protected_nopar:Npn \__unravel_macro_call_quick:
+ {
+ \exp_after:wN \__unravel_macro_call_quick_loop:NN \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
+ {
+ \use_none:n #2
+ \__unravel_input_gpop_item:NF \l__unravel_tmpa_tl
+ { \msg_error:nn { unravel } { runaway-macro-parameter } }
+ \tl_put_right:Nx \l__unravel_head_tl
+ { { \exp_not:V \l__unravel_tmpa_tl } }
+ \__unravel_macro_call_quick_loop:NN
+ }
+\cs_new_protected_nopar:Npn \__unravel_expand:
+ {
+ \__unravel_set_action_text:
+ \bool_if:NT \l__unravel_debug_bool
+ {
+ \__unravel_set_cmd:
+ \iow_term:x { Exp:~\int_use:N \l__unravel_head_cmd_int }
+ }
+ \token_if_macro:NTF \l__unravel_head_token
+ { \__unravel_macro_call: }
+ { \__unravel_expand_nonmacro: }
+ }
+\cs_new_protected_nopar:Npn \__unravel_expand_nonmacro:
+ {
+ \__unravel_set_cmd_aux_meaning:
+ \__unravel_set_cmd_aux_primitive:oTF { \l__unravel_head_meaning_tl }
+ {
+ \cs_if_exist_use:cF
+ { __unravel_expandable_ \int_use:N \l__unravel_head_cmd_int : }
+ { \msg_error:nnx { unravel } { internal } { expandable } }
+ }
+ {
+ \msg_error:nnx { unravel } { unknown-primitive }
+ { \l__unravel_head_meaning_tl }
+ \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl
+ \__unravel_print_action:
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_get_x_next:
+ {
+ \__unravel_get_next:
+ \__unravel_token_if_expandable:NT \l__unravel_head_token
+ {
+ \__unravel_expand:
+ \__unravel_get_x_next:
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_get_x_or_protected:
+ {
+ \__unravel_get_next:
+ \__unravel_token_if_protected:NF \l__unravel_head_token
+ {
+ \__unravel_expand:
+ \__unravel_get_x_or_protected:
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_get_x_non_blank:
+ {
+ \__unravel_get_x_next:
+ \token_if_eq_catcode:NNT \l__unravel_head_token \c_space_token
+ { \__unravel_get_x_non_blank: }
+ }
+\cs_new_protected_nopar:Npn \__unravel_get_x_non_relax:
+ {
+ \__unravel_get_x_next:
+ \token_if_eq_meaning:NNT \l__unravel_head_token \scan_stop:
+ { \__unravel_get_x_non_relax: }
+ {
+ \token_if_eq_catcode:NNT \l__unravel_head_token \c_space_token
+ { \__unravel_get_x_non_relax: }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_skip_optional_space:
+ {
+ \__unravel_get_x_next:
+ \token_if_eq_catcode:NNF \l__unravel_head_token \c_space_token
+ { \__unravel_back_input: }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_optional_equals:
+ {
+ \__unravel_get_x_non_blank:
+ \tl_if_eq:NNTF \l__unravel_head_tl \c__unravel_eq_tl
+ { \__unravel_prev_input:n { = } }
+ {
+ \__unravel_prev_input_silent:n { = }
+ \__unravel_back_input:
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_left_brace:
+ {
+ \__unravel_get_x_non_relax:
+ \token_if_eq_catcode:NNF \l__unravel_head_token \c_group_begin_token
+ { \__unravel_insert_group_begin_error: }
+ }
+\cs_new_protected:Npn \__unravel_scan_keyword:n #1
+ { \__unravel_scan_keyword:nTF {#1} { } { } }
+\prg_new_protected_conditional:Npnn \__unravel_scan_keyword:n #1
+ { T , F , TF }
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \c_empty_gtl
+ \__unravel_scan_keyword_loop:NNN \c_true_bool
+ #1 \q_recursion_tail \q_recursion_tail \q_recursion_stop
+ }
+\cs_new_protected:Npn \__unravel_scan_keyword_loop:NNN #1#2#3
+ {
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ { \__unravel_scan_keyword_true: }
+ \quark_if_recursion_tail_stop_do:nn {#3}
+ { \msg_error:nnx { unravel } { internal } { odd-keyword-length } }
+ \__unravel_get_x_next:
+ \__unravel_scan_keyword_test:NNTF #2#3
+ {
+ \__unravel_prev_input_gtl:N \l__unravel_head_gtl
+ \__unravel_scan_keyword_loop:NNN \c_false_bool
+ }
+ {
+ \token_if_eq_catcode:NNF \l__unravel_head_token \c_space_token
+ { \__unravel_scan_keyword_false:w }
+ \bool_if:NF #1
+ { \__unravel_scan_keyword_false:w }
+ \__unravel_scan_keyword_loop:NNN #1#2#3
+ }
+ }
+\prg_new_protected_conditional:Npnn \__unravel_scan_keyword_test:NN #1#2
+ { TF }
+ {
+ \__unravel_gtl_if_head_is_definable:NTF \l__unravel_head_gtl
+ { \prg_return_false: }
+ {
+ \str_if_eq_x:nnTF
+ { \str_head:f { \gtl_to_str:N \l__unravel_head_gtl } } {#1}
+ { \prg_return_true: }
+ {
+ \str_if_eq_x:nnTF
+ { \str_head:f { \gtl_to_str:N \l__unravel_head_gtl } } {#2}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_keyword_true:
+ {
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpb_gtl
+ \__unravel_prev_input:x { \gtl_to_str:N \l__unravel_tmpb_gtl }
+ \prg_return_true:
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_keyword_false:w
+ #1 \q_recursion_stop
+ {
+ \__unravel_back_input:
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpb_gtl
+ \__unravel_back_input_gtl:N \l__unravel_tmpb_gtl
+ \prg_return_false:
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_font_ident:
+ {
+ \__unravel_get_x_non_blank:
+ \__unravel_set_cmd:
+ \int_case:nnF \l__unravel_head_cmd_int
+ {
+ { \__unravel_tex_use:n { def_font } }
+ { \__unravel_prev_input:V \l__unravel_head_tl }
+ { \__unravel_tex_use:n { letterspace_font } }
+ { \__unravel_prev_input:V \l__unravel_head_tl }
+ { \__unravel_tex_use:n { pdf_copy_font } }
+ { \__unravel_prev_input:V \l__unravel_head_tl }
+ { \__unravel_tex_use:n { set_font } }
+ { \__unravel_prev_input:V \l__unravel_head_tl }
+ { \__unravel_tex_use:n { def_family } }
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_int:
+ }
+ }
+ {
+ \msg_error:nn { unravel } { missing-font-id }
+ \__unravel_prev_input:n { \tex_nullfont:D }
+ \__unravel_back_error:
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_font_int:
+ {
+ \int_case:nnF \l__unravel_head_char_int
+ {
+ { 0 } { \__unravel_scan_font_ident: }
+ { 1 } { \__unravel_scan_font_ident: }
+ { 6 } { \__unravel_scan_font_ident: }
+ }
+ { \__unravel_scan_font_ident: \__unravel_scan_int: }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_font_dimen:
+ {
+ \__unravel_scan_int:
+ \__unravel_scan_font_ident:
+ }
+\cs_new_protected:Npn \__unravel_scan_something_internal:n #1
+ {
+ \__unravel_set_cmd:
+ \__unravel_set_action_text:
+ \tl_set:Nf \l__unravel_tmpa_tl { \__unravel_thing_case: }
+ \exp_after:wN \__unravel_scan_something_aux:nwn
+ \l__unravel_tmpa_tl \q_stop {#1}
+ }
+\cs_new_protected:Npn \__unravel_scan_something_aux:nwn #1#2 \q_stop #3
+ {
+ \int_compare:nNnTF
+ { ( #1 + \c_two ) / \c_four } > { ( #3 + \c_two ) / \c_four }
+ { \__unravel_back_input: }
+ {
+ \tl_if_empty:nF {#2}
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ #2
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ }
+ }
+ \tl_set:Nx \l__unravel_tmpa_tl
+ { \__unravel_thing_use:nnN {#1} {#3} \l__unravel_head_tl }
+ \__unravel_prev_input_silent:V \l__unravel_tmpa_tl
+ \__unravel_set_action_text:
+ \__unravel_set_action_text:x
+ { \g__unravel_action_text_str = ~ \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}
+ }
+\cs_new_nopar:Npn \__unravel_thing_case:
+ {
+ \int_case:nnF \l__unravel_head_cmd_int
+ {
+ { 68 } { 0 } % char_given
+ { 69 } { 0 } % math_given
+ { 70 } { \__unravel_thing_last_item: } % last_item
+ { 71 } { 5 \__unravel_scan_toks_register: } % toks_register
+ { 72 } { 5 } % assign_toks
+ { 73 } { 0 } % assign_int
+ { 74 } { 1 } % assign_dimen
+ { 75 } { 2 } % assign_glue
+ { 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
+ { 80 } { 0 } % set_prev_graf
+ { 81 } { 1 } % set_page_dimen
+ { 82 } { 0 } % set_page_int
+ { 83 } { 1 \__unravel_scan_int: } % set_box_dimen
+ { 84 } { 0 \__unravel_scan_int: } % set_shape
+ { 85 } { 0 \__unravel_scan_int: } % def_code
+ { 86 } { 4 \__unravel_scan_font_ident: } % def_family
+ { 87 } { 4 \__unravel_scan_font_ident: } % set_font
+ { 88 } { 4 \__unravel_scan_font_ident: } % def_font
+ { 89 } { \__unravel_thing_register: } % register
+ }
+ { 8 }
+ }
+\cs_new_nopar:Npn \__unravel_thing_last_item:
+ {
+ \int_compare:nNnTF \l__unravel_head_char_int < { 26 }
+ {
+ \int_case:nnF \l__unravel_head_char_int
+ {
+ { 1 } { 1 } % lastkern
+ { 2 } { 2 } % lastskip
+ }
+ { 0 } % other integer parameters
+ }
+ {
+ \int_case:nnF \l__unravel_head_char_int
+ {
+ { 26 } { 0 \__unravel_scan_normal_glue: } % gluestretchorder
+ { 27 } { 0 \__unravel_scan_normal_glue: } % glueshrinkorder
+ { 28 } % fontcharwd
+ { 1 \__unravel_scan_font_ident: \__unravel_scan_int: }
+ { 29 } % fontcharht
+ { 1 \__unravel_scan_font_ident: \__unravel_scan_int: }
+ { 30 } % fontchardp
+ { 1 \__unravel_scan_font_ident: \__unravel_scan_int: }
+ { 31 } % fontcharic
+ { 1 \__unravel_scan_font_ident: \__unravel_scan_int: }
+ { 32 } { 1 \__unravel_scan_int: } % parshapelength
+ { 33 } { 1 \__unravel_scan_int: } % parshapeindent
+ { 34 } { 1 \__unravel_scan_int: } % parshapedimen
+ { 35 } { 1 \__unravel_scan_normal_glue: } % gluestretch
+ { 36 } { 1 \__unravel_scan_normal_glue: } % glueshrink
+ { 37 } { 2 \__unravel_scan_mu_glue: } % mutoglue
+ { 38 } { 3 \__unravel_scan_normal_glue: } % gluetomu
+ { 39 } % numepr
+ { 0 \__unravel_scan_expr:N \__unravel_scan_int: }
+ { 40 } % dimexpr
+ { 1 \__unravel_scan_expr:N \__unravel_scan_normal_dimen: }
+ { 41 } % glueexpr
+ { 2 \__unravel_scan_expr:N \__unravel_scan_normal_glue: }
+ { 42 } % muexpr
+ { 3 \__unravel_scan_expr:N \__unravel_scan_mu_glue: }
+ }
+ { }
+ }
+ }
+\cs_new_nopar:Npn \__unravel_thing_register:
+ {
+ \int_eval:n { \l__unravel_head_char_int / 1 000 000 - 1 }
+ \int_compare:nNnT { \tl_tail:V \l__unravel_head_char_int } = \c_zero
+ { \__unravel_scan_int: }
+ }
+\cs_new_protected:Npn \__unravel_scan_toks_register:
+ {
+ \int_compare:nNnT \l__unravel_head_char_int = \c_zero
+ { \__unravel_scan_int: }
+ }
+\cs_new:Npn \__unravel_thing_use:nnN #1#2
+ {
+ \int_case:nnF { \int_min:nn {#1} {#2} }
+ {
+ { 0 } \int_eval:n
+ { 1 } \dim_eval:n
+ { 2 } \skip_eval:n
+ { 3 } \muskip_eval:n
+ }
+ { \tex_the:D }
+ }
+\cs_new_protected:Npn \__unravel_scan_expr:N #1
+ { \__unravel_scan_expr_aux:NN #1 \c_false_bool }
+\cs_new_protected:Npn \__unravel_scan_expr_aux:NN #1#2
+ {
+ \__unravel_get_x_non_blank:
+ \__unravel_scan_factor:N #1
+ \__unravel_scan_expr_op:NN #1#2
+ }
+\cs_new_protected:Npn \__unravel_scan_expr_op:NN #1#2
+ {
+ \__unravel_get_x_non_blank:
+ \tl_case:NnF \l__unravel_head_tl
+ {
+ \c__unravel_plus_tl
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_expr_aux:NN #1#2
+ }
+ \c__unravel_minus_tl
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_expr_aux:NN #1#2
+ }
+ \c__unravel_times_tl
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_get_x_non_blank:
+ \__unravel_scan_factor:N \__unravel_scan_int:
+ \__unravel_scan_expr_op:NN #1#2
+ }
+ \c__unravel_over_tl
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_get_x_non_blank:
+ \__unravel_scan_factor:N \__unravel_scan_int:
+ \__unravel_scan_expr_op:NN #1#2
+ }
+ \c__unravel_rp_tl
+ {
+ \bool_if:NTF #2
+ { \__unravel_prev_input:V \l__unravel_head_tl }
+ { \__unravel_back_input: }
+ }
+ }
+ {
+ \bool_if:NTF #2
+ {
+ \msg_error:nn { unravel } { missing-rparen }
+ \__unravel_back_input:
+ \__unravel_prev_input:V \c__unravel_rp_tl
+ }
+ {
+ \token_if_eq_meaning:NNF \l__unravel_head_token \scan_stop:
+ { \__unravel_back_input: }
+ }
+ }
+ }
+\cs_new_protected:Npn \__unravel_scan_factor:N #1
+ {
+ \tl_if_eq:NNTF \l__unravel_head_tl \c__unravel_lp_tl
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_expr_aux:NN #1 \c_true_bool
+ }
+ {
+ \__unravel_back_input:
+ #1
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_signs:
+ {
+ \__unravel_get_x_non_blank:
+ \tl_if_eq:NNTF \l__unravel_head_tl \c__unravel_plus_tl
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_signs:
+ }
+ {
+ \tl_if_eq:NNT \l__unravel_head_tl \c__unravel_minus_tl
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_signs:
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_int:
+ {
+ \__unravel_scan_signs:
+ \__unravel_set_cmd:
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int < { \__unravel_tex_use:n { min_internal } }
+ { \__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:
+ {
+ \tl_case:NnF \l__unravel_head_tl
+ {
+ \c__unravel_lq_tl { \__unravel_scan_int_lq: }
+ \c__unravel_rq_tl
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_get_x_next:
+ \__unravel_scan_int_explicit:n { ' }
+ }
+ \c__unravel_dq_tl
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_get_x_next:
+ \__unravel_scan_int_explicit:n { " }
+ }
+ }
+ { \__unravel_scan_int_explicit:n { } }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_int_lq:
+ {
+ \__unravel_get_next:
+ \__unravel_gtl_if_head_is_definable:NF \l__unravel_head_gtl
+ {
+ \tl_set:Nx \l__unravel_head_tl
+ { \__unravel_token_to_char:N \l__unravel_head_token }
+ }
+ \tl_set:Nx \l__unravel_tmpa_tl
+ { \int_eval:n { \exp_after:wN ` \l__unravel_head_tl } }
+ \__unravel_prev_input_silent:V \l__unravel_tmpa_tl
+ \__unravel_print_action:x
+ { ` \gtl_to_str:N \l__unravel_head_gtl = \l__unravel_tmpa_tl }
+ \__unravel_skip_optional_space:
+ }
+\cs_new_protected:Npn \__unravel_scan_int_explicit:n #1
+ {
+ \if_int_compare:w \c_one
+ < #1 1 \exp_after:wN \exp_not:N \l__unravel_head_tl \exp_stop_f:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_get_x_next:
+ \__unravel_scan_int_explicit:n {#1}
+ }
+ {
+ \token_if_eq_catcode:NNF \l__unravel_head_token \c_space_token
+ { \__unravel_back_input: }
+ }
+ }
+\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_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 }
+ {
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int
+ > { \__unravel_tex_use:n { max_internal } }
+ { \__unravel_scan_dimen_char:NN #1#2 }
+ {
+ \bool_if:NTF #1
+ {
+ \__unravel_scan_something_internal:n { 3 }
+ \int_case:nnF \g__unravel_val_level_int
+ {
+ { 0 } { \__unravel_scan_dim_unit:NN #1 #2 }
+ { 3 } { }
+ }
+ {
+ \msg_error:nn { unravel } { incompatible-units }
+ % ^^A todo: error recovery
+ }
+ }
+ {
+ \__unravel_scan_something_internal:n { 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 } }
+ }
+ { }
+ }
+ }
+ }
+ \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
+ {
+ \tl_if_eq:NNT \l__unravel_head_tl \c__unravel_comma_tl
+ { \tl_set_eq:NN \l__unravel_head_tl \c__unravel_point_tl }
+ \tl_if_eq:NNTF \l__unravel_head_tl \c__unravel_point_tl
+ {
+ \__unravel_prev_input:n { . }
+ \__unravel_scan_decimal_loop:
+ }
+ {
+ \tl_if_in:nVTF { 0123456789 } \l__unravel_head_tl
+ {
+ \__unravel_back_input:
+ \__unravel_scan_int:
+ \tl_if_eq:NNT \l__unravel_head_tl \c__unravel_comma_tl
+ { \tl_set_eq:NN \l__unravel_head_tl \c__unravel_point_tl }
+ \tl_if_eq:NNT \l__unravel_head_tl \c__unravel_point_tl
+ {
+ \__unravel_input_gpop:N \l__unravel_tmpb_gtl
+ \__unravel_prev_input:n { . }
+ \__unravel_scan_decimal_loop:
+ }
+ }
+ {
+ \__unravel_back_input:
+ \__unravel_scan_int:
+ }
+ }
+ \__unravel_scan_dim_unit:NN #1#2
+ }
+\cs_new_protected:Npn \__unravel_scan_dim_unit:NN #1#2
+ {
+ \bool_if:NT #2
+ {
+ \__unravel_scan_keyword:nT { fF iI lL }
+ {
+ \__unravel_scan_inf_unit_loop:
+ \__unravel_break:w
+ }
+ }
+ \__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: }
+ {
+ \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
+ }
+ }
+ \bool_if:NT #1
+ {
+ \__unravel_scan_keyword:nT { mM uU } { \__unravel_break:w }
+ \msg_error:nn { unravel } { missing-mudim }
+ \__unravel_break:w
+ }
+ \__unravel_scan_keyword:nT { eE mM } { \__unravel_break:w }
+ \__unravel_scan_keyword:nT { eE xX } { \__unravel_break:w }
+ \__unravel_scan_keyword:nT { pP xX } { \__unravel_break:w }
+ \__unravel_scan_keyword:n { tT rR uU eE }
+ \__unravel_scan_keyword:nT { pP tT } { \__unravel_break:w }
+ \__unravel_scan_keyword:nT { iI nN } { \__unravel_break:w }
+ \__unravel_scan_keyword:nT { pP cC } { \__unravel_break:w }
+ \__unravel_scan_keyword:nT { cC mM } { \__unravel_break:w }
+ \__unravel_scan_keyword:nT { mM mM } { \__unravel_break:w }
+ \__unravel_scan_keyword:nT { bB pP } { \__unravel_break:w }
+ \__unravel_scan_keyword:nT { dD dD } { \__unravel_break:w }
+ \__unravel_scan_keyword:nT { cC cC } { \__unravel_break:w }
+ \__unravel_scan_keyword:nT { nN dD } { \__unravel_break:w }
+ \__unravel_scan_keyword:nT { nN cC } { \__unravel_break:w }
+ \__unravel_scan_keyword:nT { sS pP } { \__unravel_break:w }
+ \__unravel_break_point:
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_inf_unit_loop:
+ { \__unravel_scan_keyword:nT { lL } { \__unravel_scan_inf_unit_loop: } }
+\cs_new_protected_nopar:Npn \__unravel_scan_decimal_loop:
+ {
+ \__unravel_get_x_next:
+ \tl_if_empty:NTF \l__unravel_head_tl
+ { \use_ii:nn }
+ { \tl_if_in:nVTF { 0123456789 } \l__unravel_head_tl }
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_decimal_loop:
+ }
+ {
+ \token_if_eq_catcode:NNF \l__unravel_head_token \c_space_token
+ { \__unravel_back_input: }
+ \__unravel_prev_input_silent:n { ~ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_normal_glue:
+ { \__unravel_scan_glue:n { 2 } }
+\cs_new_protected_nopar:Npn \__unravel_scan_mu_glue:
+ { \__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
+ {
+ \__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 }
+ {
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int
+ > { \__unravel_tex_use:n { max_internal } }
+ {
+ \__unravel_back_input:
+ \__unravel_scan_dimen:NN #2 \c_false_bool
+ }
+ {
+ \__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
+ }
+ }
+ }
+ \__unravel_scan_keyword:nT { pP lL uU sS }
+ { \__unravel_scan_dimen:NN #2 \c_true_bool }
+ \__unravel_scan_keyword:nT { mM iI nN uU sS }
+ { \__unravel_scan_dimen:NN #2 \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
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_file_name:
+ {
+ \bool_gset_true:N \g__unravel_name_in_progress_bool
+ \__unravel_get_x_non_blank:
+ \__unravel_scan_file_name_loop:
+ \bool_gset_false:N \g__unravel_name_in_progress_bool
+ \__unravel_prev_input_silent:n { ~ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_file_name_loop:
+ {
+ \__unravel_gtl_if_head_is_definable:NTF \l__unravel_head_gtl
+ { \__unravel_back_input: }
+ {
+ \tl_set:Nx \l__unravel_tmpa_tl
+ { \__unravel_token_to_char:N \l__unravel_head_token }
+ \tl_if_eq:NNF \l__unravel_tmpa_tl \c_space_tl
+ {
+ \__unravel_prev_input_silent:V \l__unravel_tmpa_tl
+ \__unravel_get_x_next:
+ \__unravel_scan_file_name_loop:
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_r_token:
+ {
+ \bool_do_while:nn
+ { \tl_if_eq_p:NN \l__unravel_head_tl \c_space_tl }
+ { \__unravel_get_next: }
+ \__unravel_gtl_if_head_is_definable:NF \l__unravel_head_gtl
+ {
+ \msg_error:nn { unravel } { missing-cs }
+ \__unravel_back_input:
+ \tl_set:Nn \l__unravel_head_tl { \__unravel_inaccessible:w }
+ }
+ \__unravel_prev_input_silent:V \l__unravel_head_tl
+ \tl_set_eq:NN \l__unravel_defined_tl \l__unravel_head_tl
+ }
+\cs_new_protected:Npn \__unravel_scan_toks_to_str:
+ {
+ \seq_gput_right:Nn \g__unravel_prev_input_seq { }
+ \__unravel_scan_toks:NN \c_false_bool \c_true_bool
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \__unravel_prev_input_silent:x
+ { { \exp_after:wN \tl_to_str:n \l__unravel_tmpa_tl } }
+ }
+\cs_new_protected:Npn \__unravel_scan_toks:NN #1#2
+ {
+ \bool_if:NT #1 { \__unravel_scan_param: }
+ \__unravel_scan_left_brace:
+ \bool_if:NTF #2
+ { \__unravel_scan_group_x:N #1 }
+ { \__unravel_scan_group_n:N #1 }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_param:
+ {
+ \tl_clear:N \l__unravel_tmpa_tl
+ \__unravel_scan_param_aux:
+ \tl_put_right:NV \l__unravel_defining_tl \l__unravel_tmpa_tl
+ \__unravel_prev_input_silent:V \l__unravel_tmpa_tl
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_param_aux:
+ {
+ \__unravel_get_next:
+ \tl_concat:NNN \l__unravel_tmpa_tl
+ \l__unravel_tmpa_tl \l__unravel_head_tl
+ \tl_if_empty:NTF \l__unravel_head_tl
+ { \__unravel_back_input: } { \__unravel_scan_param_aux: }
+ }
+\cs_new_protected:Npn \__unravel_scan_group_n:N #1
+ {
+ \__unravel_back_input:
+ \__unravel_input_gpop_item:NF \l__unravel_head_tl
+ {
+ \msg_error:nn { unravel } { runaway-text }
+ \__unravel_exit:w
+ }
+ \tl_set:Nx \l__unravel_head_tl { { \exp_not:V \l__unravel_head_tl } }
+ \bool_if:NT #1
+ { \tl_put_right:NV \l__unravel_defining_tl \l__unravel_head_tl }
+ \__unravel_prev_input_silent:V \l__unravel_head_tl
+ }
+\cs_new_protected:Npn \__unravel_scan_group_x:N #1
+ {
+ \__unravel_input_gpop_tl:N \l__unravel_head_tl
+ \__unravel_back_input:V \l__unravel_head_tl
+ \bool_if:NTF #1
+ {
+ \__unravel_prev_input_silent:V \c_left_brace_str
+ \tl_put_right:Nn \l__unravel_defining_tl { { \if_false: } \fi: }
+ \__unravel_scan_group_xdef:n { 1 }
+ }
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \c_empty_gtl
+ \__unravel_prev_input_gtl:N \l__unravel_head_gtl
+ \__unravel_scan_group_x:n { 1 }
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpb_gtl
+ \__unravel_prev_input_silent:x
+ { \gtl_left_tl:N \l__unravel_tmpb_gtl }
+ }
+ }
+\cs_new_protected:Npn \__unravel_scan_group_xdef:n #1
+ {
+ \__unravel_get_token_x:N \c_true_bool
+ \tl_if_empty:NTF \l__unravel_head_tl
+ {
+ \gtl_if_head_is_group_begin:NTF \l__unravel_head_gtl
+ {
+ \__unravel_prev_input_silent:V \c_left_brace_str
+ \tl_put_right:Nn \l__unravel_defining_tl { { \if_false: } \fi: }
+ \__unravel_scan_group_xdef:f { \int_eval:n { #1 + 1 } }
+ }
+ {
+ \__unravel_prev_input_silent:V \c_right_brace_str
+ \tl_put_right:Nn \l__unravel_defining_tl { \if_false: { \fi: } }
+ \int_compare:nNnF {#1} = \c_one
+ { \__unravel_scan_group_xdef:f { \int_eval:n { #1 - 1 } } }
+ }
+ }
+ {
+ \__unravel_prev_input_silent:V \l__unravel_head_tl
+ \tl_put_right:Nx \l__unravel_defining_tl
+ { \exp_not:N \exp_not:N \exp_not:V \l__unravel_head_tl }
+ \__unravel_scan_group_xdef:n {#1}
+ }
+ }
+\cs_generate_variant:Nn \__unravel_scan_group_xdef:n { f }
+\cs_new_protected:Npn \__unravel_scan_group_x:n #1
+ {
+ \__unravel_get_token_x:N \c_false_bool
+ \__unravel_prev_input_gtl:N \l__unravel_head_gtl
+ \tl_if_empty:NTF \l__unravel_head_tl
+ {
+ \gtl_if_head_is_group_begin:NTF \l__unravel_head_gtl
+ { \__unravel_scan_group_x:f { \int_eval:n { #1 + 1 } } }
+ {
+ \int_compare:nNnF {#1} = \c_one
+ { \__unravel_scan_group_x:f { \int_eval:n { #1 - 1 } } }
+ }
+ }
+ { \__unravel_scan_group_x:n {#1} }
+ }
+\cs_generate_variant:Nn \__unravel_scan_group_x:n { f }
+\cs_new_protected:Npn \__unravel_get_token_x:N #1
+ {
+ \__unravel_get_next:
+ \__unravel_token_if_protected:NF \l__unravel_head_token
+ {
+ \__unravel_set_cmd:
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int = { \__unravel_tex_use:n { the } }
+ {
+ \__unravel_get_the:
+ \bool_if:NTF #1
+ {
+ \tl_put_right:NV \l__unravel_defining_tl \l__unravel_head_tl
+ \__unravel_prev_input:V \l__unravel_head_tl
+ }
+ {
+ \gtl_set:Nx \l__unravel_tmpb_gtl { \l__unravel_head_tl }
+ \__unravel_prev_input_gtl:N \l__unravel_tmpb_gtl
+ \__unravel_print_action:
+ }
+ }
+ { \__unravel_expand: }
+ \__unravel_get_token_x:N #1
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_alt_rule:
+ {
+ \__unravel_scan_keyword:nTF { wWiIdDtThH }
+ {
+ \__unravel_scan_normal_dimen:
+ \__unravel_scan_alt_rule:
+ }
+ {
+ \__unravel_scan_keyword:nTF { hHeEiIgGhHtT }
+ {
+ \__unravel_scan_normal_dimen:
+ \__unravel_scan_alt_rule:
+ }
+ {
+ \__unravel_scan_keyword:nT { dDeEpPtThH }
+ {
+ \__unravel_scan_normal_dimen:
+ \__unravel_scan_alt_rule:
+ }
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_spec:
+ {
+ \__unravel_scan_keyword:nTF { tT oO } { \__unravel_scan_normal_dimen: }
+ {
+ \__unravel_scan_keyword:nT { sS pP rR eE aA dD }
+ { \__unravel_scan_normal_dimen: }
+ }
+ \__unravel_scan_left_brace:
+ }
+\cs_new_protected:Npn \__unravel_do_box:N #1
+ {
+ \__unravel_get_x_non_relax:
+ \__unravel_set_cmd:
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int = { \__unravel_tex_use:n { make_box } }
+ { \__unravel_do_begin_box:N #1 }
+ {
+ \bool_if:NTF #1
+ {
+ \__unravel_cs_case:NnF \l__unravel_head_token
+ {
+ \tex_hrule:D { \__unravel_do_leaders_rule: }
+ \tex_vrule:D { \__unravel_do_leaders_rule: }
+ }
+ { \__unravel_do_box_error: }
+ }
+ { \__unravel_do_box_error: }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_do_box_error:
+ {
+ \__unravel_back_input:
+ \msg_error:nn { unravel } { missing-box }
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl }
+ }
+\cs_new_protected:Npn \__unravel_do_begin_box:N #1
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \int_case:nnTF \l__unravel_head_char_int
+ {
+ { 0 } { \__unravel_scan_int: } % box
+ { 1 } { \__unravel_scan_int: } % copy
+ { 2 } { } % lastbox
+ { 3 } % vsplit
+ {
+ \__unravel_scan_int:
+ \__unravel_scan_keyword:nF { tT oO }
+ {
+ \msg_error:nn { unravel } { missing-to }
+ \__unravel_prev_input:n { to }
+ }
+ \__unravel_scan_normal_dimen:
+ }
+ }
+ { \__unravel_do_simple_box:N #1 }
+ { \__unravel_do_box_explicit:N #1 }
+ }
+\cs_new_protected:Npn \__unravel_do_simple_box:N #1
+ {
+ \bool_if:NTF #1 { \__unravel_do_leaders_fetch_skip: }
+ {
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \tl_use:N \l__unravel_head_tl \scan_stop:
+ \gtl_put_right:NV \g__unravel_output_gtl \l__unravel_head_tl
+ \__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_do_leaders_fetch_skip:
+ {
+ \__unravel_get_x_non_relax:
+ \__unravel_set_cmd:
+ \int_compare:nNnTF \l__unravel_head_cmd_int
+ = { \__unravel_tex_use:n { \mode_if_vertical:TF { vskip } { hskip } } }
+ {
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \tl_put_left:NV \l__unravel_head_tl \l__unravel_tmpa_tl
+ \__unravel_do_append_glue:
+ }
+ {
+ \__unravel_back_input:
+ \msg_error:nn { unravel } { improper-leaders }
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl }
+ }
+ }
+\cs_new_protected:Npn \__unravel_do_box_explicit:N #1
+ {
+ \token_if_eq_meaning:NNTF \l__unravel_head_token \tex_hbox:D
+ { \__unravel_box_hook:N \tex_everyhbox:D }
+ { \__unravel_box_hook:N \tex_everyvbox:D }
+ % ^^A todo: TeX calls |normal_paragraph| here.
+ \__unravel_scan_spec:
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_set_action_text:x
+ { \tl_to_str:N \l__unravel_head_tl \iow_char:N \{ }
+ \seq_push:Nx \l__unravel_leaders_box_seq
+ { \bool_if:NTF #1 { \mode_if_vertical:TF { v } { h } } { Z } }
+ \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_box_hook_end:
+ }
+\cs_new_protected:Npn \__unravel_box_hook:N #1
+ {
+ \tl_set:NV \l__unravel_tmpa_tl #1
+ \str_if_eq_x:nnF
+ { \tl_head:N \l__unravel_tmpa_tl } { \exp_not:N \__unravel_box_hook:w }
+ {
+ \exp_args:Nx #1
+ {
+ \exp_not:n { \__unravel_box_hook:w \prg_do_nothing: }
+ \exp_not:V #1
+ }
+ }
+ \cs_gset_protected:Npn \__unravel_box_hook:w ##1 \__unravel_box_hook_end:
+ {
+ \exp_args:No #1 {##1}
+ \cs_gset_eq:NN \__unravel_box_hook:w \prg_do_nothing:
+ \__unravel_print_action:
+ \__unravel_back_input:o {##1}
+ \__unravel_set_action_text:x
+ { \token_to_meaning:N #1 \tl_to_str:o {##1} }
+ \tl_if_empty:oF {##1} { \__unravel_print_action: }
+ }
+ }
+\cs_new_eq:NN \__unravel_box_hook:w \prg_do_nothing:
+\cs_new_eq:NN \__unravel_box_hook_end: \prg_do_nothing:
+\cs_new_protected_nopar:Npn \__unravel_do_leaders_rule:
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_alt_rule:
+ \__unravel_do_leaders_fetch_skip:
+ }
+\prg_new_protected_conditional:Npnn \__unravel_charcode_if_safe:n #1 { TF }
+ {
+ \bool_if:nTF
+ {
+ \int_compare_p:n { #1 = `! }
+ || \int_compare_p:n { `' <= #1 <= `[ }
+ || \int_compare_p:n { #1 = `] }
+ || \int_compare_p:n { ` ` <= #1 <= `z }
+ }
+ { \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_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_generate_variant:Nn \__unravel_char_in_mmode:n { V , x }
+\cs_new_protected:Npn \__unravel_mathchar:n #1
+ {
+ \tex_mathchar:D #1 \scan_stop:
+ \tl_set:Nx \l__unravel_tmpa_tl
+ { \exp_not:N \mathchar \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_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 { }
+ \bool_if:NTF #1 { \tex_indent:D } { \tex_noindent:D }
+ \exp_args:NV \tex_everypar:D \l__unravel_tmpa_tl
+ \__unravel_back_input:V \l__unravel_tmpa_tl
+ \__unravel_print_action:x
+ {
+ \g__unravel_action_text_str \c_space_tl : ~
+ \token_to_str:N \everypar = { \tl_to_str:N \l__unravel_tmpa_tl }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_end_graf:
+ { \mode_if_horizontal:T { \__unravel_normal_paragraph: } }
+\cs_new_protected_nopar:Npn \__unravel_normal_paragraph:
+ {
+ \tex_par:D
+ \gtl_gput_right:Nn \g__unravel_output_gtl { \par }
+ \__unravel_print_action:x { Paragraph~end. }
+ }
+\cs_new_protected_nopar:Npn \__unravel_build_page:
+ {
+ }
+\cs_new_protected_nopar:Npn \__unravel_handle_left_brace:
+ {
+ \int_case:nnF \etex_currentgrouptype:D
+ {
+ { 1 } { \__unravel_end_simple_group: } % simple
+ { 2 } { \__unravel_end_box_group: } % hbox
+ { 3 } { \__unravel_end_box_group: } % adjusted_hbox
+ { 4 } { \__unravel_end_graf: \__unravel_end_box_group: } % vbox
+ { 5 } { \__unravel_end_graf: \__unravel_end_box_group: } % vtop
+ { 6 } { \__unravel_end_align_group: } % align
+ { 7 } { \__unravel_end_no_align_group: } % no_align
+ { 8 } { \__unravel_end_output_group: } % output
+ { 9 } { \__unravel_end_math_group: } % math
+ { 10 } { \__unravel_end_disc_group: } % disc
+ { 11 } { \__unravel_end_graf: \__unravel_end_simple_group: } % insert
+ { 12 } { \__unravel_end_graf: \__unravel_end_simple_group: } % vcenter
+ { 13 } { \__unravel_end_math_choice_group: } % math_choice
+ }
+ { % bottom_level, semi_simple, math_shift, math_left
+ \__unravel_back_input:
+ \l__unravel_head_token
+ \__unravel_print_action:
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_end_simple_group:
+ {
+ \l__unravel_head_token
+ \gtl_gconcat:NNN \g__unravel_output_gtl
+ \g__unravel_output_gtl \c_group_end_gtl
+ \__unravel_print_action:
+ }
+\cs_new_protected_nopar:Npn \__unravel_end_box_group:
+ {
+ \seq_pop:NN \l__unravel_leaders_box_seq \l__unravel_tmpa_tl
+ \str_if_eq_x:nnTF \l__unravel_tmpa_tl { Z }
+ { \__unravel_end_simple_group: }
+ {
+ \__unravel_get_x_non_relax:
+ \__unravel_set_cmd:
+ \int_compare:nNnTF \l__unravel_head_cmd_int
+ = { \__unravel_tex_use:n { \l__unravel_tmpa_tl skip } }
+ {
+ \tl_put_left:Nn \l__unravel_head_tl { \c_group_end_token }
+ \__unravel_do_append_glue:
+ }
+ {
+ \__unravel_back_input:
+ \c_group_end_token \group_begin: \group_end:
+ \__unravel_print_action:
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_off_save:
+ {
+ \int_compare:nNnTF \etex_currentgrouptype:D = { 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
+ {
+ { 14 } % semi_simple_group
+ { \gtl_set:Nn \l__unravel_head_gtl { \group_end: } }
+ { 15 } % math_shift_group
+ { \gtl_set:Nn \l__unravel_head_gtl { $ } } % $
+ { 16 } % math_left_group
+ { \gtl_set:Nn \l__unravel_head_gtl { \tex_right:D . } }
+ }
+ { \gtl_set_eq:NN \l__unravel_head_gtl \c_group_end_gtl }
+ \__unravel_back_input:
+ \msg_error:nnx { unravel } { off-save }
+ { \gtl_to_str:N \l__unravel_head_gtl }
+ }
+ }
+\cs_new_protected:Npn \__unravel_mode_math:n #1
+ { \mode_if_math:TF {#1} { \__unravel_insert_dollar_error: } }
+\cs_new_protected:Npn \__unravel_mode_non_math:n #1
+ { \mode_if_math:TF { \__unravel_insert_dollar_error: } {#1} }
+\cs_new_protected:Npn \__unravel_mode_vertical:n #1
+ {
+ \mode_if_math:TF
+ { \__unravel_insert_dollar_error: }
+ { \mode_if_horizontal:TF { \__unravel_head_for_vmode: } {#1} }
+ }
+\cs_new_protected:Npn \__unravel_mode_non_vertical:n #1
+ {
+ \mode_if_vertical:TF
+ { \__unravel_back_input: \__unravel_new_graf:N \c_true_bool }
+ {#1}
+ }
+\cs_new_protected_nopar:Npn \__unravel_head_for_vmode:
+ {
+ \mode_if_inner:TF
+ {
+ \token_if_eq_meaning:NNTF \l__unravel_head_token \tex_hrule:D
+ {
+ \msg_error:nn { unravel } { hrule-bad-mode }
+ \__unravel_print_action:
+ }
+ { \__unravel_off_save: }
+ }
+ {
+ \__unravel_back_input:
+ \gtl_set:Nn \l__unravel_head_gtl { \par }
+ \__unravel_back_input:
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_do_step:
+ {
+ \__unravel_set_action_text:
+ \bool_if:NT \l__unravel_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 : }
+ { \msg_error:nnx { unravel } { internal } { unknown-command } }
+ }
+\__unravel_new_tex_cmd:nn { relax } % 0
+ { \__unravel_print_action: }
+\__unravel_new_tex_cmd:nn { begin-group_char } % 1
+ {
+ \gtl_gconcat:NNN \g__unravel_output_gtl
+ \g__unravel_output_gtl \c_group_begin_gtl
+ \__unravel_print_action:
+ \l__unravel_head_token
+ }
+\__unravel_new_tex_cmd:nn { end-group_char } % 2
+ { \__unravel_handle_left_brace: }
+\__unravel_new_tex_cmd:nn { math_char } % 3
+ {
+ \__unravel_mode_non_vertical:n
+ {
+ \mode_if_math:TF
+ {
+ \int_compare:nNnTF
+ \etex_currentgrouplevel:D = { 15 } % math_shift_group
+ { \__unravel_after_math: }
+ { \__unravel_off_save: }
+ }
+ {
+ \__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: }
+ }
+ { \__unravel_back_input: \__unravel_goto_inner_math: }
+ }
+ }
+ }
+\__unravel_new_tex_cmd:nn { alignment_char } % 4
+ { \l__unravel_head_token \__unravel_print_action: }
+\__unravel_new_tex_cmd:nn { car_ret } % 5
+ { \l__unravel_head_token \__unravel_print_action: }
+\__unravel_new_tex_cmd:nn { macro_char } % 6
+ { \l__unravel_head_token \__unravel_print_action: }
+\__unravel_new_tex_cmd:nn { superscript_char } % 7
+ { \__unravel_mode_math:n { \__unravel_sub_sup: } }
+\__unravel_new_tex_cmd:nn { subscript_char } % 8
+ { \__unravel_mode_math:n { \__unravel_sub_sup: } }
+\cs_new_protected_nopar:Npn \__unravel_sub_sup:
+ {
+ \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_print_action:x { \tl_to_str:N \l__unravel_head_tl }
+ }
+\__unravel_new_tex_cmd:nn { endv } % 9
+ { \msg_error:nn { unravel } { not-implemented } { alignments } }
+\__unravel_new_tex_cmd:nn { blank_char } % 10
+ {
+ \mode_if_horizontal:T
+ {
+ \gtl_gput_right:Nn \g__unravel_output_gtl { ~ }
+ \l__unravel_head_token
+ }
+ \__unravel_print_action:
+ }
+\__unravel_new_tex_cmd:nn { the_char } % 11
+ {
+ \__unravel_mode_non_vertical:n
+ {
+ \tl_set:Nx \l__unravel_tmpa_tl
+ { ` \__unravel_token_to_char:N \l__unravel_head_token }
+ \mode_if_math:TF
+ { \__unravel_char_in_mmode:V \l__unravel_tmpa_tl }
+ { \__unravel_char:V \l__unravel_tmpa_tl }
+ }
+ }
+\__unravel_new_eq_tex_cmd:nn { other_char } { the_char } % 12
+\__unravel_new_tex_cmd:nn { par_end } % 13
+ {
+ \__unravel_mode_non_math:n
+ {
+ \mode_if_vertical:TF
+ { \__unravel_normal_paragraph: }
+ {
+ % if align_state<0 then off_save;
+ \__unravel_end_graf:
+ \mode_if_vertical:T
+ { \mode_if_inner:F { \__unravel_build_page: } }
+ }
+ }
+ }
+\__unravel_new_tex_cmd:nn { stop } % 14
+ {
+ \__unravel_mode_vertical:n
+ {
+ \mode_if_inner:TF
+ { \__unravel_forbidden_case: }
+ {
+ % ^^A todo: unless its_all_over
+ \int_gdecr:N \g__unravel_ends_int
+ \int_compare:nNnTF \g__unravel_ends_int > \c_zero
+ {
+ \__unravel_back_input:
+ \__unravel_back_input:n
+ {
+ \tex_hbox:D to \tex_hsize:D { }
+ \tex_vfill:D
+ \tex_penalty:D - '10000000000 ~
+ }
+ \__unravel_build_page:
+ \__unravel_print_action:x { End~everything! }
+ }
+ {
+ \__unravel_print_outcome:
+ \l__unravel_head_token
+ }
+ }
+ }
+ }
+\__unravel_new_tex_cmd:nn { delim_num } % 15
+ {
+ \__unravel_mode_math:n
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_int:
+ \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 }
+ }
+ }
+\__unravel_new_tex_cmd:nn { char_num } % 16
+ {
+ \__unravel_mode_non_vertical:n
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_int:
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \mode_if_math:TF
+ { \__unravel_char_in_mmode:x { \tl_tail:N \l__unravel_head_tl } }
+ { \__unravel_char:x { \tl_tail:N \l__unravel_head_tl } }
+ }
+ }
+\__unravel_new_tex_cmd:nn { math_char_num } % 17
+ {
+ \__unravel_mode_math:n
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_int:
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_mathchar:x { \tl_tail:N \l__unravel_head_tl }
+ }
+ }
+\__unravel_new_tex_cmd:nn { mark } % 18
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \int_compare:nNnF \l__unravel_head_char_int = \c_zero
+ { \__unravel_scan_int: }
+ \seq_gput_right:Nn \g__unravel_prev_input_seq { }
+ \__unravel_scan_toks:NN \c_false_bool \c_true_bool
+ \seq_gpop_right:Nn \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:x
+ { \tl_to_str:N \l__unravel_head_tl \tl_to_str:N \l__unravel_tmpa_tl }
+ \tl_put_right:Nx \l__unravel_head_tl
+ { { \exp_not:N \exp_not:n \exp_not:V \l__unravel_tmpa_tl } }
+ \tl_use:N \l__unravel_head_tl
+ }
+\__unravel_new_tex_cmd:nn { xray } % 19
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \int_case:nnF \l__unravel_head_char_int
+ {
+ { 0 }
+ { % show
+ \__unravel_get_next:
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \gtl_head_do:NN \l__unravel_head_gtl \l__unravel_tmpa_tl
+ }
+ { 2 }
+ { % showthe
+ \__unravel_get_x_next:
+ \__unravel_scan_something_internal:n { 5 }
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \exp_args:Nx \etex_showtokens:D
+ { \tl_tail:N \l__unravel_head_tl }
+ }
+ }
+ { % no operand for showlists, showgroups, showifs
+ \int_compare:nNnT \l__unravel_head_char_int = \c_one % showbox
+ { \__unravel_scan_int: }
+ \int_compare:nNnT \l__unravel_head_char_int = \c_five % showtokens
+ { \__unravel_scan_toks:NN \c_false_bool \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_new_tex_cmd:nn { make_box } % 20
+ {
+ \seq_gput_right:Nn \g__unravel_prev_input_seq { }
+ \__unravel_back_input:
+ \__unravel_do_box:N \c_false_bool
+ }
+\cs_new_protected_nopar:Npn \__unravel_do_move:
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_normal_dimen:
+ \__unravel_do_box:N \c_false_bool
+ }
+\__unravel_new_tex_cmd:nn { hmove } % 21
+ {
+ \mode_if_vertical:TF
+ { \__unravel_do_move: } { \__unravel_forbidden_case: }
+ }
+\__unravel_new_tex_cmd:nn { vmove } % 22
+ {
+ \mode_if_vertical:TF
+ { \__unravel_forbidden_case: } { \__unravel_do_move: }
+ }
+\cs_new_protected_nopar:Npn \__unravel_do_unpackage:
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_int:
+ \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 }
+ }
+\__unravel_new_tex_cmd:nn { un_hbox } % 23
+ { \__unravel_mode_non_vertical:n { \__unravel_do_unpackage: } }
+\__unravel_new_tex_cmd:nn { un_vbox } % 24
+ {
+ \__unravel_mode_vertical:n
+ {
+ \int_compare:nNnTF \l__unravel_head_char_int > { 1 }
+ { \l__unravel_head_token \__unravel_print_action: }
+ { \__unravel_do_unpackage: }
+ }
+ }
+\__unravel_new_tex_cmd:nn { remove_item } % 25
+ { \l__unravel_head_token \__unravel_print_action: }
+\cs_new_protected_nopar:Npn \__unravel_do_append_glue:
+ {
+ \int_compare:nNnTF \l__unravel_head_char_int < { 4 }
+ { \tl_use:N \l__unravel_head_tl \__unravel_print_action: }
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \exp_args:Nf \__unravel_scan_glue:n
+ { \int_eval:n { \l__unravel_head_char_int - 2 } }
+ \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 }
+ }
+ }
+\__unravel_new_tex_cmd:nn { hskip } % 26
+ { \__unravel_mode_non_vertical:n { \__unravel_do_append_glue: } }
+\__unravel_new_tex_cmd:nn { vskip } % 27
+ { \__unravel_mode_vertical:n { \__unravel_do_append_glue: } }
+\__unravel_new_tex_cmd:nn { mskip } % 28
+ { \__unravel_mode_math:n { \__unravel_do_append_glue: } }
+\cs_new_protected_nopar:Npn \__unravel_do_append_kern:
+ {
+ \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 }
+ \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 }
+ }
+\__unravel_new_tex_cmd:nn { kern } % 29
+ { \__unravel_do_append_kern: }
+\__unravel_new_tex_cmd:nn { mkern } % 30
+ { \__unravel_mode_math:n { \__unravel_do_append_kern: } }
+\__unravel_new_tex_cmd:nn { leader_ship } % 31
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_do_box:N \c_true_bool
+ }
+\__unravel_new_tex_cmd:nn { halign } % 32
+ { \msg_fatal:nnx { unravel } { not-implemented } { halign } }
+\__unravel_new_tex_cmd:nn { valign } % 33
+ { \msg_fatal:nnx { unravel } { not-implemented } { valign } }
+\__unravel_new_tex_cmd:nn { no_align } % 34
+ { \msg_fatal:nnx { unravel } { not-implemented } { noalign } }
+\__unravel_new_tex_cmd:nn { vrule } % 35
+ { \__unravel_mode_non_vertical:n { \__unravel_do_rule: } }
+\__unravel_new_tex_cmd:nn { hrule } % 36
+ { \__unravel_mode_vertical:n { \__unravel_do_rule: } }
+\cs_new_protected_nopar:Npn \__unravel_do_rule:
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_alt_rule:
+ \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 }
+ }
+\__unravel_new_tex_cmd:nn { insert } % 37
+ { \__unravel_begin_insert_or_adjust: }
+\__unravel_new_tex_cmd:nn { vadjust } % 38
+ {
+ \mode_if_vertical:TF
+ { \__unravel_forbidden_case: } { \__unravel_begin_insert_or_adjust: }
+ }
+\__unravel_new_tex_cmd:nn { ignore_spaces } % 39
+ {
+ \token_if_eq_meaning:NNTF \l__unravel_head_token \tex_ignorespaces:D
+ {
+ \__unravel_get_x_non_blank:
+ \__unravel_set_cmd:
+ \__unravel_do_step:
+ }
+ { \msg_error:nn { unravel } { not-implemented } { pdfprimitive } }
+ }
+\__unravel_new_tex_cmd:nn { after_assignment } % 40
+ {
+ \tl_set_eq:NN \l__unravel_tmpa_tl \l__unravel_head_tl
+ \__unravel_get_next:
+ \gtl_gset_eq:NN \g__unravel_after_assignment_gtl \l__unravel_head_gtl
+ \__unravel_print_action:x
+ {
+ Afterassignment:~\tl_to_str:N \l__unravel_tmpa_tl
+ \gtl_to_str:N \l__unravel_head_gtl
+ }
+ }
+\__unravel_new_tex_cmd:nn { after_group } % 41
+ { \msg_error:nnx { unravel } { not-implemented } { aftergroup } }
+\__unravel_new_tex_cmd:nn { break_penalty } % 42
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_int:
+ \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 }
+ }
+\__unravel_new_tex_cmd:nn { start_par } % 43
+ {
+ \mode_if_vertical:TF
+ {
+ \token_if_eq_meaning:NNTF \l__unravel_head_token \tex_noindent:D
+ { \__unravel_new_graf:N \c_false_bool }
+ { \__unravel_new_graf:N \c_true_bool }
+ }
+ {
+ \int_compare:nNnT \l__unravel_head_char_int = { 1 } % indent
+ {
+ \tex_hbox:D width \tex_parindent:D { }
+ \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl
+ }
+ \__unravel_print_action:
+ }
+ }
+\__unravel_new_tex_cmd:nn { ital_corr } % 44
+ {
+ \mode_if_vertical:TF { \__unravel_forbidden_case: }
+ { \l__unravel_head_token \__unravel_print_action: }
+ }
+\cs_new_protected_nopar:Npn \__unravel_do_accent:
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_int:
+ \__unravel_do_assignments:
+ \bool_if:nTF
+ {
+ \token_if_eq_catcode_p:NN
+ \l__unravel_head_token \c_catcode_letter_token
+ ||
+ \token_if_eq_catcode_p:NN
+ \l__unravel_head_token \c_catcode_other_token
+ ||
+ \int_compare_p:nNn
+ \l__unravel_head_cmd_int = { \__unravel_tex_use:n { char_given } }
+ }
+ { \__unravel_prev_input:V \l__unravel_head_tl }
+ {
+ \token_if_eq_meaning:NNTF \l__unravel_head_token \tex_char:D
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_int:
+ }
+ { \__unravel_break:w }
+ }
+ \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_print_action:x { \tl_to_str:N \l__unravel_head_tl }
+ \__unravel_break_point:
+ }
+\cs_new_protected_nopar:Npn \__unravel_do_math_accent:
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_int:
+ \__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_print_action:x { \tl_to_str:N \l__unravel_head_tl }
+ }
+\__unravel_new_tex_cmd:nn { accent } % 45
+ {
+ \__unravel_mode_non_vertical:n
+ {
+ \mode_if_math:TF
+ { \__unravel_do_math_accent: } { \__unravel_do_accent: }
+ }
+ }
+\__unravel_new_tex_cmd:nn { math_accent } % 46
+ { \__unravel_mode_math:n { \__unravel_do_math_accent: } }
+\__unravel_new_tex_cmd:nn { discretionary } % 47
+ { \msg_error:nnx { unravel } { not-implemented } { discretionary } }
+\__unravel_new_tex_cmd:nn { eq_no } % 48
+ { \msg_error:nnx { unravel } { not-implemented } { eqno } }
+\__unravel_new_tex_cmd:nn { left_right } % 49
+ { \msg_error:nnx { unravel } { not-implemented } { left/right } }
+\__unravel_new_tex_cmd:nn { math_comp } % 50
+ { \msg_error:nnx { unravel } { not-implemented } { math~comp } }
+\__unravel_new_tex_cmd:nn { limit_switch } % 51
+ { \msg_error:nnx { unravel } { not-implemented } { limits } }
+\__unravel_new_tex_cmd:nn { above } % 52
+ { \msg_error:nnx { unravel } { not-implemented } { above } }
+\__unravel_new_tex_cmd:nn { math_style } % 53
+ { \msg_error:nnx { unravel } { not-implemented } { math~style } }
+\__unravel_new_tex_cmd:nn { math_choice } % 54
+ { \msg_error:nnx { unravel } { not-implemented } { math~choice } }
+\__unravel_new_tex_cmd:nn { non_script } % 55
+ { \msg_error:nnx { unravel } { not-implemented } { non~script } }
+\__unravel_new_tex_cmd:nn { vcenter } % 56
+ { \msg_error:nnx { unravel } { not-implemented } { vcenter } }
+\__unravel_new_tex_cmd:nn { case_shift } % 57
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_scan_toks:NN \c_false_bool \c_false_bool
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \exp_after:wN \__unravel_case_shift:Nn \l__unravel_tmpa_tl
+ }
+\cs_new_protected:Npn \__unravel_case_shift:Nn #1#2
+ {
+ #1 { \__unravel_back_input:n {#2} }
+ \__unravel_print_action:x
+ { \token_to_meaning:N #1 ~ \tl_to_str:n { {#2} } }
+ }
+\__unravel_new_tex_cmd:nn { message } % 58
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_toks_to_str:
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \tl_use:N \l__unravel_head_tl
+ \__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl }
+ }
+\__unravel_new_tex_cmd:nn { extension } % 59
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_extension_operands:
+ \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 }
+ }
+\__unravel_new_tex_cmd:nn { in_stream } % 60
+ {
+ \seq_put_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \token_if_eq_meaning:NNTF \l__unravel_head_token \tex_openin:D
+ {
+ \__unravel_scan_int:
+ \__unravel_scan_optional_equals:
+ \__unravel_scan_file_name:
+ }
+ { \__unravel_scan_int: }
+ \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 }
+ }
+\__unravel_new_tex_cmd:nn { begin_group } % 61
+ {
+ \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl
+ \__unravel_print_action:
+ \l__unravel_head_token
+ }
+\__unravel_new_tex_cmd:nn { end_group } % 62
+ {
+ \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl
+ \__unravel_print_action:
+ \l__unravel_head_token
+ }
+\__unravel_new_tex_cmd:nn { omit } % 63
+ { \msg_error:nn { unravel } { not-implemented } { omit } }
+\__unravel_new_tex_cmd:nn { ex_space } % 64
+ {
+ \__unravel_mode_non_vertical:n
+ { \l__unravel_head_token \__unravel_print_action: }
+ }
+\__unravel_new_tex_cmd:nn { no_boundary } % 65
+ {
+ \__unravel_mode_non_vertical:n
+ { \l__unravel_head_token \__unravel_print_action: }
+ }
+\__unravel_new_tex_cmd:nn { radical } % 66
+ {
+ \__unravel_mode_math:n
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_int:
+ \__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_print_action:x { \tl_to_str:N \l__unravel_head_tl }
+ }
+ }
+\__unravel_new_tex_cmd:nn { end_cs_name } % 67
+ { \l__unravel_head_token \__unravel_print_action: }
+\__unravel_new_tex_cmd:nn { char_given } % 68
+ {
+ \__unravel_mode_non_vertical:n
+ {
+ \mode_if_math:TF
+ { \__unravel_char_in_mmode:V \l__unravel_head_char_int }
+ { \__unravel_char:V \l__unravel_head_char_int }
+ }
+ }
+\__unravel_new_tex_cmd:nn { math_given } % 69
+ {
+ \__unravel_mode_math:n
+ { \__unravel_mathchar:x { \int_use:N \l__unravel_head_char_int } }
+ }
+\__unravel_new_tex_cmd:nn { last_item } % 70
+ { \__unravel_forbidden_case: }
+\cs_new_protected_nopar:Npn \__unravel_scan_extension_operands:
+ {
+ \int_case:nnF \l__unravel_head_char_int
+ {
+ { 0 } % openout
+ {
+ \__unravel_scan_int:
+ \__unravel_scan_optional_equals:
+ \__unravel_scan_file_name:
+ }
+ { 1 } % write
+ {
+ \__unravel_scan_int:
+ \__unravel_scan_toks:NN \c_false_bool \c_false_bool
+ }
+ { 2 } % closeout
+ { \__unravel_scan_int: }
+ { 3 } % special
+ { \__unravel_scan_toks_to_str: }
+ { 4 } % immediate
+ { \__unravel_scan_immediate_operands: }
+ { 5 } % setlanguage
+ {
+ \mode_if_horizontal:TF
+ { \__unravel_scan_int: }
+ { \msg_error:nn { unravel } { invalid-mode } }
+ }
+ { 6 } % pdfliteral
+ {
+ \__unravel_scan_keyword:nF { dD iI rR eE cC tT }
+ { \__unravel_scan_keyword:n { pP aA gG eE } }
+ \__unravel_scan_pdf_ext_toks:
+ }
+ { 7 } % pdfobj
+ {
+ \__unravel_scan_keyword:nTF
+ { rR eE sS eE rR vV eE oO bB jJ nN uU mM }
+ { \__unravel_skip_optional_space: }
+ {
+ \__unravel_scan_keyword:nF { uU sS eE oO bB jJ nN uU mM }
+ { \__unravel_scan_int: }
+ \__unravel_scan_keyword:nT { sS tT rR eE aA mM }
+ {
+ \__unravel_scan_keyword:nT { aA tT tT rR }
+ { \__unravel_scan_pdf_ext_toks: }
+ }
+ \__unravel_scan_keyword:n { fF iI lL eE }
+ \__unravel_scan_pdf_ext_toks:
+ }
+ }
+ { 8 } % pdfrefobj
+ { \__unravel_scan_int: }
+ { 9 } % pdfxform
+ {
+ \__unravel_scan_keyword:nT { aA tT tT rR }
+ { \__unravel_scan_pdf_ext_toks: }
+ \__unravel_scan_keyword:nTF { rR eE sS oO uU rR cC eE sS }
+ { \__unravel_scan_pdf_ext_toks: }
+ \__unravel_scan_int:
+ }
+ { 10 } % pdfrefxform
+ { \__unravel_scan_int: }
+ { 11 } % pdfximage
+ { \__unravel_scan_image: }
+ { 12 } % pdfrefximage
+ { \__unravel_scan_int: }
+ { 13 } % pdfannot
+ {
+ \__unravel_scan_keyword:nTF
+ { rR eE sS eE rR vV eE oO bB jJ nN uU mM }
+ { \__unravel_scan_optional_space: }
+ {
+ \__unravel_scan_keyword:nT { uU sS eE oO bB jJ nN uU mM }
+ { \__unravel_scan_int: }
+ \__unravel_scan_alt_rule:
+ \__unravel_scan_pdf_ext_toks:
+ }
+ }
+ { 14 } % pdfstartlink
+ {
+ \mode_if_vertical:TF
+ { \msg_error:nn { unravel } { invalid-mode } }
+ {
+ \__unravel_scan_rule_attr:
+ \__unravel_scan_action:
+ }
+ }
+ { 15 } % pdfendlink
+ {
+ \mode_if_vertical:T
+ { \msg_error:nn { unravel } { invalid-mode } }
+ }
+ { 16 } % pdfoutline
+ {
+ \__unravel_scan_keyword:nT { aA tT tT rR }
+ { \__unravel_scan_pdf_ext_toks: }
+ \__unravel_scan_action:
+ \__unravel_scan_keyword:nT { cC oO uU nN tT }
+ { \__unravel_scan_int: }
+ \__unravel_scan_pdf_ext_toks:
+ }
+ { 17 } % pdfdest
+ { \__unravel_scan_pdfdest_operands: }
+ { 18 } % pdfthread
+ { \__unravel_scan_rule_attr: \__unravel_scan_thread_id: }
+ { 19 } % pdfstartthread
+ { \__unravel_scan_rule_attr: \__unravel_scan_thread_id: }
+ { 20 } % pdfendthread
+ { }
+ { 21 } % pdfsavepos
+ { }
+ { 22 } % pdfinfo
+ { \__unravel_scan_pdf_ext_toks: }
+ { 23 } % pdfcatalog
+ {
+ \__unravel_scan_pdf_ext_toks:
+ \__unravel_scan_keyword:n { oO pP eE nN aA cC tT iI oO nN }
+ { \__unravel_scan_action: }
+ }
+ { 24 } % pdfnames
+ { \__unravel_scan_pdf_ext_toks: }
+ { 25 } % pdffontattr
+ {
+ \__unravel_scan_font_ident:
+ \__unravel_scan_pdf_ext_toks:
+ }
+ { 26 } % pdfincludechars
+ {
+ \__unravel_scan_font_ident:
+ \__unravel_scan_pdf_ext_toks:
+ }
+ { 27 } % pdfmapfile
+ { \__unravel_scan_pdf_ext_toks: }
+ { 28 } % pdfmapline
+ { \__unravel_scan_pdf_ext_toks: }
+ { 29 } % pdftrailer
+ { \__unravel_scan_pdf_ext_toks: }
+ { 30 } % pdfresettimer
+ { }
+ { 31 } % pdffontexpand
+ {
+ \__unravel_scan_font_ident:
+ \__unravel_scan_optional_equals:
+ \__unravel_scan_int:
+ \__unravel_scan_int:
+ \__unravel_scan_int:
+ \__unravel_scan_keyword:nT { aAuUtToOeExXpPaAnNdD }
+ { \__unravel_skip_optional_space: }
+ }
+ { 32 } % pdfsetrandomseed
+ { \__unravel_scan_int: }
+ { 33 } % pdfsnaprefpoint
+ { }
+ { 34 } % pdfsnapy
+ { \__unravel_scan_normal_glue: }
+ { 35 } % pdfsnapycomp
+ { \__unravel_scan_int: }
+ { 36 } % pdfglyphtounicode
+ {
+ \__unravel_scan_pdf_ext_toks:
+ \__unravel_scan_pdf_ext_toks:
+ }
+ { 37 } % pdfcolorstack
+ { \__unravel_scan_pdfcolorstack_operands: }
+ { 38 } % pdfsetmatrix
+ { \__unravel_scan_pdf_ext_toks: }
+ { 39 } % pdfsave
+ { }
+ { 40 } % pdfrestore
+ { }
+ { 41 } % pdfnobuiltintounicode
+ { \__unravel_scan_font_ident: }
+ }
+ { } % no other cases.
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_pdfcolorstack_operands:
+ {
+ \__unravel_scan_int:
+ \__unravel_scan_keyword:nF { sSeEtT }
+ {
+ \__unravel_scan_keyword:nF { pPuUsShH }
+ {
+ \__unravel_scan_keyword:nF { pPoOpP }
+ {
+ \__unravel_scan_keyword:nF { cCuUrRrReEnNtT }
+ {
+ \msg_error:nn { unravel }
+ { color-stack-action-missing }
+ }
+ }
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_rule_attr:
+ {
+ \__unravel_scan_alt_rule:
+ \__unravel_scan_keyword:nT { aA tT tT rR }
+ { \__unravel_scan_pdf_ext_toks: }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_action:
+ {
+ \__unravel_scan_keyword:nTF { uUsSeErR }
+ { \__unravel_scan_pdf_ext_toks: }
+ {
+ \__unravel_scan_keyword:nF { gGoOtToO }
+ {
+ \__unravel_scan_keyword:nF { tThHrReEaAdD }
+ { \msg_error:nn { unravel } { action-type-missing } }
+ }
+ }
+ \__unravel_scan_keyword:nT { fFiIlLeE }
+ { \__unravel_scan_pdf_ext_toks: }
+ \__unravel_scan_keyword:nTF { pPaAgGeE }
+ {
+ \__unravel_scan_int:
+ \__unravel_scan_pdf_ext_toks:
+ }
+ {
+ \__unravel_scan_keyword:nTF { nNaAmMeE }
+ { \__unravel_scan_pdf_ext_toks: }
+ {
+ \__unravel_scan_keyword:nTF { nNuUmM }
+ { \__unravel_scan_int: }
+ { \msg_error:nn { unravel } { identifier-type-missing } }
+ }
+ }
+ \__unravel_scan_keyword:nTF { nNeEwWwWiInNdDoOwW }
+ { \__unravel_skip_optional_space: }
+ {
+ \__unravel_scan_keyword:nT { nNoOnNeEwWwWiInNdDoOwW }
+ { \__unravel_skip_optional_space: }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_image:
+ {
+ \__unravel_scan_rule_attr:
+ \__unravel_scan_keyword:nTF { nNaAmMeEdD }
+ { \__unravel_scan_pdf_ext_toks: }
+ {
+ \__unravel_scan_keyword:nT { pPaAgGeE }
+ { \__unravel_scan_int: }
+ }
+ \__unravel_scan_keyword:nT { cCoOlLoOrRsSpPaAcCeE }
+ { \__unravel_scan_int: }
+ \__unravel_scan_pdf_ext_toks:
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_immediate_operands:
+ {
+ \__unravel_get_x_next:
+ \__unravel_set_cmd:
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int = { \__unravel_tex_use:n { extension } }
+ {
+ \int_compare:nNnTF
+ \l__unravel_head_char_int < { 3 } % openout, write, closeout
+ { \__unravel_scan_immediate_operands_aux: }
+ {
+ \int_case:nnF \l__unravel_head_char_int
+ {
+ { 7 } { \__unravel_scan_extension_operands_aux: } % pdfobj
+ { 9 } { \__unravel_scan_extension_operands_aux: } % pdfxform
+ { 11 } { \__unravel_scan_extension_operands_aux: } %pdfximage
+ }
+ { \__unravel_scan_immediate_operands_bad: }
+ }
+ }
+ { \__unravel_scan_immediate_operands_bad: }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_immediate_operands_aux:
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_extension_operands:
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_immediate_operands_bad:
+ {
+ \__unravel_back_input:
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl ignored }
+ \seq_gput_right:Nn \g__unravel_prev_input_seq { }
+ }
+
+\cs_new_protected_nopar:Npn \__unravel_scan_pdfdest_operands:
+ {
+ \__unravel_scan_keyword:nTF { nNuUmM }
+ { \__unravel_scan_int: }
+ {
+ \__unravel_scan_keyword:nTF { nNaAmMeE }
+ { \__unravel_scan_pdf_ext_toks: }
+ { \msg_error:nn { unravel } { identifier-type-missing } }
+ }
+ \__unravel_scan_keyword:nTF { xXyYzZ }
+ {
+ \__unravel_scan_keyword:nT { zZoOoOmM }
+ { \__unravel_scan_int: }
+ }
+ {
+ \__unravel_scan_keyword:nF { fFiItTbBhH }
+ {
+ \__unravel_scan_keyword:nF { fFiItTbBvV }
+ {
+ \__unravel_scan_keyword:nF { fFiItTbB }
+ {
+ \__unravel_scan_keyword:nF { fFiItThHhH }
+ {
+ \__unravel_scan_keyword:nF { fFiItTvV }
+ {
+ \__unravel_scan_keyword:nTF
+ { fFiItTrR }
+ {
+ \__unravel_skip_optional_space:
+ \__unravel_scan_alt_rule:
+ \use_none:n
+ }
+ {
+ \__unravel_scan_keyword:nF
+ { fFiItT }
+ {
+ \msg_error:nn { unravel }
+ {
+ destination-type-missing
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ \__unravel_skip_optional_space:
+ }
+\cs_set_protected_nopar:Npn \__unravel_tmp:w
+ {
+ \seq_gput_right:Nn \g__unravel_prev_input_seq { }
+ \__unravel_prefixed_command:
+ }
+\int_step_inline:nnnn
+ { \__unravel_tex_use:n { max_non_prefixed_command } + 1 }
+ { 1 }
+ { \__unravel_tex_use:n { max_command } }
+ { \cs_new_eq:cN { __unravel_cmd_#1: } \__unravel_tmp:w }
+\cs_new_protected_nopar:Npn \__unravel_prefixed_command:
+ {
+ \int_while_do:nNnn
+ \l__unravel_head_cmd_int = { \__unravel_tex_use:n { prefix } }
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_get_x_non_relax:
+ \__unravel_set_cmd:
+ \int_compare:nNnF \l__unravel_head_cmd_int
+ > { \__unravel_tex_use:n { max_non_prefixed_command } }
+ {
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \msg_error:nnxx { unravel } { erroneous-prefixes }
+ { \tl_to_str:N \l__unravel_tmpa_tl }
+ { \tl_to_str:N l__unravel_head_tl }
+ \__unravel_back_input:
+ \__unravel_omit_after_assignment:w
+ }
+ }
+ % ^^A todo: Discard non-\global prefixes if they are irrelevant
+ % ^^A todo: Adjust for the setting of \globaldefs
+ \cs_if_exist_use:cF
+ { __unravel_prefixed_ \int_use:N \l__unravel_head_cmd_int : }
+ {
+ \msg_error:nnx { unravel } { internal } { prefixed }
+ \__unravel_omit_after_assignment:w
+ }
+ \__unravel_after_assignment:
+ }
+\cs_new_protected_nopar:Npn \__unravel_after_assignment:
+ {
+ \__unravel_back_input_gtl:N \g__unravel_after_assignment_gtl
+ \gtl_gclear:N \g__unravel_after_assignment_gtl
+ }
+\cs_new_protected_nopar:Npn \__unravel_omit_after_assignment:w
+ #1 \__unravel_after_assignment: { }
+\cs_new_protected:Npn \__unravel_prefixed_new:nn #1#2
+ {
+ \cs_new_protected_nopar:cpn
+ { __unravel_prefixed_ \__unravel_tex_use:n {#1} : } {#2}
+ }
+\cs_new_protected:Npn \__unravel_assign_token:n #1
+ {
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ #1
+ \tl_use:N \l__unravel_head_tl \scan_stop:
+ \__unravel_print_assigned_token:
+ }
+\cs_new_protected_nopar:Npn \__unravel_assign_register:
+ {
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \tl_use:N \l__unravel_head_tl \scan_stop:
+ \__unravel_print_assigned_register:
+ }
+\cs_new_protected:Npn \__unravel_assign_value:nn #1#2
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl }
+ #1
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ }
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \tl_set_eq:NN \l__unravel_defined_tl \l__unravel_head_tl
+ \__unravel_scan_optional_equals:
+ #2
+ \__unravel_assign_register:
+ }
+\__unravel_prefixed_new:nn { toks_register } % 71
+ {
+ \int_compare:nNnT \l__unravel_head_char_int = \c_zero
+ { % \toks
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_int:
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ }
+ \__unravel_assign_toks:
+ }
+\__unravel_prefixed_new:nn { assign_toks } % 72
+ { \__unravel_assign_toks: }
+\cs_new_protected_nopar:Npn \__unravel_assign_toks:
+ {
+ \__unravel_prev_input_silent:V \l__unravel_head_tl
+ \__unravel_print_action:
+ \tl_set_eq:NN \l__unravel_defined_tl \l__unravel_head_tl
+ \__unravel_scan_optional_equals:
+ \__unravel_get_x_non_relax:
+ \__unravel_set_cmd:
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int = { \__unravel_tex_use:n { toks_register } }
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \int_compare:nNnT \l__unravel_head_char_int = \c_zero
+ { \__unravel_scan_int: }
+ }
+ {
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int = { \__unravel_tex_use:n { assign_toks } }
+ { \__unravel_prev_input:V \l__unravel_head_tl }
+ {
+ \__unravel_back_input:
+ \__unravel_scan_toks:NN \c_false_bool \c_false_bool
+ }
+ }
+ \__unravel_assign_register:
+ }
+\__unravel_prefixed_new:nn { assign_int } % 73
+ { \__unravel_assign_value:nn { } { \__unravel_scan_int: } }
+\__unravel_prefixed_new:nn { assign_dimen } % 74
+ { \__unravel_assign_value:nn { } { \__unravel_scan_normal_dimen: } }
+\__unravel_prefixed_new:nn { assign_glue } % 75
+ { \__unravel_assign_value:nn { } { \__unravel_scan_normal_glue: } }
+\__unravel_prefixed_new:nn { assign_mu_glue } % 76
+ { \__unravel_assign_value:nn { } { \__unravel_scan_mu_glue: } }
+\__unravel_prefixed_new:nn { assign_font_dimen } % 77
+ {
+ \__unravel_assign_value:nn
+ { \__unravel_scan_int: \__unravel_scan_font_ident: }
+ { \__unravel_scan_normal_dimen: }
+ }
+\__unravel_prefixed_new:nn { assign_font_int } % 78
+ {
+ \__unravel_assign_value:nn
+ { \__unravel_scan_font_int: } { \__unravel_scan_int: }
+ }
+\__unravel_prefixed_new:nn { set_aux } % 79
+ { % prevdepth = 1, spacefactor = 0
+ \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: } }
+ }
+\__unravel_prefixed_new:nn { set_prev_graf } % 80
+ { \__unravel_assign_value:nn { } { \__unravel_scan_int: } }
+\__unravel_prefixed_new:nn { set_page_dimen } % 81
+ { \__unravel_assign_value:nn { } { \__unravel_scan_normal_dimen: } }
+\__unravel_prefixed_new:nn { set_page_int } % 82
+ { \__unravel_assign_value:nn { } { \__unravel_scan_int: } }
+\__unravel_prefixed_new:nn { set_box_dimen } % 83
+ {
+ \__unravel_assign_value:nn
+ { \__unravel_scan_int: } { \__unravel_scan_normal_dimen: }
+ }
+\__unravel_prefixed_new:nn { set_shape } % 84
+ {
+ \__unravel_assign_value:nn { \__unravel_scan_int: }
+ {
+ \prg_replicate:nn
+ {
+ \tl_if_head_eq_meaning:VNT
+ \l__unravel_defined_tl \tex_parshape:D { \c_two * }
+ \tl_tail:N \l__unravel_defined_tl
+ }
+ { \__unravel_scan_int: }
+ }
+ }
+\__unravel_prefixed_new:nn { def_code } % 85
+ {
+ \__unravel_assign_value:nn
+ { \__unravel_scan_int: } { \__unravel_scan_int: }
+ }
+\__unravel_prefixed_new:nn { def_family } % 86
+ {
+ \__unravel_assign_value:nn
+ { \__unravel_scan_int: } { \__unravel_scan_font_ident: }
+ }
+\__unravel_prefixed_new:nn { set_font } % 87
+ {
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \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:
+ \gtl_gput_right:NV \g__unravel_output_gtl \l__unravel_head_tl
+ \__unravel_print_action:
+ }
+\__unravel_prefixed_new:nn { def_font } % 88
+ {
+ \__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 }
+ \__unravel_scan_optional_equals:
+ \__unravel_scan_file_name:
+ \bool_gset_true:N \g__unravel_name_in_progress_bool
+ \__unravel_scan_keyword:nTF { aAtT }
+ { \__unravel_scan_normal_dimen: }
+ {
+ \__unravel_scan_keyword:nT { sS cC aA lL eE dD }
+ { \__unravel_scan_int: }
+ }
+ \bool_gset_false:N \g__unravel_name_in_progress_bool
+ \__unravel_assign_token:n { }
+ }
+\__unravel_prefixed_new:nn { let } % 94
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \token_if_eq_meaning:NNTF \l__unravel_head_token \tex_let:D
+ { % |let|
+ \__unravel_scan_r_token:
+ \seq_get_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \__unravel_print_action:x { \tl_to_str:N \l__unravel_tmpa_tl }
+ \__unravel_get_next:
+ \bool_while_do:nn
+ { \token_if_eq_catcode_p:NN \l__unravel_head_token \c_space_token }
+ { \__unravel_get_next: }
+ \tl_if_eq:NNT \l__unravel_head_tl \c__unravel_eq_tl
+ { \__unravel_get_next: }
+ \token_if_eq_catcode:NNT \l__unravel_head_token \c_space_token
+ { \__unravel_get_next: }
+ }
+ { % |futurelet|
+ \__unravel_scan_r_token:
+ \seq_get_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \__unravel_print_action:x { \tl_to_str:N \l__unravel_tmpa_tl }
+ \__unravel_get_next:
+ \gtl_set_eq:NN \l__unravel_tmpb_gtl \l__unravel_head_gtl
+ \__unravel_get_next:
+ \__unravel_back_input:
+ \gtl_set_eq:NN \l__unravel_head_gtl \l__unravel_tmpb_gtl
+ \__unravel_back_input:
+ }
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \tl_put_right:Nn \l__unravel_tmpa_tl { = ~ \l__unravel_head_token }
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \use:x
+ {
+ \exp_not:V \l__unravel_head_tl
+ \tex_let:D \tl_tail:N \l__unravel_tmpa_tl
+ }
+ \__unravel_print_assigned_token:
+ }
+\__unravel_prefixed_new:nn { shorthand_def } % 95
+ {
+ \__unravel_prev_input_silent:V \l__unravel_head_tl
+ \tl_set:Nx \l__unravel_prev_action_tl
+ { \tl_to_str:N \l__unravel_head_tl }
+ \__unravel_scan_r_token:
+ \__unravel_print_action:x
+ { \l__unravel_prev_action_tl \tl_to_str:N \l__unravel_defined_tl }
+ \exp_after:wN \cs_set_eq:NN \l__unravel_defined_tl \scan_stop:
+ \__unravel_scan_optional_equals:
+ \__unravel_scan_int:
+ \__unravel_assign_token:n { }
+ }
+\__unravel_prefixed_new:nn { read_to_cs } % 96
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl }
+ \__unravel_scan_int:
+ \__unravel_scan_keyword:nF { tToO }
+ {
+ \msg_error:nn { unravel } { missing-to }
+ \__unravel_prev_input:n { to }
+ }
+ \__unravel_scan_r_token:
+ \__unravel_assign_token:n { }
+ }
+\__unravel_prefixed_new:nn { def } % 97
+ {
+ \seq_get_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \tl_set:NV \l__unravel_defining_tl \l__unravel_tmpa_tl
+ \tl_put_right:NV \l__unravel_defining_tl \l__unravel_head_tl
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \int_compare:nNnTF \l__unravel_head_char_int < \c_two
+ { % def/gdef
+ \__unravel_scan_r_token:
+ \tl_put_right:NV \l__unravel_defining_tl \l__unravel_defined_tl
+ \__unravel_scan_toks:NN \c_true_bool \c_false_bool
+ }
+ { % edef/xdef
+ \__unravel_scan_r_token:
+ \tl_put_right:NV \l__unravel_defining_tl \l__unravel_defined_tl
+ \__unravel_scan_toks:NN \c_true_bool \c_true_bool
+ }
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_assign_token:n
+ { \tl_set_eq:NN \l__unravel_head_tl \l__unravel_defining_tl }
+ }
+\__unravel_prefixed_new:nn { set_box } % 98
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_int:
+ \__unravel_scan_optional_equals:
+ \bool_if:NTF \g__unravel_set_box_allowed_bool
+ { \__unravel_do_box:N \c_false_bool }
+ {
+ \msg_error:nn { unravel } { improper-setbox }
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \__unravel_omit_after_assignment:w
+ }
+ }
+\__unravel_prefixed_new:nn { hyph_data } % 99
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_scan_toks:NN \c_false_bool \c_false_bool
+ \__unravel_assign_token:n { }
+ }
+\__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_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_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_prefixed_new:nn { register } % 89
+ { \__unravel_do_register:N \c_zero }
+\__unravel_prefixed_new:nn { advance } % 90
+ { \__unravel_do_operation:N \c_one }
+\__unravel_prefixed_new:nn { multiply } % 91
+ { \__unravel_do_operation:N \c_two }
+\__unravel_prefixed_new:nn { divide } % 92
+ { \__unravel_do_operation:N \c_three }
+\cs_new_protected:Npn \__unravel_do_operation:N #1
+ {
+ \__unravel_prev_input_silent:V \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_get_x_next:
+ \__unravel_set_cmd:
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int > { \__unravel_tex_use:n { assign_mu_glue } }
+ {
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int = { \__unravel_tex_use:n { register } }
+ { \__unravel_do_register:N #1 }
+ { \__unravel_do_operation_fail:w }
+ }
+ {
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int < { \__unravel_tex_use:n { assign_int } }
+ { \__unravel_do_operation_fail:w }
+ {
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \exp_args:NNf \__unravel_do_register_set:Nn #1
+ {
+ \int_eval:n
+ {
+ \l__unravel_head_cmd_int
+ - \__unravel_tex_use:n { assign_toks }
+ }
+ }
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_do_operation_fail:w
+ {
+ \msg_error:nn { unravel } { after-advance }
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \__unravel_omit_after_assignment:w
+ }
+\cs_new_protected:Npn \__unravel_do_register:N #1
+ {
+ \exp_args:NNV \__unravel_do_register_aux:Nn #1
+ \l__unravel_head_char_int
+ }
+\cs_new_protected:Npn \__unravel_do_register_aux:Nn #1#2
+ {
+ \int_compare:nNnTF { \tl_tail:n {#2} } = \c_zero
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_scan_int:
+ \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_silent:V \l__unravel_head_tl
+ \__unravel_print_action:
+ }
+ \tl_set_eq:NN \l__unravel_defined_tl \l__unravel_head_tl
+ \exp_args:NNf \__unravel_do_register_set:Nn #1
+ { \int_eval:n { #2 / 1 000 000 } }
+ }
+\cs_new_protected:Npn \__unravel_do_register_set:Nn #1#2
+ {
+ \int_compare:nNnTF {#1} = \c_zero
+ { % truly register command
+ \__unravel_scan_optional_equals:
+ }
+ { % \advance, \multiply, \divide
+ \__unravel_scan_keyword:nF { bByY }
+ { \__unravel_prev_input_silent:n { by } }
+ }
+ \int_compare:nNnTF {#1} < \c_two
+ {
+ \int_case:nnF {#2}
+ {
+ { 1 } { \__unravel_scan_int: } % count
+ { 2 } { \__unravel_scan_normal_dimen: } % dim
+ { 3 } { \__unravel_scan_normal_glue: } % glue
+ { 4 } { \__unravel_scan_mu_glue: } % muglue
+ }
+ { \msg_error:nnx { unravel } { internal } { do-reg=#2 } }
+ }
+ { \__unravel_scan_int: }
+ \__unravel_assign_register:
+ }
+\cs_new_protected_nopar:Npn \__unravel_do_assignments:
+ {
+ \__unravel_get_x_non_relax:
+ \__unravel_set_cmd:
+ \int_compare:nNnT
+ \l__unravel_head_cmd_int
+ > { \__unravel_tex_use:n { max_non_prefixed_command } }
+ {
+ \bool_gset_false:N \g__unravel_set_box_allowed_bool
+ \seq_gput_right:Nn \g__unravel_prev_input_seq { }
+ \__unravel_prefixed_command:
+ \bool_gset_true:N \g__unravel_set_box_allowed_bool
+ \__unravel_do_assignments:
+ }
+ }
+\__unravel_new_tex_expandable:nn { undefined_cs } % 103
+ { \tl_use:N \l__unravel_head_tl \__unravel_print_action: }
+\__unravel_new_tex_expandable:nn { expand_after } % 104
+ {
+ \token_if_eq_meaning:NNTF \l__unravel_head_token \tex_expandafter:D
+ { \__unravel_expandafter: } { \__unravel_unless: }
+ }
+\cs_new_protected_nopar:Npn \__unravel_expandafter:
+ {
+ \gtl_set_eq:NN \l__unravel_tmpb_gtl \l__unravel_head_gtl
+ \__unravel_get_next:
+ \gtl_concat:NNN \l__unravel_head_gtl
+ \l__unravel_tmpb_gtl \l__unravel_head_gtl
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_gtl
+ \__unravel_print_action:x { \gtl_to_str:N \l__unravel_head_gtl }
+ \__unravel_get_next:
+ \__unravel_token_if_expandable:NTF \l__unravel_head_token
+ { \__unravel_expand: }
+ { \__unravel_back_input: }
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_gtl
+ \__unravel_set_action_text:x
+ { back_input: ~ \gtl_to_str:N \l__unravel_head_gtl }
+ \gtl_pop_left:N \l__unravel_head_gtl
+ \__unravel_back_input:
+ \__unravel_print_action:
+ }
+\cs_new_protected_nopar:Npn \__unravel_unless:
+ {
+ \__unravel_get_token:
+ \int_compare:nNnTF
+ \l__unravel_head_cmd_int = { \__unravel_tex_use:n { if_test } }
+ {
+ \token_if_eq_meaning:NNTF \l__unravel_head_token \tex_ifcase:D
+ { \__unravel_unless_bad: }
+ {
+ \tl_put_left:Nn \l__unravel_head_tl { \reverse_if:N }
+ % \int_add:Nn \l__unravel_head_char_int { 32 }
+ \__unravel_expand_nonmacro:
+ }
+ }
+ { \__unravel_unless_bad: }
+ }
+\cs_new_protected_nopar:Npn \__unravel_unless_bad:
+ {
+ \msg_error:nn { unravel } { bad-unless }
+ \__unravel_back_input:
+ }
+\__unravel_new_tex_expandable:nn { no_expand } % 105
+ {
+ \token_if_eq_meaning:NNTF \l__unravel_head_token \tex_noexpand:D
+ { \__unravel_noexpand: }
+ { \__unravel_pdfprimitive: }
+ }
+\cs_new_protected_nopar:Npn \__unravel_noexpand:
+ {
+ \__unravel_get_token:
+ \__unravel_back_input:
+ \__unravel_token_if_expandable:NT \l__unravel_head_token
+ {
+ \cs_gset_protected_nopar:Npx \__unravel_get_next:
+ {
+ \cs_gset_protected_nopar:Npn \__unravel_get_next:
+ { \exp_not:o { \__unravel_get_next: } }
+ \exp_not:o { \__unravel_get_next: }
+ \exp_not:n { \cs_set_eq:NN \l__unravel_head_token \tex_relax:D }
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_pdfprimitive:
+ { \msg_error:nnx { unravel } { not-implemented } { pdfprimitive } }
+\__unravel_new_tex_expandable:nn { input } % 106
+ {
+ \int_case:nnF \l__unravel_head_char_int
+ {
+ { 1 } { \__unravel_print_action: } % \endinput
+ { 2 } { \__unravel_scantokens: } % \scantokens
+ }
+ { % 0=\input
+ \bool_if:NTF \g__unravel_name_in_progress_bool
+ { \__unravel_insert_relax: } { \__unravel_input: }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_scantokens:
+ {
+ \seq_gput_right:Nn \g__unravel_prev_input_seq { }
+ \__unravel_scan_toks:NN \c_false_bool \c_false_bool
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \tl_set_rescan:Nno \l__unravel_head_tl { } \l__unravel_tmpa_tl
+ \__unravel_back_input:V \l__unravel_head_tl
+ \__unravel_print_action:x { \tl_to_str:N \l__unravel_tmpa_tl }
+ }
+\cs_new_protected_nopar:Npn \__unravel_input:
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_scan_file_name:
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \tl_set:Nx \l__unravel_tmpa_tl { \tl_tail:N \l__unravel_head_tl }
+ \__unravel_tl_gset_input:Nno \g__unravel_tmpc_tl { } \l__unravel_tmpa_tl
+ \__unravel_back_input:V \g__unravel_tmpc_tl
+ \__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl }
+ }
+\__unravel_new_tex_expandable:nn { cs_name } % 109
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_csname_loop:
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_back_input_tl_o:
+ }
+\cs_new_protected_nopar:Npn \__unravel_csname_loop:
+ {
+ \__unravel_get_x_next:
+ \token_if_cs:NTF \l__unravel_head_token
+ {
+ \cs_if_eq:NNF \l__unravel_head_token \tex_endcsname:D
+ {
+ \msg_error:nn { unravel } { missing-endcsname }
+ \__unravel_back_input:
+ \tl_set:Nn \l__unravel_head_tl { \tex_endcsname:D }
+ }
+ }
+ {
+ \__unravel_prev_input_silent:x
+ { \__unravel_token_to_char:N \l__unravel_head_token }
+ \__unravel_csname_loop:
+ }
+ }
+\__unravel_new_tex_expandable:nn { convert } % 110
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \int_case:nn \l__unravel_head_char_int
+ {
+ 0 \__unravel_scan_int:
+ 1 \__unravel_scan_int:
+ 2 { \__unravel_get_next: \__unravel_prev_input:V \l__unravel_head_tl }
+ 3 { \__unravel_get_next: \__unravel_prev_input:V \l__unravel_head_tl }
+ 4 \__unravel_scan_font_ident:
+ 8 \__unravel_scan_font_ident:
+ 9 \__unravel_scan_font_ident:
+ { 10 } \__unravel_scan_font_ident:
+ { 11 } \__unravel_scan_int:
+ { 12 } \__unravel_scan_int:
+ { 13 } \__unravel_scan_pdf_ext_toks:
+ { 14 } \__unravel_scan_pdf_ext_toks:
+ { 15 } \__unravel_scan_int:
+ { 16 } \__unravel_scan_int:
+ { 17 } \__unravel_scan_pdfstrcmp:
+ { 18 } \__unravel_scan_pdfcolorstackinit:
+ { 19 } \__unravel_scan_pdf_ext_toks:
+ { 20 } \__unravel_scan_pdf_ext_toks:
+ { 22 } \__unravel_scan_pdf_ext_toks:
+ { 23 } \__unravel_scan_pdf_ext_toks:
+ { 24 }
+ {
+ \__unravel_scan_keyword:n { fF iI lL eE }
+ \__unravel_scan_pdf_ext_toks:
+ }
+ { 25 } \__unravel_scan_pdffiledump:
+ { 26 } \__unravel_scan_pdfmatch:
+ { 27 } \__unravel_scan_int:
+ { 28 } \__unravel_scan_int:
+ { 30 } \__unravel_scan_int:
+ { 31 } \__unravel_scan_pdfximagebbox:
+ }
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_back_input_tl_o:
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_pdfstrcmp:
+ {
+ \__unravel_scan_toks_to_str:
+ \__unravel_scan_toks_to_str:
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_pdfximagebbox:
+ { \__unravel_scan_int: \__unravel_scan_int: }
+\cs_new_protected_nopar:Npn \__unravel_scan_pdfcolorstackinit:
+ {
+ \__unravel_scan_keyword:nTF { pP aA gG eE }
+ { \bool_set_true:N \l__unravel_tmpa_bool }
+ { \bool_set_false:N \l__unravel_tmpb_bool }
+ \__unravel_scan_keyword:nF { dD iI rR eE cC tT }
+ { \__unravel_scan_keyword:n { pP aA gG eE } }
+ \__unravel_scan_toks_to_str:
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_pdffiledump:
+ {
+ \__unravel_scan_keyword:nT { oO fF fF sS eE tT } \__unravel_scan_int:
+ \__unravel_scan_keyword:nT { lL eE nN gG tT hH } \__unravel_scan_int:
+ \__unravel_scan_pdf_ext_toks:
+ }
+\cs_new_protected_nopar:Npn \__unravel_scan_pdfmatch:
+ {
+ \__unravel_scan_keyword:n { iI cC aA sS eE }
+ \__unravel_scan_keyword:nT { sS uU bB cC oO uU nN tT }
+ { \__unravel_scan_int: }
+ \__unravel_scan_pdf_ext_toks:
+ \__unravel_scan_pdf_ext_toks:
+ }
+\__unravel_new_tex_expandable:nn { the } % 111
+ {
+ \__unravel_get_the:
+ \tl_set:Nx \l__unravel_tmpa_tl { \exp_args:NV \exp_not:o \l__unravel_head_tl }
+ \__unravel_back_input:V \l__unravel_tmpa_tl
+ \__unravel_print_action:
+ }
+\cs_new_protected_nopar:Npn \__unravel_get_the:
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \int_if_odd:nTF \l__unravel_head_char_int
+ { % \unexpanded, \detokenize
+ \__unravel_scan_toks:NN \c_false_bool \c_false_bool
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_set_action_text:x { \tl_to_str:N \l__unravel_head_tl }
+ }
+ { % \the
+ \__unravel_get_x_next:
+ \__unravel_scan_something_internal:n { 5 }
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_set_action_text:x
+ {
+ \tl_head:N \l__unravel_head_tl
+ => \tl_tail:N \l__unravel_head_tl
+ }
+ \tl_set:Nx \l__unravel_head_tl
+ { \exp_not:N \exp_not:n { \tl_tail:N \l__unravel_head_tl } }
+ }
+ }
+\__unravel_new_tex_expandable:nn { top_bot_mark } % 112
+ { \__unravel_back_input_tl_o: }
+\__unravel_new_tex_expandable:nn { end_template } % 117
+ {
+ \msg_error:nn { unravel } { not-implemented } { end-template }
+ \__unravel_back_input_tl_o:
+ }
+\cs_new_protected_nopar:Npn \__unravel_pass_text:
+ {
+ \__unravel_input_if_empty:TF
+ { \__unravel_pass_text_empty: }
+ {
+ \__unravel_input_get:N \l__unravel_tmpb_gtl
+ \if_true:
+ \if_case:w \gtl_head_do:NN \l__unravel_tmpb_gtl \c_one
+ \exp_after:wN \__unravel_pass_text_done:w
+ \fi:
+ \__unravel_input_gpop:N \l__unravel_tmpb_gtl
+ \exp_after:wN \__unravel_pass_text:
+ \else:
+ \use:c { fi: }
+ \int_set_eq:NN \l__unravel_if_nesting_int \c_one
+ \__unravel_input_gpop:N \l__unravel_tmpb_gtl
+ \exp_after:wN \__unravel_pass_text_nested:
+ \fi:
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_pass_text_done:w
+ {
+ \__unravel_get_next:
+ \token_if_eq_meaning:NNT \l__unravel_head_token \fi: { \if_true: }
+ \else:
+ }
+\cs_new_protected_nopar:Npn \__unravel_pass_text_nested:
+ {
+ \__unravel_input_if_empty:TF
+ { \__unravel_pass_text_empty: }
+ {
+ \__unravel_input_get:N \l__unravel_tmpb_gtl
+ \if_true:
+ \if_true:
+ \gtl_head_do:NN \l__unravel_tmpb_gtl \else:
+ \int_decr:N \l__unravel_if_nesting_int
+ \use_none:nnnnn
+ \fi:
+ \use_none:nnn
+ \fi:
+ \int_incr:N \l__unravel_if_nesting_int
+ \fi:
+ \__unravel_input_gpop:N \l__unravel_tmpa_gtl
+ \int_compare:nNnTF \l__unravel_if_nesting_int = \c_zero
+ { \__unravel_pass_text: }
+ { \__unravel_pass_text_nested: }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_pass_text_empty:
+ {
+ \msg_error:nn { unravel } { runaway-if }
+ \__unravel_exit:w
+ }
+\cs_new_protected:Npn \__unravel_cond_push:
+ {
+ \tl_gput_left:Nx \g__unravel_if_limit_tl
+ { { \int_use:N \g__unravel_if_limit_int } }
+ \int_gincr:N \g__unravel_if_depth_int
+ \int_gzero:N \g__unravel_if_limit_int
+ }
+\cs_new_protected_nopar:Npn \__unravel_cond_pop:
+ {
+ \int_gset:Nn \g__unravel_if_limit_int
+ { \tl_head:N \g__unravel_if_limit_tl }
+ \tl_gset:Nx \g__unravel_if_limit_tl
+ { \tl_tail:N \g__unravel_if_limit_tl }
+ \int_gdecr:N \g__unravel_if_depth_int
+ }
+\cs_new_protected:Npn \__unravel_change_if_limit:nn #1#2
+ {
+ \int_compare:nNnTF {#2} = \g__unravel_if_depth_int
+ { \int_gset:Nn \g__unravel_if_limit_int {#1} }
+ {
+ \tl_clear:N \l__unravel_tmpa_tl
+ \prg_replicate:nn { \g__unravel_if_depth_int - #2 - \c_one }
+ {
+ \tl_put_right:Nx \l__unravel_tmpa_tl
+ { { \tl_head:N \g__unravel_if_limit_tl } }
+ \tl_gset:Nx \g__unravel_if_limit_tl
+ { \tl_tail:N \g__unravel_if_limit_tl }
+ }
+ \tl_gset:Nx \g__unravel_if_limit_tl
+ { \l__unravel_tmpa_tl {#1} \tl_tail:N \g__unravel_if_limit_tl }
+ }
+ }
+\__unravel_new_tex_expandable:nn { if_test } % 107
+ {
+ \__unravel_cond_push:
+ \exp_args:NV \__unravel_cond_aux:n \g__unravel_if_depth_int
+ }
+\cs_new_protected:Npn \__unravel_cond_aux:n #1
+ {
+ \int_case:nnF \l__unravel_head_char_int
+ {
+ { 12 } { \__unravel_test_ifx:n {#1} }
+ { 16 } { \__unravel_test_case:n {#1} }
+ { 21 } { \__unravel_test_pdfprimitive:n {#1} } % ^^A todo and \unless
+ }
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \int_case:nn \l__unravel_head_char_int
+ {
+ { 0 } { \__unravel_test_two_chars: } % if
+ { 1 } { \__unravel_test_two_chars: } % ifcat
+ { 2 } % ifnum
+ { \__unravel_test_two_vals:N \__unravel_scan_int: }
+ { 3 } % ifdim
+ { \__unravel_test_two_vals:N \__unravel_scan_normal_dimen: }
+ { 4 } { \__unravel_scan_int: } % ifodd
+ % { 5 } { } % ifvmode
+ % { 6 } { } % ifhmode
+ % { 7 } { } % ifmmode
+ % { 8 } { } % ifinner
+ { 9 } { \__unravel_scan_int: } % ifvoid
+ { 10 } { \__unravel_scan_int: } % ifhbox
+ { 11 } { \__unravel_scan_int: } % ifvbox
+ { 13 } { \__unravel_scan_int: } % ifeof
+ % { 14 } { } % iftrue
+ % { 15 } { } % iffalse
+ { 17 } { \__unravel_test_ifdefined: } % ifdefined
+ { 18 } { \__unravel_test_ifcsname: } % ifcsname
+ { 19 } % iffontchar
+ { \__unravel_scan_font_ident: \__unravel_scan_int: }
+ % { 20 } { } % ifincsname % ^^A todo: something?
+ { 22 } % ifpdfabsnum
+ { \__unravel_test_two_vals:N \__unravel_scan_int: }
+ { 23 } % ifpdfabsdim
+ { \__unravel_test_two_vals:N \__unravel_scan_normal_dimen: }
+ }
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_set_action_text:x { \tl_to_str:N \l__unravel_head_tl }
+ \l__unravel_head_tl \scan_stop:
+ \exp_after:wN \__unravel_cond_true:n
+ \else:
+ \exp_after:wN \__unravel_cond_false:n
+ \fi:
+ {#1}
+ }
+ }
+\cs_new_protected:Npn \__unravel_cond_true:n #1
+ {
+ \__unravel_change_if_limit:nn { 3 } {#1} % wait for else/fi
+ \__unravel_print_action:x { \g__unravel_action_text_str = true }
+ }
+\cs_new_protected:Npn \__unravel_cond_false:n #1
+ {
+ \__unravel_cond_false_loop:n {#1}
+ \__unravel_cond_false_common:
+ \__unravel_print_action:x { \g__unravel_action_text_str = false }
+ }
+\cs_new_protected:Npn \__unravel_cond_false_loop:n #1
+ {
+ \__unravel_pass_text:
+ \int_compare:nNnTF \g__unravel_if_depth_int = {#1}
+ {
+ \token_if_eq_meaning:NNT \l__unravel_head_token \or:
+ {
+ \msg_error:nn { unravel } { extra-or }
+ \__unravel_cond_false_loop:n {#1}
+ }
+ }
+ {
+ \token_if_eq_meaning:NNT \l__unravel_head_token \fi:
+ { \__unravel_cond_pop: }
+ \__unravel_cond_false_loop:n {#1}
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_cond_false_common:
+ {
+ \token_if_eq_meaning:NNTF \l__unravel_head_token \fi:
+ { \__unravel_cond_pop: }
+ { \int_gset:Nn \g__unravel_if_limit_int { 2 } } % wait for fi
+ }
+\cs_new_protected:Npn \__unravel_test_two_vals:N #1
+ {
+ #1
+ \__unravel_get_x_non_blank:
+ \tl_if_in:nVF { < = > } \l__unravel_head_tl
+ {
+ \msg_error:nn { unravel } { missing-equals }
+ \__unravel_back_input:
+ \tl_set:Nn \l__unravel_head_tl { = }
+ }
+ \__unravel_prev_input:V \l__unravel_head_tl
+ #1
+ }
+\cs_new_protected_nopar:Npn \__unravel_test_two_chars:
+ {
+ \__unravel_test_two_chars_aux:
+ \__unravel_prev_input:V \l__unravel_head_tl
+ \__unravel_test_two_chars_aux:
+ \__unravel_prev_input:V \l__unravel_head_tl
+ }
+\cs_new_protected_nopar:Npn \__unravel_test_two_chars_aux:
+ {
+ \__unravel_get_x_next:
+ \gtl_if_tl:NF \l__unravel_head_gtl
+ {
+ \tl_set:Nx \l__unravel_head_tl
+ {
+ \gtl_if_head_is_group_begin:NTF \l__unravel_head_gtl
+ { \c_group_begin_token } { \c_group_end_token }
+ }
+ }
+ \tl_put_left:Nn \l__unravel_head_tl { \exp_not:N } % ^^A todo: prettify.
+ }
+\cs_new_protected:Npn \__unravel_test_ifx:n #1
+ {
+ \seq_gput_right:NV \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:
+ \__unravel_get_next:
+ \gtl_set_eq:NN \l__unravel_tmpb_gtl \l__unravel_head_gtl
+ \__unravel_get_next:
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_tmpa_tl
+ \__unravel_set_action_text:x
+ {
+ Compare:~ \tl_to_str:N \l__unravel_tmpa_tl
+ \gtl_to_str:N \l__unravel_tmpb_gtl
+ \gtl_to_str:N \l__unravel_head_gtl
+ }
+ \gtl_head_do:NN \l__unravel_tmpb_gtl \__unravel_test_ifx_aux:w
+ \exp_after:wN \__unravel_cond_true:n
+ \else:
+ \exp_after:wN \__unravel_cond_false:n
+ \fi:
+ {#1}
+ }
+\cs_new_nopar:Npn \__unravel_test_ifx_aux:w
+ { \gtl_head_do:NN \l__unravel_head_gtl \l__unravel_tmpa_tl }
+\cs_new_protected:Npn \__unravel_test_case:n #1
+ {
+ \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} } }
+ \__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 }
+ % ^^A does text_case_aux use prev_input_seq?
+ \exp_args:No \__unravel_test_case_aux:nn { \l__unravel_head_tl } {#1}
+ \seq_gpop_right:NN \g__unravel_prev_input_seq \l__unravel_head_tl
+ \__unravel_print_action:x { \tl_to_str:N \l__unravel_head_tl }
+ }
+\cs_new_protected:Npn \__unravel_test_case_aux:nn #1#2
+ {
+ \int_compare:nNnTF {#1} = \c_zero
+ { \__unravel_change_if_limit:nn { 4 } {#2} }
+ {
+ \__unravel_pass_text:
+ \int_compare:nNnTF \g__unravel_if_depth_int = {#2}
+ {
+ \token_if_eq_meaning:NNTF \l__unravel_head_token \or:
+ {
+ \exp_args:Nf \__unravel_test_case_aux:nn
+ { \int_eval:n { #1 - 1 } } {#2}
+ }
+ { \__unravel_cond_false_common: }
+ }
+ {
+ \token_if_eq_meaning:NNT \l__unravel_head_token \fi:
+ { \__unravel_cond_pop: }
+ \__unravel_test_case_aux:nn {#1} {#2}
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_test_ifdefined:
+ {
+ \__unravel_input_if_empty:TF
+ { \__unravel_pass_text_empty: }
+ {
+ \__unravel_input_gpop:N \l__unravel_tmpb_gtl
+ \__unravel_set_action_text:x
+ {
+ Conditional:~ \tl_to_str:N \l__unravel_head_tl
+ \gtl_to_str:N \l__unravel_tmpb_gtl
+ }
+ \__unravel_prev_input:x
+ {
+ \gtl_if_tl:NTF \l__unravel_tmpb_gtl
+ { \gtl_head:N \l__unravel_tmpb_gtl }
+ { \gtl_to_str:N \l__unravel_tmpb_gtl }
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_test_ifcsname:
+ {
+ \__unravel_csname_loop:
+ \__unravel_prev_input:V \l__unravel_head_tl
+ }
+\__unravel_new_tex_expandable:nn { fi_or_else } % 108
+ {
+ \int_compare:nNnTF \l__unravel_head_char_int > \g__unravel_if_limit_int
+ {
+ \int_compare:nNnTF \g__unravel_if_limit_int = \c_zero
+ {
+ \int_compare:nNnTF \g__unravel_if_depth_int = \c_zero
+ { \msg_error:nn { unravel } { extra-fi-or-else } }
+ { \__unravel_insert_relax: }
+ }
+ { \msg_error:nn { unravel } { extra-fi-or-else } }
+ }
+ {
+ \__unravel_set_action_text:
+ \int_compare:nNnF \l__unravel_head_char_int = \c_two
+ {
+ \__unravel_fi_or_else_loop:
+ \__unravel_set_action_text:x
+ {
+ \g__unravel_action_text_str \c_space_tl
+ => ~ skipped ~ to ~ \tl_to_str:N \l__unravel_head_tl
+ }
+ }
+ % ^^A todo: in this print_action the token itself is missing.
+ \__unravel_print_action:
+ \__unravel_cond_pop:
+ }
+ }
+\cs_new_protected_nopar:Npn \__unravel_fi_or_else_loop:
+ {
+ \int_compare:nNnF \l__unravel_head_char_int = \c_two
+ {
+ \__unravel_pass_text:
+ \__unravel_set_cmd:
+ \__unravel_fi_or_else_loop:
+ }
+ }
+\cs_new_eq:NN \__unravel_print:n \iow_term:n
+\cs_generate_variant:Nn \__unravel_print:n { x }
+\cs_new_protected:Npn \__unravel_print_message:nn #1 #2
+ { \iow_wrap:nnnN { #1 #2 } { #1 } { } \__unravel_print:n }
+\cs_new_protected:Npn \__unravel_set_action_text:x #1
+ {
+ \group_begin:
+ \int_set:Nn \tex_escapechar:D { 92 }
+ \str_gset:Nx \g__unravel_action_text_str {#1}
+ \group_end:
+ }
+\cs_new_protected_nopar:Npn \__unravel_set_action_text:
+ {
+ \__unravel_set_action_text:x
+ {
+ \tl_to_str:N \l__unravel_head_tl
+ \tl_if_single_token:VT \l__unravel_head_tl
+ { = ~ \exp_after:wN \token_to_meaning:N \l__unravel_head_tl }
+ }
+ }
+\cs_new_protected:Npn \__unravel_print_state:
+ {
+ \group_begin:
+ \int_set:Nn \tex_escapechar:D { 92 }
+ \int_compare:nNnT \g__unravel_noise_int > \c_zero
+ {
+ \exp_args:Nx \__unravel_print_state_output:n
+ { \gtl_to_str:N \g__unravel_output_gtl }
+ \seq_set_map:NNn \l__unravel_tmpa_seq \g__unravel_prev_input_seq
+ { \__unravel_to_str:n {##1} }
+ \seq_remove_all:Nn \l__unravel_tmpa_seq { }
+ \exp_args:Nx \__unravel_print_state_prev:n
+ { \seq_use:Nn \l__unravel_tmpa_seq { \\ } }
+ \exp_args:Nx \__unravel_print_state_input:n
+ { \__unravel_input_to_str: }
+ }
+ \group_end:
+ \__unravel_prompt:
+ }
+\cs_new_protected:Npn \__unravel_print_state_output:n #1
+ {
+ \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}
+ }
+ }
+ }
+\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}
+ % }
+ }
+\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}
+ }
+ }
+\cs_new_protected:Npn \__unravel_print_meaning:
+ {
+ \__unravel_input_if_empty:TF
+ { \__unravel_print_message:nn { } { Empty~input! } }
+ {
+ \__unravel_input_get:N \l__unravel_tmpb_gtl
+ \__unravel_print_message:nn { }
+ {
+ \gtl_head_do:NN \l__unravel_tmpb_gtl \token_to_str:N
+ = \gtl_head_do:NN \l__unravel_tmpb_gtl \token_to_meaning:N
+ }
+ }
+ }
+\cs_new_protected:Npn \__unravel_print_action:
+ {
+ \int_gincr:N \g__unravel_step_int
+ \__unravel_print_message:nn { }
+ {
+ % \\
+ [=====~ 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
+ { 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:
+ }
+\cs_new_protected:Npn \__unravel_print_action:x #1
+ {
+ \__unravel_set_action_text:x {#1}
+ \__unravel_print_action:
+ }
+\cs_new_protected:Npn \__unravel_print_gtl_action:N #1
+ {
+ \__unravel_print_action:x { \gtl_to_str:N #1 }
+ }
+\cs_new_eq:NN \__unravel_print_done:x \__unravel_print_action:x
+\cs_new_protected_nopar:Npn \__unravel_print_assigned_token:
+ {
+ \__unravel_after_assignment: % ^^A todo: simplify
+ \__unravel_print_action:x
+ {
+ Set~ \exp_after:wN \token_to_str:N \l__unravel_defined_tl
+ = \exp_after:wN \token_to_meaning:N \l__unravel_defined_tl
+ }
+ \__unravel_omit_after_assignment:w
+ }
+\cs_new_protected_nopar:Npn \__unravel_print_assigned_register:
+ {
+ \__unravel_after_assignment: % ^^A todo: simplify
+ \__unravel_print_action:x
+ {
+ Set~ \exp_after:wN \token_to_str:N \l__unravel_defined_tl
+ \tl_if_single:NT \l__unravel_defined_tl
+ { ( \exp_after:wN \token_to_meaning:N \l__unravel_defined_tl ) }
+ = \exp_after:wN \tex_the:D \l__unravel_defined_tl
+ }
+ \__unravel_omit_after_assignment:w
+ }
+\cs_new_protected_nopar:Npn \__unravel_print_welcome:
+ {
+ \__unravel_print_message:nn { }
+ {
+ \\
+ ========~ 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. \\
+ }
+ }
+ \__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!~=====] \\ }
+ }
+\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
+ \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
+ \__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 }
+ }
+\cs_new_protected:Npn \__unravel_prompt_treat:n #1
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \exp_args:Nx \str_case:nnF { \tl_head:n {#1} }
+ {
+ { m } { \__unravel_print_meaning: \__unravel_prompt_aux: }
+ { q }
+ {
+ \int_gset_eq:NN \g__unravel_noise_int \c_minus_one
+ \int_gzero:N \g__unravel_nonstop_int
+ }
+ { x }
+ {
+ \group_end:
+ \exp_after:wN \__unravel_exit:w \__unravel_exit:w
+ }
+ { X } { \tex_batchmode:D \tex_end:D }
+ { s } { \__unravel_prompt_scan_int:nn {#1}
+ \__unravel_prompt_silent_steps:n }
+ { o } { \__unravel_prompt_scan_int:nn {#1}
+ { \int_gset:Nn \g__unravel_noise_int } }
+ { C }
+ {
+ \tl_gset_rescan:Nnx \g__unravel_tmpc_tl
+ { \ExplSyntaxOn } { \tl_tail:n {#1} }
+ \tl_gput_left:Nn \g__unravel_tmpc_tl
+ { \tl_gclear:N \g__unravel_tmpc_tl }
+ \group_insert_after:N \g__unravel_tmpc_tl
+ }
+ }
+ { \__unravel_prompt_help: }
+ }
+ }
+\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:
+ }
+\cs_new_protected:Npn \__unravel_prompt_scan_int_after:wn #1 \scan_stop: #2
+ {
+ #2 \l__unravel_prompt_tmpa_int
+ \tl_if_blank:nF {#1} { \__unravel_prompt_treat:n {#1} }
+ }
+\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 { "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 }
+ \__unravel_prompt_aux:
+ }
+\cs_new_protected:Npn \__unravel_prompt_silent_steps:n #1
+ {
+ \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}
+ }
+\cs_new_protected:Npn \unravel #1 { \__unravel_unravel:n {#1} }
+\cs_new_protected_nopar:Npn \UnravelDebug
+ {
+ \bool_set_true:N \l__unravel_debug_bool
+ }
+\cs_new_protected:Npn \__unravel_unravel:n #1
+ {
+ \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
+ \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:
+ \__unravel_main_loop:
+ \__unravel_exit_point:
+ \__unravel_print_outcome:
+ \bool_if:nTF
+ {
+ \tl_if_empty_p:N \g__unravel_if_limit_tl
+ && \int_compare_p:nNn \g__unravel_if_limit_int = \c_zero
+ && \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:
+ }
+\cs_new_protected_nopar:Npn \__unravel_bad_finish:
+ {
+ \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 }
+ { Extra~fi,~or,~or~else. }
+\msg_new:nnn { unravel } { missing-lbrace }
+ { Missing~left~brace~inserted. }
+\msg_new:nnn { unravel } { missing-dollar }
+ { Missing~dollar~inserted. }
+\msg_new:nnn { unravel } { unknown-expandable }
+ { Internal~error:~the~expandable~command~'#1'~is~not~known. }
+\msg_new:nnn { unravel } { missing-font-id }
+ { Missing~font~identifier.~\iow_char:N\\nullfont~inserted. }
+\msg_new:nnn { unravel } { missing-rparen }
+ { Missing~right~parenthesis~inserted~for~expression. }
+\msg_new:nnn { unravel } { incompatible-units }
+ { Mu~glue/dimen~used~as~a~normal~glue/dimen~or~vice-versa. }
+\msg_new:nnn { unravel } { missing-mudim }
+ { Missing~mu~unit. }
+\msg_new:nnn { unravel } { missing-cs }
+ { Missing~control~sequence.~\iow_char:N\\inaccessible~inserted. }
+\msg_new:nnn { unravel } { missing-box }
+ { Missing~box~inserted. }
+\msg_new:nnn { unravel } { missing-to }
+ { Missing~keyword~'to'~inserted. }
+\msg_new:nnn { unravel } { improper-leaders }
+ { Leaders~not~followed~by~proper~glue. }
+\msg_new:nnn { unravel } { extra-close }
+ { Extra~right~brace~or~\iow_char:N\\endgroup. }
+\msg_new:nnn { unravel } { off-save }
+ { Something~is~wrong~with~groups. }
+\msg_new:nnn { unravel } { hrule-bad-mode }
+ { \iow_char\\hrule~used~in~wrong~mode. }
+\msg_new:nnn { unravel } { invalid-mode }
+ { Invalid~mode~for~this~command. }
+\msg_new:nnn { unravel } { color-stack-action-missing }
+ { Missing~color~stack~action. }
+\msg_new:nnn { unravel } { action-type-missing }
+ { Missing~action~type. }
+\msg_new:nnn { unravel } { identifier-type-missing }
+ { Missing~identifier~type. }
+\msg_new:nnn { unravel } { destination-type-missing }
+ { Missing~destination~type. }
+\msg_new:nnn { unravel } { erroneous-prefixes }
+ { Prefixes~appplied~to~non-assignment~command. }
+\msg_new:nnn { unravel } { improper-setbox }
+ { \iow_char:N\\setbox~while~fetching~base~of~an~accent. }
+\msg_new:nnn { unravel } { after-advance }
+ {
+ Missing~register~after~\iow_char:N\\advance,~
+ \iow_char:N\\multiply,~or~\iow_char:N\\divide.
+ }
+\msg_new:nnn { unravel } { bad-unless }
+ { \iow_char:N\\unless~not~followed~by~conditional. }
+\msg_new:nnn { unravel } { missing-endcsname }
+ { Missing~\iow_char:N\\endcsname~inserted. }
+\msg_new:nnn { unravel } { runaway-if }
+ { Runaway~\iow_char:N\\if... }
+\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. }
+\msg_new:nnn { unravel } { not-implemented }
+ { The~following~feature~is~not~implemented:~'#1'. }
+%%
+%%
+%% End of file `unravel.sty'.
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index 957c6d904cd..e442464e1cf 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -485,7 +485,7 @@ my @TLP_working = qw(
umthesis umtypewriter
unamthesis underlin underoverlap underscore undolabl
uni-wtal-ger uni-wtal-lin unicode-math unisugar units unitsdef universa
- unswcover
+ unravel unswcover
uothesis uowthesis uowthesistitlepage upca upmethodology upquote
uri url urlbst urwchancal usebib ushort uspatent
ut-thesis uwmslide uwthesis
diff --git a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
index 32bff2e30ed..261b918f3a9 100644
--- a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
@@ -851,6 +851,7 @@ depend underlin
depend underoverlap
depend undolabl
depend units
+depend unravel
depend upmethodology
depend upquote
depend uri
diff --git a/Master/tlpkg/tlpsrc/unravel.tlpsrc b/Master/tlpkg/tlpsrc/unravel.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/unravel.tlpsrc