# How to get paragraph contents

I have been using the following trick to obtain the contents of a paragraph. It works most of the time, but not on macros like \lipsum or \end{document} or \end{minipage} which expand the \par internally. Is there a way to fix this?

\documentclass{article}
\usepackage{lipsum}

\newcounter{count}

\begin{document}
\everypar{\mypar}
This is a test.

\lipsum[1]
This is a new paragraph.

\end{document}


This also demonstrats that another \mypar is executed when \lipsum expands inside \mypar (recursively).

If I convert my application to a macro instead of an environment, the inability to detect the end of the environment is no longer an issue. In other words, I could just live with it.

I believe I can detect the presence of a \par inside a macro by expanding it in a \savebox and using \everypar to increment a counter. If I store the input data as a token list, one can add tokens without expanding them. So it is just a matter of adding tokens one at a time until one expands a \par.

Of course, this only works if the macro has a single \par at the end. Macros like \item which have a \par at the beginning cannot be used with \parshape (unless modified).

• Perhaps \lipsum*[1]? – egreg Feb 29 '16 at 17:29
• Is this question specific to lipsum? Or just a general question about some areas where your \mypar doesn't work as expected? – Werner Feb 29 '16 at 17:36
• @Werner - It also doesn't work on \end{document}, so it's about \mypar. – John Kormylo Feb 29 '16 at 18:03
• @JohnKormylo: For that you might get away with \AtEndDocument{\par}. – Werner Feb 29 '16 at 18:40
• Perhaps you're interested in the shapepar package. – egreg Mar 1 '16 at 0:00

You want to use \lipsum* that does not issue \par.

\documentclass{article}
\usepackage{lipsum}

\newcounter{count}

\begin{document}
\everypar{\mypar}

This is a test.

\lipsum*[1]

This is a new paragraph.

\end{document}


If you were hoping to make \mypar into seeing the final \par in \lipsum, you're out of luck.

Instead of trying to parse the source, I decided to put each paragraph into a separate box. Also, instead of the whole document I reduced the problem to the contents of an environment (\BODY}.

By putting a \pagebreak at the end of each paragraph I can force \vsplit to pull off 1 paragraph each time and store the heights. I repeat the process using normal penalties and these heights.

\documentclass{article}
\usepackage{environ}
\usepackage{lipsum}

\newsavebox{\mybox}
\newcounter{total}
\newcounter{count}
\renewcommand{\thecount}{\Roman{count}}

\NewEnviron{test}{%
\let\oldpar=\par
\def\par{\oldpar\pagebreak}%
\everypar{\stepcounter{total}}%
\setbox\mybox=\vbox{\BODY}%
\let\par=\oldpar
\everypar{\relax}
\loop\ifnum\value{count}<\value{total}\relax
\stepcounter{count}%
\dimen0=\ht\mybox
\setbox0=\vsplit\mybox to \dimen0
\expandafter\xdef\csname testht\thecount\endcsname{\the\dimen0}%
\repeat
\global\setbox\mybox=\vbox{\BODY}%
}

\begin{document}
\parindent=0pt
\begin{test}
This is a test.

\lipsum[1]
This is a new paragraph.
\end{test}
\setcounter{count}{0}%
\loop\ifnum\value{count}<\value{total}\relax
\stepcounter{count}%
\arabic{count}\par
\dimen0=\csname testht\thecount\endcsname\relax
\setbox0=\vsplit\mybox to \dimen0
\usebox0
\repeat
\end{document}