Schleife bis zum Ende einer Seite

Schleife bis zum Ende einer Seite

Ich möchte eine Seite mit einem einzelnen Wort oder Satz füllen, der immer und immer wieder wiederholt wird. Diese Seite werde ich dann ausdrucken. Zum Beispiel:

\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}

400Ich bin jedoch durch Ausprobieren auf die Zahl gekommen . Das ist kein wirkliches Problem, da ich die Seite ausdrucken werde und die Zahl daher einfach \repetitionbeliebig hoch einstellen kann. Es ist eher ärgerlich.

Meine Frage ist also:

Gibt es eine Möglichkeit, die Schleife am Ende einer Seite anzuhalten, anstatt den Wert 400durch Ausprobieren zu ermitteln?

Antwort1

Der Seitenersteller ist asynchron und TeX hat beim Setzen eines Absatzes keine Ahnung, wo eine Seite endet. Erst wenn ein Absatz zu Ende ist, werden Entscheidungen zum Seitenumbruch getroffen.

Meine Strategie besteht darin, den riesigen Absatz in einer Box zu erstellen, die dann mit der gewünschten Texthöhe verglichen wird. Liegt er immer noch darunter, wird eine neue Box mit weiteren Wiederholungen vorbereitet. Wenn wir genügend Material haben (die Seitenhöhe plus drei Zeilen, nur um sicherzugehen), wird die Box auf der gewünschten Höhe geteilt und auf die aktuelle Seite gesetzt.

\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}

Die Meldungen auf dem Terminal und in der Protokolldatei sind

Trying 200 repetitions
Trying 220 repetitions
Trying 240 repetitions
Trying 260 repetitions
Trying 280 repetitions
Trying 300 repetitions
Trying 320 repetitions

Der Startpunkt liegt bei 200, eine grobe Schätzung des Bedarfs (man könnte bei 1 beginnen, aber das erscheint nicht sinnvoll).

Bildbeschreibung hier eingeben

Beachten Sie, dass LaTeX keine öffentliche Schnittstelle zu hat \vsplit, sodass wir auf Programmierung auf niedrigerer Ebene zurückgreifen müssen.

Hier ist eine Vollversion expl3, die im Wesentlichen gleich ist. Ich habe lediglich den Zeilensprung etwas flexibler gestaltet, um die Seite besser zu füllen.

\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}

Der Befehl \fillpagehat ein optionales Argument zum Festlegen der anfänglichen Anzahl von Wiederholungen (Standard 200), also

\fillpage[300]{Phrase to repeat }

würde bei 300 beginnen.

Antwort2

Meine Lösung druckt den wiederholten Text nur einmal in die temporäre Box0. Diese Box0 führt dann \vsplitzur aktuellen Seite.

Das Makro \toendpage{repeated text}wird mitgeliefert. Dieses Makro füllt die aktuelle Seite vom aktuellen Punkt (egal ob dieser am Seitenanfang oder in der Seitenmitte ist) bis zum Seitenende.

Das Makro \toendpagemuss berechnen, wie viele Wiederholungen des Textes wir benötigen. Diese Zahl muss ausreichend groß sein, daher wird sie wie folgt berechnet:

(1.3 * \hsize/ Breite_des_Textes + 1) * Zeilen_im_\pagegoal

Das Makro lautet wie folgt:

\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. }

verwandte Informationen