TransWikia.com

Macros: From Arguments to Keys, with Expl3: Optional Arguments

TeX - LaTeX Asked on March 18, 2021

When declaring a new command with multiple optional arguments next to each other, e.g.

NewDocumentCommand{mycmd}{ o o o }{}

one is implicitly excluding the option of passing a value for #2 without having one for #1, i.e. mycmd[][2] will fail IfNoValueT{#1}. This can be remediated by using tl_if_blank:nTF, see IfNoValueTF – How to force "no value" if there (are brackets but there) is no value for an argument. However, sometimes this is not an option (in my particular case, the xparse support of tcolorbox is limited to checking -NoValue-).

This, among other things, made me want to reprogram some commands (or, in my case, tcolorboxes) into a key-value system. My approach was to give the original command mycmd extra mandatory arguments that would remain empty, as to ensure that any combination of empty or nonempty optional arguments is possible. E.g. mycmd from above would be set with

NewDocumentCommand{mycmd}{ o m o m o }{}

With this version, I can pass a value to any of my three "real" arguments (the optional ones) without needing any of the others, while also being able to call IfValueTF on any of them.

Next, I define keys for each of the optional arguments, e.g.

keys_define:nn { mykeys } {
    a .tl_set:N = l_mykeys_a_tl,
    b .tl_set:N = l_mykeys_b_tl,
    c .tl_set:N = l_mykeys_c_tl
}

Lastly, I define a wrapper command

NewDocumentCommand{wrapper}{ O{} }{
    keys_set:nn{mykeys}{#1}
    mycmd
    tl_if_empty:NTF l_mykeys_a_tl {} { [l_mykeys_a_tl] }
    {}
    tl_if_empty:NTF l_mykeys_b_tl {} { [l_mykeys_b_tl] }
    {}
    tl_if_empty:NTF l_mykeys_c_tl {} { [l_mykeys_c_tl] }
}

with the intention that e.g. wrapper[a=13, c=2] would be equivalent to mycmd[13]{}{}[2].

This last point is where my approach fails completely. I tried to play around with exp_not:n or use:n, explained in The LaTeX3 Interfaces, but to no avail. Hence, any help or guidance would be much appreciated. Thank you!


Full MWE:

documentclass{article}

usepackage{xparse}

NewDocumentCommand{mycmd}{ o m o m o }{
    First ``real'' argument is IfValueTF{#1}{#1}{not provided}.par
    Second ``real'' argument is IfValueTF{#3}{#3}{not provided}.par
    Third ``real'' argument is IfValueTF{#5}{#5}{not provided}.par
}
ExplSyntaxOn
keys_define:nn { mykeys } {
    a .tl_set:N = l_mykeys_a_tl,
    b .tl_set:N = l_mykeys_b_tl,
    c .tl_set:N = l_mykeys_c_tl
}
NewDocumentCommand{wrapper}{ O{} }{
    keys_set:nn{mykeys}{#1}
    mycmd
    tl_if_empty:NTF l_mykeys_a_tl {} { [l_mykeys_a_tl] }
    {}
    tl_if_empty:NTF l_mykeys_b_tl {} { [l_mykeys_b_tl] }
    {}
    tl_if_empty:NTF l_mykeys_c_tl {} { [l_mykeys_c_tl] }
}
ExplSyntaxOff

begin{document}

mycmd[13]{}{}[2]

noindenthrulefill

wrapper[a=13, c=2]

end{document}

Output of MWE

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