Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't output a newline between .SH and heading text for nroff #138

Merged
merged 1 commit into from
Sep 15, 2024

Conversation

9999years
Copy link
Contributor

@9999years 9999years commented Sep 11, 2024

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 in nroff output.

@kristapsdz
Copy link
Owner

kristapsdz commented Sep 11, 2024

Thank you for looking in to this! I'll look over it closely in the coming days... did it run thru all regressions?

@9999years
Copy link
Contributor Author

did it run thru all regressions?

Ah, no, thanks for the reminder. In particular, this seems to render incorrectly:

--- regress/header-with-links.man       2024-09-10 17:05:08.982373613 -0700
+++ /var/folders/z5/fclwwdms3r1gq4k4p3pkvvc00000gn/T/tmp.YBOJG0uKmv     2024-09-11 09:47:03.831861466 -0700
@@ -1,4 +1,3 @@
-.SH
-a \fIhttps://foo.com\fR now \fBworld\fR <\fIhttps://bar.com\fR> b
+.SH a \fIhttps://foo.com\fR now \fBworld\fR <\fIhttps://bar.com\fR> b
 .LP
 c

And this isn't supposed to happen:

--- regress/diff/metadata-keep.man      2024-09-10 17:05:08.977468465 -0700
+++ /var/folders/z5/fclwwdms3r1gq4k4p3pkvvc00000gn/T/tmp.YBOJG0uKmv     2024-09-11 09:47:05.030526226 -0700
@@ -1,10 +1,7 @@
 .\" -*- mode: troff; coding: utf-8 -*-
 .TH "" "7" ""
 .PP
-.gcolor blue
-shmext
+.gcolor blue shmext
 .gcolor black
-.gcolor red
-text
-.gcolor black
-here
+.gcolor red text
+.gcolor black  here

@9999years 9999years marked this pull request as draft September 11, 2024 23:58
@9999years
Copy link
Contributor Author

9999years commented Sep 12, 2024

I think this will need a slight restructuring to only apply this logic when a LOWDOWN_HEADER node is level 1 and has exactly one child LOWDOWN_NORMAL_TEXT node. I've marked it as a draft for now.

@9999years 9999years marked this pull request as ready for review September 12, 2024 18:32
@9999years
Copy link
Contributor Author

OK, I've fixed up the patch!

  • The newline after a .SH will be omitted only if the heading has exactly one LOWDOWN_NORMAL_TEXT child node. This is enough to fix my bug without breaking rendering for output with links.
  • The implementation adds an int field to the bnode struct instead of a local variable in bqueue_flush.
  • The regression tests pass with the new patchset!

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
```
@kristapsdz
Copy link
Owner

Awesome how Mac OS X now uses mandoc to format manpages yet still uses some ancient craptastic makewhatis/apropos that has this bug (not respecting how SH can have its arguments on the next line). As a side note, being still involved in mandoc, can you guess how much Apple, a multi-trillion dollar corporation, contributed back into mandoc? You get one guess. Here's a hint. It's zero.

@kristapsdz kristapsdz merged commit fdef5af into kristapsdz:master Sep 15, 2024
kristapsdz added a commit that referenced this pull request Sep 15, 2024
This allows any content under an SH that is either normal text
or entities to be serialised on the same line as SH instead of
the subsequent line.

Properly call this "headerhack" to point out that this is not
because of lowdown or man(7), but other buggy software.

References #138
@9999years 9999years deleted the no-newline-after-sh branch September 15, 2024 23:21
@9999years
Copy link
Contributor Author

Yeah, I'm not surprised. Very frustrating!

sternenseemann pushed a commit to NixOS/nixpkgs that referenced this pull request Sep 16, 2024
- Improve UTF-8 handling by not treating bytes >=0x80, which tend to be
  UTF-8 continuation bytes, as control characters.

  This leaves control characters U+0080 through U+009F in the output
  (incorrectly) but doesn't mangle other UTF-8 characters, so it's a net
  win.

  See: kristapsdz/lowdown#140

- Don't output a newline between a `.SH` and a heading.

  This fixes `makewhatis` output on macOS and (as a result) `man`
  completions for `fish` on macOS.

  See: kristapsdz/lowdown#138
github-actions bot pushed a commit to NixOS/nixpkgs that referenced this pull request Sep 19, 2024
- Improve UTF-8 handling by not treating bytes >=0x80, which tend to be
  UTF-8 continuation bytes, as control characters.

  This leaves control characters U+0080 through U+009F in the output
  (incorrectly) but doesn't mangle other UTF-8 characters, so it's a net
  win.

  See: kristapsdz/lowdown#140

- Don't output a newline between a `.SH` and a heading.

  This fixes `makewhatis` output on macOS and (as a result) `man`
  completions for `fish` on macOS.

  See: kristapsdz/lowdown#138

(cherry picked from commit 7784c97)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants