4

This is a followup to or restatement of a previous question, because I had a great deal of difficulty in understanding both the question and the answer. The example file had a lot going on, and I think it'll be easier to understand the answer if we use a simpler example.

So say I have a file, table.csv, as follows:

FirstName,LastName,Job
Bob,Builder,construction worker
Steve,Wumbo,Politician
Greembo,Flutes,Comedian

and a tex file, main.tex, as follows:

\documentclass{article}

\usepackage{tabularray}
\usepackage{datatool}

\DTLloaddb{table}{table.csv}

\begin{document}

\begin{tblr}{}
    First name & Last name & Occupation \\
    \DTLforeach{table}{%
    \firstname=FirstName,\lastname=LastName,\occupation=Job}{%
    \firstname & \lastname & \occupation \\}
\end{tblr}

\end{document}

When I try to compile this, lualatex fails, giving me the error

! Misplaced alignment tab character &.
<argument> ...ow\romannumeral \dtlforeachlevel }}\firstname &
                                                   \lastname & \occupation \...

l.15 \end
       {tblr}

and spitting out a pretty bad looking table as a result.

Why is this happening, and what can I do to fix it?

I would really appreciate if the answer were not just a block of code but also included an explanation of the working code.

1 Answer 1

3

The reason for the error is that \DTLforeach is not expanded at the right moment. This is explained in the manual of the tabularray package: "In contrast to traditional tabular environment, tabularray environments need to see every & and \\".

As mentioned in the question, this issue and the solution are similar to the one on How to use DTLforeach (datatool) within a tabularray table?.

The solution is to first collect the result of \DTLforeach in a macro. This macro is initialized with \tl_new:N \tblrbody.

Inside \DTLforeach, the content is collected with \tl_build_put_right:Ne. Here, \exp_not:V is used which recovers the content of \firstname, \lastname and \occupation and prevents expansion. This is unnecessary with the provided data but it is necessary if the data would contain for example \emph{text}.

This process is started with \tl_build_begin:N and ended with \tl_build_end:N. Thereafter, the option expand=\tblrbody is given to the tblr environment where \tblrbody is placed.

enter image description here

\documentclass[border=6pt]{standalone}
\usepackage{tabularray}
\usepackage{datatool}
\DTLloaddb{table}{table.csv}
\begin{document}
\ExplSyntaxOn
\tl_new:N \tblrbody
\tl_build_begin:N \tblrbody
  \DTLforeach{table}{
    \firstname=FirstName,
    \lastname=LastName,
    \occupation=Job
  }{
    \tl_build_put_right:Ne \tblrbody { \exp_not:V \firstname & \exp_not:V \lastname & \exp_not:V \occupation \\ }
  }
\tl_build_end:N \tblrbody
\ExplSyntaxOff
\begin{tblr}[expand=\tblrbody]{}
First name & Last name & Occupation\\
\tblrbody
\end{tblr}
\end{document}
2
  • 1
    Is there a typo in here somewhere? It isn't compiling. Undefined control sequence: ...eral \dtlforeachlevel }}\tl_build_put_right:Ne.
    – Canyon
    Dec 10, 2023 at 20:21
  • The command \tl_build_put_right:Ne is fairly recent. An option is to update. Another option is to place \cs_generate_variant:Nn \tl_build_put_right:Nn { Ne } after \ExplSyntaxOn. Dec 11, 2023 at 8:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .