@portone/docx-editor 0.2.1 → 0.3.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 (225) hide show
  1. package/CHANGELOG.md +109 -0
  2. package/CONTRIBUTING.md +5 -1
  3. package/dist/DocxEditor.d.ts +6 -0
  4. package/dist/DocxEditor.js +12 -29
  5. package/dist/core.d.ts +23 -8
  6. package/dist/core.js +9 -4
  7. package/dist/docx/cloning.d.ts +38 -0
  8. package/dist/docx/cloning.js +74 -0
  9. package/dist/docx/commentOnlyChange.d.ts +12 -7
  10. package/dist/docx/commentOnlyChange.js +9 -156
  11. package/dist/docx/comments/constants.d.ts +0 -1
  12. package/dist/docx/comments/constants.js +0 -2
  13. package/dist/docx/comments/grammar.d.ts +10 -4
  14. package/dist/docx/comments/grammar.js +12 -2
  15. package/dist/docx/comments/{verifying.d.ts → parts.d.ts} +26 -18
  16. package/dist/docx/comments/parts.js +279 -0
  17. package/dist/docx/comments/people.d.ts +11 -2
  18. package/dist/docx/comments/people.js +16 -92
  19. package/dist/docx/comments/policy.d.ts +7 -0
  20. package/dist/docx/comments/policy.js +43 -0
  21. package/dist/docx/comments/reading.js +8 -10
  22. package/dist/docx/comments/writing.d.ts +19 -7
  23. package/dist/docx/comments/writing.js +52 -111
  24. package/dist/docx/documentSettings.d.ts +7 -0
  25. package/dist/docx/documentSettings.js +10 -2
  26. package/dist/docx/exportDocx.d.ts +40 -5
  27. package/dist/docx/exportDocx.js +69 -71
  28. package/dist/docx/exportRefs.d.ts +5 -2
  29. package/dist/docx/exportRefs.js +3 -1
  30. package/dist/docx/fidelity.d.ts +43 -0
  31. package/dist/docx/fidelity.js +64 -0
  32. package/dist/docx/formatting/attrs.d.ts +27 -0
  33. package/dist/docx/formatting/attrs.js +31 -0
  34. package/dist/docx/formatting/context.d.ts +31 -0
  35. package/dist/docx/formatting/context.js +42 -0
  36. package/dist/docx/formatting/direct.d.ts +6 -5
  37. package/dist/docx/formatting/direct.js +52 -78
  38. package/dist/docx/formatting/resolve.d.ts +45 -0
  39. package/dist/docx/formatting/resolve.js +140 -0
  40. package/dist/docx/formatting/runProperties.d.ts +93 -0
  41. package/dist/docx/formatting/runProperties.js +316 -0
  42. package/dist/docx/formatting/styles.js +3 -3
  43. package/dist/docx/formatting/tabStops.js +7 -22
  44. package/dist/docx/formatting.d.ts +4 -1
  45. package/dist/docx/formatting.js +4 -1
  46. package/dist/docx/headersFooters.js +6 -13
  47. package/dist/docx/identities.d.ts +67 -0
  48. package/dist/docx/identities.js +174 -0
  49. package/dist/docx/importDocx.d.ts +12 -1
  50. package/dist/docx/importDocx.js +72 -79
  51. package/dist/docx/importParagraph.d.ts +1 -1
  52. package/dist/docx/importParagraph.js +4 -3
  53. package/dist/docx/importTable.d.ts +1 -1
  54. package/dist/docx/importTable.js +17 -1
  55. package/dist/docx/invariants.d.ts +33 -0
  56. package/dist/docx/invariants.js +256 -0
  57. package/dist/docx/media.d.ts +6 -4
  58. package/dist/docx/media.js +6 -37
  59. package/dist/docx/newLists.d.ts +20 -0
  60. package/dist/docx/newLists.js +36 -0
  61. package/dist/docx/notes.js +3 -7
  62. package/dist/docx/numberingPlanner.d.ts +8 -0
  63. package/dist/docx/numberingPlanner.js +19 -0
  64. package/dist/docx/packageParts.d.ts +42 -0
  65. package/dist/docx/packageParts.js +135 -0
  66. package/dist/docx/pageGeometry.d.ts +2 -0
  67. package/dist/docx/pageGeometry.js +18 -9
  68. package/dist/docx/paraProps.d.ts +10 -22
  69. package/dist/docx/paraProps.js +47 -76
  70. package/dist/docx/partPlan.d.ts +36 -0
  71. package/dist/docx/partPlan.js +59 -0
  72. package/dist/docx/protectionPolicy.d.ts +127 -0
  73. package/dist/docx/protectionPolicy.js +169 -0
  74. package/dist/docx/relationships.d.ts +1 -1
  75. package/dist/docx/relationships.js +8 -13
  76. package/dist/docx/runProps.d.ts +9 -22
  77. package/dist/docx/runProps.js +15 -168
  78. package/dist/docx/scan.js +20 -52
  79. package/dist/docx/sdt.js +9 -34
  80. package/dist/docx/sdtProps.d.ts +8 -1
  81. package/dist/docx/sdtProps.js +10 -0
  82. package/dist/docx/serializeBlock.d.ts +2 -0
  83. package/dist/docx/serializeBlock.js +8 -5
  84. package/dist/docx/serializeTable.js +32 -15
  85. package/dist/docx/session.d.ts +42 -14
  86. package/dist/docx/session.js +43 -17
  87. package/dist/docx/tableFormatting/editing.js +108 -139
  88. package/dist/docx/tableFormatting/reading.d.ts +16 -6
  89. package/dist/docx/tableFormatting/reading.js +40 -20
  90. package/dist/docx/tableTemplate.js +18 -7
  91. package/dist/download.d.ts +8 -5
  92. package/dist/download.js +2 -0
  93. package/dist/editor/clipboard/inlineFormatting.js +19 -30
  94. package/dist/editor/commands/comments/editing.d.ts +6 -2
  95. package/dist/editor/commands/comments/editing.js +19 -31
  96. package/dist/editor/commands/exportQueries.d.ts +15 -0
  97. package/dist/editor/commands/exportQueries.js +14 -0
  98. package/dist/editor/commands/fidelityQueries.d.ts +12 -0
  99. package/dist/editor/commands/fidelityQueries.js +8 -0
  100. package/dist/editor/commands/formatting/editing.d.ts +2 -2
  101. package/dist/editor/commands/formatting/editing.js +26 -108
  102. package/dist/editor/commands/formatting/propertyCommands.d.ts +21 -0
  103. package/dist/editor/commands/formatting/propertyCommands.js +103 -0
  104. package/dist/editor/commands/formatting/shared.d.ts +3 -3
  105. package/dist/editor/commands/formatting/shared.js +5 -2
  106. package/dist/editor/commands/indentCommands.js +5 -4
  107. package/dist/editor/commands/index.d.ts +11 -0
  108. package/dist/editor/commands/index.js +5 -0
  109. package/dist/editor/commands/linkCommands.js +5 -6
  110. package/dist/editor/commands/listCommands.js +8 -10
  111. package/dist/editor/commands/lockCommands.d.ts +7 -1
  112. package/dist/editor/commands/lockCommands.js +35 -46
  113. package/dist/editor/commands/paragraphCommands.js +28 -31
  114. package/dist/editor/commands/spacingCommands.js +1 -1
  115. package/dist/editor/createEditor.d.ts +17 -29
  116. package/dist/editor/createEditor.js +58 -58
  117. package/dist/editor/documentStyles.d.ts +11 -35
  118. package/dist/editor/documentStyles.js +9 -52
  119. package/dist/editor/editorDocument.d.ts +56 -0
  120. package/dist/editor/editorDocument.js +74 -0
  121. package/dist/editor/externalClipboard.js +16 -45
  122. package/dist/editor/insertTable.js +4 -3
  123. package/dist/editor/paragraphEdits.d.ts +11 -18
  124. package/dist/editor/paragraphEdits.js +7 -16
  125. package/dist/editor/plugins/displayDerivation.d.ts +47 -0
  126. package/dist/editor/plugins/displayDerivation.js +78 -0
  127. package/dist/editor/plugins/imagePaste.js +4 -3
  128. package/dist/editor/plugins/keymap.js +18 -3
  129. package/dist/editor/plugins/numberingDecorations.d.ts +5 -11
  130. package/dist/editor/plugins/numberingDecorations.js +7 -17
  131. package/dist/editor/plugins/paragraphDisplay.d.ts +7 -0
  132. package/dist/editor/plugins/paragraphDisplay.js +51 -0
  133. package/dist/editor/plugins/tabLayout.js +1 -1
  134. package/dist/editor/plugins/tableDisplay.d.ts +6 -0
  135. package/dist/editor/plugins/tableDisplay.js +16 -0
  136. package/dist/index.d.ts +2 -0
  137. package/dist/model/format.d.ts +30 -8
  138. package/dist/model/format.js +35 -22
  139. package/dist/model/tabStops.d.ts +9 -0
  140. package/dist/model/tabStops.js +18 -0
  141. package/dist/numbering/listTemplate.js +24 -7
  142. package/dist/numbering/parseNumbering.d.ts +14 -1
  143. package/dist/numbering/parseNumbering.js +35 -22
  144. package/dist/numbering/writeNumbering.d.ts +3 -4
  145. package/dist/numbering/writeNumbering.js +14 -25
  146. package/dist/ooxml/childOrder.d.ts +34 -0
  147. package/dist/ooxml/childOrder.js +496 -0
  148. package/dist/ooxml/element.d.ts +24 -11
  149. package/dist/ooxml/element.js +31 -12
  150. package/dist/ooxml/errors.d.ts +3 -2
  151. package/dist/ooxml/image.d.ts +4 -0
  152. package/dist/ooxml/image.js +2 -5
  153. package/dist/ooxml/partSplice.d.ts +67 -0
  154. package/dist/ooxml/partSplice.js +169 -0
  155. package/dist/ooxml/props.d.ts +112 -0
  156. package/dist/{docx/propsXml.js → ooxml/props.js} +72 -200
  157. package/dist/ooxml/simpleTypes.d.ts +103 -0
  158. package/dist/ooxml/simpleTypes.js +182 -0
  159. package/dist/ooxml/tabStops.js +8 -27
  160. package/dist/ooxml/tagScan.d.ts +34 -0
  161. package/dist/ooxml/tagScan.js +108 -0
  162. package/dist/ooxml/units.d.ts +25 -13
  163. package/dist/ooxml/units.js +65 -31
  164. package/dist/ooxml/xml.d.ts +27 -6
  165. package/dist/ooxml/xml.js +37 -5
  166. package/dist/page/blockKinds.d.ts +61 -0
  167. package/dist/page/blockKinds.js +11 -0
  168. package/dist/page/kinds/index.d.ts +6 -0
  169. package/dist/page/kinds/index.js +10 -0
  170. package/dist/page/kinds/paragraphKind.d.ts +10 -0
  171. package/dist/page/kinds/paragraphKind.js +71 -0
  172. package/dist/page/kinds/tableKind.d.ts +10 -0
  173. package/dist/page/kinds/tableKind.js +178 -0
  174. package/dist/page/measureBlocks.d.ts +3 -14
  175. package/dist/page/measureBlocks.js +24 -45
  176. package/dist/page/pageDecorations.d.ts +27 -44
  177. package/dist/page/pageDecorations.js +70 -152
  178. package/dist/page/pageLayout.d.ts +2 -19
  179. package/dist/page/pageLayout.js +36 -6
  180. package/dist/page/usePageLayout.d.ts +2 -17
  181. package/dist/page/usePageLayout.js +3 -39
  182. package/dist/schema/attrRoles.d.ts +25 -18
  183. package/dist/schema/attrRoles.js +102 -67
  184. package/dist/schema/displayDerivation.d.ts +82 -0
  185. package/dist/schema/displayDerivation.js +130 -0
  186. package/dist/schema/docxSchema.d.ts +3 -0
  187. package/dist/schema/docxSchema.js +26 -14
  188. package/dist/schema/editGuard.d.ts +1 -1
  189. package/dist/schema/guards.d.ts +37 -14
  190. package/dist/schema/guards.js +29 -3
  191. package/dist/schema/index.d.ts +2 -0
  192. package/dist/schema/index.js +2 -0
  193. package/dist/schema/locks.d.ts +11 -44
  194. package/dist/schema/locks.js +0 -9
  195. package/dist/schema/preservedGuards.d.ts +26 -6
  196. package/dist/schema/preservedGuards.js +31 -1
  197. package/dist/schema/protection.d.ts +7 -1
  198. package/dist/schema/protection.js +2 -1
  199. package/dist/schema/sourceEquality.d.ts +1 -9
  200. package/dist/schema/sourceEquality.js +1 -27
  201. package/dist/styles/inlineStyle.js +15 -6
  202. package/dist/table/cellFormatting.d.ts +8 -1
  203. package/dist/table/cellFormatting.js +10 -18
  204. package/dist/table/commands.js +20 -18
  205. package/dist/table/format.d.ts +3 -0
  206. package/dist/table/format.js +3 -9
  207. package/dist/table/gridBorders.d.ts +14 -16
  208. package/dist/table/gridBorders.js +3 -41
  209. package/dist/table/merge.d.ts +2 -6
  210. package/dist/table/merge.js +5 -5
  211. package/package.json +7 -3
  212. package/dist/docx/comments/contentTypes.d.ts +0 -7
  213. package/dist/docx/comments/contentTypes.js +0 -38
  214. package/dist/docx/comments/verifying.js +0 -206
  215. package/dist/docx/formatting/effectiveParagraph.d.ts +0 -15
  216. package/dist/docx/formatting/effectiveParagraph.js +0 -81
  217. package/dist/docx/propsXml.d.ts +0 -67
  218. package/dist/docx/uniqueControls.d.ts +0 -14
  219. package/dist/docx/uniqueControls.js +0 -62
  220. package/dist/editor/plugins/commentReservations.d.ts +0 -5
  221. package/dist/editor/plugins/commentReservations.js +0 -26
  222. package/dist/editor/plugins/styledParagraphs.d.ts +0 -15
  223. package/dist/editor/plugins/styledParagraphs.js +0 -65
  224. package/dist/page/tableMeasurements.d.ts +0 -18
  225. package/dist/page/tableMeasurements.js +0 -119
@@ -1,185 +1,10 @@
1
- // src/docx/propsXml.ts
2
- import {
3
- elementChildren,
4
- localPart,
5
- namespaceDecls,
6
- parseXml
7
- } from "../ooxml/xml.js";
8
- var RUN_PR_ORDER = [
9
- "rStyle",
10
- "rFonts",
11
- "b",
12
- "bCs",
13
- "i",
14
- "iCs",
15
- "caps",
16
- "smallCaps",
17
- "strike",
18
- "dstrike",
19
- "outline",
20
- "shadow",
21
- "emboss",
22
- "imprint",
23
- "noProof",
24
- "snapToGrid",
25
- "vanish",
26
- "webHidden",
27
- "color",
28
- "spacing",
29
- "w",
30
- "kern",
31
- "position",
32
- "sz",
33
- "szCs",
34
- "highlight",
35
- "u",
36
- "effect",
37
- "bdr",
38
- "shd",
39
- "fitText",
40
- "vertAlign",
41
- "rtl",
42
- "cs",
43
- "em",
44
- "lang",
45
- "eastAsianLayout",
46
- "specVanish",
47
- "oMath",
48
- "rPrChange"
49
- ];
50
- var P_PR_ORDER = [
51
- "pStyle",
52
- "keepNext",
53
- "keepLines",
54
- "pageBreakBefore",
55
- "framePr",
56
- "widowControl",
57
- "numPr",
58
- "suppressLineNumbers",
59
- "pBdr",
60
- "shd",
61
- "tabs",
62
- "suppressAutoHyphens",
63
- "kinsoku",
64
- "wordWrap",
65
- "overflowPunct",
66
- "topLinePunct",
67
- "autoSpaceDE",
68
- "autoSpaceDN",
69
- "bidi",
70
- "adjustRightInd",
71
- "snapToGrid",
72
- "spacing",
73
- "ind",
74
- "contextualSpacing",
75
- "mirrorIndents",
76
- "suppressOverlap",
77
- "jc",
78
- "textDirection",
79
- "textAlignment",
80
- "textboxTightWrap",
81
- "outlineLvl",
82
- "divId",
83
- "cnfStyle",
84
- "rPr",
85
- "sectPr",
86
- "pPrChange"
87
- ];
88
- var TC_PR_ORDER = [
89
- "cnfStyle",
90
- "tcW",
91
- "gridSpan",
92
- "hMerge",
93
- "vMerge",
94
- "tcBorders",
95
- "shd",
96
- "noWrap",
97
- "tcMar",
98
- "textDirection",
99
- "tcFitText",
100
- "vAlign",
101
- "hideMark",
102
- "headers",
103
- "cellIns",
104
- "cellDel",
105
- "cellMerge",
106
- "tcPrChange"
107
- ];
108
- var TR_PR_ORDER = [
109
- "cnfStyle",
110
- "divId",
111
- "gridBefore",
112
- "gridAfter",
113
- "wBefore",
114
- "wAfter",
115
- "cantSplit",
116
- "trHeight",
117
- "tblHeader",
118
- "tblCellSpacing",
119
- "jc",
120
- "hidden",
121
- "ins",
122
- "del",
123
- "trPrChange"
124
- ];
125
- var TBL_PR_ORDER = [
126
- "tblStyle",
127
- "tblpPr",
128
- "tblOverlap",
129
- "bidiVisual",
130
- "tblStyleRowBandSize",
131
- "tblStyleColBandSize",
132
- "tblW",
133
- "jc",
134
- "tblCellSpacing",
135
- "tblInd",
136
- "tblBorders",
137
- "shd",
138
- "tblLayout",
139
- "tblCellMar",
140
- "tblLook",
141
- "tblCaption",
142
- "tblDescription",
143
- "tblPrChange"
144
- ];
145
- function skipPast(source, from, marker) {
146
- const at = source.indexOf(marker, from);
147
- return at === -1 ? -1 : at + marker.length;
148
- }
149
- function otherTag(end) {
150
- return end === -1 ? null : { kind: "other", name: "", nameEnd: end, end };
151
- }
152
- function readTag(source, lt) {
153
- if (source.startsWith("<?", lt)) return otherTag(skipPast(source, lt, "?>"));
154
- if (source.startsWith("<!--", lt))
155
- return otherTag(skipPast(source, lt, "-->"));
156
- if (source.startsWith("<![CDATA[", lt))
157
- return otherTag(skipPast(source, lt, "]]>"));
158
- if (source.startsWith("<!", lt)) return otherTag(skipPast(source, lt, ">"));
159
- const closing = source.startsWith("</", lt);
160
- let i = lt + (closing ? 2 : 1);
161
- const nameStart = i;
162
- while (i < source.length && !" \r\n/>".includes(source[i])) i += 1;
163
- const name = source.slice(nameStart, i);
164
- if (!name) return null;
165
- const nameEnd = i;
166
- let quote = null;
167
- while (i < source.length) {
168
- const ch = source[i];
169
- if (quote !== null) {
170
- if (ch === quote) quote = null;
171
- } else if (ch === '"' || ch === "'") {
172
- quote = ch;
173
- } else if (ch === ">") {
174
- const selfClosing = source[i - 1] === "/";
175
- const kind = closing ? "close" : selfClosing ? "empty" : "open";
176
- return { kind, name, nameEnd, end: i + 1 };
177
- }
178
- i += 1;
179
- }
180
- return null;
181
- }
182
- function attrsOf(source, tag) {
1
+ // src/ooxml/props.ts
2
+ import { childOrderOf } from "./childOrder.js";
3
+ import { attrsText, emptyTagXml } from "./element.js";
4
+ import { wName } from "./names.js";
5
+ import { parseAttrs, readTag } from "./tagScan.js";
6
+ import { elementChildren, localPart, namespaceDecls, parseXml } from "./xml.js";
7
+ function rawAttrs(source, tag) {
183
8
  const closeLength = tag.kind === "empty" ? 2 : 1;
184
9
  const attrs = source.slice(tag.nameEnd, tag.end - closeLength).trim();
185
10
  return attrs.length > 0 ? attrs : null;
@@ -193,7 +18,7 @@ function innerXml(xml) {
193
18
  function parseProps(xml) {
194
19
  const open = readTag(xml, 0);
195
20
  if (!open || xml[0] !== "<") return null;
196
- const attrs = attrsOf(xml, open);
21
+ const attrs = rawAttrs(xml, open);
197
22
  if (open.kind === "empty") {
198
23
  return open.end === xml.length ? { tag: open.name, attrs, children: [] } : null;
199
24
  }
@@ -259,17 +84,15 @@ function renderProps(props) {
259
84
  const inner = props.children.map((child) => (child.before ?? "") + child.xml).join("");
260
85
  return open + inner + tail + `</${props.tag}>`;
261
86
  }
262
- function insertIndex(children, name, order) {
87
+ function insertIndex(children, name, order, tag) {
263
88
  const target = order.indexOf(name);
264
- if (target === -1) return children.length;
265
- let previous = -1;
266
- for (const [index, child] of children.entries()) {
267
- const known = order.indexOf(child.name);
268
- const effective = known === -1 ? previous : known;
269
- if (effective > target) return index;
270
- previous = effective;
89
+ if (target === -1) {
90
+ throw new Error(
91
+ `${name} is not a child the order of ${tag} knows; add it to CHILD_ORDER`
92
+ );
271
93
  }
272
- return children.length;
94
+ const at = children.findIndex((child) => order.indexOf(child.name) > target);
95
+ return at === -1 ? children.length : at;
273
96
  }
274
97
  function dropChildren(children, name) {
275
98
  const kept = [];
@@ -291,7 +114,8 @@ function tailWith(props, carried) {
291
114
  const tail = carried + (props.tail ?? "");
292
115
  return tail === "" ? {} : { tail };
293
116
  }
294
- function setPropsChild(props, name, xml, order) {
117
+ function setChild(props, name, xml, parent) {
118
+ const order = childOrderOf(localPart(props.tag), parent);
295
119
  const at = props.children.findIndex((entry) => entry.name === name);
296
120
  if (at !== -1 && xml !== null) {
297
121
  const rest = dropChildren(props.children.slice(at + 1), name);
@@ -309,7 +133,7 @@ function setPropsChild(props, name, xml, order) {
309
133
  if (xml === null) {
310
134
  return { ...props, children: kept, ...tailWith(props, carried) };
311
135
  }
312
- const index = insertIndex(kept, name, order);
136
+ const index = insertIndex(kept, name, order, props.tag);
313
137
  return {
314
138
  ...props,
315
139
  children: [...kept.slice(0, index), { name, xml }, ...kept.slice(index)],
@@ -319,6 +143,53 @@ function setPropsChild(props, name, xml, order) {
319
143
  function propsChild(children, name) {
320
144
  return children.find((child) => child.name === name);
321
145
  }
146
+ function attrsOf(props) {
147
+ return props.attrs === null ? [] : parseAttrs(props.attrs);
148
+ }
149
+ function withAttrs(props, attrs) {
150
+ return { ...props, attrs: attrs.length === 0 ? null : attrsText(attrs) };
151
+ }
152
+ function childElement(props, name) {
153
+ const child = propsChild(props.children, name);
154
+ if (child === void 0) return { tag: null, attrs: [] };
155
+ const parsed = parseProps(child.xml);
156
+ const attrs = parsed === null ? null : attrsOf(parsed);
157
+ return parsed === null || attrs === null ? null : { tag: parsed.tag, attrs };
158
+ }
159
+ function renderElement(props) {
160
+ return renderProps(props) || emptyTagXml(props.tag, props.attrs);
161
+ }
162
+ function orderedElement(tag, attrs, children) {
163
+ const empty = withAttrs({ tag, attrs: null, children: [] }, attrs);
164
+ return renderElement(
165
+ children.reduce(
166
+ (props, child) => setChild(props, child.name, child.xml),
167
+ empty
168
+ )
169
+ );
170
+ }
171
+ function editPath(props, path, edit, parent) {
172
+ const [name, ...rest] = path;
173
+ const current = propsChild(props.children, name);
174
+ const parsed = current === void 0 ? null : parseProps(current.xml);
175
+ if (current !== void 0 && parsed === null) return null;
176
+ if (rest.length === 0) {
177
+ const next = edit(parsed);
178
+ return setChild(props, name, next && renderElement(next), parent);
179
+ }
180
+ const nested = editPath(
181
+ parsed ?? { tag: wName(name), attrs: null, children: [] },
182
+ rest,
183
+ edit,
184
+ localPart(props.tag)
185
+ );
186
+ if (nested === null) return null;
187
+ const rendered = renderProps(nested);
188
+ return setChild(props, name, rendered === "" ? null : rendered, parent);
189
+ }
190
+ function editChild(props, path, edit) {
191
+ return editPath(props, path, edit, void 0);
192
+ }
322
193
  function parsePropsXml(xml) {
323
194
  try {
324
195
  const wrapped = `<props ${namespaceDecls(xml)}>${xml}</props>`;
@@ -328,15 +199,16 @@ function parsePropsXml(xml) {
328
199
  }
329
200
  }
330
201
  export {
331
- P_PR_ORDER,
332
- RUN_PR_ORDER,
333
- TBL_PR_ORDER,
334
- TC_PR_ORDER,
335
- TR_PR_ORDER,
202
+ attrsOf,
203
+ childElement,
204
+ editChild,
336
205
  innerXml,
206
+ orderedElement,
337
207
  parseProps,
338
208
  parsePropsXml,
339
209
  propsChild,
210
+ renderElement,
340
211
  renderProps,
341
- setPropsChild
212
+ setChild,
213
+ withAttrs
342
214
  };
@@ -0,0 +1,103 @@
1
+ /**
2
+ * The simple types the schema names, one `{parse, format}` pair each.
3
+ *
4
+ * A measurement in OOXML is a union rather than a count. `w:pgSz w:w` is either a number of twips
5
+ * or a universal measure such as `8.5in` (§22.9.2.14, §22.9.2.15), and reading only the leading
6
+ * digits turns Letter paper into a page 8.5 twips wide. A boolean is any of `1`, `0`, `true`,
7
+ * `false`, `on` and `off` (§17.17.4). Deciding either at the call site is how a document comes to
8
+ * be read one way in one reader and another way in the next, so both are decided here, and the
9
+ * writer that puts a value back reaches for the same pair.
10
+ *
11
+ * Readers accept the decimal counts some producers write in integer slots. `format` answers null
12
+ * for a value it cannot record; a caller that intends to round must do so before formatting.
13
+ */
14
+ import { type TabAlignment, type TabLeader } from "../model/tabStops";
15
+ export interface SimpleType<T> {
16
+ /** null for an absent or unreadable value; see the type's producer compatibility rules */
17
+ parse(value: string | null): T | null;
18
+ /** null for a value the type cannot record */
19
+ format(value: T): string | null;
20
+ }
21
+ /** A twip is a twentieth of a point */
22
+ export declare const TWIPS_PER_PT = 20;
23
+ export declare const TWIPS_PER_INCH = 1440;
24
+ /** `w:sz` counts a font size in half-points, so 24 is 12pt */
25
+ export declare const HALF_POINTS_PER_PT = 2;
26
+ /** `w:sz` on a border counts its thickness in eighths of a point */
27
+ export declare const EIGHTHS_PER_PT = 8;
28
+ /**
29
+ * The largest font size a writer here records.
30
+ *
31
+ * The schema puts no ceiling on `w:sz`, but Word's own limit is 819pt, and a size beyond it is
32
+ * one no word processor will show back.
33
+ */
34
+ export declare const MAX_FONT_SIZE_PT = 819;
35
+ /** `8.5in` -> 12240. null for anything ST_UniversalMeasure does not admit (§22.9.2.15) */
36
+ export declare function universalMeasureToTwips(value: string): number | null;
37
+ /** Twips, unsigned (§22.9.2.14): `w:pgSz`, `w:trHeight`, `w:spacing/@before`, `w:tcMar` */
38
+ export declare const ST_TwipsMeasure: SimpleType<number>;
39
+ /** Twips, signed (§17.18.81): `w:ind`, `w:tab/@pos`, `w:spacing/@line` */
40
+ export declare const ST_SignedTwipsMeasure: SimpleType<number>;
41
+ /**
42
+ * Half-points (§17.18.42): `w:sz` and `w:szCs`.
43
+ *
44
+ * `format` refuses a size no writer here records: one off the half-point step the unit counts in,
45
+ * one of nothing at all, and one past `MAX_FONT_SIZE_PT`.
46
+ */
47
+ export declare const ST_HpsMeasure: SimpleType<number>;
48
+ /** Half-points, signed (§17.18.80): `w:position` */
49
+ export declare const ST_SignedHpsMeasure: SimpleType<number>;
50
+ /**
51
+ * Eighths of a point (§17.18.23): the thickness of a border side.
52
+ *
53
+ * Alone among the measurements this restricts `ST_UnsignedDecimalNumber` rather than uniting with a
54
+ * universal measure, so a thickness is a count and a unit written beside it is not one.
55
+ */
56
+ export declare const ST_EighthPointMeasure: SimpleType<number>;
57
+ /** A whole number, signed (§17.18.10): `w:numId`, `w:ilvl`, `w:start` */
58
+ export declare const ST_DecimalNumber: SimpleType<number>;
59
+ /** A whole number, unsigned (§22.9.2.16): `w:id` on a comment or a note */
60
+ export declare const ST_UnsignedDecimalNumber: SimpleType<number>;
61
+ /**
62
+ * A boolean (§17.17.4).
63
+ *
64
+ * The schema unites `xsd:boolean` with the pair `on` and `off`, so all six spellings say the same
65
+ * thing and nothing else says either. An element that carries no `w:val` at all is on, which is a
66
+ * rule about the element rather than about this value, so it is the caller that applies it.
67
+ */
68
+ export declare const ST_OnOff: SimpleType<boolean>;
69
+ /** A color, which is either six hex digits or the word `auto` (§17.18.38) */
70
+ export type HexColor = {
71
+ kind: "auto";
72
+ } | {
73
+ kind: "rgb";
74
+ hex: string;
75
+ };
76
+ /**
77
+ * `ST_HexColor` keeps the digits exactly as the document spelled them, so a color read and written
78
+ * back leaves the file as it was. A caller comparing two colors gathers them first.
79
+ */
80
+ export declare const ST_HexColor: SimpleType<HexColor>;
81
+ /**
82
+ * The width of a table or a cell (§17.18.107), which `w:type` beside it says how to read.
83
+ *
84
+ * `number` is the bare count, meaning twips under `dxa` and fiftieths of a percent under `pct`.
85
+ * `percent` carried its own `%`, and `twips` was written as a universal measure, which says an
86
+ * absolute width whatever `w:type` claims.
87
+ */
88
+ export type MeasurementOrPercent = {
89
+ kind: "number";
90
+ value: number;
91
+ } | {
92
+ kind: "percent";
93
+ value: number;
94
+ } | {
95
+ kind: "twips";
96
+ value: number;
97
+ };
98
+ export declare const ST_MeasurementOrPercent: SimpleType<MeasurementOrPercent>;
99
+ /** The kinds of custom tab stop, with the two Transitional spellings folded in */
100
+ export type TabJc = TabAlignment | "bar" | "clear";
101
+ export declare const ST_TabJc: SimpleType<TabJc>;
102
+ /** The character a tab stop draws the space it covers with (§17.18.85) */
103
+ export declare const ST_TabTlc: SimpleType<TabLeader>;
@@ -0,0 +1,182 @@
1
+ // src/ooxml/simpleTypes.ts
2
+ import {
3
+ TAB_LEADERS,
4
+ TAB_STOP_ALIGNMENTS
5
+ } from "../model/tabStops.js";
6
+ var TWIPS_PER_PT = 20;
7
+ var TWIPS_PER_INCH = 1440;
8
+ var HALF_POINTS_PER_PT = 2;
9
+ var EIGHTHS_PER_PT = 8;
10
+ var MAX_FONT_SIZE_PT = 819;
11
+ var TWIPS_PER_UNIT = {
12
+ mm: TWIPS_PER_INCH / 25.4,
13
+ cm: TWIPS_PER_INCH / 2.54,
14
+ in: TWIPS_PER_INCH,
15
+ pt: TWIPS_PER_PT,
16
+ pc: TWIPS_PER_PT * 12,
17
+ pi: TWIPS_PER_PT * 12
18
+ };
19
+ var UNIVERSAL_MEASURE = /^(-?[0-9]+(?:\.[0-9]+)?)(mm|cm|in|pt|pc|pi)$/;
20
+ function universalMeasureToTwips(value) {
21
+ const matched = UNIVERSAL_MEASURE.exec(value.trim());
22
+ if (!matched) return null;
23
+ const amount = Number(matched[1]);
24
+ const twips = amount * TWIPS_PER_UNIT[matched[2]];
25
+ return Number.isFinite(twips) ? twips : null;
26
+ }
27
+ var DECIMAL_NUMBER = /^[+-]?[0-9]+(?:\.[0-9]+)?$/;
28
+ function decimalNumber(value) {
29
+ const text = value.trim();
30
+ if (!DECIMAL_NUMBER.test(text)) return null;
31
+ const parsed = Number(text);
32
+ return Number.isFinite(parsed) ? parsed : null;
33
+ }
34
+ function measure({ twipsPerUnit, signed }) {
35
+ const admits = (value) => signed || value >= 0;
36
+ return {
37
+ parse(value) {
38
+ if (value === null) return null;
39
+ const counted = decimalNumber(value);
40
+ if (counted !== null) return admits(counted) ? counted : null;
41
+ const twips = universalMeasureToTwips(value);
42
+ if (twips === null) return null;
43
+ const converted = twips / twipsPerUnit;
44
+ return admits(converted) ? converted : null;
45
+ },
46
+ format(value) {
47
+ if (!Number.isSafeInteger(value) || !admits(value)) return null;
48
+ return `${value}`;
49
+ }
50
+ };
51
+ }
52
+ var ST_TwipsMeasure = measure({
53
+ twipsPerUnit: 1,
54
+ signed: false
55
+ });
56
+ var ST_SignedTwipsMeasure = measure({
57
+ twipsPerUnit: 1,
58
+ signed: true
59
+ });
60
+ var HPS_MEASURE = measure({
61
+ twipsPerUnit: TWIPS_PER_PT / HALF_POINTS_PER_PT,
62
+ signed: false
63
+ });
64
+ var ST_HpsMeasure = {
65
+ parse: HPS_MEASURE.parse,
66
+ format(value) {
67
+ if (value <= 0 || value > MAX_FONT_SIZE_PT * HALF_POINTS_PER_PT) {
68
+ return null;
69
+ }
70
+ return HPS_MEASURE.format(value);
71
+ }
72
+ };
73
+ var ST_SignedHpsMeasure = measure({
74
+ twipsPerUnit: TWIPS_PER_PT / HALF_POINTS_PER_PT,
75
+ signed: true
76
+ });
77
+ function wholeNumber(signed) {
78
+ const admits = (value) => signed || value >= 0;
79
+ return {
80
+ parse(value) {
81
+ if (value === null) return null;
82
+ const parsed = decimalNumber(value);
83
+ if (parsed === null) return null;
84
+ const whole = Math.trunc(parsed);
85
+ return Number.isSafeInteger(whole) && admits(whole) ? whole : null;
86
+ },
87
+ format(value) {
88
+ if (!Number.isSafeInteger(value) || !admits(value)) return null;
89
+ return `${value}`;
90
+ }
91
+ };
92
+ }
93
+ var ST_EighthPointMeasure = wholeNumber(false);
94
+ var ST_DecimalNumber = wholeNumber(true);
95
+ var ST_UnsignedDecimalNumber = wholeNumber(false);
96
+ var ST_OnOff = {
97
+ parse(value) {
98
+ if (value === null) return null;
99
+ const text = value.trim();
100
+ if (text === "1" || text === "true" || text === "on") return true;
101
+ if (text === "0" || text === "false" || text === "off") return false;
102
+ return null;
103
+ },
104
+ format(value) {
105
+ return value ? "1" : "0";
106
+ }
107
+ };
108
+ var HEX_RGB = /^[0-9a-fA-F]{6}$/;
109
+ var ST_HexColor = {
110
+ parse(value) {
111
+ if (value === null) return null;
112
+ if (value === "auto") return { kind: "auto" };
113
+ return HEX_RGB.test(value) ? { kind: "rgb", hex: value } : null;
114
+ },
115
+ format(value) {
116
+ return value.kind === "auto" ? "auto" : value.hex;
117
+ }
118
+ };
119
+ var PERCENT = /^(-?[0-9]+(?:\.[0-9]+)?)%$/;
120
+ var ST_MeasurementOrPercent = {
121
+ parse(value) {
122
+ if (value === null) return null;
123
+ const text = value.trim();
124
+ const percent = PERCENT.exec(text);
125
+ if (percent) {
126
+ const amount = decimalNumber(percent[1]);
127
+ return amount === null ? null : { kind: "percent", value: amount };
128
+ }
129
+ const counted = decimalNumber(text);
130
+ if (counted !== null) return { kind: "number", value: counted };
131
+ const twips = universalMeasureToTwips(text);
132
+ return twips === null ? null : { kind: "twips", value: twips };
133
+ },
134
+ format(value) {
135
+ if (!Number.isFinite(value.value)) return null;
136
+ if (value.kind === "percent") return `${value.value}%`;
137
+ if (value.kind === "twips") return `${value.value / TWIPS_PER_PT}pt`;
138
+ return ST_DecimalNumber.format(value.value);
139
+ }
140
+ };
141
+ var TAB_JC_BY_VALUE = {
142
+ ...Object.fromEntries(TAB_STOP_ALIGNMENTS.map((align) => [align, align])),
143
+ clear: "clear",
144
+ left: "start",
145
+ right: "end"
146
+ };
147
+ var ST_TabJc = {
148
+ parse(value) {
149
+ return value !== null && Object.hasOwn(TAB_JC_BY_VALUE, value) ? TAB_JC_BY_VALUE[value] : null;
150
+ },
151
+ format(value) {
152
+ return value;
153
+ }
154
+ };
155
+ var ST_TabTlc = {
156
+ parse(value) {
157
+ return TAB_LEADERS.find((leader) => leader === value) ?? null;
158
+ },
159
+ format(value) {
160
+ return value;
161
+ }
162
+ };
163
+ export {
164
+ EIGHTHS_PER_PT,
165
+ HALF_POINTS_PER_PT,
166
+ MAX_FONT_SIZE_PT,
167
+ ST_DecimalNumber,
168
+ ST_EighthPointMeasure,
169
+ ST_HexColor,
170
+ ST_HpsMeasure,
171
+ ST_MeasurementOrPercent,
172
+ ST_OnOff,
173
+ ST_SignedHpsMeasure,
174
+ ST_SignedTwipsMeasure,
175
+ ST_TabJc,
176
+ ST_TabTlc,
177
+ ST_TwipsMeasure,
178
+ ST_UnsignedDecimalNumber,
179
+ TWIPS_PER_INCH,
180
+ TWIPS_PER_PT,
181
+ universalMeasureToTwips
182
+ };
@@ -1,28 +1,7 @@
1
1
  // src/ooxml/tabStops.ts
2
+ import { ST_SignedTwipsMeasure, ST_TabJc, ST_TabTlc } from "./simpleTypes.js";
2
3
  import { twipsToPt, wAttr } from "./units.js";
3
4
  import { childByLocalName } from "./xml.js";
4
- var ALIGN_BY_VALUE = {
5
- left: "start",
6
- start: "start",
7
- center: "center",
8
- right: "end",
9
- end: "end",
10
- decimal: "decimal",
11
- num: "num",
12
- bar: "bar",
13
- clear: "clear"
14
- };
15
- var LEADERS = /* @__PURE__ */ new Set([
16
- "none",
17
- "dot",
18
- "hyphen",
19
- "underscore",
20
- "heavy",
21
- "middleDot"
22
- ]);
23
- function tabLeader(value) {
24
- return value !== null && LEADERS.has(value) ? value : void 0;
25
- }
26
5
  function readTabStopDirectives(pPr) {
27
6
  if (!pPr) return [];
28
7
  const tabs = childByLocalName(pPr, "tabs");
@@ -30,18 +9,20 @@ function readTabStopDirectives(pPr) {
30
9
  const stops = [];
31
10
  for (const tab of Array.from(tabs.children)) {
32
11
  if (tab.localName !== "tab") continue;
33
- const positionPt = twipsToPt(wAttr(tab, "pos"));
34
- const align = ALIGN_BY_VALUE[wAttr(tab, "val") ?? ""];
35
- if (positionPt === null || align === void 0) continue;
12
+ const positionPt = twipsToPt(
13
+ ST_SignedTwipsMeasure.parse(wAttr(tab, "pos"))
14
+ );
15
+ const align = ST_TabJc.parse(wAttr(tab, "val"));
16
+ if (positionPt === null || align === null) continue;
36
17
  if (align === "clear") {
37
18
  stops.push({ positionPt, align });
38
19
  continue;
39
20
  }
40
- const leader = tabLeader(wAttr(tab, "leader"));
21
+ const leader = ST_TabTlc.parse(wAttr(tab, "leader"));
41
22
  stops.push({
42
23
  positionPt,
43
24
  align,
44
- ...leader === void 0 ? {} : { leader }
25
+ ...leader === null ? {} : { leader }
45
26
  });
46
27
  }
47
28
  return stops;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Reading one tag out of a part or a fragment without parsing the whole of it.
3
+ *
4
+ * Everything the writers hold is text, and an edit slices one element or one attribute out of it,
5
+ * so the spots those slices run between have to be found in the text itself. A `>` may stand
6
+ * inside an attribute value and a `<` inside a comment, which is why a tag is read construct by
7
+ * construct rather than searched for.
8
+ */
9
+ import type { XmlAttr } from "./element";
10
+ export type TagKind = "open" | "close" | "empty" | "other";
11
+ export interface Tag {
12
+ kind: TagKind;
13
+ /** The name exactly as written, prefix included. Empty for a construct that has none */
14
+ name: string;
15
+ /** The spot where the tag name ends. This is the start of the attribute string */
16
+ nameEnd: number;
17
+ /** The spot right after the tag ends */
18
+ end: number;
19
+ }
20
+ /** Reads a single tag starting at a `<`. null if it cannot be made out */
21
+ export declare function readTag(source: string, lt: number): Tag | null;
22
+ /**
23
+ * Where the root element's opening tag starts, past the prolog.
24
+ *
25
+ * The prolog is walked construct by construct so that a `<` inside a comment or a processing
26
+ * instruction is not taken for the root. -1 when the source holds no element at all.
27
+ */
28
+ export declare function rootTagAt(xml: string): number;
29
+ /**
30
+ * The attribute text of an opening tag as pairs, references decoded, each name spelled as it was
31
+ * written. null for a shape a parser would refuse: an unquoted value, a missing name, one name
32
+ * given twice, or a reference nothing declares.
33
+ */
34
+ export declare function parseAttrs(raw: string): XmlAttr[] | null;