Как определить новую команду, которая допускает варианты со звездочкой и без нее, а также допускает необязательный аргумент?
Я попробовал следующее:
\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}