6

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.

3

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

  • Thanks @Steven, I didn't know that about lipsum. Unfortunately the struts don't seem to be doing it for me -- I've edited the question with a more complete example that shows how I'm using the parbox inside a list label. – Jim Paris Jul 25 '13 at 15:46
  • 1
    @JimParis I've revised answer to fix your new MWE (I think). – Steven B. Segletes Jul 25 '13 at 20:25
  • Perfect! Thanks for the update. That does the trick! – Jim Paris Jul 25 '13 at 21:04
3

Your definition of \arrowed should look like this:

\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\par\xdef\tpd{\the\prevdepth}}%
  \par\prevdepth\tpd%
}

This restores the box depth after its been set, as suggested in How to keep a constant \baselineskip when using minipages (or \parboxes)?.

enter image description here

\documentclass{article}
\usepackage{lipsum,setspace}% http://ctan.org/pkg/{lipsum,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\par\xdef\tpd{\the\prevdepth}}%
  \par\prevdepth\tpd%
}

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

However... it might be far better to use a list to set the item, since \parboxes (like minipages) are not breakable across the page boundary:

\documentclass{article}
\usepackage{lipsum,setspace,enumitem}% http://ctan.org/pkg/{lipsum,setspace,enumitem}
\setstretch{1.5}
\setlength{\parindent}{0pt}

\newlength{\len}
\newcommand{\arrowed}[1]{%
  \begin{itemize}[nosep]\item[{\makebox[2em][r]{$\rightarrow$}}]#1\end{itemize}%
}

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

enumitem provides the nosep option that removes all vertical gaps between the list, items and surrounding content.

  • Thanks @Werner. Makes sense, but unfortunately setting the depth doesn't work inside the list label that I'm trying to use. Please see my edits to the question with a more complete example. – Jim Paris Jul 25 '13 at 15:44
2

Use the paralist package, and define them as list items.

MWE:

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

\newenvironment{arrowed}{
  \begin{compactitem}[$\rightarrow$]
  \setlength{\itemsep}{0pt}
  \setlength{\parskip}{0pt}
  \setlength{\parsep}{0pt}
}{
  \end{compactitem}
}

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

I changed your sharelatex doc to reflex these changes.

Render from sharelatex

  • Thanks @El. This falls under the "other ways to achieve the same result" that I mentioned, and is unfortunately not applicable to my more complete example. Still very useful, though. – Jim Paris Jul 25 '13 at 15:48

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.