Как улучшить обслуживание отмеченных/не отмеченных звездочкой версий команд или сред

Как улучшить обслуживание отмеченных/не отмеченных звездочкой версий команд или сред

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

введите описание изображения здесь

Связанный контент