Centering a ragged right text block in ConTeXt?
One possible solution:
- Capture the contents of the environment (I use buffers)
- Calculate the width
w
of the largest line (I use framedtext with autowidth=force) - 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] \setuphead[PoemTitle] [number=no,page=yes,style=\sc,alternative=command,command=\donothing]
and change poem:buffer
to
\startsetups poems:buffer \setupnarrower[poemnarrower][left=0pt] \setuphead[PoemTitle][margin=0pt] \setbox\scratchbox\vbox {\poemframed[align=normal,autowidth=force] {\startpoemlines \getpoem \stoppoemlines}} \edef\poemhsize{\the\dimexpr(\hsize-\wd\scratchbox)/2\relax} \setuphead[PoemTitle][margin=\poemhsize] \setupnarrower[poemnarrower][left=\poemhsize] \startpoemlines \getpoem \stoppoemlines \stopsetups
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}
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.