Uh, I think the -C switch might be broken... λ GNU-Groff (master): printf '\\n(.C\n' | ./test-groff -Tutf8 | head -n1 0 λ GNU-Groff (master): printf '\\n(.C\n' | ./test-groff -C -Tutf8 | head -n1 0
As for the `.cp` register... I guess it's a necessary compromise. On Tue, 14 Apr 2020 at 11:46, G. Branden Robinson < g.branden.robin...@gmail.com> wrote: > Hi, John! > > First, let me address your lingering point. > > At 2020-04-12T13:34:04+1000, John Gardner wrote: > > Wouldn't it be simpler to inline the contents of unicode.tmac? Only > > two other macro packages reference it, and the file is arguably short > > enough not to violate any DRY principles: > > > > λ GNU-Groff (master): grep -rnw ./tmac -e unicode.tmac > > ./tmac/html.tmac:546:.mso unicode.tmac > > ./tmac/tmac.am:62: tmac/unicode.tmac \ > > ./tmac/tty.tmac:72:. mso unicode.tmac > > ./tmac/unicode.tmac:1:.\" unicode.tmac > > > > unicode.tmac has only 3 lines of (relevant) source code: > > > > .char - \[hy] > > .char ` \[oq] > > .char ' \[cq] > > We could do that. I suspect the idea was that unicode.tmac might grow > in the future, causing increasing affront to the DRY principle. > > However, I think doing so simply papers over a deeper and more insidious > issue, where groff file nesting, compatibility mode, and the historical > legacy of AT&T troff's two-character register namespace (because that's > all you'll ever need :-| ). > > I've snipped my original plan because it did not survive contact with > the enemy. What I ended up with was a small change to the parser to > support a new register. I decided to document my justification in > groff_diff(7); here it is. > > *** > > The register \n[.cp] is specialized and may require a statement of > rationale. When writing your own macro packages or documents that use > groff features and will be sourced by others with the .so request, you > may desire correct operation regardless of compatibility mode in the > surrounding context. It may occur to you to save the existing value of > \n(.C into a temporary register, say, _C, at the beginning of your > file, turn compatibility mode off with .cp 0, then restore it from that > register at the end with the .cp request. At the same time, a modular > design may lead you to multiple layers of inclusion. You cannot use > the same register name everywhere or you risk “clobbering” the value > from an outer scope. The two‐character register namespace of AT&T > troff is confining and mnemonically difficult; you may wish to use > groff's more capacious namespace. However, attempting > .nr _my_saved_C \n(.C > will not work in compatibility mode; the register name is too long. > “This is exactly what .do is for,” you think. > .do nr _my_saved_C \n(.C > The foregoing will always save zero to your register, because .do turns > compatibility mode off. It will not serve to have .do report the saved > compatibility mode in \n(.C for this special case, because the request > can do anything (except change compatibility mode in its enclosing > scope), including call macros and source files, and the value of \n(.C > must be reliable there. What you need is: > .do nr _my_saved_C \n[.cp] > .cp 0 > at the beginning of your file, followed by > .cp _my_saved_C > at the end. > > *** > > What remains to be done for this changeset: > > * Port the documentation over to an appropriate place in the Texinfo > manual. > > To be done in a subsequent changeset: > > * Change all the man pages and macro files that manipulate compatibilty > mode to use the technique described. > > See attached patch for the details. > > What do you think? > > Thank you for writing that regression test! This was quite the > adventure. > > Regards, > Branden >