Saltar al contingut principal

Capítol 3.14 · Part II · L'ofici

Configuració: pàgines compostes

Plantilles de pàgina per a les pàgines compostes: marcs, grups, decoració, herència i variants de recto i verso, els estils de rètol dels ancoratges d'una imatge i els avisos que pot donar una plantilla

Actualitzat 2026-10-166 minAl capítol 3 Configuracióenescadefritptzhjaar

En poques paraules

Aquesta pàgina tracta de les plantilles de pàgina. Una plantilla és una pàgina dibuixada als paràmetres: unes caixes amb nom, anomenades marcs, amb el seu lloc, la mida fins a la qual poden créixer i el seu aspecte. El Markdown d'una pàgina composta omple després aquests marcs pel seu nom, de manera que el text mai no guarda posicions i els paràmetres mai no guarden text. Una plantilla pot partir d'una altra i canviar només uns quants marcs, i pot ser diferent a les pàgines parells i a les senars. La pàgina recull també els estils de rètol per a les paraules que es posen sobre una imatge, i cada avís que pot donar una plantilla amb la manera de corregir-lo.

#Plantilles de pàgina

Una pàgina composta és una pàgina que pren la forma d'una plantilla de pàgina de la configuració i el contingut del Markdown d'un bloc ::::page{template="…"}. La plantilla dona nom a uns rectangles, anomenats marcs; el Markdown envia cada peça de contingut a un marc pel seu nom (el seu buit). La geometria mai no apareix al Markdown, i el text del contingut mai no apareix a la plantilla. La propietat pageTemplates conté les plantilles del llibre:

const config: PostextConfig = {
  calloutStyles: [{ id: 'caja-azul' }, { id: 'tab-titulo' }],
  pageTemplates: [
    {
      id: 'tema-cajas',
      decoration: {
        elements: [
          { kind: 'image', id: 'fondo', resourceId: '{attr.fondo}', decorative: true,
            placement: { anchor: { to: 'bleed', edge: 'top-left' }, size: { width: 'fill', height: 'fill' } } },
        ],
      },
      frames: [
        { name: 'titulo', takes: 'h1', style: 'tab-titulo' },
        { name: 'texto', flow: true },
        { name: 'dinero', style: 'caja-azul', padding: { right: { value: 62, unit: 'mm' } } },
        { name: 'dinero-fotos', layer: 2, width: { value: 60, unit: 'mm' },
          placement: { anchor: { to: '#dinero', edge: 'top-right' } } },
      ],
      groups: [
        { name: 'pagina', kind: 'stack', gap: { value: 6, unit: 'mm' }, frames: ['titulo', 'texto', 'dinero'] },
      ],
    },
  ],
};

Una plantilla que només fixa el seu id i un marc és una pàgina sencera amb aquest marc ocupant l'àrea de text. Tots els altres camps són opcionals:

PropietatTipusPer defecteDescripció
idstringobligatoriEl nom que demana un bloc de pàgina (template="tema-cajas"). Únic entre les plantilles: una segona amb el mateix id s'ignora.
namestringl'idEl nom que mostra el Sandbox. La composició mai no el llegeix.
extendsstringcapL'id de la plantilla de la qual parteix aquesta. Vegeu Herència i variants.
area'content' | 'trim' | 'bleed''content'El rectangle al qual es refereixen les posicions dels marcs. 'content' és l'àrea de text de la pàgina, reflectida a parells i senars com el text corregut; 'trim' és la pàgina al tall; 'bleed', la pàgina amb el seu sagnat.
grid{ columns, rows, columnGap?, rowGap? }capDivideix l'àrea en cel·les, de manera que un marc o un grup es pot col·locar per cel·la (grid: { col: 2, row: 1, cols: 2 }, comptant des d'1) en lloc de per placement. Els espais valen 0 per defecte.
framesFrameConfig[][]Els marcs, en l'ordre de la plantilla: l'ordre en què es mesuren i el que desfà els empats. Vegeu Marcs.
groupsFrameGroupConfig[][]Piles i fileres de marcs que es reparteixen l'espai. Vegeu Grups.
decorationDesignSlotcapImatges, filets i caixes que es pinten amb la pàgina, en el llenguatge d'elements de les capçaleres i peus. Els elements de text només porten marcadors ({pageNumber}, {chapterTitle}, {attr.x} per a un atribut del bloc de pàgina). Un element es pot ancorar a un marc o a un grup ('#dinero') i llavors es mou amb ell. La decoració es col·loca després dels marcs i mai no empeny el text.
header, footerDesignSlot | falseheretatsLa capçalera i el foli de la pàgina. Sense fixar, la pàgina conserva els del seu capítol; false els amaga.
spreadbooleanfalseLa plantilla descriu dues pàgines enfrontades compostes com un sol plec. Una doble pàgina comença sempre en una pàgina parell en un llibre d'esquerra a dreta (en una senar en un de dreta a esquerra), amb una pàgina en blanc al davant quan cal.
gutterDimension0En una doble pàgina, la franja tocant al llom que els marcs deixen lliure, tret que fixin crossGutter: true.
variants{ recto?, verso? }capCanvis per a una pàgina senar (recto) o una parell (verso), escrits com la mateixa plantilla. El costat és el físic, de manera que funcionen tant els llibres d'esquerra a dreta com els de dreta a esquerra.
overflowTemplatestringaquesta plantillaLa plantilla de les pàgines que s'afegeixen quan un marc continua a la pàgina següent (overflow.continueIn: 'next-page'). Sense fixar, la pàgina afegida fa servir aquesta plantilla amb només els marcs que continuen plens.
bodyStylestringcapUn estil de paràgraf per al text de la pàgina, com el que tenen els estils d'encapçalament.
palettestringcapUna paleta pròpia per a la pàgina, com la que tenen els estils d'encapçalament i les parts.
rolestring'composed'El paper de pàgina que veuen els elements de disseny amb un filtre pages.

#Marcs

Un marc és un rectangle amb nom que rep contingut compost. El seu name és el buit que demana el Markdown, i és únic a la seva plantilla (un grup tampoc no pot portar el nom d'un marc, perquè els ancoratges anomenen tots dos de la mateixa manera).

Un marc es col·loca per la seva cel·la de grid quan la plantilla té retícula i, si no, pel seu placement, que funciona com el d'un element de disseny: un ancoratge ('container' és l'àrea, 'page', 'bleed', o '#name' per a un altre marc o grup), una vora, un desplaçament i una mida. Un marc ancorat a un altre es mou amb ell. Sense cap dels dos, el marc ocupa tota l'àrea.

PropietatTipusPer defecteDescripció
namestringobligatoriEl nom del buit.
placementElementPlacementtota l'àreaAncoratge, vora, desplaçament i mida, com al posicionament d'elements. S'ignora quan una cel·la de la retícula col·loca el marc.
grid{ col, row, cols?, rows? }capUna cel·la de la retícula de la plantilla, comptant des d'1, que abasta cols × rows cel·les (1 per defecte). Una cel·la que surt de la retícula hi torna a entrar. S'ignora quan la plantilla no té retícula.
width, heightDimension | { percent } | 'auto' | 'fill''fill', 'auto'Una longitud fixa, un percentatge de l'àrea (de 0 a 100), 'auto' (la mida pròpia del contingut) o 'fill' (el que queda fins a la vora a la qual està ancorat el marc). Sense fixar, el marc llegeix placement.size i després el valor per defecte: tota l'amplada i tan alt com el seu contingut. Un marc de text necessita una mesura, de manera que una amplada 'auto' només té sentit en un marc que porta una sola imatge (l'amplada de la imatge a l'alçada del marc). Un valor que el motor no pot fer servir (una longitud negativa, una unitat desconeguda) es llegeix com el valor per defecte.
minWidth, maxWidth, minHeight, maxHeightDimensioncapLímits per a una mida 'auto' o 'fill' i per a l'espai que un grup dona o treu. El mínim s'imposa al màxim, i una mida fixa fora d'ells s'hi porta a dins (frameMinMax avisa dels dos casos).
stylestringsense caixaL'id d'un estil d'avís: els marcs es dibuixen amb estils d'avís (fons, vora, farciment, franja, icona, pestanya de rètol, títol). Les paraules d'una pestanya vénen del Markdown (:::frame{slot="dinero" label="El dinero"}). Els paràmetres d'avís que diuen on va una caixa en el text corregut (placement, span, columns, width, fixed…) no s'apliquen a un marc.
padding{ top?, right?, bottom?, left? }el de l'estilSubstitueix el farciment de l'estil costat per costat: lloc per a les fotos que van damunt d'una caixa, per exemple.
layernumber1Ordre de pintura. La decoració és la capa 0; una capa negativa es pinta a sota.
rotatenumber0Graus, en el sentit de les agulles del rellotge. La caixa i el seu contingut giren junts.
verticalAlign'top' | 'middle' | 'bottom' | 'justify''top'On se situa el contingut en un marc més alt que ell.
columns, columnGapnumber, Dimension1, el de l'estilColumnes dins del marc.
exclude'none' | 'push''none''push': el text dels altres marcs envolta el rectangle d'aquest.
flowbooleanfalseEl marc rep el contingut que no anomena cap buit.
takes'h1' … 'h6'capEl marc rep el primer encapçalament d'aquest nivell que no anomena cap buit, de manera que el títol d'una pàgina és només un # Títol al principi del bloc.
nextstringcapUna cadena: el contingut que no hi cap continua al marc d'aquest nom, a la mateixa pàgina.
overflow.continueInstringcapOn continua el contingut que no hi cap: '#frame' (un altre marc de la pàgina, com next), 'next-page' (el mateix marc en una pàgina que s'afegeix darrere d'aquesta) o 'template:<id>' (una pàgina d'aquesta plantilla).
overflow.markstring | falsela de la llenguaLa marca al final d'un tros tallat. Sense fixar, la paraula de continuació de la llengua del document (la mateixa que fan servir les taules partides); false no en posa cap.
fit.shrinkTextbooleantrueQuan res més no aconsegueix que el contingut hi càpiga, el seu text es pot compondre més petit.
fit.minScalenumber0.9L'escala de text més petita, més gran que 0 i com a màxim 1 (un valor més gran es llegeix com a 1).
fit.scaleImages, fit.imageMinScaleboolean, numbertrue, 0.8Si les imatges del marc es poden compondre més petites, i fins a quina escala.
pinbooleanfalseEl marc mai no es mou ni canvia de mida, per a una caixa que ha de quedar alineada amb la il·lustració. Un grup es col·loca al seu voltant.
grow, shrink, prioritynumber0Com comparteix el marc l'espai del seu grup: grow pren una part de l'espai sobrant, shrink deixa que el marc torni espai, i els marcs amb una priority més baixa el cedeixen primer.
optionalbooleanfalseCap avís quan el Markdown no envia res al marc.
crossGutterbooleanfalseEn una doble pàgina, el marc pot travessar la franja del llom.
writingMode, direction'horizontal-tb' | 'vertical-rl', 'ltr' | 'rtl'els de la pàginaUna caixa vertical en una pàgina horitzontal, o a l'inrevés.
removebooleanfalseEn una plantilla que n'estén una altra, o en una variant: treu el marc heretat amb aquest nom.

#Grups

Un grup és una pila (de dalt a baix) o una filera (del principi al final) de marcs que es reparteixen l'espai i es mouen junts. Dins d'un grup s'ignora la posició pròpia dels marcs en la direcció del grup: el grup els col·loca en ordre, amb gap entre ells. Quan creix el text d'un marc, els marcs que van darrere es desplacen. Un grup és una caixa a la qual es poden ancorar marcs i decoració ('#pagina').

PropietatTipusPer defecteDescripció
namestringobligatoriÚnic entre els marcs i grups de la plantilla.
kind'stack' | 'row''stack'De dalt a baix, o del principi al final.
framesstring[][]Els marcs del grup, en el seu ordre a la pàgina. Un marc pertany com a màxim a un grup; un nom que no és cap marc de la plantilla, o un marc ja llistat, se salta.
gapDimension0L'espai entre dos marcs del grup.
placement, gridcom als marcsla caixa dels seus marcsLa caixa pròpia del grup. Sense fixar, la caixa que envolta les caixes declarades dels seus marcs.
align'start' | 'center' | 'end' | 'space-between''start'On va l'espai sobrant quan cap marc del grup no creix.
removebooleanfalseEn una plantilla que n'estén una altra, o en una variant: treu el grup heretat.

#Herència i variants

Una plantilla amb extends parteix de la plantilla que anomena (que al seu torn en pot estendre una altra) i canvia només el que escriu:

  • Un camp com area, header o overflowTemplate substitueix el del pare. grid es combina clau a clau. spread, gutter i role també s'hereten; id, name i extends són propis de la plantilla.
  • frames i groups es combinen per nom: una entrada amb el nom d'una d'heretada canvia els camps que escriu i conserva la resta (fit, overflow i padding es combinen clau a clau; placement se substitueix sencer); remove: true la treu; un nom nou s'afegeix darrere dels heretats.
  • Els elements de decoració es combinen per id de la mateixa manera; un element amb un id nou, o sense id, s'afegeix.

variants.recto i variants.verso s'escriuen com una plantilla i es combinen igual, en una pàgina senar o en una parell. S'apliquen després de tota la cadena d'extends, primer la variant de l'arrel. Una doble pàgina té els dos costats, de manera que no se li aplica cap variant.

pageTemplates: [
  { id: 'tema', frames: [{ name: 'texto', flow: true }, { name: 'margen', width: { value: 30, unit: 'mm' },
      placement: { anchor: { to: 'container', edge: 'top-left' } } }],
    variants: { recto: { frames: [{ name: 'margen', placement: { anchor: { to: 'container', edge: 'top-right' } } }] } } },
  { id: 'tema-sin-margen', extends: 'tema', frames: [{ name: 'margen', remove: true }] },
]

Quan el Sandbox desa una plantilla, mai no descarta un valor igual al valor per defecte: en una plantilla que n'estén una altra, o en una variant, aquest valor substitueix el del pare.

Des del codi, resolvePageTemplate(config, id, { parity }) retorna una plantilla amb la seva cadena combinada, la variant del costat aplicada, tots els valors per defecte omplerts i cada referència resolta com descriuen els avisos de més avall; validatePageTemplates(config) retorna els avisos.

#Estils de rètol

La propietat labelStyles dona nom als aspectes dels rètols que es posen sobre una imatge: els mars i les ciutats d'un mapa, les parts d'un esquema. Un rètol se situa en un ancoratge de la imatge (un punt desat amb el recurs, com els parlants d'un còmic) i pren l'estil que anomena l'ancoratge o el rètol.

labelStyles: [
  { id: 'mar', fontStyle: 'italic', textTransform: 'uppercase', letterSpacing: 0.12,
    color: { hex: '#2b6ca3', model: 'hex' } },
  { id: 'ciudad', fontWeight: 600, halo: { color: { hex: '#ffffff', model: 'hex' }, width: { value: 0.6, unit: 'pt' } } },
]
PropietatTipusPer defecteDescripció
idstringobligatoriEl nom que fan servir els ancoratges i els rètols.
namestringl'idEl nom que mostra el Sandbox.
paragraphStylestringcapUn estil de paràgraf del qual el rètol pren la lletra; els camps de més avall el substitueixen.
fontFamily, fontSize, fontWeightstring, Dimension, numberels del text generalLa lletra del rètol.
fontStyle'normal' | 'italic''normal'Rodona o cursiva.
colorColorValueel del text generalEl color de les lletres.
textTransform'none' | 'uppercase''none'Majúscules, com les que posen els mapes als mars i als països.
letterSpacingnumber0Espai afegit entre lletres, en ems.
halo{ color, width }capUn contorn darrere de les lletres, perquè es llegeixin sobre una imatge carregada.
background, paddingColorValue, DimensioncapUna placa darrere del rètol, i l'espai al voltant del seu text.
minScalenumber0.85Fins a quina mida es pot reduir un rètol quan no cap en la seva amplada.

#Camps de rètol d'un ancoratge

Els ancoratges d'una imatge (Resource.anchors, els punts que fan servir els còmics per als parlants) admeten uns quants camps opcionals per a rètols. Són fraccions de la imatge, de manera que valen en totes les llengües i amb qualsevol retall de la imatge. Els còmics els ignoren.

CampTipusPer defecteDescripció
widthnumberla pròpia del rètolLa mesura del rètol, com a fracció de l'amplada de la imatge: un nom llarg es parteix en dues línies a dins.
align'start' | 'center' | 'end''center'Quin costat del rètol queda al punt de l'ancoratge.
verticalAlign'top' | 'middle' | 'bottom''middle'Quina vora del rètol queda a l'alçada de l'ancoratge.
rotatenumber0Graus, en el sentit de les agulles del rellotge, al voltant del punt de l'ancoratge: el nom d'un riu al llarg del seu curs.
stylestringcapUn id de labelStyles. Un rètol que anomena el seu propi estil el substitueix.

#Avisos de les plantilles de pàgina

A la resta de la configuració, el motor ignora una clau que no coneix. Les plantilles de pàgina i els estils de rètol, en canvi, es comproven, i cada problema és un avís de configuració a postext check i al tauler Revisió del Sandbox. El camp path d'aquests avisos és un punter JSON al camp que falla: /pageTemplates/3/frames/2/style, /pageTemplates/0/variants/recto/frames/1/next, /resources/4/anchors/0/style. Quan el camp és heretat, el punter anomena la plantilla que el va escriure. Un avís que anomena un id o un nom que no existeix proposa a més l'existent que s'hi assembla més.

Una clau mal escrita d'una plantilla, un marc, un grup, una retícula, fit, overflow, una variant o un estil de rètol és un unknownConfigKey; una paraula fora de les opcions d'un paràmetre (area, verticalAlign, exclude, takes, kind, align, writingMode, direction, fontStyle, textTransform) és un unknownConfigValue, i el paràmetre conserva el seu valor per defecte. Una plantilla sense id, o un marc o un grup sense name, s'ignora amb un unknownConfigValue en aquest camp.

AvísCausaSolució
templateDuplicateDues plantilles tenen el mateix id. Es fa servir la primera i la posterior s'ignora.Canvia el nom d'una de les dues, o esborra la còpia.
templateExtendsCycleSeguint extends es torna a la mateixa plantilla (a → b → a). Totes les plantilles del cicle, i totes les que n'estenen alguna, es descarten: cap pàgina no les pot fer servir.Treu l'extends d'una plantilla del cicle.
templateExtendsUnknownextends anomena un id que no té cap plantilla. La plantilla es fa servir sola, sense heretar res.Corregeix l'id (l'avís proposa el més semblant), o afegeix la plantilla pare.
frameDuplicateDos marcs, o dos grups, d'una mateixa llista tenen el mateix name, o un grup té el nom d'un marc. L'entrada posterior s'ignora; un ancoratge a aquest nom llegeix el marc.Dona a cada marc i a cada grup un nom propi. Per canviar un marc heretat, escriu una sola entrada amb el seu nom.
frameStyleUnknownL'style d'un marc no anomena cap estil d'avís. El marc es dibuixa sense caixa.Corregeix l'id, o afegeix l'estil a calloutStyles.
frameAnchorUnknownUn marc, un grup o un element de decoració està ancorat a '#name' i la plantilla no té cap marc, grup ni element amb aquest nom; o hi ha marcs i grups ancorats entre si en un cicle (també a través d'un grup sense ancoratge propi, la caixa del qual és la dels seus marcs). L'ancoratge es llegeix com a 'container', l'àrea.Ancora a un marc o a un grup que existeixi, o trenca el cicle ancorant-ne un a l'àrea.
frameMinMaxUn mínim és més gran que el seu màxim (minHeight 40mm > maxHeight 30mm), o un width o un height fix queda fora d'ells. S'imposa el mínim, una mida fixa es porta dins dels límits i used diu què ocupa el marc. Les longituds en unitats diferents es comparen a la resolució de la pàgina, i els ems al cos del text general.Fes que el mínim no superi el màxim, o treu el límit que contradiu la mida fixa.
groupFrameUnknownEls frames d'un grup inclouen un nom que no és cap marc de la plantilla (potser el va treure una plantilla filla o una variant). El grup se'l salta.Corregeix el nom, o treu-lo de la llista.
groupFrameTwiceUn marc figura en dos grups, o dues vegades en un. Un marc pertany a un sol grup: l'aparició posterior se salta.Deixa el marc al grup amb què es mou.
frameChainLoopUns marcs continuen els uns en els altres en un cicle a través de next o d'overflow.continueIn: '#frame' (a → b → a). L'enllaç que tanca el cicle es descarta, de manera que la cadena acaba al marc anterior.Acaba la cadena al seu últim marc: treu-li el next, o fes que continuï a la pàgina següent.
overflowTargetUnknownUn next no anomena cap marc de la plantilla; un overflow.continueIn no anomena cap marc ('#x') ni cap plantilla ('template:x'), o no té cap de les formes '#frame', 'next-page' i 'template:<id>'; o overflowTemplate no anomena cap plantilla. El contingut que no hi cap no hi continua.Corregeix el nom o l'id, o escriu una de les tres formes.
labelStyleUnknownUn ancoratge d'una imatge anomena un style que labelStyles no té. L'avís anomena el recurs. Els rètols d'aquest ancoratge prenen l'aspecte per defecte.Corregeix l'id de l'estil a l'ancoratge, o afegeix l'estil a labelStyles.

La versió de la configuració és la 15 des de les plantilles de pàgina (els paquets escrits abans es continuen carregant sense canvis: res del que diu una configuració anterior no canvia de significat).