Consider the following MWE:
\documentclass[varwidth,tightpage,border=1bp]{standalone}
\usepackage{tikz}
\pagecolor{yellow!15} % ignored with preview, but not w/ varwidth
\begin{document}
\begin{tikzpicture}
\tikzset{/tikz/line width=1cm} % no effect
\draw %[/tikz/line width=1cm] % has effect here
(0,0) -- ++(1,0)
node[fill,scale=0.5](A){};
\pgfkeysgetvalue{/tikz/line width}{\tmp}
\typeout{tmpX \tmp \meaning\tmp}
\end{tikzpicture}
\end{document}
My first question is: here I'm trying to \tikzset{/tikz/line width=1cm}
, but it has no effect (only on document size); the output is:
If I use the \draw[/tikz/line width=1cm]
, then there is effect, and the output is:
So, the question is – how come /tikz/line width
doesn't have any effect? I would have thought it is a "master" key/variable of sorts (which kicks in, if nothing else is specified).
But even more important for me is – how do I read tikz
/pgf
keys? As you can see, I'm trying with \pgfkeysgetvalue{/tikz/line width}{\tmp}
, but when I try to print it to stdout, I get this:
tmpX \tmp \relax
… which means that \tmp
in unexpandable, probably because it has been "let" to \relax
; and so I cannot read any information in /tikz/line width
.
So, how can I read TikZ/PGF keys – in an expandable format, so I can use them in code?
EDIT: After reading Simple example of pgfkeys, I simply tried .initial
:
\tikzset{/tikz/line width/.initial=1cm}
… and afterwards, the stdout printout is:
tmpX 1cmmacro:->1cm
… which means my syntax for reading keys was correct – but apparently, the key /tikz/line width
did not exist, even if I tried to "set" it?!
My question then becomes – what controls the line width of the \draw
in the case when we do not specify anything, and how can I find and print the corresponding key values (if they exist)?
possibly related:
Best Answer
Not every key sets a value.
A key can execute arbitrary code. If we look in
tikz.code.tex
then we see that when you invoke\tikzset{line width=2pt}
then it doesn't set a value, it invokes\tikz@semiaddlinewidth{2pt}
. This, in turn, expands to\tikz@addoption{\pgfsetlinewidth{2pt}}\pgfmathsetlength\pgflinewidth{2pt}
.There are two things going on here. One is that
\pgfsetlinewidth
is set up to be invoked at a later time. The other is that\pgflinewidth
is set to the desired width. Now,\pgfsetlinewidth
is the Real McCoy here. It sets the line width down in the depths of PGF's subsystem. All the messing around with\pgflinewidth
doesn't actually set the real line width. It needs a genuine call to\pgfsetlinewidth
to do this.But the key
/tikz/line width
does not directly call\pgfsetlinewidth
. It sets it up to be invoked at a later time. This is what\tikz@addoption
does. These options get invoked once the path has been constructed and before it is rendered. But the option list is blanked at the start of a path construction. So the effect of the\tikz@addoption
is nullified by the following\draw
command before it has a chance to take effect.You could do
\tikzset{every path/.append style={line width=\pgflinewidth}}
to ensure that the ambient line width is used as the default line width for every path. Or you could define a new key,\tikzset{ambient line width/.code={\pgfsetlinewidth{#1}}}
(no need to explicitly set\pgflinewidth
here).As Paul Gaborit noted in the comments, you can achieve a change of line width for a group of paths by putting them in a scope and setting the line width in the optional argument to the scope. That is,
sets the line width to 1cm for all the intervening paths.
The reason for this is that the optional arguments to the
scope
environment are passed to\tikzset
and then immediately after, the token list\tikz@options
is expanded. This means that the part of theline width
key that is hidden in the\tikz@options
token list is actually executed and therefore the line width is set properly deep in the heart of PGF.