# Problem with default values with pgfkeys

I try to make a fine macro to display the dimensions of lines inside a technical figure. This problem appears in several questions and answers but I would like to add some refinements. The next code is based on several codes and actually I have this :

\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{decorations,decorations.markings,decorations.text}

\begin{document}
\pgfkeys{/pgf/decoration/.cd, distance/.initial = 10pt}

\state{final}{%
\pgfmathsetmacro{\dist}{\pgfkeysvalueof{/pgf/decoration/distance}}
\pgfpathmoveto{\pgfpoint{0pt}{0pt}}
\pgfpathlineto{\pgfpoint{0pt}{2*\dist}}
\pgfpathmoveto{\pgfpoint{\pgfdecoratedpathlength}{0pt}}
\pgfpathlineto{\pgfpoint{(\pgfdecoratedpathlength}{2*\dist}}
\pgfsetarrowsstart{latex}
\pgfsetarrowsend{latex}
\pgfpathmoveto{\pgfpoint{0pt}{\dist}}
\pgfpathlineto{\pgfpoint{\pgfdecoratedpathlength}{\dist}}
\pgfusepath{stroke}
\pgfpathmoveto{\pgfpoint{0pt}{0pt}}
\pgfpathlineto{\pgfpoint{\pgfdecoratedpathlength}{0pt}}
}}

\tikzset{dim/.style args={#1,#2,#3}{%
decorate,
postaction = {%
decorate,
decoration={%
markings,
mark=at position .5 with {\node[inner sep=0pt,
font=\footnotesize,
fill=white,
#3] at (0,0) {#1};}
}}}}

\tikzset{dim sloped/.style args={#1,#2}{%
decorate,
postaction = {%
decorate,
decoration={%
text along path,
raise      = 3pt+\pgfkeysvalueof{/pgf/decoration/distance},
text align = {align=center},
text       = {#1}
}}}}

\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (4,2);
\coordinate (C) at (8,-2);

\draw[dim={5 cm,10pt,above=12pt}]   (A) --  (B);
\draw[dim sloped={7 cm,10pt}]  (B) --  (C);

\draw[fill=gray] (A) circle(1pt);
\draw[fill=gray] (B) circle(1pt);
\draw[fill=gray] (C) circle(1pt);
\end{tikzpicture}

\end{document}


The result is fine and it's what I want. Perhaps it's possible to add some styles to get something more friendly but now the problems :

1) With dim it's possible to write dim={,10pt,} but in this case I get a small white blank space on the main line. I can write \draw[dim={,10pt,above=12pt}] but it's not funny

2) If I can write dim={,10pt,}, I can't write \draw[dim={5 cm, ,above=12pt}]. I get the error "a number is missing". How to use the default or initial value of distance in this case ?

3) If it was possible to write \draw[dim={,,}] then I think it would be more fine to write \draw[dim={}] or perhaps \draw[dim=] . Perhaps something like \draw[dim default] is necessary ?

4) I would to have only one key like dim and not two keys with dim sloped but I try without success to modify one of theses keys. This is not very important because the mixt is a very bad thing. Sloped or not sloped , the user of the key needs to make a choice ! but i would to know if there is a solution.

-
1) You can set the fill to empty if there is no text: fill=\ifx&#1&none\else white\fi. –  Jake May 12 '12 at 18:04
2) The same approach works here: \ifx&#2&0pt\else#2\fi –  Jake May 12 '12 at 18:10
@Jake It's not the most important part of the question but you can transform your comment in an answer, I would be be happy to upvote. –  Alain Matthes May 12 '12 at 18:10
3) If you set dim/.default={,0pt,}, you can just call \draw [dim] .... Is that what you're looking for, or am I misunderstanding your question? –  Jake May 12 '12 at 18:12
I forgot dim/.default thanks ! –  Alain Matthes May 12 '12 at 18:45

1. You can set the fill to empty if there is no text: fill=\ifx&#1&none\else white\fi.
2. Similarly, you can define the distance to be 0pt if no distance is specified: distance=\ifx&#2&0pt\else#2\fi.
3. To be able to call dim without specifying any options, you can set the .default: dim/.default={,0pt,}.
4. You don't need to use the text along path decoration for sloped text along a straight line: You can just supply transform shape to the node of the markings decoration.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations,decorations.markings,decorations.text}

\begin{document}
\pgfkeys{/pgf/decoration/.cd, distance/.initial = 10pt}

\state{final}{%
\pgfmathsetmacro{\dist}{\pgfkeysvalueof{/pgf/decoration/distance}}
\pgfpathmoveto{\pgfpoint{0pt}{0pt}}
\pgfpathlineto{\pgfpoint{0pt}{2*\dist}}
\pgfpathmoveto{\pgfpoint{\pgfdecoratedpathlength}{0pt}}
\pgfpathlineto{\pgfpoint{(\pgfdecoratedpathlength}{2*\dist}}
\pgfsetarrowsstart{latex}
\pgfsetarrowsend{latex}
\pgfpathmoveto{\pgfpoint{0pt}{\dist}}
\pgfpathlineto{\pgfpoint{\pgfdecoratedpathlength}{\dist}}
\pgfusepath{stroke}
\pgfpathmoveto{\pgfpoint{0pt}{0pt}}
\pgfpathlineto{\pgfpoint{\pgfdecoratedpathlength}{0pt}}
}}

\tikzset{
dim/.style args={#1,#2,#3}{%
decorate,
postaction = {%
decorate,
decoration={%
raise=\ifx&#2&0pt\else#2\fi,
markings,
mark=at position .5 with {\node[inner sep=0pt,
font=\footnotesize,
fill=\ifx&#1&none\else white\fi,
#3] at (0,0) {#1};}
}
}
},
dim/.default={,0pt,}
}

\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (4,2);
\coordinate (C) at (8,-2);

\draw[dim={5cm,7pt,}]   (A) --  (B);
\draw[dim={7cm,10pt,transform shape}]  (B) --  (C);
\draw[dim={X,,}]  (A) --  (C);

\draw[fill=gray] (A) circle(1pt);
\draw[fill=gray] (B) circle(1pt);
\draw[fill=gray] (C) circle(1pt);
\end{tikzpicture}

\end{document}

-
transform shape is a fine idea but why ? what is the explanation ? –  Alain Matthes May 12 '12 at 18:48
@Altermundus: By default, only translations apply to nodes, but not other transformations like scaling or rotating. If you set transform shape, the rotation of the coordinate system that is set up by the markings decoration also applies to the node. –  Jake May 12 '12 at 18:50