@stll/folio-core 0.47.7 → 0.49.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 +565 -121
- package/dist/ai-edits/minimal-replacement.d.ts +64 -0
- package/dist/ai-edits/minimal-replacement.js +282 -0
- package/dist/controller/fontReadiness.js +3 -3
- package/dist/controller/hyphenationReadiness.d.ts +19 -0
- package/dist/controller/hyphenationReadiness.js +47 -0
- package/dist/controller/layoutPipeline.d.ts +3 -0
- package/dist/controller/layoutPipeline.js +70 -18
- package/dist/display-list/build/buildDisplayList.js +39 -12
- package/dist/display-list/build/pageFurniture.d.ts +7 -1
- package/dist/display-list/build/pageFurniture.js +21 -8
- package/dist/display-list/build/paragraphPrimitives.js +68 -11
- package/dist/display-list/build/tablePrimitives.js +10 -6
- package/dist/display-list/build/textBoxPrimitives.js +1 -1
- package/dist/display-list/build/unsupported.d.ts +2 -2
- package/dist/display-list/build/unsupported.js +0 -0
- package/dist/display-list/dom/renderDisplayListToDom.js +0 -1
- package/dist/docx/attributeRemainder.js +10 -2
- package/dist/docx/blockContentParser.d.ts +2 -0
- package/dist/docx/blockContentParser.js +79 -64
- package/dist/docx/bulletMarkers.d.ts +18 -2
- package/dist/docx/bulletMarkers.js +27 -2
- package/dist/docx/commentParser.d.ts +2 -1
- package/dist/docx/commentParser.js +57 -45
- package/dist/docx/containerChildren.d.ts +21 -8
- package/dist/docx/containerChildren.js +39 -9
- package/dist/docx/documentParser.d.ts +5 -1
- package/dist/docx/documentParser.js +8 -5
- package/dist/docx/documentSectionFacts.d.ts +22 -0
- package/dist/docx/documentSectionFacts.js +43 -0
- package/dist/docx/drawingGroupChildren.d.ts +60 -0
- package/dist/docx/drawingGroupChildren.js +176 -0
- package/dist/docx/drawingUtils.js +3 -0
- package/dist/docx/fieldParser.d.ts +8 -1
- package/dist/docx/fieldParser.js +47 -3
- package/dist/docx/fontTableParser.js +34 -27
- package/dist/docx/footnoteParser.d.ts +3 -2
- package/dist/docx/footnoteParser.js +15 -12
- package/dist/docx/groupDrawingParser.d.ts +9 -2
- package/dist/docx/groupDrawingParser.js +125 -37
- package/dist/docx/headerFooterParser.d.ts +7 -2
- package/dist/docx/headerFooterParser.js +15 -5
- package/dist/docx/hyperlinkParser.d.ts +48 -36
- package/dist/docx/hyperlinkParser.js +97 -82
- package/dist/docx/numberingParser.js +108 -84
- package/dist/docx/packageParts.d.ts +45 -1
- package/dist/docx/packageParts.js +93 -2
- package/dist/docx/paraIdAttribute.d.ts +3 -2
- package/dist/docx/paragraphParser.d.ts +5 -1
- package/dist/docx/paragraphParser.js +468 -365
- package/dist/docx/paragraphProperties.js +123 -109
- package/dist/docx/paragraphPropertySource.d.ts +6 -1
- package/dist/docx/paragraphPropertySource.js +9 -1
- package/dist/docx/paragraphTextBoxEnrichment.d.ts +2 -1
- package/dist/docx/paragraphTextBoxEnrichment.js +143 -10
- package/dist/docx/parser.d.ts +7 -1
- package/dist/docx/parser.js +33 -16
- package/dist/docx/previewBudget.d.ts +55 -33
- package/dist/docx/previewBudget.js +59 -65
- package/dist/docx/rezip.js +41 -58
- package/dist/docx/runParser.d.ts +4 -1
- package/dist/docx/runParser.js +182 -184
- package/dist/docx/sdtProperties.js +87 -84
- package/dist/docx/sectionParser.js +169 -160
- package/dist/docx/selectiveSaveFlags.d.ts +10 -3
- package/dist/docx/selectiveSaveFlags.js +1 -1
- package/dist/docx/selectiveXmlPatch.d.ts +56 -34
- package/dist/docx/selectiveXmlPatch.js +222 -115
- package/dist/docx/serializer/groupTextBoxWriteBack.d.ts +12 -0
- package/dist/docx/serializer/groupTextBoxWriteBack.js +101 -0
- package/dist/docx/serializer/paragraphSerializer.js +47 -42
- package/dist/docx/serializer/runSerializer.d.ts +5 -1
- package/dist/docx/serializer/runSerializer.js +4 -3
- package/dist/docx/serializer/settingsSerializer.js +19 -1
- package/dist/docx/settingsParser.js +8 -0
- package/dist/docx/shapeAlternateContent.d.ts +25 -0
- package/dist/docx/shapeAlternateContent.js +52 -0
- package/dist/docx/streamingXmlParser.d.ts +6 -2
- package/dist/docx/streamingXmlParser.js +12 -7
- package/dist/docx/styleParser.js +34 -8
- package/dist/docx/tableParser.d.ts +21 -12
- package/dist/docx/tableParser.js +518 -441
- package/dist/docx/textBoxParser.d.ts +18 -5
- package/dist/docx/textBoxParser.js +12 -6
- package/dist/docx/verbatimCapture.d.ts +10 -8
- package/dist/docx/verbatimCapture.js +45 -2
- package/dist/docx/vmlImageParser.d.ts +15 -13
- package/dist/docx/vmlImageParser.js +75 -60
- package/dist/docx/vmlPreview.d.ts +3 -3
- package/dist/docx/vmlPreview.js +3 -4
- package/dist/docx/xmlNamespaceContext.d.ts +9 -0
- package/dist/docx/xmlNamespaceContext.js +54 -0
- package/dist/docx/xmlParser.d.ts +6 -3
- package/dist/docx/xmlParser.js +11 -41
- package/dist/docx/xmlResourceLimits.d.ts +2 -1
- package/dist/docx/xmlResourceLimits.js +4 -1
- package/dist/fonts/headlessMeasure.js +0 -0
- package/dist/headless-layout.d.ts +11 -2
- package/dist/headless-layout.js +153 -107
- package/dist/internal/headlessRevisionResolution.js +50 -13
- package/dist/internal/paragraphFormattingSerialization.js +3 -3
- package/dist/layout-bridge/convert/endnoteLayout.d.ts +65 -0
- package/dist/layout-bridge/convert/endnoteLayout.js +227 -0
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +19 -3
- package/dist/layout-bridge/convert/footnoteLayout.js +40 -31
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -7
- package/dist/layout-bridge/convert/headerFooterLayout.js +5 -20
- package/dist/layout-bridge/convert/paragraphMarkFormatting.d.ts +10 -0
- package/dist/layout-bridge/convert/paragraphMarkFormatting.js +59 -0
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +29 -1
- package/dist/layout-bridge/convert/toFlowBlocks.js +284 -39
- package/dist/layout-bridge/engine/hitTest.js +5 -3
- package/dist/layout-bridge/engine/selectionRects.js +5 -3
- package/dist/layout-engine/anchorLayoutInCellCompatibility.d.ts +10 -0
- package/dist/layout-engine/anchorLayoutInCellCompatibility.js +22 -0
- package/dist/layout-engine/index.d.ts +2 -2
- package/dist/layout-engine/index.js +102 -14
- package/dist/layout-engine/justificationCompatibility.d.ts +1 -1
- package/dist/layout-engine/justificationCompatibility.js +9 -5
- package/dist/layout-engine/keep-together.d.ts +15 -6
- package/dist/layout-engine/keep-together.js +43 -16
- package/dist/layout-engine/layoutInstrumentation.d.ts +8 -2
- package/dist/layout-engine/layoutInstrumentation.js +8 -1
- package/dist/layout-engine/measure/advanceComposition.js +50 -7
- package/dist/layout-engine/measure/hyphenationDictionaries.d.ts +74 -0
- package/dist/layout-engine/measure/hyphenationDictionaries.js +138 -0
- package/dist/layout-engine/measure/hyphenationPreload.d.ts +11 -0
- package/dist/layout-engine/measure/hyphenationPreload.js +24 -0
- package/dist/layout-engine/measure/lineBreakProvider.d.ts +12 -2
- package/dist/layout-engine/measure/lineBreakProvider.js +30 -30
- package/dist/layout-engine/measure/lineBreaks.d.ts +6 -1
- package/dist/layout-engine/measure/lineBreaks.js +10 -3
- package/dist/layout-engine/measure/listMarkerWidth.d.ts +9 -6
- package/dist/layout-engine/measure/listMarkerWidth.js +20 -22
- package/dist/layout-engine/measure/measureBlocks.js +46 -10
- package/dist/layout-engine/measure/measureContainer.js +51 -8
- package/dist/layout-engine/measure/measureHelpers.d.ts +15 -3
- package/dist/layout-engine/measure/measureHelpers.js +34 -8
- package/dist/layout-engine/measure/measureParagraph.js +143 -101
- package/dist/layout-engine/measure/measureTypes.d.ts +5 -0
- package/dist/layout-engine/measure/smallCapsCasing.d.ts +56 -0
- package/dist/layout-engine/measure/smallCapsCasing.js +88 -0
- package/dist/layout-engine/measure/tabCalculator.d.ts +2 -0
- package/dist/layout-engine/measure/tabCalculator.js +2 -1
- package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
- package/dist/layout-engine/measure/tableCellFloating.js +51 -19
- package/dist/layout-engine/measure/tableCellGrid.d.ts +28 -3
- package/dist/layout-engine/measure/tableCellGrid.js +45 -5
- package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +2 -1
- package/dist/layout-engine/noteAreaFlow.d.ts +19 -0
- package/dist/layout-engine/noteAreaFlow.js +83 -0
- package/dist/layout-engine/paginator.d.ts +12 -1
- package/dist/layout-engine/paginator.js +18 -2
- package/dist/layout-engine/paragraphSpacing.d.ts +4 -2
- package/dist/layout-engine/paragraphSpacing.js +2 -1
- package/dist/layout-engine/tableRowBreak.d.ts +8 -1
- package/dist/layout-engine/tableRowBreak.js +25 -2
- package/dist/layout-engine/types.d.ts +108 -3
- package/dist/layout-engine/types.js +96 -1
- package/dist/layout-painter/index.d.ts +3 -0
- package/dist/layout-painter/renderPage.js +32 -83
- package/dist/layout-painter/renderParagraph.d.ts +6 -1
- package/dist/layout-painter/renderParagraph.js +75 -26
- package/dist/layout-painter/renderTable.js +26 -13
- package/dist/layout-painter/renderTextBox.d.ts +12 -2
- package/dist/layout-painter/renderTextBox.js +26 -2
- package/dist/prosemirror/alternateContentAttrs.d.ts +9 -0
- package/dist/prosemirror/alternateContentAttrs.js +35 -0
- package/dist/prosemirror/attrs/index.d.ts +9 -9
- package/dist/prosemirror/attrs/index.js +133 -11
- package/dist/prosemirror/commands/comments.js +51 -41
- package/dist/prosemirror/contentControlRevisions.d.ts +43 -0
- package/dist/prosemirror/contentControlRevisions.js +84 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +54 -23
- package/dist/prosemirror/conversion/markInterner.d.ts +21 -0
- package/dist/prosemirror/conversion/markInterner.js +90 -0
- package/dist/prosemirror/conversion/toProseDoc.js +117 -58
- package/dist/prosemirror/extensions/core/DocExtension.js +2 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -0
- package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.d.ts +7 -7
- package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -7
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +6 -2
- package/dist/prosemirror/extensions/marks/markUtils.js +39 -51
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +6 -3
- package/dist/prosemirror/extensions/nodes/SdtExtension.js +9 -2
- package/dist/prosemirror/extensions/nodes/ShapeExtension.js +1 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +5 -1
- package/dist/prosemirror/listMarker.d.ts +1 -0
- package/dist/prosemirror/listMarker.js +4 -2
- package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
- package/dist/prosemirror/listRenderingAttrs.js +3 -0
- package/dist/prosemirror/paragraphDirection.d.ts +29 -2
- package/dist/prosemirror/paragraphDirection.js +21 -2
- package/dist/prosemirror/plugins/suggestionMode.js +37 -8
- package/dist/prosemirror/rejoinRunCarriers.d.ts +27 -0
- package/dist/prosemirror/rejoinRunCarriers.js +66 -0
- package/dist/prosemirror/runIdentityAcrossRevisions.d.ts +10 -0
- package/dist/prosemirror/runIdentityAcrossRevisions.js +90 -0
- package/dist/prosemirror/schema/nodes.d.ts +50 -6
- package/dist/prosemirror/textBoxHostParagraph.d.ts +13 -0
- package/dist/prosemirror/textBoxHostParagraph.js +21 -0
- package/dist/prosemirror/validation.js +91 -80
- package/dist/types/content.d.ts +2 -2
- package/dist/utils/createDocument.js +10 -1
- package/dist/utils/scriptSegments.d.ts +33 -4
- package/dist/utils/scriptSegments.js +39 -6
- package/dist/utils/textFormattingMerge.d.ts +17 -3
- package/dist/utils/textFormattingMerge.js +18 -12
- package/dist/utils/trailingText.d.ts +22 -0
- package/dist/utils/trailingText.js +32 -0
- package/package.json +2 -2
- package/dist/layout-engine/justifiedLineFit.d.ts +0 -7
- package/dist/layout-engine/justifiedLineFit.js +0 -6
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { expectRunIdentityMarkAttrs } from "./attrs/index.js";
|
|
2
|
+
import "./extensions/nodes/SdtExtension.js";
|
|
3
|
+
import { RUN_IDENTITY_MARK_NAME } from "./runIdentity.js";
|
|
4
|
+
import { Fragment, Mark } from "prosemirror-model";
|
|
5
|
+
//#region src/prosemirror/runIdentityAcrossRevisions.ts
|
|
6
|
+
/**
|
|
7
|
+
* One run identity for the pieces of a `w:r` a tracked change cut.
|
|
8
|
+
*
|
|
9
|
+
* A revision inside a run splits it: `<w:r a>Sel</w:r><w:del><w:r a>ler</w:r></w:del>`,
|
|
10
|
+
* `<w:r a>Sel</w:r><w:ins>…</w:ins><w:r a>ler</w:r>`, or a `w:rPrChange` on
|
|
11
|
+
* one piece of the run only. Read back, each
|
|
12
|
+
* `w:r` is its own authored run, so resolving the revision would leave two
|
|
13
|
+
* runs where the source had one. The package cannot say whether the two were
|
|
14
|
+
* one run, but runs that carry the same attributes and that only revised
|
|
15
|
+
* content holds apart are what such a cut writes, so the later piece takes the
|
|
16
|
+
* earlier one's identity. The pieces stay separate runs while the revision
|
|
17
|
+
* holds them apart, and become one run once it is resolved and they state the
|
|
18
|
+
* same properties again (a run joins its owner only then, see `fromProseDoc`).
|
|
19
|
+
*
|
|
20
|
+
* Runs the package writes side by side under the same revision state keep
|
|
21
|
+
* their own identities.
|
|
22
|
+
*/
|
|
23
|
+
const REVISION_MARK_NAMES = /* @__PURE__ */ new Set([
|
|
24
|
+
"insertion",
|
|
25
|
+
"deletion",
|
|
26
|
+
"runPropertyChange"
|
|
27
|
+
]);
|
|
28
|
+
const identityOf = (node) => node.marks.find((mark) => mark.type.name === RUN_IDENTITY_MARK_NAME);
|
|
29
|
+
const revisionMarksOf = (node) => node.marks.filter((mark) => REVISION_MARK_NAMES.has(mark.type.name));
|
|
30
|
+
/** The identity's attrs without the id: what the run carries. */
|
|
31
|
+
const payloadKey = (identity) => JSON.stringify({
|
|
32
|
+
...expectRunIdentityMarkAttrs(identity),
|
|
33
|
+
id: 0
|
|
34
|
+
});
|
|
35
|
+
/** Whether `right` continues `left`'s run across a revision boundary. */
|
|
36
|
+
const continuesRun = ({ left, right, bridged }) => {
|
|
37
|
+
const leftIdentity = identityOf(left);
|
|
38
|
+
const rightIdentity = identityOf(right);
|
|
39
|
+
if (!leftIdentity || !rightIdentity || leftIdentity.eq(rightIdentity)) return false;
|
|
40
|
+
return (bridged || !Mark.sameSet(revisionMarksOf(left), revisionMarksOf(right))) && payloadKey(leftIdentity) === payloadKey(rightIdentity);
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* `nodes`, one inline container's content, with each run a revision cut given
|
|
44
|
+
* the identity of the run it was cut from. A control is a container of its
|
|
45
|
+
* own. `nodes` itself comes back when nothing changes.
|
|
46
|
+
*/
|
|
47
|
+
const continueRunIdentitiesAcrossRevisions = (nodes) => {
|
|
48
|
+
const renamed = /* @__PURE__ */ new Map();
|
|
49
|
+
/** The last run with an identity, while only revised content follows it. */
|
|
50
|
+
let anchor;
|
|
51
|
+
let bridged = false;
|
|
52
|
+
let changed = false;
|
|
53
|
+
const result = nodes.map((node) => {
|
|
54
|
+
if (node.type.name === "sdt") {
|
|
55
|
+
anchor = void 0;
|
|
56
|
+
const children = [];
|
|
57
|
+
node.forEach((child) => {
|
|
58
|
+
children.push(child);
|
|
59
|
+
});
|
|
60
|
+
const continued = continueRunIdentitiesAcrossRevisions(children);
|
|
61
|
+
if (continued === children) return node;
|
|
62
|
+
changed = true;
|
|
63
|
+
return node.copy(Fragment.fromArray([...continued]));
|
|
64
|
+
}
|
|
65
|
+
const identity = identityOf(node);
|
|
66
|
+
if (!identity) {
|
|
67
|
+
if (anchor && revisionMarksOf(node).length > 0) bridged = true;
|
|
68
|
+
else anchor = void 0;
|
|
69
|
+
return node;
|
|
70
|
+
}
|
|
71
|
+
const id = expectRunIdentityMarkAttrs(identity).id;
|
|
72
|
+
let replacement = renamed.get(id);
|
|
73
|
+
if (!replacement && anchor && continuesRun({
|
|
74
|
+
left: anchor,
|
|
75
|
+
right: node,
|
|
76
|
+
bridged
|
|
77
|
+
})) {
|
|
78
|
+
replacement = identityOf(anchor);
|
|
79
|
+
if (replacement) renamed.set(id, replacement);
|
|
80
|
+
}
|
|
81
|
+
const next = replacement ? node.mark(replacement.addToSet(node.marks)) : node;
|
|
82
|
+
changed ||= next !== node;
|
|
83
|
+
anchor = next;
|
|
84
|
+
bridged = false;
|
|
85
|
+
return next;
|
|
86
|
+
});
|
|
87
|
+
return changed ? result : nodes;
|
|
88
|
+
};
|
|
89
|
+
//#endregion
|
|
90
|
+
export { continueRunIdentitiesAcrossRevisions };
|
|
@@ -167,6 +167,8 @@ type ParagraphAttrs = {
|
|
|
167
167
|
listLevelNumFmts?: document_d_exports.CounterFormat[];
|
|
168
168
|
/** Initial counter for each level used by multi-level marker templates. */
|
|
169
169
|
listLevelStarts?: number[];
|
|
170
|
+
/** Custom tab stops of the numbering level (`w:lvl/w:pPr/w:tabs`). */
|
|
171
|
+
listLevelTabs?: document_d_exports.TabStop[];
|
|
170
172
|
/** Abstract numbering ID shared by numbering instances. */
|
|
171
173
|
listAbstractNumId?: number;
|
|
172
174
|
/** Numbering start override for this numId/level. */
|
|
@@ -200,10 +202,12 @@ type ParagraphAttrs = {
|
|
|
200
202
|
/** Internal table-style run overlay, used to resolve body-run provenance. */
|
|
201
203
|
_tableRunFormatting?: document_d_exports.TextFormatting;
|
|
202
204
|
/**
|
|
203
|
-
* Base text direction as a discriminated union (undecided when absent).
|
|
204
|
-
* to the
|
|
205
|
-
* `source` discriminates an
|
|
206
|
-
*
|
|
205
|
+
* Base text direction as a discriminated union (undecided when absent).
|
|
206
|
+
* Maps to the OOXML `w:bidi` tri-state via `directionToBidi` (layout) or
|
|
207
|
+
* `directionToAuthoredBidi` (serialization); the `source` discriminates an
|
|
208
|
+
* authoritative manual/import decision — the only one that is ever
|
|
209
|
+
* serialized — from a re-evaluable, view-only auto-detected one. See
|
|
210
|
+
* `paragraphDirection.ts`.
|
|
207
211
|
*/
|
|
208
212
|
direction?: ParagraphDirection | null;
|
|
209
213
|
/** The stated `w:outlineLvl`, style-resolved: a heading level or body text. */
|
|
@@ -325,7 +329,7 @@ type ParagraphPropertyChangeAttrs = Omit<document_d_exports.ParagraphPropertyCha
|
|
|
325
329
|
};
|
|
326
330
|
previousFormatting?: Omit<document_d_exports.ParagraphFormatting, "numPr"> & {
|
|
327
331
|
numPr?: ParagraphAttrs["numPr"] | null;
|
|
328
|
-
} & Partial<Pick<ParagraphAttrs, "listIsBullet" | "listIsLegal" | "listNumFmt" | "listMarker" | "listMarkerTemplate" | "listMarkerHidden" | "listMarkerFormatting" | "listMarkerAlignment" | "listMarkerSuffix" | "listMarkerAllCaps" | "listImplicitChildLevelAdvances" | "listMarkerSecondSlotOffsetTwips" | "listLevelNumFmts" | "listLevelStarts" | "listAbstractNumId" | "listStartOverride" | "lineSpacingExplicit" | "direction" | "_autospacingBase">>;
|
|
332
|
+
} & Partial<Pick<ParagraphAttrs, "listIsBullet" | "listIsLegal" | "listNumFmt" | "listMarker" | "listMarkerTemplate" | "listMarkerHidden" | "listMarkerFormatting" | "listMarkerAlignment" | "listMarkerSuffix" | "listMarkerAllCaps" | "listImplicitChildLevelAdvances" | "listMarkerSecondSlotOffsetTwips" | "listLevelNumFmts" | "listLevelStarts" | "listLevelTabs" | "listAbstractNumId" | "listStartOverride" | "lineSpacingExplicit" | "direction" | "_autospacingBase">>;
|
|
329
333
|
currentFormatting?: document_d_exports.ParagraphFormatting;
|
|
330
334
|
};
|
|
331
335
|
/**
|
|
@@ -537,6 +541,13 @@ type FieldAttrs = {
|
|
|
537
541
|
fldLock?: boolean;
|
|
538
542
|
/** Field is dirty and should be recalculated by the host application */
|
|
539
543
|
dirty?: boolean;
|
|
544
|
+
/**
|
|
545
|
+
* `displayText` is a rendering fallback folio synthesized (e.g. a legacy
|
|
546
|
+
* `FORMCHECKBOX` with no cached result run), not authored content. A save
|
|
547
|
+
* omits it from the field's result so an unedited field keeps its
|
|
548
|
+
* original, resultless bytes. See `ComplexField.fieldResultIsFallback`.
|
|
549
|
+
*/
|
|
550
|
+
fieldResultIsFallback?: boolean;
|
|
540
551
|
};
|
|
541
552
|
/**
|
|
542
553
|
* Math equation node attributes
|
|
@@ -638,10 +649,21 @@ type BlockSdtAttrs = {
|
|
|
638
649
|
/** Verbatim XML for sdt siblings after sdtContent (range markers). */
|
|
639
650
|
rawSdtChildrenAfterContent?: string;
|
|
640
651
|
};
|
|
652
|
+
/**
|
|
653
|
+
* The `mc:AlternateContent` a shape or text box was read from, with a
|
|
654
|
+
* fingerprint of the node it was attached to. `fromProseDoc` hands the element
|
|
655
|
+
* back to the model only while the node still matches the fingerprint.
|
|
656
|
+
*/
|
|
657
|
+
type AlternateContentAttrs = {
|
|
658
|
+
xml: string;
|
|
659
|
+
fingerprint: string;
|
|
660
|
+
};
|
|
641
661
|
/**
|
|
642
662
|
* Shape node attributes
|
|
643
663
|
*/
|
|
644
664
|
type ShapeAttrs = {
|
|
665
|
+
/** The source `mc:AlternateContent`; see {@link AlternateContentAttrs}. */
|
|
666
|
+
_docxAlternateContent?: AlternateContentAttrs;
|
|
645
667
|
/** Shape type preset */
|
|
646
668
|
shapeType?: string;
|
|
647
669
|
/** Preset geometry adjustments serialized as JSON. */
|
|
@@ -781,6 +803,11 @@ type TextBoxAttrs = {
|
|
|
781
803
|
title?: string;
|
|
782
804
|
/** Fill color as CSS color */
|
|
783
805
|
fillColor?: string;
|
|
806
|
+
/**
|
|
807
|
+
* The authored gradient fill, carried whole: `fillColor` cannot state a
|
|
808
|
+
* gradient, so the box paints and saves from this instead.
|
|
809
|
+
*/
|
|
810
|
+
gradientFill?: document_d_exports.ShapeFill;
|
|
784
811
|
/** Outline width in pixels */
|
|
785
812
|
outlineWidth?: number;
|
|
786
813
|
/** Outline color as CSS color */
|
|
@@ -839,12 +866,19 @@ type TextBoxAttrs = {
|
|
|
839
866
|
wrapEffectExtentSlots?: document_d_exports.EffectExtentSlots;
|
|
840
867
|
/** `wp:wrapPolygon` as authored, in the path's own units. */
|
|
841
868
|
wrapPolygon?: document_d_exports.ImageWrapPolygon;
|
|
869
|
+
/** The source `mc:AlternateContent`; see {@link AlternateContentAttrs}. */
|
|
870
|
+
_docxAlternateContent?: AlternateContentAttrs;
|
|
842
871
|
/** Original DOCX placement hint for save-path reconstruction. */
|
|
843
872
|
_docxPlacement?: "standalone" | "inlineWithPrevious";
|
|
844
873
|
/** Original DOCX paragraph group for standalone text-box reconstruction. */
|
|
845
874
|
_docxGroupId?: string;
|
|
846
875
|
/** Inline anchor linking this block node to its source run position. */
|
|
847
876
|
_docxAnchorId?: string;
|
|
877
|
+
/**
|
|
878
|
+
* The DrawingML group child this text box was read from; the writer puts its
|
|
879
|
+
* text back into the group rather than writing a drawing of its own.
|
|
880
|
+
*/
|
|
881
|
+
_docxGroupChild?: document_d_exports.DrawingGroupChild;
|
|
848
882
|
/**
|
|
849
883
|
* Ownership of the schema-required placeholder paragraph. A source text
|
|
850
884
|
* body with no children needs one paragraph while it is editable, but that
|
|
@@ -878,6 +912,16 @@ type TextBoxAttrs = {
|
|
|
878
912
|
* itself and keeps its own.
|
|
879
913
|
*/
|
|
880
914
|
_preservedAttributes?: document_d_exports.PreservedAttribute[];
|
|
915
|
+
/**
|
|
916
|
+
* The paragraph properties of the `w:p` this node was lifted out of.
|
|
917
|
+
*
|
|
918
|
+
* An inline drawing is run content of its paragraph, so that paragraph's
|
|
919
|
+
* spacing, indentation and alignment still place the box and must be
|
|
920
|
+
* written back around it. Only a `"standalone"` placement has a host to
|
|
921
|
+
* speak for. The host's identity (`paraId`, source token, attribute
|
|
922
|
+
* remainder) is not carried here: a copied node must not duplicate it.
|
|
923
|
+
*/
|
|
924
|
+
_docxHostParagraph?: Omit<ParagraphAttrs, "paraId" | "textId" | "_preservedAttributes">;
|
|
881
925
|
};
|
|
882
926
|
/** Internal inline position marker for an extracted text box block. */
|
|
883
927
|
type TextBoxAnchorAttrs = {
|
|
@@ -1181,4 +1225,4 @@ type TableCellAttrs = {
|
|
|
1181
1225
|
_docxVMergeContinuationCells?: unknown;
|
|
1182
1226
|
};
|
|
1183
1227
|
//#endregion
|
|
1184
|
-
export { AuthoredEmuAttrs, BlockSdtAttrs, BookmarkBoundaryAttrs, CommentReferenceAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, ImagePositionAttrs, MathAttrs, PRESERVED_XML_LEVELS, PageBreakRunAttrs, ParagraphAttrs, ParagraphAttrsPatch, ParagraphPropertyChangeAttrs, PreservedBlockAttrs, PreservedXmlAttrs, PreservedXmlLevel, SdtAttrs, ShapeAttrs, SuggestedStructuralMarker, SymbolAttrs, TEXT_BOX_TEXT_BODY_CONTENT_STATE_TYPES, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAnchorAttrs, TextBoxAttrs, TextBoxTextBodyContentState };
|
|
1228
|
+
export { AlternateContentAttrs, AuthoredEmuAttrs, BlockSdtAttrs, BookmarkBoundaryAttrs, CommentReferenceAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, ImagePositionAttrs, MathAttrs, PRESERVED_XML_LEVELS, PageBreakRunAttrs, ParagraphAttrs, ParagraphAttrsPatch, ParagraphPropertyChangeAttrs, PreservedBlockAttrs, PreservedXmlAttrs, PreservedXmlLevel, SdtAttrs, ShapeAttrs, SuggestedStructuralMarker, SymbolAttrs, TEXT_BOX_TEXT_BODY_CONTENT_STATE_TYPES, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAnchorAttrs, TextBoxAttrs, TextBoxTextBodyContentState };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Node } from "prosemirror-model";
|
|
2
|
+
//#region src/prosemirror/textBoxHostParagraph.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* The `w:p` a standalone text box was lifted out of, as a childless paragraph
|
|
5
|
+
* node over the host's paragraph attributes, or `undefined` when the box
|
|
6
|
+
* carries none.
|
|
7
|
+
*
|
|
8
|
+
* Building the node runs the carried attributes through the paragraph schema,
|
|
9
|
+
* so every consumer reads them with the validation any paragraph's get.
|
|
10
|
+
*/
|
|
11
|
+
declare const textBoxHostParagraph: (textBox: Node) => Node | undefined;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { textBoxHostParagraph };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { expectTextBoxAttrs } from "./attrs/index.js";
|
|
2
|
+
//#region src/prosemirror/textBoxHostParagraph.ts
|
|
3
|
+
const hostParagraphs = /* @__PURE__ */ new WeakMap();
|
|
4
|
+
/**
|
|
5
|
+
* The `w:p` a standalone text box was lifted out of, as a childless paragraph
|
|
6
|
+
* node over the host's paragraph attributes, or `undefined` when the box
|
|
7
|
+
* carries none.
|
|
8
|
+
*
|
|
9
|
+
* Building the node runs the carried attributes through the paragraph schema,
|
|
10
|
+
* so every consumer reads them with the validation any paragraph's get.
|
|
11
|
+
*/
|
|
12
|
+
const textBoxHostParagraph = (textBox) => {
|
|
13
|
+
const cached = hostParagraphs.get(textBox);
|
|
14
|
+
if (cached !== void 0) return cached ?? void 0;
|
|
15
|
+
const host = expectTextBoxAttrs(textBox)._docxHostParagraph;
|
|
16
|
+
const paragraph = host ? textBox.type.schema.nodes["paragraph"]?.create(host) : void 0;
|
|
17
|
+
hostParagraphs.set(textBox, paragraph ?? null);
|
|
18
|
+
return paragraph;
|
|
19
|
+
};
|
|
20
|
+
//#endregion
|
|
21
|
+
export { textBoxHostParagraph };
|
|
@@ -303,88 +303,99 @@ const validateNodeAttrs = (node, path, issues) => {
|
|
|
303
303
|
});
|
|
304
304
|
}
|
|
305
305
|
};
|
|
306
|
+
/**
|
|
307
|
+
* Marks already validated with no issues. A mark's attrs never change, and a
|
|
308
|
+
* conversion shares one instance per distinct mark across thousands of runs,
|
|
309
|
+
* so each distinct mark is validated once.
|
|
310
|
+
*/
|
|
311
|
+
const validMarks = /* @__PURE__ */ new WeakSet();
|
|
306
312
|
const validateMarks = (marks, path, issues) => {
|
|
307
313
|
for (const [index, mark] of marks.entries()) {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
314
|
+
if (validMarks.has(mark)) continue;
|
|
315
|
+
const issueCount = issues.length;
|
|
316
|
+
validateMark(mark, `${path}.marks[${index}]`, issues);
|
|
317
|
+
if (issues.length === issueCount) validMarks.add(mark);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
const validateMark = (mark, markPath, issues) => {
|
|
321
|
+
switch (mark.type.name) {
|
|
322
|
+
case "bold":
|
|
323
|
+
case "italic":
|
|
324
|
+
case "subscript":
|
|
325
|
+
case "superscript":
|
|
326
|
+
case "allCaps":
|
|
327
|
+
case "smallCaps":
|
|
328
|
+
case "emboss":
|
|
329
|
+
case "imprint":
|
|
330
|
+
case "hidden":
|
|
331
|
+
case "textShadow":
|
|
332
|
+
case "textOutline":
|
|
333
|
+
case "rtl": return;
|
|
334
|
+
case "textEffect":
|
|
335
|
+
appendAttrIssues(markPath, readTextEffectMarkAttrs(mark), issues);
|
|
336
|
+
return;
|
|
337
|
+
case "underline":
|
|
338
|
+
appendAttrIssues(markPath, readUnderlineMarkAttrs(mark), issues);
|
|
339
|
+
return;
|
|
340
|
+
case "strike":
|
|
341
|
+
appendAttrIssues(markPath, readStrikeMarkAttrs(mark), issues);
|
|
342
|
+
return;
|
|
343
|
+
case "textColor":
|
|
344
|
+
appendAttrIssues(markPath, readTextColorMarkAttrs(mark), issues);
|
|
345
|
+
return;
|
|
346
|
+
case "highlight":
|
|
347
|
+
appendAttrIssues(markPath, readHighlightMarkAttrs(mark), issues);
|
|
348
|
+
return;
|
|
349
|
+
case "runShading":
|
|
350
|
+
appendAttrIssues(markPath, readRunShadingMarkAttrs(mark), issues);
|
|
351
|
+
return;
|
|
352
|
+
case "fontSize":
|
|
353
|
+
appendAttrIssues(markPath, readFontSizeMarkAttrs(mark), issues);
|
|
354
|
+
return;
|
|
355
|
+
case "fontFamily":
|
|
356
|
+
appendAttrIssues(markPath, readFontFamilyMarkAttrs(mark), issues);
|
|
357
|
+
return;
|
|
358
|
+
case "language":
|
|
359
|
+
appendAttrIssues(markPath, readLanguageMarkAttrs(mark), issues);
|
|
360
|
+
return;
|
|
361
|
+
case "characterSpacing":
|
|
362
|
+
appendAttrIssues(markPath, readCharacterSpacingMarkAttrs(mark), issues);
|
|
363
|
+
return;
|
|
364
|
+
case "characterStyle":
|
|
365
|
+
appendAttrIssues(markPath, readCharacterStyleMarkAttrs(mark), issues);
|
|
366
|
+
return;
|
|
367
|
+
case "emphasisMark":
|
|
368
|
+
appendAttrIssues(markPath, readEmphasisMarkAttrs(mark), issues);
|
|
369
|
+
return;
|
|
370
|
+
case "footnoteRef":
|
|
371
|
+
appendAttrIssues(markPath, readFootnoteRefMarkAttrs(mark), issues);
|
|
372
|
+
return;
|
|
373
|
+
case "comment":
|
|
374
|
+
appendAttrIssues(markPath, readCommentMarkAttrs(mark), issues);
|
|
375
|
+
return;
|
|
376
|
+
case "insertion":
|
|
377
|
+
case "deletion":
|
|
378
|
+
appendAttrIssues(markPath, readTrackedChangeMarkAttrs(mark), issues);
|
|
379
|
+
return;
|
|
380
|
+
case "runPropertyChange":
|
|
381
|
+
appendAttrIssues(markPath, readRunPropertyChangeMarkAttrs(mark), issues);
|
|
382
|
+
return;
|
|
383
|
+
case "runIdentity":
|
|
384
|
+
appendAttrIssues(markPath, readRunIdentityMarkAttrs(mark), issues);
|
|
385
|
+
return;
|
|
386
|
+
case "runFormattingOverride":
|
|
387
|
+
appendAttrIssues(markPath, readRunFormattingOverrideMarkAttrs(mark), issues);
|
|
388
|
+
return;
|
|
389
|
+
case "hyperlink":
|
|
390
|
+
appendAttrIssues(markPath, readHyperlinkMarkAttrs(mark), issues);
|
|
391
|
+
return;
|
|
392
|
+
case "inlineWrapper":
|
|
393
|
+
appendAttrIssues(markPath, readInlineWrapperMarkAttrs(mark), issues);
|
|
394
|
+
return;
|
|
395
|
+
default: issues.push({
|
|
396
|
+
path: `${markPath}.type.name`,
|
|
397
|
+
message: `Unsupported ProseMirror mark type ${mark.type.name}.`
|
|
398
|
+
});
|
|
388
399
|
}
|
|
389
400
|
};
|
|
390
401
|
const appendAttrIssues = (path, result, issues) => {
|
package/dist/types/content.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { BlockContent, BlockSdt, BookmarkEnd, BookmarkStart, BreakContent, Column, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, ComplexField, Deletion, DisplacedByCustomXml, DocumentBackground, DocumentBackgroundDrawing, DocumentBody, DrawingContent, DrawingRawXmlMode, EffectExtentSlots, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, ImageWrapPolygon, InlineSdt, Insertion, InstrTextContent, LineNumberRestart, MathEquation, MoveFrom, MoveFromRangeEnd, MoveFromRangeStart, MoveTo, MoveToRangeEnd, MoveToRangeStart, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, PageOrientation, Paragraph, ParagraphContent, ParagraphPropertyChange, PositionalTab, PositionedBookmarkMarker, PreservedAttribute, PreservedBlock, PreservedInline, PropertyChangeInfo, Run, RunContent, RunPropertyChange, SdtProperties, SdtType, Section, SectionProperties, SectionStart, Shape, ShapeContent, ShapeFill, ShapeGeometryAdjustment, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, SymbolContent, TabContent, Table, TableCell, TableCellBlock, TableCellPropertyChange, TableRow, TableRowPropertyChange, TableStructuralChangeInfo, TextBox, TextContent, TrackedChangeInfo, TrackedRunChange, TrackedRunContent, VerticalAlign, WrapDistanceSlots } from "@stll/docx-core/model";
|
|
2
|
-
export type { BlockContent, BlockSdt, BookmarkEnd, BookmarkStart, BreakContent, Column, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, ComplexField, Deletion, DisplacedByCustomXml, DocumentBackground, DocumentBackgroundDrawing, DocumentBody, DrawingContent, DrawingRawXmlMode, EffectExtentSlots, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, ImageWrapPolygon, InlineSdt, Insertion, InstrTextContent, LineNumberRestart, MathEquation, MoveFrom, MoveFromRangeEnd, MoveFromRangeStart, MoveTo, MoveToRangeEnd, MoveToRangeStart, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, PageOrientation, Paragraph, ParagraphContent, ParagraphPropertyChange, PositionalTab, PositionedBookmarkMarker, PreservedAttribute, PreservedBlock, PreservedInline, PropertyChangeInfo, Run, RunContent, RunPropertyChange, SdtProperties, SdtType, Section, SectionProperties, SectionStart, Shape, ShapeContent, ShapeFill, ShapeGeometryAdjustment, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, SymbolContent, TabContent, Table, TableCell, TableCellBlock, TableCellPropertyChange, TableRow, TableRowPropertyChange, TableStructuralChangeInfo, TextBox, TextContent, TrackedChangeInfo, TrackedRunChange, TrackedRunContent, VerticalAlign, WrapDistanceSlots };
|
|
1
|
+
import { BlockContent, BlockSdt, BookmarkEnd, BookmarkStart, BreakContent, Column, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, ComplexField, Deletion, DisplacedByCustomXml, DocumentBackground, DocumentBackgroundDrawing, DocumentBody, DrawingContent, DrawingGroupChild, DrawingRawXmlMode, EffectExtentSlots, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, ImageWrapPolygon, InlineSdt, Insertion, InstrTextContent, LineNumberRestart, MathEquation, MoveFrom, MoveFromRangeEnd, MoveFromRangeStart, MoveTo, MoveToRangeEnd, MoveToRangeStart, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, PageOrientation, Paragraph, ParagraphContent, ParagraphPropertyChange, PositionalTab, PositionedBookmarkMarker, PreservedAttribute, PreservedBlock, PreservedInline, PropertyChangeInfo, Run, RunContent, RunPropertyChange, SdtProperties, SdtType, Section, SectionProperties, SectionStart, Shape, ShapeAlternateContent, ShapeContent, ShapeFill, ShapeGeometryAdjustment, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, SymbolContent, TabContent, Table, TableCell, TableCellBlock, TableCellPropertyChange, TableRow, TableRowPropertyChange, TableStructuralChangeInfo, TextBox, TextContent, TrackedChangeInfo, TrackedRunChange, TrackedRunContent, VerticalAlign, WrapDistanceSlots } from "@stll/docx-core/model";
|
|
2
|
+
export type { BlockContent, BlockSdt, BookmarkEnd, BookmarkStart, BreakContent, Column, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, ComplexField, Deletion, DisplacedByCustomXml, DocumentBackground, DocumentBackgroundDrawing, DocumentBody, DrawingContent, DrawingGroupChild, DrawingRawXmlMode, EffectExtentSlots, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, ImageWrapPolygon, InlineSdt, Insertion, InstrTextContent, LineNumberRestart, MathEquation, MoveFrom, MoveFromRangeEnd, MoveFromRangeStart, MoveTo, MoveToRangeEnd, MoveToRangeStart, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, PageOrientation, Paragraph, ParagraphContent, ParagraphPropertyChange, PositionalTab, PositionedBookmarkMarker, PreservedAttribute, PreservedBlock, PreservedInline, PropertyChangeInfo, Run, RunContent, RunPropertyChange, SdtProperties, SdtType, Section, SectionProperties, SectionStart, Shape, ShapeAlternateContent, ShapeContent, ShapeFill, ShapeGeometryAdjustment, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, SymbolContent, TabContent, Table, TableCell, TableCellBlock, TableCellPropertyChange, TableRow, TableRowPropertyChange, TableStructuralChangeInfo, TextBox, TextContent, TrackedChangeInfo, TrackedRunChange, TrackedRunContent, VerticalAlign, WrapDistanceSlots };
|
|
@@ -2,6 +2,7 @@ import { BUILT_IN_STYLE_NAME, builtInHeadingStyleName } from "../docx/builtInSty
|
|
|
2
2
|
import "../docx/defaultParagraphStyle.js";
|
|
3
3
|
import { createParseWarningCollector } from "../docx/parseContext.js";
|
|
4
4
|
import { formatParseWarnings } from "../docx/parseWarningMessage.js";
|
|
5
|
+
import "../docx/settingsParser.js";
|
|
5
6
|
import { STYLE_SET_PART, normalizeDocumentStyleSet } from "../style-sets/styleSetNormalization.js";
|
|
6
7
|
import "../style-sets/types.js";
|
|
7
8
|
import { panic } from "better-result";
|
|
@@ -13,6 +14,12 @@ import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
|
|
|
13
14
|
* Provides functions to create new documents programmatically.
|
|
14
15
|
*/
|
|
15
16
|
/**
|
|
17
|
+
* `compatibilityMode` a new document declares, so it is laid out, and read
|
|
18
|
+
* back, with the current rules rather than the oldest ones a package without
|
|
19
|
+
* the setting gets.
|
|
20
|
+
*/
|
|
21
|
+
const NEW_DOCUMENT_COMPATIBILITY_MODE = 15;
|
|
22
|
+
/**
|
|
16
23
|
* Get default paragraph styles (matching Google Docs defaults)
|
|
17
24
|
*
|
|
18
25
|
* Font sizes are in half-points (e.g., 22 = 11pt, 40 = 20pt)
|
|
@@ -398,7 +405,9 @@ function createEmptyDocument(options = {}) {
|
|
|
398
405
|
if (styleSet?.numbering) docxPackage.numbering = structuredClone(styleSet.numbering);
|
|
399
406
|
if (styleSet?.theme) docxPackage.theme = structuredClone(styleSet.theme);
|
|
400
407
|
if (styleSet?.fontTable) docxPackage.fontTable = structuredClone(styleSet.fontTable);
|
|
401
|
-
|
|
408
|
+
const settings = styleSet?.settings ? structuredClone(styleSet.settings) : { defaultTabStop: 720 };
|
|
409
|
+
settings.compatibilityMode ??= NEW_DOCUMENT_COMPATIBILITY_MODE;
|
|
410
|
+
docxPackage.settings = settings;
|
|
402
411
|
const parseWarnings = styleSetWarnings();
|
|
403
412
|
const document = {
|
|
404
413
|
package: docxPackage,
|
|
@@ -50,8 +50,31 @@ declare function hasCjk(text: string): boolean;
|
|
|
50
50
|
* overlap the presentation forms below.
|
|
51
51
|
*/
|
|
52
52
|
declare function isComplexScriptCodePoint(cp: number): boolean;
|
|
53
|
-
/**
|
|
54
|
-
|
|
53
|
+
/**
|
|
54
|
+
* True when `w:rFonts/@w:hint="eastAsia"` moves a code point from the
|
|
55
|
+
* `w:hAnsi` slot to the `w:eastAsia` slot (ECMA-376 §17.3.2.26): the ranges
|
|
56
|
+
* the font-slot table resolves to the East Asian font whenever the hint is
|
|
57
|
+
* `eastAsia`. Basic Latin never moves, and neither do the accented letters of
|
|
58
|
+
* Latin-1 Supplement and the Latin Extended blocks, whose move the table also
|
|
59
|
+
* conditions on the run's East Asian language.
|
|
60
|
+
*/
|
|
61
|
+
declare function isEastAsiaHintCodePoint(cp: number): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Whether a run's `w:hint="eastAsia"` takes effect. A run under `w:cs` or
|
|
64
|
+
* `w:rtl` formats every character with the complex-script slot, which the
|
|
65
|
+
* hint does not override.
|
|
66
|
+
*/
|
|
67
|
+
declare function eastAsiaHintApplies(run: {
|
|
68
|
+
readonly eastAsiaHint?: boolean | undefined;
|
|
69
|
+
readonly forceComplexScript?: boolean | undefined;
|
|
70
|
+
readonly rtl?: boolean | undefined;
|
|
71
|
+
}): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Which font slot a single code point selects. CJK wins where ranges meet.
|
|
74
|
+
* `eastAsiaHint` is the run's effective `w:hint="eastAsia"`
|
|
75
|
+
* (see {@link eastAsiaHintApplies}).
|
|
76
|
+
*/
|
|
77
|
+
declare function scriptClassOf(cp: number, eastAsiaHint?: boolean): ScriptClass;
|
|
55
78
|
/**
|
|
56
79
|
* True when the text contains at least one complex-script code point. Callers
|
|
57
80
|
* use this to skip segmentation entirely on the common all-Latin path.
|
|
@@ -68,11 +91,17 @@ declare function isRightToLeftCodePoint(cp: number): boolean;
|
|
|
68
91
|
/** True when the text contains at least one right-to-left code point. */
|
|
69
92
|
declare function hasRightToLeft(text: string): boolean;
|
|
70
93
|
declare function hasComplexScript(text: string): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* True when some code point of the text selects the `w:eastAsia` slot: a CJK
|
|
96
|
+
* code point, or under an effective `w:hint="eastAsia"` one the hint moves.
|
|
97
|
+
*/
|
|
98
|
+
declare function hasEastAsiaSlotText(text: string, eastAsiaHint?: boolean): boolean;
|
|
71
99
|
/**
|
|
72
100
|
* Split text into maximal runs of one script class (CJK vs. non-CJK). Iterates
|
|
73
101
|
* by code point so astral ideographs (surrogate pairs) are never split between
|
|
74
102
|
* fonts. Empty input yields no segments; single-class input yields one.
|
|
103
|
+
* `eastAsiaHint` is the run's effective `w:hint="eastAsia"`.
|
|
75
104
|
*/
|
|
76
|
-
declare function segmentByScript(text: string): ScriptSegment[];
|
|
105
|
+
declare function segmentByScript(text: string, eastAsiaHint?: boolean): ScriptSegment[];
|
|
77
106
|
//#endregion
|
|
78
|
-
export { SCRIPT_CLASS, ScriptClass, ScriptSegment, hasCjk, hasComplexScript, hasRightToLeft, isCjkCodePoint, isComplexScriptCodePoint, isRightToLeftCodePoint, scriptClassOf, segmentByScript };
|
|
107
|
+
export { SCRIPT_CLASS, ScriptClass, ScriptSegment, eastAsiaHintApplies, hasCjk, hasComplexScript, hasEastAsiaSlotText, hasRightToLeft, isCjkCodePoint, isComplexScriptCodePoint, isEastAsiaHintCodePoint, isRightToLeftCodePoint, scriptClassOf, segmentByScript };
|
|
@@ -52,9 +52,32 @@ function hasCjk(text) {
|
|
|
52
52
|
function isComplexScriptCodePoint(cp) {
|
|
53
53
|
return cp >= 1424 && cp <= 1535 || cp >= 1536 && cp <= 1791 || cp >= 1792 && cp <= 1871 || cp >= 1872 && cp <= 1919 || cp >= 1920 && cp <= 1983 || cp >= 1984 && cp <= 2047 || cp >= 2048 && cp <= 2111 || cp >= 2112 && cp <= 2143 || cp >= 2144 && cp <= 2159 || cp >= 2160 && cp <= 2207 || cp >= 2208 && cp <= 2303 || cp >= 2304 && cp <= 3455 || cp >= 3456 && cp <= 3583 || cp >= 3584 && cp <= 3711 || cp >= 3712 && cp <= 3839 || cp >= 3840 && cp <= 4095 || cp >= 4096 && cp <= 4255 || cp >= 6016 && cp <= 6143 || cp >= 64285 && cp <= 64335 || cp >= 64336 && cp <= 65023 || cp >= 65136 && cp <= 65279 || cp >= 68864 && cp <= 68927 || cp >= 69312 && cp <= 69375 || cp >= 69424 && cp <= 69487 || cp >= 69488 && cp <= 69551 || cp >= 125184 && cp <= 125279 || cp >= 126464 && cp <= 126719;
|
|
54
54
|
}
|
|
55
|
-
/**
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
/**
|
|
56
|
+
* True when `w:rFonts/@w:hint="eastAsia"` moves a code point from the
|
|
57
|
+
* `w:hAnsi` slot to the `w:eastAsia` slot (ECMA-376 §17.3.2.26): the ranges
|
|
58
|
+
* the font-slot table resolves to the East Asian font whenever the hint is
|
|
59
|
+
* `eastAsia`. Basic Latin never moves, and neither do the accented letters of
|
|
60
|
+
* Latin-1 Supplement and the Latin Extended blocks, whose move the table also
|
|
61
|
+
* conditions on the run's East Asian language.
|
|
62
|
+
*/
|
|
63
|
+
function isEastAsiaHintCodePoint(cp) {
|
|
64
|
+
return cp === 161 || cp === 164 || cp === 167 || cp === 168 || cp === 170 || cp === 173 || cp === 175 || cp >= 176 && cp <= 180 || cp >= 182 && cp <= 186 || cp >= 188 && cp <= 191 || cp === 215 || cp === 247 || cp >= 688 && cp <= 879 || cp >= 880 && cp <= 1023 || cp >= 1024 && cp <= 1279 || cp >= 8192 && cp <= 10175 || cp >= 57344 && cp <= 63743 || cp >= 64256 && cp <= 64284;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Whether a run's `w:hint="eastAsia"` takes effect. A run under `w:cs` or
|
|
68
|
+
* `w:rtl` formats every character with the complex-script slot, which the
|
|
69
|
+
* hint does not override.
|
|
70
|
+
*/
|
|
71
|
+
function eastAsiaHintApplies(run) {
|
|
72
|
+
return run.eastAsiaHint === true && run.forceComplexScript !== true && run.rtl !== true;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Which font slot a single code point selects. CJK wins where ranges meet.
|
|
76
|
+
* `eastAsiaHint` is the run's effective `w:hint="eastAsia"`
|
|
77
|
+
* (see {@link eastAsiaHintApplies}).
|
|
78
|
+
*/
|
|
79
|
+
function scriptClassOf(cp, eastAsiaHint = false) {
|
|
80
|
+
if (isCjkCodePoint(cp) || eastAsiaHint && isEastAsiaHintCodePoint(cp)) return SCRIPT_CLASS.eastAsia;
|
|
58
81
|
if (isComplexScriptCodePoint(cp)) return SCRIPT_CLASS.complex;
|
|
59
82
|
return SCRIPT_CLASS.western;
|
|
60
83
|
}
|
|
@@ -83,16 +106,26 @@ function hasComplexScript(text) {
|
|
|
83
106
|
return false;
|
|
84
107
|
}
|
|
85
108
|
/**
|
|
109
|
+
* True when some code point of the text selects the `w:eastAsia` slot: a CJK
|
|
110
|
+
* code point, or under an effective `w:hint="eastAsia"` one the hint moves.
|
|
111
|
+
*/
|
|
112
|
+
function hasEastAsiaSlotText(text, eastAsiaHint = false) {
|
|
113
|
+
if (!eastAsiaHint) return hasCjk(text);
|
|
114
|
+
for (const ch of text) if (scriptClassOf(ch.codePointAt(0), true) === SCRIPT_CLASS.eastAsia) return true;
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
86
118
|
* Split text into maximal runs of one script class (CJK vs. non-CJK). Iterates
|
|
87
119
|
* by code point so astral ideographs (surrogate pairs) are never split between
|
|
88
120
|
* fonts. Empty input yields no segments; single-class input yields one.
|
|
121
|
+
* `eastAsiaHint` is the run's effective `w:hint="eastAsia"`.
|
|
89
122
|
*/
|
|
90
|
-
function segmentByScript(text) {
|
|
123
|
+
function segmentByScript(text, eastAsiaHint = false) {
|
|
91
124
|
const segments = [];
|
|
92
125
|
let current = "";
|
|
93
126
|
let currentScript = SCRIPT_CLASS.western;
|
|
94
127
|
for (const ch of text) {
|
|
95
|
-
const script = scriptClassOf(ch.codePointAt(0));
|
|
128
|
+
const script = scriptClassOf(ch.codePointAt(0), eastAsiaHint);
|
|
96
129
|
if (current.length === 0) {
|
|
97
130
|
current = ch;
|
|
98
131
|
currentScript = script;
|
|
@@ -116,4 +149,4 @@ function segmentByScript(text) {
|
|
|
116
149
|
return segments;
|
|
117
150
|
}
|
|
118
151
|
//#endregion
|
|
119
|
-
export { SCRIPT_CLASS, hasCjk, hasComplexScript, hasRightToLeft, isCjkCodePoint, isComplexScriptCodePoint, isRightToLeftCodePoint, scriptClassOf, segmentByScript };
|
|
152
|
+
export { SCRIPT_CLASS, eastAsiaHintApplies, hasCjk, hasComplexScript, hasEastAsiaSlotText, hasRightToLeft, isCjkCodePoint, isComplexScriptCodePoint, isEastAsiaHintCodePoint, isRightToLeftCodePoint, scriptClassOf, segmentByScript };
|
|
@@ -2,10 +2,24 @@ import { document_d_exports } from "../types/document.js";
|
|
|
2
2
|
//#region src/utils/textFormattingMerge.d.ts
|
|
3
3
|
declare const STYLE_TOGGLE_KEYS: readonly ["bold", "boldCs", "italic", "italicCs", "allCaps", "emboss", "imprint", "outline", "shadow", "smallCaps", "strike", "hidden"];
|
|
4
4
|
/**
|
|
5
|
-
* Merge
|
|
5
|
+
* Merge one style's own run-formatting declarations onto its already-resolved
|
|
6
|
+
* `w:basedOn` ancestor.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
8
|
+
* ECMA-376 §17.7.3 resolves a toggle property (bold, italic, allCaps, ...) for a
|
|
9
|
+
* single style tier by walking the `basedOn` chain from the style itself towards
|
|
10
|
+
* its root: read the value the style declares; if it declares none, move to the
|
|
11
|
+
* parent and repeat. The first value found — whether an explicit "on" or an
|
|
12
|
+
* explicit "off" — is that tier's value, and it is *not* combined with whatever
|
|
13
|
+
* a weaker ancestor further up the chain happened to say. A style's own
|
|
14
|
+
* `<w:b w:val="0"/>` therefore turns bold off outright, even when its base style
|
|
15
|
+
* is bold; it does not defer to the base.
|
|
16
|
+
*
|
|
17
|
+
* That is exactly last-defined-wins, i.e. `mergeTextFormatting`'s existing
|
|
18
|
+
* behaviour for every other property. The toggle behaviour §17.7.3 is actually
|
|
19
|
+
* known for — combining a table style's, a paragraph style's and a character
|
|
20
|
+
* style's resolved values by Boolean XOR — combines the *outputs* of separate
|
|
21
|
+
* `basedOn` walks like this one; it is not part of resolving a single walk, so
|
|
22
|
+
* it has no place in this function.
|
|
9
23
|
*/
|
|
10
24
|
declare function mergeStyleTextFormatting(target: document_d_exports.TextFormatting | undefined, source: document_d_exports.TextFormatting | undefined): document_d_exports.TextFormatting | undefined;
|
|
11
25
|
declare function mergeTextFormatting(target: document_d_exports.TextFormatting | undefined, source: document_d_exports.TextFormatting | undefined): document_d_exports.TextFormatting | undefined;
|