doc-codec 1.0.2 → 1.1.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.
Files changed (112) hide show
  1. package/README.md +192 -50
  2. package/dist/color.cjs +166 -0
  3. package/dist/color.d.cts +20 -0
  4. package/dist/color.d.ts +20 -0
  5. package/dist/color.js +160 -0
  6. package/dist/detect.cjs +3 -0
  7. package/dist/detect.d.cts +3 -1
  8. package/dist/detect.d.ts +3 -1
  9. package/dist/detect.js +3 -1
  10. package/dist/fib/fib.cjs +9 -1
  11. package/dist/fib/fib.d.cts +1 -28
  12. package/dist/fib/fib.d.ts +1 -28
  13. package/dist/fib/fib.js +9 -1
  14. package/dist/fib/offsets.cjs +9 -1
  15. package/dist/fib/offsets.d.cts +8 -0
  16. package/dist/fib/offsets.d.ts +8 -0
  17. package/dist/fib/offsets.js +9 -1
  18. package/dist/fib/write.cjs +43 -0
  19. package/dist/fib/write.d.cts +21 -0
  20. package/dist/fib/write.d.ts +21 -0
  21. package/dist/fib/write.js +42 -0
  22. package/dist/fib-CtsLtF96.d.cts +37 -0
  23. package/dist/fib-CtsLtF96.d.ts +37 -0
  24. package/dist/index.cjs +31 -0
  25. package/dist/index.d.cts +18 -7
  26. package/dist/index.d.ts +18 -7
  27. package/dist/index.js +14 -3
  28. package/dist/list/numbering.cjs +206 -0
  29. package/dist/list/numbering.d.cts +2 -0
  30. package/dist/list/numbering.d.ts +2 -0
  31. package/dist/list/numbering.js +205 -0
  32. package/dist/metadata.cjs +14 -0
  33. package/dist/metadata.d.cts +6 -0
  34. package/dist/metadata.d.ts +6 -0
  35. package/dist/metadata.js +13 -0
  36. package/dist/numbering-Cir-uGdc.d.cts +22 -0
  37. package/dist/numbering-DF1z1PyG.d.ts +22 -0
  38. package/dist/pap-BkFo8dZO.d.ts +29 -0
  39. package/dist/pap-BmelEYEP.d.cts +29 -0
  40. package/dist/prop/chp-write.cjs +47 -0
  41. package/dist/prop/chp-write.d.cts +5 -0
  42. package/dist/prop/chp-write.d.ts +5 -0
  43. package/dist/prop/chp-write.js +46 -0
  44. package/dist/prop/chp.cjs +15 -107
  45. package/dist/prop/chp.d.cts +3 -2
  46. package/dist/prop/chp.d.ts +3 -2
  47. package/dist/prop/chp.js +15 -107
  48. package/dist/prop/fkp-write.cjs +139 -0
  49. package/dist/prop/fkp-write.d.cts +21 -0
  50. package/dist/prop/fkp-write.d.ts +21 -0
  51. package/dist/prop/fkp-write.js +135 -0
  52. package/dist/prop/pap-write.cjs +67 -0
  53. package/dist/prop/pap-write.d.cts +5 -0
  54. package/dist/prop/pap-write.d.ts +5 -0
  55. package/dist/prop/pap-write.js +66 -0
  56. package/dist/prop/pap.cjs +10 -0
  57. package/dist/prop/pap.d.cts +1 -24
  58. package/dist/prop/pap.d.ts +1 -24
  59. package/dist/prop/pap.js +11 -1
  60. package/dist/prop/sep-write.cjs +63 -0
  61. package/dist/prop/sep-write.d.cts +9 -0
  62. package/dist/prop/sep-write.d.ts +9 -0
  63. package/dist/prop/sep-write.js +60 -0
  64. package/dist/prop/sep.cjs +63 -0
  65. package/dist/prop/sep.d.cts +16 -0
  66. package/dist/prop/sep.d.ts +16 -0
  67. package/dist/prop/sep.js +61 -0
  68. package/dist/prop/sprm.d.cts +1 -25
  69. package/dist/prop/sprm.d.ts +1 -25
  70. package/dist/read.cjs +44 -18
  71. package/dist/read.d.cts +21 -4
  72. package/dist/read.d.ts +21 -4
  73. package/dist/read.js +46 -20
  74. package/dist/sprm-Djg5RNiq.d.cts +26 -0
  75. package/dist/sprm-Djg5RNiq.d.ts +26 -0
  76. package/dist/style/fonts.cjs +68 -0
  77. package/dist/style/fonts.d.cts +5 -0
  78. package/dist/style/fonts.d.ts +5 -0
  79. package/dist/style/fonts.js +66 -0
  80. package/dist/style/stsh.cjs +23 -0
  81. package/dist/style/stsh.d.cts +2 -1
  82. package/dist/style/stsh.d.ts +2 -1
  83. package/dist/style/stsh.js +23 -1
  84. package/dist/table/decoration.cjs +220 -0
  85. package/dist/table/decoration.d.cts +41 -0
  86. package/dist/table/decoration.d.ts +41 -0
  87. package/dist/table/decoration.js +205 -0
  88. package/dist/table/read.cjs +192 -0
  89. package/dist/table/read.d.cts +6 -0
  90. package/dist/table/read.d.ts +6 -0
  91. package/dist/table/read.js +191 -0
  92. package/dist/table/tap-write.cjs +125 -0
  93. package/dist/table/tap-write.d.cts +13 -0
  94. package/dist/table/tap-write.d.ts +13 -0
  95. package/dist/table/tap-write.js +124 -0
  96. package/dist/table/tap.cjs +217 -0
  97. package/dist/table/tap.d.cts +29 -0
  98. package/dist/table/tap.d.ts +29 -0
  99. package/dist/table/tap.js +213 -0
  100. package/dist/table/write.cjs +136 -0
  101. package/dist/table/write.d.cts +13 -0
  102. package/dist/table/write.d.ts +13 -0
  103. package/dist/table/write.js +135 -0
  104. package/dist/text/piece-table-write.cjs +24 -0
  105. package/dist/text/piece-table-write.d.cts +4 -0
  106. package/dist/text/piece-table-write.d.ts +4 -0
  107. package/dist/text/piece-table-write.js +23 -0
  108. package/dist/write.cjs +175 -0
  109. package/dist/write.d.cts +5 -0
  110. package/dist/write.d.ts +5 -0
  111. package/dist/write.js +174 -0
  112. package/package.json +3 -3
@@ -1,25 +1,2 @@
1
- import { Prl } from "./sprm.cjs";
2
- import { Alignment } from "document-schema.js";
3
- //#region src/prop/pap.d.ts
4
- interface ParagraphProperties {
5
- istd?: number;
6
- alignment?: Alignment;
7
- indentLeftPt?: number;
8
- indentRightPt?: number;
9
- indentFirstLinePt?: number;
10
- spacingBeforePt?: number;
11
- spacingAfterPt?: number;
12
- lineSpacing?: number;
13
- pageBreakBefore?: boolean;
14
- /** sprmPOutLvl's zero-based level, present only when the paragraph is genuinely in an outline level rather than body text. */
15
- outlineLevel?: number;
16
- inTable?: boolean;
17
- /** True on the cell mark that terminates a table row. */
18
- tableRowEnd?: boolean;
19
- listLevel?: number;
20
- /** The list identifier (sprmPIlfo), present only when the paragraph is in a list at all. */
21
- listId?: number;
22
- }
23
- declare function applyParagraphSprms(prls: readonly Prl[], into: ParagraphProperties): ParagraphProperties;
24
- //#endregion
1
+ import { n as applyParagraphSprms, t as ParagraphProperties } from "../pap-BmelEYEP.cjs";
25
2
  export { ParagraphProperties, applyParagraphSprms };
@@ -1,25 +1,2 @@
1
- import { Prl } from "./sprm.js";
2
- import { Alignment } from "document-schema.js";
3
- //#region src/prop/pap.d.ts
4
- interface ParagraphProperties {
5
- istd?: number;
6
- alignment?: Alignment;
7
- indentLeftPt?: number;
8
- indentRightPt?: number;
9
- indentFirstLinePt?: number;
10
- spacingBeforePt?: number;
11
- spacingAfterPt?: number;
12
- lineSpacing?: number;
13
- pageBreakBefore?: boolean;
14
- /** sprmPOutLvl's zero-based level, present only when the paragraph is genuinely in an outline level rather than body text. */
15
- outlineLevel?: number;
16
- inTable?: boolean;
17
- /** True on the cell mark that terminates a table row. */
18
- tableRowEnd?: boolean;
19
- listLevel?: number;
20
- /** The list identifier (sprmPIlfo), present only when the paragraph is in a list at all. */
21
- listId?: number;
22
- }
23
- declare function applyParagraphSprms(prls: readonly Prl[], into: ParagraphProperties): ParagraphProperties;
24
- //#endregion
1
+ import { n as applyParagraphSprms, t as ParagraphProperties } from "../pap-BkFo8dZO.js";
25
2
  export { ParagraphProperties, applyParagraphSprms };
package/dist/prop/pap.js CHANGED
@@ -1,4 +1,4 @@
1
- import { readInt16LE, readUint16LE, readUint8 } from "../bytes.js";
1
+ import { readInt16LE, readUint16LE, readUint32LE, readUint8 } from "../bytes.js";
2
2
  import { SGC } from "./sprm.js";
3
3
  //#region src/prop/pap.ts
4
4
  /** sprmPIstd: the istd of the paragraph style. */
@@ -33,6 +33,11 @@ const SPRM_P_F_TTP = 9239;
33
33
  const SPRM_P_ILVL = 9738;
34
34
  /** sprmPIlfo: which list the paragraph is in, as an index into PlfLfo.rgLfo. */
35
35
  const SPRM_P_ILFO = 17931;
36
+ /** sprmPItap: the paragraph's own table depth -- read only far enough to detect a depth greater than 1 (a table nested inside a table cell), which this package refuses rather than mis-reads. */
37
+ const SPRM_P_ITAP = 26185;
38
+ /** sprmPFInnerTableCell / sprmPFInnerTtp: a nested table's own cell-ending or row-ending mark. Neither is acted on beyond refusing the nested table it signals. */
39
+ const SPRM_P_F_INNER_TABLE_CELL = 9291;
40
+ const SPRM_P_F_INNER_TTP = 9292;
36
41
  const TWIPS_PER_POINT = 20;
37
42
  /** LSPD: "The spacing multiplier is dyaLine/240." */
38
43
  const LSPD_MULTIPLE_DIVISOR = 240;
@@ -125,6 +130,11 @@ function applyParagraphSprms(prls, into) {
125
130
  into.listId = ilfo === ILFO_NOT_IN_LIST || ilfo === ILFO_NOT_IN_LIST_ALT ? void 0 : Math.abs(ilfo);
126
131
  break;
127
132
  }
133
+ case SPRM_P_ITAP:
134
+ into.tableDepth = readUint32LE(prl.operand, 0);
135
+ break;
136
+ case SPRM_P_F_INNER_TABLE_CELL:
137
+ case SPRM_P_F_INNER_TTP: if (readUint8(prl.operand, 0) !== 0) into.nestedTableMark = true;
128
138
  }
129
139
  }
130
140
  return into;
@@ -0,0 +1,63 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_errors = require("../errors.cjs");
3
+ //#region src/prop/sep-write.ts
4
+ /** sprmSXaPage / sprmSYaPage: unsigned 2-byte twips, each constrained to [MS-DOC]'s own [144, 31680] page-dimension range. */
5
+ const SPRM_S_XA_PAGE = 45087;
6
+ const SPRM_S_YA_PAGE = 45088;
7
+ /** sprmSDxaLeft / sprmSDxaRight: an unsigned 2-byte twips margin. */
8
+ const SPRM_S_DXA_LEFT = 45089;
9
+ const SPRM_S_DXA_RIGHT = 45090;
10
+ /** sprmSDyaTop / sprmSDyaBottom: a signed 2-byte twips margin, written positive (minimum-margin form). */
11
+ const SPRM_S_DYA_TOP = 36899;
12
+ const SPRM_S_DYA_BOTTOM = 36900;
13
+ const TWIPS_PER_POINT = 20;
14
+ /** sprmSXaPage/sprmSYaPage's own stated operand range, in twips. */
15
+ const MIN_PAGE_DIMENSION_TWIPS = 144;
16
+ const MAX_PAGE_DIMENSION_TWIPS = 31680;
17
+ /** sprmSDxaLeft/sprmSDxaRight's unsigned 2-byte operand range. */
18
+ const MAX_UINT16 = 65535;
19
+ /** sprmSDyaTop/sprmSDyaBottom's own stated magnitude range: "MUST be less than or equal to 31665 and greater than or equal to -31665." */
20
+ const MAX_MARGIN_TWIPS = 31665;
21
+ function pushSprm(bytes, opcode, operand) {
22
+ bytes.push(opcode & 255, opcode >> 8 & 255, ...operand);
23
+ }
24
+ function pointsToTwips(pt) {
25
+ return Math.round(pt * TWIPS_PER_POINT);
26
+ }
27
+ function uint16(value, min, max, what) {
28
+ if (value < min || value > max) throw new require_errors.DocFormatError(`${what} is ${value} twips, outside the ${min}..${max} range its sprm operand can hold`);
29
+ return [value & 255, value >> 8 & 255];
30
+ }
31
+ function encodeSectionGrpprl(section) {
32
+ const bytes = [];
33
+ pushSprm(bytes, SPRM_S_XA_PAGE, uint16(pointsToTwips(section.pageSize.widthPt), MIN_PAGE_DIMENSION_TWIPS, MAX_PAGE_DIMENSION_TWIPS, "section pageSize.widthPt"));
34
+ pushSprm(bytes, SPRM_S_YA_PAGE, uint16(pointsToTwips(section.pageSize.heightPt), MIN_PAGE_DIMENSION_TWIPS, MAX_PAGE_DIMENSION_TWIPS, "section pageSize.heightPt"));
35
+ pushSprm(bytes, SPRM_S_DXA_LEFT, uint16(pointsToTwips(section.margins.leftPt), 0, MAX_UINT16, "section margins.leftPt"));
36
+ pushSprm(bytes, SPRM_S_DXA_RIGHT, uint16(pointsToTwips(section.margins.rightPt), 0, MAX_UINT16, "section margins.rightPt"));
37
+ pushSprm(bytes, SPRM_S_DYA_TOP, uint16(pointsToTwips(section.margins.topPt), 0, MAX_MARGIN_TWIPS, "section margins.topPt"));
38
+ pushSprm(bytes, SPRM_S_DYA_BOTTOM, uint16(pointsToTwips(section.margins.bottomPt), 0, MAX_MARGIN_TWIPS, "section margins.bottomPt"));
39
+ return bytes;
40
+ }
41
+ /** Sepx, [MS-DOC] 2.9.279: a 2-byte cb (grpprl's own length) followed by the grpprl itself. */
42
+ function buildSepx(grpprl) {
43
+ const bytes = new Uint8Array(2 + grpprl.length);
44
+ new DataView(bytes.buffer).setUint16(0, grpprl.length, true);
45
+ bytes.set(grpprl, 2);
46
+ return bytes;
47
+ }
48
+ /** PlcfSed for exactly one section: two CPs (0 and ccpText) bracketing the single Sed ([MS-DOC] 2.9.269) this writer ever emits, whose fcSepx names where buildSepx's own bytes were placed in the WordDocument stream and whose fn/fnMpr/fcMpr fields carry the values [MS-DOC] states are ignored. */
49
+ function buildPlcfSed(ccpText, fcSepx) {
50
+ const bytes = /* @__PURE__ */ new Uint8Array(20);
51
+ const view = new DataView(bytes.buffer);
52
+ view.setUint32(0, 0, true);
53
+ view.setUint32(4, ccpText, true);
54
+ view.setUint16(8, 0, true);
55
+ view.setUint32(10, fcSepx, true);
56
+ view.setUint16(14, 0, true);
57
+ view.setUint32(16, 4294967295, true);
58
+ return bytes;
59
+ }
60
+ //#endregion
61
+ exports.buildPlcfSed = buildPlcfSed;
62
+ exports.buildSepx = buildSepx;
63
+ exports.encodeSectionGrpprl = encodeSectionGrpprl;
@@ -0,0 +1,9 @@
1
+ import { ContentSection } from "document-schema.js";
2
+ //#region src/prop/sep-write.d.ts
3
+ declare function encodeSectionGrpprl(section: Pick<ContentSection, "pageSize" | "margins">): number[];
4
+ /** Sepx, [MS-DOC] 2.9.279: a 2-byte cb (grpprl's own length) followed by the grpprl itself. */
5
+ declare function buildSepx(grpprl: readonly number[]): Uint8Array<ArrayBuffer>;
6
+ /** PlcfSed for exactly one section: two CPs (0 and ccpText) bracketing the single Sed ([MS-DOC] 2.9.269) this writer ever emits, whose fcSepx names where buildSepx's own bytes were placed in the WordDocument stream and whose fn/fnMpr/fcMpr fields carry the values [MS-DOC] states are ignored. */
7
+ declare function buildPlcfSed(ccpText: number, fcSepx: number): Uint8Array<ArrayBuffer>;
8
+ //#endregion
9
+ export { buildPlcfSed, buildSepx, encodeSectionGrpprl };
@@ -0,0 +1,9 @@
1
+ import { ContentSection } from "document-schema.js";
2
+ //#region src/prop/sep-write.d.ts
3
+ declare function encodeSectionGrpprl(section: Pick<ContentSection, "pageSize" | "margins">): number[];
4
+ /** Sepx, [MS-DOC] 2.9.279: a 2-byte cb (grpprl's own length) followed by the grpprl itself. */
5
+ declare function buildSepx(grpprl: readonly number[]): Uint8Array<ArrayBuffer>;
6
+ /** PlcfSed for exactly one section: two CPs (0 and ccpText) bracketing the single Sed ([MS-DOC] 2.9.269) this writer ever emits, whose fcSepx names where buildSepx's own bytes were placed in the WordDocument stream and whose fn/fnMpr/fcMpr fields carry the values [MS-DOC] states are ignored. */
7
+ declare function buildPlcfSed(ccpText: number, fcSepx: number): Uint8Array<ArrayBuffer>;
8
+ //#endregion
9
+ export { buildPlcfSed, buildSepx, encodeSectionGrpprl };
@@ -0,0 +1,60 @@
1
+ import { DocFormatError } from "../errors.js";
2
+ //#region src/prop/sep-write.ts
3
+ /** sprmSXaPage / sprmSYaPage: unsigned 2-byte twips, each constrained to [MS-DOC]'s own [144, 31680] page-dimension range. */
4
+ const SPRM_S_XA_PAGE = 45087;
5
+ const SPRM_S_YA_PAGE = 45088;
6
+ /** sprmSDxaLeft / sprmSDxaRight: an unsigned 2-byte twips margin. */
7
+ const SPRM_S_DXA_LEFT = 45089;
8
+ const SPRM_S_DXA_RIGHT = 45090;
9
+ /** sprmSDyaTop / sprmSDyaBottom: a signed 2-byte twips margin, written positive (minimum-margin form). */
10
+ const SPRM_S_DYA_TOP = 36899;
11
+ const SPRM_S_DYA_BOTTOM = 36900;
12
+ const TWIPS_PER_POINT = 20;
13
+ /** sprmSXaPage/sprmSYaPage's own stated operand range, in twips. */
14
+ const MIN_PAGE_DIMENSION_TWIPS = 144;
15
+ const MAX_PAGE_DIMENSION_TWIPS = 31680;
16
+ /** sprmSDxaLeft/sprmSDxaRight's unsigned 2-byte operand range. */
17
+ const MAX_UINT16 = 65535;
18
+ /** sprmSDyaTop/sprmSDyaBottom's own stated magnitude range: "MUST be less than or equal to 31665 and greater than or equal to -31665." */
19
+ const MAX_MARGIN_TWIPS = 31665;
20
+ function pushSprm(bytes, opcode, operand) {
21
+ bytes.push(opcode & 255, opcode >> 8 & 255, ...operand);
22
+ }
23
+ function pointsToTwips(pt) {
24
+ return Math.round(pt * TWIPS_PER_POINT);
25
+ }
26
+ function uint16(value, min, max, what) {
27
+ if (value < min || value > max) throw new DocFormatError(`${what} is ${value} twips, outside the ${min}..${max} range its sprm operand can hold`);
28
+ return [value & 255, value >> 8 & 255];
29
+ }
30
+ function encodeSectionGrpprl(section) {
31
+ const bytes = [];
32
+ pushSprm(bytes, SPRM_S_XA_PAGE, uint16(pointsToTwips(section.pageSize.widthPt), MIN_PAGE_DIMENSION_TWIPS, MAX_PAGE_DIMENSION_TWIPS, "section pageSize.widthPt"));
33
+ pushSprm(bytes, SPRM_S_YA_PAGE, uint16(pointsToTwips(section.pageSize.heightPt), MIN_PAGE_DIMENSION_TWIPS, MAX_PAGE_DIMENSION_TWIPS, "section pageSize.heightPt"));
34
+ pushSprm(bytes, SPRM_S_DXA_LEFT, uint16(pointsToTwips(section.margins.leftPt), 0, MAX_UINT16, "section margins.leftPt"));
35
+ pushSprm(bytes, SPRM_S_DXA_RIGHT, uint16(pointsToTwips(section.margins.rightPt), 0, MAX_UINT16, "section margins.rightPt"));
36
+ pushSprm(bytes, SPRM_S_DYA_TOP, uint16(pointsToTwips(section.margins.topPt), 0, MAX_MARGIN_TWIPS, "section margins.topPt"));
37
+ pushSprm(bytes, SPRM_S_DYA_BOTTOM, uint16(pointsToTwips(section.margins.bottomPt), 0, MAX_MARGIN_TWIPS, "section margins.bottomPt"));
38
+ return bytes;
39
+ }
40
+ /** Sepx, [MS-DOC] 2.9.279: a 2-byte cb (grpprl's own length) followed by the grpprl itself. */
41
+ function buildSepx(grpprl) {
42
+ const bytes = new Uint8Array(2 + grpprl.length);
43
+ new DataView(bytes.buffer).setUint16(0, grpprl.length, true);
44
+ bytes.set(grpprl, 2);
45
+ return bytes;
46
+ }
47
+ /** PlcfSed for exactly one section: two CPs (0 and ccpText) bracketing the single Sed ([MS-DOC] 2.9.269) this writer ever emits, whose fcSepx names where buildSepx's own bytes were placed in the WordDocument stream and whose fn/fnMpr/fcMpr fields carry the values [MS-DOC] states are ignored. */
48
+ function buildPlcfSed(ccpText, fcSepx) {
49
+ const bytes = /* @__PURE__ */ new Uint8Array(20);
50
+ const view = new DataView(bytes.buffer);
51
+ view.setUint32(0, 0, true);
52
+ view.setUint32(4, ccpText, true);
53
+ view.setUint16(8, 0, true);
54
+ view.setUint32(10, fcSepx, true);
55
+ view.setUint16(14, 0, true);
56
+ view.setUint32(16, 4294967295, true);
57
+ return bytes;
58
+ }
59
+ //#endregion
60
+ export { buildPlcfSed, buildSepx, encodeSectionGrpprl };
@@ -0,0 +1,63 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_bytes = require("../bytes.cjs");
3
+ const require_plc = require("../plc.cjs");
4
+ const require_prop_sprm = require("./sprm.cjs");
5
+ //#region src/prop/sep.ts
6
+ /** Sed, [MS-DOC] 2.9.269: fn(2, ignored) + fcSepx(4) + fnMpr(2, ignored) + fcMpr(4, ignored) -- 12 bytes, the fixed element size parsePlc needs for PlcfSed. */
7
+ const SED_SIZE = 12;
8
+ const SED_FC_SEPX_OFFSET = 2;
9
+ /** sprmSXaPage: page width, an unsigned 2-byte twips value. */
10
+ const SPRM_S_XA_PAGE = 45087;
11
+ /** sprmSYaPage: page height, an unsigned 2-byte twips value. */
12
+ const SPRM_S_YA_PAGE = 45088;
13
+ /** sprmSDxaLeft / sprmSDxaRight: an XAS_nonNeg (unsigned 2-byte twips) left/right margin. */
14
+ const SPRM_S_DXA_LEFT = 45089;
15
+ const SPRM_S_DXA_RIGHT = 45090;
16
+ /** sprmSDyaTop / sprmSDyaBottom: a YAS (signed 2-byte twips) top/bottom margin -- positive is a minimum margin that grows to avoid a header/footer, negative a fixed margin whose absolute value is used regardless. document-schema.js's Margins has no minimum/fixed distinction, so both forms report the same absolute size (see marginFromYas below). */
17
+ const SPRM_S_DYA_TOP = 36899;
18
+ const SPRM_S_DYA_BOTTOM = 36900;
19
+ const TWIPS_PER_POINT = 20;
20
+ function twipsToPoints(twips) {
21
+ return twips / TWIPS_PER_POINT;
22
+ }
23
+ function marginFromYas(twips) {
24
+ return twipsToPoints(Math.abs(twips));
25
+ }
26
+ function applySectionSprms(prls, into) {
27
+ for (const prl of prls) {
28
+ if (prl.sprm.sgc !== require_prop_sprm.SGC.section) continue;
29
+ switch (prl.sprm.value) {
30
+ case SPRM_S_XA_PAGE:
31
+ into.pageWidthPt = twipsToPoints(require_bytes.readUint16LE(prl.operand, 0));
32
+ break;
33
+ case SPRM_S_YA_PAGE:
34
+ into.pageHeightPt = twipsToPoints(require_bytes.readUint16LE(prl.operand, 0));
35
+ break;
36
+ case SPRM_S_DXA_LEFT:
37
+ into.marginLeftPt = twipsToPoints(require_bytes.readUint16LE(prl.operand, 0));
38
+ break;
39
+ case SPRM_S_DXA_RIGHT:
40
+ into.marginRightPt = twipsToPoints(require_bytes.readUint16LE(prl.operand, 0));
41
+ break;
42
+ case SPRM_S_DYA_TOP:
43
+ into.marginTopPt = marginFromYas(require_bytes.readInt16LE(prl.operand, 0));
44
+ break;
45
+ case SPRM_S_DYA_BOTTOM: into.marginBottomPt = marginFromYas(require_bytes.readInt16LE(prl.operand, 0));
46
+ }
47
+ }
48
+ return into;
49
+ }
50
+ /** Resolves the document's first section's own page size and margins from PlcfSed/Sepx -- absent entirely when the file carries no PlcfSed at all (lcbPlcfSed 0), which read.ts's own DEFAULT_PAGE_SIZE/DEFAULT_MARGINS then stand in for field by field, exactly as an individual unstated sprm already does. This reader only ever resolves the section covering the whole main document (see read.ts's own DocContent comment on why more than one section is out of scope), so it reads PlcfSed's first Sed regardless of how many the file actually carries. */
51
+ function readSectionProperties(wordDocument, table, fib) {
52
+ if (fib.lcbPlcfSed === 0) return {};
53
+ const plc = require_plc.parsePlc(require_bytes.slice(table, fib.fcPlcfSed, fib.lcbPlcfSed, "PlcfSed in the Table stream"), SED_SIZE, "PlcfSed");
54
+ if (plc.count === 0) return {};
55
+ const sed = plc.element(0);
56
+ const fcSepx = require_bytes.readUint32LE(sed, SED_FC_SEPX_OFFSET);
57
+ const cb = require_bytes.readUint16LE(wordDocument, fcSepx);
58
+ const grpprl = require_bytes.slice(wordDocument, fcSepx + 2, cb, "Sepx grpprl in the WordDocument stream");
59
+ return applySectionSprms(require_prop_sprm.readGrpprl(grpprl), {});
60
+ }
61
+ //#endregion
62
+ exports.applySectionSprms = applySectionSprms;
63
+ exports.readSectionProperties = readSectionProperties;
@@ -0,0 +1,16 @@
1
+ import { t as Fib } from "../fib-CtsLtF96.cjs";
2
+ import { t as Prl } from "../sprm-Djg5RNiq.cjs";
3
+ //#region src/prop/sep.d.ts
4
+ interface SectionProperties {
5
+ pageWidthPt?: number;
6
+ pageHeightPt?: number;
7
+ marginLeftPt?: number;
8
+ marginRightPt?: number;
9
+ marginTopPt?: number;
10
+ marginBottomPt?: number;
11
+ }
12
+ declare function applySectionSprms(prls: readonly Prl[], into: SectionProperties): SectionProperties;
13
+ /** Resolves the document's first section's own page size and margins from PlcfSed/Sepx -- absent entirely when the file carries no PlcfSed at all (lcbPlcfSed 0), which read.ts's own DEFAULT_PAGE_SIZE/DEFAULT_MARGINS then stand in for field by field, exactly as an individual unstated sprm already does. This reader only ever resolves the section covering the whole main document (see read.ts's own DocContent comment on why more than one section is out of scope), so it reads PlcfSed's first Sed regardless of how many the file actually carries. */
14
+ declare function readSectionProperties(wordDocument: Uint8Array, table: Uint8Array, fib: Pick<Fib, "fcPlcfSed" | "lcbPlcfSed">): SectionProperties;
15
+ //#endregion
16
+ export { SectionProperties, applySectionSprms, readSectionProperties };
@@ -0,0 +1,16 @@
1
+ import { t as Fib } from "../fib-CtsLtF96.js";
2
+ import { t as Prl } from "../sprm-Djg5RNiq.js";
3
+ //#region src/prop/sep.d.ts
4
+ interface SectionProperties {
5
+ pageWidthPt?: number;
6
+ pageHeightPt?: number;
7
+ marginLeftPt?: number;
8
+ marginRightPt?: number;
9
+ marginTopPt?: number;
10
+ marginBottomPt?: number;
11
+ }
12
+ declare function applySectionSprms(prls: readonly Prl[], into: SectionProperties): SectionProperties;
13
+ /** Resolves the document's first section's own page size and margins from PlcfSed/Sepx -- absent entirely when the file carries no PlcfSed at all (lcbPlcfSed 0), which read.ts's own DEFAULT_PAGE_SIZE/DEFAULT_MARGINS then stand in for field by field, exactly as an individual unstated sprm already does. This reader only ever resolves the section covering the whole main document (see read.ts's own DocContent comment on why more than one section is out of scope), so it reads PlcfSed's first Sed regardless of how many the file actually carries. */
14
+ declare function readSectionProperties(wordDocument: Uint8Array, table: Uint8Array, fib: Pick<Fib, "fcPlcfSed" | "lcbPlcfSed">): SectionProperties;
15
+ //#endregion
16
+ export { SectionProperties, applySectionSprms, readSectionProperties };
@@ -0,0 +1,61 @@
1
+ import { readInt16LE, readUint16LE, readUint32LE, slice } from "../bytes.js";
2
+ import { parsePlc } from "../plc.js";
3
+ import { SGC, readGrpprl } from "./sprm.js";
4
+ //#region src/prop/sep.ts
5
+ /** Sed, [MS-DOC] 2.9.269: fn(2, ignored) + fcSepx(4) + fnMpr(2, ignored) + fcMpr(4, ignored) -- 12 bytes, the fixed element size parsePlc needs for PlcfSed. */
6
+ const SED_SIZE = 12;
7
+ const SED_FC_SEPX_OFFSET = 2;
8
+ /** sprmSXaPage: page width, an unsigned 2-byte twips value. */
9
+ const SPRM_S_XA_PAGE = 45087;
10
+ /** sprmSYaPage: page height, an unsigned 2-byte twips value. */
11
+ const SPRM_S_YA_PAGE = 45088;
12
+ /** sprmSDxaLeft / sprmSDxaRight: an XAS_nonNeg (unsigned 2-byte twips) left/right margin. */
13
+ const SPRM_S_DXA_LEFT = 45089;
14
+ const SPRM_S_DXA_RIGHT = 45090;
15
+ /** sprmSDyaTop / sprmSDyaBottom: a YAS (signed 2-byte twips) top/bottom margin -- positive is a minimum margin that grows to avoid a header/footer, negative a fixed margin whose absolute value is used regardless. document-schema.js's Margins has no minimum/fixed distinction, so both forms report the same absolute size (see marginFromYas below). */
16
+ const SPRM_S_DYA_TOP = 36899;
17
+ const SPRM_S_DYA_BOTTOM = 36900;
18
+ const TWIPS_PER_POINT = 20;
19
+ function twipsToPoints(twips) {
20
+ return twips / TWIPS_PER_POINT;
21
+ }
22
+ function marginFromYas(twips) {
23
+ return twipsToPoints(Math.abs(twips));
24
+ }
25
+ function applySectionSprms(prls, into) {
26
+ for (const prl of prls) {
27
+ if (prl.sprm.sgc !== SGC.section) continue;
28
+ switch (prl.sprm.value) {
29
+ case SPRM_S_XA_PAGE:
30
+ into.pageWidthPt = twipsToPoints(readUint16LE(prl.operand, 0));
31
+ break;
32
+ case SPRM_S_YA_PAGE:
33
+ into.pageHeightPt = twipsToPoints(readUint16LE(prl.operand, 0));
34
+ break;
35
+ case SPRM_S_DXA_LEFT:
36
+ into.marginLeftPt = twipsToPoints(readUint16LE(prl.operand, 0));
37
+ break;
38
+ case SPRM_S_DXA_RIGHT:
39
+ into.marginRightPt = twipsToPoints(readUint16LE(prl.operand, 0));
40
+ break;
41
+ case SPRM_S_DYA_TOP:
42
+ into.marginTopPt = marginFromYas(readInt16LE(prl.operand, 0));
43
+ break;
44
+ case SPRM_S_DYA_BOTTOM: into.marginBottomPt = marginFromYas(readInt16LE(prl.operand, 0));
45
+ }
46
+ }
47
+ return into;
48
+ }
49
+ /** Resolves the document's first section's own page size and margins from PlcfSed/Sepx -- absent entirely when the file carries no PlcfSed at all (lcbPlcfSed 0), which read.ts's own DEFAULT_PAGE_SIZE/DEFAULT_MARGINS then stand in for field by field, exactly as an individual unstated sprm already does. This reader only ever resolves the section covering the whole main document (see read.ts's own DocContent comment on why more than one section is out of scope), so it reads PlcfSed's first Sed regardless of how many the file actually carries. */
50
+ function readSectionProperties(wordDocument, table, fib) {
51
+ if (fib.lcbPlcfSed === 0) return {};
52
+ const plc = parsePlc(slice(table, fib.fcPlcfSed, fib.lcbPlcfSed, "PlcfSed in the Table stream"), SED_SIZE, "PlcfSed");
53
+ if (plc.count === 0) return {};
54
+ const sed = plc.element(0);
55
+ const fcSepx = readUint32LE(sed, SED_FC_SEPX_OFFSET);
56
+ const cb = readUint16LE(wordDocument, fcSepx);
57
+ const grpprl = slice(wordDocument, fcSepx + 2, cb, "Sepx grpprl in the WordDocument stream");
58
+ return applySectionSprms(readGrpprl(grpprl), {});
59
+ }
60
+ //#endregion
61
+ export { applySectionSprms, readSectionProperties };
@@ -1,26 +1,2 @@
1
- //#region src/prop/sprm.d.ts
2
- interface Sprm {
3
- /** The raw 16-bit opcode, which is what the property tables in [MS-DOC] 2.6.1-2.6.5 are keyed on. */
4
- readonly value: number;
5
- readonly ispmd: number;
6
- readonly fSpec: 0 | 1;
7
- readonly sgc: number;
8
- readonly spra: number;
9
- }
10
- interface Prl {
11
- readonly sprm: Sprm;
12
- readonly operand: Uint8Array;
13
- }
14
- /** Sprm.sgc, [MS-DOC] 2.6.1 -- which property family the opcode belongs to. */
15
- declare const SGC: {
16
- readonly paragraph: 1;
17
- readonly character: 2;
18
- readonly picture: 3;
19
- readonly section: 4;
20
- readonly table: 5;
21
- };
22
- declare function decodeSprm(value: number): Sprm;
23
- declare function operandSize(sprm: Sprm, bytes: Uint8Array, offset: number): number;
24
- declare function readGrpprl(bytes: Uint8Array): Prl[];
25
- //#endregion
1
+ import { a as operandSize, i as decodeSprm, n as SGC, o as readGrpprl, r as Sprm, t as Prl } from "../sprm-Djg5RNiq.cjs";
26
2
  export { Prl, SGC, Sprm, decodeSprm, operandSize, readGrpprl };
@@ -1,26 +1,2 @@
1
- //#region src/prop/sprm.d.ts
2
- interface Sprm {
3
- /** The raw 16-bit opcode, which is what the property tables in [MS-DOC] 2.6.1-2.6.5 are keyed on. */
4
- readonly value: number;
5
- readonly ispmd: number;
6
- readonly fSpec: 0 | 1;
7
- readonly sgc: number;
8
- readonly spra: number;
9
- }
10
- interface Prl {
11
- readonly sprm: Sprm;
12
- readonly operand: Uint8Array;
13
- }
14
- /** Sprm.sgc, [MS-DOC] 2.6.1 -- which property family the opcode belongs to. */
15
- declare const SGC: {
16
- readonly paragraph: 1;
17
- readonly character: 2;
18
- readonly picture: 3;
19
- readonly section: 4;
20
- readonly table: 5;
21
- };
22
- declare function decodeSprm(value: number): Sprm;
23
- declare function operandSize(sprm: Sprm, bytes: Uint8Array, offset: number): number;
24
- declare function readGrpprl(bytes: Uint8Array): Prl[];
25
- //#endregion
1
+ import { a as operandSize, i as decodeSprm, n as SGC, o as readGrpprl, r as Sprm, t as Prl } from "../sprm-Djg5RNiq.js";
26
2
  export { Prl, SGC, Sprm, decodeSprm, operandSize, readGrpprl };
package/dist/read.cjs CHANGED
@@ -10,10 +10,14 @@ const require_prop_sprm = require("./prop/sprm.cjs");
10
10
  const require_prop_fkp = require("./prop/fkp.cjs");
11
11
  const require_prop_chp = require("./prop/chp.cjs");
12
12
  const require_prop_pap = require("./prop/pap.cjs");
13
+ const require_prop_sep = require("./prop/sep.cjs");
13
14
  const require_style_stsh = require("./style/stsh.cjs");
15
+ const require_style_fonts = require("./style/fonts.cjs");
16
+ const require_list_numbering = require("./list/numbering.cjs");
17
+ const require_table_read = require("./table/read.cjs");
14
18
  let archive_codec = require("archive-codec");
15
19
  //#region src/read.ts
16
- /** The page geometry every section is given, because this reader does not yet read a document's own. US Letter with one-inch margins is Word's own default for a new document; a document that states otherwise is not yet consulted, so this is a placeholder the schema requires rather than a fact read from the file. */
20
+ /** Word's own default for a new document (US Letter, one-inch margins) -- what a field this reader resolves from PlcfSed/Sepx (prop/sep.ts's readSectionProperties) falls back to when the file states nothing for it, exactly as it would fall back to Word's own implementation-dependent default for that one unstated sprm. */
17
21
  const DEFAULT_PAGE_SIZE = {
18
22
  widthPt: 612,
19
23
  heightPt: 792
@@ -32,64 +36,86 @@ function readDocStreams(bytes) {
32
36
  const wanted = require_fib_fib.tableStreamName(fib);
33
37
  const table = streams.find((stream) => stream.path === wanted);
34
38
  if (table === void 0) throw new require_errors.DocFormatError(`FibBase.fWhichTblStm selects the "${wanted}" stream, which this compound file does not contain`);
39
+ const metadata = streams.find((stream) => stream.path === require_detect.SUMMARY_INFORMATION_STREAM);
35
40
  return {
36
41
  wordDocument: wordDocument.bytes,
37
42
  table: table.bytes,
38
- fib
43
+ fib,
44
+ metadata: metadata?.bytes
39
45
  };
40
46
  }
41
47
  function readDocContent(bytes) {
42
- const { wordDocument, table, fib } = readDocStreams(bytes);
48
+ const { wordDocument, table, fib, metadata } = readDocStreams(bytes);
43
49
  const pieceTable = require_text_piece_table.parseClx(require_bytes.slice(table, fib.fcClx, fib.lcbClx, "Clx in the Table stream"));
44
50
  const styles = fib.lcbStshf > 0 ? require_style_stsh.parseStsh(require_bytes.slice(table, fib.fcStshf, fib.lcbStshf, "STSH in the Table stream")) : void 0;
45
51
  const chpxTable = new require_prop_fkp.PropertyBinTable(wordDocument, require_bytes.slice(table, fib.fcPlcfBteChpx, fib.lcbPlcfBteChpx, "PlcBteChpx in the Table stream"), "PlcBteChpx");
46
52
  const papxTable = new require_prop_fkp.PropertyBinTable(wordDocument, require_bytes.slice(table, fib.fcPlcfBtePapx, fib.lcbPlcfBtePapx, "PlcBtePapx in the Table stream"), "PlcBtePapx");
53
+ const fonts = fib.lcbSttbfFfn > 0 ? require_style_fonts.parseFontTable(require_bytes.slice(table, fib.fcSttbfFfn, fib.lcbSttbfFfn, "SttbfFfn in the Table stream")) : void 0;
47
54
  const range = require_text_characters.readTextRange(wordDocument, pieceTable, 0, fib.ccpText);
48
- const blocks = readParagraphs(range.text, range.fcs, {
55
+ const entries = readParagraphs(range.text, range.fcs, {
49
56
  chpxTable,
50
57
  papxTable,
51
58
  styles,
59
+ fonts,
52
60
  characterProperties: /* @__PURE__ */ new Map()
53
61
  });
62
+ const blocks = require_table_read.assembleBlocks(entries);
63
+ const numbering = require_list_numbering.readNumberingDefinitions(table, fib);
64
+ const sectionProperties = require_prop_sep.readSectionProperties(wordDocument, table, fib);
54
65
  return {
55
66
  kind: "wordprocessing",
56
- metadata: {},
67
+ metadata: metadata === void 0 ? {} : (0, archive_codec.summaryInformationToLayoutMetadata)((0, archive_codec.readSummaryInformation)(metadata)),
57
68
  sections: [{
58
- pageSize: DEFAULT_PAGE_SIZE,
59
- margins: DEFAULT_MARGINS,
69
+ pageSize: {
70
+ widthPt: sectionProperties.pageWidthPt ?? DEFAULT_PAGE_SIZE.widthPt,
71
+ heightPt: sectionProperties.pageHeightPt ?? DEFAULT_PAGE_SIZE.heightPt
72
+ },
73
+ margins: {
74
+ leftPt: sectionProperties.marginLeftPt ?? DEFAULT_MARGINS.leftPt,
75
+ rightPt: sectionProperties.marginRightPt ?? DEFAULT_MARGINS.rightPt,
76
+ topPt: sectionProperties.marginTopPt ?? DEFAULT_MARGINS.topPt,
77
+ bottomPt: sectionProperties.marginBottomPt ?? DEFAULT_MARGINS.bottomPt
78
+ },
60
79
  blocks
61
- }]
80
+ }],
81
+ numbering
62
82
  };
63
83
  }
64
84
  function readParagraphs(text, fcs, context) {
65
- const blocks = [];
85
+ const entries = [];
66
86
  let start = 0;
67
87
  for (let index = 0; index < text.length; index += 1) {
68
88
  const code = text.charCodeAt(index);
69
89
  if (!require_text_special.endsParagraph(code)) continue;
70
90
  const markFc = fcs[index];
71
91
  if (markFc === void 0) throw new require_errors.DocFormatError(`character ${index} has no byte offset, so its paragraph's properties cannot be located`);
72
- blocks.push(buildParagraph(text.slice(start, index), fcs.slice(start, index), markFc, context));
92
+ entries.push(buildParagraph(text.slice(start, index), fcs.slice(start, index), markFc, code, context));
73
93
  start = index + 1;
74
94
  }
75
95
  if (start < text.length) {
76
96
  const firstFc = fcs[start];
77
97
  if (firstFc === void 0) throw new require_errors.DocFormatError(`character ${start} has no byte offset, so the trailing paragraph's properties cannot be located`);
78
- blocks.push(buildParagraph(text.slice(start), fcs.slice(start), firstFc, context));
98
+ entries.push(buildParagraph(text.slice(start), fcs.slice(start), firstFc, 13, context));
79
99
  }
80
- return blocks;
100
+ return entries;
81
101
  }
82
- function buildParagraph(text, fcs, propertyFc, context) {
102
+ function buildParagraph(text, fcs, propertyFc, terminator, context) {
83
103
  const papx = context.papxTable.papx(propertyFc);
84
104
  const properties = {};
105
+ const grpprl = papx !== void 0 ? require_prop_sprm.readGrpprl(papx.grpprl) : [];
85
106
  if (papx !== void 0) {
86
107
  properties.istd = papx.istd;
87
- require_prop_pap.applyParagraphSprms(require_prop_sprm.readGrpprl(papx.grpprl), properties);
108
+ require_prop_pap.applyParagraphSprms(grpprl, properties);
88
109
  }
89
110
  return {
90
- kind: "paragraph",
91
- runs: buildRuns(text, fcs, context),
92
- ...paragraphAttributes(properties, context)
111
+ paragraph: {
112
+ kind: "paragraph",
113
+ runs: buildRuns(text, fcs, context),
114
+ ...paragraphAttributes(properties, context)
115
+ },
116
+ properties,
117
+ grpprl,
118
+ terminator
93
119
  };
94
120
  }
95
121
  function paragraphAttributes(properties, context) {
@@ -156,7 +182,7 @@ function buildRuns(text, fcs, context) {
156
182
  let properties = context.characterProperties.get(key);
157
183
  if (properties === void 0) {
158
184
  properties = {};
159
- if (grpprl !== void 0) require_prop_chp.applyCharacterSprms(require_prop_sprm.readGrpprl(grpprl), properties);
185
+ if (grpprl !== void 0) require_prop_chp.applyCharacterSprms(require_prop_sprm.readGrpprl(grpprl), properties, context.fonts);
160
186
  context.characterProperties.set(key, properties);
161
187
  }
162
188
  currentProperties = properties;
package/dist/read.d.cts CHANGED
@@ -1,12 +1,29 @@
1
- import { Fib } from "./fib/fib.cjs";
2
- import { ContentDocument } from "document-schema.js";
1
+ import { t as Fib } from "./fib-CtsLtF96.cjs";
2
+ import { t as Prl } from "./sprm-Djg5RNiq.cjs";
3
+ import { t as ParagraphProperties } from "./pap-BmelEYEP.cjs";
4
+ import { n as NumberingDefinitions } from "./numbering-Cir-uGdc.cjs";
5
+ import { ContentDocument, ContentParagraph } from "document-schema.js";
3
6
  //#region src/read.d.ts
4
7
  interface DocStreams {
5
8
  readonly wordDocument: Uint8Array;
6
9
  readonly table: Uint8Array;
7
10
  readonly fib: Fib;
11
+ /** The raw "\x05SummaryInformation" stream bytes, or undefined when the container carries none -- a valid, spec-conformant Word Binary File need not carry document properties at all. */
12
+ readonly metadata: Uint8Array<ArrayBuffer> | undefined;
8
13
  }
9
14
  declare function readDocStreams(bytes: Uint8Array<ArrayBuffer>): DocStreams;
10
- declare function readDocContent(bytes: Uint8Array<ArrayBuffer>): ContentDocument;
15
+ /** readDocContent's own return type: a ContentDocument (kind 'wordprocessing') plus numbering -- the list-level formatting (glyph/format, level-text template, start-at value) PlfLst/PlfLfo carry, which ContentListMembership has nowhere to hold. Mirrors ooxml.js's own DocxDocument.numbering exactly in field name and NumberingDefinitions' own shape (see list/numbering.ts's top comment for why it sits outside the shared schema rather than inside ContentListMembership); unlike DocxDocument, DocContent stays a genuine ContentDocument subtype (an intersection, not a fresh shape) since readDocContent already had one return type to widen rather than two to reconcile. */
16
+ type DocContent = ContentDocument & {
17
+ readonly numbering: NumberingDefinitions;
18
+ };
19
+ declare function readDocContent(bytes: Uint8Array<ArrayBuffer>): DocContent;
20
+ /** One paragraph/cell/row-ending mark, still flat -- table/read.ts's assembleBlocks is what folds a run of these into a real ContentTable. `properties` and `grpprl` are carried alongside the already-built `paragraph` because table grouping needs sprmPFInTable/sprmPFTtp/sprmPItap (properties) and, on a row's own mark, its table-defining sgc-5 sprms (grpprl) -- neither of which survives onto a plain ContentParagraph. */
21
+ interface ParagraphEntry {
22
+ readonly paragraph: ContentParagraph;
23
+ readonly properties: ParagraphProperties;
24
+ readonly grpprl: readonly Prl[];
25
+ /** The character that terminated this paragraph in the text stream: PARAGRAPH_MARK, CELL_MARK, or SECTION_MARK. */
26
+ readonly terminator: number;
27
+ }
11
28
  //#endregion
12
- export { DocStreams, readDocContent, readDocStreams };
29
+ export { DocContent, DocStreams, ParagraphEntry, readDocContent, readDocStreams };