Zu Inhalt springen

Kerning, Bindestriche, Silbentrennung und LuaLaTeX

Hervorgehobene Antworten

Hallo in die Runde,

Ich bin gerade mit meinem Latein am Ende. Ich habe zwei Tage rumgefrickelt, weil mir im Wort "Nordrhein-Westfalen" die große Lücke zwischen dem Bindestrich und dem großen W nicht gefiel. Also habe ich mir ein Minimalbeispiel gebastelt und ein bisschen am Kerning 'rumgefummelt bis mir der Abstand gefiel. Das war etwas frickelig, weil meine Schrift (EB Garamond) mehrere Zeichen für den Bindestrich benutzt, je nachdem, ob Versalien oder Gemeine im spiel sind. Aber wie immer habe ich etwas gelernt dabei. Jetzt wollte ich meine Errungenschaft (ein selbst definiertes Lua-Feature) mal auf den eigentlichen Text loslassen und es funktionierte nicht. Also wieder etwas rumgefrickelt und dann fiel es mir wie Schuppen von den Augen: Im eigentlichen Text wird kein normale Bindestrich gesetzt. Hintergrund ist, dass LaTeX Wörter mit Bindestrich in der Regel nur am Bindestrich trennen kann. Deswegen setzt man dann einen "Bindestrich mit Trennungserlaubnis". Im Code steht dann "Nordrhein"=Westfalen". Und auch wenn das im Endergebnis den gleichen Bindestrich ergibt wie "Nordrhein-Westfalen" funktioniert mein Lua-Feature dann nicht - ganz offenbar weil der Bindestrich dann noch nicht existiert, wenn das Kerning-Feature angewandt wird. Mein Lua-Feature sieht wie folgt aus:

{

name = "dashkern",

type = "kern",

data = {

["hyphen"] = { ["W"] = -100 },

},

}

}

Und jetzt die Frage aller Fragen: Wie lösen wir das Problem? Kann ich LuaLaTeX irgendwie beibiegen, das Feature zu einem späteren Zeitpunkt anzuwenden - sprich: Wenn "= bereits gegen den Bindestrich ausgetauscht ist?

Irgendwie erinnert mich das Basteln von Lua-Features immer so ein bisschen an das Sprachenlernen mit Duolingo. Man macht das nach, was man irgendwo findet (bzw. vorgeplappert kriegt), aber irgendwie findet sich kaum eine systematische Übersicht.

Bearbeitet ( von gyps_ruepelli)

Gelöst von Diwarnai

  • Lösung
Vor 49 Minuten, gyps_ruepelli schrieb:

Wie lösen wir das Problem?

Für solche Fragen ist ChatGPT prima, da bekommst du feinst aufgedröselt eine Lösung:

Kurzfassung vorweg: Ein OpenType-/Lua-Fontfeature ist dafür der falsche Ort. Fontfeatures werden angewandt, bevor aus dem Eingabestrom Diskretionsknoten (disc) mit einem realen Bindestrich entstehen. Du kannst das Feature nicht „nach hinten verschieben“. Die saubere Lösung ist, den Diskretionsknoten selbst zu behandeln, also auf LuaTeX-Node-Ebene nach der Umsetzung von = zu einem Trennstrich einzugreifen.

Jetzt etwas ausführlicher und systematisch.

  1. Was genau passiert technisch

– In der Eingabe erzeugt = keinen Glyphenknoten.
– LuaTeX erzeugt stattdessen einen disc-Knoten (discretionary).
– Erst bei der Zeilenumbruchphase wird daraus im „no-break“-Fall ein Glyphenknoten mit dem Hyphen-Zeichen der aktuellen Schrift.
– OpenType-Features (auch Lua-Features vom Typ kern) laufen deutlich früher, nämlich beim Aufbau der Glyphenliste aus Zeichen.
– Dein Feature sieht deshalb den Hyphen nie, weil es zu diesem Zeitpunkt schlicht keinen gibt.

Das ist kein Bug, sondern Teil der Pipeline. Ein Fontfeature kann prinzipiell nicht auf etwas reagieren, das erst später materialisiert wird.

  1. Warum „Feature später anwenden“ nicht geht

LuaLaTeX kennt keine Möglichkeit, ein Fontfeature nach der Diskretionsauflösung erneut auszuführen. Features sind an die Fontverarbeitung gekoppelt, nicht an den Zeilenumbruch. Es gibt also keinen Schalter wie „apply_feature_after_disc“.

  1. Der richtige Ansatz: disc-Knoten behandeln

Wenn du das Kerning zwischen Hyphen und folgendem W beeinflussen willst, musst du:
– auf Node-Ebene arbeiten
– einen Callback verwenden, der nach der Erzeugung der disc-Knoten läuft, aber bevor die finale Ausgabe erfolgt

Die üblichen Kandidaten sind:
– pre_linebreak_filter
– hpack_filter

In diesen Callbacks kannst du:

– disc-Knoten erkennen
– den „no_break“-Teil des disc untersuchen
– dort gezielt ein Kern-Node nach dem Hyphen-Glyph einfügen oder dessen Breite verändern

Konkret: Du prüfst, ob der disc im no_break-Fall einen Hyphen-Glyph erzeugt und ob direkt danach ein Glyph mit Unicode W (oder Glyph-ID von W) folgt. Dann fügst du einen Kern-Node mit negativer Breite ein.

  1. Skizze der Logik (konzeptionell, nicht als Drop-in-Code)

– Iteriere über die Node-Liste im pre_linebreak_filter.
– Wenn
node.id == disc:
– hole disc.nobrk
– prüfe, ob disc.nobrk mit einem Hyphen-Glyph beginnt
– prüfe den folgenden Node im Hauptstrom auf Glyph W
– füge zwischen Hyphen und W einen kern-Node ein

Damit arbeitest du exakt zu dem Zeitpunkt, an dem dein Problem real existiert.

  1. Alternative, wenn es nur um diesen einen Fall geht

Falls du wirklich nur „-W“ in genau diesem Kontext brauchst, gäbe es auch typografische Workarounds:

– explizites \kern nach dem = (unschön, aber robust)
– eigenes Makro für solche Zusammensetzungen
– oder ein fontinternes Paar für Hyphen+W und dann bewusst auf = verzichten

Aber technisch sauber und generalisierbar ist eindeutig der disc-Ansatz.

  1. Fazit

– Nein, ein Lua-Fontfeature kann nicht auf = reagieren und auch nicht „später“ ausgeführt werden.
– Dein Verständnis ist korrekt: Der Bindestrich existiert beim Feature-Lauf noch nicht.
– Die Lösung liegt nicht im Font, sondern im Node-Callback.
– pre_linebreak_filter oder hpack_filter sind der richtige Ort.
– Dort behandelst du disc-Knoten gezielt und fügst das gewünschte Kerning manuell ein.

Wenn du willst, kann ich dir im nächsten Schritt einen minimalen, funktionierenden Lua-Code für genau diesen disc-Fall formulieren, sagt ChatGPT …

  • Ersteller

Danke für die Antwort.

Was ich jetzt eben mal versucht habe ist tatsächlich, das Feature auf "=" umzuschreiben. Die Lösung ist laut ChatGPT unschön, aber sie funktioniert tatsächlich.

  • 3 Monate später...

Ich würde mir hier ein \NRW definieren und dabei gleich Haupttrennstellen festlegen:

\documentclass{article}

\usepackage[ngerman]{babel}

\usepackage{fontspec}

\setmainfont{AGaramondPro-Regular.otf}

\usepackage{microtype}

\usepackage{xspace}

\def\NRW{Nord\-rhein-West\-falen\xspace}

\directlua{fonts.handlers.otf.addfeature{

name = "ktest",

type = "kern",

data = {["-"] = { ["W"] = -100 }}}

}

\begin{document}

\huge

\NRW

\fbox{\parbox{5.5cm}{\NRW}}

\addfontfeature{RawFeature=+ktest}%

\NRW

\fbox{\parbox{5.5cm}{\NRW}}

\end{document}

Die Abbildung zeigt oben die Ausgabe ohne und unten mit neuem Kerning, jeweils ohne und mit Trennung.

Bildschirmfoto 2026-05-04 um 19.05.21.png

Bearbeitet ( von CrazyHorse)

Erstelle ein Konto, um zu kommentieren

Wichtige Informationen

Wir setzen Cookies, um die Benutzung der Seite zu verbessern. Du kannst die zugehörigen Einstellungen jederzeit anpassen. Ansonsten akzeptiere bitte diese Nutzung.

Konto

Navigation

Browser-Push-Nachrichten konfigurieren

Chrome (Android)
  1. Klicke das Schloss-Symbol neben der Adressleiste.
  2. Klicke Berechtigungen → Benachrichtigungen.
  3. Passe die Einstellungen nach deinen Wünschen an.
Chrome (Desktop)
  1. Klicke das Schloss-Symbol in der Adresszeile.
  2. Klicke Seiteneinstellungen.
  3. Finde Benachrichtigungen und passe sie nach deinen Wünschen an.