Alineación de texto (centrado / irregular / justificado)

¿Por qué los párrafos compuestos por LaTeX resultan más descansados que los de un procesador de textos? La respuesta está un nivel por debajo de la alineación del texto: un procesador de textos rellena línea a línea, mientras que LaTeX sopesa el párrafo entero antes de decidir dónde termina cualquiera de sus líneas. El valor por defecto es el texto justificado, y para apartarse de él hay dos caminos: las declaraciones como \centering y los entornos como center, que producen exactamente la misma alineación pero no el mismo espacio vertical. Esta página sigue un único hilo: por qué la justificación es el valor por defecto, cómo elegir entre \centering y center, por qué \raggedright deja de partir palabras sin avisar y qué hace ragged2e al respecto, y cómo responder a un aviso Overfull \hbox.

Por qué el texto justificado es el valor por defecto: un salto de línea para todo el párrafo

Si no se indica otra cosa, LaTeX compone los párrafos en texto justificado, al ras de ambos márgenes. Ese valor por defecto no es una simple costumbre. TeX no rellena las líneas de arriba abajo: elige la combinación de cortes que cuesta menos deméritos al párrafo entero. El algoritmo se publicó como «Breaking Paragraphs into Lines», de Donald Knuth y Michael Plass (Software: Practice and Experience, vol. 11, 1981, pp. 1119–1184). Un llenado voraz, línea a línea, cobra pronto sus ganancias y pasa la factura a la última línea; TeX puede hacer lo contrario y empeorar a propósito una línea del principio para que nada se hunda más adelante. Esa optimización solo tiene margen si los espacios entre palabras pueden estirarse y encogerse, que es justo lo que aporta la justificación. De ahí el punto de partida.

El mecanismo es concreto. Para cada línea, TeX convierte el estiramiento o el encogimiento en una badness y la penalización del punto de corte en p; con l para \linepenalty y b para la badness, los deméritos de la línea valen d = (l+b)^2 + p^2. Los deméritos de un párrafo son su suma, más recargos por líneas vecinas visualmente dispares (\adjdemerits) y por dos líneas seguidas terminadas en guion (\doublehyphendemerits). Knuth y Plass califican ellos mismos esas fórmulas de «quite arbitrary», y aun así funcionan. Conviene saber además que el cortador de líneas hace hasta tres pasadas. La primera intenta el párrafo sin partir ni una palabra y solo lo acepta si cada línea se mantiene dentro de \pretolerance; la segunda recurre ya a los patrones de partición y a la \tolerance, más holgada. Es decir: un párrafo que entra con holgura nunca se parte con guiones. Solo si eso también falla se ejecuta una tercera pasada con \emergencystretch.

\centering frente al entorno center

En corto: la alineación es exactamente la misma y la única diferencia es el espacio vertical añadido arriba y abajo. En latex.ltx, center está definido como \trivlist \centering\item\relax: el entorno no es más que \centering envuelto en una lista invisible y, por ser lista, aporta un \topsep de separación con el texto que lo rodea. flushleft envuelve de igual modo a \raggedright, y flushright a \raggedleft. Medido en una clase article a 10pt, el entorno center añade unos 8pt arriba y abajo; la declaración no añade nada.

DeclaraciónEntornoBorde alineadoEspacio vertical
\centeringcenterningún borde alineado, las líneas quedan centradasnulo con la declaración, \topsep con el entorno
\raggedrightflushleftborde izquierdo alineado, derecho en banderaigual que arriba
\raggedleftflushrightborde derecho alineado, izquierdo en banderaigual que arriba
\justifyingjustifyambos bordes alineados: texto justificadorequiere ragged2e; la declaración no añade nada
latex
\begin{figure}[htbp]
  \centering                 % declaration: adds no vertical space
  \includegraphics[width=0.6\textwidth]{plot}
  \caption{Measured values against the model}
  \label{fig:plot}
\end{figure}

Por eso una figure debe usar \centering y no \begin{center}. El flotante ya trae su propio espacio arriba y abajo; superponerle el \topsep del entorno center deja la imagen y su leyenda con aspecto acolchado. El mismo razonamiento vale para una celda tabular, una \parbox, un minipage y el contenido de un \caption: allí se alinea con la declaración. A la inversa, para colocar una línea destacada en medio del texto corriente queriendo también el espacio de alrededor, el entorno center es la forma más breve de decirlo.

Las declaraciones tienen otra propiedad con la que es fácil tropezar: una declaración no abre un párrafo nuevo. La alineación se fija en el instante en que el párrafo se cierra —al leerse \par (una línea en blanco)— y lo que esté vigente entonces se aplica al párrafo entero. De ahí el comportamiento contraintuitivo de la línea siguiente.

latex
ww {\centering xx \\ yy} zz
% result: the line "ww xx" comes out centred, "yy zz" does not

Al componerlo, ww xx sale centrado mientras que yy zz empieza en el margen izquierdo. Ocurren dos cosas. Primero, \centering redefine calladamente \\ como \@centercr, que no es un salto de línea sino un \par, es decir, el final de un párrafo. Así, xx cierra su párrafo mientras \centering sigue vigente, y ese párrafo queda centrado. yy abre después un párrafo nuevo, pero la llave de cierre restaura \rightskip y compañía antes de que ese párrafo termine: sale justificado. De ahí la única regla de las declaraciones: el final del párrafo que se quiere alinear —una línea en blanco, o el \end de un entorno— tiene que caer dentro del grupo.

Por qué \raggedright deja de partir palabras y qué hace ragged2e

La causa cabe en una línea de código. \raggedright fija \rightskip —el pegamento que rellena el final de la línea— en 0pt plus 1fil, es decir, en un espacio infinitamente estirable. Con algo infinitamente estirable al final de cada línea, la badness de cualquier línea es cero. Desde el punto de vista de TeX, partir una palabra y poner un guion solo puede entonces aumentar los deméritos sin aportar nada. Así que deja de partir del todo y el borde derecho queda muy irregular. La misma frase compuesta a 4cm: con \raggedright no aparece ni un guion, salvo donde una palabra sola no cabe en una línea, y las longitudes de línea varían muchísimo.

El paquete ragged2e corrige justamente eso. Sustituye el estiramiento infinito por uno finito, 0pt plus 2em, de modo que una línea demasiado corta vuelve a tener badness real y TeX vuelve a sopesar la partición de palabras. Aporta los comandos con inicial mayúscula \RaggedRight, \RaggedLeft y \Centering, los entornos FlushLeft, FlushRight y Center, y además \justifying y el entorno justify para volver al texto justificado. Para componer todo un documento alineado a la izquierda sin perder el guionado se carga \usepackage[document]{ragged2e}: ejecuta \RaggedRight en \begin{document} y extiende el mismo ajuste a los \parbox y a las columnas p de tabular. El paquete es de Martin Schröder y hoy lo mantiene Marei Peischl.

latex
\usepackage[document]{ragged2e}   % whole document flush left, hyphenation kept

% or locally, only where it is needed:
\begin{FlushLeft}
  A paragraph set flush left with hyphenation still available,
  so the right edge stays gently ragged instead of jagged.
\end{FlushLeft}

\justifying                        % back to justified text

¿Cuándo es entonces la bandera la elección acertada? Lo decide la longitud de línea. En composiciones a varias columnas, en notas al margen y en las columnas p estrechas de un tabular, las líneas se acortan y forzar la justificación estira mucho los espacios entre palabras. Esos espacios dilatados se alinean de una línea a otra y abren canales pálidos en la página —los tipógrafos hablan de calles o ríos— que estorban la lectura en vez de facilitarla. Cuanto más corta es la línea, mayor el riesgo: una columna estrecha se lee de verdad mejor alineada a la izquierda. Un arreglo habitual en un artículo a dos columnas es dejar el cuerpo justificado y reservar \RaggedRight para leyendas y notas al pie. En una sola columna con una medida cómoda, lo prudente es no tocar la justificación.

Corregir un aviso Overfull \hbox: \sloppy y \emergencystretch

Una línea del registro como Overfull \hbox (84.8932pt too wide) in paragraph at lines 10--10 informa de que no se encontró ningún juego de cortes que mantuviera el párrafo dentro de la tolerancia; TeX se rinde y deja que una línea sobresalga por el margen. El culpable habitual es algo largo e indivisible: una URL, un identificador compuesto, una palabra larga dentro de \texttt o, sencillamente, una columna estrecha. Antes que la alineación, hay que sospechar de esa palabra.

Los remedios tienen un orden. Primero, arreglar esa palabra: indicar sus puntos de partición con \hyphenation{...}, insertar un \-, o entregar una URL a \url de url o de hyperref. Esa es la corrección de fondo. Si el aviso persiste, entra \sloppy, que afloja \tolerance a 9999, \emergencystretch a 3em y \hfuzz a 0.5pt: el trato consiste en aceptar espacios entre palabras más sueltos a cambio de que nada se desborde. Aplicado a todo el documento afloja el aspecto general del texto, así que es más suave envolver solo el párrafo problemático en el entorno sloppypar, o fijar únicamente \emergencystretch=3em. \fussy restaura los valores estrictos (\tolerance 200, \emergencystretch 0). Y si el aviso se repite en una columna estrecha, es también la señal de pasarla a bandera.

latex
% 1. tell LaTeX where the offending word may be split
\hyphenation{Bib-lio-the-ken-ver-bund}

% 2. relax the line breaker for one paragraph only
\begin{sloppypar}
  A paragraph containing a very long unbreakable token.
\end{sloppypar}

% 3. or globally, without going all the way to \sloppy
\emergencystretch=3em

Por qué \\ no sirve para terminar un párrafo

\\ solo corta una línea; no termina un párrafo. Lo termina una línea en blanco, es decir \par. La distinción importa aquí porque, como se ha visto, la alineación se decide en el instante en que el párrafo se cierra. Si se separan dos bloques de texto con \\, el segundo no se considera un párrafo nuevo: ni sangría, ni \parskip, solo un corte en medio de un mismo párrafo. Peor aún: un \\ al final del párrafo seguido de una línea en blanco llena el registro de Underfull \hbox (badness 10000) in paragraph at lines 3--4, porque se ha creado una línea vacía de más y se ha estirado hasta el ancho completo.

¿Dónde encaja entonces \\? Allí donde se quiere exactamente un salto de línea. Separar líneas dentro de center o flushright, cerrar una fila de tabular, dividir versos en verse, plegar un \caption largo: son fronteras de línea, no de párrafo. De paso, un \\ tras la última línea de un bloque center no cuesta nada —ni espacio de más ni aviso—, porque \@centercr lo cancela con \addvspace{-\parskip}. Línea en blanco para los párrafos y \\ para las líneas: mantener esa frontera elimina buena parte de los fallos de alineación que de otro modo parecen inexplicables.

Qué alineación para cada caso

El punto de partida no es el gusto sino qué es el material. Los párrafos de texto corrido siguen justificados; los objetos breves —un título, una leyenda, una línea de firma, una celda de tabla— se alinean localmente. Y la elección entre declaración y entorno se reduce a una sola pregunta: ¿se quiere el espacio vertical de alrededor o no? Tomada en ese orden, la decisión rara vez se plantea dos veces.

  • En figuras, celdas de tabla, \parbox y minipage, se alinea con una declaración como \centering; un entorno apilaría su \topsep sobre un espacio que ya existe.
  • Para una línea destacada dentro del texto corrido, el entorno center es la opción natural: el espacio de alrededor forma parte de lo que se busca.
  • Para texto occidental alineado a la izquierda o a la derecha, conviene \RaggedRight y \RaggedLeft de ragged2e antes que los comandos estándar, para conservar el guionado.
  • En una columna estrecha (composición a varias columnas, notas al margen, columnas p de tabular) no hay que aferrarse a la justificación: cuanto más corta la línea, más gana la bandera.
  • Con una declaración, el final del párrafo tiene que quedar dentro del grupo. Sin una línea en blanco ni un \end dentro, la alineación o no surte efecto o se desborda sobre texto que no se pretendía tocar.
  • Línea en blanco para terminar un párrafo y \\ para terminar una línea. Confundirlas trae a la vez Underfull \hbox y la desaparición de las sangrías.