![带有可选参数的逐字环境表现不佳](https://linux22.com/image/266534/%E5%B8%A6%E6%9C%89%E5%8F%AF%E9%80%89%E5%8F%82%E6%95%B0%E7%9A%84%E9%80%90%E5%AD%97%E7%8E%AF%E5%A2%83%E8%A1%A8%E7%8E%B0%E4%B8%8D%E4%BD%B3.png)
[已编辑以显示我实际想要使用可选参数的位置]
这个问题可以在如何将可选参数传递给具有逐字内容的环境?,但我很难将该答案应用于我的问题。如果该查询被视为重复,我将删除它。
当我使用采用可选参数(下面 MWE 中的 vb)的类似逐字的环境时,在未指定可选参数的情况下,环境中的第一个标记有时会在环境之外执行。
\documentclass{article}
\usepackage{verbatim}
\parskip 1ex\parindent 0em
\makeatletter
\newenvironment{va}{%
\def\verbatim@processline{%
{\setbox0=\hbox{\the\verbatim@line}%
\hsize=\wd0 \the\verbatim@line\par}}%
\setbox0=\vbox\bgroup \verbatim
}
{%
\endverbatim
\unskip\setbox0=\lastbox %
\egroup
\usebox0
}
\newenvironment{vb}[1][]{%
\def\verbatim@processline{%
{\setbox0=\hbox{\the\verbatim@line}%
\hsize=\wd0 \the\verbatim@line\par}}%
\setbox0=\vbox\bgroup #1 \verbatim
}
{%
\endverbatim
\unskip\setbox0=\lastbox %
\egroup
\usebox0
}
\makeatother
\begin{document}
I created two environments based on \verb|boxedverbatim| environment.
Environment \verb|va| takes no arguments. Environment \verb|vb| is
identical but takes an optional argument (which is not actually used for
anything in this MWE). In all the following cases, no optional argument
is actually passed to the \verb|vb| environment
Starting either environment with a letter works:
\begin{va}I will set \def\x{1}\end{va}
\begin{vb}I will set \def\x{1}\end{vb}
But if I start the environments with a command like \verb|\Huge|, the
\verb|vb| environment executes that command outside the environment, even
though it was not in brackets:
\begin{va}\Huge I will set \def\x{1}\end{va}
\begin{vb}\Huge I will set \def\x{1}\end{vb}
If I start the verbatim with a \verb|\def|, the \verb|vb|
environment breaks
\begin{va}\def\x{1}\end{va}
%\begin{vb}\def\x{1}\end{vb}
\end{document}
答案1
对于所有 verbatim 命令,您需要在解析参数之前切换 catcode 机制。一旦字符被标记化,verbatim 设置的 catcode 值将不起作用,因为 catcode 不会影响已创建的标记,它们仅决定如何从文件输入创建标记。
在
\begin{vb}\Huge
\vb
看看下一个令牌看看它是否是[
。TeX 必须读取文件来生成下一个标记,因此读取所有内容\Huge
并生成 cs 标记,之后 catcode 的任何设置都只会影响从文件中读取的字符;它们不会影响 Huge
。
您只需在设置 catcodes 后解析参数:
\newcommand\innervb[1][]{}
\newenvironment{vb}{%
\def\verbatim@processline{%
{\setbox0=\hbox{\the\verbatim@line}%
\hsize=\wd0 \the\verbatim@line\par}}%
\setbox0=\vbox\bgroup \verbatim\innervb
}
{%
\endverbatim
\unskip\setbox0=\lastbox %
\egroup
\usebox0
}