按照惯例自答一下,非常感谢@Eureka 和@u19850 的倾情帮助。
首先分析下错因:
对于CASEA的写法,是使用自行在外部使用\keys_set:nn {<module>}{options}
的方式定义默认值,实际上这等价于在\keys_define:nn
内部使用<key>.initial
定义其赋值方式,这两种做法均会给option赋值初始值;
对于CASEB的写法,是使用<key>.code:n
会接受名为#1
的由<key>.default
定义的初始值<value>
,并执行code
的内容;但<key>.default:n
方法定义的default值仅仅是在value缺失时的默认值,如果option不被指定是不会被赋值的。
下面附interface3
中对这两个函数的介绍原文:
⟨key⟩ .default:n = {⟨default⟩}
Creates a ⟨default⟩ value for ⟨key⟩, which is used if no value is given. This will be used if only the key name is given, but not if a blank ⟨value⟩ is given.
key .default:n = xxx
, 是 value 缺失时的默认值
例如 key .default:n = xxx
,那么\keys_set:nn {mew}{key}
等价于\keys_set:nn {mew}{key = xxx}
⟨key⟩ .initial:n = {⟨value⟩}
Initialises the ⟨key⟩ with the ⟨value⟩, equivalent to\keys_set:nn {⟨module⟩} { ⟨key⟩ = ⟨value⟩ }
key .initial:n = xxx
, 等价于执行了 \keys_set:nn{mwe}{key = xxx}
鱼老师随便一句话就是标准的文档啊,无敌了!
作为一名learner,自然要分析下为什么上面的代码都不得行:
对于CASEA:
- 第28行的
\cmd{Explorer}
输出了\l_mwe_opa_tl
以及\l_mwe_opb_tl
的默认值,因此首先输出了正常的结果。 - 第29行的
\cmd[opa=opa,opb=opb]{Explorer}
进入了\IfNoValueF
的条件逻辑中,此时(\l_mwe_opa_tl
,\l_mwe_opb_tl
)=(opa,opb),同时正常输出(opa,opb,Explorer)的内容 - 第30行的
\cmd[opa=opa]
只是制定了赋值\l_mwe_opa_tl=opa
,但由于\l_mwe_opa_tl
在上一个判断中已经被永久地赋值为了opb
,因此后文中并未将其恢复为defaultb
.(第31行同理)
此时已经不难发现是一个变量作用域的问题,可以在自定义的命令\cmd
内使用\begin_group:
以及\end_group:
。事实上鱼老师再次一阵见血地指出:
"这种一般都要加group限制"
对于CASEA,此时只要加上限制,则可以解决上述问题。
而对于CASEB,可以如上分析:
- 第21行的
\cmd{Explorer}
没有指定opa
和opb
,因此 此时default
值不会被赋值给key,code
的内容也不会输出,因此只输出了必须参数Explorer
- 第22行制定了
opa=opa,opb=opb
,default值赋值之后被用于的opa=opa
覆盖,因此输出了(opa,opb,Explorer) - 第23行指定了
opa=opa
,此时opa经历了先被赋值为defaulta
之后被用户选项覆盖为opa
,而opb
并未被invoked,因此只输出了(opa,Explorer);第24行同理只输出了(opb,Explorer).
更改方式类似,加上group
后,用指定option而不赋值的方式调用,如下图:
暂时的最后(其实还要测试下雾月给出的lttemplates
方法),最后一下Eureka老师给出的一段代码(结合了CASEA与CASEB的做法):
本来还想分析的,凡是如果你有耐心看完上面一大段的话,是显然可以实现要求的。
问 使用l3keys如何不能实现单独指定某个option?