help / color / mirror / Atom feed
From: Ingo Schwarze <>
To: Kristaps Dzonsons <>
Subject: Re: ".TS H" macro
Date: Sun, 28 Mar 2021 20:46:03 +0200	[thread overview]
Message-ID: <> (raw)
In-Reply-To: <>

Hi Kristaps,

Kristaps Dzonsons wrote on Sun, Mar 28, 2021 at 01:30:41PM +0200:

> On second glance, this is only supported by the -ms parser in groff(1) 
> and tables with groff's -man don't support the `.TS H` invocation:
> % groff -tk -man -Tpdf  >/dev/null
> error: page 2: table will not fit on one page; use .TS H/.TH with a 
> supporting macro package

Indeed, i agree with your assessment.  ".TS H" is groff_ms(7) syntax
and invalid in groff_man(7) and hence in man(7).

Here is the result of running your sample file (without the "expand"
table option that groff uses but mandoc ignores) through gmdiff:

   $ gmdiff         
   ========== ========== 
  mandoc: WARNING: missing manual title, using "": TH
  mandoc: WARNING: missing manual section, using "": TH 
  mandoc: WARNING: missing date, using "": TH
  mandoc: STYLE: RCS id missing: (OpenBSD)
  mandoc: see above the output for WARNING messages
  --- /tmp/roff.out       Sun Mar 28 20:09:57 2021
  +++ /tmp/mandoc.out     Sun Mar 28 20:09:57 2021
  @@ -1,17 +1,11 @@
  -UNTITLED(7)       Miscellaneous Information Manual       UNTITLED(7)
  +()                                                                ()
   |app | quality |
  -|    |         |
  -|    |         |
  -|    |         |
  -()   |         |                                                  ()
  -|    |         |
  -|    |         |
  -|    |         |
   |foo | bar     |

So the differences are as follows:

 1. Groff prints the page header line as soon as it sees the first .TH.
    As you wisely decided, mandoc parses first and only starts rendering
    when the parsing is complete.  Hence the difference in the first line
    of output.

 2. *Both* groff and mandoc treat the second .TH as a man(7) .TH macro,
    not as a tbl(7) instruction (we probably shouldn't call tbl(7)
    features line "T{" and ".TH" "macros" because processing of tbl(7)
    and eqn(7) input differs substantially from normal roff(7) processing).
    But both treat this second man(7) .TH macro differently.  Groff goes
    ahead an prints a second header, surrounded by the usual three blank
    lines, overlapping the table.  Mandoc just collects the information,
    leaving the table undisturbed.

> So this shouldn't affect mandoc because it doesn't accept -ms and thus 
> the `.TS H` shouldn't be used.


> Sorry for the noise!

I don't deny your first shot went slightly astray, but it wasn't all
noise.  Consider the following test document:

  .TH ONE 1 2001-01-01
  .TH TWO 2 2002-02-02
  name \- name

Groff prints both headers, which is hardly useful and not a worthy target
for making mandoc(1) bug-compatible.  But mandoc(1) silently ignores the
first header and only prints the second header.

Using the second rather than the first contradicts man(7) documentation:

     Each man document starts with the TH macro specifying the document's
     name and section, ...

It also contadicts groff_man(7) documentation:

     A man page should contain exactly one .TH call at or near the
     beginning of the file, prior to any other macro calls.

So both manuals prefer seeing the first .TH win, not the last one.

Hence, your patch isn't completely wrong.  But even more important than
fixing which macro wins is emitting an ERROR level diagnostic when
encountering more than one .TH macro in the same document.

So i added a TODO entry:

  - report double .TH in man(7) as an ERROR and let the first win
    kristaps@  28 Mar 2021 13:30:41 +0200
    loc *  exist *  algo *  size *  imp *

 To unsubscribe send an email to

      reply	other threads:[~2021-03-28 18:46 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-28 11:23 Kristaps Dzonsons
2021-03-28 11:30 ` Kristaps Dzonsons
2021-03-28 18:46   ` Ingo Schwarze [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \ \ \ \ \
    --subject='Re: ".TS H" macro' \

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).