如果我想编写一个包装器来包装另一个宏,我有时会定义一个参数处理器来(恕我直言)简化一些代码。例如,如果我编写一个包装器来包装一个带有可选项的宏,*
我最终可能会使用形式的多个分支测试\IfBooleanTF{#1}{...}{...}
,但我认为有时执行以下操作会很方便:
\newcommand\sProc[1]
{%
\IfBooleanTF{#1}
{\def\ProcessedArgument{*}}
{\def\ProcessedArgument{}}%
}
\NewDocumentCommand \wrapchap { >{\sProc}s m }
{%
\chapter#1{#2}%
}
对于s
-type 参数,这种方法效果很好。但是对于o
-type 参数,这种方法并不适用,如以下 MWE 所示
\documentclass[]{article}
\usepackage{xparse}
\newcommand\oProc[1]
{%
\IfValueTF{#1}
{\def\ProcessedArgument{[#1]}}
{\def\ProcessedArgument{}}%
}
\NewDocumentCommand \foo { >{\oProc}o m }
{%
\bar#1{#2}%
}
\renewcommand\bar[2][default]
{%
\begin{tabular}{ll}
optional & #1 \\
mandatory & #2 \\
\end{tabular}\\
}
\NewDocumentCommand \FOO { o m }
{%
\IfValueTF{#1}
{\bar[#1]{#2}}
{\bar{#2}}%
}
\begin{document}
\section{Result}
\foo{baz}
\foo[baz]{bang}
\section{Expectation}
\FOO{baz}
\FOO[baz]{bang}
\end{document}
它适用于O
-type 参数,我在这种情况下使用它(最近的一个例子是这个答案)。
问题:
- 如果可能的话,我该如何实现它?
- 为什么决定
-NoValue-
默认不应用处理器?
编辑:正如 @egreg 指出的那样,这是 的记录行为xparse
。我很清楚这一点,但想知道为什么会做出这种设计选择。因此,上述问题中的第二个对我来说更有趣。我真的不知道第一个问题的答案是否会破坏事情(因为我不知道是否有任何当前代码依赖于该行为)。
答案1
来自以下文档xparse
:
0.9 参数处理器
xparse
引入了论证处理器的概念,该处理器应用于论证后它已被底层系统抓取,但在传递给 ⟨代码⟩。因此,可以使用参数处理器在早期阶段规范输入,从而允许内部函数完全独立于输入形式。处理器应用于用户输入和可选参数的默认值,但不是到特殊-NoValue-
标记。