среда, похожая на дословную, с необязательными аргументами, ведет себя плохо

среда, похожая на дословную, с необязательными аргументами, ведет себя плохо

[ОТРЕДАКТИРОВАНО, чтобы показать, где я на самом деле хочу использовать необязательный аргумент]

На этот вопрос можно ответить по адресуКак передать необязательный аргумент в среду с дословным содержимым?, но мне трудно применить этот ответ к моей проблеме. Я удалю этот запрос, если он будет сочтен дублирующим.

Когда я использую среду, подобную дословной, которая принимает необязательный аргумент (vb в MWE ниже), то в случаях, когда необязательный аргумент не указан, первый токен в среде иногда выполняется за пределами среды.

\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 перед разбором аргументов. После того, как символ был токенизирован, значения catcode, установленные verbatim, не имеют никакого эффекта, поскольку catcodes не влияют на токены после их создания, они только определяют, как токены создаются из входного файла.

В

\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
}

Связанный контент