我不确定为什么下面的代码会导致问题。
\documentclass{article}
\usepackage{array}
\newcommand{\startStatBlock}[1]
{#1 \arraybackslash}
\newcommand{\stopStatBlock}
{\arraybackslash}
\newenvironment{statBlock}[1]
{\startStatBlock{#1}}
{\stopStatBlock}
\begin{document}
% This works just fine.
\begin{tabular}{ll}
\startStatBlock{thing}
stat one & 2 \\
stat two & 2 \\
\stopStatBlock
\end{tabular}
% The following fails with the following message:
% ! Extra }, or forgotten \endgroup.
% <recently read> \egroup
% l.22 \end{tabular}
\begin{tabular}{ll}
\begin{statBlock}{Some Stats}
stat one & 2 \\
stat two & 2 \\
\end{statBlock}
\end{tabular}
\end{document}
如果之前已经讨论过这个问题,我很抱歉,但我找不到直接相关的问题。我不确定这两者之间有什么区别。
我想使用环境的原因是为了让我的文档的语义结构更清晰,所以我更喜欢使用环境而不是命令来启动和停止环境。另外,这只是一个简化的示例,用于隔离错误;理想情况下,在最终产品中,环境statBlock
和类似环境中会有很多表示逻辑,环境内的内容主要是信息,没有太多用于指定外观的内容。
答案1
通过撤消由 so 添加的隐式分组,可以使环境语法不出现错误,\begin
\end
例如
\documentclass{article}
\newcommand{\startStatBlock}[1]
{#1 \arraybackslash}
\newcommand{\stopStatBlock}
{\arraybackslash}
\makeatletter
\newenvironment{statBlock}[1]
{\endgroup\startStatBlock{#1}}
{\stopStatBlock\begingroup\def\@currenvir{statBlock}}
\makeatother
\usepackage{array}
\begin{document}
% This works just fine.
\begin{tabular}{ll}
\startStatBlock{thing}
stat one & 2 \\
stat two & 2 \\
\stopStatBlock
\end{tabular}
% The following fails with the following message:
% ! Extra }, or forgotten \endgroup.
% <recently read> \egroup
% l.22 \end{tabular}
\begin{tabular}{ll}
\begin{statBlock}{Some Stats}
stat one & 2 \\
stat two & 2 \\
\end{statBlock}
\end{tabular}
\end{document}
但是,由于每个表格单元格都是一个组,因此该环境不能作为环境工作,例如在环境开始时,您有
#1 \arraybackslash
但是\arraybackslash
没有任何用处,因为它只是设置\\
为结束表格行,然而第二列需要这个,但是这个定义被丢弃,所以&
它只在第一列的第一个单元格中有效。