[Tex/LaTex] How to create a comma-separated list in LaTeX according to the number of elements in another list

comma-separated listmacros

I have been looking for a way to create dynamically a comma-separated list consisting of n entries, all entries equal, defined by \newcommand\mytext{species:} (example) and n being the number of entries in \newcommand\mylist. \newcommand\listtobegenerated shows how it the defined list should look like. Is there some way to do it?

I found this: Delete an element from a comma delimited list , thinking that I might be able to modify it by changing the deletion to replacement, but the accepted answer's \count@ and \toks@ gave me errors, which I was not able to solve and thought that there must be some cleaner approach instead of using \count@ and \toks@. Other answers to that question were for ConText and for expl3, and I'm looking for a LaTeX answer. So, how could I generate the content of listtobegenerated based on the content of mytext and the number of elements in mylist?

Thank you 🙂

\documentclass[12pt]{article}
\usepackage[american]{babel}
\usepackage{graphicx}

\newcommand\mylist{Haliaeetus albicilla,Lagidium viscacia,Balaenoptera musculus,Panthera pardus orientalis,Human}
\newcommand\mytext{species:}

% this is the the list I attempt to generated based on the number of elements in mylist and the content of mytext:
\newcommand\listtobegenerated{species:,species:,species:,species:,species:}

% preamble:
\def\preamble{\expandafter\xpreamble\mylist,\relax,}
\def\xpreamble#1,{%
\ifx\relax#1%
\else
c%
\expandafter\xpreamble
\fi}

% tablestart:
\def\tablestart{%
\edef\temp{\noexpand\begin{tabular}{c\preamble}\noexpand\hline}%
\temp}

% listheadings:
\def\listheadings{%
\expandafter\xlistheadings\listtobegenerated,\relax,%
\expandafter\xlistheadings\mylist,\relax,%
\hline}

% xlistheadings
\def\xlistheadings#1,{%
\ifx\relax#1%
\expandafter\\
\else
&\textbf{#1}%
\expandafter\xlistheadings
\fi}

\begin{document}
\begin{table}
\scalebox{0.7}{
\tablestart
\listheadings
\end{tabular}
} % end scalebox
\caption{Caption goes here.}
\begin{enumerate}
    \item Item number one. 
    \item Item number two.
\end{enumerate}
\end{table}
\end{document}

Best Answer

It seems that you want to build a tabular environment, so it's not so efficient to go through many useless steps:

\documentclass{article}
\usepackage{xparse,graphicx}

\ExplSyntaxOn

\NewDocumentCommand{\generatetable}{mm}{ \nrz_generate_table:nn { #1 } { #2 } }

\cs_new:Npn \nrz_generate_table:nn #1 #2 
 {
  \tl_clear:N \l_nrz_preamble_tl
  \tl_set:Nn \l_nrz_preamble_tl { c@{} }
  \tl_clear:N \l_nrz_header_one_tl
  \tl_clear:N \l_nrz_header_two_tl
  \clist_map_inline:Nn #1
   {
    \tl_put_right:Nn \l_nrz_preamble_tl { c }
    \tl_put_right:Nn \l_nrz_header_one_tl { & }
    \tl_put_right:NV \l_nrz_header_one_tl #2
    \tl_put_right:Nn \l_nrz_header_two_tl { & }
    \tl_put_right:Nn \l_nrz_header_two_tl { ##1 }
   }
  \tl_put_right:Nn \l_nrz_header_one_tl { \\ }
  \tl_put_right:Nn \l_nrz_header_two_tl { \\ }
  \nrz_build_table:
 }
\cs_new:Npn \nrz_build_table:
 {
  \resizebox{\textwidth}{!}{
  \begin{tabular}{\l_nrz_preamble_tl}
  \tl_use:N \l_nrz_header_one_tl
  \tl_use:N \l_nrz_header_two_tl
  \end{tabular}
  }
 }
\tl_new:N \l_nrz_preamble_tl
\tl_new:N \l_nrz_header_one_tl
\tl_new:N \l_nrz_header_two_tl
\ExplSyntaxOff


\newcommand\mylist{Haliaeetus albicilla,Lagidium viscacia,Balaenoptera musculus,Panthera pardus orientalis,Human}
\newcommand\mytext{species:}

\begin{document}
\noindent\generatetable{\mylist}{\mytext}
\end{document}

It wouldn't be difficult to do the same with etoolbox facilities. But I believe that this is easier to understand.


In case you really want to build the comma separated list, you can do with

\makeatletter
\newcommand\generatefromwith[3]{%
  \gdef#1{\@gobble}%
  \@for\next:=#2\do
    {\expandafter\g@addto@macro\expandafter#1\expandafter{\expandafter,#3}}%
  \expandafter\expandafter\expandafter\gdef\expandafter\expandafter\expandafter#1\expandafter\expandafter\expandafter{#1}
}
\makeatother

Then

\newcommand\mylist{Haliaeetus albicilla,Lagidium viscacia,Balaenoptera musculus,Panthera pardus orientalis,Human}
\newcommand\mytext{species:}

\generatefromwith\myheader\mylist\mytext

will define \myheader to expand to

species:,species:,species:,species:,species: