
[EDITADO para mostrar onde eu realmente quero usar o argumento opcional]
Esta pergunta pode ser respondida emComo passar um argumento opcional para um ambiente com conteúdo literal?, mas estou tendo dificuldade em tentar aplicar essa resposta ao meu problema. Excluirei esta consulta se ela for considerada duplicada.
Quando utilizo um ambiente literal que recebe um argumento opcional (vb no MWE abaixo), então, para casos em que nenhum argumento opcional é especificado, o primeiro token no ambiente às vezes é executado fora do ambiente.
\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}
Responder1
Como para todos os comandos literais, você precisa mudar o regime do código de gato antes de analisar os argumentos. Depois que um caractere é tokenizado, os valores de catcode definidos literalmente não têm efeito, pois os catcodes não afetam os tokens uma vez criados, eles apenas determinam como os tokens são criados a partir da entrada do arquivo.
Em
\begin{vb}\Huge
\vb
olha para o próximosímbolopara ver se é [
. O TeX precisa ler o arquivo para gerar o próximo token, então lê tudo \Huge
e cria um token cs, após o qual qualquer configuração do catcode afeta apenas os caracteres que são lidos do arquivo; eles não afetam o Huge
.
Você só precisa analisar os argumentos depois de configurar os 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
}