Capítulo 5 · Parte II · El oficio
Configuración: texto y encabezados
La tipografía del texto de cuerpo, la separación silábica y el idioma del documento; los encabezados, las listas y las matemáticas
En pocas palabras
Esta página reúne los ajustes de las palabras de la página. Eliges la tipografía, el cuerpo y el interlineado del texto principal, y cómo se parten las palabras al final de la línea. Le dices a Postext en qué idioma está escrito el libro. Decides el aspecto de cada nivel de título y cómo se dibujan las listas con viñetas y las numeradas. La última sección fija el tamaño y el color de las fórmulas matemáticas.
#Texto de cuerpo
La propiedad bodyText controla la tipografía de todo el texto de párrafo.
| Propiedad | Tipo | Por defecto | Descripción |
|---|---|---|---|
fontFamily | string | 'EB Garamond' | Familia tipográfica para el cuerpo de texto. Cualquier fuente de Google Fonts, del sistema, o declarada como fuente personalizada. Una sola familia, no una lista de fuentes CSS (ver más abajo). |
fontSize | Dimension | 8 pt | Tamaño de fuente base para el cuerpo de texto. |
lineHeight | Dimension | 1.5 em | Espaciado vertical entre líneas. Las unidades relativas (em, rem) escalan con el tamaño de fuente. |
paragraphSpacing | boolean | false | Cuando está activado, inserta una línea en blanco (igual al lineHeight) entre párrafos consecutivos, como hacen algunas editoriales. |
color | ColorValue | #000000 | Color del texto. |
boldColor | ColorValue | Color principal (#295AA3) | Color aplicado a los fragmentos en negrita. Se resuelve contra la entrada main-color de la paleta por defecto, de modo que cambiar ese color retintea todos los fragmentos en negrita del documento. |
italicColor | ColorValue | Color principal (#295AA3) | Color aplicado a los fragmentos en cursiva. Mismo enlace a la paleta que boldColor. |
referenceColor | ColorValue | Color principal (#295AA3) | Color aplicado a las etiquetas de :ref en línea (referencias a recursos). Mismo enlace a la paleta que boldColor. Sigue a la paleta desde postext 1.5; hasta la 1.4 se quedaba en #295AA3 fuera cual fuera el color principal. |
referenceBold | boolean | true | Renderizar las etiquetas de :ref en línea con la fuente en negrita. Una referencia conserva el énfasis del texto que la rodea (dentro de … sigue en negrita cursiva con cualquier valor); esta opción solo añade la negrita. |
referenceItalic | boolean | false | Renderizar las etiquetas de :ref en línea en cursiva. Una referencia dentro de texto en cursiva sigue en cursiva con cualquier valor. |
emphasis | 'auto' | 'italic' | 'bold' | 'color' | 'overline' | 'auto' | Cómo se compone …: en cursiva, en la negrita y boldColor, en redonda con italicColor, o en redonda con una raya encima de las palabras. 'auto' es 'bold' en un documento escrito en alfabeto árabe e 'italic' en cualquier otro. Véase Texto árabe. |
tashkil | 'keep' | 'strip' | 'strip-vowels' | 'keep' | Signos vocálicos del árabe: como están escritos, quitados todos, o quitados salvo la shadda. Véase Texto árabe. |
textAlign | 'left' | 'justify' | 'start' | 'end' | 'justify' | Alineación del texto. 'left' (o 'start') es el lado por el que empieza la línea: la derecha de un párrafo de derecha a izquierda (véase Dirección del texto). El texto justificado distribuye el espaciado a lo largo de cada línea para bordes uniformes. Las últimas líneas de los párrafos justificados se componen en bandera, a su ancho natural — salvo cuando Knuth-Plass aceptó una línea final sobrellenada confiando en la compresión del pegamento (glue): en ese caso los espacios entre palabras se comprimen para que la línea encaje exactamente en la medida (semántica de glue-setting de TeX, aplicada de forma idéntica en los backends canvas, HTML y PDF). |
fontWeight | number | 400 | Peso para el texto normal (100–900). |
boldFontWeight | number | 700 | Peso para texto en negrita/strong (100–900). |
hyphenation | HyphenationConfig | activada, 'en-us' | Configuración de separación silábica automática. Ver más abajo. |
firstLineIndent | Dimension | 1.5em | Sangría aplicada a la primera línea de cada párrafo (o a todas las líneas excepto la primera cuando la sangría francesa está activada). |
hangingIndent | boolean | false | Cuando está activado, la sangría se aplica a todas las líneas excepto la primera (sangría francesa). |
indentAfterHeading | boolean | true | Cuando vale false, el primer párrafo inmediatamente posterior a un encabezado se compone sin sangría de primera línea — convención tipográfica habitual en publicaciones científicas y en muchos estilos editoriales. Lo mismo vale para un párrafo justo después de una línea :::space. Un recuadro que sale del texto entre ambos —a la columna lateral (span: 'side'), flotado a la cabeza o al pie de una página, o fijo— y una figura flotante no cuentan: en su columna, el párrafo sigue al encabezado y se compone sin sangría. Un recuadro compuesto en el texto (placement: 'here') sí cuenta, y el párrafo que lo sigue lleva sangría. No tiene efecto cuando hangingIndent está activado. |
maxWordSpacing | number | 2 | Límite superior del espaciado entre palabras en texto justificado, expresado como multiplicador del ancho del espacio normal. Knuth-Plass mantiene dentro de él todas las líneas que el párrafo permite, y antes separa una palabra o reparte la holgura entre las líneas vecinas; una línea que ningún conjunto de cortes deja dentro del límite lo supera, y la que pasa de 3 veces el espacio normal se compone en bandera. Las líneas que superan esta proporción se consideran "flojas": ver Líneas que el algoritmo no puede llenar, y maxJustifyTracking para que tomen algo de tracking en su lugar. |
minWordSpacing | number | 0.6 | Límite inferior del espaciado entre palabras en texto justificado, como multiplicador del ancho del espacio normal. |
maxJustifyTracking | number | 0 | Tracking máximo que puede tomar una línea justificada, en milésimas de eme en uno u otro sentido (la unidad de InDesign: 10 = 0,01 em por carácter), cuando con solo sus espacios entre palabras se estiraría más allá de maxWordSpacing o se comprimiría por debajo de minWordSpacing. La parte del ajuste que pasa del límite va a las letras, así que los espacios de una línea floja vuelven a maxWordSpacing y una línea apretada cabe con minWordSpacing. Knuth-Plass lo tiene en cuenta al elegir los cortes, y solo en las líneas que el espaciado entre palabras llevaría más allá de los límites: las demás, la última línea de un párrafo (salvo que se desborde), una línea de una sola palabra y una línea con un chip no lo usan. La línea lo guarda como letterSpacing, y canvas, HTML y PDF lo pintan. Requiere optimalLineBreaking. Con 0 queda desactivado. Ver Tracking como último recurso. |
kashida | 'auto' | 'none' | 'auto' en un documento en alfabeto árabe; si no, 'none' | Justificación con cachida: una línea justificada de texto en alfabeto árabe toma su holgura en los espacios entre palabras (hasta una cuarta parte de su anchura) y después en cachidas, tatweels enteros (U+0640) insertados entre dos letras enlazadas, nunca como espaciado entre letras. Knuth-Plass cuenta el alargamiento de cada palabra como estiramiento. Nunca en palabras latinas, cifras, títulos, líneas en bandera ni en la última línea de un párrafo. Los tatweels se pintan pero quedan fuera del texto plano y del copiado. Ver Cachida en el texto árabe. |
kashidaPatterns | 'auto' | 'naskh' | 'simple' | 'nastaliq' | 'auto' | Qué enlaces toman cachida y en qué orden: las reglas clásicas del naskh, las prioridades de Microsoft o las reglas del naskh adaptadas al nastaʿlīq (según raqim-kashida). 'auto' mira la fuente del texto: ninguna en un tipo ruqʿa o dīwānī (Aref Ruqaa), reglas de nastaʿlīq en un tipo nastaʿlīq, naskh en los demás. |
kashidaPerWord | number | 1 | Máximo de alargamientos en una palabra. |
kashidaMaxLength | number | 0.6 | Alargamiento máximo en un enlace, en em; toma tantos tatweels enteros como quepan. |
optimalLineBreaking | boolean | true | Usar ruptura óptima de líneas Knuth-Plass en lugar de voraz de primer ajuste. Produce un espaciado entre palabras más uniforme en todo el párrafo. Un párrafo en chino, japonés o coreano (ver Tipografía de Asia oriental), o con una palabra más ancha que la columna, se compone igualmente línea a línea; un párrafo latino que cita unas pocas palabras CJK la conserva. El texto en bandera también la usa con optimalRagged. Ver Separación silábica y justificación. |
optimalRagged | boolean | true | Compone también con Knuth-Plass el texto corrido en bandera: el texto de cuerpo, las citas y los elementos de lista alineados a la izquierda, a la derecha o centrados, y los estilos de párrafo, los cuerpos de recuadro y los cuerpos de las partes y de los estilos de sección en bandera. Los espacios entre palabras no cambian de ancho. El algoritmo pondera cuánto se queda corta cada línea respecto de la medida (una línea 3 em más corta cuesta lo que una línea justificada con maxWordSpacing), así que empareja el margen irregular en lugar de llenar cada línea antes de pasar a la siguiente, y las reglas contra las líneas cortas (avoidRunts, tightenRunts) y hyphenateAcrossColumns actúan en el texto en bandera como en el justificado. Con hyphenation.ragged, la zona sigue decidiendo qué sílabas pueden terminar una línea (ver Texto en bandera). Los títulos en bandera, los pies, las notas, las celdas de tabla y el índice de contenidos se siguen componiendo línea a línea. Requiere optimalLineBreaking. false compone el texto en bandera línea a línea, como hasta postext 1.4; así se leen las configuraciones guardadas antes que ponen en bandera algún texto corrido (ver Paquetes escritos por postext 1.4 o anterior). |
breakAfterDashes | boolean | true | Permite que una línea termine tras una raya o una semirraya puesta entre dos palabras sin espacios: Madrid–Barcelona, I.—Que trata (un título de capítulo a la antigua) o, en un texto en inglés, say—that’s, también cuando la palabra que sigue a la raya va en otro estilo (calidad–precio). Knuth-Plass la toma como un espacio entre palabras, y la línea termina en la raya sin añadir nada. Nunca tras la raya que abre un inciso o un diálogo (—dijo, dijo "—Hola, sagte »—Ich: con un espacio, o un espacio y unas comillas, delante de la raya; tras unas comillas que cierran una palabra, como en «no»—y, el alemán „nein“—und o el francés « non »—et, la línea sí puede terminar), delante de un signo de puntuación (él—,), delante de unas comillas o un paréntesis (pensaba—» y, dijo—«no», dijo—(no): tras una raya, unas comillas suelen cerrar la cita que la raya interrumpe), dentro de una serie de rayas ni dentro de un intervalo de números con semirraya (1914–1918). false mantiene los cortes de la 1.4: Knuth-Plass nunca corta tras una raya, y el divisor línea a línea del texto con formato o del texto en bandera con separación silábica solo entre dos letras; así se leen las configuraciones guardadas antes cuyo texto tiene alguna de esas rayas (ver Paquetes escritos por postext 1.4 o anterior). Se aplica al texto corrido, los títulos, las listas, las citas y los recuadros. Los pies, las notas, las celdas de tabla y el índice de contenidos conservan los cortes de la 1.4, y un párrafo en bandera sin formato compuesto línea a línea sigue en ambos casos las reglas propias de pretext. |
breakAfterHyphens | boolean | true | Permite que una línea termine tras el guion de un compuesto, un guion entre dos letras (físico- · química, vencer- · se), en todo párrafo que corta Knuth-Plass. La línea termina en el guion y no se añade nada; el corte cuesta lo que una sílaba. Nunca tras un guion junto a una cifra o un signo (COVID-19, -5 °C). Un párrafo justificado sin formato en línea solo corta ahí con dos letras a cada lado del guion, para que ninguna línea termine en la e- de e-mail. false mantiene los cortes de la 1.4: un párrafo justificado sin formato en línea nunca corta ahí, mientras que el mismo párrafo con una palabra en cursiva en cualquier parte, un párrafo en bandera y uno compuesto línea a línea sí lo hacen; así se leen las configuraciones guardadas antes cuyo texto tiene algún compuesto (ver Paquetes escritos por postext 1.4 o anterior). Se aplica al texto corrido, los títulos, las listas, las citas y los recuadros. Ver Palabras compuestas. |
repeatHyphen | boolean | false | Empieza también con un guion la línea que sigue a un corte en el guion de un compuesto: léxico- · -semántico, como piden las normas de la Real Academia Española desde 2010, y vencer- · -se, como pide la ortografía portuguesa. El guion repetido se mide y se pinta con su línea, que lo anota como repeatedHyphen; su plainStart y su sourceStart apuntan detrás de él, de modo que los enlaces, los titulillos y el Sandbox leen la palabra tal como está escrita. El PDF lo pinta bajo un /ActualText que lo omite, así que el texto que se copia o se extrae del PDF lee la palabra una sola vez. Una dirección web nunca lo lleva. Se aplica al texto corrido, los títulos, las listas, las citas y los recuadros; un párrafo sin formato que contiene un compuesto se corta entonces con el divisor del texto con formato. |
hardLineBreaks | boolean | true | Lee una barra invertida al final de una línea del texto, y ante un espacio, como un salto de línea forzado dentro de un párrafo, una cita o un elemento de lista (el salto forzado de CommonMark): las palabras siguientes empiezan una línea nueva del mismo párrafo, y la línea anterior se compone con su anchura natural, como una última línea. Una barra invertida al final del párrafo se imprime, y dos espacios al final de una línea no son un salto (ver Formato del documento › Saltos de línea). false conserva la lectura de la 1.22: las barras se imprimen y las líneas se unen con un espacio; las configuraciones guardadas antes cuyo texto tiene una barra así se leen con ella (ver Paquetes escritos por postext 1.4 o anterior). Los títulos, los pies, las notas y las celdas de tabla se parten en en ambos casos. |
tabStops | TabStop[] | sin fijar | Tabulaciones de todos los párrafos, elementos de lista y citas: adónde lleva un tabulador (:tab, o un carácter de tabulación en el texto) las palabras que lo siguen. Un estilo de párrafo o el cuerpo de un recuadro que fija las suyas las sustituye. Sin fijar, un carácter de tabulación es un espacio entre palabras, como antes, y un :tab sin tabulación a la que ir también. Ver Tabulaciones. Desde postext 1.23. |
tabInterval | Dimension | sin fijar | Tabulaciones por defecto a intervalos regulares desde el principio de la medida, pasada la última de tabStops. Sin fijar, un tabulador más allá de la última tabulación es un espacio entre palabras. Desde postext 1.23. |
blockquote | BlockquoteConfig | ver abajo | Cómo se componen las citas de Markdown (> …): color, cursiva y sangrías. Ver Citas. |
#Citas
Una cita (las líneas que empiezan por >) toma la familia, el cuerpo, el interlineado, los pesos, la alineación y la separación silábica del texto de cuerpo. bodyText.blockquote fija lo demás; sin fijar, una cita se ve como hasta postext 1.4: gris, en cursiva, con la sangría de primera línea del cuerpo y sin sangría lateral.
| Propiedad | Tipo | Por defecto | Descripción |
|---|---|---|---|
color | ColorValue | #666666 | Color del texto. Un color enlazado a una entrada de la paleta (paletteId) sigue a esa entrada, como en todas partes; los colores de negrita, cursiva y referencias del cuerpo no se aplican dentro de una cita. |
italic | boolean | true | Compone el texto en cursiva. Un tramo … dentro vuelve a redonda; con false va en cursiva, como en un párrafo. |
indent | Dimension | 0 | Sangría de todas las líneas desde el borde izquierdo de la columna o del recuadro. La medida se estrecha en esa cantidad, así que las líneas justificadas terminan en el borde derecho. em es el cuerpo del texto. |
firstLineIndent | Dimension | la del cuerpo | Sangría de la primera línea de cada párrafo citado, contada desde indent (con el hangingIndent del cuerpo, la de todas las líneas menos la primera). Sin fijar: bodyText.firstLineIndent. |
bodyText: {
firstLineIndent: { value: 1.5, unit: 'em' },
// Versos en redonda, en el color del cuerpo, entrados 2 em y sin sangría de primera línea.
blockquote: { color: { hex: '#241f26', model: 'hex' }, italic: false, indent: { value: 2, unit: 'em' }, firstLineIndent: { value: 0, unit: 'em' } },
}En el Sandbox son el grupo Citas de la sección Texto base.
#Verso
Un poema :::verse cuyas líneas no llevan separador de hemistiquios se compone línea a línea (véase Formato del documento › :::verse). bodyText.verse da los valores por defecto de esos poemas; un atributo del mismo nombre en la apertura de un poema lo fija para ese poema.
| Propiedad | Tipo | Por defecto | Descripción |
|---|---|---|---|
layout | 'auto' | 'bayt' | 'auto' | Cómo se compone un poema cuya apertura no nombra composición. 'auto': en baits cuando una línea lleva separador (||), línea a línea si no. 'bayt': siempre en baits, y un poema sin separador como hemistiquios sueltos centrados, como hasta postext 1.22. |
indentStep | Dimension | 0.5em | Anchura de un espacio inicial de un verso (un tabulador cuenta cuatro, un espacio ideográfico dos); em es el cuerpo del poema. |
turnover | 'hang' | 'right' | 'hang' | Cómo se parte un verso más ancho que la caja: colgado en la línea siguiente, o contra el final de la caja tras turnoverMark. |
hang | Dimension | 2em | Sangría del resto colgado desde el inicio de su verso, cuando el estilo de párrafo del poema no fija hangingIndent. |
turnoverMark | string | '[' | El signo ante un resto compuesto a la derecha. |
stanzaSpace | number | 1 | Espacio entre estrofas, en líneas del interlineado del poema. En la retícula de base resulta en líneas enteras; un estilo de párrafo con snapToGrid: false lo conserva exacto. |
keepStanzas | number | 0 | Mantener en una sola columna toda estrofa de estos versos o menos. 0 lo desactiva. |
tighten | boolean | true | Apretar los espacios entre palabras de un verso un poco más ancho que la caja, hasta bodyText.minWordSpacing de su ancho natural, y mantenerlo en una línea; solo se parte el que sigue sin caber. Las letras nunca se espacian para ello. false parte todo verso más ancho que la caja, como hacía postext 1.23. El EPUB adaptable, cuyas líneas corta el sistema de lectura, no aprieta. |
bodyText: {
// Restos a la derecha tras un corchete; las tankas, enteras.
verse: { turnover: 'right', keepStanzas: 5 },
}Una configuración guardada antes de estos ajustes (configVersion 8 o anterior) que compone un poema sin separador se lee con layout: 'bayt', de modo que el poema conserva las líneas centradas que le daba postext 1.22. Una guardada con postext 1.23 (configVersion 9) que compone un poema verso a verso se lee con tighten: false, de modo que sus versos se parten donde los partía la 1.23.
En el Sandbox son el grupo Verso de la sección Texto base.
#Tabulaciones
bodyText.tabStops enumera las tabulaciones a las que va un tabulador: :tab, o un carácter de tabulación en un párrafo que tiene tabulaciones (ver Formato del documento › Tabuladores y tabulaciones para el marcado y cómo se compone una línea). El tabStops de un estilo de párrafo las sustituye para sus párrafos, y el body.tabStops de un estilo de recuadro dentro de sus cajas; una lista vacía no fija ninguna. Cada tabulación es un TabStop:
bodyText: {
tabStops: [
{ position: { value: 30, unit: 'mm' } },
{ position: 'end', align: 'end', leader: '.', leaderGap: { value: 2, unit: 'pt' } },
],
tabInterval: { value: 10, unit: 'mm' },
}| Propiedad | Tipo | Por defecto | Descripción |
|---|---|---|---|
position | | obligatorio | Dónde está la tabulación, desde el borde inicial de la medida del párrafo (tras el indent de un estilo de párrafo; em es el cuerpo del propio párrafo): una longitud, 'end' para el borde final de la medida, o una parte de la medida ('50%'). En el texto de derecha a izquierda el borde inicial es el derecho. |
align | 'start' | 'end' | 'center' | 'decimal' | 'start' | Cómo queda en la tabulación el texto que sigue al tabulador: empieza en ella, termina en ella (el texto hasta el tabulador siguiente o el final del párrafo), se centra en ella o pone en ella su separador decimal (un tramo que no lo tiene termina en ella). |
leader | string | ninguno | Relleno que se repite en el hueco anterior a la tabulación: '.', '. ', '·', '_', '-' o cualquier texto breve, en la fuente y el color del párrafo; 'rule' traza una línea un poco por debajo de la línea base. El relleno termina a ras del final de su hueco, de modo que los rellenos de varias líneas quedan alineados. Se mide como una tira entera, igual que la línea de puntos de una fila del índice general. |
leaderGap | Dimension | 0.5em | Espacio que se deja entre el relleno y el texto a cada lado, como el leader.gap del índice general. No hay ninguno antes del relleno cuando el tabulador abre su línea, ni después cuando no le sigue nada. |
decimalChar | string | el del idioma del documento | El separador en el que se alinea una tabulación 'decimal': . en inglés, chino, japonés y árabe, , en español, catalán, portugués, francés, alemán y otros. |
tabInterval añade tabulaciones a intervalos regulares desde el principio de la medida, pasada la última de la lista; sin él, un tabulador más allá de la última tabulación es un espacio entre palabras. Un carácter de tabulación escrito en el texto solo es un tabulador en un párrafo cuyo estilo tiene tabulaciones o un intervalo, propios o del cuerpo; en los demás sigue siendo el espacio entre palabras que siempre fue, así que un documento guardado se compone como antes y no necesita fijar versión.
Las tabulaciones se comprueban con el resto de la configuración (ver Avisos de configuración): una clave desconocida en una tabulación (leaders) se notifica como unknownConfigKey con la clave a la que más se parece; un align que no es ninguno de los cuatro, como unknownConfigValue, y la tabulación se compone como 'start'; una position que no es una longitud, 'end' ni un porcentaje, como unknownConfigValue con used: 'none', y la tabulación se descarta.
El color y la fuente del relleno son los del párrafo; todavía no tienen un ajuste propio.
#Letras capitulares
Un párrafo de cuerpo puede abrirse con una capitular: su primera letra, grande, junto a sus primeras líneas, que se acortan en el ancho de la letra más un espacio y se componen como cualquier otra línea (cortadas por Knuth-Plass, justificadas, con división silábica). Un estilo de párrafo se la da al primer párrafo de cada grupo :::paragraphs con ese estilo (a todos los párrafos con each: true, para un catálogo de entradas); un nivel de encabezado o un estilo de encabezado se la da al primer párrafo de cuerpo que sigue al encabezado (ver el campo dropCap de Configuración por nivel, Estilos de párrafo y Estilos de encabezado). El párrafo que sigue al encabezado se busca pasando por encima de vallas de contenedor, directivas, cajas que salieron del flujo y figuras flotantes, igual que lo busca indentAfterHeading; un párrafo dentro de un recuadro, de un elemento de lista, de una cita, de un poema o de una nota nunca la lleva. En el texto, {dropcap}, {dropcap=false} y {dropcap=N} en la línea de un encabezado o en la valla de un :::paragraphs la activan, la quitan o fijan sus líneas para ese capítulo o ese grupo (ver Formato del documento › Letras capitulares). Desde postext 1.23.
headings: {
levels: [
{ level: 1, dropCap: { lines: 3, fontFamily: 'Libre Bodoni', fontWeight: 700, color: { hex: '#8b2e2a', model: 'hex', paletteId: 'accent' }, leadIn: { words: 3 } } },
],
},| Propiedad | Tipo | Por defecto | Descripción |
|---|---|---|---|
lines | number | 3 | Líneas que abarca la capitular, desde la parte alta de sus mayúsculas hasta su línea base. 1 con un fontSize mayor es una capitular alzada, apoyada en la primera línea base. |
sink | number | lines | Líneas que la capitular baja dentro del texto: se apoya en la línea base de la línea sink, y esas líneas se acortan. Un valor menor que lines la alza por encima de la primera línea. |
characters | number | 1 | Grupos de grafemas que se componen en grande: É, una letra con un signo combinado o un carácter fuera del plano multilingüe básico cuentan como uno. Nunca más allá de la primera palabra. |
fontFamily, fontWeight, italic | string, number, boolean | los del párrafo; false | Fuente de la capitular. Se carga y se incrusta con las demás fuentes del documento. |
fontSize | Dimension | ver abajo | Cuerpo de la capitular. Sin fijar: el cuerpo que enrasa la parte alta de sus mayúsculas con las mayúsculas de la primera línea mientras se apoya lines líneas más abajo. |
color | ColorValue | el del párrafo | Un color enlazado a la paleta sigue las paletas de la parte y de la sección. |
gap | Dimension | 0.15em | Espacio entre la capitular y las líneas acortadas; em es el cuerpo del texto. |
punctuation | 'with-cap' | 'hang' | 'text' | 'with-cap' | Una comilla de apertura, ¿, ¡ o un paréntesis delante de la letra: se compone en grande como parte de la capitular, se cuelga al cuerpo del texto fuera de la medida delante de ella, o se compone al cuerpo del texto al principio de la primera línea, tras la capitular. |
leadIn | { words, smallCaps, uppercase } | ninguno | Las primeras words palabras tras la capitular, en versalitas (por defecto) o en mayúsculas (uppercase: true); words: 'line' toma las palabras de la primera línea. Las palabras de la primera línea se cuentan en una primera composición y se marcan en una segunda: en versalitas la línea puede admitir entonces una palabra más, que se compone tal como está escrita. |
shortParagraph | 'reserve' | 'shrink' | 'skip' | 'reserve' | Un párrafo de menos líneas que sink: mantener el bloque con sink líneas de alto para que el bloque siguiente quede libre de la capitular, componer la capitular sobre las líneas que tiene el párrafo, o componer el párrafo sin ella. Cada caso da un aviso de contenido dropCap. |
each | boolean | false | Solo en estilos de párrafo: todos los párrafos del grupo se abren con capitular, no solo el primero. |
Cómo se compone la letra:
- Cuerpo. Las dos alturas de mayúsculas, la del texto y la de la capitular, se miden en sus fuentes (la tinta de una
H; en texto chino o japonés, la de la propia capitular), y una fuente que no da medidas de tinta cuenta sus mayúsculas como 0,72 de su cuerpo. El cuerpo por defecto sirve para cualquier pareja de fuentes, así que no hace falta una corrección por fuente. EldropCapde un texto de diseño conserva su 0,72 fijo (ver Elementos de texto). - La letra y su palabra. La capitular toma grupos de grafemas enteros. El resto de la primera palabra sigue tras ella sin espacio; una palabra de una sola letra (A, Y) conserva su espacio al principio de la primera línea. Se quita la sangría de primera línea del propio párrafo. Al copiar, al buscar, en el mapa de fuente y con el cursor del Sandbox el párrafo se lee tal como está escrito: el texto plano del bloque incluye la letra, el
plainStartde la primera línea cuenta a partir de ella, yVDTBlock.dropCapguarda su rango y su geometría en el fragmento que tiene la primera línea. - Una capitular alzada (
lines: 1con unfontSizemayor, o unsinkmenor quelines) sobresale por encima de la primera línea, y el párrafo deja libre esa altura por encima, en líneas enteras de la retícula, para no pisar el texto anterior. - Cortes. El párrafo nunca se corta antes de la línea
sink: pasa entero a la columna o la página siguiente, salvo que esté solo en una columna vacía que no admite esas líneas; entonces se corta de todos modos y da un avisodropCap. Un encabezado que se mantiene con su texto se lleva esas líneas consigo. La parte que sigue en la columna siguiente no lleva capitular y tiene las líneas a ancho completo; si se vuelve a cortar para una columna de otro ancho, las primeras líneas conservan su sangría. El equilibrado de columnas puede componer el párrafo más flojo o más apretado como cualquier otro, y nunca añade espacio entre las líneas acortadas. - Escrituras. Las líneas se acortan por el lado inicial: la izquierda en texto latino, la derecha en árabe y hebreo. Una letra que se enlaza con la siguiente (árabe, siríaco, n'ko) no se separa, y el párrafo da un aviso
dropCap; el chino y el japonés horizontales llevan una capitular de un carácter (首字下沉). El texto vertical no lleva ninguna (con aviso). Un párrafo que no empieza por una letra o una cifra (una referencia, una fórmula, una llamada de nota) tampoco (con aviso). - Salidas. El canvas, el visor HTML y el EPUB de maquetación fija pintan la capitular junto a las líneas; el HTML la escribe justo antes del texto de la primera línea, sin nada en medio, para que un lector de pantalla lea la palabra entera. En un PDF etiquetado la capitular forma parte del
Pdel párrafo y, con el resto de su palabra, de unSpancuyo/ActualTextes la palabra: la extracción de texto lee Mucho antes, nunca M ucho antes. Un EPUB adaptable la compone comoinitial-letterde CSS (líneas, hundimiento), flotada donde el sistema de lectura no lo admite.
Los ajustes se comprueban con el resto de la configuración (ver Avisos de configuración): una clave desconocida en una capitular o en sus primeras palabras se notifica como unknownConfigKey; un punctuation o un shortParagraph que no es ninguno de sus valores, o un lines, sink o characters que no es un número entero desde 1, como unknownConfigValue, y se usa el valor por defecto. Las capitulares están desactivadas por defecto, así que ningún documento guardado cambia.
#Una sola familia por fontFamily
fontFamily —aquí y en cualquier otro campo de familia tipográfica (headings.fontFamily, tableStyle.bodyFontFamily, separatorFontFamily, el fontFamily de un estilo de chip o de un elemento de diseño…)— nombra una familia. El canvas, la salida HTML y el PDF tienen que componer con la misma fuente, y el PDF incrusta una fuente por familia, sin cadena de respaldo, así que una lista de fuentes CSS no tiene a qué recurrir. Una lista se compone en su primera familia y se notifica como aviso de configuración:
bodyText: { fontFamily: "'EB Garamond', Georgia, serif" } // se compone en EB GaramondCarga esa familia antes de componer (consulta Fuentes personalizadas y el proveedor de fuentes en Generación de PDF); si falta, el navegador mide con su fuente por defecto, diga lo que diga el resto de la lista. Una coma entre comillas forma parte del nombre ('"Foo, Bar"' es una sola familia).
#Separación silábica
Cuando la alineación del texto está configurada como 'justify', la separación silábica evita el espaciado excesivo entre palabras al romper las palabras largas en los límites silábicos. El motor utiliza patrones TeX/Liang para encontrar puntos de ruptura naturales en los límites silábicos. Ver Separación silábica y justificación para una explicación detallada. El texto en bandera solo se divide si se pide: ver Texto en bandera más abajo.
| Propiedad | Tipo | Por defecto | Descripción |
|---|---|---|---|
enabled | boolean | true | Si se permite la separación silábica. |
locale | LocaleTag | el locale de primer nivel o, si no, 'en-us' | Reglas de idioma para los límites silábicos: uno de los idiomas soportados de abajo o cualquier etiqueta BCP 47 ('es-ES', 'pt-BR'). |
ragged | boolean | false | Separa sílabas también en el texto en bandera (alineado a la izquierda, a la derecha o centrado), dentro de la zone. Ver Texto en bandera. |
zone | Dimension | 3em | Zona de separación del texto en bandera: una palabra que no cabe solo se divide cuando pasarla entera a la línea siguiente dejaría un hueco mayor que esta medida. En em es relativa al cuerpo del propio texto. No se aplica al texto justificado. |
compounds | boolean | true | Permite que el diccionario divida las palabras de un compuesto, una palabra con un guion entre dos letras (teó-rico-práctico). false deja la palabra entera salvo por su propio guion, donde la línea sí puede terminar (teórico- · práctico), como hace TeX. Un guion blando escrito en la palabra sigue permitiendo el corte, y un compuesto más ancho que toda la línea se sigue dividiendo. Se aplica al texto corrido, los títulos, las listas, las citas y los recuadros; los pies, las notas, las celdas de tabla y el índice de contenidos siguen dividiendo los compuestos. Ver Palabras compuestas. |
Idiomas soportados: 'en-us' (inglés), 'es' (español), 'fr' (francés), 'de' (alemán), 'it' (italiano), 'pt' (portugués), 'ca' (catalán), 'nl' (neerlandés).
Para elegir los patrones se ignoran las subetiquetas de región, escritura y variante, las mayúsculas y los separadores _: 'es-ES', 'es-MX' y 'es_419' se dividen con 'es', 'pt-BR' con 'pt' y cualquier etiqueta inglesa ('en', 'en-GB') con 'en-us', los únicos patrones ingleses incluidos, de modo que el texto británico recibe los cortes estadounidenses. Un idioma sin patrones incluidos ('sv', 'pl', 'fi'…) se divide con los de 'en-us', lo que da cortes equivocados en lugar de ninguno; el motor lo avisa una vez por etiqueta con un console.warn, y el Sandbox lo muestra en su panel de revisión. Para un documento así, fija enabled: false; eso también acalla el aviso. El chino, el japonés y el coreano (zh, ja, ko, con cualquier región o escritura) no necesitan patrones ni imprimen aviso: un documento en uno de ellos se compone sin separación silábica. Para dividir las palabras latinas que cita, fija enabled: true y nombra su idioma en locale ('en-us' para el inglés). Con enabled: true sin locale, o con uno chino, japonés o coreano, la separación sigue desactivada y la consola lo avisa una vez. matchHyphenationLocale(tag) devuelve el idioma incluido al que corresponde una etiqueta (undefined si no hay ninguno), y HYPHENATION_LOCALES enumera los incluidos. La configuración resuelta (doc.config.bodyText.hyphenation) nombra en locale los patrones que se usan de verdad y conserva en tag la etiqueta que diste cuando es distinta. El backend PDF declara el idioma del documento a partir de locale, en la raíz de la configuración, y solo usa esta etiqueta cuando locale falta (consulta Idioma del documento).
import { matchHyphenationLocale } from 'postext';
matchHyphenationLocale('es-MX'); // 'es'
matchHyphenationLocale('en-GB'); // 'en-us'
matchHyphenationLocale('sv'); // undefined: se divide con 'en-us', con un aviso en la consolaLas palabras de menos de 5 caracteres nunca se separan. El motor requiere al menos 2 caracteres antes y 3 caracteres después de un punto de ruptura.
Texto en bandera
Por defecto solo se divide el texto justificado: con textAlign: 'left', y en los estilos de párrafo alineados a la izquierda, centrados o a la derecha, todas las palabras se mantienen enteras por irregular que quede el margen, salvo en un guion blando (U+00AD) escrito en el texto. Fija hyphenation.ragged: true para separar sílabas también en el texto en bandera.
Una línea en bandera nunca se estira, así que dividir toda palabra que no cabe llenaría el margen de guiones. La zona de separación lo limita, como hace el componedor de una sola línea de los programas de maquetación. Cuando una palabra no cabe al final de una línea, el motor mira el hueco que dejaría pasarla entera a la línea siguiente. Si ese hueco es mayor que zone, divide la palabra por la última sílaba que cabe; si no, la palabra baja entera. Una zona en em es relativa al cuerpo del propio texto. La zona por defecto, 3em, solo divide las palabras que dejarían una línea claramente corta. Una zona más ancha da menos guiones y un margen más irregular; con 0 se divide toda palabra que no cabe. Línea a línea, nunca terminan más de dos líneas seguidas en sílaba. Los guiones propios de la palabra (enseñanza-aprendizaje), las juntas de las URL, los guiones blandos escritos en el texto y las palabras más anchas que la línea entera se cortan como siempre: la zona y el límite de dos líneas solo gobiernan las sílabas del diccionario.
El ajuste vale para todo el documento. Se aplica al texto de cuerpo y a las citas cuando van en bandera, y a todo estilo de párrafo y cuerpo de recuadro en bandera que tenga activada su propia hyphenation (que toma por defecto el hyphenation.enabled del cuerpo), de modo que hyphenation: false mantiene enteras las palabras de un estilo. Los títulos, los pies, las notas, las celdas de tabla y el índice de contenidos no se dividen; en ellos, como en todas partes, solo se corta una palabra más ancha que la medida entera. El texto de diseño — cabeceras corridas, portadillas, páginas de parte — sigue la marca hyphenate de cada elemento de texto, que llevan activada las portadillas de página completa y las páginas de parte integradas, y también usa el diccionario del documento. El texto justificado ignora ragged y zone.
const config: PostextConfig = {
locale: 'es',
bodyText: {
textAlign: 'left',
// Algo más de separación silábica que con la zona por defecto de 3 em.
hyphenation: { ragged: true, zone: { value: 2, unit: 'em' } },
},
};Con optimalRagged (el valor por defecto), el texto corrido en bandera se compone con Knuth-Plass, y la zona conserva su sentido: una palabra solo se divide cuando no cabe en lo que queda de línea y pasarla entera abajo dejaría vacío más que la zona. Dos sílabas seguidas no se rechazan, pero cuestan lo que dos guiones seguidos en el texto justificado, así que una tercera es rara. Con optimalRagged: false, o con optimalLineBreaking: false, cada línea se llena antes de pasar a la siguiente, como hasta postext 1.4.
La separación silábica en bandera compone los párrafos con el divisor de líneas que usan siempre los párrafos con formato en línea (negrita, cursiva, enlaces, fórmulas), así que activarla puede mover algún corte que no es un guion. En una línea en bandera, además de en los espacios y en las sílabas del diccionario, ese divisor corta tras un guion o una raya entre dos palabras (largas—separadas; con breakAfterDashes, tras cualquier raya puesta entre palabras sin espacios, también I.—Que y calidad–*precio*), en las juntas de las URL y entre ideogramas, y mantiene unida una palabra escrita en varios tramos (**Nota**:, (*véase*). Sin separación silábica en bandera, un párrafo en bandera sin formato lo corta Knuth-Plass cuando optimalRagged está activado (el valor por defecto): en los espacios, tras un guion entre dos letras (enseñanza- · aprendizaje), como el otro divisor, y, con breakAfterDashes, tras las rayas entre palabras. Línea a línea, pasa por el divisor de pretext, que difiere en tres cosas: puede cortar también antes de la raya que cierra un inciso o después de la que lo abre (él · — y), tras una barra cuando divide sílabas (km/ · h), y corta una palabra más ancha que la línea por cualquier carácter y sin guion, donde el otro divisor la parte antes por una sílaba.
En el Sandbox el interruptor es Separación silábica en bandera, bajo la alineación de párrafo de la sección Texto base, con la zona debajo. Con el cuerpo justificado, el mismo interruptor aparece junto a los ajustes de justificación, para los estilos de párrafo y recuadros en bandera.
#Idioma del documento
El locale de primer nivel es el idioma del documento en su conjunto. Admite los mismos valores que hyphenation.locale y es el valor al que recurre ese campo cuando no está definido, de modo que a un libro en español le basta locale: 'es' para separar sílabas en español. También elige el idioma de las cadenas integradas de continuación de tablas y de avisos partidos ((cont.) / Continued frente a Continúa, ver Tablas más altas que la página y Marcas de un recuadro partido) y el de los números de encabezado escritos con letras (Chapter One frente a Capítulo uno, ver Números con letras), y es el idioma que se etiqueta en un PDF accesible. Sin definir, el motor asume 'en-us'; el Sandbox recurre al idioma de la interfaz y muestra el campo en Diseño › Escritura.
También elige los tipos de recurso integrados. Cuando resourceTypes no está definido, buildDocument numera y rotula con defaultResourceTypes(locale), así que locale: 'de' basta para obtener Abbildung 1.1 y Tabelle 1.1. Si locale no está definido, lo sustituye el idioma de la separación silábica, tanto para los tipos de recurso como para las cadenas de las tablas. Una lista resourceTypes explícita siempre manda. Las versiones anteriores usaban los tipos en inglés fuera cual fuera el locale, salvo que pasaras tú mismo defaultResourceTypes(locale); un documento que fija locale y quiere conservar las etiquetas inglesas pasa resourceTypes: defaultResourceTypes('en'). Los libros del Sandbox y los paquetes llevan su propia lista, así que no les afecta.
Aquí vale cualquier etiqueta BCP 47, igual que en hyphenation.locale: 'de-AT' recibe las cadenas alemanas. Las cadenas integradas existen en los ocho idiomas que admite la separación silábica, en chino (en caracteres simplificados y tradicionales), en japonés y en árabe; cualquier otro idioma recibe las inglesas.
El chino admite zh, zh-Hans, zh-Hant, zh-CN, zh-SG, zh-TW, zh-HK, zh-MO y las formas largas (zh-Hant-TW), en mayúsculas o minúsculas y con - o _. Las cadenas siguen la escritura, leída con Intl.Locale(tag).maximize(): zh, zh-CN y zh-SG son chino simplificado; zh-TW, zh-HK y zh-MO, tradicional. Los valores tipográficos que dependen del idioma siguen en cambio la región, como recomienda clreq §1.2: CN, SG y MY cuentan como China continental, TW como Taiwán, HK y MO como Hong Kong, y una etiqueta sin región se rige por su escritura (zh-Hant es Taiwán; zh y zh-Hans, la China continental). El japonés admite ja, ja-JP, ja-Jpan y cualquier otra etiqueta ja (isJapaneseLanguage(tag)); desde postext 1.16 tiene sus propias cadenas y su propia región, japan, cuyos valores tipográficos por defecto siguen JLReq (ver Composición japonesa). Una tabla de cadenas sin entrada japonesa da el inglés, nunca el chino. localeScript(tag), cjkRegionOf(tag), stringsKeyOf(tag) y sameContentLocale(a, b) devuelven estas lecturas, y DOCUMENT_LANGUAGES enumera los idiomas con cadenas integradas, cada uno con su nombre en su propia lengua (日本語 entre las entradas chinas y العربية), tal como los muestra el selector de idioma del documento del Sandbox.
| Idioma | Figura: nombre, plural, etiqueta corta | Tabla: nombre, plural, etiqueta corta | Continuación de tabla: continuedSuffix, continuesMarker |
|---|---|---|---|
Inglés (en) | Figure, Figures, Fig. | Table, Tables, Tab. | (cont.), Continued |
Español (es) | Figura, Figuras, Fig. | Tabla, Tablas, Tabla | (cont.), Continúa |
Francés (fr) | Figure, Figures, Fig. | Tableau, Tableaux, Tabl. | (suite), À suivre |
Alemán (de) | Abbildung, Abbildungen, Abb. | Tabelle, Tabellen, Tab. | (Forts.), Wird fortgesetzt |
Italiano (it) | Figura, Figure, Fig. | Tabella, Tabelle, Tab. | (segue), Continua |
Portugués (pt) | Figura, Figuras, Fig. | Tabela, Tabelas, Tab. | (cont.), Continua |
Catalán (ca) | Figura, Figures, Fig. | Taula, Taules, Taula | (cont.), Continua |
Neerlandés (nl) | Figuur, Figuren, Fig. | Tabel, Tabellen, Tab. | (vervolg), Wordt vervolgd |
Chino simplificado (zh-Hans, zh, zh-CN) | 图, 图, 图 | 表, 表, 表 | (续), 接下页 |
Chino tradicional (zh-Hant, zh-TW, zh-HK) | 圖, 圖, 圖 | 表, 表, 表 | (續), 接下頁 |
Japonés (ja, ja-JP) | 図, 図, 図 | 表, 表, 表 | (続き), 次ページへ続く |
Árabe (ar, ar-EG, ar-MA…) | شكل, أشكال, شكل | جدول, جداول, جدول | (تابع), يتبع |
El prefijo del pie es el nombre del tipo (Figura 1.1.). Los tipos chinos numeran dentro del capítulo con un guion, {h1}-{n} (图 1-1); con los ajustes de pie labelNumberGap: '' y labelSeparator: ' ' el pie se lee 图1-1 标题 (ver Estilo de pies de recurso). El índice alfabético sigue también el idioma: 见 y 另见 ante una remisión, 符号 y 数字 sobre los símbolos y los números en chino simplificado; 見, 另見, 符號 y 數字 en tradicional. El japonés numera sus tipos del mismo modo y compone sus pies como 図1-1 題 sin los dos ajustes, escribe las referencias cruzadas como 第3章, 2.3節 y 12ページ, titula la bibliografía 参考文献, y su índice imprime 記号 y 数字 sobre los símbolos y los números y escribe sus remisiones con una flecha, →夏目漱石 para véase y →夏目漱石、森鷗外も見よ tras las páginas para véase también, con las etiquetas en redonda. El árabe numera sus tipos del mismo modo, {h1}-{n} (شكل 2-3), escribe las referencias cruzadas como الفصل 3, القسم 2-1 y ص 12, titula la bibliografía المراجع, y su índice imprime انظر / انظر أيضًا, رموز y أرقام, con la coma y el punto y coma árabes (، ؛).
Un documento en chino, japonés o coreano declara su idioma en la salida HTML (lang en la raíz .pt-doc, con zh-Hant-TW completo) y en el canvas que pinta (ctx.lang, en Chrome 136 y posteriores), de modo que el navegador dibuja las formas de glifo de su región: Unicode unifica los caracteres han, y un mismo punto de código se ve distinto en una fuente taiwanesa y en una japonesa. Los demás documentos no llevan lang, como antes. El PDF declara /Lang a partir de locale para todo documento, etiquetado o no, con su escritura y su región. Un documento en un idioma que se escribe de derecha a izquierda (árabe, persa, urdu, hebreo…) también declara su idioma: las formas de la lengua de la fuente (locl) y la fuente de reserva lo siguen.
const config: PostextConfig = {
locale: 'es',
bodyText: { textAlign: 'justify', hyphenation: { enabled: true } }, // separa sílabas en español
};Cifras del documento
La clave numerals de primer nivel fija las cifras de todos los números que escribe el motor: los números de página y las etiquetas de página del índice general, del índice alfabético y de las referencias a página; los números de las listas ordenadas y de las notas; los contadores de títulos y capítulos, {chapterNumber}; el {h1} y el {n} del número de una figura y de una referencia a ella; {totalPages}, {bookTotalPages} y {numberDecimal}. 'latn' escribe 0–9, 'arab' las cifras arábigo-índicas ٠–٩ y 'arabext' las persas ۰–۹. Solo cambia el formato decimal —decimal, el arabic de las listas o un ajuste que se deja por defecto—, así que un formato que el autor nombra se imprime como se nombra: lower-roman sigue siendo i, ii, iii, y arabic-indic en un documento latino escribe ١, ٢, ٣. El texto del documento nunca se reescribe.
El valor por defecto, 'auto', toma las cifras de locale (defaultNumeralsFor(tag)): 'arab' para el árabe sin región o con cualquier región fuera del Magreb (ar, ar-EG, ar-SA, ar-AE…), 'latn' para ar-MA, ar-DZ, ar-TN, ar-LY, ar-MR y ar-EH, 'arabext' para el persa (fa), el pastún (ps) y el urdu de la India (ur-IN), y 'latn' para todo lo demás, incluido el urdu de Pakistán. CLDR da latn para ar sin región y para ar-AE; los libros árabes del Máshrek y del Golfo imprimen ٠–٩, y Postext sigue a los libros. Una etiqueta que nombra sus cifras las conserva: ar-MA-u-nu-arab. Una página numerada con las cifras del documento guarda arabic-indic o persian como pageNumberFormat, de modo que las etiquetas de página del PDF muestran las mismas cifras. Un valor desconocido sigue la lengua y se avisa como unknownNumerals.
Los números que escribe el autor se leen en cualquiera de los tres sistemas: un elemento de lista ٣. empieza en 3, y {startAt=٥}, :::numbering{startAt=٥}, :::space{lines=٢} y :::part{number="٣"} (para {numberDecimal}) leen el valor.
const config: PostextConfig = { locale: 'ar' }; // ١، ٢، ٣
const magreb: PostextConfig = { locale: 'ar-MA' }; // 1, 2, 3
const forzado: PostextConfig = { locale: 'ar', numerals: 'latn' }; // 1, 2, 3Dirección del texto
direction, en el primer nivel, fija la dirección base del documento: 'ltr', 'rtl' o 'auto' (lo predeterminado), que es 'rtl' cuando la escritura del locale se escribe de derecha a izquierda (árabe, persa, urdu, hebreo, siríaco, thaana, n'ko, adlam…, según directionOf(tag)) y 'ltr' en los demás casos. Un documento de derecha a izquierda se compone en un marco espejado: sus líneas empiezan a la derecha, su primera columna es la de la derecha, sus sangrías, marcadores de lista, flotantes, notas al pie y cajas quedan a la derecha, y page.binding: 'auto' lo encuaderna por la derecha. La configuración resuelta solo lleva direction: 'rtl' en un documento así, de modo que un documento de izquierda a derecha se resuelve igual que antes. Un valor desconocido se lee como 'auto' y se avisa como unknownConfigValue. El algoritmo bidireccional de Unicode (UAX #9) ordena los tramos de cada línea en cualquiera de las dos direcciones: una cita árabe en un libro inglés se lee de derecha a izquierda en su sitio.
Dentro del documento, un título o un contenedor ::: admite {dir=ltr} o {dir=rtl}, y :ltr[…] y :rtl[…] aíslan un tramo de texto (véase Dirección del texto en el marcado); un recurso de tabla admite table.direction. Un bloque compuesto contra la dirección del documento conserva su propio lado de principio: su sangría, sus marcadores de lista y el final alineado de su última línea pasan al lado por el que empieza su texto.
Un ajuste que nombra un lado se refiere a un lado del texto o del flujo, nunca del pliego, así que un diseño hecho para un libro inglés sigue valiendo cuando el libro pasa a árabe. 'start' y 'end' se aceptan como nombres explícitos:
| Ajuste | 'left' / 'right' | 'start' / 'end' |
|---|---|---|
textAlign del cuerpo, los títulos, los estilos de párrafo, las partes, las notas al pie y el cuerpo de los avisos; align del pie y de su nota | Los lados del texto: 'left' es el lado por el que empieza la línea, la derecha de un párrafo árabe, y allí va la última línea de un párrafo justificado. | Sinónimos de 'left' y 'right'. La configuración resuelta lleva 'left' / 'right'; la guardada conserva lo que se escribió. |
align de una celda de tabla | Los lados del texto de la celda, leídos en la dirección de la tabla (table.direction). | Sinónimos, leídos en la dirección de la tabla. |
placement.align (flotantes, figuras estrechas) | Los lados del flujo: en un libro de derecha a izquierda, 'left' es la derecha del pliego. | Sinónimos. |
stripe.side, icon.cornerSide y labelTab.position de los avisos ('top-start', 'top-end') | Los lados del flujo, los mismos para todas las cajas de la página. | La dirección de la propia caja (un :::callout{dir=ltr} en un libro árabe empieza por la izquierda del pliego). |
| Ranuras de cabecera y pie; elementos de diseño anclados al pliego | Los lados del pliego. | Solo los elementos de texto: el principio y el final de su propia direction. |
placement.rotate conserva su sentido físico en una página espejada: una figura girada en el sentido de las agujas del reloj queda girada así en el pliego. Quien lee la maquetación encuentra el marco espejado en cada página (VDTPage.flow con direction: 'rtl', pageIsMirrored(page)) y el orden visual de los segmentos de cada línea en VDTLine.order; flowToPage y pageToFlow pasan del flujo al pliego y al revés. Véase Composición árabe.
const arabe: PostextConfig = { locale: 'ar' }; // de derecha a izquierda, encuadernado por la derecha
const ingles: PostextConfig = { locale: 'en', direction: 'rtl' }; // forzado; rara vez es lo que quieres#Idiomas y escrituras
Postext compone escrituras alfabéticas que se escriben de izquierda a derecha, y el chino y el japonés a lo ancho de la página y a lo alto. Composición china y Composición japonesa explican cómo se componen y qué ajustes los gobiernan; las claves están en Tipografía de Asia oriental, Escritura vertical y Encuadernación. Lo que recibe cada escritura:
- El chino lo compone el compositor CJK cuando un párrafo tiene más caracteres CJK que espacios entre palabras: sus líneas se cortan entre caracteres con las reglas de principio y final de línea de
cjk.lineBreak(ninguna línea empieza por 。、」 o ー, ninguna termina en 「 o (), mantienen enteros —— y ……, un número con sus signos y una palabra latina, y una línea justificada se ensancha entre sus caracteres hasta la medida. El ancho de la puntuación, la puntuación colgada, el espacio entre chino y latín, la retícula de caracteres, los puntos de énfasis, las marcas de nombre propio y de título, el ruby y las notas warichu siguen la región delocale, a lo largo de la línea horizontal o de la vertical (layout.writingMode: 'vertical-rl'). Un párrafo latino que cita unas pocas palabras CJK conserva la división óptima de líneas y puede cortarse junto a ellas; un signo de apertura o cierre CJK, el punto medio o un signo de ancho completo citados en texto latino (〈h〉, %) no cambian nada. - El japonés pasa por el mismo compositor con reglas propias desde postext 1.16, las de los Requisitos para la composición de textos japoneses del W3C (JLReq) y la JIS X 4051: un
localejada la regiónjapan, cuyos valores automáticos fijan los niveles de kinsoku de JLReq (los kana pequeños y ー nunca abren línea), la puntuación de ancho completo con compresión de parejas, un cuadratín tras ?!, el paréntesis que abre un párrafo en la segunda mitad de la sangría, marcas de énfasis de sésamo sobre el texto, títulos de obras entre 『』, furigana repartidos 1:2:1, contadores japoneses, notas y un índice ordenado por la lectura. Las versiones anteriores componían el japonés con los valores por defecto de China continental. - El coreano pasa por el mismo compositor y se compone sin separación silábica, pero con los valores por defecto de China continental: sus reglas propias (KLREQ) no están implementadas. El coreano se corta entre sílabas además de en sus espacios.
- El árabe y las demás escrituras de derecha a izquierda (persa, urdu, hebreo…) se componen de derecha a izquierda; Composición árabe explica cómo. La
directiondel documento sale de la escritura dellocale, el algoritmo bidireccional de Unicode ordena las palabras latinas y las cifras dentro de cada línea, el libro se encuaderna por la derecha con la primera columna a la derecha, y cada número que escribe el motor toma las cifras de la región. Una palabra con una letra del alfabeto árabe no se divide, no se espacia ni se corta nunca, y una línea árabe justificada se estira en sus espacios y con cachidas. Los signos vocálicos, el énfasis, las notas al pie y las cadenas del árabe están en Texto árabe. El persa, el urdu y el hebreo reciben la dirección, las cifras y las reglas de palabra entera, pero no cadenas integradas propias.
Hay patrones de separación silábica para ocho idiomas (en-us, es, fr, de, it, pt, ca, nl); los tipos de recurso integrados y las cadenas de continuación existen en esos ocho, en chino, en japonés y en árabe. El chino, el japonés, el coreano y las lenguas que se escriben de derecha a izquierda se componen sin separación silábica. Cualquier otro idioma se divide con los patrones del inglés de EE. UU., con un aviso en la consola, y recibe las cadenas inglesas. Para un documento así, fija hyphenation.enabled: false y pasa resourceTypes y las cadenas de continuación de tableStyle en su idioma.
#Texto árabe
Estos ajustes sirven al texto en alfabeto árabe; ninguno cambia un documento escrito en otra escritura. Composición árabe los explica junto con el resto de un libro árabe: dirección, encuadernación, cifras, verso, índice general e índice analítico.
- Signos vocálicos e interlineado. Los signos vocálicos de un texto vocalizado (fatḥa, kasra, shadda, tanwīn, el alif volado, los signos coránicos) se apilan sobre y bajo las letras, en el interlineado, que no crece por ellos. Cada línea con signos anota hasta dónde llega su tinta (
VDTLine.markInk), y el recorte de columna de los renderizadores incluye los signos de la primera y la última línea de cada columna. Cuando un signo sobre una palabra toca las letras o los signos que cuelgan bajo la palabra de encima, la composición avisa del párrafo (arabicMarksExceedLeading, en el panel Revisión del Sandbox). Solo se comparan palabras que están una sobre otra. El texto vocalizado en parte pide unos 1,7–1,85 em delineHeight, y el verso vocalizado del todo 1,9–2,1 em. - Énfasis. La letra árabe no tiene cursiva, así que en un documento cuyo
localese escribe en alfabeto árabe*…*se compone por defecto en negrita (bodyText.emphasis: 'auto').'color'lo compone en redonda conitalicColor, y'overline'traza una raya encima de las palabras, el khaṭṭ fawqī de los libros árabes. El ajuste alcanza todo texto compuesto con las fuentes del cuerpo: párrafos, listas, citas, estilos de párrafo, cuerpo de los recuadros, notas y encabezados. Los pies, las celdas de tabla, el índice general y el índice analítico conservan sus propios ajustes de cursiva. Se elija lo que se elija, el motor nunca inclina letras árabes: las palabras árabes de un tramo en cursiva van en redonda y sus palabras latinas conservan la cursiva. En un documento así, las citas van en redonda por defecto. - Tashkīl.
bodyText.tashkil: 'strip'quita los signos vocálicos y coránicos del texto que se compone, para una edición sin vocales hecha a partir de una fuente vocalizada: fatḥa, ḍamma, kasra y sus tanwīn, sukūn, shadda, el alif volado (هٰذا pasa a هذا) y los signos U+0656–U+065F y U+06D6–U+06ED.'strip-vowels'conserva la shadda, como la imprimen la mayoría de los libros modernos. La hamza y la madda se quedan (أ إ آ son letras, también tecleadas con signos combinantes). La fuente conserva sus signos; las líneas, los encabezados y el índice general se componen sin ellos, y cada carácter compuesto sigue apuntando a su lugar en la fuente. - Notas al pie.
footnotes.markerTemplate: '({n})'escribe las llamadas «(١)» con las cifras del documento,numbering: 'page'las reinicia en cada página ynoteNumberPosition: 'inline'pone sobre la línea el número de la nota. El filete separador y los números de nota quedan al principio de la columna, a la derecha en un libro de derecha a izquierda. - Palabras enteras. Una palabra con una letra del alfabeto árabe nunca se divide, se corta ni se espacia, en un libro árabe o citada en otro. Un estilo que pone
letterSpacinga texto árabe se avisa (joiningScriptLetterSpacing), y una palabra más ancha que su línea la desborda y se avisa (unbreakableWordOverflow). Véase Composición árabe. - Cachida y verso. Una línea árabe justificada se estira con cachidas además de en sus espacios (
bodyText.kashida, véase Cachida en el texto árabe), y un poema clásico se compone un bayt por línea en dos hemistiquios de una misma anchura con:::verse(véase:::verse). - Índice analítico. Un índice en árabe ordena alfabéticamente y no tiene en cuenta el artículo ال (
index.ignoreArticle), los signos vocálicos ni los soportes de la hamza; véase Índice analítico.
#Huérfanas, viudas, runts y reglas de cohesión
Consulta Separación silábica y justificación 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. |
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. |
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. |
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. |
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). Cualquier otro valor se lee como 'item'. |
hyphenateAcrossColumns | boolean | 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. 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). '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). Un marginBottom negativo sube el bloque siguiente en los dos casos. |
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.
#Encabezados
La propiedad headings controla la tipografía de todos los niveles de encabezado (H1–H6). Puedes establecer valores generales por defecto que aplican a todos los niveles, y después sobrescribir propiedades específicas por nivel.
#Valores generales por defecto
| Propiedad | Tipo | Por defecto | Descripción |
|---|---|---|---|
fontFamily | string | 'Open Sans' | Familia tipográfica para todos los encabezados. |
lineHeight | Dimension | 1.2 em | Altura de línea para encabezados. Más ajustada que el cuerpo de texto. |
color | ColorValue | Color principal (#295AA3) | Color del texto de encabezado. Enlazado a la entrada main-color de la paleta por defecto, de modo que cambiar ese color retintea todos los encabezados. |
textAlign | 'left' | 'justify' | 'center' | 'right' | 'start' | 'end' | 'left' | Alineación de todos los niveles de encabezado (no hay un valor por nivel): en bandera, justificada, centrada o alineada a la derecha. Un encabezado justificado compone su última línea a la izquierda, como un párrafo, así que un encabezado de una sola línea se ve como 'left'. Canvas, HTML y PDF colocan las líneas del mismo modo, prefijo de numeración incluido. La apertura por defecto de un encabezado span: 'page' sin diseño avanzado la sigue también (justificada queda a la izquierda); un diseño avanzado alinea sus propios elementos de texto con su align. |
fontWeight | number | 700 | Peso de fuente para encabezados (100–900). |
marginTop | Dimension | 1.5 em | Espacio sobre los encabezados. |
marginBottom | Dimension | 0.5 em | Espacio bajo los encabezados. |
keepWithNext | boolean | true | Cuando es true, un encabezado nunca se coloca como último elemento de una columna o página. Si el siguiente bloque no tuviera al menos bodyText.widowMinLines líneas de hueco tras el encabezado (o una línea cuando bodyText.avoidWidows es false), el encabezado se empuja hacia delante para quedar unido a su texto. Interactúa con bodyText.keepColonWithList: si esa regla tiene que empujar el párrafo de dos puntos por completo, los encabezados que lo preceden en la columna viajan con él en vez de quedar varados. |
keepWithNextSpread | boolean | false | Con keepWithNext, deja aun así que un encabezado cierre la última columna de texto de una página par, porque su texto abre entonces la página impar de enfrente, en el mismo pliego (JLReq §4.1.7). Los pliegos son la página 1 sola y después 2–3, 4–5…, contados con pageIndexOffset, tanto en libros encuadernados por la izquierda como por la derecha. Desde postext 1.16. |
keepWithNextSplit | 'rules' | 'fill' | 'rules' | Cómo se divide el párrafo que sigue a un encabezado cuando el encabezado queda al pie de una columna y empujar el párrafo entero lo dejaría atrás. 'rules': todas las líneas que quepan, siempre que queden al menos bodyText.widowMinLines bajo el encabezado y pasen al menos bodyText.orphanMinLines a la columna siguiente; si ninguna división cumple las dos cosas, el encabezado pasa a la columna siguiente con su párrafo, y el equilibrado de columnas rellena el hueco que deja. 'fill': todas las líneas que quepan, aunque pasen muy pocas, así que un párrafo de cuatro líneas con sitio para tres se divide 3 + 1. Hasta postext 1.4 todos los encabezados se dividían así, y las configuraciones guardadas antes de configVersion 8 lo conservan (ver Paquetes escritos por postext 1.4 o anterior). Con avoidWidows o avoidOrphans desactivado, esa parte de la regla no se aplica. |
snapToGrid | boolean | true | Si el flujo vuelve a la retícula base bajo un título. Con true el marginBottom del título se redondea a líneas enteras de la retícula; con false se conserva el margen exacto y el texto bajo el título puede quedar fuera de la retícula hasta el siguiente punto de ajuste (el final de una lista, la cola de un :::paragraphs, una ecuación) — como muchos libros, que dejan línea y media bajo el título. Un nivel (levels[].snapToGrid) o un estilo de encabezado pueden fijar su propio valor; este es el que heredan. |
inlineMarks | boolean | true | Si un encabezado lee sus marcas en línea como lo hace un párrafo: cursiva, negrita, ^superíndice^, ~subíndice~, :smallcaps[…] y enlaces. Un tramo en cursiva invierte la inclinación del encabezado, así que en un encabezado en cursiva sale en redonda; un tramo en negrita toma bodyText.boldFontWeight, o el peso del propio encabezado si es mayor. El índice también recoge los tramos en negrita y en cursiva; los titulillos y los marcadores del PDF imprimen solo el texto. Con false se quitan los marcadores y las palabras se imprimen con el estilo del encabezado, como hasta postext 1.4. La apertura por defecto de un encabezado span: 'page' sin diseño compone también los tramos en negrita, en cursiva, en superíndice y en subíndice; el diseño de un encabezado (una banda de apertura con diseño o un advancedDesign de columna) imprime como texto sin marcas en ambos casos, salvo que su elemento de texto lea las marcas en línea (inlineMarks: true): entonces conserva los tramos en negrita, en cursiva y en índice del encabezado (desde postext 1.19). Las configuraciones guardadas antes cuyos encabezados llevan marcas se leen con false (ver Paquetes escritos por postext 1.4 o anterior). |
balancing | ColumnBalancingConfig | activado | Equilibrado vertical de columnas — espacio adicional sobre los encabezados para que las columnas terminen alineadas con el pie de página. Ver más abajo. |
Encabezados centrados para poemas o los actos de una obra de teatro, sin ranura de diseño:
headings: {
textAlign: 'center',
levels: [{ level: 2, textTransform: 'uppercase' }],
}Un objeto headings conserva todos los valores por defecto de nivel que no repitas, incluido el salto de página de H1 (ver Configuración por nivel).
#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:
- 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 conclosingBox: 'off'no se mueve nunca. - Imágenes con zona segura — una imagen con zona segura (
Resource.safeArea, véase Formato del documento › 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 comoflexFigure. No tiene ajuste propio: solo crece una imagen cuyo recurso marca una zona segura. - 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
h2recibe más que unh3). 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. - 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.
- Párrafos corridos — como último recurso, se recompone un párrafo de la columna con una línea más (el
\looseness=+1de 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 debodyText.maxWordSpacing— el color tipográfico nunca supera el límite que ya tengas configurado. RequierebodyText.optimalLineBreaking.
En una retícula de caracteres (cjk.grid, véase Composición china › 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, 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. |
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. |
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. |
maxLinesAfterFloat | number | 1 | Número máximo de líneas de rejilla adicionales bajo un mismo flotante superior. |
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. |
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.
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).
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#Configuración por nivel
Cada nivel de encabezado puede sobrescribir los valores generales a través del array levels. Solo fontSize (más el breakBefore de H1, indicado abajo) difiere por defecto — todas las demás propiedades se heredan de la configuración general de encabezados.
| Nivel | Tamaño de fuente por defecto | breakBefore por defecto |
|---|---|---|
| H1 | 18 pt | { enabled: true, parity: 'always-odd' } |
| H2 | 15 pt | { enabled: false, parity: 'any' } |
| H3 | 12 pt | { enabled: false, parity: 'any' } |
| H4 | 10 pt | { enabled: false, parity: 'any' } |
| H5 | 9 pt | { enabled: false, parity: 'any' } |
| H6 | 8 pt | { enabled: false, parity: 'any' } |
El valor por defecto de H1 reproduce la maqueta clásica de un libro: cada encabezado de nivel superior se abre en una página derecha (impar) nueva, con una página separadora en blanco obligatoria que cierra el capítulo anterior. Anula levels[0].breakBefore si tu documento es más plano que un libro.
El breakBefore de un nivel se combina campo a campo con ese valor por defecto, y un objeto headings que no lo menciona lo conserva. { parity: 'odd' } en H1 mantiene el salto y solo cambia la paridad; { enabled: false } deja que los capítulos vayan seguidos:
headings: {
fontFamily: 'Merriweather', // H1 sigue saltando a una página impar nueva (always-odd)
levels: [{ level: 1, breakBefore: { parity: 'odd' } }], // …o: a una impar, sin página en blanco obligatoria
}
headings: { levels: [{ level: 1, breakBefore: { enabled: false } }] } // capítulos seguidosCambia en postext 1.5. Hasta postext 1.4, cualquier objeto headings desactivaba el salto de H1 salvo que se repitiera levels[0].breakBefore, y un breakBefore parcial completaba el campo que faltaba con el valor sin salto. Por eso una configuración escrita en código para la 1.4 con un objeto headings y sin salto de H1 abre ahora cada capítulo en una página impar nueva, con páginas pares en blanco donde haga falta. Para que los capítulos sigan yendo seguidos, basta un campo en la entrada de H1 de levels:
headings: { fontFamily: 'Merriweather', levels: [{ level: 1, breakBefore: { enabled: false } }] } // como lo componía la 1.4Donde la configuración estaba guardada, el motor puede saberlo y lo hace por ti: el Sandbox con los libros y las configuraciones que guardó entonces (ver Sandbox → Persistencia), y openBundle / readBundle con un paquete .postext escrito por postext 1.4 o anterior (ver Paquetes escritos por postext 1.4 o anterior). Una configuración que guardaste tú puede pasar por migrateConfig(config) de postext/bundle, que escribe los saltos tal como los componía la 1.4 (pinLegacyHeadingBreaks): enabled: false en un H1 que no tenía salto, y parity: 'any' junto a un enabled: true que no indicaba paridad, en H1 y en los estilos de encabezado. También fija el tamaño de las fórmulas, el espacio en torno a las figuras en línea (también en los recuadros), las marcas en línea de los encabezados, el tamaño de las letras capitales, el sitio bajo una línea de dos puntos que introduce una lista, las líneas que deja de un párrafo o de un elemento de lista el corte de una caja, los cortes de línea tras una raya, la composición línea a línea del texto en bandera, la división de un párrafo bajo un encabezado, los cortes de línea tras el guion de un compuesto y el espacio bajo los contenedores :::paragraphs, tal como los componía la 1.4. Si le pasas el markdown del libro como tercer argumento, { content }, omite la fijación de las fórmulas cuando el texto no tiene ningún $, las de los huecos cuando ninguna línea inserta un recurso (la del hueco en los recuadros cuando ninguna lo hace dentro de un recuadro), la de las marcas cuando ningún encabezado lleva ninguna, la de los dos puntos cuando ninguna lista sigue a una línea que termina en dos puntos, la del corte de las cajas cuando el texto no abre ningún :::callout, la de las rayas cuando ninguna raya va entre palabras sin espacios, la de la división bajo un encabezado cuando el texto no tiene ningún encabezado, la de los contenedores cuando el texto no abre ningún contenedor :::paragraphs, y la de los compuestos cuando ningún guion va entre dos letras; la del texto en bandera solo se aplica a una configuración que pone en bandera algún texto corrido, y la de los contenedores solo a una que declara algún estilo de párrafo (ver Paquetes escritos por postext 1.4 o anterior). Para fijar solo los saltos, llama a pinLegacyHeadingBreaks(config).
Las configuraciones por nivel soportan las mismas propiedades que los valores generales — fontSize, lineHeight, fontFamily, color, fontWeight, marginTop, marginBottom, snapToGrid — más estos campos exclusivos de cada nivel (un estilo de encabezado también los admite):
| Propiedad | Tipo | Por defecto | Descripción |
|---|---|---|---|
italic | boolean | false | Renderiza el encabezado en cursiva. Se combina con el fontWeight. |
textTransform | 'none' | 'uppercase' | 'none' | Pasa a mayúsculas el título del encabezado (el prefijo de numeración se conserva tal cual, igual que un chip o la etiqueta de una :ref que haya en él). Conserva la longitud del texto para que el mapa de origen del editor siga siendo 1:1: los caracteres cuya mayúscula se expande (ß → SS) se dejan como están. El título transformado alimenta también el marcador {titleText} de los diseños avanzados y los abridores de capítulo. Los marcadores del PDF conservan el título tal como se escribió —Contribuciones de los autores, no CONTRIBUCIONES DE LOS AUTORES—, igual que text-transform en CSS no toca el texto en sí (hasta postext 1.4 salían en mayúsculas). |
letterSpacing | Dimension | 0 | Espaciado entre letras tras cada glifo del encabezado —espacios y prefijo de numeración incluidos—, como letter-spacing en CSS. Un valor positivo abre las letras (las versales compuestas con textTransform: 'uppercase' suelen pedir un poco: { value: 0.12, unit: 'em' }); uno negativo aprieta un cuerpo de titular. Un valor en em es relativo al fontSize del nivel. Las líneas del encabezado se miden con él, de modo que cortan donde acaba el texto espaciado, y canvas, HTML y PDF lo pintan igual. Una línea centrada o alineada a la derecha se coloca por sus letras: el espaciado que sigue a su último glifo no cuenta, como en el texto de los diseños, así que un encabezado centrado queda alineado con la apertura por defecto de un encabezado span: 'page'. Un nivel dibujado con su advancedDesign lo ignora, como los demás campos tipográficos de esta tabla: cada elemento de texto del diseño tiene su propio letterSpacing. Un estilo de encabezado también puede fijarlo, para los encabezados que lo usan. Hasta postext 1.4 los encabezados no tenían espaciado entre letras, y la clave se descartaba sin aviso. |
lineSpan | number | sin fijar | Líneas que ocupa (行取り, JLReq §4.1.6): el encabezado se compone en una banda de ese número de líneas del texto, con sus caracteres centrados en ella, en lugar de marginTop y marginBottom; 3 es un encabezado 3行取り. La banda empieza en una línea del texto cuando el encabezado se ajusta a la rejilla, y el texto que lo sigue se queda en la rejilla, en los dos modos de escritura y con cjk.grid; un encabezado cuyas líneas necesitan más toma el siguiente número entero. El centro es el de los caracteres (la línea base menos el centro ideográfico de la fuente), como lo mide JLReq, no el de las cajas de línea. No se aplica a las aperturas (span: 'page'), a los encabezados dibujados con un advancedDesign, a los encabezados ocultos ni a los encabezados dentro de recuadros. Un estilo de encabezado puede fijar 0 para quitar el de su nivel. Desde postext 1.16. |
indent | Dimension | 0 | Sangría del encabezado desde el principio de la línea (字下げ), con em igual al cuerpo del texto, porque los libros japoneses cuentan las sangrías de los títulos en caracteres del texto (JLReq §4.1.3): { value: 6, unit: 'em' } es 6字下げ sea cual sea el cuerpo del encabezado. La medida se estrecha en esa cantidad, y un encabezado centrado se centra en lo que queda. Desde postext 1.16. |
firstLineIndent | Dimension | 0 | Sangría solo de la primera línea del encabezado, contada desde indent y, como ella, en cuadratines del texto: las líneas siguientes de un encabezado largo empiezan en indent (al principio de la línea si no se fija), como la GB/T 9704 compone todos los niveles de título dos caracteres adentro con las líneas siguientes al margen: { value: 2, unit: 'em' }. Con cjk.grid activado, dos cuadratines del texto son dos celdas de la retícula. Un encabezado numerado imprime su número después de la sangría, así que la plantilla de numeración no necesita espacios ideográficos, que se imprimirían también en el índice y en los marcadores del PDF. Funciona en texto vertical (desde la cabeza de la línea), con el compositor CJK (un paréntesis de apertura al principio del encabezado sigue las reglas de principio de línea, como en un párrafo) y con Knuth–Plass. Un encabezado centrado la toma como un párrafo centrado: su primera línea se centra en lo que queda después de la sangría. {firstLineIndent=N} tras el título de un encabezado la fija para ese encabezado, y {firstLineIndent=0} quita la de su nivel. Desde postext 1.24. |
jidori | number | sin fijar | Espaciado uniforme (字取り): un encabezado de una línea más estrecho que ese número de sus cuadratines propios se espacia por igual hasta medir exactamente ese ancho, así que 3 compone 序章 como 序 章. Los títulos más anchos y los encabezados de varias líneas se quedan como están. {jidori=N} tras el título de un encabezado lo fija para ese encabezado, y {jidori=0} desactiva el de su nivel. Desde postext 1.16. |
dropCap | ParagraphDropCap | false | ninguno | Una capitular que abre el primer párrafo de cuerpo tras un encabezado de este nivel (ver Letras capitulares): con un solo ajuste, cada capítulo tiene su capitular. Un encabezado la quita con {dropcap=false} o fija sus líneas con {dropcap=2}. Desde postext 1.23. |
numberingTemplate | string | '' | Plantilla del número automático del nivel. Un token … imprime el contador acumulado de ese nivel de encabezado, opcionalmente formateado con un sufijo — romanos en mayúscula, romanos en minúscula, / alfabético, con cero a la izquierda, con letras (veintiuno), como ordinal (vigesimoprimero), en numerales chinos (japoneses en un documento japonés: 第百一章), cifra a cifra, en numerales financieros y en círculo, o cualquier nombre de Grafías de los formatos de numeración — y el resto del texto es literal ('Capítulo . ', '.', '第回' para 第一百二十回; una barra invertida escapa una llave literal). Un token cuyo contador aún está vacío se pliega junto con el separador contiguo. Vacía (el valor por defecto) significa sin número automático. El número resultante se antepone al título en el flujo, alimenta el marcador de una ranura de diseño avanzado (donde el prefijo no se antepone) y se imprime en el índice de contenidos. Ver Números con letras para las palabras, y Estilos de encabezado para dar a algunos encabezados de un nivel una plantilla propia. |
numberSeparator | string | ' ' | Lo que separa el número del título: en la columna, en la apertura por defecto de un nivel span: 'page', en los titulillos que imprimen la línea del encabezado y en los marcadores del PDF. El separador del nivel 1 une también el número y el título de una parte en la página de parte y en la fila de parte del índice de contenidos cuando no tienen diseño propio. Los capítulos chinos llevan un espacio ideográfico o nada (' ': 第一回 甄士隱夢幻識通靈). El índice de contenidos conserva su propia columna de números (toc.levels[].numberGap). Un estilo de encabezado puede fijar el suyo. Cuando un título se parte en dos con , como los títulos pareados de las novelas chinas, las formas de una sola línea (la columna, el índice de contenidos, los titulillos) unen las dos mitades con un espacio ideográfico si a ambos lados hay caracteres chinos o japoneses, y con un espacio en los demás casos. |
numberPosition | 'before' | 'replace' | 'before' | Dónde va el número generado. 'before': delante del título, unido por numberSeparator. 'replace': el número es el título entero y el título escrito en el texto fuente no se imprime, así que # Noche con numberingTemplate: 'الليلة {1:ordinal-feminine}' imprime الليلة الثانية. El índice general lista el número como título de la entrada (sin columna de número), y las cabeceras (, ) y los marcadores del PDF también lo leen; queda vacío en ese título. Solo para títulos numerados con plantilla (la del nivel o la de su estilo); los demás conservan su título. Un estilo de título puede fijar el suyo, 'before' para conservar los títulos que su nivel sustituiría. |
breakBefore | HeadingBreakBeforeConfig | H1: { enabled: true, parity: 'always-odd' }H2–H6: { enabled: false, parity: 'any' } | Fuerza un salto de página antes de cada encabezado de este nivel. parity: 'odd' / 'even' restringe además en qué lado del pliego se abrirá — se inserta una página en blanco de relleno cuando sea necesario (sigue contando para la numeración). 'always-odd' / 'always-even' garantizan además al menos una página separadora en blanco obligatoria entre el contenido anterior y el nuevo encabezado (la separadora pertenece al capítulo anterior; cualquier relleno de paridad adicional pertenece al nuevo). Cuando el encabezado es el primer bloque del documento y la primera página sigue vacía, la imposición de paridad se omite — el encabezado aterriza en la página 1 tal cual. Un campo sin definir conserva el valor por defecto del nivel: { parity: 'odd' } en H1 sigue saltando. |
hidden | boolean | false | Un encabezado estructural: no imprime nada ni ocupa espacio en la columna ni dentro de una caja :::callout — ni texto, ni márgenes, ni banda de apertura —, pero hace todo lo demás que hace un encabezado. Su breakBefore sigue abriendo página, abre la sección de su estilo, cuenta (salvo que su estilo diga numbered: false) y aparece en :::toc, en las cabeceras con y en los marcadores del PDF. Para una dedicatoria, una página de epígrafe o un colofón que el índice y los marcadores del lector necesitan, pero que la página no muestra. Mejor en un estilo de encabezado que en un nivel entero; un encabezado lo sobrescribe con / . |
headings: {
fontFamily: 'Merriweather',
levels: [
// Preajuste canónico de libro: los capítulos se abren en la página derecha (impar).
{ level: 1, fontSize: { value: 24, unit: 'pt' }, breakBefore: { enabled: true, parity: 'odd' } },
{ level: 2, fontSize: { value: 18, unit: 'pt' }, italic: true },
]
}snapToGrid también funciona por nivel. Sin fijar, un nivel sigue a headings.snapToGrid; fijado, lo sustituye — así un mismo documento puede dejar sus H2 a línea y media de su texto, fuera de la retícula hasta el siguiente punto de ajuste, mientras sus H3 redondean el espacio inferior a líneas enteras de la retícula. Un estilo de encabezado también puede fijarlo, para los encabezados que lo usan.
headings: {
marginBottom: { value: 1.5, unit: 'em' },
levels: [
{ level: 2, snapToGrid: false }, // exactamente 1,5 em bajo cada H2
{ level: 3 }, // hereda headings.snapToGrid: true
],
}#Saltar antes
breakBefore es ortogonal a los controles de numeración: activarlo fuerza un salto de página, pero el contador numérico solo se reinicia cuando insertas explícitamente una directiva :::numbering. Las páginas de relleno por paridad cuentan como páginas reales en la secuencia y reciben encabezados/pies según sus reglas normales de impar/par.
Un :::pagebreak justo antes de uno de estos encabezados no sustituye a su salto: el encabezado aplica igualmente su paridad tras la página que abrió la directiva, lo que puede añadir una página en blanco. Véase Estilos de encabezado para un encabezado que deba empezar justo después de un salto manual.
Valores de paridad
| Valor | Comportamiento |
|---|---|
'any' (por defecto) | Sin restricción de paridad. El encabezado simplemente se abre en la siguiente página. |
'odd' | Garantiza que el encabezado se abra en una página impar (lado derecho). Solo se inserta una página en blanco si la siguiente página natural sería par. |
'even' | Igual pero para una página par (lado izquierdo). |
'always-odd' | Garantiza al menos una página separadora en blanco obligatoria entre el contenido anterior y el nuevo encabezado, y después fuerza la paridad impar. Útil cuando cada capítulo debe empezar un pliego nuevo. |
'always-even' | Igual pero para una página par. |
Pertenencia de las páginas en blanco
Las páginas en blanco que inserta breakBefore reciben el encabezado {chapterTitle} en función del motivo de su inserción:
- Las páginas insertadas para satisfacer una restricción de paridad (
'odd','even', o la cola de paridad de'always-*') pertenecen al capítulo entrante. Su marcador{chapterTitle}resuelve al título del nuevo capítulo — porque la página en blanco solo existe para empujar al nuevo capítulo hasta la paridad correcta. - La página separadora obligatoria que inserta
'always-odd'/'always-even'pertenece al capítulo anterior. Es una pausa de cierre de capítulo deliberada, así que{chapterTitle}sigue mostrando el título del capítulo saliente.
Las cabeceras y la paleta de una sección con estilo (véase Estilos de encabezado) siguen las mismas dos reglas en las páginas en blanco.
Excepción al inicio del documento
Cuando el primer bloque del documento es un encabezado con breakBefore activado — o la fuente empieza con :::pagebreak —, la imposición de paridad se omite mientras la primera página siga vacía. El encabezado aterriza en la página 1 tal cual, independientemente de la paridad configurada, de modo que un documento que comienza con # Capítulo 1 con parity: 'odd' no arrastra una página en blanco inicial innecesaria. Una vez que se ha colocado cualquier contenido, la imposición de paridad funciona de forma habitual.
#Span y diseño avanzado
Cada nivel de encabezado admite dos campos adicionales que controlan cómo se renderiza el encabezado como apertura de capítulo a página completa.
| Propiedad | Tipo | Predeterminado | Descripción |
|---|---|---|---|
span | 'column' | 'page' | 'column' | Cuando es 'page', el encabezado se trata como apertura de capítulo y su diseño avanzado (si está habilitado) se adjunta a la página como una banda de apertura por encima del cuerpo. Combínalo con breakBefore.enabled: true para que la apertura comience fiablemente en una nueva página. Sin un diseño propio, el título lo pinta una apertura por defecto a lo ancho de toda la caja de texto, con la tipografía y el interlineado del nivel y con sus tramos en negrita, en cursiva, en superíndice y en subíndice (headings.inlineMarks), y la banda se mide a ese ancho. La banda reserva todas las líneas que pinta la apertura: si esta ocupa más líneas que la medida del propio encabezado (un título justificado cuyos espacios cabrían apretados en una línea, un salto forzado ), la banda también las toma. Hasta postext 1.4 la banda se medía con el título ajustado al ancho de la columna, así que un título que cabe en una línea a lo ancho de la caja ocupaba una banda de dos líneas, con la línea centrada en ella. Las demás columnas empiezan bajo la banda como la columna del propio encabezado. El texto que abre una de ellas empieza donde empezaría el texto justo debajo de la apertura, venga lo que venga después de la apertura en su columna: el marginBottom de la apertura por debajo de su título o de su diseño, llevado a la línea siguiente de la retícula cuando el nivel se ajusta a ella. Un encabezado, una fórmula en bloque o una entrada del índice que abre una de ellas queda a la altura del primer encabezado o fórmula en bloque que hay bajo la apertura, con los márgenes que tiene allí; si la columna de la apertura sigue con otra cosa, empieza donde empieza ese texto. Un encabezado oculto bajo la apertura no cuenta, y el espacio que el equilibrado de columnas añade encima del encabezado que hay bajo la apertura no se repite en las demás columnas. Lo que esas columnas ajustan a la retícula cae en la retícula de la página. Hasta postext 1.4 su primer bloque quedaba en el pie de la banda: fuera de la retícula cuando la banda acababa entre dos líneas, y pegado a la banda, sin margen, cuando a la apertura la seguía un encabezado (una línea más arriba que ahora si la banda acababa en la retícula); además, un encabezado ahí perdía el margen superior que conservaba el de la primera columna. |
spanBreak | boolean | true | Si un encabezado span: 'page' empieza una página nueva. true abre la página siguiente (con el lado que elija breakBefore). false, con breakBefore.enabled: false, lo abre donde llega el texto, como un recuadro de página: las columnas de encima terminan a la misma altura (la banda se equilibra cuando headings.balancing.trailing está activo), el diseño del encabezado o la apertura por defecto se compone a todo el ancho de la caja bajo ellas y el texto sigue en todas las columnas por debajo: el segundo artículo de un boletín bajo el final del primero. Si el espacio que queda no da para el encabezado y el mínimo de líneas viudas bajo él, abre la página siguiente como con true. El papel de la página sigue siendo el que le da su primer bloque. No afecta a un encabezado span: 'column'. También en un estilo de encabezado. Desde postext 1.19. |
advancedDesign | HeadingAdvancedDesignConfig | | Ranura de diseño de composición libre para este nivel. Cuando está enabled, los elementos de la ranura componen la apertura. Utiliza dentro de un elemento de texto para renderizar el texto del título; , , etc. para insertar el número del encabezado. |
advancedDesign.minHeight | Dimension | — | Altura mínima reservada para el encabezado en el flujo de la columna. El encabezado ocupa max(fondo del contenido del diseño, minHeight) y, debajo, el marginBottom del encabezado (el de su estilo de encabezado, el de su nivel o headings.marginBottom; 0,5 em del cuerpo del encabezado si ninguno fija otro); la suma se redondea hacia arriba a la rejilla base cuando los encabezados se ajustan a ella. Así una apertura puede empujar el cuerpo hacia abajo (o reclamar la página entera) aunque sus elementos sean bajos o estén anclados a los marcos de página/sangre por encima del encabezado. Para una franja de exactamente minHeight, pon ese marginBottom a 0 y da a minHeight un número entero de líneas de la rejilla. Se aplica siempre que enabled sea true, incluso con la ranura vacía. Ver Altura reservada para saber qué cuenta en el fondo del contenido del diseño. |
Una apertura tan alta como la página. Cuando la altura reservada llega más allá del pie de la columna — una portada cuyo minHeight es la altura de la página, una imagen o una caja anclada a la página o a la sangre que baja hasta el corte —, la apertura reclama el resto de la página: el texto que la sigue empieza en la página siguiente, igual en todas las columnas de una disposición a dos columnas o de columna y media. Por eso una portada no necesita un :::pagebreak detrás (ponerlo no hace daño: no añade ninguna página en blanco). Un encabezado de columna (span: 'column') cuyo diseño es más alto que su columna reclama esa columna, y el texto empieza en la cabeza de la siguiente. El bloque del encabezado baja entonces hasta el pie de la columna que reclama, y su diseño se compone contra esa banda: los elementos anclados arriba se quedan donde están anclados, y los que siguen a la banda —anclados a su centro o a su pie, o con altura 'fill'— se ajustan al espacio que reclama el encabezado, igual que se ajustan a la altura reservada cuando cabe (hasta postext 1.4 el bloque conservaba la altura de su texto, de modo que esos elementos se componían contra una banda de la altura del título, y el texto que lo seguía se colaba bajo el diseño). Los adornos de página que no deben reclamarla — una franja a lo largo de todo el corte delantero, un ornamento al pie de la página — van en el diseño de la cabecera o del pie: anclados a 'page' o a 'bleed' y mostrados con pages: 'opener', se pintan en la página de apertura sin reservar espacio del cuerpo.
Ejemplo — una apertura de capítulo minimalista que muestra «Capítulo N» encima del título:
{
"headings": {
"levels": [
{
"level": 1,
"span": "page",
"breakBefore": { "enabled": true, "parity": "always-odd" },
"advancedDesign": {
"enabled": true,
"slot": {
"elements": [
{
"kind": "text",
"id": "chapterLabel",
"placement": {
"anchor": { "to": "container", "edge": "top" },
"offset": { "y": { "value": 48, "unit": "pt" } },
"size": { "width": "fill" }
},
"content": "Capítulo {numberRoman}",
"fontSize": { "value": 10, "unit": "pt" },
"align": "center",
"overflow": "ellipsis-end"
},
{
"kind": "text",
"id": "chapterTitle",
"placement": {
"anchor": { "to": "#chapterLabel", "edge": "below" },
"offset": { "y": { "value": 12, "unit": "pt" } },
"size": { "width": "fill" }
},
"content": "{titleText}",
"fontSize": { "value": 24, "unit": "pt" },
"fontWeight": 700,
"align": "center",
"overflow": "wrap",
"hyphenate": true
}
]
}
}
}
]
}
}Marcadores disponibles dentro de una ranura de diseño de encabezado:
{titleText}— texto plano del encabezado (sin prefijo numérico). Un salto forzado en el título (\\) es aquí un salto de línea, tanto en una banda de apertura como en un diseño dentro de la columna (hasta postext 1.4 un diseño dentro de la columna imprimía un espacio, aunque su altura se medía con el salto). Las líneas en que el encabezado oculto se reparte en su columna se vuelven a unir en el título tal como está escrito: una palabra cortada tras su propio guion conserva el guion y no lleva espacio detrás, una palabra que la columna dividió vuelve a quedar entera, sin el guion que añadió el corte, un grupo unido por un espacio de no separación que no cabía en la columna y se partió en ese espacio lo recupera (Capítulo XVIII, noCapítuloXVIII), y cada uno de los demás cortes devuelve su espacio. Hasta postext 1.4 cada salto de línea se convertía en un espacio, así que un título partido en un guion imprimíaWord- Book, y en ese título se perdía un salto forzado.{number}— número formateado segúnnumberingTemplate.{numberDecimal},{numberRoman},{numberRomanLower},{numberAlpha},{numberAlphaLower}— el contador del encabezado (la cuenta acumulada de su nivel, imprima lo que imprima la plantilla) en otros formatos de numeración: el tercer capítulo da3,III,iii,C,c, con o sinnumberingTemplate. Un encabezado sin numerar (un estilo connumbered: false) los deja vacíos.{numberWords},{numberWordsLower},{numberOrdinalWords},{numberOrdinalWordsLower}— el mismo contador con letras, con mayúscula inicial o en minúscula: Tres / tres, Tercero / tercero (ver Números con letras).{numberHan}— el mismo contador en numerales chinos, en la escritura dellocaledel documento: una apertura compuesta con第{numberHan}回imprime 第十二回 en el duodécimo capítulo mientras el índice muestra12.{chapterNumber},{chapterTitle},{pageNumber},{totalPages},{bookTotalPages},{title},{subtitle},{author},{publishDate}— metadatos compartidos.{attr.<clave>}— un atributo escrito en la propia línea del encabezado (# Título {author="I. Zango Martín"}), con el atributo del H1 del capítulo actual como respaldo. Los atributos ausentes se resuelven como cadena vacía sin aviso.
{chapterNumber} imprime lo mismo que las cabeceras para ese capítulo: el número del H1 cuando su nivel (o su estilo) tiene numberingTemplate; si no, el ordinal del capítulo —1, 2…, continuando tras los capítulos maquetados antes que este—, y nada para un capítulo sin numerar o un estilo cuya plantilla es ''. El diseño de un encabezado lee el capítulo al que pertenece su encabezado: uno de nivel 1, el suyo; uno de nivel inferior, el del último encabezado de nivel 1 anterior. Así es también cuando dos capítulos coinciden en una página, aunque las cabeceras de esa página impriman el segundo. La altura que reserva una apertura se mide con ese mismo valor. Hasta postext 1.4 se medía con el prefijo numérico del encabezado (vacío sin plantilla), así que un diseño cuya altura dependiera de {chapterNumber} podía pintarse más alto que el espacio que había reservado; y el diseño imprimía el capítulo de la página, de modo que el primero de dos capítulos que compartían página mostraba el número del segundo.
Los marcadores del contador siguen al libro a lo largo de los capítulos compuestos uno a uno (los contadores que entrega continuationAfter()), y el atributo startAt de un encabezado los reinicia (ver Formato de documento → Atributos de encabezado). Una apertura que dice Capítulo III sobre un título numerado 3. en el flujo y en el índice:
{
level: 1,
span: 'page',
numberingTemplate: '{1}.',
advancedDesign: {
enabled: true,
slot: { elements: [
{ kind: 'text', id: 'label', content: 'Capítulo {numberRoman}', fontSize: { value: 10, unit: 'pt' }, overflow: 'ellipsis-end',
placement: { anchor: { to: 'container', edge: 'top-left' }, size: { width: 'fill', height: 'auto' } } },
{ kind: 'text', id: 'title', content: '{titleText}', fontSize: { value: 24, unit: 'pt' }, overflow: 'wrap',
placement: { anchor: { to: '#label', edge: 'below' }, size: { width: 'fill', height: 'auto' } } },
] },
},
}Altura reservada
Un encabezado con diseño avanzado ocupa espacio en la columna como cualquier bloque: el texto de cuerpo que lo sigue empieza debajo de ese espacio. El espacio es la mayor de tres alturas, todas medidas hacia abajo desde la parte superior del encabezado (la parte superior del área de contenido en una apertura que empieza su página):
- el propio texto del encabezado, con la tipografía del nivel (queda oculto bajo el diseño, pero conserva sus líneas);
- el fondo del contenido del diseño: el borde inferior más bajo entre los elementos que cuentan (ver abajo);
advancedDesign.minHeight.
A continuación se suma el marginBottom del encabezado (el de su estilo de encabezado, el de su nivel o headings.marginBottom; 0,5 em si ninguno fija otro) y el resultado se ajusta hacia arriba a la rejilla base cuando los encabezados se ajustan a ella. En una apertura (span: 'page') la misma franja queda libre en todas las columnas de la página. En un encabezado de columna que no la desborda, el diseño se compone dentro de la caja del encabezado, que tiene exactamente esa altura.
Qué elementos cuentan. Cuentan todos los elementos del diseño —textos, filetes, cajas e imágenes por igual (hasta postext 1.4 un elemento image nunca contaba, así que el texto podía empezar encima de una imagen de banda si minHeight no lo impedía)—, salvo:
- los que tienen
reserve: false: decoración que puede quedar bajo el texto; - los que siguen a la propia franja: los anclados a la fila central del contenedor (
left,center,right) o a la inferior (bottom-left,bottom,bottom-right), los que tienen una altura'fill'respecto al contenedor (una caja o una línea vertical sin altura lo rellenan por defecto) y cualquier elemento anclado a uno de ellos. El contenedor es la franja reservada, así que estos elementos se apoyan en su pie o la abarcan: una línea bajo la franja, un panel de color tras el título. Siguen a la altura; nunca la fijan. Un texto de entre ellos que conserva su propia altura sí necesita sitio: un título anclado al pie de la franja hace que la franja mida al menos lo que el título, de modo que nunca empieza por encima del borde superior del encabezado. ConminHeight: 36mmy el título anclado enbottom-left, la caja del encabezado mide 36 mm más sumarginBottom, ajustada hacia arriba a la retícula, y el título queda al pie de esa caja, justo encima del texto que sigue; sinminHeight, un título que ocupa más líneas que el texto del propio encabezado hace la franja tan alta como el título. Hasta postext 1.4 ese título se pintaba hacia arriba, sobre el texto que precede al encabezado. Las cajas, los filetes y las imágenes que siguen a la franja no fijan ese mínimo, así que un panel anclado al pie puede sobresalir por encima del encabezado.
Los elementos anclados a la página o al sangrado cuentan según cuánto bajen por debajo de la parte superior del encabezado. Una banda en lo alto de la página que termina por encima del encabezado no cuenta nada; una imagen a sangre que lo sobrepasa empuja el texto hasta su borde inferior. Lo mismo ocurre con todo lo que está abajo en la página: un sello a 25 mm del pie, una banda lateral a toda altura o un marco reservan la página hasta su borde inferior, y el texto suele empezar en la página siguiente. Marca esa decoración con reserve: false —se sigue pintando y otros elementos pueden seguir anclándose a ella— y da al encabezado el espacio que necesita con sus elementos de texto o con minHeight:
{
"kind": "image", "id": "seal", "resourceId": "seal", "reserve": false,
"placement": {
"anchor": { "to": "page", "edge": "bottom-right" },
"offset": { "x": { "value": -25, "unit": "mm" }, "y": { "value": -25, "unit": "mm" } },
"size": { "width": { "value": 30, "unit": "mm" } }
}
}Un elemento anclado a otro que no reserva sigue contando salvo que también lo marques (un rótulo compuesto sobre el sello necesita su propio reserve: false).
Dónde se pinta. El diseño de una apertura (span: 'page') se dibuja antes que el cuerpo, así que la decoración que no reserva espacio queda bajo el texto. El diseño de un encabezado de columna se dibuja con el bloque del encabezado —encima de los bloques que lo preceden en la columna y debajo de los que lo siguen— allí donde esté colocado por encima del pie de su columna: también en los márgenes laterales, en el margen superior, en el sangrado y en las columnas vecinas. El pie de la columna lo corta, en el lienzo y en el PDF, porque ahí termina el flujo (ver Más alto que la columna más abajo). Hasta postext 1.4 el lienzo y el PDF también lo cortaban en la parte alta de su columna, de modo que una banda anclada a la parte alta de la página o del sangrado entraba en los márgenes laterales pero se detenía en el margen superior. La decoración anclada al pie de la página va en una apertura, o en el diseño del pie con pages: 'opener'.
Más alto que la columna. Cuando el espacio llega más allá del pie de la columna —un minHeight tan alto como la página, una imagen o un marco que bajan hasta el corte—, el encabezado reclama el resto de su página (una apertura, en todas sus columnas) o de su columna (un encabezado de columna), y el texto que lo sigue empieza en la página o en la columna siguiente. Su bloque llega entonces hasta el pie de la columna, sin recortarse nunca a la altura de su texto, de modo que la banda contra la que se compone su diseño es el espacio que reclama (minHeight incluido, hasta el pie). Un diseño más alto que la propia página —una entradilla larga en una página de pantalla pequeña— sigue cortándose en el pie de la página (un diseño de columna, en el de su columna): el Sandbox lo señala en el panel Revisión como Diseño de título cortado. La maquetación no emite ningún aviso por ello —una portada que reclama su página es lo habitual y no pierde nada—, pero cualquier anfitrión puede hacer la misma comprobación sobre la maquetación terminada: collectHeadingDesignCuts(doc) devuelve un { kind: 'headingDesignCut', pageIndex, level, where, overflowPx, sourceStart, sourceEnd } por cada encabezado cuyo texto de diseño queda más allá del pie del corte de la página (where: 'page', una apertura) o de su columna (where: 'column'), y formatWarning describe cada uno. Ver Una apertura tan alta como la página en Span y diseño avanzado.
La columna lateral. En una disposición de columna y media cuya columna lateral aloja flotantes (sideColumnRole: 'floats'), un elemento del diseño de un encabezado de columna que cae en la columna lateral —un numeral de capítulo anclado a la página en la columna del margen exterior, en la apertura de un libro de texto— mantiene la pila lateral apartada. Cada figura, tabla o recuadro con span: 'side' que la página coloca después del encabezado deja un hueco de flotante libre alrededor de cada uno de esos elementos: se queda donde lo pone la pila cuando cabe por encima del elemento y, si no, pasa por debajo de él —o espera a la página siguiente cuando el resto de la columna lateral no puede alojarlo ahí—. Así, un numeral en la cabeza del canal mantiene toda la pila por debajo, mientras que un número de sección colgado en el margen junto a un encabezado más abajo en la página deja la cabeza del canal a las figuras que cita la página (la figura marginal sigue en lo alto de su página). Lo que la columna lateral ya aloja cuando se coloca el encabezado no se mueve: una figura apilada antes en la página que llega hasta el elemento del encabezado se queda donde está, debajo del elemento; por eso, si el diseño tiene un elemento en la columna lateral a media página, conviene citar sus figuras después del encabezado. Los elementos con reserve: false dejan libre la columna lateral, igual que dejan libre el texto. Una apertura (span: 'page') no necesita nada de esto: su banda se reserva en todas las columnas, la lateral incluida. Hasta postext 1.4 una figura lateral citada en una apertura así se colocaba en la cabeza de la columna lateral, encima del numeral.
Portadas. Por eso un encabezado de portada que llena su página —con un minHeight tan alto como la página, o con una imagen a página completa en su diseño— envía por sí solo el texto que lo sigue a la página siguiente, tanto en disposiciones de una columna como de varias. Un :::pagebreak justo detrás es opcional y no hace daño: un salto de página en una página todavía vacía no hace nada, así que nunca añade una página en blanco. Solo hace falta cuando el diseño de la portada termina antes del pie de la página y aun así el texto debe empezar en una página nueva.
# Memoria anual 2026 {style="portada"}
:::pagebreak
# Carta de la presidenta#Números con letras
Dos sufijos de las plantillas de numeración escriben un contador con letras, en el idioma del documento (el locale de primer nivel o, si no está definido, el idioma de partición — ver Idioma del documento): words para el cardinal y ordinal para el ordinal. La caja del sufijo fija la de las palabras, como hacen A / a con las letras:
| Token | Inglés (21) | Español (21) | Chino (21) |
|---|---|---|---|
| twenty-one | veintiuno | 二十一 |
| Twenty-one | Veintiuno | 二十一 |
| TWENTY-ONE | VEINTIUNO | 二十一 |
| twenty-first | vigesimoprimero | 第二十一 |
| Twenty-first | Vigesimoprimero | 第二十一 |
| TWENTY-FIRST | VIGESIMOPRIMERO | 第二十一 |
Se escriben con letras el inglés, el español, el chino y el árabe; cualquier otro idioma toma las palabras en inglés, como hacen las cadenas integradas de continuación de tablas. El chino escribe los numerales informales de simp-chinese-informal o trad-chinese-informal, según la escritura de locale (一万 / 一萬), con 第 delante del ordinal; los caracteres han no tienen caja, así que las tres grafías de un sufijo imprimen lo mismo. El inglés sigue el uso estadounidense (one hundred five, sin and). El español usa las formas masculinas, como se numera un capítulo o un libro (capítulo primero, tercero, veintiuno), y escribe los ordinales del 13 al 29 en una sola palabra, como prefiere la RAE (decimotercero, vigesimoprimero). Los cardinales se escriben hasta 999 999 y los ordinales españoles hasta 999; los números mayores se imprimen en cifras.
Los números árabes concuerdan en género con el sustantivo que cuentan, así que el sufijo admite un modificador: -feminine (o -f) para un sustantivo femenino, -masculine (-m, el valor por defecto) para uno masculino; -classical escribe las centenas مائة, como las ediciones de Bulaq y la mayoría de las egipcias, en lugar del moderno مئة. {1:ordinal} escribe el ordinal definido en nominativo que usa un título: الفصل {1:ordinal} da الفصل الأول, الفصل الحادي عشر, الفصل الحادي والعشرون; الليلة {1:ordinal-feminine} da الليلة الأولى, الليلة الحادية عشرة, الليلة الحادية والعشرون, الليلة المئتان y, por encima de cien, la fórmula clásica de «después de»: الليلة الخامسة والأربعون بعد الثلاثمئة, الليلة الحادية بعد الألف. {1:words} escribe el cardinal (واحد وعشرون; en femenino إحدى عشرة, واحدة وعشرون). Los ordinales se escriben con letras hasta 9 999 y los cardinales hasta 99 999; los modificadores se combinan ({1:ordinal-f-classical}) y los demás idiomas los ignoran. El árabe no tiene mayúsculas, así que la caja del sufijo no cambia nada. Los marcadores de diseño {numberWords} y {numberOrdinalWords} escriben las formas masculinas; para una apertura en femenino, pon el ordinal en la plantilla del nivel e imprímelo con {number}.
En un diseño de encabezado, {numberWords} / {numberWordsLower} y {numberOrdinalWords} / {numberOrdinalWordsLower} escriben el contador del encabezado del mismo modo, así la apertura puede decir Capítulo uno mientras el índice muestra 1. El textTransform: 'uppercase' de un elemento de texto da las mayúsculas:
// Novela en español: «CAPÍTULO PRIMERO» sobre el título, «1.» en el índice.
{ level: 1, numberingTemplate: '{1}.', span: 'page',
advancedDesign: { enabled: true, slot: { elements: [
{ kind: 'text', id: 'n', content: 'Capítulo {numberOrdinalWordsLower}', textTransform: 'uppercase', /* … */ },
{ kind: 'text', id: 't', content: '{titleText}', /* … */ },
] } } }#Listas no ordenadas
La propiedad unorderedLists controla cómo se renderizan las listas con viñetas (-, *, +) y las listas de tareas estilo GFM (- [ ], - [x]). Se admiten hasta cinco niveles de anidamiento.
#Valores por defecto de listas no ordenadas
| Propiedad | Tipo | Por defecto | Descripción |
|---|---|---|---|
fontFamily | string | hereda bodyText.fontFamily | Fuente del texto de los elementos. |
color | ColorValue | Color principal (#295AA3) | Color del texto y de las viñetas de los elementos. Enlazado a la entrada main-color de la paleta por defecto. |
fontWeight | number | 700 | Peso del texto de los elementos (100–900). Las viñetas heredan este peso salvo que se sobrescriba por nivel. |
italic | boolean | false | Renderiza el texto de los elementos en cursiva. |
bulletChar | string | '•' | Glifo utilizado como viñeta. |
bulletFontSize | Dimension | 1 em | Tamaño del glifo de la viñeta. Las unidades relativas escalan con el tamaño del cuerpo de texto. |
gap | Dimension | 0.5 em | Espacio horizontal entre la viñeta y el texto del elemento. |
indent | Dimension | 0 em | Sangría base para el nivel 1. Los niveles más profundos se encadenan desde el inicio del texto del nivel anterior salvo que se especifique (ver más abajo). |
bulletVerticalOffset | Dimension | 0 em | Ajuste fino vertical de la viñeta. Valores negativos la suben; positivos la bajan. |
marginTop / marginBottom | Dimension | 1.5 em | Espacio antes y después del bloque de lista. |
itemSpacing | Dimension | 0 em | Espacio vertical extra entre elementos, añadido sobre la altura de línea. Alrededor de una lista anidada en un elemento de otra se aplica, a ambos lados, el de la lista exterior: antes del primer elemento de la lista anidada y después del último (hasta postext 1.4, el elemento que seguía a una lista anidada tomaba el espacio de esta). |
snapTopToGrid | boolean | false | Redondea hacia arriba el espacio sobre la lista para que su primer elemento quede en la rejilla base, como el texto bajo un encabezado; marginTop pasa a ser un mínimo. El final de la lista devuelve el flujo a la rejilla en cualquier caso, así que con itemSpacing a 0 todos los elementos quedan alineados con el texto de la columna contigua. Desactivado por defecto, como hasta postext 1.4: un marginTop que no es un número entero de líneas deja los elementos fuera de la rejilla hasta que termina la lista. No afecta a las listas dentro de recuadros, cuyo interior queda fuera de la rejilla. |
hangingIndent | boolean | true | Cuando está activo, las líneas envueltas se alinean con el primer carácter de texto en lugar de hacerlo bajo la viñeta (sangría francesa). |
levels | UnorderedListLevelConfig[] | — | Sobrescrituras por profundidad para los niveles 1–5. Ver más abajo. |
#Extensiones para listas de tareas
Los elementos de tarea GFM (- [ ] …, - [x] …) se renderizan como elementos de lista no ordenada reemplazando la viñeta por una casilla. Los siguientes campos solo aplican a las tareas:
| Propiedad | Tipo | Por defecto | Descripción |
|---|---|---|---|
taskCheckboxChar | string | '☐' | Glifo para tareas no marcadas. |
taskCheckedChar | string | '☑' | Glifo para tareas completadas. |
taskCompletedStrikethrough | boolean | true | Dibuja una línea tachando el texto de las tareas completadas. |
taskCompletedColor | ColorValue | hereda el color del elemento | Color opcional aplicado al texto de las tareas completadas. Cuando se omite, se usa el color habitual del elemento. |
#Sobrescrituras por nivel (listas no ordenadas)
Cada entrada de levels apunta a una profundidad (1–5) y puede sobrescribir cualquiera de las siguientes propiedades:
| Propiedad | Tipo | Descripción |
|---|---|---|
bulletChar | string | Glifo de viñeta para esta profundidad. |
fontFamily | string | Fuente del texto en esta profundidad. |
fontSize | Dimension | Tamaño del glifo de viñeta en esta profundidad. |
color | ColorValue | Color del texto del elemento. |
fontWeight | number | Peso del texto del elemento. |
italic | boolean | Activa la cursiva. |
indent | Dimension | Sangría explícita de la viñeta en esta profundidad. Ver la regla de encadenamiento a continuación. |
verticalOffset | Dimension | Ajuste fino vertical de la viñeta en esta profundidad. |
Encadenamiento de sangrías. El nivel 1 arranca siempre con el indent general (por defecto 0 em — las viñetas quedan pegadas al borde de la columna). Para los niveles 2–5, si dejas indent sin definir el motor coloca la viñeta en el inicio de texto del nivel anterior (sangría del padre + ancho de viñeta + gap). Define un indent explícito en un nivel para romper el encadenamiento y fijar esa profundidad donde prefieras.
unorderedLists: {
bulletChar: '—',
gap: { value: 0.4, unit: 'em' },
hangingIndent: true,
levels: [
{ level: 2, bulletChar: '·' },
{ level: 3, bulletChar: '◦', color: { hex: '#666666', model: 'hex' } },
],
}#Listas ordenadas
La propiedad orderedLists controla las listas numeradas (1., 2), etc.). Se admiten hasta cinco niveles de anidamiento y cada profundidad puede usar un formato de numeración distinto.
#Valores por defecto de listas ordenadas
| Propiedad | Tipo | Por defecto | Descripción |
|---|---|---|---|
fontFamily | string | hereda bodyText.fontFamily | Fuente del texto y del marcador numérico. |
color | ColorValue | Color principal (#295AA3) | Color del texto y del marcador numérico. Enlazado a la entrada main-color de la paleta por defecto. |
fontWeight | number | 700 | Peso del texto y del marcador numérico (100–900). |
italic | boolean | false | Renderiza el texto en cursiva. |
numberFormat | OrderedListNumberFormat | 'arabic' | Estilo de numeración: 'arabic', 'lower-alpha', 'upper-alpha', 'lower-roman', 'upper-roman'. También valen las grafías de los otros ajustes ('decimal', 'roman-lower', 'i'…; ver Grafías de los formatos de numeración); un valor desconocido numera en arábigos y se notifica. |
prefix | string | '' | Texto que precede al número, con el estilo del separador: con '(' aquí y ')' como separador, una lista china se numera (一), (二). Cuando el separador se dibuja como un tramo propio, el prefijo también, justo antes del número. |
separator | string | '.' | Carácter situado entre el número y el texto — normalmente '.' o ')'. |
separatorFontFamily | string | hereda fontFamily | Fuente del separador. Cuando algún estilo del separador difiere del número, el separador se dibuja como una tirada propia tras el número (alineado a la derecha) — p. ej. 1 en Optima Bold negro seguido de • en DIN Pro Bold azul. |
separatorFontWeight | number | hereda fontWeight | Peso del separador (100–900). |
separatorItalic | boolean | hereda italic | Renderiza el separador en cursiva. |
separatorColor | ColorValue | hereda color | Color del separador. Se respetan las referencias a la paleta. |
separatorGap | Dimension | 0 em | Espacio entre el número y el separador. El texto del elemento sigue empezando gap después del separador. |
numberFontSize | Dimension | 1 em | Tamaño del marcador numérico. |
gap | Dimension | 0.5 em | Espacio horizontal entre el número y el texto del elemento. |
indent | Dimension | 0 em | Sangría base para el nivel 1; los niveles más profundos se encadenan desde el inicio del texto del nivel anterior salvo que se especifique. |
numberVerticalOffset | Dimension | 0 em | Ajuste fino vertical del marcador numérico. |
marginTop / marginBottom | Dimension | 1.5 em | Espacio antes y después del bloque de lista. |
itemSpacing | Dimension | 0 em | Espacio vertical extra entre elementos. Alrededor de una lista anidada en un elemento de otra se aplica, a ambos lados, el de la lista exterior: antes del primer elemento de la lista anidada y después del último (hasta postext 1.4, el elemento que seguía a una lista anidada tomaba el espacio de esta). |
snapTopToGrid | boolean | false | Redondea hacia arriba el espacio sobre la lista para que su primer número quede en la rejilla base, como el texto bajo un encabezado; marginTop pasa a ser un mínimo. El final de la lista devuelve el flujo a la rejilla en cualquier caso, así que con itemSpacing a 0 todos los elementos quedan alineados con el texto de la columna contigua. Desactivado por defecto, como hasta postext 1.4: un marginTop que no es un número entero de líneas deja los elementos fuera de la rejilla hasta que termina la lista. No afecta a las listas dentro de recuadros, cuyo interior queda fuera de la rejilla. |
numberWidth | 'run' | 'level' | 'run' | El ancho de la columna de números de un elemento, que fija dónde empieza su texto; los números se alinean a la derecha dentro de ella. 'run': el número más ancho del propio tramo del elemento, los elementos de una misma profundidad sin nada más que elementos más profundos entre ellos. Una figura, un párrafo o un recuadro entre dos elementos abre un tramo nuevo, así que ii) tras una tabla puede empezar su texto algo más a la derecha que i) antes de ella, y una lista de nueve elementos compone su texto a la izquierda de una de doce. 'level': el número más ancho de esa profundidad en todo el documento (el capítulo, en un libro), así que todas las listas, y cada parte de una lista interrumpida, empiezan su texto en el mismo sitio, como ya hacen las sangrías de los niveles más profundos. |
numberAlign | 'end' | 'start' | 'end' | Cómo se coloca un número en su columna. 'end': junto al texto, así que los números de un tramo terminan a la misma altura y 9. y 10. alinean sus puntos. 'start': al principio de la columna (la izquierda en una página de izquierda a derecha, la derecha en una de derecha a izquierda, la cabeza de la línea en texto vertical), así que las etiquetas de distinta longitud empiezan a la misma altura, como los artículos de una ley (第九條, 第十一條). La columna conserva el ancho que le da numberWidth, de modo que el texto de los elementos empieza en el mismo sitio en los dos casos; con un separador de estilo propio, el separador sigue a su número. Desde postext 1.26. |
hangingIndent | boolean | true | Las líneas envueltas se alinean con el primer carácter de texto, no bajo el número. |
levels | OrderedListLevelConfig[] | — | Sobrescrituras por profundidad para los niveles 1–5. |
#Sobrescrituras por nivel (listas ordenadas)
Cada entrada de levels puede sobrescribir numberFormat, prefix, separator, fontFamily, fontSize, color, fontWeight, italic, indent, verticalOffset y el estilo del separador (separatorFontFamily, separatorFontWeight, separatorItalic, separatorColor, separatorGap) — se aplica el mismo encadenamiento de sangrías que en las listas no ordenadas. El estilo del separador de un nivel hereda el estilo de su propio número salvo que se indique el ajuste general del separador.
Alineación a la derecha. El pipeline mide el número formateado más ancho dentro de cada recorrido e indenta todos los elementos de ese recorrido para que los marcadores queden alineados por su borde derecho. Una lista de diez elementos renderizada como 1. – 10. desplaza los números de un dígito a la derecha para que el separador caiga siempre en la misma columna.
orderedLists: {
numberFormat: 'arabic',
separator: '.',
levels: [
{ level: 2, numberFormat: 'lower-alpha' },
{ level: 3, numberFormat: 'lower-roman', separator: ')' },
],
}Esto produce la clásica combinación anidada:
1. Primer elemento
a. Subelemento
i) Nota profunda
b. Subelemento
2. Segundo elemento
La jerarquía de los documentos chinos (GB/T 15834—2011, anexo B.3) tiene cinco niveles: 一、, luego (一), luego 1., luego (1) y luego ①:
orderedLists: {
levels: [
{ level: 1, numberFormat: 'simp-chinese-informal', separator: '、' },
{ level: 2, numberFormat: 'simp-chinese-informal', prefix: '(', separator: ')' },
{ level: 3, numberFormat: 'arabic', separator: '.' },
{ level: 4, numberFormat: 'arabic', prefix: '(', separator: ')' },
{ level: 5, numberFormat: 'circled-decimal', separator: '' },
],
}#Matemáticas
La propiedad math controla cómo se analizan y se renderizan las fórmulas LaTeX escritas entre delimitadores $...$ (en línea) y $$...$$ (en bloque). El motor subyacente es MathJax (el paquete mathjax-full) en modo de salida SVG, rasterizado en el canvas e incrustado como glifos escalables en el PDF.
interface MathConfig {
enabled?: boolean; // Renderizar LaTeX. Si es false, los spans salen como TeX literal.
fontSizeScale?: number; // × el tamaño del texto que rodea la fórmula (el del cuerpo en las fórmulas en bloque).
color?: ColorValue; // Color de la fórmula; hereda del cuerpo si se omite.
marginTop?: Dimension; // Espacio encima de las fórmulas en bloque.
marginBottom?: Dimension; // Espacio mínimo debajo; el snap a rejilla puede aumentarlo.
indentAfterDisplay?: boolean; // Sangrar el párrafo que sigue a una fórmula en bloque.
keepWithLeadIn?: boolean; // Mantener una fórmula en bloque con la línea que la introduce.
equationNumbering?: { // Numerar las fórmulas en bloque que llevan un \label.
enabled?: boolean; // por defecto true
numberingTemplate?: string; // '{n}'; '{h1}.{n}' numera por capítulo
resetOn?: ResourceCounterReset; // 'never' | 'h1' … 'h6'
counterFormat?: ResourceCounterFormat; // 'decimal'
format?: string; // '({n})': lo que imprimen la fórmula y \eqref
};
}| Propiedad | Tipo | Por defecto | Descripción |
|---|---|---|---|
enabled | boolean | true | Cuando es false, los spans $...$ y $$...$$ siguen analizándose (los avisos por delimitadores sin cerrar siguen disparándose), pero se renderizan como su código TeX literal. Útil cuando el contenido contiene signos de dólar a propósito o cuando quieres desactivar por completo el renderizado matemático. |
fontSizeScale | number | 1.0 | Multiplicador aplicado al tamaño del texto que rodea la fórmula antes del renderizado: un em de la fuente TeX de la fórmula mide ese tamaño × fontSizeScale — bodyText.fontSize para una fórmula en bloque y para las fórmulas en línea del texto de cuerpo, el tamaño del bloque que la contiene para una fórmula en línea en un encabezado, un estilo de párrafo, un pie o el cuerpo de un recuadro. 1.0 iguala al texto que la rodea; valores en el rango 0.9–1.1 son habituales cuando la fuente matemática parece ligeramente más grande o más pequeña que la fuente de prosa. Cambia en postext 1.5: hasta la 1.4 las fórmulas salían en torno a un 13 % más grandes (ver más abajo). |
color | ColorValue | hereda del cuerpo | Color de la fórmula renderizada. Omítelo para heredar bodyText.color. Fíjalo explícitamente cuando quieras tintar las fórmulas de forma distinta a la prosa — por ejemplo para que coincidan con el acento de los encabezados. |
marginTop | Dimension | 0.8em | Espacio por encima de una fórmula en bloque. Se ignora para fórmulas en línea. |
marginBottom | Dimension | 0.8em | Espacio por debajo de una fórmula en bloque. Es un mínimo: el ajuste a la rejilla puede ampliarlo para que la siguiente línea base caiga en una línea de la rejilla (tanto si page.baselineGrid dibuja la rejilla como si no). |
indentAfterDisplay | boolean | true | Sangra la primera línea del párrafo que sigue a una fórmula en bloque, como cualquier otro párrafo. Con false, todo párrafo justo después de una fórmula en bloque se compone sin sangría, como continuación de la frase que la fórmula interrumpió («donde L es…»). Tras una fórmula escrita dentro de un párrafo —sin línea en blanco ni encima ni debajo— el texto nunca se sangra: lo escrito bajo su $$ de cierre continúa ese párrafo (consulta Fórmulas matemáticas). |
keepWithLeadIn | boolean | false | Mantiene una fórmula en bloque en la columna de la línea que la introduce, como la penalización \predisplaypenalty de TeX. Cuando la fórmula no cabe bajo la última línea del párrafo anterior, esa línea pasa con la fórmula a la columna o página siguiente; cuando las líneas que quedarían atrás son menos de bodyText.widowMinLines (menos de una si bodyText.avoidWidows está desactivado), un párrafo que empieza en esa columna pasa entero (con los encabezados que cierran la columna por encima, según headings.keepWithNext). La línea que pasa queda sola en lo alto de la columna siguiente, diga lo que diga la regla de las huérfanas. Con false, la fórmula pasa sola, y la línea que la introduce puede cerrar la columna de arriba o quedar sobre una figura que encabeza la siguiente. |
equationNumbering | { enabled, numberingTemplate, resetOn, counterFormat, format } | true, '{n}', 'never', 'decimal', '({n})' | Cómo se numeran las fórmulas en bloque que llevan un \label (ver Ecuaciones numeradas más abajo). numberingTemplate, resetOn y counterFormat funcionan como los de un tipo de recurso: '{h1}.{n}' con resetOn: 'h1' numera (2.1), (2.2)… por capítulo, y '{h1}.{h2}.{n}' con 'h2', por sección. format es el número tal como lo imprimen la fórmula y \eqref, con {n} en el lugar del número: '[{n}]' compone [3]. enabled: false no numera nada: un \label se descarta y una referencia a él imprime su página. |
math: {
enabled: true,
fontSizeScale: 1.0,
color: { hex: '#295AA3', model: 'hex' },
marginTop: { value: 1, unit: 'em' },
marginBottom: { value: 1, unit: 'em' },
}Tamaño de las fórmulas, cambia en postext 1.5. MathJax da la caja de cada fórmula en ex, y un ex de su fuente TeX mide 0,442 em. Hasta postext 1.4 el motor lo tomaba por medio em, así que cada fórmula se componía en torno a un 13 % más grande que bodyText.fontSize × fontSizeScale. Ahora las fórmulas salen del tamaño documentado, y las líneas y páginas con matemáticas se recomponen. Una configuración escrita en código para la 1.4 conserva el tamaño de sus fórmulas de la 1.4 si pasa por pinLegacyMathSize, de postext/bundle, una sola vez y tal como está escrita:
import { pinLegacyMathSize } from 'postext/bundle';
config = pinLegacyMathSize(config); // fórmulas, y el espacio alrededor de las fórmulas en bloque, como las componía la 1.4Hay otros cambios de reglas en la 1.5 que también pueden mover sus páginas: los saltos de los encabezados, el espacio en torno a una figura en línea (en el texto corrido y en los recuadros), las marcas en línea de sus encabezados, el tamaño de sus letras capitales, el sitio que se deja bajo una línea de dos puntos para la lista que introduce, las líneas que deja de un párrafo o de un elemento de lista el corte de una caja, los cortes de línea tras una raya, la composición del texto en bandera, la división de un párrafo bajo un encabezado, los cortes de línea tras el guion de un compuesto y el espacio bajo un contenedor :::paragraphs. migrateConfig, aplicada una sola vez con el markdown que compone la configuración, fija los que ese texto necesita, también el tamaño de las fórmulas (ver Paquetes escritos por postext 1.4 o anterior):
import { migrateConfig } from 'postext/bundle';
config = migrateConfig(config, undefined, { content: markdown }); // saltos de encabezado, fórmulas, huecos en línea, marcas de los encabezados, capitales, dos puntos, cortes de las cajas, rayas, compuestos, texto en bandera, divisiones bajo un encabezado y espacio bajo los contenedores como los componía la 1.4Así se evita lo que moverían esos cambios de reglas, pero no se conservan todas las páginas de la 1.4. La 1.5 corrige además errores de composición, y una corrección no tiene fijación: una configuración antigua la recibe igual que una nueva, así que una página a la que afecte aún puede moverse. Entre ellas: un encabezado a toda la página sin diseño propio se mide a lo ancho de la página y se compone con el interlineado de su nivel; en un diseño de encabezado no se reserva nada bajo la línea base de una letra capital; una capital toma el color de la paleta de la sección y se compone también en un texto de diseño cuyo overflow no es 'wrap', que entonces pasa de línea; un párrafo dentro de una caja pinta el tracking con el que se midió; una caja partida conserva la columna del icono en cada fragmento; una línea de una caja que estiraría sus espacios más de 3× se compone en bandera, como en el texto corrido; la palanca de los párrafos flojos nunca deja una línea justificada más ancha de lo que permite maxWordSpacing; una caja flotante conserva un marginBottom (en una banda superior) o un marginTop (en una banda inferior) mayor que el hueco de los flotantes; un texto de diseño centrado o alineado a la derecha con tracking (un titulillo, el título de una apertura) se coloca por sus letras, sin el tracking que sigue a la última; bajo una apertura a toda la página, el texto que abre la segunda columna empieza donde empezaría el texto justo debajo de la apertura, también cuando a la apertura le sigue un encabezado; la línea de puntos del índice se detiene antes del número de página en una fuente cuyo kerning separa una serie de puntos; un titulillo lee el encabezado tal como está escrito, sin espacio donde una de sus líneas termina tras un guion o una raya o dentro de una palabra cortada por su ancho (MEDIOAMBIENTALES, no MEDIOAMBIENTALE S), y el {titleText} del diseño de un encabezado lo lee igual (thousand-colour, no thousand- colour); un texto anclado al pie o al centro de la franja de un diseño de encabezado mantiene la franja lo bastante alta para contenerlo, así que ya no sube sobre el texto que precede al encabezado; una palabra más ancha que su línea, cortada junto a un guion que ya lleva, se corta detrás de ese guion y no recibe otro; el elemento que sigue a una lista anidada en otra toma el itemSpacing de su propia lista, no el de la anidada; y el resto de una palabra cortada por ser más ancha que su línea conserva sus propios puntos de corte, de modo que una dirección web sigue cortándose por sus junturas y un compuesto por sus guiones en lugar de por las sílabas del diccionario.
pinLegacyMathSize multiplica la escala por 1,1312 (0,5 ÷ 0,442) y divide por el mismo factor los márgenes de las fórmulas en bloque en em. La escala sola no basta en un libro con fórmulas en bloque: sus márgenes son medidas del tamaño de la propia fórmula, así que crecerían el mismo 13 % y empujarían hacia abajo el texto que las sigue. Escritos para los márgenes por defecto, los tres valores son:
math: {
fontSizeScale: 1.131,
marginTop: { value: 0.7072, unit: 'em' },
marginBottom: { value: 0.7072, unit: 'em' },
} // fórmulas tan grandes como las componía la 1.4, con el espacio que les dejaba alrededorDonde la configuración estaba guardada, el motor puede saberlo y lo hace por ti: openBundle / readBundle con un paquete .postext escrito antes de la 1.5 (ver Paquetes escritos por postext 1.4 o anterior), y el Sandbox con los libros, la configuración de trabajo y los archivos postext-config.json que guardó entonces (ver Sandbox → Persistencia). Se leen a través de migrateConfig, que fija el tamaño (pinLegacyMathSize): fontSizeScale pasa a ser la escala guardada (1 si no había) × 1,1312, y un margen de las fórmulas en bloque en em o rem — una medida del tamaño de la propia fórmula — se divide por el mismo factor, de modo que el espacio alrededor de una fórmula en bloque queda como lo dejaba la 1.4 (los 0,8 em por defecto pasan a 0,7072 em). Un margen en una unidad de página (pt, mm…) se queda como está, y también una configuración con enabled: false o una cuyo libro no tiene ningún $. El libro antiguo se compone entonces como lo componía la 1.4, y su sección math muestra el tamaño con el que se compone. Para componer ese libro al tamaño actual, restablece esos valores: Fórmulas → Escala de tamaño, Margen superior de las fórmulas en bloque y Margen inferior de las fórmulas en bloque en el Sandbox, o en código:
math: { ...config.math, fontSizeScale: 1, marginTop: undefined, marginBottom: undefined } // tamaño y márgenes actualesEcuaciones numeradas. Una fórmula en bloque con número ocupa toda su medida (la columna, o el ancho interior del recuadro que la contiene): la ecuación va centrada y su número alineado a la derecha, en la línea de la ecuación, en cada fila numerada de un align. El número sale de un \label{eq:x} (desde postext 1.19): las fórmulas con etiqueta, y las filas con etiqueta de un align, gather, alignat, flalign o eqnarray, se numeran en orden de lectura según equationNumbering, salvo que una fila diga \nonumber o \notag. Entornos como equation no se numeran por sí solos: una fórmula sin etiqueta no lleva número. \tag{…} imprime el texto que le des, entre paréntesis, y \tag*{…}, tal cual; ninguno de los dos cuenta, y un \label a su lado le da nombre. Una ecuación numerada más ancha que su medida desborda por la derecha, como cualquier fórmula en bloque. (Hasta postext 1.4, una fórmula con \tag no llegaba a dibujarse; hasta la 1.18, solo \tag numeraba una fórmula.)
\eqref{eq:x} en el texto imprime el número en su format, (3), y \ref{eq:x}, el número solo; lo mismo hacen :ref{id="eq:x"} y @eq:x (ver Referencias cruzadas), y dentro de una fórmula \eqref lo imprime como texto. En un libro compuesto capítulo a capítulo, el contador sigue desde el capítulo anterior: continuationAfter lo lleva en LayoutContinuation.statementCounters (equation), y el esquema del libro da a cada etiqueta su número (OutlineEntry.numberLabel), de modo que una referencia a una ecuación de otro capítulo lo imprime.
math: {
equationNumbering: { numberingTemplate: '{h1}.{n}', resetOn: 'h1' }, // (1.1), (1.2)… (2.1)
}El resolver y el stripper siguen el mismo patrón que las otras secciones:
import {
DEFAULT_MATH_CONFIG,
resolveMathConfig,
stripMathDefaults,
} from 'postext';
const resolved = resolveMathConfig(config.math);
const minimal = stripMathDefaults(config.math);#Arrancar el motor de fórmulas
MathJax se carga bajo demanda, no con el resto del motor. Cuando compones en el hilo principal, arráncalo antes de construir un documento con fórmulas:
import { buildDocument, initMathEngine, renderPage } from 'postext';
await initMathEngine(); // carga MathJax una vez; las llamadas siguientes se resuelven al instante
const doc = buildDocument({ markdown: 'Euler: $e^{i\\pi}+1=0$.' }, config);
document.body.append(renderPage(doc.pages[0], doc));- Hasta que el motor arranca, las fórmulas son provisionales. Cada una se compone como una caja gris de tamaño estimado. Si un documento con fórmulas se compone sin haber llamado nunca a
initMathEngine(), la consola muestra un aviso, una sola vez. - El worker de composición lo arranca por ti. Un build en
postext/workerllama ainitMathEngine()por su cuenta cuando el markdown contiene un$. - Componer ya, y otra vez cuando esté listo.
isMathReady()indica si el motor está en marcha.onMathReady(fn)llama afnen cuanto lo está (al instante si ya lo estaba) y devuelve una función que cancela la llamada. Un editor puede mostrar las cajas provisionales enseguida y volver a componer cuando llega MathJax; mientrasinitMathEngine()está en curso no se imprime ningún aviso. - Fallos.
initMathEngine()se rechaza si MathJax no puede cargarse, y una llamada posterior lo vuelve a intentar. - Con cualquier bundler, en Node o desde una CDN. MathJax viaja dentro del paquete como un único módulo preempaquetado (unos 1,8 MB sin comprimir, que solo descarga
initMathEngine). Elimport { initMathEngine } from 'https://esm.sh/postext'de siempre funciona; no hace falta?bundle. El paquetemathjax-fullsolo hace falta para compilar postext, así que instalar postext no lo instala. MathJax y el analizador mhchem que incluye tienen licencia Apache-2.0: sus avisos y el texto de la licencia viajan junto al módulo, endist/math/THIRD_PARTY_LICENSES.txt. - Un motor por página. El motor y su caché de fórmulas renderizadas son compartidos por todo lo que importa
postexten el mismo contexto de JavaScript (consulta Estado global compartido en una página).
Para la gramática del documento ($...$, $$...$$, cómo escapar un dólar literal), consulta Formato del documento.