我想将键值对列表传递给另一个命令/环境。在此 MWE 中为tcolorbox
,但它应该可以正常工作(例如将参数传递给\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}
我不太清楚如何实现这一点。有人能帮忙吗?
答案1
一般的想法是,您需要\l_mybodule_tcb_clist
在将其作为逗号分隔的键值列表传递给某些命令/环境之前进行扩展。
首先,只需要扩展一步就可以获取l3clist
变量的内容。
然后在简单情况下,如果我们有\cmdA[options]
或\cmdA{options}
,那么
\expandafter\cmdA\expandafter[\l_options_clist]
% or
\expandafter\cmdA\expandafter{\l_options_clist}
完成工作。\LoadClass[params]{article}
属于这种类型。
在更复杂的情况下,如果之前还有其他参数options
,例如\cmdB{arg1}[options]
,那么您可以通过提供一个新宏将其作为第一个参数处理:
\def\temp{\cmdB{arg1}}%
\expandafter\temp\expandafter[\l_options_clist]
对于可扩展的解决方案,可以使用宏扩展来交换参数的顺序,扩展第一个参数,然后恢复顺序。 (sub) 包中的 latex3 函数使用的机制l3expan
与此类似。
% follow xparse' arg-spec names,
% m stands for mandatory, o stands for optional
\def\expandsecond@mo#1#2[#3]{%
\expandafter\expandafter\expandafter#1%
\expandafter\exchangetwo@mm@to@om\expandafter{#3}{#2}%
}
\def\exchangetwo@mm@to@om#1#2{{#2}[#1]}
% store key-value pairs in macro
\def\options{key1,key2,key3}
% suppose \cmdB has syntax \cmdB{}[]
% this will expand to \cmdB{arg1}[key1,key2,key3]
\expandsecond@mo\cmdB{arg1}[\options]
\begin{envname}[options]
就属于这种类型。
特别在您的示例中,由于环境mytcb
是在由环境创建的组内使用的bfigure
,\tcbset{options}\begin{mytcb}
因此相当于\begin{mytcb}[options]
,因此有@UlrikeFischer 的建议评论:
\ExplSyntaxOn
\NewDocumentEnvironment{bfigure}{O{}}
{
\keys_set:nn { mybodule/bfigure } { #1 }
\exp_args:No\tcbset{\l_mybodule_tcb_clist}
\begin{mytcb}
}
{\end{mytcb}}
\ExplSyntaxOff
答案2
不幸的是,LaTeX 的所有不同键值系统都是互不兼容的,这需要将键值树序列化为逗号分隔的列表并传递它们。到目前为止,似乎还没有一个所有人都应该遵守的主流键值系统。
由于您正在与 进行交互tcolorbox
,因此我只能建议使用pgfkeys
。与此相反l3keys
,它与包的其余部分自然集成,您可以轻松访问/tcb
子树并传递您的选项。
\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}
答案3
您显然正在使用它mytcb
作为辅助环境,因此让它接受强制参数而不是可选参数应该没有问题。
\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}