8

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
  • 1
    @Jake: True. I'll put the (minimally) adjusted MWE into an answer, because of the nicer formatting. – dhst Jun 8 '12 at 7:25
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}
  • @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
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}
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}

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.