groff
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Groff] widow/orphan control


From: Tadziu Hoffmann
Subject: Re: [Groff] widow/orphan control
Date: Sat, 4 Jan 2003 21:16:17 +0100
User-agent: Mutt/1.4i

> > > How do I accomplish widow/orphan control in groff
> > > (I'm using -me macros)?
> > >
> > > I want to avoid page breaks after the first line
> >
> > I think -me does that automatically as part of the
> > .pp, etc., macros.  The troff request is .ne, e.g.,
> >
> >     .ne 2
> >
> > means 2v of vertical space is needed.
> 
> I have not been using .pp because .pp causes a first-line
> indent which I don't like.  I prefer to have my paragraphs
> demarcated by a blank line only -- no indent.
> 
> For me, then, a blank line followed by a ".ne 2" line seems
> to do the trick for widows.  Thanks again.

(Isn't that for orphans?  I thought a widow was
the last line of a paragraph on a new page.)

If you look at the me macros, you'll see that the paragraph
macro already has a .ne request to prevent orphans.

(Otherwise, you could always define your own "wrapper"

.de p
.sp
.ne 2
.pp
..

for the paragraph macro.)

If you don't like the indent, you can set it to zero

.nr pi 0

and instead request a larger paragraph spacing

.nr ps 1v

If you prefer to have paragraphs demarcated by
blank lines, you can set the blank line macro

.blm pp

but then *all* blank lines would start a new paragraph.
Therefore, it's usually better to use an explicit paragraph
macro even if it doesn't look as "nice", since macros can do
lots of additional useful work (like above) without cluttering
up the manuscript.  You'll get used to it.


Now, about that orphan control.  (Widow control is harder,
because you need to look ahead.)

If you're writing "literature", where paragraphs consist of
only text and nothing else, ".ne 2v" is enough.  However,
in mathematical or scientific works, lines might include
equations inline which could possibly need more vertical
space than 1 v.  To find out how much space is needed you
will have to first format the paragraph into lines and then
find out how much space the first two lines (and to prevent
widows, the last two lines) actually take up.  Thus, you
need a mechanism to count the number of lines in a paragraph.

I can think of three easy methods to do this, of which
one doesn't work.

The first one (the one that doesn't work) is to use an
"active" margin character to increment a line counter.
But it seems that the character is only evaluated at the
.mc request, and not again when it is actually used, so the
counter gets incremented only once, and not with every line.
[Is it desirable to change this behaviour?  Opinions?]

The second one is to trap every single output line into a
diversion and use the trap-invoked macro to increment the
line counter.  This is surely the most versatile solution.

The third one is to use troff's builtin line numbering facility
to do the counting, but without actually outputting the line
numbers.

Below is a simple solution which implements the third method.
The first two and last two lines of a paragraph are always
kept together.  Paragraphs with 3 lines or less always get
output as a single block.  (The red stuff is for demonstration
purposes only and should be removed.)  Of course, in practice
separate begin-paragraph/end-paragraph macros should not
be necessary.  Section headers, paragraphs, etc. should do
an implicit end-paragraph if one had been begun earlier.

The macros below also test the height of every line in the
paragraph to see if it will fit in the remaining space.
(The usual bottom-margin page traps can't prevent a line
with excessive height or depth from intruding into the bottom
margin, because the trap is sprung *after* the line is output,
and then it's already too late.  This seems to be a fundamental
flaw in the design of troff.  It would be much more useful if
the trap were sprung *before* a line sweeping beyond the trap
position were output.  [Am I right in assuming this won't be
changed in the near future?])

Note that such a solution is of course not applicable in all
situations -- for example when writing a novel, where you
usually want a flush bottom margin but normally have no
stretchable space anywhere on the page to take over the
space left by breaking the page before an orphan or widow.


---------------- cut here (with a very sharp editor) ----------------
.\" preprocessors: eqn
.\" ----------------------------------------------------------------
.de BP
.br
.nm 1 1000000 1 -4
.di PD
.ti +2m
.fi
..
.\" ----------------------------------------------------------------
.de EP
.br
.di
.nm
.nf
.nr LC \\n(ln-1
.ie \\n(LC<4 \{\
\m[red]\s8\\n(dn units height needed for the following short paragraph\s0\m[]
.ne \\n(dnu
.\}
.el \{\
.nr LC -2
.di LD
.it 2 EL
.\}
.PD
..
.\" ----------------------------------------------------------------
.de EL
.\" .tm \\n(LC lines remaining
.di
\m[red]\s8\\n(dn units height needed for the following block\s0\m[]
.ne \\n(dnu
.LD
.ie \\n(LC=2 \{\
.nr LC -2
.di LD
.it 2 EL
.\}
.el .if \\n(LC>2 \{\
.nr LC -1
.di LD
.it 1 EL
.\}
..
.\" ----------------------------------------------------------------
.EQ
delim $$
.EN
.\" ----------------------------------------------------------------
.ps 12
.vs 14
.ll 8c
.sp 3c
.BP
.ti 0
Automatic sequence numbering of output lines
may be requested with nm.
.EP
.BP
It is often necessary to force
a certain amount of space
$exp (x) = sum from {i^=^0} to inf x sup i over i!$
before a new page occurs.
This is most useful to make sure that there is not a
single ``orphan'' line left at the bottom of a page.
The `ne' request ensures that there is
$roman erf (x) = 2 over sqrt pi int from 0 to x exp (-t sup 2 ) ~dt$
a certain distance, \fIspace\fP,
specified by the first argument,
before the next page is triggered.
The default scaling indicator for `ne' is `v';
the default value of \fIspace\fP is 1v if no argument
is given.
.EP




reply via email to

[Prev in Thread] Current Thread [Next in Thread]