TransWikia.com

Simple key-value example

TeX - LaTeX Asked on January 15, 2021

I try to make just a very minimalist example of pgfkeys — or other keystyle parameters package —, with a command like this one:

mycommand{title="The new book", author="John Doe"}

to get a behavior like this:

Writer John Doe

Title The new book

And, possibly, if on key is missing, it line will not appear. For example, the command

mycommand{title="The new book"}

Will only print:

Title The new book

I check in the web and also StackExchange but I only find very complicated examples including so much other things not directly related to key-value syntax.

So, how can I just put such a minimal key-value command?

4 Answers

I'm not sure what you really need. This can be something to start...

Assigning to title or author actually runs the code defined in pgfkeys. Nothing is stored.

documentclass{article}

usepackage{pgfkeys}

pgfkeys{
    /bibliography/.cd, % family
    title/.code = {ifx#1empty Aelse{textbf{Title} #1par}fi},
    author/.code = {ifx#1empty Aelse{textbf{Author} #1par}fi},
}

newcommand{mycommand}[1]{
    pgfkeys{
        /bibliography/.cd,
        #1,
    }
    pgfkeysvalueof{/bibliography/title}
    pgfkeysvalueof{/bibliography/author}
}
begin{document}
One:par
mycommand{title = {Tikz & PGF}, author={JD}}

Two:par
mycommand{author={JD}}

Three:par
mycommand{title = {Tikz & PGF}}

Four:par
mycommand{}

Five:par
mycommand{title=, author=}

end{document}

Edit

Please note that the .code is executed at "parameter time", so mycommand{author={JD}, title = {Tikz & PGF}} will print the author before the title.

Edit 2

This version uses bibtitle and bibauthor to store the data. As theses macros are global, you have to clear them (set to empty) in each call, otherwise previous values are remembered.

documentclass{article}

usepackage{pgfkeys}

pgfkeys{
    /bibliography/.cd, % family
    title/.store in = bibtitle,
    author/.store in = bibauthor,
}

newcommand{mycommand}[1]{
    pgfkeys{
        /bibliography/.cd,
        title = {},  % clear title
        author = {}, % clear author
        #1,
    }
    ifxbibtitleemptyelsetextbf{Title:} bibtitleparfi
    ifxbibauthoremptyelsetextbf{Author:} bibauthorparfi
}
begin{document}
One:par
mycommand{title = {Tikz & PGF}, author={JD}}
mycommand{author={JD}, title = {Tikz & PGF}}
    
vspace{2ex}
Two:par
mycommand{author={JD}}

vspace{2ex}
Three:par
mycommand{title = {Tikz & PGF}}

vspace{2ex}
Four:par
mycommand{}

vspace{2ex}
Five:par
mycommand{title=, author=}

end{document}

Correct answer by Jander on January 15, 2021

Here's an implementation with expl3 keys.

documentclass{article}
usepackage{xparse}

ExplSyntaxOn

% define the keys
keys_define:nn { fauve/books }
 {
  title  .tl_set:N = l__fauve_books_title_tl, % the title
  author .tl_set:N = l__fauve_books_author_tl, % the author
 }

% formatting
NewDocumentCommand{mycommand}{m}
 {
  group_begin:
  keys_set:nn { fauve/books } { #1 } % populate the keys

  % format the book
  paraddvspace{topsep}
  fauve_books_author:V l__fauve_books_author_tl
  fauve_books_title:V l__fauve_books_title_tl
  paraddvspace{topsep}
  group_end:
 }

cs_new_protected:Nn fauve_books_title:n
 {
  tl_if_empty:nF { #1 }
   {
    parnoindenttextbf{Title:}~#1
   }
 }
cs_new_protected:Nn fauve_books_author:n
 {
  tl_if_empty:nF { #1 }
   {
    parnoindenttextbf{Writer:}~#1
   }
 }
cs_generate_variant:Nn fauve_books_title:n  {V}
cs_generate_variant:Nn fauve_books_author:n {V}

ExplSyntaxOff

begin{document}

mycommand{title=The new book, author=John Doe}

mycommand{title=Another book}

end{document}

I have separated the formatting commands specific for each key, but that's optional.

enter image description here

Answered by egreg on January 15, 2021

FWIW, I'll show how to write such a macro in ConTeXt. ConTeXt has a few key-value driven interfaces, but for something as simple as this, I would just piggyback oon the setupvariables[...][..=..] and getvariable{...}{...}.

unprotect
definemycommand
    {dosingleargumentmycommand_setup}

defmycommand_setup[#1]%
    {bgroup
     setvariables[mycommand][#1]%
     mycommand_process
     egroup}

defmycommand_process
    {startlines
     doifsomething{getvariable{mycommand}{author}}
        {bold{Writer:} getvariable{mycommand}{author}endgraf}%
     doifsomething{getvariable{mycommand}{title}}
        {bold{Title:} getvariable{mycommand}{title}}%
     stoplines}
protect

starttext
mycommand[title={The new book}, author={John Doe}]

mycommand[title={The new book}]
stoptext

Note that I modified the interface (use mycommand[...] instead of mycommand{...}) to match the ConTeXt convention that arguments in square brackets are for options and arguments in curly brackets are for text which is typeset.

Answered by Aditya on January 15, 2021

With expkv-def you can use data and dataT keys.

A data key will store the information you provide in the value in a macro, but this macro also takes two arguments. If the key wasn't used it'd execute its second argument, while if the key was used it'd execute its first argument and append the value given to it in braces (so as an argument to that code).

A dataT key behaves similar, but the macro will only take one argument and would do nothing if the key wasn't used yet, whereas it would execute its argument and append the given value if it was used.

Just storing the value in a variable would be possible with the store key type instead of data.

documentclass[]{article}

usepackage{expkv-def}

makeatletter
ekvdefinekeys{fauve}
  {
     data  title  = fauve@title
    ,dataT author = fauve@author
    ,dataT year   = fauve@year
  }
ekvsetdeffauve@set{fauve}
newcommandmycommand[1]
  {%
    begingroup
      fauve@set{#1}%
      fauve@author{parnoindenttextbf{Writer} }%
      fauve@title
        {parnoindenttextbf{Title} }%
        {parnoindentemph{No title}}%
      fauve@year{parnoindenttextbf{Year} }%
    endgroup
  }
makeatother

begin{document}
mycommand{title=The new book,author=John Doe}
bigskip
mycommand{title=The new book}
bigskip
mycommand{title=The new book,year=2020}
bigskip
mycommand{author=John Doe,year=2020}
end{document}

enter image description here

Answered by Skillmon on January 15, 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