2

I'm still working on learning how to use pgfkeys. Here's a snippet of code that I'm working on. It compiles fine:

\documentclass{article}
\RequirePackage{xparse}
\RequirePackage{pgfkeys,pgffor}
\makeatletter
\pgfkeys
  { /ae/polynomials/.cd,
    base/.initial = x,
    coefficients/.initial={3,5,2},
  }

\NewDocumentCommand{\polynomial}{ O{}m } 
  {\pgfqkeys{/ae/polynomials}{coefficients={#2},#1}
   \ae@simple@polynomial
  }

\def\ae@simple@polynomial
  {\begingroup
     \pgfkeys
       {/ae/polynomials/.cd,
          coefficients/.get=\mycoefficients,
          base/.get=\myvar,
       }%%"
     %%\edef\mycoefficients{\pgfkeysvalueof{coefficients}}%%'
     \def\mydenominator{}%%'
     \def\myfraction{}%%'
     %% this next line is to assist in finding the degree of the polynomial
     \foreach \coef [count=\coefi] in \mycoefficients{}
     \edef\degree{\number\numexpr\coefi\relax}%%'
     \foreach \mytmpnumerator/\coef  [count=\coefi] in \mycoefficients%%'
       {%% find the degree of the current term in the polynomial
         \edef\degree{\number\numexpr\degree-\coefi\relax}
         %% determine whether there is a fracion present
         \ifx\mytmpnumerator\coef\else\def\myfraction{\frac}\def\mydenominator{\coef}\fi
         %% examine the coefficient
         \ifnum\coefi>1\relax
           \ifnum\mytmpnumerator<0\relax
             %% subtract the terms: reset numerator to a positive number
             -\edef\mytmpnumerator{\number\numexpr0-\mytmpnumerator\relax}%
           \else
             %% add the terms
             +\fi
         \fi
         %% print the coefficient
         \myfraction{\mytmpnumerator}{\mydenominator}
         %% print out the variables and their powers
         \ifcase\degree\relax
           \or
           \myvar\else
           \myvar^{\degree}
         \fi
         %%'
       } 
   \endgroup
  }
\makeatother
\begin{document}

\[
    \polynomial[coefficients={3,2,4/3}]{}
\]

\end{document}

Now in the pgf manual there is the following example:

\pgfkeys{/text/.store in=\mytext}
\def\a{world}
\pgfkeys{/text=Hello \a!}
\def\a{Gruffalo}
\mytext

which seems simple enough. But when I rewrite my code to follow this example, I get errors.

My first attempt was to do something like this:

\def\ae@simple@polynomial
  {\begingroup
     \pgfkeys
       {/ae/polynomials/.cd,
          coefficients/.estore in=\mycoefficients,
          base/.estore in=\myvar,
       }%%'
....
<Remainder of definition is same as original MWE>

But this results in the error:

! Undefined control sequence.
<argument> \mycoefficients 

l.59     \polynomial[coefficients={3,2,4/3}]{}

? 

This doesn't seem to match what the pgf manual suggests.

Nevertheless, I tried something else:

\def\ae@simple@polynomial
  {\begingroup
     \def\mycoefficients{}%%'
     \def\myvar{}%%'
     \pgfkeys
       {/ae/polynomials/.cd,
          coefficients/.estore in=\mycoefficients,
          base/.estore in=\myvar,
       }%%'
....
<Remainder of definition is same as original MWE>

This time I don't get an error, but \pgfkeys isn't storing my value in the variable.

What am I doing wrong?

UPDATE

Now I was previously doing something like:

\edef\mycoefficients{\pgfkeysvalueof{/ae/polynomials/coefficients}}`

which will work. But I wanted to be lazy and avoid having to write out the entire pathname for the key for each internal macro I'm trying to define.

A.Ellett
  • 50,533
  • The .estore in should be where the .initial was, yes? The .get stuff can be removed now. But why do you use .(e)store in either way? See When to use a regular .initial key or a .store in key? – Qrrbrbirlbel Jul 31 '13 at 20:15
  • @Qrrbrbirlbel I don't want the macros \mycoefficients etc. to have meaning outside of the definition of \ae@simple@polynomial. So, I'm trying to localize the assignment. – A.Ellett Jul 31 '13 at 20:17
  • Yes, the .store in doesn't do anything that defines the key as /.code=\def#1{##1}(or\edefin the case of.estore in). So the macro\myvarsand\mycoefficientswill only be defined if you use the keys. So simply define\polynomialas\begingroup \ae@simply@polynom \endgroup. (But then base is not defaulted, this only works perfectly if you use it globally or preset it in every\polynomial` macro (not a good idea IMO). – Qrrbrbirlbel Jul 31 '13 at 20:26
  • You can defined \def\polyvalueof#1{\pgfkeysvalueof{/ae/polynomials/#1}}. But with .get you already get the shortest version where you don't need to provide the path at all. There is also \pgfkeysgetvalue (see my answer on the linked question) which does work with \let and not \edef (making it a little bit safer). – Qrrbrbirlbel Jul 31 '13 at 20:29
  • @Qrrbrbirlbel The problem with .get is whether I can get it first to expand its arguments. – A.Ellett Jul 31 '13 at 20:33
  • @Qrrbrbirlbel But I'm still confused. There seems to be a problem here between what the manual seems to suggest I can do and what is actually happening. What am I doing that's not following the same idea as the manual? – A.Ellett Jul 31 '13 at 20:34
  • When it is get or when it is set? For get: do an additional \edef. For set: \coefficients/.expanded=<foo>. Well you can't define the keys as /.(e)store in after you set them in \polynomial. That doesn't work, of course, you simply overwrite the key, the store is never done. (Do you mind reducing your MWE do something more clearly or move to chat?) – Qrrbrbirlbel Jul 31 '13 at 20:36
  • If you want to be lazy in that way, try defining, say, \aepget = \pgfkeysvalueof{/ae/polynomials/#1}. – Ryan Reich Jul 31 '13 at 23:20

0 Answers0