# Applying TikZ options stored in a file

I need to set some TikZ options that have been written to a file by a script.

I thought I could use a helper macro defined with \edef and the expandable version of \input as described in Why is \input not expandable?, but the compilation of my minimal document fails with

Runaway definition?
->\tikzset { every node/.style={ fill=orange!50,draw=black,thick
! File ended while scanning definition of \auxmacro.
<inserted text>
}
l.12 \@@input inputfile.txt


Here's the test document

\documentclass{article}
\usepackage{tikz}
\usepackage{filecontents}

\begin{filecontents}{inputfile.txt}
fill=orange!50,draw=black,thick
\end{filecontents}

\makeatletter
\edef\auxmacro{\noexpand\tikzset{
every node/.style={
\@@input inputfile.txt
}
}}
\auxmacro
\makeatother

\begin{document}
\begin{tikzpicture}
\node {Testnode};
\end{tikzpicture}
\end{document}


How can I apply TikZ options stored in a file?

-
Posibly related catchfiledef-vs-\input-or-\@@input –  percusse Jun 8 '12 at 7:09
I use \input{setTikZ} for this. However, the content of my setTikZ.tex-file includes the tikzset{}-stuff already. Wouldn't a small adjustment to your script solve this problem? –  dhst Jun 8 '12 at 7:11
@dhst: Ah yes, that's a nice pragmatic approach. I'd still be interested to see a way of using a file containing only the actual keys, not the \tikset macro. –  Jake Jun 8 '12 at 7:19
@Jake: True. I'll put the (minimally) adjusted MWE into an answer, because of the nicer formatting. –  dhst Jun 8 '12 at 7:25

\everyeof e-tex primitive is your friend:

\documentclass{article}
\usepackage{tikz}
\usepackage{filecontents}

\begin{filecontents}{inputfile.txt}
fill=orange!50,draw=black,thick
\end{filecontents}

\everyeof{\relax}
\makeatletter
\def\auxmacro#1\relax{\tikzset{every node/.style={#1}}}
\expandafter\auxmacro\@@input inputfile.txt
\makeatother

\begin{document}
\begin{tikzpicture}
\node {Testnode};
\end{tikzpicture}
\end{document}

-
Works like a charm, thank you! –  Jake Jun 8 '12 at 8:59
@Jake Be careful that no \relax must be in the input file, but the delimiting token can be changed. Also \everyeof should probably be reset. –  egreg Jun 9 '12 at 10:19
@DavidCarlisle: Any tinkering with \expandafter\auxmacro\@@input inputfile.txt fails. For example, \auxmacro\input inputfile.txt doesn't make any sense, since LaTeX did \def\input{\@ifnextchar\bgroup\@iinput\@@input}. What is so special about \@@input, which is the original \input? (\ifx\@@input\@undefined\let\@@input\input\fi) –  Ahmed Musa Jun 9 '12 at 21:03
@AhmedMusa the primitive \input known as \@@input in latex is expandable which has advantages and makes it amenable to being expanded with \expandafter. However it has a weird (and system dependent) syntax. The LaTeX version uses normal {...} syntax but because it also supports the priginal syntax without braces it does an \@ifnextchar test which makes it not expandadable. –  David Carlisle Jun 9 '12 at 22:07

Including all necessary macros in the external file allows for a very straightforward approach:

\documentclass{article}
\usepackage{tikz}
\usepackage{filecontents}

\begin{filecontents}{inputfile.tex}
\tikzset{every node/.style={
fill=orange!10, draw=black, thick
}}
\end{filecontents}

\input{inputfile}

\begin{document}
\begin{tikzpicture}
\node {Testnode};
\end{tikzpicture}
\end{document}

-

Unfortunately you can't use \@@input in an \edef definition because the end-of-file triggers an error. There is the catchfile package which does this task for you by using some e-TeX features (similar to David's answer). It stores the file content in a macro which then can be used together with /.expand once in a \tikzset macro:

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

\begin{filecontents}{inputfile.txt}
fill=orange!50,draw=black,thick
\end{filecontents}

\makeatletter
\CatchFileDef{\extstyles}{inputfile.txt}{}
\tikzset{
every node/.style/.expand once=\extstyles
}
\makeatother

\begin{document}
\begin{tikzpicture}
\node {Testnode};
\end{tikzpicture}
\end{document}

-