Como definir um wrapper para um comando que recebe um argumento opcional?

Como definir um wrapper para um comando que recebe um argumento opcional?

Qual é a maneira correta de definir um wrapper para um comando que recebe um argumento opcional (como \chapter)? Quero dizer um wrapper, não um clone, de modo que possamos injetar código no wrapper sem interferir no comando do qual ele é um wrapper.

É assim que eu faço. Existe uma maneira melhor de fazer isso? (Devo a cláusula condicional a egregaqui.)

\documentclass{book}

\newcommand\mychapter[2][] {\if\relax\detokenize{#1}\relax
                             \chapter{#2}
                            \else
                             \chapter[#1]{#2}
                            \fi}

\begin{document}
\tableofcontents
\mychapter[Short title]{Long title}
\end{document}

let\mychapter\chapterirá cloná-lo, para que \mychapternão seja um wrapper para \chapter.

Responder1

Sim, existe uma maneira melhor:

\usepackage{xparse}

\NewDocumentCommand{\mychapter}{som}{%
  %%% things to do before \chapter
  \IfBooleanTF{#1}
    {\chapter*{#3}}
    {\IfNoValueTF{#2}{\chapter{#3}}{\chapter[#2]{#3}}%
  %%% things to do after \chapter
}

Isso suporta todas as três chamadas:

\mychapter*{Title}
\mychapter{Title}
\mychapter[Short title]{Long title}

Responder2

OtradicionalA maneira, antes xparsepermitida para soluções mais flexíveis, é usar \@ifnextchar[para verificar [o argumento opcional e injectoutro código no wrapper.

A versão com estrela também está incluída e pode ter um []agora também - cabe ao OP decidir o que isso []deve fazer então ;-)

\documentclass{book}



\newcommand\mychapter[2][]{\if\relax\detokenize{#1}%
                             \chapter{#2}
                            \else
                             \chapter[#1]{#2}
                            \fi}

\makeatletter
\newcommand{\myotherchapter@@opt}[2][]{%
  \chapter[#1]{#2}%
}

\newcommand{\myotherchapter@@noopt}[1]{%
  \chapter{#1}%
}

\newcommand{\myotherchapter@@starredopt}[2][]{%
  % Decide yourself what to do with #1 ;-)
  \chapter*{#2}
}


\newcommand{\myotherchapter@@starrednoopt}[1]{%
  \myotherchapter@@starredopt[#1]{#1}%
}

\newcommand{\myotherchapterstarred}{%
  \@ifnextchar[{\myotherchapter@@starredopt}{\myotherchapter@@starrednoopt}%
}

\newcommand{\myotherchapterunstarred}{%
  \@ifnextchar[{\myotherchapter@@opt}{\myotherchapter@@noopt}%
}

\newcommand{\myotherchapter}{%
  \@ifstar{\myotherchapterstarred}{\myotherchapterunstarred}%
}

\makeatother

\begin{document}

\tableofcontents

\mychapter[Short title]{Long title}

\myotherchapter{First}
\myotherchapter[Short Title]{Long title}

\myotherchapter*[Starred Short Title]{Starred Long title}

\myotherchapter*{Starred Long title}



\end{document}

informação relacionada