我在使用 xparser 时遇到了一种情况,\IfValueT{#2}{#2}
产生了-NoValue-
。
我的\NewDocumentEnvironment
poem
omo
环境正在将其三个参数传递给\NewDocumentCommand
s 进行进一步处理。这些命令将参数o
作为参数m
,然后测试是否-NoValue-
使用常规命令。
但是……它并没有按预期工作。似乎-NoValue-
在传递给强制参数之后,可能被视为只是字符串“-NoValue-”——导致它通过检查IfValueT
。但据我所知,xparse 文档没有提到发生这样的转换。也许我误解了,但它们甚至似乎与这个想法相矛盾:“由于 \IfNoValue(TF) 测试是可扩展的,因此可以稍后测试这些值,例如在排版时或在扩展上下文中。”
将可选参数传播到其他命令以进行进一步处理的正确方法是什么,同时保留检查的能力-NoValue-
?
我也尝试过通过 params 传递可选参数o
,但这似乎会带来相同的结果。我很确定(虽然没有尝试过)如果我在顶层进行检查并在最初省略可选参数时完全省略它,那么它的缺失将按预期传播;但这会导致代码重复,而这正是我想要避免的。
我想这可能和十年前的情况重复了:如何将可选参数作为可选参数传递?
相关命令和环境:
% 1: title 2: date
\NewDocumentCommand \partialpoemtitleimpl { m m } {%
#1%
\IfValueT{#2}{#2}
}
% 1: say 'Poem' 2: title 3: date
\NewDocumentCommand \poemtitleimpl { m m m } {%
\IfBooleanT{#1}{Poem: }%
\partialpoemtitleimpl{#2}{#3}
}
% *:prepend ``Poem:'' to title in heading and table of contents, 2:examplarline, 3: title, 4:date
\NewDocumentCommand \poemenvstart { s m m m } {%
\renewcommand*{\section}{
\flagverse{\Roman{vsection}\addtocounter{vsection}{1}}
}
\PoemTitle*{\poemtitleimpl{#1}{#3}{#4}}
% \section*{\poemtitleimpl{#1}{#3}{#4}}
\addcontentsline{toc}{section}{\poemtitleimpl{#1}{#3}{#4}}
\addcontentsline{poems}{section}{\partialpoemtitleimpl{#3}{#4}}
\setcounter{vsection}{1}
\IfValueTF{#2}{%
\settowidth{\versewidth}{#2}%
\begin{verse}[\versewidth]
}{%
\begin{verse}%
}
}
\NewDocumentCommand \poemenvend { } {%
\end{verse}%
}
% 1:examplarline, 2: title, 3:date
\NewDocumentEnvironment{poem}{omo}{%
\poemenvstart{#1}{#2}{#3}%
}{%
\poemenvend{}%
}
% Starred environment prepends ``Poem:'' to title in heading and table of contents
% 1:examplarline, 2: title, 3:date
\NewDocumentEnvironment{poem*}{omo}{%
\poemenvstart*{#1}{#2}{#3}%
}{%
\poemenvend{}%
}