这似乎是一个非常基本的问题,我相信它一定在某个地方得到过回答,但我找不到任何答案。我找到的最接近的答案是这个问题,但接受的答案中的任何解决方案都无法帮助我的代码。
我正在尝试根据命名空间参数的值进行分支。如果我用\namedordefaulteraparameter{#1}{formatdecoration}
文字替换yes
,我会得到我预期的“y”,并且只需打印该宏的值也会得到它应该得到的“yes”。但是,当我将宏传递给测试时,我总是得到“n”。我猜这是由于\doifsamestringelse
测试值而不扩展它们,但无论\expandafter
我使用多少个 s 或将它们放在哪里,我都无法获得要包含的第一个结果。我遗漏了什么?
\definenamespace[era][
type=module,
name=era,
command=yes,
setup=yes,
]
\setupera[
formatdecoration=yes,
]
\define[2]\namedordefaulteraparameter{%
\doifsomethingelse
{\namederaparameter{#1}{#2}}
{\namederaparameter{#1}{#2}}
{\eraparameter{#2}}%
}
\def\eradecorated[#1]#2{%
\doifsamestringelse{yes}{\namedordefaulteraparameter{#1}{formatdecoration}}
{y}
{n}%
}
我知道我可以在 Lua 中轻松完成此操作,但对于如此简单的事情,我看不出有任何理由添加额外的语法。
答案1
您的示例中存在几个缺陷:
\doifsamestringelse
将对两个字符串进行去标记化,然后比较结果。您必须使用\doifelse
。\namedordefaulteraparameter
不可扩展,但是为了\doifelse
永远为真,两个操作数必须扩展为相同的结果。\doifsomethingelse
不可扩展。您必须使用可扩展的替代方案\expdoifelse
。
实施可扩展的测试并使其中的所有内容也可扩展,我们就可以开始了。
\definenamespace[era][
type=module,
name=era,
command=yes,
setup=yes,
]
\setupera[
formatdecoration=yes,
]
\def\namedordefaulteraparameter#1#2{%
\expdoifelse{\namederaparameter{#1}{#2}}{}%
{\eraparameter{#2}}%
{\namederaparameter{#1}{#2}}%
}
\def\eradecorated[#1]#2{%
\expdoifelse{yes}{\namedordefaulteraparameter{#1}{formatdecoration}}%
{y}%
{n}%
}
\starttext
\eradecorated[era]{}
\stoptext
答案2
我不确定你为什么要定义\namedordefaultparameter
。返回默认参数的标准方法如下:
\definenamespace
[era]
[
type=module,
name=era,
command=yes,
setup=yes,
parent=era, % NOTE: Added this!!
]
\setupera
[
formatdecoration=yes,
]
\defineera[test1][formatdecoration=no]
\defineera[test2]
\starttext
\namederaparameter{test1}{formatdecoration}
\namederaparameter{test2}{formatdecoration}
\stoptext
这使
no yes
基于此,可以定义\eradecorated
宏如下:
\def\eradecorated[#1]%
{\doifelse{\namederaparameter{#1}{formatdecoration}}{yes}
{y}{n}}
并将其用作
\eradecorated[test1]
\eradecorated[test2]
这使
n y
注意,严格来说,上面的宏并不等同于你定义的宏。如果我设置了\defineera[test2][formatdefinition=]
,那么我的宏会给出结果n n
,而你的宏仍然会给出结果n y
。我不知道你是否在意其中的区别。