[Tex/LaTex] Flexible vspace

paragraphsspacing

I created a macro to insert diary-like right-aligned paragraphs.

\newcommand{\diarydate}[1]{\begin{flushright}\textit{#1}\end{flushright}}

Example:

\diarydate{New York, August 1992}

enter image description here

This looks great at the top of the page, but not if there's a paragraph preceding it. Therefore, I want to add vertical spacing before the diarydate text if it is located between two paragraphs, but not when it's at the top of a page or right after a heading.

Is there an easy command or macro that covers all those use cases?

Best Answer

You want to use a sectioning command, that will guarantee that no page break will be taken between the diary date and the following text. For instance

\documentclass{article}
\usepackage[pass,showframe]{geometry} % to show the page frame
\usepackage{lipsum}
\makeatletter
\newcounter{diary} % to keep LaTeX happy
\newcommand{\diarymark}[1]{} % ditto
\newcommand\diarydate{%
  \@startsection{diary}%
    {10}%        level for secnumdepth and tocdepth
    {\z@}%       indentation
    {\topsep}%   space before
    {\topsep}%   space below
    {\raggedleft\normalfont\itshape}% format of the text
}
\makeatother
\begin{document}
\lipsum[2]
\diarydate{New York, August 1992}
\lipsum[2]
\section{A section}
\diarydate{New York, August 1992}
\lipsum[2]
\section{B section}
\lipsum[2]
\newpage
\diarydate{New York, August 1992}
\lipsum[2]
\end{document}

The space in the case of \section followed by \diarydate is the same as the space between a section title and normal text.

If you change the "space before" line into

    {-\topsep}%   space before

the first line after \diarydate will not be indented. I used \topsep as it is the vertical space used by flushright.

Here are the pictures.

First page

enter image description here

Second page

enter image description here


If you really want to suppress vertical spacing after a heading, you can do it in two steps:

\makeatletter
\newcounter{diary} % to keep LaTeX happy
\newcommand{\diarymark}[1]{} % ditto
\newcommand\@diarydate{%
  \@startsection{diary}%
    {10}%
    {\z@}%
    {\topsep}%
    {\topsep}%
    {\raggedleft\normalfont\itshape}%
}
\newcommand{\diarydate}{%
  \par % ensure vertical mode
  \if@nobreak % we're after a heading
    \vskip-\lastskip % suppress the space added by the heading
    \vskip-\topsep % suppress the space added by \@diarydate
  \fi
  \@diarydate}
\makeatother

and use \diarydate as before.