[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

We have OSC 8 terminal hyperlink support now

From: G. Branden Robinson
Subject: We have OSC 8 terminal hyperlink support now
Date: Sat, 2 Oct 2021 14:02:36 +1000
User-agent: NeoMutt/20180716

Hi all,

I'm pleased to report that I've landed a new feature in groff Git HEAD.

The grotty(1) output driver now recognizes a new "link" device control
subcommand and uses it to synthesize ECMA-48 OSC 8 escape sequences to
pass hyperlink information to the terminal device.  This means that, on
terminal emulators that support OSC 8, groff documents can embed
clickable hyperlinks.

I tested this feature with gnome-terminal 3.30.2.  (My daily driver,
xterm, doesn't support OSC 8 yet.)

Here's how I've documented it in grotty(1).  It's linked with SGR
support, another ECMA-48 feature.

       By default, grotty emits SGR escape  sequences  (from  ISO  6429,
       popularly called “ANSI escapes”) to change text attributes (bold,
       italic,  underline, reverse-video, and colors).  Devices support‐
       ing the appropriate sequences can view roff documents using eight
       different background and foreground colors.  Following ISO  6429,
       the  following colors are defined in tty.tmac: black, white, red,
       green, blue, yellow, magenta, and cyan.  Unrecognized colors  are
       mapped  to  the default color, which is dependent on the settings
       of the terminal.  OSC 8 hyperlinks are  produced  for  these  de‐
   SGR and OSC support in pagers
       When paging grotty’s output with less(1), the latter program must
       be  instructed  to  pass SGR and OSC sequences through to the de‐
       vice; its -R option is one way to achieve this (less version  566
       or  later is required for OSC 8 support).  Consequently, programs
       like man(1) which page roff documents with less must call it with
       an appopriate option.
   Device control commands
       grotty  understands  the  following device control functions pro‐
       duced using the roff \X escape sequence in a document.

       \X'tty: link [uri [key=value] ...]'
              Embed a hyperlink using the  OSC  8  terminal  escape  se‐
              quence.  Specifying uri starts hyperlinked text, and omit‐
              ting  it  ends the hyperlink.  When uri is is present, any
              number of additional key/value  pairs  can  be  specified;
              their interpretation is the responsibility of the terminal
              emulator.   Spaces or tabs cannot appear literally in uri,
              key, or value; they must be represented  in  an  alternate
       -c     Use grotty’s legacy output format (see subsection  “Legacy
              output  format”  above).   OSC 8 hyperlink terminal escape
              sequences are not emitted.

Having already thus belabored the point, I trust the reader to infer
that setting $GROFF_NO_SGR will also prevent the emission of OSC 8
escape sequences.  (I say it here for the sake of future web searches.)

People who maintain their own macro packages or eschew their use can put
grotty(1)'s OSC 8 support to work immediately; it's a "git pull" away.

To further demonstrate this feature, I have enhanced the groff man(7) UR
and MT macro ("URL" and "mailto") implementations to use device control
escape sequences to exercise it.  As planned and desired, this required
to changes to any man page text; the hyperlinks simply appear.  When
rendered, the link content will no longer be formatted as output (the
hyperlinked _text_ of course, if any, will continue to be).

The lack of universal support for OSC 8 and the absence of a means for
the formatter to query terminal capabilities at runtime (a major
architectural challenge given *roff design) however, means that I have
disabled our man(7) implementation's use of the aforementioned device
control by default for the time being, in the man.local file.

Moreover, lack of terminal emulator support isn't even the biggest
problem facing this feature; well-coded terminal emulators silently
ignore OSC escape sequences they don't understand.  Unfortunately,
another party often interposes itself in communications between
grotty(1) and the terminal device--that would be the pager.  less(1)
only developed OSC 8 support in version 566, released about one year
ago.  Versions prior to that misinterpreted the OSC 8 escape sequence
and would write parts of it to the terminal window, an unsightly mess
that would be sure to displease users.  I haven't checked, but I fear
that the behavior of other pagers (more, most, pg--are there others?) is
similarly poor, and, worse, that their development is moribund.

I expect and encourage groff users, particularly OS distributors, to
survey their systems' pager and terminal emulator offerings and delete
the only non-comment lines in the man.local we ship to expose this handy
feature to users.

The means of this support is a new register, "U", recognized by our
man(7) implementation.  You can think of it as mnemonic for "URL
support".  For orthogonality I applied its recognition to our man(7)
support for the "html" output device as well.  (It is thus now possible
to render to HTML without hyperlinked text[1].)

Future Directions

Obvious next steps to me include:

(1) Hook up our man(7) UR and MT macros to gropdf(1).
(2) It might be nice to make this "link" device control command
    applicable across output drivers.  Maybe we could promote "link" to
    a "name space" instead of having it be device-specific, then have
    grohtml(1), grotty(1), and gropdf(1) all support it with a common
(3) Get the feature working with other macro packages when they render
    in nroff mode.  ms(7) has no native support for hyperlinks, but our
    "www" package, demonstrated in out example document "",
    continues to work, so I reckon that would be the first place to
(4) Work on the man(7) MR macro for man page cross references, using the
    "man:" schema by default to avoid file name resolution issues.

I appreciate feedback, including suggestions regarding relative
priorities of the next steps (or additions to that list).


[1] Thanks to the "devtag" package, internal anchors are still placed
    for section headings, but at present nothing in man(7)'s HTML
    support generates links to them.

Attachment: signature.asc
Description: PGP signature

reply via email to

[Prev in Thread] Current Thread [Next in Thread]