以下最小示例创建了一个 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}