Break Mode.Character()- Module
- std.
typeset - Receiver
- Not applicable
- Minimum arity
- 0
- Maximum arity
- 0
Declaration and parameters
LinkAvailability
Included by default: Pending
Import std.typeset in language mode 5.21.
The current compiler selects std/typeset.tpz for this language mode. Availability in other released editions and inclusion in each installed distribution are Pending.
Source evidence
- compiler/crates/topaz_resolve/src/std/typeset/model.tpz at
b48527d0a174· 11 - compiler/crates/topaz_resolve/src/stdlib.rs at
b48527d0a174· 40
Receiver
Parameter constraints
BreakPolicy supplies every classification choice explicitly. rules selects the character boundary policy. mode selects word protection. The two choices are independent and neither consults the host locale.
forbidBefore and forbidAfter contain Unicode scalar values. Each integer must be between zero and 1114111 and outside 55296 through 57343. Invalid values return TypesetError.InvalidPolicy. Ordering and duplicate entries do not change membership.
At an ordinary interior boundary, forbidAfter checks the final scalar on the left and forbidBefore checks the first scalar on the right. These custom bans filter admitted candidates and do not create candidates. They do not replace non-tailorable Unicode decisions.
The shaping boundary mask can remove an ordinary candidate. A mask conflict with a mandatory or non-tailorable required Unicode opportunity returns TypesetError.InvalidInput. A generated hyphen or character mode never bypasses a false mask entry.
generatedHyphenEnds contains exclusive interior cluster indices. Both neighboring clusters must consist of Unicode Alphabetic scalars or the apostrophes U+0027 and U+2019. An out of range index or nonword neighbor returns TypesetError.InvalidInput. Duplicate indices have no additional effect.
A generated index changes a missing or HardFallback candidate to LatinSoftHyphen when Unicode permits tailoring there. It does not replace another category or a non-tailorable prohibition. The selected locale, custom bans, shaping mask, and short-word policy still apply. The function does not insert text or measure a hyphen glyph.
narrowestWordTarget and bodyWordTarget are independent nonnegative point lengths. A negative target returns TypesetError.InvalidPolicy. Zero is accepted and equality with a target counts as fitting.
For a HardFallback inside a contiguous run of Alphabetic or apostrophe clusters, protectFittingLatin suppresses the break when the measured run width is at most narrowestWordTarget. Word mode also suppresses that break when the run width is at most bodyWordTarget. Character mode removes this second word-fit test while retaining all other constraints.
Word mode can add emergency boundaries inside an oversized word whose width exceeds bodyWordTarget. Unicode modes retain non-tailorable prohibitions and locale bans. Unicode16Ko also preserves a fitting whitespace-delimited Hangul run at bodyWordTarget.
With preserveShortWords, an interior boundary between nonwhitespace clusters is suppressed when their whitespace-delimited run has at most three Alphabetic or Number scalars. It is also suppressed when that run fits bodyWordTarget. These tests include generated hyphens. Mandatory and non-tailorable required Unicode opportunities retain their priority.
Related rule: Apply word policy without crossing protected cluster boundariesResult
Effects
Failures
Result and effects
LinkCharacter mode removes the ordinary Word-mode fitting test. It does not split a cluster or bypass Unicode prohibitions, shaping masks, custom bans, protectFittingLatin, or preserveShortWords.
Resolved contracts
LinkRelated entries
LinkApply word policy without crossing protected cluster boundaries
LinkApply word policy without crossing protected cluster boundaries
BreakPolicy supplies every classification choice explicitly. rules selects the character boundary policy. mode selects word protection. The two choices are independent and neither consults the host locale.
forbidBefore and forbidAfter contain Unicode scalar values. Each integer must be between zero and 1114111 and outside 55296 through 57343. Invalid values return TypesetError.InvalidPolicy. Ordering and duplicate entries do not change membership.
At an ordinary interior boundary, forbidAfter checks the final scalar on the left and forbidBefore checks the first scalar on the right. These custom bans filter admitted candidates and do not create candidates. They do not replace non-tailorable Unicode decisions.
The shaping boundary mask can remove an ordinary candidate. A mask conflict with a mandatory or non-tailorable required Unicode opportunity returns TypesetError.InvalidInput. A generated hyphen or character mode never bypasses a false mask entry.
generatedHyphenEnds contains exclusive interior cluster indices. Both neighboring clusters must consist of Unicode Alphabetic scalars or the apostrophes U+0027 and U+2019. An out of range index or nonword neighbor returns TypesetError.InvalidInput. Duplicate indices have no additional effect.
A generated index changes a missing or HardFallback candidate to LatinSoftHyphen when Unicode permits tailoring there. It does not replace another category or a non-tailorable prohibition. The selected locale, custom bans, shaping mask, and short-word policy still apply. The function does not insert text or measure a hyphen glyph.
narrowestWordTarget and bodyWordTarget are independent nonnegative point lengths. A negative target returns TypesetError.InvalidPolicy. Zero is accepted and equality with a target counts as fitting.
For a HardFallback inside a contiguous run of Alphabetic or apostrophe clusters, protectFittingLatin suppresses the break when the measured run width is at most narrowestWordTarget. Word mode also suppresses that break when the run width is at most bodyWordTarget. Character mode removes this second word-fit test while retaining all other constraints.
Word mode can add emergency boundaries inside an oversized word whose width exceeds bodyWordTarget. Unicode modes retain non-tailorable prohibitions and locale bans. Unicode16Ko also preserves a fitting whitespace-delimited Hangul run at bodyWordTarget.
With preserveShortWords, an interior boundary between nonwhitespace clusters is suppressed when their whitespace-delimited run has at most three Alphabetic or Number scalars. It is also suppressed when that run fits bodyWordTarget. These tests include generated hyphens. Mandatory and non-tailorable required Unicode opportunities retain their priority.
Why
Word fitting and character breaking answer different layout needs. Explicit thresholds let callers retain fitting words while admitting emergency breaks in oversized text. Applying shaping and punctuation constraints after candidate generation prevents a convenience option from splitting protected text.
Source evidence
- compiler/crates/topaz_resolve/src/std/typeset/breaks.tpz at
f3807a34248e· 4-16 - compiler/crates/topaz_resolve/src/std/typeset/breaks.tpz at
f3807a34248e· 57-86 - compiler/crates/topaz_resolve/src/std/typeset/locale.tpz at
f3807a34248e· 61-106 - compiler/crates/topaz_resolve/src/std/typeset/measure.tpz at
f3807a34248e· 24-25 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
f3807a34248e· 691-713 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
f3807a34248e· 1319-1340 -
topaz.stdlib.contract.typeset-break-policyatworking-tree
Keep generated hyphens behind the shaping mask
Linkimport std.typeset as tsimport std.ioimport std.testlet clusters = [ts.BreakCluster { text: "a", advance: 1pt, trackingAfter: 0pt }, ts.BreakCluster { text: "b", advance: 1pt, trackingAfter: 0pt }]let selected = ts.BreakPolicy {mode: ts.BreakMode.Character(),rules: ts.KinsokuRules.AtlasDefault(),forbidBefore: [],forbidAfter: [],boundaryAllowed: [false, true],generatedHyphenEnds: [1, 1],protectFittingLatin: false,preserveShortWords: false,narrowestWordTarget: 0pt,bodyWordTarget: 0pt}let breaks = test.assertOk(ts.classifyBreaks(clusters, selected))for boundary in (breaks) {io.writeLine("{boundary.unitEnd}")}
2
Expected result
Expected result
Execution completes. Exit code 0.
2
Source evidence
- compiler/crates/topaz_resolve/src/std/typeset/breaks.tpz at
f3807a34248e· 4-16 - compiler/crates/topaz_resolve/src/std/typeset/breaks.tpz at
f3807a34248e· 57-86 - compiler/crates/topaz_resolve/src/std/typeset/locale.tpz at
f3807a34248e· 61-106 - compiler/crates/topaz_resolve/src/std/typeset/measure.tpz at
f3807a34248e· 24-25 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
f3807a34248e· 691-713 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
f3807a34248e· 1319-1340 -
topaz.stdlib.contract.typeset-break-policyatworking-tree
Keep a word together at the fitting threshold
Linkimport std.typeset as tsimport std.ioimport std.testlet clusters = [ts.BreakCluster { text: "a", advance: 1pt, trackingAfter: 0pt }, ts.BreakCluster { text: "b", advance: 1pt, trackingAfter: 0pt }, ts.BreakCluster { text: "c", advance: 1pt, trackingAfter: 0pt }, ts.BreakCluster { text: "d", advance: 1pt, trackingAfter: 0pt }]let fitting = ts.BreakPolicy {mode: ts.BreakMode.Word(),rules: ts.KinsokuRules.AtlasDefault(),forbidBefore: [],forbidAfter: [],boundaryAllowed: [true, true, true, true],generatedHyphenEnds: [],protectFittingLatin: false,preserveShortWords: false,narrowestWordTarget: 0pt,bodyWordTarget: 4pt}let oversized = ts.BreakPolicy {mode: ts.BreakMode.Word(),rules: ts.KinsokuRules.AtlasDefault(),forbidBefore: [],forbidAfter: [],boundaryAllowed: [true, true, true, true],generatedHyphenEnds: [],protectFittingLatin: false,preserveShortWords: false,narrowestWordTarget: 0pt,bodyWordTarget: 3pt}let guarded = ts.BreakPolicy {mode: ts.BreakMode.Character(),rules: ts.KinsokuRules.AtlasDefault(),forbidBefore: [],forbidAfter: [],boundaryAllowed: [true, true, true, true],generatedHyphenEnds: [],protectFittingLatin: true,preserveShortWords: false,narrowestWordTarget: 4pt,bodyWordTarget: 0pt}let a = test.assertOk(ts.classifyBreaks(clusters, fitting))let b = test.assertOk(ts.classifyBreaks(clusters, oversized))let c = test.assertOk(ts.classifyBreaks(clusters, guarded))io.writeLine("{a.length} {b.length} {c.length}")
1 4 1
Expected result
Expected result
Execution completes. Exit code 0.
1 4 1
Source evidence
- compiler/crates/topaz_resolve/src/std/typeset/breaks.tpz at
f3807a34248e· 4-16 - compiler/crates/topaz_resolve/src/std/typeset/breaks.tpz at
f3807a34248e· 57-86 - compiler/crates/topaz_resolve/src/std/typeset/locale.tpz at
f3807a34248e· 61-106 - compiler/crates/topaz_resolve/src/std/typeset/measure.tpz at
f3807a34248e· 24-25 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
f3807a34248e· 691-713 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
f3807a34248e· 1319-1340 -
topaz.stdlib.contract.typeset-break-policyatworking-tree
Classify one generated hyphen boundary despite duplicate input indices
Linkimport std.typeset as tsimport std.ioimport std.testlet clusters = [ts.BreakCluster { text: "a", advance: 1pt, trackingAfter: 0pt }, ts.BreakCluster { text: "b", advance: 1pt, trackingAfter: 0pt }, ts.BreakCluster { text: "c", advance: 1pt, trackingAfter: 0pt }, ts.BreakCluster { text: "d", advance: 1pt, trackingAfter: 0pt }]let selected = ts.BreakPolicy {mode: ts.BreakMode.Word(),rules: ts.KinsokuRules.AtlasDefault(),forbidBefore: [],forbidAfter: [],boundaryAllowed: [true, true, true, true],generatedHyphenEnds: [2, 2],protectFittingLatin: true,preserveShortWords: false,narrowestWordTarget: 4pt,bodyWordTarget: 4pt}let breaks = test.assertOk(ts.classifyBreaks(clusters, selected))for boundary in (breaks) {let category = match (boundary.kind) {case LatinSoftHyphen() => "hyphen"case ForcedEnd() => "end"case _ => "unexpected kind"}io.writeLine("{boundary.unitEnd} {category}")}
2 hyphen 4 end
Expected result
Expected result
Execution completes. Exit code 0.
2 hyphen4 end
Source evidence
- compiler/crates/topaz_resolve/src/std/typeset/breaks.tpz at
f3807a34248e· 4-16 - compiler/crates/topaz_resolve/src/std/typeset/breaks.tpz at
f3807a34248e· 57-86 - compiler/crates/topaz_resolve/src/std/typeset/locale.tpz at
f3807a34248e· 61-106 - compiler/crates/topaz_resolve/src/std/typeset/measure.tpz at
f3807a34248e· 24-25 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
f3807a34248e· 691-713 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
f3807a34248e· 1319-1340 -
topaz.stdlib.contract.typeset-break-policyatworking-tree
Preserve a word of three counted scalars
Linkimport std.typeset as tsimport std.ioimport std.testlet clusters = [ts.BreakCluster { text: "a", advance: 1pt, trackingAfter: 0pt }, ts.BreakCluster { text: "b", advance: 1pt, trackingAfter: 0pt }, ts.BreakCluster { text: "c", advance: 1pt, trackingAfter: 0pt }]let selected = ts.BreakPolicy {mode: ts.BreakMode.Character(),rules: ts.KinsokuRules.AtlasDefault(),forbidBefore: [],forbidAfter: [],boundaryAllowed: [true, true, true],generatedHyphenEnds: [],protectFittingLatin: false,preserveShortWords: true,narrowestWordTarget: 0pt,bodyWordTarget: 0pt}let breaks = test.assertOk(ts.classifyBreaks(clusters, selected))io.writeLine("{breaks.length} {breaks[0].unitEnd}")
1 3
Expected result
Expected result
Execution completes. Exit code 0.
1 3
Source evidence
- compiler/crates/topaz_resolve/src/std/typeset/breaks.tpz at
f3807a34248e· 4-16 - compiler/crates/topaz_resolve/src/std/typeset/breaks.tpz at
f3807a34248e· 57-86 - compiler/crates/topaz_resolve/src/std/typeset/locale.tpz at
f3807a34248e· 61-106 - compiler/crates/topaz_resolve/src/std/typeset/measure.tpz at
f3807a34248e· 24-25 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
f3807a34248e· 691-713 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
f3807a34248e· 1319-1340 -
topaz.stdlib.contract.typeset-break-policyatworking-tree
Distinguish invalid policy values from invalid generated boundaries
Linkimport std.typeset as tsimport std.ioimport std.testfunction outcome(value: Result<Array<ts.BreakOpportunity>, ts.TypesetError>) -> string {match (value) {case Ok(_) => "Ok"case Err(InvalidInput(_)) => "InvalidInput"case Err(InvalidPolicy(_)) => "InvalidPolicy"case Err(_) => "unexpected error"}}let clusters = [ts.BreakCluster { text: "a", advance: 1pt, trackingAfter: 0pt }, ts.BreakCluster { text: "b", advance: 1pt, trackingAfter: 0pt }]let target = ts.BreakPolicy {mode: ts.BreakMode.Character(),rules: ts.KinsokuRules.AtlasDefault(),forbidBefore: [],forbidAfter: [],boundaryAllowed: [true, true],generatedHyphenEnds: [],protectFittingLatin: false,preserveShortWords: false,narrowestWordTarget: 0pt,bodyWordTarget: -1pt}let scalar = ts.BreakPolicy {mode: ts.BreakMode.Character(),rules: ts.KinsokuRules.AtlasDefault(),forbidBefore: [55296],forbidAfter: [],boundaryAllowed: [true, true],generatedHyphenEnds: [],protectFittingLatin: false,preserveShortWords: false,narrowestWordTarget: 0pt,bodyWordTarget: 0pt}let boundary = ts.BreakPolicy {mode: ts.BreakMode.Character(),rules: ts.KinsokuRules.AtlasDefault(),forbidBefore: [],forbidAfter: [],boundaryAllowed: [true, true],generatedHyphenEnds: [2],protectFittingLatin: false,preserveShortWords: false,narrowestWordTarget: 0pt,bodyWordTarget: 0pt}io.writeLine(outcome(ts.classifyBreaks(clusters, target)))io.writeLine(outcome(ts.classifyBreaks(clusters, scalar)))io.writeLine(outcome(ts.classifyBreaks(clusters, boundary)))
InvalidPolicy InvalidPolicy InvalidInput
Expected result
Expected result
Execution completes. Exit code 0.
InvalidPolicyInvalidPolicyInvalidInput
Source evidence
- compiler/crates/topaz_resolve/src/std/typeset/breaks.tpz at
f3807a34248e· 4-16 - compiler/crates/topaz_resolve/src/std/typeset/breaks.tpz at
f3807a34248e· 57-86 - compiler/crates/topaz_resolve/src/std/typeset/locale.tpz at
f3807a34248e· 61-106 - compiler/crates/topaz_resolve/src/std/typeset/measure.tpz at
f3807a34248e· 24-25 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
f3807a34248e· 691-713 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
f3807a34248e· 1319-1340 -
topaz.stdlib.contract.typeset-break-policyatworking-tree