使用 datatool 构建条件表

使用 datatool 构建条件表

以下最小示例创建了一个 3 行表格,其中水平分隔线为第 2 行和第 3 行:

在此处输入图片描述

\documentclass{article}
\usepackage{filecontents,datatool,booktabs}
\usepackage[table]{xcolor}

\begin{filecontents*}{data.txt}
fieldA,fieldB,fieldC
A,,textA
B,,textB
C,X,textC
\end{filecontents*}
%D,X,textD% Add this row to the above file... Booooooom!

\begin{document}

\DTLloaddb[keys={fieldA,fieldB,fieldC}]{data}{data.txt}

\makeatletter
\gdef\tabulardata{}
\DTLforeach*{data}
  {\fieldA=fieldA,\fieldB=fieldB,\fieldC=fieldC}{%
  \DTLifnullorempty{\fieldB}{%
    \gdef\tabularrule{}% No rule
  }{% \fieldB is not NULL nor empty
    \gdef\tabularrule{\noexpand\arrayrulecolor{black!15}\noexpand\cmidrule{1-3}\noexpand\arrayrulecolor{black}}% Grey rule
  }
  \g@addto@macro\tabularrule{\fieldA}% Append \fieldA to \tabularrule
  \protected@xdef\tabulardata{\tabulardata%
    \tabularrule% Insert tabular rule + \fieldA
    & \fieldB & \fieldC \tabularnewline
  }% Construct new tabular row
  }
\makeatother

\begin{tabular}{ *{3}{c} }
  \toprule
  Field A & Field B & Field C \\
  \midrule
  \tabulardata
  \\[-\normalbaselineskip]\bottomrule
\end{tabular}

\end{document}

如果我将注释掉的第四行插入D,X,textD到文件中data.txt,示例将无法再编译。这是为什么?应该输出另一条规则和另一行:

在此处输入图片描述

理想情况下,我希望得到以下输出,其中\cmidrule仅放置在第一次出现非 NULL/空之前\fieldB

在此处输入图片描述

\begin{tabular}{ *{3}{c} }
  \toprule
  Field A & Field B & Field C \\
  \midrule
  A &   & textA \\
  B &   & textB \\
  \arrayrulecolor{black!15}\cmidrule{1-3}\arrayrulecolor{black}
  C & X & textC \\
  D & X & textD \\
  \\[-\normalbaselineskip]\bottomrule
\end{tabular}

答案1

\noexpand扩展为无用,第二次应用时protected@xdef操作系统不存在,命令不受保护。您需要一种机制,使它们在每次应用 xdef 时都不会扩展:

在此处输入图片描述

\documentclass{article}
\usepackage{filecontents,datatool,booktabs}
\usepackage[table]{xcolor}

\begin{filecontents*}{data.txt}
fieldA,fieldB,fieldC
A,,textA
B,,textB
C,X,textC
D,X,textD
\end{filecontents*}
%D,X,textD% Add this row to the above file... Booooooom!

\begin{document}

\DTLloaddb[keys={fieldA,fieldB,fieldC}]{data}{data.txt}

\makeatletter
\gdef\tabulardata{}
\DTLforeach*{data}
  {\fieldA=fieldA,\fieldB=fieldB,\fieldC=fieldC}{%
  \DTLifnullorempty{\fieldB}{%
    \gdef\tabularrule{}% No rule
  }{% \fieldB is not NULL nor empty
    \gdef\tabularrule{\arrayrulecolor{black!15}\cmidrule{1-3}\arrayrulecolor{black}}% Grey rule
  }
      {\let\arrayrulecolor\relax
    \let\cmidrule\relax
\g@addto@macro\tabularrule{\fieldA}% Append \fieldA to \tabularrule
  \protected@xdef\tabulardata{\tabulardata%
    \tabularrule% Insert tabular rule + \fieldA
    & \fieldB & \fieldC \tabularnewline
  }}% Construct new tabular row
  }
\makeatother

\begin{tabular}{ *{3}{c} }
  \toprule
  Field A & Field B & Field C \\
  \midrule
  \tabulardata
  \\[-\normalbaselineskip]\bottomrule
\end{tabular}

\end{document}

相关内容