reamkit 1.30.0 → 1.31.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 (78) hide show
  1. package/README.md +60 -24
  2. package/dist/esm/core/converter/project.js +3 -1
  3. package/dist/esm/core/crypto/offcrypto.js +1 -1
  4. package/dist/esm/core/document-model/index.d.ts +1 -1
  5. package/dist/esm/core/document-model/types.d.ts +63 -0
  6. package/dist/esm/core/font/index.d.ts +2 -0
  7. package/dist/esm/core/font/ttf-build.d.ts +113 -0
  8. package/dist/esm/core/font/ttf-build.js +1224 -0
  9. package/dist/esm/core/font/ttf-subset.d.ts +19 -0
  10. package/dist/esm/core/font/ttf-subset.js +14 -1
  11. package/dist/esm/core/fonts/provider.d.ts +17 -0
  12. package/dist/esm/core/fonts/provider.js +27 -2
  13. package/dist/esm/core/fonts/remote-fonts.js +8 -1
  14. package/dist/esm/core/ir/flow.d.ts +71 -1
  15. package/dist/esm/core/numbering/index.d.ts +1 -1
  16. package/dist/esm/core/numbering/state.d.ts +11 -1
  17. package/dist/esm/core/numbering/state.js +10 -1
  18. package/dist/esm/core/style-cascade/resolver.js +35 -4
  19. package/dist/esm/core/style-cascade/types.d.ts +19 -1
  20. package/dist/esm/core/style-cascade/types.js +3 -0
  21. package/dist/esm/index.d.ts +2 -2
  22. package/dist/esm/layout/page-doc.d.ts +10 -3
  23. package/dist/esm/layout/styled-layout.d.ts +48 -7
  24. package/dist/esm/layout/styled-layout.js +881 -119
  25. package/dist/esm/layout/turned-section.d.ts +38 -0
  26. package/dist/esm/layout/turned-section.js +193 -0
  27. package/dist/esm/pdf/styled-page-emitter.js +78 -2
  28. package/dist/esm/pdf-reader/cff-outline.d.ts +27 -0
  29. package/dist/esm/pdf-reader/cff-outline.js +169 -21
  30. package/dist/esm/pdf-reader/content.d.ts +53 -0
  31. package/dist/esm/pdf-reader/content.js +9 -1
  32. package/dist/esm/pdf-reader/display.d.ts +36 -0
  33. package/dist/esm/pdf-reader/display.js +66 -1
  34. package/dist/esm/pdf-reader/document.js +5 -1
  35. package/dist/esm/pdf-reader/embedded-fonts.d.ts +2 -1
  36. package/dist/esm/pdf-reader/embedded-fonts.js +32 -2
  37. package/dist/esm/pdf-reader/encodings.d.ts +8 -0
  38. package/dist/esm/pdf-reader/encodings.js +25 -3
  39. package/dist/esm/pdf-reader/face-outlines.d.ts +78 -0
  40. package/dist/esm/pdf-reader/face-outlines.js +362 -0
  41. package/dist/esm/pdf-reader/figures.d.ts +52 -0
  42. package/dist/esm/pdf-reader/figures.js +433 -0
  43. package/dist/esm/pdf-reader/flow-build.d.ts +131 -5
  44. package/dist/esm/pdf-reader/flow-build.js +345 -26
  45. package/dist/esm/pdf-reader/font.js +321 -36
  46. package/dist/esm/pdf-reader/glyf-outline.d.ts +33 -0
  47. package/dist/esm/pdf-reader/glyf-outline.js +135 -1
  48. package/dist/esm/pdf-reader/glyph-names.js +154 -1
  49. package/dist/esm/pdf-reader/layout.d.ts +93 -0
  50. package/dist/esm/pdf-reader/layout.js +1703 -214
  51. package/dist/esm/pdf-reader/page-numbers.d.ts +53 -0
  52. package/dist/esm/pdf-reader/page-numbers.js +167 -0
  53. package/dist/esm/pdf-reader/tagged.js +182 -23
  54. package/dist/esm/pdf-reader/text.d.ts +6 -3
  55. package/dist/esm/pdf-reader/text.js +98 -9
  56. package/dist/esm/pdf-reader/type1-outline.d.ts +11 -0
  57. package/dist/esm/pdf-reader/type1-outline.js +63 -8
  58. package/dist/esm/pdf-reader/vector.js +71 -1
  59. package/dist/esm/word/doc/doc-reader.js +6 -2
  60. package/dist/esm/word/doc/doc-text.d.ts +6 -0
  61. package/dist/esm/word/doc/doc-text.js +19 -1
  62. package/dist/esm/word/document-parser.d.ts +2 -2
  63. package/dist/esm/word/document-parser.js +11 -1
  64. package/dist/esm/word/docx-reader.js +5 -3
  65. package/dist/esm/word/docx-writer.js +207 -21
  66. package/dist/esm/word/drawing-parser.d.ts +5 -3
  67. package/dist/esm/word/drawing-parser.js +49 -8
  68. package/dist/esm/word/font-embed.d.ts +30 -0
  69. package/dist/esm/word/font-embed.js +173 -0
  70. package/dist/esm/word/font-table.d.ts +10 -0
  71. package/dist/esm/word/font-table.js +13 -1
  72. package/dist/esm/word/index.js +1 -1
  73. package/dist/esm/word/numbering-parser.d.ts +3 -1
  74. package/dist/esm/word/numbering-parser.js +2 -1
  75. package/dist/esm/word/paragraph-properties.d.ts +7 -6
  76. package/dist/esm/word/paragraph-properties.js +14 -2
  77. package/dist/esm/word/run-properties.js +26 -0
  78. package/package.json +8 -3
@@ -0,0 +1,173 @@
1
+ import { buildTrueType, editableEmbedding } from "../core/font/ttf-build.js";
2
+ import { FEATURES } from "../core/ir/features.js";
3
+ import { obfuscateEmbeddedFont } from "./font-table.js";
4
+ import { md5 } from "../core/crypto/primitives.js";
5
+ //#region src/word/font-embed.ts
6
+ /** §17.8.1 — the content type of an obfuscated embedded font. */
7
+ var OBFUSCATED_FONT_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.obfuscatedFont";
8
+ var REL_FONT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/font";
9
+ /** §17.8.3 — the four faces a family may embed, in the order CT_Font lists them. */
10
+ var SLOTS = [
11
+ "Regular",
12
+ "Bold",
13
+ "Italic",
14
+ "BoldItalic"
15
+ ];
16
+ /**
17
+ * Build the embedded fonts for the faces the runs name (§17.8.1).
18
+ *
19
+ * The faces are gathered by family and by slot — the style each face IS. Two
20
+ * faces in one slot (a SemiBold and a Bold, both written bold) become one font:
21
+ * the face with the most characters, and the other's characters it lacks.
22
+ *
23
+ * A face its licence keeps out is reported, not written.
24
+ *
25
+ * @param used The run font names the document's runs carry.
26
+ * @param outlines Run font name → the face's outlines.
27
+ * @param families Run font name → the family a word processor knows it by.
28
+ * @param losses Appended to for every face left out.
29
+ * @returns The fonts to write and the font table's references to them.
30
+ */
31
+ function embedFaces(used, outlines, families, losses) {
32
+ const bySlot = /* @__PURE__ */ new Map();
33
+ for (const name of new Set(used)) {
34
+ const face = outlines.get(name);
35
+ const family = families.get(name)?.family;
36
+ if (!face || family === void 0) continue;
37
+ if (!editableEmbedding(face.fsType)) {
38
+ losses.push({
39
+ severity: "degraded",
40
+ feature: FEATURES.fontsEmbedding,
41
+ detail: `font ${face.postScriptName} not embedded: its licence (OS/2 fsType ${face.fsType}) does not allow it in an editable document`
42
+ });
43
+ continue;
44
+ }
45
+ const slot = face.bold ? face.italic ? "BoldItalic" : "Bold" : face.italic ? "Italic" : "Regular";
46
+ let slots = bySlot.get(family);
47
+ if (!slots) bySlot.set(family, slots = /* @__PURE__ */ new Map());
48
+ slots.set(slot, [...slots.get(slot) ?? [], face]);
49
+ }
50
+ const elements = /* @__PURE__ */ new Map();
51
+ const parts = [];
52
+ const relationships = [];
53
+ for (const family of [...bySlot.keys()].sort()) {
54
+ const slots = bySlot.get(family);
55
+ for (const slot of SLOTS) {
56
+ const faces = [...slots.get(slot) ?? []].sort((a, b) => b.glyphs.size - a.glyphs.size);
57
+ const first = faces[0];
58
+ if (!first) continue;
59
+ const glyphs = new Map(first.glyphs);
60
+ const kerning = new Map(first.kerning);
61
+ const ligatures = new Map(first.ligatures);
62
+ for (const other of faces.slice(1)) {
63
+ for (const [char, glyph] of other.glyphs) if (!glyphs.has(char)) glyphs.set(char, glyph);
64
+ for (const [pair, value] of other.kerning ?? []) if (!kerning.has(pair)) kerning.set(pair, value);
65
+ for (const [letters, glyph] of other.ligatures ?? []) if (!ligatures.has(letters)) ligatures.set(letters, glyph);
66
+ }
67
+ const built = builtGlyphs(glyphs);
68
+ if (built.length + ligatures.size > 8e3) {
69
+ losses.push({
70
+ severity: "degraded",
71
+ feature: FEATURES.fontsEmbedding,
72
+ detail: `font ${first.postScriptName} not embedded: ${built.length + ligatures.size} glyphs is more than an embedded subset holds`
73
+ });
74
+ continue;
75
+ }
76
+ const program = buildTrueType({
77
+ family,
78
+ bold: slot === "Bold" || slot === "BoldItalic",
79
+ italic: slot === "Italic" || slot === "BoldItalic",
80
+ postScriptName: first.postScriptName,
81
+ glyphs: built,
82
+ ascent: first.ascent,
83
+ descent: first.descent,
84
+ ...first.capHeight !== void 0 ? { capHeight: first.capHeight } : {},
85
+ ...first.xHeight !== void 0 ? { xHeight: first.xHeight } : {},
86
+ italicAngle: first.italicAngle,
87
+ fixedPitch: first.fixedPitch,
88
+ fsType: statedFsType(first.fsType),
89
+ kerning: kernPairs(kerning),
90
+ ligatures: [...ligatures].map(([letters, glyph]) => ({
91
+ codePoints: [...letters].map((c) => c.codePointAt(0)),
92
+ outline: glyph.outline,
93
+ advance: glyph.advance
94
+ }))
95
+ });
96
+ const fontKey = fontKeyOf(program);
97
+ const index = parts.length + 1;
98
+ const target = `fonts/font${index}.odttf`;
99
+ const id = `rId${index}`;
100
+ parts.push({
101
+ path: `word/${target}`,
102
+ data: obfuscateEmbeddedFont(program, fontKey),
103
+ contentType: OBFUSCATED_FONT_CONTENT_TYPE
104
+ });
105
+ relationships.push({
106
+ id,
107
+ type: REL_FONT,
108
+ target,
109
+ targetMode: "Internal"
110
+ });
111
+ elements.set(family, `${elements.get(family) ?? ""}<w:embed${slot} r:id="${id}" w:fontKey="${fontKey}" w:subsetted="1"/>`);
112
+ }
113
+ }
114
+ return {
115
+ elements,
116
+ parts,
117
+ relationships
118
+ };
119
+ }
120
+ /**
121
+ * A face's characters as the glyphs of a font: characters that share one glyph
122
+ * (the space and the no-break space) select the same one, and the glyphs stand
123
+ * in the order of their first character.
124
+ */
125
+ function builtGlyphs(glyphs) {
126
+ const byGlyph = /* @__PURE__ */ new Map();
127
+ for (const [char, glyph] of glyphs) {
128
+ const cp = char.codePointAt(0);
129
+ if (cp === void 0) continue;
130
+ byGlyph.set(glyph, [...byGlyph.get(glyph) ?? [], cp]);
131
+ }
132
+ return [...byGlyph].map(([glyph, codePoints]) => ({
133
+ codePoints: codePoints.sort((a, b) => a - b),
134
+ outline: glyph.outline,
135
+ advance: glyph.advance
136
+ })).sort((a, b) => a.codePoints[0] - b.codePoints[0]);
137
+ }
138
+ /** The face's kerning pairs as the font states them: by code point, left then right. */
139
+ function kernPairs(kerning) {
140
+ const out = [];
141
+ for (const [pair, value] of kerning) {
142
+ const [left, right] = [...pair].map((c) => c.codePointAt(0));
143
+ if (left !== void 0 && right !== void 0) out.push({
144
+ left,
145
+ right,
146
+ value
147
+ });
148
+ }
149
+ return out;
150
+ }
151
+ /**
152
+ * The `fsType` the built font states: the program's own, less the bits the
153
+ * format reserves; Editable where the program stated none — which is the use
154
+ * the font is put to here, and no more than that.
155
+ */
156
+ function statedFsType(fsType) {
157
+ if (fsType === void 0) return EDITABLE_EMBEDDING;
158
+ return fsType & DEFINED_FS_TYPE_BITS;
159
+ }
160
+ /** OS/2 `fsType` — Editable embedding, and every bit the format defines. */
161
+ var EDITABLE_EMBEDDING = 8;
162
+ var DEFINED_FS_TYPE_BITS = 782;
163
+ /**
164
+ * §17.8.1 — the GUID a font is obfuscated with, drawn from the font's own bytes
165
+ * so the same document always writes the same package.
166
+ */
167
+ function fontKeyOf(program) {
168
+ const hex = [...md5(program)].map((b) => b.toString(16).padStart(2, "0").toUpperCase());
169
+ const group = (from, to) => hex.slice(from, to).join("");
170
+ return `{${group(0, 4)}-${group(4, 6)}-${group(6, 8)}-${group(8, 10)}-${group(10, 16)}}`;
171
+ }
172
+ //#endregion
173
+ export { OBFUSCATED_FONT_CONTENT_TYPE, embedFaces };
@@ -18,6 +18,16 @@ interface FontTableEntry {
18
18
  * @returns The de-obfuscated bytes, or `data` unchanged when `fontKey` is not a GUID.
19
19
  */
20
20
  export declare function deobfuscateEmbeddedFont(data: Uint8Array, fontKey: string): Uint8Array;
21
+ /**
22
+ * §17.8.1 — obfuscate a font for embedding. The obfuscation is an XOR of the
23
+ * first 32 bytes with the `fontKey` GUID's bytes in reverse order, so it is its
24
+ * own inverse: this is {@link deobfuscateEmbeddedFont} run on a plain font.
25
+ *
26
+ * @param data The plain sfnt bytes.
27
+ * @param fontKey The GUID the font table states as its `w:fontKey`.
28
+ * @returns The bytes to store as the `.odttf` part.
29
+ */
30
+ export declare function obfuscateEmbeddedFont(data: Uint8Array, fontKey: string): Uint8Array;
21
31
  /**
22
32
  * Parse `word/fontTable.xml` for its embedded-font references (§17.8). Returns
23
33
  * one `FontTableEntry` per `w:font` that carries at least one `w:embed*` child,
@@ -28,6 +28,18 @@ function deobfuscateEmbeddedFont(data, fontKey) {
28
28
  return out;
29
29
  }
30
30
  /**
31
+ * §17.8.1 — obfuscate a font for embedding. The obfuscation is an XOR of the
32
+ * first 32 bytes with the `fontKey` GUID's bytes in reverse order, so it is its
33
+ * own inverse: this is {@link deobfuscateEmbeddedFont} run on a plain font.
34
+ *
35
+ * @param data The plain sfnt bytes.
36
+ * @param fontKey The GUID the font table states as its `w:fontKey`.
37
+ * @returns The bytes to store as the `.odttf` part.
38
+ */
39
+ function obfuscateEmbeddedFont(data, fontKey) {
40
+ return deobfuscateEmbeddedFont(data, fontKey);
41
+ }
42
+ /**
31
43
  * Parse `word/fontTable.xml` for its embedded-font references (§17.8). Returns
32
44
  * one `FontTableEntry` per `w:font` that carries at least one `w:embed*` child,
33
45
  * each naming the relationship id + `w:fontKey` for a Regular/Bold/Italic/
@@ -103,4 +115,4 @@ function loadEmbeddedFonts(pkg) {
103
115
  return out;
104
116
  }
105
117
  //#endregion
106
- export { deobfuscateEmbeddedFont, loadEmbeddedFonts, parseFontTable };
118
+ export { deobfuscateEmbeddedFont, loadEmbeddedFonts, obfuscateEmbeddedFont, parseFontTable };
@@ -1,9 +1,9 @@
1
1
  import "./run-properties.js";
2
2
  import "./paragraph-properties.js";
3
3
  import "./table-parser.js";
4
+ import "./numbering-parser.js";
4
5
  import "./document-parser.js";
5
6
  import "./text-extractor.js";
6
7
  import "./styles-parser.js";
7
8
  import "./font-table.js";
8
- import "./numbering-parser.js";
9
9
  import "./settings-parser.js";
@@ -1,6 +1,8 @@
1
- import { Numbering } from '../core/document-model/index.js';
1
+ import { Numbering, NumberingFormat } from '../core/document-model/index.js';
2
2
  import { ResourceId } from '../core/ir/index.js';
3
3
  import { ThemeFonts } from '../core/drawingml/theme-parser.js';
4
+ /** §17.18.59 ST_NumberFormat — the formats this reader knows by name. */
5
+ export declare const FORMATS: ReadonlySet<NumberingFormat>;
4
6
  /** The empty {@link Numbering} returned when a document has no `numbering.xml`. */
5
7
  export declare const EMPTY_NUMBERING: Numbering;
6
8
  /**
@@ -14,6 +14,7 @@ var parser = new XMLParser({
14
14
  parseTagValue: false,
15
15
  trimValues: false
16
16
  });
17
+ /** §17.18.59 ST_NumberFormat — the formats this reader knows by name. */
17
18
  var FORMATS = new Set([
18
19
  "decimal",
19
20
  "decimalZero",
@@ -184,4 +185,4 @@ function getValVal(node) {
184
185
  return typeof v === "string" ? v : void 0;
185
186
  }
186
187
  //#endregion
187
- export { EMPTY_NUMBERING, parseNumbering };
188
+ export { EMPTY_NUMBERING, FORMATS, parseNumbering };
@@ -1,10 +1,11 @@
1
1
  import { ParagraphProperties } from '../core/document-model/index.js';
2
2
  import { ThemeFonts } from '../core/drawingml/theme-parser.js';
3
3
  /**
4
- * §17.3.1.1/§17.3.1.3 — the gap `w:*Autospacing` asks the consumer for. Word's
5
- * own automatic value is HTML's 14pt, and only a document old enough to state
6
- * no `w:compatSetting compatibilityMode` still gets it: from Word 2007 on the
7
- * automatic value is nothing at all, which is what both references leave.
4
+ * §17.3.1.1/§17.3.1.3 — the gap `w:*Autospacing` asks the consumer for:
5
+ * HTML's 14pt, in every compatibility mode. Word for Mac stands two such
6
+ * paragraphs 14.02pt apart in modes 14, 15 and none alike; LibreOffice leaves
7
+ * nothing for a document that states a mode, which is where the earlier
8
+ * reading of "nothing from Word 2007 on" came from.
8
9
  */
9
10
  export declare const HTML_AUTO_SPACING_PT = 14;
10
11
  /**
@@ -16,8 +17,8 @@ export declare const HTML_AUTO_SPACING_PT = 14;
16
17
  * @param pPr The `w:pPr` element in flat (fast-xml-parser) shape, or anything
17
18
  * non-element (yielding an empty result).
18
19
  * @param autoSpacingPt What `w:beforeAutospacing`/`w:afterAutospacing` resolve
19
- * to — {@link HTML_AUTO_SPACING_PT} for a document that states no
20
- * compatibility mode, and 0 (the default) for every Word 2007-or-later one.
20
+ * to — {@link HTML_AUTO_SPACING_PT} for a Word document, 0 (the default)
21
+ * where the caller has no automatic spacing to give.
21
22
  * @returns The extracted properties; an empty object when `pPr` is absent.
22
23
  */
23
24
  export declare function parseParagraphProperties(pPr: unknown, autoSpacingPt?: number, themeFonts?: ThemeFonts): ParagraphProperties;
@@ -100,8 +100,8 @@ function parseFramePr(node) {
100
100
  * @param pPr The `w:pPr` element in flat (fast-xml-parser) shape, or anything
101
101
  * non-element (yielding an empty result).
102
102
  * @param autoSpacingPt What `w:beforeAutospacing`/`w:afterAutospacing` resolve
103
- * to — {@link HTML_AUTO_SPACING_PT} for a document that states no
104
- * compatibility mode, and 0 (the default) for every Word 2007-or-later one.
103
+ * to — {@link HTML_AUTO_SPACING_PT} for a Word document, 0 (the default)
104
+ * where the caller has no automatic spacing to give.
105
105
  * @returns The extracted properties; an empty object when `pPr` is absent.
106
106
  */
107
107
  function parseParagraphProperties(pPr, autoSpacingPt = 0, themeFonts) {
@@ -172,6 +172,18 @@ function parseParagraphProperties(pPr, autoSpacingPt = 0, themeFonts) {
172
172
  const v = parseToggle(el["w:pageBreakBefore"]);
173
173
  if (v !== void 0) out.pageBreakBefore = v;
174
174
  }
175
+ if ("w:keepNext" in el) {
176
+ const v = parseToggle(el["w:keepNext"]);
177
+ if (v !== void 0) out.keepNext = v;
178
+ }
179
+ if ("w:keepLines" in el) {
180
+ const v = parseToggle(el["w:keepLines"]);
181
+ if (v !== void 0) out.keepLines = v;
182
+ }
183
+ if ("w:widowControl" in el) {
184
+ const v = parseToggle(el["w:widowControl"]);
185
+ if (v !== void 0) out.widowControl = v;
186
+ }
175
187
  if ("w:bidi" in el) {
176
188
  const v = parseToggle(el["w:bidi"]);
177
189
  if (v !== void 0) out.bidi = v;
@@ -20,6 +20,24 @@ var VERTICAL_ALIGNS = new Set([
20
20
  "superscript",
21
21
  "subscript"
22
22
  ]);
23
+ var LIGATURES = new Set([
24
+ "none",
25
+ "standard",
26
+ "contextual",
27
+ "historical",
28
+ "discretional",
29
+ "standardContextual",
30
+ "standardHistorical",
31
+ "contextualHistorical",
32
+ "standardDiscretional",
33
+ "contextualDiscretional",
34
+ "historicalDiscretional",
35
+ "standardContextualHistorical",
36
+ "standardContextualDiscretional",
37
+ "standardHistoricalDiscretional",
38
+ "contextualHistoricalDiscretional",
39
+ "all"
40
+ ]);
23
41
  var HIGHLIGHT_COLORS = new Map([
24
42
  ["black", "000000"],
25
43
  ["blue", "0000FF"],
@@ -110,6 +128,14 @@ function parseRunProperties(rPr, themeFonts) {
110
128
  const n = v === void 0 ? NaN : Number(v);
111
129
  if (Number.isFinite(n) && n !== 0) out.letterSpacingPt = twipsToPt(n);
112
130
  }
131
+ if ("w:kern" in el) {
132
+ const n = Number(getVal(el["w:kern"]));
133
+ if (Number.isFinite(n) && n >= 0) out.kerningMinPt = halfPtToPt(n);
134
+ }
135
+ if ("w14:ligatures" in el) {
136
+ const v = asElement(el["w14:ligatures"])?.["@_w14:val"];
137
+ if (typeof v === "string" && LIGATURES.has(v)) out.ligatures = v;
138
+ }
113
139
  if ("w:shd" in el) {
114
140
  const shd = el["w:shd"];
115
141
  const hex = shadingFillHex(getVal(shd), getAttr(shd, "color"), getAttr(shd, "fill"));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reamkit",
3
- "version": "1.30.0",
4
- "description": "Ream — convert DOCX, XLSX, PPTX and PDF to PDF, SVG, HTML, DOCX and XLSX, built from scratch on the ECMA-376 and ISO 32000 specifications. Parse once, convert anywhere.",
3
+ "version": "1.31.0",
4
+ "description": "Ream — convert DOCX, XLSX, PPTX, PDF and legacy DOC, XLS and PPT to PDF, SVG, HTML, Markdown, DOCX and XLSX, built from scratch on the ECMA-376 and ISO 32000 specifications. Parse once, convert anywhere.",
5
5
  "license": "MIT",
6
6
  "author": "Alex Krassavin <info@reamkit.dev>",
7
7
  "repository": {
@@ -48,7 +48,12 @@
48
48
  "word",
49
49
  "excel",
50
50
  "powerpoint",
51
- "converter"
51
+ "converter",
52
+ "doc",
53
+ "xls",
54
+ "ppt",
55
+ "markdown",
56
+ "pdf-to-docx"
52
57
  ],
53
58
  "scripts": {
54
59
  "build": "vite build",