Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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}
share|improve this question
    
That sounds interesting indeed... –  ℝaphink Sep 28 '11 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. –  mbork Sep 28 '11 at 18:56

2 Answers 2

up vote 0 down vote accepted

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}
share|improve this answer
    
Why use \def\no@par{\no@par}? –  Werner Sep 28 '11 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 '11 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}
  {\par\addvspace{\topsep}\leftskip=\leftmargini\rightskip=\leftskip
   \lettrine}
  {\par\addvspace{\topsep}}

The (apparent) arguments to lquotation will be passed to \lettrine:

\begin{lquotation}{V}{oici}
a quotation.

With two paragraphs.
\end{lquotation}
share|improve this answer
    
The lettrine package has more problems than that for me, although the features for positioning and indentation are very nice. The biggest problem I face is that it does not work with RtL languages using bidi. I am creating my own lettrines as a result. –  Rik Sep 28 '11 at 21:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.