5

I would like to convert a list of terms like : A, B, C, D, E, F

to a table like:

| A | B | C |

| D | E | F |

or

| A | C | E |

| B | D | F |

but without having to rewrite my table each time, as inserting items or moving/deleting some is really hard with big tables.

Does any package exists to help doing that ?

EDIT:

By using a mix of all of what you provided, here is a version which has alignement problems - without the center block, the vertical version is slightly moved on the right, but this is intended to be centered in my document - with the center block, the horizontal version is not centered.

However here it is :

\documentclass{book}
\RequirePackage{etoolbox}%

\newcounter{argcolumns}
\newcounter{argtargetcolumns}

\newcommand{\mylisttable}[3][h]{
  \setcounter{argcolumns}{0}
  \setcounter{argtargetcolumns}{#2}
  \def\mytable{}
  \def\mylist{}
  \forcsvlist{\listadd\mylist}{#3}

  \def\parser ##1{%
    \ifnumequal{\value{argcolumns}}{\value{argtargetcolumns}-1}{%
      \setcounter{argcolumns}{0}%
      \expandafter\def\expandafter\mytable\expandafter{%
        \mytable ##1 \cr%
      }%
    }{%
      \stepcounter{argcolumns}%
      \expandafter\def\expandafter\mytable\expandafter{%
        \mytable ##1 & %
      }%
    }%
  }%

  \forlistloop{\parser}{\mylist}%
  \begin{center}
    \ifx #1v \expandafter\valign\else\expandafter\halign\fi{& \hbox spread 0.1em{\hfil\strut##\hfil}\crcr
      \mytable%
      \whileboolexpr{%
        not (test {\ifnumequal{\value{argcolumns}}{0}}) and %
        test {\ifnumless{\value{argcolumns}}{\value{argtargetcolumns}-1}}
      }%
      {%
        & \stepcounter{argcolumns}%
      }\setcounter{argcolumns}{0}\cr
    }
  \end{center}
}

\begin{document}

\mylisttable[h]{4}{aaaaaaaaa,b,caaaa,daaaaaaaaaaaa,e,faaaaaaaaaa,g,h}
\mylisttable[h]{2}{a,b,c,d,e,f,g,h}
\mylisttable[v]{2}{a,b,c,d,e,f,g,h}
\mylisttable[v]{2}{a,b,c,d,e,f,g,h}
\mylisttable[h]{2}{a,b,c,d,e,f,g,h}
\end{document}
4
  • Datatool and / or pgfplotstable.
    – user11232
    Commented Sep 5, 2012 at 13:55
  • Maybe you can try to use \hbox, \vbox, \hfil and \vfil (and their fill equivalent) to obtain a better result than your combination of center and align. I think maybe your problem comes from the fact that they use the same kind of glue at some point. Also remember that these commands will always center your table in the column they belong to at best. Therefore, if your layout is asymetrical, you cannot expect it to be easily centerable on the page (but it will always be, related to the text). Commented Sep 6, 2012 at 6:24
  • @SamuelAlbert I really don't know how to use these. Do you have any reference ?
    – Bjonnh
    Commented Sep 7, 2012 at 12:28
  • 1
    \hbox and \vbox are boxes whose dimensions are horizontally or vertically fixed (although the horizontal dimension of a \vbox is also fixed via \hsize). \hfil and \vfil are horizontal and vertical glues. You will find detailed information on how to use these in there and an example on how to practically use these in the kind of situation you are in in there Commented Sep 7, 2012 at 14:31

3 Answers 3

4

To do this, you can quite easily do it using etoolbox and its list handling tools.

For exemple, in your case, I would do :

EDIT : This was the first solution. See the final solution after which is probably better.

\RequirePackage{etoolbox}%

\newtoggle{firstarg}%
\newtoggle{secondarg}%
\togglefalse{firstarg}%
\togglefalse{secondarg}%

\def\mycsvlist{A,B,C,D,E,F}%
\def\mylist{}%
\def\mytable{}%
%
\expandafter\forcsvlist\expandafter{%
  \expandafter\listadd\expandafter\mylist\expandafter}%
  \expandafter{\mycsvlist}
%
\def\parser #1{%
  \iftoggle{firstarg}%
  {%
    \iftoggle{secondarg}%
      {%
        \expandafter\def\expandafter\mytable\expandafter{%
          \mytable #1 \tabularnewline\hline%
        }%
        \togglefalse{firstarg}%
        \togglefalse{secondarg}%
      }{%
        \expandafter\def\expandafter\mytable\expandafter{%
          \mytable #1 & %
        }%
        \toggletrue{secondarg}%
      }%
    }{%
    \expandafter\def\expandafter\mytable\expandafter{%
      \mytable #1 & %
    }%
    \toggletrue{firstarg}%
  }%
}%
\forlistloop{\parser}{\mylist}%

Okay, following the @Bjonnh 's question about having it scalable to other numbers of columns than just 3, I improved my solution and here is what I came up with :

\documentclass[10pt,a4paper,titlepage,twoside,onecolumn]{report}
\makeatletter

\RequirePackage{etoolbox}%

\newcounter{argcolumns}
\newcounter{argtargetcolumns}
\setcounter{argtargetcolumns}{4}

\def\mycsvlist{A,B,C,D,E,F}%
\def\mylist{}
\def\mytable{}

\expandafter\forcsvlist\expandafter{%
  \expandafter\listadd\expandafter\mylist\expandafter}%
  \expandafter{\mycsvlist}

\def\parser #1{%
  \ifnumequal{\value{argcolumns}}{\value{argtargetcolumns}-1}{%
    \setcounter{argcolumns}{0}%
    \expandafter\def\expandafter\mytable\expandafter{%
      \mytable #1 \tabularnewline\hline%
    }%
  }{%
    \stepcounter{argcolumns}%
    \expandafter\def\expandafter\mytable\expandafter{%
      \mytable #1 & %
    }%
  }%
}%

\forlistloop{\parser}{\mylist}%

\makeatother

\begin{document}
      \begin{tabular}{|c|c|c|c|}%
    \hline%
    \mytable%
    \whileboolexpr{%
      not (test {\ifnumequal{\value{argcolumns}}{0}}) and %
      test {\ifnumless{\value{argcolumns}}{\value{argtargetcolumns}-1}}
    }%
    {%
      & \stepcounter{argcolumns}%
    }\setcounter{argcolumns}{0}\tabularnewline%
    \hline%
  \end{tabular}
\end{document}

If you want to change the number of columns, you just have to change the value of argtargetcolumns to the number of columns you want (and obviously the number of columns in your table).

I also added code in the table so that you automatically finish filling the last line with empty cells.

If you however wish to do that by hand (or to continue filling the table with something else), then you really just need \mytable in your tabular environment.

4
  • Is it easily scalale to x*y tables, not 2-lines ones ? Can't we use a kind of for loop with two parameters ?
    – Bjonnh
    Commented Sep 5, 2012 at 13:59
  • Well, by using standardized names instead of firstarg and secondarg (for example, you can think of arg1, arg2, ...), you can then compose the names using a counter and with some recursive definition of the function, it should be possible. It could however be kind of complex to program. If you want, I can try, but I cannot give any guarantees. Commented Sep 5, 2012 at 14:03
  • By the way, I just remarked I made some mistakes in my solution and corrected it. Commented Sep 5, 2012 at 16:07
  • @Bjonnh I added the solution you asked for which is scalable. It was even easier than I thought. Commented Sep 5, 2012 at 16:28
3

The memoir class provides the \autorows and \autocols macros which take a comma-separated list of items (e.g., words) and displays them in tabular form either in row or column order. The number of columns and the position of the entries (left, center, right) in the columns can be specified.

1
  • I tried to get the commands to insert them in my class, but it seems I have to import pages and pages of code for this…
    – Bjonnh
    Commented Sep 5, 2012 at 21:09
2

Food for thought:

\halign{& \hbox spread 1em{\hfil\strut#\hfil}\crcr
  A & B & C \cr
  D & E & F \cr
}
\bye

enter image description here

and changing \halign to \valign (literally, just change the h to v and nothing else):

enter image description here

2
  • That's really neat, I tried this in a MNWE (edit of the question) and I got some alignement problems. But the vertical version is really cool looking with my data, and easier to read.
    – Bjonnh
    Commented Sep 5, 2012 at 21:11
  • look at the edit of the question to see your code in action :)
    – Bjonnh
    Commented Sep 7, 2012 at 12:28

You must log in to answer this question.

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