postext 0.3.6 → 0.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/exports.test.js +3 -0
- package/dist/__tests__/exports.test.js.map +1 -1
- package/dist/canvas-backend/blockRender.d.ts +3 -0
- package/dist/canvas-backend/blockRender.d.ts.map +1 -0
- package/dist/canvas-backend/blockRender.js +176 -0
- package/dist/canvas-backend/blockRender.js.map +1 -0
- package/dist/canvas-backend/decorations.d.ts +6 -0
- package/dist/canvas-backend/decorations.d.ts.map +1 -0
- package/dist/canvas-backend/decorations.js +106 -0
- package/dist/canvas-backend/decorations.js.map +1 -0
- package/dist/{canvas-backend.d.ts → canvas-backend/index.d.ts} +2 -2
- package/dist/canvas-backend/index.d.ts.map +1 -0
- package/dist/canvas-backend/index.js +66 -0
- package/dist/canvas-backend/index.js.map +1 -0
- package/dist/defaults/index.d.ts +1 -0
- package/dist/defaults/index.d.ts.map +1 -1
- package/dist/defaults/index.js +9 -0
- package/dist/defaults/index.js.map +1 -1
- package/dist/defaults/pdfGeneration.d.ts +5 -0
- package/dist/defaults/pdfGeneration.d.ts.map +1 -0
- package/dist/defaults/pdfGeneration.js +37 -0
- package/dist/defaults/pdfGeneration.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/knuthPlass/breakpoints.d.ts +6 -0
- package/dist/knuthPlass/breakpoints.d.ts.map +1 -0
- package/dist/knuthPlass/breakpoints.js +284 -0
- package/dist/knuthPlass/breakpoints.js.map +1 -0
- package/dist/knuthPlass/constants.d.ts +8 -0
- package/dist/knuthPlass/constants.d.ts.map +1 -0
- package/dist/knuthPlass/constants.js +8 -0
- package/dist/knuthPlass/constants.js.map +1 -0
- package/dist/knuthPlass/index.d.ts +12 -0
- package/dist/knuthPlass/index.d.ts.map +1 -0
- package/dist/knuthPlass/index.js +11 -0
- package/dist/knuthPlass/index.js.map +1 -0
- package/dist/knuthPlass/pretextAdapter.d.ts +12 -0
- package/dist/knuthPlass/pretextAdapter.d.ts.map +1 -0
- package/dist/knuthPlass/pretextAdapter.js +178 -0
- package/dist/knuthPlass/pretextAdapter.js.map +1 -0
- package/dist/knuthPlass/richAdapter.d.ts +26 -0
- package/dist/knuthPlass/richAdapter.d.ts.map +1 -0
- package/dist/knuthPlass/richAdapter.js +189 -0
- package/dist/knuthPlass/richAdapter.js.map +1 -0
- package/dist/{knuthPlass.d.ts → knuthPlass/types.d.ts} +1 -31
- package/dist/knuthPlass/types.d.ts.map +1 -0
- package/dist/knuthPlass/types.js +5 -0
- package/dist/knuthPlass/types.js.map +1 -0
- package/dist/knuthPlass/utils.d.ts +2 -0
- package/dist/knuthPlass/utils.d.ts.map +1 -0
- package/dist/knuthPlass/utils.js +4 -0
- package/dist/knuthPlass/utils.js.map +1 -0
- package/dist/measure/cache.d.ts +5 -0
- package/dist/measure/cache.d.ts.map +1 -0
- package/dist/measure/cache.js +38 -0
- package/dist/measure/cache.js.map +1 -0
- package/dist/measure/canvas.d.ts +8 -0
- package/dist/measure/canvas.d.ts.map +1 -0
- package/dist/measure/canvas.js +30 -0
- package/dist/measure/canvas.js.map +1 -0
- package/dist/measure/font.d.ts +19 -0
- package/dist/measure/font.d.ts.map +1 -0
- package/dist/measure/font.js +34 -0
- package/dist/measure/font.js.map +1 -0
- package/dist/measure/index.d.ts +7 -0
- package/dist/measure/index.d.ts.map +1 -0
- package/dist/measure/index.js +6 -0
- package/dist/measure/index.js.map +1 -0
- package/dist/measure/plain.d.ts +13 -0
- package/dist/measure/plain.d.ts.map +1 -0
- package/dist/measure/plain.js +167 -0
- package/dist/measure/plain.js.map +1 -0
- package/dist/measure/rich.d.ts +25 -0
- package/dist/measure/rich.d.ts.map +1 -0
- package/dist/measure/rich.js +246 -0
- package/dist/measure/rich.js.map +1 -0
- package/dist/measure/types.d.ts +28 -0
- package/dist/measure/types.d.ts.map +1 -0
- package/dist/measure/types.js +2 -0
- package/dist/measure/types.js.map +1 -0
- package/dist/parse/blockParser.d.ts +28 -0
- package/dist/parse/blockParser.d.ts.map +1 -0
- package/dist/parse/blockParser.js +302 -0
- package/dist/parse/blockParser.js.map +1 -0
- package/dist/parse/index.d.ts +4 -0
- package/dist/parse/index.d.ts.map +1 -0
- package/dist/parse/index.js +3 -0
- package/dist/parse/index.js.map +1 -0
- package/dist/parse/inlineFormatting.d.ts +12 -0
- package/dist/parse/inlineFormatting.d.ts.map +1 -0
- package/dist/parse/inlineFormatting.js +90 -0
- package/dist/parse/inlineFormatting.js.map +1 -0
- package/dist/parse/inlineMath.d.ts +29 -0
- package/dist/parse/inlineMath.d.ts.map +1 -0
- package/dist/parse/inlineMath.js +141 -0
- package/dist/parse/inlineMath.js.map +1 -0
- package/dist/parse/sourceMapping.d.ts +12 -0
- package/dist/parse/sourceMapping.d.ts.map +1 -0
- package/dist/parse/sourceMapping.js +130 -0
- package/dist/parse/sourceMapping.js.map +1 -0
- package/dist/{parse.d.ts → parse/types.d.ts} +2 -25
- package/dist/parse/types.d.ts.map +1 -0
- package/dist/parse/types.js +2 -0
- package/dist/parse/types.js.map +1 -0
- package/dist/pipeline/build.d.ts.map +1 -1
- package/dist/pipeline/build.js +34 -276
- package/dist/pipeline/build.js.map +1 -1
- package/dist/pipeline/buildBlockKind.d.ts +33 -0
- package/dist/pipeline/buildBlockKind.d.ts.map +1 -0
- package/dist/pipeline/buildBlockKind.js +82 -0
- package/dist/pipeline/buildBlockKind.js.map +1 -0
- package/dist/pipeline/buildHelpers.d.ts +47 -0
- package/dist/pipeline/buildHelpers.d.ts.map +1 -0
- package/dist/pipeline/buildHelpers.js +169 -0
- package/dist/pipeline/buildHelpers.js.map +1 -0
- package/dist/pipeline/buildMeasurement.d.ts +27 -0
- package/dist/pipeline/buildMeasurement.d.ts.map +1 -0
- package/dist/pipeline/buildMeasurement.js +49 -0
- package/dist/pipeline/buildMeasurement.js.map +1 -0
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/canvas-backend.d.ts.map +0 -1
- package/dist/canvas-backend.js +0 -370
- package/dist/canvas-backend.js.map +0 -1
- package/dist/knuthPlass.d.ts.map +0 -1
- package/dist/knuthPlass.js +0 -665
- package/dist/knuthPlass.js.map +0 -1
- package/dist/measure.d.ts +0 -61
- package/dist/measure.d.ts.map +0 -1
- package/dist/measure.js +0 -512
- package/dist/measure.js.map +0 -1
- package/dist/parse.d.ts.map +0 -1
- package/dist/parse.js +0 -653
- package/dist/parse.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEhE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAElF,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,cAAc,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAE1M,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,8BAA8B,EAAE,2BAA2B,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEhE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAElF,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,cAAc,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAE1M,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,8BAA8B,EAAE,2BAA2B,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAyE1nC,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breakpoints.d.ts","sourceRoot":"","sources":["../../src/knuthPlass/breakpoints.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAa,MAAM,SAAS,CAAC;AA4C5D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,GAAG,MAAM,EAAE,CAyShF"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Knuth-Plass dynamic-programming breakpoint selection.
|
|
3
|
+
*/
|
|
4
|
+
import { BADNESS_CAP, DEFAULT_CONSECUTIVE_HYPHEN_DEMERIT, DEFAULT_FITNESS_CLASS_DEMERIT, KP_INFINITY, } from './constants';
|
|
5
|
+
function classifyFitness(r) {
|
|
6
|
+
if (r < -0.5)
|
|
7
|
+
return 0; // tight
|
|
8
|
+
if (r < 0.5)
|
|
9
|
+
return 1; // normal
|
|
10
|
+
if (r < 1.0)
|
|
11
|
+
return 2; // loose
|
|
12
|
+
return 3; // very loose
|
|
13
|
+
}
|
|
14
|
+
function computeBadness(r) {
|
|
15
|
+
const absR = Math.abs(r);
|
|
16
|
+
const b = Math.round(100 * absR * absR * absR);
|
|
17
|
+
return Math.min(b, BADNESS_CAP);
|
|
18
|
+
}
|
|
19
|
+
export function computeBreakpoints(items, options) {
|
|
20
|
+
const { lineWidth, consecutiveHyphenDemerit = DEFAULT_CONSECUTIVE_HYPHEN_DEMERIT, fitnessClassDemerit = DEFAULT_FITNESS_CLASS_DEMERIT, runtPenalty = 0, runtMinWidth = 0, } = options;
|
|
21
|
+
const terminalBreakPosition = items.length - 1;
|
|
22
|
+
// Running totals up to current item
|
|
23
|
+
let sumWidth = 0;
|
|
24
|
+
let sumStretch = 0;
|
|
25
|
+
let sumShrink = 0;
|
|
26
|
+
// Prefix sums: sumWidthAt[i] = sum of widths of items 0..i-1
|
|
27
|
+
// We build these incrementally and store for the range computations.
|
|
28
|
+
const sumWidthAt = [0];
|
|
29
|
+
const sumStretchAt = [0];
|
|
30
|
+
const sumShrinkAt = [0];
|
|
31
|
+
for (const item of items) {
|
|
32
|
+
if (item.type === 'box') {
|
|
33
|
+
sumWidth += item.width;
|
|
34
|
+
}
|
|
35
|
+
else if (item.type === 'glue') {
|
|
36
|
+
sumWidth += item.width;
|
|
37
|
+
sumStretch += item.stretch;
|
|
38
|
+
sumShrink += item.shrink;
|
|
39
|
+
}
|
|
40
|
+
// Penalties don't contribute to running width/stretch/shrink
|
|
41
|
+
sumWidthAt.push(sumWidth);
|
|
42
|
+
sumStretchAt.push(sumStretch);
|
|
43
|
+
sumShrinkAt.push(sumShrink);
|
|
44
|
+
}
|
|
45
|
+
// Seed active node list with a "start of paragraph" sentinel
|
|
46
|
+
let activeNodes = [{
|
|
47
|
+
position: -1,
|
|
48
|
+
line: 0,
|
|
49
|
+
fitnessClass: 1,
|
|
50
|
+
totalWidth: 0,
|
|
51
|
+
totalStretch: 0,
|
|
52
|
+
totalShrink: 0,
|
|
53
|
+
totalDemerits: 0,
|
|
54
|
+
previous: null,
|
|
55
|
+
}];
|
|
56
|
+
for (let i = 0; i < items.length; i++) {
|
|
57
|
+
const item = items[i];
|
|
58
|
+
// Determine if this position is a legal breakpoint
|
|
59
|
+
let isLegalBreak = false;
|
|
60
|
+
if (item.type === 'glue') {
|
|
61
|
+
// Glue breaks if preceded by a box
|
|
62
|
+
if (i > 0 && items[i - 1].type === 'box') {
|
|
63
|
+
isLegalBreak = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (item.type === 'penalty') {
|
|
67
|
+
if (item.penalty < KP_INFINITY) {
|
|
68
|
+
isLegalBreak = true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (!isLegalBreak)
|
|
72
|
+
continue;
|
|
73
|
+
// Width contribution of breaking at this item
|
|
74
|
+
const breakWidth = item.type === 'penalty' ? item.width : 0;
|
|
75
|
+
const isFlagged = item.type === 'penalty' && item.flagged;
|
|
76
|
+
// For glue breakpoints, the line content goes up to (but excluding) this glue.
|
|
77
|
+
// For penalty breakpoints, the line content goes up to this penalty.
|
|
78
|
+
// The content width from after active node a to break at i:
|
|
79
|
+
// If glue: sumWidthAt[i] - a.totalWidth (excludes glue itself)
|
|
80
|
+
// If penalty: sumWidthAt[i] - a.totalWidth (sumWidthAt doesn't include penalty width)
|
|
81
|
+
// Plus breakWidth for penalties.
|
|
82
|
+
// Compute the content width from the items between a.position and i.
|
|
83
|
+
// After the break at active node a.position:
|
|
84
|
+
// - If a.position was a glue break, the next line starts at the item AFTER the glue
|
|
85
|
+
// - If a.position was a penalty break, the next line starts at the item AFTER the penalty
|
|
86
|
+
// - For the sentinel (-1), the line starts at item 0
|
|
87
|
+
// Total width from start to just before item i (excluding this glue/penalty's own width):
|
|
88
|
+
// For a glue at i: line content = sumWidthAt[i] (which includes all box+glue widths before i)
|
|
89
|
+
// but we need to subtract the width of glues/boxes after the previous break.
|
|
90
|
+
// Actually sumWidthAt[i] already accounts for that.
|
|
91
|
+
// We subtract a.totalWidth which is sumWidthAt at the point right after a's break.
|
|
92
|
+
const newNodes = [];
|
|
93
|
+
const toDeactivate = new Set();
|
|
94
|
+
for (let ai = 0; ai < activeNodes.length; ai++) {
|
|
95
|
+
const a = activeNodes[ai];
|
|
96
|
+
// Line content width: width of boxes and glues from after a's break to this break.
|
|
97
|
+
// For glue break: content is items from (a.position+1) to (i-1) inclusive + breakWidth
|
|
98
|
+
// = sumWidthAt[i] - a.totalWidth
|
|
99
|
+
// For penalty break: content is items from (a.position+1) to (i-1) inclusive + penalty.width
|
|
100
|
+
// = sumWidthAt[i] - a.totalWidth + breakWidth
|
|
101
|
+
// Note: sumWidthAt[i] does NOT include item i if it's a penalty.
|
|
102
|
+
// sumWidthAt[i] includes item i's width only for box/glue through the push.
|
|
103
|
+
// Wait — re-examine: sumWidthAt[i] is the prefix sum BEFORE item i is processed.
|
|
104
|
+
// Actually, sumWidthAt has length items.length + 1. sumWidthAt[0] = 0, sumWidthAt[k+1] includes item k.
|
|
105
|
+
// So sumWidthAt[i] includes items 0..i-1, and sumWidthAt[i+1] includes items 0..i.
|
|
106
|
+
// For a glue break at position i:
|
|
107
|
+
// The line goes from after a's break to just before this glue.
|
|
108
|
+
// Content width = sumWidthAt[i] - a.totalWidth
|
|
109
|
+
// (sumWidthAt[i] includes items 0..i-1, which covers everything up to but not including the glue)
|
|
110
|
+
//
|
|
111
|
+
// For a penalty break at position i:
|
|
112
|
+
// The line includes everything up to but not including the penalty, plus breakWidth
|
|
113
|
+
// Content width = sumWidthAt[i] - a.totalWidth + breakWidth
|
|
114
|
+
const contentWidth = sumWidthAt[i] - a.totalWidth + breakWidth;
|
|
115
|
+
const available = lineWidth(a.line);
|
|
116
|
+
const slack = available - contentWidth;
|
|
117
|
+
// Stretch/shrink from the items on this line
|
|
118
|
+
const lineStretch = sumStretchAt[i] - a.totalStretch;
|
|
119
|
+
const lineShrink = sumShrinkAt[i] - a.totalShrink;
|
|
120
|
+
let r;
|
|
121
|
+
if (slack >= 0) {
|
|
122
|
+
r = lineStretch > 0 ? slack / lineStretch : KP_INFINITY;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
r = lineShrink > 0 ? slack / lineShrink : -KP_INFINITY;
|
|
126
|
+
}
|
|
127
|
+
// Deactivate nodes that are too far behind (line too wide, can't shrink enough)
|
|
128
|
+
if (r < -1) {
|
|
129
|
+
toDeactivate.add(ai);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
// Feasibility: don't allow extreme stretching
|
|
133
|
+
// We allow r up to a generous threshold; the demerits will naturally penalize loose lines
|
|
134
|
+
if (r > KP_INFINITY) {
|
|
135
|
+
// Infeasible — too few items to fill the line
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const badness = computeBadness(r);
|
|
139
|
+
const pen = item.type === 'penalty' ? item.penalty : 0;
|
|
140
|
+
// Runt: when this break closes the paragraph with a too-short final
|
|
141
|
+
// line, inject `runtPenalty` as equivalent badness — so it enters the
|
|
142
|
+
// squared demerit formula alongside `badness`, on the same scale as
|
|
143
|
+
// hyphen penalties. Applied linearly (old behavior) it was dwarfed by
|
|
144
|
+
// badness² (up to 10001² ≈ 1e8) from any stretched alternative.
|
|
145
|
+
const isRunt = runtPenalty > 0 &&
|
|
146
|
+
i === terminalBreakPosition &&
|
|
147
|
+
contentWidth > 0 &&
|
|
148
|
+
contentWidth < runtMinWidth;
|
|
149
|
+
const effectiveBadness = isRunt ? badness + runtPenalty : badness;
|
|
150
|
+
let d;
|
|
151
|
+
if (pen >= 0) {
|
|
152
|
+
d = (1 + effectiveBadness + pen) * (1 + effectiveBadness + pen);
|
|
153
|
+
}
|
|
154
|
+
else if (pen > -KP_INFINITY) {
|
|
155
|
+
d = (1 + effectiveBadness) * (1 + effectiveBadness) - pen * pen;
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
d = (1 + effectiveBadness) * (1 + effectiveBadness);
|
|
159
|
+
}
|
|
160
|
+
// Consecutive hyphen demerit
|
|
161
|
+
const prevIsFlagged = a.position >= 0 &&
|
|
162
|
+
items[a.position].type === 'penalty' &&
|
|
163
|
+
items[a.position].flagged;
|
|
164
|
+
if (isFlagged && prevIsFlagged) {
|
|
165
|
+
d += consecutiveHyphenDemerit;
|
|
166
|
+
}
|
|
167
|
+
// Fitness class demerit
|
|
168
|
+
const fc = classifyFitness(r);
|
|
169
|
+
if (Math.abs(fc - a.fitnessClass) > 1) {
|
|
170
|
+
d += fitnessClassDemerit;
|
|
171
|
+
}
|
|
172
|
+
const totalDemerits = a.totalDemerits + d;
|
|
173
|
+
// The total width/stretch/shrink after this break:
|
|
174
|
+
// After a glue break: the glue is consumed. Next line starts at item i+1.
|
|
175
|
+
// totalWidth = sumWidthAt[i+1] (includes the glue's width — but we DON'T want it on the next line)
|
|
176
|
+
// Actually, for the "totalWidth" tracked in active nodes, it represents the cumulative
|
|
177
|
+
// width at the START of the next line. After a glue break at i, the next line starts at i+1.
|
|
178
|
+
// So totalWidth should be sumWidthAt[i+1], which includes the glue.
|
|
179
|
+
// When computing content width for the next line: sumWidthAt[j] - totalWidth
|
|
180
|
+
// This correctly excludes the consumed glue.
|
|
181
|
+
//
|
|
182
|
+
// After a penalty break: the penalty is not consumed as content on the next line.
|
|
183
|
+
// totalWidth = sumWidthAt[i+1] (which for penalties is same as sumWidthAt[i] since penalties
|
|
184
|
+
// don't add to sumWidth). Wait — let me re-check: penalties don't contribute to sumWidth,
|
|
185
|
+
// so sumWidthAt[i+1] == sumWidthAt[i] for a penalty at position i.
|
|
186
|
+
// But the next line starts at i+1. So totalWidth = sumWidthAt[i+1].
|
|
187
|
+
const newTotalWidth = sumWidthAt[i + 1];
|
|
188
|
+
const newTotalStretch = sumStretchAt[i + 1];
|
|
189
|
+
const newTotalShrink = sumShrinkAt[i + 1];
|
|
190
|
+
newNodes.push({
|
|
191
|
+
position: i,
|
|
192
|
+
line: a.line + 1,
|
|
193
|
+
fitnessClass: fc,
|
|
194
|
+
totalWidth: newTotalWidth,
|
|
195
|
+
totalStretch: newTotalStretch,
|
|
196
|
+
totalShrink: newTotalShrink,
|
|
197
|
+
totalDemerits: totalDemerits,
|
|
198
|
+
previous: a,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
// Remove deactivated nodes
|
|
202
|
+
if (toDeactivate.size > 0) {
|
|
203
|
+
activeNodes = activeNodes.filter((_, idx) => !toDeactivate.has(idx));
|
|
204
|
+
}
|
|
205
|
+
// Deduplicate new nodes by (line, fitnessClass): keep best demerits.
|
|
206
|
+
// Different breakpoint positions must NOT be merged — only nodes at the
|
|
207
|
+
// same position (which all newNodes share) can be compared.
|
|
208
|
+
const deduped = [];
|
|
209
|
+
for (const node of newNodes) {
|
|
210
|
+
const key = node.line * 4 + node.fitnessClass;
|
|
211
|
+
let found = false;
|
|
212
|
+
for (let di = 0; di < deduped.length; di++) {
|
|
213
|
+
const existing = deduped[di];
|
|
214
|
+
if (existing.line * 4 + existing.fitnessClass === key) {
|
|
215
|
+
if (node.totalDemerits < existing.totalDemerits) {
|
|
216
|
+
deduped[di] = node;
|
|
217
|
+
}
|
|
218
|
+
found = true;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (!found) {
|
|
223
|
+
deduped.push(node);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Append all deduplicated nodes to the active set
|
|
227
|
+
for (const node of deduped) {
|
|
228
|
+
activeNodes.push(node);
|
|
229
|
+
}
|
|
230
|
+
// Forced breaks: when penalty = -INFINITY, remove all active nodes that
|
|
231
|
+
// are NOT at this position. The break is mandatory — no line can skip it.
|
|
232
|
+
if (item.type === 'penalty' && item.penalty <= -KP_INFINITY) {
|
|
233
|
+
activeNodes = activeNodes.filter((a) => a.position === i);
|
|
234
|
+
}
|
|
235
|
+
// Emergency fallback: if active set is empty, force a break here
|
|
236
|
+
if (activeNodes.length === 0) {
|
|
237
|
+
activeNodes.push({
|
|
238
|
+
position: i,
|
|
239
|
+
line: 1, // We lost track — start fresh
|
|
240
|
+
fitnessClass: 1,
|
|
241
|
+
totalWidth: sumWidthAt[i + 1],
|
|
242
|
+
totalStretch: sumStretchAt[i + 1],
|
|
243
|
+
totalShrink: sumShrinkAt[i + 1],
|
|
244
|
+
totalDemerits: 0,
|
|
245
|
+
previous: null,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Find best final node: only consider nodes at the last breakpoint position
|
|
250
|
+
// (the forced penalty at the end of the paragraph).
|
|
251
|
+
const lastBreakPosition = items.length - 1;
|
|
252
|
+
let best = null;
|
|
253
|
+
for (const a of activeNodes) {
|
|
254
|
+
if (a.position !== lastBreakPosition)
|
|
255
|
+
continue;
|
|
256
|
+
if (best === null || a.totalDemerits < best.totalDemerits) {
|
|
257
|
+
best = a;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// Fallback: if no node reached the final position, take any node with the
|
|
261
|
+
// highest position (nearest to the end).
|
|
262
|
+
if (!best) {
|
|
263
|
+
for (const a of activeNodes) {
|
|
264
|
+
if (a.position < 0)
|
|
265
|
+
continue;
|
|
266
|
+
if (best === null || a.position > best.position ||
|
|
267
|
+
(a.position === best.position && a.totalDemerits < best.totalDemerits)) {
|
|
268
|
+
best = a;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (!best)
|
|
273
|
+
return [];
|
|
274
|
+
// Traceback
|
|
275
|
+
const breaks = [];
|
|
276
|
+
let node = best;
|
|
277
|
+
while (node !== null && node.position >= 0) {
|
|
278
|
+
breaks.push(node.position);
|
|
279
|
+
node = node.previous;
|
|
280
|
+
}
|
|
281
|
+
breaks.reverse();
|
|
282
|
+
return breaks;
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=breakpoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breakpoints.js","sourceRoot":"","sources":["../../src/knuthPlass/breakpoints.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const KP_INFINITY = 10000;
|
|
2
|
+
export declare const HYPHEN_PENALTY = 50;
|
|
3
|
+
export declare const DEFAULT_CONSECUTIVE_HYPHEN_DEMERIT = 3000;
|
|
4
|
+
export declare const DEFAULT_FITNESS_CLASS_DEMERIT = 100;
|
|
5
|
+
export declare const BADNESS_CAP = 10000;
|
|
6
|
+
export declare const MAX_STRETCH: number;
|
|
7
|
+
export declare const SOFT_HYPHEN = "\u00AD";
|
|
8
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/knuthPlass/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,QAAQ,CAAC;AACjC,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,kCAAkC,OAAO,CAAC;AACvD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AACjD,eAAO,MAAM,WAAW,QAAQ,CAAC;AACjC,eAAO,MAAM,WAAW,QAA0B,CAAC;AAEnD,eAAO,MAAM,WAAW,WAAW,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const KP_INFINITY = 10000;
|
|
2
|
+
export const HYPHEN_PENALTY = 50;
|
|
3
|
+
export const DEFAULT_CONSECUTIVE_HYPHEN_DEMERIT = 3000;
|
|
4
|
+
export const DEFAULT_FITNESS_CLASS_DEMERIT = 100;
|
|
5
|
+
export const BADNESS_CAP = 10000;
|
|
6
|
+
export const MAX_STRETCH = Number.MAX_SAFE_INTEGER;
|
|
7
|
+
export const SOFT_HYPHEN = '\u00AD';
|
|
8
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/knuthPlass/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC;AACjC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,kCAAkC,GAAG,IAAI,CAAC;AACvD,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AACjD,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC;AACjC,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAEnD,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knuth-Plass optimal paragraph line-breaking algorithm.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the greedy first-fit line breaker with a dynamic-programming
|
|
5
|
+
* approach that minimizes total demerits across all lines of a paragraph,
|
|
6
|
+
* producing more even word-spacing and fewer "loose" lines.
|
|
7
|
+
*/
|
|
8
|
+
export type { KPBox, KPGlue, KPPenalty, KPItem, KPOptions, RichTokenMeta, } from './types';
|
|
9
|
+
export { computeBreakpoints } from './breakpoints';
|
|
10
|
+
export { pretextSegmentsToItems, reconstructPretextLines } from './pretextAdapter';
|
|
11
|
+
export { richTokensToItems, reconstructRichLines } from './richAdapter';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/knuthPlass/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACV,KAAK,EACL,MAAM,EACN,SAAS,EACT,MAAM,EACN,SAAS,EACT,aAAa,GACd,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knuth-Plass optimal paragraph line-breaking algorithm.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the greedy first-fit line breaker with a dynamic-programming
|
|
5
|
+
* approach that minimizes total demerits across all lines of a paragraph,
|
|
6
|
+
* producing more even word-spacing and fewer "loose" lines.
|
|
7
|
+
*/
|
|
8
|
+
export { computeBreakpoints } from './breakpoints';
|
|
9
|
+
export { pretextSegmentsToItems, reconstructPretextLines } from './pretextAdapter';
|
|
10
|
+
export { richTokensToItems, reconstructRichLines } from './richAdapter';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/knuthPlass/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter between @chenglou/pretext `PreparedTextWithSegments` and the
|
|
3
|
+
* Knuth-Plass item stream, plus reconstruction of VDT lines from the
|
|
4
|
+
* optimal breakpoint sequence.
|
|
5
|
+
*/
|
|
6
|
+
import type { PreparedTextWithSegments } from '@chenglou/pretext';
|
|
7
|
+
import type { VDTLine } from '../vdt';
|
|
8
|
+
import type { TextAlign } from '../types';
|
|
9
|
+
import type { KPItem } from './types';
|
|
10
|
+
export declare function pretextSegmentsToItems(prepared: PreparedTextWithSegments, normalSpaceWidth: number, maxStretchRatio: number, minShrinkRatio: number): KPItem[];
|
|
11
|
+
export declare function reconstructPretextLines(items: KPItem[], breaks: number[], prepared: PreparedTextWithSegments, lineHeightPx: number, lineWidthFn: (lineIndex: number) => number, lineIndentFn: (lineIndex: number) => number, normalSpaceWidth: number, textAlign: TextAlign): VDTLine[];
|
|
12
|
+
//# sourceMappingURL=pretextAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pretextAdapter.d.ts","sourceRoot":"","sources":["../../src/knuthPlass/pretextAdapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,QAAQ,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAItC,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,wBAAwB,EAClC,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,GACrB,MAAM,EAAE,CAmFV;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,EAAE,wBAAwB,EAClC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAC1C,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAC3C,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,SAAS,GACnB,OAAO,EAAE,CAoGX"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter between @chenglou/pretext `PreparedTextWithSegments` and the
|
|
3
|
+
* Knuth-Plass item stream, plus reconstruction of VDT lines from the
|
|
4
|
+
* optimal breakpoint sequence.
|
|
5
|
+
*/
|
|
6
|
+
import { createBoundingBox } from '../vdt';
|
|
7
|
+
import { HYPHEN_PENALTY, KP_INFINITY, MAX_STRETCH, SOFT_HYPHEN } from './constants';
|
|
8
|
+
import { cleanSoftHyphens } from './utils';
|
|
9
|
+
export function pretextSegmentsToItems(prepared, normalSpaceWidth, maxStretchRatio, minShrinkRatio) {
|
|
10
|
+
const items = [];
|
|
11
|
+
const segments = prepared.segments;
|
|
12
|
+
const widths = prepared.widths;
|
|
13
|
+
const kinds = prepared.kinds;
|
|
14
|
+
const discretionaryHyphenWidth = prepared.discretionaryHyphenWidth;
|
|
15
|
+
const stretchPerSpace = normalSpaceWidth * (maxStretchRatio - 1);
|
|
16
|
+
const shrinkPerSpace = normalSpaceWidth * (1 - minShrinkRatio);
|
|
17
|
+
for (let i = 0; i < segments.length; i++) {
|
|
18
|
+
const kind = kinds[i];
|
|
19
|
+
const w = widths[i];
|
|
20
|
+
switch (kind) {
|
|
21
|
+
case 'text':
|
|
22
|
+
items.push({ type: 'box', width: w, sourceIndex: i });
|
|
23
|
+
break;
|
|
24
|
+
case 'space':
|
|
25
|
+
case 'glue':
|
|
26
|
+
items.push({
|
|
27
|
+
type: 'glue',
|
|
28
|
+
width: w,
|
|
29
|
+
stretch: stretchPerSpace,
|
|
30
|
+
shrink: shrinkPerSpace,
|
|
31
|
+
sourceIndex: i,
|
|
32
|
+
});
|
|
33
|
+
break;
|
|
34
|
+
case 'soft-hyphen':
|
|
35
|
+
items.push({
|
|
36
|
+
type: 'penalty',
|
|
37
|
+
width: discretionaryHyphenWidth,
|
|
38
|
+
penalty: HYPHEN_PENALTY,
|
|
39
|
+
flagged: true,
|
|
40
|
+
sourceIndex: i,
|
|
41
|
+
});
|
|
42
|
+
break;
|
|
43
|
+
case 'hard-break':
|
|
44
|
+
items.push({
|
|
45
|
+
type: 'penalty',
|
|
46
|
+
width: 0,
|
|
47
|
+
penalty: -KP_INFINITY,
|
|
48
|
+
flagged: false,
|
|
49
|
+
sourceIndex: i,
|
|
50
|
+
});
|
|
51
|
+
break;
|
|
52
|
+
case 'zero-width-break':
|
|
53
|
+
items.push({
|
|
54
|
+
type: 'penalty',
|
|
55
|
+
width: 0,
|
|
56
|
+
penalty: 0,
|
|
57
|
+
flagged: false,
|
|
58
|
+
sourceIndex: i,
|
|
59
|
+
});
|
|
60
|
+
break;
|
|
61
|
+
case 'preserved-space':
|
|
62
|
+
case 'tab':
|
|
63
|
+
items.push({ type: 'box', width: w, sourceIndex: i });
|
|
64
|
+
break;
|
|
65
|
+
default:
|
|
66
|
+
items.push({ type: 'box', width: w, sourceIndex: i });
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Final-line glue (infinite stretch) + forced break
|
|
71
|
+
items.push({
|
|
72
|
+
type: 'glue',
|
|
73
|
+
width: 0,
|
|
74
|
+
stretch: MAX_STRETCH,
|
|
75
|
+
shrink: 0,
|
|
76
|
+
sourceIndex: -1,
|
|
77
|
+
});
|
|
78
|
+
items.push({
|
|
79
|
+
type: 'penalty',
|
|
80
|
+
width: 0,
|
|
81
|
+
penalty: -KP_INFINITY,
|
|
82
|
+
flagged: false,
|
|
83
|
+
sourceIndex: -1,
|
|
84
|
+
});
|
|
85
|
+
return items;
|
|
86
|
+
}
|
|
87
|
+
export function reconstructPretextLines(items, breaks, prepared, lineHeightPx, lineWidthFn, lineIndentFn, normalSpaceWidth, textAlign) {
|
|
88
|
+
const segments = prepared.segments;
|
|
89
|
+
const widths = prepared.widths;
|
|
90
|
+
const discretionaryHyphenWidth = prepared.discretionaryHyphenWidth;
|
|
91
|
+
const lines = [];
|
|
92
|
+
let lineStart = 0; // item index where current line content starts
|
|
93
|
+
for (let li = 0; li < breaks.length; li++) {
|
|
94
|
+
const breakAt = breaks[li];
|
|
95
|
+
const isLastLine = li === breaks.length - 1;
|
|
96
|
+
const lineIndent = lineIndentFn(li);
|
|
97
|
+
const lineMaxWidth = lineWidthFn(li);
|
|
98
|
+
// Determine if this break is at a penalty (hyphenation)
|
|
99
|
+
const breakItem = items[breakAt];
|
|
100
|
+
const hyphenated = breakItem.type === 'penalty' && breakItem.flagged;
|
|
101
|
+
// Collect segments for this line: items from lineStart to breakAt
|
|
102
|
+
// For glue breaks: line content is items lineStart..breakAt-1 (exclude the breaking glue)
|
|
103
|
+
// For penalty breaks: line content is items lineStart..breakAt-1 (exclude the penalty itself)
|
|
104
|
+
const contentEnd = breakItem.type === 'glue' ? breakAt : breakAt;
|
|
105
|
+
const lineSegments = [];
|
|
106
|
+
const textParts = [];
|
|
107
|
+
for (let j = lineStart; j < contentEnd; j++) {
|
|
108
|
+
const it = items[j];
|
|
109
|
+
if (it.sourceIndex < 0)
|
|
110
|
+
continue; // skip synthetic items
|
|
111
|
+
if (it.type === 'box') {
|
|
112
|
+
const seg = segments[it.sourceIndex];
|
|
113
|
+
const w = widths[it.sourceIndex];
|
|
114
|
+
if (seg === SOFT_HYPHEN)
|
|
115
|
+
continue;
|
|
116
|
+
const cleanText = cleanSoftHyphens(seg);
|
|
117
|
+
lineSegments.push({ kind: 'text', text: cleanText, width: w });
|
|
118
|
+
textParts.push(cleanText);
|
|
119
|
+
}
|
|
120
|
+
else if (it.type === 'glue') {
|
|
121
|
+
const seg = segments[it.sourceIndex];
|
|
122
|
+
const w = widths[it.sourceIndex];
|
|
123
|
+
lineSegments.push({ kind: 'space', text: seg, width: w });
|
|
124
|
+
textParts.push(seg);
|
|
125
|
+
}
|
|
126
|
+
// Penalties within the line are skipped (they're just potential break points)
|
|
127
|
+
}
|
|
128
|
+
// Trim trailing spaces
|
|
129
|
+
while (lineSegments.length > 0 && lineSegments[lineSegments.length - 1].kind === 'space') {
|
|
130
|
+
lineSegments.pop();
|
|
131
|
+
textParts.pop();
|
|
132
|
+
}
|
|
133
|
+
// If hyphenated, append '-' to the last text segment
|
|
134
|
+
if (hyphenated && lineSegments.length > 0) {
|
|
135
|
+
const lastIdx = lineSegments.length - 1;
|
|
136
|
+
const last = lineSegments[lastIdx];
|
|
137
|
+
if (last.kind === 'text') {
|
|
138
|
+
lineSegments[lastIdx] = {
|
|
139
|
+
kind: 'text',
|
|
140
|
+
text: last.text + '-',
|
|
141
|
+
width: last.width + discretionaryHyphenWidth,
|
|
142
|
+
};
|
|
143
|
+
textParts[textParts.length - 1] = last.text + '-';
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const lineText = textParts.join('');
|
|
147
|
+
const contentWidth = lineSegments.reduce((s, seg) => s + seg.width, 0);
|
|
148
|
+
// Compute justifiedSpaceRatio
|
|
149
|
+
let justifiedSpaceRatio;
|
|
150
|
+
if (textAlign === 'justify' && !isLastLine && normalSpaceWidth > 0) {
|
|
151
|
+
let wordWidth = 0;
|
|
152
|
+
let spaceCount = 0;
|
|
153
|
+
for (const seg of lineSegments) {
|
|
154
|
+
if (seg.kind === 'space')
|
|
155
|
+
spaceCount++;
|
|
156
|
+
else
|
|
157
|
+
wordWidth += seg.width;
|
|
158
|
+
}
|
|
159
|
+
if (spaceCount > 0) {
|
|
160
|
+
const justifiedSpaceWidth = (lineMaxWidth - wordWidth) / spaceCount;
|
|
161
|
+
justifiedSpaceRatio = justifiedSpaceWidth / normalSpaceWidth;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
lines.push({
|
|
165
|
+
text: lineText,
|
|
166
|
+
bbox: createBoundingBox(lineIndent, li * lineHeightPx, contentWidth, lineHeightPx),
|
|
167
|
+
baseline: li * lineHeightPx + lineHeightPx * 0.8,
|
|
168
|
+
hyphenated,
|
|
169
|
+
segments: lineSegments,
|
|
170
|
+
isLastLine,
|
|
171
|
+
...(justifiedSpaceRatio !== undefined ? { justifiedSpaceRatio } : {}),
|
|
172
|
+
});
|
|
173
|
+
// Next line starts after the break
|
|
174
|
+
lineStart = breakAt + 1;
|
|
175
|
+
}
|
|
176
|
+
return lines;
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=pretextAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pretextAdapter.js","sourceRoot":"","sources":["../../src/knuthPlass/pretextAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter between the bold/italic/math-aware "rich token" stream produced
|
|
3
|
+
* by the measure pipeline and the Knuth-Plass item stream, plus
|
|
4
|
+
* reconstruction of VDT lines from the optimal breakpoint sequence.
|
|
5
|
+
*/
|
|
6
|
+
import type { VDTLine } from '../vdt';
|
|
7
|
+
import type { TextAlign } from '../types';
|
|
8
|
+
import type { KPItem } from './types';
|
|
9
|
+
interface RichBreakPoint {
|
|
10
|
+
charIndex: number;
|
|
11
|
+
widthBefore: number;
|
|
12
|
+
}
|
|
13
|
+
interface RichToken {
|
|
14
|
+
text: string;
|
|
15
|
+
bold: boolean;
|
|
16
|
+
italic: boolean;
|
|
17
|
+
kind: 'text' | 'space';
|
|
18
|
+
width: number;
|
|
19
|
+
breakPoints?: RichBreakPoint[];
|
|
20
|
+
hyphenWidth?: number;
|
|
21
|
+
mathRender?: import('../math/types').MathRender;
|
|
22
|
+
}
|
|
23
|
+
export declare function richTokensToItems(tokens: RichToken[], normalSpaceWidth: number, maxStretchRatio: number, minShrinkRatio: number): KPItem[];
|
|
24
|
+
export declare function reconstructRichLines(items: KPItem[], breaks: number[], tokens: RichToken[], lineHeightPx: number, lineWidthFn: (lineIndex: number) => number, lineIndentFn: (lineIndex: number) => number, normalSpaceWidth: number, textAlign: TextAlign): VDTLine[];
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=richAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"richAdapter.d.ts","sourceRoot":"","sources":["../../src/knuthPlass/richAdapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,QAAQ,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,SAAS,CAAC;AAIrD,UAAU,cAAc;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,eAAe,EAAE,UAAU,CAAC;CACjD;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EAAE,EACnB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,GACrB,MAAM,EAAE,CA4FV;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,MAAM,EAAE,EAChB,MAAM,EAAE,SAAS,EAAE,EACnB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAC1C,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAC3C,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,SAAS,GACnB,OAAO,EAAE,CAuGX"}
|