30

The question

I would like to control the height of the pages of the PDF documents I produce with LaTeX.

Starting with a LaTeX document and two parameters:

  • a given page size (heightPage and widthPage)
  • a given length called initialVerticalInset,

I would like to produce a PDF whose page lengths follow the pattern

  • the normal height of the pages is heightPage
  • BUT, the height of the first page is (heightPage - initialVerticalInset)
  • AND, the height of the last page equals the "height of its content", i.e. "the last page is cut" after the end of its content

If possible, I would like also :

  • if any of these pages are put next to another one, the baselines should be aligned
  • the margins could be set a minimal value (such as 0pt)

Example 1

enter image description here

enter image description here


Example 2

enter image description here


Minimal documents to be tested

In a previous similar question, I noticed that one difficulty could be the compatibility with :

  • itemize environments
  • mdframed environments
  • the case of short documents has to be dealt with too.

So, I prepared three MWE to be tested.

Short document

\documentclass{article}

\usepackage[paperwidth=8cm, paperheight=10cm, hmargin=0mm, 
    top=0mm, bottom=0mm] {geometry}

\setlength{\initialVerticalInset}{4.5cm}


\begin{document}

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

\end{document}

Documents with itemize environments

\documentclass{article}

\usepackage[paperwidth=8cm, paperheight=10cm, hmargin=0mm, 
    top=0mm, bottom=0mm] {geometry}


\pagestyle{empty}

\setlength{\initialVerticalInset}{4.5cm}


\begin{document}


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? 
\end{document}

Documents with mdframed environments

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

\setlength{\initialVerticalInset}{5cm}

\begin{document}

\begin{mybox}
\lipsum[1]
\end{mybox}
\lipsum[1-7]

\end{document}
10
  • 2
    given the cut last page requirement are you not adding page head and foot, or just not adding foot on last page or ... Nov 27, 2014 at 12:46
  • No, I don't need to add page foot. Actually. In what I want to do, there is no page head or foot (I don't do anything special about them).
    – Colas
    Nov 27, 2014 at 23:00
  • 6
    Do you really not think that either of the solutions to your previous question is worthy of your acceptance? It really is not fair to ask a difficult question to which you receive sophisticated solutions, with significant follow-up in some cases, and then say 'well, I won't accept your answer unless you also solve this, this, and this further problem'. This is especially true when you are asking questions which cannot possibly be answered in ways which will be robust under all possible scenarios.
    – cfr
    Nov 28, 2014 at 1:43
  • 2
    @Colas Maybe I missed something but I thought they answered your original question i.e. before you edited it with additional requirements. Apologies if I'm mistaken about that.
    – cfr
    Nov 29, 2014 at 0:33
  • 2
    @wipet You mean rather like this answer? (Except for the misplaced addition which has been edited in?)
    – cfr
    Dec 11, 2014 at 0:59

2 Answers 2

5
+500

I think this does the job. Thnaks to the idea \pdfpageheight=\pagetotal from wipet's answer How to have a precise control on the size of each page?

\documentclass{article}

\newlength{\initialVerticalInset}
\setlength{\initialVerticalInset}{4.5cm}

\usepackage[paperwidth=10cm, 
            paperheight=-\dimexpr\initialVerticalInset- 10cm\relax,
            margin=0mm]{geometry}

\makeatletter

\newcommand{\setnewvsize}[1]{%
\global\paperheight\dimexpr#1+\initialVerticalInset\relax%
\global\pdfpageheight\paperheight%
\global\textheight\paperheight%
\global\@colht\textheight \global\@colroom\textheight \global\vsize\textheight%
\global\initialVerticalInset=0pt}


\let\mt@outputpage\@outputpage
\def\@outputpage{\mt@outputpage\setnewvsize\paperheight}

\makeatother

\AtEndDocument{\initialVerticalInset=0pt\vskip-\lastskip\nobreak\par\vskip1pt\par\setnewvsize\pagetotal}

\usepackage{lipsum}

\begin{document}


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? 

\end{document}

Itemize

enter image description here

mdframed

enter image description here

Example 2 pages only

enter image description here

Example only one page

enter image description here

8
  • Hi touhami, so far your macro works great, but there is a little problem. As you can see for example in the last picture you have put, the last line of text is cut very sharply. It is cut on the base line, and the comma is not wholly visible. The same problem would happen with letters such as g, p, etc. So you see a way to solve this? Thanks!
    – Colas
    Sep 17, 2015 at 19:19
  • I tried to modify the margins of geometry, but it breaks everything... Just change margin=0mm to margin=1mm and will see (In the Example with only one page). Thanks!
    – Colas
    Sep 17, 2015 at 19:49
  • I don't need to change the margins in the middle of the document. I tried to change the margins because of the first problem, but what I really need is margin=0mm. I pointed out the margin≠0mm problem just in case of. Thanks
    – Colas
    Sep 17, 2015 at 20:14
  • @Colas answer edited. I use \AtEndDocument{\initialVerticalInset=0pt\vskip-\lastskip\nobreak\par\vskip1pt\par\setnewvsize\pagetotal} this help for the first problem
    – touhami
    Sep 17, 2015 at 20:41
  • Your edit solves the problem for the very last page, but it does not solve it for the other pages. See for example the first document "Itemize" (with \setlength{\initialVerticalInset}{5cm}). Thanks
    – Colas
    Sep 17, 2015 at 20:47
2

Problem with this answer

Floating objects

I have tried to see if this answer works with figure environments. If they appear to be at the last page, then it does not work as wanted (the last page has the \normalHeigt and not the "clipping height")

PS: Since I don't know anything about TeX and I am not a super user of LaTeX, maybe there are mistakes or bad syntax. If you think the following code can be improved, please comment!

Answer

This answer is elaborated on touhami's answer.

\documentclass{article}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newlength{\initialHeight}
\setlength{\initialHeight}{5.5cm}

\newlength{\normalHeight}
\setlength{\normalHeight}{10cm}

\newlength{\normalWidth}
\setlength{\normalWidth}{10cm}

\newlength{\horizontalMargin}
\setlength{\horizontalMargin}{0mm}

\newlength{\topMargin}
\setlength{\topMargin}{0mm}

\newlength{\bottomMargin}
\setlength{\bottomMargin}{0mm}
% This is a crucial line
% see http://tex.stackexchange.com/a/268943/8323
\setlength{\maxdepth}{0pt}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Size
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\usepackage[paperwidth=\normalWidth, 
            paperheight=\initialHeight,
            left=\horizontalMargin,
            right=\horizontalMargin,
            top=\topMargin,
            bottom=\bottomMargin]{geometry}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Core
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\makeatletter


% Set the vertical size of the page
%
\newcommand{\setnewvsize}[1]{%
\global\paperheight\dimexpr#1\relax%
\global\pdfpageheight\paperheight%
\global\textheight\dimexpr\paperheight - \bottomMargin - \topMargin\relax%
\global\@colht\textheight%
\global\@colroom\textheight%
\global\vsize\textheight%
}

% Change the vsize after the first page
% (after the first output)
%
\newcommand\firstPassageInOutput{1}
\let\mt@outputpage\@outputpage
\def\@outputpage{\mt@outputpage\ifnum\firstPassageInOutput=1\setnewvsize\normalHeight\renewcommand\firstPassageInOutput{0}\fi}


% Change the vsize after the last page
%
\AtEndDocument{%
% The following line is needed is the case when the last page is only one line
\vskip-\lastskip\nobreak\par\vskip0pt\par
% Core
\global\paperheight\dimexpr\pagetotal + \bottomMargin + \topMargin \relax%
\global\pdfpageheight\paperheight%
\global\textheight\dimexpr\pagetotal
}
\makeatother




\usepackage{lipsum}

\begin{document}
lipsum{}
\end{document}

Outputs of the MWE to be tested

enter image description here

enter image description here

enter image description here

enter image description here

13
  • This is the natural idea. Some remark 1) \dimexpr end optionally by \relax not obligatory but good practice 2) \global declares the following definition or assignment to be global.
    – touhami
    Sep 18, 2015 at 6:35
  • @touhami I made some improvements following your remarks. I have also added also some \global\@colht\textheight, etc. although I don't know what is it for.
    – Colas
    Sep 18, 2015 at 13:53
  • final tuning % (don't really know what I'm doing here) this is not necessart. \begin{document} will do this for you.
    – touhami
    Sep 18, 2015 at 15:16
  • I think you don't really need \normalWidth and \initialHeight.
    – touhami
    Sep 18, 2015 at 19:30
  • I like variables!
    – Colas
    Sep 23, 2015 at 13:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .