Discussion:
newenvironment with optional arg
(too old to reply)
Tim Arnold
2005-10-12 15:51:03 UTC
Permalink
This minimal example shows how newenvironment behaves with and without an
optional argument in its definition. I've read the FAQ and googled, but I
still don't understand this.
The first example displays 'BEGIN_these are three ... etc.' (_=space)
The second displays 'BEGINthese are three ... etc.'

==========================
\documentclass{book}
\begin{document}
\newenvironment{code}{BEGIN}{END}

hi

\begin{code}
these are three
lines that are
indented \textit{three} spaces.
\end{code}

there

\renewenvironment{code}[1][]{BEGIN}{END}

\begin{code}
these are three
lines that are
indented \textit{three} spaces.
\end{code}

bye

\end{document}
=====================

fyi, what I had originally desired was the following environment, using
memoir.cls:
--------------------------------------
\newenvironment{code}[1][small]{%
\setverbatimfont{\csname#1\endcsname\ttfamily\bfseries}%
\verbatim}
{\endverbatim}
-------------------------------------
in which case beginning spaces in the 'code' first line are ignored.

thanks,
--Tim Arnold
Heiko Oberdiek
2005-10-12 19:33:32 UTC
Permalink
Post by Tim Arnold
The first example displays 'BEGIN_these are three ... etc.' (_=space)
The second displays 'BEGINthese are three ... etc.'
\renewenvironment{code}[1][]{BEGIN}{END}
\begin{code}
these are three
The LaTeX code for an optional argument looks for the argument and
calls \***@ifnextchar (\@ifnextchar). This command eats up spaces,
see latex/base/ltdefns.dtx:

% \DescribeMacro
% {\@ifnextchar} X\marg{YES}\marg{NO}\\
% Expands to \meta{YES} if next character is an `X',
% and to \meta{NO} otherwise.
% (Uses |\***@a|--|\***@c|.)
% NOTE: GOBBLES ANY SPACE FOLLOWING IT.
Post by Tim Arnold
fyi, what I had originally desired was the following environment, using
--------------------------------------
\newenvironment{code}[1][small]{%
\setverbatimfont{\csname#1\endcsname\ttfamily\bfseries}%
\verbatim}
{\endverbatim}
-------------------------------------
in which case beginning spaces in the 'code' first line are ignored.
\verbatim changes catcodes, however the lookahead for the
optional argument is done before, thus you can end up with
a token of wrong catcode (macro, active character, ...).

\makeatletter
\renewenvironment{code}{%
\obeylines
\let\do\@makeother
\dospecials
\catcode`\ =\active % space token is active in
% memoir's verbatim
\***@bs
\catcode`\^^I=\active % tab token if \tabson
\fi
\futurelet\@***@token\@code}{\endverbatim}
\newcommand*{\@code}{%
\ifx\@***@token[%
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\@@code}{\@@code[small]}%
}
\def\@@code[#1]{%
\setverbatimfont{%
\@nameuse{#1}%
\ttfamily
\bfseries
}%
\verbatim
}
\makeatother

Yours sincerely
Heiko <***@uni-freiburg.de>
Tim Arnold
2005-10-13 15:25:35 UTC
Permalink
Post by Heiko Oberdiek
Post by Tim Arnold
The first example displays 'BEGIN_these are three ... etc.' (_=space)
The second displays 'BEGINthese are three ... etc.'
\renewenvironment{code}[1][]{BEGIN}{END}
\begin{code}
these are three
The LaTeX code for an optional argument looks for the argument and
% \DescribeMacro
% Expands to \meta{YES} if next character is an `X',
% and to \meta{NO} otherwise.
% NOTE: GOBBLES ANY SPACE FOLLOWING IT.
Post by Tim Arnold
fyi, what I had originally desired was the following environment, using
--------------------------------------
\newenvironment{code}[1][small]{%
\setverbatimfont{\csname#1\endcsname\ttfamily\bfseries}%
\verbatim}
{\endverbatim}
-------------------------------------
in which case beginning spaces in the 'code' first line are ignored.
\verbatim changes catcodes, however the lookahead for the
optional argument is done before, thus you can end up with
a token of wrong catcode (macro, active character, ...).
\makeatletter
\renewenvironment{code}{%
\obeylines
\dospecials
\catcode`\ =\active % space token is active in
% memoir's verbatim
\catcode`\^^I=\active % tab token if \tabson
\fi
\else
\fi
}
\setverbatimfont{%
\ttfamily
\bfseries
}%
\verbatim
}
\makeatother
Yours sincerely
Thanks Heiko: An explanation of why my code didn't work as expected, and
working code for my particular situation.

I appreciate your taking the time to help. I see now why things work that
way (I had thought at first that I'd found a bug); now I'm parsing out your
code so I can understand. It's working in the meantime--thanks very much.

--Tim Arnold

Loading...