# Configuración: viudas, huérfanas y equilibrado

> Las reglas que mantienen juntas las líneas y los bloques en un salto de columna, y las palancas que hacen que todas las columnas terminen a la misma altura

- Versión HTML: https://postext.dev/es/docs/configuration-page-flow
- Última actualización: 2026-10-16
- Tiempo de lectura: 24 min
- Otros idiomas: [en](https://postext.dev/en/docs/configuration-page-flow.md), [ca](https://postext.dev/ca/docs/configuration-page-flow.md), [de](https://postext.dev/de/docs/configuration-page-flow.md), [fr](https://postext.dev/fr/docs/configuration-page-flow.md), [it](https://postext.dev/it/docs/configuration-page-flow.md), [pt](https://postext.dev/pt/docs/configuration-page-flow.md), [zh](https://postext.dev/zh/docs/configuration-page-flow.md), [ja](https://postext.dev/ja/docs/configuration-page-flow.md), [ar](https://postext.dev/ar/docs/configuration-page-flow.md)

## En pocas palabras

Esta página explica cómo decide Postext dónde termina una columna o una página. Una línea de un párrafo no debe quedarse sola arriba o abajo de una columna, y un título no debe quedarse sin su texto. Estas reglas pueden dejar una columna más corta que las demás. Entonces Postext hace pequeños cambios, en un orden fijo, para que todas las columnas terminen a la misma altura. La página enumera cada regla y cada cambio, y cómo ver cuál se ha usado.

## Huérfanas, viudas, *runts* y reglas de cohesión

Consulta [Separación silábica y justificación](https://postext.dev/es/docs/justification.md) para entender la mecánica de deméritos que hay detrás. Esta sección es la referencia de las claves de `bodyText` que gobiernan esas penalizaciones.

Más allá de la separación silábica y los límites de espaciado, la configuración del cuerpo expone las reglas *blandas* que evitan las rupturas de párrafo estructuralmente incómodas. Todas ellas se inyectan como deméritos en el algoritmo de ruptura de líneas Knuth-Plass — sesgan la maquetación hacia rupturas limpias sin imponer nunca una regla dura. Pon a `0` cualquier `*Penalty` para desactivar esa penalización.

| Propiedad | Tipo | Por defecto | Descripción |
| --- | --- | --- | --- |
| `avoidOrphans` | `boolean` | `true` | Desaconsejar que un párrafo termine con menos de `orphanMinLines` líneas al principio de la siguiente columna. En una retícula de caracteres (`cjk.grid`) de la región `japan` el valor por defecto es `false`. |
| `orphanMinLines` | `number` | `2` | Líneas mínimas requeridas al principio de la siguiente columna cuando un párrafo se parte. Solo activo cuando `avoidOrphans` es `true`. |
| `orphanPenalty` | `number` | `1000` | Demérito añadido cuando se incumple la restricción de huérfanas. Valores más altos sesgan más fuertemente al algoritmo; `0` desactiva la penalización. |
| `avoidOrphansInLists` | `boolean` | `true` | Cuando es `true`, los elementos de lista también reciben protección contra huérfanas (no solo los párrafos). Solo efectivo si `avoidOrphans` es `true`. |
| `avoidWidows` | `boolean` | `true` | Desaconsejar que un párrafo empiece con menos de `widowMinLines` líneas al final de la columna actual. En una retícula de caracteres (`cjk.grid`) el valor por defecto es `false`: la página contiene las líneas que su retícula cuenta. |
| `widowMinLines` | `number` | `2` | Líneas mínimas requeridas al final de la columna actual cuando un párrafo se parte. Solo activo cuando `avoidWidows` es `true`. |
| `widowPenalty` | `number` | `1000` | Demérito añadido cuando se incumple la restricción de viudas. `0` desactiva la penalización. |
| `avoidWidowsInLists` | `boolean` | `true` | Cuando es `true`, los elementos de lista también reciben protección contra viudas. Solo efectivo si `avoidWidows` es `true`. |
| `shortListSplit` | `'allow' \| 'warn' \| 'avoid'` | `'allow'` | Una lista corta partida entre dos columnas o páginas: una lista de hasta `shortListMaxItems` ítems en el texto corrido, como una de tres ítems compuesta 1 + 2. `avoidOrphansInLists` y `avoidWidowsInLists` mantienen juntas las líneas de un ítem; esta regla mantiene juntos los ítems de una lista. `'allow'` parte la lista donde acaba la columna, como cualquier otra. `'warn'` la compone igual e informa de cada lista partida (un aviso `shortListSplit`, véase [Avisos del documento](https://postext.dev/es/docs/configuration-programmatic-usage.md#avisos-del-documento)). `'avoid'` compone la lista entera: si no cabe bajo lo que ya tiene la columna, abre la siguiente, y los encabezados que tenga justo encima y la línea de dos puntos que la introduce (`keepColonWithList`) van con ella. Una lista más alta que una columna vacía se parte como cualquier otra, y se avisa. Las listas de dentro de un `:::callout` siguen las reglas de corte de la caja, y las entradas de `:::toc` y de `:::index` no son listas. Desde postext 1.28. |
| `shortListMaxItems` | `number` | `3` | Cuántos ítems puede tener como máximo una lista para contar como corta en `shortListSplit`, incluidos los de sus listas anidadas. Un número entero, 1 como mínimo. Desde postext 1.28. |
| `avoidRunts` | `boolean` | `true` | Desaconsejar que los párrafos terminen con una línea corta: una última línea muy breve, p. ej. una única palabra corta aislada. También en el texto en bandera, con `optimalRagged`. Un párrafo chino, japonés o coreano no termina en una línea de un solo carácter, solo o con los signos que lo cierran (孤字): la línea anterior le cede su último carácter si aún puede justificarse dentro del tope de espaciado. Una línea alineada a la izquierda, a la derecha o centrada también lo cede y queda un carácter corta; con `cjk.grid.fullLines` (papel de manuscrito) conserva todas sus casillas, y el párrafo puede acabar en un solo carácter. |
| `runtMinCharacters` | `number` | `20` | Umbral para la última línea de un párrafo, contado en espacios entre palabras, no en letras: la línea es corta cuando es más estrecha que `runtMinCharacters × anchoDeEspacioNormal` píxeles. En la mayoría de los tipos de texto un espacio mide entre un cuarto y un tercio de em, más o menos media letra minúscula, así que el valor por defecto, 20, alcanza a las últimas líneas de menos de 4 a 7 em: unas 8 a 12 letras. Para alcanzar las de menos de unas N letras, ponlo en torno a 2 × N. |
| `runtPenalty` | `number` | `1000` | Penalización equivalente a *badness* (se inyecta en la fórmula cuadrática de Knuth–Plass, en la misma escala que el *badness* de línea, que satura en 10000). `0` desactiva la penalización. |
| `gradedRuntPenalty` | `boolean` | `false` | Gradúa la penalización por línea corta según lo corta que se queda la última línea: una última línea de ancho *w* bajo el umbral *t* cuesta `runtPenalty × (1 − w / t)` en lugar de la penalización entera. Así, un final de dos palabras cuesta menos que uno de una, y el algoritmo baja una palabra cuando una línea de arriba puede cederla («…sallies of» / «our minds.» en lugar de «…sallies of our» / «minds.»). Desactivado por defecto: todas las líneas cortas cuestan lo mismo, y el algoritmo conserva las líneas más apretadas de arriba. |
| `avoidRuntsInLists` | `boolean` | `true` | Cuando es `true`, los elementos de lista también reciben la penalización por línea corta. Solo efectivo si `avoidRunts` es `true`. |
| `tightenRunts` | `boolean` | `true` | Cuando la penalización no ha podido evitar una línea corta, compone el párrafo con una línea menos: los espacios se aprietan (nunca por debajo de `minWordSpacing`) y, si con eso no basta, entra además algo de tracking negativo. La composición más corta se descarta, y la línea corta se queda, si estira una línea justificada más allá de `maxWordSpacing` o, si el párrafo ya tiene una línea justificada más abierta, más que esa línea, o si compone en bandera (más de 3 veces el espacio normal) más líneas que el párrafo. Los espacios del texto en bandera no cambian de ancho, así que ahí solo interviene el tracking. Requiere `optimalLineBreaking` y `avoidRunts` (y `optimalRagged` en el texto en bandera). |
| `maxRuntTracking` | `number` | `10` | Tracking máximo que puede tomar ese ajuste, en milésimas de eme (la unidad de InDesign: 10 = 0,01 em por carácter), aplicado como apriete. Con `0` el ajuste se limita al espaciado entre palabras. |
| `slackWeight` | `number` | `10` | Peso aplicado al coste cuadrático del "espacio de columna no usado". Valores más altos hacen que la maquetación prefiera llenar las columnas al máximo; `0` desactiva esta presión por completo. |
| `keepColonWithList` | `boolean` | `true` | Cuando un párrafo termina con dos puntos que introducen directamente una lista, mantiene la línea de los dos puntos unida a la lista: si colocar el párrafo no deja sitio para que el primer elemento de la lista empiece en la misma columna/página, la última línea (o el párrafo entero, si tiene una sola línea) se mueve a la siguiente columna junto con la lista. Cuánto sitio basta lo dice `colonListRoom`. Cuando esta regla tenga que empujar el párrafo completo y justo antes haya una secuencia de títulos en la columna, esos títulos también se arrastran hacia adelante para que `headings.keepWithNext` siga cumpliéndose. |
| `colonListRoom` | `'item' \| 'line'` | `'item'` | El sitio que pide `keepColonWithList` bajo la línea de los dos puntos. `'item'`: el que las reglas de huérfanas y viudas de las listas dejarían del primer elemento al pie de la columna, una línea si puede partirse ahí, todo él si lo mantienen entero (un elemento de dos líneas, por ejemplo). `'line'`: una línea, como hasta postext 1.4; un primer elemento que esas reglas mantienen entero pasa entonces solo a la columna siguiente y deja la línea de los dos puntos al pie. Una configuración guardada antes de `configVersion` 6, en un libro que introduce una lista con dos puntos, se lee con `'line'` (ver [Paquetes escritos por postext 1.4 o anterior](https://postext.dev/es/docs/configuration-bundles.md#paquetes-escritos-por-postext-14-o-anterior)). Cualquier otro valor se lee como `'item'`. |
| `hyphenateAcrossColumns` | `boolean \| 'withinPage'` | `true` | Permite que una columna o una página termine en una palabra partida (el *Hyphenate Across Column* de InDesign). Con `false`, el párrafo que cruza el salto de columna se vuelve a cortar para que su última línea en la columna termine en una palabra entera; los espacios entre palabras de las líneas de arriba absorben la diferencia, dentro de `maxWordSpacing` y `minWordSpacing`. Es una preferencia: donde ningún corte dentro de esos límites lo evita, el guion se queda. Lo intenta en todos los saltos de columna de un párrafo: en el primero y en los siguientes que caen donde termina una columna llena, con un nuevo corte; y en un salto posterior que cae en otro sitio (una viuda evitada, una banda cortada a nivel), con otro nuevo corte desde esa columna, que deja las líneas ya colocadas en las columnas anteriores con sus cortes y solo vuelve a cortar el resto. `'withinPage'` protege las líneas que cierran una página y ninguna otra: una palabra puede partirse entre dos columnas de una misma página, y la última línea de una página termina en una palabra entera siempre que los límites lo permiten. Cambia menos líneas que `false`, y eso pesa con tres columnas o más, donde dos de cada tres finales de columna quedan dentro de la página; con una sola columna los dos valores dan las mismas líneas. Una columna cierra su página cuando ninguna columna posterior de la página recibe texto: no lo recibe una columna lateral reservada a los flotantes, ni una columna que una tabla o una figura ha llenado. No afecta al cuerpo de los recuadros. Con `optimalRagged`, un párrafo en bandera se vuelve a cortar igual: sus espacios entre palabras no cambian de ancho, así que solo se mueven los finales de sus líneas. Cada nuevo corte mide el párrafo una vez más, así que un libro con muchos guiones al pie de columna tarda algo más en componerse. Necesita `optimalLineBreaking`, y `optimalRagged` en el texto en bandera. |
| `paragraphContainerSpacing` | `'collapse' \| 'add'` | `'collapse'` | El espacio bajo un contenedor `:::paragraphs` que se cierra con un párrafo, entre ese párrafo y el bloque siguiente (ver [El contenedor `:::paragraphs`](https://postext.dev/es/docs/configuration-styles.md#el-contenedor-paragraphs)). `'collapse'`: el mayor entre el `spaceBetween` y el `marginBottom` del estilo y la separación entre párrafos del texto que rodea al contenedor (una línea con `paragraphSpacing`; en un recuadro, la del recuadro), fundido con el espacio que el bloque siguiente deja sobre sí, como entre dos párrafos del texto corrido: un encabezado bajo una bibliografía queda a su propio `marginTop` de ella, no a ese margen más la separación de las entradas. `'add'`: como hasta postext 1.4, bajo la última línea se pone solo el espacio del estilo antes del ajuste a la rejilla, el espacio que el bloque siguiente deja sobre sí se suma debajo y la separación entre párrafos no cuenta, así que el párrafo que sigue al contenedor podía quedar más pegado a él que a cualquier otro. Una configuración guardada antes de `configVersion` 8 que declara algún estilo de párrafo, en un libro que tiene uno de estos contenedores, se lee con `'add'` (ver [Paquetes escritos por postext 1.4 o anterior](https://postext.dev/es/docs/configuration-bundles.md#paquetes-escritos-por-postext-14-o-anterior)). Un `marginBottom` negativo sube el bloque siguiente en los dos casos. Un estilo de párrafo puede fijar su propia regla para sus contenedores (`containerSpacing`, desde postext 1.28). |

**Sobre las líneas cortas.** Una línea corta (*runt*, en inglés) es la última línea de un párrafo cuando es demasiado corta para sentirse como una línea de texto propiamente dicha — típicamente una o dos palabras cortas varadas al final del párrafo. Como la comprobación se basa en el ancho en píxeles de la línea relativo al ancho del espacio normal, `runtMinCharacters` se adapta automáticamente al tamaño de fuente actual. Una palabra corta visualmente más ancha que `runtMinCharacters × anchoDeEspacio` es válida; una palabra más estrecha que eso (o verdaderamente sola) dispara la penalización. El umbral cuenta espacios entre palabras, que miden más o menos la mitad que una letra: el valor por defecto, 20, equivale a una última línea de unas 8 a 12 letras. Toda línea corta cuesta la penalización entera, así que entre dos finales por debajo del umbral el algoritmo conserva las líneas más apretadas de arriba; `gradedRuntPenalty` valora cada uno según lo que le falta y gana el final más largo. Para quien sienta curiosidad matemática: con el `runtPenalty` por defecto de 1000, evitar una línea corta domina sobre cualquier alternativa que exigiera un estiramiento del espacio entre palabras de hasta aproximadamente r≈2,15.

**Blandas, no duras.** Ninguna de estas reglas puede *impedir* una ruptura — el motor siempre produce una maquetación. Son deméritos: el algoritmo combina en una única optimización global la "badness" (desigualdad), el coste de la separación silábica, la suavidad de clase de encaje y estas penalizaciones estructurales, y elige el conjunto de rupturas con el coste total más bajo. Si necesitas una garantía más dura, sube la penalización; si un documento concreto se lee mejor con la penalización relajada, bájala.

## Equilibrado de columnas

Las editoriales esperan que cada columna empiece en la parte superior de la página y termine alineada con su parte inferior. Las reglas de ruptura (protección de huérfanas y viudas, títulos unidos a su texto, figuras indivisibles) dejan columnas cortas de forma natural — una o más líneas de rejilla base vacías al final. Con el equilibrado activado, el motor hace lo que haría un maquetista, aplicando sus palancas en orden de prioridad editorial:

1. **Una caja que cierra la columna** — un callout que termina una columna corta baja exactamente el espacio que queda bajo su pie, de modo que su borde inferior cae en la última casilla de rejilla de la página, a nivel con la última línea de la columna contigua. Ocupa ese espacio aunque sea menor que una línea, siempre que nada pase a otra columna. Por defecto actúa antes que cualquier otra palanca y se queda con todo el hueco, de modo que un recuadro que comenta el párrafo de encima puede acabar varias líneas por debajo de él; con `closingBox: 'last'` los encabezados, los finales de lista y las demás palancas de espacio toman antes las líneas enteras, y el recuadro solo lo que dejan, y con `closingBox: 'off'` no se mueve nunca.
2. **Imágenes con zona segura** — una imagen con zona segura (`Resource.safeArea`, véase [Formato del documento › Zona segura](https://postext.dev/es/docs/document-format-resources.md#zona-segura)) colocada en línea en la columna corta, o flotada en su cabeza o su pie y solo sobre ella, crece en líneas enteras de rejilla, recortada dentro de su zona segura, hasta llenar la columna o hasta que el recorte llega a la zona segura. Una imagen más alta no deja ningún hueco en la página, así que actúa antes de añadir ningún espacio; un flotante en la cabeza de una columna de una página o banda cuyas cabezas de columna quedan a nivel (véase más abajo) no crece. Se anota como `flexFigure`. No tiene ajuste propio: solo crece una imagen cuyo recurso marca una zona segura.
3. **Encabezados** — se añaden líneas completas de rejilla al margen superior de los encabezados de la columna corta. Cuando hacen falta varias líneas y la columna contiene varios encabezados, las líneas se reparten entre ellos, dejando siempre la mayor parte al encabezado más importante (un `h2` recibe más que un `h3`). Los encabezados situados al principio de una columna nunca reciben espacio adicional, de modo que las columnas siguen empezando en la parte superior — salvo un encabezado justo bajo una figura o tabla que encabeza su columna en una página que fluye hacia la siguiente: el espacio va sobre ese encabezado, bajo la figura. Un encabezado toma así como mucho `maxLinesBeforeLoose` líneas (dos por defecto) antes de probar las palancas siguientes, y las demás, hasta `maxLinesPerHeading`, solo cuando estas ya no pueden dar más.
4. **Finales de lista** — cuando los encabezados no pueden absorber todo el hueco, se añade una línea de rejilla donde termina una lista o enumeración (el aire tras una lista se lee con naturalidad), con un máximo por lista.
5. **Bajo fórmulas, cajas y figuras** — después va una línea de rejilla bajo una fórmula destacada o una caja tras la que sigue el texto (`stretchAfterDisplays`; se lee como margen del propio elemento), y bajo una figura o tabla que encabeza la columna (`stretchAfterFloats`, con el máximo de `maxLinesAfterFloat`).
6. **Párrafos corridos** — como último recurso, se recompone un párrafo de la columna con una línea más (el `\looseness=+1` de TeX), eligiendo el párrafo más largo para que el espaciado adicional se diluya de forma invisible. La solución corrida solo se acepta cuando todas sus líneas quedan **por debajo de `bodyText.maxWordSpacing`** — el color tipográfico nunca supera el límite que ya tengas configurado. Requiere `bodyText.optimalLineBreaking`.

En una retícula de caracteres (`cjk.grid`, véase [Composición china › La retícula de caracteres](https://postext.dev/es/docs/chinese-layout.md#la-retícula-de-caracteres)) cada carácter ocupa una casilla de un cuadratín de ancho y cada línea cae en el paso de líneas de la retícula, que es también la rejilla base. Allí el equilibrado está desactivado por defecto, como en el texto vertical: una página compuesta línea a línea sobre una retícula, a la manera de la GB/T 9704, que cuenta 22 líneas de 28 caracteres, deja corta la columna que termina corta. Una configuración que fija `enabled: true` recibe palancas que respetan la retícula: los encabezados, los finales de lista, las fórmulas en bloque y las figuras toman líneas enteras de la retícula, de modo que el texto de debajo se desplaza filas enteras, y `gridLines: 'off'` deja fuera esas palancas para una norma que no tiene ninguna fila vacía que ceder. Un párrafo chino o japonés gana una línea solo cuando ningún hueco entre dos de sus caracteres se abre más de `maxTracking`, y no recibe tracking en sus letras: una línea a la que le falta un carácter reparte un cuadratín entre sus huecos, muy por encima de los 0,01 em por defecto, así que en una retícula de casillas enteras la palanca de párrafos corridos casi nunca encuentra nada. La caja que cierra una columna y las imágenes con zona segura quedan fuera de la retícula por diseño y funcionan como en cualquier otra página.

La última columna de una página solo se equilibra cuando la página fluye de forma natural hacia la siguiente — la página final de un capítulo termina corta de forma legítima. Esa página, y una banda de cierre cortada a nivel por `trailing`, mantienen además las cabezas de sus columnas a la misma altura: no se añade ninguna línea bajo una figura o tabla que encabece una de sus columnas (la palanca tras flotantes), y un encabezado o una caja que abre una columna bajo esa figura se queda en su cabeza, diga lo que diga `stretchAfterFloats`, igual que el encabezado que va justo debajo de una apertura `span: 'page'`, en la columna de esa apertura, de modo que ninguna columna empieza más abajo que su vecina solo para igualar los pies.

| Propiedad | Tipo | Por defecto | Descripción |
| --- | --- | --- | --- |
| `enabled` | `boolean` | `true` | Si se equilibran los finales de columna. Desactivado por defecto en texto vertical (`layout.writingMode: 'vertical-rl'`) y en una retícula de caracteres (`cjk.grid.enabled`, desde postext 1.25); `true` lo activa también ahí. |
| `maxLinesPerHeading` | `number` | `4` | Número máximo de líneas de rejilla adicionales que pueden añadirse sobre un mismo encabezado. |
| `maxLinesBeforeLoose` | `number` | `2` | Líneas de rejilla que un encabezado puede tomar antes de probar las palancas siguientes: los finales de lista, las fórmulas y cajas, las figuras y los párrafos corridos. El encabezado solo recibe las demás, hasta `maxLinesPerHeading`, cuando esas ya no pueden dar más, de modo que una página con un solo encabezado no abre cuatro líneas sobre él mientras sus párrafos podrían correr una línea. Un valor igual o mayor que `maxLinesPerHeading` da primero todas sus líneas a los encabezados, como hasta postext 1.27; `0` prueba las demás palancas antes de añadir ninguna línea sobre un encabezado. Desde postext 1.28; los documentos guardados antes conservan el orden anterior (`pinLegacyLooseOrder`). |
| `stretchAfterLists` | `boolean` | `true` | Permite líneas de rejilla adicionales donde termina una lista, cuando los encabezados no pueden absorber todo el hueco. |
| `maxLinesAfterList` | `number` | `1` | Número máximo de líneas de rejilla adicionales tras el final de una misma lista. |
| `stretchAfterDisplays` | `boolean` | `true` | Permite una línea de rejilla adicional bajo una fórmula destacada, y bajo una caja, en la columna corta, tras la palanca de los finales de lista: el bloque que la sigue baja una línea. Con `false`, el espacio bajo fórmulas y cajas queda como lo fijan sus propios márgenes; el hueco pasa a las palancas siguientes y la columna termina corta si no lo cierran. Desde postext 1.28. |
| `stretchAfterFloats` | `boolean` | `true` | Permite líneas de rejilla adicionales bajo una figura o tabla que encabeza la columna corta (un flotante superior), tras la palanca de los finales de lista, de modo que el texto de debajo baja en lugar de acabar la columna corta. Nunca en una página que no fluye hacia la siguiente (la página final de un capítulo) ni en una banda de cierre cortada a nivel por `trailing`: ahí las cabezas de las columnas quedan a la misma altura y la última columna puede terminar una línea más corta. El primer bloque bajo la figura puede ser la continuación de un párrafo empezado en la página anterior: baja igualmente, la línea que las reglas de corte dejaron libre al pie de la columna (una línea que la regla de viudas dejó vacía, o un espacio entre párrafos sin sitio para texto detrás). Con `false`, el texto queda justo debajo de la figura. Bajo un flotante a varias columnas, las columnas bajan juntas o no bajan: véase `stretchAfterWideFloats`. |
| `maxLinesAfterFloat` | `number` | `1` | Número máximo de líneas de rejilla adicionales bajo un mismo flotante superior. |
| `stretchAfterWideFloats` | `'flush' \| 'always'` | `'flush'` | Bajo una figura o tabla que ocupa dos o más columnas de texto. Con `'flush'`, una columna solo baja bajo ella cuando todas las columnas de texto que quedan bajo el flotante toman las mismas líneas, de modo que sus cabezas siguen a la misma altura, o cuando las líneas dejan esa columna a ras; no se añade una línea que bajaría la cabeza de una columna y la dejaría corta igualmente, y el hueco pasa a los párrafos corridos. `'always'` estira esa columna como bajo cualquier flotante, como hasta postext 1.27. Cualquier otro valor se lee como `'flush'`. Desde postext 1.28; los documentos guardados antes conservan `'always'` (`pinLegacyWideFloatStretch`). |
| `looseParagraphs` | `boolean` | `true` | Último recurso: recompone párrafos de una columna corta con una línea más (una línea extra cada uno), sin superar `bodyText.maxWordSpacing`. |
| `maxLooseParagraphs` | `number` | `2` | Cuántos párrafos de una misma columna corta pueden ganar una línea, los más largos primero. |
| `trackParagraphs` | `boolean` | `true` | Cuando el espaciado entre palabras no basta para ganar la línea, el párrafo corrido puede tomar además el menor tracking positivo (interletrado) que lo consiga. |
| `maxTracking` | `number` | `10` | Límite de ese tracking, en milésimas de eme por carácter (10 = 0,01 em). |
| `trailing` | `boolean` | `true` | Nivela la banda de cierre de cada capítulo y del documento: cuando el flujo termina antes de llenar la página (en una apertura de capítulo, un `:::part`, una caja `placement: 'fixed'` que cierra el capítulo o el final del documento) con las columnas desiguales, se cortan a la misma altura — un tope de banda de `ceil(Σ usado / N / rejilla)` líneas, resuelto después de que las palancas anteriores hayan asentado las páginas previas —, de modo que una bibliografía corta termina a la misma altura en todas las columnas en lugar de llenar la primera y dejar la última a medias. El corte respeta las reglas de una banda sin cortar: cuando un bloque que no puede partirse en él (el final de un párrafo que los mínimos de huérfanas y viudas mantienen entero, una caja que no se parte) lo rebasaría — y perdería sus últimas líneas, porque los renderizadores recortan cada columna a su caja — o un encabezado cerraría una columna mientras su texto abre la siguiente (con `headings.keepWithNext`, el valor por defecto), el corte baja una línea, hasta tres veces, y si no basta se descarta. Un bloque que no puede empezar en las líneas que el corte deja bajo una figura que encabeza una columna (un párrafo necesita ahí su mínimo de huérfanas) pasa a la columna siguiente de la banda, como lo haría desde una columna sin cortar, y la figura queda sola en su columna. Las columnas cuyos pies difieren en una línea de la rejilla o menos se dejan como están: una banda de cierre cuya última columna termina una línea más corta es el final habitual, y cortarla solo movería una línea. El corte va a la banda en la que se midió, igual que el que pide una caja a ancho de página a mitad de página: hasta postext 1.4, cuando el primer texto de la página de cierre se había ofrecido antes a una banda sin sitio para él (una página que ocupa entera un flotante, la banda estrecha que deja al pie de la página anterior una caja a ancho de página), el corte se gastaba en esa banda y la página de cierre dejaba todas sus líneas en la primera columna. Las columnas de anchos distintos (una disposición de columna y media con texto en las dos) se cortan por superficie, pesando la altura de cada columna por su ancho, porque una línea de la columna estrecha lleva menos texto. Solo actúa cuando `enabled` es true. |
| `trailingStep` | `'lines' \| 'grid'` | `'lines'` | La unidad del corte a nivel que hace `trailing` (y del corte que hace `beforeSpan` tras una caja que pasa a la página siguiente). `'lines'`: una banda cuyo texto va con un interlineado propio (un índice, una lista de referencias, un contenedor en cuerpo pequeño) se corta, y se reintenta, por líneas enteras de ese interlineado: la altura que comparte la mayoría de las líneas de la banda, sin contar encabezados ni cajas. Sus columnas terminan entonces con una línea de diferencia como mucho, como las de una banda de texto base. Una banda de texto base, y una que mezcla dos interlineados a partes iguales, se corta en la rejilla base como antes. También una banda cuyas líneas comparten altura pero quedan separadas por una fracción de línea (referencias con un espacio entre entradas, grupos de índice con un margen puesto a mano): cuatro de cada cinco líneas de cada columna han de estar a un número entero de líneas unas de otras. `'grid'`: todo corte es un número entero de líneas de rejilla base, como hasta postext 1.27, donde un corte en la rejilla dejaba entrar una línea de más en una columna de una banda fuera de rejilla y un corte fallido bajaba más de una de sus líneas (columnas con hasta tres líneas de diferencia). Cualquier otro valor se lee como `'lines'`. Desde postext 1.28; los documentos guardados antes conservan `'grid'` (`pinLegacyTrailingStep`). |
| `beforeSpan` | `boolean` | `true` | Nivela la banda que deja atrás un bloque a ancho de página: cuando un aviso `span: 'page'` no cabe bajo las columnas actuales ni siquiera tras un corte nivelado, y tiene que pasar a la página siguiente o partirse (`calloutStyles[].keepTogether: false`), las columnas que interrumpe se cortan a la misma altura — el mismo tope de cierre que recibe una banda final — en lugar de que la primera llene la página y la última termine corta. La página queda como salto explícito para que las palancas anteriores no vuelvan a estirar su última columna hasta el pie; la caja, o la parte que cabe, queda entonces bajo las columnas niveladas. Solo actúa cuando `enabled` es true. |
| `closingBox` | `'first' \| 'last' \| 'off'` | `'first'` | Cuándo toma un recuadro que cierra una columna corta el espacio bajo su pie (la palanca 1, registrada como `trailingCallout`). `'first'`: antes que cualquier otra palanca, como hasta postext 1.4 — el recuadro se queda con todo el hueco, aunque sean varias líneas, y los encabezados de encima no reciben nada. `'last'`: después de las palancas de encabezados, finales de lista, fórmulas y flotantes, que toman antes las líneas enteras; el recuadro baja con el texto de encima y luego toma solo lo que dejaron, normalmente una fracción de línea, de modo que su pie sigue cayendo en la última casilla de la rejilla y queda cerca del texto que comenta. `'off'`: nunca; el recuadro conserva el espacio bajo su pie, aunque las demás palancas aún pueden bajarlo líneas enteras cuando añaden espacio por encima, y la fracción de línea que sobra se queda. En una página de cierre, donde el recuadro es la única palanca que alinea su pie con la columna contigua, `'off'` lo deja donde lo puso el flujo. Cualquier otro valor se lee como `'first'`. Un recuadro que cierra la única columna de texto de su banda (una página de una sola columna que acaba antes de tiempo y cuyo bloque siguiente abre la página siguiente) nunca se mueve: no hay columna al lado con la que alinearlo (desde postext 1.19). |
| `gridLines` | `'allow' \| 'off'` | `'allow'` | En una retícula de caracteres: si pueden actuar las palancas que añaden líneas enteras de la retícula (sobre un encabezado, donde termina una lista, bajo una fórmula en bloque o una caja, bajo una figura que encabeza la columna). Mantienen cada carácter en su casilla; `'off'` conviene a una norma que cuenta las líneas de la página, y deja corta la columna. Sin efecto fuera de la retícula. Cualquier otro valor se lee como `'allow'`. Desde postext 1.25. |

### Qué palanca actuó

La maquetación deja constancia de cada palanca que aplica, en el bloque sobre el que la aplica: `block.balancing` en el VDT que devuelve `buildDocument`. Una hoja de pruebas, un test o un informe pueden decir por qué una columna termina alineada — y qué columnas no pudo cerrar ninguna palanca. Los bloques que el equilibrado deja como estaban no llevan `balancing`, y un documento compuesto con `enabled: false` no lo lleva en ninguno.

En una retícula de caracteres el documento dice por qué una columna puede terminar corta: `doc.gridBalancing` es `{ off: true }` cuando el equilibrado está desactivado porque la página va sobre una retícula y la configuración no lo activa, y `{ gridLines: 'off' }` cuando actúa sin las palancas de líneas enteras; una columna que sigue corta lleva `column.gridRefused`, las palancas que la retícula le negó (`'looseParagraph'` cuando un párrafo solo podía ganar su línea sacando sus caracteres de sus casillas, y las palancas de líneas enteras con `gridLines: 'off'`). Ninguno de los dos aparece fuera de la retícula.

```ts
interface VDTBalancing {
  levers: BalanceLever[]; // normalmente una: un párrafo tras una lista puede tomar la línea de final de lista y además ganar una línea
  spaceAbove: number;     // px que las palancas de espaciado añadieron sobre el bloque (0 si solo actuó looseParagraph o flexFigure)
  bodyGrowth?: number;    // flexFigure: px que creció la imagen, recortada dentro de su zona segura
  extraLines?: number;    // looseParagraph: líneas que ganó el párrafo
  tracking?: number;      // looseParagraph: el tracking con que las ganó, en milésimas de eme (0 = solo con el espaciado entre palabras)
}
type BalanceLever = 'trailingCallout' | 'flexFigure' | 'heading' | 'listEnd' | 'afterDisplay' | 'afterFloat' | 'looseParagraph';
```

| Palanca | Se registra en | Qué hizo |
| --- | --- | --- |
| `trailingCallout` | el bloque del marco del aviso | Una caja que cierra la columna bajó exactamente el espacio que quedaba bajo su pie (`spaceAbove`; puede ser una fracción de línea). |
| `flexFigure` | el bloque de la imagen (en línea) o el flotante | Una imagen con zona segura compuesta `bodyGrowth` px más alta, en líneas enteras de rejilla, recortada dentro de la zona segura. El `bodySource` del bloque del recurso es la parte que se ve, y `bodyFlex.delta` el mismo crecimiento. |
| `heading` | el encabezado | Líneas enteras de rejilla sobre el encabezado, hasta `maxLinesPerHeading`. |
| `listEnd` | el primer bloque tras la lista | Una línea de rejilla donde termina una lista, hasta `maxLinesAfterList`. |
| `afterDisplay` | el bloque tras la fórmula o la caja | Una línea de rejilla bajo una fórmula en bloque o una caja de aviso. |
| `afterFloat` | el primer bloque de la columna | Una línea de rejilla entre una banda de flotantes que encabeza la columna y su texto, hasta `maxLinesAfterFloat`. |
| `looseParagraph` | el párrafo | El párrafo recompuesto `extraLines` más largo, con el menor tracking que lo consiguió (`tracking`; `block.letterSpacing` es el mismo valor en px). |

Los cortes nivelados se registran en las columnas que cortan: `column.bandCapped` vale true en toda columna cortada a nivel (la banda que deja un bloque a ancho de página, una banda de cierre), y `column.trailingCap` marca además la banda de cierre de un capítulo o del documento (`trailing`).

```ts
import { buildDocument } from 'postext';

const doc = buildDocument(content, config);
for (const page of doc.pages) {
  page.columns.forEach((column, i) => {
    const levers: string[] = column.blocks.flatMap((block) => block.balancing?.levers ?? []);
    if (column.trailingCap) levers.push('banda de cierre nivelada');
    else if (column.bandCapped) levers.push('banda nivelada');
    if (levers.length > 0) console.log(`página ${page.index + 1}, columna ${i + 1}: ${levers.join(', ')}`);
  });
}
// página 3, columna 1: heading, heading
// página 3, columna 2: listEnd, looseParagraph
```
