3

I used \whileboolexpr command from etoolbox package to generate a table. But there was an extra unwanted row. What is the problem with the following code? enter image description here

\documentclass[12pt]{article}

\usepackage{etoolbox}

\begin{document}

\newcounter{row}
\newcounter{rowcount}
\newcommand{\myand}{&}

\newcommand{\mylines}{%
  \setcounter{rowcount}{0}%
  \whileboolexpr{
      test{\ifnumless{\value{rowcount}}{\value{row}}}
  }{%
      \stepcounter{rowcount}%
      Number \myand 1 \myand 2 \myand 3 \\ \hline
  }%
}

\newcommand{\mytable}[1]{
  \setcounter{row}{#1}%
  \begin{tabular}{|c|*{3}{c|}}
    \hline
    \mylines
  \end{tabular}%
}

\mytable{4}

\end{document}
  • 2
    LaTeX has already started a new cell when it realizes the loop should end. – egreg Nov 19 '18 at 10:12
2

As egreg says, LaTeX starts the next cell before it realises that the table has finished. I realise that your real application is more complex, but a really efficient way to implement your MWE is using \prg_replicate:nn from LaTeX3 to produce:

enter image description here

Here's the code:

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\newcommand\mytable[1]{%
  \begin{tabular}{|c|*{3}{c|}}\hline
    \prg_replicate:nn {#1} {Number &1&2&3\\\hline}
  \end{tabular}%
}
\ExplSyntaxOff
\begin{document}

  \mytable{4}

\end{document}

Edit

Given the comment below, here is a more general approach that might be closer to what is required. It produces

enter image description here

from the input

  \mytable{
    {\one  &1&2&3},
    {\two  &4&6},
    {\three&1},
    {\four &1&2&2}
  }

where \one, \two, ... are some random macros.

The \mytable macro accepts a comma separated list of table-rows. By default the table has four columns but this can be changes with an optional argument so that, for example, \mytable[6]{...} gives a table with 6 columns. There is an obvious issue here with "dangling \hlines. This is easy enough to fix but as the OP does not gives details as to what is actually required there is little doing this without more information. For the reasons explained in the booktabs manual I'd drop the vertical rules and use \toprule and \bottomrule for the top and bottom rules, this would fix this problem and produce:

enter image description here

Here's the code:

\documentclass{article}
\usepackage{expl3}
\usepackage{booktabs}

\ExplSyntaxOn
\clist_new:N \l_table_clist
\newcommand\mytable[2][4]{
  \clist_set:Nn \l_table_clist {#2}
  \begin{tabular}{*{#1}{c}}\toprule
    \clist_use:Nn \l_table_clist {\\\hline}
    \\\bottomrule
  \end{tabular}%
}
\ExplSyntaxOff

\begin{document}

  \newcommand\one{One}
  \newcommand\two{Two}
  \newcommand\three{Three}
  \newcommand\four{Four}
  \mytable{
    {\one&1&2&3},
    {\two& 4&6},
    {\three& 1},
    {\four&1&2&2}
  }

\end{document}
  • Yes, my real application is more complex: number of columns is not fixed, and all cells are generated by commands, and every row is different. So I could not accept your answer. – Z.H. Nov 19 '18 at 10:44
  • @Z.H. Without knowing what you want to do it is hard to suggest what you should do except provide a better MWE. I suspect that there are better tools that you could use. Above I have given another approach. You might also find posts like tex.stackexchange.com/questions/367979 helpful – Andrew Nov 19 '18 at 19:30
3

My weekly (some say daily) \xintFor exercise.

\documentclass[12pt]{article}

\usepackage{xinttools}

\newcommand{\mytable}[1]{
  \begin{tabular}{|c|*{3}{c|}}
    \hline
    \xintFor* ##1 in {\xintSeq{1}{#1}}:
    {%
      Number & 1 & 2 & 3 \\ \hline
    }%
  \end{tabular}%
}

\begin{document}

\mytable{4}

\end{document}

enter image description here

  • The idea here is that each row may be entirely decided by the value of ##1 which will be 1, then 2, then – user4686 Nov 19 '18 at 22:12
1

You can generate the row code outside of the tabular:

enter image description here

\documentclass{article}

\usepackage{etoolbox}

\begin{document}

\newcounter{row}
\newcommand{\myand}{&}

\makeatletter
\newcommand{\mylines}[1]{%
  \setcounter{row}{#1}%
  \def\@mylines{}%
  \whileboolexpr{%
      test{\ifnumless{0}{\value{row}}}%
  }{%
      \addtocounter{row}{-1}%
      \xdef\@mylines{\@mylines \hline
        Number \myand 1 \myand 2 \myand 3 \\
      }%
  }%
}

\newcommand{\mytable}[1]{%
  {\let\hline\relax % Avoid expansion of \hline in \xdef
   \let\\\relax % Avoid expansion of \\ in \xdef
   \mylines{#1}}% This generates \@mylines
  \begin{tabular}{ | c | *{3}{c|} }
    \@mylines \hline % Print \@mylines
  \end{tabular}%
}
\makeatother

\mytable{4}

\end{document}

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.