TransWikia.com

How to construct a macro with key=value by pgfkeys

TeX - LaTeX Asked by lyl on July 29, 2021

I just learn pgfkeys, but don’t quite understand how to use it for making a macro with key=value options.

I’d like to give the following simple example as a practice to show my idea.

documentclass{article}
usepackage{tikz}

newcommand{mycolorbox}[1][]{
  pgfkeys{
  color/.initial=red,
  text/.initial=some text,
  #1,
  exe/.code=colorbox{color}{text}
}
}
begin{document}
mycolorbox[color=blue, text=This is a practice.]
end{document}

This does not work. Anyone can help me with this?

3 Answers

You want to define your own namespace for keys and separate key definition from usage.

documentclass{article}
usepackage{tikz}

pgfkeys{/lyl/mycolorbox/.cd, % define your own space
  color/.store in=mycolorboxcolor,
  text/.store in=mycolorboxtext,
  color=red!40,
  text=some text,
}

newcommand{mycolorbox}[1][]{%
  begingroup
  pgfkeys{/lyl/mycolorbox/.cd,#1}%
  colorbox{mycolorboxcolor}{mycolorboxtext}%
  endgroup
}

begin{document}

mycolorbox[color=blue!20]

mycolorbox[text=This is a practice.]

mycolorbox[color=blue!20, text=This is a practice.]

end{document}

The expl3 version:

documentclass{article}
usepackage{xcolor}

ExplSyntaxOn

keys_define:nn { lyl/mycolorbox }
 {
  color .tl_set:N  = l__lyl_mycolorbox_color_tl,
  text  .tl_set:N  = l__lyl_mycolorbox_text_tl,
  color .initial:n = red!40,
  text  .initial:n = some~text,
 }

NewDocumentCommand{mycolorbox}{O{}}
 {
  group_begin:
  keys_set:nn { lyl/mycolorbox } { #1 }
  colorbox{l__lyl_mycolorbox_color_tl}{l__lyl_mycolorbox_text_tl}
  group_end:
 }

ExplSyntaxOff

begin{document}

mycolorbox[color=blue!20]

mycolorbox[text=This is a practice.]

mycolorbox[color=blue!20, text=This is a practice.]

end{document}

enter image description here

Correct answer by egreg on July 29, 2021

Another way to store values is inside the key paths themselves (that doesn't mean you don't use as many commands, so this doesn't ease the namespace-heaviness).

documentclass[]{article}

usepackage{xcolor}
usepackage{pgfkeys}

pgfkeys
  {%
     /mycolorbox/.is family
    ,/mycolorbox
    ,color/.initial=blue
    ,text/.initial=some text
  }
newcommandmycolorbox[1][]
  {%
    begingroup
      pgfqkeys{/mycolorbox}{#1}%
      colorbox
        {pgfkeysvalueof{/mycolorbox/color}}
        {pgfkeysvalueof{/mycolorbox/text}}%
    endgroup
  }

begin{document}
mycolorbox

mycolorbox[color=red]

mycolorbox[text=foobar]
end{document}

(note: pgfqkeys{/<path>}{<keys>} is the same as pgfkeys{/<path>/.cd,<keys>} but faster)

enter image description here

Answered by Skillmon on July 29, 2021

If you're just setting up a simple macro with a few keys (and that's the only interface accessing and using those keys), you could as well build your macro with expkv-cs:

documentclass[]{article}

usepackage{xcolor}
usepackage{expkv-cs}

ekvcSplitmycolorbox
  {
     color=blue
    ,text=some text
  }
  {colorbox{#1}{#2}}%

begin{document}
mycolorbox{}

mycolorbox{color=red}

mycolorbox{text=foobar}
end{document}

(expkv-cs defines the macro mycolorbox with a mandatory argument, if you want to use an optional one, just add a wrapper like: newcommandmycolorbox[1][]{mycolorboxSplit{#1}} and changing the name of the macro after ekvcSplit to mycolorboxSplit).

enter image description here

Answered by Skillmon on July 29, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP