4

I am working on a project where a book gets generated from a JSON file with thousands of entries which are used as paragraphs. When I plug my code into LaTeX some paragraphs are split across two pages. I was wondering if there is a way to say something like: “If paragraph will break, move the whole of it to the next page”?

Something like \newpage will not be useful in my case because there are too many entries to do it by hand. I'm looking for a more programmatic solution. I have also looked at:

\widowpenalties 1 10000
\raggedbottom

But what that seems to do in my case is to just expand the text until the page is finished and not propagating the text to new page. Here a simplified version of my code with the formatting that is being used:

%------------------------
% Invoke Packages
%------------------------

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{lipsum,lineno}

%------------------------
% Set Dimensions
%------------------------
\usepackage[ 
paperwidth = 168.3mm,
paperheight = 260.4mm,
top = 6mm,
bottom = 7mm,
outer = 6mm,
inner = 20mm
]{geometry}

%------------------------
% Remove indentation from all paragraphs
%------------------------
\setlength\parindent{0pt}

% Comments
\newcommand{\CommentFontSize}{21}
\newcommand{\CommentSkipMult}{25}
% Author
\newcommand{\UserFontSize}{16}
\newcommand{\UserSkipMult}{0}
% Date
\newcommand{\DateFontSize}{15}
\newcommand{\DateSkipMult}{0}

% Comments
\newenvironment{commentTextFont}{
\fontfamily{mdugm} 
\fontsize{\CommentFontSize}{\CommentSkipMult}
\selectfont}
{\par}
% Author
\newenvironment{userFont}{
\fontfamily{mdugm} 
\fontsize{\UserFontSize}{\UserSkipMult}
\selectfont}
{\par}
% Date
\newenvironment{dateFont}{
\fontfamily{mdugm} 
\fontsize{\DateFontSize}{\DateSkipMult}
\selectfont}
{\par}

%------------------------
% Set commands 
%------------------------

\newcommand{\uComment}[3]{
\begin{commentTextFont} #1 \end{commentTextFont}
\vspace*{0.5cm}
\begin{userFont} \textit{#2}
\hspace*{\fill} \begin{dateFont} #3 \end{dateFont}
\end{userFont}
\vspace*{0.8cm}
}

%------------------------
% Document
%------------------------

\begin{document}
\begin{flushleft}

\uComment{\lipsum[73]}{someone}{2000}
\uComment{\lipsum[75]}{someone}{2000}
\uComment{\lipsum[66]}{someone}{2000}

\end{flushleft}
\end{document}

Any ideas how this could be approached?

  • do all your paragraphs fit on a page and never need to break, if so it is simple, just set each paragraph in a \parbox if you will sometimes have a long para that needs to break, it;s harder. – David Carlisle May 13 '17 at 15:18
  • Yes, they will be short or long, so sometimes will need a break, sometimes not. The solution by @egreg worked wonderfully. – Darien Brito May 19 '17 at 15:19
5

The definitions you use are quite complicated and could be simplified, in my opinion, but the solution is anyway easy:

\newcommand{\uComment}[3]{%
  \filbreak
  \begin{commentTextFont}#1\end{commentTextFont}%
  \vspace*{0.5cm}
  \begin{userFont}\textit{#2}\hspace*{\fill}%
  \begin{dateFont}#3\end{dateFont}\end{userFont}%
  \vspace*{0.8cm}
}

I used \filbreak before the paragraph, which means: break a page here unless a further \filbreak comes along and the text in between fits the page.

Here's the complete code, with all spurious spaces you insert removed.

%------------------------
% Invoke Packages
%------------------------

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{lipsum,lineno}

%------------------------
% Set Dimensions
%------------------------
\usepackage[ 
  paperwidth = 168.3mm,
  paperheight = 260.4mm,
  top = 6mm,
  bottom = 7mm,
  outer = 6mm,
  inner = 20mm
]{geometry}

%------------------------
% Remove indentation from all paragraphs
%------------------------
\setlength\parindent{0pt}

% Comments
\newcommand{\CommentFontSize}{21}
\newcommand{\CommentSkipMult}{25}
% Author
\newcommand{\UserFontSize}{16}
\newcommand{\UserSkipMult}{0}
% Date
\newcommand{\DateFontSize}{15}
\newcommand{\DateSkipMult}{0}

% Comments
\newenvironment{commentTextFont}
 {\fontfamily{mdugm}%
  \fontsize{\CommentFontSize}{\CommentSkipMult}%
  \selectfont}
 {\par}
% Author
\newenvironment{userFont}
 {\fontfamily{mdugm}%
  \fontsize{\UserFontSize}{\UserSkipMult}%
  \selectfont}
 {\par}
% Date
\newenvironment{dateFont}
 {\fontfamily{mdugm}%
  \fontsize{\DateFontSize}{\DateSkipMult}%
  \selectfont}
 {\par}

%------------------------
% Set commands 
%------------------------

\newcommand{\uComment}[3]{%
  \filbreak
  \begin{commentTextFont}#1\end{commentTextFont}%
  \vspace*{0.5cm}
  \begin{userFont}\textit{#2}\hspace*{\fill}%
  \begin{dateFont}#3\end{dateFont}\end{userFont}%
  \vspace*{0.8cm}
}

%------------------------
% Document
%------------------------

\begin{document}

\raggedright

\uComment{\lipsum[73]}{someone}{2000}
\uComment{\lipsum[75]}{someone}{2000}
\uComment{\lipsum[66]}{someone}{2000}

\end{document}

A picture of the page break.

enter image description here

  • Fantastic! Thanks a lot, this works out perfectly and it was so simple. Sorry for the weird environment definitions, I have built it like this because the code is for a designer that will most likely define a new font/fontsize for every item, so I had to think of a way to modularise it all. I am wondering... would there be any way of instead of moving the paragraph to a new page, removing it from the final text? – Darien Brito May 19 '17 at 15:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.