gbranden pushed a commit to branch master
in repository groff.
commit 89373c759bd3ede5c270b0e06e907836422d1993
Author: G. Branden Robinson <[email protected]>
AuthorDate: Sun Apr 12 06:38:34 2026 -0500
[troff]: Fix Savannah #68205 (args to `phw` req).
The `phw` request now accepts arguments. Each is interpreted as a
possible hyphenation word, ignoring hyphens in the input, looked up in
the hyphenation exception list for the hyphenation language, and if
found, is reported with its hyphenation points. Only hyphenation
exceptions defined by the `hw` request are reported.
* src/roff/troff/env.cpp (print_hyphenation_exceptions_request):
Implement it.
* src/roff/groff/tests/phw-request-works.sh: Test it.
* src/roff/groff/groff.am (groff_TESTS): Run test.
* doc/groff.texi.in (Debugging):
* man/groff.7.man (Request short reference):
* man/groff_diff.7.man (New requests):
* NEWS: Document it.
Fixes <https://savannah.gnu.org/bugs/?68205>.
---
ChangeLog | 22 ++++++++++++
NEWS | 6 ++++
doc/groff.texi.in | 13 ++++++-
man/groff.7.man | 16 +++++++++
man/groff_diff.7.man | 15 +++++++-
src/roff/groff/groff.am | 1 +
src/roff/groff/tests/phw-request-works.sh | 58 +++++++++++++++++++++++++++++++
src/roff/troff/env.cpp | 42 +++++++++++++++++++++-
8 files changed, 170 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c246fdb3b..aa6addd0a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2026-04-12 G. Branden Robinson <[email protected]>
+
+ [troff]: The `phw` request now accepts arguments. Each is
+ interpreted as a possible hyphenation word, ignoring hyphens in
+ the input, looked up in the hyphenation exception list for the
+ hyphenation language, and if found, is reported with its
+ hyphenation points. Only hyphenation exceptions defined by the
+ `hw` request are reported.
+
+ * src/roff/troff/env.cpp (print_hyphenation_exceptions_request):
+ Implement it.
+
+ * src/roff/groff/tests/phw-request-works.sh: Test it.
+ * src/roff/groff/groff.am (groff_TESTS): Run test.
+
+ * doc/groff.texi.in (Debugging):
+ * man/groff.7.man (Request short reference):
+ * man/groff_diff.7.man (New requests):
+ * NEWS: Document it.
+
+ Fixes <https://savannah.gnu.org/bugs/?68205>.
+
2026-04-12 G. Branden Robinson <[email protected]>
* src/roff/troff/env.cpp (print_hyphenation_exceptions):
diff --git a/NEWS b/NEWS
index 1ab709182..1346fc271 100644
--- a/NEWS
+++ b/NEWS
@@ -43,6 +43,12 @@ troff
the request (and issues a warning in category "range"), leaving the
operand (first request argument) unchanged instead of emptying it.
+* The `phw` request now accepts arguments. Each is interpreted as a
+ possible hyphenation word, ignoring hyphens in the input, looked
+ up in the hyphenation exception list for the hyphenation language,
+ and if found, is reported with its hyphenation points. Only
+ hyphenation exceptions defined by the `hw` request are reported.
+
* A new request, `rhw`, clears the current hyphenation language's list
of user-defined hyphenation exception words. Those supplied by files
like "tmac/hyphenex.{cs,en,pl}" are retained.
diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index c9a015bb0..7e58b486b 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -21537,18 +21537,29 @@ The ``from'' font identifier is listed first,
followed by its ``to'' translation.
@endDefreq
-@Defreq {phw, }
+@Defreq {phw, [@Var{word} @r{@dots{}}]}
@cindex dumping hyphenation exception words (@code{phw})
@cindex hyphenation exception words, dumping (@code{phw})
@cindex exception words, hyphenation, dumping (@code{phw})
Report,
to the standard error stream,
+the hyphenation points of each
+hyphenation exception word
+@var{word}
+defined by the
+@code{hw}
+request,
+or,
+without arguments,
the list of hyphenation exception words
associated with the hyphenation language
selected by the
@code{hla}
request;
recall @ref{Manipulating Hyphenation}.
+Hyphens in
+@var{word}
+are ignored.
A
@samp{-}
marks each hyphenation point.
diff --git a/man/groff.7.man b/man/groff.7.man
index f3a134497..e8075ba91 100644
--- a/man/groff.7.man
+++ b/man/groff.7.man
@@ -4636,6 +4636,22 @@ with a tab and asterisk
.
.
.TPx
+.REQ .phw "word \fR\&.\|.\|.\&\fP"
+Report,
+to the standard error stream,
+the hyphenation points of each
+hyphenation exception word
+.I word
+defined by the
+.B hw
+request.
+.
+Hyphens in
+.I word
+are ignored.
+.
+.
+.TPx
.REQ .pi command
Pipe GNU
.I troff \" GNU
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index 5c6f59a5c..8fa01c6e6 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -3970,15 +3970,28 @@ followed by its \[lq]to\[rq] translation.
.
.
.TP
-.B .phw
+.BR .phw \~[\c
+.IR word \~\&.\|.\|.]
Report,
to the standard error stream,
+the hyphenation points of each
+hyphenation exception word
+.I word
+defined by the
+.B hw
+request,
+or,
+without arguments,
the list of hyphenation exception words
associated with the hyphenation language
selected by the
.B hla
request.
.
+Hyphens in
+.I word
+are ignored.
+.
A
.RB \[lq] \- \[rq]
marks each hyphenation point.
diff --git a/src/roff/groff/groff.am b/src/roff/groff/groff.am
index 7b12a9276..a1e45e020 100644
--- a/src/roff/groff/groff.am
+++ b/src/roff/groff/groff.am
@@ -113,6 +113,7 @@ groff_TESTS = \
src/roff/groff/tests/pchar-request-works.sh \
src/roff/groff/tests/pdf-device-smoke-test.sh \
src/roff/groff/tests/phw-request-skips-line-if-no-hyph-lang.sh \
+ src/roff/groff/tests/phw-request-works.sh \
src/roff/groff/tests/pi-request-works.sh \
src/roff/groff/tests/po-request-works.sh \
src/roff/groff/tests/ps-device-smoke-test.sh \
diff --git a/src/roff/groff/tests/phw-request-works.sh
b/src/roff/groff/tests/phw-request-works.sh
new file mode 100755
index 000000000..0e3a74524
--- /dev/null
+++ b/src/roff/groff/tests/phw-request-works.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+#
+# Copyright 2026 G. Branden Robinson
+#
+# This file is part of groff, the GNU roff typesetting system.
+#
+# 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"
+ fail=yes
+}
+
+input='.
+.phw foobar
+.hw baz-qux
+.phw bazqux
+.hw tab-le qqq-xxx-zzz
+.phw t-a-b-l-e * qqqxxxzzz
+.'
+
+output=$(printf '%s\n' "$input" | "$groff" -W char 2>&1)
+echo "$output"
+
+# No exception word for 'foobar' is defined; expect no output.
+echo "checking report of hyphenation exception word 'foobar'" >&2
+echo "$output" | grep -qx "foo.*bar" && wail
+
+echo "checking report of hyphenation exception word 'bazqux'" >&2
+echo "$output" | grep -qx "baz-qux" || wail
+
+echo "checking report of hyphenation exception word 'table'" >&2
+echo "$output" | grep -qx "tab-le" || wail # deliberately incorrect
+
+echo "checking report of hyphenation exception word 'qqqxxxzzz'" >&2
+echo "$output" | grep -qx "qqq-xxx-zzz" || wail
+
+echo "checking for error indicator character" >&2
+echo "$output" | grep -qx "#" && wail
+
+test -z "$fail"
+
+# vim:set autoindent expandtab shiftwidth=4 tabstop=4 textwidth=72:
diff --git a/src/roff/troff/env.cpp b/src/roff/troff/env.cpp
index 1868c5bd1..5cefbdeef 100644
--- a/src/roff/troff/env.cpp
+++ b/src/roff/troff/env.cpp
@@ -4104,11 +4104,51 @@ static void print_hyphenation_exceptions_request() //
.phw
// Pathologically, we could have a hyphenation point after every
// character in a word except the last. The word may have a trailing
// space; see `hyphen_trie::read_patterns_file()`.
- // C++11: constexp
+ // C++11: constexpr
static const size_t bufsz = WORD_MAX * 2;
// C++03: char wordbuf[bufsz]();
char wordbuf[bufsz]; // We need to `errprint()` it, so not `unsigned`.
(void) memset(wordbuf, '\0', bufsz);
+ while (has_arg()) {
+ // C++11: constexp
+ static const size_t readbufsz = WORD_MAX;
+ // C++03: char readbuf[readbufsz]();
+ unsigned char readbuf[readbufsz];
+ if (read_hyphenation_exception_word(readbuf)) {
+ // See above regarding "slovenly typing" and Savannah #68230.
+ char *rbuf = reinterpret_cast<char *>(readbuf);
+ unsigned char *bp
+ = static_cast<unsigned char *>(
+ current_language->exceptions.lookup(rbuf));
+ if (bp != 0 /* nullptr */) {
+ size_t r = 0;
+ // Array indices are 0-based; breakpoints are 1-based, occurring
+ // after the nth letter of a word.
+ size_t w = 1;
+ unsigned char ch = readbuf[r++];
+ wordbuf[0] = '#'; // Make a screw-up more obvious.
+ while (ch != 0U) {
+ if (ch != '-') {
+ wordbuf[w] = ch;
+ if (r == *bp) {
+ wordbuf[++w] = '-';
+ bp++;
+ }
+ w++;
+ }
+ ch = readbuf[r++];
+ }
+ wordbuf[w] = '\0';
+ errprint("%1\n", &wordbuf[1]); // Don't print the initial '#'.
+ fflush(stderr);
+ assert(0U == *bp);
+ }
+ }
+ if (!has_arg()) {
+ skip_line();
+ return;
+ }
+ }
// We must use the nuclear `reinterpret_cast` operator because GNU
// troff's dictionary types use a pre-STL approach to containers.
while (iter.get(&entry, reinterpret_cast<void **>(&hypoint))) {
_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit