Cómo mejorar el mantenimiento de versiones destacadas/no destacadas de comandos o entornos

Cómo mejorar el mantenimiento de versiones destacadas/no destacadas de comandos o entornos

Todas las documentaciones que he leído sobre versiones de comandos destacadas/no destacadas recomiendan más o menos la siguiente forma de hacerlo (siguiendo por ejemplola lista de preguntas frecuentes de 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 los entornos, el esquema es similar (siguiendo por ejemploesta respuesta):

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

Pero, en la mayoría de los casos, sólo hay ligeras diferencias entre las versiones destacadas y no destacadas y esta forma de hacerlo requiere copiar todos los cambios en el código común entre las dos versiones, lo cual es una molestia de mantenimiento (particularmente si el código común es largo).

¿Existe una forma más eficiente de hacerlo?

Respuesta1

Depende principalmente de lo que deberían hacer los comandos. Si \mycommand*difiere de \mycommandsimplemente porque se debe ejecutar algún código diferente al principio, el siguiente enfoque debería 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>
}

Con xparseesto se vuelve más 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 el medio ambiente hay complicaciones adicionales, porque no hay nada \@ifstardisponible.

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

No es posible una simplificación real con xparse.

Respuesta2

El xparsepaquete, que forma parte del paquete LaTeX3, es muy útil a este respecto. Por ejemplo:

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\foo}{s}{This is the \IfBooleanTF{#1}{starred }{}foo command.}
\begin{document}
\foo{}

\foo*{}
\end{document}

ingrese la descripción de la imagen aquí

información relacionada