At 2022-03-20T01:29:32+0100, Alejandro Colomar (man-pages) wrote: > Hi Branden, > > I've met some undocumented (or I couldn't find it) behavior of double > quotes ("), which might be a bug in groff(1):
Hi Alex! Ralph's description, as I parse it, is correct. I'll speak to the broader issue of documentation coverage of the matter. > Could you please improve the documentation regarding '"'? Yes, something about this should become part of groff(7). In groff_man_style(7), I have restricted the discussion to advising people to use the \(dq special character (also spellable as \[dq]). The issue _is_ discussed in the groff Texinfo manual. Here's the relevant material from the groff 1.22.4 version. [[ 5.5.1.1 Request and Macro Arguments ................................... [...] A double quote that isn't preceded by a space doesn't start a macro argument. If not closing a string, it is printed literally. For example, .xxx a" "b c" "de"fg" has the arguments 'a"', 'b c', 'de', and 'fg"'. Don't rely on this obscure behaviour! There are two possibilities to get a double quote reliably. * Enclose the whole argument with double quotes and use two consecutive double quotes to represent a single one. This traditional solution has the disadvantage that double quotes don't survive argument expansion again if called in compatibility mode (using the '-C' option of 'groff'): .de xx . tm xx: `\\$1' `\\$2' `\\$3' . . yy "\\$1" "\\$2" "\\$3" .. .de yy . tm yy: `\\$1' `\\$2' `\\$3' .. .xx A "test with ""quotes""" . => xx: `A' `test with "quotes"' `.' => yy: `A' `test with ' `quotes""' If not in compatibility mode, you get the expected result xx: `A' `test with "quotes"' `.' yy: `A' `test with "quotes"' `.' since 'gtroff' preserves the input level. * Use the double quote glyph '\(dq'. This works with and without compatibility mode enabled since 'gtroff' doesn't convert '\(dq' back to a double quote input character. Note that this method won't work with Unix 'troff' in general since the glyph 'dq' isn't defined normally. Double quotes in the 'ds' request are handled differently. *Note Strings::, for more details. ]] > I've also seen """ to mean \(dq in some manual pages. If you wanted to pass a macro a lone double quote as an argument, and wanted to avoid \(dq for some reason, you would, amazingly enough, need to type four double quotes in a row. > I guess the behavior is related to this report, but I'd like to > understand why it works that way. The quote preceded by a space suppresses recognition of spaces as argument delimiters. A subsequent double quote _not followed immediately by another double quote_ ends the argument and reactivates recognition of spaces as argument delimiters. Any other double quote is treated as a literal. There is a kind of elegance to that; unfortunately, as our Texinfo manual notes, the non-literal double quotes are removed in the process of macro argument interpolation, so if one macro wraps another naïvely, the result will be unfortunate. The following demonstration is written to be compatible with AT&T troff, and works the same with and without groff's -C option. This is also with groff 1.22.4, though Git HEAD behaves the same (as it should). [[ $ cat EXPERIMENTS/double-quotes.roff .de In INNER: $1=\\$1, $2=\\$2, $3=\\$3 .. .de Ou OUTER: $1=\\$1, $2=\\$2, $3=\\$3 .br .In \\$1 \\$2 \\$3 .. .Ou """" "flavored with ""meat""" $ groff -b -ww -Tutf8 EXPERIMENTS/double-quotes.roff | cat -s OUTER: $1=", $2=flavored with "meat", $3= INNER: $1= flavored with , $2=meat", $3= ]] I haven't checked yet, but I _think_ all *roffs that are actively developed (so, ours, Heirloom Doctools's, and neatroff) make a point of defining the `dq` special character. It baffles me that Kernighan didn't establish this practice when making AT&T troff device-independent in ~1979. Maybe some day if I ever get the chance, I'll ask him why. Somewhere else in groff's docs--I've forgotten where--there was a nicely economical description of these quotation rules (they are re-used in another part of the system), and I aim to promote them to this Texinfo node and the corresponding section of groff(7) when I revise that part of the manual. I would like to drop the statement Don't rely on this obscure behaviour! from our Texinfo manual. I suspect that no implementation can change these semantics without leaving a smoking crater where even vaguely compatible macro argument processing once was. The key point is to recommend the use of \(dq except where "pathological levels of portability" are required, e.g., to write new documents for Unix V7 or 2.11BSD in SIMH. This mechanism of embedding a double quote in a macro argument may not be best practice, but it should be _reliable_--if you don't need to pass that argument to another macro. Does this help? Regards, Branden
signature.asc
Description: PGP signature