# How can I right-align a quotation attribution, on the same line as the quotation if possible?

Often quotations are set with the attribution aligned right:

The attribution is on a new line after the quotation. Suppose however, that there were enough empty space on the last line of the quotation to hold the attribution. Then we might want it to be on the same line to avoid excessive whitespace.

We would want to define a command (call it quoteattr) that calculates whether the quotation will fit and will place it accordingly, automatically.

Code without command definition:

\documentclass[12pt]{book}

\begin{document}

\quoteattr{Early to bed and early to rise,\\
Makes a man healthy, wealthy, and wise.}{Benjamin Franklin, 1706--1790}

\quoteattr{Seek not the favor of the multitude; it is seldom got by honest and lawful means. But seek the testimony of few; and number not voices, but weigh them.}{Immanuel Kant, 1724--1804}

\end{document}


It appears that the tabto package can help in this regard.

\documentclass[12pt]{book}
\usepackage{tabto}
\def\quoteattr#1#2{\setbox0=\hbox{#2}#1\tabto{\dimexpr\linewidth-\wd0}\box0}
\parskip 1em
\begin{document}
\quoteattr{Early to bed and early to rise,\\
Makes a man healthy, wealthy, and wise.}{Benjamin Franklin, 1706--1790}

\quoteattr{Seek not the favor of the multitude; it is seldom got by honest and lawful means. But seek the testimony of few; and number not voices, but weigh them.}{Immanuel Kant, 1724--1804}

\quoteattr{In attempting to make this not give enough space... Seek not the favor of the multitude; it is seldom got by honest and lawful means. But seek the testimony of few; and number not voices, but weigh them.}{Immanuel Kant, 1724--1804}
\end{document}


• Excellent. I will only add that to ensure a bit of padding, you can add \hspace{1em} before \hbox{#2}. – Micah Walter Sep 30 '14 at 0:31

This can be handled in classic TeX fashion with a macro from The TeXBook, p106, just by fiddling with penalties, skips, and boxes:

\def\signed #1 (#2){{\unskip\nobreak\hfil\penalty50
\hskip2em\hbox{}\nobreak\hfil\sl#1\/ \rm(#2)
\parfillskip=0pt \finalhyphendemerits=0 \par}}


This will allow you to enter your quotations as follows:

\begin{quote}Here is one way to solve the problem.
\signed Donald E. Knuth (Berkeley, CA)
\end{quote}


If there is room for 2em and the signature on the same line, there it goes; otherwise, it goes on a new line. Of course, perhaps you just want a name, rather than name and location, or perhaps you'd just like it a bit more LaTeX-style; in that case, you could do something like this:

\def\signed#1{{\unskip\nobreak\hfil\penalty50
\hskip2em\hbox{}\nobreak\hfil\sl#1
\parfillskip=0pt \finalhyphendemerits=0 \par}}


And you'd enter it as above, but with \signed{Donald E. Knuth} instead.

To implement this, we will use \newsavebox to find the length of filling the empty line. We can't use \hfill, since this always has a nominal length of 0. Instead, we'll use the linegoal package.

We will also use xifthen to allow us to write the condition.

Two passes will be necessary.

\documentclass[12pt]{book}

\usepackage{linegoal}
\usepackage{xifthen}

\newsavebox{\quotebox}
\newlength{\emptywidth}% To save the length of empty space
\newlength{\attrwidth}% To save the length of the attribution

% Define the new command
\newcommand{\quoteattr}[2]{
\begin{quote}#1%
\begin{lrbox}{\quotebox}\hspace{\linegoal}\end{lrbox}
\setlength{\emptywidth}{\linegoal}
\settowidth{\attrwidth}{\textit{#2}}
% The following line can be tweaked to force attributions
% onto a new line if it would be a very tight squeeze
% Compare the two widths.
\ifthenelse{\lengthtest{\emptywidth>\attrwidth}}
% If it fits:
{\null\hfill\textit{#2}}
% If it doesn't:
% We need to provide a stretch in this way because TeX
% might compress a slightly-too-long line to prevent
% a loose line followed by a lonely word. However, then
% on the next run, TeX won't compress it because of the
% following text on a new line.
{\hspace{0pt plus \textwidth minus 3pt}\null\nopagebreak\linebreak\null\hfill{\textit{#2}}}%

% For debugging, display the lengths.
Empty space: \the\emptywidth