# Split long string into paragraphs

How can I test a string to see if it has more than one paragraph, and split a string that contains multiple paragraphs into two strings, one with the first paragraph of the original, one with the remainder.

Background: xstring fails when presented with a long (in the \long\def sense) string. I am writing a routine which takes quotations and formats them with a lettrine and some user-specified amount of emphasized (typically small-cap) text at the beginning. This works fine for single-paragraph input, but fails for multi-. In all multi-paragraph quotations, the styling needs to be done only in the first paragraph, hence the CAR/CDR request (and that can be iterated to handle long strings with more than two paragraphs).

I am happy to share my working code with anyone who is interested.

MWE:

\documentclass{minimal}
\usepackage{xstring}
\begin{document}
\newcommand*{\InputOne}{abc\endgraf def}\InputOne

---

\newcommand{\InputTwo}{ghi\par jkl}\InputTwo

---

\StrLeft{\InputOne}{2}

---

\StrLeft{\InputTwo}{2}

---

\StrLeft{mno

pqr}{2}
\end{document}

• That sounds interesting indeed... Sep 28, 2011 at 18:21
• One possible idea might be to define a macro like this: \long\def\dosomethingwithalongtext #1\par #2\blahblah{...} and feed it with your string terminated by \par\blahblah. It might check for emptiness of the second argument then. Sep 28, 2011 at 18:56

I would write something like this:

\documentclass{minimal}
\makeatletter
\def\no@par{\no@par}
\long\def\remove@nopar#1\par\no@par{#1}%
\long\def\splitpar#1#2#3{%
\long\def\split@par##1\par##2\@nil{%
\def#2{##1}\def#3{##2}%
\ifx#3\no@par\let#3\@empty
\else\expandafter\def\expandafter#3\expandafter{\remove@nopar##2}%
\fi}%
\expandafter\split@par#1\par\no@par\@nil}
\makeatother
\begin{document}
\newcommand\InputOne{ghi\par jkl

mnopq}
\splitpar\InputOne\firstpar\remain

\firstpar

\hrulefill

\remain
\end{document}

• Why use \def\no@par{\no@par}?
– Werner
Sep 28, 2011 at 20:11
• Pretty close. This line \else\expandafter\def\expandafter#3\expandafter{\remove@nopar##2}% should create a \long\def and restore the \par at the front. But it does seem to work so far in my testing.
– Rik
Sep 28, 2011 at 21:27

The \lettrine macro from the lettrine package doesn't cooperate well with quotation, because both act using \parshape. This is a problem, because list environments like quotation use a clever mechanism for avoiding the resetting of \parshape at the end of the paragraph.

That's why applying \lettrine to the beginning of a quotation has the effect of carrying over the paragraph shape. This wouldn't be solved by splitting the environment's contents into two parts.

A "solution" would be to emulate the quotation environment in a way that won't work inside lists or other special places, but should be the same as \quotation in normal text.

\newenvironment{lquotation}
\lettrine}

The (apparent) arguments to lquotation will be passed to \lettrine:
\begin{lquotation}{V}{oici}