gbranden pushed a commit to branch master
in repository groff.
commit 190d01502ec8f8caab05bd3eb11ee04411c1e332
Author: G. Branden Robinson <[email protected]>
AuthorDate: Mon Mar 4 00:14:39 2024 -0600
Revert "[troff]: Fix Savannah #64484."
This reverts commit 9dbf227a5b3870a19c1e6d90e5b619c4ae3e7f3e.
Reopens Savannah #64484.
Test src/roff/groff/tests/device-control-special-character-handling.sh
fails at this commit.
---
ChangeLog | 26 -----------------
NEWS | 17 ------------
doc/groff.texi.in | 31 +++++++++++----------
man/groff.7.man | 3 +-
src/roff/troff/input.cpp | 72 +++++++++++++++++++++++-------------------------
5 files changed, 52 insertions(+), 97 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 0ffdd0403..af982750a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1170,32 +1170,6 @@
necessary. Restores the ability for some PDF viewers to accept
"#label" as suffix to the file name.
-2024-01-13 G. Branden Robinson <[email protected]>
-
- [troff]: Fix Savannah #64484.
-
- * src/roff/troff/input.cpp (encode_char_for_troff_output):
- Annotate the function's purpose. Initially assume the character
- to be encoded as valid. If the current token is a plain space,
- write a space (U+0020) to the output. (This is necessary
- because the `device` request no longer reads its arguments in
- copy mode; see below.) Move the `sc` local variable to a higher
- scope. Update the new `is_char_valid` Boolean instead of
- issuing an error diagnostic at each point of validation failure.
- When done processing the character, test `is_char_valid` and
- emit different diagnostics depending on whether the input was a
- special character escape sequence we can't handle, or something
- else. Emit a self-quoted escape character _as a backslash_, not
- as the current *roff escape character.
- (device_request): Rewrite to operate in interpretation mode, not
- copy mode.
-
- * doc/groff.texi (Postprocessor Access):
- * man/groff.7.man (Request short reference):
- * NEWS: Document it.
-
- Fixes <https://savannah.gnu.org/bugs/?64484>.
-
2024-01-13 G. Branden Robinson <[email protected]>
* src/roff/groff/tests/\
diff --git a/NEWS b/NEWS
index b1d8f65b4..168e802da 100644
--- a/NEWS
+++ b/NEWS
@@ -84,23 +84,6 @@ o The read-only registers `.m` and `.M` now interpolate
"default" when
the default color is selected as the stroke or fill color,
respectively, rather than interpolating nothing.
-o The `device` request no longer reads its arguments in copy mode; this
- change makes it more consistent with the `\X` device control command
- escape sequence.
-
-o The `device` request and `\X` escape sequence no longer emit a
- self-quoted *roff escape character as itself, but instead as a
- backslash, because troff's input and output languges are not the same
- thing, and to avoid the need to extend the *roff output language to
- support a configurable escape character.
-
- This and the previous change are to enable postprocessors to reliably
- interpret device control commands that wish to express arbitrary
- character sequences (using whatever escaping convention they prefer)
- without requiring different syntax for the arguments to the `device`
- request and `\X` escape sequences. For example, PDF bookmarks need to
- be expressed in UTF-16LE.
-
eqn
---
diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index f80a21650..dda99b83a 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -16542,18 +16542,15 @@ returned by the function @cite{getenv@r{(3)}}.
@cindex access to postprocessor
Two escape sequences and two requests enable documents to pass
-information directly to an output driver or other postprocessor. These
-are useful for exercising device-specific capabilities that the
-@code{groff} language does not abstract or generalize; examples include
-the embedding of hyperlinks and image files. Device-specific functions
-are documented in each output driver's man page, such as
-@cite{gropdf@r{(1)}}, @cite{grops@r{(1)}}, or @cite{grotty@r{(1)}}.
+information directly to a postprocessor. These are useful for
+exercising device-specific capabilities that the @code{groff} language
+does not abstract or generalize; examples include the embedding of
+hyperlinks and image files. Device-specific functions are documented in
+each output driver's man page, such as @cite{gropdf@r{(1)}},
+@cite{grops@r{(1)}}, or @cite{grotty@r{(1)}}.
@DefreqList {device, [@code{"}]@Var{contents}}
-@c XXX: Can't mark the parameters with @Var because @Var gets called
-@c recursively if we do.
-@c @DefescListEndx {\\X, @code{'}, @Var{contents}, @code{'}}
-@DefescListEndx {\\X, @code{'}, contents, @code{'}}
+@DefescListEndx {\\X, @code{'}, contents @r{@dots{}}, @code{'}}
Embed @var{contents} into GNU @command{troff} output as parameters to an
@w{@samp{x X}} device control command.@footnote{@xref{gtroff Output}.}
The interpretation of such parameters is determined by the output driver
@@ -16562,6 +16559,12 @@ or other postprocessor.
The @code{device} request strips a leading neutral double quote from
@var{contents} to allow embedding of leading spaces.
+@cindex @code{device} request, and copy mode
+@cindex copy mode, and @code{device} request
+@cindex mode, copy, and @code{device} request
+The @code{device} request processes its arguments in copy mode
+(@pxref{Copy Mode}). An initial neutral double quote in @var{contents}
+is stripped to allow embedding of leading spaces.
@cindex @code{\&}, in device control commands
@cindex @code{\)}, in device control commands
@cindex @code{\%}, in device control commands
@@ -16571,7 +16574,7 @@ The @code{device} request strips a leading neutral
double quote from
@ifinfo
@cindex @code{\@r{<colon>}}, in device control commands
@end ifinfo
-Within a device control command, the escape sequences @code{\&},
+By contrast, within @code{\X} arguments, the escape sequences @code{\&},
@code{\)}, @code{\%}, and @code{\:} are ignored; @code{\@key{SPC}} and
@code{\~} are converted to single space characters; and a self-escaped
escape character is output as a backslash @code{\}. So that the basic
@@ -16584,10 +16587,8 @@ characters; see the @cite{groff_char@r{(7)}} man page.
For this
transformation, character translations and special character definitions
are ignored.@footnote{They are bypassed because these parameters are not
rendered as glyphs in the output; instead, they remain abstract
-characters---in a PDF bookmark or a URL, for example.}
-
-Escape sequences other than the foregoing in device control command
-may be ignored, or produce an error.
+characters---in a PDF bookmark or a URL, for example.} The use of any
+other escape sequence in @code{\X} parameters is normally an error.
A device control command issued with the @code{device} request will not
be reflected in the output unless a partially collected line exists at
diff --git a/man/groff.7.man b/man/groff.7.man
index 0c0a8f7f0..0278e0df2 100644
--- a/man/groff.7.man
+++ b/man/groff.7.man
@@ -3008,7 +3008,8 @@ with compatibility mode disabled when the macro is
interpreted.
.TPx
.REQ .device contents
Write
-.I contents
+.IR contents ,
+read in copy mode,
to
.I @g@troff
output as a device control command.
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index c1f22b5d9..fdf14d0f1 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -5616,19 +5616,14 @@ static node *do_non_interpreted()
return new non_interpreted_node(mac);
}
-// In troff output, we translate the escape character to '\', but it is
-// up to the postprocessor to interpret it as such. (This mostly
-// matters for device control commands.)
static void encode_char_for_troff_output(macro *mac, const char c)
{
- bool is_char_valid = true;
- const char *sc = 0 /* nullptr */;
if ('\0' == c) {
- if (tok.is_space()
- || tok.is_stretchable_space()
- || tok.is_unstretchable_space())
+ if (tok.is_stretchable_space()
+ || tok.is_unstretchable_space())
mac->append(' ');
else if (tok.is_special()) {
+ const char *sc;
if (font::use_charnames_in_special) {
charinfo *ci = tok.get_char(true /* required */);
sc = ci->get_symbol()->contents();
@@ -5662,34 +5657,29 @@ static void encode_char_for_troff_output(macro *mac,
const char c)
mac->append(']');
}
else
- is_char_valid = false;
+ error("special character '%1' cannot be used within a"
+ " device control escape sequence", sc);
}
else
- is_char_valid = false;
+ error("special character '%1' cannot be used within a device"
+ " control escape sequence", sc);
}
}
else if (tok.is_hyphen_indicator()
|| tok.is_dummy()
|| tok.is_transparent_dummy()
|| tok.is_zero_width_break())
- /* silently ignore */;
- else
- is_char_valid = false;
- if (!is_char_valid) {
- if (sc != 0 /* nullptr */)
- error("special character '%1' is invalid within a device"
- " control command", sc);
- else
- error("%1 is invalid within a device control command",
- tok.description());
- }
+ error("%1 is invalid within device control escape sequence",
+ tok.description());
}
else {
- if (c == escape_char) {
- mac->append('\\');
- }
- else
+ if ((font::use_charnames_in_special) && ('\\' == c)) {
+ /*
+ * add escape escape sequence
+ */
mac->append(c);
+ }
+ mac->append(c);
}
}
@@ -5733,28 +5723,34 @@ static node *do_special()
static void device_request()
{
- if (!has_arg()) {
- warning(WARN_MISSING, "device request expects arguments");
- skip_line();
- return;
+ // We can't use `has_arg()` here because we want to read in copy mode.
+ int c;
+ for (;;) {
+ c = input_stack::peek();
+ if (' ' == c)
+ (void) get_copy(0 /* nullptr */);
+ else
+ break;
}
- if (tok.is_newline() || tok.is_eof()) {
- warning(WARN_MISSING, "device request expects arguments");
+ if (('\n' == c) || (EOF == c)) {
+ warning(WARN_MISSING, "device control request expects arguments");
skip_line();
return;
}
- if ('"' == tok.ch()) {
- tok.next();
- }
macro mac;
for (;;) {
- if (tok.is_newline() || tok.is_eof())
+ c = get_copy(0 /* nullptr */);
+ if ('"' == c) {
+ c = get_copy(0 /* nullptr */);
+ break;
+ }
+ if (c != ' ' && c != '\t')
break;
- encode_char_for_troff_output(&mac, tok.ch());
- tok.next();
}
+ for (; c != '\n' && c != EOF; c = get_copy(0 /* nullptr */))
+ mac.append(c);
curenv->add_node(new special_node(mac));
- skip_line();
+ tok.next();
}
static void device_macro_request()
_______________________________________________
Groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit