5

I want to create a tabular with i+2 many columns where i is a counter. The tabular should have the following layout:

-------------------------------
| 1 | 2 | ... | i | foo | bar |
-------------------------------

That means, the first row should have a 1 as content and the second a 2 and so on until i and the last two rows should have foo resp. bar as their content.

I tried it with a LaTeX3 while loop but of course this does not work as intended:

\int_new:N \l_loop_ctr_int
\int_zero:N \l_loop_ctr_int
\begin{tabular}{
  \int_while_do:nn {\l_loop_ctr_int < \arabic{i}}{l \int_incr:N \l_loop_ctr_int}
  ll
}
\int_zero:N \l_loop_ctr_int
\int_while_do:nn {\l_loop_ctr_int < \arabic{i}}{\int_incr:N \l_loop_ctr_int &}
foo & bar \\
\end{tabular}

Does anyone has a hint for me?

  • \value{i} instead of \arabic{i}, but I would not call the counter i, but I fear the loop isn't expandable in the column specifier argument of tabular – user31729 Mar 8 '16 at 9:11
3

In my opinion the \int_.... loop do not expand correctly in \begin{tabular}{....}, but generating the column specifiers before and storing them in token list works.

\documentclass{article}

\usepackage{xparse}

\newcounter{ictr}
\setcounter{ictr}{10}
\begin{document}

\ExplSyntaxOn


\int_new:N \ictr_int 
\int_set:Nn \ictr_int {\value{ictr}}
\int_step_inline:nnnn {1}{1}{\ictr_int}{%
  \tl_put_right:Nn \l_tmpa_tl {l}
}
\begin{tabular}{\tl_use:N \l_tmpa_tl ll}
  \int_step_inline:nnnn {1}{1}{\ictr_int}{#1 &}
  foo & bar \\
\end{tabular}

    \par
\setcounter{ictr}{20}
\int_set:Nn \ictr_int {\value{ictr}}
\int_step_inline:nnnn {1}{1}{\ictr_int}{%
  \tl_put_right:Nn \l_tmpa_tl {l}
}
\begin{tabular}{\tl_use:N \l_tmpa_tl ll}
  \int_step_inline:nnnn {1}{1}{\ictr_int}{#1 &}
  foo & bar \\
\end{tabular}
\ExplSyntaxOff

\end{document}

enter image description here

Update with a macro:

\documentclass{article}

\usepackage{xparse}

\newcounter{ictr}
\setcounter{ictr}{10}

\ExplSyntaxOn
\int_new:N \ictr_int 
\newcommand{\testfoobar}[1]{%
  \tl_clear:N \l_tmpa_tl
  \int_set:Nn \ictr_int {#1}
  \int_step_inline:nnnn {1}{1}{\ictr_int+2}{%  Use 2 more columns
    \tl_put_right:Nn \l_tmpa_tl {l}
  }
\begin{tabular}{\l_tmpa_tl}
  \int_step_inline:nnnn {1}{1}{\ictr_int}{##1 &}
  foo & bar \\
\end{tabular}
}
\ExplSyntaxOff

\usepackage{pgffor}

\begin{document}
\testfoobar{\value{ictr}}

\foreach \x in {1,...,20} {%
\testfoobar{\x}

}


\end{document}

enter image description here

  • That is a very nice solution! However, I still get some compile time error when I try to put the code inside a macro: \newcommand\testfoobar{<your code here>} if I call the macro inside begin/end-document I get the following error: ! Illegal parameter number in definition of \testfoobar. Do you have any hint for me? – Max Maier Mar 8 '16 at 10:00
  • @MaxMaier: I'll update – user31729 Mar 8 '16 at 10:01
  • @MaxMaier: See the update please -- The reason why your version fails is most likely due to #1 inside of the macro -- You have to use ##1 then, since there is an implicit definition of a macro inside (the \int_step_inline:nnnn does this) and this needs the ##1 to access the current integer number – user31729 Mar 8 '16 at 10:16
  • Thank you very much for your explainations. I learned a lot! – Max Maier Mar 9 '16 at 18:55
  • @MaxMaier: You're welcome. Happy TeXing! – user31729 Mar 9 '16 at 21:02
3

\int_while_do:nn cannot start in a table cell and end in another one.

You can use \prg_replicate:nn that delivers the whole thing at once, though.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\maiertable}{mmm}
 {% #1 = number of columns (minus 2), #2 and #3 = last two cells
  \begin{tabular}{|*{\int_eval:n { #1 + 2 }}{c|}}
  \hline
  \int_zero:N \g_tmpa_int
  \prg_replicate:nn { #1 } { \int_gincr:N \g_tmpa_int \int_to_arabic:n { \g_tmpa_int } & }
  #2 & #3 \\
  \hline
  \end{tabular}
 }
\ExplSyntaxOff

\begin{document}

\maiertable{3}{foo}{bar}

\medskip

\maiertable{10}{foo}{bar}

\end{document}

enter image description here

2

Just for comparison, this is how you would do this is LuaTeX. The code below is in ConTeXt, but the LaTeX code should be equally straight forward.

\startluacode
  thirddata = thirddata or {}

  function thirddata.fancytable(n, s1, s2) 
    context.bTABLE()
    context.bTR()
    for i = 1, n do
      context.bTD() context(i) context.eTD()
    end
    context.bTD() context(s1) context.eTD()
    context.bTD() context(s2) context.eTD()
    context.eTABLE()
  end
\stopluacode

\define[3]\FancyTable{\ctxlua{thirddata.fancytable(#1,"#2", "#3")}}

\starttext
\FancyTable{5}{foo}{bar}
\stoptext

enter image description here

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.