@forevka/wordcanvas 0.7.0 → 0.7.1
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/README.md +48 -1
- package/dist-lib/assets/{worker-BsOsK39A.js → worker-D8rUOKfg.js} +9603 -9451
- package/dist-lib/assets/worker-wXuuyshQ.js +2258 -0
- package/dist-lib/{blockFactory-Bcy0U40y.js → blockFactory-CUI4Rqiq.js} +50 -42
- package/dist-lib/{browser-5Sv4CuNy.js → browser-DkKxreJM.js} +404 -383
- package/dist-lib/builder.js +364 -109
- package/dist-lib/editorApp-DLXMmtu5.js +8023 -0
- package/dist-lib/export.js +3820 -3768
- package/dist-lib/generate-toc.js +4 -4
- package/dist-lib/import.js +4 -1538
- package/dist-lib/{lists-BegzmTmD.js → lists-Sc5I40JO.js} +2 -2
- package/dist-lib/pipeline-CbxmCE84.js +1705 -0
- package/dist-lib/recalc-docx.js +2 -2
- package/dist-lib/recalcToc-g1hFKSNs.js +3935 -0
- package/dist-lib/toc-B6VpkJge.js +213 -0
- package/dist-lib/{webmcp-B7Gvd58E.js → webmcp-6WxRNKCc.js} +2 -2
- package/dist-lib/{wordcanvas-BAxBeErX.js → wordcanvas-CFqpDK0k.js} +1 -1
- package/dist-lib/wordcanvas.js +1 -1
- package/dist-node/{chunk-GXFDF7UY.js → chunk-22JHAERT.js} +95 -23
- package/dist-node/chunk-22JHAERT.js.map +7 -0
- package/dist-node/{chunk-2RCPB7UZ.js → chunk-6AJJMHKY.js} +1 -1
- package/dist-node/chunk-6AJJMHKY.js.map +7 -0
- package/dist-node/{chunk-XDUDPPJW.js → chunk-CDN6WU2P.js} +89 -26
- package/dist-node/chunk-CDN6WU2P.js.map +7 -0
- package/dist-node/{chunk-TBSXA2I4.js → chunk-EGSAVPCC.js} +1 -1
- package/dist-node/chunk-EGSAVPCC.js.map +7 -0
- package/dist-node/{chunk-IJLL6IFJ.js → chunk-RNB336F3.js} +116 -5
- package/dist-node/{chunk-IJLL6IFJ.js.map → chunk-RNB336F3.js.map} +2 -2
- package/dist-node/{engine-FRCX7PXF.js → engine-5FGDJD2H.js} +3 -3
- package/dist-node/export.js +92 -31
- package/dist-node/export.js.map +2 -2
- package/dist-node/generate-toc.js +5 -5
- package/dist-node/import.js +3 -3
- package/dist-node/recalc-docx.js +4 -4
- package/dist-node/recalc-docx.js.map +1 -1
- package/package.json +1 -1
- package/types/model.d.ts +231 -225
- package/types/recalc-docx.d.ts +27 -27
- package/dist-lib/assets/worker-BbFAIxdy.js +0 -2163
- package/dist-lib/editorApp-DvjFPHiy.js +0 -7582
- package/dist-lib/recalcToc-uaLWt59L.js +0 -3835
- package/dist-lib/toc-CZel_Kk3.js +0 -127
- package/dist-node/chunk-2RCPB7UZ.js.map +0 -7
- package/dist-node/chunk-GXFDF7UY.js.map +0 -7
- package/dist-node/chunk-TBSXA2I4.js.map +0 -7
- package/dist-node/chunk-XDUDPPJW.js.map +0 -7
- /package/dist-node/{engine-FRCX7PXF.js.map → engine-5FGDJD2H.js.map} +0 -0
|
@@ -6,7 +6,7 @@ const __filename = __fileURLToPath(import.meta.url);
|
|
|
6
6
|
const __dirname = __pathDirname(__filename);
|
|
7
7
|
import {
|
|
8
8
|
runImport
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-22JHAERT.js";
|
|
10
10
|
import {
|
|
11
11
|
el,
|
|
12
12
|
escapeText,
|
|
@@ -16,10 +16,10 @@ import {
|
|
|
16
16
|
} from "./chunk-4PDVRJF6.js";
|
|
17
17
|
import {
|
|
18
18
|
findMainDocumentPart
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-6AJJMHKY.js";
|
|
20
20
|
import {
|
|
21
21
|
pageOfBlockMap
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-EGSAVPCC.js";
|
|
23
23
|
import {
|
|
24
24
|
strFromU8,
|
|
25
25
|
strToU8,
|
|
@@ -28,14 +28,14 @@ import {
|
|
|
28
28
|
} from "./chunk-5PUCGN47.js";
|
|
29
29
|
import {
|
|
30
30
|
createLayoutEngine
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-RNB336F3.js";
|
|
32
32
|
import {
|
|
33
33
|
detectTocHeadings,
|
|
34
34
|
inRange,
|
|
35
35
|
parseTocInstruction,
|
|
36
36
|
textOfRuns,
|
|
37
37
|
tocEntryStyle
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-CDN6WU2P.js";
|
|
39
39
|
import "./chunk-4ICCHZX4.js";
|
|
40
40
|
import "./chunk-XSRSBST2.js";
|
|
41
41
|
|
package/dist-node/import.js
CHANGED
|
@@ -6,10 +6,10 @@ const __filename = __fileURLToPath(import.meta.url);
|
|
|
6
6
|
const __dirname = __pathDirname(__filename);
|
|
7
7
|
import {
|
|
8
8
|
runImport
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-22JHAERT.js";
|
|
10
|
+
import "./chunk-6AJJMHKY.js";
|
|
11
11
|
import "./chunk-5PUCGN47.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-CDN6WU2P.js";
|
|
13
13
|
import "./chunk-XSRSBST2.js";
|
|
14
14
|
export {
|
|
15
15
|
runImport
|
package/dist-node/recalc-docx.js
CHANGED
|
@@ -6,10 +6,10 @@ const __filename = __fileURLToPath(import.meta.url);
|
|
|
6
6
|
const __dirname = __pathDirname(__filename);
|
|
7
7
|
import {
|
|
8
8
|
findMainDocumentPart
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6AJJMHKY.js";
|
|
10
10
|
import {
|
|
11
11
|
pageOfBlockMap
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-EGSAVPCC.js";
|
|
13
13
|
import {
|
|
14
14
|
strFromU8,
|
|
15
15
|
strToU8,
|
|
@@ -18,8 +18,8 @@ import {
|
|
|
18
18
|
} from "./chunk-5PUCGN47.js";
|
|
19
19
|
import {
|
|
20
20
|
createLayoutEngine
|
|
21
|
-
} from "./chunk-
|
|
22
|
-
import "./chunk-
|
|
21
|
+
} from "./chunk-RNB336F3.js";
|
|
22
|
+
import "./chunk-CDN6WU2P.js";
|
|
23
23
|
import "./chunk-4ICCHZX4.js";
|
|
24
24
|
import "./chunk-XSRSBST2.js";
|
|
25
25
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/recalc/patchTocDocx.ts"],
|
|
4
|
-
"sourcesContent": ["// Patch a .docx's TOC page numbers IN PLACE \u2014 the faithful path for fixing an\n// externally-authored document (e.g. a C# render pipeline that emits a real Word\n// TOC field but can't compute page numbers). We import only to RUN THE LAYOUT and\n// learn each heading's page; we then surgically rewrite the cached PAGEREF result\n// digits in the ORIGINAL document.xml and re-zip. Everything else \u2014 the live TOC\n// field, PAGEREF/HYPERLINK fields, footer PAGE/NUMPAGES, styles, and any OOXML our\n// model doesn't represent \u2014 survives byte-for-byte. Because we never regenerate the\n// file through the export writer, there is no import\u2194export pagination drift.\n//\n// Limitation (documented, intentional): only arabic (\\d+) cached page numbers are\n// recalculated. A roman/alpha cached value is left untouched and counted in\n// `skipped` rather than being overwritten with a wrong arabic number.\n\nimport { strFromU8, strToU8, unzipSync, zipSync, type Unzipped } from \"fflate\";\nimport type { Document } from \"@cw/shared\";\nimport { findMainDocumentPart } from \"../import/docx/contentTypes\";\nimport { createLayoutEngine } from \"../layout/engine\";\nimport type { LayoutTree } from \"../layout/layoutTree\";\nimport { pageOfBlockMap } from \"./recalcToc\";\n\n/** bookmark name \u2192 displayed page number (as a string) of the block it starts at.\n * The PAGEREF instruction in the XML references the same bookmark name, so this is\n * how the layout's per-block page maps onto the document's fields. */\nexport function pageByBookmark(doc: Document, tree: LayoutTree): Record<string, string> {\n const pageOfBlock = pageOfBlockMap(tree);\n const out: Record<string, string> = {};\n for (const [name, range] of Object.entries(doc.bookmarks ?? {})) {\n const page = pageOfBlock.get(range.start.blockId);\n if (page !== undefined) out[name] = String(page);\n }\n return out;\n}\n\nexport interface PatchResult {\n bytes: Uint8Array;\n /** PAGEREF cached numbers rewritten to a new value. */\n changed: number;\n /** PAGEREF results left untouched because the cached value was non-arabic. */\n skipped: number;\n}\n\nconst PAGEREF_RE = /\\bPAGEREF\\s+(\"[^\"]+\"|\\S+)/;\n\n// fldChar (begin|separate|end) | instrText(content) | w:t(open)(content)(close)\nconst TOKEN_RE =\n /<w:fldChar\\b[^>]*?w:fldCharType=\"(begin|separate|end)\"[^>]*?\\/?>|<w:instrText\\b[^>]*?>([\\s\\S]*?)<\\/w:instrText>|(<w:t\\b[^>]*?>)([\\s\\S]*?)(<\\/w:t>)/g;\n\ninterface Frame {\n instr: string;\n anchor?: string; // set when the field is a PAGEREF\n sawSeparate: boolean;\n done: boolean; // first result run handled\n replaced: boolean; // we rewrote the number \u2192 blank any split remainder\n}\n\n/** Rewrite cached PAGEREF result digits in one document-part XML string. */\nfunction patchXml(xml: string, pages: Record<string, string>): { xml: string; changed: number; skipped: number } {\n const stack: Frame[] = [];\n let out = \"\";\n let cursor = 0;\n let changed = 0;\n let skipped = 0;\n TOKEN_RE.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = TOKEN_RE.exec(xml)) !== null) {\n const top = stack[stack.length - 1];\n let replacement: string | null = null; // non-null \u2192 replace this match's slice\n\n if (m[1] !== undefined) {\n // w:fldChar\n if (m[1] === \"begin\") stack.push({ instr: \"\", sawSeparate: false, done: false, replaced: false });\n else if (m[1] === \"separate\") {\n if (top) top.sawSeparate = true;\n } else stack.pop(); // \"end\"\n } else if (m[2] !== undefined) {\n // w:instrText\n if (top) {\n top.instr += m[2];\n const pm = top.instr.match(PAGEREF_RE);\n if (pm) top.anchor = pm[1]!.replace(/^\"|\"$/g, \"\");\n }\n } else {\n // w:t \u2014 group 3 open, 4 content, 5 close\n if (top?.anchor && top.sawSeparate) {\n if (!top.done) {\n top.done = true;\n const num = pages[top.anchor];\n if (num !== undefined && /^\\d+$/.test(m[4]!)) {\n if (m[4] !== num) {\n replacement = m[3]! + num + m[5]!;\n changed++;\n top.replaced = true;\n }\n } else if (num !== undefined && !/^\\d+$/.test(m[4]!.trim()) && m[4]!.trim().length > 0) {\n skipped++; // non-arabic cached value \u2014 leave it (unsupported)\n }\n } else if (top.replaced && m[4] !== \"\") {\n // Split number (\"1\",\"2\"): the full value went into the first run; blank the rest.\n replacement = m[3]! + m[5]!;\n }\n }\n }\n\n if (replacement !== null) {\n out += xml.slice(cursor, m.index) + replacement;\n cursor = m.index + m[0].length;\n }\n }\n out += xml.slice(cursor);\n return { xml: out, changed, skipped };\n}\n\n/** Patch the cached TOC/cross-reference page numbers in a .docx, preserving every\n * field and every other part. `pages` maps bookmark name \u2192 new page number. */\nexport function patchTocPageNumbers(docxBytes: Uint8Array, pages: Record<string, string>): PatchResult {\n const parts: Unzipped = unzipSync(docxBytes);\n const ctXml = parts[\"[Content_Types].xml\"];\n const mainPart =\n (ctXml ? findMainDocumentPart(strFromU8(ctXml)) : undefined) ?? \"word/document.xml\";\n const docPart = parts[mainPart];\n if (!docPart) return { bytes: docxBytes, changed: 0, skipped: 0 };\n\n const { xml, changed, skipped } = patchXml(strFromU8(docPart), pages);\n if (changed === 0) return { bytes: docxBytes, changed: 0, skipped };\n\n parts[mainPart] = strToU8(xml);\n return { bytes: zipSync(parts), changed, skipped };\n}\n\n/** Convenience: lay the doc out and patch the original bytes from it. The caller\n * MUST have awaited installMeasureHost() first (layout measures text). */\nexport function patchTocFromLayout(docxBytes: Uint8Array, doc: Document): PatchResult {\n const tree = createLayoutEngine().layout(doc);\n return patchTocPageNumbers(docxBytes, pageByBookmark(doc, tree));\n}\n"],
|
|
4
|
+
"sourcesContent": ["// Patch a .docx's TOC page numbers IN PLACE \u2014 the faithful path for fixing an\r\n// externally-authored document (e.g. a C# render pipeline that emits a real Word\r\n// TOC field but can't compute page numbers). We import only to RUN THE LAYOUT and\r\n// learn each heading's page; we then surgically rewrite the cached PAGEREF result\r\n// digits in the ORIGINAL document.xml and re-zip. Everything else \u2014 the live TOC\r\n// field, PAGEREF/HYPERLINK fields, footer PAGE/NUMPAGES, styles, and any OOXML our\r\n// model doesn't represent \u2014 survives byte-for-byte. Because we never regenerate the\r\n// file through the export writer, there is no import\u2194export pagination drift.\r\n//\r\n// Limitation (documented, intentional): only arabic (\\d+) cached page numbers are\r\n// recalculated. A roman/alpha cached value is left untouched and counted in\r\n// `skipped` rather than being overwritten with a wrong arabic number.\r\n\r\nimport { strFromU8, strToU8, unzipSync, zipSync, type Unzipped } from \"fflate\";\r\nimport type { Document } from \"@cw/shared\";\r\nimport { findMainDocumentPart } from \"../import/docx/contentTypes\";\r\nimport { createLayoutEngine } from \"../layout/engine\";\r\nimport type { LayoutTree } from \"../layout/layoutTree\";\r\nimport { pageOfBlockMap } from \"./recalcToc\";\r\n\r\n/** bookmark name \u2192 displayed page number (as a string) of the block it starts at.\r\n * The PAGEREF instruction in the XML references the same bookmark name, so this is\r\n * how the layout's per-block page maps onto the document's fields. */\r\nexport function pageByBookmark(doc: Document, tree: LayoutTree): Record<string, string> {\r\n const pageOfBlock = pageOfBlockMap(tree);\r\n const out: Record<string, string> = {};\r\n for (const [name, range] of Object.entries(doc.bookmarks ?? {})) {\r\n const page = pageOfBlock.get(range.start.blockId);\r\n if (page !== undefined) out[name] = String(page);\r\n }\r\n return out;\r\n}\r\n\r\nexport interface PatchResult {\r\n bytes: Uint8Array;\r\n /** PAGEREF cached numbers rewritten to a new value. */\r\n changed: number;\r\n /** PAGEREF results left untouched because the cached value was non-arabic. */\r\n skipped: number;\r\n}\r\n\r\nconst PAGEREF_RE = /\\bPAGEREF\\s+(\"[^\"]+\"|\\S+)/;\r\n\r\n// fldChar (begin|separate|end) | instrText(content) | w:t(open)(content)(close)\r\nconst TOKEN_RE =\r\n /<w:fldChar\\b[^>]*?w:fldCharType=\"(begin|separate|end)\"[^>]*?\\/?>|<w:instrText\\b[^>]*?>([\\s\\S]*?)<\\/w:instrText>|(<w:t\\b[^>]*?>)([\\s\\S]*?)(<\\/w:t>)/g;\r\n\r\ninterface Frame {\r\n instr: string;\r\n anchor?: string; // set when the field is a PAGEREF\r\n sawSeparate: boolean;\r\n done: boolean; // first result run handled\r\n replaced: boolean; // we rewrote the number \u2192 blank any split remainder\r\n}\r\n\r\n/** Rewrite cached PAGEREF result digits in one document-part XML string. */\r\nfunction patchXml(xml: string, pages: Record<string, string>): { xml: string; changed: number; skipped: number } {\r\n const stack: Frame[] = [];\r\n let out = \"\";\r\n let cursor = 0;\r\n let changed = 0;\r\n let skipped = 0;\r\n TOKEN_RE.lastIndex = 0;\r\n let m: RegExpExecArray | null;\r\n while ((m = TOKEN_RE.exec(xml)) !== null) {\r\n const top = stack[stack.length - 1];\r\n let replacement: string | null = null; // non-null \u2192 replace this match's slice\r\n\r\n if (m[1] !== undefined) {\r\n // w:fldChar\r\n if (m[1] === \"begin\") stack.push({ instr: \"\", sawSeparate: false, done: false, replaced: false });\r\n else if (m[1] === \"separate\") {\r\n if (top) top.sawSeparate = true;\r\n } else stack.pop(); // \"end\"\r\n } else if (m[2] !== undefined) {\r\n // w:instrText\r\n if (top) {\r\n top.instr += m[2];\r\n const pm = top.instr.match(PAGEREF_RE);\r\n if (pm) top.anchor = pm[1]!.replace(/^\"|\"$/g, \"\");\r\n }\r\n } else {\r\n // w:t \u2014 group 3 open, 4 content, 5 close\r\n if (top?.anchor && top.sawSeparate) {\r\n if (!top.done) {\r\n top.done = true;\r\n const num = pages[top.anchor];\r\n if (num !== undefined && /^\\d+$/.test(m[4]!)) {\r\n if (m[4] !== num) {\r\n replacement = m[3]! + num + m[5]!;\r\n changed++;\r\n top.replaced = true;\r\n }\r\n } else if (num !== undefined && !/^\\d+$/.test(m[4]!.trim()) && m[4]!.trim().length > 0) {\r\n skipped++; // non-arabic cached value \u2014 leave it (unsupported)\r\n }\r\n } else if (top.replaced && m[4] !== \"\") {\r\n // Split number (\"1\",\"2\"): the full value went into the first run; blank the rest.\r\n replacement = m[3]! + m[5]!;\r\n }\r\n }\r\n }\r\n\r\n if (replacement !== null) {\r\n out += xml.slice(cursor, m.index) + replacement;\r\n cursor = m.index + m[0].length;\r\n }\r\n }\r\n out += xml.slice(cursor);\r\n return { xml: out, changed, skipped };\r\n}\r\n\r\n/** Patch the cached TOC/cross-reference page numbers in a .docx, preserving every\r\n * field and every other part. `pages` maps bookmark name \u2192 new page number. */\r\nexport function patchTocPageNumbers(docxBytes: Uint8Array, pages: Record<string, string>): PatchResult {\r\n const parts: Unzipped = unzipSync(docxBytes);\r\n const ctXml = parts[\"[Content_Types].xml\"];\r\n const mainPart =\r\n (ctXml ? findMainDocumentPart(strFromU8(ctXml)) : undefined) ?? \"word/document.xml\";\r\n const docPart = parts[mainPart];\r\n if (!docPart) return { bytes: docxBytes, changed: 0, skipped: 0 };\r\n\r\n const { xml, changed, skipped } = patchXml(strFromU8(docPart), pages);\r\n if (changed === 0) return { bytes: docxBytes, changed: 0, skipped };\r\n\r\n parts[mainPart] = strToU8(xml);\r\n return { bytes: zipSync(parts), changed, skipped };\r\n}\r\n\r\n/** Convenience: lay the doc out and patch the original bytes from it. The caller\r\n * MUST have awaited installMeasureHost() first (layout measures text). */\r\nexport function patchTocFromLayout(docxBytes: Uint8Array, doc: Document): PatchResult {\r\n const tree = createLayoutEngine().layout(doc);\r\n return patchTocPageNumbers(docxBytes, pageByBookmark(doc, tree));\r\n}\r\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;AAuBO,SAAS,eAAe,KAAe,MAA0C;AACtF,QAAM,cAAc,eAAe,IAAI;AACvC,QAAM,MAA8B,CAAC;AACrC,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,IAAI,aAAa,CAAC,CAAC,GAAG;AAC/D,UAAM,OAAO,YAAY,IAAI,MAAM,MAAM,OAAO;AAChD,QAAI,SAAS,OAAW,KAAI,IAAI,IAAI,OAAO,IAAI;AAAA,EACjD;AACA,SAAO;AACT;AAUA,IAAM,aAAa;AAGnB,IAAM,WACJ;AAWF,SAAS,SAAS,KAAa,OAAkF;AAC/G,QAAM,QAAiB,CAAC;AACxB,MAAI,MAAM;AACV,MAAI,SAAS;AACb,MAAI,UAAU;AACd,MAAI,UAAU;AACd,WAAS,YAAY;AACrB,MAAI;AACJ,UAAQ,IAAI,SAAS,KAAK,GAAG,OAAO,MAAM;AACxC,UAAM,MAAM,MAAM,MAAM,SAAS,CAAC;AAClC,QAAI,cAA6B;AAEjC,QAAI,EAAE,CAAC,MAAM,QAAW;AAEtB,UAAI,EAAE,CAAC,MAAM,QAAS,OAAM,KAAK,EAAE,OAAO,IAAI,aAAa,OAAO,MAAM,OAAO,UAAU,MAAM,CAAC;AAAA,eACvF,EAAE,CAAC,MAAM,YAAY;AAC5B,YAAI,IAAK,KAAI,cAAc;AAAA,MAC7B,MAAO,OAAM,IAAI;AAAA,IACnB,WAAW,EAAE,CAAC,MAAM,QAAW;AAE7B,UAAI,KAAK;AACP,YAAI,SAAS,EAAE,CAAC;AAChB,cAAM,KAAK,IAAI,MAAM,MAAM,UAAU;AACrC,YAAI,GAAI,KAAI,SAAS,GAAG,CAAC,EAAG,QAAQ,UAAU,EAAE;AAAA,MAClD;AAAA,IACF,OAAO;AAEL,UAAI,KAAK,UAAU,IAAI,aAAa;AAClC,YAAI,CAAC,IAAI,MAAM;AACb,cAAI,OAAO;AACX,gBAAM,MAAM,MAAM,IAAI,MAAM;AAC5B,cAAI,QAAQ,UAAa,QAAQ,KAAK,EAAE,CAAC,CAAE,GAAG;AAC5C,gBAAI,EAAE,CAAC,MAAM,KAAK;AAChB,4BAAc,EAAE,CAAC,IAAK,MAAM,EAAE,CAAC;AAC/B;AACA,kBAAI,WAAW;AAAA,YACjB;AAAA,UACF,WAAW,QAAQ,UAAa,CAAC,QAAQ,KAAK,EAAE,CAAC,EAAG,KAAK,CAAC,KAAK,EAAE,CAAC,EAAG,KAAK,EAAE,SAAS,GAAG;AACtF;AAAA,UACF;AAAA,QACF,WAAW,IAAI,YAAY,EAAE,CAAC,MAAM,IAAI;AAEtC,wBAAc,EAAE,CAAC,IAAK,EAAE,CAAC;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAEA,QAAI,gBAAgB,MAAM;AACxB,aAAO,IAAI,MAAM,QAAQ,EAAE,KAAK,IAAI;AACpC,eAAS,EAAE,QAAQ,EAAE,CAAC,EAAE;AAAA,IAC1B;AAAA,EACF;AACA,SAAO,IAAI,MAAM,MAAM;AACvB,SAAO,EAAE,KAAK,KAAK,SAAS,QAAQ;AACtC;AAIO,SAAS,oBAAoB,WAAuB,OAA4C;AACrG,QAAM,QAAkB,UAAU,SAAS;AAC3C,QAAM,QAAQ,MAAM,qBAAqB;AACzC,QAAM,YACH,QAAQ,qBAAqB,UAAU,KAAK,CAAC,IAAI,WAAc;AAClE,QAAM,UAAU,MAAM,QAAQ;AAC9B,MAAI,CAAC,QAAS,QAAO,EAAE,OAAO,WAAW,SAAS,GAAG,SAAS,EAAE;AAEhE,QAAM,EAAE,KAAK,SAAS,QAAQ,IAAI,SAAS,UAAU,OAAO,GAAG,KAAK;AACpE,MAAI,YAAY,EAAG,QAAO,EAAE,OAAO,WAAW,SAAS,GAAG,QAAQ;AAElE,QAAM,QAAQ,IAAI,QAAQ,GAAG;AAC7B,SAAO,EAAE,OAAO,QAAQ,KAAK,GAAG,SAAS,QAAQ;AACnD;AAIO,SAAS,mBAAmB,WAAuB,KAA4B;AACpF,QAAM,OAAO,mBAAmB,EAAE,OAAO,GAAG;AAC5C,SAAO,oBAAoB,WAAW,eAAe,KAAK,IAAI,CAAC;AACjE;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forevka/wordcanvas",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Open-source embeddable Word-style document editor: canvas-rendered, with live collaboration, track changes & comments, and DOCX/PDF import & export. A lightweight alternative to Syncfusion, OnlyOffice, and DevExpress document editors. Self-contained, zero runtime dependencies.",
|
|
6
6
|
"license": "MIT",
|
package/types/model.d.ts
CHANGED
|
@@ -1,225 +1,231 @@
|
|
|
1
|
-
// Public document-model types for @forevka/wordcanvas. Hand-written (like
|
|
2
|
-
// wordcanvas.d.ts) so the published surface stays self-contained and stable;
|
|
3
|
-
// mirrors shared/src/model — the editor, builder, and exporters all consume
|
|
4
|
-
// this same plain-data shape.
|
|
5
|
-
|
|
6
|
-
export interface CharStyle {
|
|
7
|
-
fontFamily: string;
|
|
8
|
-
fontSizePx: number;
|
|
9
|
-
bold: boolean;
|
|
10
|
-
italic: boolean;
|
|
11
|
-
underline: boolean;
|
|
12
|
-
strikethrough: boolean;
|
|
13
|
-
/** CSS color, e.g. "#202124". */
|
|
14
|
-
color: string;
|
|
15
|
-
/** Hidden text (OOXML w:vanish) — preserved but never laid out or painted. */
|
|
16
|
-
hidden?: boolean;
|
|
17
|
-
letterSpacingPx?: number;
|
|
18
|
-
/** Background highlight (Word's text highlight). */
|
|
19
|
-
highlightColor?: string | undefined;
|
|
20
|
-
/** Sub/superscript. */
|
|
21
|
-
verticalAlign?: "sub" | "super" | undefined;
|
|
22
|
-
/** Hyperlink target; linked runs paint blue+underlined. */
|
|
23
|
-
link?: string | undefined;
|
|
24
|
-
/** Footnote reference id — this run is the marker. */
|
|
25
|
-
footnoteRef?: string | undefined;
|
|
26
|
-
/** Content-control membership (properties live in Document.sdts). */
|
|
27
|
-
sdtId?: string | undefined;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface TabStop {
|
|
31
|
-
/** Position from the left content edge, px. */
|
|
32
|
-
posPx: number;
|
|
33
|
-
align?: "left" | "center" | "right" | "decimal";
|
|
34
|
-
leader?: "none" | "dot" | "dash" | "underscore";
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface ParaStyle {
|
|
38
|
-
align: "left" | "center" | "right" | "justify";
|
|
39
|
-
/** Line height multiplier. */
|
|
40
|
-
lineHeight: number;
|
|
41
|
-
spaceBeforePx: number;
|
|
42
|
-
spaceAfterPx: number;
|
|
43
|
-
indentFirstLinePx: number;
|
|
44
|
-
indentLeftPx: number;
|
|
45
|
-
indentRightPx?: number;
|
|
46
|
-
keepWithNext?: boolean;
|
|
47
|
-
keepLinesTogether?: boolean;
|
|
48
|
-
/** This paragraph starts a new page. */
|
|
49
|
-
pageBreakBefore?: boolean;
|
|
50
|
-
/** List membership: definition id + level 0..8. */
|
|
51
|
-
list?: { listId: string; level: number } | undefined;
|
|
52
|
-
/** Named style reference into Document.stylesheet (e.g. "Heading1"). */
|
|
53
|
-
namedStyle?: string;
|
|
54
|
-
columnBreakBefore?: boolean;
|
|
55
|
-
tabStops?: TabStop[];
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/** Style-homogeneous span of text. */
|
|
59
|
-
export interface Run {
|
|
60
|
-
text: string;
|
|
61
|
-
style: CharStyle;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface Paragraph {
|
|
65
|
-
kind: "paragraph";
|
|
66
|
-
/** Stable unique id. */
|
|
67
|
-
id: string;
|
|
68
|
-
revision: number;
|
|
69
|
-
runs: Run[];
|
|
70
|
-
style: ParaStyle;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export interface ImageBlock {
|
|
74
|
-
kind: "image";
|
|
75
|
-
id: string;
|
|
76
|
-
revision: number;
|
|
77
|
-
/** Image URL — use data: URLs for portable documents. */
|
|
78
|
-
src: string;
|
|
79
|
-
/** Content address of the bytes (sha256 hex), when registered. */
|
|
80
|
-
mediaId?: string;
|
|
81
|
-
widthPx: number;
|
|
82
|
-
heightPx: number;
|
|
83
|
-
align: "left" | "center" | "right";
|
|
84
|
-
/** 'block' (default): own line. 'square': floats per align, text wraps. */
|
|
85
|
-
wrap?: "block" | "square";
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export interface CellBorder {
|
|
89
|
-
color: string;
|
|
90
|
-
widthPx: number;
|
|
91
|
-
style?: "single" | "double" | "dashed" | "dotted";
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export interface CellBorders {
|
|
95
|
-
top?: CellBorder;
|
|
96
|
-
right?: CellBorder;
|
|
97
|
-
bottom?: CellBorder;
|
|
98
|
-
left?: CellBorder;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export interface CellMargin {
|
|
102
|
-
top: number;
|
|
103
|
-
right: number;
|
|
104
|
-
bottom: number;
|
|
105
|
-
left: number;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface TableCell {
|
|
109
|
-
id: string;
|
|
110
|
-
blocks: Block[];
|
|
111
|
-
colSpan?: number;
|
|
112
|
-
rowSpan?: number;
|
|
113
|
-
/** Background fill (CSS color). */
|
|
114
|
-
shading?: string;
|
|
115
|
-
borders?: CellBorders;
|
|
116
|
-
margin?: CellMargin;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export interface TableRow {
|
|
120
|
-
cells: TableCell[];
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export interface TableBlock {
|
|
124
|
-
kind: "table";
|
|
125
|
-
id: string;
|
|
126
|
-
revision: number;
|
|
127
|
-
rows: TableRow[];
|
|
128
|
-
/** Column widths as fractions of content width (sum = 1). Absent = equal. */
|
|
129
|
-
colFractions?: number[];
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export type Block = Paragraph | ImageBlock | TableBlock;
|
|
133
|
-
|
|
134
|
-
export type BandContainer = "header" | "footer" | "headerFirst" | "headerEven" | "footerFirst" | "footerEven";
|
|
135
|
-
|
|
136
|
-
export interface SectionProps {
|
|
137
|
-
pageWidthPx: number;
|
|
138
|
-
pageHeightPx: number;
|
|
139
|
-
marginPx: { top: number; right: number; bottom: number; left: number };
|
|
140
|
-
/** Newspaper columns. Absent = single column. */
|
|
141
|
-
columns?: { count: number; gapPx: number };
|
|
142
|
-
pageNumberStart?: number;
|
|
143
|
-
headerDistancePx?: number;
|
|
144
|
-
footerDistancePx?: number;
|
|
145
|
-
/** Header/footer block stories. {page}/{pages} tokens in run text are
|
|
146
|
-
* substituted per page at layout time. */
|
|
147
|
-
header?: Block[];
|
|
148
|
-
footer?: Block[];
|
|
149
|
-
headerFirst?: Block[];
|
|
150
|
-
headerEven?: Block[];
|
|
151
|
-
footerFirst?: Block[];
|
|
152
|
-
footerEven?: Block[];
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export interface NamedStyle {
|
|
156
|
-
/** Shares the docx styleId space ("Normal", "Heading1", …). */
|
|
157
|
-
id: string;
|
|
158
|
-
/** Display name. */
|
|
159
|
-
name: string;
|
|
160
|
-
basedOn?: string;
|
|
161
|
-
char: Partial<CharStyle>;
|
|
162
|
-
para: Partial<ParaStyle>;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export interface Stylesheet {
|
|
166
|
-
styles: NamedStyle[];
|
|
167
|
-
defaultStyleId: string;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
export type ListNumberFormat = "bullet" | "decimal" | "lowerLetter" | "upperLetter" | "lowerRoman" | "upperRoman";
|
|
171
|
-
|
|
172
|
-
export interface ListLevel {
|
|
173
|
-
format: ListNumberFormat;
|
|
174
|
-
/** Marker pattern; %N is level N-1's counter (e.g. "%1."). Ignored for bullets. */
|
|
175
|
-
text: string;
|
|
176
|
-
bulletChar?: string;
|
|
177
|
-
indentLeftPx: number;
|
|
178
|
-
hangingPx: number;
|
|
179
|
-
start: number;
|
|
180
|
-
markerStyle?: Partial<CharStyle>;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
export interface ListDefinition {
|
|
184
|
-
id: string;
|
|
185
|
-
/** Up to 9 levels (0..8). */
|
|
186
|
-
levels: ListLevel[];
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export interface DocPosition {
|
|
190
|
-
blockId: string;
|
|
191
|
-
offset: number;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export interface BookmarkRange {
|
|
195
|
-
start: DocPosition;
|
|
196
|
-
end: DocPosition;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
export type SdtType = "richText" | "plainText" | "checkbox" | "dropDown" | "comboBox" | "date";
|
|
200
|
-
|
|
201
|
-
export interface SdtProps {
|
|
202
|
-
type: SdtType;
|
|
203
|
-
alias?: string;
|
|
204
|
-
tag?: string;
|
|
205
|
-
placeholder?: boolean;
|
|
206
|
-
listItems?: { display: string; value: string }[];
|
|
207
|
-
dateFormat?: string;
|
|
208
|
-
checked?: boolean;
|
|
209
|
-
lockContent?: boolean;
|
|
210
|
-
lockControl?: boolean;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export interface Document {
|
|
214
|
-
section: SectionProps;
|
|
215
|
-
blocks: Block[];
|
|
216
|
-
stylesheet?: Stylesheet;
|
|
217
|
-
/** List definitions keyed by id. */
|
|
218
|
-
lists?: Record<string, ListDefinition>;
|
|
219
|
-
/** Footnote bodies keyed by ref id. */
|
|
220
|
-
footnotes?: Record<string, Paragraph[]>;
|
|
221
|
-
/** Content-control properties keyed by sdtId. */
|
|
222
|
-
sdts?: Record<string, SdtProps>;
|
|
223
|
-
/** Bookmark name → character range. */
|
|
224
|
-
bookmarks?: Record<string, BookmarkRange>;
|
|
225
|
-
|
|
1
|
+
// Public document-model types for @forevka/wordcanvas. Hand-written (like
|
|
2
|
+
// wordcanvas.d.ts) so the published surface stays self-contained and stable;
|
|
3
|
+
// mirrors shared/src/model — the editor, builder, and exporters all consume
|
|
4
|
+
// this same plain-data shape.
|
|
5
|
+
|
|
6
|
+
export interface CharStyle {
|
|
7
|
+
fontFamily: string;
|
|
8
|
+
fontSizePx: number;
|
|
9
|
+
bold: boolean;
|
|
10
|
+
italic: boolean;
|
|
11
|
+
underline: boolean;
|
|
12
|
+
strikethrough: boolean;
|
|
13
|
+
/** CSS color, e.g. "#202124". */
|
|
14
|
+
color: string;
|
|
15
|
+
/** Hidden text (OOXML w:vanish) — preserved but never laid out or painted. */
|
|
16
|
+
hidden?: boolean;
|
|
17
|
+
letterSpacingPx?: number;
|
|
18
|
+
/** Background highlight (Word's text highlight). */
|
|
19
|
+
highlightColor?: string | undefined;
|
|
20
|
+
/** Sub/superscript. */
|
|
21
|
+
verticalAlign?: "sub" | "super" | undefined;
|
|
22
|
+
/** Hyperlink target; linked runs paint blue+underlined. */
|
|
23
|
+
link?: string | undefined;
|
|
24
|
+
/** Footnote reference id — this run is the marker. */
|
|
25
|
+
footnoteRef?: string | undefined;
|
|
26
|
+
/** Content-control membership (properties live in Document.sdts). */
|
|
27
|
+
sdtId?: string | undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface TabStop {
|
|
31
|
+
/** Position from the left content edge, px. */
|
|
32
|
+
posPx: number;
|
|
33
|
+
align?: "left" | "center" | "right" | "decimal";
|
|
34
|
+
leader?: "none" | "dot" | "dash" | "underscore";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface ParaStyle {
|
|
38
|
+
align: "left" | "center" | "right" | "justify";
|
|
39
|
+
/** Line height multiplier. */
|
|
40
|
+
lineHeight: number;
|
|
41
|
+
spaceBeforePx: number;
|
|
42
|
+
spaceAfterPx: number;
|
|
43
|
+
indentFirstLinePx: number;
|
|
44
|
+
indentLeftPx: number;
|
|
45
|
+
indentRightPx?: number;
|
|
46
|
+
keepWithNext?: boolean;
|
|
47
|
+
keepLinesTogether?: boolean;
|
|
48
|
+
/** This paragraph starts a new page. */
|
|
49
|
+
pageBreakBefore?: boolean;
|
|
50
|
+
/** List membership: definition id + level 0..8. */
|
|
51
|
+
list?: { listId: string; level: number } | undefined;
|
|
52
|
+
/** Named style reference into Document.stylesheet (e.g. "Heading1"). */
|
|
53
|
+
namedStyle?: string;
|
|
54
|
+
columnBreakBefore?: boolean;
|
|
55
|
+
tabStops?: TabStop[];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Style-homogeneous span of text. */
|
|
59
|
+
export interface Run {
|
|
60
|
+
text: string;
|
|
61
|
+
style: CharStyle;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface Paragraph {
|
|
65
|
+
kind: "paragraph";
|
|
66
|
+
/** Stable unique id. */
|
|
67
|
+
id: string;
|
|
68
|
+
revision: number;
|
|
69
|
+
runs: Run[];
|
|
70
|
+
style: ParaStyle;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface ImageBlock {
|
|
74
|
+
kind: "image";
|
|
75
|
+
id: string;
|
|
76
|
+
revision: number;
|
|
77
|
+
/** Image URL — use data: URLs for portable documents. */
|
|
78
|
+
src: string;
|
|
79
|
+
/** Content address of the bytes (sha256 hex), when registered. */
|
|
80
|
+
mediaId?: string;
|
|
81
|
+
widthPx: number;
|
|
82
|
+
heightPx: number;
|
|
83
|
+
align: "left" | "center" | "right";
|
|
84
|
+
/** 'block' (default): own line. 'square': floats per align, text wraps. */
|
|
85
|
+
wrap?: "block" | "square";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface CellBorder {
|
|
89
|
+
color: string;
|
|
90
|
+
widthPx: number;
|
|
91
|
+
style?: "single" | "double" | "dashed" | "dotted";
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface CellBorders {
|
|
95
|
+
top?: CellBorder;
|
|
96
|
+
right?: CellBorder;
|
|
97
|
+
bottom?: CellBorder;
|
|
98
|
+
left?: CellBorder;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface CellMargin {
|
|
102
|
+
top: number;
|
|
103
|
+
right: number;
|
|
104
|
+
bottom: number;
|
|
105
|
+
left: number;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface TableCell {
|
|
109
|
+
id: string;
|
|
110
|
+
blocks: Block[];
|
|
111
|
+
colSpan?: number;
|
|
112
|
+
rowSpan?: number;
|
|
113
|
+
/** Background fill (CSS color). */
|
|
114
|
+
shading?: string;
|
|
115
|
+
borders?: CellBorders;
|
|
116
|
+
margin?: CellMargin;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface TableRow {
|
|
120
|
+
cells: TableCell[];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface TableBlock {
|
|
124
|
+
kind: "table";
|
|
125
|
+
id: string;
|
|
126
|
+
revision: number;
|
|
127
|
+
rows: TableRow[];
|
|
128
|
+
/** Column widths as fractions of content width (sum = 1). Absent = equal. */
|
|
129
|
+
colFractions?: number[];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export type Block = Paragraph | ImageBlock | TableBlock;
|
|
133
|
+
|
|
134
|
+
export type BandContainer = "header" | "footer" | "headerFirst" | "headerEven" | "footerFirst" | "footerEven";
|
|
135
|
+
|
|
136
|
+
export interface SectionProps {
|
|
137
|
+
pageWidthPx: number;
|
|
138
|
+
pageHeightPx: number;
|
|
139
|
+
marginPx: { top: number; right: number; bottom: number; left: number };
|
|
140
|
+
/** Newspaper columns. Absent = single column. */
|
|
141
|
+
columns?: { count: number; gapPx: number };
|
|
142
|
+
pageNumberStart?: number;
|
|
143
|
+
headerDistancePx?: number;
|
|
144
|
+
footerDistancePx?: number;
|
|
145
|
+
/** Header/footer block stories. {page}/{pages} tokens in run text are
|
|
146
|
+
* substituted per page at layout time. */
|
|
147
|
+
header?: Block[];
|
|
148
|
+
footer?: Block[];
|
|
149
|
+
headerFirst?: Block[];
|
|
150
|
+
headerEven?: Block[];
|
|
151
|
+
footerFirst?: Block[];
|
|
152
|
+
footerEven?: Block[];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export interface NamedStyle {
|
|
156
|
+
/** Shares the docx styleId space ("Normal", "Heading1", …). */
|
|
157
|
+
id: string;
|
|
158
|
+
/** Display name. */
|
|
159
|
+
name: string;
|
|
160
|
+
basedOn?: string;
|
|
161
|
+
char: Partial<CharStyle>;
|
|
162
|
+
para: Partial<ParaStyle>;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface Stylesheet {
|
|
166
|
+
styles: NamedStyle[];
|
|
167
|
+
defaultStyleId: string;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export type ListNumberFormat = "bullet" | "decimal" | "lowerLetter" | "upperLetter" | "lowerRoman" | "upperRoman";
|
|
171
|
+
|
|
172
|
+
export interface ListLevel {
|
|
173
|
+
format: ListNumberFormat;
|
|
174
|
+
/** Marker pattern; %N is level N-1's counter (e.g. "%1."). Ignored for bullets. */
|
|
175
|
+
text: string;
|
|
176
|
+
bulletChar?: string;
|
|
177
|
+
indentLeftPx: number;
|
|
178
|
+
hangingPx: number;
|
|
179
|
+
start: number;
|
|
180
|
+
markerStyle?: Partial<CharStyle>;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export interface ListDefinition {
|
|
184
|
+
id: string;
|
|
185
|
+
/** Up to 9 levels (0..8). */
|
|
186
|
+
levels: ListLevel[];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export interface DocPosition {
|
|
190
|
+
blockId: string;
|
|
191
|
+
offset: number;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export interface BookmarkRange {
|
|
195
|
+
start: DocPosition;
|
|
196
|
+
end: DocPosition;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export type SdtType = "richText" | "plainText" | "checkbox" | "dropDown" | "comboBox" | "date";
|
|
200
|
+
|
|
201
|
+
export interface SdtProps {
|
|
202
|
+
type: SdtType;
|
|
203
|
+
alias?: string;
|
|
204
|
+
tag?: string;
|
|
205
|
+
placeholder?: boolean;
|
|
206
|
+
listItems?: { display: string; value: string }[];
|
|
207
|
+
dateFormat?: string;
|
|
208
|
+
checked?: boolean;
|
|
209
|
+
lockContent?: boolean;
|
|
210
|
+
lockControl?: boolean;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface Document {
|
|
214
|
+
section: SectionProps;
|
|
215
|
+
blocks: Block[];
|
|
216
|
+
stylesheet?: Stylesheet;
|
|
217
|
+
/** List definitions keyed by id. */
|
|
218
|
+
lists?: Record<string, ListDefinition>;
|
|
219
|
+
/** Footnote bodies keyed by ref id. */
|
|
220
|
+
footnotes?: Record<string, Paragraph[]>;
|
|
221
|
+
/** Content-control properties keyed by sdtId. */
|
|
222
|
+
sdts?: Record<string, SdtProps>;
|
|
223
|
+
/** Bookmark name → character range. */
|
|
224
|
+
bookmarks?: Record<string, BookmarkRange>;
|
|
225
|
+
/** The document's `TOC` field instruction (e.g. ` TOC \o "1-3" \h `), captured
|
|
226
|
+
* on import. Absent when the document has no TOC field. */
|
|
227
|
+
tocInstruction?: string;
|
|
228
|
+
/** Block id of the paragraph holding the (empty/placeholder) `TOC` field, captured
|
|
229
|
+
* on import so a headless render can build the entries at the right spot. */
|
|
230
|
+
tocAnchorBlockId?: string;
|
|
231
|
+
}
|
package/types/recalc-docx.d.ts
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
// Public types for @forevka/wordcanvas/recalc-docx — patch a .docx's cached TOC /
|
|
2
|
-
// cross-reference page numbers IN PLACE (drift-free: the file is never re-exported,
|
|
3
|
-
// so every field and unmodeled byte survives). Hand-written + self-contained.
|
|
4
|
-
// Await installMeasureHost() (from "@forevka/wordcanvas/export/measure") first —
|
|
5
|
-
// the layout pass measures text.
|
|
6
|
-
|
|
7
|
-
import type { Document } from "./model";
|
|
8
|
-
|
|
9
|
-
export type { Document } from "./model";
|
|
10
|
-
|
|
11
|
-
export interface PatchResult {
|
|
12
|
-
bytes: Uint8Array;
|
|
13
|
-
/** PAGEREF cached numbers rewritten to a new value. */
|
|
14
|
-
changed: number;
|
|
15
|
-
/** PAGEREF results left untouched because the cached value was non-arabic. */
|
|
16
|
-
skipped: number;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/** Rewrite cached PAGEREF page numbers from a bookmark → page-number map,
|
|
20
|
-
* preserving every field and other part. */
|
|
21
|
-
export declare function patchTocPageNumbers(
|
|
22
|
-
docxBytes: Uint8Array,
|
|
23
|
-
pages: Record<string, string>,
|
|
24
|
-
): PatchResult;
|
|
25
|
-
|
|
26
|
-
/** Lay `doc` out and patch the original `docxBytes` from the resulting page map. */
|
|
27
|
-
export declare function patchTocFromLayout(docxBytes: Uint8Array, doc: Document): PatchResult;
|
|
1
|
+
// Public types for @forevka/wordcanvas/recalc-docx — patch a .docx's cached TOC /
|
|
2
|
+
// cross-reference page numbers IN PLACE (drift-free: the file is never re-exported,
|
|
3
|
+
// so every field and unmodeled byte survives). Hand-written + self-contained.
|
|
4
|
+
// Await installMeasureHost() (from "@forevka/wordcanvas/export/measure") first —
|
|
5
|
+
// the layout pass measures text.
|
|
6
|
+
|
|
7
|
+
import type { Document } from "./model";
|
|
8
|
+
|
|
9
|
+
export type { Document } from "./model";
|
|
10
|
+
|
|
11
|
+
export interface PatchResult {
|
|
12
|
+
bytes: Uint8Array;
|
|
13
|
+
/** PAGEREF cached numbers rewritten to a new value. */
|
|
14
|
+
changed: number;
|
|
15
|
+
/** PAGEREF results left untouched because the cached value was non-arabic. */
|
|
16
|
+
skipped: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Rewrite cached PAGEREF page numbers from a bookmark → page-number map,
|
|
20
|
+
* preserving every field and other part. */
|
|
21
|
+
export declare function patchTocPageNumbers(
|
|
22
|
+
docxBytes: Uint8Array,
|
|
23
|
+
pages: Record<string, string>,
|
|
24
|
+
): PatchResult;
|
|
25
|
+
|
|
26
|
+
/** Lay `doc` out and patch the original `docxBytes` from the resulting page map. */
|
|
27
|
+
export declare function patchTocFromLayout(docxBytes: Uint8Array, doc: Document): PatchResult;
|