12

I have a file called assocFile.dat. The file has the following format:

0/b

1/d

2/f

3/h

I want to use this file to draw nodes (however it would be nice if this question can be answered in a general way, without having to worry about the number of values in a row).

\foreach\a/\b in {??} {
    \draw (\a,0) node{\b};
}

is there a way to open the file and process tikz commands with the content of it?

EDIT: The .tex file also writes to the file:

I've defined the following macro:

\newcommand{\writeToAssoc}[1]\newcommand{\writeToFile}{\immediate\write\assocfile{\arabic{assocCounter}/#1}\refstepcounter{assocCounter}}

after (!) writing the TikZ code I have the following sequence of commands:

\newwrite\assocfile
\immediate\openout\assocfile=assocFile.dat
\writeToAssoc{b}
\writeToAssoc{d}
\writeToAssoc{f}
\writeToAssoc{h}
\immediate\closeout\assocfile

2 Answers 2

13

You can use catchfile: the command \CatchFileDef defines its first argument to expand to the contents of the file given as third argument; the third is used to apply some setup, here we tell TeX to change the end-of-line character into a comma; next we have to pass the data to TikZ in a suitable form, so we define \tempb to expand to the prolog of \foreach and in the braces we expand \tempa.

\documentclass{article}
\usepackage{catchfile,tikz}

\begin{document}

\begin{tikzpicture}
  \CatchFileDef{\tempa}{assocFile.dat}{\endlinechar=`,}
  \edef\tempb{\unexpanded{\foreach\a/\b in }{\unexpanded\expandafter{\tempa}}}
  \tempb { \draw (\a,0) node{\b}; }
\end{tikzpicture}

\end{document}

(Note: the added \unexpanded around \tempa is irrelevant in your example, but might be necessary if the \b part has arbitrary contents.)

EXAMPLE

\begin{filecontents*}{assocFile.dat}
1/-1-
2/-2-
3/-3-
4/-4-
\end{filecontents*}

\documentclass{article}
\usepackage{catchfile,tikz}

\begin{document}

\begin{tikzpicture}
  \CatchFileDef{\tempa}{assocFile.dat}{\endlinechar=`,}
  \edef\tempb{\unexpanded{\foreach\a/\b in }{\unexpanded\expandafter{\tempa}}}
  \tempb { \draw (\a,\a) node{\b}; }
\end{tikzpicture}

\end{document}

enter image description here

10
  • Thanks! The program only stops after the first line? Is there a way to solve this? It seems to me that the reader actually skips the newline, because the next number is added to the text of the first node. Is there a way to check first if the file exists, and in the case it doesn't skip the commands? Mar 20, 2012 at 1:08
  • @CommuSoft I don't understand: the picture compiles as the added example shows.
    – egreg
    Mar 20, 2012 at 7:25
  • Well the code compiles and no runtime errors, but it only prints the first element resulting in "-1- 2" (without the quotes). So I think it doesn't respect the end-char. And reads until the next /. I'm using Linux and I know there are differences between the endline characters in Windows and Linux. A quick look at your website however shows me you are probably also running Linux :D Mar 20, 2012 at 9:15
  • The file itself is generated by the LaTeX file itself (with \write) statements, another solution would be to place ,-chars instead of newlines as separators. I have searched the internet to solve this, however I haven't found a solution yet. Mar 20, 2012 at 9:25
  • @CommuSoft Probably the problem is exactly in how you generate the file. Can you show how you do it?
    – egreg
    Mar 20, 2012 at 12:12
5

You can read the data file into a pgfplotstable and then loop over the rows by using \pgfplotstableforeachcolumnelement:

\documentclass{article}
\usepackage{pgfplotstable}
\begin{filecontents}{assocFile.dat}
0/b
1/d
2/f
3/h
\end{filecontents}

\pgfplotstableread[header=false,white space chars=/]{assocFile.dat}\datatable

\begin{document}
\begin{tikzpicture}
\pgfplotstableforeachcolumnelement{[index]0}\of\datatable\as\cell{
    \pgfplotstablegetelem{\pgfplotstablerow}{[index]1}\of\datatable
    \node at (\cell,0) {\pgfplotsretval};
}
\end{tikzpicture}
\end{document}

You must log in to answer this question.

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