TeX - LaTeX Asked on July 15, 2021
I have the following family of options
pgfkeys{
/opts/.is family,
/opts,
name/.store in = @@Style@Name,
property/.code = {
expandaftergdefexpandaftercsname @@Style@ @@StyleName @Poperty endcsname#1},
}
I want to create a global command @@Style@<value of the "name">@Property
and assign it the value of "property" if it is passed.
For example, the code pgfkeys{/opts, name = A, property = B}
should create a command @@Style@A@Propety
with the value B
. How can I do that.
Minimal non-working example:
documentclass{article}
usepackage{pgfkeys}
makeatletter
pgfkeys{
/opts/.is family,
/opts,
name/.store in = @@Style@Name,
property/.code = {
expandaftergdefexpandaftercsname @@Style@ @@StyleName @Poperty endcsname#1},
}
begin{document}
pgfkeys{/opts, name = A, property = B}
@@Style@A@Propety
end{document}
The exact syntax from the question is implemented below (see With the syntax from the question), but my suggestion would be to use a slightly different one, namely:
pgfkeys{/myopts={A=foo, B={bar bazquux}}}
in order to set @@Style@A@Property
to foo
and @@Style@B@Property
to bar bazquux
(thus two assignments in this example, but you can perform as many as you want with my code). Indeed, the syntax you asked for requires stateful code:
one needs to remember that the property name has been set until we see the value, or that the value has been set until we see the name;
one needs to specify what happens with dubious input like pgfkeys{/opts, name=foo, name=bar, property=whatever}
or pgfkeys{/opts, property=whatever}
, etc.
The syntax I propose can be implemented by defining the /some dir/.unknown
handler, which is invoked by pgfkeys
whenever an unknown key in /some dir
is used.
documentclass{article}
usepackage{pgfkeys}
usepackage{etoolbox} % for csgdef (syntactic sugar)
makeatletter
pgfkeys{
/myopts/dir/.unknown/.code={%
csgdef{@@Style@pgfkeyscurrentname @Property}{#1}%
},
/myopts/.code={pgfkeys{/myopts/dir/.cd, #1}},
}
makeatother
begin{document}
pgfkeys{/myopts={A=foo, B={bar bazquux}}}
makeatletter
show@@Style@A@Property % @@Style@A@Property=macro:->foo.
show@@Style@B@Property % @@Style@B@Property=macro:->bar bazquux.
makeatother
end{document}
Regarding the code you posted, please note that
expandaftergdefexpandaftercsname @@Style@ @@StyleName @Property endcsname#1}
should rather be something like this:
expandaftergdefcsname @@Style@@@StyleName @Propertyendcsname{#1}
(no need for the second expandafter
because it is csname
that needs to be expanded early here; beware of unwanted spaces; wrap the macro replacement text within curly braces).
Since the OP insists on having exactly the syntax from the question, namely pgfkeys{/opts, name = A, property = B}
, here it is. I don't recommend it, though (there might be good reasons but they haven't been revealed so far, AFAICT). The name
must be given before the property
(as in the question).
documentclass{article}
usepackage{pgfkeys}
usepackage{etoolbox} % for csgdef (syntactic sugar)
makeatletter
pgfkeys{
/opts/.is family,
/opts/name/.store in=@@My@PropName,
/opts/property/.code={%
csgdef{@@Style@@@My@PropName @Property}{#1}%
},
}
makeatother
begin{document}
pgfkeys{/opts, name = A, property = B}
makeatletter
show@@Style@A@Property % @@Style@A@Property=macro:->B.
makeatother
end{document}
Answered by frougon on July 15, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP