
Todas as documentações que li sobre versões de comandos com/sem estrela recomendam mais ou menos a seguinte maneira de fazer (seguindo por exemploa lista de perguntas frequentes do 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>
}
Para ambientes, o esquema é semelhante (seguindo por exemploesta resposta):
\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>
}
Mas, na maioria dos casos, existem apenas pequenas diferenças entre as versões com e sem estrela e esta forma de fazer requer a cópia de todas as alterações no código comum entre as duas versões, o que é uma tarefa difícil de manutenção (especialmente se o código comum for longo).
Existe uma maneira mais eficiente de fazer?
Responder1
Depende principalmente do que os comandos devem fazer. Se \mycommand*
for diferente \mycommand
apenas porque algum código diferente precisa ser executado no início, a seguinte abordagem deve funcionar:
\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>
}
Com xparse
isso fica mais fácil:
\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>%
}
Para a forma ambiental há complicações adicionais, pois não há \@ifstar
disponível.
\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>
}
Nenhuma simplificação real é possível com xparse
.
Responder2
O xparse
pacote, parte do pacote LaTeX3, é muito útil nesse aspecto. Por exemplo:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\foo}{s}{This is the \IfBooleanTF{#1}{starred }{}foo command.}
\begin{document}
\foo{}
\foo*{}
\end{document}