bugGNU roff - Bugs: bug #64004, [troff] make character and glyph...

 
 

bug #64004: [troff] make character and glyph handling more discoverable (.pchar, ".if C", ".if G", ".if N"?)

Submitter:  G. Branden Robinson <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 Planned Release:  None
* Mandatory Fields

Post a Comment

Add a New Comment Rich Markup
   

Discussion

Jump to the original submission

Tue 09 Sep 2025 07:43:45 PM UTC, comment #7: 

Bug #67492 is born.

G. Branden Robinson <gbranden>
Group administrator
Tue 09 Sep 2025 07:32:56 PM UTC, comment #6: 

So I think I want to split off the "report character resolution progress" part of an enhancement to the (relatively new) `pchar` request into its own new ticket, upon which bug #44235 can depend.

The "having a `pchar` request at all" part of this ticket is already achieved (but I'll retain it in the Summary for searchability).

For this ticket, that leaves the prospect of new conditional expressions to help groff documents make sense of string/macro/diversion contents.

G. Branden Robinson <gbranden>
Group administrator
Thu 04 Sep 2025 09:37:36 PM UTC, comment #5: 

It's Summary was not the clearest.  Hopefully my update addressed that.

Dave <barx>
Group Member
Wed 03 Sep 2025 09:30:27 PM UTC, comment #4: 

You are absolutely right Dave, this belongs there! I did a bug search for schar which did not find the most suitable.

Deri James <deri>
Group Member
Wed 03 Sep 2025 06:30:29 PM UTC, comment #3: 

comment #2:

> Maybe we need a new zchar which is used after
> the DESC fonts have been checked.


If I'm understanding this idea, it sounds like the topic of bug #44235, specifically the proposal introduced in comment 2.

Dave <barx>
Group Member
Wed 03 Sep 2025 04:23:39 PM UTC, comment #2: 

Hi Branden,

Just a question loosely associated to this.

The fallback characters in ps.tmac using schar defeat finding the precise glyph in a font pre-loaded in the DESC file. I am now using the Symbola font as one of the fonts in the DESC fonts line. I also run with DESC family set Tinos. Now groff_char.7 runs with no missing glyphs except \[bs]. However, if I look at what fonts are installed in the pdf I was surprised to see one character from the TR font included, it was the "/"! The reason is because ps.tmac has an schar fallback for \[ne] which perversely uses the "/" from TR. The Symbola font has a perfectly good glyph for \[ne] but the only way to defeat the fallback is with "\f[Symbola]\[ne]\fP". In the attached screenshot the fallback glyph is on the left and the Symbola glyph is on the right.

When groff was first developed type 1 fonts had a few hundred glyphs but these days glyph coverage is much larger and fallbacks get in the way. A fallback which approximates a glyph is never as good as a custom designed glyph in a font, so fallbacks should be the glyph of last resort. Maybe we need a new zchar which is used after the DESC fonts have been checked. (It's even got it's own theme tune! https://duckduckg ... 3Fv%3Dj54YES7umn4
)


Deri James <deri>
Group Member
Sun 18 Aug 2024 12:10:55 PM UTC, comment #1: 

Kicking out past groff 1.24.

G. Branden Robinson <gbranden>
Group administrator
Wed 05 Apr 2023 10:26:46 PM UTC, original submission:  

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.

G. Branden Robinson <gbranden>
Group administrator

 

Attached Files

Attached Files

(Note: upload size limit is set to 4.0MiB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

 

Dependencies

This item does not depend on any other items.

No items depend on this one.

 

Mail Notification Carbon-Copy List

Carbon-Copy List
  • -email is unavailable- added by barx (Posted a comment)
  • -email is unavailable- added by deri (Updated the item)
  • -email is unavailable- added by barx
  • -email is unavailable- added by gbranden (Submitted the item)
  •  

    Votes

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    History

    Follow 8 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2025-09-03 deri Attached File- Added Screenshot_20250903_162122.png, #57617
    2025-08-30 gbranden Summary[troff] make character and glyph handling more discoverable (.pchar, &quot;.if C&quot;, &quot;.if G&quot;) [troff] make character and glyph handling more discoverable (.pchar, ".if C", ".if G", ".if N"?)
    2024-08-18 gbranden DependenciesRemoved dependency from bugs #65099 -
    2024-08-18 gbranden StatusNone Postponed
    2024-03-22 gbranden Summarymake character and glyph handling more discoverable (.pchar, &quot;.if C&quot;, &quot;.if G&quot;) [troff] make character and glyph handling more discoverable (.pchar, ".if C", ".if G")
    2024-01-01 gbranden Dependencies- bugs #65099 is dependent
    2023-08-10 gbranden StatusPostponed None
    2023-04-06 barx Carbon-Copy- Added barx

    Back to the top

    Powered by Savane 3.16-8b18.
    Corresponding source code