22

\parshape can handle arbitrary paragraph shapes. One extreme is contained within How to layout irregular paragraph shape, where it can handle setting paragraphs like this:

enter image description here

However, a simplified (and far more often-used) version of \parshape typically switches between two lengths over a number of lines. For example,

enter image description here

\documentclass{article}
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\begin{document}

\parshape 5
  0pt 0.5\textwidth
  0pt 0.5\textwidth
  0pt 0.5\textwidth
  0pt 0.5\textwidth
  0.5\textwidth 0.5\textwidth
\noindent\lipsum[1]

\end{document}

However, the use of explicit line lengths that are duplicated makes for cumbersome input - the more lines, the more duplication. Would it be possible to create a macro \newparshape (say) that would provide the same as the above, yet allow for input of the form

\newparshape{<num>}{<ind> <wd>}[<indL> <wdL>]

where it would set <num> lines with indent <ind> and width <wd>, while subsequent line (<num>+1 onward) set with indent <indL> and width <wdL>. The above example (default) usage would then be replaced with

\newparshape{4}{0pt 0.5\textwidth}[0.5\textwidth 0.5\textwidth]
\noindent\lipsum[1]

In a more general setting, expanding the restriction of setting only two lengths to more would be to generate \newparshape to accept input of the form

\newparshape
  {3}{0pt 0.5\textwidth}% 3 lines with 0pt indent and width 0.5\textwidth, followed by
  {2}{0.25\textwidth 200pt}% 2 lines with 0.25\textwidth indent and width 200pt, followed by
  {..}{...}% .. lines with ... and ..., followed by
  [...]% subsequent lines with indent ... and width ...

Of course, a different interface altogether is also acceptable. For example, something more tabular-like:

\newparshape{{4}{0pt 0.5\textwidth}{2}{0.25\textwidth 200pt}{..}{...}}[...]

where pairs of arguments are grouped within the first argument of \newparshape{<lines>}[<other>], followed by a possible specification of <other> for the treatment of subsequent lines in an optional argument.

3
  • 1
    You may want to look at \hangindent and \hangafter (I think that's how the primitives are called), which are a simplified form of \parshape. Aug 9, 2013 at 17:50
  • 1
    If you are feeling adventurous, I could write up an xgalley-based answer :-)
    – Joseph Wright
    Aug 9, 2013 at 17:54
  • @JosephWright I'm feeling curious – is xgalley supposed to be able to do this? Because I was about to ask another Q specific to expl3's coffins. Sep 13, 2015 at 0:45

1 Answer 1

14

enter image description here

\documentclass{article}
\usepackage{lipsum}% http://ctan.org/pkg/lipsum

\parindent0pt
\parskip\bigskipamount

\makeatletter
\def\newparshape{\parshape\@npshape0{}}
\def\@npshape#1#2#3{\ifx\\#3\expandafter\@@@npshape\else\expandafter\@@npshape\fi
{#1}{#2}{#3}}
\def\@@npshape#1#2#3#4#5{%
\ifnum#3>\z@\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\expandafter\@@npshape\expandafter{\the\numexpr#1+1\relax}{#2 #4 #5}{\numexpr#3-1\relax}{#4}{#5}}%
{\@npshape{#1}{#2}}}
\def\@@@npshape#1#2#3{#1 #2 }
\makeatother


\begin{document}

\newparshape{3}{5pt}{5cm}{4}{10pt}{2cm}{1}{5cm}{8cm}\\\lipsum[1]

\newparshape{2}{5cm}{5cm}{2}{4cm}{5cm}{2}{3cm}{5cm}{1}{0pt}{\textwidth}\\\lipsum[1]



\end{document}
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .