每当我尝试与和\textbf
交互时,都会收到错误。这是一个 MWE,它在调用结束时给出和(缺少的控制序列原来是)。使用代替 可以按预期工作。pgffor
xparse
ERROR: Extra \else
ERROR: Missing control sequence inserted
\coljoin
\inaccessible
\flang
\textbf
\usepackage{pgffor}
\newcommand{\coljoin}[1]{%
\let\acc\empty%
\foreach \x in #1 {%
\xdef\acc{\acc & \textbf{\x}}}%
\acc}
\newcommand{\llist}{a,b,c,d,e}
\newcommand{\flang}[1]{#1+1}
\begin{tabular}{cccccc}
\coljoin{\llist}
\end{tabular}
是否有人了解与\textbf
编程实用程序交互的操作?
实际目标是获得一些数据列表,这些数据的更改会在整个文档中传播,而无需我进行额外的列计数等。我想用这种方式将生成的一些行加粗。我最欣赏的解决方案是允许在\coljoin
数据连接之前采用映射到数据上的可选参数(即调用为\coljoin[\textbf]{\llist}
或\coljoin[\flang]{\llist}
)。
额外尝试:我尝试使用相同的累加器策略,但使用\multido
和docsvlist
。它们对于非粗体值都表现正常,而\inaccessible
对于粗体值则给出错误。
答案1
您必须使用\protected@xdef
:
如下定义的第一个参数\coljoin
可用于传入需要为每个条目执行的宏。它默认只传递单元格数据,而不进行任何额外处理。
参考:
代码:
\documentclass{article}
\usepackage{pgffor}
\makeatletter
\newcommand{\coljoin}[2][]{%
\let\acc\empty%
\foreach \x in #2 {%
\protected@xdef\acc{\acc & #1{\x}}}%
\acc}
\makeatother
\newcommand{\llist}{a,b,c,d,e}
\newcommand{\flang}[1]{#1+1}
\begin{document}
\begin{tabular}{cccccc}
\coljoin{\llist} \\
\coljoin[\textbf]{\llist} \\
\coljoin[\flang]{\llist}
\end{tabular}
\end{document}
答案2
正如 Peter Grill 所解释的,错误在于拥有\xdef
;“健壮的”命令不喜欢在\edef
或里面\xdef
。
但是,您会得到一个虚假的第一列,因此您应该将其初始化\acc
为\@gobble
而不是\empty
。
\documentclass{article}
\usepackage{pgffor}
\makeatletter
\newcommand{\coljoin}[1]{%
\let\acc\@gobble
\foreach \x in #1 {%
\protected@xdef\acc{\acc &\textbf{\x}}}% <--- no space between & and \textbf
\acc}
\makeatother
\newcommand{\llist}{a,b,c,d,e}
\begin{document}
the ``explicit table''
\begin{tabular}{ccccc}
\bfseries a &
\bfseries b &
\bfseries c &
\bfseries d &
\bfseries e
\end{tabular}
some text above
\begin{tabular}{ccccc}
\coljoin{\llist}
\end{tabular}
some text below
\end{document}
\empty
而不是你\@gobble
需要在表格序言中添加一列,结果是
不同的策略是使用xparse
和expl3
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\coljoin}{ s m }
{
\IfBooleanTF { #1 }
{ \mdrop_coljoin:o { #2 } } % the *-variant expands once the argument
{ \mdrop_coljoin:n { #2 } }
}
\seq_new:N \l__mdrop_row_seq % this will contain row data
\cs_new_protected:Npn \mdrop_coljoin:n #1
{
\seq_clear:N \l__mdrop_row_seq
% add each item surrounded by \textbf{ and }
\clist_map_inline:nn { #1 } { \seq_put_right:Nn \l__mdrop_row_seq { \textbf{##1} } }
% deliver the items with & between them
\seq_use:Nn \l__mdrop_row_seq { & }
}
% this generates the `expanding once' variant
\cs_generate_variant:Nn \mdrop_coljoin:n { o }
\ExplSyntaxOff
\newcommand{\llist}{a,b,c,d,e}
\begin{document}
\begin{tabular}{ccccc}
\coljoin*{\llist} \\
\coljoin{a,b,c,d,e}
\end{tabular}
\end{document}
请注意,当命令在 的参数中使用时\coljoin
,*
必须使用 -variant。在我看来,这更清楚。