2

Suppose we have a list of elements {1, 2, ..., 18}. I have to write a Latex program so that the elements can be written in the following dynamic table. Please help me. Thank you in advance.

table-form

2

I think that the following command \Table will do the job. The first argument is the number of columns wanted in the table and the second argument is the list of the numbers (separated by commas).

Eg: \Table{4}{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21}

\documentclass{article}
\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand {\Table} {mm}
   {\clist_set:Nn \l_tmpa_clist {#2}
    \int_do_until:nNnn {\clist_count:N \l_tmpa_clist} < {#1+1}
       {\int_step_inline:nnnn 1 1 {#1-1} 
           {\clist_pop:NN \l_tmpa_clist \l_tmpb_tl
            \tl_put_right:NV \l_tmpa_tl \l_tmpb_tl 
            \tl_put_right:Nn \l_tmpa_tl {&}}
        \clist_pop:NN \l_tmpa_clist \l_tmpb_tl
        \tl_put_right:NV \l_tmpa_tl \l_tmpb_tl 
        \tl_put_right:Nn \l_tmpa_tl {\\ \hline}}
    \int_set:Nn \l_tmpa_int {\clist_count:N \l_tmpa_clist}
    \int_compare:nNnT \l_tmpa_int > 0
       {\int_step_inline:nnnn 1 1 {\l_tmpa_int - 1}
         {\clist_pop:NN \l_tmpa_clist \l_tmpb_tl
          \tl_put_right:NV \l_tmpa_tl \l_tmpb_tl
          \tl_put_right:Nn \l_tmpa_tl {&}}
        \clist_pop:NN \l_tmpa_clist \l_tmpb_tl
        \tl_put_right:NV \l_tmpa_tl \l_tmpb_tl 
        \int_step_inline:nnnn 1 1 {#1 - \l_tmpa_int}
          {\tl_put_right:Nn \l_tmpa_tl {&}}
        \tl_put_right:Nn \l_tmpa_tl {\\ \hline}}
       \begin{tabular}{|*{#1}{c|}}
        \hline
        \l_tmpa_tl
        \end{tabular}}
\ExplSyntaxOff    


\begin{document}
\Table{4}{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21}
\end{document}
1

Tables in Latex can be made by using the tabular environment. It starts by begining the environment and by telling how we want the data in each column to be aligned. An 'l' is used to align the items to the left. Then your data follows with a '&' to separate the columns and two backslashes to end the line. At the end you close the environment. If you would like to add borders to your table you can do that by adding '|' in the header and \hline at the end of the rows.

For example
This code

\begin{tabular}{|l|l|l|l|l|}
\hline
1  & 2  & 3  & 4  & 5  \\ \hline
6  & 7  & 8  & 9  & 10 \\ \hline
11 & 12 & 13 & 14 & 15 \\ \hline
16 & 17 & 18 &    &    \\ \hline
\end{tabular}

Will result in this table:
enter image description here

I often use this online Table Generator tool for creating more complex tables.

  • Thank you for your answer. This is not the dynamic table. You just create manual table. This is not my requirement. If you change the list the table will be formed automatically. – Arindam Bandyopadhyay Nov 4 '18 at 18:57
  • So what do you mean exactly by a dynamic table then? Do you want some automated script to write the table for you? – Bassie-c Nov 4 '18 at 19:02
  • Yes. {1,...,18} as an input will produce the above table. If we change the input list then the table will be changed automatically. – Arindam Bandyopadhyay Nov 4 '18 at 19:06
1

You decide the number of columns and, optionally, the column widths (all equal, in this case).

\documentclass{article}
\usepackage{xparse}
\usepackage{array}

\ExplSyntaxOn

\NewDocumentCommand{\dyntable}{omm}
 {% #1 is the cell width, if specified
  % #2 is the number of columns
  % #3 is the list of elements
  \IfNoValueTF { #1 }
   {
    \arindam_dyntable:nnn { * } { #2 } { #3 }
   }
   {
    \arindam_dyntable:nnn { #1 } { #2 } { #3 }
   }
 }

\tl_new:N \l__arindam_dyntable_body_tl
\int_new:N \l__arindam_dyntable_count_int

\cs_new_protected:Nn \arindam_dyntable:nnn
 {
  \tl_clear:N \l__arindam_dyntable_body_tl
  \int_zero:N \l__arindam_dyntable_count_int
  \clist_map_inline:nn { #3 }
   {
    \int_incr:N \l__arindam_dyntable_count_int
    \tl_put_right:Nn \l__arindam_dyntable_body_tl { ##1 }
    \int_compare:nTF
     { \int_mod:nn { \l__arindam_dyntable_count_int } { #2 } = 0 }
     { \tl_put_right:Nn \l__arindam_dyntable_body_tl { \\ \hline } }
     { \tl_put_right:Nn \l__arindam_dyntable_body_tl { & } }
   }
  \int_compare:nT
   {
    \int_mod:nn { \l__arindam_dyntable_count_int } { #2 } > 0
   }
   { % we need to fill the last line
    \prg_replicate:nn 
     {
      #2-1-\int_mod:nn { \l__arindam_dyntable_count_int } { #2 }
     }
     { \tl_put_right:Nn \l__arindam_dyntable_body_tl { & } }
    \tl_put_right:Nn \l__arindam_dyntable_body_tl { \\ \hline }
   }
  % print the table
  \str_if_eq:nnTF { #1 } { * }
   { \begin{tabular}{|*{#2}{c|}} }
   { \begin{tabular}{|*{#2}{w{c}{#1}|}} }
  \hline
  \tl_use:N \l__arindam_dyntable_body_tl
  \end{tabular}
 }
\ExplSyntaxOff

\begin{document}

\dyntable[1.5em]{4}{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18}

\bigskip

\dyntable{6}{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18}

\bigskip

\dyntable[3em]{6}{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18}

\bigskip

\dyntable{4}{
  apple, banana, orange, pineapple, cherry, mango, pear,
  apricot, peach
}

\bigskip

\dyntable[5em]{4}{
  apple, banana, orange, pineapple, cherry, mango, pear,
  apricot, peach
}

\end{document}

The list of items is traversed and each item is added to the body of the table; when we have reached the number of columns, \\ is appended, otherwise &.

There is the problem of filling the last row, if short, which is done by adding the appropriate number of & and a trailing \\.

If no optional argument is specified, we pass *, which eventually means c column type. If a length is specified in the optional argument, we use w{c}{<length>} to get equal width columns.

enter image description here

  • Excellent!!!. This fulfills my need. Thank you for your quick answer. – Arindam Bandyopadhyay Nov 5 '18 at 2:25
1

Without using xparse, there is listofitems package which could be used with a \foreach from TikZ.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{listofitems}
\setsepchar{,}
\newlength{\mysize}
\setlength{\mysize}{1cm}%size of the squares
\begin{document}
    \readlist\mylist{You,can,put,here,what,you,want,8,9,10,11,12,13,14,15,16,17,18}
    \begin{tikzpicture}
        \foreach \i [evaluate=\i as \myrow using {int((\i-1)/5)},
        evaluate=\i as \mycol using {mod((\i-1),5)}] in {1,2,...,18}{
        \node[draw, rectangle, minimum size=\mysize, text height=.5\mysize, text depth=.2\mysize] at (\mycol*\mysize,-\myrow*\mysize) {\mylist[\i]};}
    \end{tikzpicture}
\end{document}

enter image description here

  • Excellent work!!! This fulfills my needs. This is very simple to use. Thank you once again. – Arindam Bandyopadhyay Nov 5 '18 at 3:00

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.