ページの最後までループする

ページの最後までループする

1つの単語またはフレーズを何度も繰り返してページを埋めたいのですが、このページを印刷します。たとえば、

\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 は段落をタイプセットするときにページが終了する場所を把握していません。段落が終了した場合にのみ、ページ分割の決定が行われます。

私の戦略は、巨大な段落をボックス内に構築し、それを希望のテキストの高さと比較することです。それでもまだ希望の高さより低い場合は、より多くの繰り返しを含む新しいボックスを準備します。十分な素材 (ページの高さプラス 3 行) が揃ったら、ボックスを希望の高さで分割し、現在のページに配置します。

\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

私の解決策では、一時的なボックス 0 内の繰り返しテキストを 1 回だけ印刷します。その後、このボックス 0 が\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. }

関連情報