Capítulo 3.6 · Parte II · O ofício
Configuração: viúvas, órfãs e equilíbrio
As regras que mantêm linhas e blocos juntos numa quebra de coluna, e os recursos que fazem todas as colunas terminarem na mesma altura
Em poucas palavras
Esta página trata de como o Postext decide onde uma coluna ou uma página termina. Uma linha de um parágrafo não deve ficar sozinha no alto ou no pé de uma coluna, e um título não deve ficar separado do seu texto. Essas regras podem deixar uma coluna mais curta que as outras. O Postext então faz pequenas mudanças, numa ordem fixa, para que todas as colunas terminem na mesma altura. A página lista cada regra e cada mudança, e mostra como ver qual delas foi usada.
#Órfãs, viúvas, linhas curtas e regras de manter junto
Veja Hifenização e justificação para a mecânica por trás destes deméritos. Esta seção é a referência das chaves de bodyText que os controlam.
Além da hifenização e dos limites de espaçamento, a configuração do texto do corpo expõe as regras flexíveis que evitam quebras de parágrafo estruturalmente desajeitadas. Todas entram no algoritmo de quebra de linhas de Knuth-Plass como deméritos: elas puxam o layout para quebras limpas sem nunca impor uma regra rígida. Defina os valores *Penalty como 0 para desativar, na prática, qualquer uma delas.
| Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
avoidOrphans | boolean | true | Desestimula que um parágrafo termine com menos de orphanMinLines linhas no alto da coluna seguinte. Numa grade de caracteres (cjk.grid) da região japan o padrão é false. |
orphanMinLines | number | 2 | Mínimo de linhas exigidas no alto da coluna seguinte quando um parágrafo é dividido. Só atua quando avoidOrphans é true. |
orphanPenalty | number | 1000 | Demérito somado quando a restrição de órfã é violada. Valores maiores inclinam o algoritmo mais fortemente contra órfãs; 0 desativa a penalidade. |
avoidOrphansInLists | boolean | true | Com true, os itens de lista também recebem proteção contra órfãs (não só os parágrafos). Só tem efeito quando avoidOrphans é true. |
avoidWidows | boolean | true | Desestimula que um parágrafo comece com menos de widowMinLines linhas no pé da coluna atual. Numa grade de caracteres (cjk.grid) o padrão é false: a página contém as linhas que a grade conta. |
widowMinLines | number | 2 | Mínimo de linhas exigidas no pé da coluna atual quando um parágrafo é dividido. Só atua quando avoidWidows é true. |
widowPenalty | number | 1000 | Demérito somado quando a restrição de viúva é violada. 0 desativa a penalidade. |
avoidWidowsInLists | boolean | true | Com true, os itens de lista também recebem proteção contra viúvas. Só tem efeito quando avoidWidows é true. |
shortListSplit | 'allow' | 'warn' | 'avoid' | 'allow' | Uma lista curta dividida entre duas colunas ou páginas: uma lista de até shortListMaxItems itens no texto corrido, como uma de três itens composta em 1 + 2. avoidOrphansInLists e avoidWidowsInLists mantêm juntas as linhas de um item; esta regra mantém juntos os itens de uma lista. 'allow' divide a lista onde a coluna termina, como qualquer outra. 'warn' não muda a diagramação e relata cada lista dividida (um aviso shortListSplit, veja Avisos no documento). 'avoid' compõe a lista inteira: se ela não couber abaixo do que a coluna já tem, abre a coluna seguinte, e os títulos logo acima dela e a linha dos dois-pontos que a introduz (keepColonWithList) vão junto. Uma lista mais alta que uma coluna vazia é dividida como qualquer outra, e relatada. As listas dentro de um :::callout seguem as regras de corte do próprio boxe, e as entradas de :::toc e de :::index não são listas. Desde o postext 1.28. |
shortListMaxItems | number | 3 | Quantos itens uma lista pode ter, no máximo, para contar como curta em shortListSplit, incluídos os das suas listas aninhadas. Um número inteiro, no mínimo 1. Desde o postext 1.28. |
avoidRunts | boolean | true | Desestimula parágrafos que terminam com uma última linha muito curta, uma linha curta (runt), por exemplo uma única palavra curta sozinha. Vale também para texto alinhado à esquerda, com optimalRagged. Um parágrafo em chinês, japonês ou coreano não termina numa linha com um só caractere, sozinho ou com os sinais de fechamento (孤字): a linha de cima lhe cede o último caractere quando ainda pode ser justificada dentro do limite de tracking. Uma linha alinhada à esquerda, à direita ou centralizada também o cede e fica um caractere mais curta; com cjk.grid.fullLines (papel de manuscrito) mantém todas as casas, e o parágrafo pode terminar em um só caractere. |
runtMinCharacters | number | 20 | Limite para a última linha de um parágrafo, contado em espaços entre palavras, não em letras: a linha é curta quando é mais estreita que runtMinCharacters × normalSpaceWidth pixels. Um espaço entre palavras mede de um quarto a um terço de eme na maioria das fontes de texto, cerca de meia letra minúscula, então o padrão 20 pega últimas linhas com menos de 4 a 7 emes, mais ou menos 8 a 12 letras. Para pegar as últimas linhas com menos de cerca de N letras, use um valor perto de 2 × N. |
runtPenalty | number | 1000 | Equivalente de badness injetado na fórmula de demérito quadrático de Knuth–Plass (mesma escala da badness da linha, que satura em 10000). 0 desativa a penalidade. |
gradedRuntPenalty | boolean | false | Gradua a penalidade de linha curta conforme o quanto a última linha fica curta: uma última linha de largura w abaixo do limite t custa runtPenalty × (1 − w / t) em vez da penalidade inteira. Um final de duas palavras passa a custar menos que um de uma, e o algoritmo de quebra desce uma palavra quando uma linha de cima pode cedê-la ('…sallies of' / 'our minds.' em vez de '…sallies of our' / 'minds.'). Desligado por padrão: toda linha curta custa o mesmo, e o algoritmo mantém as linhas mais apertadas acima. |
avoidRuntsInLists | boolean | true | Com true, os itens de lista também recebem a penalidade de linha curta. Só tem efeito quando avoidRunts é true. |
tightenRunts | boolean | true | Quando a penalidade não conseguiu evitar uma linha curta, compõe o parágrafo com uma linha a menos: os espaços entre palavras se apertam (nunca abaixo de minWordSpacing) e, se isso não bastar para recolher a linha, entra um pouco de tracking negativo. A versão mais curta é recusada, e a linha curta fica, quando esticaria uma linha justificada além de maxWordSpacing ou, se o parágrafo já tiver uma linha justificada mais frouxa, além dessa linha, ou quando deixaria mais linhas em bandeira (além de 3× o espaço normal) do que o parágrafo tinha. Os espaços entre palavras do texto alinhado à esquerda mantêm a largura, então ali só o tracking participa. Requer optimalLineBreaking e avoidRunts (e optimalRagged para texto alinhado à esquerda). |
maxRuntTracking | number | 10 | O máximo de tracking que a correção de uma linha curta pode usar, em milésimos de eme (a unidade do InDesign: 10 = 0,01 em por caractere), aplicado como aperto. 0 deixa a correção só para o espaçamento entre palavras. |
slackWeight | number | 10 | Peso aplicado ao custo quadrático do “espaço de coluna não usado”. Valores maiores fazem o layout preferir encher bem as colunas; 0 desativa totalmente a pressão de folga. |
keepColonWithList | boolean | true | Quando um parágrafo termina com dois-pontos que introduzem diretamente uma lista, mantém a última linha, a dos dois-pontos, junto da lista: se colocar o parágrafo não deixar espaço para o primeiro item da lista começar na mesma coluna/página, a última linha (ou o parágrafo inteiro, se tiver uma só linha) passa para a coluna seguinte junto com a lista. Quanto espaço basta é definido por colonListRoom. Quando esta regra empurraria o parágrafo inteiro e há uma sequência de títulos logo antes dele na coluna, esses títulos também são levados adiante, para que headings.keepWithNext continue valendo. |
colonListRoom | 'item' | 'line' | 'item' | O espaço que keepColonWithList pede sob a linha dos dois-pontos. 'item': o que as regras de órfãs e viúvas para listas deixariam do primeiro item no pé da coluna, uma linha quando ele pode ser dividido ali, ele inteiro quando elas o mantêm junto (um item de duas linhas, por exemplo). 'line': uma linha, como até o postext 1.4; um primeiro item que essas regras mantêm inteiro vai então sozinho para a coluna seguinte e deixa a linha dos dois-pontos no pé. Uma configuração salva antes do configVersion 6, num livro que introduz uma lista com dois-pontos, é lida com 'line' (veja Pacotes gravados pelo postext 1.4 ou anterior). Qualquer outro valor é lido como 'item'. |
hyphenateAcrossColumns | boolean | 'withinPage' | true | Permite que uma coluna ou uma página termine numa palavra hifenizada (o Hyphenate Across Column do InDesign). false quebra de novo o parágrafo que atravessa a quebra de coluna, para que a última linha dele na coluna termine numa palavra inteira; os espaços entre palavras das linhas acima absorvem a diferença, dentro de maxWordSpacing e minWordSpacing. É uma preferência: onde nenhuma quebra dentro desses limites o evita, o hífen fica. Tenta todas as quebras de coluna de um parágrafo: a primeira e as seguintes que caem onde termina uma coluna cheia, numa só requebra; e uma quebra posterior que cai em outro ponto (uma viúva mantida, um corte de faixa nivelado) em outra, a partir dessa coluna, que mantém nas suas quebras as linhas já compostas nas colunas anteriores e só quebra o resto. 'withinPage' protege as linhas que fecham uma página e nenhuma outra: uma palavra pode ser dividida entre duas colunas de uma mesma página, e a última linha de uma página termina numa palavra inteira sempre que os limites permitem. Muda menos linhas que false, o que pesa em três ou mais colunas, onde dois de cada três fins de coluna ficam dentro da página; em uma coluna só, os dois valores dão as mesmas linhas. Uma coluna fecha a sua página quando nenhuma coluna posterior da página recebe texto: não recebe uma coluna lateral reservada aos flutuantes, nem uma coluna que uma tabela ou uma figura preencheu. O corpo dos boxes não é afetado. Com optimalRagged, um parágrafo alinhado à esquerda é quebrado de novo da mesma forma: os espaços entre palavras mantêm a largura, então só os finais das linhas se movem. Cada requebra mede o parágrafo mais uma vez, por isso um livro com muitos hífens em fim de coluna é diagramado um pouco mais devagar. Requer optimalLineBreaking, e optimalRagged para texto alinhado à esquerda. |
paragraphContainerSpacing | 'collapse' | 'add' | 'collapse' | O espaço sob um contêiner :::paragraphs que fecha num parágrafo, entre esse parágrafo e o bloco seguinte (veja O contêiner :::paragraphs). 'collapse': o maior entre o spaceBetween e o marginBottom do estilo e o espaçamento de parágrafo do texto em volta do contêiner (uma linha com paragraphSpacing; num boxe, o do boxe), fundido com o espaço que o bloco seguinte reserva acima de si, como entre dois parágrafos de texto corrido: um título sob uma bibliografia fica à distância do próprio marginTop, não dessa margem mais o espaçamento das entradas. 'add': como até o postext 1.4, só o espaço do estilo é posto sob a última linha antes do ajuste à grade, o espaço próprio do bloco seguinte é somado abaixo dele, e o espaçamento de parágrafo fica de fora, de modo que o parágrafo depois do contêiner podia ficar mais perto dele do que de qualquer outro. Uma configuração salva antes do configVersion 8 que declara um estilo de parágrafo, num livro que contém um contêiner assim, é lida com 'add' (veja Pacotes gravados pelo postext 1.4 ou anterior). Um marginBottom negativo puxa o bloco seguinte para cima em qualquer caso. Um estilo de parágrafo pode definir a própria regra para seus contêineres (containerSpacing, desde o postext 1.28). |
Sobre linhas curtas. Uma linha curta é a última linha de um parágrafo curta demais para parecer uma linha de texto de verdade, em geral uma ou duas palavras curtas isoladas no fim do parágrafo. Como a verificação se baseia no comprimento da linha em pixels em relação à largura do espaço normal, runtMinCharacters se adapta sozinho ao corpo da fonte atual. Uma palavra curta que, visualmente, é mais larga que runtMinCharacters × spaceWidth não tem problema; uma palavra mais estreita que isso (ou realmente sozinha) recebe a penalidade de linha curta. O limite conta espaços entre palavras, que têm cerca de metade da largura das letras: o padrão 20 corresponde a uma última linha de mais ou menos 8 a 12 letras. Toda linha curta custa a penalidade inteira, então entre dois finais abaixo do limite o algoritmo de quebra mantém as linhas mais apertadas acima; gradedRuntPenalty cobra cada um pelo que lhe falta, e o final mais longo vence. Para os curiosos de matemática: com o runtPenalty padrão de 1000, evitar uma linha curta supera qualquer conjunto de quebras alternativo que exija um esticamento do espaçamento entre palavras de até cerca de r≈2,15.
Flexíveis, não rígidas. Nenhuma destas regras pode impedir uma quebra: o motor sempre produz um layout. São deméritos: o algoritmo pondera badness, custo de hifenização, suavidade das classes de aptidão e estas penalidades estruturais numa única otimização global e escolhe o conjunto de quebras com o menor custo total. Se você precisa de uma garantia mais firme, aumente a penalidade; se um documento fica melhor com a penalidade mais branda, diminua-a.
#Equilíbrio de colunas
As editoras esperam que toda coluna comece no alto da página e termine alinhada com o pé. As regras de quebra (proteção contra órfãs e viúvas, títulos mantidos com o seu texto, figuras indivisíveis) deixam naturalmente colunas curtas, com uma ou mais linhas vazias da grade de linhas de base no pé. Com o equilíbrio ativado, o motor faz o que um compositor faria e aplica seus recursos na ordem de prioridade editorial:
- Um boxe que fecha a coluna: um boxe que termina uma coluna curta é empurrado para baixo exatamente pelo espaço que sobra sob o seu pé, de modo que a borda inferior cai na última posição da grade da página, alinhada com a última linha da coluna ao lado. Ele ocupa esse espaço mesmo quando é menor que uma linha, desde que nada passe para outra coluna. Por padrão, roda antes de qualquer outro recurso e ocupa a lacuna inteira, então um boxe que comenta o parágrafo acima dele pode acabar várias linhas abaixo;
closingBox: 'last'deixa os títulos, os finais de lista e os outros recursos de espaçamento ficarem primeiro com as linhas inteiras, e o boxe só com o que sobrar, eclosingBox: 'off'nunca o move. - Imagens com área segura: uma imagem com área segura (
Resource.safeArea, veja Formato do documento › Área segura) inserida na linha da coluna curta, ou flutuando no alto ou no pé dela só sobre essa coluna, cresce em linhas inteiras da grade, recortada dentro da área segura, até a coluna ficar cheia ou o recorte chegar à área segura. Uma imagem mais alta não deixa buraco na página, por isso roda antes de qualquer espaço ser somado; um flutuante no alto de uma coluna numa página ou faixa cujas cabeças de coluna ficam niveladas (veja abaixo) não cresce. Registrado comoflexFigure. Não tem ajuste próprio: só cresce uma imagem cujo recurso marca uma área segura. - Títulos: linhas inteiras da grade são somadas à margem superior dos títulos dentro da coluna curta. Quando são necessárias várias linhas e a coluna tem vários títulos, as linhas se distribuem entre eles, sempre com a maior parte para o título mais importante (um
h2recebe mais que umh3). Títulos no alto de uma coluna nunca recebem espaço extra, para que as colunas continuem começando no alto da página, exceto um título logo abaixo de uma figura ou tabela que encabeça a coluna numa página que continua: o espaço vai acima desse título, sob a figura. Um título recebe assim no máximomaxLinesBeforeLooselinhas (duas por padrão) antes de os recursos seguintes serem tentados, e as demais, atémaxLinesPerHeading, só quando eles não têm mais o que dar. - Finais de lista: quando os títulos não conseguem absorver a lacuna inteira, uma linha da grade é somada onde uma lista ou enumeração termina (espaço depois de uma lista soa natural), com um limite por final de lista.
- Sob fórmulas, boxes e figuras: depois, uma linha da grade vai sob uma fórmula em destaque ou um boxe depois do qual o texto continua (
stretchAfterDisplays; ela é lida como margem do próprio elemento), e sob uma figura ou tabela que encabeça a coluna (stretchAfterFloats, com o limite demaxLinesAfterFloat). - Parágrafos frouxos: como último recurso, um parágrafo da coluna é quebrado de novo com uma linha a mais (o
\looseness=+1do TeX), escolhendo o parágrafo mais longo para que o espaçamento extra entre palavras se dilua sem ser notado. A solução frouxa só é aceita quando toda linha fica abaixo debodyText.maxWordSpacing: a cor tipográfica nunca passa do limite que você já configurou. RequerbodyText.optimalLineBreaking.
Numa grade de caracteres (cjk.grid, veja Composição chinesa › A grade de caracteres) cada caractere ocupa uma célula de um em de largura e cada linha cai no passo de linhas da grade, que é também a grade de linhas de base. Ali o equilíbrio fica desativado por padrão, como no texto vertical: uma página composta linha a linha sobre uma grade, à maneira da GB/T 9704, que conta 22 linhas de 28 caracteres, deixa curta a coluna que termina curta. Uma configuração que define enabled: true recebe recursos que respeitam a grade: os títulos, os finais de lista, as fórmulas em destaque e as figuras ocupam linhas inteiras da grade, de modo que o texto abaixo deles se desloca em fileiras inteiras, e gridLines: 'off' deixa esses recursos de fora para uma norma que não tem nenhuma fileira vazia para ceder. Um parágrafo chinês ou japonês ganha uma linha só quando nenhum vão entre dois dos seus caracteres se abre mais que maxTracking, e não recebe tracking nas suas letras: uma linha a que falta um caractere distribui um em pelos seus vãos, muito acima dos 0,01 em do padrão, então numa grade de células inteiras o recurso dos parágrafos frouxos quase nunca encontra nada. O boxe que fecha uma coluna e as imagens com área segura ficam fora da grade por projeto e funcionam como em qualquer outra página.
A última coluna de uma página só é equilibrada quando a página continua naturalmente na seguinte: a página de fechamento de um capítulo pode, legitimamente, terminar curta. Uma página assim, e uma faixa de fechamento cortada por igual por trailing, também mantém niveladas as cabeças de coluna: nenhuma linha é somada sob uma figura ou tabela que encabeça uma das colunas (o recurso de depois do flutuante), e um título ou um boxe que abre uma coluna sob essa figura fica no alto dela, diga o que disser stretchAfterFloats, assim como o título que vem logo abaixo de uma abertura span: 'page', na coluna dessa abertura, de modo que uma coluna nunca começa mais abaixo que a vizinha só para alinhar os pés.
| Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
enabled | boolean | true | Se os pés das colunas são equilibrados. Desativado por padrão no texto vertical (layout.) e numa grade de caracteres (cjk.grid.enabled, desde o postext 1.25); true o ativa ali também. |
maxLinesPerHeading | number | 4 | Máximo de linhas extras da grade que podem ser somadas acima de um único título. |
maxLinesBeforeLoose | number | 2 | Linhas da grade que um título pode receber antes de tentar os recursos seguintes: os finais de lista, as fórmulas e os boxes, as figuras e os parágrafos frouxos. O título só recebe as demais, até maxLinesPerHeading, quando esses recursos não têm mais o que dar, de modo que uma página com um único título não abre quatro linhas acima dele enquanto os parágrafos poderiam ganhar uma linha. Um valor igual ou maior que maxLinesPerHeading dá primeiro todas as linhas aos títulos, como até o postext 1.27; 0 tenta os outros recursos antes de somar qualquer linha acima de um título. Desde o postext 1.28; os documentos salvos antes mantêm a ordem anterior (pinLegacyLooseOrder). |
stretchAfterLists | boolean | true | Permite linhas extras da grade onde uma lista termina, quando os títulos não conseguem absorver a lacuna inteira. |
maxLinesAfterList | number | 1 | Máximo de linhas extras da grade depois de um único final de lista. |
stretchAfterDisplays | boolean | true | Permite uma linha extra da grade sob uma fórmula em destaque, e sob um boxe, na coluna curta, depois do recurso de final de lista: o bloco seguinte desce uma linha. Defina como false para deixar o espaço sob fórmulas e boxes como as próprias margens definem; a lacuna passa aos recursos seguintes, e a coluna termina curta se eles não a fecharem. Desde o postext 1.28. |
stretchAfterFloats | boolean | true | Permite linhas extras da grade sob uma figura ou tabela que encabeça a coluna curta (um flutuante no alto), depois do recurso de final de lista, para que o texto abaixo desça em vez de a coluna terminar curta. Nunca numa página que não continua (a página de fechamento de um capítulo) nem numa faixa de fechamento cortada por igual por trailing: ali as cabeças de coluna ficam niveladas e a última coluna pode terminar uma linha mais curta. O primeiro bloco sob a figura pode ser o resto de um parágrafo começado na página anterior: ele desce do mesmo jeito, pela linha que as regras de quebra deixaram livre no pé da coluna (uma linha que a regra de viúvas deixou vazia, ou um espaço de parágrafo sem lugar para texto depois dele). Defina como false para manter o texto logo abaixo da figura. Sob um flutuante em várias colunas, as colunas descem juntas ou não descem: veja stretchAfterWideFloats. |
maxLinesAfterFloat | number | 1 | Máximo de linhas extras da grade sob um único flutuante no alto. |
stretchAfterWideFloats | 'flush' | 'always' | 'flush' | Sob uma figura ou tabela que ocupa duas ou mais colunas de texto. Com 'flush', uma coluna só desce sob ela quando todas as colunas de texto sob o flutuante recebem as mesmas linhas, de modo que as cabeças continuam niveladas, ou quando as linhas deixam essa coluna rente ao pé; não se soma uma linha que baixaria a cabeça de uma coluna e ainda a deixaria curta, e a lacuna passa aos parágrafos frouxos. 'always' estica essa coluna como sob qualquer flutuante, como até o postext 1.27. Qualquer outro valor é lido como 'flush'. Desde o postext 1.28; os documentos salvos antes mantêm 'always' (pinLegacyWideFloatStretch). |
looseParagraphs | boolean | true | Último recurso: quebra de novo parágrafos de uma coluna curta com uma linha mais frouxa (uma linha a mais cada um), dentro de bodyText.maxWordSpacing. |
maxLooseParagraphs | number | 2 | Quantos parágrafos de uma mesma coluna curta podem ganhar uma linha, do mais longo para o mais curto. |
trackParagraphs | boolean | true | Quando o espaçamento entre palavras sozinho não consegue ganhar a linha, um parágrafo frouxo pode também usar o menor tracking positivo (espaçamento entre letras) que consiga. |
maxTracking | number | 10 | Limite superior desse tracking, em milésimos de eme por caractere (10 = 0,01 em). |
trailing | boolean | true | Nivela a faixa de fechamento de um capítulo e do documento: quando o fluxo termina antes de a página ficar cheia (numa abertura de capítulo, num :::part, num boxe placement: 'fixed' que fecha o capítulo ou no fim do documento) com as colunas desiguais, elas são cortadas por igual, com um limite de faixa de ceil(Σ used / N / grid) linhas, resolvido depois que os recursos acima acertaram as páginas anteriores, para que uma bibliografia curta termine na mesma altura em todas as colunas em vez de encher a primeira e deixar a última meio vazia. O corte respeita as regras que uma faixa sem corte respeita: quando um bloco que não pode ser dividido nele (uma cauda de parágrafo que os mínimos de órfãs e viúvas mantêm inteira, um boxe que se mantém junto) passaria do corte, e perderia as últimas linhas, já que os renderizadores recortam a coluna pela sua caixa, ou quando um título fecharia uma coluna enquanto o texto dele abre a seguinte (com headings.keepWithNext, o padrão), o corte desce uma linha, até três vezes, e senão é abandonado. Um bloco que não consegue começar nas linhas que o corte deixa sob uma figura que encabeça uma coluna (um parágrafo precisa ali do seu mínimo de órfãs) passa para a coluna seguinte da faixa, como faria a partir de uma coluna sem corte, e a figura fica sozinha na coluna. Colunas cujos pés diferem em uma linha da grade ou menos ficam como estão: uma faixa de fechamento cuja última coluna termina uma linha mais curta é o acabamento habitual, e cortá-la só moveria uma linha. O corte vai para a faixa em que foi medido, e o mesmo vale para o corte que um boxe de página inteira pede no meio da página: até o postext 1.4, quando o primeiro texto da página de fechamento tinha sido oferecido antes a uma faixa sem espaço para ele (uma página que um flutuante ocupa inteira, a faixa estreita que um boxe de página inteira deixa no pé da página anterior), o corte era gasto nessa faixa e a página de fechamento mantinha todas as linhas na primeira coluna. Colunas de larguras diferentes (um layout de coluna e meia com texto nas duas) são cortadas por área, com a altura de cada coluna ponderada pela largura, já que uma linha da coluna estreita comporta menos texto. Só atua quando enabled é true. |
trailingStep | 'lines' | 'grid' | 'lines' | A unidade do corte por igual que trailing faz (e do corte que beforeSpan faz atrás de um boxe que passa para a página seguinte). 'lines': uma faixa cujo texto tem entrelinha própria (um índice, uma lista de referências, um contêiner em corpo pequeno) é cortada, e tentada de novo, por linhas inteiras dessa entrelinha: a altura que a maioria das linhas da faixa tem, sem contar títulos e boxes. As colunas terminam então com no máximo uma linha de diferença, como numa faixa de texto base. Uma faixa de texto base, e uma que mistura duas entrelinhas em partes iguais, é cortada na grade de linha de base como antes. Também uma faixa cujas linhas têm a mesma altura mas ficam separadas por uma fração de linha (referências com um espaço entre as entradas, grupos de índice com uma margem posta à mão): quatro de cada cinco linhas de cada coluna precisam estar a um número inteiro de linhas umas das outras. 'grid': todo corte é um número inteiro de linhas da grade de linha de base, como até o postext 1.27, em que um corte na grade deixava entrar uma linha a mais numa coluna de uma faixa fora da grade e um corte que falhava descia mais do que uma linha dela (colunas com até três linhas de diferença). Qualquer outro valor é lido como 'lines'. Desde o postext 1.28; os documentos salvos antes mantêm 'grid' (pinLegacyTrailingStep). |
beforeSpan | boolean | true | Nivela a faixa que um bloco de página inteira deixa para trás: quando um boxe span: 'page' não cabe sob as colunas atuais nem depois de um corte por igual, e precisa passar para a página seguinte ou se dividir (calloutStyles[].), as colunas que ele interrompe são cortadas por igual, com o mesmo limite de fechamento que uma faixa de fechamento recebe, em vez de a primeira encher a página e a última terminar curta. A página fica como uma quebra explícita, para que os recursos acima não estiquem de novo a última coluna até o pé da página; o boxe, ou a parte dele que cabe, fica então sob as colunas niveladas. Só atua quando enabled é true. |
closingBox | 'first' | 'last' | 'off' | 'first' | Quando um boxe que fecha uma coluna curta ocupa o espaço sob o seu pé (recurso 1, registrado como trailingCallout). 'first': antes de qualquer outro recurso, como até o postext 1.4; o boxe ocupa a lacuna inteira, mesmo várias linhas, e os títulos acima dele não recebem nada. 'last': depois dos recursos de título, final de lista, fórmula em destaque e flutuante, que ficam primeiro com as linhas inteiras; o boxe desce com o texto acima dele e depois ocupa só o que sobrou, em geral uma fração de linha, de modo que o pé dele ainda encontra a última posição da grade e ele fica perto do texto que comenta. 'off': nunca; o boxe mantém o espaço sob o seu pé, embora os outros recursos ainda possam descê-lo em linhas inteiras quando somam espaço acima dele, e a fração de linha que sobra sob ele fica. Numa página de fechamento, onde o boxe é o único recurso que alinha o seu pé com a coluna ao lado, 'off' o deixa onde o fluxo o pôs. Qualquer outro valor é lido como 'first'. Um boxe que fecha a única coluna de texto da sua faixa (uma página de uma coluna que termina antes, com o bloco seguinte abrindo a página seguinte) nunca é movido: não há coluna ao lado com a qual alinhar (desde o postext 1.19). |
gridLines | 'allow' | 'off' | 'allow' | Numa grade de caracteres: se os recursos que somam linhas inteiras da grade (acima de um título, onde uma lista termina, sob uma fórmula em destaque ou um boxe, sob uma figura que encabeça a coluna) podem atuar. Eles mantêm cada caractere na sua célula; 'off' convém a uma norma que conta as linhas da página, e deixa a coluna curta. Sem efeito fora da grade. Qualquer outro valor é lido como 'allow'. Desde o postext 1.25. |
#Qual recurso atuou
O layout registra cada recurso aplicado no bloco em que o aplicou: block.balancing no VDT que buildDocument devolve. Uma prova, um teste ou um relatório pode dizer por que uma coluna termina alinhada, e quais colunas nenhum recurso conseguiu fechar. Os blocos que o equilíbrio não tocou não levam balancing, e um documento construído com enabled: false não tem nenhum.
Numa grade de caracteres o documento diz por que uma coluna pode terminar curta: doc.gridBalancing é { off: true } quando o equilíbrio está desativado porque a página está sobre uma grade e a configuração não o ativa, e { gridLines: 'off' } quando ele roda sem os recursos de linhas inteiras; uma coluna que continua curta leva column.gridRefused, os recursos que a grade lhe negou ('looseParagraph' quando um parágrafo só podia ganhar a sua linha tirando os caracteres das suas células, e os recursos de linhas inteiras com gridLines: 'off'). Nenhum dos dois aparece fora da grade.
interface VDTBalancing {
levers: BalanceLever[]; // em geral um: um parágrafo depois de uma lista pode ficar com a linha do final de lista e também ganhar uma linha
spaceAbove: number; // px que os recursos de espaçamento somaram acima do bloco (0 quando só atuou looseParagraph ou flexFigure)
bodyGrowth?: number; // flexFigure: px que a imagem cresceu, recortada dentro da área segura
extraLines?: number; // looseParagraph: linhas que o parágrafo ganhou
tracking?: number; // looseParagraph: o tracking que as ganhou, em milésimos de eme (0 = só espaçamento entre palavras)
}
type BalanceLever = 'trailingCallout' | 'flexFigure' | 'heading' | 'listEnd' | 'afterDisplay' | 'afterFloat' | 'looseParagraph';| Recurso | Registrado em | O que fez |
|---|---|---|
trailingCallout | o bloco de moldura do boxe | Um boxe que fecha a coluna desceu exatamente pelo espaço sob o seu pé (spaceAbove; uma fração de linha é aceitável). |
flexFigure | o bloco da imagem (na linha) ou o flutuante | Uma imagem com área segura composta bodyGrowth px mais alta, em linhas inteiras da grade, recortada dentro da área segura. O bodySource do bloco do recurso é a parte mostrada e bodyFlex.delta, o mesmo crescimento. |
heading | o título | Linhas inteiras da grade acima do título, até maxLinesPerHeading. |
listEnd | o primeiro bloco depois da lista | Uma linha da grade onde uma lista termina, até maxLinesAfterList. |
afterDisplay | o bloco depois da fórmula ou do boxe | Uma linha da grade sob uma fórmula em destaque ou um boxe. |
afterFloat | o primeiro bloco da coluna | Uma linha da grade entre uma faixa de flutuantes que encabeça a coluna e o texto dela, até maxLinesAfterFloat. |
looseParagraph | o parágrafo | O parágrafo quebrado de novo com extraLines a mais, com o menor tracking que o conseguiu (tracking; block.letterSpacing é o mesmo valor em px). |
Os cortes por igual ficam registrados nas colunas que cortam: column.bandCapped é true em toda coluna cortada por igual (a faixa que um boxe de página inteira deixa, uma faixa de fechamento), e column.trailingCap marca também a faixa de fechamento de um capítulo ou do 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('closing band cut level');
else if (column.bandCapped) levers.push('band cut level');
if (levers.length > 0) console.log(`page ${page.index + 1}, column ${i + 1}: ${levers.join(', ')}`);
});
}
// page 3, column 1: heading, heading
// page 3, column 2: listEnd, looseParagraph