bugGNU roff - Bugs: bug #64018, [man,mdoc] decide on a common base...

 
 

bug #64018: [man,mdoc] decide on a common base paragraph indentation

Submitter:  G. Branden Robinson <gbranden>
Submitted:  Sun 09 Apr 2023 08:24:42 PM UTC
   
 
Category:  Macro package - others/general Severity:  3 - Normal
Item Group:  Feature change Status:  Fixed
Privacy:  Public Assigned to:  gbranden
Open/Closed:  Closed Planned Release:  1.24.0
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Fri 11 Aug 2023 01:03:14 AM UTC, comment #26: 

Not really relevant to this bug, but since all the relevant matters appear to have been addressed:

comment #15:

> Dave Kemper and I (both Americans) have different views on
> how wide the space after a sentence should be,


We certainly have different views on what should be the default sentence spacing in groff (join the argument in bug #58500!), but I bet we're not far apart on what we think looks best.

But personal preferences aside, the American typesetting convention started moving toward using the same size of space between words and sentences nearly a century ago, and anything published by a reputable American publisher in the past 50 years is firmly in the one-size-space-fits-all camp; both these facts are well documented in the essay you cited:

> but we both found the following resource valuable.
>
> https://web.archive.org/web/20171217060354/http://www.heracliteanriver.com/?p=324


So in typeset material, it's not really accurate to say Americans double-space after a full stop.  In American typing classes, they used to teach this practice, but manuscript convention is different from typographic convention.  I've no idea what they used to teach, or teach now, in European typing classes.  (Are typing classes even still a thing?  Don't kids these days learn to type with their thumbs on tiny screens about age 3?)

Dave <barx>
Group Member
Thu 10 Aug 2023 06:36:52 AM UTC, comment #25: 


commit 5d2e49f8182afc9bf210b7f6dd18e465319fef7b
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
Date:   Wed Aug 9 19:41:31 2023 -0500

    [man,mdoc]: Make base paragraph indent 5n (1/2).

    Change base paragraph indentation to 5n.  This corresponds to the amount
    used by historical man(7) and mdoc(7) implementations going back to Unix
    Version 7 and 4.3BSD-Reno, respectively.

    * tmac/an.tmac: Introduce new interface register, `BP`, to control the
      base paragraph indentation amount.  Formerly, `IN` determined it _and_
      the default relative inset amount.

      (an-reset-margin-and-inset-level, SH, SS): Use it.

    * tmac/doc.tmac: Introduce `BP` register, replacing `IN`.
    * tmac/mdoc/doc-common (Sh): Use it.

    * src/preproc/tbl/tests/save-and-restore-tab-stops.sh:
    * tmac/tests/an-ext_SY-and-YS-work.sh:
    * tmac/tests/an_TH-repairs-hy-damage.sh:
    * tmac/tests/an_UE-breaks-before-long-URIs.sh:
    * tmac/tests/an_adjust-link-text-correctly.sh:
    * tmac/tests/an_link-macros-work-in-paragraph-tags.sh:
    * tmac/tests/an_use-input-traps-correctly.sh:
    * tmac/tests/andoc_flush-between-packages.sh:
    * tmac/tests/doc_Mt-works.sh:
    * tmac/tests/doc_indents-correctly.sh:
    * tmac/tests/doc_synopsis_is_not_adjusted.sh: Update amount of
      indentation expected in output.

    Fixes <https://savannah.gnu.org/bugs/?64018>.  Thanks to Thorsten Glaser
    and Ingo Schwarze for the discussion.

commit ab9e82cd9716d929051eedfb104d227a02c964e5
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
Date:   Thu Aug 10 00:03:13 2023 -0500

    [man,mdoc]: Make base paragraph indent 5n (2/2).

    * tmac/groff_man.7.man.in:
    * tmac/groff_mdoc.7.man: Document it.

    * NEWS: Add item.


G. Branden Robinson <gbranden>
Group administrator
Wed 09 Aug 2023 11:50:55 PM UTC, comment #24: 

Working on this.

G. Branden Robinson <gbranden>
Group administrator
Mon 07 Aug 2023 06:40:48 PM UTC, comment #23: 

Thanks for the history! I also don’t see it used anywhere really.

>By the way, do we still have that ancient README file in the groff git tree?
>I think that OpenBSD still has it lying around in the source tree in
>/usr/src/share/tmac/mdoc/README is a mistake, too.


Unsure about groff, but in MirBSD I still have it, probably from OpenBSD; as I said, my tmac is a merger of OpenBSD’s pre-mdocml and the “last” one from classic BSD, which I then made work with the last nroff under the Caldera licence. Maybe also not based on the one from OpenBSD. But if you have meaningful comments on
http://www.mirbsd.org/cvs.cgi/src/share/tmac/mdoc/README?rev=HEAD
(or the rest of tmac, really), be my guest (but perhaps not here unless it’s for cross-*roff compatibility).

Thorsten Glaser <mirabilos>
Mon 07 Aug 2023 06:33:24 PM UTC, comment #22: 

comment #15:

> > > > We cannot, obviously, have three-letter requests.
> > > Nope.  Like I said, there's room for `Cq`, `Co`, and `Cc`.
> >
> > Indeed, I see only Co used grepping through all tmacs:
> > tmac.doc.old has it as macro (just .tm’ing to say it’s
> > not an mdoc macro) plus…
>
> It's in groff's "doc-old.tmac", too, which has the same origin.
>
> Huh.  I wonder what the story behind that is.


Some years ago, i talked to Cynthia, i think Kirk McKusick helped establish the contact back then.

What groff calls "doc-old.tmac" is what Cynthia used to call "tmac version 2" around 1990, whereas she called the language we are now used to "tmac version 3" back then.  If i remember correctly, even Cynthia herself did not keep a copy of "tmac version 1", and i think she considered it unlikely that such a copy exists anywhere.  But it's also next to irrelevant at this point.  As people usually do when designing a new language, she experimented a lot with preliminary ideas during the early stages and took stuff out again when she had better ideas and/or collected experience using her new language for practical work.

Even version 2 was a pre-alpha thing and never used consistently, not even for any alpha release of the BSD system.  It was used in a relatively small minority of manual pages in 4.3BSD-Reno (June 1990), which you might call an official Beta release; the name was intended to indicate "running this is akin to visiting a Casino."  The vast majority of manual pages in Reno still used man(7) because the design of the mdoc(7) language was nowhere near finished and the main work of rewriting the documentation under a free license had barely started.

Consequently, what mdoc version 2 did or did not do is of very limited interest even to extreme BSD history geeks.  Compatibility with mdoc version 2 is completely irrelevant for any purpose one could possibly think of because version 2 was never considered ready for production in the first place.  There certainly aren't any mdoc version 2 documents that anybody uses for any contemporary purpose in 2023.  Even finding purely historical mdoc version 2 documents that you could use a version 2 formatter on is not all that easy, in particular not outside McKusick's BSD history CDs.

I suspect that maybe Cynthia poisoned .Co in mdoc version 2 because in 4.2BSD, 4.3BSD-Reno, and 4.4BSD, the documentation of the "MH" email handling system, written in Eric Raymond's -me macros, defined its own .Co macro and used it at quite a few places - but i'm not sure that's the reason.  It certainly no longer matters today.

> > | mdoc/README:.\" NS Co register (site) Width Needed for Column offset
> >
> > … I’m not sure if this is still true, given my grep
> > did not find any other occurrence? I think this is
> > old/wrong and needs to be removed.
>
> It seems likely to me.


I failed to unearth evidence for \n(Co ever being used for anything in any of my 4.2BSD, 4.3BSD, or 4.4BSD trees.
It seems that line in Cythia's README file refers to one of her experimental ideas that she discarded before it ever grew up sufficiently for production use.

By the way, do we still have that ancient README file in the groff git tree?
I don't readily see it in git, and keeping it would almost certainly be a mistake.

I think that OpenBSD still has it lying around in the source tree in /usr/src/share/tmac/mdoc/README is a mistake, too.


> I would guess that Ingo has the world's biggest corpus of mdoc(7) documents readily at hand--but perhaps not the time to grep them for our benefit.  :P


I tried to figure out why you consider `Cq`, `Co`, and `Cc` only to fail - still scratching my head...

All the same, FWIW, i just grep'ed the manual pages in the base systems of

OpenBSD-current
FreeBSD-13.0
NetBSD-9.2
DragonFly-3.8.2
4.4BSD-Lite2  (some of these are old, but that may not matter for the purpose at hand)

and came out completely empty-handed for '^\. *\<Co\>', i.e. .Co as a line macro.

Obviously, .Co as a sub-macro is harder to grep for, but '^\..* Co ' and '^\..* Co$' did not find anything, either.

And Co as a register name?  Well-written mdoc(7) manuals should not expand registers, but i looked anyway using '\\n.Co': again, nothing.

Maybe a string register name then?  I tried '\\\*.Co': again, only false positives.

So it doesn't appear anything anywhere is using "Co" as a roff(7) identifier in mdoc(7) manual pages.

Then again, please be aware that i never attempted to build a repository of mdoc(7) manual pages as comprehensive as possible, i merely have a number of BSD trees lying around.  I did not check Illumos nor some stand-alone portable software projects that are using mdoc(7).  Then again, it would be seriously ill-adwised for Illumos or any such projects to introduce any completely new features, at least not without carefully coordinating with both groff and mandoc.

Ingo Schwarze <schwarze>
Group Member
Mon 07 Aug 2023 04:19:43 PM UTC, comment #21: 

Regarding editing manual page source code in such a way as to avoid particularly ugly line breaks in standard-width 80 column terminal windows:

comment #12:

> Possibly, mdoc(7) page authors knew this and carefully edited the ones that did, so that now no one sees them.
> But they would have be de-semanticizing their inputs by sweating formatting details.
> Perhaps Ingo will join me in finding that dubious,


In OpenBSD, people mostly avoid such hand-optimization of presentational markup and stick to semantic markup.  In the vast majority of cases, that yields good results and minimizes maintenance effort.

However, a smaller number of pages exists that, for one reason or another, are hard to get into a state both easy to read and looking pleasant, if you purely stick to presentational markup.  It typically  happens with content that is more complicated and harder to understand in the first place.  These cases are not typically as simple and straightforward as SYNOPSIS sections; we tend to stick to semantic markup in the SYNOPSIS.  The auto-breaking features of .Op, .Fl, and .Ar tend to work reliably in general.

I know for sure that in such cases, our chief documentation maintainer, Jason McIntyre, occasionally does resort to manually optimizing the source code such that output lines do not exceed 80 columns, do not break in bad places places, and so on.  Now if we would suddenly increase the global indentation by 2n, most of these hand-optimized cases would suddenly become hard to read and ugly in precisely the way Jason spent some work on avoiding.  That would be bad because, as i said, these are not just random cases, but typically cases with complicated content, where causing an additional distraction for the readers would be particularly unfortunate.

For that reason, i'm definitely not going to increase the global offset from 5n to 7n in mandoc(1).  Even if you were to do that in groff(1), mandoc would certainly not follow, and i might possibly even patch it back in the OpenBSD port of groff.

I'm not quite sure how this kind of hand-optimization is regarded in FreeBSD and NetBSD.  I talked to both Warren Block and Thomas Klausner multiple times face-to-face, but don't recall ever bringing up this particular topic.  I guess their view might be somewhat similar, but i'm not completely sure.  It seems likely to me their approach might be somewhat less systematic and more ad-hoc than in OpenBSD.  So i cannot exclude that hand-optimization might be slightly more common and semantic markup slightly weaker on average in their pages than in ours.  In general, they tend to invest less into documentation than we do.  I know even less about DragonflyBSD, except that they usually follow FreeBSD quite closely (even though often with significant time delays) unless they are specifically working on an area of their system, so i doubt they are doing much general-purpose manual page work in the first place.

> even if he hates the changed indentation (which I aim to change back, and port over to groff man(7), in case that wasn't clear).


I felt relieved when earlier comments in this ticket made this seem likely to me.  Thank you!

Ingo Schwarze <schwarze>
Group Member
Sun 06 Aug 2023 01:48:24 AM UTC, comment #20: 

Hmh. I personally don’t care about the obsolete/legacy man(7) macropackage, only mdoc(7), but 7n sounds like quite a lot, and I would rather mdoc(7) stick to 5n as it used to.

Thorsten Glaser <mirabilos>
Sun 06 Aug 2023 01:13:14 AM UTC, comment #19: 

Alex's case of cringe at my `is_family_valid` function has been raised on the groff development list.

https://lists.gnu.org/archive/html/groff/2023-08/msg00008.html
https://lists.gnu.org/archive/html/groff/2023-08/msg00009.html

It is off-topic for this ticket; let's please discuss `lengthof` elsewhere.

Let me update my intentions from comment #5 as follows.


This ticket contemplates two new registers for man(7), and restricted
meaning for the `IN` register, first exposed/documented by Documenter's
Workbench (DWB) 1.0 in 1984.

* BP: base paragraph indentation configures how far the left margin of
  a normal paragraph is inset from the page offset (which is 0 on
  terminals) to which relative insets are added.  Default: 5n.
  Currently, `IN` is used for this purpose as well as `RS`.

* IN: the "standard indentation" would now configure only the default
  indentation increment used for relative inset.  Default: 7n/7.2n (no
  change).

* TS: the "tag spacing" configures the size the of the gap that is
  required after a paragraph tag.  This amount is added to the width of
  the diversion created by the `IP` and `TP` macros to format the tag.
  If that amount is greater than the standard indentation, a break is
  emitted and the remainder of the paragraph is formatted starting on a
  new output line, indented by the `IN` increment.  Default: 2n.
  Currently, a value of 1n is used for this purpose.  (In groff 1.23.0,
  it's stored in the internal `an-tag-separation` register, but not
  readily user-configurable.)

For consistent rendering of mdoc(7) pages, these parameters (if set)
would be honored by that macro package too, as `SN` and `IN` already
are, where comparable macro semantics permit.


G. Branden Robinson <gbranden>
Group administrator
Sun 06 Aug 2023 01:01:35 AM UTC, comment #18: 

comment #9:

> comment #8:
> What do you mean by "very narrow"?  Over the decades man pages have "bloated" from an expected line length of 65n to more like 78n, and even then there are many carelessly composed tbl(1) tables that will overrun the line length.  In groff 1.23.0 I've made tbl diagnose that in more cases (bug #61878).


Incorrect cross reference there.

I was thinking of bug #61854.

G. Branden Robinson <gbranden>
Group administrator
Fri 04 Aug 2023 12:32:58 AM UTC, comment #17: 

comment #15:

> I regret that the implementation language makes groff so stinky for people.  Having seen the problems it was solving, I can understand why Clark selected it over the just-born ANSI C.  It's much closer to applications programming than systems programming, and C++ had much promise there.  Of course Stroustrup promoted as the best language for everything.  :-/
>
> From today's perspective, in groff there are huge amounts of data-structure walking code that could be replaced by C++98 "algorithms" (they are, but God the name assaults the nose like a bottle of brogrammer patchouli oil), or cleanly replaced by C++11 idioms.
>
> I get the feeling that Clark ended up not doing as much input validation as he might simply because it was so incredibly tedious to walk data structures.
>
> Here's a recent example of some validation I added, with annotations of future possibilities.
>


> bool is_family_valid(const char *fam)
> {
>   // std::vector<const char *> styles{"R", "I", "B", "BI"}; // C++11
>   const size_t nstyles = 4;
>   const char *st[nstyles] = { "R", "I", "B", "BI" };
>   std::vector<const char *> styles(st, (st + nstyles));
>   // for (auto style : styles) // C++11
>   std::vector<const char *>::iterator style;
>   for (style = styles.begin(); style != styles.end(); style++)
>     if (!check_font(fam, *style))
>       return false;
>   return true;
> }


>
> C++11 would cut this function about in half.  Of course, the whole thing is pure bloat from an Annotated Reference Manual C++ perspective, where'd you skip all this ridiculous validation entirely because what could go wrong?  The ARPAnet is such a friendly place...


Wow!  You can cut that in half in C.


#define lengthof(a)  (sizeof(a) / sizeof((a)[0]))


bool is_family_valid(const char *fam)
{
        static const char  st[][3] = { "R", "I", "B", "BI" };

        for (size_t i = 0; i < lengthof(st); i++) {
                if (!check_font(fam, st[i]))
                        return false;
        }
        return true;
}

Alejandro Colomar <alx>
Thu 03 Aug 2023 11:45:40 PM UTC, comment #16: 

My stance on that is: you can do two spaces after a full stop if you want (I won’t as I’m continental-european), but not in fixed-width / monospaced settings, as the dot is already widened there by necessity. But I was just using the terms american vs french spacing as that’s what my text editor uses.

> not Kernighan's rewrite


I think that means the same thing as I was referring to as ditroff earlier.

The tape archive I have was sent to me by someone from a UK university (another entity which cannot hold copyright), so it’s not entirely unmodified, but certainly this historic artefact AIUI. I’ll point you to it in private mail, perhaps it helps. As I said, I’d need a licence I don’t have to make use of it myself, otherwise I would have liked to use it.

AIUI both Plan 9’s and heirloom-doctools are also both of that lineage.

No, I’m stuck with the 1970s nroff.




As to C++… one thing is I don’t speak it myself, and I prefer to use software I can maintain if needed (it happened too often that I suddenly became the new maintainer, including with GNU CVS funnily enough, at least de-facto, the Savannah people asked me, but they never got the de-iure part done).

The other thing is that the MirBSD base compiler is an ancient GCC, and to not have its C++ part (but if one wants C++ then install one of the newer compilers from ports) makes library versioning easier (some things need the newer compilers, and you can’t mix those with libraries from the old G++ due to ABI changes). So this was a deliberate decision in the context of a hobby OS.

Goodnight,
mirabilos

Thorsten Glaser <mirabilos>
Thu 03 Aug 2023 11:12:58 PM UTC, comment #15: 

comment #14:

> > Possibly, mdoc(7) page authors knew this and carefully edited the
> > ones that did, so that now no one sees them.
>
> Exactly, we do that… I recently also begun rewording things to
> avoid hyphenation as well, although only with “french” spacing
> (no american double-space after a full stop) since that’s what
> I use in my BSD.



Dave Kemper and I (both Americans) have different views on how wide the space after a sentence should be, but we both found the following resource valuable.

https://web.archive.org/web/20171217060354/http://www.heracliteanriver.com/?p=324

groff makes this parameter tunable for all output devices, so it's not a source of strife, except among those who don't read documentation.

> >> We figured out that putting \& after punctuation only for stuff like
> >> “e.g.\&” (where you don’t want the american double-spacing after),
> >> and otherwise before (e.g. “\&.”
>
> That would be “.Dq \&.”, for the sake of completeness.
> I also saw “.Dq .\&”, and, for some time, people were
> not clear about which one to use, but in discussion
> with J�rg, it got clear that the most portable is to
> put the \& in front always except “e.g.\&”.


For the case of ".Dq .", I agree.  The macro itself won't (shouldn't) put a bare dot at the beginning of an (interpolated) input line, so the worry is that interpolation will result in the quoted dot being treated as the end of a sentence, just as:


He said, "the guys just left."


is.

> No, something like “.Dq \&Li”, that is, where I have a
> two-character argument to a parsed macro, so it isn’t
> interpreted as callable macro.
>
> This application is disctinct from escaping a leading
> dot or apostrophe or an end-of-line dot that’s not a
> full stop.


Agreed.  This is an additional application of the dummy character created by mdoc(7)'s unique design.
 

> > Interesting.  I did not know `In` was a late-breaking macro
>
> I first saw it in manpages from NetBSD, and OpenBSD did
> not have it, nor use it. (I think that before the switch
> to mdocml they didn’t change their tmacs much.)


Interesting.  Perhaps the feeling was that it wasn't worth maintaining any aspect of troff as the desire built to kill it.

> >> We cannot, obviously, have three-letter requests.
> > Nope.  Like I said, there's room for `Cq`, `Co`, and `Cc`.
>
> Indeed, I see only Co used grepping through all tmacs:
> tmac.doc.old has it as macro (just .tm’ing to say it’s
> not an mdoc macro) plus…


It's in groff's "doc-old.tmac", too, which has the same origin.

Huh.  I wonder what the story behind that is.

> | mdoc/README:.\" NS Co register (site) Width Needed for Column offset
>
> … I’m not sure if this is still true, given my grep
> did not find any other occurrence? I think this is
> old/wrong and needs to be removed.


It seems likely to me.

I would guess that Ingo has the world's biggest corpus of mdoc(7) documents readily at hand--but perhaps not the time to grep them for our benefit.  :P

> >> The codebase is the “last” nroff I could use under the Caldera
> >> licence, i.e. that was shipped with a BSD covered by these. The
>
> > Is there anyplace these can currently be obtained?
>
> I got them from minnie.tuhs.org; if your CVS skills are still
> not too rusty, you can get the subset I imported from MirBSD
> anoncvs, too.


My CVS skills are pretty rusty but this wouldn't help me.  Every time someone has pointed me to something they said was "1980s troff sources", it was a descendant of Ossanna troff, not Kernighan's rewrite.  In other words, it was 1970s troff.

I think the first time someone sent me on that goose chase it was to Kirk McKusick's CSRG CD-ROMs.  Much great stuff, but not a vintage 1981 Kernighan troff.  I want that so bad.
 

> And yes, it’s not the later one, it’s the old one where troff
> was for that one typesetter(?) machine. I do also have a
> tape archive of a ditroff predating 1990 which would be in the
> PD in the USA but not in the rest of the world, so I cannot
> use it (and trying to figure out who even could give a
> licence is probably not worth the effort… I think it was
> Lucent labs at some point, and someone told me they generally
> don’t even have an idea about this),


Look into that DWB 3.3 link I shared.  This sounds like a very similar thing.

> so I had to bite the sour
> apple and use the last one from the Caldera drop, which is
> pretty much 1970s C code. No prototypes, and every variable
> (other than some which are short or char) is of the data type
> int or char* which are identical and interchangeable, and they
> manually paged part of the -fcommon data area relying on the
> in-memory layout to match the one from the source…


K&R C was the best language ever because it was so weakly typed. :-|


> > I hope that's a labor of love
>
> Oh, definitely!
>
> (This also allowed me to get rid of C++ from the base system;
> groff was the last remaining part, and now I can just install
> one from ports on the box where I render the ps→pdf docs.)


I regret that the implementation language makes groff so stinky for people.  Having seen the problems it was solving, I can understand why Clark selected it over the just-born ANSI C.  It's much closer to applications programming than systems programming, and C++ had much promise there.  Of course Stroustrup promoted as the best language for everything.  :-/

From today's perspective, in groff there are huge amounts of data-structure walking code that could be replaced by C++98 "algorithms" (they are, but God the name assaults the nose like a bottle of brogrammer patchouli oil), or cleanly replaced by C++11 idioms.

I get the feeling that Clark ended up not doing as much input validation as he might simply because it was so incredibly tedious to walk data structures.

Here's a recent example of some validation I added, with annotations of future possibilities.


bool is_family_valid(const char *fam)
{
  // std::vector<const char *> styles{"R", "I", "B", "BI"}; // C++11
  const size_t nstyles = 4;
  const char *st[nstyles] = { "R", "I", "B", "BI" };
  std::vector<const char *> styles(st, (st + nstyles));
  // for (auto style : styles) // C++11
  std::vector<const char *>::iterator style;
  for (style = styles.begin(); style != styles.end(); style++)
    if (!check_font(fam, *style))
      return false;
  return true;
}


C++11 would cut this function about in half.  Of course, the whole thing is pure bloat from an Annotated Reference Manual C++ perspective, where'd you skip all this ridiculous validation entirely because what could go wrong?  The ARPAnet is such a friendly place...
 

> As for tbl, IIUC the limitation is because of the limitation
> on string names in nroff.


Yeah, the two-character name space feels limited in short order.  But it made Ken Thompson's fan club ecstatic.

> I wonder if I can relax the latter
> a little in my implementation, having already raised the amount
> of things it can handle, just enough to make that page work…
>
> … gah, not tonight. No nerdsnipey for me.


Maybe I'll get you next time...

G. Branden Robinson <gbranden>
Group administrator
Thu 03 Aug 2023 10:43:27 PM UTC, comment #14: 



> Possibly, _mdoc_(7) page authors knew this and carefully edited the
> ones that did, so that now no one sees them.

Exactly, we do that… I recently also begun rewording things to
avoid hyphenation as well, although only with “french” spacing
(no american double-space after a full stop) since that’s what
I use in my BSD.


>> We figured out that putting \& after punctuation only for stuff like
>> “e.g.\&” (where you don’t want the american double-spacing after),
>> and otherwise before (e.g. “\&.”

That would be “.Dq \&.”, for the sake of completeness.
I also saw “.Dq .\&”, and, for some time, people were
not clear about which one to use, but in discussion
with J�rg, it got clear that the most portable is to
put the \& in front always except “e.g.\&”.

>> or “\&xx” where xx is a request name) works best.
> I assume you mean `\&.xx' in that last example.

No, something like “.Dq \&Li”, that is, where I have a
two-character argument to a parsed macro, so it isn’t
interpreted as callable macro.

This application is disctinct from escaping a leading
dot or apostrophe or an end-of-line dot that’s not a
full stop.

> Interesting.  I did not know `In` was a late-breaking macro

I first saw it in manpages from NetBSD, and OpenBSD did
not have it, nor use it. (I think that before the switch
to mdocml they didn’t change their tmacs much.)

>> We cannot, obviously, have three-letter requests.
> Nope.  Like I said, there's room for `Cq`, `Co`, and `Cc`.

Indeed, I see only Co used grepping through all tmacs:
tmac.doc.old has it as macro (just .tm’ing to say it’s
not an mdoc macro) plus…

| mdoc/README:.\" NS Co register (site) Width Needed for Column offset

… I’m not sure if this is still true, given my grep
did not find any other occurrence? I think this is
old/wrong and needs to be removed.


>> The codebase is the “last” nroff I could use under the Caldera
>> licence, i.e. that was shipped with a BSD covered by these. The

> Is there anyplace these can currently be obtained?

I got them from minnie.tuhs.org; if your CVS skills are still
not too rusty, you can get the subset I imported from MirBSD
anoncvs, too.

And yes, it’s not the later one, it’s the old one where troff
was for that one typesetter(?) machine. I *do* also have a
tape archive of a ditroff predating 1990 which would be in the
PD in the USA but not in the rest of the world, so I cannot
use it (and trying to figure out who even _could_ give a
licence is probably not worth the effort… I think it was
Lucent labs at some point, and someone told me they generally
don’t even have an idea about this), so I had to bite the sour
apple and use the last one from the Caldera drop, which is
pretty much 1970s C code. No prototypes, and every variable
(other than some which are short or char) is of the data type
int or char* which are identical and interchangeable, and they
manually paged part of the -fcommon data area relying on the
in-memory layout to match the one from the source…

> I hope that's a labor of love

Oh, definitely!

(This also allowed me to get rid of C++ from the base system;
groff was the last remaining part, and now I can just install
one from ports on the box where I render the ps→pdf docs.)

As for tbl, IIUC the limitation is because of the limitation
on string names in nroff. I wonder if I can relax the latter
a little in my implementation, having already raised the amount
of things it can handle, just enough to make that page work…

… gah, not tonight. No nerdsnipey for me.

Thorsten Glaser <mirabilos>
Thu 03 Aug 2023 09:56:32 PM UTC, comment #13: 

comment #11:

> The codebase is the “last” nroff I could use under the Caldera licence, i.e. that was shipped with a BSD covered by these. The macropackages are a conglomerate from the TUHS archives and pre-mdocml OpenBSD’s,


Is there anyplace these can currently be obtained?  I'm curious to see if this is the same place from which the modernized (just for build/portability purposes) DWB 3.3 troff originated.

> but I invested heavily into them to get them to mostly work (modulo missing pieces). I also added a hack (with pre‑ and postprocessor) for 8-bit/UTF-8 support, but that’s nowhere near mature.


> I only ported nroff, not troff (since nobody has the hardware it drives any more),


That wouldn't be DWB 3.3 troff, then, because people do still have PostScript devices.

https://github.com/n-t-roff/DWB3.3/tree/master/postscript/

[...]

> With the exception of terminfo(5)¹ I use this exclusively to build catmanpages, but I use groff with custom fonts to build PDF manpages for the website for the “portable subprojects” like mksh.


I hope that's a labor of love, because it sounds like punishment to me.  (Which is no doubt what some people think of some of my avocations...)

> ① “Too many text block diversions”, which probably means this cannot be rendered with tbl(1) at all and needs GNU tbl, if I understand this correctly.


Yes.

tbl(1) from groff 1.23.0:


  GNU tbl enhancements
    In addition to extensions noted above, GNU tbl removes constraints
    endured by users of AT&T tbl.

    • Region options can be specified in any lettercase.

    • There is no limit on the number of columns in a table, regardless
      of their classification, nor any limit on the number of text
      blocks.

    • All table rows are considered when deciding column widths, not
      just those occurring in the first 200 input lines of a region.
      Similarly, table continuation (.T&) tokens are recognized outside
      a region’s first 200 input lines.

    • Numeric and alphabetic entries may appear in the same column.

    • Numeric and alphabetic entries may span horizontally.


G. Branden Robinson <gbranden>
Group administrator
Thu 03 Aug 2023 09:49:44 PM UTC, comment #12: 

comment #10:

> Merely ugly.

[...]

> Very ugly though ;-)


Wow, you're not kidding.  That's pretty awful.  But given that the change in indentation amount is all it took to produce this yuckiness, I would think there have to be synopses that would be just as horrid with a base paragraph indentation of 5n.

Possibly, mdoc(7) page authors knew this and carefully edited the ones that did, so that now no one sees them.  But they would have be de-semanticizing their inputs by sweating formatting details.  Perhaps Ingo will join me in finding that dubious, even if he hates the changed indentation (which I aim to change back, and port over to groff man(7), in case that wasn't clear).

> These are all with standard 80 columns.
>
> Sorry, I don’t have a guide… most of the time, it’s the nine-argument limit (sometimes eight, but I fixed some of these cases), and more rarely converting \[xx] to \(xx.


Understood.

> There is also an issue with where \& should be placed, which also affects J�rg Schilling’s systems. We figured out that putting \& after punctuation only for stuff like “e.g.\&” (where you don’t want the american double-spacing after), and otherwise before (e.g. “\&.” or “\&xx” where xx is a request name) works best.


I assume you mean `\&.xx` in that last example.

And yes, those two applications have always been intended and expected.

groff_man_style(7) says:


    \&  Dummy character.  Insert at the beginning of an input line to
        prevent a dot or apostrophe from being interpreted as beginning
        a roff control line.  Append to an end‐of‐sentence punctuation
        sequence to keep it from being recognized as such.


The groff manual says more.

I remember Joerg well.  If you have any exhibits of *_roff_ input that he insisted was correct, all other implementations be damned, I'd be curious to see them.

> I did add some of the new features to my tmac, like .In to mdoc(7) and the Xr-like .MR to man(7).


Interesting.  I did not know `In` was a late-breaking macro in the mdoc(7) world.  I (feel that I) have a good grasp of man's history, and a poor one of mdoc's.

> We cannot, obviously, have three-letter requests.


Nope.  Like I said, there's room for `Cq`, `Co`, and `Cc`.

Thanks for following up!

G. Branden Robinson <gbranden>
Group administrator
Thu 03 Aug 2023 09:26:36 PM UTC, comment #11: 

Oh sorry, submitted too early.

The codebase is the “last” nroff I could use under the Caldera licence, i.e. that was shipped with a BSD covered by these. The macropackages are a conglomerate from the TUHS archives and pre-mdocml OpenBSD’s, but I invested heavily into them to get them to mostly work (modulo missing pieces). I also added a hack (with pre‑ and postprocessor) for 8-bit/UTF-8 support, but that’s nowhere near mature.

I only ported nroff, not troff (since nobody has the hardware it drives any more), and the codebase is a mess I had cleaned up a little over the years. It builds with -O1 on ILP32 with a patched GCC 3.4.6 but GCC 4 already kills it, and sparc has an issue i386 hasn’t (or had, the latest changes might have solved that, but I have yet to have someone run electricity to where my SPARCstations are in the new house and so couldn’t test that yet).

I have recently begun working on porting it to ILP32 GNU/Linux and newer GCC so I can use UBSan to find the remaining issues, but that’s a low-priority project unfortunately.

With the exception of terminfo(5)¹ I use this exclusively to build catmanpages, but I use groff with custom fonts to build PDF manpages for the website for the “portable subprojects” like mksh.

① “Too many text block diversions”, which probably means this cannot be rendered with tbl(1) at all and needs GNU tbl, if I understand this correctly.

Thorsten Glaser <mirabilos>
Thu 03 Aug 2023 09:16:25 PM UTC, comment #10: 

Merely ugly.

Old:

SYNOPSIS
     mksh [-+abCefhiklmnprUuvXx] [-+o option] [-T [!]tty|-] [file [arg1 ...]]
     mksh [-+abCefhiklmnprUuvXx] [-+o option] [-T [!]tty|-] -c cmd [arg0 ...]
     mksh [-+abCefhiklmnprUuvXx] [-+o option] [-T [!]tty|-] -s [arg1 ...]
     builtin-name [argument ...]

New:

SYNOPSIS
       mksh     [-+abCefhiklmnprUuvXx]     [-+o    option]    [-T    [!]tty|-]
            [file [arg1 ...]]
       mksh  [-+abCefhiklmnprUuvXx]  [-+o  option]  [-T   [!]tty|-]   -c   cmd
            [arg0 ...]
       mksh [-+abCefhiklmnprUuvXx] [-+o option] [-T [!]tty|-] -s [arg1 ...]
       builtin‐name [argument ...]

Very ugly though ;-)

These are all with standard 80 columns.

Sorry, I don’t have a guide… most of the time, it’s the nine-argument limit (sometimes eight, but I fixed some of these cases), and more rarely converting \[xx] to \(xx.
There is also an issue with where \& should be placed, which also affects J�rg Schilling’s systems. We figured out that putting \& after punctuation only for stuff like “e.g.\&” (where you don’t want the american double-spacing after), and otherwise before (e.g. “\&.” or “\&xx” where xx is a request name) works best.

I did add some of the new features to my tmac, like .In to mdoc(7) and the Xr-like .MR to man(7).

We cannot, obviously, have three-letter requests.

Thorsten Glaser <mirabilos>
Thu 03 Aug 2023 09:00:34 PM UTC, comment #9: 

comment #8:

> Just chiming in that the change from GNU groff 1.22.x to 1.23 in GNU mdoc is wrapping all my manpages badly because it reduces the already very narrow screen estate.


Are the lines breaking in inappropriate places, as in the 82nd character cell on an 80-column terminal?

Or is the output "merely" ugly?

What do you mean by "very narrow"?  Over the decades man pages have "bloated" from an expected line length of 65n to more like 78n, and even then there are many carelessly composed tbl(1) tables that will overrun the line length.  In groff 1.23.0 I've made tbl diagnose that in more cases (bug #61878).

> I’m using AT&T nroff


There were many AT&T nroffs.  Which release of Unix, or DWB?

> with UCB mdoc to write my manpages, but make their rendering portable to work also with GNU groff (with BSD or GNU mdoc), and mdocml has also learnt to render them correctly.


I'm curious to know what portability issues there are!  Do you have a guide somewhere?

For instance, the 3-character request names for brace enclosures cannot possibly be portable to AT&T troff.  There is space in the mdoc macro name space to rename them such that s/Br/C/.  What do you think?

G. Branden Robinson <gbranden>
Group administrator
Thu 03 Aug 2023 08:49:19 PM UTC, comment #8: 

Just chiming in that the change from GNU groff 1.22.x to 1.23 in GNU mdoc is wrapping all my manpages badly because it reduces the already very narrow screen estate.

I’m using AT&T nroff with UCB mdoc to write my manpages, but make their rendering portable to work also with GNU groff (with BSD or GNU mdoc), and mdocml has also learnt to render them correctly.

Thorsten Glaser <mirabilos>
Mon 10 Apr 2023 05:15:21 PM UTC, comment #7: 

Not yet; I am hoping Bertrand will have some RC4 work for me today.

Also, I'm not settled yet on these register names.

I don't expect this change to become available until 1.23.1 or 1.24, whichever we have.

G. Branden Robinson <gbranden>
Group administrator
Mon 10 Apr 2023 02:47:22 PM UTC, comment #6: 

LGTM.

Do you have something to test in a branch?

Alejandro Colomar <alx>
Mon 10 Apr 2023 01:59:20 AM UTC, comment #5: 

To summarize, this ticket contemplates two new registers for man(7), and restricted meaning for the `IN` register, first exposed/documented by Documenter's Workbench (DWB) 1.0 in 1984.

  • BP: base paragraph indentation configures how far the left margin of a normal paragraph is inset from the page offset (which is 0 on terminals) when no relative insets are active.
  • IN: the "standard indentation" would now configure only the default indentation increment used for relative inset.
  • TS: the "tag spacing" configures the size the of the gap that is required after a paragraph tag.  Effectively, this amount is added to the width of the diversion created by the `IP` and `TP` macros to format the tag.  If that amount is greater than the standard indentation, a break is emitted and the remainder of the paragraph is formatted starting on a new output line, indented by the `IN` increment.


Presently, groff man(7) acts as if BP=IN=7n (7.2n on typesetters), and TS is 1n.

For consistent rendering of mdoc(7) pages, these parameters (if set) would be honored by that macro package too, as `SN` and `IN` already are, where comparable macro semantics permit.

G. Branden Robinson <gbranden>
Group administrator
Mon 10 Apr 2023 01:45:45 AM UTC, comment #4: 


comment #3:

> I see no reason why the standard indentation of running text from the left margin of the paper and the default indentation inside a tagged paragraph need to be related in any way.  In fact, in 1990 Kernighan troff, the former was \n(IN and the latter was \n()I.  Both happened to be .5i, but they could be contolled independently of each other.


...if you knew about them, yes.  :)  We see the same use in my exhibits from SunOS 4.
 

> As another example, in mdoc(7), the default indentation inside tagged lists is 8n - 6n for the tag itself and an additional 2n for spacing, exactly as suggested by Alejandro.


The congruence of measurements here may not be a coincidence, but a bit of convergent evolution.

> Would anything be wrong with restoring the indentation of running text from the left margin from 7n to again be 5n but at the same time leaving anything that happens inside the document content, i.e. to the right of those 7n or 5n of global indentation, completely unchanged?


Not that I can see.  I don't mind adding exposing another configurable register for this, splitting the present semantics of `IN`.  Maybe `BP` or `PI` to suggest "base paragraph indentation".

I'd need another register anyway to make the post-tag spacing configurable anyway, and told Alex I'd look into it after 1.23.0 final.  Adding him to CC.

G. Branden Robinson <gbranden>
Group administrator
Mon 10 Apr 2023 12:41:51 AM UTC, comment #3: 

I see no reason why the standard indentation of running text from the left margin of the paper and the default indentation inside a tagged paragraph need to be related in any way.  In fact, in 1990 Kernighan troff, the former was \n(IN and the latter was \n()I.  Both happened to be .5i, but they could be contolled independently of each other.

As another example, in mdoc(7), the default indentation inside tagged lists is 8n - 6n for the tag itself and an additional 2n for spacing, exactly as suggested by Alejandro.

Would anything be wrong with restoring the indentation of running text from the left margin from 7n to again be 5n but at the same time leaving anything that happens inside the document content, i.e. to the right of those 7n or 5n of global indentation, completely unchanged?

Ingo Schwarze <schwarze>
Group Member
Sun 09 Apr 2023 11:22:04 PM UTC, comment #2: 

comment #1:

> The setting ".nr IN 7.2n" is present since the beginning of the groff repository, i.e. groff-1.06, Sep 1 12:28:08 1992, file tmac/tmac.an .

[...]

> Consequently, it is almost certain that it was James Clark who changed from 5n to 7n during the very early stages of groff development, and definitely earlier than the 1.01 release.  In the CHANGES and ChangeLog files contained in groff-1.01, i see no explanation of why he made the change.
>
> I also consider it likely that AT&T troff never moved away from the 5n default.  For example, UNIX v10 (1988) contains:
>
> https://minnie.tuhs.org/cgi-bin/utree.pl?file=V10/man/man0/tmac.v10


> .if n .nr )M 5n
> .nr IN \\n()Mu

[...]

> To summarize, it was likely James Clark who changed the indentation without so much as providing a rationale, at least not one that survives to this day, while it is mdoc(7) that upholds the original UNIX tradition in this respect.


Thanks for digging into this.

I can rule out my SunOS hypothesis, too.  The tape archives I have for SunOS 4.0 similarly use half-inch indentation.

(The output below is abbreviated.)


.\"     @(#)tmac.an 1.35 88/03/05 SMI;
.ds ]W Sun Release 4.0
'       # month name

'       # reset the basic page layout
.de }E
.}f
.in \\n()Ru+\\n(INu
.ll \\n(LLu
..

'       # set title and heading
.de TH
.PD
.DT
.if n .nr IN .5i
.if t .nr IN .5i
.if t .po .588i
.ll 6.5i
.nr LL \\n(.l

'       # hanging indent
.de HP
.sp \\n()Pu
.ne 2
.if !"\\$1"" .nr )I \\$1n
.ll \\n(LLu
.in \\n()Ru+\\n(INu+\\n()Iu
.ti \\n()Ru+\\n(INu
.}f
..

'       # end of TP (cf }N below)
.de }1
.ds ]X \&\\*(]B\\
.nr )E 0
.if !"\\$1"" .nr )I \\$1n
.}f
.ll \\n(LLu
.in \\n()Ru+\\n(INu+\\n()Iu
.ti \\n(INu
.ie !\\n()Iu+\\n()Ru-\w^G\\*(]X^Gu-3p \{\\*(]X
.br\}
.el \\*(]X\h^G|\\n()Iu+\\n()Ru^G\c
.}f
..


The only rationale for the 7n/7.2n indentation I'm aware of is that because it's the "standard indentation", it's also used as a default for the `TP` macro, which is frequently used.

And if you want to set a command line option with argument, 5n is a little bit too tight.  For instance,


-a arg


...won't fit on a terminal (because you need 1n of space after the tag for the remainder of the paragraph to be set on the same line).  And as I recall, Alex Colomar has lobbied for 2n of tag separation instead of 1.

Let's take it to the list and see if any of the professional typographers there have a case for groff's status quo--the half of it in man(7), at any rate.

An experiment I may undertake is to change the standard indentation to 5n in my working copy and see how that changes the page count of groff-man-pages.pdf.  If it gets longer (due to many more line breaks forced by the tighter space for paragraph tags), the economy of 5n may be a false one.

G. Branden Robinson <gbranden>
Group administrator
Sun 09 Apr 2023 10:02:50 PM UTC, comment #1: 

The setting ".nr IN 7.2n" is present since the beginning of the groff repository, i.e. groff-1.06, Sep 1 12:28:08 1992, file tmac/tmac.an .

The groff-1.01 released by James Clark on Mar 13 12:49:40 1991 and declared as a "beta-test version" that is contained in 4.3BSD-Net/2 (Aug 20, 1991) also contains ".nr IN 7.2n".

The 4.3BSD-Reno release (June 1990) does not yet contain groff (possibly because groff did not yet exist in June 1990, not even as a beta release - Wikipedia claims the first groff release was 0.3.1 in June 1990, without specifying a source) and still uses Kernighan's non-free device independent troff, licensed from AT&T.  It contains ".nr IN .5i" in the man macro set.

Consequently, it is almost certain that it was James Clark who changed from 5n to 7n during the very early stages of groff development, and definitely earlier than the 1.01 release.  In the CHANGES and ChangeLog files contained in groff-1.01, i see no explanation of why he made the change.

I also consider it likely that AT&T troff never moved away from the 5n default.  For example, UNIX v10 (1988) contains:

https://minnie.tuhs.org/cgi-bin/utree.pl?file=V10/man/man0/tmac.v10

.if n .nr )M 5n
.nr IN \\n()Mu


I admit the following remains somewhat speculative unless we ask her, but it seems likely to me that Cynthia used the 5n default for mdoc(7) because she likely did not yet have access to groff when she started mdoc(7) development: Reno already contains mdoc(7) macros, but no groff yet.  She once told me that when she got access to groff, she liked it so much that she proposed to drop support for Kernighan's troff in manual pages, but that proposal was vetoed by other members of the CSRG, so the mdoc(7) macros remained compatible with both roff implementations until the CSRG disbanded in 1995.

To summarize, it was likely James Clark who changed the indentation without so much as providing a rationale, at least not one that survives to this day, while it is mdoc(7) that upholds the original UNIX tradition in this respect.

Ingo Schwarze <schwarze>
Group Member
Sun 09 Apr 2023 08:24:42 PM UTC, original submission:  

Ingo passionately feels that 5n should be it; see bug #63958.

He claims that groff's long-standing default of 7n (on terminal devices; the default is 7.2n on typesetting devices) "objectively wastes too much real estate".

I don't know what Ayn Rand novel this "objective" standard came from.  It's like how Beethoven had an objectively dark and incorrect sense-of-life, unlike the composers of Viennese waltzes!

> That is emphatically a subjective, not an objective, assessment.  Confusing these two is not a good way to build a convincing argument with me.


> How does one measure the waste of screen real estate?  By counting empty character cells in a terminal window?  On how large a terminal window?  With or without adjustment?  With or without hyphenation?  If adjustment is enabled, do only empty character cells outside the paragraph margins count as wasted?  Most importantly, what percentage of empty character cells constitutes the threshold of waste, and how is that percentage "objectively" arrived at?  If a percentage is not used as the metric of screen real estate wastage, what is, where is it documented, and how is anyone else to have known of this "objective" metric?


> I see that I need to look up when and why groff changed to 7n/7.2n for man(7).  Who knows?  Maybe it was a SunOS change that groff copied back in 1989 without making a lot of noise about it, like the the `SB` macro and registers C, D, P, and X.


> So I'll [put this into] status "Need Info" again as a homework assignment for myself.


I'll report back here.

G. Branden Robinson <gbranden>
Group administrator

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by barx (Posted a comment)
  • -email is unavailable- added by mirabilos (Posted a comment)
  • -email is unavailable- added by alx (Posted a comment)
  • -email is unavailable- added by gbranden (regarding configuration of post-tag horizontal space in man(7))
  • -email is unavailable- added by schwarze (Posted a comment)
  • -email is unavailable- added by gbranden (Submitted the item)
  • -email is unavailable- added by gbranden (original reporter)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 8 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2023-08-10 gbranden Item GroupRendering/Cosmetics Feature change
        StatusIn Progress Fixed
        Open/ClosedOpen Closed
    2023-08-09 gbranden StatusConfirmed In Progress
        Planned ReleaseNone 1.24.0
    2023-08-06 gbranden StatusNeed Info Confirmed
    2023-04-10 gbranden Carbon-Copy- Added -email is unavailable-
    2023-04-09 gbranden Carbon-Copy- Added -email is unavailable-

    Back to the top

    Powered by Savane 3.13-e652.
    Corresponding source code