rtf-codec 2.1.0 → 3.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.
@@ -15,13 +15,15 @@ declare const RtfDiagnosticCodes: {
15
15
  readonly UNSUPPORTED_CODEPAGE: "rtf/unsupported-codepage";
16
16
  readonly UNSUPPORTED_PICTURE_FORMAT: "rtf/unsupported-picture-format";
17
17
  readonly PICTURE_SIZE_UNSTATED: "rtf/picture-size-unstated";
18
+ readonly EMBEDDED_OBJECT_UNREADABLE: "rtf/embedded-object-unreadable";
18
19
  readonly TABLE_ROW_WITHOUT_DEFINITION: "rtf/table-row-without-definition";
19
20
  readonly TABLE_COLUMN_WIDTH_INVALID: "rtf/table-column-width-invalid";
20
21
  readonly NESTED_TABLE_FLATTENED: "rtf/nested-table-flattened";
21
22
  readonly SECTION_BREAK_UNREPRESENTED: "rtf/section-break-unrepresented";
22
23
  readonly BOOKMARK_UNPAIRED: "rtf/bookmark-unpaired";
24
+ readonly FORM_FIELD_SPAN_DROPPED: "rtf/form-field-span-dropped";
25
+ readonly FORM_FIELD_KEYWORD_LOST: "rtf/form-field-keyword-lost";
23
26
  readonly CONSTRUCT_UNREPRESENTED: "rtf/construct-unrepresented";
24
- readonly EMBEDDED_OBJECT_DROPPED: "rtf/embedded-object-dropped";
25
27
  readonly PACKAGE_TABLE_DROPPED: "rtf/package-table-dropped";
26
28
  };
27
29
  declare class RtfParseError extends Error {
@@ -8,13 +8,15 @@ const RtfDiagnosticCodes = {
8
8
  UNSUPPORTED_CODEPAGE: "rtf/unsupported-codepage",
9
9
  UNSUPPORTED_PICTURE_FORMAT: "rtf/unsupported-picture-format",
10
10
  PICTURE_SIZE_UNSTATED: "rtf/picture-size-unstated",
11
+ EMBEDDED_OBJECT_UNREADABLE: "rtf/embedded-object-unreadable",
11
12
  TABLE_ROW_WITHOUT_DEFINITION: "rtf/table-row-without-definition",
12
13
  TABLE_COLUMN_WIDTH_INVALID: "rtf/table-column-width-invalid",
13
14
  NESTED_TABLE_FLATTENED: "rtf/nested-table-flattened",
14
15
  SECTION_BREAK_UNREPRESENTED: "rtf/section-break-unrepresented",
15
16
  BOOKMARK_UNPAIRED: "rtf/bookmark-unpaired",
17
+ FORM_FIELD_SPAN_DROPPED: "rtf/form-field-span-dropped",
18
+ FORM_FIELD_KEYWORD_LOST: "rtf/form-field-keyword-lost",
16
19
  CONSTRUCT_UNREPRESENTED: "rtf/construct-unrepresented",
17
- EMBEDDED_OBJECT_DROPPED: "rtf/embedded-object-dropped",
18
20
  PACKAGE_TABLE_DROPPED: "rtf/package-table-dropped"
19
21
  };
20
22
  var RtfParseError = class extends Error {
@@ -1,2 +1,2 @@
1
- import { a as RtfDiagnosticSink, c as RtfNotAnRtfDocumentError, d as RtfWriteError, i as RtfDiagnosticSeverity, l as RtfParseError, n as RtfDiagnostic, o as RtfInputTooLargeError, r as RtfDiagnosticCodes, s as RtfNestingLimitExceededError, t as NOOP_RTF_DIAGNOSTIC_SINK, u as RtfUnsupportedDocumentKindError } from "./diagnostics-BgG_KAiN.cjs";
1
+ import { a as RtfDiagnosticSink, c as RtfNotAnRtfDocumentError, d as RtfWriteError, i as RtfDiagnosticSeverity, l as RtfParseError, n as RtfDiagnostic, o as RtfInputTooLargeError, r as RtfDiagnosticCodes, s as RtfNestingLimitExceededError, t as NOOP_RTF_DIAGNOSTIC_SINK, u as RtfUnsupportedDocumentKindError } from "./diagnostics-CjMoO7x1.cjs";
2
2
  export { NOOP_RTF_DIAGNOSTIC_SINK, RtfDiagnostic, RtfDiagnosticCodes, RtfDiagnosticSeverity, RtfDiagnosticSink, RtfInputTooLargeError, RtfNestingLimitExceededError, RtfNotAnRtfDocumentError, RtfParseError, RtfUnsupportedDocumentKindError, RtfWriteError };
@@ -1,2 +1,2 @@
1
- import { a as RtfDiagnosticSink, c as RtfNotAnRtfDocumentError, d as RtfWriteError, i as RtfDiagnosticSeverity, l as RtfParseError, n as RtfDiagnostic, o as RtfInputTooLargeError, r as RtfDiagnosticCodes, s as RtfNestingLimitExceededError, t as NOOP_RTF_DIAGNOSTIC_SINK, u as RtfUnsupportedDocumentKindError } from "./diagnostics-BgG_KAiN.js";
1
+ import { a as RtfDiagnosticSink, c as RtfNotAnRtfDocumentError, d as RtfWriteError, i as RtfDiagnosticSeverity, l as RtfParseError, n as RtfDiagnostic, o as RtfInputTooLargeError, r as RtfDiagnosticCodes, s as RtfNestingLimitExceededError, t as NOOP_RTF_DIAGNOSTIC_SINK, u as RtfUnsupportedDocumentKindError } from "./diagnostics-CjMoO7x1.js";
2
2
  export { NOOP_RTF_DIAGNOSTIC_SINK, RtfDiagnostic, RtfDiagnosticCodes, RtfDiagnosticSeverity, RtfDiagnosticSink, RtfInputTooLargeError, RtfNestingLimitExceededError, RtfNotAnRtfDocumentError, RtfParseError, RtfUnsupportedDocumentKindError, RtfWriteError };
@@ -7,13 +7,15 @@ const RtfDiagnosticCodes = {
7
7
  UNSUPPORTED_CODEPAGE: "rtf/unsupported-codepage",
8
8
  UNSUPPORTED_PICTURE_FORMAT: "rtf/unsupported-picture-format",
9
9
  PICTURE_SIZE_UNSTATED: "rtf/picture-size-unstated",
10
+ EMBEDDED_OBJECT_UNREADABLE: "rtf/embedded-object-unreadable",
10
11
  TABLE_ROW_WITHOUT_DEFINITION: "rtf/table-row-without-definition",
11
12
  TABLE_COLUMN_WIDTH_INVALID: "rtf/table-column-width-invalid",
12
13
  NESTED_TABLE_FLATTENED: "rtf/nested-table-flattened",
13
14
  SECTION_BREAK_UNREPRESENTED: "rtf/section-break-unrepresented",
14
15
  BOOKMARK_UNPAIRED: "rtf/bookmark-unpaired",
16
+ FORM_FIELD_SPAN_DROPPED: "rtf/form-field-span-dropped",
17
+ FORM_FIELD_KEYWORD_LOST: "rtf/form-field-keyword-lost",
15
18
  CONSTRUCT_UNREPRESENTED: "rtf/construct-unrepresented",
16
- EMBEDDED_OBJECT_DROPPED: "rtf/embedded-object-dropped",
17
19
  PACKAGE_TABLE_DROPPED: "rtf/package-table-dropped"
18
20
  };
19
21
  var RtfParseError = class extends Error {
@@ -0,0 +1,215 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let document_schema_js = require("document-schema.js");
3
+ let archive_codec = require("archive-codec");
4
+ //#region src/embedded-object.ts
5
+ const PACKAGE_LABEL = "rtf-codec-embedded-object.json";
6
+ const OBJECT_HEADER_FORMAT_ID_EMBEDDED = 2;
7
+ const OBJECT_HEADER_FORMAT_ID_LINKED = 1;
8
+ const OBJECT_HEADER_OLE_VERSION = 1281;
9
+ const OBJECT_HEADER_CLASS_NAME = "Package";
10
+ const ANSI_DECODER = new TextDecoder("windows-1252");
11
+ const PRESENTATION_OBJECT_HEADER_FORMAT_ID = 5;
12
+ const PRESENTATION_CLASS_NAME = "";
13
+ const CLIPBOARD_FORMAT_CF_DIB = 8;
14
+ const DIB_HEADER_SIZE_BITMAPINFOHEADER = 40;
15
+ const DIB_BIT_COUNT_MONOCHROME = 1;
16
+ function writeLengthPrefixedAnsiString(value) {
17
+ if (value.length === 0) return /* @__PURE__ */ new Uint8Array(4);
18
+ for (let index = 0; index < value.length; index++) {
19
+ const code = value.charCodeAt(index);
20
+ if (code > 127) throw new Error(`ObjectHeader string contains a character (U+${code.toString(16).padStart(4, "0")}) outside ASCII; encoding it to an arbitrary windows-1252 byte would need a full codepage table this module does not carry`);
21
+ }
22
+ const length = value.length + 1;
23
+ const out = new Uint8Array(4 + length);
24
+ new DataView(out.buffer).setUint32(0, length, true);
25
+ for (let index = 0; index < value.length; index++) out[4 + index] = value.charCodeAt(index);
26
+ return out;
27
+ }
28
+ function readLengthPrefixedAnsiString(bytes, offset, fieldName) {
29
+ if (offset + 4 > bytes.length) throw new Error(`ObjectHeader ends before its ${fieldName} length field`);
30
+ const length = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(offset, true);
31
+ offset += 4;
32
+ if (length === 0) return {
33
+ value: "",
34
+ next: offset
35
+ };
36
+ if (offset + length > bytes.length) throw new Error(`ObjectHeader's ${fieldName} declares ${length} bytes but only ${bytes.length - offset} remain`);
37
+ return {
38
+ value: ANSI_DECODER.decode(bytes.subarray(offset, offset + length - 1)),
39
+ next: offset + length
40
+ };
41
+ }
42
+ function writeObjectHeader() {
43
+ const classNameBytes = writeLengthPrefixedAnsiString(OBJECT_HEADER_CLASS_NAME);
44
+ const topicNameBytes = writeLengthPrefixedAnsiString("");
45
+ const itemNameBytes = writeLengthPrefixedAnsiString("");
46
+ const out = new Uint8Array(8 + classNameBytes.length + topicNameBytes.length + itemNameBytes.length);
47
+ const view = new DataView(out.buffer);
48
+ view.setUint32(0, OBJECT_HEADER_OLE_VERSION, true);
49
+ view.setUint32(4, OBJECT_HEADER_FORMAT_ID_EMBEDDED, true);
50
+ let offset = 8;
51
+ out.set(classNameBytes, offset);
52
+ offset += classNameBytes.length;
53
+ out.set(topicNameBytes, offset);
54
+ offset += topicNameBytes.length;
55
+ out.set(itemNameBytes, offset);
56
+ return out;
57
+ }
58
+ function readObjectHeader(bytes) {
59
+ if (bytes.length < 8) throw new Error("ObjectHeader ends before its FormatID field");
60
+ const formatId = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(4, true);
61
+ let offset = 8;
62
+ offset = readLengthPrefixedAnsiString(bytes, offset, "ClassName").next;
63
+ offset = readLengthPrefixedAnsiString(bytes, offset, "TopicName").next;
64
+ offset = readLengthPrefixedAnsiString(bytes, offset, "ItemName").next;
65
+ return {
66
+ formatId,
67
+ next: offset
68
+ };
69
+ }
70
+ function writeMinimalDib() {
71
+ const width = 1;
72
+ const height = 1;
73
+ const colorCount = 2;
74
+ const out = new Uint8Array(48 + 4 * Math.abs(height));
75
+ const view = new DataView(out.buffer);
76
+ view.setUint32(0, DIB_HEADER_SIZE_BITMAPINFOHEADER, true);
77
+ view.setInt32(4, width, true);
78
+ view.setInt32(8, height, true);
79
+ view.setUint16(12, 1, true);
80
+ view.setUint16(14, DIB_BIT_COUNT_MONOCHROME, true);
81
+ view.setUint32(16, 0, true);
82
+ view.setUint32(20, 0, true);
83
+ view.setInt32(24, 0, true);
84
+ view.setInt32(28, 0, true);
85
+ view.setUint32(32, colorCount, true);
86
+ view.setUint32(36, 0, true);
87
+ out.set([
88
+ 0,
89
+ 0,
90
+ 0,
91
+ 0
92
+ ], DIB_HEADER_SIZE_BITMAPINFOHEADER);
93
+ out.set([
94
+ 255,
95
+ 255,
96
+ 255,
97
+ 0
98
+ ], 44);
99
+ return out;
100
+ }
101
+ function writePresentationObjectHeader() {
102
+ const classNameBytes = writeLengthPrefixedAnsiString(PRESENTATION_CLASS_NAME);
103
+ const out = new Uint8Array(8 + classNameBytes.length);
104
+ const view = new DataView(out.buffer);
105
+ view.setUint32(0, OBJECT_HEADER_OLE_VERSION, true);
106
+ view.setUint32(4, PRESENTATION_OBJECT_HEADER_FORMAT_ID, true);
107
+ out.set(classNameBytes, 8);
108
+ return out;
109
+ }
110
+ function writeClipboardFormatHeader() {
111
+ const headerBytes = writePresentationObjectHeader();
112
+ const out = new Uint8Array(headerBytes.length + 4);
113
+ out.set(headerBytes, 0);
114
+ new DataView(out.buffer).setUint32(headerBytes.length, CLIPBOARD_FORMAT_CF_DIB, true);
115
+ return out;
116
+ }
117
+ function writePresentationObject() {
118
+ const headerBytes = writeClipboardFormatHeader();
119
+ const dib = writeMinimalDib();
120
+ const out = new Uint8Array(headerBytes.length + 4 + dib.length);
121
+ out.set(headerBytes, 0);
122
+ new DataView(out.buffer).setUint32(headerBytes.length, dib.length, true);
123
+ out.set(dib, headerBytes.length + 4);
124
+ return out;
125
+ }
126
+ function skipPresentationObjectHeader(bytes, offset) {
127
+ if (offset + 8 > bytes.length) throw new Error("the Presentation field ends before its PresentationObjectHeader's FormatID");
128
+ const formatId = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(offset + 4, true);
129
+ if (formatId !== PRESENTATION_OBJECT_HEADER_FORMAT_ID) throw new Error(`PresentationObjectHeader.FormatID is 0x${formatId.toString(16).padStart(8, "0")}, not the 0x00000005 this module's own Presentation field always writes`);
130
+ return readLengthPrefixedAnsiString(bytes, offset + 8, "PresentationObjectHeader.ClassName").next;
131
+ }
132
+ function skipClipboardFormatHeader(bytes, offset) {
133
+ const afterHeader = skipPresentationObjectHeader(bytes, offset);
134
+ if (afterHeader + 4 > bytes.length) throw new Error("ClipboardFormatHeader ends before its ClipboardFormat field");
135
+ const clipboardFormat = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(afterHeader, true);
136
+ if (clipboardFormat !== CLIPBOARD_FORMAT_CF_DIB) throw new Error(`ClipboardFormatHeader.ClipboardFormat is 0x${clipboardFormat.toString(16).padStart(8, "0")}, not the CF_DIB (0x00000008) this module's own Presentation field always writes`);
137
+ return afterHeader + 4;
138
+ }
139
+ function skipPresentationObject(bytes, offset) {
140
+ const afterHeader = skipClipboardFormatHeader(bytes, offset);
141
+ if (afterHeader + 4 > bytes.length) throw new Error("StandardClipboardFormatPresentationObject ends before its PresentationDataSize field");
142
+ const presentationDataSize = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(afterHeader, true);
143
+ const dataStart = afterHeader + 4;
144
+ if (dataStart + presentationDataSize > bytes.length) throw new Error(`StandardClipboardFormatPresentationObject's PresentationDataSize declares ${String(presentationDataSize)} bytes but only ${String(bytes.length - dataStart)} remain`);
145
+ return dataStart + presentationDataSize;
146
+ }
147
+ function writeEmbeddedObjectData(embedded) {
148
+ const payload = {
149
+ objectKind: embedded.objectKind,
150
+ document: embedded.document,
151
+ frame: embedded.frame,
152
+ anchorRow: embedded.anchorRow,
153
+ anchorColumn: embedded.anchorColumn,
154
+ offsetXPt: embedded.offsetXPt,
155
+ offsetYPt: embedded.offsetYPt,
156
+ source: embedded.source
157
+ };
158
+ const fileBytes = new TextEncoder().encode(JSON.stringify(payload));
159
+ const packageBytes = (0, archive_codec.writeOlePackage)({
160
+ label: PACKAGE_LABEL,
161
+ sourcePath: "",
162
+ tempPath: "",
163
+ fileBytes
164
+ });
165
+ const nativeData = (0, archive_codec.writeCompoundFile)([{
166
+ path: "Package",
167
+ bytes: packageBytes
168
+ }]);
169
+ const headerBytes = writeObjectHeader();
170
+ const presentationBytes = writePresentationObject();
171
+ const out = new Uint8Array(headerBytes.length + 4 + nativeData.length + presentationBytes.length);
172
+ out.set(headerBytes, 0);
173
+ new DataView(out.buffer).setUint32(headerBytes.length, nativeData.length, true);
174
+ out.set(nativeData, headerBytes.length + 4);
175
+ out.set(presentationBytes, headerBytes.length + 4 + nativeData.length);
176
+ return out;
177
+ }
178
+ function knownContentEmbeddedObjectFields(embedded) {
179
+ const source = document_schema_js.SourceResidueSchema.safeParse(embedded.source);
180
+ return {
181
+ objectKind: embedded.objectKind,
182
+ document: embedded.document,
183
+ frame: embedded.frame,
184
+ ...embedded.anchorRow === void 0 ? {} : { anchorRow: embedded.anchorRow },
185
+ ...embedded.anchorColumn === void 0 ? {} : { anchorColumn: embedded.anchorColumn },
186
+ ...embedded.offsetXPt === void 0 ? {} : { offsetXPt: embedded.offsetXPt },
187
+ ...embedded.offsetYPt === void 0 ? {} : { offsetYPt: embedded.offsetYPt },
188
+ ...source.success ? { source: source.data } : {}
189
+ };
190
+ }
191
+ function readEmbeddedObjectData(bytes) {
192
+ try {
193
+ const header = readObjectHeader(bytes);
194
+ if (header.formatId !== OBJECT_HEADER_FORMAT_ID_EMBEDDED && header.formatId !== OBJECT_HEADER_FORMAT_ID_LINKED) return;
195
+ if (header.next + 4 > bytes.length) return;
196
+ const nativeDataSize = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(header.next, true);
197
+ const nativeDataStart = header.next + 4;
198
+ if (nativeDataStart + nativeDataSize > bytes.length) return;
199
+ const nativeData = bytes.subarray(nativeDataStart, nativeDataStart + nativeDataSize);
200
+ const packageStream = (0, archive_codec.readCompoundFile)(nativeData).find((stream) => stream.path === "Package");
201
+ if (packageStream === void 0) return;
202
+ const olePackage = (0, archive_codec.readOlePackage)(packageStream.bytes);
203
+ const text = new TextDecoder("utf-8").decode(olePackage.fileBytes);
204
+ const parsed = JSON.parse(text);
205
+ const result = document_schema_js.ContentEmbeddedObjectSchema.safeParse(parsed);
206
+ if (!result.success) return;
207
+ skipPresentationObject(bytes, nativeDataStart + nativeDataSize);
208
+ return knownContentEmbeddedObjectFields(result.data);
209
+ } catch {
210
+ return;
211
+ }
212
+ }
213
+ //#endregion
214
+ exports.readEmbeddedObjectData = readEmbeddedObjectData;
215
+ exports.writeEmbeddedObjectData = writeEmbeddedObjectData;
@@ -0,0 +1,6 @@
1
+ import { ContentEmbeddedObject } from "document-schema.js";
2
+ //#region src/embedded-object.d.ts
3
+ declare function writeEmbeddedObjectData(embedded: ContentEmbeddedObject): Uint8Array<ArrayBuffer>;
4
+ declare function readEmbeddedObjectData(bytes: Uint8Array<ArrayBuffer>): ContentEmbeddedObject | undefined;
5
+ //#endregion
6
+ export { readEmbeddedObjectData, writeEmbeddedObjectData };
@@ -0,0 +1,6 @@
1
+ import { ContentEmbeddedObject } from "document-schema.js";
2
+ //#region src/embedded-object.d.ts
3
+ declare function writeEmbeddedObjectData(embedded: ContentEmbeddedObject): Uint8Array<ArrayBuffer>;
4
+ declare function readEmbeddedObjectData(bytes: Uint8Array<ArrayBuffer>): ContentEmbeddedObject | undefined;
5
+ //#endregion
6
+ export { readEmbeddedObjectData, writeEmbeddedObjectData };
@@ -0,0 +1,213 @@
1
+ import { ContentEmbeddedObjectSchema, SourceResidueSchema } from "document-schema.js";
2
+ import { readCompoundFile, readOlePackage, writeCompoundFile, writeOlePackage } from "archive-codec";
3
+ //#region src/embedded-object.ts
4
+ const PACKAGE_LABEL = "rtf-codec-embedded-object.json";
5
+ const OBJECT_HEADER_FORMAT_ID_EMBEDDED = 2;
6
+ const OBJECT_HEADER_FORMAT_ID_LINKED = 1;
7
+ const OBJECT_HEADER_OLE_VERSION = 1281;
8
+ const OBJECT_HEADER_CLASS_NAME = "Package";
9
+ const ANSI_DECODER = new TextDecoder("windows-1252");
10
+ const PRESENTATION_OBJECT_HEADER_FORMAT_ID = 5;
11
+ const PRESENTATION_CLASS_NAME = "";
12
+ const CLIPBOARD_FORMAT_CF_DIB = 8;
13
+ const DIB_HEADER_SIZE_BITMAPINFOHEADER = 40;
14
+ const DIB_BIT_COUNT_MONOCHROME = 1;
15
+ function writeLengthPrefixedAnsiString(value) {
16
+ if (value.length === 0) return /* @__PURE__ */ new Uint8Array(4);
17
+ for (let index = 0; index < value.length; index++) {
18
+ const code = value.charCodeAt(index);
19
+ if (code > 127) throw new Error(`ObjectHeader string contains a character (U+${code.toString(16).padStart(4, "0")}) outside ASCII; encoding it to an arbitrary windows-1252 byte would need a full codepage table this module does not carry`);
20
+ }
21
+ const length = value.length + 1;
22
+ const out = new Uint8Array(4 + length);
23
+ new DataView(out.buffer).setUint32(0, length, true);
24
+ for (let index = 0; index < value.length; index++) out[4 + index] = value.charCodeAt(index);
25
+ return out;
26
+ }
27
+ function readLengthPrefixedAnsiString(bytes, offset, fieldName) {
28
+ if (offset + 4 > bytes.length) throw new Error(`ObjectHeader ends before its ${fieldName} length field`);
29
+ const length = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(offset, true);
30
+ offset += 4;
31
+ if (length === 0) return {
32
+ value: "",
33
+ next: offset
34
+ };
35
+ if (offset + length > bytes.length) throw new Error(`ObjectHeader's ${fieldName} declares ${length} bytes but only ${bytes.length - offset} remain`);
36
+ return {
37
+ value: ANSI_DECODER.decode(bytes.subarray(offset, offset + length - 1)),
38
+ next: offset + length
39
+ };
40
+ }
41
+ function writeObjectHeader() {
42
+ const classNameBytes = writeLengthPrefixedAnsiString(OBJECT_HEADER_CLASS_NAME);
43
+ const topicNameBytes = writeLengthPrefixedAnsiString("");
44
+ const itemNameBytes = writeLengthPrefixedAnsiString("");
45
+ const out = new Uint8Array(8 + classNameBytes.length + topicNameBytes.length + itemNameBytes.length);
46
+ const view = new DataView(out.buffer);
47
+ view.setUint32(0, OBJECT_HEADER_OLE_VERSION, true);
48
+ view.setUint32(4, OBJECT_HEADER_FORMAT_ID_EMBEDDED, true);
49
+ let offset = 8;
50
+ out.set(classNameBytes, offset);
51
+ offset += classNameBytes.length;
52
+ out.set(topicNameBytes, offset);
53
+ offset += topicNameBytes.length;
54
+ out.set(itemNameBytes, offset);
55
+ return out;
56
+ }
57
+ function readObjectHeader(bytes) {
58
+ if (bytes.length < 8) throw new Error("ObjectHeader ends before its FormatID field");
59
+ const formatId = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(4, true);
60
+ let offset = 8;
61
+ offset = readLengthPrefixedAnsiString(bytes, offset, "ClassName").next;
62
+ offset = readLengthPrefixedAnsiString(bytes, offset, "TopicName").next;
63
+ offset = readLengthPrefixedAnsiString(bytes, offset, "ItemName").next;
64
+ return {
65
+ formatId,
66
+ next: offset
67
+ };
68
+ }
69
+ function writeMinimalDib() {
70
+ const width = 1;
71
+ const height = 1;
72
+ const colorCount = 2;
73
+ const out = new Uint8Array(48 + 4 * Math.abs(height));
74
+ const view = new DataView(out.buffer);
75
+ view.setUint32(0, DIB_HEADER_SIZE_BITMAPINFOHEADER, true);
76
+ view.setInt32(4, width, true);
77
+ view.setInt32(8, height, true);
78
+ view.setUint16(12, 1, true);
79
+ view.setUint16(14, DIB_BIT_COUNT_MONOCHROME, true);
80
+ view.setUint32(16, 0, true);
81
+ view.setUint32(20, 0, true);
82
+ view.setInt32(24, 0, true);
83
+ view.setInt32(28, 0, true);
84
+ view.setUint32(32, colorCount, true);
85
+ view.setUint32(36, 0, true);
86
+ out.set([
87
+ 0,
88
+ 0,
89
+ 0,
90
+ 0
91
+ ], DIB_HEADER_SIZE_BITMAPINFOHEADER);
92
+ out.set([
93
+ 255,
94
+ 255,
95
+ 255,
96
+ 0
97
+ ], 44);
98
+ return out;
99
+ }
100
+ function writePresentationObjectHeader() {
101
+ const classNameBytes = writeLengthPrefixedAnsiString(PRESENTATION_CLASS_NAME);
102
+ const out = new Uint8Array(8 + classNameBytes.length);
103
+ const view = new DataView(out.buffer);
104
+ view.setUint32(0, OBJECT_HEADER_OLE_VERSION, true);
105
+ view.setUint32(4, PRESENTATION_OBJECT_HEADER_FORMAT_ID, true);
106
+ out.set(classNameBytes, 8);
107
+ return out;
108
+ }
109
+ function writeClipboardFormatHeader() {
110
+ const headerBytes = writePresentationObjectHeader();
111
+ const out = new Uint8Array(headerBytes.length + 4);
112
+ out.set(headerBytes, 0);
113
+ new DataView(out.buffer).setUint32(headerBytes.length, CLIPBOARD_FORMAT_CF_DIB, true);
114
+ return out;
115
+ }
116
+ function writePresentationObject() {
117
+ const headerBytes = writeClipboardFormatHeader();
118
+ const dib = writeMinimalDib();
119
+ const out = new Uint8Array(headerBytes.length + 4 + dib.length);
120
+ out.set(headerBytes, 0);
121
+ new DataView(out.buffer).setUint32(headerBytes.length, dib.length, true);
122
+ out.set(dib, headerBytes.length + 4);
123
+ return out;
124
+ }
125
+ function skipPresentationObjectHeader(bytes, offset) {
126
+ if (offset + 8 > bytes.length) throw new Error("the Presentation field ends before its PresentationObjectHeader's FormatID");
127
+ const formatId = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(offset + 4, true);
128
+ if (formatId !== PRESENTATION_OBJECT_HEADER_FORMAT_ID) throw new Error(`PresentationObjectHeader.FormatID is 0x${formatId.toString(16).padStart(8, "0")}, not the 0x00000005 this module's own Presentation field always writes`);
129
+ return readLengthPrefixedAnsiString(bytes, offset + 8, "PresentationObjectHeader.ClassName").next;
130
+ }
131
+ function skipClipboardFormatHeader(bytes, offset) {
132
+ const afterHeader = skipPresentationObjectHeader(bytes, offset);
133
+ if (afterHeader + 4 > bytes.length) throw new Error("ClipboardFormatHeader ends before its ClipboardFormat field");
134
+ const clipboardFormat = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(afterHeader, true);
135
+ if (clipboardFormat !== CLIPBOARD_FORMAT_CF_DIB) throw new Error(`ClipboardFormatHeader.ClipboardFormat is 0x${clipboardFormat.toString(16).padStart(8, "0")}, not the CF_DIB (0x00000008) this module's own Presentation field always writes`);
136
+ return afterHeader + 4;
137
+ }
138
+ function skipPresentationObject(bytes, offset) {
139
+ const afterHeader = skipClipboardFormatHeader(bytes, offset);
140
+ if (afterHeader + 4 > bytes.length) throw new Error("StandardClipboardFormatPresentationObject ends before its PresentationDataSize field");
141
+ const presentationDataSize = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(afterHeader, true);
142
+ const dataStart = afterHeader + 4;
143
+ if (dataStart + presentationDataSize > bytes.length) throw new Error(`StandardClipboardFormatPresentationObject's PresentationDataSize declares ${String(presentationDataSize)} bytes but only ${String(bytes.length - dataStart)} remain`);
144
+ return dataStart + presentationDataSize;
145
+ }
146
+ function writeEmbeddedObjectData(embedded) {
147
+ const payload = {
148
+ objectKind: embedded.objectKind,
149
+ document: embedded.document,
150
+ frame: embedded.frame,
151
+ anchorRow: embedded.anchorRow,
152
+ anchorColumn: embedded.anchorColumn,
153
+ offsetXPt: embedded.offsetXPt,
154
+ offsetYPt: embedded.offsetYPt,
155
+ source: embedded.source
156
+ };
157
+ const fileBytes = new TextEncoder().encode(JSON.stringify(payload));
158
+ const packageBytes = writeOlePackage({
159
+ label: PACKAGE_LABEL,
160
+ sourcePath: "",
161
+ tempPath: "",
162
+ fileBytes
163
+ });
164
+ const nativeData = writeCompoundFile([{
165
+ path: "Package",
166
+ bytes: packageBytes
167
+ }]);
168
+ const headerBytes = writeObjectHeader();
169
+ const presentationBytes = writePresentationObject();
170
+ const out = new Uint8Array(headerBytes.length + 4 + nativeData.length + presentationBytes.length);
171
+ out.set(headerBytes, 0);
172
+ new DataView(out.buffer).setUint32(headerBytes.length, nativeData.length, true);
173
+ out.set(nativeData, headerBytes.length + 4);
174
+ out.set(presentationBytes, headerBytes.length + 4 + nativeData.length);
175
+ return out;
176
+ }
177
+ function knownContentEmbeddedObjectFields(embedded) {
178
+ const source = SourceResidueSchema.safeParse(embedded.source);
179
+ return {
180
+ objectKind: embedded.objectKind,
181
+ document: embedded.document,
182
+ frame: embedded.frame,
183
+ ...embedded.anchorRow === void 0 ? {} : { anchorRow: embedded.anchorRow },
184
+ ...embedded.anchorColumn === void 0 ? {} : { anchorColumn: embedded.anchorColumn },
185
+ ...embedded.offsetXPt === void 0 ? {} : { offsetXPt: embedded.offsetXPt },
186
+ ...embedded.offsetYPt === void 0 ? {} : { offsetYPt: embedded.offsetYPt },
187
+ ...source.success ? { source: source.data } : {}
188
+ };
189
+ }
190
+ function readEmbeddedObjectData(bytes) {
191
+ try {
192
+ const header = readObjectHeader(bytes);
193
+ if (header.formatId !== OBJECT_HEADER_FORMAT_ID_EMBEDDED && header.formatId !== OBJECT_HEADER_FORMAT_ID_LINKED) return;
194
+ if (header.next + 4 > bytes.length) return;
195
+ const nativeDataSize = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(header.next, true);
196
+ const nativeDataStart = header.next + 4;
197
+ if (nativeDataStart + nativeDataSize > bytes.length) return;
198
+ const nativeData = bytes.subarray(nativeDataStart, nativeDataStart + nativeDataSize);
199
+ const packageStream = readCompoundFile(nativeData).find((stream) => stream.path === "Package");
200
+ if (packageStream === void 0) return;
201
+ const olePackage = readOlePackage(packageStream.bytes);
202
+ const text = new TextDecoder("utf-8").decode(olePackage.fileBytes);
203
+ const parsed = JSON.parse(text);
204
+ const result = ContentEmbeddedObjectSchema.safeParse(parsed);
205
+ if (!result.success) return;
206
+ skipPresentationObject(bytes, nativeDataStart + nativeDataSize);
207
+ return knownContentEmbeddedObjectFields(result.data);
208
+ } catch {
209
+ return;
210
+ }
211
+ }
212
+ //#endregion
213
+ export { readEmbeddedObjectData, writeEmbeddedObjectData };
package/dist/header.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as RtfDiagnosticSink } from "./diagnostics-BgG_KAiN.cjs";
1
+ import { a as RtfDiagnosticSink } from "./diagnostics-CjMoO7x1.cjs";
2
2
  import { RtfToken } from "./tokenize.cjs";
3
3
  import { Color, LayoutMetadata } from "document-schema.js";
4
4
  //#region src/header.d.ts
package/dist/header.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as RtfDiagnosticSink } from "./diagnostics-BgG_KAiN.js";
1
+ import { a as RtfDiagnosticSink } from "./diagnostics-CjMoO7x1.js";
2
2
  import { RtfToken } from "./tokenize.js";
3
3
  import { Color, LayoutMetadata } from "document-schema.js";
4
4
  //#region src/header.d.ts
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { rtfBytesFromLatin1 } from "./bytes.cjs";
2
2
  import { RtfBytesSchema, rtfCodec, rtfContentCodec } from "./codec.cjs";
3
- import { a as RtfDiagnosticSink, c as RtfNotAnRtfDocumentError, d as RtfWriteError, i as RtfDiagnosticSeverity, l as RtfParseError, n as RtfDiagnostic, o as RtfInputTooLargeError, r as RtfDiagnosticCodes, s as RtfNestingLimitExceededError, t as NOOP_RTF_DIAGNOSTIC_SINK, u as RtfUnsupportedDocumentKindError } from "./diagnostics-BgG_KAiN.cjs";
3
+ import { a as RtfDiagnosticSink, c as RtfNotAnRtfDocumentError, d as RtfWriteError, i as RtfDiagnosticSeverity, l as RtfParseError, n as RtfDiagnostic, o as RtfInputTooLargeError, r as RtfDiagnosticCodes, s as RtfNestingLimitExceededError, t as NOOP_RTF_DIAGNOSTIC_SINK, u as RtfUnsupportedDocumentKindError } from "./diagnostics-CjMoO7x1.cjs";
4
4
  import { DEFAULT_MAX_GROUP_DEPTH, DEFAULT_MAX_INPUT_BYTES, ReadRtfOptions, RtfLineEnding, WriteRtfOptions } from "./options.cjs";
5
5
  import { ReadRtfContentResult, ReadRtfResult, readRtf, readRtfContent } from "./read.cjs";
6
6
  import { writeRtf, writeRtfContent } from "./write.cjs";
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { rtfBytesFromLatin1 } from "./bytes.js";
2
2
  import { RtfBytesSchema, rtfCodec, rtfContentCodec } from "./codec.js";
3
- import { a as RtfDiagnosticSink, c as RtfNotAnRtfDocumentError, d as RtfWriteError, i as RtfDiagnosticSeverity, l as RtfParseError, n as RtfDiagnostic, o as RtfInputTooLargeError, r as RtfDiagnosticCodes, s as RtfNestingLimitExceededError, t as NOOP_RTF_DIAGNOSTIC_SINK, u as RtfUnsupportedDocumentKindError } from "./diagnostics-BgG_KAiN.js";
3
+ import { a as RtfDiagnosticSink, c as RtfNotAnRtfDocumentError, d as RtfWriteError, i as RtfDiagnosticSeverity, l as RtfParseError, n as RtfDiagnostic, o as RtfInputTooLargeError, r as RtfDiagnosticCodes, s as RtfNestingLimitExceededError, t as NOOP_RTF_DIAGNOSTIC_SINK, u as RtfUnsupportedDocumentKindError } from "./diagnostics-CjMoO7x1.js";
4
4
  import { DEFAULT_MAX_GROUP_DEPTH, DEFAULT_MAX_INPUT_BYTES, ReadRtfOptions, RtfLineEnding, WriteRtfOptions } from "./options.js";
5
5
  import { ReadRtfContentResult, ReadRtfResult, readRtf, readRtfContent } from "./read.js";
6
6
  import { writeRtf, writeRtfContent } from "./write.js";
@@ -1,4 +1,4 @@
1
- import { a as RtfDiagnosticSink } from "./diagnostics-BgG_KAiN.cjs";
1
+ import { a as RtfDiagnosticSink } from "./diagnostics-CjMoO7x1.cjs";
2
2
  //#region src/options.d.ts
3
3
  declare const DEFAULT_MAX_INPUT_BYTES: number;
4
4
  declare const DEFAULT_MAX_GROUP_DEPTH = 256;
package/dist/options.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as RtfDiagnosticSink } from "./diagnostics-BgG_KAiN.js";
1
+ import { a as RtfDiagnosticSink } from "./diagnostics-CjMoO7x1.js";
2
2
  //#region src/options.d.ts
3
3
  declare const DEFAULT_MAX_INPUT_BYTES: number;
4
4
  declare const DEFAULT_MAX_GROUP_DEPTH = 256;