% visualtoks.tex, version 1.1 % Copyright (C) 2025 plante % This package is released under the LaTeX Project Public License (LPPL) 1.3c. % visualtoks: typeset TeXbook-style visualisations of token lists. % Usage: `\visualtoks { }` % This package may be used in plain TeX or LaTeX by `\input{visualtoks}`. % See the documentation for typeset examples and caveats. \ifdefined\visualtoks \expandafter\endinput \fi \edef\next{\catcode`\noexpand\@=\the\catcode`\@\space} \catcode`\@=11 \long\def\visualtoks@firstoftwo#1#2{#1} \long\def\visualtoks@secondoftwo#1#2{#2} % \visualtoks@cycle { tokens } % Apply \visualtoksA to each token in tokens. Space tokens, left and right braces % are replaced with \visualtoks@cycle@space, \visualtoks@cycle@bgroup, and % \visualtoks@cycle@egroup respectively. Expandable. \long\def\visualtoks@cycle#1{\iffalse{\fi\visualtoks@cycleA#1{\visualtoks@cycle@nil}\visualtoks@cycle@nil\iffalse}\fi} \long\def\visualtoks@cycleA#1#{% \visualtoks@cycleB\visualtoks@cycleC#1 \visualtoks@cycle@nil \visualtoks@cycle@nil \visualtoks@cycleD } \long\def\visualtoks@cycleB#1#2 #3\visualtoks@cycle@nil{% \if\relax\detokenize{#3}\relax \expandafter\visualtoks@firstoftwo \else \expandafter\visualtoks@secondoftwo \fi {#1#2\visualtoks@cycle@nil}% {\visualtoks@cycleB#1#2\visualtoks@cycle@space#3\visualtoks@cycle@nil}% } \long\def\visualtoks@cycleC#1{% \ifx\visualtoks@cycle@nil#1\visualtoks@cycleF\fi \visualtoksA{#1}\visualtoks@cycleC } \long\def\visualtoks@cycleD#1{% \if\relax\detokenize\expandafter{\visualtoks@cycleE#1\visualtoks@cycle@nil}\relax \else \visualtoks@cycleF \fi \visualtoksA\visualtoks@cycle@bgroup \visualtoks@cycle{#1}% \visualtoksA\visualtoks@cycle@egroup \visualtoks@cycleA } \long\def\visualtoks@cycleE#1\visualtoks@cycle@nil{} \long\def\visualtoks@cycleF#1\visualtoks@cycle@nil{\fi} \protected\def\visualtoks@cycle@bgroup{\noexpand\visualtoks@cycle@bgroup} \protected\def\visualtoks@cycle@egroup{\noexpand\visualtoks@cycle@egroup} \protected\def\visualtoks@cycle@space {\noexpand\visualtoks@cycle@space} \protected\def\visualtoks@cycle@nil{\noexpand\visualtoks@cycle@nil} \newdimen\visualtokssep \visualtokssep=1em \protected\long\def\visualtoks#1{% \begingroup \leavevmode \ifcsname ttfamily\endcsname \ttfamily \else \tt \fi \m@th \hskip-\visualtokssep \visualtoks@cycle{#1}% \endgroup } \long\def\visualtoksA#1{% \hskip\visualtokssep \ifx\visualtoks@cycle@space#1% \char`\ $_{10}$% \else\ifx\visualtoks@cycle@bgroup#1% \char`\{$_1$% \else\ifx\visualtoks@cycle@egroup#1% \char`\}$_2$% \else \escapechar`\\% \edef\tempa{\string#1}% \escapechar\m@ne \edef\tempb{\string#1}% \ifx\tempa\tempb \expandafter\visualtoks@firstoftwo \else \expandafter\visualtoks@secondoftwo \fi {\string#1$_{% \let~\empty \lccode`~=`#1\lowercase{\let~}\empty \ifcat$\noexpand#13\fi \ifcat &\noexpand#14\fi \ifcat##\noexpand#16\fi \ifcat ^\noexpand#17\fi \ifcat _\noexpand#18\fi \ifcat\space\noexpand#110\fi \ifcat a\noexpand#111\fi \ifcat !\noexpand#112\fi \ifcat\noexpand~\noexpand#113\fi }$}% {\visualtoksB{\string#1}% \long\expandafter\def\expandafter\tempa\expandafter##\expandafter1\csname\string#1\endcsname{}% \if\relax\detokenize\expandafter\expandafter\expandafter {\expandafter\tempa\expandafter#1\csname\string#1\endcsname}\relax *\fi }% \fi\fi\fi } \long\def\visualtoksB#1{% \hbox{% \vrule \vtop{% \vbox{% \hrule \kern\p@ \hbox{\vphantom/\thinspace#1\thinspace}% }% \kern\p@ \hrule }% \vrule }% } \next \endinput