groff
[Top][All Lists]
Advanced

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

Re: RS/RE and paragraphing macros


From: G. Branden Robinson
Subject: Re: RS/RE and paragraphing macros
Date: Mon, 20 Feb 2023 18:29:22 -0600

At 2023-02-21T00:46:11+0100, Alex Colomar wrote:
> On 2/21/23 00:30, Alex Colomar wrote:
> > Hummm, this is definitely not as simple as "breaks the line and moves
> > the margin".  The margin is not moved because of 0, so this should be
> > just equivalent to .br from your own definition.  However, it's not.  It
> > does some extra magic, which I'd call "RS sets the indentation of the
> > scoped block to 0; RE resets to the previous indentation".
> 
> That's not even completely true.  Let's try something more precise.
> 
> RS breaks the line, moves the left margin by a relative inset, and sets the
> indentation to 0.

Close.

.\" Start a relative inset level (by the amount given in the argument).
.\" .RS [indent]
.de1 RS
.  nr an-saved-margin\\n[an-inset-level] \\n[an-margin]
.  nr an-saved-prevailing-indent\\n[an-inset-level] \
     \\n[an-prevailing-indent]
.  ie \\n[.$] .nr an-margin +(n;\\$1)
.  el         .nr an-margin +\\n[an-prevailing-indent]
.  in \\n[an-margin]u
.  nr an-prevailing-indent \\n[IN]
.  nr an-inset-level +1
..

RS (1) saves the previous margin setting and "prevailing indent" (this
term goes all the way back to McIlroy's 1979 man(7)); (2) insets (moves
right) the margin by the amount in the argument, or by the
aforementioned prevailing indent if there is no argument; (3) sets the
formatter's indentation to this new value (not "0"); (4) updates the
prevailing indent by the user-configurable standard indentation
(register `IN`); and (5) increments the inset level.

> RE breaks the line, resets the left margin to the previous value, and
> resets the default indentation of indented paragraphs to the one
> previous to RS (so if the next paragraph is IP, it will continue with
> the old indentation).

It does a lot of error checking first.

.\" End relative inset level, backing up by one level (or to the level
.\" given by the argument).
.\" .RE [inset-level]
.de1 RE
.  ie \\n[.$] .nr an-RE-requested-level \\$1
.  el         .nr an-RE-requested-level (\\n[an-inset-level] - 1)
.  ie \\n[.$] \{\
.    if (\\n[an-RE-requested-level] = \\n[an-inset-level]) \
.      ds an-RE-problem already at level \\n[an-inset-level]\"
.    if (\\n[an-RE-requested-level] > \\n[an-inset-level]) \
.      ds an-RE-problem too large\"
.    if (\\n[an-RE-requested-level] < 1) \
.      ds an-RE-problem too small\"
.    if d an-RE-problem \
.      an-style-warn argument """\\$1""" to .\\$0 \\*[an-RE-problem]
.    rm an-RE-problem
.  \}
.  el .if !(\\n[an-RE-requested-level]) .an-style-warn unbalanced .\\$0
.  rr an-RE-requested-level

...and with that out of the way, we get to an implementation fairly
symmetric with RS.

.  ie \\n[.$] .nr an-inset-level ((;\\$1) <? \\n[an-inset-level])
.  el         .nr an-inset-level -1
.  nr an-inset-level (1 >? \\n[an-inset-level])
.  nr an-margin \\n[an-saved-margin\\n[an-inset-level]]
.  nr an-prevailing-indent \
     \\n[an-saved-prevailing-indent\\n[an-inset-level]]
.  in \\n[an-margin]u
..

Essentially it "pops" the prevailing indent and margin that `RS` pushed,
permitting multiple pops at once.

> I'm not sure how to word it better.

What I quoted in my previous message in the best I've been able to do.

You will note that neither macro _explicitly_ breaks.  That is because
the `in` request causes a break (when invoked with the regular control
character).  And both macros _always_ invoke `in`, barring usage errors.

Regards,
Branden

Attachment: signature.asc
Description: PGP signature


reply via email to

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