gbranden pushed a commit to branch master in repository groff. commit 0d5a8fe5db117f3392fa74cb4c228db79c05443f Author: G. Branden Robinson <g.branden.robin...@gmail.com> AuthorDate: Tue Jul 15 22:35:05 2025 -0500
[man]: Fix Savannah #67363 (1/4). Make man page rendering more robust against meddling with the hyphenation mode by individual pages. In part this is to ensure that meddling doesn't persist outside the meddlesome document when rendering multiple pages, but it also makes user preferences more reliably discernible. Prompted by a discussion (about adjustment) with Russ Allbery in late 2023. * tmac/an.tmac ([initialization]): When rendering a man page, this macro file is read before any man(7) document: track man/mdoc initialization status in new register `andoc*is-initialized`. When initializing, if the `HY` register is set, we know it was specified on the command line or by the "man.local" file. Stash its value in new register `andoc*HY` so it can be recovered after meddling by the document. (an*reset-hyphenation-mode): Accept an argument, and if valid, assign its value to the `HY` register. (TH): Remove the potentially page-local `HY` register when starting a new document, and call `an*reset-hyphenation-mode` interpolating `andoc*HY` as an argument to impose the user's preference (or the package default) at each new document. * tmac/tests/an_hyphenation-mode-restoration-works.sh: Add test to verify preservation of document- and user-selected hyphenation mode. * tmac/tmac.am (tmac_TESTS): Run test. Fixes <https://savannah.gnu.org/bugs/?67363> (1/4). Thanks to Russ Allbery for posing the challenge. --- ChangeLog | 31 ++++++++ tmac/an.tmac | 35 +++++--- .../tests/an_hyphenation-mode-restoration-works.sh | 92 ++++++++++++++++++++++ tmac/tmac.am | 1 + 4 files changed, 147 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4558fdd24..f48f133ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2025-07-27 G. Branden Robinson <g.branden.robin...@gmail.com> + + [man]: Make man page rendering more robust against meddling with + the hyphenation mode by individual pages. In part this is to + ensure that meddling doesn't persist outside the meddlesome + document when rendering multiple pages, but it also makes user + preferences more reliably discernible. Prompted by a discussion + {about adjustment} with Russ Allbery in late 2023. + + * tmac/an.tmac ([initialization]): When rendering a man page, + this macro file is read before any man(7) document: track + man/mdoc initialization status in new register + `andoc*is-initialized`. When initializing, if the `HY` register + is set, we know it was specified on the command line or by the + "man.local" file. Stash its value in new register `andoc*HY` so + it can be recovered after meddling by the document. + (an*reset-hyphenation-mode): Accept an argument, and if valid, + assign its value to the `HY` register. + (TH): Remove the potentially page-local `HY` register when + starting a new document, and call `an*reset-hyphenation-mode` + interpolating `andoc*HY` as an argument to impose the user's + preference (or the package default) at each new document. + + * tmac/tests/an_hyphenation-mode-restoration-works.sh: Add test + to verify preservation of document- and user-selected + hyphenation mode. + * tmac/tmac.am (tmac_TESTS): Run test. + + Fixes <https://savannah.gnu.org/bugs/?67363> (1/4). Thanks to + Russ Allbery for posing the challenge. + 2025-07-30 G. Branden Robinson <g.branden.robin...@gmail.com> * src/preproc/html/pre-html.cpp (get_resolution) diff --git a/tmac/an.tmac b/tmac/an.tmac index 89cbbfe90..d85f0458b 100644 --- a/tmac/an.tmac +++ b/tmac/an.tmac @@ -152,25 +152,26 @@ . vs \\n[VS]u .. . -.\" Resetting the hyphenation mode is a complicated dance because: +.\" Resetting the hyphenation mode is a complicated dance. .\" 1. Man pages sometimes disable automatic hyphenation--when they -.\" do, they nearly always forget to put it back the way it was; -.\" 2. in AT&T troff there was no register exposing the hyphenation +.\" do, they nearly always forget to put it back the way it was. +.\" 2. In AT&T troff there was no register exposing the hyphenation .\" mode (nor the enablement status of automatic hyphenation), so -.\" no idioms for performing such restoration have arisen; -.\" 3. groff man(7)'s `HY` register isn't supported everywhere; -.\" 4. we want user preferences, if expressed, to override the page -.\" author's; and -.\" 5. even if we didn't want (4), one page author's can override +.\" no idioms for performing such restoration have arisen. +.\" 3. groff man(7)'s `HY` register isn't supported everywhere. +.\" 4. We want user preferences, if expressed, to override the page +.\" author's. +.\" 5. Even if we didn't want (4), one page author's can override .\" another's when formatting multiple man(7) documents in .\" sequence--we thus keep track of the initial hyphenation mode. .\" .\" So we recover the "page's" preferred hyphenation mode, if expressed .\" via `HY`, at every paragraph (and (sub)sectioning macro call; and -.\" recover the user's preferred hyphenation mode at each new document. -.\" +.\" recover the user's preferred hyphenation mode at each new document +.\" by accepting it as an argument (see the `TH` macro definition). .\" Also see the initialization logic below. .de an*reset-hyphenation-mode +. if \\n[.$] .if \B'\\$1' .nr HY \\$1 . nr an*want-hyphenation 1 . if r HY .if !\\n[HY] .nr an*want-hyphenation 0 . ie \\n[an*want-hyphenation] \ @@ -307,6 +308,11 @@ . rr TW . nr an-was-tbl-failure-reported 0 . +. \" When rendering multiple documents, we want to clear any page-local +. \" manipulation of hyphenation mode from the previous document. +. rr HY +. +. an*reset-hyphenation-mode \\n[andoc*HY] . an*reset-section-parameters . an*reset-paragraph-parameters . ll \\n[LL]u @@ -1468,6 +1474,13 @@ contains unsupported escape sequence .ie d msoquiet .msoquiet man.local .el .mso man.local . +.\" Save `HY` value configured by {man,mdoc}.local or command line. +.if !r andoc*is-initialized \{\ +. ie r HY .nr andoc*HY \n[HY] +. el .nr andoc*HY 1 +. nr andoc*is-initialized 1 +.\} +. .\" Set each rendering parameter only if its -[dr] option or man.local .\" did not. . @@ -1563,8 +1576,6 @@ contains unsupported escape sequence . \} .\} . -.\" We handle `HY` in `an*reset-hyphenation-mode`, not here. -. .\" standard indentation .if !r IN \{\ . \" We select an integer indentation value in nroff mode because this diff --git a/tmac/tests/an_hyphenation-mode-restoration-works.sh b/tmac/tests/an_hyphenation-mode-restoration-works.sh new file mode 100755 index 000000000..6ea7b3846 --- /dev/null +++ b/tmac/tests/an_hyphenation-mode-restoration-works.sh @@ -0,0 +1,92 @@ +#!/bin/sh +# +# Copyright (C) 2025 Free Software Foundation, Inc. +# +# This file is part of groff. +# +# groff is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# groff is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail() { + echo ...FAILED >&2 + fail=yes +} + +input='. +.TH foo 1 2025-07-15 "groff test suite" +.nr HY 0 +.SH Name +foo \- a command with a very short name +.SH Description +This paragraph should not be hyphenated. +Sed ut perspiciatis, unde omnis iste natus error sit voluptatem +accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab +illo inventore veritatis et quasi architecto beatae vitae dicta sunt, +explicabo. +.P +This paragraph should also not be hyphenated. +Ut enim ad minima veniam, quis nostrum exercitationem ullam +corporis suscipitlaboriosam suscipitlaboriosam suscipitlaboriosam, +nisi ut aliquid ex ea commodi consequatur? +.TH bar 1 2025-07-15 "groff test suite" +.SH Name +bar \- another command with a very short name +.SH Description +This paragraph should be hyphenated. +Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur +aut odit aut fugit, sed quia consequuntur magni dolores eos, qui ratione +voluptatem sequi nesciunt, neque porro quisquam est, qui dolorem ipsum, +quia dolor sit amet consectetur adipiscivelit, sed quia non-numquam eius +modi tempora incidunt, ut labore et dolore magnam aliquam quaerat +voluptatem. +.nr HY 1 \" attempt to meddle with next document +.TH baz 1 2025-07-27 "groff test suite" +baz \- you guessed it +.SH Description +This paragraph should not be hyphenated. +Quis autem vel eum iure reprehenderit, qui inea voluptate velit esse, +quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat, quo +voluptas nulla pariatur? +.' + +# A line length of 78n avoids adjustment on the hyphenated line. +output=$(printf "%s\n" "$input" \ + | "$groff" -rLL=78n -man -T ascii -P -cbou) +echo "$output" + +echo "checking that the first document's first paragraph is not" \ + "hyphenated" >&2 +echo "$output" | grep -q 'veritatis *et *quasi$' || wail + +echo "checking that the first document's second paragraph is not" \ + "hyphenated" >&2 +echo "$output" | grep -q 'ullam *corporis *suscipitlaboriosam' || wail + +echo "checking that the second document's paragraph is hyphenated" >&2 +echo "$output" | grep -q 'ut labore et dolore mag-' || wail + +output=$(printf "%s\n" "$input" \ + | "$groff" -rHY=0 -rLL=78n -man -T ascii -P -cbou) +echo "$output" + +echo "checking that the third document's paragraph is not hyphenated" \ + "when disabled by user" >&2 +echo "$output" | grep -q 'autem *vel *eum *iure' || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/tmac/tmac.am b/tmac/tmac.am index bfafa1985..4d0482e10 100644 --- a/tmac/tmac.am +++ b/tmac/tmac.am @@ -169,6 +169,7 @@ tmac_TESTS = \ tmac/tests/an_do-not-abbreviate-escape-using-TH-arguments.sh \ tmac/tests/an_font-remapping-does-not-affect-titles.sh \ tmac/tests/an_handle-degenerate-input-quietly.sh \ + tmac/tests/an_hyphenation-mode-restoration-works.sh \ tmac/tests/an_inner-footer-abbreviation-works.sh \ tmac/tests/an_link-macros-work-in-paragraph-tags.sh \ tmac/tests/an_link-trailing-text-hugs-previous.sh \ _______________________________________________ groff-commit mailing list groff-commit@gnu.org https://lists.gnu.org/mailman/listinfo/groff-commit