Ajustar saltos de línea

La primera línea de hyphen.tex, incluido en TeX Live 2024, es un grito: The Plain TeX hyphenation tables [NOT TO BE CHANGED IN ANY WAY!]. El archivo guarda los 4447 patrones que LaTeX consulta cada vez que decide dónde cortar una línea, y al final lleva una lista de excepciones escrita a mano con apenas catorce palabras. Dos de ellas —present y project— no tienen ningún punto de división, porque cada una es una palabra distinta según cómo se pronuncie y TeX no puede saber a cuál se refiere. Ajustar los saltos de línea consiste, en el fondo, en repetir ese juicio en el propio manuscrito. Esta página cubre \\, \newline, \linebreak[n], \nolinebreak[n], el guión discrecional \-, \hyphenation{...}, el paquete hyphenat y los patrones por idioma de babel, con cifras medidas y no repetidas de oídas.

Primero, una frontera. Empezar un párrafo nuevo (con una línea en blanco o \par) es una cosa; mover dónde se cortan las líneas dentro de un párrafo es otra. Lo primero trae consigo la sangría y el espacio entre párrafos; lo segundo solo desplaza el final de las líneas dentro de un mismo párrafo. Por encima de ambas hay una tercera capa —el diseño del ritmo de la página, el mundo de \widowpenalty y \raggedbottom—, que corresponde a la página sobre saltos de página. Allí está también \looseness, la petición de componer un párrafo una línea más corto o más largo, con su medición. Esta página trata exclusivamente la capa de las líneas.

\\ frente a \newline: la misma macro, otra puerta

\newline está definido como \@normalcr\relax, y \\ es esa misma macro sin el \relax (latex.ltx). Ese único elemento es toda la diferencia. \\ sigue adelante y busca un * o un [longitud] que le sigan; a \newline se lo impide el \relax y ni siquiera mira. Componga Alpha\newline[2ex] Beta y la página imprimirá literalmente [2ex]. En cambio \\[2ex] añade 2ex de espacio vertical tras la línea, y \\* prohíbe un salto de página en ese punto. En la práctica: \\ cuando hagan falta las opciones, \newline cuando convenga que la intención se lea en el fuente.

Lo que ambos comparten es que terminan la línea sin estirarla. El cuerpo es \unskip … \nobreak \hfil \break: se coloca a la derecha un \hfil de estiramiento infinito y solo entonces se corta. Ese \hfil se traga toda la holgura, de modo que la línea se detiene en su longitud natural y queda corta. Por eso encajan en direcciones y versos, donde cada línea debe acabar donde uno quiere. Hay un efecto secundario. Un \\ al final mismo de un párrafo crea una última línea vacía y produce Underfull \hbox (badness 10000) in paragraph at lines 6--7. Un párrafo no necesita un \\ final, y la línea que sigue a un título tampoco. Usado donde no hay línea alguna que terminar (al principio de un párrafo, por ejemplo), lo que sale es ! LaTeX Error: There's no line here to end.

latex
% \\ and \newline end the line short; \linebreak justifies it to the margin.
First road is steep\\
second road is gentle.

% \\ takes an optional length and a star; \newline takes neither.
Alpha\\[2ex] Beta        % 2ex of vertical space after the line
Alpha\\*    Gamma        % no page break allowed here
Alpha\newline[2ex] Delta % prints a literal [2ex] on the page

% A trailing \\ at the end of a paragraph produces
%   Underfull \hbox (badness 10000) in paragraph at lines 6--7
This paragraph does not need one.

Dentro de una tabla los dos papeles se separan con nitidez. En una celda que genera párrafo, como una columna p{...} de tabular, \newline corta solo dentro de esa celda mientras que \\ termina la fila entera. ¿Una dirección en dos líneas dentro de una celda? Eso es \newline. Medido: Line one\newline Line two en una celda p{3cm} apila dos líneas dentro de la misma fila, y la celda de al lado no se mueve. En el entorno array, \\ es igualmente el separador de filas. Use \newline en una columna que no genera párrafo, como l o c, y no habrá línea que terminar: sale el error de antes.

Qué número hay detrás de la n de \linebreak[n] y \nolinebreak[n]

n va de 0 a 4 y se traduce en las penalizaciones 0, 51, 151, 301 y 10000. \@getpen, en latex.ltx, devuelve 0 / \@lowpenalty / \@medpenalty / \@highpenalty / \@M, y en las clases estándar esos tres valen 51, 151 y 301 según las líneas 118–120 de article.cls. \linebreak[n] inserta ese valor en negativo —cortar aquí es una recompensa— y \nolinebreak[n] lo inserta en positivo —cortar aquí cuesta—. Si se omite el argumento, ambos toman 4, es decir ∓10000, el infinito de TeX. Con las cifras a la vista la elección se resuelve sola: el 51 de [1] es un susurro que la badness del texto corriente vence sin esfuerzo, el 301 de [3] es el primero que replica, y solo [4] es una orden.

Argumentolinebreak insertanolinebreak insertaFuerza real
[0]00solo un punto de corte legal, sin coste
[1]-5151un susurro; la badness del texto lo vence
[2]-151151el peso aproximado del \widowpenalty por defecto
[3]-301301el primero que replica
[4]-1000010000el valor por defecto; infinito, o sea una orden

\linebreak y \\ producen el mismo corte pero resultados opuestos. \linebreak solo deja caer una penalización, así que la línea se justifica como siempre y se estira hasta el margen derecho: de ahí que el espacio entre palabras tienda a abrirse. \\ se traga la holgura con ese \hfil y se queda corta. La regla nemotécnica: \\ para cortar corto, \linebreak para justificar al margen. En detalle, \@no@lnbk quita el espacio anterior con \unskip, inserta la penalización y luego repone un espacio del mismo ancho, de modo que word\linebreak word no acaba con doble espacio.

Prohibir el corte aquí: la ligadura ~ y lo que cuesta \mbox

Si solo hace falta proteger un espacio, la tilde ~ es la primera opción. Tiene el ancho de un espacio normal entre palabras; la única diferencia es que allí no puede cortarse la línea. Úsela allí donde una palabra no debe separarse de una cifra o un símbolo: Fig.~3, Dr.~Smith, Chapter~12, equation~\ref{eq:1}. Lo importante es que ~ no impide que las palabras vecinas se dividan con guión. Equivale a \nobreak más un espacio —una penalización infinita (\nobreak es \penalty10000) en ese único punto—, de modo que las palabras siguen pudiendo partirse. Para una fuerza graduada existe \nolinebreak[n]; para una prohibición tajante, el \nobreak de bajo nivel.

\mbox{...} es otra cosa. Empaqueta su contenido en una sola caja, de modo que el material ni se corta entre líneas ni se divide con guión. Va bien para una locución corta que no debe partirse, como T-34, pero tiene precio. Medido: en una minipage de 4,2 cm, dichlorodiphenyltrichloroethane cabe por sí solo; envuelto en \mbox{...} informa Overfull \hbox (18.8814pt too wide) y sobresale 18,88 pt del margen derecho. Congelar URL largas o nombres químicos dentro de \mbox es un remedio peor que la enfermedad. La entrada sin guiones de \hyphenation{...} y el \nohyphens{...} de hyphenat, ambos más abajo, apagan la división sin construir una caja.

Añadir un punto de división con \-: no «también aquí» sino «solo aquí»

Basta con insertar un solo \- en una palabra para que LaTeX la divida únicamente donde usted marcó, jamás en los puntos que él mismo habría encontrado. Todos los candidatos derivados de los patrones desaparecen. \showhyphens lo deja claro: sin tocar, supercalifragilistic se parte en cinco sitios, su-per-cal-ifrag-ilis-tic; escriba super\-califragilistic y queda solo super-califragilistic. Del mismo modo, hyphenation pasa de hy-phen-ation a hyphen-ation en cuanto escribe hyphen\-ation. Es decir, \- sustituye la lista de candidatos en lugar de ampliarla, y hay que deletrear cada punto de corte deseado. Además, \- no fuerza la división: solo dice «si se divide, ha de ser en uno de estos sitios».

latex
% Ask TeX where it would break, and read the answer in the .log:
%   [] \T1/cmr/m/n/10 su-per-cal-ifrag-ilis-tic
\showhyphens{supercalifragilistic}
%   [] \T1/cmr/m/n/10 super-califragilistic   <- one \- killed the other four
\showhyphens{super\-califragilistic}

% So spell out every break point you actually want:
super\-cali\-fragi\-listic

Por qué la segunda mitad de long-standing no se divide: hyphenat y \hyp

Porque la misma regla se aplica al guión corriente que usted mismo escribió. Compruébelo con \showhyphens: longstanding se parte en tres, long-stand-ing; pero escriba long-standing y queda solo long-standing —sobrevive únicamente el guión que tecleó, y stand-ing desaparece—. Todos los compuestos se comportan igual: well-known, X-ray, state-of-the-art. Esta regla explica por qué la composición se complica de golpe cuando un compuesto largo cae al final de la línea. La solución es \hyp, del paquete hyphenat. Escriba long\hyp standing y la medición vuelve a dar long-stand-ing: el guión se imprime igual que antes, pero los candidatos de los patrones resucitan.

hyphenat trae además un sustituto de \mbox. \nohyphens{...} es una definición de una sola línea que se limita a conmutar \language, dentro del grupo, a un idioma sin patrones. Medido, \nohyphens{supercalifragilistic} da cero candidatos. Como no construye ninguna caja, las líneas pueden seguir cortándose antes y después de la palabra: nada de un saliente de 18 pt como con \mbox. Con la misma idea, \bshyp, \fshyp, \dothyp y \colonhyp convierten la \, la /, el . y los : de URL y rutas en caracteres divisibles, y la opción de paquete [none] detiene la división en todo el documento con solo dos asignaciones: \hyphenpenalty=10000\exhyphenpenalty=10000.

latex
\usepackage{hyphenat}

% A plain "-" kills the rest of the word:  long-standing
% \hyp prints the same hyphen and keeps the patterns: long-stand-ing
long\hyp standing, well\hyp known, state\hyp of\hyp the\hyp art

% No hyphens in this word, but the line may still break around it.
% Unlike \mbox this cannot overflow the margin.
\nohyphens{supercalifragilistic}

% Breakable punctuation for URLs and paths:
https:\fshyp\fshyp example\dothyp com\fshyp very\fshyp long\fshyp path

Cuando \hyphenation{...} no hace nada: acentos, flexiones, mayúsculas

Si la misma palabra reaparece una y otra vez, registre la excepción una sola vez en el preámbulo en lugar de ensuciar el cuerpo. La sintaxis es exactamente la que usó Knuth al final de hyphen.tex: enumerar las palabras con sus puntos de corte marcados por guiones dentro de \hyphenation{...}. El mecanismo tiene un uso que la sintaxis no anuncia: registre una palabra sin ningún guión y no volverá a dividirse nunca. Medido: tras \hyphenation{fortran}, \showhyphens{fortran} da cero candidatos. Por eso mismo present y project figuran en la lista de excepciones de Knuth sin un solo punto de corte. A diferencia de \mbox, esto no construye caja alguna, así que nada puede desbordar el margen.

Tres motivos de fallo, todos medidos. Primero, los acentos. Con OT1 —la codificación de fuente por defecto—, \hyphenation{r\'e-sum\'e} se detiene con ! Improper \hyphenation will be flushed., porque en OT1 un carácter acentuado se compone con \accent y no es una letra. Añada \usepackage[T1]{fontenc} y pasa a ser un único glifo: la misma línea pasa sin rechistar. Segundo, la coincidencia exacta. Registre \hyphenation{hyphena-tion} y hyphenation se divide como hyphena-tion, pero el plural hyphenations no encuentra la excepción y vuelve a los patrones como hy-phen-ations. Las formas flexionadas necesitan su propia entrada. Tercero, no distingue mayúsculas de minúsculas. TeX pasa a minúscula mediante \lccode antes de comparar, así que la única entrada For-tran hizo que FORTRAN, Fortran y fortran se dividieran como FOR-TRAN, For-tran y for-tran.

latex
\usepackage[T1]{fontenc}   % without this, an accent in \hyphenation errors:
                           % ! Improper \hyphenation will be flushed.

\hyphenation{% one entry per inflected form; case does not matter
  hyphena-tion  hyphena-tions
  r\'e-sum\'e
  fortran                 % no hyphens = never break this word
}

Los patrones por idioma de babel: Wissenschaft se divide de dos maneras

Los patrones de división son propios de cada idioma, y cambiar \language hace que la misma palabra se corte en otro sitio. La medición lo dice todo. Cargue \usepackage[english,ngerman]{babel} y \language pasa a 36 (ngerman); \showhyphens{Wissenschaft Wahrscheinlichkeit} da entonces el correcto Wis-sen-schaft Wahr-schein-lich-keit. Cambie a \selectlanguage{english} (\language 0) y esas mismas palabras salen como Wis-senschaft Wahrschein-lichkeit, incorrecto en alemán. Y al revés: componga inglés bajo los patrones alemanes y typesetting se convierte en ty-pe-set-ting. Un artículo en alemán escrito sin babel suele verse sutilmente mal justo por esto.

De ahí se sigue una consecuencia directa: la lista de excepciones de \hyphenation{...} también se guarda por \language, de modo que solo se aplica al idioma que estuviera vigente al declararla. Medido: tras \usepackage[english,ngerman]{babel}, escribir \hyphenation{Wiss-en-schaft} en el preámbulo hace que la palabra se divida como Wiss-en-schaft en el texto en ngerman; pero justo después de \selectlanguage{english} la excepción es invisible y los patrones ingleses devuelven Wis-senschaft. En un documento multilingüe la regla es tajante: declare las excepciones después de seleccionar el idioma al que pertenecen. El japonés no tiene división silábica en este sentido, así que \- y \hyphenation son herramientas para las partes en lengua occidental.

latex
\usepackage[T1]{fontenc}
\usepackage[english,ngerman]{babel}

% Exceptions belong to the language that is current when they are declared.
% Select the language first, then declare.
\selectlanguage{ngerman}
\hyphenation{Wiss-en-schaft}
\selectlanguage{english}
\hyphenation{hyphena-tion hyphena-tions}

% Check the result rather than guessing:
%   ngerman -> Wis-sen-schaft   english -> Wis-senschaft
\showhyphens{Wissenschaft}
ComandoFunción¿Estira la línea?
\\ , \newlineFuerza un salto de línea (no de párrafo); solo \\ admite [longitud] y *No: \hfil absorbe la holgura y la línea queda corta
\linebreak[n]Inserta la penalización −(0/51/151/301/10000); por defecto n=4Sí: la línea se justifica hasta el margen derecho
\nolinebreak[n]Inserta la penalización +(0/51/151/301/10000); n=4 lo prohíbe del todo
~Espacio entre palabras irrompible; sigue permitiendo la división
\mbox{...}Una sola caja; ni corte ni guión: causa habitual de cajas desbordadas
\-Guión discrecional; la palabra solo se divide donde se marcó
\hyphyphenat; imprime el guión y deja divisible el resto de la palabra
\nohyphens{...}hyphenat; solo suprime los guiones — sin caja, no puede desbordar
\hyphenation{...}Lista de excepciones del preámbulo; coincidencia exacta, sin distinguir mayúsculas, por \language
\showhyphens{...}Diagnóstico: escribe en el .log los puntos de corte actuales de la palabra

El orden para corregir avisos de salto de línea: forzar, lo último

La peor corrección posible es plantar un \\ allí donde apareció el aviso. TeX optimiza el salto de línea sobre el párrafo entero, así que fijar una línea redistribuye el resto y rompe otra. El orden es: reescribir el texto, luego añadir oportunidades de división, luego prohibir cortes localmente con ~ o \nolinebreak, y solo entonces relajar la tolerancia del párrafo. Ese último escalón —\tolerance, \emergencystretch, \sloppy (con \fussy para volver al valor por defecto) y cómo leer un Overfull \hbox— corresponde a la página sobre cajas desbordadas, donde \sloppy está medido como nada más que cuatro asignaciones. Dejar que microtype estire mínimamente los glifos también pertenece allí.

  • Localice primero las palabras largas, las URL y los nombres químicos. Páselos por \showhyphens{...} para ver si tienen algún punto de corte.
  • Dé a los términos técnicos una entrada en \hyphenation{...}. Una por forma flexionada y, en documentos multilingües, escrita tras \selectlanguage.
  • Reserve \- para la palabra que quede. Recuerde que uno solo borra todos los demás candidatos de esa palabra.
  • Ate nombres, números y unidades con ~. Deje \mbox para locuciones cortas que de verdad no deben partirse.
  • Cargue siempre babel en un documento multilingüe. Sin cambiar de idioma, uno de ellos se dividirá siempre donde no debe.