\DTLiflastrow安全吗\DTLifoddrow?

\DTLiflastrow安全吗\DTLifoddrow?

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}

这不起作用,因为\rowcolorTeX 对齐方式\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\noaligndatatool\DTLiflastrow\noalign\relax\DTLiflastrow\else\noaligndatatool\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*datatooldatatool


脚注

  1. TeX 对齐的行尾原语(\halign和),由和朋友\valign内部使用。tabulararray

相关内容