6

I'm learning pgfkeys and trying to use it for key-value argument handling.

I'm trying to set a style using it. For it, I defined a macro \mystyle to handle it, and use the same technique as in here to solve the execution of the style. Now, if I want to add more code to the argument using .append, the macro doesn't reflect the changes on it.

\documentclass{article}
\usepackage{tikz}

\pgfkeys{
  /test/.cd,
  my style/.store in=\mystyle,
  my style/.default={draw,color=cyan,},
  my style,
  % helpers to get execution on styles
  % https://tex.stackexchange.com/a/85647/7561
  /tikz/.cd,
  execute style/.style = {#1},
  execute macro/.style = {execute style/.expand once=#1},%
}

\newcommand{\makenode}[2][]{
\pgfkeys{/test/.cd,#1}
\begin{tikzpicture}
\node[execute macro=\mystyle]{#2};
\end{tikzpicture}
}


\pagestyle{empty}
\begin{document}

\makenode{testing}
\makenode[my style={draw,color=blue,line width=5pt,}]{testing blue}
% this should be yellow, with thin line
\makenode[my style/.append={color=yellow,line width=1pt}]{testing blue}


\end{document}

From what I understood from the manual, the argument should be appended to the value of the key. So if I have in the value <something>, and I do <key>/.append={<more>}, the value in <key> should be <something><more>. But that isn't happening.

What am I missing?

adn
  • 11,233

1 Answers1

6

Not sure why you want to use =, .append= and .default= at the same time. The remaining is based on my guess.

  • If you pass [my style=\A] to \makenode, the style list \A is applied.
  • If you pass [append my style=\B] to \makenode, the style list \B is applied along with draw,color=cyan, your default.
  • If you pass nothing to \makenode, the \newcommand inserts its default, append my style={}. That means nothing but only draw,color=cyan is applied.

\documentclass[tikz,border=10]{standalone}
\pgfkeys{
  /test/.cd,
  my style/.style={
    /test/final style/.style={#1}
  },
  append my style/.style={
    /test/final style/.style={draw,color=cyan,#1}
  }
}
\newcommand{\makenode}[2][append my style={}]{
    \pgfkeys{/test/.cd,#1}
    \begin{tikzpicture}
        \node[/test/final style]{#2};
    \end{tikzpicture}
}
\begin{document}
    \makenode{testing}
    \makenode[my style={}]{testing plain}
    \makenode[my style={fill=blue,line width=5pt}]{testing blue}
    \makenode[append my style={fill=yellow,line width=1pt}]{testing yellow}
\end{document}

Hence

  • for testing, it is drawn in cyan, your default;
  • for testing plain, all styles are reset;
  • for testing blue, draw and color=cyan is covered so no drawing happens;
    • (Otherwise it should be much taller due to line width=5pt)
  • for testing yellow, filling happens along with drawing.

Too Long. Short?

The essential problem, with cyan being the default, is what you expect the following do?

  • \makenode[blue]{testing}
  • \makenode[]{testing}

This sounds stupid: The first node appears in blue while the second obeys the default color... But wait, what is the default now? Blue or cyan?

The answer may be blue because writing my style=blue or my style/.style=blue causes PGF to forget the old value/old style. The only way to keep a global default is my style/.default={cyan}, which assumes my style to be an action. An action is declared by .code and neither .append nor .append style is applicable.

In conclusion, =, .append, and .default are not designed to work together. Maybe there is a tricky way to get over it. But sooner or later you will confuse PGF... and yourself.

Symbol 1
  • 36,855
  • I'm learning pgfkeys, and in the page 897 in the manual it says that .append should work like .append style but for the value. Since, I may need to use the same for several keys, I thought that the way to go was to use a similar style as the default for styles, i.e., .append style. And regarding the use of =, .default, can you elaborate why is not good to use them? – adn Mar 12 '15 at 12:12
  • @adn It is not not good. The only reason it that they are not designed to work together. Have a look at my edit. – Symbol 1 Mar 12 '15 at 13:31
  • your /.code handlers can be written simply as /.style because they just set keys and /.style takes care of the family switches for you too. – percusse Mar 12 '15 at 14:12
  • I knew it is not minimal!! thanks @percusse – Symbol 1 Mar 12 '15 at 14:36