问题:我想要一个命令,它接受一个强制参数和一个可选参数。如果可选参数存在,则选择相应的案例,否则返回所有案例机会。根据 #2 参数的类型,它会返回不同的结果(#1)。我不知道如何有效/优雅/(完全)解决嵌套“案例”的其他部分。我不喜欢硬输入“[返回所有案例]”部分,因为输入太多了。不是针对当前示例,而是针对我想使用此代码的情况。我无法解决的部分是,如何在不硬输入的情况下返回所有案例。
可选参数只能取值 00,10,01,11,20,02。
我最好在 expl3 框架内解决这个问题。
伪代码:
if #2
{basket}{
if #1 exist:
case #1
{01}{kiwi}
{11}{mango}
{02}{papaya}
otherwise: [return all cases separated with "+"]
}
{bowl}{
if #1 exist:
case #1
{00}{apple}
{10}{pear}
{20}{banana}
otherwise: [return all cases separated with "+"]
}
输入:
\whatfruitinwhat[01]{basket}
\whatfruitinwhat{basket}
\whatfruitinwhat[20]{bowl}
\whatfruitinwhat{bowl}
输出:
There is kiwi in the basket.
There is kiwi + mango + papaya in the basket.
There is banana in the bowl.
There is apple + pear + banana in the bowl.
感谢您的帮助,谢谢!
答案1
您可以存储列表,然后使用全部或仅使用一项:
\documentclass{article}
\begin{document}
\ExplSyntaxOn
\clist_const:Nn\l_basket_clist{kiwi,mango,papya}
\clist_const:Nn\l_bowl_clist{apple,pair,banana}
\NewDocumentCommand\whatfruitinwhat{O{0}m}{
\int_compare:nTF{0 = #1}
{\clist_use:cn{l_#2_clist}{ + }}
{\clist_item:cn{l_#2_clist}{#1}}}
\ExplSyntaxOff
1 \whatfruitinwhat[1]{basket}
2 \whatfruitinwhat{basket}
3 \whatfruitinwhat[3]{bowl}
4 \whatfruitinwhat{bowl}
\end{document}
在评论中你表明你想要任意键而不是数字索引,因此使用 l3prop 而不是 clist:
\documentclass{article}
\begin{document}
\ExplSyntaxOn
\prop_const_from_keyval:Nn\c_basket_prop{
zz=kiwi,
ZZ=mango,
99=papya}
\prop_const_from_keyval:Nn\c_bowl_prop{
zzz=apple,
Z=pair,
02=banana}
\NewDocumentCommand\whatfruitinwhat{om}{
\IfNoValueTF{#1}
{
\tl_set:Nn\l_sep{}
\prop_map_inline:cn{c_#2_prop}{\l_sep ##2 \tl_set:Nn\l_sep{+} }
}
{\prop_item:cn{c_#2_prop}{#1}}}
\ExplSyntaxOff
1 \whatfruitinwhat[zz]{basket}
2 \whatfruitinwhat{basket}
3 \whatfruitinwhat[02]{bowl}
4 \whatfruitinwhat{bowl}
\end{document}
答案2
这是完全可扩展的。
\documentclass{article}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\whatfruitinwhat}{om}
{% #1 = optional index, #2 = name of container
\prop_if_exist:cTF { l_keenontex_fruit_#2_prop }
{% the list exists
\IfNoValueTF { #1 }
{% no index
\keenontex_fruit:n { #2 }
}
{% index
\keenontex_fruit:nn { #2 } { #1 }
}
}
{% the list doesn't exist
\msg_error:nnn { fruit } { not-exist } { #2 }
}
}
\NewDocumentCommand{\definecontainer}{mm}
{% #1 = name of container, #2 = items
\prop_clear_new:c { l_keenontex_fruit_#1_prop }
\clist_clear_new:c { l_keenontex_fruit_#1_clist }
\prop_set_from_keyval:cn { l_keenontex_fruit_#1_prop } { #2 }
\prop_map_inline:cn { l_keenontex_fruit_#1_prop }
{
\clist_put_right:cn { l_keenontex_fruit_#1_clist } { ##2 }
}
}
\cs_new:Nn \keenontex_fruit:n
{
\clist_use:cn { l_keenontex_fruit_#1_clist } { + }
}
\cs_new:Nn \keenontex_fruit:nn
{
\prop_if_exist:cTF { l_keenontex_fruit_#1_prop }
{
\prop_if_in:cnTF { l_keenontex_fruit_#1_prop } { #2 }
{
\prop_item:cn { l_keenontex_fruit_#1_prop } { #2 }
}
{
\msg_error:nnnn { fruit } { no-item } { #1 } { #2 }
}
}
{
\msg_error:nnnn { fruit } { not-exist } { #1 }
}
}
\msg_new:nnnn { fruit } { not-exist }
{ Non~existent~container~#1 }
{ The~container~#1~has~not~been~defined }
\msg_new:nnnn { fruit } { no-item }
{ Non~existent~item~#2~in~container~#1 }
{ The~container~#1~contains~no~#2~item }
\ExplSyntaxOff
\definecontainer{basket}{
01=kiwi,
11=mango,
02=papaya
}
\definecontainer{bowl}{
00=apple,
10=pear,
20=banana
}
\begin{document}
\whatfruitinwhat[01]{basket}
\whatfruitinwhat{basket}
\whatfruitinwhat[20]{bowl}
\whatfruitinwhat{bowl}
\whatfruitinwhat{foo}
\whatfruitinwhat[4]{basket}
\end{document}
控制台将打印
! Package fruit Error: Non existent container foo
For immediate help type H <return>.
...
l.75 \whatfruitinwhat{foo}
? h
The container foo has not been defined
?
! Package fruit Error: Non existent item 4 in container basket
For immediate help type H <return>.
...
l.77 \whatfruitinwhat[4]{basket}
? h
The container basket contains no 4 item
?
foo
对于调用容器或容器中没有具有指定键的项目的情况。