
Все прочитанные мной документы о версиях команд со звездочкой/без звездочки рекомендуют более или менее следующий способ выполнения (например,Список часто задаваемых вопросов по 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}