gbranden pushed a commit to branch master
in repository groff.

commit f21b40dafcb0f3b2165129b9eba3775ebd63b30f
Author: G. Branden Robinson <[email protected]>
AuthorDate: Thu Apr 16 10:46:49 2026 -0500

    [troff]: `rhw` request now accepts arguments.
    
    * src/roff/troff/env.cpp (remove_hyphenation_exception_words_request):
      Implement argument processing; each is normalized (hyphens are
      removed), looked up in the current hyphenation language's exception
      word dictionary, and deleted thence if present.
    
    * src/roff/groff/tests/rhw-request-works.sh: Test functionality.
    
    * doc/groff.texi.in (Manipulating Hyphenation):
    * man/groff.7.man (Request short reference):
    * man/groff_diff.7.man (New requests):
    * NEWS: Document it.
---
 ChangeLog                                 | 17 +++++++++++++++++
 NEWS                                      |  6 +++---
 doc/groff.texi.in                         | 13 ++++++++++---
 man/groff.7.man                           | 10 ++++++++++
 man/groff_diff.7.man                      | 15 ++++++++++++---
 src/roff/groff/tests/rhw-request-works.sh | 20 ++++++++++----------
 src/roff/troff/env.cpp                    | 23 ++++++++++++++++++++---
 7 files changed, 82 insertions(+), 22 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ad73937cf..6cdb91dba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2026-04-16  G. Branden Robinson <[email protected]>
+
+       * src/roff/troff/env.cpp
+       (remove_hyphenation_exception_words_request): Implement argument
+       processing; each is normalized (hyphens are removed), looked up
+       in the current hyphenation language's exception word dictionary,
+       and deleted thence if present.
+
+       * src/roff/groff/tests/rhw-request-works.sh: Test functionality.
+
+       * doc/groff.texi.in (Manipulating Hyphenation):
+       * man/groff.7.man (Request short reference):
+       * man/groff_diff.7.man (New requests):
+       * NEWS: Document it.
+
+       Fixes <https://savannah.gnu.org/bugs/?64478>.
+
 2026-04-16  G. Branden Robinson <[email protected]>
 
        [groff]: Unit-test `pnr` request.
diff --git a/NEWS b/NEWS
index 3739866af..af1db520d 100644
--- a/NEWS
+++ b/NEWS
@@ -56,9 +56,9 @@ troff
    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.
+*  A new request, `rhw`, removes user-defined hyphenation exception
+   words from the current hyphenation language's list thereof.  Those
+   supplied by files like "tmac/hyphenex.{cs,en,pl}" are retained.
 
 Macro packages
 --------------
diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index 80dacb8b7..9a26dd928 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -10273,12 +10273,19 @@ matching a hyphenation exception word defined with
 @code{hw}.
 
 @cindex hyphenation exception words, removing
-@Defreq {rhw}
-Empty the current hyphenation language's exception word list
-of all entries populated by the input.@footnote{GNU
+@Defreq {rhw, [@Var{word} @r{@dots{}}]}
+Remove each
+@var{word}
+from the current hyphenation language's exception word list
+or,
+without arguments,
+empty that list of all entries populated by the input.@footnote{GNU
 @command{troff} @c GNU
 retains those supplied by hyphenation pattern exception files;
 see below.}
+Hyphens in
+@var{word}
+are ignored.
 @endDefreq
 
 Situations also arise when only a specific occurrence of a word needs
diff --git a/man/groff.7.man b/man/groff.7.man
index 4feefb416..1b2d9b3dc 100644
--- a/man/groff.7.man
+++ b/man/groff.7.man
@@ -4872,6 +4872,16 @@ Empty the current hyphenation language's exception word 
list
 of all entries populated by the input.
 .
 .TPx
+.REQ .rhw "word \fR\&.\|.\|.\&\fP"
+Remove each
+.I word
+from the current hyphenation language's exception word list.
+.
+Hyphens in
+.I word
+are ignored.
+.
+.TPx
 .REQ .rj
 Break,
 right-align the output of the next productive input line without
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index 006a75ca4..5658fe49e 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -4255,9 +4255,18 @@ See
 .
 .
 .TP
-.B .rhw
-Empty the current hyphenation language's exception word list
-of all entries populated by the input.
+.BR .rhw \~[\c
+.IR word \~\&.\|.\|.]
+Remove each
+.I word
+from the current hyphenation language's exception word list
+or,
+without arguments,
+empty that list of all entries populated by the input.
+.
+Hyphens in
+.I word
+are ignored.
 .
 .
 .TP
diff --git a/src/roff/groff/tests/rhw-request-works.sh 
b/src/roff/groff/tests/rhw-request-works.sh
index 9d70c13d4..d59413988 100755
--- a/src/roff/groff/tests/rhw-request-works.sh
+++ b/src/roff/groff/tests/rhw-request-works.sh
@@ -37,16 +37,16 @@ output=$(printf '%s\n' "$input" | "$groff" 2>&1)
 echo "$output"
 echo "$output" | grep -Eqx "(baz-qux|kwy-ji-bo|sa-hu-agin)" && wail
 
-#input='.
-#.hw baz-qux kwy-ji-bo sa-hu-agin
-#.rhw kwyjibo
-#.phw
-#.'
-#
-#echo "checking operation of 'rhw' request without arguments"
-#output=$(printf '%s\n' "$input" | "$groff" 2>&1)
-#echo "$output"
-#echo "$output" | grep -qx "kwyjibo" || wail
+input='.
+.hw baz-qux kwy-ji-bo sa-hu-agin
+.rhw kwyjibo
+.phw
+.'
+
+echo "checking operation of 'rhw' request with arguments"
+output=$(printf '%s\n' "$input" | "$groff" 2>&1)
+echo "$output"
+echo "$output" | grep -qx "kwy-*ji-*bo" && wail
 
 test -z "$fail"
 
diff --git a/src/roff/troff/env.cpp b/src/roff/troff/env.cpp
index dae553d09..70d115b96 100644
--- a/src/roff/troff/env.cpp
+++ b/src/roff/troff/env.cpp
@@ -4071,6 +4071,25 @@ static void remove_hyphenation_exception_words_request() 
// .rhw
     skip_line();
     return;
   }
+  while (has_arg()) {
+    // C++11: constexpr
+    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 *word
+       = static_cast<unsigned char *>(
+         current_language->exceptions.lookup(rbuf));
+      if (word != 0 /* nullptr */)
+       current_language->exceptions.remove(rbuf);
+    }
+    if (!has_arg()) {
+      skip_line();
+      return;
+    }
+  }
   dictionary_iterator iter(current_language->exceptions);
   symbol entry;
   unsigned char *word = 0 /* nullptr */;
@@ -4091,8 +4110,6 @@ static void remove_hyphenation_exception_words_request() 
// .rhw
       }
     }
   }
-  // TODO: Else read each argument as a word, normalize any hyphens
-  // (dashes) out of it, and remove it from the exceptions dictionary.
   skip_line();
 }
 
@@ -4114,7 +4131,7 @@ static void print_hyphenation_exceptions_request() // .phw
   char wordbuf[bufsz]; // We need to `errprint()` it, so not `unsigned`.
   (void) memset(wordbuf, '\0', bufsz);
   while (has_arg()) {
-    // C++11: constexp
+    // C++11: constexpr
     static const size_t readbufsz = WORD_MAX;
     // C++03: char readbuf[readbufsz]();
     unsigned char readbuf[readbufsz];

_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit

Reply via email to