Skip to content

Commit

Permalink
Don't output a newline after .SH
Browse files Browse the repository at this point in the history
On macOS, `makewhatis` fails to parse `NAME` headings in man pages if
there's a newline between `.SH` and `NAME`. This is silly, but I can't
exactly get them to update it:

```
$ /usr/libexec/makewhatis -v -o /tmp/whatis outputs/out/share/man | head
man directory outputs/out/share/man
  outputs/out/share/man/man5
        reading outputs/out/share/man/man5/nix.conf.5
        ignoring junk description ""
        reading outputs/out/share/man/man5/nix-profiles.5
        ignoring junk description ""
```

Through a circuitous sequence of events, this results in shell
completions for the `man` command being broken in Fish for man pages
generated with Lowdown:
https://git.lix.systems/lix-project/lix/issues/515

This patch, then, replaces the trailing newline after blocks with a
trailing space for `.SH` blocks which only contain normal text in
`nroff` output.

The restriction that `.SH` blocks only contain normal text is because
(for example) this doesn't render correctly:

```
.SH a \fIhttps://foo.com\fR now \fBworld\fR <\fIhttps://bar.com\fR> b
```
  • Loading branch information
9999years committed Sep 12, 2024
1 parent 1200b9f commit e05929a
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 16 deletions.
29 changes: 25 additions & 4 deletions nroff.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ struct bnode {
unsigned int colour; /* if BNODE_COLOUR */
#define BFONT_BLUE 0x01
#define BFONT_RED 0x02
int trailingspace; /* BSCOPE_BLOCK .SH */
TAILQ_ENTRY(bnode) entries;
};

Expand Down Expand Up @@ -369,6 +370,7 @@ bqueue_flush(const struct nroff *st, struct lowdown_buf *ob,
const struct bnode *bn, *chk, *next;
const char *cp;
int nextblk;
char trailingchar;

TAILQ_FOREACH(bn, bq, entries) {
nextblk = 0;
Expand Down Expand Up @@ -515,11 +517,11 @@ bqueue_flush(const struct nroff *st, struct lowdown_buf *ob,
return 0;
}

/* Finally, trailing newline. */

/* Finally, trailing newline/space. */
trailingchar = bn->trailingspace ? ' ' : '\n';
if (nextblk && ob->size > 0 &&
ob->data[ob->size - 1] != '\n' &&
!hbuf_putc(ob, '\n'))
ob->data[ob->size - 1] != trailingchar &&
!hbuf_putc(ob, trailingchar))
return 0;
}

Expand Down Expand Up @@ -840,6 +842,7 @@ rndr_header(struct nroff *st, struct bnodeq *obq,
struct lowdown_buf *buf = NULL;
const struct lowdown_buf *nbuf;
int rc = 0;
const struct lowdown_node *child = NULL;

level = (ssize_t)n->rndr_header.level + st->headers_offs;
if (level < 1)
Expand All @@ -857,6 +860,24 @@ rndr_header(struct nroff *st, struct bnodeq *obq,
bqueue_block(obq, ".SS");
if (bn == NULL)
return 0;

if (level == 1
&& (child = TAILQ_FIRST(&n->children))
&& !TAILQ_NEXT(child, entries)) {
/* This is a first-level header and there is exactly one child.
*
* If the child is a `LOWDOWN_NORMAL_TEXT`, put
* a single space between the `.SH` and the
* heading instead of a newline.
*
* This renders headers as (e.g.) `.SH
* SYNOPSIS` instead of `.SH\nSYNOPSIS`, which
* is important for macOS `makewhatis`.
*
* See: https://github.com/kristapsdz/lowdown/pull/138
*/
bn->trailingspace = child->type == LOWDOWN_NORMAL_TEXT;
}
TAILQ_CONCAT(obq, bq, entries);
st->post_para = 1;
return 1;
Expand Down
3 changes: 1 addition & 2 deletions regress/diff/metadata-add.man
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.\" -*- mode: troff; coding: utf-8 -*-
.TH "" "7" ""
.SH
section
.SH section
.LP
body
3 changes: 1 addition & 2 deletions regress/diff/metadata-remove.man
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.\" -*- mode: troff; coding: utf-8 -*-
.TH "" "7" ""
.SH
section
.SH section
.LP
body
6 changes: 2 additions & 4 deletions regress/shift-heading-level-by-neg.man
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
.SH
header 1
.SH header 1
.LP
1
.SH
header 2
.SH header 2
.LP
2
.SS
Expand Down
3 changes: 1 addition & 2 deletions regress/shift-heading-level-by-zero.man
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.SH
header 1
.SH header 1
.LP
1
.SS
Expand Down
3 changes: 1 addition & 2 deletions regress/simple.man
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.SH
An h1 header
.SH An h1 header
.LP
Paragraphs are separated by a blank line.
.PP
Expand Down

0 comments on commit e05929a

Please sign in to comment.