Module resilient.patches.overhang

Experimental hanging punctuation (overhang) support.

This file is part of re·sil·ient, a set of extensions to SILE.

See LIMITATIONS below.

Knuth said that hanging punctuation is a solved problem... There are (at least) two approaches, for the general case:

One is to cancel the width of the punctuation and to add the overhang width to the next glue. It thus require a lookahead to check that there is a glue after the punctuation, and to modify it.

The other is to insert two kerns after the punctuation (one negative, one positive), and to let the Knuth-Plass line breaker do its job (see TeXbook, app. D "dirty tricks").

This implementation uses the second approach.

Both approaches requires some tweaks at the node breaking (segmenter) level, so this is what we do here, though in a monkey-patch way.

Discretionary nodes neeed another dedicated approach. It's simpler, in a way, because we can just tweak the width of the prebreak content.

Info:

  • Copyright: (c) 2025 Omikhkeia / Didier Willis
  • License: MIT

Class SILE.nodeMakers.unicode

unicode.makeOverhang (self, w) (Hard-patch) Add a makeOverhang() method to the unicode node maker.
unicode.handleWordBreak (self, item) (Hard-patch) Override the handleWordBreak method.

Class SILE.types.node.discretionary

discretionary:_init (...) (Hard-patch) Override the discretionary constructor to adjust the width of the prebreak.


Class SILE.nodeMakers.unicode

Hook into the Unicode node maker to insert the overhang logic.
unicode.makeOverhang (self, w)
(Hard-patch) Add a makeOverhang() method to the unicode node maker.

Parameters:

  • self Instance pointer
  • w number Width of the overhang
unicode.handleWordBreak (self, item)
(Hard-patch) Override the handleWordBreak method.

LIMITATIONS:

This will NOT work for languages that inherit from unicode but override handleWordBreak, such as:

  • French (because of the special space rules before punctuation)
  • Czech, Spanish, and others (because of special handling for repeated dashes)

So this experiment is not a general solution, but raises other questions on how the various Unicode segmenters work in SILE.

Parameters:

  • self Instance pointer
  • item table The item to handle

Class SILE.types.node.discretionary

Hook into the discretionary node to adjust the width of the prebreak.
discretionary:_init (...)
(Hard-patch) Override the discretionary constructor to adjust the width of the prebreak.

Parameters:

  • ...
generated by LDoc 1.5.0 Last updated 2025-09-14 22:28:52