Tell me more ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to use pgfkeys in a macro. One key contains a foreach statement which handles a variable number of values. I have some problems concerning the right order of the output. Here a simplified example:

\documentclass[article]{memoir}
\usepackage[latin]{babel}
\usepackage{algpseudocode}
\usepackage{pgfkeys}

\pgfkeys{%
/test/.is family,
/test/.cd,
    key a/.store in = \keyA,
    key a print/.code = \texttt{\keyA},
    key b/.code = {\foreach \x in {#1}{\textbf{\x}--}}
}%

\newcommand\mymacro[1]{\pgfkeys{/test, #1, key a print}}

\begin{document}
\mymacro{key a = valueKeyA, key b = {valueKeyB1, valueKeyB2, valueKeyB3}}
\end{document}

The order of the output is: valueKeyB1–valueKeyB2–valueKeyB3–valueKeyA

How can I achieve that valueKeyA is typeset first? If I put #1 at the end of the key list in my example code I get an error message. If I place it at the end of the key list in my actual code the values of the first keys are missing. I guess it has either something to do with the order in which the values are stored and the keys are executed or my use of #1 is mixed up.

I am using pgfkeys for a short time and would be glad if someone could give me a hint.

share|improve this question

1 Answer

At the moment, the keys are executed in the following order:

  1. key a = valueKeyA. This stores valueKeyA in the macro \keyA.
  2. key b = {valueKeyB1, valueKeyB2, valueKeyB3}. This prints out valueKeyB1--valueKeyB2--valueKeyB3-- (ignoring formatting)
  3. key a print. This prints out \keyA which expands to valueKeyA.

So the problem is that for key a, the processing is split into two parts: storing and printing, whilst for key b this is all done in one step. The order in which you call things means that the two steps for a are split by the one step for b. There are a variety of ways to fix this depending on what you want to achieve.

Before giving some, let me explain why putting #1 at the end doesn't work. This is because that puts step 3 above first, whereupon it tries to print out the value of \keyA which hasn't been set yet.

As I said, how to fix this depends on what you want to do in your real code. Here are a couple.

  1. Put the key a print inside the argument to \mymacro in the right place, so we have:

    \newcommand\mymacro[1]{\pgfkeys{/test, #1}}
    
    \begin{document}
    \mymacro{key a = valueKeyA, key a print, key b = {valueKeyB1, valueKeyB2, valueKeyB3}}
    
  2. Make the key a step both store and print its value, something like:

    \pgfkeys{/test/.cd, key a/.code={\def\keyA{#1}\texttt{#1}}}
    

    Then remove key a print from everywhere.

  3. Make the key b step store its result in a macro to be printed out later. Something like:

    \pgfkeys{/test/.cd, key b/.code={\def\keyB{}\foreach \x in {#1}{\expandafter\gdef\expandafter\keyB\expandafter{\keyB\textbf{\x}--}}}, key b print/.code={\keyB}}
    

    Then add key b print after key a print (or do a combined print all keys).

There are probably more - even if those don't prove to be useful they should help you figure out what features of a solution you would like.

share|improve this answer
Thanks for your help! The order in which the different steps are achieved is quiet what I expected. I did even try something like you suggest in your third solution, but obviously I made a mistake. The second way works fine for me and keeps everything simple, which is a good thing... – Aik May 7 '12 at 13:47
In case the value stored in \keyA is used in the code of several keys which are supposed to deliver different outputs, the third solution would be better. So out of interest i tried to solve the problem this way, too. If I use the code of your third suggestion a long dash (for the three en dashes in the example) is printed, but the values (valueKeyB1-3) are missing. Do you know why the values are not printed? I roughly understand your trick but not well enough to fix this. – Aik May 7 '12 at 20:27
@Aik I will confess to posting this without actually trying out the code. I will take another look at the third version and see what went wrong. – Andrew Stacey May 7 '12 at 20:33

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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