The expex package has a nice macro \trailingcitation which typesets a citation at the right margin of the same line if there is space, or flushed right on the line if there is no space (first two examples below, using a simplified version of \trailingcitation). Unfortunately this macro cannot handle citations longer than a single line (third example).
I tried to use Peter Wilson's \atright, but it puts as little text of the citation as possible on the first line (fourth example).
What I want instead is that if the citation is longer than a single line, it starts on a new line, and is flushed right (or, ideally, justified but with the last line aligned with the right rather than the left margin) (fifth example). How do I accomplish this?
\documentclass[draft]{article}
\usepackage[a4paper,margin=5cm]{geometry}
\usepackage{parskip}
\def\trailingcitation#1{% adapted from expex
\hskip 1.5em plus 1fill
\penalty100\null\nobreak \hskip 0pt plus 1fill
\hbox{#1}}
\newcommand*{\atright}[1]{{%
\unskip\nobreak\hfil\penalty50
\hskip2em\hbox{}\nobreak\hfil#1
\parfillskip=0pt\finalhyphendemerits=0\par}}
\begin{document}
A short quote gets a citation on the same line.
\trailingcitation{(Smith 2015)}
When the citation does not fit on the same line, a new line is used.
\trailingcitation{(Smith 2015)}
Due to \verb$\hbox$, long citations cause an overfull hbox.
\trailingcitation{(Author, \textit{Some very long title of a secondary source}, in citation by Smith 2015)}
\verb$\atright$ will make the first line as short as possible:
\atright{(Author, \textit{Some very long title of a secondary source}, in citation by Smith 2015)}
Whereas I want something like this (but only if it does not fit on the same line):\par\vspace{-1ex}
{\raggedleft (Author, \textit{Some very long title of a secondary source}, in citation by Smith 2015)\par}
\end{document}



quote. Wrapping the last example in your answer inquotecauses the citation to overflow in the right margin by the same amount as the environment is indented. I could fix this by adding\hline=\linewidthat the start of the\vtop. Since expex does not set\linewidthin examples, I needed to use this method to calculate the remaining width in\exand\pexcontexts. – Keelan Aug 18 '23 at 08:12\discretionaryand\lastboxconstructs anyway so I couldn't use high level latex constructs. – David Carlisle Aug 18 '23 at 08:40\ifto determine in which environment we are. – Keelan Aug 18 '23 at 08:52