Cuando envuelves una región una y otra vez con el mismo formato, puedes construir tu propio \begin{name}…\end{name}. La base es \newenvironment. Si una macro es una *orden* hecha a mano, un entorno es su equivalente de bloque. Esta página recorre los fundamentos: el código separado que se ejecuta al inicio y al final, cómo pasar argumentos y su trampa, cómo redefinir un entorno existente y el moderno \NewDocumentEnvironment.
Definir un entorno con \newenvironment
La herramienta básica es \newenvironment{name}{⟨begin-def⟩}{⟨end-def⟩}. El primer argumento es el nombre del entorno que quieres, sin barra invertida; los dos siguientes son el código que se ejecuta al inicio y el código que se ejecuta al final. Cuando LaTeX encuentra \begin{name}, ejecuta ⟨begin-def⟩; cuando encuentra \end{name}, ejecuta ⟨end-def⟩; y el cuerpo entre ambos se compone de forma normal.
% プリアンブルで定義 / define in the preamble
\newenvironment{warning}{%
\par\noindent\textbf{注意:}\itshape
}{%
\par
}
% 本文で使う / use it in the body
\begin{warning}
この操作は元に戻せません。
\end{warning}Una propiedad decisiva: un entorno es por sí mismo un grupo implícito, es decir, un ámbito local. Las reglas de LaTeX indican que el código ⟨begin-def⟩, el cuerpo del entorno y el código ⟨end-def⟩ se procesan todos dentro de un grupo. Por tanto, cualquier cambio de fuente o espaciado hecho en ⟨begin-def⟩ se deshace automáticamente en \end{name} y no se filtra al texto circundante. Por eso, en el ejemplo, solo el cuerpo sale en cursiva aunque nunca desactivemos \itshape explícitamente.
Este agrupamiento automático es muy cómodo cuando quieres confinar un cambio de fuente o espaciado a un tramo fijo. Hacer lo mismo con una macro (\newcommand) obliga a envolver tú mismo el contenido en { … } para formar un grupo; con un entorno, \begin…\end ya cumple esa función.
Entornos con argumentos, y por qué el código final no puede verlos
Para variar el contenido en cada llamada, da argumentos al entorno. Igual que con \newcommand, escribes el número de argumentos entre corchetes después del nombre y los referencias dentro de ⟨begin-def⟩ como #1, #2, etc.: \newenvironment{name}[⟨nargs⟩]{⟨begin-def⟩}{⟨end-def⟩} (de #1 a #9, nueve como máximo).
% 見出しの語を引数で受け取る / take the heading word as an argument
\newenvironment{point}[1]{%
\par\noindent\textbf{#1}\quad
}{%
\par
}
\begin{point}{結論}
早めにバックアップを取ること。
\end{point}También como con \newcommand, puedes hacer opcional el primer argumento y darle un valor por defecto. Al duplicar los corchetes — \newenvironment{name}[⟨nargs⟩][⟨default⟩]{...}{...} — #1 se vuelve opcional y su valor por defecto es ⟨default⟩. Se abre como \begin{name} (usa el valor por defecto) o \begin{name}[x] (#1 pasa a ser x). Como en \newcommand, el ⟨nargs⟩ de [⟨nargs⟩] es el número total de argumentos, incluido el opcional.
Aquí está la gran trampa propia de los entornos. Los argumentos #1, #2, … solo pueden usarse en ⟨begin-def⟩; no puedes usarlos en ⟨end-def⟩. Las reglas lo dicen de forma explícita: el código final no puede contener parámetros; es decir, ahí no se pueden usar #1, #2, etc. En pocas palabras, cuando se ejecuta \end{name}, los argumentos ya no están disponibles. Escribir #1 en ⟨end-def⟩ no expande el argumento, sino que produce un error.
Si necesitas el valor de un argumento al final, el movimiento estándar es guardarlo mientras aún estás en ⟨begin-def⟩. Para texto, guárdalo en una caja (resérvala con \newsavebox y rellénala con \sbox), o haz que una macro lo recuerde mediante \newcommand/\def, y recupéralo en ⟨end-def⟩. Como todo el entorno es un grupo, lo que guardes en ⟨begin-def⟩ sobrevive hasta ⟨end-def⟩. El ejemplo de abajo imprime una atribución al final de una cita: toma la fuente como #1 (por defecto Shakespeare), la guarda en \quoteauthor y la usa al cerrar.
\newsavebox{\quoteauthor}
\newenvironment{citequote}[1][Shakespeare]{%
\sbox\quoteauthor{#1}% begin-def で引数を保存 / save the arg here
\begin{quotation}
}{%
\hspace{1em plus 1fill}---\usebox{\quoteauthor}% end-def で取り出す
\end{quotation}%
}
\begin{citequote}
To be, or not to be.
\end{citequote}
\begin{citequote}[Knuth]
Premature optimization is the root of all evil.
\end{citequote}\renewenvironment y nombres ya existentes
Los entornos tienen la misma red de seguridad que \newcommand: \newenvironment solo tiene éxito si el nombre aún no está definido. Usarlo sobre un entorno ya existente se detiene con LaTeX Error: Command \name already defined. (un entorno name se apoya internamente en una orden \name, de ahí el texto). Es deliberado, para evitar que sobrescribas un entorno existente sin darte cuenta.
Para rehacer un entorno existente, usa \renewenvironment. Toma argumentos exactamente como \newenvironment, incluidos [⟨nargs⟩][⟨default⟩]; solo cambia el comportamiento. \renewenvironment da error si el objetivo no está ya definido: la imagen especular de \newenvironment. Lo usarás para sustituir el contenido de entornos incorporados como quote o itemize.
% 既存の quote を、本文を斜体にする版へ作り直す
\renewenvironment{quote}{%
\list{}{\rightmargin\leftmargin}\item\relax\itshape
}{%
\endlist
}Hay algunas reglas. Primero, un nombre de entorno no puede empezar por la cadena end, porque el procesamiento de \end{...} usa internamente una orden llamada \end<name> y así se evita una colisión. Segundo, \newenvironment y \renewenvironment tienen una forma con estrella, escrita con * después del nombre, que difiere en el tratamiento de los espacios finales en los argumentos; normalmente basta la forma sin estrella. No existe en el estándar un equivalente de \providecommand para entornos, “definir solo si falta”; si lo necesitas, usa la interfaz moderna de la sección siguiente.
Patrones comunes
En la práctica, definir entornos propios suele caer en tres patrones. Todos comparten el mismo esqueleto: preparar en ⟨begin-def⟩ y limpiar en ⟨end-def⟩.
- Envolver contenido en formato — establecer la fuente, tamaño o alineación en
⟨begin-def⟩y dejar que el cuerpo adopte ese aspecto. Gracias al agrupamiento,⟨end-def⟩puede estar vacío y el cambio se revierte automáticamente. - Añadir espacio antes y después — poner espacio vertical como
\par\medskipal comienzo de⟨begin-def⟩y al final de⟨end-def⟩, enmarcando el cuerpo con márgenes superior e inferior. - Construir sobre un entorno existente — abrir otro entorno con
\begin{...}en⟨begin-def⟩y cerrar el\end{...}correspondiente en⟨end-def⟩. Así se aderezaquote,centerolistcon algo extra.
El tercer patrón, construir sobre un entorno existente, es el más común. Un entorno smallquote, por ejemplo, que reutiliza quotation pero en letra más pequeña, simplemente activa \small y abre \begin{quotation} en ⟨begin-def⟩, luego cierra \end{quotation} en ⟨end-def⟩. El comportamiento del entorno base, como sangría y márgenes, se conserva.
% 1) 書式で包む / wrap in formatting
\newenvironment{aside}{\par\small\itshape}{\par}
% 2) 前後に空きを入れる / add space around
\newenvironment{spaced}{\par\medskip\noindent}{\par\medskip}
% 3) 既存の環境の上に作る / build on quotation
\newenvironment{smallquote}{%
\small\begin{quotation}
}{%
\end{quotation}
}Cuida cerrar en ⟨end-def⟩ todo lo que abras en ⟨begin-def⟩, manteniendo las parejas equilibradas. También ayuda terminar las líneas de código con % para que los espacios accidentales al final de ⟨begin-def⟩ o de una línea de código no entren en la salida; por eso cada línea de los ejemplos multilínea anteriores acaba en %.
El moderno \NewDocumentEnvironment
LaTeX moderno ofrece otra forma más potente: \NewDocumentEnvironment{name}{⟨arg-spec⟩}{⟨begin-code⟩}{⟨end-code⟩}. Es la contraparte de \NewDocumentCommand en el lado de las macros; originalmente era una función del paquete xparse, pero forma parte del núcleo de LaTeX desde octubre de 2020 y está disponible sin \usepackage. En vez de un número de argumentos, declaras una especificación de argumentos (arg-spec): letras como m (obligatorio), o (opcional), O{default} (opcional con valor por defecto) y s (estrella opcional). La página “xparse” cubre los especificadores en detalle.
Esta interfaz supera al viejo \newenvironment en dos aspectos. Primero, puede tomar varios argumentos opcionales y manejar variantes con estrella correctamente. Segundo, y de forma decisiva, los argumentos están disponibles tanto en ⟨end-code⟩ como en ⟨begin-code⟩. La documentación del núcleo lo dice claramente: tanto el código inicial como el final pueden acceder a los argumentos definidos por ⟨arg-spec⟩. Eso elimina la maniobra de guardar valores en cajas mostrada antes.
% #1 を begin でも end でも使える / #1 usable in both begin and end
\NewDocumentEnvironment{citequote}{O{Shakespeare}}{%
\begin{quotation}
}{%
\hspace{1em plus 1fill}---#1%
\end{quotation}%
}
\begin{citequote}[Knuth]
Premature optimization is the root of all evil.
\end{citequote}\NewDocumentEnvironment también trae la familia que refleja a los parientes de \newenvironment: \RenewDocumentEnvironment (redefinir), \ProvideDocumentEnvironment (definir solo si falta) y \DeclareDocumentEnvironment (definir sin importar si ya existe). Para código nuevo, esta interfaz moderna es la opción recomendada, tanto por la flexibilidad de sus argumentos como porque el código final puede verlos.