Hyphenation and line breaking
Papyra wraps text at measured glyph widths. Beyond whitespace, the line breaker understands three more kinds of break opportunity - two always on, one opt-in.
Soft hyphens (always on)
Section titled “Soft hyphens (always on)”Insert U+00AD (SOFT HYPHEN, \u00AD in C#) wherever a word may break. The character is invisible
in the output - unless the line actually breaks there, in which case a hyphen is drawn at the
line end:
doc.Paragraph(p => p.Text("Donau\u00ADdampf\u00ADschiff\u00ADfahrt"));A soft hyphen is only taken when the resulting prefix (including the hyphen) fits the line; otherwise the word behaves like any unbreakable word. In DOCX and HTML the soft hyphen passes through in the text - Word and browsers handle it natively.
No-break spaces (always on)
Section titled “No-break spaces (always on)”U+00A0 (no-break space), U+2007 (figure space), and U+202F (narrow no-break space) glue their
neighbors together: no line break, no justify-stretching. Use them for values that must not
separate, like 10\u00A0kg or Dr.\u00A0Meier. A zero-width space (U+200B) is the opposite -
an invisible break opportunity inside otherwise unbreakable text (URLs, long identifiers).
CJK line breaking (always on)
Section titled “CJK line breaking (always on)”Chinese, Japanese, and Korean text wraps between characters, with basic kinsoku shori: closing
punctuation (。, 、, 」, small kana, ー) never starts a line, and opening brackets (「, ()
never end one - the prohibited character wraps together with its neighbor.
Automatic hyphenation (opt-in)
Section titled “Automatic hyphenation (opt-in)”Hyphenation(language) enables TeX-pattern hyphenation for the whole document:
var document = Document.Create(doc => doc .PageSize(PageSize.A4) .Hyphenation("de") // or "de-AT", "en-US", … .Paragraph(p => p.Text("Donaudampfschifffahrtsgesellschaften " + "verbessern den Grauwert schmaler Spalten.")));Patterns are embedded for de, en, es, fr, it, nl, pt (the hyph-utf8 pattern sets; the primary
subtag selects the patterns, so "de-AT" uses the German set). An unsupported language throws at
compose time. Words break at pattern positions only when the line would otherwise wrap early or
overflow, and only when the prefix plus hyphen actually fits.
Rules worth knowing:
- Soft hyphens win. A word containing a soft hyphen breaks only at those author-chosen points - patterns are not consulted for it (TeX semantics).
- Pattern hyphenation applies to single-style, all-letter words. Words assembled across differently-styled spans, and words containing digits or other non-letters, are never pattern-hyphenated.
- An explicit
-is not a break opportunity.
Per-format behavior
Section titled “Per-format behavior”| Format | Behavior |
|---|---|
The layout engine breaks lines itself, so hyphens appear exactly where the patterns decided; the document language is declared as a catalog /Lang (PDF/A-friendly). |
|
| DOCX | Word re-wraps text, so Papyra declares intent natively: w:autoHyphenation plus the document language (w:lang in the style defaults). Word applies its own hyphenation dictionaries. |
| HTML | The browser wraps: the <html> element gets a real lang attribute and the document gets hyphens: auto. |
| XLSX | Excel reflows cell text itself and has no automatic hyphenation - the option is ignored. |
Because DOCX and HTML hyphenate with their own engines, the exact break positions can differ from the PDF - same language, same intent, each engine’s own dictionary.
© 2026 Stefan Nikolei. Payments are processed by Paddle.com as merchant of record.