Opciones y creación de clases

Cuando las clases ya hechas se quedan cortas, puedes escribir la tuya. Esta página trata de crear una clase. Primero cubrimos las opciones estándar que una clase suele aceptar (tamaño de letra, papel, columnas, etc.); después construimos el contenido de un archivo .cls o .sty: identificarlo con \ProvidesClass, declarar opciones con \DeclareOption, ejecutarlas con \ProcessOptions y apoyarse en una clase existente con \LoadClass, hasta terminar con un ejemplo completo que extiende article. Para usar opciones desde el documento, consulta “Document class & preamble”.

¿Clase o paquete?

Antes de escribir nada, decide si vas a crear una clase (.cls) o un paquete (.sty). Una clase define el tipo de documento y se carga exactamente una vez, con \documentclass; aporta el esqueleto general y el aspecto predeterminado de un artículo, un libro o unas diapositivas. Un paquete, en cambio, se carga con \usepackagetantos como quieras — y añade funciones independientes del tipo de documento (amsmath para matemáticas, graphicx para figuras, etc.).

En palabras del clsguide oficial, la prueba es sencilla: si la función podría usarse con cualquier clase de documento, hazla paquete; si no, hazla clase. ¿Quieres definir todo un aspecto? Una clase. ¿Solo añadir una función? Un paquete. Las convenciones de autoría son casi idénticas en ambos casos; los comandos simplemente tienen una versión Class y una versión Package (\ProvidesClass\ProvidesPackage, \LoadClass\RequirePackage, \PassOptionsToClass\PassOptionsToPackage).

Las opciones estándar que acepta tu clase

Los usuarios pasarán opciones a tu clase igual que a una estándar, así que como mínimo conviene admitir las habituales: 10pt / 11pt / 12pt para el tamaño base del cuerpo, a4paper / letterpaper para el papel, onecolumn / twocolumn para las columnas, oneside / twoside para una o dos caras, y draft (marca las líneas desbordadas con una barra negra; su opuesto es final). No necesitas implementarlas tú mismo: como veremos en “pasar opciones a una clase base”, lo normal es reenviarlas a una clase base como article.

OpciónSignificadoPredeterminado
10pt / 11pt / 12ptTamaño base del cuerpo10pt
a4paper / letterpaperTamaño del papel (también b5paper, legalpaper, etc.)letterpaper
onecolumn / twocolumnUna columna / dos columnasonecolumn
oneside / twosideDiseño a una cara / doble caraoneside (pero twoside en book)
draft / finalSi se marcan las líneas desbordadas con una barra negrafinal

Para ejemplos detallados de cómo especificar y usar estas opciones en el lado \documentclass[...] del documento, y opciones propias de book como openright, consulta la página hermana “Document class & preamble”. A partir de aquí nos centramos en cómo escribir la clase que las recibe.

Identificar el archivo al principio

Las dos primeras líneas de un archivo de clase (myclass.cls) son casi boilerplate. Primero, \NeedsTeXFormat{LaTeX2e} declara que el archivo está pensado para LaTeX2e; cargarlo con un formato más antiguo produce una advertencia. Después, \ProvidesClass{myclass}[2026/01/01 v1.0 ...] anuncia el nombre de la clase, fecha de publicación, versión y breve descripción. La parte entre corchetes es opcional, pero permite a los usuarios exigir una versión mínima mediante la fecha, en formato YYYY/MM/DD, por ejemplo \documentclass{...}[2026/01/01], y registra la identificación en el log.

Si escribes un paquete, el equivalente es \ProvidesPackage{mypackage}[2026/01/01 v1.0 ...]; \NeedsTeXFormat es común a ambos. Regla firme: el nombre en \ProvidesClass / \ProvidesPackage debe coincidir con el nombre real del archivo; dentro de myclass.cls siempre escribes \ProvidesClass{myclass}.

latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2026/01/01 v1.0 My example class]

Declarar opciones — \DeclareOption

Cada opción que acepta tu clase se declara con \DeclareOption{option}{code}. Cuando el usuario especifica esa opción, su código se ejecuta al llegar a \ProcessOptions (descrito más abajo). Por ejemplo, puedes proporcionar tu propio interruptor draft que active una bandera booleana.

El receptor para opciones que no has declarado es la forma con estrella \DeclareOption*{code}. Dentro de ella, \CurrentOption se expande al nombre de la opción que se está procesando. La línea más común en una clase propia reenvía cualquier opción desconocida directamente a la clase base. Gracias a ella, los usuarios pueden pasar opciones estándar como 10pt o a4paper con normalidad, aunque tú no las hayas declarado.

latex
% pass anything we do not handle ourselves on to article
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}

En un paquete usas el equivalente \PassOptionsToPackage{\CurrentOption}{base}. Si quieres aplicar valores predeterminados antes de \ProcessOptions, escribe \ExecuteOptions{a4paper,11pt}: eso ejecuta primero el código de esas opciones, aunque el usuario no especifique nada.

Procesar opciones y pasar a una clase base

Declarar opciones no hace nada por sí solo; su código se ejecuta únicamente cuando llamas a \ProcessOptions. En la práctica casi siempre se escribe \ProcessOptions\relax. Como también existe la forma con estrella \ProcessOptions*, el \relax final es la forma idiomática de seleccionar con seguridad la versión sin estrella. \ProcessOptions sin estrella procesa las opciones en el orden en que las declaraste; la forma con estrella las procesa en el orden especificado por quien llama.

Construir un diseño desde cero es mucho trabajo, así que la mayoría de clases propias se apoyan en una existente. Eso es \LoadClass[options]{article}, que carga todos los comandos y el estilo de article.cls (también puedes pasar twocolumn y similares entre corchetes). \LoadClass solo puede usarse dentro de un archivo de clase. El orden importa: para que las opciones dadas por el usuario en \documentclass[...] lleguen a la clase base, pon \LoadClass después del procesamiento de opciones (\ProcessOptions). Primero configura el reenvío, deja que \ProcessOptions despache las opciones y solo entonces carga la base.

Si solo quieres dar a la clase base las mismas opciones que recibió tu clase, \LoadClassWithOptions{article} es cómodo: reenvía tal cual las opciones globales de la clase. Al escribir un paquete, usa \RequirePackage en lugar de \LoadClass (el equivalente de autor a \usepackage en el preámbulo), y \RequirePackageWithOptions para pasar todo sin cambios.

Todo lo que sigue a \LoadClass es donde por fin va el carácter de tu clase: redefinir estilos de encabezado con \renewcommand, ajustar márgenes con \setlength, definir comandos y entornos nuevos con \newcommand / \newenvironment, y cargar desde ahí los paquetes adicionales necesarios con \RequirePackage.

Ejemplo completo: una clase mínima que extiende article

Al unir todo lo anterior se obtiene este .cls mínimo. Se apoya en article, añade su propia opción draft, reenvía las opciones desconocidas a article y por último ajusta los márgenes y define un comando propio. Guárdalo como myclass.cls y úsalo desde un documento con \documentclass[11pt,a4paper]{myclass}.

latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2026/01/01 v1.0 My example class]

% --- declare options ---
\newif\ifmy@draft
\DeclareOption{draft}{\my@drafttrue}
% forward everything else to article
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}

% --- execute and load the base class ---
\ExecuteOptions{a4paper}      % a default if the user gives none
\ProcessOptions\relax
\LoadClass{article}

% --- this class's own setup ---
\RequirePackage[margin=25mm]{geometry}
\setlength{\parindent}{0pt}
\newcommand{\version}{v1.0}
\ifmy@draft \RequirePackage{draftwatermark}\fi

\endinput

El \endinput final le dice a LaTeX que no lea más de este archivo; es convencional incluirlo. Para hacer un paquete, cambia la apertura por \ProvidesPackage y \LoadClass por \RequirePackage: el mismo esqueleto se convierte en un archivo .sty.

La forma moderna: opciones clave-valor (expl3)

El mecanismo \DeclareOption anterior sigue siendo totalmente válido, pero está pensado sobre todo para opciones de tipo interruptor, presentes o ausentes. Para código nuevo que quiera opciones clave-valor naturales como name=value, la recomendación actual es la interfaz propia del kernel de LaTeX: declarar claves con \DeclareKeys y procesarlas con \ProcessKeyOptions. Basado en l3keys de expl3 (LaTeX3), forma parte de los kernels recientes de LaTeX.

Antes esto se hacía con el paquete l3keys2e, pero el núcleo de esa funcionalidad ya está incorporado al kernel, así que el código nuevo puede llamar directamente a \ProcessKeyOptions sin cargar el paquete. Dicho esto, muchos tutoriales existentes y muchos paquetes siguen centrados en el estilo \DeclareOption, por lo que entender el esqueleto de esta página sigue siendo valioso. Al pasar a opciones clave-valor, consulta la sección correspondiente del clsguide actual (“LaTeX2e for class and package writers”).

Una prueba mínima antes de compartir

Una clase afecta a todo el documento en cuanto se carga, así que fija su comportamiento con un documento de prueba diminuto antes de escribir contenido real. Comprueba primero que opciones estándar como 10pt, 11pt, a4paper y draft llegan a la clase base, mientras que solo tus opciones propias las maneja tu código. Si falla, la causa suele ser la posición de \ProcessOptions / \ProcessKeyOptions, el reenvío de opciones desconocidas o el orden de \LoadClass.

latex
\documentclass[11pt,a4paper,draft]{myclass}
\begin{document}
\section{Smoke test}
本文の基準サイズ、用紙、下書き表示、見出し、余白を確認する。
\end{document}
  • ¿El log identifica la clase? Confirma que la fecha y versión de \ProvidesClass aparecen en el .log. Una discrepancia entre nombre de archivo y nombre de clase causa confusión después.
  • ¿Conservaste las opciones estándar? Si 11pt o twocolumn se ignoran, revisa el manejador que reenvía opciones desconocidas a la clase base.
  • ¿Las macros de documento se comportan en el preámbulo y el cuerpo? Compila un encabezado, una nota, una figura y una tabla, porque son lo primero que tocarán usuarios reales.
  • Mantén inerte todo lo posterior a \endinput. Dejar notas o ejemplos después puede hacer que se lea texto inesperado si el marcador falta o se mueve.

Piensa también en la forma de distribución

Una clase propia no se pone a prueba cuando funciona por primera vez para ti, sino cuando otra persona la carga en otro entorno. Como mínimo, mantén juntos el .cls, un documento de ejemplo corto, un README y un changelog, y asegúrate de que el ejemplo compila tal cual. En el README, separa las opciones reenviadas a la clase base de las que maneja tu clase, para que los usuarios vean dónde tienen efecto 11pt o a4paper. Pon en el ejemplo un encabezado, una lista, una figura/tabla y una bibliografía, de modo que se comprueben juntos los elementos que una clase suele romper primero.

terminal
myclass/
  myclass.cls
  sample.tex
  README.md
  CHANGELOG.md

Antes de distribuir, pon \listfiles en el ejemplo para que el log registre los archivos y versiones cargados. Eso ayuda a diagnosticar si un usuario tiene un myclass.cls local antiguo o si los paquetes necesarios se cargan como se espera. Como una clase es la base de todo el documento, a largo plazo importan más el orden de carga, el procesamiento de opciones y la información del log que añadir otra macro para el cuerpo.