TeX - LaTeX Asked on November 1, 2021
I would like to pass a list of key-value pairs to another command/environment. In this MWE to tcolorbox
, but it should work in general (e.g. pass parameters to LoadClass[params]{article}
).
documentclass{article}
usepackage{xparse,graphicx}
RequirePackage{tcolorbox}
tcbuselibrary{xparse}
DeclareTColorBox{mytcb}{O{}}{#1}
ExplSyntaxOn
keys_define:nn { mybodule/bfigure }
{
caption .tl_set:N = l_mybodule_caption_tl,
tcb .clist_set:N = l_mybodule_tcb_clist,
}
NewDocumentEnvironment{bfigure}{O{}}
{
keys_set:nn { mybodule/bfigure } { #1 }
begin{mytcb}[l_mybodule_tcb_clist]
}
{end{mytcb}}
ExplSyntaxOff
begin{document}
begin{bfigure}[tcb={left=-3pt}]
includegraphics[width=1cm]{example-grid-100x100pt}
end{bfigure}
end{document}
I am not quite sure how I can achieve this. Can anyone help?
You're apparently using mytcb
as an auxiliary environment, so there should be no problem into making it accept a mandatory argument rather than an optional one.
documentclass{article}
usepackage{xparse,graphicx}
usepackage{tcolorbox}
tcbuselibrary{xparse}
DeclareTColorBox{mytcb}{m}{#1}
ExplSyntaxOn
keys_define:nn { mybodule/bfigure }
{
caption .tl_set:N = l_mybodule_caption_tl,
tcb .clist_set:N = l_mybodule_tcb_clist,
}
NewDocumentEnvironment{bfigure}{O{}}
{
keys_set:nn { mybodule/bfigure } { #1 }
exp_args:NnV begin{mytcb} l_mybodule_tcb_clist
}
{end{mytcb}}
ExplSyntaxOff
begin{document}
begin{bfigure}[tcb={left=-3pt}]
includegraphics[width=1cm]{example-grid-100x100pt}
end{bfigure}
begin{bfigure}[tcb={left=20pt,right=4cm}]
includegraphics[width=1cm]{example-grid-100x100pt}
something that will show the effect of the texttt{right}
option, for lack of knowledge what other keys you plan to use
end{bfigure}
end{document}
Answered by egreg on November 1, 2021
It is very unfortunate that all the different key-value systems for LaTeX are mutually incompatible which requires serializing key-value trees as comma-separated lists and passing them around. As of yet, there also seems to be no predominant key-value system which everyone else should adhere to.
Since you are interacting with tcolorbox
, I can only recommend using pgfkeys
. In contrast to l3keys
this integrates naturally with the rest of the package and you can easily access the /tcb
subtree and just pass on your options.
documentclass{article}
usepackage{xparse,graphicx}
RequirePackage{tcolorbox}
tcbuselibrary{xparse}
DeclareTColorBox{mytcb}{O{}}{#1}
pgfqkeys{/mybodule/bfigure}{%
caption/.initial={},
tcb/.style={/tcb/.cd,#1},
}
NewDocumentEnvironment{bfigure}{O{}}{%
pgfqkeys{/mybodule/bfigure}{#1}%
begin{mytcb}%
}{%
Caption: pgfkeysvalueof{/mybodule/bfigure/caption}%
end{mytcb}%
}
begin{document}
begin{bfigure}[caption={foobar},tcb={left=-3pt}]
includegraphics[width=1cm]{example-grid-100x100pt}
end{bfigure}
end{document}
Answered by Henri Menke on November 1, 2021
The general idea is that you need to expand l_mybodule_tcb_clist
before passing it to some command/environment as comma-separated key-value list.
Firstly, it only takes one step of expansion to get the contents of a l3clist
variable.
Then, in a simple case, if we have cmdA[options]
or `cmdA{options}, then
expandaftercmdAexpandafter[l_options_clist]
% or
expandaftercmdAexpandafter{l_options_clist}
does the job. LoadClass[params]{article}
falls into this type.
In a more complex situation, if there are other arguments before options
, for example cmdB{arg1}[options]
, then you can treat it as first argument by providing a new macro:
deftemp{cmdB{arg1}}%
expandaftertempexpandafter[l_options_clist]
For an expandable solution, you can use macro expansion to exchange the order of arguments, expand the first argument, and then restore the order.
The mechanism used by latex3 functions in l3expan
(sub)package is similar to this.
% follow xparse' arg-spec names,
% m stands for mandatory, o stands for optional
defexpandsecond@mo#1#2[#3]{%
expandafterexpandafterexpandafter#1%
expandafterexchangetwo@mm@to@omexpandafter{#3}{#2}%
}
defexchangetwo@mm@to@om#1#2{{#2}[#1]}
% store key-value pairs in macro
defoptions{key1,key2,key3}
% suppose cmdB has syntax cmdB{}[]
% this will expand to cmdB{arg1}[key1,key2,key3]
expandsecond@mocmdB{arg1}[options]
begin{envname}[options]
falls into this type.
Specially, in your example, since environment mytcb
is used inside a group created by environment bfigure
, tcbset{options}begin{mytcb}
is equivalent to begin{mytcb}[options]
, hence there is @UlrikeFischer's suggestion in comment:
ExplSyntaxOn
NewDocumentEnvironment{bfigure}{O{}}
{
keys_set:nn { mybodule/bfigure } { #1 }
exp_args:Notcbset{l_mybodule_tcb_clist}
begin{mytcb}
}
{end{mytcb}}
ExplSyntaxOff
Answered by muzimuzhi Z on November 1, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP