使用 \bgroup 和 \egroup 将一些前置和后置代码设置为宏

使用 \bgroup 和 \egroup 将一些前置和后置代码设置为宏

为什么不能以这种方式\bgroup使用?\egroup

\documentclass{article}

\def\precode{\fbox\bgroup}
\def\postcode{\egroup}

\newcommand{\mymacro}[1]{\precode#1\postcode}

\begin{document}
\mymacro{Text}
\end{document}

我知道我可以直接将参数存储到框中或\fbox在定义中使用笑脸\mymacro,但是这个 MWE 的应用有点复杂,所以这两种方式都行不通。现在我想知道为什么这段代码没有给出错误,也没有给出文本。

答案1

据我所知,只有少数命令(例如 TeX 框基元,如\hbox)可以像这样使用\bgroup\egroup例如:

\newcommand\premybox{\leavevmode\hbox\bgroup\bfseries(}
\newcommand\postmybox{)\egroup}

\premybox hello\postmybox

但是,\mbox\fbox以及其他宏不能这样使用。请参阅TeX Hacks 的博客\mbox和的新定义\fbox允许这种用法。


你可以使用environ包来获取两个宏之间的内容。这个更简单的 TeXnique 也很有用:

\def\precode #1\postcode{something about #1}

答案2

你不能,因为\fbox定义为

\newcommand\fbox[1]{%
  \leavevmode\setbox\@tempboxa\hbox{%
    \color@begingroup\kern\fboxsep{#1}\kern\fboxsep\color@endgroup}%
  \@frameb@x\relax}

\mymacro{Text}你一起做\precode Text\postcode会变成

\fbox\bgroup Text\egroup

但是\bgroup不是此处的参数分隔符:only明确的括号是。因此\bgroup被视为,#1并且您获得了错误的标记列表。

如果color包未加载,\color@begingroup并且\color@endgroup被定义为\relax,那么接下来得到的是

\leavevmode\setbox\@tempboxa\hbox{%
    \color@begingroup\kern\fboxsep{\bgroup}\kern\fboxsep\color@endgroup}%
  \@frameb@x\relax Text\egroup

在 内部\hbox\bgroup充当组分隔符,并由}紧挨着它的 匹配。最后一个\egroup关闭了\hbox{,因此这解释了为什么您没有得到任何输出。

如果color包被加载,\color@begingroup则变成\begingroup并且\color@endgroup变成\endgraf\endgroup;如果您尝试,您将收到一个错误,因为组没有正确平衡。

答案3

\precode你可以通过向 TeX 撒谎,让他误解你的和 的意思\postcode

\documentclass{article}

% egreg's clever macros
\def\obrace{\iftrue{\else}\fi}
\def\cbrace{\iffalse{\else}\fi}

\def\precode#1\postcode{%
 \edef\next{\noexpand\fbox\obrace\unexpanded{#1}\cbrace}%
 \next
}

\newcommand{\mymacro}[1]{\precode#1\postcode}

\begin{document}
 \mymacro{Text}
\end{document}

相关内容