ConTeXt:将宏结果与字符串进行比较

ConTeXt:将宏结果与字符串进行比较

这似乎是一个非常基本的问题,我相信它一定在某个地方得到过回答,但我找不到任何答案。我找到的最接近的答案是这个问题,但接受的答案中的任何解决方案都无法帮助我的代码。

我正在尝试根据命名空间参数的值进行分支。如果我用\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

您的示例中存在几个缺陷:

  1. \doifsamestringelse将对两个字符串进行去标记化,然后比较结果。您必须使用\doifelse
  2. \namedordefaulteraparameter不可扩展,但是为了\doifelse永远为真,两个操作数必须扩展为相同的结果。
  3. \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。我不知道你是否在意其中的区别。

相关内容