js.documents 4.0.20 → 4.4.5
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/README.md +43 -29
- package/dist/cell-typing-CEWlywIc.d.cts +22 -0
- package/dist/cell-typing-CEWlywIc.d.ts +22 -0
- package/dist/codecs/read.cjs +66 -0
- package/dist/codecs/read.d.cts +15 -0
- package/dist/codecs/read.d.ts +15 -0
- package/dist/codecs/read.js +64 -0
- package/dist/codecs/registry.cjs +13 -59
- package/dist/codecs/registry.d.cts +2 -8
- package/dist/codecs/registry.d.ts +2 -8
- package/dist/codecs/registry.js +20 -64
- package/dist/convert/codec.cjs +11 -10
- package/dist/convert/codec.js +2 -1
- package/dist/convert/composition-to-pdf.cjs +133 -0
- package/dist/convert/composition-to-pdf.d.cts +7 -0
- package/dist/convert/composition-to-pdf.d.ts +7 -0
- package/dist/convert/composition-to-pdf.js +131 -0
- package/dist/convert/composition.cjs +31 -129
- package/dist/convert/composition.d.cts +14 -4
- package/dist/convert/composition.d.ts +14 -4
- package/dist/convert/composition.js +25 -128
- package/dist/convert/convert.cjs +35 -75
- package/dist/convert/convert.d.cts +5 -20
- package/dist/convert/convert.d.ts +5 -20
- package/dist/convert/convert.js +2 -32
- package/dist/convert/from-package.cjs +2 -1
- package/dist/convert/from-package.js +2 -1
- package/dist/convert/from-pdf.cjs +50 -0
- package/dist/convert/from-pdf.d.cts +26 -0
- package/dist/convert/from-pdf.d.ts +26 -0
- package/dist/convert/from-pdf.js +39 -0
- package/dist/convert/local.cjs +2 -1
- package/dist/convert/local.js +2 -1
- package/dist/convert/pdf-package-tables.cjs +76 -0
- package/dist/convert/pdf-package-tables.d.cts +6 -0
- package/dist/convert/pdf-package-tables.d.ts +6 -0
- package/dist/convert/pdf-package-tables.js +75 -0
- package/dist/csv/read.d.cts +1 -1
- package/dist/csv/read.d.ts +1 -1
- package/dist/diagnostics-DVAXKgcf.d.cts +10 -0
- package/dist/diagnostics-DVAXKgcf.d.ts +10 -0
- package/dist/edit/docx/content.cjs +1 -0
- package/dist/edit/docx/content.js +1 -0
- package/dist/edit/docx/paragraph.cjs +18 -1
- package/dist/edit/docx/paragraph.d.cts +3 -0
- package/dist/edit/docx/paragraph.d.ts +3 -0
- package/dist/edit/docx/paragraph.js +18 -1
- package/dist/edit/docx/props.cjs +1 -0
- package/dist/edit/docx/props.js +1 -0
- package/dist/edit/markdown/editor.cjs +1 -1
- package/dist/edit/markdown/editor.js +1 -1
- package/dist/edit/pdf/item.cjs +42 -1
- package/dist/edit/pdf/item.d.cts +2 -2
- package/dist/edit/pdf/item.d.ts +2 -2
- package/dist/edit/pdf/item.js +42 -2
- package/dist/edit/pdf/page.d.cts +1 -1
- package/dist/edit/pdf/page.d.ts +1 -1
- package/dist/fonts/registry.d.cts +1 -19
- package/dist/fonts/registry.d.ts +1 -19
- package/dist/hsqldb/binary-script.d.cts +1 -1
- package/dist/hsqldb/binary-script.d.ts +1 -1
- package/dist/hsqldb/cache.d.cts +1 -1
- package/dist/hsqldb/cache.d.ts +1 -1
- package/dist/hsqldb/rowformat.d.cts +1 -24
- package/dist/hsqldb/rowformat.d.ts +1 -24
- package/dist/index.cjs +17 -16
- package/dist/index.d.cts +11 -10
- package/dist/index.d.ts +11 -10
- package/dist/index.js +8 -7
- package/dist/{item-D9vQKT0T.d.cts → item-DhXpJNAQ.d.cts} +17 -3
- package/dist/{item-D9vQKT0T.d.ts → item-DhXpJNAQ.d.ts} +17 -3
- package/dist/layout/cell-typing.d.cts +1 -21
- package/dist/layout/cell-typing.d.ts +1 -21
- package/dist/layout/reconstruct.cjs +177 -14
- package/dist/layout/reconstruct.d.cts +1 -1
- package/dist/layout/reconstruct.d.ts +1 -1
- package/dist/layout/reconstruct.js +175 -12
- package/dist/layout/shared.cjs +2 -2
- package/dist/layout/shared.js +1 -1
- package/dist/markdown/math.cjs +5 -7
- package/dist/markdown/math.js +5 -7
- package/dist/markdown/read.cjs +15 -1
- package/dist/markdown/read.js +16 -2
- package/dist/markdown/write.cjs +7 -10
- package/dist/markdown/write.d.cts +3 -6
- package/dist/markdown/write.d.ts +3 -6
- package/dist/markdown/write.js +8 -11
- package/dist/metadata/write.cjs +2 -1
- package/dist/metadata/write.js +2 -1
- package/dist/model/bytes.cjs +8 -0
- package/dist/model/bytes.d.cts +2 -1
- package/dist/model/bytes.d.ts +2 -1
- package/dist/model/bytes.js +8 -1
- package/dist/odb/read.d.cts +1 -1
- package/dist/odb/read.d.ts +1 -1
- package/dist/odb/report/content.d.cts +1 -1
- package/dist/odb/report/content.d.ts +1 -1
- package/dist/odb/report/source.d.cts +1 -1
- package/dist/odb/report/source.d.ts +1 -1
- package/dist/odf/odt/read.cjs +1 -1
- package/dist/odf/odt/read.js +1 -1
- package/dist/registry-BcBT-bnX.d.cts +20 -0
- package/dist/registry-D1Pu5XxB.d.ts +20 -0
- package/dist/rowformat-Cl2exlEh.d.cts +25 -0
- package/dist/rowformat-Cl2exlEh.d.ts +25 -0
- package/dist/svg/diagnostics.d.cts +1 -9
- package/dist/svg/diagnostics.d.ts +1 -9
- package/dist/svg/read.d.cts +1 -1
- package/dist/svg/read.d.ts +1 -1
- package/dist/svg/write.d.cts +1 -1
- package/dist/svg/write.d.ts +1 -1
- package/package.json +27 -10
- package/dist/metadata/read.cjs +0 -15
- package/dist/metadata/read.d.cts +0 -9
- package/dist/metadata/read.d.ts +0 -9
- package/dist/metadata/read.js +0 -14
|
@@ -1,22 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
//#region src/layout/cell-typing.d.ts
|
|
3
|
-
type CellTypeRule = 'boolean-literal' | 'iso-date' | 'named-month-date' | 'plain-number' | 'grouped-number' | 'percentage' | 'currency';
|
|
4
|
-
type CellTypeDeclineReason = 'ambiguous-boolean-word' | 'ambiguous-date-order' | 'ambiguous-grouping-separator' | 'leading-zero-digits' | 'precision-loss';
|
|
5
|
-
type CellTypeInferenceResult = {
|
|
6
|
-
readonly outcome: 'retyped';
|
|
7
|
-
readonly value: ContentCellValue;
|
|
8
|
-
readonly rule: CellTypeRule;
|
|
9
|
-
} | {
|
|
10
|
-
readonly outcome: 'declined';
|
|
11
|
-
readonly reason: CellTypeDeclineReason;
|
|
12
|
-
};
|
|
13
|
-
type CellTypeInference = {
|
|
14
|
-
readonly sheetIndex: number;
|
|
15
|
-
readonly row: number;
|
|
16
|
-
readonly column: number;
|
|
17
|
-
readonly displayText: string;
|
|
18
|
-
} & CellTypeInferenceResult;
|
|
19
|
-
type CellTypeInferenceSink = (inference: CellTypeInference) => void;
|
|
20
|
-
declare function inferCellValue(displayText: string): CellTypeInferenceResult | undefined;
|
|
21
|
-
//#endregion
|
|
1
|
+
import { a as CellTypeRule, i as CellTypeInferenceSink, n as CellTypeInference, o as inferCellValue, r as CellTypeInferenceResult, t as CellTypeDeclineReason } from "../cell-typing-CEWlywIc.js";
|
|
22
2
|
export { CellTypeDeclineReason, CellTypeInference, CellTypeInferenceResult, CellTypeInferenceSink, CellTypeRule, inferCellValue };
|
|
@@ -5,7 +5,8 @@ const require_layout_cell_typing = require("./cell-typing.cjs");
|
|
|
5
5
|
const require_layout_shared = require("./shared.cjs");
|
|
6
6
|
const require_ports_abort = require("../ports/abort.cjs");
|
|
7
7
|
const require_layout_lattice = require("./lattice.cjs");
|
|
8
|
-
let
|
|
8
|
+
let pdf_codec_fonts = require("pdf-codec/fonts");
|
|
9
|
+
let pdf_codec_afm_widths = require("pdf-codec/afm-widths");
|
|
9
10
|
//#region src/layout/reconstruct.ts
|
|
10
11
|
const ZERO_MARGINS = {
|
|
11
12
|
topPt: 0,
|
|
@@ -31,8 +32,8 @@ function clusterIntoLines(items) {
|
|
|
31
32
|
return working;
|
|
32
33
|
}
|
|
33
34
|
function textItemVerticalExtent(item) {
|
|
34
|
-
const { standardName } = (0,
|
|
35
|
-
const metrics =
|
|
35
|
+
const { standardName } = (0, pdf_codec_fonts.resolveStandardFont)(item.font.family, item.font.weight === "bold", item.font.style === "italic");
|
|
36
|
+
const metrics = pdf_codec_afm_widths.STANDARD_METRICS[standardName];
|
|
36
37
|
return {
|
|
37
38
|
ascentPt: metrics.ascender / 1e3 * item.sizePt,
|
|
38
39
|
descentPt: Math.abs(metrics.descender) / 1e3 * item.sizePt
|
|
@@ -41,8 +42,8 @@ function textItemVerticalExtent(item) {
|
|
|
41
42
|
function textItemToContentRun(item) {
|
|
42
43
|
return {
|
|
43
44
|
text: item.text,
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
...item.font.weight === "bold" ? { bold: true } : {},
|
|
46
|
+
...item.font.style === "italic" ? { italic: true } : {},
|
|
46
47
|
fontFamily: item.font.family,
|
|
47
48
|
sizePt: item.sizePt,
|
|
48
49
|
color: item.color
|
|
@@ -133,33 +134,70 @@ function estimateModalLineSpacing(lines) {
|
|
|
133
134
|
}
|
|
134
135
|
function reconstructWordprocessing(doc, options) {
|
|
135
136
|
const signal = options?.signal;
|
|
137
|
+
doc = dropHiddenLayerContent(doc);
|
|
138
|
+
const headingLevels = headingSizeLevels(doc);
|
|
136
139
|
const sections = [];
|
|
137
140
|
let currentGroup = [];
|
|
138
141
|
let groupStartPageIndex = 0;
|
|
139
142
|
for (const page of doc.pages) {
|
|
140
143
|
require_ports_abort.throwIfAborted(signal);
|
|
141
144
|
if (currentGroup.length > 0 && !samePageSize(currentGroup[0], page)) {
|
|
142
|
-
sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images));
|
|
145
|
+
sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form));
|
|
143
146
|
groupStartPageIndex += currentGroup.length;
|
|
144
147
|
currentGroup = [];
|
|
145
148
|
}
|
|
146
149
|
currentGroup.push(page);
|
|
147
150
|
}
|
|
148
|
-
if (currentGroup.length > 0) sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images));
|
|
151
|
+
if (currentGroup.length > 0) sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form));
|
|
149
152
|
return {
|
|
150
153
|
kind: "wordprocessing",
|
|
151
154
|
metadata: doc.metadata,
|
|
152
155
|
sections
|
|
153
156
|
};
|
|
154
157
|
}
|
|
158
|
+
function layerOf(item) {
|
|
159
|
+
return item.kind === "link" || item.kind === "internalLink" ? void 0 : item.layer;
|
|
160
|
+
}
|
|
161
|
+
function dropHiddenLayerContent(doc) {
|
|
162
|
+
const hidden = new Set((doc.layers ?? []).filter((layer) => layer.visible !== true).map((layer) => layer.name));
|
|
163
|
+
if (hidden.size === 0) return doc;
|
|
164
|
+
return {
|
|
165
|
+
...doc,
|
|
166
|
+
pages: doc.pages.map((page) => ({
|
|
167
|
+
...page,
|
|
168
|
+
items: page.items.filter((item) => layerOf(item) === void 0 || !hidden.has(layerOf(item)))
|
|
169
|
+
}))
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const HEADING_MIN_SIZE_DELTA_PT = 2;
|
|
173
|
+
const MAX_HEADING_LEVEL = 6;
|
|
174
|
+
function headingSizeLevels(doc) {
|
|
175
|
+
const sizes = [];
|
|
176
|
+
for (const page of doc.pages) for (const item of page.items) if (item.kind === "text") sizes.push(item.sizePt);
|
|
177
|
+
if (sizes.length === 0) return /* @__PURE__ */ new Map();
|
|
178
|
+
const bodySizePt = modeOf(sizes, .5);
|
|
179
|
+
const headingBuckets = /* @__PURE__ */ new Set();
|
|
180
|
+
for (const size of sizes) {
|
|
181
|
+
const bucket = Math.round(size / .5) * .5;
|
|
182
|
+
if (bucket - bodySizePt >= HEADING_MIN_SIZE_DELTA_PT) headingBuckets.add(bucket);
|
|
183
|
+
}
|
|
184
|
+
const levels = /* @__PURE__ */ new Map();
|
|
185
|
+
[...headingBuckets].sort((a, b) => b - a).forEach((bucket, index) => {
|
|
186
|
+
levels.set(bucket, Math.min(index + 1, MAX_HEADING_LEVEL));
|
|
187
|
+
});
|
|
188
|
+
return levels;
|
|
189
|
+
}
|
|
190
|
+
function headingLevelOf(paragraph, levels) {
|
|
191
|
+
return levels.get(modeOf(paragraph.lines.flatMap((line) => line.items.map((item) => item.sizePt)), .5));
|
|
192
|
+
}
|
|
155
193
|
function samePageSize(a, b) {
|
|
156
194
|
return a.widthPt === b.widthPt && a.heightPt === b.heightPt;
|
|
157
195
|
}
|
|
158
|
-
function buildSection(pages, startPageIndex, images) {
|
|
196
|
+
function buildSection(pages, startPageIndex, images, headingLevels, form) {
|
|
159
197
|
const blocks = [];
|
|
160
198
|
pages.forEach((page, i) => {
|
|
161
199
|
if (i > 0) blocks.push({ kind: "pageBreak" });
|
|
162
|
-
blocks.push(...reconstructPageBlocks(page, startPageIndex + i, images));
|
|
200
|
+
blocks.push(...reconstructPageBlocks(page, startPageIndex + i, images, headingLevels, form));
|
|
163
201
|
});
|
|
164
202
|
return {
|
|
165
203
|
pageSize: {
|
|
@@ -170,7 +208,7 @@ function buildSection(pages, startPageIndex, images) {
|
|
|
170
208
|
blocks
|
|
171
209
|
};
|
|
172
210
|
}
|
|
173
|
-
function reconstructPageBlocks(page, pageIndex, images) {
|
|
211
|
+
function reconstructPageBlocks(page, pageIndex, images, headingLevels, form) {
|
|
174
212
|
const recoveredTable = recoverTable(page, pageIndex);
|
|
175
213
|
const consumedText = recoveredTable?.consumedText;
|
|
176
214
|
const textItems = page.items.filter((i) => i.kind === "text" && consumedText?.has(i) !== true);
|
|
@@ -179,7 +217,7 @@ function reconstructPageBlocks(page, pageIndex, images) {
|
|
|
179
217
|
const positioned = [];
|
|
180
218
|
for (const paragraph of paragraphs) positioned.push({
|
|
181
219
|
yPt: paragraph.lines[0].baselineY,
|
|
182
|
-
block: paragraphToContentParagraph(paragraph, pageIndex)
|
|
220
|
+
block: paragraphToContentParagraph(paragraph, pageIndex, headingLevelOf(paragraph, headingLevels))
|
|
183
221
|
});
|
|
184
222
|
for (const img of imageItems) {
|
|
185
223
|
const asset = images[img.imageId];
|
|
@@ -213,7 +251,121 @@ function reconstructPageBlocks(page, pageIndex, images) {
|
|
|
213
251
|
block: recoveredVectors.block
|
|
214
252
|
});
|
|
215
253
|
positioned.sort((a, b) => b.yPt - a.yPt);
|
|
216
|
-
|
|
254
|
+
const blocks = positioned.map((p) => p.block);
|
|
255
|
+
reconcileLinks(blocks, page, pageIndex);
|
|
256
|
+
appendAnnotationConstructs(blocks, page, pageIndex);
|
|
257
|
+
appendFormFieldConstructs(blocks, form, pageIndex);
|
|
258
|
+
return blocks;
|
|
259
|
+
}
|
|
260
|
+
function framesIntersect(a, b) {
|
|
261
|
+
return a.xPt < b.xPt + b.widthPt && b.xPt < a.xPt + a.widthPt && a.yPt < b.yPt + b.heightPt && b.yPt < a.yPt + a.heightPt;
|
|
262
|
+
}
|
|
263
|
+
function intersectionArea(a, b) {
|
|
264
|
+
const width = Math.min(a.xPt + a.widthPt, b.xPt + b.widthPt) - Math.max(a.xPt, b.xPt);
|
|
265
|
+
const height = Math.min(a.yPt + a.heightPt, b.yPt + b.heightPt) - Math.max(a.yPt, b.yPt);
|
|
266
|
+
return width > 0 && height > 0 ? width * height : 0;
|
|
267
|
+
}
|
|
268
|
+
function reconcileLinks(blocks, page, pageIndex) {
|
|
269
|
+
for (const item of page.items) {
|
|
270
|
+
if (item.kind !== "link" && item.kind !== "internalLink") continue;
|
|
271
|
+
if (item.kind === "link") {
|
|
272
|
+
let matchedRun = false;
|
|
273
|
+
for (const block of blocks) {
|
|
274
|
+
if (block.kind !== "paragraph") continue;
|
|
275
|
+
for (const run of block.runs) if ((run.frames ?? []).some((frame) => frame.pageIndex === pageIndex && framesIntersect(item, frame))) {
|
|
276
|
+
run.hyperlink = item.uri;
|
|
277
|
+
matchedRun = true;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
if (matchedRun) continue;
|
|
281
|
+
}
|
|
282
|
+
wrapBestBlock(blocks, item, pageIndex, linkDescriptor(item));
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function linkDescriptor(item) {
|
|
286
|
+
if (item.kind === "link") return {
|
|
287
|
+
kind: "link",
|
|
288
|
+
target: {
|
|
289
|
+
kind: "external",
|
|
290
|
+
uri: item.uri
|
|
291
|
+
},
|
|
292
|
+
...item.title !== void 0 ? { title: item.title } : {}
|
|
293
|
+
};
|
|
294
|
+
return {
|
|
295
|
+
kind: "link",
|
|
296
|
+
target: {
|
|
297
|
+
kind: "internal",
|
|
298
|
+
anchor: item.destination
|
|
299
|
+
},
|
|
300
|
+
...item.title !== void 0 ? { title: item.title } : {}
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
function blockFramesOn(block, pageIndex) {
|
|
304
|
+
return block.kind === "constructStart" || block.kind === "constructEnd" ? [] : (block.frames ?? []).filter((frame) => frame.pageIndex === pageIndex);
|
|
305
|
+
}
|
|
306
|
+
function wrapBestBlock(blocks, rect, pageIndex, descriptor) {
|
|
307
|
+
let bestIndex = -1;
|
|
308
|
+
let bestArea = 0;
|
|
309
|
+
blocks.forEach((block, index) => {
|
|
310
|
+
const area = blockFramesOn(block, pageIndex).reduce((sum, frame) => sum + intersectionArea(rect, frame), 0);
|
|
311
|
+
if (area > bestArea) {
|
|
312
|
+
bestArea = area;
|
|
313
|
+
bestIndex = index;
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
const start = {
|
|
317
|
+
kind: "constructStart",
|
|
318
|
+
descriptor
|
|
319
|
+
};
|
|
320
|
+
const end = { kind: "constructEnd" };
|
|
321
|
+
if (bestIndex >= 0) {
|
|
322
|
+
blocks.splice(bestIndex, 0, start);
|
|
323
|
+
blocks.splice(bestIndex + 2, 0, end);
|
|
324
|
+
} else blocks.push(start, end);
|
|
325
|
+
}
|
|
326
|
+
function appendAnnotationConstructs(blocks, page, pageIndex) {
|
|
327
|
+
(page.annotations ?? []).forEach((annotation, annotIndex) => {
|
|
328
|
+
const key = `pdf-annot-${String(pageIndex)}-${String(annotIndex)}`;
|
|
329
|
+
blocks.push({
|
|
330
|
+
kind: "constructStart",
|
|
331
|
+
descriptor: {
|
|
332
|
+
kind: "anchor",
|
|
333
|
+
anchorType: "comment",
|
|
334
|
+
name: key,
|
|
335
|
+
definition: key,
|
|
336
|
+
...annotation.source !== void 0 ? { source: annotation.source } : {}
|
|
337
|
+
}
|
|
338
|
+
}, { kind: "constructEnd" });
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
function controlTypeOf(field) {
|
|
342
|
+
if (field.fieldType === "text") return "plainText";
|
|
343
|
+
if (field.fieldType === "button") return "button";
|
|
344
|
+
if (field.fieldType === "combobox") return "comboBox";
|
|
345
|
+
if (field.fieldType === "listbox") return "dropDown";
|
|
346
|
+
return "checkbox";
|
|
347
|
+
}
|
|
348
|
+
function appendFormFieldConstructs(blocks, form, pageIndex) {
|
|
349
|
+
const visit = (fields) => {
|
|
350
|
+
for (const field of fields) {
|
|
351
|
+
visit(field.children);
|
|
352
|
+
if (field.fieldType === "group" || field.fieldType === "signature") continue;
|
|
353
|
+
for (const widget of field.widgets) {
|
|
354
|
+
if (widget.pageIndex !== pageIndex) continue;
|
|
355
|
+
wrapBestBlock(blocks, widget, pageIndex, {
|
|
356
|
+
kind: "contentControl",
|
|
357
|
+
controlType: controlTypeOf(field),
|
|
358
|
+
tag: field.name,
|
|
359
|
+
...field.alias !== void 0 ? { alias: field.alias } : {},
|
|
360
|
+
...field.readOnly === true ? { lock: "content" } : {},
|
|
361
|
+
...field.value !== void 0 ? { value: field.value } : {},
|
|
362
|
+
...field.checked !== void 0 ? { checked: field.checked } : {},
|
|
363
|
+
...field.options !== void 0 ? { options: [...field.options] } : {}
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
visit(form ?? []);
|
|
217
369
|
}
|
|
218
370
|
function clusterIntoParagraphs(lines) {
|
|
219
371
|
if (lines.length === 0) return [];
|
|
@@ -230,6 +382,7 @@ function clusterIntoParagraphs(lines) {
|
|
|
230
382
|
}
|
|
231
383
|
function startsNewParagraph(prev, next, modalSpacing, dominantLeftX) {
|
|
232
384
|
if (prev.baselineY - next.baselineY > PARAGRAPH_GAP_MULTIPLIER * modalSpacing) return true;
|
|
385
|
+
if (!fontSizesClose(prev.items[0].sizePt, next.items[0].sizePt)) return true;
|
|
233
386
|
const nextLeft = next.items[0].xPt;
|
|
234
387
|
const prevLeft = prev.items[0].xPt;
|
|
235
388
|
const emPt = next.items[0].sizePt;
|
|
@@ -238,12 +391,16 @@ function startsNewParagraph(prev, next, modalSpacing, dominantLeftX) {
|
|
|
238
391
|
return nextIndented && prevAtMargin;
|
|
239
392
|
}
|
|
240
393
|
const LEFT_ALIGN_TOLERANCE_PT = 2;
|
|
241
|
-
function paragraphToContentParagraph(paragraph, pageIndex) {
|
|
394
|
+
function paragraphToContentParagraph(paragraph, pageIndex, headingLevel) {
|
|
242
395
|
const dominantLeftX = modeOf(paragraph.lines.map((l) => l.items[0].xPt), 1);
|
|
243
396
|
const result = {
|
|
244
397
|
kind: "paragraph",
|
|
245
398
|
runs: [],
|
|
246
|
-
alignment: paragraph.lines.every((l) => Math.abs(l.items[0].xPt - dominantLeftX) <= LEFT_ALIGN_TOLERANCE_PT) ? "left" : void 0
|
|
399
|
+
alignment: paragraph.lines.every((l) => Math.abs(l.items[0].xPt - dominantLeftX) <= LEFT_ALIGN_TOLERANCE_PT) ? "left" : void 0,
|
|
400
|
+
...headingLevel !== void 0 ? {
|
|
401
|
+
styleId: `Heading${String(headingLevel)}`,
|
|
402
|
+
headingLevel
|
|
403
|
+
} : {}
|
|
247
404
|
};
|
|
248
405
|
paragraph.lines.forEach((line, lineIndex) => {
|
|
249
406
|
require_layout_shared.stampFrame(result, pageIndex, lineBox(line, pageIndex));
|
|
@@ -253,6 +410,12 @@ function paragraphToContentParagraph(paragraph, pageIndex) {
|
|
|
253
410
|
}
|
|
254
411
|
pushRunsForLine(result.runs, line, pageIndex);
|
|
255
412
|
});
|
|
413
|
+
if (headingLevel !== void 0) result.runs = result.runs.map((run) => {
|
|
414
|
+
if (run.bold !== true) return run;
|
|
415
|
+
const withoutBold = { ...run };
|
|
416
|
+
delete withoutBold.bold;
|
|
417
|
+
return withoutBold;
|
|
418
|
+
});
|
|
256
419
|
return result;
|
|
257
420
|
}
|
|
258
421
|
function reconstructPresentation(doc, options) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CellTypeInferenceSink } from "
|
|
1
|
+
import { i as CellTypeInferenceSink } from "../cell-typing-CEWlywIc.cjs";
|
|
2
2
|
import { ContentDocument } from "document-schema.js";
|
|
3
3
|
import { LayoutDocument } from "pdf-codec";
|
|
4
4
|
//#region src/layout/reconstruct.d.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CellTypeInferenceSink } from "
|
|
1
|
+
import { i as CellTypeInferenceSink } from "../cell-typing-CEWlywIc.js";
|
|
2
2
|
import { ContentDocument } from "document-schema.js";
|
|
3
3
|
import { LayoutDocument } from "pdf-codec";
|
|
4
4
|
//#region src/layout/reconstruct.d.ts
|
|
@@ -4,7 +4,8 @@ import { inferCellValue } from "./cell-typing.js";
|
|
|
4
4
|
import { stampFrame } from "./shared.js";
|
|
5
5
|
import { throwIfAborted } from "../ports/abort.js";
|
|
6
6
|
import { detectGridLattice, findColumnIndex, findRowIndex } from "./lattice.js";
|
|
7
|
-
import {
|
|
7
|
+
import { resolveStandardFont } from "pdf-codec/fonts";
|
|
8
|
+
import { STANDARD_METRICS } from "pdf-codec/afm-widths";
|
|
8
9
|
//#region src/layout/reconstruct.ts
|
|
9
10
|
const ZERO_MARGINS = {
|
|
10
11
|
topPt: 0,
|
|
@@ -40,8 +41,8 @@ function textItemVerticalExtent(item) {
|
|
|
40
41
|
function textItemToContentRun(item) {
|
|
41
42
|
return {
|
|
42
43
|
text: item.text,
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
...item.font.weight === "bold" ? { bold: true } : {},
|
|
45
|
+
...item.font.style === "italic" ? { italic: true } : {},
|
|
45
46
|
fontFamily: item.font.family,
|
|
46
47
|
sizePt: item.sizePt,
|
|
47
48
|
color: item.color
|
|
@@ -132,33 +133,70 @@ function estimateModalLineSpacing(lines) {
|
|
|
132
133
|
}
|
|
133
134
|
function reconstructWordprocessing(doc, options) {
|
|
134
135
|
const signal = options?.signal;
|
|
136
|
+
doc = dropHiddenLayerContent(doc);
|
|
137
|
+
const headingLevels = headingSizeLevels(doc);
|
|
135
138
|
const sections = [];
|
|
136
139
|
let currentGroup = [];
|
|
137
140
|
let groupStartPageIndex = 0;
|
|
138
141
|
for (const page of doc.pages) {
|
|
139
142
|
throwIfAborted(signal);
|
|
140
143
|
if (currentGroup.length > 0 && !samePageSize(currentGroup[0], page)) {
|
|
141
|
-
sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images));
|
|
144
|
+
sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form));
|
|
142
145
|
groupStartPageIndex += currentGroup.length;
|
|
143
146
|
currentGroup = [];
|
|
144
147
|
}
|
|
145
148
|
currentGroup.push(page);
|
|
146
149
|
}
|
|
147
|
-
if (currentGroup.length > 0) sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images));
|
|
150
|
+
if (currentGroup.length > 0) sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form));
|
|
148
151
|
return {
|
|
149
152
|
kind: "wordprocessing",
|
|
150
153
|
metadata: doc.metadata,
|
|
151
154
|
sections
|
|
152
155
|
};
|
|
153
156
|
}
|
|
157
|
+
function layerOf(item) {
|
|
158
|
+
return item.kind === "link" || item.kind === "internalLink" ? void 0 : item.layer;
|
|
159
|
+
}
|
|
160
|
+
function dropHiddenLayerContent(doc) {
|
|
161
|
+
const hidden = new Set((doc.layers ?? []).filter((layer) => layer.visible !== true).map((layer) => layer.name));
|
|
162
|
+
if (hidden.size === 0) return doc;
|
|
163
|
+
return {
|
|
164
|
+
...doc,
|
|
165
|
+
pages: doc.pages.map((page) => ({
|
|
166
|
+
...page,
|
|
167
|
+
items: page.items.filter((item) => layerOf(item) === void 0 || !hidden.has(layerOf(item)))
|
|
168
|
+
}))
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
const HEADING_MIN_SIZE_DELTA_PT = 2;
|
|
172
|
+
const MAX_HEADING_LEVEL = 6;
|
|
173
|
+
function headingSizeLevels(doc) {
|
|
174
|
+
const sizes = [];
|
|
175
|
+
for (const page of doc.pages) for (const item of page.items) if (item.kind === "text") sizes.push(item.sizePt);
|
|
176
|
+
if (sizes.length === 0) return /* @__PURE__ */ new Map();
|
|
177
|
+
const bodySizePt = modeOf(sizes, .5);
|
|
178
|
+
const headingBuckets = /* @__PURE__ */ new Set();
|
|
179
|
+
for (const size of sizes) {
|
|
180
|
+
const bucket = Math.round(size / .5) * .5;
|
|
181
|
+
if (bucket - bodySizePt >= HEADING_MIN_SIZE_DELTA_PT) headingBuckets.add(bucket);
|
|
182
|
+
}
|
|
183
|
+
const levels = /* @__PURE__ */ new Map();
|
|
184
|
+
[...headingBuckets].sort((a, b) => b - a).forEach((bucket, index) => {
|
|
185
|
+
levels.set(bucket, Math.min(index + 1, MAX_HEADING_LEVEL));
|
|
186
|
+
});
|
|
187
|
+
return levels;
|
|
188
|
+
}
|
|
189
|
+
function headingLevelOf(paragraph, levels) {
|
|
190
|
+
return levels.get(modeOf(paragraph.lines.flatMap((line) => line.items.map((item) => item.sizePt)), .5));
|
|
191
|
+
}
|
|
154
192
|
function samePageSize(a, b) {
|
|
155
193
|
return a.widthPt === b.widthPt && a.heightPt === b.heightPt;
|
|
156
194
|
}
|
|
157
|
-
function buildSection(pages, startPageIndex, images) {
|
|
195
|
+
function buildSection(pages, startPageIndex, images, headingLevels, form) {
|
|
158
196
|
const blocks = [];
|
|
159
197
|
pages.forEach((page, i) => {
|
|
160
198
|
if (i > 0) blocks.push({ kind: "pageBreak" });
|
|
161
|
-
blocks.push(...reconstructPageBlocks(page, startPageIndex + i, images));
|
|
199
|
+
blocks.push(...reconstructPageBlocks(page, startPageIndex + i, images, headingLevels, form));
|
|
162
200
|
});
|
|
163
201
|
return {
|
|
164
202
|
pageSize: {
|
|
@@ -169,7 +207,7 @@ function buildSection(pages, startPageIndex, images) {
|
|
|
169
207
|
blocks
|
|
170
208
|
};
|
|
171
209
|
}
|
|
172
|
-
function reconstructPageBlocks(page, pageIndex, images) {
|
|
210
|
+
function reconstructPageBlocks(page, pageIndex, images, headingLevels, form) {
|
|
173
211
|
const recoveredTable = recoverTable(page, pageIndex);
|
|
174
212
|
const consumedText = recoveredTable?.consumedText;
|
|
175
213
|
const textItems = page.items.filter((i) => i.kind === "text" && consumedText?.has(i) !== true);
|
|
@@ -178,7 +216,7 @@ function reconstructPageBlocks(page, pageIndex, images) {
|
|
|
178
216
|
const positioned = [];
|
|
179
217
|
for (const paragraph of paragraphs) positioned.push({
|
|
180
218
|
yPt: paragraph.lines[0].baselineY,
|
|
181
|
-
block: paragraphToContentParagraph(paragraph, pageIndex)
|
|
219
|
+
block: paragraphToContentParagraph(paragraph, pageIndex, headingLevelOf(paragraph, headingLevels))
|
|
182
220
|
});
|
|
183
221
|
for (const img of imageItems) {
|
|
184
222
|
const asset = images[img.imageId];
|
|
@@ -212,7 +250,121 @@ function reconstructPageBlocks(page, pageIndex, images) {
|
|
|
212
250
|
block: recoveredVectors.block
|
|
213
251
|
});
|
|
214
252
|
positioned.sort((a, b) => b.yPt - a.yPt);
|
|
215
|
-
|
|
253
|
+
const blocks = positioned.map((p) => p.block);
|
|
254
|
+
reconcileLinks(blocks, page, pageIndex);
|
|
255
|
+
appendAnnotationConstructs(blocks, page, pageIndex);
|
|
256
|
+
appendFormFieldConstructs(blocks, form, pageIndex);
|
|
257
|
+
return blocks;
|
|
258
|
+
}
|
|
259
|
+
function framesIntersect(a, b) {
|
|
260
|
+
return a.xPt < b.xPt + b.widthPt && b.xPt < a.xPt + a.widthPt && a.yPt < b.yPt + b.heightPt && b.yPt < a.yPt + a.heightPt;
|
|
261
|
+
}
|
|
262
|
+
function intersectionArea(a, b) {
|
|
263
|
+
const width = Math.min(a.xPt + a.widthPt, b.xPt + b.widthPt) - Math.max(a.xPt, b.xPt);
|
|
264
|
+
const height = Math.min(a.yPt + a.heightPt, b.yPt + b.heightPt) - Math.max(a.yPt, b.yPt);
|
|
265
|
+
return width > 0 && height > 0 ? width * height : 0;
|
|
266
|
+
}
|
|
267
|
+
function reconcileLinks(blocks, page, pageIndex) {
|
|
268
|
+
for (const item of page.items) {
|
|
269
|
+
if (item.kind !== "link" && item.kind !== "internalLink") continue;
|
|
270
|
+
if (item.kind === "link") {
|
|
271
|
+
let matchedRun = false;
|
|
272
|
+
for (const block of blocks) {
|
|
273
|
+
if (block.kind !== "paragraph") continue;
|
|
274
|
+
for (const run of block.runs) if ((run.frames ?? []).some((frame) => frame.pageIndex === pageIndex && framesIntersect(item, frame))) {
|
|
275
|
+
run.hyperlink = item.uri;
|
|
276
|
+
matchedRun = true;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (matchedRun) continue;
|
|
280
|
+
}
|
|
281
|
+
wrapBestBlock(blocks, item, pageIndex, linkDescriptor(item));
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function linkDescriptor(item) {
|
|
285
|
+
if (item.kind === "link") return {
|
|
286
|
+
kind: "link",
|
|
287
|
+
target: {
|
|
288
|
+
kind: "external",
|
|
289
|
+
uri: item.uri
|
|
290
|
+
},
|
|
291
|
+
...item.title !== void 0 ? { title: item.title } : {}
|
|
292
|
+
};
|
|
293
|
+
return {
|
|
294
|
+
kind: "link",
|
|
295
|
+
target: {
|
|
296
|
+
kind: "internal",
|
|
297
|
+
anchor: item.destination
|
|
298
|
+
},
|
|
299
|
+
...item.title !== void 0 ? { title: item.title } : {}
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
function blockFramesOn(block, pageIndex) {
|
|
303
|
+
return block.kind === "constructStart" || block.kind === "constructEnd" ? [] : (block.frames ?? []).filter((frame) => frame.pageIndex === pageIndex);
|
|
304
|
+
}
|
|
305
|
+
function wrapBestBlock(blocks, rect, pageIndex, descriptor) {
|
|
306
|
+
let bestIndex = -1;
|
|
307
|
+
let bestArea = 0;
|
|
308
|
+
blocks.forEach((block, index) => {
|
|
309
|
+
const area = blockFramesOn(block, pageIndex).reduce((sum, frame) => sum + intersectionArea(rect, frame), 0);
|
|
310
|
+
if (area > bestArea) {
|
|
311
|
+
bestArea = area;
|
|
312
|
+
bestIndex = index;
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
const start = {
|
|
316
|
+
kind: "constructStart",
|
|
317
|
+
descriptor
|
|
318
|
+
};
|
|
319
|
+
const end = { kind: "constructEnd" };
|
|
320
|
+
if (bestIndex >= 0) {
|
|
321
|
+
blocks.splice(bestIndex, 0, start);
|
|
322
|
+
blocks.splice(bestIndex + 2, 0, end);
|
|
323
|
+
} else blocks.push(start, end);
|
|
324
|
+
}
|
|
325
|
+
function appendAnnotationConstructs(blocks, page, pageIndex) {
|
|
326
|
+
(page.annotations ?? []).forEach((annotation, annotIndex) => {
|
|
327
|
+
const key = `pdf-annot-${String(pageIndex)}-${String(annotIndex)}`;
|
|
328
|
+
blocks.push({
|
|
329
|
+
kind: "constructStart",
|
|
330
|
+
descriptor: {
|
|
331
|
+
kind: "anchor",
|
|
332
|
+
anchorType: "comment",
|
|
333
|
+
name: key,
|
|
334
|
+
definition: key,
|
|
335
|
+
...annotation.source !== void 0 ? { source: annotation.source } : {}
|
|
336
|
+
}
|
|
337
|
+
}, { kind: "constructEnd" });
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
function controlTypeOf(field) {
|
|
341
|
+
if (field.fieldType === "text") return "plainText";
|
|
342
|
+
if (field.fieldType === "button") return "button";
|
|
343
|
+
if (field.fieldType === "combobox") return "comboBox";
|
|
344
|
+
if (field.fieldType === "listbox") return "dropDown";
|
|
345
|
+
return "checkbox";
|
|
346
|
+
}
|
|
347
|
+
function appendFormFieldConstructs(blocks, form, pageIndex) {
|
|
348
|
+
const visit = (fields) => {
|
|
349
|
+
for (const field of fields) {
|
|
350
|
+
visit(field.children);
|
|
351
|
+
if (field.fieldType === "group" || field.fieldType === "signature") continue;
|
|
352
|
+
for (const widget of field.widgets) {
|
|
353
|
+
if (widget.pageIndex !== pageIndex) continue;
|
|
354
|
+
wrapBestBlock(blocks, widget, pageIndex, {
|
|
355
|
+
kind: "contentControl",
|
|
356
|
+
controlType: controlTypeOf(field),
|
|
357
|
+
tag: field.name,
|
|
358
|
+
...field.alias !== void 0 ? { alias: field.alias } : {},
|
|
359
|
+
...field.readOnly === true ? { lock: "content" } : {},
|
|
360
|
+
...field.value !== void 0 ? { value: field.value } : {},
|
|
361
|
+
...field.checked !== void 0 ? { checked: field.checked } : {},
|
|
362
|
+
...field.options !== void 0 ? { options: [...field.options] } : {}
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
visit(form ?? []);
|
|
216
368
|
}
|
|
217
369
|
function clusterIntoParagraphs(lines) {
|
|
218
370
|
if (lines.length === 0) return [];
|
|
@@ -229,6 +381,7 @@ function clusterIntoParagraphs(lines) {
|
|
|
229
381
|
}
|
|
230
382
|
function startsNewParagraph(prev, next, modalSpacing, dominantLeftX) {
|
|
231
383
|
if (prev.baselineY - next.baselineY > PARAGRAPH_GAP_MULTIPLIER * modalSpacing) return true;
|
|
384
|
+
if (!fontSizesClose(prev.items[0].sizePt, next.items[0].sizePt)) return true;
|
|
232
385
|
const nextLeft = next.items[0].xPt;
|
|
233
386
|
const prevLeft = prev.items[0].xPt;
|
|
234
387
|
const emPt = next.items[0].sizePt;
|
|
@@ -237,12 +390,16 @@ function startsNewParagraph(prev, next, modalSpacing, dominantLeftX) {
|
|
|
237
390
|
return nextIndented && prevAtMargin;
|
|
238
391
|
}
|
|
239
392
|
const LEFT_ALIGN_TOLERANCE_PT = 2;
|
|
240
|
-
function paragraphToContentParagraph(paragraph, pageIndex) {
|
|
393
|
+
function paragraphToContentParagraph(paragraph, pageIndex, headingLevel) {
|
|
241
394
|
const dominantLeftX = modeOf(paragraph.lines.map((l) => l.items[0].xPt), 1);
|
|
242
395
|
const result = {
|
|
243
396
|
kind: "paragraph",
|
|
244
397
|
runs: [],
|
|
245
|
-
alignment: paragraph.lines.every((l) => Math.abs(l.items[0].xPt - dominantLeftX) <= LEFT_ALIGN_TOLERANCE_PT) ? "left" : void 0
|
|
398
|
+
alignment: paragraph.lines.every((l) => Math.abs(l.items[0].xPt - dominantLeftX) <= LEFT_ALIGN_TOLERANCE_PT) ? "left" : void 0,
|
|
399
|
+
...headingLevel !== void 0 ? {
|
|
400
|
+
styleId: `Heading${String(headingLevel)}`,
|
|
401
|
+
headingLevel
|
|
402
|
+
} : {}
|
|
246
403
|
};
|
|
247
404
|
paragraph.lines.forEach((line, lineIndex) => {
|
|
248
405
|
stampFrame(result, pageIndex, lineBox(line, pageIndex));
|
|
@@ -252,6 +409,12 @@ function paragraphToContentParagraph(paragraph, pageIndex) {
|
|
|
252
409
|
}
|
|
253
410
|
pushRunsForLine(result.runs, line, pageIndex);
|
|
254
411
|
});
|
|
412
|
+
if (headingLevel !== void 0) result.runs = result.runs.map((run) => {
|
|
413
|
+
if (run.bold !== true) return run;
|
|
414
|
+
const withoutBold = { ...run };
|
|
415
|
+
delete withoutBold.bold;
|
|
416
|
+
return withoutBold;
|
|
417
|
+
});
|
|
255
418
|
return result;
|
|
256
419
|
}
|
|
257
420
|
function reconstructPresentation(doc, options) {
|
package/dist/layout/shared.cjs
CHANGED
|
@@ -3,8 +3,8 @@ const require_mathml_layout = require("../mathml/layout.cjs");
|
|
|
3
3
|
const require_layout_text_layout = require("./text-layout.cjs");
|
|
4
4
|
let ooxml_js = require("ooxml.js");
|
|
5
5
|
let document_schema_js = require("document-schema.js");
|
|
6
|
-
let pdf_codec = require("pdf-codec");
|
|
7
6
|
let byte_codec = require("byte-codec");
|
|
7
|
+
let pdf_codec_layout = require("pdf-codec/layout");
|
|
8
8
|
//#region src/layout/shared.ts
|
|
9
9
|
function stampFrame(node, pageIndex, box) {
|
|
10
10
|
const frame = {
|
|
@@ -39,7 +39,7 @@ function packagePagesOf(pages) {
|
|
|
39
39
|
}
|
|
40
40
|
function layoutDocumentOf(metadata, pages, images) {
|
|
41
41
|
return {
|
|
42
|
-
formatVersion:
|
|
42
|
+
formatVersion: pdf_codec_layout.LAYOUT_FORMAT_VERSION,
|
|
43
43
|
metadata,
|
|
44
44
|
pages,
|
|
45
45
|
images
|
package/dist/layout/shared.js
CHANGED
|
@@ -2,8 +2,8 @@ import { layoutFormula } from "../mathml/layout.js";
|
|
|
2
2
|
import { wrapRunsToWidth } from "./text-layout.js";
|
|
3
3
|
import { base64ToBytes } from "ooxml.js";
|
|
4
4
|
import { COLOR_BLACK, DEFAULT_LAYOUT_FONT } from "document-schema.js";
|
|
5
|
-
import { LAYOUT_FORMAT_VERSION } from "pdf-codec";
|
|
6
5
|
import { crc32, decodePng, readJpegInfo } from "byte-codec";
|
|
6
|
+
import { LAYOUT_FORMAT_VERSION } from "pdf-codec/layout";
|
|
7
7
|
//#region src/layout/shared.ts
|
|
8
8
|
function stampFrame(node, pageIndex, box) {
|
|
9
9
|
const frame = {
|
package/dist/markdown/math.cjs
CHANGED
|
@@ -3,7 +3,6 @@ const require_model_formula = require("../model/formula.cjs");
|
|
|
3
3
|
const require_latex_symbols = require("../latex/symbols.cjs");
|
|
4
4
|
const require_latex_lower = require("../latex/lower.cjs");
|
|
5
5
|
//#region src/markdown/math.ts
|
|
6
|
-
const MATH_BLOCK_STYLE_ID = "MathBlock";
|
|
7
6
|
const MATH_INLINE_FONT_MARKER = "Cambria Math";
|
|
8
7
|
const STAND_IN_FRAME = {
|
|
9
8
|
xPt: 0,
|
|
@@ -62,14 +61,13 @@ function lowerMarkdownMath(document, options) {
|
|
|
62
61
|
});
|
|
63
62
|
continue;
|
|
64
63
|
}
|
|
65
|
-
if (block.kind
|
|
66
|
-
|
|
64
|
+
if (block.kind === "embeddedObject" && block.objectKind === "formula" && block.document.kind === "formula" && block.document.formula.presentation !== void 0) {
|
|
65
|
+
const formulaBlock = lowerOne(block.document.formula.presentation.latex, MATH_BLOCK_SOURCE);
|
|
66
|
+
out.push(formulaBlock ?? block);
|
|
67
67
|
continue;
|
|
68
68
|
}
|
|
69
|
-
if (block.
|
|
70
|
-
|
|
71
|
-
const formulaBlock = lowerOne(latex, MATH_BLOCK_SOURCE);
|
|
72
|
-
out.push(formulaBlock ?? block);
|
|
69
|
+
if (block.kind !== "paragraph") {
|
|
70
|
+
out.push(block);
|
|
73
71
|
continue;
|
|
74
72
|
}
|
|
75
73
|
const extraction = extractInlineMath(block.runs);
|