在 \newenvironment 内使用列分隔符 & (& 符号)

在 \newenvironment 内使用列分隔符 & (& 符号)

我想定义一个语法环境基本上包裹了一个表格环境。在语法环境我想使用一个名为生产插入行。例如:

\documentclass[a4paper,10pt]{文章}

\newenvironment{生产}[1]
{\noindent\ignorespaces#1 ::= &}
{\\}

\newenvironment{语法}
{\begin{表格}{p{3cm}l}}
{\end{表格}}

\开始{文档}
\开始{语法}
\开始{生产}{XmlStartTag}
  ...
\结束{生产}
\开始{生产}{XmlEndTag}
  ...
\结束{生产}
\结束{语法}

\结束{文档}

该代码的目标是将正在定义的非终端的名称放入表格的左列中,并将实际生成放入表格的右列中。

&不幸的是\\,由于生产环境。我猜这与宏扩展有关。我猜我必须用仅在使用宏后才扩展的东西来逃避&and ?\\

谢谢!

答案1

问题在于\begin{...}\end{...}对命令会自动创建一个“组”,这样,实际上和&对于\\表格来说“超出了范围”,而在“生产”环境中,它们只是出现在编译器意想不到的地方。

您的定义的第二个问题是,即使它们可以工作,它们也会\\在表格末尾添加一个额外的内容,在末尾添加一个不必要的空格。也许一些更合适的定义是

\documentclass[a4paper,10pt]{article}

\newcommand{\production}[1]{#1 ::= &}
\newenvironment{grammar}{\tabular{p{3cm}l}}{\endtabular}

\begin{document}
\begin{grammar}
\production{XmlStartTag} ... \\
\production{XmlOtherTag} ... \\
\production{XmlEndTag} ...
\end{grammar}
\end{document}

注意\\最后一个产生式末尾的 no。此外,在 的定义中,grammar您不需要重复\begin/的工作\end,而可以直接使用\tabularand \endtabular

答案2

编辑:这个答案完全错误;向那些投票赞成的人表示抱歉。

我在尝试解决时发现了一个技巧这个问题。您可以使用该environ包并定义production环境,如下所示:

\usepackage{environ}
\NewEnviron{production}[1]{%
  \toks0={\noindent\ignorespaces#1 ::= &}%
  \toks2=\expandafter{\BODY}%
  \toks4={\\}%
  \xdef\gtemp{\the\toks0 \the\toks2 \the\toks4 }%
  \aftergroup\gtemp
}

\BODY是环境的内容。代码的工作原理如下:将 存储\noindent\ignorespaces#1 ::= &到标记寄存器中\toks0,然后将\BODY(扩展的\expandafter)存储到 中\toks2,并将尾随代码存储\\到 中\toks4。将所有内容一起放入全局标记列表 中\gtemp\xdef扩展\the\toks0\the\toks2\the\toks4(数字后的空格很重要)。最后,\aftergroup\gtemp将 放置\gtemp在 形成的组的末尾之后\begin{production}...\end{production},以便该组不会干扰表格生成的组。请参阅答案问题我上面提到过。

有两个问题想问更有经验的 TeXers:我可以用什么\unexpanded方法做得更好?有没有好的方法可以执行很多事情\aftergroup:我讨厌必须进行\gtemp全局定义。

答案3

它与宏扩展无关,但与分组有关:表格中的单元格组成一个组。您正在一个组中启动一个环境,然后在下一个组中关闭它。最好使用命令 \production。

答案4

我想有单独的产品1产品生产命令将允许自动插入 \\:make产品在前面添加 \\。

相关内容