¿Cómo puedo hacer que un comando esté disponible dentro del argumento de otro comando?

¿Cómo puedo hacer que un comando esté disponible dentro del argumento de otro comando?

Cuando defino un entorno con \newenvironment, puedo usarlo newcommanddentro de la parte "antes" para que los comandos estén disponibles para el código dentro del entorno.

¿Es esto posible con comandos simples? En otras palabras, ¿puedo crear un comando tal que en el argumento el usuario pueda usar una macro que no esté definida externamente?

Ejemplo: supongamos que quiero codificar un comando \setpara componer definiciones de conjuntos matemáticos y quiero que \suchthatse use un comando dentro, como en:

\set{x\in X \suchthat x > 42}

Esto es fácil, pero me gustaría que el \suchthatcomando solo esté disponible dentro de un argumento de \set.

Respuesta1

Puedes definir un comando como

\newcommand\set[1]{%%
   \begingroup
     \def\suchthat{... some definition...}%%
     ... other macro content ....
    \endgroup}

Y esto estará \suchthatdisponible dentro de la macro.

Podrías haber hecho esto con \bgroupy \egroup, pero eso crea una subfórmula con consecuencias sobre cómo se maneja el espaciado si se usa en modo matemático. Los \begingroupy \endgroupaquí localizan la definición de nuevas macros. Puede utilizar cualquiera de los siguientes para definir un comando local, \def, \edefy \newcommand.

Siguiendo la sugerencia de @barbarabeeto podrías hacer algo como esto en tu preámbulo:

\makeatletter
\def\ae@suchthat{... definition of such that ...}
\newcommand\aset[1]{%%
  \let\suchthat\ae@suchthat
    the body of the macro: #1
  \let\suchthat\undefined
}
\makeatother

Esto es mucho mejor. Además de las razones que sugiere barbarabeeto, esto también permitiría que su macro, si así lo desea, defina o establezca valores a los que quizás desee acceder más adelante en el documento. Con este \begingroup/\endgroupenfoque, habría que globalizarlos, lo que quizá no sea lo que se desearía.

Un enfoque híbrido podría parecer

\makeatletter
\def\ae@suchthat{... definition of such that ...}
\newcommand\aset[1]{%%
  \begingroup
    \let\suchthat\ae@suchthat
      the body of the macro: #1
  \endgroup
}
\makeatother

Respuesta2

Las sugerencias de A. Ellett son buenas, pero hay algunas sutilezas relacionadas con este enfoque.

  1. Localizar la definición con \bgroupy \egroupes malo, porque la \setmacro se usa claramente en modo matemático. Tal construcción generaría una subfórmula, con la consecuencia de que los espacios se congelan y no participan en el estiramiento y la contracción de la línea; usando \begingroupy \endgroupno sufre este problema.

  2. Se debe proporcionar una definición predeterminada de \suchthattodos modos, porque es posible que la desee \suchthaten el título de una sección.

  3. Ambos comandos deberían ser robustos, por la misma razón.

Aquí hay una implementación.

\documentclass{article}
\usepackage{etoolbox}

\makeatletter
\newrobustcmd{\suchthat}{%
  \@latex@error{Use \noexpand\suchthat only in \string\set}
    {You are allowed to use \noexpand\suchthat only in the\MessageBreak
     argument of \string\set}%
}
\newcommand\giga@suchthat{\mid}
\newrobustcmd{\set}[1]{%
  \begingroup
  \let\suchthat\giga@suchthat
  \{\,#1\,\}%
  \endgroup
}
\makeatother

\begin{document}

\tableofcontents

\section{The set $\set{x\in X \suchthat x>42}$}

Let's study $\set{x\in X \suchthat x>42}$.

\suchthat

\end{document}

La salida en la terminal:

! LaTeX Error: Use \suchthat only in \set.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.27 \suchthat

? h
You are allowed to use \suchthat only in the
argument of \set

La salida

ingrese la descripción de la imagen aquí

información relacionada