postext 0.1.3 → 0.1.4

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.
Files changed (45) hide show
  1. package/dist/__tests__/exports.test.js +25 -0
  2. package/dist/__tests__/exports.test.js.map +1 -1
  3. package/dist/canvas-backend.d.ts +5 -0
  4. package/dist/canvas-backend.d.ts.map +1 -0
  5. package/dist/canvas-backend.js +156 -0
  6. package/dist/canvas-backend.js.map +1 -0
  7. package/dist/createLayout.d.ts +2 -2
  8. package/dist/createLayout.d.ts.map +1 -1
  9. package/dist/createLayout.js +25 -2
  10. package/dist/createLayout.js.map +1 -1
  11. package/dist/defaults.d.ts +15 -3
  12. package/dist/defaults.d.ts.map +1 -1
  13. package/dist/defaults.js +276 -8
  14. package/dist/defaults.js.map +1 -1
  15. package/dist/hyphenate.d.ts +11 -0
  16. package/dist/hyphenate.d.ts.map +1 -0
  17. package/dist/hyphenate.js +140 -0
  18. package/dist/hyphenate.js.map +1 -0
  19. package/dist/index.d.ts +11 -2
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +7 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/measure.d.ts +40 -0
  24. package/dist/measure.d.ts.map +1 -0
  25. package/dist/measure.js +267 -0
  26. package/dist/measure.js.map +1 -0
  27. package/dist/parse.d.ts +17 -0
  28. package/dist/parse.d.ts.map +1 -0
  29. package/dist/parse.js +152 -0
  30. package/dist/parse.js.map +1 -0
  31. package/dist/pipeline.d.ts +4 -0
  32. package/dist/pipeline.d.ts.map +1 -0
  33. package/dist/pipeline.js +324 -0
  34. package/dist/pipeline.js.map +1 -0
  35. package/dist/types.d.ts +111 -7
  36. package/dist/types.d.ts.map +1 -1
  37. package/dist/units.d.ts +9 -0
  38. package/dist/units.d.ts.map +1 -0
  39. package/dist/units.js +27 -0
  40. package/dist/units.js.map +1 -0
  41. package/dist/vdt.d.ts +83 -0
  42. package/dist/vdt.d.ts.map +1 -0
  43. package/dist/vdt.js +50 -0
  44. package/dist/vdt.js.map +1 -0
  45. package/package.json +4 -1
package/dist/parse.js ADDED
@@ -0,0 +1,152 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Minimal block-level markdown tokenizer
3
+ // ---------------------------------------------------------------------------
4
+ const HEADING_RE = /^(#{1,6})\s+(.+)$/;
5
+ /**
6
+ * Strip inline markdown formatting for plain-text extraction.
7
+ * Handles bold, italic, code, links, and images.
8
+ */
9
+ function stripInlineFormatting(text) {
10
+ return text
11
+ .replace(/!\[.*?\]\(.*?\)/g, '') // images
12
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // links
13
+ .replace(/\*\*(.+?)\*\*/g, '$1') // bold
14
+ .replace(/__(.+?)__/g, '$1') // bold alt
15
+ .replace(/\*(.+?)\*/g, '$1') // italic
16
+ .replace(/_(.+?)_/g, '$1') // italic alt
17
+ .replace(/`(.+?)`/g, '$1') // inline code
18
+ .trim();
19
+ }
20
+ /**
21
+ * Strip non-bold inline formatting (images, links, italic, code) but keep text.
22
+ */
23
+ function stripNonBoldFormatting(text) {
24
+ return text
25
+ .replace(/!\[.*?\]\(.*?\)/g, '') // images
26
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // links
27
+ .replace(/`(.+?)`/g, '$1'); // inline code
28
+ }
29
+ /**
30
+ * Parse inline formatting to produce spans with bold flag.
31
+ * Strips non-bold formatting first, then extracts bold regions.
32
+ */
33
+ function parseInlineFormatting(text) {
34
+ const cleaned = stripNonBoldFormatting(text);
35
+ const spans = [];
36
+ // Match **bold** and __bold__ patterns
37
+ const boldRe = /\*\*(.+?)\*\*|__(.+?)__/g;
38
+ let lastIndex = 0;
39
+ let match;
40
+ while ((match = boldRe.exec(cleaned)) !== null) {
41
+ // Text before the bold marker
42
+ if (match.index > lastIndex) {
43
+ const before = stripItalicFormatting(cleaned.slice(lastIndex, match.index));
44
+ if (before.length > 0) {
45
+ spans.push({ text: before, bold: false });
46
+ }
47
+ }
48
+ // The bold text itself
49
+ const boldText = stripItalicFormatting(match[1] ?? match[2]);
50
+ if (boldText.length > 0) {
51
+ spans.push({ text: boldText, bold: true });
52
+ }
53
+ lastIndex = match.index + match[0].length;
54
+ }
55
+ // Remaining text after last bold
56
+ if (lastIndex < cleaned.length) {
57
+ const remaining = stripItalicFormatting(cleaned.slice(lastIndex));
58
+ if (remaining.length > 0) {
59
+ spans.push({ text: remaining, bold: false });
60
+ }
61
+ }
62
+ // If no spans were produced (empty text), return a single empty span
63
+ if (spans.length === 0) {
64
+ const trimmed = stripItalicFormatting(cleaned).trim();
65
+ if (trimmed.length > 0) {
66
+ spans.push({ text: trimmed, bold: false });
67
+ }
68
+ }
69
+ return spans;
70
+ }
71
+ /**
72
+ * Strip italic markers (* and _) from text.
73
+ */
74
+ function stripItalicFormatting(text) {
75
+ return text
76
+ .replace(/\*(.+?)\*/g, '$1')
77
+ .replace(/_(.+?)_/g, '$1');
78
+ }
79
+ /**
80
+ * Join spans into a single plain text string.
81
+ */
82
+ function spansToText(spans) {
83
+ return spans.map((s) => s.text).join('').trim();
84
+ }
85
+ /**
86
+ * Merge consecutive blockquote lines into a single block, and consecutive
87
+ * non-blank, non-special lines into paragraphs.
88
+ */
89
+ export function parseMarkdown(markdown) {
90
+ const blocks = [];
91
+ const rawLines = markdown.split('\n');
92
+ let i = 0;
93
+ while (i < rawLines.length) {
94
+ const line = rawLines[i];
95
+ const trimmed = line.trim();
96
+ // Skip blank lines
97
+ if (trimmed === '') {
98
+ i++;
99
+ continue;
100
+ }
101
+ // Heading
102
+ const headingMatch = trimmed.match(HEADING_RE);
103
+ if (headingMatch) {
104
+ const text = stripInlineFormatting(headingMatch[2]);
105
+ blocks.push({
106
+ type: 'heading',
107
+ text,
108
+ spans: [{ text, bold: false }],
109
+ level: headingMatch[1].length,
110
+ });
111
+ i++;
112
+ continue;
113
+ }
114
+ // Blockquote — collect consecutive > lines
115
+ if (trimmed.startsWith('>')) {
116
+ const quoteLines = [];
117
+ while (i < rawLines.length) {
118
+ const ql = rawLines[i].trim();
119
+ if (!ql.startsWith('>'))
120
+ break;
121
+ quoteLines.push(ql.replace(/^>\s?/, ''));
122
+ i++;
123
+ }
124
+ const spans = parseInlineFormatting(quoteLines.join(' '));
125
+ blocks.push({
126
+ type: 'blockquote',
127
+ text: spansToText(spans),
128
+ spans,
129
+ });
130
+ continue;
131
+ }
132
+ // Paragraph — collect consecutive non-blank, non-special lines
133
+ const paraLines = [];
134
+ while (i < rawLines.length) {
135
+ const pl = rawLines[i].trim();
136
+ if (pl === '' || pl.match(HEADING_RE) || pl.startsWith('>'))
137
+ break;
138
+ paraLines.push(pl);
139
+ i++;
140
+ }
141
+ if (paraLines.length > 0) {
142
+ const spans = parseInlineFormatting(paraLines.join(' '));
143
+ blocks.push({
144
+ type: 'paragraph',
145
+ text: spansToText(spans),
146
+ spans,
147
+ });
148
+ }
149
+ }
150
+ return blocks;
151
+ }
152
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { PostextContent, PostextConfig } from './types';
2
+ import { type VDTDocument } from './vdt';
3
+ export declare function buildDocument(content: PostextContent, config?: PostextConfig): VDTDocument;
4
+ //# sourceMappingURL=pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAyC,MAAM,SAAS,CAAC;AAQpG,OAAO,EAQL,KAAK,WAAW,EAKjB,MAAM,OAAO,CAAC;AAyOf,wBAAgB,aAAa,CAC3B,OAAO,EAAE,cAAc,EACvB,MAAM,CAAC,EAAE,aAAa,GACrB,WAAW,CAwNb"}
@@ -0,0 +1,324 @@
1
+ import { resolvePageConfig, resolveLayoutConfig, resolveBodyTextConfig, resolveHeadingsConfig, } from './defaults';
2
+ import { dimensionToPx } from './units';
3
+ import { createBoundingBox, createVDTDocument, createVDTPage, createVDTColumn, createVDTBlock, } from './vdt';
4
+ import { parseMarkdown } from './parse';
5
+ import { buildFontString, measureBlock, measureRichBlock, initHyphenator } from './measure';
6
+ // ---------------------------------------------------------------------------
7
+ // Config resolution helpers
8
+ // ---------------------------------------------------------------------------
9
+ function resolveAllConfig(config) {
10
+ return {
11
+ page: resolvePageConfig(config?.page),
12
+ layout: resolveLayoutConfig(config?.layout),
13
+ bodyText: resolveBodyTextConfig(config?.bodyText),
14
+ headings: resolveHeadingsConfig(config?.headings),
15
+ };
16
+ }
17
+ // ---------------------------------------------------------------------------
18
+ // Baseline grid computation
19
+ // ---------------------------------------------------------------------------
20
+ function computeBaselineGrid(resolved) {
21
+ const dpi = resolved.page.dpi;
22
+ const bodyFontSizePx = dimensionToPx(resolved.bodyText.fontSize, dpi);
23
+ const lineHeightDim = resolved.bodyText.lineHeight;
24
+ // em/rem: multiplier of font size; pt/px/cm/etc: absolute
25
+ if (lineHeightDim.unit === 'em' || lineHeightDim.unit === 'rem') {
26
+ return bodyFontSizePx * lineHeightDim.value;
27
+ }
28
+ return dimensionToPx(lineHeightDim, dpi, bodyFontSizePx);
29
+ }
30
+ // ---------------------------------------------------------------------------
31
+ // Column layout computation
32
+ // ---------------------------------------------------------------------------
33
+ function computeColumnBboxes(contentArea, resolved) {
34
+ const { layoutType, gutterWidth, sideColumnPercent } = resolved.layout;
35
+ const dpi = resolved.page.dpi;
36
+ if (layoutType === 'single') {
37
+ return [createBoundingBox(contentArea.x, contentArea.y, contentArea.width, contentArea.height)];
38
+ }
39
+ const gutterPx = dimensionToPx(gutterWidth, dpi);
40
+ if (layoutType === 'double') {
41
+ const colWidth = (contentArea.width - gutterPx) / 2;
42
+ return [
43
+ createBoundingBox(contentArea.x, contentArea.y, colWidth, contentArea.height),
44
+ createBoundingBox(contentArea.x + colWidth + gutterPx, contentArea.y, colWidth, contentArea.height),
45
+ ];
46
+ }
47
+ // oneAndHalf
48
+ const sideWidth = contentArea.width * (sideColumnPercent / 100);
49
+ const mainWidth = contentArea.width - sideWidth - gutterPx;
50
+ return [
51
+ createBoundingBox(contentArea.x, contentArea.y, mainWidth, contentArea.height),
52
+ createBoundingBox(contentArea.x + mainWidth + gutterPx, contentArea.y, sideWidth, contentArea.height),
53
+ ];
54
+ }
55
+ function resolveBodyStyle(resolved) {
56
+ const dpi = resolved.page.dpi;
57
+ const fontSizePx = dimensionToPx(resolved.bodyText.fontSize, dpi);
58
+ const lineHeightPx = computeBaselineGrid(resolved);
59
+ const weight = resolved.bodyText.fontWeight.toString();
60
+ const fontString = buildFontString(resolved.bodyText.fontFamily, fontSizePx, weight);
61
+ const boldWeight = resolved.bodyText.boldFontWeight.toString();
62
+ const boldFontString = buildFontString(resolved.bodyText.fontFamily, fontSizePx, boldWeight);
63
+ const textAlign = resolved.bodyText.textAlign;
64
+ const hyphenate = resolved.bodyText.hyphenation.enabled && textAlign === 'justify';
65
+ return { fontString, boldFontString, fontSizePx, lineHeightPx, color: resolved.bodyText.color.hex, textAlign, hyphenate, marginTopPx: 0, marginBottomPx: 0 };
66
+ }
67
+ function resolveHeadingStyle(level, resolved) {
68
+ const dpi = resolved.page.dpi;
69
+ const headingConfig = resolved.headings.levels.find((l) => l.level === level) ?? resolved.headings.levels[0];
70
+ const fontSizePx = dimensionToPx(headingConfig.fontSize, dpi);
71
+ const lineHeightDim = headingConfig.lineHeight;
72
+ let lineHeightPx;
73
+ if (lineHeightDim.unit === 'em' || lineHeightDim.unit === 'rem') {
74
+ lineHeightPx = fontSizePx * lineHeightDim.value;
75
+ }
76
+ else {
77
+ lineHeightPx = dimensionToPx(lineHeightDim, dpi, fontSizePx);
78
+ }
79
+ const weight = headingConfig.fontWeight.toString();
80
+ const fontString = buildFontString(headingConfig.fontFamily, fontSizePx, weight);
81
+ const textAlign = resolved.headings.textAlign;
82
+ const marginTopPx = dimensionToPx(headingConfig.marginTop, dpi, fontSizePx);
83
+ const marginBottomPx = dimensionToPx(headingConfig.marginBottom, dpi, fontSizePx);
84
+ return { fontString, fontSizePx, lineHeightPx, color: headingConfig.color.hex, textAlign, hyphenate: false, marginTopPx, marginBottomPx };
85
+ }
86
+ function resolveBlockquoteStyle(resolved) {
87
+ const dpi = resolved.page.dpi;
88
+ const fontSizePx = dimensionToPx(resolved.bodyText.fontSize, dpi);
89
+ const lineHeightPx = computeBaselineGrid(resolved);
90
+ const weight = resolved.bodyText.fontWeight.toString();
91
+ const fontString = buildFontString(resolved.bodyText.fontFamily, fontSizePx, weight, 'italic');
92
+ const boldWeight = resolved.bodyText.boldFontWeight.toString();
93
+ const boldFontString = buildFontString(resolved.bodyText.fontFamily, fontSizePx, boldWeight, 'italic');
94
+ const textAlign = resolved.bodyText.textAlign;
95
+ const hyphenate = resolved.bodyText.hyphenation.enabled && textAlign === 'justify';
96
+ return { fontString, boldFontString, fontSizePx, lineHeightPx, color: '#666666', textAlign, hyphenate, marginTopPx: 0, marginBottomPx: 0 };
97
+ }
98
+ // ---------------------------------------------------------------------------
99
+ // Line position reset (for split blocks)
100
+ // ---------------------------------------------------------------------------
101
+ function resetLinePositions(lines, lineHeightPx) {
102
+ return lines.map((line, i) => ({
103
+ ...line,
104
+ bbox: createBoundingBox(0, i * lineHeightPx, line.bbox.width, lineHeightPx),
105
+ baseline: i * lineHeightPx + lineHeightPx * 0.8,
106
+ }));
107
+ }
108
+ // ---------------------------------------------------------------------------
109
+ // Page creation with columns
110
+ // ---------------------------------------------------------------------------
111
+ function createPageWithColumns(pageIndex, resolved, contentArea, pageWidthPx, pageHeightPx) {
112
+ const page = createVDTPage(pageIndex, pageWidthPx, pageHeightPx);
113
+ const colBboxes = computeColumnBboxes(contentArea, resolved);
114
+ for (let i = 0; i < colBboxes.length; i++) {
115
+ page.columns.push(createVDTColumn(i, colBboxes[i]));
116
+ }
117
+ return page;
118
+ }
119
+ function currentColumn(doc, cursor) {
120
+ return doc.pages[cursor.pageIndex].columns[cursor.columnIndex];
121
+ }
122
+ function advanceToNextColumn(doc, cursor, resolved, contentArea, pageWidthPx, pageHeightPx) {
123
+ const page = doc.pages[cursor.pageIndex];
124
+ if (cursor.columnIndex < page.columns.length - 1) {
125
+ cursor.columnIndex++;
126
+ }
127
+ else {
128
+ // New page
129
+ const newPage = createPageWithColumns(doc.pages.length, resolved, contentArea, pageWidthPx, pageHeightPx);
130
+ doc.pages.push(newPage);
131
+ cursor.pageIndex = newPage.index;
132
+ cursor.columnIndex = 0;
133
+ }
134
+ }
135
+ function placeBlockInColumn(block, blockHeight, col, cursor) {
136
+ const y = col.bbox.y + (col.bbox.height - col.availableHeight);
137
+ block.bbox = createBoundingBox(col.bbox.x, y, col.bbox.width, blockHeight);
138
+ block.pageIndex = cursor.pageIndex;
139
+ block.columnIndex = cursor.columnIndex;
140
+ // Offset all line bboxes to absolute page coordinates
141
+ for (const line of block.lines) {
142
+ line.bbox.x += col.bbox.x;
143
+ line.bbox.y += y;
144
+ line.baseline += y;
145
+ }
146
+ col.blocks.push(block);
147
+ col.availableHeight -= blockHeight;
148
+ }
149
+ // ---------------------------------------------------------------------------
150
+ // Public API
151
+ // ---------------------------------------------------------------------------
152
+ export function buildDocument(content, config) {
153
+ const resolved = resolveAllConfig(config);
154
+ const dpi = resolved.page.dpi;
155
+ // Initialize hyphenator if needed
156
+ if (resolved.bodyText.hyphenation.enabled && resolved.bodyText.textAlign === 'justify') {
157
+ initHyphenator(resolved.bodyText.hyphenation.locale);
158
+ }
159
+ // Compute baseline grid
160
+ const baselineGrid = computeBaselineGrid(resolved);
161
+ // Create document
162
+ const doc = createVDTDocument(resolved, baselineGrid);
163
+ // Page dimensions in px
164
+ const pageWidthPx = dimensionToPx(resolved.page.width, dpi);
165
+ const pageHeightPx = dimensionToPx(resolved.page.height, dpi);
166
+ // Margins in px
167
+ const marginTop = dimensionToPx(resolved.page.margins.top, dpi);
168
+ const marginBottom = dimensionToPx(resolved.page.margins.bottom, dpi);
169
+ const marginLeft = dimensionToPx(resolved.page.margins.left, dpi);
170
+ const marginRight = dimensionToPx(resolved.page.margins.right, dpi);
171
+ // Content area
172
+ const contentArea = createBoundingBox(marginLeft, marginTop, pageWidthPx - marginLeft - marginRight, pageHeightPx - marginTop - marginBottom);
173
+ // Create first page
174
+ const firstPage = createPageWithColumns(0, resolved, contentArea, pageWidthPx, pageHeightPx);
175
+ doc.pages.push(firstPage);
176
+ // Parse markdown
177
+ const contentBlocks = parseMarkdown(content.markdown);
178
+ // Resolve styles
179
+ const bodyStyle = resolveBodyStyle(resolved);
180
+ const blockquoteStyle = resolveBlockquoteStyle(resolved);
181
+ // Placement cursor
182
+ const cursor = { pageIndex: 0, columnIndex: 0 };
183
+ let blockIdCounter = 0;
184
+ let pendingSpacing = 0;
185
+ for (let blockIdx = 0; blockIdx < contentBlocks.length; blockIdx++) {
186
+ const contentBlock = contentBlocks[blockIdx];
187
+ const id = `block-${blockIdCounter++}`;
188
+ let style;
189
+ let vdtType;
190
+ let headingLevel;
191
+ switch (contentBlock.type) {
192
+ case 'heading':
193
+ style = resolveHeadingStyle(contentBlock.level ?? 1, resolved);
194
+ vdtType = 'heading';
195
+ headingLevel = contentBlock.level;
196
+ break;
197
+ case 'blockquote':
198
+ style = blockquoteStyle;
199
+ vdtType = 'blockquote';
200
+ break;
201
+ default:
202
+ style = bodyStyle;
203
+ vdtType = 'paragraph';
204
+ break;
205
+ }
206
+ // Measure text — use rich measurement for blocks with bold spans
207
+ const col = currentColumn(doc, cursor);
208
+ const hasRichSpans = contentBlock.spans.some((s) => s.bold);
209
+ const measured = hasRichSpans && style.boldFontString
210
+ ? measureRichBlock(contentBlock.spans, style.fontString, style.boldFontString, col.bbox.width, style.lineHeightPx, { textAlign: style.textAlign, hyphenate: style.hyphenate })
211
+ : measureBlock(contentBlock.text, style.fontString, col.bbox.width, style.lineHeightPx, { textAlign: style.textAlign, hyphenate: style.hyphenate });
212
+ if (measured.lines.length === 0)
213
+ continue;
214
+ // For headings, only snap to baseline grid if the next block is NOT a heading.
215
+ // Consecutive headings flow without grid snapping; the last heading in the
216
+ // group snaps so that the following body text realigns with the grid.
217
+ const nextBlock = blockIdx + 1 < contentBlocks.length ? contentBlocks[blockIdx + 1] : null;
218
+ const nextIsHeading = nextBlock?.type === 'heading';
219
+ const shouldSnapToGrid = vdtType === 'heading' && !nextIsHeading;
220
+ // Place block, splitting across columns/pages if needed
221
+ const canSplit = vdtType === 'paragraph' || vdtType === 'blockquote';
222
+ let remainingLines = [...measured.lines];
223
+ let partIndex = 0;
224
+ while (remainingLines.length > 0) {
225
+ const curCol = currentColumn(doc, cursor);
226
+ const isFirstInColumn = curCol.blocks.length === 0;
227
+ // Compute spacing before this block — margin collapsing between
228
+ // consecutive headings: only the larger of marginBottom / marginTop applies
229
+ let spacingBefore = 0;
230
+ if (!isFirstInColumn) {
231
+ spacingBefore = pendingSpacing;
232
+ if (vdtType === 'heading') {
233
+ spacingBefore = Math.max(spacingBefore, style.marginTopPx);
234
+ }
235
+ }
236
+ const effectiveAvailable = curCol.availableHeight - spacingBefore;
237
+ const linesPerAvailable = Math.floor(effectiveAvailable / style.lineHeightPx);
238
+ const totalRemainHeight = remainingLines.length * style.lineHeightPx;
239
+ // Block fits in current column
240
+ if (totalRemainHeight <= effectiveAvailable) {
241
+ // Consume spacing
242
+ if (spacingBefore > 0) {
243
+ curCol.availableHeight -= spacingBefore;
244
+ }
245
+ const partId = partIndex === 0 ? id : `${id}-cont-${partIndex}`;
246
+ const blk = createVDTBlock(partId, vdtType, style.fontString, style.color, style.textAlign);
247
+ if (style.boldFontString)
248
+ blk.boldFontString = style.boldFontString;
249
+ if (partIndex === 0)
250
+ blk.headingLevel = headingLevel;
251
+ blk.lines = resetLinePositions(remainingLines, style.lineHeightPx);
252
+ blk.dirty = false;
253
+ blk.snappedToGrid = shouldSnapToGrid && partIndex === 0;
254
+ let h = totalRemainHeight;
255
+ if (shouldSnapToGrid && partIndex === 0) {
256
+ // Snap using the absolute position in the column so that the block
257
+ // bottom lands on a baseline grid line. This accounts for off-grid
258
+ // starts (e.g. after consecutive unsnapped headings) and bakes in
259
+ // the minimum marginBottom — the grid always wins, but the margin
260
+ // below is guaranteed to be at least marginBottomPx.
261
+ const usedHeight = curCol.bbox.height - curCol.availableHeight;
262
+ const naturalBottom = usedHeight + totalRemainHeight + style.marginBottomPx;
263
+ const snappedBottom = Math.ceil(naturalBottom / baselineGrid) * baselineGrid;
264
+ h = snappedBottom - usedHeight;
265
+ }
266
+ placeBlockInColumn(blk, h, curCol, cursor);
267
+ doc.blocks.push(blk);
268
+ // For snapped headings the margin is baked into the snap;
269
+ // for unsnapped headings (consecutive) track it for collapsing
270
+ pendingSpacing = (shouldSnapToGrid && partIndex === 0) ? 0 : style.marginBottomPx;
271
+ break;
272
+ }
273
+ // Block doesn't fit — try to split
274
+ if (canSplit && linesPerAvailable >= 2) {
275
+ // Consume spacing
276
+ if (spacingBefore > 0) {
277
+ curCol.availableHeight -= spacingBefore;
278
+ }
279
+ const partId = partIndex === 0 ? id : `${id}-cont-${partIndex}`;
280
+ const splitLines = remainingLines.slice(0, linesPerAvailable);
281
+ const blk = createVDTBlock(partId, vdtType, style.fontString, style.color, style.textAlign);
282
+ if (style.boldFontString)
283
+ blk.boldFontString = style.boldFontString;
284
+ if (partIndex === 0)
285
+ blk.headingLevel = headingLevel;
286
+ blk.lines = resetLinePositions(splitLines, style.lineHeightPx);
287
+ blk.dirty = false;
288
+ blk.snappedToGrid = false;
289
+ const splitHeight = linesPerAvailable * style.lineHeightPx;
290
+ placeBlockInColumn(blk, splitHeight, curCol, cursor);
291
+ doc.blocks.push(blk);
292
+ remainingLines = remainingLines.slice(linesPerAvailable);
293
+ partIndex++;
294
+ pendingSpacing = 0;
295
+ advanceToNextColumn(doc, cursor, resolved, contentArea, pageWidthPx, pageHeightPx);
296
+ continue;
297
+ }
298
+ // Cannot split — advance to next column if current has content
299
+ if (curCol.blocks.length > 0) {
300
+ pendingSpacing = 0;
301
+ advanceToNextColumn(doc, cursor, resolved, contentArea, pageWidthPx, pageHeightPx);
302
+ continue;
303
+ }
304
+ // Empty column but block still doesn't fit (block taller than page) — place anyway
305
+ const partId = partIndex === 0 ? id : `${id}-cont-${partIndex}`;
306
+ const blk = createVDTBlock(partId, vdtType, style.fontString, style.color, style.textAlign);
307
+ if (style.boldFontString)
308
+ blk.boldFontString = style.boldFontString;
309
+ if (partIndex === 0)
310
+ blk.headingLevel = headingLevel;
311
+ blk.lines = resetLinePositions(remainingLines, style.lineHeightPx);
312
+ blk.dirty = false;
313
+ blk.snappedToGrid = false;
314
+ placeBlockInColumn(blk, totalRemainHeight, curCol, cursor);
315
+ doc.blocks.push(blk);
316
+ pendingSpacing = style.marginBottomPx;
317
+ break;
318
+ }
319
+ }
320
+ doc.converged = true;
321
+ doc.iterationCount = 1;
322
+ return doc;
323
+ }
324
+ //# sourceMappingURL=pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}