Take the 2-minute tour ×
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'm creating rather complicated diagram and would like to put all the controls all in one easy to find location and not scattered throughout the document. To do this, I've created setter and getter functions for a LaTeX3 property list. Here's the code:

\documentclass{article}
\usepackage{pstricks,pst-node}
\usepackage{xparse}
\ExplSyntaxOn
\prop_new:N \g__sunset_plist
\NewDocumentCommand{\setattr}{ mm }
    {
        \prop_gput:Nnn \g__sunset_plist {#1} {#2}
    }
\DeclareExpandableDocumentCommand{\gettr}{ m }
    {
        \prop_get:Nn \g__sunset_plist { #1 }
    }
\ExplSyntaxOff
\setattr{my_linestyle}{linestyle=dashed,linecolor=blue}
\setattr{my_line}{\psline[linestyle=dashed,linecolor=blue](A)(B)}
\pagestyle{empty}
\begin{document}

\begin{pspicture}(10,10)

    \pnode(0,0){A}
    \pnode(10,10){B}
    \pnode(10,0){C}
    \pnode(0,10){D}

    \gettr{my_line}   %% <-- works as expected
    \psline[\gettr{my_linestyle}](C)(D)  %% <-- not working

\end{pspicture}

\end{document}

The line

    \gettr{my_line}   %% <-- works as expected

works but I don't want to approach the problem this way. I'd prefer to write

    \psline[\gettr{my_linestyle}](C)(D)  %% <-- not working

because this line shows me exactly what I'm doing: drawing a line from point C to point D. What's hidden are the attributes to that line. I'd prefer this approach. But what seems to be happening is that when \gettr{my_linestyle} is expanded, LaTeX sees:

    \psline[{linestyle=dashed,linecolor=blue}](C)(D)  %% <-- not working

How do I get my getter function to expand without the surrounding {...}?

EDIT

Here's the error message

! Package xkeyval Error: `linestyle=dashed,linecolor=blue' undefined in familie
s `,pstricks,pst-node'.

See the xkeyval package documentation for explanation.
Type  H <return>  for immediate help.

So it seems that some kind of expansion is happening before xkeyval is getting the keys.

share|improve this question
1  
You must feed \psline with the list of options, not with something that ultimately expands to a list of options. –  egreg Feb 6 '13 at 18:51
    
@egreg. That's what I was afraid of hearing. :( –  A.Ellett Feb 6 '13 at 18:55
    
@A.Ellett This is general: most TeX keyval implementations are very careful to avoid any expansion of their argument. –  Joseph Wright Feb 6 '13 at 19:32
    
@JosephWright, I guess I might have suspected that. But my error seems to suggest that \gettr{...} is getting expanded, but then placed within its own group before getting passed as keys. I was hoping there would be a trick to remove the surrounding parentheses before keyval got ahold of anything. –  A.Ellett Feb 6 '13 at 19:56
    

1 Answer 1

up vote 3 down vote accepted

You can define a "prefix" macro:

\documentclass{article}
\usepackage{pstricks,pst-node}
\usepackage{xparse}
\ExplSyntaxOn
\prop_new:N \g__ellett_sunset_plist
\NewDocumentCommand{\setattr}{ mm }
 {
  \prop_gput:Nnn \g__ellett_sunset_plist {#1} {#2}
 }
\NewDocumentCommand{\gettr}{ m }
 {
  \prop_get:Nn \g__ellett_sunset_plist { #1 }
 }
\NewDocumentCommand{\expandoptions}{mO{}}
 {
  \use:x { \exp_not:N #1 [ #2 ] }
 }
\ExplSyntaxOff

\setattr{my_linestyle}{linestyle=dashed,linecolor=blue}
\setattr{my_line}{\psline[linestyle=dashed,linecolor=blue](A)(B)}

\pagestyle{empty}

\begin{document}

\begin{pspicture}(10,10)
  \pnode(0,0){A}
  \pnode(10,10){B}
  \pnode(10,0){C}
  \pnode(0,10){D}

  \gettr{my_line}   %% <-- works as expected
  \expandoptions\psline[\gettr{my_linestyle}](C)(D)  %% <-- not working

\end{pspicture}

\end{document}

Using \use:x is a "last resort", but four expansions of \gettr still are far from the final result. Beware of other options containing dangerous tokens; text and lengths are safe.

share|improve this answer
    
Thank you. I like the \expandoptions macro. I'd been trying something like \exp_after:wN with very little success. It hadn't occurred to me to combine \use:x with \exp_not:N. –  A.Ellett Feb 6 '13 at 23:27

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.