这个问题分为两部分。我主要想实现一个\newcommand
可以接受任意数量的参数并将它们设置在矩阵的单个列中的函数。
我尝试了以下操作,但是它引发了缺失\endgroup
错误(这似乎是的结果\\
,因为取出\\
可以消除错误,但没有达到预期的结果):
\documentclass{article}
\usepackage{pgffor}
\usepackage{amsmath}
\newcommand*{\Features}[1]{%
\(%
\begin{bmatrix}%
\foreach \entry in {#1} {\text{\entry}\\}
\end{bmatrix}%
\)%
}
\begin{document}
\Features{--ACC, +PL}
\end{document}
有没有简单的方法可以解决这个问题并使其按预期工作?
问题的第二部分是为什么发生了这种情况。出于学习目的以及为了将来能够编写更好的宏,我很好奇,但我一直无法弄清楚是什么导致了缺失错误\endgroup
。
答案1
Enrico Gregorio 已经在他的评论:
\foreach
将其循环主体放在一个组中。这与矩阵环境的单元分组相冲突。另一个问题是,如果行尾后有不可展开的内容(组尾、\relax
……),则会创建一个新的(空)行。
下面使用循环来定义\MatrixBody
包含矩阵行的。链\expandafter
展开\entry
一次。否则宏\MatrixBody
将包含\entry
每个矩阵行,循环后未定义。
全局赋值仅用于\g@addto@macro
允许向宏添加内容的 LaTeX 内核。(局部变量由包定义,例如ltxcmds
)。
\documentclass{article}
\usepackage{pgffor}
\usepackage{amsmath}
\makeatletter
\newcommand*{\Features}[1]{%
\global\let\MatrixBody\@empty
\foreach \entry in {#1} {%
\expandafter\g@addto@macro\expandafter\MatrixBody
\expandafter{%
\expandafter\text\expandafter{\entry}\\%
}%
}%
\(%
\begin{bmatrix}%
\MatrixBody
\end{bmatrix}%
\)%
}
\makeatother
\begin{document}
\Features{--ACC, +PL}
\end{document}
答案2
问题是\foreach
执行组中的每个循环。所以在你的情况下你基本上是在做
\(
\begin{bmatrix}
\begingroup\text{--ACC}\\\endgroup
\begingroup\text{+PL}\\\endgroup
\end{bmatrix}
\)
这确实停止了
! Missing \endgroup inserted.
<inserted text>
\endgroup
您必须事先构建矩阵的内容。另外,使用不分组的循环过程无论如何都是一场失败的战斗,因为表格单元格也会按组进行评估并\\
结束它。
这是一个expl3
基于的宏。
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
% the user level command
\NewDocumentCommand{\Features}{ m }
{
\adam_features:n { #1 }
}
% a variable
\seq_new:N \l_adam_items_seq
% the programmer level function
\cs_new_protected:Npn \adam_features:n #1
{
% clear the sequence
\seq_clear:N \l_adam_items_seq
% do a mapping on the comma list separated input
% adding the item between \mathrm{ and }
\clist_map_inline:nn { #1 }
{
\seq_put_right:Nn \l_adam_items_seq { \mathrm { ##1 } }
}
\(
\begin{bmatrix}
% deliver the items separated by \\
\seq_use:Nn \l_adam_items_seq { \\ }
\end{bmatrix}
\)
}
\ExplSyntaxOff
\begin{document}
\Features{-ACC, +PL}
\end{document}
请注意,我使用\mathrm
而不是\text
;但这是个人选择。
答案3
pgffor
我相信我已经找到了一种比目前给出的解决方案更简单的替代方案。它使用\forcsvlist
来自etoolbox
,这似乎不会受到中的分组问题的影响pgffor
。
\documentclass{minimal}
\usepackage{amsmath}
\usepackage{etoolbox}
\newcommand*{\textmatrixline}[1]{\text{#1}\\}
\newcommand*{\bigsqbr}[1]{%
\(%
\begin{bmatrix}%
\forcsvlist{\textmatrixline}{#1}
\end{bmatrix}%
\)%
}
\begin{document}
\bigsqbr{--ACC, +PL}
\end{document}