%20contenido%20en%20una%20macro.png)
Digamos que tenemos una gran cantidad de texto para componer contenido en una sola macro, llamémosla\myverylongtext
\newcommand{\myverylongtext}{
This is some really long text: \blindtext[4].
And it continues even more: \blindtext[1].
}
Para simplificar, digamos que no hay un comando de sección/nueva página en \myverylongtext
, pero puede tener comandos de salto de línea y varios párrafos (¿comandos de salto de párrafo?). Además, suponga que el tamaño de fuente y el interlineado permanecen constantes en todo momento, aunque todos los demás comandos de composición tipográfica de LaTeX (\textbf, etc.) están permitidos dentro del texto y deberían tener efecto.
¿Es posible definir una macro eficiente* que (cuando se encuentre) obtenga el siguiente fragmento de texto de una dimensión especificada? Por ejemplo:
\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
}
Las nuevas llamadas a esta macro \getnextchunk
deberían obtener el siguiente fragmento de texto, como si el texto contenido en ella \myverylongtext
se redistribuyera del fragmento anterior a este fragmento.
* Esto \myverylongtext
puede ser muy largo y puede haber numerosos fragmentos de este tipo, por lo que se necesita eficiencia. No se puede componer la parte restante \myverylongtext
varias veces. Una visión que tengo de la solución para tal problema es que un cuadro de tamaño 0 se llena de forma iterativa hasta que crece hasta la métrica especificada: ancho (en dimensión de longitud), alto (en líneas) y justificación requerida; aunque no entiendo tex/luatex/expl3 de bajo nivel para escribirlo yo mismo.
Además, los comandos de justificación como raggedright/raggedleft/full-justified especificados en \myverylongtext
deberían surtir efecto mágicamente, o podemos establecer una restricción para que no tengamos dichos comandos en \myverylongtext
& en lugar de pasarlos como un cuarto argumento \getnextchunk
(creo que este último es preferible, y haría que sea más fácil y/o más limpio codificar/usar).
Otra forma de visualizar el problema es imaginar que tenemos múltiples cuadros de texto rectangulares (de diferente ancho y alto) que fluyen entre sí secuencialmente a medida que los encontramos en nuestro documento (no se preocupe por la ubicación de estos cuadros de texto, *tex ya tiene múltiples soluciones elegantes para eso). Además, no sabemos cuándo ni cuántos cuadros de texto de este tipo se encontrarán en el documento por adelantado. En mi opinión, después de años de usar *tex, resolver solo este problema abrirá toneladas de posibilidades y hará que tex sea imbatible (contra InDesign, etc.) en valor como herramienta tipográfica para diseños orientados al diseño. Herramientas como InDesign y Affinity Publisher permiten vincular cuadros de texto que eventualmente fluyen entre sí como una corriente, y es algo indispensable para un sistema tipográfico que pretende atender a la tipografía expresiva moderna y la pluralidad de diseños. Eso puede abrir a *tex como tipógrafo a una comunidad tipográfica/de diseño mucho más amplia.
Respuesta1
Mi solución no es exactamente la que usted desea, pero toda la información se administra en un solo lugar. Espero que no sea un problema aceptar tres pasadas sobre los parámetros.
Los datos deberían verse así:
% 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
Primero, calculamos las dimensiones de todos los fragmentos (por número de líneas para las alturas y por dimensiones para los anchos). En segundo lugar, formateamos el texto dado. Finalmente, podemos obtener algunos datos y guardarlos en cuadros, por ejemplo. Están justificados en bloques de forma predeterminada. Si necesitamos hacer otra configuración, podemos volver a colocar estas casillas. Nuestro ejemplo muestra que el segundo cuadro está irregular hacia la derecha y el cuarto cuadro está irregular hacia la izquierda. Es más, puedes hacer
\vbox to<dimension>{\unvbox103} \vtop to12mm{\unvbox105} etc.
por ejemplo, porque hay capacidad de estiramiento y contracción entre líneas.
Implementación: obtenemos todos \parshape
los parámetros mediante la lista de \declchunk
s, luego formateamos el texto usando estos parámetros (solo una vez) \vbox\allchunks
y luego lo hacemos \vsplit
cuando \getnextcunk
se llama. Finalmente, podemos modificar un poco el formato si el usuario necesita una justificación del bloque de formulario algo diferente.
Mi implementación funciona solo con TeX simple y TeX clásico. No necesitamos ninguna extensión TeX y (por supuesto) no necesitamos 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.
}