automatic list/table rendering

i'm looking for a solution to automatically render data lists. In the current scenario, my input data is a list of strings, which should be displayed in a three column list w/ sequential numbers:

+--------------+-------------+------------+
| 4  dfasdfas  | 3  23ea3ad  | 4  898sd   |
|                   .....                 |
+-----------------------------------------+

For now, it's enough having a fixed number of items (in my case: 30), so I've just defined 30 different macros with the values, which are then referenced by the template, where everything's just hardcoded.

Of course, that's pretty static, so I'm looking for a better solution, where the tex input just defines the data like that:

\putItem{xyzxyz}
\putItem{dfasdfas}
\putItem{898sd}
...

Does anyone have a good idea ?

thx

• Do the strings have spaces in them, or could a space be used as a string separator? – Steven B. Segletes Mar 19 '14 at 17:56
• Also, are these strings in a separate file, or are they being generated by the LaTeX code? – Steven B. Segletes Mar 19 '14 at 17:57

\documentclass{article}

\newcommand\putItem[1]{\refstepcounter{enumi}\makebox[.3\textwidth][l]{\theenumi. #1}\hfill\ignorespaces}
\begin{document}

\begin{flushleft}
\putItem{xyzxyz}
\putItem{dfasdfas}
\putItem{898sd}
\putItem{xyzxyz}
\putItem{dfasdfas}
\putItem{898sd}
\end{flushleft}

\end{document}

Here is a slight improvement over David Carlisle's solution in that a simple comma separated list can be spcified:

Notes:

• Use a custom counter in case which allows for use within other enumerated environments.
• Counter is rest for each invocation of \ListTable.

Code:

\documentclass{article}
\usepackage{pgffor}
\usepackage{xstring}

\newcounter{MyCounter}
\newcommand\putItem[1]{\refstepcounter{MyCounter}\makebox[.3\textwidth][l]{\theMyCounter. #1}\hfill\ignorespaces}
\begin{document}

\newcommand{\DefaultNumberOfColumns}{3}%
\newcommand{\ListTable}[2][\DefaultNumberOfColumns]{%
% #1 = optional number of columns, defaults to \DefaultNumberOfColumns
% #2 = common separated list
\setcounter{MyCounter}{0}%
\noindent
\edef\ListMembersExpanded{#2}%
\foreach \x in \ListMembersExpanded {%
\IfStrEq{\x}{}{}{% Need to eliminate any empty enteries (allows for trailing comma)
\putItem{\x}%
}%
}%
}%

\ListTable{%
xyzxyz,
dfasdfas,
898sd,
xyzxyz,
dfasdfas,
898sd,
}%

\end{document}

Based on my answer at How to put content from multiple databases in one table using datatool?, I came up with this. Currently, this MWE reads the data from a file data.txt, currently containing

dfkdsfs
sdf
dsfdsfgsdfg
ds4543
rg
ere
r
ewrf
sfs
edfds
swdf
sdfdsfdsfdsf
rtg
435
rtgre
t546
tgr
ret
4trswe
dfdf
fdfsdf
435435rsggf
dsfds
gff
vcvx
gfgfd
asdfdsf
rt
34
32e3
~

though the external file can be dispensed with if the \readdef{data.txt}{\tmpa} were replaced by

\def\tmpa{dfkdsfs sdf dsfdsfgsdfg ds4543 rg ere r ewrf sfs edfds swdf
sdfdsfdsfdsf rtg 435 rtgre t546 tgr ret 4trswe dfdf fdfsdf 435435rsggf
dsfds gff vcvx gfgfd asdfdsf rt 34 32e3 ~
}

The ~ in the last row is a filler (I'll come back to that). I'm also assuming that data entries have no spaces, which I inferred from the OP's description. The macro \readArrayij{\tmpa}{first}{3} reads the data into an array identified as first, with 3 columns. Partial rows are discarded, and so here is why I added a blank and newline at the end of the data, so that a partial row is not lost.

The structure uses Herbert's \tabtoks approach (How to programmatically make tabular rows using \whiledo ?) to add the data to a tabular, 3 elements at a time, in this case, adding an index identifier to the front end.

\documentclass{article}
\newcounter{index}
\newcounter{mycell}
% Based on:
% https://tex.stackexchange.com/questions/7590/
% how-to-programmatically-make-tabular-rows-using-whiledo
\makeatletter
\newcounter{tabindex}
\newtoks\@tabtoks
\@tabtoks\expandafter{\the\@tabtoks\stepcounter{tabindex}#1}}
\newcommand*\resettabtoks{\@tabtoks{}}
\newcommand*\synctabindex[1]{\setcounter{tabindex}{\value{#1}}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother
\begin{document}

%
\resettabtoks
\setcounter{index}{0}
\setcounter{mycell}{0}
\synctabindex{index}
\whiledo{\value{index} < \numexpr\firstROWS\relax}{%

\stepcounter{mycell}
\themycell: \arrayij{first}{\thetabindex}{1} &
\stepcounter{mycell}
\themycell: \arrayij{first}{\thetabindex}{2} &
\stepcounter{mycell}
\themycell: \arrayij{first}{\thetabindex}{3}
\ifthenelse{\equal{\thetabindex}{\nrows}}{\\\hline}{\\\hline}%
}
}
\begin{tabular}{|l|l|l|}
\hline
\printtabtoks
\end{tabular}
\end{document}