Knuth Plass Policy. final Flagged Demerit: int- Module
- std.
typeset - Receiver
- Knuth
Plass Policy - 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· 48 - compiler/crates/topaz_resolve/src/stdlib.rs at
b48527d0a174· 40
Receiver
KnuthPlassPolicy
Parameter constraints
Every KnuthPlassPolicy field is a nonnegative int. A negative toleranceR, linePenalty, fitnessDemerit, flaggedDemerit, or finalFlaggedDemerit returns TypesetError.InvalidPolicy. Validation applies even when the selected CostModel is FixedPoint.
KnuthPlass uses explicit GlueItem stretch and shrink. JustificationPolicy values are validated but do not replace these capacities or its ratio score. Leading glue is discarded for the natural width and capacities. An ordinary break discards trailing glue, while a Forced break consumes trailing glue so a caller can represent a ragged final line.
Let slack be the target minus natural text width and selected penalty width. Nonnegative slack uses total stretch and negative slack uses total shrink. Zero capacity admits an exact fit and rejects a nonzero slack. Shrink admits ratios down to negative one. Positive ratios must be no greater than toleranceR divided by 100000000.
The reported adjustment ratio is scaled by 100000000 and rounded to nearest with ties to even. Admission and fitness use the exact ratio before rounding. Badness is 100 times the absolute ratio cubed, rounded to nearest with ties to even and capped at 10000.
Add linePenalty and badness, then square their sum for the basic line score. An Allowed penalty adds its squared value when nonnegative and subtracts its squared value when negative. Forced penalties add no such term. The resulting score is a signed checked int.
The four fitness classes are ratios below negative one half, ratios from negative one half through one half, ratios above one half through one, and ratios above one. Add fitnessDemerit when consecutive lines differ by more than one class. The first line has no preceding fitness transition.
Add flaggedDemerit when both the preceding and selected penalties are flagged. Add finalFlaggedDemerit when the final line follows a flagged penalty, whether or not its own penalty is flagged. The first line has no preceding flag.
An exact fit with linePenalty equal to 10, zero penalty cost, and no transition demerit has line cost 100 and adjustmentRatioR equal to zero. A nonexact line with no usable stretch or shrink is inadmissible, including a final line whose caller supplied no terminal capacity.
Related rule: Set Knuth Plass tolerance and transition costsResult
The declared result type is int.
Effects
Failures
Result and effects
LinkSelect this field from a value of its named type without call parentheses.
Add this nonnegative int when the final line follows a flagged penalty, regardless of its own flag.
Why
LinkTolerance controls acceptable adjustment and demerits control the relative cost of adjacent lines. Explicit glue capacities make final line behavior and flagged transitions reproducible without hidden default glue or a separate final line algorithm.
Resolved contracts
LinkRelated entries
LinkSet Knuth Plass tolerance and transition costs
LinkSet Knuth Plass tolerance and transition costs
Every KnuthPlassPolicy field is a nonnegative int. A negative toleranceR, linePenalty, fitnessDemerit, flaggedDemerit, or finalFlaggedDemerit returns TypesetError.InvalidPolicy. Validation applies even when the selected CostModel is FixedPoint.
KnuthPlass uses explicit GlueItem stretch and shrink. JustificationPolicy values are validated but do not replace these capacities or its ratio score. Leading glue is discarded for the natural width and capacities. An ordinary break discards trailing glue, while a Forced break consumes trailing glue so a caller can represent a ragged final line.
Let slack be the target minus natural text width and selected penalty width. Nonnegative slack uses total stretch and negative slack uses total shrink. Zero capacity admits an exact fit and rejects a nonzero slack. Shrink admits ratios down to negative one. Positive ratios must be no greater than toleranceR divided by 100000000.
The reported adjustment ratio is scaled by 100000000 and rounded to nearest with ties to even. Admission and fitness use the exact ratio before rounding. Badness is 100 times the absolute ratio cubed, rounded to nearest with ties to even and capped at 10000.
Add linePenalty and badness, then square their sum for the basic line score. An Allowed penalty adds its squared value when nonnegative and subtracts its squared value when negative. Forced penalties add no such term. The resulting score is a signed checked int.
The four fitness classes are ratios below negative one half, ratios from negative one half through one half, ratios above one half through one, and ratios above one. Add fitnessDemerit when consecutive lines differ by more than one class. The first line has no preceding fitness transition.
Add flaggedDemerit when both the preceding and selected penalties are flagged. Add finalFlaggedDemerit when the final line follows a flagged penalty, whether or not its own penalty is flagged. The first line has no preceding flag.
An exact fit with linePenalty equal to 10, zero penalty cost, and no transition demerit has line cost 100 and adjustmentRatioR equal to zero. A nonexact line with no usable stretch or shrink is inadmissible, including a final line whose caller supplied no terminal capacity.
Why
Tolerance controls acceptable adjustment and demerits control the relative cost of adjacent lines. Explicit glue capacities make final line behavior and flagged transitions reproducible without hidden default glue or a separate final line algorithm.
Source evidence
- compiler/crates/topaz_resolve/src/std/typeset/knuth_plass.tpz at
f3807a34248e· 1-51 - compiler/crates/topaz_resolve/src/std/typeset/admission.tpz at
f3807a34248e· 32-35 - compiler/crates/topaz_resolve/src/std/typeset/model.tpz at
f3807a34248e· 46-48 - compiler/crates/topaz_resolve/src/std/typeset/wide.tpz at
f3807a34248e· 4-28 -
topaz.stdlib.contract.typeset-knuth-plass-policyatworking-tree
Score an exact Knuth Plass line
Linkimport std.typeset as tsimport std.iolet items: Array<ts.Item> = [ts.Item.BoxItem(ts.Box { unitIndex: 0, text: "a", width: 10pt, trackingAfter: 0pt }),ts.Item.PenaltyItem(ts.Penalty { unitEnd: 1, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false })]let input = ts.Paragraph {grid: ts.DistanceGrid.MilliPoint(),items: items,geometry: ts.LineGeometry { bodyTarget: 10pt, firstTarget: 10pt, dropCapSpan: 0, dropCapInset: 0pt },justification: ts.JustificationPolicy {mode: ts.JustificationMode.Unjustified(), minGapCount: 0,minLineWidthRatioM: 0, minFinalLineWidthRatioM: None(),maxAdjustment: 0pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,latinSpacing: None(), cjkStretchRatio: 0.0},costModel: ts.CostModel.KnuthPlass(),knuthPlass: ts.KnuthPlassPolicy { toleranceR: 100000000, linePenalty: 10, fitnessDemerit: 0, flaggedDemerit: 0, finalFlaggedDemerit: 0 }}match (ts.breakParagraph(input)) {case Ok(result) => {let line = result.optimized.lines[0]io.writeLine("{line.cost} {line.adjustmentRatioR} {result.optimized.totalCost}")match (line.postValidationWidthLimit) {case None() => io.writeLine("ratio admission")case Some(_) => io.writeLine("unexpected width limit")}}case Err(_) => io.writeLine("unexpected error")}
100 0 100 ratio admission
Expected result
Expected result
Execution completes. Exit code 0.
100 0 100ratio admission
Source evidence
- compiler/crates/topaz_resolve/src/std/typeset/knuth_plass.tpz at
f3807a34248e· 1-51 - compiler/crates/topaz_resolve/src/std/typeset/admission.tpz at
f3807a34248e· 32-35 - compiler/crates/topaz_resolve/src/std/typeset/model.tpz at
f3807a34248e· 46-48 - compiler/crates/topaz_resolve/src/std/typeset/wide.tpz at
f3807a34248e· 4-28 -
topaz.stdlib.contract.typeset-knuth-plass-policyatworking-tree
Validate Knuth Plass policy before choosing a cost model
Linkimport std.typeset as tsimport std.iolet items: Array<ts.Item> = [ts.Item.BoxItem(ts.Box { unitIndex: 0, text: "a", width: 1pt, trackingAfter: 0pt }),ts.Item.PenaltyItem(ts.Penalty { unitEnd: 1, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false })]let input = ts.Paragraph {grid: ts.DistanceGrid.MilliPoint(),items: items,geometry: ts.LineGeometry { bodyTarget: 10pt, firstTarget: 10pt, dropCapSpan: 0, dropCapInset: 0pt },justification: ts.JustificationPolicy {mode: ts.JustificationMode.Unjustified(), minGapCount: 0,minLineWidthRatioM: 0, minFinalLineWidthRatioM: None(),maxAdjustment: 0pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,latinSpacing: None(), cjkStretchRatio: 0.0},costModel: ts.CostModel.FixedPoint(),knuthPlass: ts.KnuthPlassPolicy { toleranceR: -1, linePenalty: 10, fitnessDemerit: 0, flaggedDemerit: 0, finalFlaggedDemerit: 0 }}match (ts.breakParagraph(input)) {case Err(InvalidPolicy(_)) => io.writeLine("InvalidPolicy")case _ => io.writeLine("unexpected result")}
InvalidPolicy
Expected result
Expected result
Execution completes. Exit code 0.
InvalidPolicy
Source evidence
- compiler/crates/topaz_resolve/src/std/typeset/knuth_plass.tpz at
f3807a34248e· 1-51 - compiler/crates/topaz_resolve/src/std/typeset/admission.tpz at
f3807a34248e· 32-35 - compiler/crates/topaz_resolve/src/std/typeset/model.tpz at
f3807a34248e· 46-48 - compiler/crates/topaz_resolve/src/std/typeset/wide.tpz at
f3807a34248e· 4-28 -
topaz.stdlib.contract.typeset-knuth-plass-policyatworking-tree
Report a line with no capacity to reach its target
Linkimport std.typeset as tsimport std.iolet items: Array<ts.Item> = [ts.Item.BoxItem(ts.Box { unitIndex: 0, text: "a", width: 9pt, trackingAfter: 0pt }),ts.Item.PenaltyItem(ts.Penalty { unitEnd: 1, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false })]let input = ts.Paragraph {grid: ts.DistanceGrid.MilliPoint(),items: items,geometry: ts.LineGeometry { bodyTarget: 10pt, firstTarget: 10pt, dropCapSpan: 0, dropCapInset: 0pt },justification: ts.JustificationPolicy {mode: ts.JustificationMode.Unjustified(), minGapCount: 0,minLineWidthRatioM: 0, minFinalLineWidthRatioM: None(),maxAdjustment: 0pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,latinSpacing: None(), cjkStretchRatio: 0.0},costModel: ts.CostModel.KnuthPlass(),knuthPlass: ts.KnuthPlassPolicy { toleranceR: 100000000, linePenalty: 10, fitnessDemerit: 0, flaggedDemerit: 0, finalFlaggedDemerit: 0 }}match (ts.breakParagraph(input)) {case Err(NoGreedyPlan()) => io.writeLine("NoGreedyPlan")case _ => io.writeLine("unexpected result")}
NoGreedyPlan
Expected result
Expected result
Execution completes. Exit code 0.
NoGreedyPlan
Source evidence
- compiler/crates/topaz_resolve/src/std/typeset/knuth_plass.tpz at
f3807a34248e· 1-51 - compiler/crates/topaz_resolve/src/std/typeset/admission.tpz at
f3807a34248e· 32-35 - compiler/crates/topaz_resolve/src/std/typeset/model.tpz at
f3807a34248e· 46-48 - compiler/crates/topaz_resolve/src/std/typeset/wide.tpz at
f3807a34248e· 4-28 -
topaz.stdlib.contract.typeset-knuth-plass-policyatworking-tree