21

I would like to produce a pdf document whose pages have various lengths and fixed widths.

An easier situation

The easiest case would be for instance: the first page has a length of 10cm all the next pages have a length of 15cm. But, what I am looking is more complicated. I wonder if it is possible.

The real situation

Here is what I would like to achieve:

  • the first page has a variable length, depending of the content (cf. this question), which is at most 10cm
  • the next pages have a length equal to 15cm
  • the last page has a variable length, depending of the content, which is at most 15cm

Bounty-rewarded

For those interested, there will be bounties for answers.

"Bug" in Heiko's solution

The solution propped by Heiko, which is great by the way, seems to have problem handling the list. Here is a MWE that shows this problem. The problem is that when there is a list (an itemize environment), the page change is done too early, and, as a result, the first page, whose height should be 8cm in the following example, is too short.

\documentclass{article}

\usepackage% [paperwidth=10.000000cm, paperheight=8cm, hmargin=1.000000mm, top=1.000000mm, bottom=1.000000mm] {geometry}

\pagestyle{empty}

\flushbottom \setlength{\maxdepth}{0pt}% to address the "third bug" \setlength{\topskip}{0pt}% no space above the first line

% assuming the page number is the absolute page number \usepackage{zref-totpages,zref-savepos} \usepackage{atbegshi}

\makeatletter \providecommand{\zsaveposy}{\zsavepos}% for older zref-savepos \def@oddhead{\PosFirstHead\PosLastHead\hss}% \def@evenhead{\PosLastHead\hss}% \newcommand{\PosFirstHead}{% \ifnum\value{page}=1 % \zsaveposy{PosFirstHead}% \global\let\PosFirstHead@empty \fi } \newcommand*{\PosLastHead}{% \ifnum\value{page}=\ztotpages \zsaveposy{PosLastHead}% \global\let\PosLastHead@empty \fi } \AtBeginShipout{% \ifnum\value{page}=1 % \dimen@=\dimexpr \zposy{PosFirstHead}sp-\headsep -\zposy{PosFirst}sp% \relax \setbox\AtBeginShipoutBox=\vbox{% \kern-\dimen@ % \copy\AtBeginShipoutBox }% \advance\pdfpageheight by -\dimen@ \else \ifnum\value{page}=\ztotpages \advance\pdfpageheight by% -\dimexpr \textheight -\zposy{PosLastHead}sp+\headsep +\zposy{PosLast}sp% \relax \fi \fi } \AtEndDocument{% \par \nobreak \dimen@=\prevdepth \ifdim\dimen@>\maxdepth \kern-\maxdepth \else \ifdim\dimen@>0pt % \kern-\dimen@ \fi \fi \zsaveposy{PosLast}% } \makeatother

\usepackage{lipsum}% provides dummy text

\interlinepenalty=-100

\begin{document} \vspace*{\dimexpr0.000cm-\topskip plus 1fill} \zsaveposy{PosFirst} \nointerlineskip

This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it?

This is a test: \begin{itemize} \item Hello

\item This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test.

\item Good Bye

\item Hello

\item This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. \end{itemize}

This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it?

This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it?

This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? This is a test. This is a longer sentence with some more words, isn't it? \end{document}

enter image description here

"Bug" in wipet's solution

I tried wipet's solution with the package mdframed and it clashes. Here is a MWE. It produces a document with only one page.

\documentclass{article}

\usepackage[ paperwidth=15cm, paperheight=15cm, hmargin=1cm, vmargin=0cm, ]{geometry}

\usepackage[framemethod=tikz, needspace=1.5cm]{mdframed} \usepackage{lipsum}

\newmdenv[% innerleftmargin = 2mm, innerrightmargin = 2mm, innertopmargin = 2mm, innerbottommargin = 2mm, leftmargin = 0mm, rightmargin = 0mm, splitbottomskip = 2mm, splittopskip = 4mm, middlelinewidth = 0mm, linecolor = red, backgroundcolor = red, roundcorner = 0pt, skipbelow = 0mm, skipabove = 0mm, ] {mybox}

\pagestyle{empty}

\topmargin=0pt % vertical shift of the text in the page \pdfvorigin=0in % vertical margins above and below the text

\let\textheight=\vsize \expandafter\let\csname @colht\endcsname=\vsize \newdimen\topbotmargin \topbotmargin=2\pdfvorigin \advance\topbotmargin by2\voffset \headheight=0pt \headsep=0pt \long\def\firstpage#1{\setbox0=\vbox{#1}\pdfpageheight=\ht0 \advance\pdfpageheight by\topbotmargin \vsize=\ht0 \box0 \vfil\break \pdfpageheight=15cm \vsize=\pdfpageheight \advance\vsize by-\topbotmargin } \AtEndDocument{\pdfpageheight=\pagetotal \vsize=\pagetotal \advance\pdfpageheight by\topbotmargin }

\begin{document}

\begin{mybox} Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque. \end{mybox}

\lipsum[1-9] \end{document}

Colas
  • 6,772
  • 4
  • 46
  • 96
  • I think the geometry package in conjunction with \geometry{<options>} will suit to your needs. You can declare this on a page-by-page basis, or (more advanced!) automate it between two values with a boolean. – 1010011010 May 22 '14 at 11:57
  • @1010011010 and do you think geometry can also handle the issue of indeterminate length? – Colas May 22 '14 at 12:05
  • @ChristianHupfer If the "content is short", then the length is not 10cm but the length according to the content. If the content is "longer than 10cm", then the length of the page is 10cm. – Colas May 22 '14 at 12:22
  • @Colas: I see, but what is the content? Formulas, text, graphics, tables...? ;-) –  May 22 '14 at 12:23
  • It can be anything ! – Colas May 22 '14 at 12:32
  • @ChristianHupfer What was wrong with using \newgeometry? – 1010011010 May 22 '14 at 12:36
  • Thank you @ChristianHupfer. Otherwise, you could give me the directions and I could try to do it. It could be an opportunity for me to learn TeX! – Colas May 22 '14 at 12:38
  • @ChristianHupfer I don't know but maybe this post http://tex.stackexchange.com/a/19241/8323 can also be helpful! Thanks very much for your help. (This question will have a bounty) – Colas May 22 '14 at 12:46
  • Please clarify: Who controls the page breaks (manual vs. automatic via output routine)? Elements of the page layout? Which TeX format? How is the document compiled (not all drivers can output different page sizes)? – Heiko Oberdiek May 22 '14 at 18:46
  • @HeikoOberdiek The page break has to be automatic. The page layout is simple: constant width and variable height; normal margins. The document is in LaTeX. I plan to use LuaTeX later (I guess it should not be a problem). For now, the document is compiled with pdflatex. Thanks. – Colas May 22 '14 at 18:50
  • @Colas: pdfTeX and LuaTeX are fine, they have full control over the page size. Are there header and/or footer? – Heiko Oberdiek May 22 '14 at 19:00
  • No there are not. – Colas May 22 '14 at 19:01
  • @ChristianHupfer You can leave an answer so that I give you a bounty! Even if I will choose Heiko's solution, your interest has been helpful! – Colas May 23 '14 at 12:01
  • 2
    @Colas: The first "bug" is not related to package mdframed. You require a shorter last page (10cm). If the last page is 11cm, for example, you have a problem: 11cm does not fit on 10cm and 11cm does not fill 15cm and leaves something for the final 10cm page. You have to shorten your text or make it longer. – Heiko Oberdiek May 27 '14 at 12:26
  • @HeikoOberdiek: Is it possible to fix this last step, in order that this situation is well handled by the macro? Thanks!! – Colas May 27 '14 at 12:28
  • The second "bug" is correct behavior, the last line cannot be put on the page three, because of the requirement that the height of the last page must be smaller than 10cm. – Heiko Oberdiek May 27 '14 at 12:30
  • So, why the big white space in the page before? – Colas May 27 '14 at 12:34
  • 1
    @Colas: There is not enough material to fill the page. You can add \flushbottom and add some glue to \parskip/\baselineskip, e.g. \addtolength{\parskip}{0pt plus 2ex} to stretch the white spaces. – Heiko Oberdiek May 27 '14 at 12:36
  • @HeikoOberdiek OK, now I realize that this condition on the last page cannot always be realized in a proper way. It excludes all document whose length is 10cm + n*15cm + x, with x between 10 and 15. I will drop this condition. Thanks! Do you know how to fix the issue about the margins? (the same issue happens on the last page) – Colas May 27 '14 at 12:44
  • 1
    @Colas: \setlength{\maxdepth}{0pt}\flushbottom should move the last line of the text page right to the bottom border of the text area without descenders outside the text area. – Heiko Oberdiek May 27 '14 at 12:47
  • Thanks! I think \flushbottom is better because the same margin to the baseline is applied everywhere. Thank you very much for this help!!! – Colas May 27 '14 at 12:50
  • @HeikoOberdiek By the way, I think you misread my question (I didn't ask for the last page to be max 10cm) – Colas May 27 '14 at 12:53
  • 1
    @Colas: Yes, I have read 10 instead of 15 for the last page. Answer updated. – Heiko Oberdiek May 27 '14 at 13:15
  • If you want to have equal base lines for the bottom lines, then do not change \maxdepth. But you have to leave some space in the margins. Otherwise the descenders (of g, p, ...) are outside the page. – Heiko Oberdiek May 27 '14 at 21:14
  • @heikoOberdiek Yes that's what I planned to do, to add some margins. But before, I wanted to be sure that the layout is the same for each page. In my last MWE, I haven't set \maxdepth to 0pt, I have just called \flushbottom. What do I need to do apart from that "not to change \maxdepth"? Thanks again!! – Colas May 27 '14 at 21:19
  • @Colas: Your contents does not have any strechability. There are underfull \vbox warnings. The example can be fixed, e.g. by \addtolength{\parskip}{0pt plus 1ex} and \makeatletter\g@addto@macro\normalsize{\addtolength{\baselineskip}{0pt plus 1pt}}\makeatother. – Heiko Oberdiek May 27 '14 at 22:02
  • @HeikoOberdiek Thanks! I have added these lines at the top of your macro and it works (though I don't understand what it does). Another question: is it possible to reduce the space between the top of the page and the first baseline (without cutting out any character) or is it already at the minimum? Thank you. – Colas May 28 '14 at 09:21
  • 1
    @Colas: You could set \setlength{\topskip}{0pt}, but then the first baseline might vary depending on the text. An alternative: \settoheight{\topskip}{ABC}. – Heiko Oberdiek May 28 '14 at 11:26
  • @HeikoOberdiek, if you are interested by a bounty, I have updated the question... There is a new case where you solution does not work. Anyway, thanks a lot ! – Colas Sep 18 '14 at 16:01

2 Answers2

14

The following example uses package geometry to set the page layout with page height 15cm for all pages. At the beginning of the first page and at the end of the last page a space of 5cm plus 1fill is added. It fills the remaining space and ensures that the contents is small enough for a maximum page height of 10cm.

Position markers of package zref-savepos are set on the first page in the header and the start of the contents after the filler space. Package atbegshi is used to hook into the output routine. The free space is measured using the positions and the whole page is moved to the top by the amount of the free space and the page height is shortened accordingly.

For the last page, the position markers are added in the header and the end of the contents. Again the page height is shortened by the amount of free space that is calculated via the position markers and the height of the text block (\textheight).

For the previous action we must know the page number of the last pages. This is provided by package zref-totpages that stores the number of pages in \ztotpages via the reference system. It is assumed that the page numbering of the document is absolute.

Because both the reference for the number of pages and the position markers need an additional LaTeX run, three LaTeX runs are needed.

Both pdfTeX and LuaTeX support position markers (\pdfsavepos and \pdflastposy are used by package zref-savepos) and the setting of the media size (\pdfpageheight).

\flushbottom fills the text area to the bottom. \setlength{\maxdepth}{0pt} avoids that the descenders of the last line are outside the text area. Important, if the vertical margins are zero. Then the descenders would be out of the page.

\setlength{\topskip}{0pt} and \nointerlineskip after \zsavepos{PosFirst} remove white space at the top of the text area.

\documentclass{article}
\usepackage[
  paperwidth=15cm,
  paperheight=15cm,
  hmargin=1cm,
  vmargin=0cm,
]{geometry}
\pagestyle{empty}

\flushbottom
\setlength{\maxdepth}{0pt}% to address the "third bug"
\setlength{\topskip}{0pt}% no space above the first line

% assuming the page number is the absolute page number
\usepackage{zref-totpages,zref-savepos}
\usepackage{atbegshi}

\makeatletter
\providecommand*{\zsaveposy}{\zsavepos}% for older zref-savepos
\def\@oddhead{\PosFirstHead\PosLastHead\hss}%
\def\@evenhead{\PosLastHead\hss}%
\newcommand*{\PosFirstHead}{%
  \ifnum\value{page}=1 %
    \zsaveposy{PosFirstHead}%
    \global\let\PosFirstHead\@empty
  \fi
}
\newcommand*{\PosLastHead}{%
  \ifnum\value{page}=\ztotpages
    \zsaveposy{PosLastHead}%
    \global\let\PosLastHead\@empty
  \fi
}
\AtBeginShipout{%
  \ifnum\value{page}=1 %
    \dimen@=\dimexpr
      \zposy{PosFirstHead}sp-\headsep
      -\zposy{PosFirst}sp%
    \relax
    \setbox\AtBeginShipoutBox=\vbox{%
      \kern-\dimen@ %
      \copy\AtBeginShipoutBox
    }%
    \advance\pdfpageheight by -\dimen@
  \else
    \ifnum\value{page}=\ztotpages
      \advance\pdfpageheight by%
        -\dimexpr
          \textheight
          -\zposy{PosLastHead}sp+\headsep
          +\zposy{PosLast}sp%
        \relax
    \fi
  \fi
}
\AtEndDocument{%
  \par
  \nobreak
  \dimen@=\prevdepth
  \ifdim\dimen@>\maxdepth
    \kern-\maxdepth
  \else
    \ifdim\dimen@>0pt %
      \kern-\dimen@
    \fi
  \fi
  \zsaveposy{PosLast}%
}
\makeatother

\usepackage{lipsum}% provides dummy text

\begin{document}
\vspace*{\dimexpr5cm-\topskip plus 1fill}% first page should not be larger than 15cm
\zsaveposy{PosFirst}
\nointerlineskip

\lipsum[1-9]

\end{document}

Page 1 Page 2 Page 3


Older version with the constraint that the last page does not exceed 10 cm:

\documentclass{article}
\usepackage[
  paperwidth=15cm,
  paperheight=15cm,
  hmargin=1cm,
  vmargin=.9cm,
]{geometry}
\pagestyle{empty}

% \flushbottom % optional
\setlength{\maxdepth}{0pt}% to address the "third bug"

% assuming the page number is the absolute page number
\usepackage{zref-totpages,zref-savepos}
\usepackage{atbegshi}

\makeatletter
\providecommand*{\zsaveposy}{\zsavepos}% for older zref-savepos
\def\@oddhead{\PosFirstHead\PosLastHead\hss}%
\def\@evenhead{\PosLastHead\hss}%
\newcommand*{\PosFirstHead}{%
  \ifnum\value{page}=1 %
    \zsaveposy{PosFirstHead}%
    \global\let\PosFirstHead\@empty
  \fi
}
\newcommand*{\PosLastHead}{%
  \ifnum\value{page}=\ztotpages
    \zsaveposy{PosLastHead}%
    \global\let\PosLastHead\@empty
  \fi
}
\AtBeginShipout{%
  \ifnum\value{page}=1 %
    \dimen@=\dimexpr
      \zposy{PosFirstHead}sp-\headsep
      -\zposy{PosFirst}sp%
    \relax
    \setbox\AtBeginShipoutBox=\vbox{%
      \kern-\dimen@ %
      \copy\AtBeginShipoutBox
    }%
    \advance\pdfpageheight by -\dimen@
  \else
    \ifnum\value{page}=\ztotpages
      \advance\pdfpageheight by%
        -\dimexpr
          \textheight
          -\zposy{PosLastHead}sp+\headsep
          +\zposy{PosLast}sp%
        \relax
    \fi
  \fi
}
\AtEndDocument{%
  \par
  \nobreak
  \dimen@=\prevdepth
  \ifdim\dimen@>\maxdepth
    \kern-\maxdepth
  \else
    \ifdim\dimen@>0pt %
      \kern-\dimen@
    \fi
  \fi
  \zsaveposy{PosLast}%
  \vspace*{5cm plus 1fill}% last page should not be largern than 15cm
}
\makeatother

\usepackage{lipsum}% provides dummy text

\begin{document}
\vspace*{\dimexpr5cm-\topskip plus 1fill}% first page should not be larger than 15cm
\zsaveposy{PosFirst}

\lipsum[1-11]

\end{document}

Page 1 Page 2 Page 3 Page 4

Workaround for mdframed version

The environment of mdframed adds additional breakpoints (e.g. via \needspace), which are preferred over the regular break points between lines.

As workaround the \interlinepenalty can be set to a negative value (-100):

\documentclass{article}
\usepackage[
  paperwidth=15cm,
  paperheight=15cm,
  hmargin=1cm,
  vmargin=0cm,
]{geometry}

\usepackage[framemethod=tikz, needspace=1.5cm]{mdframed}

\newmdenv[%
innerleftmargin = 2mm,
innerrightmargin = 2mm,
innertopmargin = 2mm,
innerbottommargin = 2mm,
leftmargin = 0mm,
rightmargin = 0mm,
splitbottomskip = 2mm,
splittopskip = 4mm,
middlelinewidth = 0mm,
linecolor = red,
backgroundcolor = red,
roundcorner = 0pt,
skipbelow = 0mm,
skipabove = 0mm,
]
{mybox}

\pagestyle{empty}

\flushbottom
\setlength{\maxdepth}{0pt}% to address the "third bug"
\setlength{\topskip}{0pt}% no space above the first line

% assuming the page number is the absolute page number
\usepackage{zref-totpages,zref-savepos}
\usepackage{atbegshi}

\makeatletter
\providecommand*{\zsaveposy}{\zsavepos}% for older zref-savepos
\def\@oddhead{\PosFirstHead\PosLastHead\hss}%
\def\@evenhead{\PosLastHead\hss}%
\newcommand*{\PosFirstHead}{%
  \ifnum\value{page}=1 %
    \zsaveposy{PosFirstHead}%
    \global\let\PosFirstHead\@empty
  \fi
}
\newcommand*{\PosLastHead}{%
  \ifnum\value{page}=\ztotpages
    \zsaveposy{PosLastHead}%
    \global\let\PosLastHead\@empty
  \fi
}
\AtBeginShipout{%
  \ifnum\value{page}=1 %
    \dimen@=\dimexpr
      \zposy{PosFirstHead}sp-\headsep
      -\zposy{PosFirst}sp%
    \relax
    \setbox\AtBeginShipoutBox=\vbox{%
      \kern-\dimen@ %
      \copy\AtBeginShipoutBox
    }%
    \advance\pdfpageheight by -\dimen@
  \else
    \ifnum\value{page}=\ztotpages
      \advance\pdfpageheight by%
        -\dimexpr
          \textheight
          -\zposy{PosLastHead}sp+\headsep
          +\zposy{PosLast}sp%
        \relax
    \fi
  \fi
}
\AtEndDocument{%
  \par
  \nobreak
  \dimen@=\prevdepth
  \ifdim\dimen@>\maxdepth
    \kern-\maxdepth
  \else
    \ifdim\dimen@>0pt %
      \kern-\dimen@
    \fi
  \fi
  \zsaveposy{PosLast}%
}
\makeatother

\usepackage{lipsum}% provides dummy text

\interlinepenalty=-100

\begin{document}
\vspace*{\dimexpr5cm-\topskip plus 1fill}% first page should not be larger than 15cm
\zsaveposy{PosFirst}
\nointerlineskip
\begin{mybox}
\lipsum[1]
\end{mybox}
\lipsum[1-9]

\end{document}

Page 1 Page 2 Page 3

A negative \interlinepenalty has its drawbacks (encouraging too early page breaks).

An alternative would be to put the framed environment inside a non-breakable minipage that removes the additional breakpoints:

\noindent
\begin{minipage}[b]{\linewidth}
\begin{mybox}
\lipsum[1]
\end{mybox}%
\end{minipage}

But then a longer mybox cannot be broken across pages.

A more reliable solution can probably be provided by a rewrite/patch of the output routine. However, that might clash with packages like longtable, which uses their own modifications of the output routine.

Heiko Oberdiek
  • 271,626
  • Awesome ! That really looks like what I was looking for! – Colas May 23 '14 at 00:16
  • there is a clash between your solution and the package mdframed. Do you think you can fix it? Thank you very much!!

    I put a MWE as en edit of my question.

    – Colas May 27 '14 at 12:09
  • Yes I have found an occurrence of this situation without mdframed (see my edit). Can it be fixed automatically? Thanks!! – Colas May 27 '14 at 12:23
  • @HeikoOberdieck: I have noticed something else. The bottom margin of the first page does not follow the same rule as the bottom page of all other pages. See my edit. Thanks ;-) – Colas May 27 '14 at 12:32
  • @Colas: Add \setlength{\maxdepth}{0pt} to prevent that descenders leave the text body. And you might want to add \flushbottom. – Heiko Oberdiek May 27 '14 at 12:41
  • @HeikoOberdieck: I have another question, about the bottom of the pages. See me edit. Thank you. – Colas May 27 '14 at 17:05
  • @HeikoOberdieck: Hi Heiko, I am still using your solution (still to be accepted by the way), and I have found a case where it is not working: when there are boxes (created with mdframed). I update my question to show a MWE. Thank you, again! Hope you're fine ;-) – Colas Sep 11 '14 at 18:34
  • AH... Since I did not get any modification when you modified your message, I did not see that you answered my issue and deserved the bounty :( I don't have enough reputation to start a new bounty (I lost all my reputation with this question). But, be sure that when I'll have more reputation, I'll open a new bounty here to thank you for your help! – Colas Oct 13 '14 at 09:50
  • In some situations, the line \vspace*{\dimexpr5cm-\topskip plus 1fill}% first page should not be larger than 15cm seems to create problems. More precisely, when I have a box, then a itemize environment... I am investigating! – Colas Oct 13 '14 at 11:27
  • Hi @Heiko! I am really sorry to keep finding nasty situations where there are problems... Nonetheless, this new non-working situation is not far-fetched! There is a problem when dealing with itemize environments. Could you cast your eye on it (see the edit in the question)? Thanks !

    As soon as I will be able to deliver a bounty (and for this question, it has to be huge, since it will be the third or forth one), it will be for you!

    – Colas Oct 21 '14 at 11:08
  • @Colas The solution works for some simple, not too complicated inputs. But to make it work for all kind of TeX stuff it costs too much time, which I do not have right now. – Heiko Oberdiek Oct 21 '14 at 16:47
  • OK I really understand. Thanks for your help, again. If by any chance, you see the beginning of a solution for this last problem, I am very interested ! – Colas Oct 21 '14 at 18:45
  • Hi @Heiko. I have asked this question about the issue of lists. David Carlisle advised me to replace \vspace*{\dimexpr5cm-\topskip plus 1fill} by \vspace*{\dimexpr5cm-\topskip}. Why in the first place did you use plus 1fill? Can you see a situation where the plus 1fill might be needed? Thanks ;-) – Colas Nov 04 '14 at 12:27
  • @Colas Just do, what David proposes. If it is not working, then you can claim him. ;-) – Heiko Oberdiek Nov 04 '14 at 16:33
  • Sorry that you take it like that. I am really grateful to you for your help! Thanks again! – Colas Nov 04 '14 at 16:56
  • @HeikoOberdiek The site really should warn people that they can be claimed if they offer solutions which fail ;). – cfr Nov 28 '14 at 01:39
  • @cfr I am not claiming. I am politely asking and I am 100% OK if anyone don't have time/energy/don't want/canno't answer my questions. I admit that what I am asking is very precise and complicated and that I asked again and again for improvements... – Colas Nov 28 '14 at 09:14
  • 1
    @Colas That comment was not intended as a criticism. It is a (possibly twisted) joke based on a typo in one of Heiko's comments above. ('If it is not working, then you can claim him.' I take it that the intended statement was 'If it is not working, then you can blaim him.' Claiming him would be another matter altogether!) – cfr Nov 28 '14 at 12:39
  • Hi Heiko, I thought you may find interesting the answer http://tex.stackexchange.com/a/265893/8323 to a similar question. Thank you again for all the help you provided here in this question! – Colas Sep 17 '15 at 19:34
  • 2
    Whatever blaiming is, of course. – cfr Sep 17 '15 at 21:05
14

The page height is controlled by \pdfpageheight primitive register. It means that the following code does what you want:

\def\lorem{Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do 
  eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad   
  minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
  commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
  velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
  cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
  est laborum} 

\setbox0=\vbox{\lorem.\par\lorem.}

\pdfpageheight=\ht0 
\advance\pdfpageheight by2\voffset \advance\pdfpageheight by2in
\vsize=\ht0

\vbox to 0pt{\box0\vss}\vfil\break

\pdfpageheight=15cm 
\vsize=\pdfpageheight \advance\vsize by-2in \advance\vsize by-2\voffset

\lorem.\par \lorem. \lorem.\par
\lorem.\par \lorem. \lorem.\par
\lorem.\par \lorem.\par
\lorem.\par \lorem.\par

\pdfpageheight=\pagetotal \vsize=\pagetotal
\advance\pdfpageheight by2\voffset \advance\pdfpageheight by2in

\end

Compile it by pdftex document.

Edit: I'v added the last page calculation.

Why there is non-LaTeX solution? Because 1) LaTeX was not specified in the question, 2) I never use LaTeX, 3) I want to show the core of the solution: setting the \pdfpageheight primitive register. This core is not exacly shown in the second answer here but it must use it.

EDIT2 (May 28): Colas: Can you make it a LaTeX solution...

Because I am not using LaTeX, my LaTeX solution can look as Assembler code inside C++ language. But it works.

\documentclass{article}

\topmargin=0pt  % vertical shift of the text in the page
\pdfvorigin=1in % vertical margins above and below the text

\let\textheight=\vsize
\expandafter\let\csname @colht\endcsname=\vsize
\newdimen\topbotmargin
\topbotmargin=2\pdfvorigin \advance\topbotmargin by2\voffset
\headheight=0pt \headsep=0pt
\long\def\firstpage#1{\setbox0=\vbox{#1}\pdfpageheight=\ht0
   \advance\pdfpageheight by\topbotmargin \vsize=\ht0 \box0 \vfil\break
   \pdfpageheight=15cm \vsize=\pdfpageheight \advance\vsize by-\topbotmargin
}
\AtEndDocument{\pdfpageheight=\pagetotal \vsize=\pagetotal
   \advance\pdfpageheight by\topbotmargin
}
\def\lorem{Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
  eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
  minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
  ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
  velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
  cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
  est laborum}

\begin{document}

\firstpage{\lorem.\par \lorem.}

\lorem.\par \lorem. \lorem.\par
\lorem.\par \lorem. \lorem.\par
\lorem.\par \lorem.\par
\lorem.\par \lorem.\par

\end{document}

Note the dirty trick \let\textheight=\vsize and \let\@colht=\vsize. LaTeX uses \vsize primitive as \textheight for users and uses \@colht in its \output routine. I need to let all of these as one object because my macros manipulate only with \vsize.

Colas
  • 6,772
  • 4
  • 46
  • 96
wipet
  • 74,238
  • 1
    Thanks! Can you provide a MWE and a picture of the output? – Colas May 23 '14 at 00:18
  • 1
    The code itself is working example. You can grab it to the file (say) document.tex and you can process the command pdftex document. You can get picture of the output when you use evince or another PDF viewer. – wipet May 23 '14 at 03:46
  • Very impressive! I wish I knew TeX... Can I learn it quickly to you think? – Colas May 23 '14 at 08:57
  • 6
    @colas Here is my evolution: first (20 years ago) cca 1 month with TeXbook and intesive study, then maintenance the cplain format and csfonts (till now), then rewriting internals of TeX (encTeX extension which can deal with all UTF-8 characters as with one token in old pdfTeX engine), then writing comprehensive books about TeX internals and macro programming for Czech users (TeX for pragmatics, TeXbook inside out, both have full text available at internet), then writing simple macro OPmac (funcionality comparable with whole LaTeX+nfss+hyperref+colors+... but only with 1.7k lines of code). – wipet May 24 '14 at 01:59
  • Can you make it a LaTeX solution (I don't know TeX and I use LaTeX). Thanks. – Colas May 27 '14 at 17:04
  • Hi wipet, I tried to use your solution in a LaTeX environment. It works well but there is a clash with a package called mdframed. I will edit your answer to show you some code. Thanks. – Colas Oct 13 '14 at 09:59
  • @Colas could you check again? I doubt it... – doed Oct 13 '14 at 10:41
  • 1
    @Colas Sorry, I never heard about mdframed. If I need to put the text into colored box, I am able to write my own macro for such purpose (very simple and written in short time). The basic principle for your original task is known: you have to set \pdfpageheight primitive properly. All others is only a fight with the LaTeX's complicated macros and its complicated packages. I'll not subordinate to this, because I need not use LaTeX and I advice to other people: don't use LaTeX. – wipet Oct 13 '14 at 12:10
  • @wipet your answer is great but the first page if of arbitrary length (with your command \firstpage{...}), which is not what I am looking for. See http://tex.stackexchange.com/q/213750/8323 for the same question asked in more understandable terms. – Colas Dec 11 '14 at 08:38
  • It would be good if you could tidy this answer up and remove additions which ought not be in the 'answer' space. It is very confusing as it is, and other users are likely to find this more useful. (Or you could just roll back if that's more appropriate.) @Colas should have edited the question rather than messing up the answer. – cfr Sep 17 '15 at 21:03