[Tex/LaTex] Vertical spacing around a parbox

boxesspacing

Given this:

\documentclass{article}
\usepackage{lipsum}
\usepackage{setspace}
\setstretch{1.5}
\setlength{\parindent}{0pt}

\newlength{\len}
\newcommand{\arrowed}[1]{%
  % draw an arrow, then a parbox that's exactly
  % the remaining width of the line
  \settowidth{\len}{$\rightarrow$}%
  \addtolength{\len}{-2\len}%
  \addtolength{\len}{\textwidth}%
  $\rightarrow$\parbox[t]{\len}{#1}%
}

\begin{document}
\lipsum[2]
\arrowed{\lipsum[4]}
\lipsum[6]
\arrowed{But this is OK, since it's only one line.}
\lipsum[2]
\end{document}

It's double-spaced, except for immediately after the big parbox. How do I fix that?

(I know there are other ways to achieve the same result as what I did here, but it's part of something else that is using the parbox in a list item label, and the problem that I'm having is that the spacing after the parbox is wrong if the contents are more than one line long.)


Edit:

Thanks for the suggestions. Here is some more complete code that shows how
I'm using the parbox as part of a list item label, as mentioned. I've tried to incorporate your suggestions: @Werner's suggestion (marked 1 in the code) gives You can't use \prevdepth in restricted horizontal mode, while @Steven's suggestion (marked [2]) doesn't seem to have any effect. I've tried a few variations of those but haven't had any luck.

\documentclass{article}
\usepackage{setspace,lipsum}
\makeatletter
\newcommand\singlelipsum[1]{%
  \begingroup\let\lips@par\relax\csname lipsum@\@roman{#1}\endcsname
\endgroup }
\newlength{\argwidth}
\newcommand{\argparams}[1]{%
  \parbox[t]{\argwidth}{%
    \setstretch{1.5}%
    #1)%
    %\par\xdef\tpd{\the\prevdepth}%  [1]
    %\strut%  [2]
  }%
  %\par\prevdepth\tpd%  [1]
  %\\\strut\ignorespaces%   [2]
}
\newcommand{\argfunc}[1]{\textbf{#1}(}
\newcommand{\argitem}[2]{
  \settowidth{\argwidth}{\argfunc{#1}}%
  \addtolength{\argwidth}{-2\argwidth}%
  \addtolength{\argwidth}{\textwidth}%
  \item[\argfunc{#1}\argparams{#2}]%
}
\newcommand{\argitemlabel}[1]{%
  \@tempdima\linewidth%
  \advance\@tempdima \leftmargin\makebox[\@tempdima][l]{#1}%
}
\newenvironment{arglist}{
  \begin{list}{}{%
      \setlength\labelwidth{\leftmargin}
      \setlength\labelsep{0pt}
      \setlength\rightmargin{0pt}
      \let\makelabel=\argitemlabel%
    }%
}{\end{list}}
\makeatother
\begin{document}
\setstretch{2}
\begin{arglist}
\argitem{function}{args} body
\argitem{function}{\singlelipsum{4}} \singlelipsum{2}
\end{arglist}
\end{document}

problem

By the way, the approach I'm using is based on the sphinx.sty used by Sphinx-doc. I think they don't have the problem because it's single spaced there.

Best Answer

UPDATE (to reflect revised MWE):

The only thing I changed from your non-working MWE is that I added a \relax\strut\ignorespaces to the end of \argitem. If I am understanding it properly, the \item had to be ended, because you had no text as part of the item (the \parbox was part of the \item's optional argument). So any \strut applied immediately afterward was set back on the top line of the paragraph (as part of the \item). The \relax basically stopped the \strut from being gobbled by the \item. I'm probably wrong in this explanation, but someone will correct me.

\documentclass{article}
\usepackage{setspace,lipsum}
\makeatletter
\newcommand\singlelipsum[1]{%
  \begingroup\let\lips@par\relax\csname lipsum@\@roman{#1}\endcsname
\endgroup }
\newlength{\argwidth}
\newcommand{\argparams}[1]{%
  \parbox[t]{\argwidth}{%
    \setstretch{1.5}%
    #1)%
    %\par\xdef\tpd{\the\prevdepth}%  [1]
    %\strut%  [2]
  }%
  %\par\prevdepth\tpd%  [1]
  %\\\strut\ignorespaces%   [2]
}
\newcommand{\argfunc}[1]{\textbf{#1}(}
\newcommand{\argitem}[2]{
  \settowidth{\argwidth}{\argfunc{#1}}%
  \addtolength{\argwidth}{-2\argwidth}%
  \addtolength{\argwidth}{\textwidth}%
  \item[\argfunc{#1}\argparams{#2}]\relax\strut\ignorespaces%
}
\newcommand{\argitemlabel}[1]{%
  \@tempdima\linewidth%
  \advance\@tempdima \leftmargin\makebox[\@tempdima][l]{#1}%
}
\newenvironment{arglist}{
  \begin{list}{}{%
      \setlength\labelwidth{\leftmargin}
      \setlength\labelsep{0pt}
      \setlength\rightmargin{0pt}
      \let\makelabel=\argitemlabel%
    }%
}{\end{list}}
\makeatother
\begin{document}
\setstretch{2}
\begin{arglist}
\argitem{function}{args} body
\argitem{function}{\singlelipsum{4}} \singlelipsum{2}
\end{arglist}
\end{document}

enter image description here

ORIGINAL SOLUTION (for original MWE):

I see two things going on. The first, concerning the bottom of a \parbox can be resolved with judicious use of \struts.

The second issue relates to the \lipsum[] material commonly used in MWEs. When lipsum paragraphs are output, they contain more than text. They contain paragraph formatting, in the form of \pars and stuff like that. Typically, if one were typing text as an argument for \arrowed, one would not end on a \par. And so, it would be better to get lipsum to output just the text of a paragraph, without the ending \par and such.

The author of lipsum told me how to do that:

\newcommand\singlelipsum[1]{%
  \begingroup\let\lips@par\relax\csname lipsum@\@roman{#1}\endcsname
\endgroup }

And so, with the combination of \strut and \singlelipsum (which gives just the text of a single lipsum paragraph), one can fix the problem with

\documentclass{article}
\usepackage{lipsum}
\usepackage{setspace}
\setstretch{1.5}
\setlength{\parindent}{0pt}
\makeatletter
\newcommand\singlelipsum[1]{%
  \begingroup\let\lips@par\relax\csname lipsum@\@roman{#1}\endcsname
\endgroup }
\makeatother
\newlength{\len}
\newcommand{\arrowed}[1]{%
  % draw an arrow, then a parbox that's exactly
  % the remaining width of the line
  \settowidth{\len}{$\rightarrow$}%
  \addtolength{\len}{-2\len}%
  \addtolength{\len}{\textwidth}%
  $\rightarrow$\parbox[t]{\len}{#1\strut}\\\strut\ignorespaces%
}

\begin{document}
\lipsum[2]
\arrowed{\singlelipsum{4}}
\lipsum[6]
\arrowed{But this is OK, since it's only one line.}
\lipsum[2]
\end{document}

enter image description here