reamkit 0.1.0-alpha.0 → 1.0.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 (200) hide show
  1. package/README.md +107 -30
  2. package/dist/esm/{bidi → core/bidi}/algorithm.js +1 -1
  3. package/dist/esm/{bidi → core/bidi}/char-types.js +1 -1
  4. package/dist/esm/{bidi → core/bidi}/index.d.ts +2 -0
  5. package/dist/esm/{bidi → core/bidi}/index.js +2 -1
  6. package/dist/esm/core/bidi/segments.d.ts +6 -0
  7. package/dist/esm/core/bidi/segments.js +41 -0
  8. package/dist/esm/core/bytes.d.ts +1 -0
  9. package/dist/esm/core/bytes.js +11 -0
  10. package/dist/esm/core/converter/facade.d.ts +45 -0
  11. package/dist/esm/core/converter/facade.js +89 -0
  12. package/dist/esm/core/converter/index.d.ts +4 -0
  13. package/dist/esm/core/converter/project.d.ts +4 -0
  14. package/dist/esm/core/converter/project.js +17 -0
  15. package/dist/esm/core/converter/ream.d.ts +35 -0
  16. package/dist/esm/core/converter/ream.js +101 -0
  17. package/dist/esm/{crypto → core/crypto}/asn1.js +1 -1
  18. package/dist/esm/{crypto → core/crypto}/cms.js +1 -1
  19. package/dist/esm/core/document-model/index.d.ts +1 -0
  20. package/dist/esm/{document-model → core/document-model}/types.d.ts +57 -41
  21. package/dist/esm/{ooxml → core}/drawingml/chart-parser.d.ts +1 -1
  22. package/dist/esm/{ooxml → core}/drawingml/chart-parser.js +6 -29
  23. package/dist/esm/{ooxml → core}/drawingml/colors.d.ts +3 -0
  24. package/dist/esm/{ooxml → core}/drawingml/colors.js +32 -2
  25. package/dist/esm/{ooxml → core}/drawingml/theme-parser.js +2 -2
  26. package/dist/esm/{font → core/font}/arabic-joining.js +1 -1
  27. package/dist/esm/{font → core/font}/binary-reader.js +1 -1
  28. package/dist/esm/{font → core/font}/font-registry.d.ts +1 -0
  29. package/dist/esm/{font → core/font}/font-registry.js +17 -16
  30. package/dist/esm/{font → core/font}/index.d.ts +3 -0
  31. package/dist/esm/core/font/measure.d.ts +7 -0
  32. package/dist/esm/core/font/measure.js +30 -0
  33. package/dist/esm/{font → core/font}/opentype-layout.js +1 -1
  34. package/dist/esm/{font → core/font}/ttf-parser.js +1 -1
  35. package/dist/esm/{font → core/font}/ttf-subset.js +1 -1
  36. package/dist/esm/core/fonts/provider.d.ts +60 -0
  37. package/dist/esm/core/fonts/provider.js +163 -0
  38. package/dist/esm/{fonts → core/fonts}/remote-fonts.js +1 -1
  39. package/dist/esm/{hyphenation → core/hyphenation}/index.js +1 -1
  40. package/dist/esm/{hyphenation → core/hyphenation}/liang.js +1 -1
  41. package/dist/esm/{hyphenation → core/hyphenation}/patterns-en-us.js +1 -1
  42. package/dist/esm/{hyphenation → core/hyphenation}/patterns-ru.js +1 -1
  43. package/dist/esm/core/images.d.ts +17 -0
  44. package/dist/esm/core/images.js +308 -0
  45. package/dist/esm/core/ir/adapters.d.ts +37 -0
  46. package/dist/esm/core/ir/features.d.ts +25 -0
  47. package/dist/esm/core/ir/features.js +24 -0
  48. package/dist/esm/core/ir/flow.d.ts +24 -0
  49. package/dist/esm/core/ir/index.d.ts +11 -0
  50. package/dist/esm/core/ir/loss.d.ts +22 -0
  51. package/dist/esm/core/ir/loss.js +15 -0
  52. package/dist/esm/core/ir/resources.d.ts +16 -0
  53. package/dist/esm/core/ir/resources.js +50 -0
  54. package/dist/esm/core/ir/units.d.ts +16 -0
  55. package/dist/esm/core/ir/units.js +41 -0
  56. package/dist/esm/core/line-breaker/index.d.ts +2 -0
  57. package/dist/esm/{line-breaker → core/line-breaker}/knuth-plass.d.ts +1 -0
  58. package/dist/esm/{line-breaker → core/line-breaker}/knuth-plass.js +3 -3
  59. package/dist/esm/core/numbering/apply.d.ts +3 -0
  60. package/dist/esm/core/numbering/apply.js +62 -0
  61. package/dist/esm/core/numbering/index.d.ts +2 -0
  62. package/dist/esm/{numbering → core/numbering}/state.js +1 -1
  63. package/dist/esm/{opc → core/opc}/core-properties.js +1 -1
  64. package/dist/esm/{opc → core/opc}/package.d.ts +2 -1
  65. package/dist/esm/{opc → core/opc}/package.js +7 -3
  66. package/dist/esm/{opc → core/opc}/relationship-types.js +1 -1
  67. package/dist/esm/{opc → core/opc}/relationships.js +1 -1
  68. package/dist/esm/{ooxml/wordproc → core}/po-helpers.js +1 -1
  69. package/dist/esm/core/style-cascade/index.d.ts +3 -0
  70. package/dist/esm/core/style-cascade/index.js +2 -0
  71. package/dist/esm/core/style-cascade/resolver.d.ts +7 -0
  72. package/dist/esm/{style-cascade → core/style-cascade}/resolver.js +82 -10
  73. package/dist/esm/{style-cascade → core/style-cascade}/types.d.ts +10 -8
  74. package/dist/esm/{style-cascade → core/style-cascade}/types.js +9 -8
  75. package/dist/esm/core/vector.d.ts +45 -0
  76. package/dist/esm/core/vector.js +48 -0
  77. package/dist/esm/{ooxml/spreadsheet → excel}/cell-reference.js +1 -1
  78. package/dist/esm/{ooxml/spreadsheet → excel}/defined-name-ref.js +1 -1
  79. package/dist/esm/{ooxml/spreadsheet → excel}/index.d.ts +1 -1
  80. package/dist/esm/{ooxml/spreadsheet → excel}/number-format.js +1 -1
  81. package/dist/esm/excel/print-model.d.ts +18 -0
  82. package/dist/esm/{converter/xlsx-to-pdf.js → excel/print-model.js} +39 -148
  83. package/dist/esm/{ooxml/spreadsheet → excel}/shared-strings-parser.js +1 -1
  84. package/dist/esm/{ooxml/spreadsheet → excel}/styles-parser.js +1 -1
  85. package/dist/esm/{ooxml/spreadsheet → excel}/workbook-parser.js +1 -1
  86. package/dist/esm/{ooxml/spreadsheet → excel}/worksheet-parser.js +1 -1
  87. package/dist/esm/excel/xlsx-reader.d.ts +4 -0
  88. package/dist/esm/excel/xlsx-reader.js +91 -0
  89. package/dist/esm/{converter → excel}/xlsx-to-pdf.d.ts +13 -2
  90. package/dist/esm/excel/xlsx-to-pdf.js +69 -0
  91. package/dist/esm/index.d.ts +23 -8
  92. package/dist/esm/index.js +18 -10
  93. package/dist/esm/{pdf → layout}/arc-to-bezier.d.ts +1 -1
  94. package/dist/esm/{pdf → layout}/arc-to-bezier.js +2 -2
  95. package/dist/esm/{pdf → layout}/chart-geometry.d.ts +1 -1
  96. package/dist/esm/{pdf → layout}/math-layout.d.ts +2 -2
  97. package/dist/esm/{pdf → layout}/math-layout.js +1 -1
  98. package/dist/esm/layout/page-doc.d.ts +133 -0
  99. package/dist/esm/layout/page-doc.js +38 -0
  100. package/dist/esm/{pdf → layout}/preset-geometry.d.ts +2 -2
  101. package/dist/esm/{pdf → layout}/preset-geometry.js +2 -2
  102. package/dist/esm/layout/styled-layout.d.ts +84 -0
  103. package/dist/esm/layout/styled-layout.js +1729 -0
  104. package/dist/esm/pdf/cid-font.d.ts +1 -1
  105. package/dist/esm/pdf/cid-font.js +6 -21
  106. package/dist/esm/pdf/image-xobject.d.ts +4 -5
  107. package/dist/esm/pdf/image-xobject.js +21 -324
  108. package/dist/esm/pdf/index.d.ts +2 -2
  109. package/dist/esm/pdf/index.js +1 -0
  110. package/dist/esm/pdf/signature.js +4 -4
  111. package/dist/esm/pdf/styled-page-emitter.d.ts +11 -0
  112. package/dist/esm/pdf/styled-page-emitter.js +557 -0
  113. package/dist/esm/pdf/styled-page-renderer.d.ts +4 -42
  114. package/dist/esm/pdf/styled-page-renderer.js +4 -2311
  115. package/dist/esm/pdf/text-page-renderer.d.ts +1 -1
  116. package/dist/esm/pdf/vector-graphics.d.ts +3 -45
  117. package/dist/esm/pdf/vector-graphics.js +2 -46
  118. package/dist/esm/svg/svg-writer.d.ts +8 -0
  119. package/dist/esm/svg/svg-writer.js +137 -0
  120. package/dist/esm/word/document-parser.d.ts +16 -0
  121. package/dist/esm/{ooxml/wordproc → word}/document-parser.js +55 -47
  122. package/dist/esm/word/docx-reader.d.ts +4 -0
  123. package/dist/esm/word/docx-reader.js +191 -0
  124. package/dist/esm/word/docx-to-pdf.d.ts +34 -0
  125. package/dist/esm/word/docx-to-pdf.js +112 -0
  126. package/dist/esm/{ooxml/wordproc → word}/drawing-parser.d.ts +10 -9
  127. package/dist/esm/{ooxml/wordproc → word}/drawing-parser.js +15 -42
  128. package/dist/esm/{ooxml/wordproc → word}/font-table.d.ts +2 -2
  129. package/dist/esm/{ooxml/wordproc → word}/font-table.js +2 -2
  130. package/dist/esm/{ooxml/wordproc → word}/index.d.ts +3 -2
  131. package/dist/esm/{ooxml/wordproc → word}/numbering-parser.d.ts +1 -1
  132. package/dist/esm/{ooxml/wordproc → word}/numbering-parser.js +1 -1
  133. package/dist/esm/{ooxml/math → word}/omml-parser.d.ts +2 -2
  134. package/dist/esm/{ooxml/math → word}/omml-parser.js +2 -2
  135. package/dist/esm/{ooxml/wordproc → word}/paragraph-properties.d.ts +1 -1
  136. package/dist/esm/{ooxml/wordproc → word}/paragraph-properties.js +9 -8
  137. package/dist/esm/{ooxml/wordproc → word}/po-to-flat.d.ts +1 -1
  138. package/dist/esm/{ooxml/wordproc → word}/po-to-flat.js +2 -2
  139. package/dist/esm/{ooxml/wordproc → word}/run-properties.d.ts +1 -1
  140. package/dist/esm/{ooxml/wordproc → word}/run-properties.js +3 -2
  141. package/dist/esm/{ooxml/wordproc → word}/settings-parser.js +2 -2
  142. package/dist/esm/word/styles-parser.d.ts +2 -0
  143. package/dist/esm/{ooxml/wordproc → word}/styles-parser.js +4 -7
  144. package/dist/esm/word/table-parser.d.ts +4 -0
  145. package/dist/esm/{ooxml/wordproc → word}/table-parser.js +80 -26
  146. package/dist/esm/{ooxml/wordproc → word}/xml-helpers.js +1 -1
  147. package/package.json +5 -6
  148. package/dist/esm/converter/docx-to-pdf.d.ts +0 -15
  149. package/dist/esm/converter/docx-to-pdf.js +0 -227
  150. package/dist/esm/converter/index.d.ts +0 -4
  151. package/dist/esm/converter/index.js +0 -2
  152. package/dist/esm/document-model/index.d.ts +0 -1
  153. package/dist/esm/line-breaker/index.d.ts +0 -2
  154. package/dist/esm/numbering/index.d.ts +0 -1
  155. package/dist/esm/ooxml/index.d.ts +0 -1
  156. package/dist/esm/ooxml/wordproc/document-parser.d.ts +0 -9
  157. package/dist/esm/ooxml/wordproc/styles-parser.d.ts +0 -3
  158. package/dist/esm/ooxml/wordproc/table-parser.d.ts +0 -3
  159. package/dist/esm/style-cascade/index.d.ts +0 -3
  160. package/dist/esm/style-cascade/resolver.d.ts +0 -4
  161. /package/dist/esm/{bidi → core/bidi}/algorithm.d.ts +0 -0
  162. /package/dist/esm/{bidi → core/bidi}/char-types.d.ts +0 -0
  163. /package/dist/esm/{crypto → core/crypto}/asn1.d.ts +0 -0
  164. /package/dist/esm/{crypto → core/crypto}/cms.d.ts +0 -0
  165. /package/dist/esm/{crypto → core/crypto}/index.d.ts +0 -0
  166. /package/dist/esm/{crypto → core/crypto}/index.js +0 -0
  167. /package/dist/esm/{document-model → core/document-model}/index.js +0 -0
  168. /package/dist/esm/{ooxml → core}/drawingml/theme-parser.d.ts +0 -0
  169. /package/dist/esm/{font → core/font}/arabic-joining.d.ts +0 -0
  170. /package/dist/esm/{font → core/font}/binary-reader.d.ts +0 -0
  171. /package/dist/esm/{font → core/font}/opentype-layout.d.ts +0 -0
  172. /package/dist/esm/{font → core/font}/ttf-parser.d.ts +0 -0
  173. /package/dist/esm/{font → core/font}/ttf-subset.d.ts +0 -0
  174. /package/dist/esm/{fonts → core/fonts}/index.d.ts +0 -0
  175. /package/dist/esm/{fonts → core/fonts}/remote-fonts.d.ts +0 -0
  176. /package/dist/esm/{hyphenation → core/hyphenation}/index.d.ts +0 -0
  177. /package/dist/esm/{hyphenation → core/hyphenation}/liang.d.ts +0 -0
  178. /package/dist/esm/{hyphenation → core/hyphenation}/patterns-en-us.d.ts +0 -0
  179. /package/dist/esm/{hyphenation → core/hyphenation}/patterns-ru.d.ts +0 -0
  180. /package/dist/esm/{numbering → core/numbering}/state.d.ts +0 -0
  181. /package/dist/esm/{opc → core/opc}/core-properties.d.ts +0 -0
  182. /package/dist/esm/{opc → core/opc}/index.d.ts +0 -0
  183. /package/dist/esm/{opc → core/opc}/index.js +0 -0
  184. /package/dist/esm/{opc → core/opc}/relationship-types.d.ts +0 -0
  185. /package/dist/esm/{opc → core/opc}/relationships.d.ts +0 -0
  186. /package/dist/esm/{ooxml/wordproc → core}/po-helpers.d.ts +0 -0
  187. /package/dist/esm/{ooxml/spreadsheet → excel}/cell-reference.d.ts +0 -0
  188. /package/dist/esm/{ooxml/spreadsheet → excel}/defined-name-ref.d.ts +0 -0
  189. /package/dist/esm/{ooxml/spreadsheet → excel}/index.js +0 -0
  190. /package/dist/esm/{ooxml/spreadsheet → excel}/number-format.d.ts +0 -0
  191. /package/dist/esm/{ooxml/spreadsheet → excel}/shared-strings-parser.d.ts +0 -0
  192. /package/dist/esm/{ooxml/spreadsheet → excel}/styles-parser.d.ts +0 -0
  193. /package/dist/esm/{ooxml/spreadsheet → excel}/workbook-parser.d.ts +0 -0
  194. /package/dist/esm/{ooxml/spreadsheet → excel}/worksheet-parser.d.ts +0 -0
  195. /package/dist/esm/{pdf → layout}/chart-geometry.js +0 -0
  196. /package/dist/esm/{ooxml/wordproc → word}/index.js +0 -0
  197. /package/dist/esm/{ooxml/wordproc → word}/settings-parser.d.ts +0 -0
  198. /package/dist/esm/{ooxml/wordproc → word}/text-extractor.d.ts +0 -0
  199. /package/dist/esm/{ooxml/wordproc → word}/text-extractor.js +0 -0
  200. /package/dist/esm/{ooxml/wordproc → word}/xml-helpers.d.ts +0 -0
@@ -1,4 +1,4 @@
1
- import { ParsedTtf } from '../font/index.js';
1
+ import { ParsedTtf } from '../core/font/index.js';
2
2
  export type FontInput = ParsedTtf | {
3
3
  readonly bytes: Uint8Array;
4
4
  };
@@ -1,46 +1,4 @@
1
- export type PathSegment = {
2
- readonly op: 'move';
3
- readonly x: number;
4
- readonly y: number;
5
- } | {
6
- readonly op: 'line';
7
- readonly x: number;
8
- readonly y: number;
9
- } | {
10
- readonly op: 'cubic';
11
- readonly x1: number;
12
- readonly y1: number;
13
- readonly x2: number;
14
- readonly y2: number;
15
- readonly x: number;
16
- readonly y: number;
17
- } | {
18
- readonly op: 'close';
19
- };
20
- export interface VectorPath {
21
- readonly segments: ReadonlyArray<PathSegment>;
22
- readonly fillRule?: 'nonzero' | 'evenodd';
23
- }
24
- export interface StrokeStyle {
25
- readonly colorHex: string;
26
- readonly widthPt: number;
27
- readonly cap?: 'butt' | 'round' | 'square';
28
- readonly join?: 'miter' | 'round' | 'bevel';
29
- readonly dash?: ReadonlyArray<number>;
30
- }
31
- export interface VectorShape {
32
- readonly paths: ReadonlyArray<VectorPath>;
33
- readonly fillColorHex?: string;
34
- readonly stroke?: StrokeStyle;
35
- readonly transform: readonly [number, number, number, number, number, number];
36
- }
37
- export declare class PathBuilder {
38
- private readonly segments;
39
- moveTo(x: number, y: number): this;
40
- lineTo(x: number, y: number): this;
41
- cubicTo(x1: number, y1: number, x2: number, y2: number, x: number, y: number): this;
42
- append(segments: ReadonlyArray<PathSegment>): this;
43
- close(): this;
44
- build(fillRule?: 'nonzero' | 'evenodd'): VectorPath;
45
- }
1
+ import { VectorShape } from '../core/vector.js';
2
+ export type { PathSegment, StrokeStyle, VectorPath, VectorShape } from '../core/vector.js';
3
+ export { PathBuilder } from '../core/vector.js';
46
4
  export declare function emitVectorShape(shape: VectorShape): Array<string>;
@@ -1,49 +1,5 @@
1
+ import "../core/vector.js";
1
2
  //#region src/pdf/vector-graphics.ts
2
- var PathBuilder = class {
3
- segments = [];
4
- moveTo(x, y) {
5
- this.segments.push({
6
- op: "move",
7
- x,
8
- y
9
- });
10
- return this;
11
- }
12
- lineTo(x, y) {
13
- this.segments.push({
14
- op: "line",
15
- x,
16
- y
17
- });
18
- return this;
19
- }
20
- cubicTo(x1, y1, x2, y2, x, y) {
21
- this.segments.push({
22
- op: "cubic",
23
- x1,
24
- y1,
25
- x2,
26
- y2,
27
- x,
28
- y
29
- });
30
- return this;
31
- }
32
- append(segments) {
33
- for (const s of segments) this.segments.push(s);
34
- return this;
35
- }
36
- close() {
37
- this.segments.push({ op: "close" });
38
- return this;
39
- }
40
- build(fillRule) {
41
- return {
42
- segments: this.segments.slice(),
43
- ...fillRule ? { fillRule } : {}
44
- };
45
- }
46
- };
47
3
  function emitVectorShape(shape) {
48
4
  const out = [];
49
5
  out.push("q");
@@ -100,4 +56,4 @@ function hexToRgb01(hex) {
100
56
  ];
101
57
  }
102
58
  //#endregion
103
- export { PathBuilder, emitVectorShape };
59
+ export { emitVectorShape };
@@ -0,0 +1,8 @@
1
+ import { DocumentWriter, WriteResult } from '../core/ir/adapters.js';
2
+ import { LaidOutDocument } from '../layout/page-doc.js';
3
+ export interface SvgWriteOptions {
4
+ /** Gap between stacked pages, in px/pt (default 12). */
5
+ readonly pageGap?: number;
6
+ }
7
+ export declare function writeSvg(laid: LaidOutDocument, opts?: SvgWriteOptions): WriteResult;
8
+ export declare const svgWriter: DocumentWriter<LaidOutDocument>;
@@ -0,0 +1,137 @@
1
+ import { FEATURES } from "../core/ir/features.js";
2
+ import { paintPlan } from "../layout/page-doc.js";
3
+ //#region src/svg/svg-writer.ts
4
+ var PAGE_GAP = 12;
5
+ function writeSvg(laid, opts = {}) {
6
+ const gap = opts.pageGap ?? PAGE_GAP;
7
+ const losses = [];
8
+ const width = Math.max(1, ...laid.pages.map((p) => p.width));
9
+ const height = laid.pages.reduce((s, p) => s + p.height, 0) + gap * Math.max(0, laid.pages.length - 1);
10
+ const parts = [];
11
+ parts.push(`<svg xmlns="http://www.w3.org/2000/svg" width="${fmt(width)}" height="${fmt(height)}" viewBox="0 0 ${fmt(width)} ${fmt(height)}">`);
12
+ let yOffset = 0;
13
+ laid.pages.forEach((page, i) => {
14
+ parts.push(`<g transform="translate(0 ${fmt(yOffset)})" data-page="${i + 1}">`);
15
+ parts.push(`<rect x="0" y="0" width="${fmt(page.width)}" height="${fmt(page.height)}" fill="#ffffff" stroke="#cccccc"/>`);
16
+ emitPage(parts, page, laid, losses);
17
+ parts.push("</g>");
18
+ yOffset += page.height + gap;
19
+ });
20
+ parts.push("</svg>");
21
+ return {
22
+ bytes: new TextEncoder().encode(parts.join("\n")),
23
+ losses
24
+ };
25
+ }
26
+ var svgWriter = {
27
+ id: "svg",
28
+ consumes: "page",
29
+ supports: new Set([
30
+ FEATURES.text,
31
+ FEATURES.tables,
32
+ FEATURES.images,
33
+ FEATURES.shapes
34
+ ]),
35
+ write: (doc, opts) => writeSvg(doc, opts ?? {})
36
+ };
37
+ function emitPage(out, page, laid, losses) {
38
+ const plan = paintPlan(page.commands);
39
+ for (const f of plan.fills) out.push(`<rect x="${fmt(f.x)}" y="${fmt(f.y)}" width="${fmt(f.width)}" height="${fmt(f.height)}" fill="#${f.fillColorHex}"/>`);
40
+ for (const img of plan.images) {
41
+ const href = imageHref(img.imageResourceName, laid);
42
+ if (!href) continue;
43
+ out.push(`<image x="${fmt(img.x)}" y="${fmt(img.y)}" width="${fmt(img.width)}" height="${fmt(img.height)}" href="${href}" preserveAspectRatio="none"/>`);
44
+ }
45
+ for (const b of plan.borders) {
46
+ const x2 = b.x + b.width;
47
+ const yTop = b.y;
48
+ const yBottom = b.y + b.height;
49
+ const [ax, ay, bx, by] = b.side === "top" ? [
50
+ b.x,
51
+ yTop,
52
+ x2,
53
+ yTop
54
+ ] : b.side === "bottom" ? [
55
+ b.x,
56
+ yBottom,
57
+ x2,
58
+ yBottom
59
+ ] : b.side === "left" ? [
60
+ b.x,
61
+ yTop,
62
+ b.x,
63
+ yBottom
64
+ ] : [
65
+ x2,
66
+ yTop,
67
+ x2,
68
+ yBottom
69
+ ];
70
+ out.push(`<line x1="${fmt(ax)}" y1="${fmt(ay)}" x2="${fmt(bx)}" y2="${fmt(by)}" stroke="#${b.borderColorHex}" stroke-width="${fmt(b.borderSizePt)}"/>`);
71
+ }
72
+ for (const sh of plan.shapes) emitShape(out, sh.shape);
73
+ for (const t of plan.lines) emitTextLine(out, t, losses);
74
+ }
75
+ function emitTextLine(out, item, losses) {
76
+ const y = item.baselineY;
77
+ let x = item.originX;
78
+ for (const tok of item.line.tokens) {
79
+ if (tok.kind === "image") {
80
+ x += tok.widthPt;
81
+ continue;
82
+ }
83
+ if (tok.kind === "math") {
84
+ losses.push({
85
+ severity: "dropped",
86
+ feature: FEATURES.math,
87
+ detail: "inline math box not rendered by the SVG writer (v0)"
88
+ });
89
+ x += tok.widthPt;
90
+ continue;
91
+ }
92
+ if (tok.text.trim().length > 0) out.push(`<text x="${fmt(x)}" y="${fmt(y)}" font-family="sans-serif" font-size="${fmt(tok.fontSizePt)}" fill="#${tok.resolvedRun.colorHex}">${escapeXml(tok.text)}</text>`);
93
+ x += tok.widthPt;
94
+ }
95
+ }
96
+ function emitShape(out, shape) {
97
+ const [a, b, c, d, e, f] = shape.transform;
98
+ const transform = `matrix(${fmt(a)} ${fmt(b)} ${fmt(c)} ${fmt(d)} ${fmt(e)} ${fmt(f)})`;
99
+ const fill = shape.fillColorHex ? `#${shape.fillColorHex}` : "none";
100
+ const stroke = shape.stroke ? ` stroke="#${shape.stroke.colorHex}" stroke-width="${fmt(shape.stroke.widthPt)}"` : "";
101
+ for (const path of shape.paths) {
102
+ const d2 = pathData(path.segments);
103
+ const rule = path.fillRule === "evenodd" ? " fill-rule=\"evenodd\"" : "";
104
+ out.push(`<path d="${d2}" fill="${fill}"${rule}${stroke} transform="${transform}"/>`);
105
+ }
106
+ }
107
+ function pathData(segments) {
108
+ const parts = [];
109
+ for (const s of segments) if (s.op === "move") parts.push(`M ${fmt(s.x)} ${fmt(s.y)}`);
110
+ else if (s.op === "line") parts.push(`L ${fmt(s.x)} ${fmt(s.y)}`);
111
+ else if (s.op === "cubic") parts.push(`C ${fmt(s.x1)} ${fmt(s.y1)} ${fmt(s.x2)} ${fmt(s.y2)} ${fmt(s.x)} ${fmt(s.y)}`);
112
+ else parts.push("Z");
113
+ return parts.join(" ");
114
+ }
115
+ function imageHref(resourceName, laid) {
116
+ if (!resourceName) return void 0;
117
+ for (const [resourceId, res] of laid.imageResources) {
118
+ if (res.resourceName !== resourceName) continue;
119
+ const bytes = laid.resources.get(resourceId);
120
+ if (!bytes) return void 0;
121
+ return `data:${res.prepared.mimeType};base64,${toBase64(bytes)}`;
122
+ }
123
+ }
124
+ function toBase64(bytes) {
125
+ let bin = "";
126
+ for (const b of bytes) bin += String.fromCharCode(b);
127
+ return btoa(bin);
128
+ }
129
+ function escapeXml(s) {
130
+ return s.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;");
131
+ }
132
+ function fmt(n) {
133
+ const r = Math.round(n * 100) / 100;
134
+ return Object.is(r, -0) ? "0" : String(r);
135
+ }
136
+ //#endregion
137
+ export { svgWriter, writeSvg };
@@ -0,0 +1,16 @@
1
+ import { BodyElement, Section, SectionProperties } from '../core/document-model/index.js';
2
+ import { ColorResolver } from '../core/drawingml/colors.js';
3
+ import { ResourceId } from '../core/ir/index.js';
4
+ import { PoNode } from '../core/po-helpers.js';
5
+ export type ImageResolver = (relId: string) => ResourceId | undefined;
6
+ export interface ParseContext {
7
+ readonly resolveColor: ColorResolver;
8
+ readonly resolveImage?: ImageResolver;
9
+ }
10
+ export declare const DEFAULT_PARSE_CONTEXT: ParseContext;
11
+ export declare function parseDocument(documentXml: Uint8Array, ctx?: ParseContext): Array<BodyElement>;
12
+ export declare const EMPTY_SECTION: SectionProperties;
13
+ export declare function parseSection(documentXml: Uint8Array): SectionProperties;
14
+ export declare function parseSections(documentXml: Uint8Array): Array<Section>;
15
+ export declare function parseHeaderFooter(xml: Uint8Array, ctx?: ParseContext): Array<BodyElement>;
16
+ export declare function parseBodyElements(children: ReadonlyArray<PoNode>, ctx?: ParseContext): Array<BodyElement>;
@@ -1,13 +1,14 @@
1
- import { poAttr, poChildren, poFindByPath, poIntAttr, poIs, poText } from "./po-helpers.js";
2
- import { defaultColorResolver } from "../drawingml/colors.js";
3
- import { parseOMath } from "../math/omml-parser.js";
1
+ import { twipsToPt } from "../core/ir/units.js";
2
+ import { poAttr, poChildren, poFindByPath, poIntAttr, poIs, poText } from "../core/po-helpers.js";
3
+ import { defaultColorResolver } from "../core/drawingml/colors.js";
4
+ import { parseOMath } from "./omml-parser.js";
4
5
  import { expandMcChildren, parseDrawing } from "./drawing-parser.js";
5
6
  import { parseRunProperties } from "./run-properties.js";
6
7
  import { parseParagraphProperties } from "./paragraph-properties.js";
7
8
  import { poElementToFlat } from "./po-to-flat.js";
8
9
  import { parseTable } from "./table-parser.js";
9
10
  import { XMLParser } from "fast-xml-parser";
10
- //#region src/ooxml/wordproc/document-parser.ts
11
+ //#region src/word/document-parser.ts
11
12
  var decoder = new TextDecoder("utf-8");
12
13
  var parser = new XMLParser({
13
14
  ignoreAttributes: false,
@@ -26,11 +27,12 @@ var RUN_CONTAINER_TAGS = new Set([
26
27
  "w:ins",
27
28
  "w:moveTo"
28
29
  ]);
29
- function parseDocument(documentXml, resolveColor = defaultColorResolver) {
30
+ var DEFAULT_PARSE_CONTEXT = { resolveColor: defaultColorResolver };
31
+ function parseDocument(documentXml, ctx = DEFAULT_PARSE_CONTEXT) {
30
32
  const xml = decoder.decode(documentXml);
31
33
  const body = poFindByPath(parser.parse(xml), ["w:document", "w:body"]);
32
34
  if (!body) return [];
33
- return parseBodyElements(poChildren(body), resolveColor);
35
+ return parseBodyElements(poChildren(body), ctx);
34
36
  }
35
37
  var HF_TYPES = new Set([
36
38
  "default",
@@ -83,8 +85,8 @@ function parseSectPrNode(sectPr) {
83
85
  const h = poIntAttr(child, "h");
84
86
  const orientRaw = poAttr(child, "orient");
85
87
  if (w !== void 0 && h !== void 0) pageSize = {
86
- widthTwips: w,
87
- heightTwips: h,
88
+ width: twipsToPt(w),
89
+ height: twipsToPt(h),
88
90
  ...orientRaw === "portrait" || orientRaw === "landscape" ? { orientation: orientRaw } : {}
89
91
  };
90
92
  } else if (poIs(child, "w:pgMar")) {
@@ -95,12 +97,12 @@ function parseSectPrNode(sectPr) {
95
97
  const header = poIntAttr(child, "header");
96
98
  const footer = poIntAttr(child, "footer");
97
99
  margins = {
98
- topTwips: top ?? 1440,
99
- rightTwips: right ?? 1440,
100
- bottomTwips: bottom ?? 1440,
101
- leftTwips: left ?? 1440,
102
- ...header !== void 0 ? { headerTwips: header } : {},
103
- ...footer !== void 0 ? { footerTwips: footer } : {}
100
+ top: twipsToPt(top ?? 1440),
101
+ right: twipsToPt(right ?? 1440),
102
+ bottom: twipsToPt(bottom ?? 1440),
103
+ left: twipsToPt(left ?? 1440),
104
+ ...header !== void 0 ? { header: twipsToPt(header) } : {},
105
+ ...footer !== void 0 ? { footer: twipsToPt(footer) } : {}
104
106
  };
105
107
  } else if (poIs(child, "w:headerReference")) pushHeaderFooter(child, headers);
106
108
  else if (poIs(child, "w:footerReference")) pushHeaderFooter(child, footers);
@@ -126,26 +128,26 @@ function pushHeaderFooter(node, list) {
126
128
  relationshipId: rId
127
129
  });
128
130
  }
129
- function parseHeaderFooter(xml, resolveColor = defaultColorResolver) {
131
+ function parseHeaderFooter(xml, ctx = DEFAULT_PARSE_CONTEXT) {
130
132
  const root = parser.parse(decoder.decode(xml)).find((n) => poIs(n, "w:hdr") || poIs(n, "w:ftr"));
131
133
  if (!root) return [];
132
- return parseBodyElements(poChildren(root), resolveColor);
134
+ return parseBodyElements(poChildren(root), ctx);
133
135
  }
134
- function parseBodyElements(children, resolveColor = defaultColorResolver) {
136
+ function parseBodyElements(children, ctx = DEFAULT_PARSE_CONTEXT) {
135
137
  const out = [];
136
138
  for (const child of children) if (poIs(child, "w:p")) {
137
- const drawing = tryExtractDrawingFromParagraph(child, resolveColor);
139
+ const drawing = tryExtractDrawingFromParagraph(child, ctx);
138
140
  out.push(drawing ?? {
139
141
  kind: "paragraph",
140
- paragraph: parseParagraph(child)
142
+ paragraph: parseParagraph(child, ctx)
141
143
  });
142
144
  } else if (poIs(child, "w:tbl")) out.push({
143
145
  kind: "table",
144
- table: parseTable(child)
146
+ table: parseTable(child, ctx)
145
147
  });
146
148
  return out;
147
149
  }
148
- function tryExtractDrawingFromParagraph(p, resolveColor) {
150
+ function tryExtractDrawingFromParagraph(p, ctx) {
149
151
  let drawing;
150
152
  let hasText = false;
151
153
  for (const child of poChildren(p)) {
@@ -156,27 +158,30 @@ function tryExtractDrawingFromParagraph(p, resolveColor) {
156
158
  else if (poIs(runChild, "w:tab") || poIs(runChild, "w:br") || poIs(runChild, "w:noBreakHyphen")) hasText = true;
157
159
  }
158
160
  if (!drawing || hasText) return null;
159
- const parseBody = (children) => parseBodyElements(children, resolveColor);
160
- const content = parseDrawing(drawing, resolveColor, parseBody);
161
+ const parseBody = (children) => parseBodyElements(children, ctx);
162
+ const content = parseDrawing(drawing, ctx.resolveColor, parseBody);
161
163
  if (!content) return null;
162
164
  const pPrNode = poChildren(p).find((c) => poIs(c, "w:pPr"));
163
165
  const paragraphProperties = pPrNode ? parseParagraphProperties(poElementToFlat(pPrNode)) : {};
164
- if (content.kind === "image") return {
165
- kind: "image",
166
- image: {
167
- imageId: content.imageId,
168
- widthEmu: content.widthEmu,
169
- heightEmu: content.heightEmu,
170
- paragraphProperties,
171
- ...content.altText ? { altText: content.altText } : {}
172
- }
173
- };
166
+ if (content.kind === "image") {
167
+ const resource = ctx.resolveImage?.(content.imageId);
168
+ return {
169
+ kind: "image",
170
+ image: {
171
+ ...resource ? { resource } : {},
172
+ width: content.width,
173
+ height: content.height,
174
+ paragraphProperties,
175
+ ...content.altText ? { altText: content.altText } : {}
176
+ }
177
+ };
178
+ }
174
179
  if (content.kind === "chart") return {
175
180
  kind: "chart",
176
181
  chart: {
177
182
  chartRelId: content.chartRelId,
178
- widthEmu: content.widthEmu,
179
- heightEmu: content.heightEmu,
183
+ width: content.width,
184
+ height: content.height,
180
185
  paragraphProperties,
181
186
  ...content.altText ? { altText: content.altText } : {}
182
187
  }
@@ -190,7 +195,7 @@ function tryExtractDrawingFromParagraph(p, resolveColor) {
190
195
  }
191
196
  };
192
197
  }
193
- function parseParagraph(p) {
198
+ function parseParagraph(p, ctx) {
194
199
  const pPr = poChildren(p).find((c) => poIs(c, "w:pPr"));
195
200
  let properties = parseParagraphProperties(pPr ? poElementToFlat(pPr) : void 0);
196
201
  const mathPara = poChildren(p).find((c) => poIs(c, "m:oMathPara"));
@@ -204,17 +209,17 @@ function parseParagraph(p) {
204
209
  };
205
210
  }
206
211
  const runs = [];
207
- collectRuns(p, runs);
212
+ collectRuns(p, runs, ctx);
208
213
  return {
209
214
  properties,
210
215
  runs
211
216
  };
212
217
  }
213
- function collectRuns(container, out) {
218
+ function collectRuns(container, out, ctx) {
214
219
  for (const child of poChildren(container)) {
215
220
  if (poIs(child, "w:pPr")) continue;
216
221
  if (poIs(child, "w:r")) {
217
- out.push(parseRun(child));
222
+ out.push(parseRun(child, ctx));
218
223
  continue;
219
224
  }
220
225
  if (poIs(child, "m:oMath")) {
@@ -234,10 +239,10 @@ function collectRuns(container, out) {
234
239
  continue;
235
240
  }
236
241
  const tag = elementTag(child);
237
- if (tag && RUN_CONTAINER_TAGS.has(tag)) collectRuns(child, out);
242
+ if (tag && RUN_CONTAINER_TAGS.has(tag)) collectRuns(child, out, ctx);
238
243
  }
239
244
  }
240
- function parseRun(r) {
245
+ function parseRun(r, ctx) {
241
246
  const rPr = poChildren(r).find((c) => poIs(c, "w:rPr"));
242
247
  const properties = parseRunProperties(rPr ? poElementToFlat(rPr) : void 0);
243
248
  let text = "";
@@ -253,11 +258,14 @@ function parseRun(r) {
253
258
  else if (poIs(child, "w:softHyphen")) text += "­";
254
259
  else if (poIs(child, "w:drawing")) {
255
260
  const content = parseDrawing(child, defaultColorResolver);
256
- if (content && content.kind === "image") inlineImage = {
257
- imageId: content.imageId,
258
- widthEmu: content.widthEmu,
259
- heightEmu: content.heightEmu
260
- };
261
+ if (content && content.kind === "image") {
262
+ const resource = ctx.resolveImage?.(content.imageId);
263
+ inlineImage = {
264
+ ...resource ? { resource } : {},
265
+ width: content.width,
266
+ height: content.height
267
+ };
268
+ }
261
269
  }
262
270
  }
263
271
  return {
@@ -271,4 +279,4 @@ function elementTag(node) {
271
279
  for (const key of Object.keys(node)) if (key !== ":@" && key !== "#text") return key;
272
280
  }
273
281
  //#endregion
274
- export { EMPTY_SECTION, parseBodyElements, parseDocument, parseHeaderFooter, parseSections };
282
+ export { DEFAULT_PARSE_CONTEXT, EMPTY_SECTION, parseBodyElements, parseDocument, parseHeaderFooter, parseSections };
@@ -0,0 +1,4 @@
1
+ import { DocumentReader, ReadResult } from '../core/ir/adapters.js';
2
+ import { FlowDoc } from '../core/ir/flow.js';
3
+ export declare function readDocx(docx: Uint8Array): ReadResult<FlowDoc>;
4
+ export declare const docxReader: DocumentReader<FlowDoc>;