0

I've found myself in a situation where I need to dynamically add a list of strings inside a tabular cell in multiple instances, each string in their own line. To tackle this, I tried to go with the following approach, using the makecell and forarray packages:

\documentclass{article}
\usepackage{makecell}
\usepackage{forarray}

\begin{document}

\newcommand{\listcontacts}[1]{\ForEach{,}{\scriptsize\textbf{\thislevelitem}\\}{#1}}

\begin{tabular}{ r r }
    \hline
    \textbf{NAME} & \textbf{CONTACT} \\ 
    \hline
    John Doe & \makecell[r]{\listcontacts{Number One,Number Two,Number Three}} \\ % Error: Tried to expand an \endforeachtoken. Something is wrong.
    \hline
\end{tabular}

\listcontacts{Number One,Number Two,Number Three} % renders fine

\end{document}

enter image description here

As you can see, the list renders fine outside of the table, but behaves strangely inside makecell due to the programmatically added line breaks, on top of an error thrown at the affected line. Using anything different than a line break, it renders fine inside the cell as well.

I already tried to use pgfmath as an alternative way to iterate, as well as \StrSubstitute from the xstring package to downright replace the commata with line breaks. Even line breaks in the command parameter itself won't be processed correctly by makecell.

This leaves me wondering, is there any way to add line breaks inside makecell besides to do so statically? How would I achieve this?

1 Answer 1

2

Using L3's \clist_map_inline:nn instead of forarray this works as intended. The issue is that each line in \makecell forms a cell in a nested tabular, and hence is a group. It seems the loop of forarray doesn't cope with that well.

\documentclass{article}
\usepackage{makecell}

\ExplSyntaxOn
\NewDocumentCommand \listcontacts { m }
  { \clist_map_inline:nn {#1} { \scriptsize \textbf {##1} \\ } }
\ExplSyntaxOff

\begin{document}

\begin{tabular}{ r r }
    \hline
    \textbf{NAME} & \textbf{CONTACT} \\ 
    \hline
    John Doe & \makecell[r]{\listcontacts{Number One,Number Two,Number Three}} \\ % Error: Tried to expand an \endforeachtoken. Something is wrong.
    \hline
\end{tabular}

\listcontacts{Number One,Number Two,Number Three} % renders fine

\end{document}

But this way we get an additional \\ at the end, which causes \makecell to display an empty line at the bottom. To get rid of that we need to treat the first row differently from the others (or the last row, but that would be harder to implement). Additionally, if you use your macro as it is outside of a tabular the \scriptsize would leak and affect the other stuff, so we put it into the argument of \textbf to keep it local.

Everything sticked together looks like this:

\documentclass{article}
\usepackage{makecell}

\ExplSyntaxOn
\seq_new:N \l_strikeagainst_contacts_seq
\NewDocumentCommand \listcontacts { m }
  {
    \seq_set_from_clist:Nn \l_strikeagainst_contacts_seq {#1}
    \seq_pop_left:NNT \l_strikeagainst_contacts_seq \l_tmpa_tl
      {
        \textbf { \scriptsize \l_tmpa_tl }
        \seq_map_inline:Nn \l_strikeagainst_contacts_seq
          { \\ \textbf { \scriptsize ##1 } }
      }
  }
\ExplSyntaxOff

\begin{document}

\begin{tabular}{ r r }
    \hline
    \textbf{NAME} & \textbf{CONTACT} \\ 
    \hline
    John Doe & \makecell[r]{\listcontacts{Number One,Number Two,Number Three}} \\ % Error: Tried to expand an \endforeachtoken. Something is wrong.
    \hline
\end{tabular}

\listcontacts{Number One,Number Two,Number Three} % renders fine

\end{document}

enter image description here

1
  • Thank you a lot, this worked excellently! Sep 12 at 14:21

You must log in to answer this question.

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