3

Note: this question follows my previous question about \pgfkeyssetvalue.

The \pgfkeyssetvalue is defined in pgfkeys.code.tex file by:

\newtoks\pgfkeys@temptoks
% [...] 
\long\def\pgfkeyssetvalue#1#2{%
  \pgfkeys@temptoks{#2}\expandafter\edef\csname pgfk@#1\endcsname{\the\pgfkeys@temptoks}%
}

How to define \pgfkeyssetexpandedvalue as \pgfkeyssetvalue but where the second argument is expanded?

As this second argument can contains thinks like #1, ... #9, we can't use \edef.

PS: The \pgfkeyssetexpandedvalue macro can help to fix this bug revealed by “Example: Spherical and cartesian grids” isn't compiled to the right figure.

10
  • what do you mean by expanded here? (that is you clearly mean something different to the expansion done by edef, otherwise you could use edef) what do you want to happen to #1 or \def\foo{} appearing within the argument, would you want \foo to expand to the value it had before the definition (which is what edef would do)? Jan 2, 2017 at 23:25
  • @DavidCarlisle All sequences #1...#9 (and may be ##) should be kept as they are, \def is not expandable and \foo should be expanded. Jan 2, 2017 at 23:34
  • @DavidCarlisle ...Exactly as with \edef but without the error "Illegal parameter number in definition"! ;-) Jan 2, 2017 at 23:40
  • so if \foo has been defined by \def\foo{abc} you want \def\foo{} in the argument to expand to \def abc{} and generate an error when used, just as it would in \edef but \def\foo#1{#1} it normally doesn't make sense to keep #1 as #1 if \foo has been expanded ? Jan 3, 2017 at 1:01
  • @DavidCarlisle If \foo has been defined by \def\foo{abc}, I would like that \pgfkeyssetexpandedvalue{xxx}{\foo{} #1 #2} defines the same macro that \pgfkeyssetvalue{xxx}{abc #1 #2}... if possible! Jan 4, 2017 at 1:02

1 Answer 1

4
+500

Maybe you need something like this:

\long\def\pgfkeyssetexpandvalue#1#2{%
  \edef\tmp##1##2##3##4##5##6##7##8##9{#2}%
  \expandafter\def\csname pgfk@#1\expandafter\endcsname\expandafter
  {\tmp{####1}{####2}{####3}{####4}{####5}{####6}{####7}{####8}{####9}}%
}


%% test:
\pgfkeyssetexpandvalue{xxx}{aha#1+#3}

\catcode`@=11
\show\pgfk@xxx  %% \pgfk@xxx=macro: aha##1+##3.

\end

Edit: Considering your comment (that you need to double all hashes, not only single hashes followed by numbers), you can try the following trick:

\newtoks\mytoks
\long\def\pgfkeyssetexpandvalue#1#2{%
   \mytoks={#2}%
   \scantokens\expandafter{\expandafter\mytoks\expandafter{\the\mytoks}}%
   \expandafter
      \edef\csname pgfk@#1\expandafter\endcsname\expandafter{\the\mytoks}%
}

%test
\pgfkeyssetexpandvalue{xxx}{abc#1+##3}

\catcode`@=11
\show\pgfk@xxx  % \pgfk@xxx=macro: abc##1+####3.

\bye

The line 4 of the code is the core of the trick: the hashes are doubled in \mytoks using \scantokens.

5
  • Very nice trick. I tried it in pgfkeys.code.tex and it seems to work. Jan 5, 2017 at 14:21
  • There is still a problem: I can't use a value like {\def\noexpand\foo##1{[##1]}\noexpand\foo{#1}} (valid for\edef). The error is ! Illegal parameter number in definition. Jan 6, 2017 at 14:36
  • @PaulGaborit I don't understand your intent. The usage \noexpand\foo{#1} has no sense, because the #1 parameter is out the definition body and out of parameter mask of \foo. The meaningful usage is only {\def\noexpand\foo#1{[#1]}\noexpand\foo{something-real}}
    – wipet
    Jan 6, 2017 at 16:29
  • Your second proposition is very good. My last request: is it possible to use \pgfkeys@temptoks instead of \mytoks? (the catcode of @ can cause problem to \scantokens). Jan 8, 2017 at 0:57
  • @PaulGaborit If you need to use @ in \temptoks, then you can try \pgfkeys@temtoks=\scantokens\expandafter{\expandafter{\the\pgfkeys@temptoks}}.
    – wipet
    Jan 8, 2017 at 10:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.