LineBreak

LineBreak :: # (opaque)

Unicode 17 default line-break opportunities and decisions (UAX #14 rev 55).

This module reports logical boundaries; it does not choose a line width. The exact un-tailored Unicode algorithm is the obvious no-configuration API. PreserveGraphemes is an explicit restriction profile.

preserve_graphemes_revision : ProfileRevision

Revision of the package-defined tailoring policy, independent of the Unicode/UAX version that defines the default algorithm.

iter_boundaries : Str -> Iter(BreakBoundary)

Lazily report every scalar boundary under the exact Unicode default, including LB2 start and LB3 end.

Exhaustive traversal may perform bounded forward lookahead and replay that span from the retained Str. Total work is linear, no coordinate list is retained, and early stop decodes no suffix beyond the lookahead semantically required for the last requested boundary.

iter_opportunities : Str -> Iter(BreakOpportunity)

Lazily report only Allowed and Mandatory boundaries under the exact Unicode default. This path decodes and classifies each scalar once.

boundaries : Str -> List(BreakBoundary)

Collect every boundary under the exact Unicode default.

opportunities : Str -> List(BreakOpportunity)

Collect Allowed and Mandatory opportunities under the exact default.

Profile : [UnicodeDefault, PreserveGraphemes]
Decision : [Mandatory, Allowed, Prohibited]

Cursor

LineBreak.Cursor :: # (opaque)
init : {  } -> Cursor

Begin an exact Unicode-default opportunity stream.

init_with : Profile -> Cursor

Begin an opportunity stream under an explicit profile.

push : Cursor, Str, state, (state, BreakOpportunity -> state) -> [
    Pushed({ cursor : Cursor, state : state, consumed : U64 }),
    Failed({ cursor : Cursor, state : state, consumed : U64, error : Error }),
]

Consume one scalar-aligned Str chunk and emit only irrevocable Allowed or Mandatory opportunities in source order.

Chunk ends are not end of text. The cursor retains one pending right-context decision and coordinates, never a chunk or substring. Exhaustive Prohibited events intentionally belong to replayable-Str traversal: for PR OP CM* X, PR|OP can depend on X, while every following boundary inside CM* is already prohibited, so an ordered non-replayable exhaustive cursor would need an unbounded coordinate queue.

Pushed accepts the whole chunk. Failed seals the cursor and returns the caller state containing all earlier irrevocable opportunities plus the accepted byte count within this chunk. Byte offset overflow is checked before scanning, so that failure has no emissions and consumes zero bytes. A returned cursor never retains the unconsumed chunk suffix.

finish : Cursor, state, (state, BreakOpportunity -> state) -> [
    End({ cursor : Cursor, state : state }),
    Failed({ cursor : Cursor, state : state, error : Error }),
]

Resolve end-sensitive candidates and emit the mandatory end opportunity exactly once. After End, later calls fail with AlreadyFinished; after any terminal push failure they fail with AlreadyFailed.