
Cuando defino un entorno con \newenvironment
, puedo usarlo newcommand
dentro 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 \set
para componer definiciones de conjuntos matemáticos y quiero que \suchthat
se use un comando dentro, como en:
\set{x\in X \suchthat x > 42}
Esto es fácil, pero me gustaría que el \suchthat
comando 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á \suchthat
disponible dentro de la macro.
Podrías haber hecho esto con \bgroup
y \egroup
, pero eso crea una subfórmula con consecuencias sobre cómo se maneja el espaciado si se usa en modo matemático. Los \begingroup
y \endgroup
aquí localizan la definición de nuevas macros. Puede utilizar cualquiera de los siguientes para definir un comando local, \def
, \edef
y \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/\endgroup
enfoque, 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.
Localizar la definición con
\bgroup
y\egroup
es malo, porque la\set
macro 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\begingroup
y\endgroup
no sufre este problema.Se debe proporcionar una definición predeterminada de
\suchthat
todos modos, porque es posible que la desee\suchthat
en el título de una sección.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