@stll/folio-core 0.32.1 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/dist/ai-edits/__fixtures__/paragraphs.d.ts +17 -0
  2. package/dist/ai-edits/__fixtures__/paragraphs.js +33 -0
  3. package/dist/ai-edits/apply.d.ts +49 -3
  4. package/dist/ai-edits/apply.js +692 -75
  5. package/dist/ai-edits/blockRange.d.ts +7 -3
  6. package/dist/ai-edits/blockRange.js +14 -6
  7. package/dist/ai-edits/headless.d.ts +39 -5
  8. package/dist/ai-edits/headless.js +76 -17
  9. package/dist/ai-edits/index.d.ts +6 -6
  10. package/dist/ai-edits/index.js +3 -3
  11. package/dist/ai-edits/read.d.ts +4 -0
  12. package/dist/ai-edits/read.js +30 -6
  13. package/dist/ai-edits/scoped-reading.js +4 -3
  14. package/dist/ai-edits/snapshot.d.ts +42 -2
  15. package/dist/ai-edits/snapshot.js +127 -62
  16. package/dist/ai-edits/table-row-column-mutations.d.ts +24 -1
  17. package/dist/ai-edits/table-row-column-mutations.js +98 -6
  18. package/dist/ai-edits/table-targets.d.ts +12 -3
  19. package/dist/ai-edits/table-targets.js +15 -5
  20. package/dist/ai-edits/types.d.ts +235 -7
  21. package/dist/ai-edits/word-diff.d.ts +54 -11
  22. package/dist/ai-edits/word-diff.js +221 -61
  23. package/dist/compare/__fixtures__/body-sequence.d.ts +33 -0
  24. package/dist/compare/__fixtures__/body-sequence.js +67 -0
  25. package/dist/compare/__fixtures__/nested-table.d.ts +16 -0
  26. package/dist/compare/__fixtures__/nested-table.js +50 -0
  27. package/dist/compare/__fixtures__/numbered-list.d.ts +34 -0
  28. package/dist/compare/__fixtures__/numbered-list.js +85 -0
  29. package/dist/compare/column-alignment.d.ts +27 -0
  30. package/dist/compare/column-alignment.js +162 -0
  31. package/dist/compare/compare.d.ts +107 -0
  32. package/dist/compare/compare.js +406 -0
  33. package/dist/compare/formatting.d.ts +29 -0
  34. package/dist/compare/formatting.js +84 -0
  35. package/dist/compare/plan.d.ts +22 -0
  36. package/dist/compare/plan.js +1059 -0
  37. package/dist/compare/reproducible-package.d.ts +17 -0
  38. package/dist/compare/reproducible-package.js +30 -0
  39. package/dist/compare/scenario.d.ts +77 -0
  40. package/dist/compare/scenario.js +263 -0
  41. package/dist/compare/types.d.ts +282 -0
  42. package/dist/compare/types.js +32 -0
  43. package/dist/compare/verification.d.ts +55 -0
  44. package/dist/compare/verification.js +146 -0
  45. package/dist/compat/eigenpal.d.ts +9 -6
  46. package/dist/compat/eigenpal.js +6 -3
  47. package/dist/controller/layoutPipeline.d.ts +13 -0
  48. package/dist/controller/layoutPipeline.js +15 -1
  49. package/dist/display-list/build/buildContext.d.ts +39 -0
  50. package/dist/display-list/build/buildContext.js +31 -0
  51. package/dist/display-list/build/buildDisplayList.d.ts +79 -0
  52. package/dist/display-list/build/buildDisplayList.js +283 -0
  53. package/dist/display-list/build/colors.d.ts +20 -0
  54. package/dist/display-list/build/colors.js +136 -0
  55. package/dist/display-list/build/floatingImages.d.ts +24 -0
  56. package/dist/display-list/build/floatingImages.js +41 -0
  57. package/dist/display-list/build/fontTable.d.ts +31 -0
  58. package/dist/display-list/build/fontTable.js +97 -0
  59. package/dist/display-list/build/furniture.d.ts +86 -0
  60. package/dist/display-list/build/furniture.js +98 -0
  61. package/dist/display-list/build/glyphs.d.ts +55 -0
  62. package/dist/display-list/build/glyphs.js +103 -0
  63. package/dist/display-list/build/headerFooterPrimitives.d.ts +17 -0
  64. package/dist/display-list/build/headerFooterPrimitives.js +40 -0
  65. package/dist/display-list/build/imagePrimitives.d.ts +35 -0
  66. package/dist/display-list/build/imagePrimitives.js +264 -0
  67. package/dist/display-list/build/pageBorderPrimitives.d.ts +23 -0
  68. package/dist/display-list/build/pageBorderPrimitives.js +111 -0
  69. package/dist/display-list/build/pageFurniture.d.ts +35 -0
  70. package/dist/display-list/build/pageFurniture.js +141 -0
  71. package/dist/display-list/build/paragraphPrimitives.d.ts +19 -0
  72. package/dist/display-list/build/paragraphPrimitives.js +819 -0
  73. package/dist/display-list/build/regions.d.ts +46 -0
  74. package/dist/display-list/build/regions.js +56 -0
  75. package/dist/display-list/build/storyPrimitives.d.ts +29 -0
  76. package/dist/display-list/build/storyPrimitives.js +279 -0
  77. package/dist/display-list/build/strokes.d.ts +19 -0
  78. package/dist/display-list/build/strokes.js +78 -0
  79. package/dist/display-list/build/tablePrimitives.d.ts +38 -0
  80. package/dist/display-list/build/tablePrimitives.js +409 -0
  81. package/dist/display-list/build/textBoxPrimitives.d.ts +14 -0
  82. package/dist/display-list/build/textBoxPrimitives.js +129 -0
  83. package/dist/display-list/build/textDecorations.d.ts +29 -0
  84. package/dist/display-list/build/textDecorations.js +29 -0
  85. package/dist/display-list/build/unsupported.d.ts +57 -0
  86. package/dist/display-list/build/unsupported.js +0 -0
  87. package/dist/display-list/build/watermarkPrimitives.d.ts +15 -0
  88. package/dist/display-list/build/watermarkPrimitives.js +128 -0
  89. package/dist/display-list/dom/renderDisplayListToDom.d.ts +26 -0
  90. package/dist/display-list/dom/renderDisplayListToDom.js +620 -0
  91. package/dist/display-list/editor/displayListPagePainter.d.ts +22 -0
  92. package/dist/display-list/editor/displayListPagePainter.js +63 -0
  93. package/dist/display-list/editor/pageRenderer.d.ts +24 -0
  94. package/dist/display-list/editor/pageRenderer.js +36 -0
  95. package/dist/display-list/primitives.d.ts +95 -0
  96. package/dist/display-list/primitives.js +127 -0
  97. package/dist/display-list/types.d.ts +472 -0
  98. package/dist/display-list/types.js +0 -0
  99. package/dist/document-operations.d.ts +42 -9
  100. package/dist/document-operations.js +171 -16
  101. package/dist/document-stories.d.ts +16 -0
  102. package/dist/document-stories.js +48 -4
  103. package/dist/docx/packageParts.d.ts +35 -0
  104. package/dist/docx/packageParts.js +120 -0
  105. package/dist/docx/paragraphParser.js +22 -22
  106. package/dist/docx/paragraphTraversal.js +1 -1
  107. package/dist/docx/renderedPageBreakNormalization.js +3 -1
  108. package/dist/docx/revisionIdNormalization.d.ts +13 -0
  109. package/dist/docx/revisionIdNormalization.js +103 -0
  110. package/dist/docx/rezip.js +26 -17
  111. package/dist/docx/selectiveSave.js +2 -2
  112. package/dist/docx/serializer/commentSerializer.js +6 -1
  113. package/dist/docx/serializer/paragraphSerializer.js +33 -4
  114. package/dist/docx/serializer/runSerializer.js +11 -10
  115. package/dist/docx/serializer/tableSerializer.js +2 -1
  116. package/dist/docx/server/applyDocxXmlPatchProposal.js +1 -1
  117. package/dist/docx/server/createBilingualDocx.js +3 -2
  118. package/dist/docx/streamingXmlParser.d.ts +13 -1
  119. package/dist/docx/streamingXmlParser.js +49 -11
  120. package/dist/docx/unzip.d.ts +1 -2
  121. package/dist/docx/unzip.js +25 -6
  122. package/dist/docx/xmlParser.d.ts +3 -1
  123. package/dist/docx/xmlParser.js +33 -27
  124. package/dist/export-pdf.d.ts +43 -0
  125. package/dist/export-pdf.js +98 -0
  126. package/dist/fonts/headlessMeasure.d.ts +76 -0
  127. package/dist/fonts/headlessMeasure.js +0 -0
  128. package/dist/fonts/sfnt/parse.d.ts +51 -0
  129. package/dist/fonts/sfnt/parse.js +525 -0
  130. package/dist/fonts/sfnt/subset.d.ts +20 -0
  131. package/dist/fonts/sfnt/subset.js +350 -0
  132. package/dist/fonts/sfnt/tables.d.ts +88 -0
  133. package/dist/fonts/sfnt/tables.js +131 -0
  134. package/dist/fonts/sfnt/woff.d.ts +14 -0
  135. package/dist/fonts/sfnt/woff.js +163 -0
  136. package/dist/generated/text_shaper.js +324 -0
  137. package/dist/generated/text_shaper_bg.wasm +0 -0
  138. package/dist/headless-layout.d.ts +75 -0
  139. package/dist/headless-layout.js +350 -0
  140. package/dist/index.d.ts +9 -6
  141. package/dist/index.js +6 -3
  142. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  143. package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
  144. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  145. package/dist/layout-bridge/convert/headerFooterLayout.js +2 -0
  146. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +3 -1
  147. package/dist/layout-bridge/convert/toFlowBlocks.js +2 -0
  148. package/dist/layout-engine/measure/advanceComposition.d.ts +62 -0
  149. package/dist/layout-engine/measure/advanceComposition.js +148 -0
  150. package/dist/layout-engine/measure/cache.d.ts +2 -0
  151. package/dist/layout-engine/measure/measureContainer.js +13 -0
  152. package/dist/layout-engine/measure/measureParagraph.js +1 -2
  153. package/dist/layout-engine/measure/measureTypes.d.ts +12 -0
  154. package/dist/layout-engine/measure/tableInlinePlacement.d.ts +3 -2
  155. package/dist/layout-engine/measure/tableInlinePlacement.js +14 -1
  156. package/dist/layout-engine/tableIndentCompatibility.d.ts +5 -0
  157. package/dist/layout-engine/tableIndentCompatibility.js +15 -0
  158. package/dist/layout-engine/types.d.ts +8 -0
  159. package/dist/layout-painter/renderPage.d.ts +29 -1
  160. package/dist/layout-painter/renderPage.js +47 -19
  161. package/dist/layout-painter/renderParagraph.d.ts +21 -2
  162. package/dist/layout-painter/renderParagraph.js +1 -1
  163. package/dist/layout-painter/renderTable.js +37 -4
  164. package/dist/managers/editorShortcuts.d.ts +33 -1
  165. package/dist/managers/editorShortcuts.js +20 -1
  166. package/dist/markdown/renderRuns.js +7 -2
  167. package/dist/markdown/renderTable.js +5 -1
  168. package/dist/model.d.ts +3 -3
  169. package/dist/model.js +2 -2
  170. package/dist/pdf/contentStream.d.ts +73 -0
  171. package/dist/pdf/contentStream.js +143 -0
  172. package/dist/pdf/fonts.d.ts +96 -0
  173. package/dist/pdf/fonts.js +593 -0
  174. package/dist/pdf/images.d.ts +28 -0
  175. package/dist/pdf/images.js +439 -0
  176. package/dist/pdf/objects.d.ts +93 -0
  177. package/dist/pdf/objects.js +237 -0
  178. package/dist/pdf/pageSpace.d.ts +43 -0
  179. package/dist/pdf/pageSpace.js +57 -0
  180. package/dist/pdf/paint.d.ts +32 -0
  181. package/dist/pdf/paint.js +442 -0
  182. package/dist/pdf/writePdf.d.ts +56 -0
  183. package/dist/pdf/writePdf.js +345 -0
  184. package/dist/prosemirror/commands/comments.js +91 -6
  185. package/dist/prosemirror/conversion/fromProseDoc.js +41 -7
  186. package/dist/prosemirror/conversion/toProseDoc.js +41 -4
  187. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.d.ts +15 -2
  188. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +35 -6
  189. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +2 -2
  190. package/dist/prosemirror/extensions/features/pasteCleanup.js +4 -3
  191. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.d.ts +3 -1
  192. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +5 -3
  193. package/dist/prosemirror/extensions/nodes/RenderedPageBreakExtension.d.ts +7 -1
  194. package/dist/prosemirror/extensions/nodes/RenderedPageBreakExtension.js +9 -3
  195. package/dist/prosemirror/extensions/nodes/TableExtension.js +56 -39
  196. package/dist/prosemirror/extensions/nodes/TextBoxAnchorExtension.d.ts +3 -1
  197. package/dist/prosemirror/extensions/nodes/TextBoxAnchorExtension.js +5 -3
  198. package/dist/prosemirror/plugins/suggestionMode.js +1 -0
  199. package/dist/prosemirror/revisionCarriers.js +19 -2
  200. package/dist/prosemirror/utils/extractTrackedChanges.d.ts +2 -2
  201. package/dist/prosemirror/utils/extractTrackedChanges.js +59 -23
  202. package/dist/prosemirror/validation.js +55 -27
  203. package/dist/prosemirror/zeroWidthAnchors.d.ts +10 -0
  204. package/dist/prosemirror/zeroWidthAnchors.js +23 -0
  205. package/dist/redline.js +12 -79
  206. package/dist/server.d.ts +4 -4
  207. package/dist/server.js +2 -2
  208. package/dist/shaping/placeRun.d.ts +51 -0
  209. package/dist/shaping/placeRun.js +84 -0
  210. package/dist/shaping/shaper.d.ts +92 -0
  211. package/dist/shaping/shaper.js +102 -0
  212. package/dist/types/block-id.d.ts +18 -2
  213. package/dist/types/block-id.js +49 -5
  214. package/dist/types/content.d.ts +2 -2
  215. package/dist/utils/clipboard.js +4 -3
  216. package/dist/utils/fontResolver.js +183 -0
  217. package/dist/utils/htmlComments.d.ts +17 -0
  218. package/dist/utils/htmlComments.js +22 -0
  219. package/dist/utils/scriptSegments.d.ts +12 -1
  220. package/dist/utils/scriptSegments.js +17 -1
  221. package/dist/version-comparison.d.ts +1 -1
  222. package/package.json +7 -3
@@ -0,0 +1,102 @@
1
+ import __wbg_init, { shapeRun } from "../generated/text_shaper.js";
2
+ import { TaggedError } from "better-result";
3
+ //#region src/shaping/shaper.ts
4
+ /**
5
+ * The boundary to the text shaper.
6
+ *
7
+ * Shaping is the one part of text layout that cannot be derived from code
8
+ * points: Arabic letters take their form from their neighbours, lam-alef
9
+ * ligates, Devanagari reorders and forms conjuncts, Hebrew points hang off the
10
+ * letter they belong to. One implementation answers that question, in Rust, and
11
+ * every caller reaches it through this module: a measurement in CSS pixels and
12
+ * a PDF text matrix scale the same glyph ids and the same advances, so the two
13
+ * cannot describe different text.
14
+ *
15
+ * The artifact is loaded on demand. It carries the OpenType layout engine and
16
+ * the Unicode data that engine needs, and a document in Latin, Cyrillic or
17
+ * Greek needs none of it: `getShaper` is called only once a run in a shaping
18
+ * script is about to be measured or painted, and never before.
19
+ */
20
+ /** Which way a run advances. Resolved by the producer, never guessed here. */
21
+ const SHAPING_DIRECTION = {
22
+ leftToRight: "ltr",
23
+ rightToLeft: "rtl"
24
+ };
25
+ var ShaperError = class extends TaggedError("ShaperError") {};
26
+ /**
27
+ * The flat buffer the WebAssembly entry returns:
28
+ * `[unitsPerEm, glyphCount, (glyphId, cluster, xAdvance, yAdvance, xOffset,
29
+ * yOffset) * glyphCount]`. A page of Arabic is tens of thousands of glyphs, and
30
+ * an object each would cost more in boundary crossings than the shaping itself.
31
+ */
32
+ const HEADER_FIELDS = 2;
33
+ const FIELDS_PER_GLYPH = 6;
34
+ const decode = (buffer) => {
35
+ const unitsPerEm = buffer[0] ?? 0;
36
+ const glyphCount = buffer[1] ?? 0;
37
+ const glyphs = [];
38
+ for (let index = 0; index < glyphCount; index += 1) {
39
+ const at = HEADER_FIELDS + index * FIELDS_PER_GLYPH;
40
+ glyphs.push({
41
+ glyphId: buffer[at] ?? 0,
42
+ cluster: buffer[at + 1] ?? 0,
43
+ xAdvance: buffer[at + 2] ?? 0,
44
+ yAdvance: buffer[at + 3] ?? 0,
45
+ xOffset: buffer[at + 4] ?? 0,
46
+ yOffset: buffer[at + 5] ?? 0
47
+ });
48
+ }
49
+ return {
50
+ glyphs,
51
+ unitsPerEm
52
+ };
53
+ };
54
+ const shaper = { shapeRun: ({ font, faceIndex = 0, text, direction, script = "", language = "", featuresOn = [], featuresOff = [] }) => {
55
+ try {
56
+ return decode(shapeRun(font, faceIndex, text, direction === SHAPING_DIRECTION.rightToLeft, script, language, [...featuresOn], [...featuresOff]));
57
+ } catch (cause) {
58
+ throw new ShaperError({
59
+ message: "Could not shape a run of text",
60
+ cause
61
+ });
62
+ }
63
+ } };
64
+ let loading;
65
+ /**
66
+ * Loads the shaper, once, and hands back the single implementation both the
67
+ * measurer and the PDF backend use.
68
+ *
69
+ * Calling this is what fetches the artifact, so a caller asks for it only after
70
+ * establishing that some run actually needs shaping.
71
+ */
72
+ const getShaper = () => {
73
+ loading ??= __wbg_init().then(() => {
74
+ resolved = shaper;
75
+ return shaper;
76
+ }).catch((cause) => {
77
+ loading = void 0;
78
+ throw new ShaperError({
79
+ message: "Could not initialize the text shaper",
80
+ cause
81
+ });
82
+ });
83
+ return loading;
84
+ };
85
+ /**
86
+ * Whether the artifact has been loaded in this process.
87
+ *
88
+ * Exists for the test that a document in a non-shaping script never pays for
89
+ * it, which is the whole reason this is a separate artifact.
90
+ */
91
+ const shaperLoaded = () => loading !== void 0;
92
+ let resolved = null;
93
+ /**
94
+ * The shaper if it is already loaded, and never a load.
95
+ *
96
+ * The measure seam is synchronous: a measurement cannot await an artifact. So
97
+ * whoever is about to measure text that shapes resolves {@link getShaper}
98
+ * first, and the measurer reads the result here.
99
+ */
100
+ const resolvedShaper = () => resolved;
101
+ //#endregion
102
+ export { SHAPING_DIRECTION, ShaperError, getShaper, resolvedShaper, shaperLoaded };
@@ -11,12 +11,21 @@
11
11
  * branded type makes the divergence a compile-time error rather
12
12
  * than a silent "scrollToBlock retries 20 times and gives up".
13
13
  *
14
- * Two id shapes are allowed:
14
+ * Three id shapes are allowed:
15
15
  * - Word's `w14:paraId` (or any non-empty allocator-generated id),
16
16
  * surfaced verbatim when the source paragraph carries one.
17
17
  * - A zero-padded `seq-NNNN` fallback derived from document order,
18
18
  * used when the paragraph has no paraId or the paraId collides
19
19
  * with one already taken in the same derivation pass.
20
+ * - A zero-padded `blank-NNNN` fallback for a paragraph that holds no
21
+ * text, numbered in its own sequence.
22
+ *
23
+ * The two sequences are separate on purpose. `seq-NNNN` counts the
24
+ * paragraphs that carry text, and that count is the published
25
+ * contract: the server extractor derives the same numbers, and a
26
+ * citation stored against one has to keep naming the same paragraph.
27
+ * Numbering blank paragraphs into the same sequence would renumber
28
+ * every stored citation after the first blank line in a document.
20
29
  */
21
30
  type FolioBlockId = string & {
22
31
  readonly __brand: "folio.blockId";
@@ -37,7 +46,14 @@ type DeriveBlockIdInput = {
37
46
  taken: ReadonlySet<string>;
38
47
  };
39
48
  declare const deriveBlockId: ({ paraId, index, taken }: DeriveBlockIdInput) => FolioBlockId;
49
+ /**
50
+ * The id for a paragraph that holds no text, when it carries no
51
+ * paraId to be named by. Numbered in its own sequence so the
52
+ * published `seq-NNNN` positions stay where they are.
53
+ */
54
+ declare const deriveBlankBlockId: ({ paraId, index, taken }: DeriveBlockIdInput) => FolioBlockId;
40
55
  declare const isSequentialFolioBlockId: (id: string) => boolean;
56
+ declare const isBlankFolioBlockId: (id: string) => boolean;
41
57
  /**
42
58
  * Extract the paraId an id was derived from, if any. Returns `null`
43
59
  * for sequential fallbacks. Accepts plain `string` so consumers that
@@ -60,4 +76,4 @@ declare const getSequentialFolioBlockIdIndex: (id: string) => number | null;
60
76
  */
61
77
  declare const isFolioBlockId: (value: unknown) => value is FolioBlockId;
62
78
  //#endregion
63
- export { DeriveBlockIdInput, FolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, getSequentialFolioBlockIdIndex, isFolioBlockId, isSequentialFolioBlockId };
79
+ export { DeriveBlockIdInput, FolioBlockId, deriveBlankBlockId, deriveBlockId, getFolioParaIdFromBlockId, getSequentialFolioBlockIdIndex, isBlankFolioBlockId, isFolioBlockId, isSequentialFolioBlockId };
@@ -11,17 +11,29 @@
11
11
  * branded type makes the divergence a compile-time error rather
12
12
  * than a silent "scrollToBlock retries 20 times and gives up".
13
13
  *
14
- * Two id shapes are allowed:
14
+ * Three id shapes are allowed:
15
15
  * - Word's `w14:paraId` (or any non-empty allocator-generated id),
16
16
  * surfaced verbatim when the source paragraph carries one.
17
17
  * - A zero-padded `seq-NNNN` fallback derived from document order,
18
18
  * used when the paragraph has no paraId or the paraId collides
19
19
  * with one already taken in the same derivation pass.
20
+ * - A zero-padded `blank-NNNN` fallback for a paragraph that holds no
21
+ * text, numbered in its own sequence.
22
+ *
23
+ * The two sequences are separate on purpose. `seq-NNNN` counts the
24
+ * paragraphs that carry text, and that count is the published
25
+ * contract: the server extractor derives the same numbers, and a
26
+ * citation stored against one has to keep naming the same paragraph.
27
+ * Numbering blank paragraphs into the same sequence would renumber
28
+ * every stored citation after the first blank line in a document.
20
29
  */
21
30
  const SEQUENTIAL_BLOCK_ID_PREFIX = "seq-";
31
+ const BLANK_BLOCK_ID_PREFIX = "blank-";
22
32
  const SEQUENTIAL_BLOCK_ID_PADDING = 4;
23
33
  const SEQUENTIAL_BLOCK_ID_PATTERN = /^seq-\d{4,}$/u;
24
- const formatSequentialBlockId = (index) => `${SEQUENTIAL_BLOCK_ID_PREFIX}${String(index).padStart(SEQUENTIAL_BLOCK_ID_PADDING, "0")}`;
34
+ const BLANK_BLOCK_ID_PATTERN = /^blank-\d{4,}$/u;
35
+ const formatWithPrefix = (prefix, index) => `${prefix}${String(index).padStart(SEQUENTIAL_BLOCK_ID_PADDING, "0")}`;
36
+ const formatSequentialBlockId = (index) => formatWithPrefix(SEQUENTIAL_BLOCK_ID_PREFIX, index);
25
37
  /**
26
38
  * The opaque `FolioBlockId` brand has no constructor; an unchecked
27
39
  * cast is the runtime no-op that mints one. Centralising the cast
@@ -29,8 +41,22 @@ const formatSequentialBlockId = (index) => `${SEQUENTIAL_BLOCK_ID_PREFIX}${Strin
29
41
  * on.
30
42
  */
31
43
  const brand = (value) => value;
44
+ /**
45
+ * Whether a source id would be read back as one this module generated.
46
+ *
47
+ * `seq-` and `blank-` are reserved: `getFolioParaIdFromBlockId` reports an id
48
+ * in either shape as having no source paragraph, and `isFolioBlockId` holds
49
+ * both to their exact pattern. A `w14:paraId` that happened to look like one
50
+ * would therefore be told apart from itself, so it is not used verbatim and
51
+ * the paragraph takes a generated id instead. (A real `w14:paraId` is eight
52
+ * hex digits, so this costs nothing on any package Word writes; it is here so
53
+ * a hand-written or synthesized source cannot break the round trip.)
54
+ */
55
+ const isReservedShape = (paraId) => paraId.startsWith(SEQUENTIAL_BLOCK_ID_PREFIX) || paraId.startsWith(BLANK_BLOCK_ID_PREFIX);
56
+ const usableParaId = (paraId, taken) => paraId !== null && paraId.length > 0 && !taken.has(paraId) && !isReservedShape(paraId) ? paraId : null;
32
57
  const deriveBlockId = ({ paraId, index, taken }) => {
33
- if (paraId !== null && paraId.length > 0 && !taken.has(paraId)) return brand(paraId);
58
+ const usable = usableParaId(paraId, taken);
59
+ if (usable !== null) return brand(usable);
34
60
  let candidate = index;
35
61
  let formatted = formatSequentialBlockId(candidate);
36
62
  while (taken.has(formatted)) {
@@ -39,14 +65,31 @@ const deriveBlockId = ({ paraId, index, taken }) => {
39
65
  }
40
66
  return brand(formatted);
41
67
  };
68
+ /**
69
+ * The id for a paragraph that holds no text, when it carries no
70
+ * paraId to be named by. Numbered in its own sequence so the
71
+ * published `seq-NNNN` positions stay where they are.
72
+ */
73
+ const deriveBlankBlockId = ({ paraId, index, taken }) => {
74
+ const usable = usableParaId(paraId, taken);
75
+ if (usable !== null) return brand(usable);
76
+ let candidate = index;
77
+ let formatted = formatWithPrefix(BLANK_BLOCK_ID_PREFIX, candidate);
78
+ while (taken.has(formatted)) {
79
+ candidate += 1;
80
+ formatted = formatWithPrefix(BLANK_BLOCK_ID_PREFIX, candidate);
81
+ }
82
+ return brand(formatted);
83
+ };
42
84
  const isSequentialFolioBlockId = (id) => SEQUENTIAL_BLOCK_ID_PATTERN.test(id);
85
+ const isBlankFolioBlockId = (id) => BLANK_BLOCK_ID_PATTERN.test(id);
43
86
  /**
44
87
  * Extract the paraId an id was derived from, if any. Returns `null`
45
88
  * for sequential fallbacks. Accepts plain `string` so consumers that
46
89
  * have a raw id (snapshot anchors, operation blockIds) can call it
47
90
  * without an upfront brand check.
48
91
  */
49
- const getFolioParaIdFromBlockId = (id) => isSequentialFolioBlockId(id) ? null : id;
92
+ const getFolioParaIdFromBlockId = (id) => isSequentialFolioBlockId(id) || isBlankFolioBlockId(id) ? null : id;
50
93
  /**
51
94
  * The 1-based document position encoded in a sequential fallback id
52
95
  * (`seq-0011` -> 11), or `null` for paraId-backed ids. The number is
@@ -67,7 +110,8 @@ const getSequentialFolioBlockIdIndex = (id) => {
67
110
  const isFolioBlockId = (value) => {
68
111
  if (typeof value !== "string" || value.length === 0) return false;
69
112
  if (value.startsWith(SEQUENTIAL_BLOCK_ID_PREFIX)) return SEQUENTIAL_BLOCK_ID_PATTERN.test(value);
113
+ if (value.startsWith(BLANK_BLOCK_ID_PREFIX)) return BLANK_BLOCK_ID_PATTERN.test(value);
70
114
  return true;
71
115
  };
72
116
  //#endregion
73
- export { deriveBlockId, getFolioParaIdFromBlockId, getSequentialFolioBlockIdIndex, isFolioBlockId, isSequentialFolioBlockId };
117
+ export { deriveBlankBlockId, deriveBlockId, getFolioParaIdFromBlockId, getSequentialFolioBlockIdIndex, isBlankFolioBlockId, isFolioBlockId, isSequentialFolioBlockId };
@@ -1,2 +1,2 @@
1
- import { BlockContent, BlockSdt, BookmarkEnd, BookmarkStart, BreakContent, Column, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, ComplexField, Deletion, DocumentBody, DrawingContent, DrawingRawXmlMode, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, InlineSdt, Insertion, InstrTextContent, LineNumberRestart, MathEquation, MoveFrom, MoveFromRangeEnd, MoveFromRangeStart, MoveTo, MoveToRangeEnd, MoveToRangeStart, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, PageOrientation, Paragraph, ParagraphContent, ParagraphPropertyChange, PositionalTab, PropertyChangeInfo, Run, RunContent, RunPropertyChange, SdtProperties, SdtType, Section, SectionProperties, SectionStart, Shape, ShapeContent, ShapeFill, ShapeGeometryAdjustment, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, SymbolContent, TabContent, Table, TableCell, TableCellPropertyChange, TableRow, TableRowPropertyChange, TableStructuralChangeInfo, TextBox, TextContent, TrackedChangeInfo, TrackedRunChange, VerticalAlign } from "@stll/docx-core/model";
2
- export type { BlockContent, BlockSdt, BookmarkEnd, BookmarkStart, BreakContent, Column, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, ComplexField, Deletion, DocumentBody, DrawingContent, DrawingRawXmlMode, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, InlineSdt, Insertion, InstrTextContent, LineNumberRestart, MathEquation, MoveFrom, MoveFromRangeEnd, MoveFromRangeStart, MoveTo, MoveToRangeEnd, MoveToRangeStart, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, PageOrientation, Paragraph, ParagraphContent, ParagraphPropertyChange, PositionalTab, PropertyChangeInfo, Run, RunContent, RunPropertyChange, SdtProperties, SdtType, Section, SectionProperties, SectionStart, Shape, ShapeContent, ShapeFill, ShapeGeometryAdjustment, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, SymbolContent, TabContent, Table, TableCell, TableCellPropertyChange, TableRow, TableRowPropertyChange, TableStructuralChangeInfo, TextBox, TextContent, TrackedChangeInfo, TrackedRunChange, VerticalAlign };
1
+ import { BlockContent, BlockSdt, BookmarkEnd, BookmarkStart, BreakContent, Column, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, ComplexField, Deletion, DocumentBody, DrawingContent, DrawingRawXmlMode, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, InlineSdt, Insertion, InstrTextContent, LineNumberRestart, MathEquation, MoveFrom, MoveFromRangeEnd, MoveFromRangeStart, MoveTo, MoveToRangeEnd, MoveToRangeStart, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, PageOrientation, Paragraph, ParagraphContent, ParagraphPropertyChange, PositionalTab, PropertyChangeInfo, Run, RunContent, RunPropertyChange, SdtProperties, SdtType, Section, SectionProperties, SectionStart, Shape, ShapeContent, ShapeFill, ShapeGeometryAdjustment, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, SymbolContent, TabContent, Table, TableCell, TableCellPropertyChange, TableRow, TableRowPropertyChange, TableStructuralChangeInfo, TextBox, TextContent, TrackedChangeInfo, TrackedRunChange, TrackedRunContent, VerticalAlign } from "@stll/docx-core/model";
2
+ export type { BlockContent, BlockSdt, BookmarkEnd, BookmarkStart, BreakContent, Column, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, ComplexField, Deletion, DocumentBody, DrawingContent, DrawingRawXmlMode, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, InlineSdt, Insertion, InstrTextContent, LineNumberRestart, MathEquation, MoveFrom, MoveFromRangeEnd, MoveFromRangeStart, MoveTo, MoveToRangeEnd, MoveToRangeStart, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, PageOrientation, Paragraph, ParagraphContent, ParagraphPropertyChange, PositionalTab, PropertyChangeInfo, Run, RunContent, RunPropertyChange, SdtProperties, SdtType, Section, SectionProperties, SectionStart, Shape, ShapeContent, ShapeFill, ShapeGeometryAdjustment, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, SymbolContent, TabContent, Table, TableCell, TableCellPropertyChange, TableRow, TableRowPropertyChange, TableStructuralChangeInfo, TextBox, TextContent, TrackedChangeInfo, TrackedRunChange, TrackedRunContent, VerticalAlign };
@@ -1,3 +1,4 @@
1
+ import { htmlCommentEnd } from "./htmlComments.js";
1
2
  import { stripXmlDeclarations } from "./stripXmlDeclarations.js";
2
3
  import createDOMPurify from "dompurify";
3
4
  //#region src/utils/clipboard.ts
@@ -259,9 +260,9 @@ function stripHtmlComments(html) {
259
260
  break;
260
261
  }
261
262
  result += html.slice(cursor, start);
262
- const end = html.indexOf("-->", start + 4);
263
- if (end === -1) break;
264
- cursor = end + 3;
263
+ const end = htmlCommentEnd(html, start);
264
+ if (end === null) break;
265
+ cursor = end;
265
266
  }
266
267
  return result;
267
268
  }
@@ -445,6 +445,189 @@ const FONT_MAPPINGS = {
445
445
  unitsPerEm: 2048
446
446
  })
447
447
  },
448
+ "arial narrow": {
449
+ googleFont: "Arimo",
450
+ category: "sans-serif",
451
+ fallbackStack: [
452
+ "Arial Narrow",
453
+ "Arimo",
454
+ "Arial",
455
+ "Helvetica",
456
+ "sans-serif"
457
+ ],
458
+ singleLineRatio: singleLineRatioOf({
459
+ source: "hhea",
460
+ hheaAscent: 1916,
461
+ hheaDescent: -434,
462
+ hheaLineGap: 0,
463
+ unitsPerEm: 2048
464
+ })
465
+ },
466
+ helvetica: {
467
+ googleFont: "Arimo",
468
+ category: "sans-serif",
469
+ fallbackStack: [
470
+ "Helvetica",
471
+ "Arimo",
472
+ "Arial",
473
+ "sans-serif"
474
+ ],
475
+ singleLineRatio: singleLineRatioOf({
476
+ source: "measured",
477
+ ratio: 1.2,
478
+ note: "Measured at 11pt against a 13.2pt reference-layout line pitch. Helvetica's hhea ascent and descent sum to exactly one em, and that 1.0 ratio is not the rendered pitch, so the formula does not apply here."
479
+ })
480
+ },
481
+ "bookman old style": {
482
+ googleFont: "EB Garamond",
483
+ category: "serif",
484
+ fallbackStack: [
485
+ "Bookman Old Style",
486
+ "EB Garamond",
487
+ "Georgia",
488
+ "serif"
489
+ ],
490
+ singleLineRatio: singleLineRatioOf({
491
+ source: "hhea",
492
+ hheaAscent: 1929,
493
+ hheaDescent: -475,
494
+ hheaLineGap: 0,
495
+ unitsPerEm: 2048
496
+ })
497
+ },
498
+ "franklin gothic book": {
499
+ googleFont: "Libre Franklin",
500
+ category: "sans-serif",
501
+ fallbackStack: [
502
+ "Franklin Gothic Book",
503
+ "Libre Franklin",
504
+ "Arial",
505
+ "sans-serif"
506
+ ],
507
+ singleLineRatio: singleLineRatioOf({
508
+ source: "hhea",
509
+ hheaAscent: 1877,
510
+ hheaDescent: -445,
511
+ hheaLineGap: 0,
512
+ unitsPerEm: 2048
513
+ })
514
+ },
515
+ "calibri light": {
516
+ googleFont: "Carlito",
517
+ category: "sans-serif",
518
+ fallbackStack: [
519
+ "Calibri Light",
520
+ "Calibri",
521
+ "Carlito",
522
+ "Arial",
523
+ "sans-serif"
524
+ ],
525
+ singleLineRatio: singleLineRatioOf({
526
+ source: "hhea",
527
+ hheaAscent: 1950,
528
+ hheaDescent: -550,
529
+ hheaLineGap: 0,
530
+ unitsPerEm: 2048
531
+ })
532
+ },
533
+ candara: {
534
+ googleFont: "Carlito",
535
+ category: "sans-serif",
536
+ fallbackStack: [
537
+ "Candara",
538
+ "Carlito",
539
+ "Arial",
540
+ "sans-serif"
541
+ ],
542
+ singleLineRatio: singleLineRatioOf({
543
+ source: "hhea",
544
+ hheaAscent: 1484,
545
+ hheaDescent: -564,
546
+ hheaLineGap: 452,
547
+ unitsPerEm: 2048
548
+ })
549
+ },
550
+ constantia: {
551
+ googleFont: "Caladea",
552
+ category: "serif",
553
+ fallbackStack: [
554
+ "Constantia",
555
+ "Caladea",
556
+ "Georgia",
557
+ "serif"
558
+ ],
559
+ singleLineRatio: singleLineRatioOf({
560
+ source: "hhea",
561
+ hheaAscent: 1538,
562
+ hheaDescent: -510,
563
+ hheaLineGap: 452,
564
+ unitsPerEm: 2048
565
+ })
566
+ },
567
+ corbel: {
568
+ googleFont: "Carlito",
569
+ category: "sans-serif",
570
+ fallbackStack: [
571
+ "Corbel",
572
+ "Carlito",
573
+ "Arial",
574
+ "sans-serif"
575
+ ],
576
+ singleLineRatio: singleLineRatioOf({
577
+ source: "hhea",
578
+ hheaAscent: 1523,
579
+ hheaDescent: -525,
580
+ hheaLineGap: 425,
581
+ unitsPerEm: 2048
582
+ })
583
+ },
584
+ dubai: {
585
+ googleFont: "Noto Sans Arabic",
586
+ category: "sans-serif",
587
+ fallbackStack: [
588
+ "Dubai",
589
+ "Noto Sans Arabic",
590
+ "Arial",
591
+ "sans-serif"
592
+ ],
593
+ singleLineRatio: singleLineRatioOf({
594
+ source: "hhea",
595
+ hheaAscent: 1129,
596
+ hheaDescent: -559,
597
+ hheaLineGap: 0,
598
+ unitsPerEm: 1e3
599
+ })
600
+ },
601
+ "simplified arabic": {
602
+ googleFont: "Noto Naskh Arabic",
603
+ category: "serif",
604
+ fallbackStack: [
605
+ "Simplified Arabic",
606
+ "Noto Naskh Arabic",
607
+ "Times New Roman",
608
+ "serif"
609
+ ],
610
+ singleLineRatio: singleLineRatioOf({
611
+ source: "measured",
612
+ ratio: 1.6582,
613
+ note: "Measured at 11pt against an 18.24pt reference-layout line pitch; the face ships with the office suite, not as a readable font file."
614
+ })
615
+ },
616
+ "sakkal majalla": {
617
+ googleFont: "Noto Naskh Arabic",
618
+ category: "serif",
619
+ fallbackStack: [
620
+ "Sakkal Majalla",
621
+ "Noto Naskh Arabic",
622
+ "Times New Roman",
623
+ "serif"
624
+ ],
625
+ singleLineRatio: singleLineRatioOf({
626
+ source: "measured",
627
+ ratio: 1.3964,
628
+ note: "Measured at 11pt against a 15.36pt reference-layout line pitch; the face ships with the office suite, not as a readable font file."
629
+ })
630
+ },
448
631
  "ms mincho": {
449
632
  googleFont: "Noto Serif JP",
450
633
  category: "serif",
@@ -0,0 +1,17 @@
1
+ //#region src/utils/htmlComments.d.ts
2
+ /**
3
+ * Index just past the HTML comment that opens at `start`, or `null` when the
4
+ * comment is never closed.
5
+ *
6
+ * `<!-->` and `<!--->` are ABRUPT-CLOSING comments: the tokenizer's comment
7
+ * start and comment-start-dash states end the comment at that `>` (HTML
8
+ * §13.2.5.42-43). Scanning for `-->` from `start + 4` runs straight past them,
9
+ * finds nothing, and every caller then treats the rest of the document as one
10
+ * unterminated comment — a pasted payload that opens with `<!-->` is dropped
11
+ * whole and silently.
12
+ *
13
+ * Both comment strippers resolve the terminator here so the two cannot drift.
14
+ */
15
+ declare const htmlCommentEnd: (html: string, start: number) => number | null;
16
+ //#endregion
17
+ export { htmlCommentEnd };
@@ -0,0 +1,22 @@
1
+ //#region src/utils/htmlComments.ts
2
+ /**
3
+ * Index just past the HTML comment that opens at `start`, or `null` when the
4
+ * comment is never closed.
5
+ *
6
+ * `<!-->` and `<!--->` are ABRUPT-CLOSING comments: the tokenizer's comment
7
+ * start and comment-start-dash states end the comment at that `>` (HTML
8
+ * §13.2.5.42-43). Scanning for `-->` from `start + 4` runs straight past them,
9
+ * finds nothing, and every caller then treats the rest of the document as one
10
+ * unterminated comment — a pasted payload that opens with `<!-->` is dropped
11
+ * whole and silently.
12
+ *
13
+ * Both comment strippers resolve the terminator here so the two cannot drift.
14
+ */
15
+ const htmlCommentEnd = (html, start) => {
16
+ if (html[start + 4] === ">") return start + 5;
17
+ if (html[start + 4] === "-" && html[start + 5] === ">") return start + 6;
18
+ const end = html.indexOf("-->", start + 4);
19
+ return end === -1 ? null : end + 3;
20
+ };
21
+ //#endregion
22
+ export { htmlCommentEnd };
@@ -56,6 +56,17 @@ declare function scriptClassOf(cp: number): ScriptClass;
56
56
  * True when the text contains at least one complex-script code point. Callers
57
57
  * use this to skip segmentation entirely on the common all-Latin path.
58
58
  */
59
+ /**
60
+ * True when a code point belongs to a right-to-left script.
61
+ *
62
+ * A subset of the complex-script ranges: Thai, Lao, Khmer, Myanmar, Tibetan and
63
+ * the Indic scripts shape but read left to right. Shaping needs the answer
64
+ * because the direction decides the order glyphs come back in, and a run shaped
65
+ * the wrong way round reads backwards.
66
+ */
67
+ declare function isRightToLeftCodePoint(cp: number): boolean;
68
+ /** True when the text contains at least one right-to-left code point. */
69
+ declare function hasRightToLeft(text: string): boolean;
59
70
  declare function hasComplexScript(text: string): boolean;
60
71
  /**
61
72
  * Split text into maximal runs of one script class (CJK vs. non-CJK). Iterates
@@ -64,4 +75,4 @@ declare function hasComplexScript(text: string): boolean;
64
75
  */
65
76
  declare function segmentByScript(text: string): ScriptSegment[];
66
77
  //#endregion
67
- export { SCRIPT_CLASS, ScriptClass, ScriptSegment, hasCjk, hasComplexScript, isCjkCodePoint, isComplexScriptCodePoint, scriptClassOf, segmentByScript };
78
+ export { SCRIPT_CLASS, ScriptClass, ScriptSegment, hasCjk, hasComplexScript, hasRightToLeft, isCjkCodePoint, isComplexScriptCodePoint, isRightToLeftCodePoint, scriptClassOf, segmentByScript };
@@ -62,6 +62,22 @@ function scriptClassOf(cp) {
62
62
  * True when the text contains at least one complex-script code point. Callers
63
63
  * use this to skip segmentation entirely on the common all-Latin path.
64
64
  */
65
+ /**
66
+ * True when a code point belongs to a right-to-left script.
67
+ *
68
+ * A subset of the complex-script ranges: Thai, Lao, Khmer, Myanmar, Tibetan and
69
+ * the Indic scripts shape but read left to right. Shaping needs the answer
70
+ * because the direction decides the order glyphs come back in, and a run shaped
71
+ * the wrong way round reads backwards.
72
+ */
73
+ function isRightToLeftCodePoint(cp) {
74
+ 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 >= 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;
75
+ }
76
+ /** True when the text contains at least one right-to-left code point. */
77
+ function hasRightToLeft(text) {
78
+ for (const ch of text) if (isRightToLeftCodePoint(ch.codePointAt(0))) return true;
79
+ return false;
80
+ }
65
81
  function hasComplexScript(text) {
66
82
  for (const ch of text) if (isComplexScriptCodePoint(ch.codePointAt(0))) return true;
67
83
  return false;
@@ -100,4 +116,4 @@ function segmentByScript(text) {
100
116
  return segments;
101
117
  }
102
118
  //#endregion
103
- export { SCRIPT_CLASS, hasCjk, hasComplexScript, isCjkCodePoint, isComplexScriptCodePoint, scriptClassOf, segmentByScript };
119
+ export { SCRIPT_CLASS, hasCjk, hasComplexScript, hasRightToLeft, isCjkCodePoint, isComplexScriptCodePoint, isRightToLeftCodePoint, scriptClassOf, segmentByScript };
@@ -1,6 +1,6 @@
1
1
  import { FolioAIBlock } from "./ai-edits/types.js";
2
- import { FolioDocumentStoryHandle } from "./ai-edits/headless.js";
3
2
  import { WordDiffSegment } from "./ai-edits/word-diff.js";
3
+ import { FolioDocumentStoryHandle } from "./ai-edits/headless.js";
4
4
  import { FOLIO_DOCUMENT_METADATA_PROPERTIES, FolioDocumentMetadataProperty, FolioDocumentPrivacyOptions, FolioDocumentPrivacyReport, FolioDocumentPrivacyTransform } from "./docx/metadataPrivacy.js";
5
5
  //#region src/version-comparison.d.ts
6
6
  /** One word-level diff segment within a `modified` block. Mirrors {@link WordDiffSegment}. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stll/folio-core",
3
- "version": "0.32.1",
3
+ "version": "0.33.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",
@@ -108,12 +108,14 @@
108
108
  "prepack": "bun run build",
109
109
  "pack:dry-run": "bun pm pack --dry-run",
110
110
  "typecheck": "bun ../../scripts/tsc-native.ts --noEmit -p tsconfig.build.json",
111
- "test": "bun test src",
111
+ "test": "bun test src scripts",
112
+ "wasm:check": "bun ../../scripts/build-shaper-wasm.ts --check",
113
+ "wasm:generate": "bun ../../scripts/build-shaper-wasm.ts --write",
112
114
  "test:property": "bun test $(grep -rlF 'fc.assert' src --include='*.test.ts')",
113
115
  "perf": "bun scripts/profile-editor.ts"
114
116
  },
115
117
  "dependencies": {
116
- "@stll/docx-core": "^0.18.0",
118
+ "@stll/docx-core": "^0.19.0",
117
119
  "@stll/docx-utils": "^0.1.0",
118
120
  "@stll/template-conditions": "^0.1.0",
119
121
  "better-result": "3.0.1",
@@ -138,6 +140,8 @@
138
140
  "yjs": "^13.6.31"
139
141
  },
140
142
  "devDependencies": {
143
+ "@fontsource/noto-sans-devanagari": "^5.3.0",
144
+ "@fontsource/noto-sans-hebrew": "^5.3.0",
141
145
  "@types/hyphen": "1.14.0"
142
146
  },
143
147
  "main": "./dist/index.js",