3

I want to loop through a list and print some text. The placement of that text is inside a table, inside a \makecell command. I could hard-code the items from the list I want, including some \\ commands to break lines. But I don't want to hard-code, I want to use a loop. MWE:

\documentclass[]{article}
\usepackage{makecell}
\usepackage{pgffor}
\newcommand\AuthorList{First MI. Last, First MI. Last, First MI. Last}
\newcommand\PrintAuthorList{\foreach \x in \AuthorList
    {
        \x
    }
}

\begin{document}

\begin{table*}[h]
    \begin{tabular}{|l|l|}
        \hline
        \makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
        \hline
        row 2, no cells & \makecell{This is where I want to print the author list, one per line:\\ \PrintAuthorList}\\
        \hline
    \end{tabular}
\end{table*}

\begin{table*}[h]
    \begin{tabular}{|l|l|}
        \hline
        \makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
        \hline
        row 2, no cells & \makecell{This is where I've hard-coded the result I want:\\ First MI. Last\\First MI. Last\\First MI. Last}\\
        \hline
    \end{tabular}
\end{table*}

\end{document}

That code will compile but will not break lines between author names. If I add \\ to the foreach loop, it won't even compile.

My thought is that I have one command create a string with the slashes that I want, and have that string passed as code in my \makecell environment. For example:

\newcommand{\MakeAuthorString}{\foreach \x in \AuthorList{\x\textbackslash\textbackslash}}

But passing this into the makecell environment obviously just prints the backslashes as text. I want the string to be passed somehow as code... with actual backslashes that don't evaluate until they get in the makecell environment.

  • unrelated but don't use \begin{table*}[h] : table* is for tables that span two columns and does not have h it just does something here as in single node table* drops back to being table – David Carlisle Nov 1 '19 at 20:04
2

It's a one liner with xparse and expl3:

\documentclass[]{article}
\usepackage{makecell}
\usepackage{xparse}

\newcommand\AuthorList{First MI. Last, First MI. Last, First MI. Last}

\ExplSyntaxOn
\NewDocumentCommand\PrintAuthorList{}
 {
  \clist_use:Nn \AuthorList { \\ }
 }
\ExplSyntaxOff

\begin{document}

\begin{tabular}{|l|l|}
\hline
\makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
\hline
row 2, no cells & \makecell{Author List:\\ \PrintAuthorList}\\
\hline
\end{tabular}

\end{document}

enter image description here

| improve this answer | |
1

In case you like \expandafter-orgies, you can use \foreach for accumulating table-rows in a temporary macro:

\documentclass[]{article}
\usepackage{makecell}
\usepackage{pgffor}
\newcommand\AuthorList{First MI. Last1, First MI. Last2, First MI. Last3}
\newcommand\MyTemp{}%
\newcommand\PrintAuthorList{%
  \gdef\MyTemp{}%
  \foreach \x in \AuthorList
  {%
    \ifx\MyTemp\empty\else
      \expandafter\def\expandafter\MyTemp\expandafter{\MyTemp\\}%
    \fi
    \expandafter\expandafter\expandafter\gdef
    \expandafter\expandafter\expandafter\MyTemp
    \expandafter\expandafter\expandafter{%
    \expandafter\MyTemp
    \x}%
  }%
  %\show\MyTemp
  \expandafter\gdef\expandafter\MyTemp\expandafter{\expandafter}\MyTemp
}%

\begin{document}

\begin{table}[h]
    \begin{tabular}{|l|l|}
        \hline
        \makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
        \hline
        row 2, no cells & \makecell{This is where I want to print the author list, one per line:\\ \PrintAuthorList}\\
        \hline
    \end{tabular}
\end{table}

\begin{table}[h]
    \begin{tabular}{|l|l|}
        \hline
        \makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
        \hline
        row 2, no cells & \makecell{This is where I've hard-coded the result I want:\\ First MI. Last1\\First MI. Last2\\First MI. Last3}\\
        \hline
    \end{tabular}
\end{table}

\end{document}

A variant without pgffor and without temporary macro—the author-names in \AuthorList must contain neither unbalanced \else/\fi nor tokens whose meaning equals the meaning of \MyListEndDenoter :

\documentclass[]{article}
\usepackage{makecell}

\newcommand\AuthorList{% 
  % Not a comma-list this time but a list of undelimited/brace-nested arguments:
  {First MI. Last1}%
  {First MI. Last2}%
  {First MI. Last3}%
}%

\newcommand\PrintAuthorList{%
  \expandafter\Exchange\expandafter{\AuthorList}{\AccumulateTableRowsLoop{}{}}{\MyListEndDenoter}%
}%
\makeatletter
\newcommand\AccumulateTableRowsLoop[3]{%
  % #1 - Either empty or \\
  % #2 - Accumulated table rows
  % #3 - Element of AuthorList or \MyListEndDenoter
  \ifx\MyListEndDenoter#3\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  {#2}{\AccumulateTableRowsLoop{\\}{#2#1#3}}%
}%
\makeatother
\newcommand\Exchange[2]{#2#1}%
\newcommand\MyListEndDenoter{ItMustHaveAWeirdAndBizarreDefinitionWhichNoOtherMacroHas}%


\begin{document}

\begin{table}[h]
    \begin{tabular}{|l|l|}
        \hline
        \makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
        \hline
        row 2, no cells & \makecell{This is where I want to print the author list, one per line:\\ \PrintAuthorList}\\
        \hline
    \end{tabular}
\end{table}

\begin{table}[h]
    \begin{tabular}{|l|l|}
        \hline
        \makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
        \hline
        row 2, no cells & \makecell{This is where I've hard-coded the result I want:\\ First MI. Last1\\First MI. Last2\\First MI. Last3}\\
        \hline
    \end{tabular}
\end{table}

\end{document}

enter image description here

| improve this answer | |

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.