# \widthof text in a def'd subroutine inside a tikzpicture? [duplicate]

I have already seen \widthof within tikzpicture, but this is slightly different.

I have a rather complex Tikz image, which I'd like to eventually include in a Latex document; as such, I'd like this .tikz file to be as self contained as possible. There are a bunch of commands in there relevant to building the plot; unfortunately if I leave them as-is, I get Wrong placement (and/or size) of picture / plot with groupplot of table (... and discontinuity)? (even in a standalone .tex file). Specifically, if the commands execute between {document} and {tikzpicture}, then the extraneous space is generated; I could have the commands in preamble, but then the .tikz file will not be self-contained.

So, I thought I'd collect these commands in a \def subroutine, and have them run inside the {tikzpicture}. Unfortunately, one of those commands is \widthof, which I intended for measuring the width of the text "256" in the tiny font, and wanted to use that to set the x scale of the pgfplot. So I came to this MWE:

% \documentclass{article}
\documentclass{standalone}

\usepackage{calc} %\widthof
\usepackage{pgfplots}
\pgfplotsset{compat=1.5.1}
\usetikzlibrary{pgfplots.groupplots}
\usepackage{pgfplotstable}

\pagecolor{yellow!15}

% \newcommand\prepCmds{
\def\prepCmds{
\newlength{\smlblwtmp}
\setlength{\smlblwtmp}{\widthof{\tiny 256}}
\global\let\smlblwid\smlblwtmp
\typeout{smlblwid FIRST: \the\smlblwid}
}

% \prepCmds{} % smlblwid FIRST: 10.2085pt

\begin{document}

% \prepCmds{} % smlblwid FIRST: 10.2085pt

\begin{tikzpicture}

\prepCmds{} % smlblwid FIRST: 0.0pt

\begin{axis}[
x=2*\smlblwid,
]
\end{axis}

\end{tikzpicture}

\end{document}


As it can be seen, only when I call the \prepCmds inside {tikzpicture}, the \widtgof fails and returns 0 (everywhere else, it returns a correct number); when that happens, pdflatex shows this:

PGFPlots warning: The ticklabel anchor cannot be determined, the normal vector
-(0.0pt,-1.0pt) and the unit y vector (0.0pt,1.00005pt) are almost parallel (ab
s(cos(angle)) = 1.00005pt)!
pgfplots@borderanchor@for@axis 1,2,3: y, 1v0, rectangle


One would say, as expected for x unit of 0 - but it took me hours to debug this so far: among other things, I inserted a \message in the pgfplots source so the arguments of \pgfplots@borderanchor@for@axis are plotted (when the width is not zero, with \prepCmds running elsewhere, the arguments are x, v00, rectangle).

Obviously, all this boils down to \widthof returning 0 inside a {tikzpicture}; now that I know this, I guess I could move just the \widthof calculation out of the subroutine. However, I'd still prefer for the \widthof calculation to be inside the subroutine, for self-containment reasons, so I would like to ask: why is \widthof inside a {tikzpicture} zero; and is there some sort of a trick (maybe "globalize" some tikz intern variables?) that would make \widthof work inside a {tikzpicture} properly?

## marked as duplicate by egreg, percusse tikz-pgf StackExchange.ready(function() { if (StackExchange.options.isMobile) return; $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() { var$hover = $(this).addClass('hover-bound'),$msg = $hover.siblings('.dupe-hammer-message');$hover.hover( function() { $hover.showInfoMessage('', { messageElement:$msg.clone().show(), transient: false, position: { my: 'bottom left', at: 'top center', offsetTop: -7 }, dismissable: false, relativeToBody: true }); }, function() { StackExchange.helpers.removeMessages(); } ); }); }); Jun 7 '14 at 12:59

• First of all move \newlength{\smlblwtmp} outside the definition of \prepCmds. About the specific problem: inside a tikzpicture, the current font is set to \nullfont that has no character, so the width you're measuring is zero. – egreg Jun 7 '14 at 12:36
• Many thanks @egreg - that explains it; if you don't mind posting that as an answer, I'll accept it. Cheers! – sdaau Jun 7 '14 at 12:53
• I'd rather close this as a duplicate. – egreg Jun 7 '14 at 12:57
• Oh, damn. I have a hammer. please let us know if you want to keep it open. I didn't know that it closes right away – percusse Jun 7 '14 at 13:00
• @egreg: sure - closure sounds good, the answer is in the comments anyways (as long as the question isn't deleted, I do think alternative formulations can be useful :)) Cheers! – sdaau Jun 7 '14 at 13:01

As @egreg mentioned, inside the TikZ environment, in order to keep the non code garbage not printed, \nullfont is applied. So

\tikz{la la laaa. x sdf tgrert}


prints nothing. Here you can also use PGF math function width too without calc but as a stupid side-effect you need to protect the text font switches three times from expansion.

% \documentclass{article}
\documentclass{standalone}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.5.1}
\usetikzlibrary{pgfplots.groupplots}
\pagecolor{yellow!15}

\newlength\smlblwid

\def\prepCmds{
\pgfmathparse{width("\noexpand\noexpand\noexpand\noexpand\noexpand\noexpand\noexpand\tiny 256")}
\smlblwid=\pgfmathresult pt
}

\begin{document}

\begin{tikzpicture}

\prepCmds{}

\begin{axis}[
x=2*\smlblwid,
]