6

Is it possible to append switches to the existing settings for the TikZ font key?

For example, suppose that I want all nodes to be in the \sffamily typeface. This can be done by setting every node/.append style={font=\sffamily}. I might later wish to have a node that inherits the every node font settings and, additionally, uses the italic shape \itshape. Unfortunately, as the following shows, it does not work to simply add font=\itshape; doing so overrides the previous font setting, and the default type family (in italic) is used.

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}[every node/.append style={font=\sffamily}]
    \node {Sans serif};
    \node [font=\itshape] at (3,0) {Sans serif, italic};
  \end{tikzpicture}
\end{document}

enter image description here

Digging through the manual, I found the <key>/.append handler, which looked promising.

Key handler <key>/.append={<append value>}
Adds the <append value> at the end of the value stored in <key>.

What if I used font/.append=\itshape? Well, this does not work either:

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}[every node/.append style={font=\sffamily}]
    \node {Sans serif};
    \node [font/.append=\itshape] at (3,0) {Sans serif, italic};
  \end{tikzpicture}
\end{document}

enter image description here

Thus, I have two questions:

  • Why does font/.append=\itshape not work here?
  • How can I append switches to the existing settings for font?

1 Answer 1

8

Here's an answer to the second question; I do not know why font/.append=\itshape does not work.

\documentclass{standalone}
\usepackage{tikz}

\makeatletter
\tikzset{font append/.style={font/.expand once=\tikz@textfont #1},
         font append/.value required}
\makeatother

\begin{document}
  \begin{tikzpicture}[every node/.append style={font=\sffamily}]
    \node {Sans serif};
    \node [font append=\itshape] at (3,0) {Sans serif, italic};
  \end{tikzpicture}
\end{document}

enter image description here

Here's why this works: The font key is (roughly) defined with

\tikzset{font/.code=\def\tikz@textfont{#1}}

When needed, the value for font is then accessed through \tikz@textfont. So, the solution is to expand \tikz@textfont to get the current value of font, and then manually append whatever font switches we want.

However, I do not know why font stores its value in \tikz@textfont rather than being a value-key directly.

8
  • You have to append font={\sffamily\itshape}. Actually you have to overwrite as they are not cumulative properties.
    – percusse
    Aug 24, 2012 at 22:34
  • @percusse Yes, I could just write font={\sffamily\itshape}, but what if I change the every node style to have, say, font=\ttfamily (or even some other typeface included via the fontspec package in XeLaTeX)? This way, I don't have to remember to also update the font value for the second node. (I know, I know, I shouldn't be so greedy... :)) What I don't understand is why the value is stored in \tikz@textfont rather than directly in the key itself (i.e., use \pgfkeysvalueof to get the value). Aug 25, 2012 at 19:30
  • Because the mechanism is different. As I said the keys are not commutative. so they cannot be accumulated. Also the mechanism is a code not a style so if you want to pull the current value you have to pull back a macro not a value. Supoose you have keys [bold,italic] the result won't be bold and italic but just italic. Since each will call a different macro. Also the code goes into a box and immediately forgotten once the \nodeparttextbox is established. So pulling back the value is double difficult.
    – percusse
    Aug 25, 2012 at 19:38
  • @percusse Oh, that explanation for why \pgfkeysvalueof doesn't work (i.e., that it's a /.code not a /.style) makes sense. But isn't this a design decision in TikZ? Couldn't one imagine an alternate implementation of the font key that stores the value directly in the key rather than in a macro via the /.code handler? Then, the imaginary implementation of \nodeparttextbox would use \pgfkeysvalueof{/tikz/font} in place of \tikz@textfont. Would that implementation fail because some code goes into a box, as you point out? Aug 25, 2012 at 20:01
  • That's seemingly possible but note that tikz inherits the text properties from its environment and the text typesetting is done out of TikZ. That's why you get a nice blend when you place a TikZ picture inside a document which uses a different font. Therefore, TikZ doesn't actually draw the text which would be great if it did so but that's an incredible task hence only strong externals such as PS can handle such complications. So any key would be pointless unless TeX understands what to do. Right now, by design, TikZ just leaves the box handling to TeX but draws anything else by itself.
    – percusse
    Aug 25, 2012 at 20:14

You must log in to answer this question.

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