我正在尝试实现一个可以执行其参数并打印它的命令。
为此,我将参数转储到 toks 寄存器中,并使用 LuaTex 将其与非活动的 catcodes 一起放回;正如手册中所说:
tex.print(<number> n, <string> s, ...)
如果 n 为 −1,则使用当前活动的 catcode 机制。如果 n 为 −2,则生成的 catcode 为 \the\toks 的结果:除空格字符外,所有类别代码均为 12(其他),其类别代码为 10(空格)
\newcommand{\showandtell}[1]{\toks0{#1}%
{using the argument #1 executes}\\
{printing with current
\directlua{tex.print(-1, tex.toks[0])} executes}\\
{printing with inert \texttt{
\directlua{tex.print(-2, tex.toks[0])}} shows the code}\\
{reading the register \the\toks0 executes}
}
\noindent\showandtell{\bfseries\color{red}}
从手册中的“生成的 catcodes 是 \the\toks 的结果”来看,我期望\the\toks0
得到相反的效果。
print(-2
我怎样才能获得纯 TeX的效果?
令牌寄存器似乎被存储为一个字符串,丢弃了原始的 catcode,但是像 verbatim 这样的包如何才能只使用\the\verbatim@line
并产生简单的输出?
答案1
您可以在 e-TeX(而不是 Knuth TeX)中使用 获得相同的效果\detokenize
,当使用 LaTeX 时可用(在不超过十年的 TeX 发行版上)。
\documentclass{article}
\usepackage{color}
\newcommand{\showandtell}[1]{%
{using the argument #1 executes}\\%
printing with detokenize \texttt{\detokenize{#1}} shows the code%
}
\begin{document}
\noindent
\showandtell{\bfseries\color{red}}
\end{document}
如果您想使用令牌寄存器,那么\detokenize\expandafter{\the\toks0}
就可以了。
逐字模式通过在开始阅读材料之前更改类别代码来实现其目的,这就是为什么它们不能用作命令的参数的原因。但请注意,\detokenize
就像您使用的 LuaTeX 代码一样,在控制字后添加了一个空格(逐字模式不会这样做)。
答案2
也可以通过 在 Knuth TeX 中实现这一点。虽然如果可用的话\meaning
没有理由不使用。\detokenize
\documentclass{article}
\usepackage{color}
\makeatletter
\let\StripPrefix\strip@prefix % Latex kernel command
\makeatother
\newcommand{\showandtell}[1]{%
{using the argument #1 executes}\\%
\def\TEMP {#1}%
playing tricks with meaning \texttt{\expandafter\StripPrefix\meaning\TEMP} shows the code%
}
\begin{document}
\noindent
\showandtell{\bfseries\color{red}}
\end{document}
如果你想显示来自\toks0
寄存器的内容,你可以这样做
\expandafter\def\expandafter\TEMP\expandafter{\the\toks0}
或更简单
\edef\TEMP{\the\toks0}
然后就是那个\meaning
东西。