datatool
我尝试使用包和命令获取交替着色的行(就像图中所示的表格一样)\rowcolor
。我按照数据工具用户手册中条纹表的示例进行操作,但效果并不十分清晰。对我来说,问题是如何为第一行着色,因为手册并没有真正处理这个问题。
它看起来像、、\rowcolor
并且本身具有某些我无法完全理解的规则。\DTLifoddrow
\DTLiffirstrow
\DTLiflastrow
有没有更紧凑的方法来做到这一点?我的意思是,为什么不能在循环内调用所有 \rowcolor 语句?
\documentclass{article}
\usepackage[table]{xcolor}
\usepackage{datatool}
\begin{filecontents*}{data.csv}
position
first
second
third
fourth
\end{filecontents*}
\DTLloaddb{rows}{data.csv}
\begin{document}
\begin{tabular}{c}
\hline
\rowcolor{orange} % <- redundant? really needed?
\DTLforeach*{rows}{\word=position}{
\word%
\DTLiflastrow{}{\\\DTLifoddrow{\rowcolor{gray}}{\rowcolor{orange}}}%
}
\\ \hline
\end{tabular}
\end{document}
答案1
由于您的目标似乎是减少冗余,我建议使用类似这样的方法,或者使用下面给出的更灵活的变体:
\RequirePackage{filecontents}
\begin{filecontents*}{data.csv}
position
first
second
third
fourth
\end{filecontents*}
\documentclass{article}
\usepackage[table]{xcolor}
\usepackage{datatool}
\colorlet{OddRowColor}{orange}%
\colorlet{EvenRowColor}{gray!20}%
\DTLloaddb{rows}{data.csv}
\begin{document}
\begin{tabular}{c}
\rowcolor{OddRowColor}%
\DTLforeach*{rows}{\word=position}{%
\word
\\ % ending the row, \noalign can thus be used here
\DTLiflastrow{}{% This is the color for the *next* row, hence the odd/even
% shift compared to what datatool just processed
\DTLifoddrow{\rowcolor{EvenRowColor}}{\rowcolor{OddRowColor}}%
}%
}
\end{tabular}
\end{document}
注意filecontents
:如果您的 LaTeX2e 版本是 2019 年 10 月或更新的版本,则它具有使该 filecontents
软件包过时的功能。在这种情况下,您可以将前面的部分替换\documentclass
为以下内容(请参阅这里有关详细信息,特别是LaTeX2e 新闻第 30 期):
\begin{filecontents}[noheader,overwrite]{data.csv}
position
first
second
third
fourth
\end{filecontents}
回到我们的文档。如果你发现 中的标记太冗长tabular
,你可以定义一个这样的宏:
\newcommand*{\myApplyAlternatingColorsForTable}{%
\DTLiflastrow{}{% This is the color for the *next* row, hence the odd/even
% shift compared to what datatool just processed
\DTLifoddrow{\rowcolor{EvenRowColor}}{\rowcolor{OddRowColor}}%
}%
}
然后你的表格看起来如下:
\begin{tabular}{c}
\rowcolor{OddRowColor}%
\DTLforeach*{rows}{\word=position}{%
\word
\\ % ending the row, \noalign can thus be used here
\myApplyAlternatingColorsForTable
}
\end{tabular}
接受两种颜色作为参数很诱人\myApplyAlternatingColorsForTable
,但这会忽略第一个表格行,因为该行也需要指定其颜色。因此,为了更进一步,您需要在表格之前定义宏,以扩展到所需的颜色,如下所示:
\RequirePackage{filecontents}
\begin{filecontents*}{data.csv}
position
first
second
third
fourth
\end{filecontents*}
\documentclass{article}
\usepackage[table]{xcolor}
\usepackage{datatool}
\newcommand*{\myApplyAlternatingColorsForTable}{%
\DTLiflastrow{}{% This is the color for the *next* row, hence the odd/even
% shift compared to what datatool just processed
\DTLifoddrow{\rowcolor{\myColorForEvenRows}}%
{\rowcolor{\myColorForOddRows}}%
}%
}
\newcommand*{\mySetColorsForNextTable}[2]{%
\def\myColorForOddRows{#1}%
\def\myColorForEvenRows{#2}%
}
\newcommand*{\myApplyColorToFirstRow}{%
\rowcolor{\myColorForOddRows}%
}
\DTLloaddb{rows}{data.csv}
\begin{document}
\mySetColorsForNextTable{orange}{gray!20}%
\begin{tabular}{c}
\myApplyColorToFirstRow
\DTLforeach*{rows}{\word=position}{%
\word
\\ % ending the row, \noalign can thus be used here
\myApplyAlternatingColorsForTable
}
\end{tabular}
\end{document}
你可能想做的是这样的:
\begin{tabular}{c}
\DTLforeach*{rows}{\word=position}{%
\DTLifoddrow{\rowcolor{orange}}{\rowcolor{gray}}%
\word
\\
}
\end{tabular}
这不起作用,因为\rowcolor
TeX 对齐方式\halign
(如tabular
环境)的工作方式。\rowcolor
使用名为 的 TeX 基元\noalign
,它只能出现在第一行的开头或或之后\cr
(当您使用 时\crcr
,由 内部使用以tabular
结束表格行\\
)。当寻找\noalign
或\omit
(与本讨论中一样特殊\noalign
)时,TeX 会扩展标记并在第一个不可扩展的非空格标记处停止(参见 TeXbook 第 240 页)。
\rowcolor
当在行首或行末使用时,找到的第一个不可扩展、非空格标记是\noalign
,因此它可以正常工作。但是当使用比上述无效代码更简单的东西时:
\begin{tabular}{c}
\DTLforeach*{rows}{\word=position}{%
\rowcolor{blue}%
\word
\\
}
\end{tabular}
你会得到如下错误:
./thefile.tex:23: Misplaced \noalign.
\rowcolor ->\noalign
{\ifnum 0=`}\fi \global \let \CT@do@color \CT@@[email protected] }
这是因为\DTLforeach
作为前述过程的一部分进行了扩展,在此过程中,TeX 会扩展寻找\noalign
或 的标记,并且在有机会扩展并产生\omit
之前,它会在不可扩展、非空间的标记处停止。事实上,为了检查它的星号形式是否被使用,首先调用,它的扩展中包含,并且恰恰是一个不可扩展、非空间的标记。此时,在下一个或之前使用,1变为无效。然后,TeX 会处理下一列的起始模板(使用包时可以用 定义的内容),然后处理条目内容,最后到达该列的结束模板。在处理条目内容时,TeX 会扩展之后的宏,这个扩展会产生我们已经提到的 。不幸的是,在这里 有效已经太晚了,因为从 的扩展中获得的。只有在下一个或之后才能再次看到它。\rowcolor
\noalign
\DTLforeach
\new@ifnextchar
\let
\let
\noalign
\cr
\crcr
>{...}
array
\rowcolor
\DTLforeach*{rows}{\word=position}{
\noalign
\noalign
\let
\DTLforeach
\noalign
\cr
\crcr
\DTLiflastrow
安全吗\DTLifoddrow
?
您可能想知道为什么在我们的示例中\DTLiflastrow
似乎\DTLifoddrow
有效,但实际上却\DTLforeach*
无效。好吧...因为您很幸运!更新:我们正在解释datatool 2018/12/07 v2.31 中存在错误datatool
;同时已于2019/09/27 v2.32中修复。
看看这个定义:
\gdef\DTLiflastrow##1##2{%
\expandafter\ifnum
\csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname
=\csname dtlrows@#2\endcsname\relax
##1%
\else
##2%
\fi}%
有一个小错误(或者说,不良行为):没有 它会更好地工作\relax
。为了触发错误(仅存在于<2.32 中),尝试在 \DTLiflastrow 的 〈true〉 子句中datatool
使用,您会收到“Misplaced ”错误,正如我们所解释的那样。因此,对于“旧” (例如,2018/12/07 v2.31),只能在 〈false〉 子句中包含材料。您没有受到错误的影响,因为当测试为假时(即,当它正在寻找令牌时),TeX 会跳过而看不到它,而您只在 〈false〉 子句中使用材料。但问题很容易纠正,现在在2019/09/27 v2.32中修复:因为是一个令牌,根据 TeX 的语法它是一个 〈number〉 ,因此不需要。如果删除(注意,有\rowcolor
\noalign
datatool
\DTLiflastrow
\noalign
\relax
\DTLiflastrow
\else
\noalign
datatool
\dtlrows@DBNAME
\countdef
\relax
\relax
两个地方\gdef\DTLiflastrow
在 datatool.sty 中执行的操作,一个用于\DTLforeach
,一个用于\DTLforeach*
),然后可以手动将包含 的绿线附加abc
到表格中,如下所示:
\RequirePackage{filecontents}
\begin{filecontents*}{data.csv}
position
first
second
third
fourth
\end{filecontents*}
\documentclass{article}
\usepackage[table]{xcolor}
\usepackage{datatool}
\newcommand*{\myApplyAlternatingColorsForTable}{%
\DTLiflastrow{\rowcolor{green}}{%
\DTLifoddrow{\rowcolor{\myColorForEvenRows}}%
{\rowcolor{\myColorForOddRows}}%
}%
}
\newcommand*{\mySetColorsForNextTable}[2]{%
\def\myColorForOddRows{#1}%
\def\myColorForEvenRows{#2}%
}
\newcommand*{\myApplyColorToFirstRow}{%
\rowcolor{\myColorForOddRows}%
}
\DTLloaddb{rows}{data.csv}
\begin{document}
\mySetColorsForNextTable{orange}{gray!20}%
\begin{tabular}{c}
\myApplyColorToFirstRow
\DTLforeach*{rows}{\word=position}{%
\word
\\ % ending the row, \noalign can thus be used here
\myApplyAlternatingColorsForTable
}
abc
\end{tabular}
\end{document}
\DTLifoddrow
没有这个错误(我们会注意到,因为我们同时使用了它的 〈true〉 和 〈false〉 子句),但在 <2.32中和\DTLiffirstrow
都存在这个错误 。所有这些都已在2019/09/27 v2.32 中修复。上述示例在该版本中开箱即用。\DTLforeach
\DTLforeach*
datatool
datatool
脚注
- TeX 对齐的行尾原语(
\halign
和),由和朋友\valign
内部使用。tabular
array