%20contido%20em%20uma%20macro.png)
Digamos que temos muito texto para ser digitado contido em uma única macro, vamos chamá-lo\myverylongtext
\newcommand{\myverylongtext}{
This is some really long text: \blindtext[4].
And it continues even more: \blindtext[1].
}
Para simplificar, digamos que não haja comando de seção/newpage em \myverylongtext
, mas ele pode ter comandos de quebra de linha e vários parágrafos (comandos de quebra de parágrafo?). Além disso, suponha que o tamanho da fonte e o início permaneçam constantes, embora todos os outros comandos de composição LaTeX (\textbf, etc) sejam permitidos no texto e devam entrar em vigor.
É possível definir uma macro eficiente* que (quando encontrada) obtenha o próximo pedaço de texto da dimensão especificada? Por exemplo:
\newcommand{\getnextchunk}[4]{
% #1 is name of macro (in our case \myverylongtext)
% #2 width of text box
% #3 height of text box in lines
% #4 draftmode: optional boolean argument that, when set, instead of typesetting contents returns the actual height (in lines), and width (in length units) of the chunk. (useful in making dynamic layout decisions)
% returns/typesets a box of shape width * height
}
Novas chamadas para esta macro \getnextchunk
devem obter o próximo pedaço de texto, como se o texto contido em \myverylongtext
refluísse do pedaço anterior para este pedaço.
* Isso \myverylongtext
pode ser muito longo e pode haver vários desses pedaços, portanto, é necessária eficiência. Você não pode digitar a parte restante \myverylongtext
várias vezes. Uma visão que tenho de solução para tal problema é que uma caixa de tamanho 0 seja preenchida iterativamente até atingir a métrica especificada: largura (em dimensão de comprimento), altura (em linhas) e justificativa necessária; embora eu não tenha compreensão de tex/luatex/expl3 de baixo nível para escrevê-lo sozinho.
Além disso, comandos de justificação como raggedright/raggedleft/full-justified especificados em \myverylongtext
devem entrar em vigor magicamente, ou podemos definir uma restrição de que não teremos tais comandos no \myverylongtext
&, em vez disso, passá-los como um quarto argumento para \getnextchunk
(acho que o último é preferível e tornaria mais fácil e/ou mais limpo codificar/usar).
Outra forma de visualizar o problema é imaginar que temos múltiplas caixas de texto retangulares (de diferentes larguras e alturas) que fluem umas para as outras sequencialmente à medida que as encontramos em nosso documento (não se preocupe com o posicionamento dessas caixas de texto, *tex já tem várias soluções elegantes para isso). Além disso, não sabemos quando e quantas dessas caixas de texto serão encontradas antecipadamente no documento. Na minha opinião, após anos de uso do *tex, resolver apenas esse problema abrirá inúmeras possibilidades e tornará o tex imbatível (contra o InDesign, etc.) em valor como ferramenta tipográfica para layouts orientados ao design. Ferramentas como InDesign e Affinity Publisher permitem vincular caixas de texto que eventualmente fluem entre si como um fluxo, e é algo indispensável para um sistema tipográfico que pretende atender à tipografia expressiva moderna e à pluralidade de designs. Isso pode abrir o *tex como compositor para uma comunidade de composição/design muito mais ampla.
Responder1
Minha solução não é exatamente o que você deseja, mas todas as informações são gerenciadas em um só lugar. Espero que não seja problema aceitar três passagens de parâmetros.
Os dados devem ficar assim:
% lines width
\declchunk 5 10cm ;
\declchunk 6 12cm ;
\declchunk 12 13cm ;
\declchunk 9 10cm ;
\declchunk 9 10cm ;
\declchunk 9 10cm ;
\declchunk 7 8cm ;
\declchunk 5 10cm ;
\formatchunks \myverylongtext
\setbox101 = \getnextchunk
\setbox102 = \getnextchunk \rebox 102:{\raggedright}
\setbox103 = \getnextchunk
\setbox104 = \getnextchunk \rebox 104:{\raggedleft}
\setbox105 = \getnextchunk
% you can place these boxes everywhere. the following code is only for testing:
box 101: \par \box101 \bigskip
box 102: \par \box102 \bigskip
box 103: \par \box103 \bigskip
box 104: \par \box104 \bigskip
box 105: \par \box105 \bigskip
\bye
Primeiro, determinamos as dimensões de todos os pedaços (por número de linhas para alturas e por dimensões para larguras). Em segundo lugar, formatamos o texto fornecido. Finalmente, podemos obter alguns dados e salvá-los em caixas, por exemplo. Eles são justificados para blocos por padrão. Se precisarmos fazer outra configuração, podemos reencaixar essas caixas. Nosso exemplo mostra que a segunda caixa está irregular para a direita e a quarta caixa está irregular para a esquerda. Além disso, você pode fazer
\vbox to<dimension>{\unvbox103} \vtop to12mm{\unvbox105} etc.
por exemplo, porque existe elasticidade e encolhimento entre as linhas.
Implementação: obtemos todos \parshape
os parâmetros pela lista de \declchunk
s, depois formatamos o texto usando esses parâmetros (apenas uma vez) \vbox\allchunks
e então fazemos \vsplit
quando \getnextcunk
é chamado. Finalmente, podemos fazer um pequeno re-boxing se o usuário precisar de uma justificativa de bloco de formulário diferente.
Minha implementação funciona apenas com TeX simples e TeX clássico. Não precisamos de nenhuma extensão TeX e (é claro) não precisamos de LaTeX :).
\newcount\tmpnum
\newcount\shapenum
\newcount\globpar
\newbox\allchunks
\newif\ifrepeat
\splittopskip=\baselineskip
\def\formatchunks#1{\setbox\allchunks=\vbox{%
\def\par{\ifhmode\shapepar\fi}
\def\shapepar{\prevgraf=\globpar
\parshape\shapenum\shapelist \endgraf
\globpar=\prevgraf
\ifnum\prevgraf>\shapenum \let\par=\endgraf \fi}
\dimen0=\baselineskip \baselineskip=\dimen0 plus2pt minus2pt
\widowpenalty=0 \clubpenalty=0 \brokenpenalty=0
\penalty0 #1\vfil}
\setbox0=\vsplit\allchunks to0pt % \splittopskip added
\expandafter \renewsize \sizelist \relax
}
\def\shapelist{} \def\sizelist{}
\splittopskip=\baselineskip
\def\shapelist{} \def\sizelist{}
\def\declchunk #1 #2;{\edef\sizelist{\sizelist#1\space}
\tmpnum=0
\loop \advance\tmpnum by1 \advance\shapenum by1
\edef\shapelist{\shapelist 0pt#2}%
\ifnum\tmpnum<#1 \repeat
}
\def\getnextchunk{\vsplit\allchunks to\size
\ifx\sizelist\empty \def\size{\baselineskip}%
\else \expandafter \renewsize \sizelist \relax \fi
}
\def\renewsize #1 #2\relax{%
\def\size{#1\baselineskip}\def\sizelist{#2}%
}
\def\rebox#1:#2{\setbox#1=\vbox{%
\setbox0=\hbox{}%
\repeattrue
\def\raggedright{\rightskip=0pt plus1fill minus1em \relax}%
\def\raggedleft{\leftskip=0pt plus1fill minus1em \relax}%
\hsize=\wd#1
\unvbox#1
\loop
\setbox2=\lastbox
\ifvoid2 \repeatfalse
\else \setbox0=\hbox{\hbox{\unhbox2}\penalty-10000 \unhbox0 }
\unskip\unskip\unpenalty
\fi
\ifrepeat \repeat
\null
#2\noindent \hfil \unhbox0 \par
}}
\def\myverylongtext{%
Lorem ipsum dolor sit amet, consectetuer
...
purus eget enim. Nunc vitae tortor. Proin tempus nibh sit amet nisl.
Vivamus quis tortor vitae risus porta vehicula.
}