3

The following minimal example creates a 3-row table width a horizontal rule separating rows 2 and 3:

enter image description here

\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}

If I insert the commented fourth-row D,X,textD into the file data.txt, the example doesn't compile any more. Why is that? It should output another rule with another row:

enter image description here

Ideally I'd like the following output, where the \cmidrule is only placed before the first occurrence of a non-NULL/empty \fieldB:

enter image description here

\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}
4

\noexpand expands to nothing do on the second application of protected@xdef it os not there and the commands are unprotected. You need a mechanism that keeps them unexpanded on every application of xdef:

enter image description here

\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}
  • Okay, so the key here is to redefine the macros you don't want expanded as \relax. Good trick. – Werner Dec 30 '14 at 3:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.