1

I need to define a style contained in a macro without expanding this macro.

The problem is that if the macro contains several keys like or sets a value to a key like here:

\def\myconfiguration{text={The value of my great counter is \themycounter}}

it fails because pgfkey tries to first evaluate the macro, and then checks if a key is named text={The value ...}, which of course is wrong.

So what is the good way to define a pgfkey style inside a macro, and make sure that this macro is not expanded at definition time?

MWE:

\documentclass{article}

\usepackage{pgfkeys}

\newcounter{mycounter}
\def\myconfiguration{text={The value of my great counter is \themycounter}}

\pgfkeys{
  /prAtEnd/.cd, 
  % Text
  text/.code={\def\sayhello{#1}},
  configuration options/.style={
    text={The counter value is \themycounter},
    \myconfiguration %% This lines fails!
  },
}

\begin{document}

\pgfkeys{/prAtEnd/.cd, configuration options}

\sayhello

\stepcounter{mycounter}
\sayhello

\stepcounter{mycounter}
\sayhello
\end{document}

-- EDIT -- I would like to have at the end the same result as if \myconfiguration was replaced with it's definition, i.e. text={The value of my great counter is \number\value{mycounter}}. So the output must be:

enter image description here

tobiasBora
  • 8,684

2 Answers2

1

\myconfiguration is not a style. Below is something that works, but if you tell us what you really have in mind there might very well be a better proposal.

\documentclass{article}

\usepackage{pgfkeys}

\newcounter{mycounter}
\def\myconfiguration{text={The value of my great counter is \number\value{mycounter}}}

\pgfkeys{/prAtEnd/.cd, 
  % Text 
  text/.code={\def\sayhello{#1}},
  configuration options/.style={
    text={The counter value is \number\value{mycounter}}},
  configuration options/.style/.expand once=\myconfiguration
}

\begin{document}

\pgfkeys{/prAtEnd/.cd, configuration options}

\sayhello

\stepcounter{mycounter}
\sayhello

\stepcounter{mycounter}
\sayhello
\end{document}

enter image description here

  • thanks for the answer, but it's not exactly what I want. What I would like to have is to replace all the The counter value is X with The value of my great counter is X (as configured in the \myconfiguration macro). Basically, you can imagine that you replace the \myconfiguration with text={The value of my great counter is \number\value{mycounter}} to get what I want. (see my edit) – tobiasBora May 06 '19 at 18:39
  • @tobiasBora I added a version that does that. However, I would like to argue that it would be much more elegant if the store the revised configuration options in a style, and not in a macro. –  May 06 '19 at 18:53
  • Thanks for the edit, I didn't know the .expanded trick. But there is still two issues: first I'd like to avoid to change the definition of \myconfiguration because I would like it to be consistent with the remaining configuration that does not require \noexpand. Second, this overwrite all the definitions of configuration options (this may be fixable by using a temporary style, but sounds strange). – tobiasBora May 06 '19 at 19:06
  • For your second comment, I'm not sure if I can, because I'm getting this macro from two ways: the first time I'm getting it from kvoptions (this is send to package configuration), and the second time I need to define a "global" style to go though environments, so I use \global\def..., and unfortunately pgfkeys seems to be only local. – tobiasBora May 06 '19 at 19:06
  • @tobiasBora Well, the main problem is that I do not understand your question. I thought I did to some extent, but then there are all the extra boundary conditions not listed in the question. You wrote "I would like to have at the end the same result as if \myconfiguration was replaced with it's definition", and this is what the above answer accomplishes. –  May 06 '19 at 20:00
  • Well your last version is indeed very close (I added +1), but the thing is that you modified the definition of \myconfiguration by adding this "\noexpand" which is a bit of "cheating". Indeed, if you copy paste text={The value of my great counter is \noexpand\number\noexpand\value{mycounter}}} in place of \myconfiguration the compilation will fail because of the noexpand. So it leads to two "syntax" for a user, depending on whether he is configuring the package (use "noexpand") or directly a style (no "noexpand") which is confusing for him. Is it clearer? Sorry I'm super bud to explain… – tobiasBora May 06 '19 at 20:24
  • And sorry I'm not always super-clear, I hope it's clearer now, and thanks a lot for your help. – tobiasBora May 06 '19 at 20:25
  • @tobiasBora The basic problem is that you want to assign a macro to a style. But then TikZ does by default not know what to do with it. If you expand the macro, this is as if you gave TikZ the content of the macro, so that works, but then you need to prevent \number and \value from being expanded. Alternatively you could decompose the thing in two pieces: the text and the \number\value{mycounter} bit, which you could store in a code. Would this be an option? –  May 06 '19 at 20:34
  • The thing is that this text could contain arbitrary macro, including links, counters, references... And I cannot really know in advance what shape it must have... I tried to play a bit with expl3/edef+noexpand/... solutions explains here to say "expand just once", but I'm soo bad with it ^^ Wouldnhttps://tex.stackexchange.com/questions/104506/expanding-arguments-before-macro-call – tobiasBora May 07 '19 at 07:09
  • (and by the way if you have another solution, could you please keep the current solution as well? It does not match all my needs but it can be useful for people that does not mind these two-syntax stuff) Thanks! – tobiasBora May 07 '19 at 07:10
  • I finally have a working code, could you let me know if you think it's the best way to proceed? If you want you can edit your answer and add this method as well (and eventually explain quickly what this magic \unexpanded\expandafter expands only once) so that I can accept your answer ;-) Thanks! – tobiasBora May 07 '19 at 07:30
  • Oh, I found a still better way inspired by your method: change .style/.expanded into .style/.expand once and it works exactly as expected! Once you change it I'll accept the answer. Thanks a lot! – tobiasBora May 07 '19 at 09:11
  • @tobiasBora That's very generous of you and I will be happy to revert my answer if you change your mind and write your own answer. (And I learned something here. ;-) –  May 07 '19 at 14:03
1

After getting inspired by this, I came up with this solution (edit: .expand once is better):

\documentclass{article}

\usepackage{pgfkeys}

\newcounter{mycounter}
\def\myconfiguration{text={The value of my greatt counter is \number\value{mycounter}}}

\show\myconfiguration

\pgfkeys{
  /prAtEnd/.cd, 
  % Text
  text/.code={\def\sayhello{#1}},
  second text/.code={\def\saybye{#1}},
  configuration options/.style={
    text={The counter value is \number\value{mycounter}},
  },
}

\edef\mydefinepgfkeys{\noexpand\pgfkeys{%
    /prAtEnd/.cd,%
    configuration options/.append style={%
      \unexpanded\expandafter{\myconfiguration}%
    },%
  }}\mydefinepgfkeys

\begin{document}

\pgfkeys{/prAtEnd/.cd, configuration options}

\sayhello
% \saybye
\stepcounter{mycounter}
\sayhello

\stepcounter{mycounter}
\sayhello
\end{document}
tobiasBora
  • 8,684