gbranden pushed a commit to branch master
in repository groff.
commit 1161ad06f075956b8062d6fdde3ca955faa90948
Author: G. Branden Robinson <[email protected]>
AuthorDate: Mon Apr 21 02:04:26 2025 -0500
[troff]: Add more diagnostics to `bd` request.
* src/roff/troff/node.cpp (embolden_font): Add diagnostics. Throw error
when input attempts to apply emboldening request to syntactically
invalid object (e.g., ".bd \N'12'" or ".bd 1 \N'12'"). Add new
Boolean local variable `emboldening_may_be_conditional` to improve
diagnostics when the argument count makes the request ambiguous.
Throw warning if we're ignoring the third argument because the first
two were interpreted as a mounting position and emboldening amount,
respectively. As annotated in comments, 'Does ".bd 1 2" mean
"embolden font position 1 by 2 units" (really one unit), or "stop
conditionally emboldening font 2 when font 1 is selected"?' Also
parenthesize complex expression.
---
ChangeLog | 15 +++++++++++++++
src/roff/troff/node.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index cfa445e03..633da264a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2025-04-21 G. Branden Robinson <[email protected]>
+
+ * src/roff/troff/node.cpp (embolden_font): Add diagnostics.
+ Throw error when input attempts to apply emboldening request to
+ syntactically invalid object (e.g., ".bd \N'12'" or ".bd 1
+ \N'12'"). Add new Boolean local variable
+ `emboldening_may_be_conditional` to improve diagnostics when the
+ argument count makes the request ambiguous. Throw warning if
+ we're ignoring the third argument because the first two were
+ interpreted as a mounting position and emboldening amount,
+ respectively. As annotated in comments, 'Does ".bd 1 2" mean
+ "embolden font position 1 by 2 units" (really one unit), or
+ "stop conditionally emboldening font 2 when font 1 is
+ selected"?' Also parenthesize complex expression.
+
2025-04-20 G. Branden Robinson <[email protected]>
[groff]: Add unit test for `bd` request.
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 9056434dd..602f3e24e 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -7036,7 +7036,6 @@ hunits env_narrow_space_width(environment *env)
// not position. Does ".bd 1 2" mean "embolden font position 1 by 2
// units" (really one unit), or "stop conditionally emboldening font 2
// when font 1 is selected"?
-
static void embolden_font()
{
if (!(has_arg())) {
@@ -7048,6 +7047,29 @@ static void embolden_font()
skip_line();
return;
}
+ if ((!tok.is_character())
+ || tok.is_special_character()
+ || tok.is_indexed_character()) {
+ error("emboldening request expects font name or mounting position"
+ " as first argument, got %1", tok.description());
+ skip_line();
+ return;
+ }
+ // If the 1st argument starts with a non-numeral, we must be prepared
+ // to expect a third argument to specify an emboldening amount...
+ // .bd S TB 3 \" embolden S when `TB` selected
+ // ...or removal of conditional emboldening.
+ // .bd S TB \" don't embolden S when `TB` selected
+ //
+ // XXX: Our approach forecloses the emboldening of fonts whose names
+ // _start_ with numerals but _contain_ non-numerals, like '3foo'. If
+ // one agrees that Kernighan's grammar for the extended `bd` request
+ // of device-independent troff is ambiguous, there may not be a
+ // perfect solution. (This approach could be improved by scanning
+ // ahead in the input, but is it worth the trouble?)
+ bool emboldening_may_be_conditional = false;
+ if (!csdigit(tok.ch()))
+ emboldening_may_be_conditional = true;
font_lookup_info finfo;
if (!read_font_identifier(&finfo)) {
font_lookup_error(finfo, "for emboldening");
@@ -7056,7 +7078,18 @@ static void embolden_font()
}
int n = finfo.position;
if (has_arg()) {
- if (tok.is_usable_as_delimiter()) {
+ if ((!tok.is_character())
+ || tok.is_special_character()
+ || tok.is_indexed_character()) {
+ error("emboldening request expects font name or emboldening"
+ " amount as second argument, got %1", tok.description());
+ skip_line();
+ return;
+ }
+ // If both arguments start with numerals, assume this form.
+ // .bd 2 4 \" embolden font position 2 by 3 (yes, 3) units
+ // ...otherwise...
+ if (emboldening_may_be_conditional && !(csdigit(tok.ch()))) {
font_lookup_info finfo2;
if (!read_font_identifier(&finfo2)) {
font_lookup_error(finfo2, "for conditional emboldening");
@@ -7066,18 +7099,23 @@ static void embolden_font()
int f = finfo2.position;
units offset;
if (has_arg()
- && read_measurement(&offset, 'u') && offset >= 1)
+ && read_measurement(&offset, 'u')
+ && (offset >= 1))
font_table[f]->set_conditional_bold(n, hunits(offset - 1));
else
font_table[f]->conditional_unbold(n);
}
else {
- // A numeric second argument must be an emboldening amount.
+ // The second argument must be an emboldening amount.
units offset;
- if (read_measurement(&offset, 'u') && offset >= 1)
+ if (read_measurement(&offset, 'u') && (offset >= 1))
font_table[n]->set_bold(hunits(offset - 1));
else
font_table[n]->unbold();
+ if (has_arg())
+ warning(WARN_FONT, "ignoring third argument to font emboldening"
+ " request when first interpreted as mounting position"
+ " and second as emboldening amount");
}
}
else
_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit