@stll/folio-core 0.32.2 → 0.33.0
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/ai-edits/__fixtures__/paragraphs.d.ts +17 -0
- package/dist/ai-edits/__fixtures__/paragraphs.js +33 -0
- package/dist/ai-edits/apply.d.ts +49 -3
- package/dist/ai-edits/apply.js +649 -85
- package/dist/ai-edits/blockRange.d.ts +7 -3
- package/dist/ai-edits/blockRange.js +14 -6
- package/dist/ai-edits/headless.d.ts +39 -5
- package/dist/ai-edits/headless.js +76 -17
- package/dist/ai-edits/index.d.ts +6 -6
- package/dist/ai-edits/index.js +3 -3
- package/dist/ai-edits/read.d.ts +4 -0
- package/dist/ai-edits/read.js +30 -6
- package/dist/ai-edits/scoped-reading.js +4 -3
- package/dist/ai-edits/snapshot.d.ts +42 -2
- package/dist/ai-edits/snapshot.js +127 -62
- package/dist/ai-edits/table-row-column-mutations.d.ts +24 -1
- package/dist/ai-edits/table-row-column-mutations.js +98 -6
- package/dist/ai-edits/table-targets.d.ts +12 -3
- package/dist/ai-edits/table-targets.js +15 -5
- package/dist/ai-edits/types.d.ts +219 -15
- package/dist/ai-edits/word-diff.d.ts +54 -11
- package/dist/ai-edits/word-diff.js +221 -61
- package/dist/compare/__fixtures__/body-sequence.d.ts +33 -0
- package/dist/compare/__fixtures__/body-sequence.js +67 -0
- package/dist/compare/__fixtures__/nested-table.d.ts +16 -0
- package/dist/compare/__fixtures__/nested-table.js +50 -0
- package/dist/compare/__fixtures__/numbered-list.d.ts +34 -0
- package/dist/compare/__fixtures__/numbered-list.js +85 -0
- package/dist/compare/column-alignment.d.ts +27 -0
- package/dist/compare/column-alignment.js +162 -0
- package/dist/compare/compare.d.ts +107 -0
- package/dist/compare/compare.js +406 -0
- package/dist/compare/formatting.d.ts +29 -0
- package/dist/compare/formatting.js +84 -0
- package/dist/compare/plan.d.ts +22 -0
- package/dist/compare/plan.js +1059 -0
- package/dist/compare/reproducible-package.d.ts +17 -0
- package/dist/compare/reproducible-package.js +30 -0
- package/dist/compare/scenario.d.ts +77 -0
- package/dist/compare/scenario.js +263 -0
- package/dist/compare/types.d.ts +282 -0
- package/dist/compare/types.js +32 -0
- package/dist/compare/verification.d.ts +55 -0
- package/dist/compare/verification.js +146 -0
- package/dist/compat/eigenpal.d.ts +9 -6
- package/dist/compat/eigenpal.js +6 -3
- package/dist/controller/layoutPipeline.d.ts +13 -0
- package/dist/controller/layoutPipeline.js +15 -1
- package/dist/display-list/build/buildContext.d.ts +39 -0
- package/dist/display-list/build/buildContext.js +31 -0
- package/dist/display-list/build/buildDisplayList.d.ts +79 -0
- package/dist/display-list/build/buildDisplayList.js +283 -0
- package/dist/display-list/build/colors.d.ts +20 -0
- package/dist/display-list/build/colors.js +136 -0
- package/dist/display-list/build/floatingImages.d.ts +24 -0
- package/dist/display-list/build/floatingImages.js +41 -0
- package/dist/display-list/build/fontTable.d.ts +31 -0
- package/dist/display-list/build/fontTable.js +97 -0
- package/dist/display-list/build/furniture.d.ts +86 -0
- package/dist/display-list/build/furniture.js +98 -0
- package/dist/display-list/build/glyphs.d.ts +55 -0
- package/dist/display-list/build/glyphs.js +103 -0
- package/dist/display-list/build/headerFooterPrimitives.d.ts +17 -0
- package/dist/display-list/build/headerFooterPrimitives.js +40 -0
- package/dist/display-list/build/imagePrimitives.d.ts +35 -0
- package/dist/display-list/build/imagePrimitives.js +264 -0
- package/dist/display-list/build/pageBorderPrimitives.d.ts +23 -0
- package/dist/display-list/build/pageBorderPrimitives.js +111 -0
- package/dist/display-list/build/pageFurniture.d.ts +35 -0
- package/dist/display-list/build/pageFurniture.js +141 -0
- package/dist/display-list/build/paragraphPrimitives.d.ts +19 -0
- package/dist/display-list/build/paragraphPrimitives.js +819 -0
- package/dist/display-list/build/regions.d.ts +46 -0
- package/dist/display-list/build/regions.js +56 -0
- package/dist/display-list/build/storyPrimitives.d.ts +29 -0
- package/dist/display-list/build/storyPrimitives.js +279 -0
- package/dist/display-list/build/strokes.d.ts +19 -0
- package/dist/display-list/build/strokes.js +78 -0
- package/dist/display-list/build/tablePrimitives.d.ts +38 -0
- package/dist/display-list/build/tablePrimitives.js +409 -0
- package/dist/display-list/build/textBoxPrimitives.d.ts +14 -0
- package/dist/display-list/build/textBoxPrimitives.js +129 -0
- package/dist/display-list/build/textDecorations.d.ts +29 -0
- package/dist/display-list/build/textDecorations.js +29 -0
- package/dist/display-list/build/unsupported.d.ts +57 -0
- package/dist/display-list/build/unsupported.js +0 -0
- package/dist/display-list/build/watermarkPrimitives.d.ts +15 -0
- package/dist/display-list/build/watermarkPrimitives.js +128 -0
- package/dist/display-list/dom/renderDisplayListToDom.d.ts +26 -0
- package/dist/display-list/dom/renderDisplayListToDom.js +620 -0
- package/dist/display-list/editor/displayListPagePainter.d.ts +22 -0
- package/dist/display-list/editor/displayListPagePainter.js +63 -0
- package/dist/display-list/editor/pageRenderer.d.ts +24 -0
- package/dist/display-list/editor/pageRenderer.js +36 -0
- package/dist/display-list/primitives.d.ts +95 -0
- package/dist/display-list/primitives.js +127 -0
- package/dist/display-list/types.d.ts +472 -0
- package/dist/display-list/types.js +0 -0
- package/dist/document-operations.d.ts +39 -8
- package/dist/document-operations.js +169 -16
- package/dist/document-stories.d.ts +16 -0
- package/dist/document-stories.js +48 -4
- package/dist/docx/packageParts.d.ts +35 -0
- package/dist/docx/packageParts.js +120 -0
- package/dist/docx/paragraphParser.js +22 -22
- package/dist/docx/paragraphTraversal.js +1 -1
- package/dist/docx/renderedPageBreakNormalization.js +3 -1
- package/dist/docx/revisionIdNormalization.d.ts +13 -0
- package/dist/docx/revisionIdNormalization.js +103 -0
- package/dist/docx/rezip.js +26 -17
- package/dist/docx/selectiveSave.js +2 -2
- package/dist/docx/serializer/commentSerializer.js +6 -1
- package/dist/docx/serializer/paragraphSerializer.js +33 -4
- package/dist/docx/serializer/runSerializer.js +11 -10
- package/dist/docx/serializer/tableSerializer.js +2 -1
- package/dist/docx/server/applyDocxXmlPatchProposal.js +1 -1
- package/dist/docx/server/createBilingualDocx.js +3 -2
- package/dist/docx/streamingXmlParser.d.ts +13 -1
- package/dist/docx/streamingXmlParser.js +49 -11
- package/dist/docx/unzip.d.ts +1 -2
- package/dist/docx/unzip.js +25 -6
- package/dist/docx/xmlParser.d.ts +3 -1
- package/dist/docx/xmlParser.js +33 -27
- package/dist/export-pdf.d.ts +43 -0
- package/dist/export-pdf.js +98 -0
- package/dist/fonts/headlessMeasure.d.ts +76 -0
- package/dist/fonts/headlessMeasure.js +0 -0
- package/dist/fonts/sfnt/parse.d.ts +51 -0
- package/dist/fonts/sfnt/parse.js +525 -0
- package/dist/fonts/sfnt/subset.d.ts +20 -0
- package/dist/fonts/sfnt/subset.js +350 -0
- package/dist/fonts/sfnt/tables.d.ts +88 -0
- package/dist/fonts/sfnt/tables.js +131 -0
- package/dist/fonts/sfnt/woff.d.ts +14 -0
- package/dist/fonts/sfnt/woff.js +163 -0
- package/dist/generated/text_shaper.js +324 -0
- package/dist/generated/text_shaper_bg.wasm +0 -0
- package/dist/headless-layout.d.ts +75 -0
- package/dist/headless-layout.js +350 -0
- package/dist/index.d.ts +9 -6
- package/dist/index.js +6 -3
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.js +2 -0
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +3 -1
- package/dist/layout-bridge/convert/toFlowBlocks.js +2 -0
- package/dist/layout-engine/measure/advanceComposition.d.ts +62 -0
- package/dist/layout-engine/measure/advanceComposition.js +148 -0
- package/dist/layout-engine/measure/cache.d.ts +2 -0
- package/dist/layout-engine/measure/measureContainer.js +13 -0
- package/dist/layout-engine/measure/measureParagraph.js +1 -2
- package/dist/layout-engine/measure/measureTypes.d.ts +12 -0
- package/dist/layout-engine/measure/tableInlinePlacement.d.ts +3 -2
- package/dist/layout-engine/measure/tableInlinePlacement.js +14 -1
- package/dist/layout-engine/tableIndentCompatibility.d.ts +5 -0
- package/dist/layout-engine/tableIndentCompatibility.js +15 -0
- package/dist/layout-engine/types.d.ts +8 -0
- package/dist/layout-painter/renderPage.d.ts +29 -1
- package/dist/layout-painter/renderPage.js +47 -19
- package/dist/layout-painter/renderParagraph.d.ts +21 -2
- package/dist/layout-painter/renderParagraph.js +1 -1
- package/dist/layout-painter/renderTable.js +37 -4
- package/dist/managers/editorShortcuts.d.ts +33 -1
- package/dist/managers/editorShortcuts.js +20 -1
- package/dist/markdown/renderRuns.js +7 -2
- package/dist/markdown/renderTable.js +5 -1
- package/dist/model.d.ts +3 -3
- package/dist/model.js +2 -2
- package/dist/pdf/contentStream.d.ts +73 -0
- package/dist/pdf/contentStream.js +143 -0
- package/dist/pdf/fonts.d.ts +96 -0
- package/dist/pdf/fonts.js +593 -0
- package/dist/pdf/images.d.ts +28 -0
- package/dist/pdf/images.js +439 -0
- package/dist/pdf/objects.d.ts +93 -0
- package/dist/pdf/objects.js +237 -0
- package/dist/pdf/pageSpace.d.ts +43 -0
- package/dist/pdf/pageSpace.js +57 -0
- package/dist/pdf/paint.d.ts +32 -0
- package/dist/pdf/paint.js +442 -0
- package/dist/pdf/writePdf.d.ts +56 -0
- package/dist/pdf/writePdf.js +345 -0
- package/dist/prosemirror/commands/comments.js +91 -6
- package/dist/prosemirror/conversion/fromProseDoc.js +41 -7
- package/dist/prosemirror/conversion/toProseDoc.js +41 -4
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.d.ts +15 -2
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +35 -6
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +2 -2
- package/dist/prosemirror/extensions/features/pasteCleanup.js +4 -3
- package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.d.ts +3 -1
- package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +5 -3
- package/dist/prosemirror/extensions/nodes/RenderedPageBreakExtension.d.ts +7 -1
- package/dist/prosemirror/extensions/nodes/RenderedPageBreakExtension.js +9 -3
- package/dist/prosemirror/extensions/nodes/TableExtension.js +56 -39
- package/dist/prosemirror/extensions/nodes/TextBoxAnchorExtension.d.ts +3 -1
- package/dist/prosemirror/extensions/nodes/TextBoxAnchorExtension.js +5 -3
- package/dist/prosemirror/plugins/suggestionMode.js +1 -0
- package/dist/prosemirror/revisionCarriers.js +19 -2
- package/dist/prosemirror/utils/extractTrackedChanges.d.ts +2 -2
- package/dist/prosemirror/utils/extractTrackedChanges.js +59 -23
- package/dist/prosemirror/validation.js +55 -27
- package/dist/prosemirror/zeroWidthAnchors.d.ts +10 -0
- package/dist/prosemirror/zeroWidthAnchors.js +23 -0
- package/dist/redline.js +12 -79
- package/dist/server.d.ts +3 -3
- package/dist/server.js +2 -2
- package/dist/shaping/placeRun.d.ts +51 -0
- package/dist/shaping/placeRun.js +84 -0
- package/dist/shaping/shaper.d.ts +92 -0
- package/dist/shaping/shaper.js +102 -0
- package/dist/types/block-id.d.ts +18 -2
- package/dist/types/block-id.js +49 -5
- package/dist/types/content.d.ts +2 -2
- package/dist/utils/clipboard.js +4 -3
- package/dist/utils/fontResolver.js +183 -0
- package/dist/utils/htmlComments.d.ts +17 -0
- package/dist/utils/htmlComments.js +22 -0
- package/dist/utils/scriptSegments.d.ts +12 -1
- package/dist/utils/scriptSegments.js +17 -1
- package/dist/version-comparison.d.ts +1 -1
- package/package.json +7 -3
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import { parseDocx } from "./docx/parser.js";
|
|
2
|
+
import { buildHeaderFooterFieldValues } from "./fields/resolveFieldValues.js";
|
|
3
|
+
import { extractEmbeddedFonts } from "./fonts/embeddedFonts.js";
|
|
4
|
+
import { buildFontAlternates } from "./fonts/fontAlternates.js";
|
|
5
|
+
import { buildFootnoteContentMap, collectEndnoteRefs, collectFootnoteRefs, computeNoteDisplayNumbers, remapNoteMarkerText } from "./layout-bridge/convert/footnoteLayout.js";
|
|
6
|
+
import { convertHeaderFooterToContent } from "./layout-bridge/convert/headerFooterLayout.js";
|
|
7
|
+
import { toFlowBlocks } from "./layout-bridge/convert/toFlowBlocks.js";
|
|
8
|
+
import { resolveSectionHeaderFooterRefs } from "./layout-engine/headerFooterRefs.js";
|
|
9
|
+
import { layoutDocument } from "./layout-engine/index.js";
|
|
10
|
+
import { measureBlocks } from "./layout-engine/measure/measureBlocks.js";
|
|
11
|
+
import { getMeasureProvider } from "./layout-engine/measure/measureProvider.js";
|
|
12
|
+
import "./layout-engine/types.js";
|
|
13
|
+
import { getMargins, getPageNumbering, getPageSize } from "./paged-layout/sectionGeometry.js";
|
|
14
|
+
import { toProseDoc } from "./prosemirror/conversion/toProseDoc.js";
|
|
15
|
+
import { needsShaping } from "./shaping/placeRun.js";
|
|
16
|
+
import { getShaper } from "./shaping/shaper.js";
|
|
17
|
+
import { toArrayBuffer } from "./utils/docxInput.js";
|
|
18
|
+
import { getDocumentWatermark } from "./watermark/index.js";
|
|
19
|
+
import { Result, TaggedError } from "better-result";
|
|
20
|
+
import { createHash } from "node:crypto";
|
|
21
|
+
//#region src/headless-layout.ts
|
|
22
|
+
/**
|
|
23
|
+
* Lay a `.docx` package out to pages without a browser.
|
|
24
|
+
*
|
|
25
|
+
* The editor reaches `Layout` through `controller/layoutPipeline.ts`, which
|
|
26
|
+
* needs an `EditorState`, a painter and a live DOM. Export, agents and CI need
|
|
27
|
+
* the same pages with none of that, so this module walks the four pure stages
|
|
28
|
+
* directly: parse, project to ProseMirror, flatten to flow blocks, measure and
|
|
29
|
+
* paginate.
|
|
30
|
+
*
|
|
31
|
+
* ## The other stories
|
|
32
|
+
*
|
|
33
|
+
* Headers, footers and footnotes are separate OOXML stories that the editor
|
|
34
|
+
* lays out as their own ProseMirror views, but neither conversion needs a view:
|
|
35
|
+
* `convertHeaderFooterToContent` and `buildFootnoteContentMap` run the same
|
|
36
|
+
* `toFlowBlocks → measureBlocks` chain the body runs. This entry therefore lays
|
|
37
|
+
* them out too and returns them as {@link HeadlessLayoutResult.furniture}, so
|
|
38
|
+
* an export paints the pages the editor paints rather than bare bodies.
|
|
39
|
+
* Endnotes remain unpaginated and say so through
|
|
40
|
+
* {@link HeadlessLayoutResult.unsupported}.
|
|
41
|
+
*
|
|
42
|
+
* What this entry still does not do is push the body down for a header taller
|
|
43
|
+
* than its margin: the editor's margin clearing lives in the controller, and a
|
|
44
|
+
* document whose header overflows its margin will overlap the body here.
|
|
45
|
+
*
|
|
46
|
+
* ## Measurement
|
|
47
|
+
*
|
|
48
|
+
* Layout is only as good as the installed `MeasureProvider`. The caller
|
|
49
|
+
* installs one (`installHeadlessMeasureProvider` for a server, the canvas
|
|
50
|
+
* backend in a browser); this module refuses to guess, because a silently
|
|
51
|
+
* wrong provider produces a plausible layout that is wrong everywhere.
|
|
52
|
+
*/
|
|
53
|
+
var HeadlessLayoutError = class extends TaggedError("HeadlessLayoutError") {};
|
|
54
|
+
/**
|
|
55
|
+
* Stories this entry still does not lay out, keyed by story so the map is total
|
|
56
|
+
* over the union. `satisfies Record<…>` is what makes it total in both
|
|
57
|
+
* directions: a story left unpaginated but unlisted is a compile error rather
|
|
58
|
+
* than content that vanishes without a report, and a story that starts being
|
|
59
|
+
* laid out cannot keep a stale entry, because removing it narrows the union.
|
|
60
|
+
*
|
|
61
|
+
* Endnotes are the only one left. They are collected at the end of the
|
|
62
|
+
* document rather than reserved per page, so nothing in `Layout` and nothing in
|
|
63
|
+
* the painter's render options places them yet; laying them out is a
|
|
64
|
+
* pagination feature, not a conversion this entry could call.
|
|
65
|
+
*/
|
|
66
|
+
const UNPAGINATED_STORIES = { endnote: {
|
|
67
|
+
story: "endnote",
|
|
68
|
+
detail: "Endnotes are their own story and are not paginated with the body."
|
|
69
|
+
} };
|
|
70
|
+
const hasStory = (document, story) => {
|
|
71
|
+
switch (story) {
|
|
72
|
+
case "endnote": return (document.package.endnotes?.length ?? 0) > 0;
|
|
73
|
+
default: return false;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const readPaintFeatures = (document) => ({
|
|
77
|
+
pageBorders: (document.package.document.sections ?? []).some((section) => Object.values(section.properties.pageBorders ?? {}).some((border) => border !== void 0)),
|
|
78
|
+
watermark: getDocumentWatermark(document) !== void 0
|
|
79
|
+
});
|
|
80
|
+
const buildFlowOptions = (document, pageContentHeight) => {
|
|
81
|
+
const settings = document.package.settings;
|
|
82
|
+
const options = {
|
|
83
|
+
pageContentHeight,
|
|
84
|
+
fontAlternates: buildFontAlternates(document.package.fontTable)
|
|
85
|
+
};
|
|
86
|
+
const theme = document.package.theme;
|
|
87
|
+
if (theme) options.theme = theme;
|
|
88
|
+
if (settings?.defaultTabStop !== void 0) options.defaultTabStopTwips = settings.defaultTabStop;
|
|
89
|
+
if (settings?.lineBreakRules) options.lineBreakRules = settings.lineBreakRules;
|
|
90
|
+
if (settings?.autoHyphenation === true) options.automaticHyphenation = {
|
|
91
|
+
enabled: true,
|
|
92
|
+
...settings.doNotHyphenateCaps === void 0 ? {} : { doNotHyphenateCaps: settings.doNotHyphenateCaps },
|
|
93
|
+
...settings.consecutiveHyphenLimit === void 0 ? {} : { consecutiveLineLimit: settings.consecutiveHyphenLimit },
|
|
94
|
+
...settings.hyphenationZoneTwips === void 0 ? {} : { hyphenationZoneTwips: settings.hyphenationZoneTwips }
|
|
95
|
+
};
|
|
96
|
+
return options;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* `w:mirrorMargins` is parsed into `FolioDocumentSettings` but the shared
|
|
100
|
+
* `Document` model types `settings` as the narrower `DocumentSettings`, so the
|
|
101
|
+
* flag is present at runtime and invisible to the type. The React paged editor
|
|
102
|
+
* narrows the same way; both should stop once the model carries the field.
|
|
103
|
+
*/
|
|
104
|
+
const readsMirrorMargins = (settings) => settings !== void 0 && "mirrorMargins" in settings && settings.mirrorMargins === true;
|
|
105
|
+
const buildBlockLookup = (blocks, measures) => new Map(blocks.flatMap((block, index) => {
|
|
106
|
+
const measure = measures.at(index);
|
|
107
|
+
return measure === void 0 ? [] : [[String(block.id), {
|
|
108
|
+
block,
|
|
109
|
+
measure
|
|
110
|
+
}]];
|
|
111
|
+
}));
|
|
112
|
+
const buildStoryOptions = (document, flowOptions) => ({
|
|
113
|
+
...document.package.styles ? { styles: document.package.styles } : {},
|
|
114
|
+
...flowOptions.theme === void 0 ? {} : { theme: flowOptions.theme },
|
|
115
|
+
...flowOptions.fontAlternates === void 0 ? {} : { fontAlternates: flowOptions.fontAlternates },
|
|
116
|
+
...flowOptions.defaultTabStopTwips === void 0 ? {} : { defaultTabStopTwips: flowOptions.defaultTabStopTwips },
|
|
117
|
+
...flowOptions.lineBreakRules === void 0 ? {} : { lineBreakRules: flowOptions.lineBreakRules },
|
|
118
|
+
...flowOptions.automaticHyphenation === void 0 ? {} : { automaticHyphenation: flowOptions.automaticHyphenation }
|
|
119
|
+
});
|
|
120
|
+
const convertStories = ({ parts, contentWidth, metrics, storyOptions, pageCount, now }) => {
|
|
121
|
+
const contentByRId = /* @__PURE__ */ new Map();
|
|
122
|
+
for (const [rId, part] of parts ?? []) {
|
|
123
|
+
const content = convertHeaderFooterToContent(part, contentWidth, metrics, {
|
|
124
|
+
...storyOptions,
|
|
125
|
+
measureBlocks: (blocks, width) => measureBlocks(blocks, width, void 0, void 0, buildHeaderFooterFieldValues(blocks, pageCount, now)),
|
|
126
|
+
rId
|
|
127
|
+
});
|
|
128
|
+
if (content) contentByRId.set(rId, content);
|
|
129
|
+
}
|
|
130
|
+
return contentByRId;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Watermarks by the header part that carries them. Word puts the shape in a
|
|
134
|
+
* header, so a document with `w:titlePg` or even/odd headers can carry a
|
|
135
|
+
* different watermark per page; the per-rId map is what lets the builder pick
|
|
136
|
+
* the right one instead of painting one header's watermark behind every page.
|
|
137
|
+
*/
|
|
138
|
+
const collectWatermarks = (headers) => {
|
|
139
|
+
const byRId = /* @__PURE__ */ new Map();
|
|
140
|
+
for (const [rId, header] of headers ?? []) if (header.watermark) byRId.set(rId, header.watermark);
|
|
141
|
+
return byRId;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* A picture watermark's bytes, as a `data:` URL.
|
|
145
|
+
*
|
|
146
|
+
* Resolved through `imageTarget`, the package path the relationship pointed at
|
|
147
|
+
* when the watermark was parsed: relationship ids are scoped per header part
|
|
148
|
+
* and repeat across parts, so the path is the only unambiguous handle. A linked
|
|
149
|
+
* (external) image resolves to nothing, and the builder reports it.
|
|
150
|
+
*/
|
|
151
|
+
const resolveWatermarkImageSrc = (document, watermark) => {
|
|
152
|
+
if (watermark?.kind !== "picture" || watermark.imageTargetExternal === true) return;
|
|
153
|
+
const target = watermark.imageTarget;
|
|
154
|
+
return target === void 0 ? void 0 : document.package.media?.get(target)?.dataUrl;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* The scope every extracted face's family carries here.
|
|
158
|
+
*
|
|
159
|
+
* `getEmbeddedFontFaces` defaults it to a fresh random id, which would make two
|
|
160
|
+
* layouts of one package differ in a field the caller compares. Deriving it
|
|
161
|
+
* from the package's own bytes keeps two layouts of one package identical
|
|
162
|
+
* while keeping two *different* packages apart: a DOM backend registers each
|
|
163
|
+
* face under this name, so a fixed scope would let two documents on one page
|
|
164
|
+
* define competing faces under one name and leave which one wins to font
|
|
165
|
+
* matching.
|
|
166
|
+
*/
|
|
167
|
+
const embeddedFontNonce = (source) => createHash("sha256").update(new Uint8Array(source)).digest("hex").slice(0, NONCE_LENGTH);
|
|
168
|
+
/** Enough of the digest to separate packages without bloating every family. */
|
|
169
|
+
const NONCE_LENGTH = 12;
|
|
170
|
+
/** Whether `fontTable.xml` declares any embedded face at all. */
|
|
171
|
+
const declaresEmbeddedFonts = (document) => (document.package.fontTable?.fonts ?? []).some((font) => font.embedRegular !== void 0 || font.embedBold !== void 0 || font.embedItalic !== void 0 || font.embedBoldItalic !== void 0);
|
|
172
|
+
/**
|
|
173
|
+
* Parse and paginate a package. Fails rather than defaulting when no
|
|
174
|
+
* measurement backend is installed: a layout measured by the wrong provider
|
|
175
|
+
* is wrong in a way no downstream check catches.
|
|
176
|
+
*/
|
|
177
|
+
/**
|
|
178
|
+
* Whether any text in the package needs shaping.
|
|
179
|
+
*
|
|
180
|
+
* Every story a page paints, body, headers, footers and notes alike, is built
|
|
181
|
+
* from the same content model, so one walk over the package answers for all of
|
|
182
|
+
* them. The answer decides whether the shaper is fetched at all: a document in
|
|
183
|
+
* Latin, Cyrillic or Greek must not pay for an artifact it has no use for.
|
|
184
|
+
*/
|
|
185
|
+
const packageNeedsShaping = (value) => {
|
|
186
|
+
if (Array.isArray(value)) return value.some(packageNeedsShaping);
|
|
187
|
+
if (typeof value !== "object" || value === null) return false;
|
|
188
|
+
const entries = Object.entries(value);
|
|
189
|
+
const text = entries.find(([key]) => key === "text")?.[1];
|
|
190
|
+
if (entries.find(([key]) => key === "type")?.[1] === "text" && typeof text === "string" && needsShaping(text)) return true;
|
|
191
|
+
return entries.some(([, child]) => packageNeedsShaping(child));
|
|
192
|
+
};
|
|
193
|
+
const layoutDocxHeadless = async (input, options = {}) => {
|
|
194
|
+
const providerCheck = Result.try(() => getMeasureProvider().getFontMetrics({ fontSize: 11 }));
|
|
195
|
+
if (providerCheck.isErr()) return Result.err(new HeadlessLayoutError({
|
|
196
|
+
message: "No MeasureProvider is installed. Install one (installHeadlessMeasureProvider on a server, installCanvasMeasureProvider in a browser) before laying out.",
|
|
197
|
+
cause: providerCheck.error
|
|
198
|
+
}));
|
|
199
|
+
const parsed = await Result.tryPromise({
|
|
200
|
+
try: () => parseDocx(input, { preloadFonts: false }),
|
|
201
|
+
catch: (cause) => new HeadlessLayoutError({
|
|
202
|
+
message: "The package could not be parsed.",
|
|
203
|
+
cause
|
|
204
|
+
})
|
|
205
|
+
});
|
|
206
|
+
if (parsed.isErr()) return Result.err(parsed.error);
|
|
207
|
+
const document = parsed.value;
|
|
208
|
+
const projected = Result.try(() => toProseDoc(document, {
|
|
209
|
+
...document.package.styles ? { styles: document.package.styles } : {},
|
|
210
|
+
...document.package.theme ? { theme: document.package.theme } : {}
|
|
211
|
+
}));
|
|
212
|
+
if (projected.isErr()) return Result.err(new HeadlessLayoutError({
|
|
213
|
+
message: "The document could not be projected to the editable model.",
|
|
214
|
+
cause: projected.error
|
|
215
|
+
}));
|
|
216
|
+
if (packageNeedsShaping(document.package)) {
|
|
217
|
+
const loaded = await Result.tryPromise({
|
|
218
|
+
try: () => getShaper(),
|
|
219
|
+
catch: (cause) => new HeadlessLayoutError({
|
|
220
|
+
message: "The text shaper could not be loaded, and this document needs one.",
|
|
221
|
+
cause
|
|
222
|
+
})
|
|
223
|
+
});
|
|
224
|
+
if (loaded.isErr()) return Result.err(loaded.error);
|
|
225
|
+
}
|
|
226
|
+
const sections = document.package.document.sections ?? [];
|
|
227
|
+
const firstSection = sections.at(0)?.properties;
|
|
228
|
+
const finalSection = sections.at(-1)?.properties ?? firstSection;
|
|
229
|
+
const pageSize = getPageSize(firstSection);
|
|
230
|
+
const margins = getMargins(firstSection);
|
|
231
|
+
const contentWidth = pageSize.w - margins.left - margins.right;
|
|
232
|
+
const pageContentHeight = pageSize.h - margins.top - margins.bottom;
|
|
233
|
+
const flowOptions = buildFlowOptions(document, pageContentHeight);
|
|
234
|
+
const storyOptions = buildStoryOptions(document, flowOptions);
|
|
235
|
+
const laidOut = Result.try(() => {
|
|
236
|
+
const authored = toFlowBlocks(projected.value, flowOptions);
|
|
237
|
+
const footnotes = document.package.footnotes ?? [];
|
|
238
|
+
const endnotes = document.package.endnotes ?? [];
|
|
239
|
+
const footnoteRefs = collectFootnoteRefs(authored);
|
|
240
|
+
const blocks = remapNoteMarkerText(authored, {
|
|
241
|
+
footnoteNumbers: computeNoteDisplayNumbers(footnotes, footnoteRefs.map((ref) => ref.footnoteId)),
|
|
242
|
+
endnoteNumbers: computeNoteDisplayNumbers(endnotes, collectEndnoteRefs(authored).map((ref) => ref.endnoteId))
|
|
243
|
+
});
|
|
244
|
+
const measures = measureBlocks(blocks, contentWidth);
|
|
245
|
+
const footnoteContentById = footnoteRefs.length === 0 ? void 0 : buildFootnoteContentMap(footnotes, footnoteRefs, contentWidth, {
|
|
246
|
+
...storyOptions,
|
|
247
|
+
measureBlocks
|
|
248
|
+
});
|
|
249
|
+
const footnoteHeightById = /* @__PURE__ */ new Map();
|
|
250
|
+
for (const [id, content] of footnoteContentById ?? []) footnoteHeightById.set(id, content.height + 0);
|
|
251
|
+
const sectionHeaderFooterRefs = resolveSectionHeaderFooterRefs(document);
|
|
252
|
+
const finalPageSize = getPageSize(finalSection);
|
|
253
|
+
const finalMargins = getMargins(finalSection);
|
|
254
|
+
return {
|
|
255
|
+
layout: layoutDocument(blocks, measures, {
|
|
256
|
+
pageSize,
|
|
257
|
+
margins,
|
|
258
|
+
pageNumbering: getPageNumbering(firstSection),
|
|
259
|
+
finalPageSize,
|
|
260
|
+
finalMargins,
|
|
261
|
+
finalPageNumbering: getPageNumbering(finalSection),
|
|
262
|
+
pageGap: options.pageGap ?? 0,
|
|
263
|
+
titlePage: firstSection?.titlePg === true,
|
|
264
|
+
evenAndOddHeaders: document.package.settings?.evenAndOddHeaders === true,
|
|
265
|
+
mirrorMargins: readsMirrorMargins(document.package.settings),
|
|
266
|
+
...footnoteHeightById.size === 0 ? {} : { footnoteHeightById },
|
|
267
|
+
...sectionHeaderFooterRefs === void 0 ? {} : { sectionHeaderFooterRefs }
|
|
268
|
+
}),
|
|
269
|
+
blockLookup: buildBlockLookup(blocks, measures),
|
|
270
|
+
footnoteContentById
|
|
271
|
+
};
|
|
272
|
+
});
|
|
273
|
+
if (laidOut.isErr()) return Result.err(new HeadlessLayoutError({
|
|
274
|
+
message: "The document could not be paginated.",
|
|
275
|
+
cause: laidOut.error
|
|
276
|
+
}));
|
|
277
|
+
const { layout, blockLookup, footnoteContentById } = laidOut.value;
|
|
278
|
+
const stories = Result.try(() => {
|
|
279
|
+
const pageCount = layout.pages.length;
|
|
280
|
+
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
281
|
+
const shared = {
|
|
282
|
+
contentWidth,
|
|
283
|
+
storyOptions,
|
|
284
|
+
pageCount,
|
|
285
|
+
now
|
|
286
|
+
};
|
|
287
|
+
return {
|
|
288
|
+
headerContentByRId: convertStories({
|
|
289
|
+
...shared,
|
|
290
|
+
parts: document.package.headers,
|
|
291
|
+
metrics: {
|
|
292
|
+
section: "header",
|
|
293
|
+
pageSize,
|
|
294
|
+
margins
|
|
295
|
+
}
|
|
296
|
+
}),
|
|
297
|
+
footerContentByRId: convertStories({
|
|
298
|
+
...shared,
|
|
299
|
+
parts: document.package.footers,
|
|
300
|
+
metrics: {
|
|
301
|
+
section: "footer",
|
|
302
|
+
pageSize,
|
|
303
|
+
margins
|
|
304
|
+
}
|
|
305
|
+
})
|
|
306
|
+
};
|
|
307
|
+
});
|
|
308
|
+
if (stories.isErr()) return Result.err(new HeadlessLayoutError({
|
|
309
|
+
message: "The header and footer stories could not be laid out.",
|
|
310
|
+
cause: stories.error
|
|
311
|
+
}));
|
|
312
|
+
const embeddedFonts = declaresEmbeddedFonts(document) ? await Result.tryPromise({
|
|
313
|
+
try: async () => {
|
|
314
|
+
const source = await toArrayBuffer(input);
|
|
315
|
+
return extractEmbeddedFonts(source, embeddedFontNonce(source));
|
|
316
|
+
},
|
|
317
|
+
catch: (cause) => new HeadlessLayoutError({
|
|
318
|
+
message: "The package's embedded fonts could not be extracted.",
|
|
319
|
+
cause
|
|
320
|
+
})
|
|
321
|
+
}) : Result.ok([]);
|
|
322
|
+
if (embeddedFonts.isErr()) return Result.err(embeddedFonts.error);
|
|
323
|
+
const watermark = getDocumentWatermark(document);
|
|
324
|
+
const watermarksByHeader = collectWatermarks(document.package.headers);
|
|
325
|
+
const pictureSources = new Set([watermark, ...watermarksByHeader.values()].filter((candidate) => candidate !== void 0).map((candidate) => resolveWatermarkImageSrc(document, candidate)));
|
|
326
|
+
const watermarkImageSrc = pictureSources.size === 1 ? [...pictureSources].at(0) : void 0;
|
|
327
|
+
const pageBorders = firstSection?.pageBorders;
|
|
328
|
+
return Result.ok({
|
|
329
|
+
layout,
|
|
330
|
+
blockLookup,
|
|
331
|
+
document,
|
|
332
|
+
proseDoc: projected.value,
|
|
333
|
+
documentFeatures: readPaintFeatures(document),
|
|
334
|
+
furniture: {
|
|
335
|
+
...pageBorders === void 0 ? {} : { pageBorders },
|
|
336
|
+
...document.package.theme === void 0 ? {} : { theme: document.package.theme },
|
|
337
|
+
...watermark === void 0 ? {} : { watermark },
|
|
338
|
+
watermarkByHeaderRId: watermarksByHeader,
|
|
339
|
+
...watermarkImageSrc === void 0 ? {} : { watermarkImageSrc },
|
|
340
|
+
headerContentByRId: stories.value.headerContentByRId,
|
|
341
|
+
footerContentByRId: stories.value.footerContentByRId,
|
|
342
|
+
titlePg: firstSection?.titlePg === true,
|
|
343
|
+
...footnoteContentById === void 0 ? {} : { footnoteContentById }
|
|
344
|
+
},
|
|
345
|
+
embeddedFonts: embeddedFonts.value,
|
|
346
|
+
unsupported: Object.values(UNPAGINATED_STORIES).filter((gap) => hasStory(document, gap.story))
|
|
347
|
+
});
|
|
348
|
+
};
|
|
349
|
+
//#endregion
|
|
350
|
+
export { HeadlessLayoutError, layoutDocxHeadless };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAISignatureParty } from "./ai-edits/types.js";
|
|
2
|
-
import {
|
|
1
|
+
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIBlockTableLocation, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAISignatureParty } from "./ai-edits/types.js";
|
|
2
|
+
import { WORD_DIFF_GRANULARITIES, WordDiffGranularity, WordDiffNormalization, WordDiffOptions, WordDiffSegment, diffWordSegments } from "./ai-edits/word-diff.js";
|
|
3
|
+
import { FolioAIEditApplyOutcome, FolioRevisionStamp, FolioWordDiffOptions, applyFolioAIEditOperations } from "./ai-edits/apply.js";
|
|
3
4
|
import { document_d_exports } from "./types/document.js";
|
|
4
|
-
import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
|
|
5
|
-
import { createFolioAIEditSnapshot, hashFolioAIBlockText, normalizeFolioAIBlockText } from "./ai-edits/snapshot.js";
|
|
5
|
+
import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
|
|
6
|
+
import { createFolioAIEditSnapshot, hashFolioAIBlockText, isFolioAIContentBlock, normalizeFolioAIBlockText } from "./ai-edits/snapshot.js";
|
|
6
7
|
import { DeriveBlockIdInput, FolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "./types/block-id.js";
|
|
7
|
-
import { WordDiffSegment, diffWordSegments } from "./ai-edits/word-diff.js";
|
|
8
8
|
import "./ai-edits/index.js";
|
|
9
9
|
import { AIBarStatus, AIChatMode, AICitation, AICitationSource, AIGenerateInput, AISuggestion, AISuggestionApplyMode, AISuggestionPreset, AISuggestionSeverity, AISuggestionStatus, DEFAULT_AI_SUGGESTION_PRESETS } from "./ai-suggestions/types.js";
|
|
10
10
|
import { ApplyResult, applySuggestions } from "./ai-suggestions/apply.js";
|
|
11
11
|
import { ResolvedAnchor, isSuggestionStale, resolveSuggestionAnchor } from "./ai-suggestions/conflict.js";
|
|
12
12
|
import { PositionalText, buildPositionalText } from "./ai-suggestions/text-positions.js";
|
|
13
|
+
import { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareVerification, CompareVerificationCause, CompareVerificationFailure, CompareVerificationInvariant } from "./compare/verification.js";
|
|
14
|
+
import { COMPARE_UNSUPPORTED_REASONS, CompareChange, CompareChangeLocation, CompareDocxApplyError, CompareDocxError, CompareDocxOperationLimitError, CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, CompareFormatRange, CompareResult, CompareUnsupportedPart, CompareUnsupportedReason, InvalidCompareDocxOptionsError } from "./compare/types.js";
|
|
15
|
+
import { MAX_COMPARE_OPERATIONS, compareDocx } from "./compare/compare.js";
|
|
13
16
|
import { DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DocumentPreset, DocumentStyleSet } from "./style-sets/types.js";
|
|
14
17
|
import { CreateEmptyDocumentOptions, createEmptyDocument } from "./utils/createDocument.js";
|
|
15
18
|
import { mergeDocumentContent } from "./utils/mergeDocumentContent.js";
|
|
@@ -35,4 +38,4 @@ import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled
|
|
|
35
38
|
import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
|
|
36
39
|
type Document = document_d_exports.Document;
|
|
37
40
|
type DocxConformanceClass = document_d_exports.DocxConformanceClass;
|
|
38
|
-
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidFolioDocumentOperationBatchError, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
41
|
+
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, CompareDocxApplyError, type CompareDocxError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFormatRange, type CompareResult, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { applyFolioAIEditOperations } from "./ai-edits/apply.js";
|
|
2
|
-
import { createFolioAIEditSnapshot, hashFolioAIBlockText, normalizeFolioAIBlockText } from "./ai-edits/snapshot.js";
|
|
3
|
-
import { diffWordSegments } from "./ai-edits/word-diff.js";
|
|
2
|
+
import { createFolioAIEditSnapshot, hashFolioAIBlockText, isFolioAIContentBlock, normalizeFolioAIBlockText } from "./ai-edits/snapshot.js";
|
|
3
|
+
import { WORD_DIFF_GRANULARITIES, diffWordSegments } from "./ai-edits/word-diff.js";
|
|
4
4
|
import { applySuggestions } from "./ai-suggestions/apply.js";
|
|
5
5
|
import { isSuggestionStale, resolveSuggestionAnchor } from "./ai-suggestions/conflict.js";
|
|
6
6
|
import { buildPositionalText } from "./ai-suggestions/text-positions.js";
|
|
7
7
|
import { DEFAULT_AI_SUGGESTION_PRESETS } from "./ai-suggestions/types.js";
|
|
8
|
+
import { MAX_COMPARE_OPERATIONS, compareDocx } from "./compare/compare.js";
|
|
9
|
+
import { COMPARE_UNSUPPORTED_REASONS, CompareDocxApplyError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, InvalidCompareDocxOptionsError } from "./compare/types.js";
|
|
10
|
+
import { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS } from "./compare/verification.js";
|
|
8
11
|
import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
|
|
9
12
|
import { inspectDocxCompatibility } from "./docx/compatibility.js";
|
|
10
13
|
import { createDocx } from "./docx/rezip.js";
|
|
@@ -28,4 +31,4 @@ import { createEmptyDocument } from "./utils/createDocument.js";
|
|
|
28
31
|
import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "./utils/fontResolver.js";
|
|
29
32
|
import { mergeDocumentContent } from "./utils/mergeDocumentContent.js";
|
|
30
33
|
import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
|
|
31
|
-
export { DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
34
|
+
export { COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
@@ -12,6 +12,7 @@ type ConvertFootnoteOptions = {
|
|
|
12
12
|
defaultTabStopTwips?: number;
|
|
13
13
|
lineBreakRules?: ToFlowBlocksOptions["lineBreakRules"];
|
|
14
14
|
justificationCompatibility?: ToFlowBlocksOptions["justificationCompatibility"];
|
|
15
|
+
tableIndentCompatibility?: ToFlowBlocksOptions["tableIndentCompatibility"];
|
|
15
16
|
automaticHyphenation?: ToFlowBlocksOptions["automaticHyphenation"];
|
|
16
17
|
};
|
|
17
18
|
/**
|
|
@@ -200,6 +200,7 @@ function convertFootnoteToContent(footnote, displayNumber, contentWidth, options
|
|
|
200
200
|
if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
|
|
201
201
|
if (options.lineBreakRules) flowOptions.lineBreakRules = options.lineBreakRules;
|
|
202
202
|
if (options.justificationCompatibility) flowOptions.justificationCompatibility = options.justificationCompatibility;
|
|
203
|
+
if (options.tableIndentCompatibility) flowOptions.tableIndentCompatibility = options.tableIndentCompatibility;
|
|
203
204
|
if (options.automaticHyphenation) flowOptions.automaticHyphenation = options.automaticHyphenation;
|
|
204
205
|
const blocks = applyFootnotePresentation(toFlowBlocks(pmDoc, flowOptions), displayNumber);
|
|
205
206
|
const measures = options.measureBlocks ? options.measureBlocks(blocks, contentWidth) : measureFootnoteBlocks(blocks, contentWidth);
|
|
@@ -47,6 +47,7 @@ type ConvertHeaderFooterOptions = {
|
|
|
47
47
|
defaultTabStopTwips?: number;
|
|
48
48
|
lineBreakRules?: ToFlowBlocksOptions["lineBreakRules"];
|
|
49
49
|
justificationCompatibility?: ToFlowBlocksOptions["justificationCompatibility"];
|
|
50
|
+
tableIndentCompatibility?: ToFlowBlocksOptions["tableIndentCompatibility"];
|
|
50
51
|
automaticHyphenation?: ToFlowBlocksOptions["automaticHyphenation"];
|
|
51
52
|
/**
|
|
52
53
|
* Relationship id of the source HF part. Stamped onto the returned
|
|
@@ -337,6 +337,7 @@ function convertHeaderFooterToContent(headerFooter, contentWidth, metrics, optio
|
|
|
337
337
|
if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
|
|
338
338
|
if (options.lineBreakRules) flowOptions.lineBreakRules = options.lineBreakRules;
|
|
339
339
|
if (options.justificationCompatibility) flowOptions.justificationCompatibility = options.justificationCompatibility;
|
|
340
|
+
if (options.tableIndentCompatibility) flowOptions.tableIndentCompatibility = options.tableIndentCompatibility;
|
|
340
341
|
if (options.automaticHyphenation) flowOptions.automaticHyphenation = options.automaticHyphenation;
|
|
341
342
|
return finalizeHeaderFooterContent(toFlowBlocks(pmDoc, flowOptions), contentWidth, metrics, options);
|
|
342
343
|
}
|
|
@@ -359,6 +360,7 @@ function convertHeaderFooterPmDocToContent(pmDoc, contentWidth, metrics, options
|
|
|
359
360
|
if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
|
|
360
361
|
if (options.lineBreakRules) flowOptions.lineBreakRules = options.lineBreakRules;
|
|
361
362
|
if (options.justificationCompatibility) flowOptions.justificationCompatibility = options.justificationCompatibility;
|
|
363
|
+
if (options.tableIndentCompatibility) flowOptions.tableIndentCompatibility = options.tableIndentCompatibility;
|
|
362
364
|
if (options.automaticHyphenation) flowOptions.automaticHyphenation = options.automaticHyphenation;
|
|
363
365
|
return finalizeHeaderFooterContent(toFlowBlocks(pmDoc, flowOptions), contentWidth, metrics, options);
|
|
364
366
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { document_d_exports } from "../../types/document.js";
|
|
2
|
-
import { BorderStyle, FlowBlock, ParagraphAttrs } from "../../layout-engine/types.js";
|
|
2
|
+
import { BorderStyle, FlowBlock, ParagraphAttrs, TableBlock } from "../../layout-engine/types.js";
|
|
3
3
|
import { FontAlternates } from "../../fonts/fontAlternates.js";
|
|
4
4
|
import { formatCounter, resolveListTemplate } from "../../prosemirror/listMarker.js";
|
|
5
5
|
import { Node } from "prosemirror-model";
|
|
@@ -58,6 +58,8 @@ type ToFlowBlocksOptions = {
|
|
|
58
58
|
};
|
|
59
59
|
/** Document-generation policy for justified line fitting. */
|
|
60
60
|
justificationCompatibility?: NonNullable<ParagraphAttrs["justificationCompatibility"]>;
|
|
61
|
+
/** Document-generation policy for where `w:tblInd` is measured from. */
|
|
62
|
+
tableIndentCompatibility?: NonNullable<TableBlock["indentCompatibility"]>;
|
|
61
63
|
/** Document-wide automatic hyphenation policy. */
|
|
62
64
|
automaticHyphenation?: NonNullable<ParagraphAttrs["automaticHyphenation"]>;
|
|
63
65
|
/** Line pitch for the final body section, whose properties live outside the PM body. */
|
|
@@ -1148,6 +1148,7 @@ function convertTable(node, startPos, options) {
|
|
|
1148
1148
|
const originalFormatting = attrs._originalFormatting;
|
|
1149
1149
|
const effectiveIndent = attrs._resolvedIndent ?? originalFormatting?.indent;
|
|
1150
1150
|
const indentPx = effectiveIndent?.value !== void 0 && effectiveIndent?.type === "dxa" ? twipsToPixels(effectiveIndent.value) : void 0;
|
|
1151
|
+
const dropsAuthoredIndent = effectiveIndent?.value !== void 0 && indentPx === void 0;
|
|
1151
1152
|
const floating = attrs.floating;
|
|
1152
1153
|
let floatingPx;
|
|
1153
1154
|
if (floating) {
|
|
@@ -1177,6 +1178,7 @@ function convertTable(node, startPos, options) {
|
|
|
1177
1178
|
if (originalFormatting?.layout !== void 0) tableBlock.layout = originalFormatting.layout;
|
|
1178
1179
|
if (justification) tableBlock.justification = justification;
|
|
1179
1180
|
if (indentPx !== void 0) tableBlock.indent = indentPx;
|
|
1181
|
+
if (options.tableIndentCompatibility && !dropsAuthoredIndent) tableBlock.indentCompatibility = options.tableIndentCompatibility;
|
|
1180
1182
|
if (floatingPx) tableBlock.floating = floatingPx;
|
|
1181
1183
|
if (attrs._resolvedBidi ?? originalFormatting?.bidi) tableBlock.bidi = true;
|
|
1182
1184
|
return tableBlock;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { FontMetrics, FontStyle, RunMeasurement } from "./measureTypes.js";
|
|
2
|
+
import { ScriptClass } from "../../utils/scriptSegments.js";
|
|
3
|
+
//#region src/layout-engine/measure/advanceComposition.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Raw advance of `text` in `style`, with no letter spacing, no horizontal
|
|
6
|
+
* scale and no text transform applied: those are this module's job.
|
|
7
|
+
*/
|
|
8
|
+
type GlyphAdvanceFn = (text: string, style: FontStyle) => number;
|
|
9
|
+
/**
|
|
10
|
+
* Advances for a whole string, one per code point, from a backend that shapes.
|
|
11
|
+
*
|
|
12
|
+
* Separate from {@link GlyphAdvanceFn} because a shaped run has no per-code-point
|
|
13
|
+
* width to ask for: two letters that ligate have one advance between them, and
|
|
14
|
+
* a letter's width depends on the neighbours it joins to. A backend that can
|
|
15
|
+
* answer for the string as a whole supplies this; one that cannot leaves it out
|
|
16
|
+
* and every code point is measured alone.
|
|
17
|
+
*/
|
|
18
|
+
type GlyphAdvancesFn = (text: string, style: FontStyle) => readonly number[];
|
|
19
|
+
declare const applyMeasurementTextTransform: (text: string, style: FontStyle) => string;
|
|
20
|
+
/** Resolve the independent font/style slot a script segment selects. */
|
|
21
|
+
declare const scriptStyle: (style: FontStyle, script: ScriptClass) => FontStyle;
|
|
22
|
+
/**
|
|
23
|
+
* Keep only the properties that change a glyph's advance, so a per-script
|
|
24
|
+
* segment takes the single-font path: letter spacing and horizontal scale are
|
|
25
|
+
* applied once over the whole string, never per segment.
|
|
26
|
+
*/
|
|
27
|
+
declare const glyphAdvanceStyle: (style: FontStyle) => FontStyle;
|
|
28
|
+
type ComposeTextWidthOptions = {
|
|
29
|
+
readonly text: string;
|
|
30
|
+
readonly style: FontStyle;
|
|
31
|
+
readonly advanceOf: GlyphAdvanceFn;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Width of a string: the advance width used for line breaking, never the
|
|
35
|
+
* painted (ink) extent, which includes overhang a break decision must ignore.
|
|
36
|
+
*/
|
|
37
|
+
declare const composeTextWidth: ({ text, style: source, advanceOf }: ComposeTextWidthOptions) => number;
|
|
38
|
+
type ComposeRunMeasurementOptions = {
|
|
39
|
+
readonly text: string;
|
|
40
|
+
readonly style: FontStyle;
|
|
41
|
+
readonly metrics: FontMetrics;
|
|
42
|
+
readonly advanceOf: GlyphAdvanceFn;
|
|
43
|
+
/**
|
|
44
|
+
* Used for the stretches of text whose glyphs shaping chooses. Absent when
|
|
45
|
+
* the backend has no shaper, which leaves those stretches measured one code
|
|
46
|
+
* point at a time: visibly wrong for the script, and the reason a document
|
|
47
|
+
* that contains one resolves a shaper before it is laid out.
|
|
48
|
+
*/
|
|
49
|
+
readonly advancesOf?: GlyphAdvancesFn | undefined;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Per-code-point advances for click positioning.
|
|
53
|
+
*
|
|
54
|
+
* Iterates whole code points so an astral ideograph takes the East-Asian font
|
|
55
|
+
* and gets a real width, while `charWidths` stays one entry per UTF-16 unit
|
|
56
|
+
* (the trailing unit of a surrogate pair carries 0) so it keeps aligning with
|
|
57
|
+
* ProseMirror offsets. The total differs from {@link composeTextWidth} for a
|
|
58
|
+
* kerned or ligature-forming run, because each code point is measured alone.
|
|
59
|
+
*/
|
|
60
|
+
declare const composeRunMeasurement: ({ text, style: source, metrics, advanceOf, advancesOf }: ComposeRunMeasurementOptions) => RunMeasurement;
|
|
61
|
+
//#endregion
|
|
62
|
+
export { GlyphAdvanceFn, GlyphAdvancesFn, applyMeasurementTextTransform, composeRunMeasurement, composeTextWidth, glyphAdvanceStyle, scriptStyle };
|