@stll/folio-core 0.6.1 → 0.8.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/blockRange.d.ts +13 -2
- package/dist/ai-edits/blockRange.js +23 -2
- package/dist/ai-edits/index.d.ts +4 -2
- package/dist/ai-edits/index.js +3 -1
- package/dist/ai-edits/scoped-reading.d.ts +9 -0
- package/dist/ai-edits/scoped-reading.js +60 -0
- package/dist/ai-edits/snapshot.js +13 -4
- package/dist/ai-edits/types.d.ts +44 -2
- package/dist/compat/eigenpal.d.ts +5 -2
- package/dist/compat/eigenpal.js +4 -1
- package/dist/controller/fontReadiness.d.ts +29 -0
- package/dist/controller/fontReadiness.js +139 -0
- package/dist/controller/layoutPipeline.js +86 -11
- package/dist/docx/blockContentParser.js +51 -8
- package/dist/docx/capabilities.d.ts +41 -0
- package/dist/docx/capabilities.js +322 -0
- package/dist/docx/compatibility.d.ts +34 -2
- package/dist/docx/compatibility.js +128 -38
- package/dist/docx/conformance.d.ts +6 -0
- package/dist/docx/conformance.js +18 -0
- package/dist/docx/ensureParaIds.d.ts +29 -0
- package/dist/docx/ensureParaIds.js +423 -0
- package/dist/docx/groupDrawingParser.d.ts +1 -1
- package/dist/docx/groupDrawingParser.js +49 -8
- package/dist/docx/numberingParser.js +1 -0
- package/dist/docx/paragraphParser.js +9 -0
- package/dist/docx/paragraphTextBoxEnrichment.js +141 -2
- package/dist/docx/parser.js +2 -0
- package/dist/docx/runParser.js +11 -2
- package/dist/docx/selectiveXmlPatch.d.ts +10 -1
- package/dist/docx/selectiveXmlPatch.js +1 -1
- package/dist/docx/serializer/paragraphSerializer.js +4 -0
- package/dist/docx/serializer/runSerializer.js +7 -2
- package/dist/docx/serializer/tableSerializer.js +4 -0
- package/dist/docx/server/boundedArchive.d.ts +24 -0
- package/dist/docx/server/boundedArchive.js +106 -0
- package/dist/docx/server/extractDocxText.d.ts +23 -0
- package/dist/docx/server/extractDocxText.js +154 -0
- package/dist/docx/tableParser.js +8 -0
- package/dist/docx/textBoxParser.js +6 -1
- package/dist/docx/vmlImageParser.js +145 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +4 -1
- package/dist/layout-bridge/convert/headerFooterLayout.js +16 -2
- package/dist/layout-bridge/convert/paragraphFrames.d.ts +7 -0
- package/dist/layout-bridge/convert/paragraphFrames.js +136 -0
- package/dist/layout-bridge/convert/toFlowBlocks.js +106 -13
- package/dist/layout-bridge/engine/hitTest.js +2 -1
- package/dist/layout-bridge/engine/selectionRects.js +2 -1
- package/dist/layout-engine/headerFooterRefs.d.ts +7 -0
- package/dist/layout-engine/headerFooterRefs.js +40 -0
- package/dist/layout-engine/index.d.ts +3 -2
- package/dist/layout-engine/index.js +125 -72
- package/dist/layout-engine/keep-together.d.ts +7 -5
- package/dist/layout-engine/keep-together.js +20 -4
- package/dist/layout-engine/measure/cache.js +2 -0
- package/dist/layout-engine/measure/listMarkerWidth.d.ts +3 -1
- package/dist/layout-engine/measure/listMarkerWidth.js +23 -4
- package/dist/layout-engine/measure/measureBlocks.d.ts +3 -0
- package/dist/layout-engine/measure/measureBlocks.js +133 -51
- package/dist/layout-engine/measure/measureParagraph.js +42 -15
- package/dist/layout-engine/measure/tableCellGrid.d.ts +15 -0
- package/dist/layout-engine/measure/tableCellGrid.js +62 -0
- package/dist/layout-engine/measure/textBoxParagraphLayout.d.ts +18 -0
- package/dist/layout-engine/measure/textBoxParagraphLayout.js +32 -0
- package/dist/layout-engine/paginator.d.ts +2 -1
- package/dist/layout-engine/paginator.js +17 -8
- package/dist/layout-engine/paragraphFrame.d.ts +22 -0
- package/dist/layout-engine/paragraphFrame.js +17 -0
- package/dist/layout-engine/paragraphSequence.d.ts +7 -0
- package/dist/layout-engine/paragraphSequence.js +25 -0
- package/dist/layout-engine/paragraphSpacing.d.ts +17 -0
- package/dist/layout-engine/paragraphSpacing.js +30 -0
- package/dist/layout-engine/renderedBreakReconciliation.d.ts +58 -0
- package/dist/layout-engine/renderedBreakReconciliation.js +63 -0
- package/dist/layout-engine/types.d.ts +31 -10
- package/dist/layout-engine/types.js +15 -2
- package/dist/layout-painter/renderPage.js +2 -2
- package/dist/layout-painter/renderParagraph.js +94 -10
- package/dist/layout-painter/renderTable.js +42 -12
- package/dist/layout-painter/renderTextBox.js +17 -7
- package/dist/managers/DocumentLoaderManager.js +1 -1
- package/dist/paged-layout/sectionBlockWidths.d.ts +3 -0
- package/dist/paged-layout/sectionBlockWidths.js +9 -0
- package/dist/paged-layout/sectionGeometry.js +1 -1
- package/dist/prosemirror/attrs/index.js +11 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +2 -0
- package/dist/prosemirror/conversion/toProseDoc.js +29 -23
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -0
- package/dist/prosemirror/extensions/features/ListExtension.js +1 -0
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +68 -16
- package/dist/prosemirror/extensions/nodes/TableExtension.js +1 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +2 -1
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +7 -0
- package/dist/prosemirror/schema/nodes.d.ts +6 -3
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
- package/dist/prosemirror/utils/tabCalculator.js +1 -1
- package/dist/server.d.ts +6 -2
- package/dist/server.js +5 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/utils/createDocument.js +26 -18
- package/dist/utils/formatToStyle.js +3 -3
- package/dist/utils/hexId.d.ts +8 -1
- package/dist/utils/hexId.js +11 -3
- package/dist/utils/units.d.ts +6 -6
- package/dist/utils/units.js +8 -8
- package/package.json +1 -1
|
@@ -4,26 +4,76 @@ import { ignoreTrackedChanges } from "./ParagraphChangeTrackerExtension.js";
|
|
|
4
4
|
import { Plugin, PluginKey } from "prosemirror-state";
|
|
5
5
|
//#region src/prosemirror/extensions/features/ParaIdAllocatorExtension.ts
|
|
6
6
|
const paraIdAllocatorKey = new PluginKey("paraIdAllocator");
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const isUsableParaId = (value) => typeof value === "string" && value.length > 0 && value !== "00000000";
|
|
8
|
+
/**
|
|
9
|
+
* For every valid paraId in the pre-transaction doc, the position its
|
|
10
|
+
* paragraph ends up at after `transactions` — the occurrence that
|
|
11
|
+
* rightfully keeps the id when the new doc holds duplicates. Ids whose
|
|
12
|
+
* paragraph start was deleted by the steps are left out.
|
|
13
|
+
*/
|
|
14
|
+
const mapKeeperPositions = (oldDoc, transactions) => {
|
|
15
|
+
const keepers = /* @__PURE__ */ new Map();
|
|
16
|
+
oldDoc.descendants((node, pos) => {
|
|
17
|
+
if (node.type.name !== "paragraph") return true;
|
|
18
|
+
const id = node.attrs["paraId"];
|
|
19
|
+
if (!isUsableParaId(id) || keepers.has(id)) return false;
|
|
20
|
+
let mapped = pos;
|
|
21
|
+
let deleted = false;
|
|
22
|
+
for (const tr of transactions) {
|
|
23
|
+
const result = tr.mapping.mapResult(mapped);
|
|
24
|
+
if (result.deleted) {
|
|
25
|
+
deleted = true;
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
mapped = result.pos;
|
|
29
|
+
}
|
|
30
|
+
if (!deleted) keepers.set(id, mapped);
|
|
31
|
+
return false;
|
|
32
|
+
});
|
|
33
|
+
return keepers;
|
|
34
|
+
};
|
|
35
|
+
const collectParaIdUpdates = (doc, keeperPositions) => {
|
|
36
|
+
const missing = [];
|
|
37
|
+
const occurrencesById = /* @__PURE__ */ new Map();
|
|
10
38
|
doc.descendants((node, pos) => {
|
|
11
|
-
if (node.type.name !== "paragraph") return;
|
|
39
|
+
if (node.type.name !== "paragraph") return true;
|
|
12
40
|
const id = node.attrs["paraId"];
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
41
|
+
if (!isUsableParaId(id)) missing.push({
|
|
42
|
+
pos,
|
|
43
|
+
attrs: node.attrs
|
|
44
|
+
});
|
|
45
|
+
else {
|
|
46
|
+
const occurrences = occurrencesById.get(id) ?? [];
|
|
47
|
+
occurrences.push({
|
|
18
48
|
pos,
|
|
19
|
-
attrs:
|
|
20
|
-
...node.attrs,
|
|
21
|
-
paraId: newId
|
|
22
|
-
}
|
|
49
|
+
attrs: node.attrs
|
|
23
50
|
});
|
|
24
|
-
|
|
51
|
+
occurrencesById.set(id, occurrences);
|
|
52
|
+
}
|
|
25
53
|
return false;
|
|
26
54
|
});
|
|
55
|
+
const needFreshId = [...missing];
|
|
56
|
+
for (const [id, occurrences] of occurrencesById) {
|
|
57
|
+
if (occurrences.length === 1) continue;
|
|
58
|
+
const keeperPos = keeperPositions?.get(id);
|
|
59
|
+
const keeper = occurrences.find((occurrence) => occurrence.pos === keeperPos) ?? occurrences[0];
|
|
60
|
+
for (const occurrence of occurrences) if (occurrence !== keeper) needFreshId.push(occurrence);
|
|
61
|
+
}
|
|
62
|
+
const taken = new Set(occurrencesById.keys());
|
|
63
|
+
const updates = [];
|
|
64
|
+
for (const { pos, attrs } of needFreshId) {
|
|
65
|
+
let newId = generateHexId();
|
|
66
|
+
while (taken.has(newId)) newId = generateHexId();
|
|
67
|
+
taken.add(newId);
|
|
68
|
+
updates.push({
|
|
69
|
+
pos,
|
|
70
|
+
attrs: {
|
|
71
|
+
...attrs,
|
|
72
|
+
paraId: newId
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
updates.sort((a, b) => a.pos - b.pos);
|
|
27
77
|
return updates;
|
|
28
78
|
};
|
|
29
79
|
const ensureParaIdsInState = (state) => {
|
|
@@ -38,12 +88,14 @@ const ensureParaIdsInState = (state) => {
|
|
|
38
88
|
};
|
|
39
89
|
const createParaIdAllocatorPlugin = () => new Plugin({
|
|
40
90
|
key: paraIdAllocatorKey,
|
|
41
|
-
appendTransaction(transactions,
|
|
91
|
+
appendTransaction(transactions, oldState, newState) {
|
|
42
92
|
if (!transactions.some((t) => t.docChanged)) return null;
|
|
43
|
-
const
|
|
93
|
+
const keeperPositions = mapKeeperPositions(oldState.doc, transactions);
|
|
94
|
+
const updates = collectParaIdUpdates(newState.doc, keeperPositions);
|
|
44
95
|
if (updates.length === 0) return null;
|
|
45
96
|
const tr = newState.tr;
|
|
46
97
|
for (const u of updates) tr.setNodeMarkup(u.pos, void 0, u.attrs);
|
|
98
|
+
ignoreTrackedChanges(tr);
|
|
47
99
|
tr.setMeta(paraIdAllocatorKey, "allocated");
|
|
48
100
|
tr.setMeta("addToHistory", false);
|
|
49
101
|
return tr;
|
|
@@ -6,7 +6,8 @@ import { ImagePositionAttrs } from "../../schema/nodes.js";
|
|
|
6
6
|
//#region src/prosemirror/extensions/nodes/TextBoxExtension.d.ts
|
|
7
7
|
type TextBoxAttrs = {
|
|
8
8
|
/** Width in pixels */width?: number; /** Height in pixels */
|
|
9
|
-
height?: number; /**
|
|
9
|
+
height?: number; /** Text fitting behavior */
|
|
10
|
+
autoFit?: document_d_exports.ShapeTextBody["autoFit"]; /** Unique identifier */
|
|
10
11
|
textBoxId?: string; /** Fill color as CSS color */
|
|
11
12
|
fillColor?: string; /** Outline width in pixels */
|
|
12
13
|
outlineWidth?: number; /** Outline color as CSS color */
|
|
@@ -15,6 +15,9 @@ function parseTextBoxPosition(raw) {
|
|
|
15
15
|
function parseTextBoxWrapType(raw) {
|
|
16
16
|
for (const value of IMAGE_WRAP_TYPE_VALUES) if (value === raw) return value;
|
|
17
17
|
}
|
|
18
|
+
function parseTextBoxAutoFit(raw) {
|
|
19
|
+
if (raw === "none" || raw === "normal" || raw === "shape") return raw;
|
|
20
|
+
}
|
|
18
21
|
const TextBoxExtension = createNodeExtension({
|
|
19
22
|
name: "textBox",
|
|
20
23
|
schemaNodeName: "textBox",
|
|
@@ -26,6 +29,7 @@ const TextBoxExtension = createNodeExtension({
|
|
|
26
29
|
attrs: {
|
|
27
30
|
width: { default: 200 },
|
|
28
31
|
height: { default: null },
|
|
32
|
+
autoFit: { default: null },
|
|
29
33
|
textBoxId: { default: null },
|
|
30
34
|
fillColor: { default: null },
|
|
31
35
|
outlineWidth: { default: null },
|
|
@@ -55,9 +59,11 @@ const TextBoxExtension = createNodeExtension({
|
|
|
55
59
|
const d = dom.dataset;
|
|
56
60
|
const position = parseTextBoxPosition(d["position"]);
|
|
57
61
|
const wrapType = parseTextBoxWrapType(d["wrapType"]);
|
|
62
|
+
const autoFit = parseTextBoxAutoFit(d["autoFit"]);
|
|
58
63
|
return {
|
|
59
64
|
...d["width"] ? { width: Number(d["width"]) } : {},
|
|
60
65
|
...d["height"] ? { height: Number(d["height"]) } : {},
|
|
66
|
+
...autoFit ? { autoFit } : {},
|
|
61
67
|
...d["textboxId"] ? { textBoxId: d["textboxId"] } : {},
|
|
62
68
|
...d["fillColor"] ? { fillColor: d["fillColor"] } : {},
|
|
63
69
|
...d["outlineWidth"] ? { outlineWidth: Number(d["outlineWidth"]) } : {},
|
|
@@ -85,6 +91,7 @@ const TextBoxExtension = createNodeExtension({
|
|
|
85
91
|
const domAttrs = { class: "docx-textbox" };
|
|
86
92
|
if (attrs.width) domAttrs["data-width"] = String(attrs.width);
|
|
87
93
|
if (attrs.height) domAttrs["data-height"] = String(attrs.height);
|
|
94
|
+
if (attrs.autoFit) domAttrs["data-auto-fit"] = attrs.autoFit;
|
|
88
95
|
if (attrs.textBoxId) domAttrs["data-textbox-id"] = attrs.textBoxId;
|
|
89
96
|
if (attrs.fillColor) domAttrs["data-fill-color"] = attrs.fillColor;
|
|
90
97
|
if (attrs.outlineWidth) domAttrs["data-outline-width"] = String(attrs.outlineWidth);
|
|
@@ -46,7 +46,8 @@ type ParagraphAttrs = {
|
|
|
46
46
|
listMarker?: string; /** Whether the list marker is hidden (w:vanish on numbering level rPr) */
|
|
47
47
|
listMarkerHidden?: boolean; /** Marker font family from numbering level rPr */
|
|
48
48
|
listMarkerFontFamily?: string; /** Marker font size from numbering level rPr, in points */
|
|
49
|
-
listMarkerFontSize?: number;
|
|
49
|
+
listMarkerFontSize?: number; /** Horizontal alignment of the marker around the paragraph's list anchor. */
|
|
50
|
+
listMarkerAlignment?: "left" | "center" | "right";
|
|
50
51
|
/**
|
|
51
52
|
* `w:suff` (§17.9.25) — what follows the marker before body text.
|
|
52
53
|
* `tab` (default) grows the marker to the next tab stop; `space` adds one
|
|
@@ -307,7 +308,8 @@ type ShapeAttrs = {
|
|
|
307
308
|
*/
|
|
308
309
|
type TextBoxAttrs = {
|
|
309
310
|
/** Width in pixels */width?: number; /** Height in pixels */
|
|
310
|
-
height?: number; /**
|
|
311
|
+
height?: number; /** Text fitting behavior */
|
|
312
|
+
autoFit?: document_d_exports.ShapeTextBody["autoFit"]; /** Unique identifier */
|
|
311
313
|
textBoxId?: string; /** Fill color as CSS color */
|
|
312
314
|
fillColor?: string; /** Outline width in pixels */
|
|
313
315
|
outlineWidth?: number; /** Outline color as CSS color */
|
|
@@ -347,7 +349,8 @@ type TableAttrs = {
|
|
|
347
349
|
right?: number;
|
|
348
350
|
}; /** Table look flags for conditional formatting (w:tblLook) */
|
|
349
351
|
look?: document_d_exports.TableLook; /** Table-level borders (w:tblBorders) — full BorderSpec per side */
|
|
350
|
-
borders?: document_d_exports.TableBorders; /**
|
|
352
|
+
borders?: document_d_exports.TableBorders; /** Effective table indent after style resolution. PM-only; never serialized. */
|
|
353
|
+
_resolvedIndent?: NonNullable<document_d_exports.TableFormatting["indent"]>; /** Original table formatting from DOCX for lossless round-trip serialization */
|
|
351
354
|
_originalFormatting?: document_d_exports.TableFormatting; /** Tracked table property changes (w:tblPrChange) for round-trip + accept/reject */
|
|
352
355
|
tblPrChange?: document_d_exports.TablePropertyChange[];
|
|
353
356
|
};
|
|
@@ -86,6 +86,7 @@ function listAttrsFromResolvedStyle(resolved, numbering) {
|
|
|
86
86
|
listMarkerHidden: rendering?.markerHidden ?? null,
|
|
87
87
|
listMarkerFontFamily: rendering?.markerFontFamily ?? null,
|
|
88
88
|
listMarkerFontSize: rendering?.markerFontSize ?? null,
|
|
89
|
+
listMarkerAlignment: rendering?.markerAlignment ?? null,
|
|
89
90
|
listMarkerSuffix: rendering?.markerSuffix ?? null,
|
|
90
91
|
listMarkerAllCaps: rendering?.markerAllCaps ?? null,
|
|
91
92
|
listImplicitChildLevelAdvances: null,
|
|
@@ -105,7 +105,7 @@ function calculateTabWidth(currentXPx, context, following = {}) {
|
|
|
105
105
|
...nextStop.leader !== void 0 ? { leader: nextStop.leader } : {},
|
|
106
106
|
alignment: "bar"
|
|
107
107
|
};
|
|
108
|
-
if (width
|
|
108
|
+
if (width <= 0) {
|
|
109
109
|
const defaultTabPx = twipsToPixels(defaultTabInterval);
|
|
110
110
|
let fallbackWidth = defaultTabPx - currentXPx % defaultTabPx;
|
|
111
111
|
if (fallbackWidth <= 0) fallbackWidth = defaultTabPx;
|
package/dist/server.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditSnapshot, FolioAIInlineFormatting, FolioAITextRangeHandle } from "./ai-edits/types.js";
|
|
1
|
+
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditSnapshot, FolioAIInlineFormatting, FolioAITextRangeHandle, FolioDocumentNavigationTarget, FolioDocumentOutline, FolioDocumentOutlineEntry, FolioDocumentSection, FolioDocumentSectionHandle, FolioDocumentSectionReadResult } from "./ai-edits/types.js";
|
|
2
2
|
import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationStatus, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
|
|
3
3
|
import { FolioReviewChange, FolioReviewChangeKind } from "./ai-edits/read.js";
|
|
4
4
|
import { ApplyFolioAIEditsToBufferOptions, ApplyFolioAIEditsToBufferResult, FolioApplyDocumentOperationsOptions, FolioApplyOperationsOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocxReviewer, FolioDocxReviewerOptions, FolioReviewChangeFilter, FolioReviewComment, FolioReviewCommentFilter, FolioReviewCommentReply, FolioReviewReplyInput, applyFolioAIEditsToBuffer } from "./ai-edits/headless.js";
|
|
5
5
|
import { createFolioAITextRangeHandle } from "./ai-edits/snapshot.js";
|
|
6
|
+
import { getFolioDocumentOutline, readFolioDocumentSection } from "./ai-edits/scoped-reading.js";
|
|
6
7
|
import { DeriveBlockIdInput, FolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "./types/block-id.js";
|
|
7
8
|
import { CreateEmptyDocumentOptions, createEmptyDocument } from "./utils/createDocument.js";
|
|
8
9
|
import { createDocx } from "./docx/rezip.js";
|
|
10
|
+
import { EnsureParaIdsError, EnsureParaIdsOptions, EnsureParaIdsResult, ensureParaIds } from "./docx/ensureParaIds.js";
|
|
9
11
|
import { CreateCommentReplyInput, replyToComment } from "./docx/replyToComment.js";
|
|
12
|
+
import { DocxArchiveError } from "./docx/server/boundedArchive.js";
|
|
13
|
+
import { DocxParagraphSource, ExtractedDocxParagraph, ExtractedDocxText, extractDocxText } from "./docx/server/extractDocxText.js";
|
|
10
14
|
import { GenerateRedlineDocxOptions, GenerateRedlineDocxResult, generateRedlineDocx } from "./redline.js";
|
|
11
15
|
import { FolioBlockDiff, FolioFormatProperty, FolioVersionDiff, FolioVersionDiffSegment, compareDocxVersions } from "./version-comparison.js";
|
|
12
|
-
export { type ApplyFolioAIEditsToBufferOptions, type ApplyFolioAIEditsToBufferResult, type CreateCommentReplyInput, type CreateEmptyDocumentOptions, type DeriveBlockIdInput, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditSnapshot, type FolioAIInlineFormatting, type FolioAITextRangeHandle, type FolioApplyDocumentOperationsOptions, type FolioApplyOperationsOptions, type FolioBlockDiff, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocumentStory, type FolioDocumentStoryHandle, FolioDocxReviewer, type FolioDocxReviewerOptions, type FolioFormatProperty, type FolioReviewChange, type FolioReviewChangeFilter, type FolioReviewChangeKind, type FolioReviewComment, type FolioReviewCommentFilter, type FolioReviewCommentReply, type FolioReviewReplyInput, type FolioVersionDiff, type FolioVersionDiffSegment, type GenerateRedlineDocxOptions, type GenerateRedlineDocxResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioAIEditsToBuffer, assertSupportedFolioDocumentOperationVersion, compareDocxVersions, createDocx, createEmptyDocument, createFolioAITextRangeHandle, deriveBlockId, generateRedlineDocx, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch, replyToComment };
|
|
16
|
+
export { type ApplyFolioAIEditsToBufferOptions, type ApplyFolioAIEditsToBufferResult, type CreateCommentReplyInput, type CreateEmptyDocumentOptions, type DeriveBlockIdInput, DocxArchiveError, type DocxParagraphSource, EnsureParaIdsError, type EnsureParaIdsOptions, type EnsureParaIdsResult, type ExtractedDocxParagraph, type ExtractedDocxText, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditSnapshot, type FolioAIInlineFormatting, type FolioAITextRangeHandle, type FolioApplyDocumentOperationsOptions, type FolioApplyOperationsOptions, type FolioBlockDiff, type FolioBlockId, type FolioDocumentNavigationTarget, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocumentOutline, type FolioDocumentOutlineEntry, type FolioDocumentSection, type FolioDocumentSectionHandle, type FolioDocumentSectionReadResult, type FolioDocumentStory, type FolioDocumentStoryHandle, FolioDocxReviewer, type FolioDocxReviewerOptions, type FolioFormatProperty, type FolioReviewChange, type FolioReviewChangeFilter, type FolioReviewChangeKind, type FolioReviewComment, type FolioReviewCommentFilter, type FolioReviewCommentReply, type FolioReviewReplyInput, type FolioVersionDiff, type FolioVersionDiffSegment, type GenerateRedlineDocxOptions, type GenerateRedlineDocxResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioAIEditsToBuffer, assertSupportedFolioDocumentOperationVersion, compareDocxVersions, createDocx, createEmptyDocument, createFolioAITextRangeHandle, deriveBlockId, ensureParaIds, extractDocxText, generateRedlineDocx, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch, readFolioDocumentSection, replyToComment };
|
package/dist/server.js
CHANGED
|
@@ -3,8 +3,12 @@ import { createFolioAITextRangeHandle } from "./ai-edits/snapshot.js";
|
|
|
3
3
|
import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
|
|
4
4
|
import { createEmptyDocument } from "./utils/createDocument.js";
|
|
5
5
|
import { createDocx } from "./docx/rezip.js";
|
|
6
|
+
import { getFolioDocumentOutline, readFolioDocumentSection } from "./ai-edits/scoped-reading.js";
|
|
6
7
|
import { replyToComment } from "./docx/replyToComment.js";
|
|
7
8
|
import { FolioDocxReviewer, applyFolioAIEditsToBuffer } from "./ai-edits/headless.js";
|
|
8
9
|
import { compareDocxVersions } from "./version-comparison.js";
|
|
9
10
|
import { generateRedlineDocx } from "./redline.js";
|
|
10
|
-
|
|
11
|
+
import { EnsureParaIdsError, ensureParaIds } from "./docx/ensureParaIds.js";
|
|
12
|
+
import { DocxArchiveError } from "./docx/server/boundedArchive.js";
|
|
13
|
+
import { extractDocxText } from "./docx/server/extractDocxText.js";
|
|
14
|
+
export { DocxArchiveError, EnsureParaIdsError, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocxReviewer, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioAIEditsToBuffer, assertSupportedFolioDocumentOperationVersion, compareDocxVersions, createDocx, createEmptyDocument, createFolioAITextRangeHandle, deriveBlockId, ensureParaIds, extractDocxText, generateRedlineDocx, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch, readFolioDocumentSection, replyToComment };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ type ConditionalFormatStyle = document_d_exports.ConditionalFormatStyle;
|
|
|
13
13
|
type DocDefaults = document_d_exports.DocDefaults;
|
|
14
14
|
type Document = document_d_exports.Document;
|
|
15
15
|
type DocumentBody = document_d_exports.DocumentBody;
|
|
16
|
+
type DocxConformanceClass = document_d_exports.DocxConformanceClass;
|
|
16
17
|
type DocxPackage = document_d_exports.DocxPackage;
|
|
17
18
|
type DrawingContent = document_d_exports.DrawingContent;
|
|
18
19
|
type EmphasisMark = document_d_exports.EmphasisMark;
|
|
@@ -104,4 +105,4 @@ type ThemeFont = document_d_exports.ThemeFont;
|
|
|
104
105
|
type ThemeFontScheme = document_d_exports.ThemeFontScheme;
|
|
105
106
|
type UnderlineStyle = document_d_exports.UnderlineStyle;
|
|
106
107
|
type VerticalAlign = document_d_exports.VerticalAlign;
|
|
107
|
-
export type { AbstractNumbering, BlockContent, BookmarkEnd, BookmarkStart, BorderSpec, BreakContent, CellMargins, ColorValue, Column, ComplexField, ConditionalFormatStyle, DocDefaults, Document, DocumentBody, DocxPackage, DrawingContent, EmphasisMark, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FloatingTableProperties, FontInfo, FontTable, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, InstrTextContent, LevelSuffix, LineNumberRestart, LineSpacingRule, ListLevel, ListRendering, MediaFile, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, NumberFormat, NumberingDefinitions, NumberingInstance, PageOrientation, Paragraph, ParagraphAlignment, ParagraphContent, ParagraphFormatting, Relationship, RelationshipMap, RelationshipType, Run, RunContent, Section, SectionProperties, SectionStart, ShadingProperties, Shape, ShapeContent, ShapeFill, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, Style, StyleDefinitions, StyleType, SymbolContent, TabContent, TabLeader, TabStop, TabStopAlignment, Table, TableBorders, TableCell, TableCellFormatting, TableFormatting, TableLook, TableMeasurement, TableRow, TableRowFormatting, TableWidthType, TextBox, TextContent, TextEffect, TextFormatting, Theme, ThemeColorScheme, ThemeColorSlot, ThemeFont, ThemeFontScheme, UnderlineStyle, VerticalAlign };
|
|
108
|
+
export type { AbstractNumbering, BlockContent, BookmarkEnd, BookmarkStart, BorderSpec, BreakContent, CellMargins, ColorValue, Column, ComplexField, ConditionalFormatStyle, DocDefaults, Document, DocumentBody, DocxConformanceClass, DocxPackage, DrawingContent, EmphasisMark, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FloatingTableProperties, FontInfo, FontTable, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, InstrTextContent, LevelSuffix, LineNumberRestart, LineSpacingRule, ListLevel, ListRendering, MediaFile, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, NumberFormat, NumberingDefinitions, NumberingInstance, PageOrientation, Paragraph, ParagraphAlignment, ParagraphContent, ParagraphFormatting, Relationship, RelationshipMap, RelationshipType, Run, RunContent, Section, SectionProperties, SectionStart, ShadingProperties, Shape, ShapeContent, ShapeFill, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, Style, StyleDefinitions, StyleType, SymbolContent, TabContent, TabLeader, TabStop, TabStopAlignment, Table, TableBorders, TableCell, TableCellFormatting, TableFormatting, TableLook, TableMeasurement, TableRow, TableRowFormatting, TableWidthType, TextBox, TextContent, TextEffect, TextFormatting, Theme, ThemeColorScheme, ThemeColorSlot, ThemeFont, ThemeFontScheme, UnderlineStyle, VerticalAlign };
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
|
|
1
2
|
//#region src/utils/createDocument.ts
|
|
2
3
|
/**
|
|
4
|
+
* Create Document Utility
|
|
5
|
+
*
|
|
6
|
+
* Provides functions to create new documents programmatically.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
3
9
|
* Get default paragraph styles (matching Google Docs defaults)
|
|
4
10
|
*
|
|
5
11
|
* Font sizes are in half-points (e.g., 22 = 11pt, 40 = 20pt)
|
|
@@ -207,26 +213,28 @@ function createEmptyDocument(options = {}) {
|
|
|
207
213
|
type: "text",
|
|
208
214
|
text: options.initialText || ""
|
|
209
215
|
};
|
|
216
|
+
const documentBody = {
|
|
217
|
+
content: [{
|
|
218
|
+
type: "paragraph",
|
|
219
|
+
content: [{
|
|
220
|
+
type: "run",
|
|
221
|
+
content: options.initialText ? [textContent] : [],
|
|
222
|
+
formatting: {
|
|
223
|
+
fontSize: 22,
|
|
224
|
+
fontFamily: {
|
|
225
|
+
ascii: "Arial",
|
|
226
|
+
hAnsi: "Arial"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}],
|
|
230
|
+
formatting: { lineSpacing: 276 }
|
|
231
|
+
}],
|
|
232
|
+
finalSectionProperties: sectionProps
|
|
233
|
+
};
|
|
210
234
|
return {
|
|
211
235
|
package: {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
type: "paragraph",
|
|
215
|
-
content: [{
|
|
216
|
-
type: "run",
|
|
217
|
-
content: options.initialText ? [textContent] : [],
|
|
218
|
-
formatting: {
|
|
219
|
-
fontSize: 22,
|
|
220
|
-
fontFamily: {
|
|
221
|
-
ascii: "Arial",
|
|
222
|
-
hAnsi: "Arial"
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}],
|
|
226
|
-
formatting: { lineSpacing: 276 }
|
|
227
|
-
}],
|
|
228
|
-
finalSectionProperties: sectionProps
|
|
229
|
-
},
|
|
236
|
+
conformanceClass: DOCX_CONFORMANCE_CLASSES.TRANSITIONAL,
|
|
237
|
+
document: documentBody,
|
|
230
238
|
styles: {
|
|
231
239
|
docDefaults: {
|
|
232
240
|
rPr: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { eighthsToPixels, formatPx, halfPointsToPixels, halfPointsToPoints, twipsToPixels } from "./units.js";
|
|
1
|
+
import { AUTO_PARAGRAPH_SPACING_PX, eighthsToPixels, formatPx, halfPointsToPixels, halfPointsToPoints, twipsToPixels } from "./units.js";
|
|
2
2
|
import { resolveFontFamily, resolveThemeFont } from "./fontResolver.js";
|
|
3
3
|
import { resolveColor, resolveHighlightToCss, resolveShadingColor } from "./colorResolver.js";
|
|
4
4
|
//#region src/utils/formatToStyle.ts
|
|
@@ -89,9 +89,9 @@ function paragraphToStyle(formatting, theme) {
|
|
|
89
89
|
if (!formatting) return {};
|
|
90
90
|
const style = {};
|
|
91
91
|
if (formatting.alignment) style.textAlign = mapAlignment(formatting.alignment);
|
|
92
|
-
if (formatting.beforeAutospacing) style.marginTop = formatPx(
|
|
92
|
+
if (formatting.beforeAutospacing) style.marginTop = formatPx(AUTO_PARAGRAPH_SPACING_PX);
|
|
93
93
|
else if (formatting.spaceBefore !== void 0) style.marginTop = formatPx(twipsToPixels(formatting.spaceBefore));
|
|
94
|
-
if (formatting.afterAutospacing) style.marginBottom = formatPx(
|
|
94
|
+
if (formatting.afterAutospacing) style.marginBottom = formatPx(AUTO_PARAGRAPH_SPACING_PX);
|
|
95
95
|
else if (formatting.spaceAfter !== void 0) style.marginBottom = formatPx(twipsToPixels(formatting.spaceAfter));
|
|
96
96
|
if (formatting.lineSpacing !== void 0 && formatting.lineSpacing > 0) if (formatting.lineSpacingRule === "exact") {
|
|
97
97
|
const exactPx = twipsToPixels(formatting.lineSpacing);
|
package/dist/utils/hexId.d.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Lifted from
|
|
4
4
|
* https://github.com/eigenpal/docx-editor/blob/main/packages/core/src/utils/hexId.ts
|
|
5
5
|
* (Apache-2.0). Keep the bound and the comments in sync upstream.
|
|
6
|
+
* folio divergence: `00000000` is excluded from both generators — Word
|
|
7
|
+
* treats a zero `w14:paraId` as unassigned, so it must never be minted.
|
|
6
8
|
*/
|
|
7
9
|
/**
|
|
8
10
|
* Strictest OOXML `ST_LongHexNumber` upper bound (exclusive) across the
|
|
@@ -17,7 +19,8 @@ declare const MAX_HEX_ID_EXCLUSIVE = 2147483647;
|
|
|
17
19
|
* Random 8-char uppercase hex id, matching Microsoft's `w14:paraId`
|
|
18
20
|
* extension format (also reused for comment `paraId` / `durableId`).
|
|
19
21
|
*
|
|
20
|
-
* Range is `[
|
|
22
|
+
* Range is `[1, MAX_HEX_ID_EXCLUSIVE)` = `[1, 0x7FFFFFFE]` — zero is
|
|
23
|
+
* excluded because Word reads `w14:paraId="00000000"` as "no id".
|
|
21
24
|
*
|
|
22
25
|
* Uses `Math.random()` rather than `crypto.randomUUID()` so the
|
|
23
26
|
* generator works in non-secure contexts (file://, web workers).
|
|
@@ -27,6 +30,10 @@ declare const generateHexId: () => string;
|
|
|
27
30
|
* Deterministic 8-char uppercase hex id (FNV-1a over `seed`), `< 0x7FFFFFFF`.
|
|
28
31
|
* Re-deriving from the same seed mints the same id, so content/position-derived
|
|
29
32
|
* ids (block paraIds, comment thread keys) are stable across saves.
|
|
33
|
+
*
|
|
34
|
+
* A hash of exactly zero is remapped to `1`: `00000000` is Word's "no id"
|
|
35
|
+
* sentinel, and remapping only that one (already invalid) output keeps every
|
|
36
|
+
* previously shipped deterministic id unchanged.
|
|
30
37
|
*/
|
|
31
38
|
declare const deterministicHexId: (seed: string) => string;
|
|
32
39
|
//#endregion
|
package/dist/utils/hexId.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Lifted from
|
|
4
4
|
* https://github.com/eigenpal/docx-editor/blob/main/packages/core/src/utils/hexId.ts
|
|
5
5
|
* (Apache-2.0). Keep the bound and the comments in sync upstream.
|
|
6
|
+
* folio divergence: `00000000` is excluded from both generators — Word
|
|
7
|
+
* treats a zero `w14:paraId` as unassigned, so it must never be minted.
|
|
6
8
|
*/
|
|
7
9
|
/**
|
|
8
10
|
* Strictest OOXML `ST_LongHexNumber` upper bound (exclusive) across the
|
|
@@ -17,21 +19,27 @@ const MAX_HEX_ID_EXCLUSIVE = 2147483647;
|
|
|
17
19
|
* Random 8-char uppercase hex id, matching Microsoft's `w14:paraId`
|
|
18
20
|
* extension format (also reused for comment `paraId` / `durableId`).
|
|
19
21
|
*
|
|
20
|
-
* Range is `[
|
|
22
|
+
* Range is `[1, MAX_HEX_ID_EXCLUSIVE)` = `[1, 0x7FFFFFFE]` — zero is
|
|
23
|
+
* excluded because Word reads `w14:paraId="00000000"` as "no id".
|
|
21
24
|
*
|
|
22
25
|
* Uses `Math.random()` rather than `crypto.randomUUID()` so the
|
|
23
26
|
* generator works in non-secure contexts (file://, web workers).
|
|
24
27
|
*/
|
|
25
|
-
const generateHexId = () => Math.floor(Math.random() * MAX_HEX_ID_EXCLUSIVE).toString(16).toUpperCase().padStart(8, "0");
|
|
28
|
+
const generateHexId = () => (Math.floor(Math.random() * (MAX_HEX_ID_EXCLUSIVE - 1)) + 1).toString(16).toUpperCase().padStart(8, "0");
|
|
26
29
|
/**
|
|
27
30
|
* Deterministic 8-char uppercase hex id (FNV-1a over `seed`), `< 0x7FFFFFFF`.
|
|
28
31
|
* Re-deriving from the same seed mints the same id, so content/position-derived
|
|
29
32
|
* ids (block paraIds, comment thread keys) are stable across saves.
|
|
33
|
+
*
|
|
34
|
+
* A hash of exactly zero is remapped to `1`: `00000000` is Word's "no id"
|
|
35
|
+
* sentinel, and remapping only that one (already invalid) output keeps every
|
|
36
|
+
* previously shipped deterministic id unchanged.
|
|
30
37
|
*/
|
|
31
38
|
const deterministicHexId = (seed) => {
|
|
32
39
|
let hash = 2166136261;
|
|
33
40
|
for (const character of seed) hash = Math.imul(hash ^ (character.codePointAt(0) ?? 0), 16777619) >>> 0;
|
|
34
|
-
|
|
41
|
+
const value = hash % MAX_HEX_ID_EXCLUSIVE;
|
|
42
|
+
return (value === 0 ? 1 : value).toString(16).toUpperCase().padStart(8, "0");
|
|
35
43
|
};
|
|
36
44
|
//#endregion
|
|
37
45
|
export { MAX_HEX_ID_EXCLUSIVE, deterministicHexId, generateHexId };
|
package/dist/utils/units.d.ts
CHANGED
|
@@ -13,16 +13,16 @@
|
|
|
13
13
|
*/
|
|
14
14
|
/** Twips per inch (1 inch = 1440 twips) */
|
|
15
15
|
declare const TWIPS_PER_INCH = 1440;
|
|
16
|
+
/** Pixels per inch at standard DPI */
|
|
17
|
+
declare const PIXELS_PER_INCH = 96;
|
|
16
18
|
/**
|
|
17
19
|
* Word's auto paragraph spacing in px. HTML-origin paragraphs use
|
|
18
20
|
* `w:beforeAutospacing`/`w:afterAutospacing` instead of explicit before/after;
|
|
19
|
-
* Word ignores any explicit value on such paragraphs and renders
|
|
20
|
-
* value is empirical (Word's rendered auto gap), not derivable from a
|
|
21
|
-
* conversion. See eigenpal/docx-editor#823.
|
|
21
|
+
* Word ignores any explicit value on such paragraphs and renders a 14pt gap.
|
|
22
|
+
* The value is empirical (Word's rendered auto gap), not derivable from a
|
|
23
|
+
* twips conversion. See eigenpal/docx-editor#823.
|
|
22
24
|
*/
|
|
23
|
-
declare const AUTO_PARAGRAPH_SPACING_PX
|
|
24
|
-
/** Pixels per inch at standard DPI */
|
|
25
|
-
declare const PIXELS_PER_INCH = 96;
|
|
25
|
+
declare const AUTO_PARAGRAPH_SPACING_PX: number;
|
|
26
26
|
/**
|
|
27
27
|
* Convert twips to pixels (at 96 DPI)
|
|
28
28
|
*
|
package/dist/utils/units.js
CHANGED
|
@@ -15,14 +15,6 @@
|
|
|
15
15
|
const STANDARD_DPI = 96;
|
|
16
16
|
/** Twips per inch (1 inch = 1440 twips) */
|
|
17
17
|
const TWIPS_PER_INCH = 1440;
|
|
18
|
-
/**
|
|
19
|
-
* Word's auto paragraph spacing in px. HTML-origin paragraphs use
|
|
20
|
-
* `w:beforeAutospacing`/`w:afterAutospacing` instead of explicit before/after;
|
|
21
|
-
* Word ignores any explicit value on such paragraphs and renders ~14px. The
|
|
22
|
-
* value is empirical (Word's rendered auto gap), not derivable from a twips
|
|
23
|
-
* conversion. See eigenpal/docx-editor#823.
|
|
24
|
-
*/
|
|
25
|
-
const AUTO_PARAGRAPH_SPACING_PX = 14;
|
|
26
18
|
/** EMUs per inch (1 inch = 914400 EMUs) */
|
|
27
19
|
const EMUS_PER_INCH = 914400;
|
|
28
20
|
/** Points per inch (1 inch = 72 points) */
|
|
@@ -34,6 +26,14 @@ const EIGHTHS_PER_INCH = 576;
|
|
|
34
26
|
/** Pixels per inch at standard DPI */
|
|
35
27
|
const PIXELS_PER_INCH = STANDARD_DPI;
|
|
36
28
|
/**
|
|
29
|
+
* Word's auto paragraph spacing in px. HTML-origin paragraphs use
|
|
30
|
+
* `w:beforeAutospacing`/`w:afterAutospacing` instead of explicit before/after;
|
|
31
|
+
* Word ignores any explicit value on such paragraphs and renders a 14pt gap.
|
|
32
|
+
* The value is empirical (Word's rendered auto gap), not derivable from a
|
|
33
|
+
* twips conversion. See eigenpal/docx-editor#823.
|
|
34
|
+
*/
|
|
35
|
+
const AUTO_PARAGRAPH_SPACING_PX = pointsToPixels(14);
|
|
36
|
+
/**
|
|
37
37
|
* Convert twips to pixels (at 96 DPI)
|
|
38
38
|
*
|
|
39
39
|
* 1 inch = 1440 twips = 96 pixels
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Headless, framework-neutral core of folio: the OOXML (.docx) parser, document model, ProseMirror integration, and page-layout engine. No React.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"document-model",
|