[Top][All Lists]

[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: Tue, 14 Feb 2023 20:16:28 -0600

Hi Alex,

At 2023-02-15T00:07:14+0100, Alejandro Colomar wrote:
> I finally got a reproducible case of what I had in mind for a long
> time that .RS wasn't a good replacement for .in.


> Here it is:
> $ cat 
> .TH a b c d
> .SH Experiment
> .TP
> foo
> .RS 4
> .EX
> int
> main(void)
> {
>     return 42;
> }
> .EE
> .RE
> .IP
> The code above was an example.
> .TP
> bar
> .in +4n
> .EX
> int
> main(void)
> {
>     return 43;
> }
> .EE
> .in
> .IP
> The code above was an example.
> $ groff -man -Tascii ./ 
> a(b)                                                                      a(b)
> Experiment
>        foo
>            int
>            main(void)
>            {
>                return 42;
>            }
>               The code above was an example.
>        bar
>                   int
>                   main(void)
>                   {
>                       return 43;
>                   }
>               The code above was an example.
> d                                      c                                  a(b)
> "bar" is what I'd expect.  Now that I know what I was looking for,
> I could search it and find it.  Michael had this to say:
> <>
> Shouldn't RS/RE nest nicely in paragraphing macros?

It does.  The problem is that there is a difference between the "left
margin" and the "indentation".  Frustration with this was one of the
issues that drew me into groff development almost 6 years ago.

Here is what groff_man_style(7) has to say about these matters today.

    .RS [indentation]
        Start a new relative inset level.  The left margin moves right
        by indentation, if specified, and by a default amount otherwise;
        see subsection "Horizontal and vertical spacing" below.  Calls
        to .RS can be nested; each increments the inset level used by
        .RE.  The level prior to any .RS calls is 1.

    .RE [level]
        End a relative inset; move the left margin back to that
        corresponding to inset level level.  If no argument is given,
        move the left margin one level back.

  Horizontal and vertical spacing
    The indentation argument accepted by .RS, .IP, .TP, and the
    deprecated .HP is a number plus an optional scaling unit.  If no
    scaling unit is given, the man package assumes "n"; that is, the
    width of a letter "n" in the font current when the macro is called
    (see section "Measurements" in groff(7)).  An indentation specified
    in a call to .IP, .TP, or the deprecated .HP persists until (1)
    another of these macros is called with an indentation argument, or
    (2) .SH, .SS, or .P or its synonyms is called; these clear the
    indentation entirely.  Relative insets created by .RS move the left
    margin and persist until .RS, .RE, .SH, or .SS is called.

    The indentation amount exhibited by ordinary paragraphs set with .P
    (and its synonyms) not within an .RS/.RE relative inset, and the
    default used when .IP, .RS, .TP, and the deprecated .HP are not
    given an indentation argument, is 7.2n for typesetting devices and
    7n for terminal devices (but see the -rIN option).  Headers, footers
    (both set with .TH), and section headings (.SH) are set at the left
    margin, and subsection headings (.SS) indented from it by 3n (but
    see the -rSN option).  HTML output devices ignore indentation.

    It may be helpful to think of the left margin and indentation as
    related but distinct concepts; groff’s implementation of the man
    macro package tracks them separately.  The left margin is
    manipulated by .RS and .RE (and by .SH and .SS, which reset it to
    the default).  Indentation is controlled by the paragraphing macros
    (though, again, .SH and .SS reset it); it is imposed by the .TP,
    .IP, and deprecated .HP macros, and cancelled by .P and its
    synonyms.  An extensive example follows.

    This ordinary (.P) paragraph is not in a relative inset nor does it
    possess an indentation.

    This ordinary (.P) paragraph is not in a relative inset nor does it
    possess an indentation.

        Now we have created a relative inset (in other words, moved the
        left margin) with .RS and started another ordinary paragraph
        with .P.

        tag This tagged paragraph, set with .TP, is still within the .RS
            region, but lines after the first have a supplementary
            indentation that the tag lacks.

            A paragraph like this one, set with .IP, will appear to the
            reader as also associated with the tag above, because .IP
            re-uses the previous paragraph's indentation unless given an
            argument to change it.  This paragraph is affected both by
            the moved left margin (.RS) and indentation (.IP).
            | This table is affected both by   |
            | the left margin and indentation. |

        o   This indented paragraph has a bullet for a tag, making it
            more obvious that the left margin and indentation are
            distinct; only the former affects the tag, but both affect
            the text of the paragraph.

        This ordinary (.P) paragraph resets the indentation, but the
        left margin is still inset.
        | This table is affected only |
        | by the left margin.         |

    Finally, we have ended the relative inset by using .RE, which
    (because we used only one .RS/.RE pair) has reset the left margin to
    the default.  This is an ordinary .P paragraph.
--end snip--

I know the above is lengthy; please point out any part of it that you
find difficult to follow.

I came up with a list of constraints that Michael had on how he wanted
to set code examples in the Linux man-pages.

Phrasing one of them a different way, I _think_ one of the things
Michael wanted was to be able to relocate examples within man pages with
complete disregard for the left margin/indentation used in the
surrounding context.  (I suspect this was so that the diffs would be
really clean, and so he'd have extreme flexibility in example placement,
never having to worry about remeasuring the output line lengths.)

I _suppose_ we could do something like add an argument to the `EX` macro
to specify an "absolute indentation amount", or maybe it would be better
to extend the semantics of `RS` (with a second argument, or
interpretation of its first argument as a string initially, permitting
some sort of alternative operation mode).  Both of these would of course
be ignored by other implementations--certainly at first, and perhaps

But before we start designing anything, we need to be on the same page
with respect to what's going on; only then can we clearly articulate the
nature of the desired change.

Well, we need goals for groff 1.24, don't we?  ;-)


Attachment: signature.asc
Description: PGP signature

reply via email to

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