Documentation
¶
Overview ¶
Package text provides Unicode-aware text measurement, wrapping, truncation, and alignment operations for terminal UIs and text layout engines.
This package coordinates multiple Unicode standards (UAX #11, #14, #29, #9, UTS #51) to provide practical text operations that are correct for CJK characters, emoji, combining marks, and bidirectional text.
Based on:
- UAX #11: East Asian Width (https://www.unicode.org/reports/tr11/)
- UAX #14: Line Breaking (https://www.unicode.org/reports/tr14/)
- UAX #29: Text Segmentation (https://www.unicode.org/reports/tr29/)
- UAX #9: Bidirectional Algorithm (https://www.unicode.org/reports/tr9/)
- UTS #51: Unicode Emoji (https://www.unicode.org/reports/tr51/)
Units ¶
All width measurements (MaxWidth, Width, Line.Width) are in "abstract units" determined by the MeasureFunc configuration:
- For terminals: character cells (1.0 per ASCII, 2.0 per CJK)
- For canvas: pixels (varies by font)
The package doesn't care about the unit semantics - it just accumulates whatever your MeasureFunc returns.
Quick Start ¶
import "github.com/SCKelemen/text"
// Create terminal text handler
txt := text.NewTerminal()
// Measure width (accounts for wide characters, emoji)
width := txt.Width("Hello 世界") // 9.0 cells
// Wrap text to fit width
lines := txt.Wrap("Long text here...", text.WrapOptions{
MaxWidth: 40, // 40 character cells
})
// Truncate with ellipsis
short := txt.Truncate("Very long text", text.TruncateOptions{
MaxWidth: 10, // 10 character cells
Strategy: text.TruncateEnd,
})
// Align text
aligned := txt.Align("Hello", 20, text.AlignCenter) // 20 cells total
Configuration ¶
The package is renderer-agnostic through the MeasureFunc configuration:
// Terminal: measure in cells
txt := text.New(text.Config{
MeasureFunc: text.TerminalMeasure,
})
// Canvas: measure in pixels (future)
txt := text.New(text.Config{
MeasureFunc: func(r rune) float64 {
return fontFace.GlyphAdvance(r)
},
})
Index ¶
- Constants
- func IsCJKIdeograph(r rune) bool
- func IsClosingFullwidthPunctuation(r rune) bool
- func IsClosingPunctuation(r rune) bool
- func IsFullwidthPunctuation(r rune) bool
- func IsHorizontalWritingMode(mode WritingMode) bool
- func IsIdeographic(r rune) bool
- func IsOpeningFullwidthPunctuation(r rune) bool
- func IsOpeningPunctuation(r rune) bool
- func IsStopPunctuation(r rune) bool
- func IsVerticalWritingMode(mode WritingMode) bool
- func TerminalMeasure(r rune) float64
- func TerminalMeasureEastAsian(r rune) float64
- type Alignment
- type AutospaceFlags
- type BidiClass
- type CSSTextBounds
- type CSSTextStyle
- type CSSWrapOptions
- type Config
- type DictionaryProvider
- type Direction
- type ElideContext
- type EmptyDictionary
- type EnglishDictionary
- func (d *EnglishDictionary) AddAbbreviation(abbrev string)
- func (d *EnglishDictionary) AddAbbreviations(abbrevs []string)
- func (d *EnglishDictionary) GetHyphenationPoints(word string) []int
- func (d *EnglishDictionary) IsAbbreviation(word string) bool
- func (d *EnglishDictionary) IsCompoundWord(word string) bool
- type EnglishDictionaryWithHyphenation
- type FontMetrics
- type HangingPunctuation
- type HyphenationDictionary
- func NewDanishHyphenation() *HyphenationDictionary
- func NewEnglishHyphenation() *HyphenationDictionary
- func NewFrenchHyphenation() *HyphenationDictionary
- func NewGermanHyphenation() *HyphenationDictionary
- func NewHyphenationDictionary(patterns map[string]string, minLeft, minRight int) *HyphenationDictionary
- func NewNorwegianHyphenation() *HyphenationDictionary
- func NewSpanishHyphenation() *HyphenationDictionary
- func NewSwedishHyphenation() *HyphenationDictionary
- type Hyphens
- type IntrinsicSize
- type KnuthPlassOptions
- type Line
- type LineBoxMetrics
- type LineBreak
- type MeasureFunc
- type Metrics
- type OverflowWrap
- type PhraseBreaker
- type TabSize
- type TabSizeUnit
- type Text
- func (t *Text) Align(text string, width float64, align Alignment) string
- func (t *Text) AlignLines(lines []Line, width float64, style CSSTextStyle) []Line
- func (t *Text) AlignWithDirection(text string, width float64, align Alignment, direction Direction, ...) string
- func (t *Text) ApplyAutospace(text string, flags AutospaceFlags) string
- func (t *Text) ApplyAutospaceMode(text string, mode TextAutospace) string
- func (t *Text) ApplyTextOverflow(text string, maxWidth float64, style CSSTextStyle) string
- func (t *Text) CharOrientation(r rune, orientation TextOrientation) uax50.Orientation
- func (t *Text) DetectDirection(text string) uax9.Direction
- func (t *Text) Elide(text string, maxWidth float64) string
- func (t *Text) ElideAuto(text string, maxWidth float64) string
- func (t *Text) ElideEnd(text string, maxWidth float64) string
- func (t *Text) ElideEndUnicode(text string, maxWidth float64) string
- func (t *Text) ElideEndWith(text string, maxWidth float64, ellipsis string) string
- func (t *Text) ElideForContext(text string, maxWidth float64, context ElideContext) string
- func (t *Text) ElidePath(path string, maxWidth float64) string
- func (t *Text) ElideStart(text string, maxWidth float64) string
- func (t *Text) ElideStartUnicode(text string, maxWidth float64) string
- func (t *Text) ElideStartWith(text string, maxWidth float64, ellipsis string) string
- func (t *Text) ElideURL(url string, maxWidth float64) string
- func (t *Text) ElideUnicode(text string, maxWidth float64) string
- func (t *Text) ElideWith(text string, maxWidth float64, ellipsis string) string
- func (t *Text) ExpandTabs(text string, tabSize TabSize) string
- func (t *Text) GetBidiClass(r rune) BidiClass
- func (t *Text) GraphemeAt(text string, index int) string
- func (t *Text) GraphemeCount(text string) int
- func (t *Text) Graphemes(text string) []string
- func (t *Text) IntrinsicSizing(text string) IntrinsicSize
- func (t *Text) IsRotated(r rune, style VerticalTextStyle) bool
- func (t *Text) IsUpright(r rune, style VerticalTextStyle) bool
- func (t *Text) JustifyText(text string, targetWidth float64, method TextJustify) string
- func (t *Text) LineContainingPosition(lines []Line, position int) int
- func (t *Text) MeasureCSS(text string, cssOpts CSSWrapOptions, textStyle TextStyle) CSSTextBounds
- func (t *Text) MeasureLineBox(text string, style TextStyle) LineBoxMetrics
- func (t *Text) MeasureMultiLine(text string, wrapOpts WrapOptions, style TextStyle) TextBounds
- func (t *Text) MeasureVertical(text string, style VerticalTextStyle) VerticalMetrics
- func (t *Text) MirrorBrackets(text string) string
- func (t *Text) PositionToXOffset(line Line, position int) float64
- func (t *Text) ProcessWhiteSpace(text string, whiteSpace WhiteSpace) (processed string, allowWrap bool)
- func (t *Text) Reorder(text string) string
- func (t *Text) ReorderLine(text string, direction Direction) string
- func (t *Text) ReorderParagraph(text string, baseDirection Direction) string
- func (t *Text) ReorderWithDirection(text string, dir uax9.Direction) string
- func (t *Text) SentenceCount(text string) int
- func (t *Text) SentenceCountWithDictionary(text string, dict DictionaryProvider) int
- func (t *Text) Sentences(text string) []string
- func (t *Text) SentencesWithDictionary(text string, dict DictionaryProvider) []string
- func (t *Text) ShouldHang(text string, position int, mode HangingPunctuation) (shouldHang bool, hangWidth float64)
- func (t *Text) Transform(text string, transform TextTransform) string
- func (t *Text) TrimCJKSpacing(text string, mode TextSpacingTrim) string
- func (t *Text) Truncate(text string, opts TruncateOptions) string
- func (t *Text) Width(s string) float64
- func (t *Text) WidthBytes(b []byte) float64
- func (t *Text) WidthMany(strings []string) []float64
- func (t *Text) WidthRange(s string, start, end int) float64
- func (t *Text) WidthUpTo(s string, maxWidth float64) (width float64, exceeded bool)
- func (t *Text) WithFontMetrics(fm FontMetrics) *Text
- func (t *Text) WordCount(text string) int
- func (t *Text) Words(text string) []string
- func (t *Text) Wrap(text string, opts WrapOptions) []Line
- func (t *Text) WrapBalanced(text string, maxWidth float64) []Line
- func (t *Text) WrapCSS(text string, opts CSSWrapOptions) []Line
- func (t *Text) WrapKnuthPlass(text string, opts KnuthPlassOptions) []Line
- func (t *Text) WrapPretty(text string, maxWidth float64) []Line
- func (t *Text) WrapVertical(text string, opts VerticalWrapOptions) []VerticalLine
- func (t *Text) WrapWithControls(text string, maxWidth float64, controls []WrapPoint) []Line
- func (t *Text) WrapWithPhrases(text string, maxWidth float64, breaker PhraseBreaker) []Line
- func (t *Text) WrapWithPhrasesAndControls(text string, maxWidth float64, breaker PhraseBreaker, controls []WrapPoint) []Line
- func (t *Text) XOffsetToPosition(line Line, xOffset float64) XOffsetInfo
- type TextAutospace
- type TextBounds
- type TextCombineUpright
- type TextConfig
- type TextIndent
- type TextJustify
- type TextOrientation
- type TextOverflow
- type TextSpacingTrim
- type TextStyle
- type TextTransform
- type TextWrap
- type TextWrapMode
- type TextWrapStyle
- type TruncateOptions
- type TruncateStrategy
- type VerticalLine
- type VerticalMetrics
- type VerticalTextStyle
- type VerticalWrapOptions
- type WhiteSpace
- type WhiteSpaceCollapse
- type WhiteSpaceTrim
- type WordBreak
- type WordSpaceTransform
- type WrapControl
- type WrapInside
- type WrapOptions
- type WrapPoint
- type WritingMode
- type XOffsetInfo
Constants ¶
const ( // Strong types ClassL = uax9.ClassL // Left-to-Right ClassR = uax9.ClassR // Right-to-Left ClassAL = uax9.ClassAL // Right-to-Left Arabic // Weak types ClassEN = uax9.ClassEN // European Number ClassES = uax9.ClassES // European Number Separator ClassET = uax9.ClassET // European Number Terminator ClassAN = uax9.ClassAN // Arabic Number ClassCS = uax9.ClassCS // Common Number Separator ClassNSM = uax9.ClassNSM // Nonspacing Mark ClassBN = uax9.ClassBN // Boundary Neutral // Neutral types ClassB = uax9.ClassB // Paragraph Separator ClassS = uax9.ClassS // Segment Separator ClassWS = uax9.ClassWS // Whitespace ClassON = uax9.ClassON // Other Neutrals // Explicit formatting types ClassLRE = uax9.ClassLRE // Left-to-Right Embedding ClassLRO = uax9.ClassLRO // Left-to-Right Override ClassRLE = uax9.ClassRLE // Right-to-Left Embedding ClassRLO = uax9.ClassRLO // Right-to-Left Override ClassPDF = uax9.ClassPDF // Pop Directional Format ClassLRI = uax9.ClassLRI // Left-to-Right Isolate ClassRLI = uax9.ClassRLI // Right-to-Left Isolate ClassFSI = uax9.ClassFSI // First Strong Isolate ClassPDI = uax9.ClassPDI // Pop Directional Isolate )
Bidirectional character classes (re-exported from uax9)
Variables ¶
This section is empty.
Functions ¶
func IsCJKIdeograph ¶
IsCJKIdeograph returns true if the rune is a CJK ideograph.
func IsClosingFullwidthPunctuation ¶
IsClosingFullwidthPunctuation returns true if the rune is closing fullwidth punctuation.
func IsClosingPunctuation ¶
IsClosingPunctuation returns true if the rune is closing punctuation.
func IsFullwidthPunctuation ¶
IsFullwidthPunctuation returns true if the rune is fullwidth punctuation.
func IsHorizontalWritingMode ¶
func IsHorizontalWritingMode(mode WritingMode) bool
IsHorizontalWritingMode returns true if the writing mode is horizontal.
func IsIdeographic ¶
IsIdeographic returns true if the rune is an ideographic character. Includes CJK ideographs, Hiragana, Katakana, and Hangul.
func IsOpeningFullwidthPunctuation ¶
IsOpeningFullwidthPunctuation returns true if the rune is opening fullwidth punctuation.
func IsOpeningPunctuation ¶
IsOpeningPunctuation returns true if the rune is opening punctuation.
func IsStopPunctuation ¶
IsStopPunctuation returns true if the rune is a stop/comma.
func IsVerticalWritingMode ¶
func IsVerticalWritingMode(mode WritingMode) bool
IsVerticalWritingMode returns true if the writing mode is vertical.
func TerminalMeasure ¶
TerminalMeasure measures characters in terminal cells.
Returns:
- 2 for wide characters (CJK ideographs, fullwidth, emoji)
- 1 for narrow characters (ASCII, halfwidth)
- 0 for zero-width characters (combining marks, ZWJ, variation selectors, emoji modifiers)
Uses UAX #11 with ContextNarrow (ambiguous characters treated as narrow). UTS #51 takes precedence for emoji characters.
func TerminalMeasureEastAsian ¶
TerminalMeasureEastAsian measures characters in terminal cells with East Asian context.
Same as TerminalMeasure but treats ambiguous characters as wide (2 cells). Use this for terminals with East Asian locales (Chinese, Japanese, Korean).
Types ¶
type Alignment ¶
type Alignment int
Alignment specifies text alignment.
Specification:
- CSS Text Level 3: https://www.w3.org/TR/css-text-3/#text-align-property
- CSS Text Level 3 (text-align-last): https://www.w3.org/TR/css-text-3/#text-align-last-property
- MDN text-align: https://developer.mozilla.org/en-US/docs/Web/CSS/text-align
- MDN text-align-last: https://developer.mozilla.org/en-US/docs/Web/CSS/text-align-last
const ( // AlignLeft aligns text to the left (physical direction). AlignLeft Alignment = iota // AlignCenter centers text. AlignCenter // AlignRight aligns text to the right (physical direction). AlignRight // AlignJustify distributes padding between words. AlignJustify // AlignStart aligns text to the start edge (flow-relative). // Left in LTR, right in RTL. AlignStart // AlignEnd aligns text to the end edge (flow-relative). // Right in LTR, left in RTL. AlignEnd // AlignMatchParent inherits parent's alignment, computed for direction. AlignMatchParent )
type AutospaceFlags ¶
type AutospaceFlags int
AutospaceFlags specifies which autospace features to apply.
const ( // AutospaceNone disables all autospace features. AutospaceNone AutospaceFlags = 0 // AutospaceIdeographAlpha adds spacing between ideographic and non-ideographic characters. AutospaceIdeographAlpha AutospaceFlags = 1 << 0 // AutospaceIdeographNumeric adds spacing between ideographic and numeric characters. AutospaceIdeographNumeric AutospaceFlags = 1 << 1 // AutospacePunctuation adjusts spacing around fullwidth punctuation. AutospacePunctuation AutospaceFlags = 1 << 2 // AutospaceAll enables all autospace features. AutospaceAll = AutospaceIdeographAlpha | AutospaceIdeographNumeric | AutospacePunctuation )
type CSSTextBounds ¶
type CSSTextBounds struct {
TextBounds
// CSS intrinsic sizes
Intrinsic IntrinsicSize
// Applied spacing
LetterSpacing units.Length
WordSpacing units.Length
TextIndent TextIndent
}
CSSTextBounds extends TextBounds with CSS-specific measurements.
type CSSTextStyle ¶
type CSSTextStyle struct {
// White space handling
WhiteSpace WhiteSpace
// Text transformation
TextTransform TextTransform
// Word and line breaking
WordBreak WordBreak
LineBreak LineBreak
OverflowWrap OverflowWrap
Hyphens Hyphens
// Text overflow (CSS Overflow Module)
// https://drafts.csswg.org/css-overflow/#text-overflow
TextOverflow TextOverflow // How to handle overflow (applies to both ends if TextOverflowEnd not set)
TextOverflowEnd TextOverflow // How to handle overflow at end (if different from start)
TextOverflowClipString string // Custom string for clip mode
TextOverflowEllipsisString string // Custom ellipsis string (default: "...")
// Spacing (using CSS length units)
LetterSpacing units.Length // Additional spacing between characters
WordSpacing units.Length // Additional spacing between words
// Indentation and alignment
TextIndent TextIndent // First line indentation (supports hanging, each-line)
TextAlign Alignment // Horizontal alignment
TextAlignLast Alignment // Alignment of last line (justify becomes start)
VerticalAlign Alignment // Vertical alignment within line box
Direction Direction // Text direction (LTR, RTL, Auto)
// Hanging punctuation (CSS Text Level 3 §6)
HangingPunctuation HangingPunctuation // Controls punctuation hanging outside line box
// Text spacing trim (CSS Text Level 4)
TextSpacingTrim TextSpacingTrim // Controls CJK spacing trimming
}
CSSTextStyle represents CSS text properties for text layout.
func DefaultCSSTextStyle ¶
func DefaultCSSTextStyle() CSSTextStyle
DefaultCSSTextStyle returns a CSSTextStyle with default values matching CSS defaults.
type CSSWrapOptions ¶
type CSSWrapOptions struct {
MaxWidth units.Length
Style CSSTextStyle
}
CSSWrapOptions extends WrapOptions with CSS text properties.
type Config ¶
type Config struct {
// MeasureFunc measures the width of a single rune in abstract units.
// For terminals: returns 1 or 2 (cells)
// For canvas: returns pixel width from font metrics
MeasureFunc MeasureFunc
// AmbiguousAsWide determines UAX #11 context for ambiguous width characters.
// Set to true for East Asian contexts (Chinese, Japanese, Korean).
// Set to false (default) for non-East Asian contexts.
AmbiguousAsWide bool
// HyphenationMode specifies UAX #14 line breaking preferences.
HyphenationMode uax14.Hyphens
// BaseDirection specifies the default paragraph direction for UAX #9.
BaseDirection uax9.Direction
}
Config configures text measurement and layout behavior.
type DictionaryProvider ¶
type DictionaryProvider interface {
// IsAbbreviation returns true if the word is a known abbreviation.
// This is used to prevent sentence breaks after abbreviated words.
//
// Example: "Dr." -> true, "Mr." -> true, "hello" -> false
IsAbbreviation(word string) bool
// GetHyphenationPoints returns hyphenation points for a word.
// Returns slice of byte indices where hyphenation is allowed.
//
// Example: "example" -> []int{2, 4} (ex-am-ple)
GetHyphenationPoints(word string) []int
// IsCompoundWord returns true if the word is a compound that shouldn't be broken.
// Used for language-specific compound word handling.
//
// Example: "JavaScript" -> true
IsCompoundWord(word string) bool
}
DictionaryProvider provides domain-specific dictionaries for text segmentation.
This allows extending UAX #29 sentence and word boundary detection with: - Common abbreviations (Dr., Mrs., Ph.D., etc.) - Language-specific rules - Domain-specific terminology - Hyphenation patterns
type Direction ¶
type Direction int
Direction specifies text directionality (LTR or RTL).
Specification:
- CSS Writing Modes Level 3: https://www.w3.org/TR/css-writing-modes-3/#direction
- MDN direction: https://developer.mozilla.org/en-US/docs/Web/CSS/direction
type ElideContext ¶
type ElideContext int
ElideContext represents different elision contexts.
const ( // ElideContextGeneral is for general text (middle elision). ElideContextGeneral ElideContext = iota // ElideContextPath is for file paths (preserve filename). ElideContextPath // ElideContextURL is for URLs (preserve domain). ElideContextURL // ElideContextEmail is for email addresses (preserve domain). ElideContextEmail // ElideContextDescription is for descriptions (end elision). ElideContextDescription // ElideContextCode is for code identifiers (middle elision). ElideContextCode )
type EmptyDictionary ¶
type EmptyDictionary struct{}
EmptyDictionary provides no dictionary support (pure UAX #29).
func (*EmptyDictionary) GetHyphenationPoints ¶
func (d *EmptyDictionary) GetHyphenationPoints(word string) []int
GetHyphenationPoints always returns nil.
func (*EmptyDictionary) IsAbbreviation ¶
func (d *EmptyDictionary) IsAbbreviation(word string) bool
IsAbbreviation always returns false.
func (*EmptyDictionary) IsCompoundWord ¶
func (d *EmptyDictionary) IsCompoundWord(word string) bool
IsCompoundWord always returns false.
type EnglishDictionary ¶
type EnglishDictionary struct {
// contains filtered or unexported fields
}
EnglishDictionary provides common English abbreviations and rules.
func NewEnglishDictionary ¶
func NewEnglishDictionary() *EnglishDictionary
NewEnglishDictionary creates a dictionary with common English abbreviations.
func (*EnglishDictionary) AddAbbreviation ¶
func (d *EnglishDictionary) AddAbbreviation(abbrev string)
AddAbbreviation adds a custom abbreviation to the dictionary.
func (*EnglishDictionary) AddAbbreviations ¶
func (d *EnglishDictionary) AddAbbreviations(abbrevs []string)
AddAbbreviations adds multiple custom abbreviations.
func (*EnglishDictionary) GetHyphenationPoints ¶
func (d *EnglishDictionary) GetHyphenationPoints(word string) []int
GetHyphenationPoints implements DictionaryProvider. Returns empty slice for now - hyphenation requires more complex rules.
Future enhancement: Implement Liang's TeX hyphenation algorithm with language-specific pattern dictionaries.
func (*EnglishDictionary) IsAbbreviation ¶
func (d *EnglishDictionary) IsAbbreviation(word string) bool
IsAbbreviation implements DictionaryProvider.
func (*EnglishDictionary) IsCompoundWord ¶
func (d *EnglishDictionary) IsCompoundWord(word string) bool
IsCompoundWord implements DictionaryProvider.
type EnglishDictionaryWithHyphenation ¶
type EnglishDictionaryWithHyphenation struct {
*EnglishDictionary
// contains filtered or unexported fields
}
EnglishDictionaryWithHyphenation extends EnglishDictionary with hyphenation.
func NewEnglishDictionaryWithHyphenation ¶
func NewEnglishDictionaryWithHyphenation() *EnglishDictionaryWithHyphenation
NewEnglishDictionaryWithHyphenation creates a full-featured English dictionary.
func (*EnglishDictionaryWithHyphenation) GetHyphenationPoints ¶
func (d *EnglishDictionaryWithHyphenation) GetHyphenationPoints(word string) []int
GetHyphenationPoints implements DictionaryProvider with actual hyphenation.
type FontMetrics ¶
type FontMetrics interface {
// Ascent returns the distance from baseline to top of tallest glyph.
Ascent() float64
// Descent returns the distance from baseline to bottom of lowest glyph.
Descent() float64
// LineGap returns the recommended line spacing (leading).
LineGap() float64
// CapHeight returns the height of capital letters.
CapHeight() float64
// XHeight returns the height of lowercase 'x'.
XHeight() float64
// UnitsPerEm returns the font's units per em.
UnitsPerEm() float64
}
FontMetrics provides actual font measurements.
This interface allows integration with font rendering libraries that can provide real font metrics (not just approximations).
For future integration with: - freetype-go - golang.org/x/image/font - harfbuzz bindings
type HangingPunctuation ¶
type HangingPunctuation int
HangingPunctuation controls whether punctuation can hang outside the line box.
Specification:
- CSS Text Level 3: https://www.w3.org/TR/css-text-3/#hanging-punctuation-property
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/hanging-punctuation
const ( // HangingPunctuationNone disables hanging punctuation. HangingPunctuationNone HangingPunctuation = 0 // HangingPunctuationFirst allows opening brackets/quotes to hang at start. HangingPunctuationFirst HangingPunctuation = 1 << 0 // HangingPunctuationLast allows closing brackets/quotes to hang at end. HangingPunctuationLast HangingPunctuation = 1 << 1 // HangingPunctuationForceEnd allows stops/commas to hang at end if needed. HangingPunctuationForceEnd HangingPunctuation = 1 << 2 // HangingPunctuationAllowEnd allows stops/commas to hang at end if they don't fit. HangingPunctuationAllowEnd HangingPunctuation = 1 << 3 )
type HyphenationDictionary ¶
type HyphenationDictionary struct {
// contains filtered or unexported fields
}
HyphenationDictionary provides hyphenation patterns for a language.
Users can create custom dictionaries by loading patterns from TeX hyphen files: https://github.com/hyphenation/tex-hyphen
Example:
dict := text.NewHyphenationDictionary(myPatterns, 2, 3)
points := dict.Hyphenate("example")
func NewDanishHyphenation ¶
func NewDanishHyphenation() *HyphenationDictionary
NewDanishHyphenation creates a hyphenation dictionary with Danish patterns.
func NewEnglishHyphenation ¶
func NewEnglishHyphenation() *HyphenationDictionary
NewEnglishHyphenation creates a hyphenation dictionary with English (US) patterns.
Provides decent coverage for common English words. For comprehensive hyphenation, load full TeX patterns: https://github.com/hyphenation/tex-hyphen/tree/master/hyph-utf8/tex/generic/hyph-utf8/patterns/txt
func NewFrenchHyphenation ¶
func NewFrenchHyphenation() *HyphenationDictionary
NewFrenchHyphenation creates a hyphenation dictionary with French patterns.
func NewGermanHyphenation ¶
func NewGermanHyphenation() *HyphenationDictionary
NewGermanHyphenation creates a hyphenation dictionary with German patterns.
func NewHyphenationDictionary ¶
func NewHyphenationDictionary(patterns map[string]string, minLeft, minRight int) *HyphenationDictionary
NewHyphenationDictionary creates a custom hyphenation dictionary.
Parameters:
- patterns: Map of hyphenation patterns (see Liang's algorithm)
- minLeft: Minimum characters required on left side of hyphen
- minRight: Minimum characters required on right side of hyphen
Example:
patterns := map[string]string{
"ex1am": "ex1am", // Allow break after "ex"
"ta1ble": "ta1ble", // Allow break after "ta"
}
dict := text.NewHyphenationDictionary(patterns, 2, 3)
func NewNorwegianHyphenation ¶
func NewNorwegianHyphenation() *HyphenationDictionary
NewNorwegianHyphenation creates a hyphenation dictionary with Norwegian patterns.
func NewSpanishHyphenation ¶
func NewSpanishHyphenation() *HyphenationDictionary
NewSpanishHyphenation creates a hyphenation dictionary with Spanish patterns.
func NewSwedishHyphenation ¶
func NewSwedishHyphenation() *HyphenationDictionary
NewSwedishHyphenation creates a hyphenation dictionary with Swedish patterns.
func (*HyphenationDictionary) Hyphenate ¶
func (h *HyphenationDictionary) Hyphenate(word string) []int
Hyphenate returns hyphenation points for a word using Liang's algorithm.
Returns byte indices where hyphenation is allowed. Uses pattern matching with priority levels to determine break points.
Example:
dict := text.NewEnglishHyphenation()
points := dict.Hyphenate("example")
// Returns []int{2, 4} for ex-am-ple
func (*HyphenationDictionary) HyphenateWithString ¶
func (h *HyphenationDictionary) HyphenateWithString(word, hyphen string) string
HyphenateWithString returns the hyphenated word with hyphens inserted.
Example:
dict := text.NewEnglishHyphenation()
result := dict.HyphenateWithString("example", "-")
// Returns "ex-am-ple"
type IntrinsicSize ¶
type IntrinsicSize struct {
// MinContent is the minimum width without overflow.
// This is the width of the longest word/grapheme cluster.
MinContent float64
// MaxContent is the width if the text never wraps.
// This is the total width of all text on a single line.
MaxContent float64
// PreferredWidth is a suggested width for comfortable reading.
// For text, this is typically around 60-80 characters.
PreferredWidth float64
}
IntrinsicSize represents the intrinsic dimensions of text.
Based on CSS Box Sizing Module Level 3: https://www.w3.org/TR/css-sizing-3/#intrinsic-sizes
type KnuthPlassOptions ¶
type KnuthPlassOptions struct {
// MaxWidth is the target line width
MaxWidth float64
// Tolerance controls how much stretch/shrink is acceptable
// Higher values allow more variation in line lengths
// Default: 1.0 (TeX uses 1.0)
Tolerance float64
// FitnessClass controls which fitness classes are compatible
// Prevents mixing very tight and very loose lines adjacent to each other
// Default: true
FitnessClass bool
// Hyphenate enables hyphenation for better line breaks
// Default: false
Hyphenate bool
// HyphenPenalty is the penalty for breaking at a hyphen
// Default: 50
HyphenPenalty float64
// LinePenalty is the penalty for each line (encourages fewer lines)
// Default: 10
LinePenalty float64
}
KnuthPlassOptions configures the Knuth-Plass line breaking algorithm.
func DefaultKnuthPlassOptions ¶
func DefaultKnuthPlassOptions(maxWidth float64) KnuthPlassOptions
DefaultKnuthPlassOptions returns sensible defaults.
type Line ¶
type Line struct {
// Content is the text content of the line.
Content string
// Width is the display width of the line in abstract units.
// For terminals: character cells
// For canvas: pixels
Width float64
// Start is the rune index in the original text where this line starts.
Start int
// End is the rune index in the original text where this line ends.
End int
}
Line represents a wrapped line of text.
type LineBoxMetrics ¶
type LineBoxMetrics struct {
// Content dimensions
Width float64 // Content width (advance)
Content string // Text content
// Baseline and vertical metrics (in abstract units)
Ascent float64 // Distance above baseline
Descent float64 // Distance below baseline
Leading float64 // Extra space distributed above/below
// Line box dimensions
LineHeight float64 // Total line height (ascent + descent + leading)
Baseline float64 // Position of baseline from top
// Position in source text
Start int // Rune index in original text
End int // Rune index in original text
}
LineBoxMetrics provides complete metrics for a single line of text.
Based on CSS Inline Layout Module: https://www.w3.org/TR/css-inline-3/#line-box
type LineBreak ¶
type LineBreak int
LineBreak controls line breaking strictness for CJK text.
Specification:
- CSS Text Level 3: https://www.w3.org/TR/css-text-3/#line-break-property
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/line-break
const ( // LineBreakAuto uses the default line breaking rule. LineBreakAuto LineBreak = iota // LineBreakLoose uses the least restrictive line break rule. // Allows breaks at more positions. LineBreakLoose // LineBreakNormal uses the common line break rule. LineBreakNormal // LineBreakStrict uses the most restrictive line break rule. // Follows traditional typography rules strictly. LineBreakStrict // LineBreakAnywhere allows breaks at any character, even within words. LineBreakAnywhere )
type MeasureFunc ¶
MeasureFunc measures the width of a single rune in abstract units.
For terminal rendering, it should return 1 or 2 (character cells). For pixel-based rendering, it should return the actual pixel width.
type Metrics ¶
type Metrics struct {
// contains filtered or unexported fields
}
Metrics implements layout.TextMetricsProvider for integration with the layout engine.
Example:
// Create metrics for terminal rendering
metrics := text.NewMetrics(text.Config{
MeasureFunc: text.TerminalMeasure,
})
// In your layout engine setup:
layout.SetTextMetricsProvider(metrics)
func NewMetrics ¶
NewMetrics creates a layout-compatible metrics provider.
func NewTerminalMetrics ¶
func NewTerminalMetrics() *Metrics
NewTerminalMetrics creates metrics configured for terminal rendering.
func (*Metrics) Measure ¶
Measure implements layout.TextMetricsProvider interface.
Returns:
- advance: The display width of the text
- ascent: The distance above the baseline (for line height calculation)
- descent: The distance below the baseline (for line height calculation)
For terminal rendering:
- advance is measured in character cells
- ascent/descent are proportional to line height for proper spacing
func (*Metrics) Text ¶
Text returns the underlying Text instance for direct access to text operations.
This allows using all text.Text methods (Wrap, Truncate, Align, etc.) alongside the metrics provider.
Example:
metrics := text.NewTerminalMetrics()
layout.SetTextMetricsProvider(metrics)
// Also use for direct text operations
txt := metrics.Text()
truncated := txt.Truncate("Long text...", text.TruncateOptions{
MaxWidth: 40,
})
type OverflowWrap ¶
type OverflowWrap int
OverflowWrap controls whether to break within words to prevent overflow.
Specification:
- CSS Text Level 3: https://www.w3.org/TR/css-text-3/#overflow-wrap-property
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-wrap
const ( // OverflowWrapNormal breaks only at allowed break points. OverflowWrapNormal OverflowWrap = iota // OverflowWrapBreakWord breaks within words if necessary to prevent overflow. OverflowWrapBreakWord // OverflowWrapAnywhere breaks at any point if necessary. OverflowWrapAnywhere )
type PhraseBreaker ¶
type PhraseBreaker interface {
// FindPhrases returns phrase boundary positions (rune indices).
// Positions should be sorted and include 0 as the first position.
//
// Example: "你好世界" might return [0, 2, 4] for "你好" and "世界"
FindPhrases(text string) []int
}
PhraseBreaker is an interface for language-specific phrase segmentation.
This enables word-break: auto-phrase for CJK languages by allowing users to provide their own dictionary/ML-based segmentation.
Specification:
- CSS Text Level 4: https://www.w3.org/TR/css-text-4/#word-break-property
- MDN word-break: https://developer.mozilla.org/en-US/docs/Web/CSS/word-break
- web.dev CJK Breaking: https://web.dev/learn/css/typography/#line-breaking
Users should integrate external libraries for phrase breaking:
- Chinese: jieba, pkuseg, HanLP
- Japanese: MeCab, kuromoji, Sudachi
- Korean: KoNLPy, Mecab-ko
- Thai: ICU, libthai
Example:
type MyJiebaBreaker struct {
segmenter *jieba.Segmenter
}
func (j *MyJiebaBreaker) FindPhrases(text string) []int {
segments := j.segmenter.Cut(text, true)
positions := []int{0}
offset := 0
for _, seg := range segments {
offset += len([]rune(seg))
positions = append(positions, offset)
}
return positions
}
breaker := &MyJiebaBreaker{segmenter: jieba.NewSegmenter()}
lines := txt.WrapWithPhrases("你好世界", 20, breaker)
type TabSize ¶
type TabSize struct {
// Value is the tab width
Value float64
// Unit determines if Value is spaces or a length
Unit TabSizeUnit
}
TabSize controls the width of tab characters.
Specification:
- CSS Text Level 3: https://www.w3.org/TR/css-text-3/#tab-size-property
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/tab-size
func DefaultTabSize ¶
func DefaultTabSize() TabSize
DefaultTabSize returns the default tab size (8 spaces).
type TabSizeUnit ¶
type TabSizeUnit int
TabSizeUnit specifies how tab size is measured.
const ( // TabSizeSpaces measures tabs in number of space characters. TabSizeSpaces TabSizeUnit = iota // TabSizeLength measures tabs in CSS length units. TabSizeLength )
type Text ¶
type Text struct {
// contains filtered or unexported fields
}
Text provides high-level Unicode-aware text operations.
func NewTerminal ¶
func NewTerminal() *Text
NewTerminal creates a Text instance configured for terminal rendering.
Uses:
- TerminalMeasure for width calculation (1 or 2 cells)
- ContextNarrow for UAX #11 ambiguous characters
- Manual hyphenation for UAX #14
- LTR base direction for UAX #9
func NewTerminalEastAsian ¶
func NewTerminalEastAsian() *Text
NewTerminalEastAsian creates a Text instance configured for East Asian terminals.
Same as NewTerminal but treats ambiguous characters as wide (2 cells).
func (*Text) Align ¶
Align pads text to a specific width with the specified alignment. For flow-relative alignment (start/end), assumes LTR direction. Use AlignWithDirection for RTL support.
The width parameter is in abstract units (cells for terminals, pixels for canvas).
Example:
txt := text.NewTerminal()
aligned := txt.Align("Hello", 20, text.AlignCenter)
fmt.Printf("|%s|", aligned) // "| Hello |" (20 cells total)
func (*Text) AlignLines ¶
func (t *Text) AlignLines(lines []Line, width float64, style CSSTextStyle) []Line
AlignLines aligns multiple lines according to CSS text-align and text-align-last properties.
Based on CSS Text Module Level 3: - text-align: https://www.w3.org/TR/css-text-3/#text-align-property - text-align-last: https://www.w3.org/TR/css-text-3/#text-align-last-property
Example:
lines := []Line{
{Content: "First line", Width: 10},
{Content: "Second line", Width: 11},
{Content: "Last", Width: 4},
}
aligned := txt.AlignLines(lines, 20.0, text.CSSTextStyle{
TextAlign: text.AlignJustify,
TextAlignLast: text.AlignLeft,
})
func (*Text) AlignWithDirection ¶
func (t *Text) AlignWithDirection(text string, width float64, align Alignment, direction Direction, parentAlign Alignment) string
AlignWithDirection pads text to a specific width with the specified alignment, respecting text direction for flow-relative alignments (start/end/match-parent).
Parameters:
- text: The text to align
- width: The target width
- align: The alignment mode
- direction: Text direction (LTR, RTL, or Auto)
- parentAlign: Parent's alignment (used for match-parent)
Example:
txt := text.NewTerminal()
// In RTL context, start means right
aligned := txt.AlignWithDirection("مرحبا", 20, text.AlignStart, text.DirectionRTL, text.AlignLeft)
func (*Text) ApplyAutospace ¶
func (t *Text) ApplyAutospace(text string, flags AutospaceFlags) string
ApplyAutospace applies automatic spacing according to text-autospace rules.
Example:
txt := text.NewTerminal()
result := txt.ApplyAutospace("Hello世界123", text.AutospaceAll)
// Returns "Hello 世界 123" (with spacing between scripts)
func (*Text) ApplyAutospaceMode ¶
func (t *Text) ApplyAutospaceMode(text string, mode TextAutospace) string
ApplyAutospaceMode applies text-autospace with predefined mode.
func (*Text) ApplyTextOverflow ¶
func (t *Text) ApplyTextOverflow(text string, maxWidth float64, style CSSTextStyle) string
ApplyTextOverflow applies CSS text-overflow property to text that exceeds maxWidth.
Based on CSS Overflow Module Level 3 §3: https://drafts.csswg.org/css-overflow/#text-overflow
Example:
txt := text.NewTerminal()
result := txt.ApplyTextOverflow("Very long text here", 15, text.CSSTextStyle{
TextOverflow: text.TextOverflowEllipsis,
TextOverflowEllipsisString: "…",
})
// Returns: "Very long t…"
func (*Text) CharOrientation ¶
func (t *Text) CharOrientation(r rune, orientation TextOrientation) uax50.Orientation
CharOrientation returns the orientation for a character in vertical text.
This implements the UAX #50 algorithm combined with CSS text-orientation property. For TextOrientationMixed, it respects UAX #50 defaults. For TextOrientationUpright, all characters are upright. For TextOrientationSideways, all characters are rotated.
func (*Text) DetectDirection ¶
DetectDirection automatically detects paragraph direction.
func (*Text) Elide ¶
Elide shortens text by removing the middle portion if it exceeds maxWidth.
This is a convenience function that uses TruncateMiddle strategy. Common for displaying file paths, URLs, and identifiers.
Example:
txt := text.NewTerminal()
short := txt.Elide("/very/long/path/to/some/file.txt", 20)
// Returns: "/very/.../file.txt"
func (*Text) ElideAuto ¶
ElideAuto automatically chooses the best elision strategy based on content.
Detects if text looks like a path, URL, email, etc. and applies the most appropriate elision strategy.
Example:
txt := text.NewTerminal()
txt.ElideAuto("/path/to/file.txt", 15) // Uses path elision
txt.ElideAuto("https://example.com/path", 20) // Uses URL elision
txt.ElideAuto("user@domain.com", 15) // Uses email elision
func (*Text) ElideEnd ¶
ElideEnd shortens text by truncating at the end.
Common for displaying snippets, descriptions, and body text.
Example:
txt := text.NewTerminal()
short := txt.ElideEnd("This is a very long description", 20)
// Returns: "This is a very lo..."
func (*Text) ElideEndUnicode ¶
ElideEndUnicode truncates at end with Unicode ellipsis (…).
func (*Text) ElideEndWith ¶
ElideEndWith shortens text at the end with custom ellipsis.
func (*Text) ElideForContext ¶
func (t *Text) ElideForContext(text string, maxWidth float64, context ElideContext) string
ElideForContext elides text using strategy appropriate for the context.
func (*Text) ElidePath ¶
ElidePath intelligently shortens file paths.
Preserves the filename and important directory information. Uses middle truncation but tries to break at path separators.
Example:
txt := text.NewTerminal()
short := txt.ElidePath("/usr/local/share/applications/myapp.desktop", 30)
// Returns: "/usr/.../applications/myapp.desktop"
func (*Text) ElideStart ¶
ElideStart shortens text by truncating at the start.
Common for displaying file paths where the end is most important.
Example:
txt := text.NewTerminal()
short := txt.ElideStart("/path/to/myfile.txt", 15)
// Returns: "...myfile.txt"
func (*Text) ElideStartUnicode ¶
ElideStartUnicode truncates at start with Unicode ellipsis (…).
func (*Text) ElideStartWith ¶
ElideStartWith shortens text at the start with custom ellipsis.
func (*Text) ElideURL ¶
ElideURL intelligently shortens URLs.
Preserves the domain and important parts of the path.
Example:
txt := text.NewTerminal()
short := txt.ElideURL("https://example.com/very/long/path/to/resource", 35)
// Returns: "https://example.com/.../resource"
func (*Text) ElideUnicode ¶
ElideUnicode uses the proper Unicode horizontal ellipsis character (…).
This is more typographically correct than three dots (...).
Example:
txt := text.NewTerminal()
short := txt.ElideUnicode("Long text here", 10)
// Returns: "Long t…re" (using U+2026)
func (*Text) ElideWith ¶
ElideWith shortens text using a custom ellipsis string.
Useful for different UI contexts or localization.
Example:
txt := text.NewTerminal()
short := txt.ElideWith("Long text", 10, "…") // Single character ellipsis
short = txt.ElideWith("Long text", 10, " [...] ") // Bracketed ellipsis
func (*Text) ExpandTabs ¶
ExpandTabs expands tab characters according to tab-size.
func (*Text) GetBidiClass ¶
GetBidiClass returns the bidirectional character type for a rune.
This is useful for understanding how a character behaves in bidirectional text or for implementing custom bidirectional algorithms.
Example:
txt := text.NewTerminal()
class := txt.GetBidiClass('a') // ClassL (Left-to-Right)
class := txt.GetBidiClass('א') // ClassR (Right-to-Left Hebrew)
class := txt.GetBidiClass('ا') // ClassAL (Right-to-Left Arabic)
class := txt.GetBidiClass('5') // ClassEN (European Number)
func (*Text) GraphemeAt ¶
GraphemeAt returns the grapheme cluster at the specified index.
func (*Text) GraphemeCount ¶
GraphemeCount returns the number of grapheme clusters.
func (*Text) Graphemes ¶
Graphemes splits text into grapheme clusters (user-perceived characters).
Uses UAX #29 to properly handle:
- Emoji sequences with ZWJ: 👨👩👧👦
- Emoji with skin tones: 👋🏻
- Combining marks: é (e + ́)
- Regional indicators: 🇺🇸
Example:
txt := text.NewTerminal()
graphemes := txt.Graphemes("Hello👋🏻")
fmt.Println(len(graphemes)) // 6, not 7 (emoji+modifier is 1 grapheme)
func (*Text) IntrinsicSizing ¶
func (t *Text) IntrinsicSizing(text string) IntrinsicSize
IntrinsicSizing calculates intrinsic sizes for text.
Returns:
- MinContent: Width of the widest word/grapheme (won't overflow)
- MaxContent: Width if text never wraps (single line)
- PreferredWidth: Comfortable reading width (60-80 ch)
Example:
txt := text.NewTerminal()
sizes := txt.IntrinsicSizing("Hello world! This is a test.")
// sizes.MinContent = 6.0 (widest word "Hello!" or "world!")
// sizes.MaxContent = 28.0 (full line width)
func (*Text) IsRotated ¶
func (t *Text) IsRotated(r rune, style VerticalTextStyle) bool
IsRotated returns true if the character should be rotated in vertical text.
func (*Text) IsUpright ¶
func (t *Text) IsUpright(r rune, style VerticalTextStyle) bool
IsUpright returns true if the character should be displayed upright in vertical text.
func (*Text) JustifyText ¶
func (t *Text) JustifyText(text string, targetWidth float64, method TextJustify) string
JustifyText applies justification to text to fit a specific width.
Uses the specified justification method to distribute extra space.
Example:
txt := text.NewTerminal()
justified := txt.JustifyText("Hello world", 20, text.TextJustifyInterWord)
func (*Text) LineContainingPosition ¶
LineContainingPosition finds which line contains the given text position.
Returns:
- Line index if position is within a line
- -1 if position is before all lines
- len(lines) if position is after all lines
Example:
txt := text.NewTerminal()
lines := []text.Line{
{Start: 0, End: 5},
{Start: 5, End: 10},
}
lineIdx := txt.LineContainingPosition(lines, 7) // Returns 1
func (*Text) MeasureCSS ¶
func (t *Text) MeasureCSS(text string, cssOpts CSSWrapOptions, textStyle TextStyle) CSSTextBounds
MeasureCSS calculates complete bounds with CSS text properties.
This combines: - Multi-line wrapping with CSS white-space - Intrinsic sizing for layout - Text transformation - Letter/word spacing
Example:
txt := text.NewTerminal()
bounds := txt.MeasureCSS("hello world", text.CSSWrapOptions{
MaxWidth: units.Ch(40),
Style: text.CSSTextStyle{
WhiteSpace: text.WhiteSpaceNormal,
TextTransform: text.TextTransformUppercase,
LetterSpacing: units.Px(1),
},
}, text.TextStyle{
LineHeight: 1.5,
})
func (*Text) MeasureLineBox ¶
func (t *Text) MeasureLineBox(text string, style TextStyle) LineBoxMetrics
MeasureLineBox calculates complete metrics for a line of text.
Parameters:
- text: The line content
- style: Font and line height settings
Returns metrics needed for proper line box positioning and alignment.
func (*Text) MeasureMultiLine ¶
func (t *Text) MeasureMultiLine(text string, wrapOpts WrapOptions, style TextStyle) TextBounds
MeasureMultiLine calculates bounds for wrapped text.
This is essential for layout engines that need to know: - Total height of text block - Baseline positions for alignment - Per-line metrics for rendering
Example:
txt := text.NewTerminal()
bounds := txt.MeasureMultiLine("Long text...", text.WrapOptions{
MaxWidth: 40,
}, text.TextStyle{
LineHeight: 1.5,
})
// bounds.Height = total height with line spacing
// bounds.FirstBaseline = for vertical-align: baseline
func (*Text) MeasureVertical ¶
func (t *Text) MeasureVertical(text string, style VerticalTextStyle) VerticalMetrics
MeasureVertical measures text dimensions for vertical layout.
In vertical layout:
- Advance is the vertical distance (top to bottom or bottom to top)
- InlineSize is the width (perpendicular to flow)
- BlockSize is the height (parallel to flow)
func (*Text) MirrorBrackets ¶
MirrorBrackets mirrors brackets for RTL display.
In RTL text, opening brackets like '(' should become ')' and vice versa. This function is typically called automatically by the reordering algorithm, but is exposed for cases where manual bracket handling is needed.
Note: The UAX #9 algorithm handles this automatically in most cases. This function is provided for special situations or debugging.
Example:
txt := text.NewTerminal()
result := txt.MirrorBrackets("(hello)")
// result: ")hello(" (brackets mirrored)
func (*Text) PositionToXOffset ¶
PositionToXOffset finds the x-offset of a text position within a line.
This converts a character position to its visual offset from the start of the line. Returns 0 if position is before the line, line.Width if after.
Example:
txt := text.NewTerminal()
line := text.Line{Content: "Hello", Start: 0, End: 5}
offset := txt.PositionToXOffset(line, 2) // Returns 2.0 (position of 'l')
func (*Text) ProcessWhiteSpace ¶
func (t *Text) ProcessWhiteSpace(text string, whiteSpace WhiteSpace) (processed string, allowWrap bool)
ProcessWhiteSpace processes text according to CSS white-space property. Returns the processed text and whether line wrapping is allowed.
func (*Text) Reorder ¶
Reorder applies the bidirectional algorithm for display.
Uses UAX #9 to properly reorder mixed LTR/RTL text (e.g., Latin + Arabic).
Example:
txt := text.NewTerminal()
display := txt.Reorder("Hello שלום world")
fmt.Println(display) // Properly reordered for display
func (*Text) ReorderLine ¶
ReorderLine reorders a single line after wrapping.
This is used internally by wrapping functions to ensure each wrapped line is properly reordered for display. Layout engines should call this after computing line breaks.
Example:
txt := text.NewTerminal()
line := text.Line{
Content: "Hello مرحبا world",
Width: 15.0,
Start: 0,
End: 17,
}
// Reorder the line content
line.Content = txt.ReorderLine(line.Content, text.DirectionAuto)
func (*Text) ReorderParagraph ¶
ReorderParagraph reorders a paragraph, handling line breaks properly.
This function: 1. Splits text by line breaks 2. Detects direction for each paragraph 3. Reorders each line independently 4. Rejoins with line breaks
Example:
txt := text.NewTerminal() input := "Hello world\nمرحبا العالم\nMixed text" result := txt.ReorderParagraph(input, text.DirectionAuto) // Each line reordered according to its detected direction
func (*Text) ReorderWithDirection ¶
ReorderWithDirection applies bidirectional algorithm with explicit direction.
func (*Text) SentenceCount ¶
SentenceCount returns the number of sentences in the text.
func (*Text) SentenceCountWithDictionary ¶
func (t *Text) SentenceCountWithDictionary(text string, dict DictionaryProvider) int
SentenceCountWithDictionary returns the number of sentences using dictionary support.
func (*Text) SentencesWithDictionary ¶
func (t *Text) SentencesWithDictionary(text string, dict DictionaryProvider) []string
SentencesWithDictionary splits text into sentences using dictionary support.
This provides more accurate sentence boundary detection by: - Not breaking after known abbreviations (Dr., Mrs., etc.) - Handling language-specific rules - Supporting domain-specific terminology
Example:
dict := text.NewEnglishDictionary()
sentences := txt.SentencesWithDictionary("Dr. Smith is here.", dict)
// Returns ["Dr. Smith is here."] instead of ["Dr. ", "Smith is here."]
func (*Text) ShouldHang ¶
func (t *Text) ShouldHang(text string, position int, mode HangingPunctuation) (shouldHang bool, hangWidth float64)
ShouldHang determines if punctuation should hang outside the line box.
func (*Text) Transform ¶
func (t *Text) Transform(text string, transform TextTransform) string
Transform applies text transformation according to CSS text-transform property.
func (*Text) TrimCJKSpacing ¶
func (t *Text) TrimCJKSpacing(text string, mode TextSpacingTrim) string
TrimCJKSpacing trims spacing around CJK characters according to the trim mode.
func (*Text) Truncate ¶
func (t *Text) Truncate(text string, opts TruncateOptions) string
Truncate shortens text to fit within maxWidth, adding an ellipsis.
Uses UAX #29 to respect grapheme cluster boundaries, ensuring emoji and combining marks are not broken.
Example:
txt := text.NewTerminal()
short := txt.Truncate("Hello 世界!", text.TruncateOptions{
MaxWidth: 10,
Strategy: text.TruncateEnd,
})
fmt.Println(short) // "Hello 世..."
func (*Text) Width ¶
Width measures the display width of text in abstract units.
Units are determined by the MeasureFunc configuration:
- For terminals: character cells (1.0 per ASCII char, 2.0 per CJK char)
- For canvas: pixels (12.5 per 'a', 24.3 per 'W', etc.)
This correctly handles:
- CJK characters (2 cells/units wide)
- Emoji (2 cells/units wide)
- Emoji sequences (flags, ZWJ sequences, modifiers - all 2 cells wide)
- Combining marks (0 width)
- Zero-width joiners (0 width)
Example:
txt := text.NewTerminal()
width := txt.Width("Hello") // 5.0 cells
width = txt.Width("Hello 世界") // 9.0 cells (5 + 1 space + 2 + 2)
width = txt.Width("👋🏻") // 2.0 cells (emoji + skin tone modifier)
width = txt.Width("🇺🇸") // 2.0 cells (flag emoji)
func (*Text) WidthBytes ¶
WidthBytes measures the display width of a UTF-8 byte buffer.
This is more efficient than Width(string(bytes)) as it avoids string allocation and conversion overhead for large buffers.
Example:
txt := text.NewTerminal()
buf := []byte("Hello 世界")
width := txt.WidthBytes(buf) // 9.0 cells
func (*Text) WidthMany ¶
WidthMany efficiently measures multiple strings in a batch.
This can be more efficient than calling Width() multiple times if the implementation can reuse internal state or optimize for batch operations.
Example:
txt := text.NewTerminal()
strings := []string{"Hello", "世界", "Test"}
widths := txt.WidthMany(strings)
// widths = [5.0, 4.0, 4.0]
func (*Text) WidthRange ¶
WidthRange measures the display width of a substring by rune indices.
Example:
txt := text.NewTerminal() text := "Hello 世界" width := txt.WidthRange(text, 0, 5) // 5.0 (just "Hello") width = txt.WidthRange(text, 6, 8) // 4.0 (just "世界")
func (*Text) WidthUpTo ¶
WidthUpTo measures display width up to a maximum, with early termination.
Returns the measured width and whether it exceeded the maximum. This is more efficient than Width() when you only care about fitting within a maximum width, as it stops measuring once the limit is reached.
Example:
txt := text.NewTerminal()
width, exceeded := txt.WidthUpTo("Very long text here", 10.0)
if exceeded {
// Text is too wide, needs truncation
}
func (*Text) WithFontMetrics ¶
func (t *Text) WithFontMetrics(fm FontMetrics) *Text
WithFontMetrics creates a Text instance with real font metrics.
When provided, font metrics override the default ascent/descent calculations. This enables proper support for font-relative units (em, ex, cap, ch, ic).
Future enhancement: Store and use font metrics in line box measurement for pixel-perfect canvas/GUI rendering with proper baseline alignment.
func (*Text) Words ¶
Words splits text into words using UAX #29 word boundaries. Returns a slice of word segments (includes spaces and punctuation).
func (*Text) Wrap ¶
func (t *Text) Wrap(text string, opts WrapOptions) []Line
Wrap breaks text into lines that fit within maxWidth.
Uses UAX #14 for proper line break opportunities and UAX #29 to avoid breaking within grapheme clusters (emoji, combining marks, etc.).
Example:
txt := text.NewTerminal()
lines := txt.Wrap("Hello 世界! This is a test.", text.WrapOptions{
MaxWidth: 15,
})
for _, line := range lines {
fmt.Println(line.Content)
}
// Output:
// Hello 世界!
// This is a test.
func (*Text) WrapBalanced ¶
WrapBalanced wraps text with balanced line lengths.
func (*Text) WrapCSS ¶
func (t *Text) WrapCSS(text string, opts CSSWrapOptions) []Line
WrapCSS wraps text according to CSS text properties. This is a more sophisticated version of Wrap that handles white-space, word-break, line-break, and other CSS properties.
func (*Text) WrapKnuthPlass ¶
func (t *Text) WrapKnuthPlass(text string, opts KnuthPlassOptions) []Line
WrapKnuthPlass wraps text using the Knuth-Plass optimal line breaking algorithm.
This produces better-looking paragraphs than greedy wrapping by considering all possible break points and choosing the set that minimizes total "badness".
Example:
txt := text.NewTerminal()
opts := text.DefaultKnuthPlassOptions(40.0)
lines := txt.WrapKnuthPlass("The quick brown fox jumps over the lazy dog", opts)
func (*Text) WrapPretty ¶
WrapPretty wraps text optimizing for readability.
func (*Text) WrapVertical ¶
func (t *Text) WrapVertical(text string, opts VerticalWrapOptions) []VerticalLine
WrapVertical wraps text for vertical layout.
In vertical layout, "lines" are vertical columns that flow from top to bottom. When a column reaches MaxBlockSize, text wraps to the next column.
func (*Text) WrapWithControls ¶
WrapWithControls wraps text respecting wrap-before/wrap-after controls.
This function modifies line break opportunities based on CSS wrap-before and wrap-after properties: - WrapControlAvoid: Avoids breaking at this position if possible - WrapControlAlways: Forces a break at this position - WrapControlAuto: Uses normal UAX #14 break opportunities
Example:
controls := []WrapPoint{
{Position: 5, After: WrapControlAlways}, // Force break after position 5
{Position: 10, Before: WrapControlAvoid}, // Avoid breaking before position 10
}
lines := txt.WrapWithControls("Hello world test", 20, controls)
func (*Text) WrapWithPhrases ¶
func (t *Text) WrapWithPhrases(text string, maxWidth float64, breaker PhraseBreaker) []Line
WrapWithPhrases wraps text using phrase boundaries from a PhraseBreaker.
This implements CSS word-break: auto-phrase, which breaks at natural phrase boundaries in languages that don't use spaces between words.
The PhraseBreaker interface allows users to integrate language-specific dictionaries without requiring this library to ship with large dictionary files or ML models.
Example:
// User provides their own phrase breaker
breaker := &MyChineseBreaker{}
lines := txt.WrapWithPhrases("你好世界,这是一个测试。", 20, breaker)
func (*Text) WrapWithPhrasesAndControls ¶
func (t *Text) WrapWithPhrasesAndControls(text string, maxWidth float64, breaker PhraseBreaker, controls []WrapPoint) []Line
WrapWithPhrasesAndControls combines phrase breaking with wrap controls.
This allows fine-grained control over phrase-based line breaking.
Example:
controls := []WrapPoint{
{Position: 5, After: WrapControlAvoid}, // Don't break after phrase at position 5
}
lines := txt.WrapWithPhrasesAndControls(text, 20, breaker, controls)
func (*Text) XOffsetToPosition ¶
func (t *Text) XOffsetToPosition(line Line, xOffset float64) XOffsetInfo
XOffsetToPosition finds the character position at the given x-offset within a line.
This is the core text operation for finding where a click or cursor should go within a line's content. The layout engine provides the x-offset within the line.
Example:
txt := text.NewTerminal()
line := text.Line{Content: "Hello", Width: 5.0, Start: 0, End: 5}
info := txt.XOffsetToPosition(line, 2.3)
// info.Position = 2 (character 'l')
// info.IsTrailing = false (left half of 'l')
type TextAutospace ¶
type TextAutospace int
TextAutospace controls automatic spacing around ideographic characters.
Specification:
- CSS Text Level 4: https://www.w3.org/TR/css-text-4/#text-autospace-property
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/text-autospace
const ( // TextAutospaceNormal creates extra spacing as specified. TextAutospaceNormal TextAutospace = iota // TextAutospaceNoAutospace disables automatic spacing. TextAutospaceNoAutospace // TextAutospaceAuto uses language-specific spacing rules. TextAutospaceAuto )
type TextBounds ¶
type TextBounds struct {
// Total dimensions
Width float64 // Width of widest line
Height float64 // Total height of all lines
// Baseline information
FirstBaseline float64 // Position of first line's baseline from top
LastBaseline float64 // Position of last line's baseline from top
// Line information
LineCount int // Number of lines
Lines []LineBoxMetrics // Metrics for each line
}
TextBounds represents the bounding box of multi-line text.
type TextCombineUpright ¶
type TextCombineUpright int
TextCombineUpright controls horizontal text runs in vertical layout. Based on CSS Writing Modes Module Level 4 §9: https://www.w3.org/TR/css-writing-modes-4/#text-combine-upright
const ( // TextCombineUprightNone disables text combining. TextCombineUprightNone TextCombineUpright = iota // TextCombineUprightAll enables combining for all characters. // Used for numbers, acronyms, etc. in vertical text (tate-chu-yoko in Japanese). TextCombineUprightAll // TextCombineUprightDigits enables combining for digit sequences only. TextCombineUprightDigits )
type TextConfig ¶
type TextConfig struct {
*Text
Dictionary DictionaryProvider
}
TextConfig extends Text with dictionary support.
func NewTerminalWithEnglishDictionary ¶
func NewTerminalWithEnglishDictionary() *TextConfig
NewTerminalWithEnglishDictionary creates a terminal text handler with English dictionary.
func NewTextWithDictionary ¶
func NewTextWithDictionary(config Config, dict DictionaryProvider) *TextConfig
NewTextWithDictionary creates a Text instance with dictionary support.
func (*TextConfig) SentenceCount ¶
func (tc *TextConfig) SentenceCount(text string) int
SentenceCount returns sentence count using the configured dictionary.
func (*TextConfig) Sentences ¶
func (tc *TextConfig) Sentences(text string) []string
Sentences uses the configured dictionary for sentence segmentation.
type TextIndent ¶
type TextIndent struct {
// Length is the indentation amount (can be negative).
Length units.Length
// Hanging applies indent to all lines except the first (reverse indent).
// CSS: text-indent: 2em hanging;
Hanging bool
// EachLine applies indent to each line after a forced line break.
// CSS: text-indent: 2em each-line;
EachLine bool
}
TextIndent controls indentation of the first line or all lines.
Specification:
- CSS Text Level 3: https://www.w3.org/TR/css-text-3/#text-indent-property
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/text-indent
func DefaultTextIndent ¶
func DefaultTextIndent() TextIndent
DefaultTextIndent returns zero indentation.
type TextJustify ¶
type TextJustify int
TextJustify specifies the justification method.
Specification:
- CSS Text Level 3: https://www.w3.org/TR/css-text-3/#text-justify-property
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/text-justify
const ( // TextJustifyAuto allows the browser to choose (typically inter-word). TextJustifyAuto TextJustify = iota // TextJustifyNone disables justification. TextJustifyNone // TextJustifyInterWord adds space between words. // Best for scripts that use word separators (Latin, Greek, Cyrillic). TextJustifyInterWord // TextJustifyInterCharacter adds space between characters. // Best for CJK scripts without word separators. TextJustifyInterCharacter // TextJustifyDistribute distributes space evenly (similar to inter-character). // Legacy value, maps to inter-character. TextJustifyDistribute )
type TextOrientation ¶
type TextOrientation int
TextOrientation controls glyph orientation in vertical text. Based on CSS Writing Modes Module Level 4 §7.1: https://www.w3.org/TR/css-writing-modes-4/#text-orientation
const ( // TextOrientationMixed uses upright orientation for CJK and rotates other characters. // This is the default for vertical writing modes. TextOrientationMixed TextOrientation = iota // TextOrientationUpright forces all characters to upright orientation. TextOrientationUpright // TextOrientationSideways rotates all characters 90° clockwise. TextOrientationSideways // TextOrientationSidewaysRight is deprecated, use Sideways instead. TextOrientationSidewaysRight )
type TextOverflow ¶
type TextOverflow int
TextOverflow controls how overflowing inline content is signaled to users. Based on CSS Basic User Interface Module Level 4 §3.1: https://www.w3.org/TR/css-ui-4/#text-overflow
const ( // TextOverflowClip clips the text at the content edge (no ellipsis). TextOverflowClip TextOverflow = iota // TextOverflowEllipsis displays an ellipsis ('...') to represent clipped text. TextOverflowEllipsis // TextOverflowString displays a custom string to represent clipped text. // The string value is specified separately. TextOverflowString // TextOverflowFade fades out the end of the text (not widely supported). TextOverflowFade )
type TextSpacingTrim ¶
type TextSpacingTrim int
TextSpacingTrim controls trimming of CJK spacing.
Specification:
- CSS Text Level 4: https://www.w3.org/TR/css-text-4/#text-spacing-trim-property
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/text-spacing-trim
const ( // TextSpacingTrimNone disables spacing trim. TextSpacingTrimNone TextSpacingTrim = iota // TextSpacingTrimSpaceAll trims space before/after ideographic characters. TextSpacingTrimSpaceAll // TextSpacingTrimSpaceFirst trims space at line start. TextSpacingTrimSpaceFirst // TextSpacingTrimAuto uses language-specific rules. TextSpacingTrimAuto )
type TextStyle ¶
type TextStyle struct {
FontSize float64
LineHeight float64
LetterSpacing float64
FontFamily string
Bold bool
Italic bool
}
TextStyle mirrors the text styling properties from the layout engine. This avoids importing the layout package directly.
type TextTransform ¶
type TextTransform int
TextTransform controls case transformation of text.
Specification:
- CSS Text Level 3: https://www.w3.org/TR/css-text-3/#text-transform-property
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/text-transform
const ( // TextTransformNone performs no transformation. TextTransformNone TextTransform = iota // TextTransformUppercase converts all characters to uppercase. TextTransformUppercase // TextTransformLowercase converts all characters to lowercase. TextTransformLowercase // TextTransformCapitalize capitalizes the first character of each word. TextTransformCapitalize // TextTransformFullWidth converts characters to their fullwidth forms. // Used in East Asian typography. TextTransformFullWidth // TextTransformFullSizeKana converts small kana to full-size equivalents. TextTransformFullSizeKana )
type TextWrap ¶
type TextWrap int
TextWrap controls advanced text wrapping strategies.
Specification:
- CSS Text Level 4: https://www.w3.org/TR/css-text-4/#text-wrap-property
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/text-wrap
- web.dev Balance Text: https://web.dev/articles/css-text-wrap-balance
const ( // TextWrapWrap allows wrapping at any break point (default). TextWrapWrap TextWrap = iota // TextWrapNowrap disables wrapping. TextWrapNowrap // TextWrapBalance tries to balance line lengths. // Good for headings and short blocks of text. TextWrapBalance // TextWrapStable minimizes reflow when editing. // Only wraps when next word doesn't fit. TextWrapStable // TextWrapPretty optimizes for readability. // Avoids orphans and short last lines. TextWrapPretty )
type TextWrapMode ¶
type TextWrapMode int
TextWrapMode controls whether lines may wrap at soft wrap opportunities.
Specification:
- CSS Text Level 4: https://www.w3.org/TR/css-text-4/#text-wrap-mode
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/text-wrap-mode
const ( // TextWrapModeWrap allows wrapping at soft wrap opportunities. TextWrapModeWrap TextWrapMode = iota // TextWrapModeNowrap prevents wrapping. TextWrapModeNowrap )
type TextWrapStyle ¶
type TextWrapStyle int
TextWrapStyle controls how wrapping is performed.
Specification:
- CSS Text Level 4: https://www.w3.org/TR/css-text-4/#text-wrap-style
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/text-wrap-style
- web.dev: https://web.dev/articles/css-text-wrap-balance
const ( // TextWrapStyleAuto uses standard wrapping. TextWrapStyleAuto TextWrapStyle = iota // TextWrapStyleBalance tries to balance line lengths. TextWrapStyleBalance // TextWrapStyleStable minimizes reflow when editing. TextWrapStyleStable // TextWrapStylePretty optimizes for readability. TextWrapStylePretty )
type TruncateOptions ¶
type TruncateOptions struct {
// MaxWidth is the maximum width for the truncated text in abstract units.
// For terminals: character cells (e.g., 20 means 20 columns)
// For canvas: pixels (e.g., 200.0 means 200 pixels)
// Units are determined by the MeasureFunc configuration.
MaxWidth float64
// Ellipsis is the string to append when truncating (default: "...").
Ellipsis string
// Strategy specifies where to truncate.
Strategy TruncateStrategy
}
TruncateOptions configures truncation behavior.
type TruncateStrategy ¶
type TruncateStrategy int
TruncateStrategy specifies where to truncate text.
const ( // TruncateEnd truncates at the end: "Hello wo..." TruncateEnd TruncateStrategy = iota // TruncateMiddle truncates in the middle: "Hel...rld" TruncateMiddle // TruncateStart truncates at the start: "...o world" TruncateStart )
type VerticalLine ¶
type VerticalLine struct {
Content string
Advance float64 // Vertical advance (column height)
InlineSize float64 // Horizontal size (column width)
Start int
End int
}
VerticalLine represents a line in vertical layout (a column).
type VerticalMetrics ¶
type VerticalMetrics struct {
// Advance is the vertical advance (height) for this text segment.
Advance float64
// InlineSize is the inline dimension (width in vertical layout).
InlineSize float64
// BlockSize is the block dimension (height in vertical layout).
BlockSize float64
// BaselineOffset is the offset from the baseline.
BaselineOffset float64
}
VerticalMetrics provides measurements for vertical text layout.
type VerticalTextStyle ¶
type VerticalTextStyle struct {
WritingMode WritingMode
TextOrientation TextOrientation
TextCombineUpright TextCombineUpright
// GlyphOrientationVertical controls glyph rotation in vertical text.
// Deprecated in favor of TextOrientation, but kept for compatibility.
// Value in degrees: 0, 90, -90, or auto.
GlyphOrientationVertical float64
}
VerticalTextStyle configures vertical text layout properties.
func DefaultVerticalTextStyle ¶
func DefaultVerticalTextStyle() VerticalTextStyle
DefaultVerticalTextStyle returns default vertical text style (horizontal layout).
type VerticalWrapOptions ¶
type VerticalWrapOptions struct {
// MaxBlockSize is the maximum block dimension before wrapping.
// For vertical text, this is the maximum column height.
MaxBlockSize float64
// Style configures vertical text properties.
Style VerticalTextStyle
// BaseOptions provides standard wrapping options.
BaseOptions WrapOptions
}
VerticalWrapOptions extends WrapOptions for vertical text.
type WhiteSpace ¶
type WhiteSpace int
WhiteSpace controls how white space is handled inside an element.
Specification:
- CSS Text Level 3: https://www.w3.org/TR/css-text-3/#white-space-property
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/white-space
const ( // WhiteSpaceNormal collapses white space sequences and wraps lines. // Newlines are treated as spaces. WhiteSpaceNormal WhiteSpace = iota // WhiteSpacePre preserves all white space and does not wrap. // Like HTML <pre> tag. WhiteSpacePre // WhiteSpaceNoWrap collapses white space but does not wrap lines. WhiteSpaceNoWrap // WhiteSpacePreWrap preserves white space and wraps lines. WhiteSpacePreWrap // WhiteSpacePreLine collapses white space sequences but preserves newlines. WhiteSpacePreLine // WhiteSpaceBreakSpaces preserves white space and allows breaking at spaces. WhiteSpaceBreakSpaces )
type WhiteSpaceCollapse ¶
type WhiteSpaceCollapse int
WhiteSpaceCollapse controls how white space sequences are handled.
Specification:
- CSS Text Level 4: https://www.w3.org/TR/css-text-4/#white-space-collapsing
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/white-space-collapse
const ( // WhiteSpaceCollapseCollapse collapses sequences of white space into single space. WhiteSpaceCollapseCollapse WhiteSpaceCollapse = iota // WhiteSpaceCollapsePreserve preserves all white space. WhiteSpaceCollapsePreserve // WhiteSpaceCollapsePreserveBreaks collapses white space but preserves line breaks. WhiteSpaceCollapsePreserveBreaks // WhiteSpaceCollapsePreserveSpaces preserves space characters but collapses other whitespace. WhiteSpaceCollapsePreserveSpaces // WhiteSpaceCollapseBreakSpaces like preserve but allows breaking at spaces. WhiteSpaceCollapseBreakSpaces )
type WhiteSpaceTrim ¶
type WhiteSpaceTrim int
WhiteSpaceTrim controls trimming of whitespace at box boundaries.
Specification:
- CSS Text Level 4: https://www.w3.org/TR/css-text-4/#white-space-trim
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/white-space-trim
const ( // WhiteSpaceTrimNone disables trimming. WhiteSpaceTrimNone WhiteSpaceTrim = iota // WhiteSpaceTrimDiscardBefore trims whitespace at start of box. WhiteSpaceTrimDiscardBefore // WhiteSpaceTrimDiscardAfter trims whitespace at end of box. WhiteSpaceTrimDiscardAfter // WhiteSpaceTrimDiscardInner trims whitespace between boxes. WhiteSpaceTrimDiscardInner )
type WordBreak ¶
type WordBreak int
WordBreak controls word breaking rules for CJK and other scripts.
Specification:
- CSS Text Level 3: https://www.w3.org/TR/css-text-3/#word-break-property
- MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/word-break
const ( // WordBreakNormal uses default line break rules. WordBreakNormal WordBreak = iota // WordBreakBreakAll allows breaks between any characters for non-CJK scripts. WordBreakBreakAll // WordBreakKeepAll prevents breaks between CJK characters. // Only breaks at whitespace and punctuation. WordBreakKeepAll // WordBreakBreakWord is like normal, but allows breaking within words // if there are no acceptable break points in the line. WordBreakBreakWord )
type WordSpaceTransform ¶
type WordSpaceTransform int
WordSpaceTransform transforms word separators between styles.
Specification:
- CSS Text Level 4: https://www.w3.org/TR/css-text-4/#word-space-transform
const ( // WordSpaceTransformNone performs no transformation. WordSpaceTransformNone WordSpaceTransform = iota // WordSpaceTransformSpace preserves/converts to space character. WordSpaceTransformSpace // WordSpaceTransformIdeographicSpace converts to ideographic space (U+3000). WordSpaceTransformIdeographicSpace // WordSpaceTransformAutoPhrase enables auto phrase detection. WordSpaceTransformAutoPhrase )
type WrapControl ¶
type WrapControl int
WrapControl specifies wrap behavior before/after an element.
Specification:
- CSS Text Level 4: https://www.w3.org/TR/css-text-4/#wrap-before
- CSS Text Level 4: https://www.w3.org/TR/css-text-4/#wrap-after
- MDN wrap-before: https://developer.mozilla.org/en-US/docs/Web/CSS/wrap-before
- MDN wrap-after: https://developer.mozilla.org/en-US/docs/Web/CSS/wrap-after
const ( // WrapControlAuto uses normal line breaking rules. WrapControlAuto WrapControl = iota // WrapControlAvoid avoids breaking before/after if possible. WrapControlAvoid // WrapControlAlways forces a break before/after. WrapControlAlways )
type WrapInside ¶
type WrapInside int
WrapInside controls whether line breaking is allowed within an element.
Specification:
- CSS Text Level 4: https://www.w3.org/TR/css-text-4/#wrap-inside
const ( // WrapInsideAuto allows normal line breaking within the element. WrapInsideAuto WrapInside = iota // WrapInsideAvoid suppresses line breaking within the element. WrapInsideAvoid )
type WrapOptions ¶
type WrapOptions struct {
// MaxWidth is the maximum width for wrapped lines in abstract units.
// For terminals: character cells (e.g., 40 means 40 columns)
// For canvas: pixels (e.g., 400.0 means 400 pixels)
// Units are determined by the MeasureFunc configuration.
MaxWidth float64
// BreakWords allows breaking in the middle of words if necessary.
// If false, only breaks at UAX #14 line break opportunities.
BreakWords bool
// PreserveNewlines keeps existing newline characters as line breaks.
PreserveNewlines bool
}
WrapOptions configures text wrapping behavior.
type WrapPoint ¶
type WrapPoint struct {
Position int // Position in text (rune index)
Before WrapControl // Wrap behavior before this position
After WrapControl // Wrap behavior after this position
}
WrapPoint represents a position where wrapping behavior is controlled.
type WritingMode ¶
type WritingMode int
WritingMode specifies the block flow direction. Based on CSS Writing Modes Module Level 4: https://www.w3.org/TR/css-writing-modes-4/#block-flow
const ( // WritingModeHorizontalTB flows top to bottom, inline left to right. // This is the default for Latin scripts. WritingModeHorizontalTB WritingMode = iota // WritingModeVerticalRL flows right to left, inline top to bottom. // Used in traditional Chinese, Japanese, Korean typography. WritingModeVerticalRL // WritingModeVerticalLR flows left to right, inline top to bottom. // Used in some Mongolian and certain historical scripts. WritingModeVerticalLR // WritingModeSidewaysRL flows right to left with characters rotated 90° clockwise. // Used for mixed scripts in vertical layout. WritingModeSidewaysRL // WritingModeSidewaysLR flows left to right with characters rotated 90° counter-clockwise. WritingModeSidewaysLR )
type XOffsetInfo ¶
type XOffsetInfo struct {
// Position in the text (rune index)
Position int
// CharXOffset is the x-offset of the character's left edge
CharXOffset float64
// CharWidth is the width of the character
CharWidth float64
// IsTrailing indicates if offset is in trailing half of character
// Used for determining cursor position: before or after character
IsTrailing bool
// IsWithinLine indicates if the offset is within the line's width
IsWithinLine bool
}
XOffsetInfo contains information about a position found at an x-offset.