
假設我們有很多需要排版的文字包含在一個巨集中,我們稱之為\myverylongtext
\newcommand{\myverylongtext}{
This is some really long text: \blindtext[4].
And it continues even more: \blindtext[1].
}
為簡單起見,假設 中沒有分段/新頁命令\myverylongtext
,但它可以有換行命令和多個段落(分段命令?)。另外,假設字體大小和行距始終保持不變,儘管文字中允許所有其他 LaTeX 排版命令(\textbf 等)並且應該生效。
是否可以定義一個高效率的*巨集(當遇到時)取得指定尺寸的下一個文字區塊?例如:
\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
}
對此巨集的新呼叫應該會取得下一個文字區塊,就好像包含在從前一個區塊回流到此區塊中\getnextchunk
的文字一樣。\myverylongtext
* 這\myverylongtext
可能會很長,而且這樣的塊可能有很多,所以需要效率。您不能\myverylongtext
多次排版剩餘部分。我對此類問題的解決方案的一個願景是,迭代填充大小為 0 的盒子,直到它增長到指定的度量:寬度(以長度尺寸)、高度(以行為單位)和所需的理由;雖然我缺乏對低階 tex/luatex/expl3 的理解來自己寫它。
另外,要么像 raggedright/raggedleft/full-justified 這樣指定的對齊命令\myverylongtext
會神奇地生效,要么我們可以設定一個限制,在 & 中不會有這樣的命令,\myverylongtext
而是將其作為第四個參數傳遞給\getnextchunk
(我認為後者是更可取,並且會使編碼/使用更容易和/或更乾淨)。
視覺化問題的另一種方法是想像我們有多個矩形文字方塊(不同寬度和高度),當我們在文件中遇到它們時,這些矩形文字方塊會依次流入彼此(不用擔心這些文字方塊的放置, *tex 已經有多種優雅的解決方案)。另外,我們不知道文檔中何時以及會遇到多少這樣的文字方塊。在我看來,從多年使用 *tex 的經驗來看,解決這一問題將開啟大量的可能性,並使 tex 作為面向設計的佈局的排版工具具有無與倫比的價值(相對於 InDesign 等)。 InDesign 和 Affinity Publisher 等工具允許連結文字框,最終以流的形式相互流入,對於旨在滿足現代表現力排版和多元化設計的排版系統來說是不可或缺的。這可以將 *tex 作為排版機向更廣泛的排版/設計社群開放。
答案1
我的解決方案並不完全是您想要的,但所有資訊都在一個地方進行管理。我希望接受三次參數不會有問題。
數據應如下所示:
% 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
首先,我們指定所有區塊的尺寸(以行數表示高度,以尺寸表示寬度)。其次,我們格式化給定的文字。最後,我們可以獲得一些數據並將它們保存到盒子中,例如。預設情況下,它們是合理的。如果我們需要進行其他設置,那麼我們可以重新裝箱這些盒子。我們的範例顯示第二個框右側參差不齊,第四個框左側參差不齊。此外,你可以做
\vbox to<dimension>{\unvbox103} \vtop to12mm{\unvbox105} etc.
例如,因為線條之間存在伸縮性。
實作:我們\parshape
透過 s 列表取得所有參數\declchunk
,然後使用這些參數(僅一次)格式化文本,然後在呼叫時\vbox\allchunks
執行。最後,如果使用者需要稍微不同的表單區塊對齊方式,我們可以進行一些重新裝箱。\vsplit
\getnextcunk
我的實作僅適用於純 TeX 和經典 TeX。我們不需要任何 TeX 擴展,(當然)我們也不需要 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.
}