1

Hi I am using the following code to try and dynamically set the number of columns in a Latex tabular environment:

    \documentclass{article}

\usepackage{array}

\newcounter{numcols}
\setcounter{numcols}{4}

\begin{document}

\begin{tabular}{
$\loop
\stepcounter{col}
\ifnum \value{col} < \value{numcols}
    c & 
\else
    c
\fi
\ifnum \value{col} = \value{numcols}
    \setcounter{col}{0}
\repeat$
}
\hline
\loop
\stepcounter{col}
\ifnum \value{col} < \value{numcols}
    \textbf{Column \thecol} & 
\else
    \textbf{Column \thecol} \\
\fi
\ifnum \value{col} = \value{numcols}
    \setcounter{col}{0}
\repeat
\hline
\loop
\stepcounter{row}
\ifnum \value{row} < 10
    \loop
    \stepcounter{col}
    \ifnum \value{col} < \value{numcols}
        Cell \therow,\thecol & 
    \else
        Cell \therow,\thecol \\
    \fi
    \ifnum \value{col} = \value{numcols}
        \setcounter{col}{0}
    \repeat
\repeat
\hline
\end{tabular}

\end{document}

However, it throws an error that Illegal pream-token ($): c' used if I remove the $ I receive the same error but it says Illegal pream-token (\loop): c' used.

Any help on solving this error would be much appreciated.

I need to create a table with a dynamic number of columns in Latex

3

1 Answer 1

2

Why $ that introduces math mode?

And do you also need to fill the body of the table?

If not, it's much simpler to get a table preamble consisting of a certain number of c columns, namely

\begin{tabular}{ *{4}{c} }

Instead of 4 you can use \value{numcols}, but I don't see an advantage, because you need to set the counter beforehand.

For filling a generic tabular:

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\generictabular}{mm}
 {% #1 = number of rows, #2 = number of columns
  \tl_clear:N \l__mencel_tabular_body_tl
  \mencel_tabular:nn { #1 } { #2 }
  \begin{tabular}{ *{#2}{c} }
  \hline
  \tl_use:N \l__mencel_tabular_body_tl
  \hline
  \end{tabular}
 }

\tl_new:N \l__mencel_tabular_body_tl

\cs_new_protected:Nn \mencel_tabular:nn
 {
  \int_step_inline:nn { #1 }
   {% ##1 is the row index
    \int_step_inline:nn { #2 }
     {% ####1 is the column index
      \tl_put_right:Nn \l__mencel_tabular_body_tl { Cell~##1.####1 }
      \int_compare:nTF { ####1 = #2 }
       {
        \tl_put_right:Nn \l__mencel_tabular_body_tl { \\ }
       }
       {
        \tl_put_right:Nn \l__mencel_tabular_body_tl { & }
       }
     }
   }
 }

\ExplSyntaxOff

\begin{document}

\generictabular{5}{4}

\end{document}

enter image description here

The nested \int_step_inline:nn functions are the analog of your loops. We need to build the table body before typesetting it.

Perhaps more efficient is to use \tl_build...

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\generictabular}{mm}
 {% #1 = number of rows, #2 = number of columns
  \mencel_tabular:nn { #1 } { #2 }
  \begin{tabular}{ *{#2}{c} }
  \hline
  \tl_use:N \l__mencel_tabular_body_tl
  \hline
  \end{tabular}
 }

\tl_new:N \l__mencel_tabular_body_tl

\cs_new_protected:Nn \mencel_tabular:nn
 {
  \tl_build_begin:N \l__mencel_tabular_body_tl
  \int_step_inline:nn { #1 }
   {% ##1 is the row index
    \int_step_inline:nn { #2 }
     {% ####1 is the column index
      \tl_build_put_right:Nn \l__mencel_tabular_body_tl { Cell~##1.####1 }
      \int_compare:nTF { ####1 = #2 }
       {
        \tl_build_put_right:Nn \l__mencel_tabular_body_tl { \\ }
       }
       {
        \tl_build_put_right:Nn \l__mencel_tabular_body_tl { & }
       }
     }
   }
  \tl_build_end:N \l__mencel_tabular_body_tl
 }

\ExplSyntaxOff

\begin{document}

\generictabular{5}{4}

\end{document}

You must log in to answer this question.

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