¿Cómo definir un contenedor para un comando que toma un argumento opcional?

¿Cómo definir un contenedor para un comando que toma un argumento opcional?

¿Cuál es la forma correcta de definir un contenedor para un comando que toma un argumento opcional (como \chapter)? Me refiero a un contenedor, no a un clon, de modo que podamos inyectar código en el contenedor sin interferir con el comando del cual es un contenedor.

Así es como lo hago. ¿Existe una mejor manera de hacerlo? (Le debo la cláusula condicional a egregaquí.)

\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\chapterlo clonará, por lo que \mychapterno será un envoltorio para \chapter.

Respuesta1

Sí, hay una mejor manera:

\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
}

Esto admite las tres llamadas:

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

Respuesta2

EltradicionalLa forma, antes xparsepermitida para soluciones más flexibles, es usar \@ifnextchar[para verificar el [argumento opcional y injectotro código en el contenedor.

La versión destacada también está incluida y []también puede tener un ahora; depende del OP decidir qué []debe hacer en ese momento ;-)

\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}

información relacionada