@stll/folio-core 0.54.2 → 0.56.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/apply.js +185 -33
- package/dist/ai-edits/headless.js +3 -2
- package/dist/ai-edits/types.d.ts +7 -1
- package/dist/compare/compare.js +1 -0
- package/dist/compare/content-types.d.ts +3 -15
- package/dist/compare/reproducible-package.d.ts +0 -17
- package/dist/compare/reproducible-package.js +12 -18
- package/dist/controller/canonicalClipboard.d.ts +23 -0
- package/dist/controller/canonicalClipboard.js +476 -0
- package/dist/controller/canonicalClipboardResources.d.ts +21 -0
- package/dist/controller/canonicalClipboardResources.js +382 -0
- package/dist/controller/canonicalComposition.d.ts +53 -0
- package/dist/controller/canonicalComposition.js +296 -0
- package/dist/controller/canonicalInlineProjection.d.ts +113 -0
- package/dist/controller/canonicalInlineProjection.js +393 -0
- package/dist/controller/canonicalInput.d.ts +54 -0
- package/dist/controller/canonicalInput.js +377 -0
- package/dist/controller/canonicalInputTimer.d.ts +7 -0
- package/dist/controller/canonicalInputTimer.js +11 -0
- package/dist/controller/canonicalOperations.d.ts +22 -0
- package/dist/controller/canonicalOperations.js +85 -0
- package/dist/controller/canonicalPublicOperations.d.ts +48 -0
- package/dist/controller/canonicalPublicOperations.js +556 -0
- package/dist/controller/canonicalReview.d.ts +12 -0
- package/dist/controller/canonicalReview.js +19 -0
- package/dist/controller/canonicalSession.d.ts +167 -0
- package/dist/controller/canonicalSession.js +1186 -0
- package/dist/controller/canonicalStoryEditor.d.ts +36 -0
- package/dist/controller/canonicalStoryEditor.js +87 -0
- package/dist/controller/canonicalStructure.d.ts +16 -0
- package/dist/controller/canonicalStructure.js +322 -0
- package/dist/controller/canonicalTocSelection.d.ts +11 -0
- package/dist/controller/canonicalTocSelection.js +43 -0
- package/dist/controller/folioEditor.d.ts +3 -10
- package/dist/controller/folioEditor.js +14 -4
- package/dist/controller/headerFooterEditorManager.d.ts +5 -0
- package/dist/controller/headerFooterEditorManager.js +72 -3
- package/dist/controller/hiddenEditorApi.d.ts +45 -0
- package/dist/controller/hiddenEditorApi.js +29 -8
- package/dist/controller/hiddenEditorManager.d.ts +13 -2
- package/dist/controller/hiddenEditorManager.js +639 -31
- package/dist/controller/layoutPipeline.d.ts +1 -1
- package/dist/controller/layoutPipeline.js +2 -0
- package/dist/controller/noteEditorManager.d.ts +5 -0
- package/dist/controller/noteEditorManager.js +114 -15
- package/dist/document-operations.d.ts +8 -1
- package/dist/document-operations.js +6 -4
- package/dist/docx/attributeRemainder.js +1 -0
- package/dist/docx/blockPlainText.d.ts +1 -1
- package/dist/docx/blockPlainText.js +11 -3
- package/dist/docx/canonicalResourceSave.d.ts +16 -0
- package/dist/docx/canonicalResourceSave.js +27 -0
- package/dist/docx/canonicalSave.d.ts +29 -0
- package/dist/docx/canonicalSave.js +101 -0
- package/dist/docx/canonicalSessionInput.d.ts +11 -0
- package/dist/docx/canonicalSessionInput.js +27 -0
- package/dist/docx/canonicalStoryRepack.d.ts +10 -0
- package/dist/docx/canonicalStoryRepack.js +74 -0
- package/dist/docx/contentTypeRegistry.d.ts +8 -0
- package/dist/docx/contentTypeRegistry.js +64 -0
- package/dist/docx/documentParser.d.ts +1 -13
- package/dist/docx/documentParser.js +1 -47
- package/dist/docx/ensureParaIds.d.ts +7 -1
- package/dist/docx/ensureParaIds.js +173 -215
- package/dist/docx/foldedListNumberFields.d.ts +85 -0
- package/dist/docx/foldedListNumberFields.js +267 -0
- package/dist/docx/footnoteParser.d.ts +1 -11
- package/dist/docx/footnoteParser.js +1 -16
- package/dist/docx/headerFooterParser.d.ts +1 -9
- package/dist/docx/headerFooterParser.js +1 -12
- package/dist/docx/headerFooterVerbatim.d.ts +39 -1
- package/dist/docx/headerFooterVerbatim.js +173 -2
- package/dist/docx/imageParser.d.ts +13 -1
- package/dist/docx/imageParser.js +20 -11
- package/dist/docx/metadataPrivacy.js +6 -1
- package/dist/docx/noteIds.d.ts +5 -0
- package/dist/docx/noteIds.js +6 -2
- package/dist/docx/noteReferenceMark.d.ts +3 -1
- package/dist/docx/noteReferenceMark.js +15 -14
- package/dist/docx/numberingParser.d.ts +3 -1
- package/dist/docx/numberingParser.js +17 -3
- package/dist/docx/packageParts.d.ts +3 -1
- package/dist/docx/packageParts.js +74 -19
- package/dist/docx/paragraphMarkPropertyPresence.d.ts +9 -0
- package/dist/docx/paragraphMarkPropertyPresence.js +21 -0
- package/dist/docx/paragraphParser.js +101 -53
- package/dist/docx/paragraphPropertySource.d.ts +15 -1
- package/dist/docx/paragraphPropertySource.js +77 -22
- package/dist/docx/parser.js +3 -1
- package/dist/docx/removeHeaderFooterParts.js +17 -6
- package/dist/docx/reviewHistoryNamespace.d.ts +4 -0
- package/dist/docx/reviewHistoryNamespace.js +4 -0
- package/dist/docx/reviewResolutionProvenance.d.ts +25 -0
- package/dist/docx/reviewResolutionProvenance.js +153 -0
- package/dist/docx/rezip.d.ts +54 -6
- package/dist/docx/rezip.js +835 -257
- package/dist/docx/runConsolidator.d.ts +2 -58
- package/dist/docx/runConsolidator.js +3 -175
- package/dist/docx/runParser.d.ts +2 -1
- package/dist/docx/runParser.js +156 -116
- package/dist/docx/saveDiagnostics.d.ts +22 -0
- package/dist/docx/saveDiagnostics.js +0 -0
- package/dist/docx/selectiveSave.d.ts +3 -1
- package/dist/docx/selectiveSave.js +36 -4
- package/dist/docx/selectiveXmlPatch.d.ts +16 -8
- package/dist/docx/selectiveXmlPatch.js +81 -7
- package/dist/docx/serializer/documentSerializer.d.ts +9 -2
- package/dist/docx/serializer/documentSerializer.js +29 -10
- package/dist/docx/serializer/headerFooterSerializer.d.ts +5 -1
- package/dist/docx/serializer/headerFooterSerializer.js +19 -11
- package/dist/docx/serializer/noteSerializer.d.ts +2 -2
- package/dist/docx/serializer/noteSerializer.js +24 -8
- package/dist/docx/serializer/paragraphSerializer.js +41 -4
- package/dist/docx/serializer/partNamespaces.js +2 -1
- package/dist/docx/serializer/runSerializer.js +3 -1
- package/dist/docx/server/applyDocxXmlPatchProposal.js +14 -9
- package/dist/docx/settingsHeaderFooterUpdate.d.ts +5 -0
- package/dist/docx/settingsHeaderFooterUpdate.js +90 -0
- package/dist/docx/settingsParser.d.ts +1 -2
- package/dist/docx/settingsParser.js +5 -6
- package/dist/docx/storyBlockReplay.d.ts +31 -0
- package/dist/docx/storyBlockReplay.js +471 -0
- package/dist/docx/storyPlainText.d.ts +20 -0
- package/dist/docx/storyPlainText.js +23 -0
- package/dist/docx/streamingXmlParser.d.ts +22 -1
- package/dist/docx/streamingXmlParser.js +49 -3
- package/dist/docx/structuralXmlPatch.js +18 -23
- package/dist/docx/styleParser.d.ts +5 -1
- package/dist/docx/styleParser.js +1 -1
- package/dist/docx/tableParser.d.ts +1 -8
- package/dist/docx/tableParser.js +1 -28
- package/dist/docx/textBoxParser.d.ts +1 -5
- package/dist/docx/textBoxParser.js +1 -20
- package/dist/docx/unzip.js +6 -1
- package/dist/docx/verbatimCapture.d.ts +3 -1
- package/dist/docx/verbatimCapture.js +49 -6
- package/dist/i18n/messages/ar.gen.d.ts +5 -0
- package/dist/i18n/messages/ar.gen.js +656 -0
- package/dist/i18n/messages/cs.gen.d.ts +5 -0
- package/dist/i18n/messages/cs.gen.js +656 -0
- package/dist/i18n/messages/de.gen.d.ts +5 -0
- package/dist/i18n/messages/de.gen.js +656 -0
- package/dist/i18n/messages/en.gen.d.ts +5 -0
- package/dist/i18n/messages/en.gen.js +656 -0
- package/dist/i18n/messages/es.gen.d.ts +5 -0
- package/dist/i18n/messages/es.gen.js +656 -0
- package/dist/i18n/messages/et.gen.d.ts +5 -0
- package/dist/i18n/messages/et.gen.js +656 -0
- package/dist/i18n/messages/fr.gen.d.ts +5 -0
- package/dist/i18n/messages/fr.gen.js +656 -0
- package/dist/i18n/messages/he.gen.d.ts +5 -0
- package/dist/i18n/messages/he.gen.js +656 -0
- package/dist/i18n/messages/hi.gen.d.ts +5 -0
- package/dist/i18n/messages/hi.gen.js +656 -0
- package/dist/i18n/messages/hu.gen.d.ts +5 -0
- package/dist/i18n/messages/hu.gen.js +656 -0
- package/dist/i18n/messages/locales.d.ts +5 -0
- package/dist/i18n/messages/locales.js +22 -0
- package/dist/i18n/messages/lt.gen.d.ts +5 -0
- package/dist/i18n/messages/lt.gen.js +656 -0
- package/dist/i18n/messages/lv.gen.d.ts +5 -0
- package/dist/i18n/messages/lv.gen.js +656 -0
- package/dist/i18n/messages/pl.gen.d.ts +5 -0
- package/dist/i18n/messages/pl.gen.js +656 -0
- package/dist/i18n/messages/pt-BR.gen.d.ts +5 -0
- package/dist/i18n/messages/pt-BR.gen.js +656 -0
- package/dist/i18n/messages/sk.gen.d.ts +5 -0
- package/dist/i18n/messages/sk.gen.js +656 -0
- package/dist/i18n/messages/tr.gen.d.ts +5 -0
- package/dist/i18n/messages/tr.gen.js +656 -0
- package/dist/i18n/messages/zh-CN.gen.d.ts +5 -0
- package/dist/i18n/messages/zh-CN.gen.js +656 -0
- package/dist/i18n/messages.d.ts +2 -3
- package/dist/i18n/messages.js +1 -19
- package/dist/internal/acceptedBlockProjection.d.ts +12 -0
- package/dist/internal/acceptedBlockProjection.js +45 -0
- package/dist/internal/noteMarkerAttrs.d.ts +8 -0
- package/dist/internal/noteMarkerAttrs.js +16 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.js +1 -0
- package/dist/internal/prosemirrorAttrBoundary.d.ts +21 -0
- package/dist/internal/prosemirrorAttrBoundary.js +50 -0
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +3 -3
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.js +1 -0
- package/dist/layout-bridge/convert/noteReferences.d.ts +1 -3
- package/dist/layout-bridge/convert/noteReferences.js +1 -6
- package/dist/layout-bridge/convert/paragraphRuns.js +2 -4
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +2 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +2 -2
- package/dist/managers/DocumentLoaderManager.d.ts +1 -0
- package/dist/managers/DocumentLoaderManager.js +9 -1
- package/dist/markdown/escape.d.ts +3 -1
- package/dist/markdown/escape.js +9 -2
- package/dist/markdown/renderBlock.js +20 -121
- package/dist/markdown/renderParagraph.js +13 -15
- package/dist/markdown/renderRuns.d.ts +7 -1
- package/dist/markdown/renderRuns.js +35 -15
- package/dist/markdown/renderTable.js +2 -0
- package/dist/markdown/types.d.ts +3 -9
- package/dist/prosemirror/attrs/index.d.ts +2 -12
- package/dist/prosemirror/attrs/index.js +22 -48
- package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +2 -1
- package/dist/prosemirror/canonicalCommands.d.ts +121 -0
- package/dist/prosemirror/canonicalCommands.js +35 -0
- package/dist/prosemirror/canonicalSelectionRange.d.ts +9 -0
- package/dist/prosemirror/canonicalSelectionRange.js +15 -0
- package/dist/prosemirror/clipboardIntent.d.ts +7 -0
- package/dist/prosemirror/clipboardIntent.js +9 -0
- package/dist/prosemirror/commands/pageBreak.js +15 -1
- package/dist/prosemirror/commands/pastePlainText.js +2 -1
- package/dist/prosemirror/commentReferenceAttrs.d.ts +2 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +91 -19
- package/dist/prosemirror/conversion/hyphenTextCarriers.d.ts +8 -0
- package/dist/prosemirror/conversion/hyphenTextCarriers.js +8 -0
- package/dist/prosemirror/conversion/listRenderingDefinition.d.ts +6 -0
- package/dist/prosemirror/conversion/listRenderingDefinition.js +97 -0
- package/dist/prosemirror/conversion/toProseDoc.d.ts +11 -4
- package/dist/prosemirror/conversion/toProseDoc.js +55 -14
- package/dist/prosemirror/executeEditorCommand.d.ts +11 -0
- package/dist/prosemirror/executeEditorCommand.js +26 -0
- package/dist/prosemirror/extensions/StarterKit.js +2 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +88 -48
- package/dist/prosemirror/extensions/features/ListExtension.js +18 -5
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +5 -2
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +13 -1
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +56 -28
- package/dist/prosemirror/extensions/marks/TextColorExtension.js +3 -2
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
- package/dist/prosemirror/extensions/marks/markUtils.js +72 -8
- package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.js +36 -0
- package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +4 -2
- package/dist/prosemirror/insertOperations.js +2 -1
- package/dist/prosemirror/listMarker.d.ts +1 -0
- package/dist/prosemirror/listMarker.js +16 -7
- package/dist/prosemirror/listNumbering.js +26 -5
- package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
- package/dist/prosemirror/listRenderingAttrs.js +3 -0
- package/dist/prosemirror/markupViewNotes.js +3 -2
- package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +2 -1
- package/dist/prosemirror/noteReferenceReview.js +5 -3
- package/dist/prosemirror/paragraphPropertyCarry.d.ts +7 -1
- package/dist/prosemirror/paragraphPropertyCarry.js +8 -3
- package/dist/prosemirror/plugins/suggestionMode.js +57 -7
- package/dist/prosemirror/rangeAnchorAttrs.d.ts +2 -1
- package/dist/prosemirror/runFormattingFromMarks.d.ts +4 -1
- package/dist/prosemirror/runFormattingFromMarks.js +15 -1
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +2 -1
- package/dist/prosemirror/runFormattingInlineCarriers.js +4 -1
- package/dist/prosemirror/schema/marks.d.ts +2 -0
- package/dist/prosemirror/schema/nodes.d.ts +10 -2
- package/dist/prosemirror/textBoxAnchorAttrs.d.ts +2 -1
- package/dist/prosemirror/textInput.js +5 -1
- package/dist/prosemirror/trackedRevisionPath.js +2 -1
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -0
- package/dist/prosemirror/trackedRunInlineAtoms.js +1 -0
- package/dist/prosemirror/validation.js +4 -0
- package/dist/types/canonicalCapabilities.d.ts +215 -0
- package/dist/types/canonicalCapabilities.js +212 -0
- package/dist/types/canonicalSave.d.ts +11 -0
- package/dist/types/canonicalSave.js +0 -0
- package/dist/types/content.d.ts +2 -2
- package/dist/types/docxSerialization.d.ts +14 -0
- package/dist/types/docxSerialization.js +7 -0
- package/dist/utils/createDocument.js +2 -2
- package/package.json +16 -4
package/dist/i18n/messages.js
CHANGED
|
@@ -1,24 +1,6 @@
|
|
|
1
1
|
import { CATALOGS as CATALOGS$1 } from "./messages/catalogs.gen.js";
|
|
2
|
+
import { FOLIO_LOCALES } from "./messages/locales.js";
|
|
2
3
|
//#region src/i18n/messages.ts
|
|
3
|
-
const FOLIO_LOCALES = [
|
|
4
|
-
"en",
|
|
5
|
-
"de",
|
|
6
|
-
"fr",
|
|
7
|
-
"es",
|
|
8
|
-
"cs",
|
|
9
|
-
"ar",
|
|
10
|
-
"et",
|
|
11
|
-
"he",
|
|
12
|
-
"hi",
|
|
13
|
-
"hu",
|
|
14
|
-
"lt",
|
|
15
|
-
"lv",
|
|
16
|
-
"pl",
|
|
17
|
-
"pt-BR",
|
|
18
|
-
"sk",
|
|
19
|
-
"tr",
|
|
20
|
-
"zh-CN"
|
|
21
|
-
];
|
|
22
4
|
const CATALOGS = CATALOGS$1;
|
|
23
5
|
const FOLIO_LOCALE_SET = new Set(FOLIO_LOCALES);
|
|
24
6
|
const isFolioLocale = (locale) => FOLIO_LOCALE_SET.has(locale);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
//#region src/internal/acceptedBlockProjection.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Read a model story through the same structural resolver as Accept All and
|
|
5
|
+
* the editor's No Markup view. The authored model is never changed.
|
|
6
|
+
*/
|
|
7
|
+
declare const projectAcceptedBlocks: (blocks: readonly document_d_exports.BlockContent[], pkg: document_d_exports.DocxPackage | undefined) => {
|
|
8
|
+
blocks: readonly document_d_exports.BlockContent[];
|
|
9
|
+
completeness: string;
|
|
10
|
+
} | null;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { projectAcceptedBlocks };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { getCachedNumberingMap } from "../docx/numberingParser.js";
|
|
2
|
+
import { proseDocToBlocks } from "../prosemirror/conversion/fromProseDoc.js";
|
|
3
|
+
import { headerFooterToProseDoc } from "../prosemirror/conversion/toProseDoc.js";
|
|
4
|
+
import { createStyleEngine } from "../style-engine/styleEngine.js";
|
|
5
|
+
import { resolveWholeStory } from "./wholeStoryRevisionResolution.js";
|
|
6
|
+
import { panic } from "better-result";
|
|
7
|
+
//#region src/internal/acceptedBlockProjection.ts
|
|
8
|
+
/** Inline revisions alone are already handled by the Markdown run renderer. */
|
|
9
|
+
const hasBlockRevision = (blocks) => blocks.some((block) => {
|
|
10
|
+
switch (block.type) {
|
|
11
|
+
case "paragraph": return block.pPrMark !== void 0;
|
|
12
|
+
case "table": return block.rows.some((row) => row.structuralChange !== void 0 || row.cells.some((cell) => cell.structuralChange !== void 0 || hasBlockRevision(cell.content)));
|
|
13
|
+
case "blockSdt":
|
|
14
|
+
case "blockCustomXml": return hasBlockRevision(block.content);
|
|
15
|
+
case "preservedBlock":
|
|
16
|
+
case "bookmarkStart":
|
|
17
|
+
case "bookmarkEnd": return false;
|
|
18
|
+
default: return panic("Unsupported block in accepted projection", { unsupported: block });
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* Read a model story through the same structural resolver as Accept All and
|
|
23
|
+
* the editor's No Markup view. The authored model is never changed.
|
|
24
|
+
*/
|
|
25
|
+
const projectAcceptedBlocks = (blocks, pkg) => {
|
|
26
|
+
if (!hasBlockRevision(blocks)) return null;
|
|
27
|
+
const options = {
|
|
28
|
+
...pkg?.styles !== void 0 && { styles: pkg.styles },
|
|
29
|
+
...pkg?.theme !== void 0 && { theme: pkg.theme },
|
|
30
|
+
...pkg?.numbering !== void 0 && { numbering: pkg.numbering }
|
|
31
|
+
};
|
|
32
|
+
const doc = headerFooterToProseDoc([...blocks], options);
|
|
33
|
+
const result = resolveWholeStory({
|
|
34
|
+
doc,
|
|
35
|
+
mode: "accept",
|
|
36
|
+
styleResolver: createStyleEngine(pkg?.styles),
|
|
37
|
+
numbering: pkg?.numbering ? getCachedNumberingMap(pkg.numbering) : null
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
blocks: result.resolved.eq(doc) ? blocks : proseDocToBlocks(result.resolved, [...blocks], pkg?.styles),
|
|
41
|
+
completeness: result.failed ? "partial" : "complete"
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
export { projectAcceptedBlocks };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { NoteMarkerAttrs } from "../prosemirror/schema/nodes.js";
|
|
2
|
+
import { ReadProseMirrorAttrsResult } from "./prosemirrorAttrBoundary.js";
|
|
3
|
+
import { Node } from "prosemirror-model";
|
|
4
|
+
//#region src/internal/noteMarkerAttrs.d.ts
|
|
5
|
+
declare const readNoteMarkerAttrs: (node: Node) => ReadProseMirrorAttrsResult<NoteMarkerAttrs>;
|
|
6
|
+
declare const expectNoteMarkerAttrs: (node: Node) => NoteMarkerAttrs;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { expectNoteMarkerAttrs, readNoteMarkerAttrs };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { attrsRecord, attrsResult, expectCachedNodeAttrs, expectNodeType } from "./prosemirrorAttrBoundary.js";
|
|
2
|
+
//#region src/internal/noteMarkerAttrs.ts
|
|
3
|
+
const noteMarkerAttrsCache = /* @__PURE__ */ new WeakMap();
|
|
4
|
+
const readNoteMarkerAttrs = (node) => {
|
|
5
|
+
const attrs = attrsRecord(node.attrs);
|
|
6
|
+
const issues = [];
|
|
7
|
+
expectNodeType(node, "noteMarker", issues);
|
|
8
|
+
if (attrs["kind"] !== "footnote" && attrs["kind"] !== "endnote") issues.push({
|
|
9
|
+
path: "noteMarker.attrs.kind",
|
|
10
|
+
message: "Expected footnote or endnote."
|
|
11
|
+
});
|
|
12
|
+
return attrsResult(attrs, issues);
|
|
13
|
+
};
|
|
14
|
+
const expectNoteMarkerAttrs = (node) => expectCachedNodeAttrs(node, noteMarkerAttrsCache, readNoteMarkerAttrs, "noteMarker attrs");
|
|
15
|
+
//#endregion
|
|
16
|
+
export { expectNoteMarkerAttrs, readNoteMarkerAttrs };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Node } from "prosemirror-model";
|
|
2
|
+
//#region src/internal/prosemirrorAttrBoundary.d.ts
|
|
3
|
+
type ProseMirrorAttrIssue = {
|
|
4
|
+
readonly path: string;
|
|
5
|
+
readonly message: string;
|
|
6
|
+
};
|
|
7
|
+
type ReadProseMirrorAttrsResult<T> = {
|
|
8
|
+
ok: true;
|
|
9
|
+
value: T;
|
|
10
|
+
} | {
|
|
11
|
+
ok: false;
|
|
12
|
+
issues: readonly ProseMirrorAttrIssue[];
|
|
13
|
+
};
|
|
14
|
+
declare const attrsRecord: (attrs: unknown) => Record<string, unknown>;
|
|
15
|
+
declare const isRecord: (value: unknown) => value is Record<string, unknown>;
|
|
16
|
+
declare const attrsResult: <T>(attrs: Record<string, unknown>, issues: ProseMirrorAttrIssue[]) => ReadProseMirrorAttrsResult<T>;
|
|
17
|
+
declare const expectAttrs: <T>(result: ReadProseMirrorAttrsResult<T>, label: string) => T;
|
|
18
|
+
declare function expectCachedNodeAttrs<T extends object>(node: Node, cache: WeakMap<Node, T>, reader: (node: Node) => ReadProseMirrorAttrsResult<T>, label: string): T;
|
|
19
|
+
declare const expectNodeType: (node: Node, expected: string, issues: ProseMirrorAttrIssue[]) => void;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { ProseMirrorAttrIssue, ReadProseMirrorAttrsResult, attrsRecord, attrsResult, expectAttrs, expectCachedNodeAttrs, expectNodeType, isRecord };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { panic } from "better-result";
|
|
2
|
+
//#region src/internal/prosemirrorAttrBoundary.ts
|
|
3
|
+
const attrsRecord = (attrs) => {
|
|
4
|
+
if (isRecord(attrs)) return attrs;
|
|
5
|
+
return {};
|
|
6
|
+
};
|
|
7
|
+
const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8
|
+
const attrsResult = (attrs, issues) => {
|
|
9
|
+
if (issues.length > 0) return {
|
|
10
|
+
ok: false,
|
|
11
|
+
issues
|
|
12
|
+
};
|
|
13
|
+
let normalizedAttrs;
|
|
14
|
+
return {
|
|
15
|
+
ok: true,
|
|
16
|
+
get value() {
|
|
17
|
+
if (normalizedAttrs !== void 0) return normalizedAttrs;
|
|
18
|
+
const presentAttrs = {};
|
|
19
|
+
for (const key in attrs) {
|
|
20
|
+
if (!Object.hasOwn(attrs, key)) continue;
|
|
21
|
+
const value = attrs[key];
|
|
22
|
+
if (value !== null) presentAttrs[key] = value;
|
|
23
|
+
}
|
|
24
|
+
normalizedAttrs = presentAttrs;
|
|
25
|
+
return normalizedAttrs;
|
|
26
|
+
},
|
|
27
|
+
set value(value) {
|
|
28
|
+
normalizedAttrs = value;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
const expectAttrs = (result, label) => {
|
|
33
|
+
if (result.ok) return result.value;
|
|
34
|
+
panic(`Invalid ProseMirror ${label}:\n${result.issues.map((issue) => `${issue.path}: ${issue.message}`).join("\n")}`);
|
|
35
|
+
};
|
|
36
|
+
function expectCachedNodeAttrs(node, cache, reader, label) {
|
|
37
|
+
const cached = cache.get(node);
|
|
38
|
+
if (cached) return cached;
|
|
39
|
+
const value = expectAttrs(reader(node), label);
|
|
40
|
+
cache.set(node, value);
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
const expectNodeType = (node, expected, issues) => {
|
|
44
|
+
if (node.type.name !== expected) issues.push({
|
|
45
|
+
path: "node.type.name",
|
|
46
|
+
message: `Expected ${expected}, got ${node.type.name}.`
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
//#endregion
|
|
50
|
+
export { attrsRecord, attrsResult, expectAttrs, expectCachedNodeAttrs, expectNodeType, isRecord };
|
|
@@ -6,6 +6,7 @@ import "./toFlowBlocks.js";
|
|
|
6
6
|
type MeasureBlocksFn = (blocks: FlowBlock[], contentWidth: number) => Measure[];
|
|
7
7
|
type ConvertFootnoteOptions = {
|
|
8
8
|
styles?: document_d_exports.StyleDefinitions | null;
|
|
9
|
+
numbering?: document_d_exports.NumberingDefinitions;
|
|
9
10
|
theme?: document_d_exports.Theme | null;
|
|
10
11
|
defaultSize?: number;
|
|
11
12
|
fontAlternates?: ToFlowBlocksOptions["fontAlternates"];
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { measureParagraph } from "../../layout-engine/measure/measureParagraph.js";
|
|
2
2
|
import { layoutTextBoxContent } from "../../layout-engine/measure/textBoxParagraphLayout.js";
|
|
3
3
|
import { DEFAULT_TEXTBOX_MARGINS, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, isFloatingImageRun, resolveTableWidthPx } from "../../layout-engine/types.js";
|
|
4
|
-
import { expectPreservedXmlAttrs } from "../../prosemirror/attrs/index.js";
|
|
5
4
|
import { footnoteToProseDoc } from "../../prosemirror/conversion/toProseDoc.js";
|
|
6
|
-
import { collectNoteRefs
|
|
5
|
+
import { collectNoteRefs } from "./noteReferences.js";
|
|
7
6
|
import { toFlowBlocks } from "./toFlowBlocks.js";
|
|
8
7
|
//#region src/layout-bridge/convert/footnoteLayout.ts
|
|
9
8
|
/** Default footnote font size in points */
|
|
@@ -203,6 +202,7 @@ function convertNoteStoryToFlowBlocks(content, options, referenceMarkText) {
|
|
|
203
202
|
const proseOptions = {};
|
|
204
203
|
if (options.styles) proseOptions.styles = options.styles;
|
|
205
204
|
if (options.theme !== void 0) proseOptions.theme = options.theme;
|
|
205
|
+
if (options.numbering !== void 0) proseOptions.numbering = options.numbering;
|
|
206
206
|
const pmDoc = footnoteToProseDoc(content, proseOptions);
|
|
207
207
|
const flowOptions = {};
|
|
208
208
|
if (options.defaultSize !== void 0) flowOptions.defaultSize = options.defaultSize;
|
|
@@ -225,7 +225,7 @@ function containsNoteReferenceMark(doc) {
|
|
|
225
225
|
let found = false;
|
|
226
226
|
doc.descendants((node) => {
|
|
227
227
|
if (found) return false;
|
|
228
|
-
if (node.type.name === "
|
|
228
|
+
if (node.type.name === "noteMarker") found = true;
|
|
229
229
|
return !found;
|
|
230
230
|
});
|
|
231
231
|
return found;
|
|
@@ -41,6 +41,7 @@ declare function calculateHeaderFooterMarginPushBounds(blocks: FlowBlock[], meas
|
|
|
41
41
|
declare function calculateHeaderFooterBodyTopClearance(blocks: FlowBlock[], flowHeight: number, metrics: HeaderFooterMetrics): number | undefined;
|
|
42
42
|
type ConvertHeaderFooterOptions = {
|
|
43
43
|
styles?: document_d_exports.StyleDefinitions | null;
|
|
44
|
+
numbering?: document_d_exports.NumberingDefinitions;
|
|
44
45
|
theme?: document_d_exports.Theme | null;
|
|
45
46
|
defaultSize?: number;
|
|
46
47
|
fontAlternates?: ToFlowBlocksOptions["fontAlternates"];
|
|
@@ -340,6 +340,7 @@ function convertHeaderFooterToContent(headerFooter, contentWidth, metrics, optio
|
|
|
340
340
|
const proseDocOptions = {};
|
|
341
341
|
if (options.styles) proseDocOptions.styles = options.styles;
|
|
342
342
|
if (options.theme !== void 0) proseDocOptions.theme = options.theme;
|
|
343
|
+
if (options.numbering !== void 0) proseDocOptions.numbering = options.numbering;
|
|
343
344
|
const pmDoc = headerFooter.watermarkBlockIndex === void 0 ? headerFooterToProseDoc(headerFooter.content, proseDocOptions) : headerFooterToProseDocWithDetachedWatermarkHost(headerFooter, proseDocOptions);
|
|
344
345
|
const flowOptions = {};
|
|
345
346
|
if (options.defaultSize !== void 0) flowOptions.defaultSize = options.defaultSize;
|
|
@@ -8,7 +8,5 @@ declare function collectNoteRefs(blocks: readonly FlowBlock[], idKey: "footnoteR
|
|
|
8
8
|
noteId: number;
|
|
9
9
|
pmPos: number;
|
|
10
10
|
}[];
|
|
11
|
-
/** Whether captured run-child markup is a note story's `w:footnoteRef`/`w:endnoteRef`. */
|
|
12
|
-
declare function isNoteReferenceMarkXml(xml: string): boolean;
|
|
13
11
|
//#endregion
|
|
14
|
-
export { collectNoteRefs
|
|
12
|
+
export { collectNoteRefs };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
//#region src/layout-bridge/convert/noteReferences.ts
|
|
2
|
-
const NOTE_REFERENCE_MARK_XML = /^<(?:[^\s:/>]+:)?(?:footnoteRef|endnoteRef)[\s/>]/u;
|
|
3
2
|
/**
|
|
4
3
|
* Runs with `idKey` set, in document order: the note references a block list
|
|
5
4
|
* makes, through table cells (and tables within cells) and text boxes.
|
|
@@ -21,9 +20,5 @@ function collectNoteRefs(blocks, idKey) {
|
|
|
21
20
|
walk(blocks);
|
|
22
21
|
return refs;
|
|
23
22
|
}
|
|
24
|
-
/** Whether captured run-child markup is a note story's `w:footnoteRef`/`w:endnoteRef`. */
|
|
25
|
-
function isNoteReferenceMarkXml(xml) {
|
|
26
|
-
return NOTE_REFERENCE_MARK_XML.test(xml);
|
|
27
|
-
}
|
|
28
23
|
//#endregion
|
|
29
|
-
export { collectNoteRefs
|
|
24
|
+
export { collectNoteRefs };
|
|
@@ -3,7 +3,6 @@ import { expectFieldAttrs, expectImageAttrs, expectMathAttrs, expectParagraphAtt
|
|
|
3
3
|
import { decodeOoxmlSymbolCharacter } from "../../utils/ooxmlSymbol.js";
|
|
4
4
|
import { tableOfContentsStyleLevel } from "../../utils/tableOfContentsStyle.js";
|
|
5
5
|
import { buildImageRun, constrainImageToPage, hasPaintableImageSource, hasRelationshipBackedImageBox } from "./imageConversion.js";
|
|
6
|
-
import { isNoteReferenceMarkXml } from "./noteReferences.js";
|
|
7
6
|
import { applyCharacterStyleToggleFormatting, markDefaultBlackTextColorSource, mergeRunFormatting } from "./runFormattingMerge.js";
|
|
8
7
|
import { extractRunFormatting } from "./runMarkFormatting.js";
|
|
9
8
|
import { paragraphRunDefaults } from "./textFormattingConversion.js";
|
|
@@ -135,9 +134,8 @@ function paragraphToRuns(node, startPos, _options, pageBreaks) {
|
|
|
135
134
|
});
|
|
136
135
|
return;
|
|
137
136
|
}
|
|
138
|
-
if (child.type.name === "preservedXml") {
|
|
139
|
-
const
|
|
140
|
-
const text = capturedText === "" && _options.noteReferenceMarkText !== void 0 && isNoteReferenceMarkXml(xml) ? _options.noteReferenceMarkText : capturedText;
|
|
137
|
+
if (child.type.name === "preservedXml" || child.type.name === "noteMarker") {
|
|
138
|
+
const text = child.type.name === "noteMarker" ? _options.noteReferenceMarkText ?? "" : expectPreservedXmlAttrs(child).text;
|
|
141
139
|
if (text === "") return;
|
|
142
140
|
const formatting = extractRunFormatting(effectiveMarks, theme, fontAlternates);
|
|
143
141
|
applyCharacterStyleToggleFormatting({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FlowBlock } from "../../layout-engine/types.js";
|
|
2
2
|
import { formatCounter, resolveListTemplate } from "../../prosemirror/listMarker.js";
|
|
3
3
|
import { ToFlowBlocksOptions, resetBlockIdCounter } from "./flowConversionShared.js";
|
|
4
|
-
import { collectNoteRefs
|
|
4
|
+
import { collectNoteRefs } from "./noteReferences.js";
|
|
5
5
|
import { convertBorderSpecToLayout } from "./flowBorders.js";
|
|
6
6
|
import { Node } from "prosemirror-model";
|
|
7
7
|
//#region src/layout-bridge/convert/toFlowBlocks.d.ts
|
|
@@ -21,4 +21,4 @@ declare const WORD_UNSPECIFIED_FONT_SIZE = 10;
|
|
|
21
21
|
*/
|
|
22
22
|
declare function toFlowBlocks(doc: Node, options?: ToFlowBlocksOptions): FlowBlock[];
|
|
23
23
|
//#endregion
|
|
24
|
-
export { type ToFlowBlocksOptions, WORD_UNSPECIFIED_FONT_SIZE, collectNoteRefs, convertBorderSpecToLayout, formatCounter,
|
|
24
|
+
export { type ToFlowBlocksOptions, WORD_UNSPECIFIED_FONT_SIZE, collectNoteRefs, convertBorderSpecToLayout, formatCounter, resetBlockIdCounter, resolveListTemplate, toFlowBlocks };
|
|
@@ -12,7 +12,7 @@ import { mergeRunInParagraphs, reserveLeadingEmptyOutlineHeight, suppressFinalEm
|
|
|
12
12
|
import { convertBorderSpecToLayout } from "./flowBorders.js";
|
|
13
13
|
import { nextBlockId, resetBlockIdCounter, twipsToPixels } from "./flowConversionShared.js";
|
|
14
14
|
import { convertImage } from "./imageConversion.js";
|
|
15
|
-
import { collectNoteRefs
|
|
15
|
+
import { collectNoteRefs } from "./noteReferences.js";
|
|
16
16
|
import { splitParagraphAtPageBreaks } from "./pageBreakSplitting.js";
|
|
17
17
|
import { convertParagraph, drawsParagraphBorder } from "./paragraphConversion.js";
|
|
18
18
|
import { groupParagraphFrames } from "./paragraphFrames.js";
|
|
@@ -417,4 +417,4 @@ function toFlowBlocks(doc, options = {}) {
|
|
|
417
417
|
}), readFinalSectionStart(doc)), options.splitPageBreakAndParagraphMark === true, sectionBreaksWithoutMarker), nextBlockId);
|
|
418
418
|
}
|
|
419
419
|
//#endregion
|
|
420
|
-
export { WORD_UNSPECIFIED_FONT_SIZE, collectNoteRefs, convertBorderSpecToLayout, formatCounter,
|
|
420
|
+
export { WORD_UNSPECIFIED_FONT_SIZE, collectNoteRefs, convertBorderSpecToLayout, formatCounter, resetBlockIdCounter, resolveListTemplate, toFlowBlocks };
|
|
@@ -23,6 +23,7 @@ type DocumentLoaderHistory = {
|
|
|
23
23
|
type DocumentLoaderCallbacks = {
|
|
24
24
|
/** Editor history to reset/seed with the loaded document. */
|
|
25
25
|
history: DocumentLoaderHistory;
|
|
26
|
+
getExperimentalSession?: () => "canonical" | undefined;
|
|
26
27
|
/**
|
|
27
28
|
* Receives the identity of the document that just landed in history. Every
|
|
28
29
|
* load allocates a fresh identity, so the adapter can tell an external load
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { prepareCanonicalDocxInput } from "../docx/canonicalSessionInput.js";
|
|
1
2
|
import { inspectDocxCompatibility } from "../docx/compatibility.js";
|
|
2
3
|
import { parseDocx } from "../docx/parser.js";
|
|
3
4
|
import { recordDocumentLoadPhase } from "../layout-engine/layoutInstrumentation.js";
|
|
5
|
+
import { CANONICAL_GAP, usesCanonicalSession } from "../types/canonicalCapabilities.js";
|
|
4
6
|
import { resetAuthorColors } from "../utils/authorColors.js";
|
|
5
7
|
import { loadFontsWithMapping } from "../utils/fontLoader.js";
|
|
6
8
|
//#region src/managers/DocumentLoaderManager.ts
|
|
@@ -60,7 +62,13 @@ var DocumentLoaderManager = class {
|
|
|
60
62
|
const parseStartedAt = performance.now();
|
|
61
63
|
let doc;
|
|
62
64
|
try {
|
|
63
|
-
|
|
65
|
+
let input = buffer;
|
|
66
|
+
if (usesCanonicalSession(this.callbacks.getExperimentalSession?.(), CANONICAL_GAP.authorityRouting)) {
|
|
67
|
+
const prepared = await prepareCanonicalDocxInput(buffer);
|
|
68
|
+
if (prepared.isErr()) throw prepared.error;
|
|
69
|
+
input = prepared.value;
|
|
70
|
+
}
|
|
71
|
+
doc = await parseDocx(input, {
|
|
64
72
|
detectVariables: false,
|
|
65
73
|
preloadFonts: false,
|
|
66
74
|
password: options.password
|
|
@@ -25,6 +25,8 @@ declare function escapeInline(text: string): string;
|
|
|
25
25
|
* line.
|
|
26
26
|
*/
|
|
27
27
|
declare function escapeTableCell(text: string): string;
|
|
28
|
+
/** Single-line Markdown blocks express inline breaks without their two-space syntax. */
|
|
29
|
+
declare const inlineBreaksToHtml: (text: string) => string;
|
|
28
30
|
declare function escapeLinkUrl(url: string): string;
|
|
29
31
|
/**
|
|
30
32
|
* Alt text inside ``. Raw (un-escaped) text, so escape the backslash
|
|
@@ -33,4 +35,4 @@ declare function escapeLinkUrl(url: string): string;
|
|
|
33
35
|
*/
|
|
34
36
|
declare function escapeAltText(text: string): string;
|
|
35
37
|
//#endregion
|
|
36
|
-
export { escapeAltText, escapeInline, escapeLinkUrl, escapeTableCell };
|
|
38
|
+
export { escapeAltText, escapeInline, escapeLinkUrl, escapeTableCell, inlineBreaksToHtml };
|
package/dist/markdown/escape.js
CHANGED
|
@@ -30,8 +30,15 @@ function escapeInline(text) {
|
|
|
30
30
|
* line.
|
|
31
31
|
*/
|
|
32
32
|
function escapeTableCell(text) {
|
|
33
|
-
return text.replace(/\|/gu, "|")
|
|
33
|
+
return inlineBreaksToHtml(text.replace(/\|/gu, "|"));
|
|
34
34
|
}
|
|
35
|
+
/** Single-line Markdown blocks express inline breaks without their two-space syntax. */
|
|
36
|
+
const inlineBreaksToHtml = (text) => text.split(/\r?\n/u).map((line, index, lines) => {
|
|
37
|
+
if (index === lines.length - 1) return line;
|
|
38
|
+
let end = line.length;
|
|
39
|
+
while (end > 0 && line.at(end - 1) === " ") end--;
|
|
40
|
+
return line.slice(0, end);
|
|
41
|
+
}).join("<br>");
|
|
35
42
|
/**
|
|
36
43
|
* Hyperlink URLs in inline form need parens balanced; we URL-encode the
|
|
37
44
|
* problematic characters rather than escape, so the link still resolves.
|
|
@@ -55,4 +62,4 @@ function escapeAltText(text) {
|
|
|
55
62
|
return text.replace(/(?<ch>[\\[\]])/gu, "\\$<ch>").replace(/\r?\n/gu, " ");
|
|
56
63
|
}
|
|
57
64
|
//#endregion
|
|
58
|
-
export { escapeAltText, escapeInline, escapeLinkUrl, escapeTableCell };
|
|
65
|
+
export { escapeAltText, escapeInline, escapeLinkUrl, escapeTableCell, inlineBreaksToHtml };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ALT_CHUNK_READER_DIAGNOSTIC, isAltChunkMarkup } from "../docx/altChunk.js";
|
|
2
2
|
import { OPAQUE_REVISION_CARRIER_READER_DIAGNOSTIC, isOpaqueNestedRowMarkup, opaqueRevisionCarrierName } from "../docx/opaqueCarrier.js";
|
|
3
|
-
import {
|
|
3
|
+
import { projectAcceptedBlocks } from "../internal/acceptedBlockProjection.js";
|
|
4
|
+
import { pushWarning } from "./internals.js";
|
|
4
5
|
import { renderParagraphBlock } from "./renderParagraph.js";
|
|
5
6
|
import { renderTable } from "./renderTable.js";
|
|
6
7
|
import { panic } from "better-result";
|
|
@@ -10,128 +11,14 @@ import { panic } from "better-result";
|
|
|
10
11
|
* markdown for each block, suppressing redundant blank lines between list items
|
|
11
12
|
* of the same list. Ported from eigenpal/docx-editor PR #595.
|
|
12
13
|
*/
|
|
13
|
-
/**
|
|
14
|
-
* In `trackedChanges: "clean"` mode every change is accepted, as the editor's
|
|
15
|
-
* accept-all resolves the story (`internal/wholeStoryRevisionResolution.ts`).
|
|
16
|
-
*
|
|
17
|
-
* A paragraph whose mark is pending deletion loses its break on accept and
|
|
18
|
-
* runs on into the paragraph after it, which is the paragraph left: its mark
|
|
19
|
-
* ends the joined text, and a paragraph's properties (style, list) live on its
|
|
20
|
-
* mark. A run of consecutive deletions collapses into that last paragraph.
|
|
21
|
-
*
|
|
22
|
-
* With a table right after it, its words run on into the table's first cell
|
|
23
|
-
* and lead that cell's first paragraph (`prosemirror/tableRunIn.ts`), unless
|
|
24
|
-
* it ends a section, keeps nothing once accepted, or that cell is pending.
|
|
25
|
-
* Otherwise a paragraph that cannot join keeps its place, or goes when it
|
|
26
|
-
* keeps nothing and something follows it.
|
|
27
|
-
*/
|
|
28
|
-
function mergeAcceptedParagraphBreaks(blocks) {
|
|
29
|
-
const reversed = [];
|
|
30
|
-
let survivor = null;
|
|
31
|
-
let tableFollows = false;
|
|
32
|
-
let followed = false;
|
|
33
|
-
const flush = () => {
|
|
34
|
-
if (survivor) reversed.push(survivor);
|
|
35
|
-
survivor = null;
|
|
36
|
-
};
|
|
37
|
-
for (let index = blocks.length - 1; index >= 0; index--) {
|
|
38
|
-
const block = blocks[index];
|
|
39
|
-
if (!block) continue;
|
|
40
|
-
if (block.type !== "paragraph") {
|
|
41
|
-
flush();
|
|
42
|
-
reversed.push(block);
|
|
43
|
-
tableFollows = block.type === "table";
|
|
44
|
-
followed ||= tableFollows;
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
const goes = block.pPrMark?.kind === "del" || block.pPrMark?.kind === "moveFrom";
|
|
48
|
-
if (goes && survivor) {
|
|
49
|
-
survivor = cloneParagraphWithoutPropertySource(survivor, { content: [...block.content, ...survivor.content] });
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
const table = reversed.at(-1);
|
|
53
|
-
if (goes && tableFollows && table?.type === "table") {
|
|
54
|
-
const ranIn = tableWithParagraphRunIn(table, block);
|
|
55
|
-
if (ranIn) {
|
|
56
|
-
reversed[reversed.length - 1] = ranIn;
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
flush();
|
|
61
|
-
tableFollows = false;
|
|
62
|
-
if (goes && holdsNothingOnAccept(block) && followed && index + reversed.length > 0) continue;
|
|
63
|
-
survivor = block;
|
|
64
|
-
followed = true;
|
|
65
|
-
}
|
|
66
|
-
flush();
|
|
67
|
-
return reversed.reverse();
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Whether the cell a paragraph's words would run into is itself pending (its
|
|
71
|
-
* row or the cell, through nested tables' first cells), as
|
|
72
|
-
* `prosemirror/tableRunIn.ts` reads it.
|
|
73
|
-
*/
|
|
74
|
-
const runInCellPending = (table) => {
|
|
75
|
-
const row = table.rows[0];
|
|
76
|
-
const cell = row?.cells[0];
|
|
77
|
-
if (!row || !cell) return false;
|
|
78
|
-
if (row.structuralChange !== void 0 || cell.structuralChange !== void 0) return true;
|
|
79
|
-
const first = cell.content[0];
|
|
80
|
-
return first?.type === "table" && runInCellPending(first);
|
|
81
|
-
};
|
|
82
|
-
/**
|
|
83
|
-
* `table` with `paragraph`'s words leading its first cell's first paragraph,
|
|
84
|
-
* descending into nested tables, or null when the paragraph keeps its place.
|
|
85
|
-
*/
|
|
86
|
-
const tableWithParagraphRunIn = (table, paragraph) => {
|
|
87
|
-
if (paragraph.sectionProperties !== void 0 || holdsNothingOnAccept(paragraph)) return null;
|
|
88
|
-
if (runInCellPending(table)) return null;
|
|
89
|
-
const runIn = (current) => {
|
|
90
|
-
const [row, ...rows] = current.rows;
|
|
91
|
-
const [cell, ...cells] = row?.cells ?? [];
|
|
92
|
-
const [first, ...rest] = cell?.content ?? [];
|
|
93
|
-
if (!row || !cell || !first) return null;
|
|
94
|
-
let led = null;
|
|
95
|
-
if (first.type === "paragraph") led = cloneParagraphWithoutPropertySource(first, { content: [...paragraph.content, ...first.content] });
|
|
96
|
-
else if (first.type === "table") led = runIn(first);
|
|
97
|
-
if (!led) return null;
|
|
98
|
-
return {
|
|
99
|
-
...current,
|
|
100
|
-
rows: [{
|
|
101
|
-
...row,
|
|
102
|
-
cells: [{
|
|
103
|
-
...cell,
|
|
104
|
-
content: [led, ...rest]
|
|
105
|
-
}, ...cells]
|
|
106
|
-
}, ...rows]
|
|
107
|
-
};
|
|
108
|
-
};
|
|
109
|
-
return runIn(table);
|
|
110
|
-
};
|
|
111
|
-
/** Paragraph content that shows nothing: range boundaries and anchors. */
|
|
112
|
-
const ZERO_WIDTH_CONTENT = /* @__PURE__ */ new Set([
|
|
113
|
-
"bookmarkStart",
|
|
114
|
-
"bookmarkEnd",
|
|
115
|
-
"commentRangeStart",
|
|
116
|
-
"commentRangeEnd",
|
|
117
|
-
"commentReference",
|
|
118
|
-
"moveFromRangeStart",
|
|
119
|
-
"moveFromRangeEnd",
|
|
120
|
-
"moveToRangeStart",
|
|
121
|
-
"moveToRangeEnd"
|
|
122
|
-
]);
|
|
123
|
-
/** Whether an item shows nothing once every change is accepted. */
|
|
124
|
-
const showsNothingOnAccept = (item) => {
|
|
125
|
-
if (item.type === "deletion" || item.type === "moveFrom" || ZERO_WIDTH_CONTENT.has(item.type)) return true;
|
|
126
|
-
if (item.type === "insertion" || item.type === "moveTo") return item.content.every(showsNothingOnAccept);
|
|
127
|
-
return item.type === "run" && item.content.every((content) => content.type === "renderedPageBreak");
|
|
128
|
-
};
|
|
129
|
-
/** Whether a paragraph keeps no visible content once every change is accepted. */
|
|
130
|
-
const holdsNothingOnAccept = (paragraph) => paragraph.content.every(showsNothingOnAccept);
|
|
131
14
|
function renderBlocks(ctx, pkg, blocks) {
|
|
15
|
+
const outerListIndentWidths = ctx.listIndentWidths;
|
|
16
|
+
ctx.listIndentWidths = [];
|
|
132
17
|
const out = [];
|
|
133
18
|
let prevWasListItem = false;
|
|
134
|
-
const
|
|
19
|
+
const projection = ctx.opts.trackedChanges === "clean" ? projectAcceptedBlocks(blocks, pkg) : null;
|
|
20
|
+
if (projection?.completeness === "partial") pushWarning(ctx, "Some tracked structural changes could not be resolved.");
|
|
21
|
+
const ordered = projection?.blocks ?? blocks;
|
|
135
22
|
for (const block of ordered) switch (block.type) {
|
|
136
23
|
case "paragraph": {
|
|
137
24
|
const { markdown: md, isListItem } = renderParagraphBlock(ctx, pkg, block);
|
|
@@ -146,7 +33,9 @@ function renderBlocks(ctx, pkg, blocks) {
|
|
|
146
33
|
break;
|
|
147
34
|
}
|
|
148
35
|
case "table": {
|
|
36
|
+
ctx.listIndentWidths = [];
|
|
149
37
|
const md = renderTable(ctx, pkg, block);
|
|
38
|
+
ctx.listIndentWidths = [];
|
|
150
39
|
if (md) {
|
|
151
40
|
if (out.length) out.push("");
|
|
152
41
|
out.push(md);
|
|
@@ -156,22 +45,32 @@ function renderBlocks(ctx, pkg, blocks) {
|
|
|
156
45
|
}
|
|
157
46
|
case "blockSdt":
|
|
158
47
|
case "blockCustomXml": {
|
|
48
|
+
ctx.listIndentWidths = [];
|
|
159
49
|
const nested = renderBlocks(ctx, pkg, block.content);
|
|
160
50
|
if (nested) {
|
|
161
51
|
if (out.length) out.push("");
|
|
162
52
|
out.push(nested);
|
|
163
53
|
}
|
|
54
|
+
ctx.listIndentWidths = [];
|
|
55
|
+
prevWasListItem = false;
|
|
164
56
|
break;
|
|
165
57
|
}
|
|
166
|
-
case "preservedBlock":
|
|
58
|
+
case "preservedBlock": {
|
|
59
|
+
const previousLength = out.length;
|
|
167
60
|
if (isAltChunkMarkup(block.xml)) out.push(block.readerText === void 0 ? ALT_CHUNK_READER_DIAGNOSTIC : `${ALT_CHUNK_READER_DIAGNOSTIC}\n\n${block.readerText}`);
|
|
168
61
|
else if (opaqueRevisionCarrierName(block.xml) !== void 0) out.push(OPAQUE_REVISION_CARRIER_READER_DIAGNOSTIC);
|
|
169
62
|
else if (isOpaqueNestedRowMarkup(block.xml)) out.push("[Unsupported nested w:tr content]");
|
|
63
|
+
if (out.length !== previousLength) {
|
|
64
|
+
ctx.listIndentWidths = [];
|
|
65
|
+
prevWasListItem = false;
|
|
66
|
+
}
|
|
170
67
|
break;
|
|
68
|
+
}
|
|
171
69
|
case "bookmarkStart":
|
|
172
70
|
case "bookmarkEnd": break;
|
|
173
71
|
default: panic(`Unsupported block content in markdown: ${JSON.stringify(block)}`);
|
|
174
72
|
}
|
|
73
|
+
ctx.listIndentWidths = outerListIndentWidths;
|
|
175
74
|
return out.join("\n");
|
|
176
75
|
}
|
|
177
76
|
//#endregion
|