postext 0.1.7 → 0.1.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.
Files changed (48) hide show
  1. package/README.md +48 -21
  2. package/dist/__tests__/exports.test.js +4 -0
  3. package/dist/__tests__/exports.test.js.map +1 -1
  4. package/dist/__tests__/frontmatter.test.d.ts +2 -0
  5. package/dist/__tests__/frontmatter.test.d.ts.map +1 -0
  6. package/dist/__tests__/frontmatter.test.js +41 -0
  7. package/dist/__tests__/frontmatter.test.js.map +1 -0
  8. package/dist/__tests__/numbering.test.d.ts +2 -0
  9. package/dist/__tests__/numbering.test.d.ts.map +1 -0
  10. package/dist/__tests__/numbering.test.js +95 -0
  11. package/dist/__tests__/numbering.test.js.map +1 -0
  12. package/dist/canvas-backend.d.ts.map +1 -1
  13. package/dist/canvas-backend.js +16 -7
  14. package/dist/canvas-backend.js.map +1 -1
  15. package/dist/defaults.d.ts +4 -1
  16. package/dist/defaults.d.ts.map +1 -1
  17. package/dist/defaults.js +74 -6
  18. package/dist/defaults.js.map +1 -1
  19. package/dist/frontmatter.d.ts +9 -0
  20. package/dist/frontmatter.d.ts.map +1 -0
  21. package/dist/frontmatter.js +15 -0
  22. package/dist/frontmatter.js.map +1 -0
  23. package/dist/index.d.ts +4 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/measure.d.ts +1 -1
  28. package/dist/measure.d.ts.map +1 -1
  29. package/dist/measure.js +34 -36
  30. package/dist/measure.js.map +1 -1
  31. package/dist/numbering.d.ts +16 -0
  32. package/dist/numbering.d.ts.map +1 -0
  33. package/dist/numbering.js +169 -0
  34. package/dist/numbering.js.map +1 -0
  35. package/dist/parse.d.ts +11 -0
  36. package/dist/parse.d.ts.map +1 -1
  37. package/dist/parse.js +188 -41
  38. package/dist/parse.js.map +1 -1
  39. package/dist/pipeline.d.ts.map +1 -1
  40. package/dist/pipeline.js +127 -16
  41. package/dist/pipeline.js.map +1 -1
  42. package/dist/types.d.ts +31 -0
  43. package/dist/types.d.ts.map +1 -1
  44. package/dist/vdt.d.ts +22 -1
  45. package/dist/vdt.d.ts.map +1 -1
  46. package/dist/vdt.js +1 -0
  47. package/dist/vdt.js.map +1 -1
  48. package/package.json +3 -2
package/dist/parse.js CHANGED
@@ -18,69 +18,178 @@ function stripInlineFormatting(text) {
18
18
  .trim();
19
19
  }
20
20
  /**
21
- * Strip non-bold inline formatting (images, links, italic, code) but keep text.
21
+ * Strip non-emphasis inline formatting (images, links, code) but keep bold/italic markers.
22
22
  */
23
- function stripNonBoldFormatting(text) {
23
+ function stripNonEmphasisFormatting(text) {
24
24
  return text
25
25
  .replace(/!\[.*?\]\(.*?\)/g, '') // images
26
26
  .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // links
27
27
  .replace(/`(.+?)`/g, '$1'); // inline code
28
28
  }
29
29
  /**
30
- * Parse inline formatting to produce spans with bold flag.
31
- * Strips non-bold formatting first, then extracts bold regions.
30
+ * Split a text region into italic/non-italic spans, carrying an ambient bold flag.
31
+ */
32
+ function splitItalicSpans(text, bold, forcedItalic, out) {
33
+ if (forcedItalic) {
34
+ if (text.length > 0)
35
+ out.push({ text, bold, italic: true });
36
+ return;
37
+ }
38
+ const italicRe = /\*(.+?)\*|_(.+?)_/g;
39
+ let last = 0;
40
+ let m;
41
+ while ((m = italicRe.exec(text)) !== null) {
42
+ if (m.index > last) {
43
+ const before = text.slice(last, m.index);
44
+ if (before.length > 0)
45
+ out.push({ text: before, bold, italic: false });
46
+ }
47
+ const inner = m[1] ?? m[2];
48
+ if (inner.length > 0)
49
+ out.push({ text: inner, bold, italic: true });
50
+ last = m.index + m[0].length;
51
+ }
52
+ if (last < text.length) {
53
+ const rest = text.slice(last);
54
+ if (rest.length > 0)
55
+ out.push({ text: rest, bold, italic: false });
56
+ }
57
+ }
58
+ /**
59
+ * Parse inline formatting to produce spans with bold and italic flags.
60
+ * Recognizes ***bold italic***, **bold**, *italic* (and underscore equivalents).
32
61
  */
33
62
  function parseInlineFormatting(text) {
34
- const cleaned = stripNonBoldFormatting(text);
63
+ const cleaned = stripNonEmphasisFormatting(text);
35
64
  const spans = [];
36
- // Match **bold** and __bold__ patterns
37
- const boldRe = /\*\*(.+?)\*\*|__(.+?)__/g;
65
+ // Triple markers (bold+italic) first, then double (bold) — longest first.
66
+ const boldRe = /\*\*\*(.+?)\*\*\*|___(.+?)___|\*\*(.+?)\*\*|__(.+?)__/g;
38
67
  let lastIndex = 0;
39
68
  let match;
40
69
  while ((match = boldRe.exec(cleaned)) !== null) {
41
- // Text before the bold marker
42
70
  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
- }
71
+ splitItalicSpans(cleaned.slice(lastIndex, match.index), false, false, spans);
72
+ }
73
+ const triple = match[1] ?? match[2];
74
+ if (triple !== undefined) {
75
+ splitItalicSpans(triple, true, true, spans);
47
76
  }
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 });
77
+ else {
78
+ const inner = match[3] ?? match[4];
79
+ splitItalicSpans(inner, true, false, spans);
52
80
  }
53
81
  lastIndex = match.index + match[0].length;
54
82
  }
55
- // Remaining text after last bold
56
83
  if (lastIndex < cleaned.length) {
57
- const remaining = stripItalicFormatting(cleaned.slice(lastIndex));
58
- if (remaining.length > 0) {
59
- spans.push({ text: remaining, bold: false });
60
- }
84
+ splitItalicSpans(cleaned.slice(lastIndex), false, false, spans);
61
85
  }
62
- // If no spans were produced (empty text), return a single empty span
63
86
  if (spans.length === 0) {
64
- const trimmed = stripItalicFormatting(cleaned).trim();
87
+ const trimmed = cleaned.trim();
65
88
  if (trimmed.length > 0) {
66
- spans.push({ text: trimmed, bold: false });
89
+ splitItalicSpans(trimmed, false, false, spans);
67
90
  }
68
91
  }
69
92
  return spans;
70
93
  }
71
94
  /**
72
- * Strip italic markers (* and _) from text.
95
+ * Build a per-character map from plain text to absolute source offsets.
96
+ * Greedy matches each plain char against the raw source (delimited by
97
+ * [blockSrcStart, blockSrcEnd)), skipping markdown markers and treating
98
+ * newlines/tabs as spaces for paragraph line joins.
73
99
  */
74
- function stripItalicFormatting(text) {
75
- return text
76
- .replace(/\*(.+?)\*/g, '$1')
77
- .replace(/_(.+?)_/g, '$1');
100
+ function computeSourceMap(markdown, blockSrcStart, blockSrcEnd, plainText) {
101
+ const map = new Array(plainText.length);
102
+ let r = blockSrcStart;
103
+ for (let p = 0; p < plainText.length; p++) {
104
+ const ch = plainText[p];
105
+ const isSpace = ch === ' ';
106
+ while (r < blockSrcEnd) {
107
+ const rc = markdown[r];
108
+ if (rc === ch)
109
+ break;
110
+ if (isSpace && (rc === '\n' || rc === '\t'))
111
+ break;
112
+ r++;
113
+ }
114
+ if (r >= blockSrcEnd) {
115
+ map[p] = blockSrcEnd;
116
+ }
117
+ else {
118
+ map[p] = r;
119
+ r++;
120
+ }
121
+ }
122
+ return map;
78
123
  }
124
+ const COLLAPSIBLE_WS_RE = /[ \t\n\r\f]/;
79
125
  /**
80
- * Join spans into a single plain text string.
126
+ * Collapse runs of `[ \t\n\r\f]` to a single space and strip leading/trailing
127
+ * whitespace across spans. Mirrors pretext's `normalizeWhitespaceNormal` so
128
+ * that `spans` and the block's plain text stay aligned with what the layout
129
+ * engine actually renders — otherwise cursor/selection mapping drifts by one
130
+ * character per collapsed whitespace character.
81
131
  */
82
- function spansToText(spans) {
83
- return spans.map((s) => s.text).join('').trim();
132
+ function normalizeWhitespaceInSpans(spans) {
133
+ const out = [];
134
+ let inSpace = true; // start true to strip leading whitespace
135
+ for (const span of spans) {
136
+ let result = '';
137
+ for (const ch of span.text) {
138
+ if (COLLAPSIBLE_WS_RE.test(ch)) {
139
+ if (!inSpace) {
140
+ result += ' ';
141
+ inSpace = true;
142
+ }
143
+ }
144
+ else {
145
+ result += ch;
146
+ inSpace = false;
147
+ }
148
+ }
149
+ out.push({ ...span, text: result });
150
+ }
151
+ // Strip trailing space from the last span that contributed content
152
+ for (let i = out.length - 1; i >= 0; i--) {
153
+ const text = out[i].text;
154
+ if (text.length === 0)
155
+ continue;
156
+ if (text.endsWith(' ')) {
157
+ out[i] = { ...out[i], text: text.slice(0, -1) };
158
+ }
159
+ break;
160
+ }
161
+ return out.filter((s) => s.text.length > 0);
162
+ }
163
+ /**
164
+ * Build normalized text, spans, and sourceMap for a block. The plain text is
165
+ * whitespace-normalized to match pretext's internal normalization so that the
166
+ * per-character `sourceMap` aligns with rendered line segments.
167
+ */
168
+ function buildBlockMapping(markdown, blockSrcStart, blockSrcEnd, rawSpans) {
169
+ const rawText = rawSpans.map((s) => s.text).join('');
170
+ const rawSourceMap = computeSourceMap(markdown, blockSrcStart, blockSrcEnd, rawText);
171
+ const spans = normalizeWhitespaceInSpans(rawSpans);
172
+ const text = spans.map((s) => s.text).join('');
173
+ // Walk the raw text building the same normalization, and project each kept
174
+ // normalized character onto the rawSourceMap to obtain the source offset.
175
+ const sourceMap = [];
176
+ let inSpace = true;
177
+ for (let i = 0; i < rawText.length; i++) {
178
+ const ch = rawText[i];
179
+ if (COLLAPSIBLE_WS_RE.test(ch)) {
180
+ if (!inSpace) {
181
+ sourceMap.push(rawSourceMap[i] ?? blockSrcEnd);
182
+ inSpace = true;
183
+ }
184
+ }
185
+ else {
186
+ sourceMap.push(rawSourceMap[i] ?? blockSrcEnd);
187
+ inSpace = false;
188
+ }
189
+ }
190
+ if (sourceMap.length > text.length)
191
+ sourceMap.length = text.length;
192
+ return { text, spans, sourceMap };
84
193
  }
85
194
  /**
86
195
  * Merge consecutive blockquote lines into a single block, and consecutive
@@ -89,6 +198,18 @@ function spansToText(spans) {
89
198
  export function parseMarkdown(markdown) {
90
199
  const blocks = [];
91
200
  const rawLines = markdown.split('\n');
201
+ // Precompute starting offset of each raw line in the original markdown.
202
+ // lineOffsets[i] = offset of first char of rawLines[i]. Line terminator '\n'
203
+ // contributes exactly 1 character between consecutive lines.
204
+ const lineOffsets = new Array(rawLines.length);
205
+ {
206
+ let cur = 0;
207
+ for (let k = 0; k < rawLines.length; k++) {
208
+ lineOffsets[k] = cur;
209
+ cur += rawLines[k].length + 1; // +1 for the '\n' that was split away
210
+ }
211
+ }
212
+ const lineEndOffset = (k) => lineOffsets[k] + rawLines[k].length;
92
213
  let i = 0;
93
214
  while (i < rawLines.length) {
94
215
  const line = rawLines[i];
@@ -101,12 +222,20 @@ export function parseMarkdown(markdown) {
101
222
  // Heading
102
223
  const headingMatch = trimmed.match(HEADING_RE);
103
224
  if (headingMatch) {
104
- const text = stripInlineFormatting(headingMatch[2]);
225
+ const rawText = stripInlineFormatting(headingMatch[2]);
226
+ const srcStart = lineOffsets[i];
227
+ const srcEnd = lineEndOffset(i);
228
+ const mapping = buildBlockMapping(markdown, srcStart, srcEnd, [
229
+ { text: rawText, bold: false, italic: false },
230
+ ]);
105
231
  blocks.push({
106
232
  type: 'heading',
107
- text,
108
- spans: [{ text, bold: false }],
233
+ text: mapping.text,
234
+ spans: mapping.spans.length > 0 ? mapping.spans : [{ text: '', bold: false, italic: false }],
109
235
  level: headingMatch[1].length,
236
+ sourceStart: srcStart,
237
+ sourceEnd: srcEnd,
238
+ sourceMap: mapping.sourceMap,
110
239
  });
111
240
  i++;
112
241
  continue;
@@ -114,36 +243,54 @@ export function parseMarkdown(markdown) {
114
243
  // Blockquote — collect consecutive > lines
115
244
  if (trimmed.startsWith('>')) {
116
245
  const quoteLines = [];
246
+ const startIdx = i;
247
+ let lastIdx = i;
117
248
  while (i < rawLines.length) {
118
249
  const ql = rawLines[i].trim();
119
250
  if (!ql.startsWith('>'))
120
251
  break;
121
252
  quoteLines.push(ql.replace(/^>\s?/, ''));
253
+ lastIdx = i;
122
254
  i++;
123
255
  }
124
- const spans = parseInlineFormatting(quoteLines.join(' '));
256
+ const rawSpans = parseInlineFormatting(quoteLines.join(' '));
257
+ const srcStart = lineOffsets[startIdx];
258
+ const srcEnd = lineEndOffset(lastIdx);
259
+ const mapping = buildBlockMapping(markdown, srcStart, srcEnd, rawSpans);
125
260
  blocks.push({
126
261
  type: 'blockquote',
127
- text: spansToText(spans),
128
- spans,
262
+ text: mapping.text,
263
+ spans: mapping.spans,
264
+ sourceStart: srcStart,
265
+ sourceEnd: srcEnd,
266
+ sourceMap: mapping.sourceMap,
129
267
  });
130
268
  continue;
131
269
  }
132
270
  // Paragraph — collect consecutive non-blank, non-special lines
133
271
  const paraLines = [];
272
+ const startIdx = i;
273
+ let lastIdx = i;
134
274
  while (i < rawLines.length) {
135
275
  const pl = rawLines[i].trim();
136
276
  if (pl === '' || pl.match(HEADING_RE) || pl.startsWith('>'))
137
277
  break;
138
278
  paraLines.push(pl);
279
+ lastIdx = i;
139
280
  i++;
140
281
  }
141
282
  if (paraLines.length > 0) {
142
- const spans = parseInlineFormatting(paraLines.join(' '));
283
+ const rawSpans = parseInlineFormatting(paraLines.join(' '));
284
+ const srcStart = lineOffsets[startIdx];
285
+ const srcEnd = lineEndOffset(lastIdx);
286
+ const mapping = buildBlockMapping(markdown, srcStart, srcEnd, rawSpans);
143
287
  blocks.push({
144
288
  type: 'paragraph',
145
- text: spansToText(spans),
146
- spans,
289
+ text: mapping.text,
290
+ spans: mapping.spans,
291
+ sourceStart: srcStart,
292
+ sourceEnd: srcEnd,
293
+ sourceMap: mapping.sourceMap,
147
294
  });
148
295
  }
149
296
  }
package/dist/parse.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"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"}
@@ -1 +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;AA+Of,wBAAgB,aAAa,CAC3B,OAAO,EAAE,cAAc,EACvB,MAAM,CAAC,EAAE,aAAa,GACrB,WAAW,CA4Ob"}
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;AA6Pf,wBAAgB,aAAa,CAC3B,OAAO,EAAE,cAAc,EACvB,MAAM,CAAC,EAAE,aAAa,GACrB,WAAW,CAoUb"}
package/dist/pipeline.js CHANGED
@@ -2,6 +2,8 @@ import { resolvePageConfig, resolveLayoutConfig, resolveBodyTextConfig, resolveH
2
2
  import { dimensionToPx } from './units';
3
3
  import { createBoundingBox, createVDTDocument, createVDTPage, createVDTColumn, createVDTBlock, } from './vdt';
4
4
  import { parseMarkdown } from './parse';
5
+ import { computeHeadingNumbers } from './numbering';
6
+ import { extractFrontmatter } from './frontmatter';
5
7
  import { buildFontString, measureBlock, measureRichBlock, initHyphenator } from './measure';
6
8
  // ---------------------------------------------------------------------------
7
9
  // Config resolution helpers
@@ -60,11 +62,13 @@ function resolveBodyStyle(resolved) {
60
62
  const fontString = buildFontString(resolved.bodyText.fontFamily, fontSizePx, weight);
61
63
  const boldWeight = resolved.bodyText.boldFontWeight.toString();
62
64
  const boldFontString = buildFontString(resolved.bodyText.fontFamily, fontSizePx, boldWeight);
65
+ const italicFontString = buildFontString(resolved.bodyText.fontFamily, fontSizePx, weight, 'italic');
66
+ const boldItalicFontString = buildFontString(resolved.bodyText.fontFamily, fontSizePx, boldWeight, 'italic');
63
67
  const textAlign = resolved.bodyText.textAlign;
64
68
  const hyphenate = resolved.bodyText.hyphenation.enabled && textAlign === 'justify';
65
69
  const firstLineIndentPx = dimensionToPx(resolved.bodyText.firstLineIndent, dpi, fontSizePx);
66
70
  const hangingIndent = resolved.bodyText.hangingIndent;
67
- return { fontString, boldFontString, fontSizePx, lineHeightPx, color: resolved.bodyText.color.hex, textAlign, hyphenate, marginTopPx: 0, marginBottomPx: 0, firstLineIndentPx, hangingIndent };
71
+ return { fontString, boldFontString, italicFontString, boldItalicFontString, fontSizePx, lineHeightPx, color: resolved.bodyText.color.hex, textAlign, hyphenate, marginTopPx: 0, marginBottomPx: 0, firstLineIndentPx, hangingIndent };
68
72
  }
69
73
  function resolveHeadingStyle(level, resolved) {
70
74
  const dpi = resolved.page.dpi;
@@ -79,11 +83,16 @@ function resolveHeadingStyle(level, resolved) {
79
83
  lineHeightPx = dimensionToPx(lineHeightDim, dpi, fontSizePx);
80
84
  }
81
85
  const weight = headingConfig.fontWeight.toString();
82
- const fontString = buildFontString(headingConfig.fontFamily, fontSizePx, weight);
86
+ const baseItalic = headingConfig.italic ? 'italic' : 'normal';
87
+ const flipItalic = headingConfig.italic ? 'normal' : 'italic';
88
+ const fontString = buildFontString(headingConfig.fontFamily, fontSizePx, weight, baseItalic);
89
+ const boldFontString = fontString;
90
+ const italicFontString = buildFontString(headingConfig.fontFamily, fontSizePx, weight, flipItalic);
91
+ const boldItalicFontString = italicFontString;
83
92
  const textAlign = resolved.headings.textAlign;
84
93
  const marginTopPx = dimensionToPx(headingConfig.marginTop, dpi, fontSizePx);
85
94
  const marginBottomPx = dimensionToPx(headingConfig.marginBottom, dpi, fontSizePx);
86
- return { fontString, fontSizePx, lineHeightPx, color: headingConfig.color.hex, textAlign, hyphenate: false, marginTopPx, marginBottomPx, firstLineIndentPx: 0, hangingIndent: false };
95
+ return { fontString, boldFontString, italicFontString, boldItalicFontString, fontSizePx, lineHeightPx, color: headingConfig.color.hex, textAlign, hyphenate: false, marginTopPx, marginBottomPx, firstLineIndentPx: 0, hangingIndent: false };
87
96
  }
88
97
  function resolveBlockquoteStyle(resolved) {
89
98
  const dpi = resolved.page.dpi;
@@ -93,11 +102,14 @@ function resolveBlockquoteStyle(resolved) {
93
102
  const fontString = buildFontString(resolved.bodyText.fontFamily, fontSizePx, weight, 'italic');
94
103
  const boldWeight = resolved.bodyText.boldFontWeight.toString();
95
104
  const boldFontString = buildFontString(resolved.bodyText.fontFamily, fontSizePx, boldWeight, 'italic');
105
+ // Inside a blockquote (already italic), `*text*` flips back to upright.
106
+ const italicFontString = buildFontString(resolved.bodyText.fontFamily, fontSizePx, weight, 'normal');
107
+ const boldItalicFontString = buildFontString(resolved.bodyText.fontFamily, fontSizePx, boldWeight, 'normal');
96
108
  const textAlign = resolved.bodyText.textAlign;
97
109
  const hyphenate = resolved.bodyText.hyphenation.enabled && textAlign === 'justify';
98
110
  const firstLineIndentPx = dimensionToPx(resolved.bodyText.firstLineIndent, dpi, fontSizePx);
99
111
  const hangingIndent = resolved.bodyText.hangingIndent;
100
- return { fontString, boldFontString, fontSizePx, lineHeightPx, color: '#666666', textAlign, hyphenate, marginTopPx: 0, marginBottomPx: 0, firstLineIndentPx, hangingIndent };
112
+ return { fontString, boldFontString, italicFontString, boldItalicFontString, fontSizePx, lineHeightPx, color: '#666666', textAlign, hyphenate, marginTopPx: 0, marginBottomPx: 0, firstLineIndentPx, hangingIndent };
101
113
  }
102
114
  // ---------------------------------------------------------------------------
103
115
  // Line position reset (for split blocks)
@@ -188,8 +200,17 @@ export function buildDocument(content, config) {
188
200
  // Create first page
189
201
  const firstPage = createPageWithColumns(0, resolved, contentArea, pageWidthPx, pageHeightPx);
190
202
  doc.pages.push(firstPage);
191
- // Parse markdown
192
- const contentBlocks = parseMarkdown(content.markdown);
203
+ // Extract frontmatter, then parse the remaining markdown body
204
+ const { metadata: frontmatterMeta, content: markdownBody, contentOffset: bodyOffset } = extractFrontmatter(content.markdown);
205
+ doc.metadata = { ...(content.metadata ?? {}), ...frontmatterMeta };
206
+ const contentBlocks = parseMarkdown(markdownBody);
207
+ const headingTemplates = {};
208
+ for (const lvl of resolved.headings.levels) {
209
+ if (lvl.numberingTemplate && lvl.numberingTemplate.length > 0) {
210
+ headingTemplates[lvl.level] = lvl.numberingTemplate;
211
+ }
212
+ }
213
+ const headingPrefixes = computeHeadingNumbers(contentBlocks, headingTemplates);
193
214
  // Resolve styles
194
215
  const bodyStyle = resolveBodyStyle(resolved);
195
216
  const blockquoteStyle = resolveBlockquoteStyle(resolved);
@@ -198,17 +219,29 @@ export function buildDocument(content, config) {
198
219
  let blockIdCounter = 0;
199
220
  let pendingSpacing = 0;
200
221
  for (let blockIdx = 0; blockIdx < contentBlocks.length; blockIdx++) {
201
- const contentBlock = contentBlocks[blockIdx];
222
+ const rawBlock = contentBlocks[blockIdx];
202
223
  const id = `block-${blockIdCounter++}`;
203
224
  let style;
204
225
  let vdtType;
205
226
  let headingLevel;
206
- switch (contentBlock.type) {
207
- case 'heading':
208
- style = resolveHeadingStyle(contentBlock.level ?? 1, resolved);
227
+ let numberPrefix;
228
+ let contentBlock = rawBlock;
229
+ switch (rawBlock.type) {
230
+ case 'heading': {
231
+ style = resolveHeadingStyle(rawBlock.level ?? 1, resolved);
209
232
  vdtType = 'heading';
210
- headingLevel = contentBlock.level;
233
+ headingLevel = rawBlock.level;
234
+ numberPrefix = headingPrefixes[blockIdx];
235
+ if (numberPrefix) {
236
+ const sep = `${numberPrefix} `;
237
+ const firstSpan = rawBlock.spans[0];
238
+ const newSpans = firstSpan
239
+ ? [{ text: sep + firstSpan.text, bold: firstSpan.bold, italic: firstSpan.italic }, ...rawBlock.spans.slice(1)]
240
+ : [{ text: sep, bold: false, italic: false }];
241
+ contentBlock = { ...rawBlock, text: sep + rawBlock.text, spans: newSpans };
242
+ }
211
243
  break;
244
+ }
212
245
  case 'blockquote':
213
246
  style = blockquoteStyle;
214
247
  vdtType = 'blockquote';
@@ -220,18 +253,60 @@ export function buildDocument(content, config) {
220
253
  }
221
254
  // Measure text — use rich measurement for blocks with bold spans
222
255
  const col = currentColumn(doc, cursor);
223
- const hasRichSpans = contentBlock.spans.some((s) => s.bold);
256
+ const hasRichSpans = contentBlock.spans.some((s) => s.bold || s.italic);
224
257
  const measureOptions = {
225
258
  textAlign: style.textAlign,
226
259
  hyphenate: style.hyphenate,
227
260
  firstLineIndentPx: style.firstLineIndentPx,
228
261
  hangingIndent: style.hangingIndent,
229
262
  };
230
- const measured = hasRichSpans && style.boldFontString
231
- ? measureRichBlock(contentBlock.spans, style.fontString, style.boldFontString, col.bbox.width, style.lineHeightPx, measureOptions)
263
+ const measured = hasRichSpans && style.boldFontString && style.italicFontString && style.boldItalicFontString
264
+ ? measureRichBlock(contentBlock.spans, style.fontString, style.boldFontString, style.italicFontString, style.boldItalicFontString, col.bbox.width, style.lineHeightPx, measureOptions)
232
265
  : measureBlock(contentBlock.text, style.fontString, col.bbox.width, style.lineHeightPx, measureOptions);
233
266
  if (measured.lines.length === 0)
234
267
  continue;
268
+ // Per-line source-range mapping using the block's plain→source map.
269
+ // Accounts for heading numbering prefix which prepends chars with no source.
270
+ const blockSrcStart = rawBlock.sourceStart + bodyOffset;
271
+ const blockSrcEnd = rawBlock.sourceEnd + bodyOffset;
272
+ const srcMap = rawBlock.sourceMap;
273
+ const prefixLen = contentBlock.text.length - rawBlock.text.length;
274
+ const plainToSrc = (p) => {
275
+ const idx = p - prefixLen;
276
+ if (idx <= 0)
277
+ return blockSrcStart;
278
+ if (idx >= srcMap.length)
279
+ return blockSrcEnd;
280
+ return srcMap[idx] + bodyOffset;
281
+ };
282
+ let cumPlain = 0;
283
+ const lastLineIdx = measured.lines.length - 1;
284
+ for (let li = 0; li < measured.lines.length; li++) {
285
+ const line = measured.lines[li];
286
+ // If segments are present, prefer their aggregate text length for a more
287
+ // accurate plain-char count (excludes trailing hyphen for hyphenated lines).
288
+ let lineLen;
289
+ if (line.segments && line.segments.length > 0) {
290
+ lineLen = line.segments.reduce((s, seg) => s + seg.text.length, 0);
291
+ if (line.hyphenated) {
292
+ const last = line.segments[line.segments.length - 1];
293
+ if (last.text.endsWith('-'))
294
+ lineLen -= 1;
295
+ }
296
+ }
297
+ else {
298
+ lineLen = line.text.length - (line.hyphenated ? 1 : 0);
299
+ }
300
+ line.plainStart = cumPlain;
301
+ line.plainEnd = cumPlain + lineLen;
302
+ // Advance past the separator space that was consumed to break the line
303
+ // (skip when hyphenated — break was at a soft hyphen — or on the last line).
304
+ const skipSeparator = !line.hyphenated && li !== lastLineIdx ? 1 : 0;
305
+ cumPlain = line.plainEnd + skipSeparator;
306
+ line.sourceStart = plainToSrc(line.plainStart);
307
+ line.sourceEnd = plainToSrc(line.plainEnd);
308
+ }
309
+ const absoluteSourceMap = srcMap.map((o) => o + bodyOffset);
235
310
  // For headings, only snap to baseline grid if the next block is NOT a heading.
236
311
  // Consecutive headings flow without grid snapping; the last heading in the
237
312
  // group snaps so that the following body text realigns with the grid.
@@ -267,11 +342,24 @@ export function buildDocument(content, config) {
267
342
  const blk = createVDTBlock(partId, vdtType, style.fontString, style.color, style.textAlign);
268
343
  if (style.boldFontString)
269
344
  blk.boldFontString = style.boldFontString;
270
- if (partIndex === 0)
345
+ if (style.italicFontString)
346
+ blk.italicFontString = style.italicFontString;
347
+ if (style.boldItalicFontString)
348
+ blk.boldItalicFontString = style.boldItalicFontString;
349
+ if (partIndex === 0) {
271
350
  blk.headingLevel = headingLevel;
351
+ if (numberPrefix)
352
+ blk.numberPrefix = numberPrefix;
353
+ }
272
354
  blk.lines = resetLinePositions(remainingLines, style.lineHeightPx);
273
355
  blk.dirty = false;
274
356
  blk.snappedToGrid = shouldSnapToGrid && partIndex === 0;
357
+ if (remainingLines.length > 0) {
358
+ blk.sourceStart = remainingLines[0].sourceStart;
359
+ blk.sourceEnd = remainingLines[remainingLines.length - 1].sourceEnd;
360
+ }
361
+ blk.sourceMap = absoluteSourceMap;
362
+ blk.plainPrefixLen = prefixLen;
275
363
  let h = totalRemainHeight;
276
364
  if (shouldSnapToGrid && partIndex === 0) {
277
365
  // Snap using the absolute position in the column so that the block
@@ -302,11 +390,24 @@ export function buildDocument(content, config) {
302
390
  const blk = createVDTBlock(partId, vdtType, style.fontString, style.color, style.textAlign);
303
391
  if (style.boldFontString)
304
392
  blk.boldFontString = style.boldFontString;
305
- if (partIndex === 0)
393
+ if (style.italicFontString)
394
+ blk.italicFontString = style.italicFontString;
395
+ if (style.boldItalicFontString)
396
+ blk.boldItalicFontString = style.boldItalicFontString;
397
+ if (partIndex === 0) {
306
398
  blk.headingLevel = headingLevel;
399
+ if (numberPrefix)
400
+ blk.numberPrefix = numberPrefix;
401
+ }
307
402
  blk.lines = resetLinePositions(splitLines, style.lineHeightPx);
308
403
  blk.dirty = false;
309
404
  blk.snappedToGrid = false;
405
+ if (splitLines.length > 0) {
406
+ blk.sourceStart = splitLines[0].sourceStart;
407
+ blk.sourceEnd = splitLines[splitLines.length - 1].sourceEnd;
408
+ }
409
+ blk.sourceMap = absoluteSourceMap;
410
+ blk.plainPrefixLen = prefixLen;
310
411
  const splitHeight = linesPerAvailable * style.lineHeightPx;
311
412
  placeBlockInColumn(blk, splitHeight, curCol, cursor);
312
413
  doc.blocks.push(blk);
@@ -327,11 +428,21 @@ export function buildDocument(content, config) {
327
428
  const blk = createVDTBlock(partId, vdtType, style.fontString, style.color, style.textAlign);
328
429
  if (style.boldFontString)
329
430
  blk.boldFontString = style.boldFontString;
431
+ if (style.italicFontString)
432
+ blk.italicFontString = style.italicFontString;
433
+ if (style.boldItalicFontString)
434
+ blk.boldItalicFontString = style.boldItalicFontString;
330
435
  if (partIndex === 0)
331
436
  blk.headingLevel = headingLevel;
332
437
  blk.lines = resetLinePositions(remainingLines, style.lineHeightPx);
333
438
  blk.dirty = false;
334
439
  blk.snappedToGrid = false;
440
+ if (remainingLines.length > 0) {
441
+ blk.sourceStart = remainingLines[0].sourceStart;
442
+ blk.sourceEnd = remainingLines[remainingLines.length - 1].sourceEnd;
443
+ }
444
+ blk.sourceMap = absoluteSourceMap;
445
+ blk.plainPrefixLen = prefixLen;
335
446
  placeBlockInColumn(blk, totalRemainHeight, curCol, cursor);
336
447
  doc.blocks.push(blk);
337
448
  pendingSpacing = style.marginBottomPx;