你好,接下来是以下问题使用 pgfplotstable 的多行标题,解决方案是单独设置每个受影响的单元格。我决定拼凑一个命令来做到这一点,但不断遇到错误Argument of \reserved@a has an extra }. <inserted text> \par
我正在使用的代码片段如下 -
\DeclareRobustCommand{\pgfplotstableeach}[4][1]{
\foreach \col in {#1,...,#2}
\foreach \ro in {0,...,#3}
{\ifthenelse{\col=#2 \AND \ro=#3}{every row \ro\ column \col/.style=\{#4\}}{every row \ro\ column \col/.style=\{#4\},}}
}
这在环境之外生成文本很有效,pgfplotstabletypeset
但在环境内部却失败了。
我已尝试过\newcommand
,\newcommand{\protect\pgfplotstableeach}{<macro>}
但都没有用。
如果我用我想要输入的文本替换宏,例如,"every row 0 column 1/.style=..."
它会失败并显示Missing \endcsname inserted. <to be read again> \protect
。我实际上认为这会相当简单,但我对错误完全感到困惑。
我究竟做错了什么?
编辑以包括下面的 MWE
\documentclass{article}
\usepackage{array,datatool,pgfplotstable}
\begin{filecontents}{sample.csv}
item,2008,2009,2010,2011
,Actual,Actual,Forecast,Forecast
,GBP,GBP,GBP,GBP
,('000),('000),('000),('000) rounded
Area 1 OP, 1000000,1500000,1750000,250000
Area 2 OP, 400000,500000, 450000,-50000
Area 51 OP, 300000,375000,390000,15000
No P, 1250000, 1000000, 950000, 50000
Residuals, 800000, 80000, 90000, 10000
\end{filecontents}
\DeclareRobustCommand{\pgfplotstableeach}[4][1]{
\foreach \col in {#1,...,#2}
\foreach \ro in {0,...,#3}
{\ifthenelse{\col=#2 \AND \ro=#3}
{every row \ro\ column \col/.style=\{#4\}}
{every row \ro\ column \col/.style=\{#4\},}}
}
\begin{document}
\pgfplotstableread[col sep=comma,header=false]{sample.csv}\mystuff
\pgfplotstabletypeset[fixed,
\pgfplotstableeach{4}{4}{string type}]\mystuff
\end{document}
答案1
您的示例依赖于对 TeX/PGF 中扩展工作方式的非法假设。 在您的特定情况下,它存在两个问题:
\foreach
失去一切除非您明确将其声明为全局变量,否则该变量已在内部设置。对于您的情况,它会失去所有选项。您不能直接在选项列表内执行自定义宏。
(1.) 的解决方案是将所有选项收集到一个巨大的(全局!)列表中,并在语句之后执行它\foreach
。
(2.) 的解决方案是在 之前设置所有这些选项\pgfplotstabletypeset
。您可以用花括号将完整的语句括起来:这将限定效果(就像 内部一样\foreach
)。
有趣的是,(1.) 的解决方案比听起来要复杂得多。这是因为 TeX 的扩展与你可能遇到的几乎所有其他扩展都不同。
这是一个解决方案。你可能想决定是否要学习扩展控制的细节(即“什么是\toks*
?”或“什么是\expandafter
?”之类的问题),方法是研究http://pgfplots.sourceforge.net/TeX-programming-notes.pdf
\documentclass{article}
\usepackage{array,datatool,pgfplotstable}
\begin{filecontents}{sample.csv}
item,2008,2009,2010,2011
,Actual,Actual,Forecast,Forecast
,GBP,GBP,GBP,GBP
,('000),('000),('000),('000) rounded
Area 1 OP, 1000000,1500000,1750000,250000
Area 2 OP, 400000,500000, 450000,-50000
Area 51 OP, 300000,375000,390000,15000
No P, 1250000, 1000000, 950000, 50000
Residuals, 800000, 80000, 90000, 10000
\end{filecontents}
\newcommand{\pgfplotstableeach}[4][1]{
\xdef\ACCUM{}%
\foreach \col in {#1,...,#2} {%
\foreach \ro in {0,...,#3}
{%
\toks0=\expandafter{\ACCUM}%
\edef\temp{every row \ro\space column \col/.style}%
\toks1={#4}%
\xdef\ACCUM{\the\toks0 \temp={\the\toks1},}%
}%
}%
\message{setting \meaning\ACCUM^^J}%
\expandafter\pgfplotstableset\expandafter{\ACCUM},
}
\begin{document}
\pgfplotstableread[col sep=comma,header=false]{sample.csv}\mystuff
\pgfplotstableeach{4}{4}{string type}
\pgfplotstabletypeset[fixed,]\mystuff
\end{document}
请注意,该示例不完整;它会导致编译失败(因为只有选定的单元格才有string type
)。