[looping in Russ Allbery for a podlators/pod2man question] At 2025-08-24T13:18:59-0500, G. Branden Robinson wrote: > My proposal would be stronger if I could point to a real-world man > page that misrenders due to `"`'s transparency, true, so I'll go > looking for one.
I found one. I won't claim it's a high-impact case because the syntax of the programming language being illustrated doesn't attach significance to the difference, but a rendering change _does_ result. $ zgrep -C1 'no id' $(man -w MIME::Field::ParamVal) \& # Get an attribute, or undefined if not present: \& print "no id!" if defined($field\->param(\*(Aqid\*(Aq)); \& \& # Same, but use empty string for missing values: \& print "no id!" if ($field\->paramstr(\*(Aqid\*(Aq) eq \*(Aq\*(Aq); \& $ zcat $(man -w MIME::Field::ParamVal) | nroff -Wreg -Wfont -man \ | grep -C1 'no id' # Get an attribute, or undefined if not present: print "no id!" if defined($field->param('id')); # Same, but use empty string for missing values: print "no id!" if ($field->paramstr('id') eq ''); $ zcat $(man -w MIME::Field::ParamVal) | nroff -Wreg -Wfont -man -mfr \ | grep -C1 'no id' # Get an attribute, or undefined if not present: print "no id!" if defined($field->param('id')); # Same, but use empty string for missing values: print "no id!" if ($field->paramstr('id') eq ''); Notice how two spaces shrink to one after the rendered `no id!`. We do encourage _groff man_ users to configure supplemental inter-sentence space to their preference, so we can't dismiss it as affecting only non-English man pages. groff_man_style(7): /.../share/groff/site-tmac/man.local Put siteālocal changes and customizations into this file. .\" Put only one space after the end of a sentence. .ss 12 0 \" See groff(7). .\" Keep pages narrow even on wide terminals. .if n .if \n[LL]>80n .nr LL 80n Russ, I observe the following in "lib/Pod/Man.pm". .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' Do you think it would be worthwhile to do the following as well? .ie \n(.g .ds Dq \(dq .el .ds Dq ""\" two double quotes because `ds` strips the first I don't understand the patterns where you're replacing ` and ' in POD input to make them `\*(Aq` in *roff output well enough to make a literal suggestion for `\*(Dq` here, unfortunately. But I think substituting `"` with `\*(Dq` would produce better results in most cases--I'll cover a (possibly notional) exception below--and be backward compatible to groff 1.23 and earlier, and correct regardless of whether groff 1.24 makes the `cflags` change to the `"` character, for man pages only, as proposed in this thread. The exception has to do with traditional troffs and the use of double quotes as macro arguments. Here is an unfortunately lengthy exploration of the problem from groff's Texinfo manual. The bit near the end about "repeated argument expansion" is where I suspect the headache sets in for podlators. You already avoid many of these problems by using font selection escape sequences instead of font style macros, but this issue is worth knowing about if `"` characters appear in (sub)section headings or as `TP` paragraph tags. Please let me know if I can be of assistance. ---snip--- 5.6.3 Calling Macros -------------------- If a macro of the desired name does not exist when called, the formatter creates it and assigns it an empty definition.(1) (*note Calling Macros-Footnote-1::) Calling an undefined macro _does_ end a macro definition naming it as its end macro (*note Writing Macros::). To embed spaces _within_ a macro argument, enclose the argument in neutral double quotes '"'. Horizontal motion escape sequences are sometimes a better choice for arguments to be formatted as text. Consider calls to a hypothetical section heading macro 'uh'. .uh The Mouse Problem .uh "The Mouse Problem" .uh The\~Mouse\~Problem .uh The\ Mouse\ Problem The first line calls 'uh' with three arguments: 'The', 'Mouse', and 'Problem'. The remainder call the 'uh' macro with one argument, 'The Mouse Problem'. The last solution, using escaped spaces, can be found in documents prepared for AT&T 'troff'. It can cause surprise when text is adjusted, because '\<SPC>' inserts a _fixed-width_, non-breaking space. GNU 'troff''s '\~' escape sequence inserts an adjustable, non-breaking space.(2) (*note Calling Macros-Footnote-2::) The foregoing raises the question of how to embed neutral double quotes or backslashes in macro arguments when _those_ characters are desired as literals. In GNU 'troff', the special character escape sequence '\[rs]' produces a backslash and '\[dq]' a neutral double quote. In GNU 'troff''s AT&T compatibility mode, these characters remain available as '\(rs' and '\(dq', respectively. AT&T 'troff' did not consistently define these special characters, but its descendants can be made to support them. *Note Device and Font Description Files::. If even that is not feasible, options remain. To obtain a literal escape character in a macro argument, you can simply type it if you change or disable the escape character first. *Note Using Escape Sequences::. Otherwise, you must escape the escape character repeatedly to a context-dependent extent. *Note Copy Mode::. For the (neutral) double quote, you have recourse to an obscure syntactical feature of AT&T 'troff'. Because a double quote can begin a macro argument, the formatter keeps track of whether the current argument was started thus, and doesn't require a space after the double quote that ends it.(3) (*note Calling Macros-Footnote-3::) In the argument list to a macro, a double quote that _isn't_ preceded by a space _doesn't_ start a macro argument. If not preceded by a double quote that began an argument, this double quote becomes part of the argument. Furthermore, within a quoted argument, a pair of adjacent double quotes becomes a literal double quote. .de eq . tm arg1:\\$1 arg2:\\$2 arg3:\\$3 . tm arg4:\\$4 arg5:\\$5 arg6:\\$6 .. \" 4 backslashes on the next line .eq a" "b c" "de"f\\\\g" h""i "j""k" error-> arg1:a" arg2:b c arg3:de error-> arg4:f\g" arg5:h""i arg6:j"k Apart from the complexity of the rules, this traditional solution has the disadvantage that double quotes don't survive repeated argument expansion in AT&T 'troff' or GNU 'troff''s compatibility mode. This can frustrate efforts to pass such arguments intact through multiple macro calls. .cp 1 .de eq . tm arg1:\\$1 arg2:\\$2 arg3:\\$3 . tm arg4:\\$4 arg5:\\$5 arg6:\\$6 .. .de xe . eq \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 .. \" 8 backslashes on the next line .xe a" "b c" "de"f\\\\\\\\g" h""i "j""k" error-> arg1:a" arg2:b arg3:c error-> arg4:de arg5:f\g" arg6:h""i Outside of compatibility mode, GNU 'troff' doesn't exhibit this problem because it tracks the nesting depth of interpolations. *Note Implementation Differences::. ---end snip--- Regards, Branden
signature.asc
Description: PGP signature