URL: <https://savannah.gnu.org/bugs/?64004>
Summary: make character and glyph handling more discoverable (.pchar, ".if C", ".if G") Group: GNU roff Submitter: gbranden Submitted: Wed 05 Apr 2023 10:26:46 PM UTC Category: Core Severity: 3 - Normal Item Group: Feature change Status: Postponed Privacy: Public Assigned to: gbranden Open/Closed: Open Discussion Lock: Any Planned Release: None _______________________________________________________ Follow-up Comments: ------------------------------------------------------- Date: Wed 05 Apr 2023 10:26:46 PM UTC By: G. Branden Robinson <gbranden> Creating something of a placeholder ticket since Dave mentioned over in bug #63812 that I hadn't documented my vague intentions in this area. My complaint is that it is too damn hard to figure out exactly how groff decides to resolve a character into a glyph. Our Texinfo manual, in language I have not dared to touch, documents a lengthy process. 5.19.4 Using Symbols -------------------- A "glyph" is a graphical representation of a "character". While a character is an abstract entity containing semantic information, a glyph is something that can be actually seen on screen or paper. It is possible that a character has multiple glyph representation forms (for example, the character 'A' can be either written in a roman or an italic font, yielding two different glyphs); sometimes more than one character maps to a single glyph (this is a "ligature"--the most common is 'fi'). A "symbol" is simply a named glyph. Within 'gtroff', all glyph names of a particular font are defined in its font file. If the user requests a glyph not available in this font, 'gtroff' looks up an ordered list of "special fonts". ... Fonts mounted with the 'fonts' keyword in the 'DESC' file are globally available. To install additional special fonts locally (i.e., for a particular font), use the 'fspecial' request. Here are the exact rules how 'gtroff' searches a given symbol: * If the symbol has been defined with the 'char' request, use it. This hides a symbol with the same name in the current font. * Check the current font. * If the symbol has been defined with the 'fchar' request, use it. * Check whether the current font has a font-specific list of special fonts; test all fonts in the order of appearance in the last * Check whether the current font has a font-specific list of special fonts; test all fonts in the order of appearance in the last 'fspecial' call if appropriate. * If the symbol has been defined with the 'fschar' request for the current font, use it. * Check all fonts in the order of appearance in the last 'special' call. * If the symbol has been defined with the 'schar' request, use it. * As a last resort, consult all fonts loaded up to now for special fonts and check them, starting with the lowest font number. This can sometimes lead to surprising results since the 'fonts' line in the 'DESC' file often contains empty positions, which are filled later on. ... I want a few things that would expose aspects of this complex machinery to people using and debugging groff. Of first importance conceptually is simply to better permit insight into what's happening. So I propose the addition of a new request, `pchar`, along the lines of `pm`, `pnr`, `pev`, and `ptr`. I don't have clear ideas yet what its output format would be, but as none of its existing kin have rigidly specified output (and are for debugging, and go to the standard error stream anyway), maybe that need be no barrier to getting things off the ground. My proposed syntax is pretty simple: .pchar char where _char_ is an ordinary or special character. (Probably any extraneous input on the line after the first character would be ignored, and if _char_ is null--but not an empty `char` definition or similar--no output would be produced.) I also propose--subject to change depending on what I learn after experiencing a surprise or two from the output of `pchar` on various entities--at least one new conditional expression operator. _groff_ already introduced a `c` operator (as in `.if c`) long ago. However, it appears to undergo the _entire_ multi-stage character-to-glyph resolution process as quoted above. What if I want to know if _char_ is a _groff_ language character definition? We might call an operator that tests this predicate "C" (big C for a big, fancy character--internally, in GNU _troff_ these appear to be fully fledged macro definitions). What if I want to know if a font (maybe just the current one) truly has coverage for a character? We might call an operator that tests this predicate "g", for "glyph", since if a font can draw it, it does so in a specific fashion that makes it a glyph. There is no obvious way to decide these matters within _groff_ logic itself. You can usually find out by reading device-independent output--but by then your document has already been fully formatted. Or you could trace the source code with a debugger. This is not user friendly to say the least. I _think_ these two predicates combined with the existing 'c' conditional operator would suffice to permit writing _groff_ language logic that can discern and make decisions based on whether: 1. A character has a _groff_ character definition (`.if C'). 2. A character has no _groff_ character definition but does have coverage in some available per the ordinary character resolution process (`.if c` and not `.if C`). 3. A character has no _groff_ character definition but does have coverage in the current font, without recourse to fallbacks of any sort (`.if g`). We _might_ need/want a fourth conditional operator, say, `G` to check for glyphs in "special" fonts. This would return false if its argument has a groff character definition or has coverage in the current font, but resolves nevertheless. At present I don't anticipate a need to distinguish "general" special fonts from "font-specific" special fonts. (See the `fspecial` request.) Whether this question can be decided by composing _groff_ logic for it (possibly including temporary font change operations) remains to be seen. That's my rough sketch. _______________________________________________________ Reply to this item at: <https://savannah.gnu.org/bugs/?64004> _______________________________________________ Message sent via Savannah https://savannah.gnu.org/