3

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:

+--------------+-------------+------------+
| 1  xyzxyz    | 2  sadsdasd | 3  sadasdf |
| 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{sadsdasd}
\putItem{dfasdfas}
\putItem{23ea3ad}
\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
5
\documentclass{article}

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

\begin{flushleft}
\putItem{xyzxyz}
\putItem{sadsdasd}
\putItem{dfasdfas}
\putItem{23ea3ad}
\putItem{898sd} 
\putItem{xyzxyz}
\putItem{sadsdasd}
\putItem{dfasdfas}
\putItem{23ea3ad}
\putItem{898sd}
\end{flushleft}

\end{document}
2

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

enter image description here

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,
    sadsdasd,
    dfasdfas,
    23ea3ad,
    898sd,
    xyzxyz,
    sadsdasd,
    dfasdfas,
    23ea3ad,
    898sd,
}%

\end{document}
0

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}
\usepackage{readarray}
\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
  \newcommand\addtabtoks[1]{%
    \@tabtoks\expandafter{\the\@tabtoks\stepcounter{tabindex}#1}}
  \newcommand*\resettabtoks{\@tabtoks{}}
  \newcommand*\synctabindex[1]{\setcounter{tabindex}{\value{#1}}}
  \newcommand*\printtabtoks{\the\@tabtoks}
  \makeatother
\begin{document}
\readdef{data.txt}{\tmpa}
\readArrayij{\tmpa}{first}{3}

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

  \addtabtoks{%
    \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}%
  }
  \addtocounter{index}{1}%
}
\begin{tabular}{|l|l|l|}
  \hline
  \printtabtoks
\end{tabular}
\end{document}

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.