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?
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.
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}
Answered by Skillmon on January 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