6

I want to find the width that a node will have when it is later constructed. The width depends on the node's content and the style applied to the node. The style may alter the font using the font key.

My attempt was to use \settowidth on a TikZ picture containing just the node, with the style applied but inner sep set to zero. This works fine if the style used is something like red or text opacity=.1 or, even,fill=colour@background. But if the user adds font=\scriptsize to the style, then compilation fails with a fatal error.

MNWE:

\documentclass[border=10pt,multi,tikz]{standalone} \newlength\mylength \tikzset{% my code/.code={% \settowidth\mylength{\tikz{\node[my style] {something};}}% \draw (0,0) -- +(\mylength,0); }, my style/.style={red}, } \begin{document} \begin{tikzpicture} [ my code, ] \end{tikzpicture} \begin{tikzpicture} [ my style/.style={font=\normalfont},% or font=\scriptszie or font=\itshape or whatever my code, ]% this is line 119 mentioned in the error message \end{tikzpicture} \end{document} 

Here's the error in all its lethal glory:

! TeX capacity exceeded, sorry [input stack size=5000]. \pgf@selectfontorig ->\pgf@selectfontorig \nullfont l.119 ] ! ==> Fatal error occurred, no output PDF file produced! 

Now \nullfont looks clearly dodgy, but I'm not sure why TikZ would be falling through to it.

In any case, my approach is clearly far too simple-minded.

What is the cause of the error and how can it be avoided?

3
  • 1
    If I just do \settowidth{\node ...} I don't get errors, but is that really correct? Commented Aug 15, 2016 at 1:19
  • 1
    I get a width of zero, of course, regardless of content, so I could just as well use 0pt and be done with it ;). Commented Aug 15, 2016 at 1:29
  • 1
    In a tikzpicture, outside of nodes, the default font is \nullfont (cf. p.124, pgfmanual v3.0.1a). Commented Aug 15, 2016 at 8:33

1 Answer 1

4

You may use the calc library and a very distant scope with overlay key:

enter image description here

enter image description here

\documentclass[border=10pt,multi,tikz]{standalone} \usetikzlibrary{calc} \tikzset{% my code/.code={% \begin{scope}[overlay] \node[my style,anchor=west] (a) at (-16000pt,0) {something}; \path let \p1 = (a.east), \p2 = (a.west), \n1 = {veclen(\x2-\x1,0)} in \pgfextra{\xdef\mygloballenght{\n1}}; \end{scope} \draw[black] (0,0) -- +(\mygloballenght,0); }, } \begin{document} \begin{tikzpicture}[my style/.style={red,font=\Large}] \draw[red] (0,1) -- (2,1); \tikzset{my code} \end{tikzpicture} \begin{tikzpicture}[my style/.style={font=\normalfont}] \draw[red] (0,1) -- (2,1); \tikzset{my code} \end{tikzpicture} \end{document} 
7
  • Thanks you! Could you explain why veclen is needed? Why isn't this just like using \x2-\x1? Do you by any chance know why the manual says it is possible to 'escape back' to normal typesetting but then fails to say anything about how to do so?! Commented Aug 15, 2016 at 12:08
  • @cfr I use veclen to not to pay attention to the sign...! You may escape back by using carefully the pgfinterruptpicture environment. Commented Aug 15, 2016 at 13:21
  • Not abs()? Or does that not work with dimensions? Thanks. Commented Aug 15, 2016 at 14:41
  • @cfr abs is another solution (because, here, the second coordinate is zero). Commented Aug 15, 2016 at 15:16
  • Thanks again. Just wanted to make sure I wasn't missing something. (I never use veclen. I do use abs, I guess.) pgfinterruptpicture is interesting. Commented Aug 15, 2016 at 22:28

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.