9

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?

Jake
  • 232,450

3 Answers3

6

\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}
David Carlisle
  • 757,742
  • @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 09 '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 09 '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 09 '12 at 22:07
5

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}
dhst
  • 1,078
3

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}
Martin Scharrer
  • 262,582