我想用一遍又一遍重複的單字或短語來填充一頁。然後我將列印此頁。例如,
\documentclass[12pt]{article}
\usepackage[margin=0.5in]{geometry}
\usepackage{pgffor}
\begin{document}
\thispagestyle{empty}
\pagestyle{empty}
\setlength{\parindent}{0cm}
\def\Phrase{Phrase to repeat }
\def\repititions{400}%The issue is with the number 400.
\foreach \n in {0,...,\repititions}{\Phrase}
\end{document}
400
然而,我透過反覆試驗得出了這個數字。這並不是真正的問題,因為我將列印頁面,因此可以將數字設為\repetition
任意大。相反,這是一種煩惱。
所以,我的問題是:
有沒有辦法在頁面末尾停止循環,而不是
400
透過反覆試驗得出值?
答案1
頁面建立器是異步的,TeX 在排版段落時沒有任何頁面結束位置的線索。只有當段落結束時才會做出分頁決定。
我的策略是在一個框中建立巨大的段落,然後將其與所需的文字高度進行比較。如果它仍然低於它,則準備一個新的盒子並進行更多的重複。當我們有足夠的材料(頁面高度加上三行以確保)時,框會在所需的高度上分割並放在當前頁面上。
\documentclass[12pt]{article}
\usepackage[
margin=0.5in,
heightrounded, % whole number of lines on the page
showframe, % just for the example
]{geometry}
\usepackage{expl3}
\ExplSyntaxOn
% faster than \pgffor
\cs_set_eq:NN \repeatphrase \prg_replicate:nn
\ExplSyntaxOff
\pagestyle{empty}
\setlength{\parindent}{0cm}
\begin{document}
\def\Phrase{Phrase to repeat }
\count255=200 % or anything that seems fit
\loop
\typeout{Trying \the\count255\space\space repetitions}
\setbox0=\vbox{\repeatphrase{\count255}{\Phrase}}
\ifdim\ht0<\dimexpr\textheight+3\baselineskip\relax
\advance\count255 by 20
\repeat
\setbox0=\vbox to \textheight{
\vbadness=10000 % remove a spurious message
\vsplit0 to \textheight
}
\unvbox0
\end{document}
終端機和日誌檔案上的消息是
Trying 200 repetitions
Trying 220 repetitions
Trying 240 repetitions
Trying 260 repetitions
Trying 280 repetitions
Trying 300 repetitions
Trying 320 repetitions
起始點是 200,這是對所需內容的粗略估計(可以從 1 開始,但這似乎沒有意義)。
請注意,LaTeX 沒有公共接口\vsplit
,因此我們必須訴諸較低級別的程式設計。
expl3
這是基本上相同的完整版本。我只是為行間跳過添加了一點靈活性,以便更好地填充頁面。
\documentclass[12pt]{article}
\usepackage[
margin=0.5in,
heightrounded, % whole number of lines on the page
showframe, % just for the example
]{geometry}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\fillpage}{O{200}m}
{
\clearpage
\egreg_fillpage:nn { #1 } { #2 }
\clearpage
}
\int_new:N \l__egreg_fillpage_copies_int
\box_new:N \l__egreg_fillpage_box
\cs_new_protected:Npn \egreg_fillpage:nn #1 #2
{
\int_set:Nn \l__egreg_fillpage_copies_int { #1 }
\bool_do_until:nn
{
\dim_compare_p:nNn { \box_ht:N \l__egreg_fillpage_box } > { \textheight + 3\baselineskip }
}
{
\typeout{Trying~\int_eval:n { \l__egreg_fillpage_copies_int }~repetitions}
\vbox_set:Nn \l__egreg_fillpage_box
{
\skip_set:Nn \baselineskip { 1\baselineskip plus 0.1pt }
\prg_replicate:nn { \l__egreg_fillpage_copies_int } { #2 }
}
\int_add:Nn \l__egreg_fillpage_copies_int { 20 }
}
\vbox_set_split_to_ht:NNn \l__egreg_fillpage_box \l__egreg_fillpage_box { \textheight }
\box_use_drop:N \l__egreg_fillpage_box
}
\ExplSyntaxOff
\pagestyle{empty}
\setlength{\parindent}{0cm}
\begin{document}
\fillpage{Phrase to repeat }
\end{document}
此指令\fillpage
有一個可選參數用於設定初始重複次數(預設 200),因此
\fillpage[300]{Phrase to repeat }
將從300開始。
答案2
我的解決方案僅在臨時 box0 中列印一次重複文字。那麼這個box0就是\vsplit
到目前頁面了。
\toendpage{repeated text}
提供了宏。該巨集從當前點(無論是在頁面的開頭還是在頁面的中間都無關)填充當前頁面到頁面的結尾。
巨集\toendpage
需要計算我們需要多少文字重複。這個數字必須夠大,因此計算公式為
(1.3 * \hsize
/ 文字寬度 + 1) * 文字行數\pagegoal
宏如下:
\newcount\tmpnum
\def\toendpage#1{\par \bgroup
\setbox0=\hbox{#1}
\null \nobreak \vskip-\baselineskip % we need to set \pagegoal and set zero \prevdepth
\dimen0=\pagegoal
\divide\dimen0 by\baselineskip
\tmpnum=\dimen0 % \tmpnum= number of lines in \pagegoal
\dimen0=1.3\hsize
\divide\dimen0 by\wd0 % \dimen0= number of text in 1.3\hsize
\advance\dimen0 by1sp % increased by one
\multiply\dimen0 by\tmpnum % \dimen0= number of repeats of the text
\tmpnum=0
\setbox0=\vbox{\null \loop #1\advance\tmpnum by1 \ifnum\tmpnum<\dimen0 \repeat}
\vbadness=10000
\dimen0=\pagegoal \advance\dimen0 by-\pagetotal
\setbox0=\vsplit0 to\dimen0 % \vsplit to the end of the current page
\unvbox0
\vfil\break \egroup
}
Usage:
\toendpage{This is repeated text. }