我xparse
想要定义一个命令 Command-One,它会调用一个命令 Command-Two,并且当且仅当调用了 Command-One 的 *ed 版本时才会调用 *ed 版本。
具体来说,我想做类似的事情:
\DeclareDocumentCommand{\CTwo}{s o m}
{\IfBooleanTF{#1}{#2}{#3}}
\DeclareDocumentCommand{\CTest}{s o}
{\CTwo#1[#2]{testing}}
\CTest*[work]
并让其输出“work”。
我意识到我可以这样做
\DeclareDocumentCommand{\CTest}{s o}
{\IfBooleanTF{#1}
{\CTwo*[#2]{testing}}
{\CTwo[#2]{testing}}}
但这不够优雅,而且我将定义几个不同的命令,每个命令都有不同的#3
in值\CTwo
,而且总是需要多次复制 If-Then 语句(以及必须复制两次特定参数)
以下是使用环境的更详细示例。具体来说,我希望能够定义一个环境模板,然后只需向其传递参数即可使用它来定义几个不同的环境。
\documentclass{amsart}
\usepackage{amsthm}
\usepackage{xparse, l3fp,l3tl}
\begin{document}
\ExplSyntaxOn
\def\TheoremDepth{section}
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}[\TheoremDepth]%
\newtheorem*{theoremstar}{Theorem}%
\DeclareDocumentEnvironment{TheoremTemplate}{s o m m}
{
\IfBooleanTF{#1}
{ Do something
\begin{#1}}
{ Do something else
\begin{#2} }
}
{
\IfBooleanTF{#1}
{ Do something
\end{#1}}
{ Do something else
\end{#2} }
}
\DeclareDocumentEnvironment{MyTheorem}{s o}
{
\begin{TheoremTemplate}#1[#2]{theorem}{theoremstar}
}
{
\end{TheoremTemplate}
}
\ExplSyntaxOff
\end{document}
然后我希望能够调用 \begin{theorem} 和 \begin{theorem}* 并让它们做相应的事情。
答案1
我的印象是你使用了错误的方法;此外,这\begin{theorem}*
似乎不是最好的语法。
\documentclass{article}
\usepackage{xparse,amsthm}
\NewDocumentCommand{\DeclareTheorem}{momo}{%
% #1=environment's name
% #2=sibling counter
% #3=label
% #4=parent counter
\IfNoValueTF{#4}
{%
\IfNoValueTF{#2}
{\newtheorem{#1}{#3}}
{\newtheorem{#1}[#2]{#3}}%
}
{%
\newtheorem{#1}{#3}[#4]%
}
\newtheorem*{#1*}{#3}
}
\theoremstyle{plain}
\DeclareTheorem{thm}{Theorem}[section]
\DeclareTheorem{lem}[thm]{Lemma}
\begin{document}
\section{Test}
\begin{lem}
Numbered.
\end{lem}
\begin{thm}
This is numbered.
\end{thm}
\begin{lem*}
Unnumbered.
\end{lem*}
\begin{thm*}
This is unnumbered.
\end{thm*}
\end{document}
如果你希望定理默认按照章节或节进行编号,你可以将该\NewDocumentCommand
行更改为
\NewDocumentCommand{\DeclareTheorem}{momO{\TheoremDepth}}{%
给出适当的定义\TheoremDepth
;在这种情况下,上面的声明将变成
\DeclareTheorem{thm}{Theorem}
\DeclareTheorem{lem}[thm]{Lemma}
如果\TheoremDepth
被定义为section
。
答案2
为了扩展我的评论,我有几个假设。为什么\CTest
需要调用\CTwo
?如果\CTest
采用可选参数,为什么需要星号来指示是否使用它?\CTest
如果没有可选参数,应该如何表现?
通常(按照expl3
惯例),你会定义一个具有固定数量参数的底层函数,该函数在处理可选参数后接受你的输入,依此类推。为了简化示例(也许会降低复杂性,但我希望你能理解),你可以编写如下代码:
\documentclass{article}
\usepackage{xparse}
\begin{document}
\ExplSyntaxOn
\cs_new:Nn \my_output:n {#1}
\DeclareDocumentCommand{\CTest}{s O{testing}}
{
\IfBooleanTF{#1}
{ \my_output:n {#2} }
{ \my_output:n {testing} }
}
\ExplSyntaxOff
\CTest\\
\CTest*\\
\CTest[work]\\
\CTest*[work]\\
\end{document}
因为您似乎有两种应该使用默认值的情况(当不存在星号时,以及当不存在参数时),所以需要在两个地方输入此默认值。
您可能还希望有类似您\CTwo
定义的单独调用此\my_output:n
命令的功能。如果这不能体现您要执行的操作的复杂性,我建议您澄清您的问题。