# Centering a ragged right text block in ConTeXt?

I am trying to typeset a book of poems that I wrote in ConTeXt.

Consider the following:

\definehead[PoemTitle][section]

\starttext

\PoemTitle{A Silly Whimsy}
\startlines
Some really
poetic lines
are here
and here, these are
deeply moving
\stoplines

\stoptext


This works well for breaking the lines, but the overall positioning on the page is poor, given the short nature of the lines.

I am trying to center this text block (not the line) on the page, including the \PoemTitle header. The centered text block needs to be able to break over pages.

I have been playing with the narrower environment (doesn't move the \PoemTitle header with the text block), the \hbox command (can't seem to implement anything useful), and the \defineblock and \setupblock commands. I haven't managed to get useful.

Any ideas?

EDIT:

@Will In LaTeX this gave me the desired result:

\documentclass{memoir}

\renewcommand{\PoemTitlefont}{%
\normalfont\scshape\flushleft% Remove centering from poem title
\hspace*{0.5\linewidth}\hspace*{-0.5\versewidth}}% Makes poem title flush left with body block.

\begin{document}

\settowidth{\versewidth}{Some really deep moving}
\PlainPoemTitle
\PoemTitle{willy nilly}
\begin{verse}[\versewidth]

Some really deep moving\\
lines of poetry\\
here.\\
It is all\\
so moving\\
\end{verse}

\end{document}


@Aditya:I would want to calculate the width of the longest line and choose an offset so that the longest line is in the middle of the text area, as in the LaTeX code above. It might be nice if the calculation of the longest line was automatic.

-
I do not completely understand what you mean by centering. Do you want all lines to start from a fixed offset from the left edge (as if the page had wider margins) or do you want to calculate the width of the longest line and choose an offset so that the longest line is in the middle of the text area? –  Aditya Nov 15 '10 at 1:09
I assume that you're still only interested in ConTeXt solutions? –  Will Robertson Nov 18 '10 at 3:01
It occurs to me that this design will cause different poems to be indented by different amounts. Which might be okay if each poem starts on a new page, but otherwise might be a bit strange. Are you sure this is what you want? –  Will Robertson Nov 20 '10 at 3:06
Yes, still interested in context solutions. and in my context file, i have set each poem to begin on a new page. i find the look to be much more balanced than just have the poems on the left margin. –  Mica Nov 21 '10 at 4:19
@Mica: Did you really want to start another bounty for this question, or did you just try to award the bounty? For the latter it was late. –  Hendrik Vogt Nov 25 '10 at 9:41

One possible solution:

1. Capture the contents of the environment (I use buffers)
2. Calculate the width w of the largest line (I use framedtext with autowidth=force)
3. Set a narrower environment with left spacing equal to (hsize-w)/2

In addition, I use lines so that you do not have to manually enter \\.

\defineframedtext[poemframed]
[width=\textwidth,autowidth=force,align=flushleft,
before=,after=,frame=off]

\definenarrower[poemnarrower]

\definelines[poemlines]
[before={\startpoemnarrower[left]},
after=\stoppoemnarrower,
]

\definebuffer[poem]

\def\stoppoem{\setups{poems:buffer}}

\startsetups poems:buffer
\setupnarrower[poemnarrower][left=0pt]
\setbox\scratchbox\vbox
{\poemframed
{\startpoemlines
\getpoem
\stoppoemlines}}
\edef\poemhsize{\the\dimexpr(\hsize-\wd\scratchbox)/2\relax}
\setupnarrower[poemnarrower][left=\poemhsize]
\startpoemlines
\getpoem
\stoppoemlines
\stopsetups


This can be then used as

\starttext
\startpoem
Some really deep moving
lines of poetry
here.
It is all
so moving
\stoppoem

\startpoem
Some really deep moving, really really deep moving
lines of poetry
here.
It is all
so moving
\stoppoem
\stoptext


If you want, you can use other features of lines (automatic indenting of alternate lines, etc).

EDIT Forgot that you also wanted section titles to be middle aligned. For that add

\definehead[PoemTitle][section]

[number=no,page=yes,style=\sc,alternative=command,command=\donothing]


and change poem:buffer to

\startsetups poems:buffer
\setupnarrower[poemnarrower][left=0pt]
\setbox\scratchbox\vbox
{\poemframed[align=normal,autowidth=force]
{\startpoemlines
\getpoem
\stoppoemlines}}
\edef\poemhsize{\the\dimexpr(\hsize-\wd\scratchbox)/2\relax}
\setupnarrower[poemnarrower][left=\poemhsize]
\startpoemlines
\getpoem
\stoppoemlines
\stopsetups

-
Looks good. This would be the same approach I'd use in LaTeX. (I.e., setting and measuring before setting on the page with appropriate paragraph settings.) –  Will Robertson Nov 19 '10 at 3:57
This will fail if the content is somewhat sophisticated (automatic counters, etc). TSo, the measuring phase should have \settrialtypesetting (in MkIV) and \trialtypesettingtrue (in MkII). I wonder if luatex makes such things easier: in principle one could create a node list, measure the max width, and move it around using attributes. –  Aditya Nov 19 '10 at 4:10
Sorry, I have been without a working computer for a few days. I will test this over the weekend. Thanks for the answer! –  Mica Nov 22 '10 at 20:47

Obligatory LaTeX example :) I know the question specifies a ConTeXt solution, but it's good to cross-pollinate ideas.

Since Aditya queried the intended output in the comments, here's how I interpret what the question is looking for: (I haven't attempted to replicate the proper markup for creating the poem title or anything, though)

\documentclass{article}
\usepackage{varwidth,lipsum}
\begin{document}
\lipsum[1]
\begin{center}
\begin{varwidth}{\linewidth}
\obeylines
\textsc{A Silly Whimsy}
Some really
poetic lines
are here
and here, these are
deeply moving
\end{varwidth}
\end{center}
\lipsum[2]
\end{document}

-
+1 for a LaTeX solution :) But the OP wanted an environment that splits across pages, and varwidth is built on top of minipage so won't break across a page. –  Aditya Nov 15 '10 at 5:59
@Aditya — Ah, in that case I'd use Mica's solution but typeset the whole poem in a box first to pre-calculate the maximum line width. –  Will Robertson Nov 15 '10 at 8:07

Based on Will's answer, this is how you can do the same in ConTeXt. This uses framedtexts, so will not break across pages.

First, to center align the head, just add alternative=middle to \setuphead

To center the contents first define

\defineframedtext[poemframed]
[width=\textwidth,
autowidth=force,
align=flushleft,
before=,
after=,
frame=off]


This is equivalent to the varwidth environment in LaTeX. Basically, autowidth=force forces the width of the box to equal the length of the largest line.

Next, we plug in this framedtext to a poems environment that obeys the lines.

\definelines[poem]
[before={\startpoemframed[middle]},
after=\stoppoemframed]


The middle in \startpoemframed[middle] ensures that the box is middle aligned. Now you can use

\startpoem
...
\stoppoem


to get middle aligned, left flushed, lines. As I said earlier, this will not break across pages. I don't know an easy way to ensure that the contents break across pages.

-

If it is not a problem to figure out the widest line manually, then a much shorter solution is possible:

\def\startpoem[#1]%
{\begingroup
\setbox0\hbox{#1}%
\setupnarrower[left=\dimexpr (\the\hsize-\the\wd0)/2\relax]%
\startnarrower[left]%
\startlines}

\def\stoppoem
{\stoplines
\stopnarrower
\endgroup}


But then of course you need

\startpoem[and here, these are]

-
I have been without a working computer for a few days. I will try this over the weekend. Thanks for taking the time to answer! –  Mica Nov 22 '10 at 20:47
@Mica: Don't forget to award the bounty within the next 8 hours (if possible)! –  Hendrik Vogt Nov 23 '10 at 16:59

To add another latex solution (which perhaps triggers ideas in the context users): Use longtable

\documentclass{article}
\usepackage{lipsum,longtable}
\begin{document}

\lipsum[1]

\begin{longtable}{l}
\large\bfseries Title \\*[1ex]
line 1\\
line 2\\
line 3 a bit longer
\end{longtable}
\end{document}

-