\newcommand: Объединить (необязательно) звездочку и необязательный параметр

\newcommand: Объединить (необязательно) звездочку и необязательный параметр

Как определить новую команду, которая допускает варианты со звездочкой и без нее, а также допускает необязательный аргумент?

Я попробовал следующее:

\documentclass{minimal}
\makeatletter
\newcommand\MyCommand[1][1]{%
  \@ifstar{%
    The starred variant with parameter: #1%
  }{%
    The non-starred variant with parameter: #1%
  }
}
\makeatother
\begin{document}
\MyCommand    \\    
\MyCommand*   \\
\MyCommand[2] \\
\MyCommand*[2]
\end{document}

Но это дает:

Вариант без звездочки с параметром: 1
Вариант со звездочкой с параметром: 1
Вариант без звездочки с параметром: 2
Вариант со звездочкой с параметром: 1[2]

Конечно, можно написать так \MyCommand[2]*, чтобы получить «Помеченный звездочкой вариант с параметром: 2», но мне бы хотелось, чтобы работала версия выше.

решение1

С xparseего помощью очень легко экспериментировать с необязательными аргументами и отмеченными звездочками вариантами:

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\MyCommand
  {
    s % optional *
    O{1} % first optional argument (default = 1)
  }
  {%
    \IfBooleanTF{#1}
      {The starred variant with parameter: #2}
      {The non-starred variant with parameter: #2}
  }
\begin{document}
\noindent
\MyCommand   \\
\MyCommand*  \\
\MyCommand[2]\\
\MyCommand*[2]
\end{document}

С LaTeX \newcommandвсе немного сложнее. \@ifstarМакрос смотрит на следующий токен после того, как макрос развернут и поглотил свои аргументы, поэтому сначала нужно проверить *и только потом искать необязательный аргумент:

\documentclass{article}
\makeatletter
\newcommand\MyCommand
  {%
    \@ifstar
      {\MyCommand@star}
      {\MyCommand@nostar}%
  }
\newcommand\MyCommand@star[1][1]{%
  The starred variant with parameter: #1%
}
\newcommand\MyCommand@nostar[1][1]{%
  The non-starred variant with parameter: #1%
}
\makeatother
\begin{document}
\noindent
\MyCommand   \\
\MyCommand*  \\
\MyCommand[2]\\
\MyCommand*[2]
\end{document}

Обе версии печатают:

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

Ваш код работает, но не так, как вы ожидаете. Поиск \MyCommand[1][1]необязательного аргумента «while expand» \MyCommand, который затем дает вам:

\@ifstar{%
  The starred variant with parameter: <optional argument or default>%
}{%
  The non-starred variant with parameter: <optional argument or default>%
}

и толькопосле этоготест \@ifstarбудет расширен для поиска необязательного значения *и выбора соответствующего текста, поэтому фактический синтаксис для определенной вами команды следующий:

\MyCommand[optional argument]<optional star>

решение2

Не брать \MyCommandникаких параметров, а просто вычислить звезду. Затем разветвляться оттуда.

\documentclass{minimal}
\makeatletter
\newcommand\MyCommand{%
  \@ifstar{\mycommandstar}{\mycommandnostar}
}
\newcommand\mycommandstar[1][1]{The starred variant with parameter: #1}
\newcommand\mycommandnostar[1][1]{The non-starred variant with parameter: #1}
\makeatother
\begin{document}
\MyCommand    \\    
\MyCommand*   \\
\MyCommand[2] \\
\MyCommand*[2]
\end{document}

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

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