我读过的有关带星号/无星号版本的命令的所有文档或多或少都推荐以下操作方式(例如TeX 常见问题列表):
\newcommand{\mycommand}{\@ifstar\mycommandStar\mycommandNoStar}
\newcommand{\mycommandStar}{%
<few lines of code only for starred mycommand>
<many lines of code common to starred/non starred mycommand>
}
\newcommand{\mycommandNoStar}{%
<few lines of code only for non starred mycommand>
<many lines of code common to starred/non starred mycommand>
}
对于环境来说,方案是类似的(例如这个答案):
\newenvironment{myenvironment}{%
<few lines of code only for non starred myenvironment>
<many lines of code common to starred/non starred myenvironment>
}{%
<few lines of code only for non starred myenvironment>
<many lines of code common to starred/non starred myenvironment>
}
\newenvironment{myenvironment*}{%
<few lines of code only for starred myenvironment>
<many lines of code common to starred/non starred myenvironment>
}{%
<few lines of code only for starred myenvironment>
<many lines of code common to starred/non starred myenvironment>
}
但是,大多数情况下,加星号的版本和非加星号的版本之间只有细微的差别,而这种方式需要在两个版本之间复制通用代码中的所有更改,这会给维护带来麻烦(特别是如果通用代码很长)。
有没有更有效的方法呢?
答案1
这主要取决于命令应该做什么。如果\mycommand*
不同,\mycommand
只是因为在开始时必须执行一些不同的代码,则以下方法应该有效:
\newcommand{\mycommand}{\@ifstar{\@tempswatrue\@mycommand}{\@tempswafalse\@mycommand}}
\newcommand{\@mycommand}{%
\if@tempswa
<few lines of code only for starred mycommand>
\else
<few lines of code only for non starred mycommand>
\fi
<many lines of code common to starred/non starred mycommand>
}
这样xparse
就变得更容易了:
\usepackage{xparse}
\NewDocumentCommand{\mycommand}{s}
{\IfBooleanTF{#1}
{<few lines of code only for starred mycommand>}
{<few lines of code only for non starred mycommand>}%
<many lines of code common to starred/non starred mycommand>%
}
对于环境形式,存在额外的复杂性,因为没有\@ifstar
可用的。
\newenvironment{myenvironment}{%
<few lines of code only for non starred myenvironment>
\@myenvironmentstart
}{%
<few lines of code only for non starred myenvironment>
\@myenvironmentfinish
}
\newenvironment{myenvironment*}{%
<few lines of code only for starred myenvironment>
\@myenvironmentstart
}{%
<few lines of code only for starred myenvironment>
\@myenvironmentfinish
}
\newcommand{\@myenvironmentstart}{%
<many lines of code common to starred/non starred myenvironment>
}
\newcommand{\@myenvironmentfinish}{%
<many lines of code common to starred/non starred myenvironment>
}
无法实现真正的简化xparse
。
答案2
该xparse
软件包是 LaTeX3 软件包的一部分,在这方面非常方便。例如:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\foo}{s}{This is the \IfBooleanTF{#1}{starred }{}foo command.}
\begin{document}
\foo{}
\foo*{}
\end{document}