5

I would like to create some name badges using a loop. I have a spreadsheet with names and affiliations that I save in names.csv file as follows

"Name1","Surname1","Affiliation1",
"Name2","Surname2","Affiliation2",
"Name3","Surname3","Affiliation3"

I can copy the content of names.csv in a string array and use a loop to recover the entries. The following is an example of working code producing the output Surname2:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgf}
\usepackage{array}

\def\names{{"Name1","Surname1","Affiliation1",
"Name2","Surname2","Affiliation2",
"Name3","Surname3","Affiliation3"}}

\begin{document}

\pgfmathparse{\names[4]}\pgfmathresult

\end{document}

I can use this idea to create hundreds of name badges in a loop. But instead of writing the whole list in the .tex file I would like to call directly my names.csv file. I used the modified code

\documentclass{article}
\usepackage{tikz}
\usepackage{pgf}
\usepackage{array}

\def\names{{\input{names.csv}}}

\begin{document}

\pgfmathparse{\names[4]}\pgfmathresult

\end{document}

which apparently enters in an endless loop. I understood that \input{} works just as copy-pastying, but it doesn't seem the case. Of course I can work in the spreadsheet and then copy paste the names.csv file content, but I would like to understand what happens. Any clues?

PS edit: The suggested solution is enough for my case. But still I would like to be able to define macros with \input'. It seems that\input{}' inside a macro is not expanded immediately. I mean if I have some code in file.tex', that I want to plugin in a new macro,\def\mymacro{\input{file}}' will save \mymacro' as '\input{file}' and will only look what's inside the file when I call the macro in the document. That's why in the previous example\names' is not understood as an array. In the same way

\begin{filecontent*}{newfile.tex}
\input{file}
\end{filecontent*}

will save the code \input{file}' innewfile.tex', but not the content in `file.tex'. Anyone has any idea how to force input to expand?

0

3 Answers 3

4

Instead of importing the whole csv file you can read it row wise. There are some packages for this, here I use csvsimple. The file names.csv is created by the filecontents environment just to have it all in one file for this example.

\documentclass{article}
\usepackage{filecontents}
%% Create file
\begin{filecontents*}{names.csv}
Name1, Surname1, Affiliation1
Name2, S. Urname2, A f filiation2
Name3, Surname3, Affiliation3
Name4, Surname4, Affiliation4
Name5, Surname5, Affiliation5
\end{filecontents*}
\usepackage{tikz}
\usepackage{csvsimple}
\begin{document}
List of participants:
\begin{itemize}
  \csvreader[no head]{names.csv}{1=\name, 2=\surname, 3=\affiliation}{%
  \item \name\ \surname\ at \affiliation
  }
\end{itemize}

Badges:\newline
\csvreader[no head]{names.csv}{1=\name, 2=\surname, 3=\affiliation}{%
  \begin{tikzpicture}
    \draw[clip] (0,0) rectangle (6,4);
    \node at (3,2){\Large\name\ \surname};
    \node at (3,1.3){\affiliation};
    %% Logo
    \fill[color=red!40] (0.7,3.3) circle(1);
    \node[fill=green!40,opacity=0.5,rounded corners=5pt,anchor=west] at (0.8,3.5){\textsf{The Epic Event}};
    \node[anchor=west] at (0.8,3.5){\textsf{The Epic Event}};
  \end{tikzpicture}
}

\end{document}

enter image description here

1
  • This solution is nice enough for my case, and runs smoothly. But still I wonder if it is possible to work with arrays, for a more flexible case.
    – Alberto
    Commented Apr 26, 2017 at 17:24
1

The readarray package is set up to digest file data into arrays.

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{names.csv}
Name1,Surname1,Affiliation1,
Name2,Surname2,Affiliation2,
Name3,Surname3,Affiliation3
\end{filecontents*}
\usepackage{tikz}
\usepackage{pgf}
\usepackage{array}

\usepackage{readarray}
\readarraysepchar{,}
\begin{document}

\readdef{names.csv}\namedata

\readarray\namedata\names[-,\ncols]

\names[2,2] and \names[3,3]
\end{document}

enter image description here

5
  • Is it possible to use readarray to reproduce the functionality of this answer tex.stackexchange.com/a/634894/2288?
    – Diaa
    Commented Jun 9, 2022 at 6:18
  • @Diaa Given that each row of the file could contain a different number of comma-separated entries, I'm thinking that listofitems might have a better chance of working...however, you might use readarray's \readdef to get the file contents into a \def, to then be operated on by \readlist* of the listofitems package. Commented Jun 12, 2022 at 0:20
  • @Diaa For example, using the mycoeffs.csv file data in your cited question, \ignoreemptyitems \readarraysepchar{\\} \readdef{mycoeffs.csv}\mydata \setsepchar{\\/,} \readlist*\mylist{\mydata} will get the file into an array \mylist, such that \mylist[2,1] will yield the first element of the second row, that is Second; \mylist[3,2] will similarly yield 5 (the 2nd element of the 3rd row); and the number of row elements can be determined with, for example, \listlen\mylist[3], which indicates that row 3 has 4 elements in it. Commented Jun 12, 2022 at 0:32
  • @Diaa Once the data is into an array, as shown above, then you just need a macro to identify from which row you want to extract data, and to set the polynomial, based on how many elements are in the given row data. Commented Jun 12, 2022 at 0:36
  • Thanks for your input; the main challenge is that I need to look up the row and access its values by searching for the rows using the cell in the first column. So, I can find the data I need without having to remember where it lies as done here and here.
    – Diaa
    Commented Jun 13, 2022 at 12:27
1

You need to define \names so that its definition is the contents of the file. This means some expansion is required:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgf}
\usepackage{array}

\begingroup
\makeatletter
\endlinechar=-1\relax
\everyeof{\noexpand}\relax
\edef\x{\endgroup\def\noexpand\names{{\@@input names.csv }}}\x

\begin{document}

\pgfmathparse{\names[4]}\pgfmathresult

\end{document}
1
  • Can you explain why and how this works to load the contents of a file into a macro? I tried forever with \edef and \expandafter to get just the actual text in a file expanded into a macro, and I kept getting weird complaints like Argument of \@iinput has an extra } that I can't parse. What is \@@input, as opposed to normal \input? Why are you creating a group and then ending it inside \x? Why do you need to define \x at all if you then immediately use it? Where is the documentation for \everyeof and how do you know to use it here?
    – interfect
    Commented May 10, 2021 at 20:57

You must log in to answer this question.

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