rtf-codec 1.0.0 → 1.1.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.
@@ -0,0 +1,131 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/constructs.ts
3
+ const RTF_SOURCE_FORMAT = "rtf";
4
+ function bookmarkAnchorDescriptor(name, columns) {
5
+ const residue = bookmarkColumnResidue(columns);
6
+ return {
7
+ kind: "anchor",
8
+ anchorType: "bookmark",
9
+ name,
10
+ ...residue === void 0 ? {} : { source: {
11
+ format: "rtf",
12
+ xml: residue
13
+ } }
14
+ };
15
+ }
16
+ function bookmarkColumnResidue(columns) {
17
+ if (columns === void 0) return;
18
+ const parts = [columns.first === void 0 ? "" : `\\bkmkcolf${String(columns.first)}`, columns.last === void 0 ? "" : `\\bkmkcoll${String(columns.last)}`].join("");
19
+ return parts.length === 0 ? void 0 : parts;
20
+ }
21
+ function bookmarkResidueControlWords(descriptor) {
22
+ const source = descriptor.source;
23
+ return source?.format === "rtf" ? source.xml : "";
24
+ }
25
+ function isBookmarkAnchor(descriptor) {
26
+ return descriptor.kind === "anchor" && descriptor.anchorType === "bookmark";
27
+ }
28
+ const NO_REVISION = {
29
+ revised: false,
30
+ revisedAuthor: void 0,
31
+ revisedDateTime: void 0,
32
+ deleted: false,
33
+ deletedAuthor: void 0,
34
+ deletedDateTime: void 0,
35
+ moved: void 0,
36
+ movedAuthor: void 0,
37
+ movedDateTime: void 0,
38
+ formatAuthor: void 0,
39
+ formatDateTime: void 0
40
+ };
41
+ function hasRevision(state) {
42
+ return state.revised || state.deleted || state.moved !== void 0 || state.formatAuthor !== void 0;
43
+ }
44
+ function provenanceDescriptors(state, authors) {
45
+ const out = [];
46
+ if (state.revised) out.push(provenanceDescriptor("insertion", state.revisedAuthor, state.revisedDateTime, authors));
47
+ if (state.deleted) out.push(provenanceDescriptor("deletion", state.deletedAuthor, state.deletedDateTime, authors));
48
+ if (state.moved !== void 0) out.push(provenanceDescriptor(state.moved, state.movedAuthor, state.movedDateTime, authors));
49
+ if (state.formatAuthor !== void 0) out.push(provenanceDescriptor("formatChange", state.formatAuthor, state.formatDateTime, authors));
50
+ return out;
51
+ }
52
+ function provenanceDescriptor(change, authorIndex, dateTime, authors) {
53
+ const author = authorIndex === void 0 ? void 0 : authors[authorIndex];
54
+ const dateIso = dateTime === void 0 ? void 0 : isoFromDttm(dateTime);
55
+ return {
56
+ kind: "provenance",
57
+ change,
58
+ ...author === void 0 || author.length === 0 ? {} : { author },
59
+ ...dateIso === void 0 ? {} : { dateIso }
60
+ };
61
+ }
62
+ const DTTM_MINUTE_MASK = 63;
63
+ const DTTM_HOUR_SHIFT = 6;
64
+ const DTTM_HOUR_MASK = 31;
65
+ const DTTM_DAY_SHIFT = 11;
66
+ const DTTM_DAY_MASK = 31;
67
+ const DTTM_MONTH_SHIFT = 16;
68
+ const DTTM_MONTH_MASK = 15;
69
+ const DTTM_YEAR_SHIFT = 20;
70
+ const DTTM_YEAR_MASK = 511;
71
+ const DTTM_YEAR_EPOCH = 1900;
72
+ function isoFromDttm(value) {
73
+ const bits = value >>> 0;
74
+ const minute = bits & DTTM_MINUTE_MASK;
75
+ const hour = bits >>> DTTM_HOUR_SHIFT & DTTM_HOUR_MASK;
76
+ const day = bits >>> DTTM_DAY_SHIFT & DTTM_DAY_MASK;
77
+ const month = bits >>> DTTM_MONTH_SHIFT & DTTM_MONTH_MASK;
78
+ const year = (bits >>> DTTM_YEAR_SHIFT & DTTM_YEAR_MASK) + DTTM_YEAR_EPOCH;
79
+ if (day === 0 || month === 0 || month > 12 || day > 31) return;
80
+ return `${pad(year, 4)}-${pad(month, 2)}-${pad(day, 2)}T${pad(hour, 2)}:${pad(minute, 2)}:00`;
81
+ }
82
+ const ISO_DATE_TIME = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::\d{2}(?:\.\d+)?)?)?/;
83
+ function dttmFromIso(dateIso) {
84
+ const match = ISO_DATE_TIME.exec(dateIso);
85
+ if (match === null) return;
86
+ const year = Number(match[1]) - DTTM_YEAR_EPOCH;
87
+ const month = Number(match[2]);
88
+ const day = Number(match[3]);
89
+ const hour = match[4] === void 0 ? 0 : Number(match[4]);
90
+ const minute = match[5] === void 0 ? 0 : Number(match[5]);
91
+ if (year < 0 || year > DTTM_YEAR_MASK) return;
92
+ return minute & DTTM_MINUTE_MASK | (hour & DTTM_HOUR_MASK) << DTTM_HOUR_SHIFT | (day & DTTM_DAY_MASK) << DTTM_DAY_SHIFT | (month & DTTM_MONTH_MASK) << DTTM_MONTH_SHIFT | (year & DTTM_YEAR_MASK) << DTTM_YEAR_SHIFT | 0;
93
+ }
94
+ function pad(value, width) {
95
+ return String(value).padStart(width, "0");
96
+ }
97
+ function coalesceRunConstructs(perRun) {
98
+ const open = /* @__PURE__ */ new Map();
99
+ const out = [];
100
+ const close = (key, end) => {
101
+ const entry = open.get(key);
102
+ if (entry === void 0) return;
103
+ out.push({
104
+ descriptor: entry.descriptor,
105
+ startRun: entry.start,
106
+ endRun: end
107
+ });
108
+ open.delete(key);
109
+ };
110
+ for (const [index, descriptors] of perRun.entries()) {
111
+ const present = new Map(descriptors.map((descriptor) => [JSON.stringify(descriptor), descriptor]));
112
+ for (const key of [...open.keys()]) if (!present.has(key)) close(key, index);
113
+ for (const [key, descriptor] of present) if (!open.has(key)) open.set(key, {
114
+ descriptor,
115
+ start: index
116
+ });
117
+ }
118
+ for (const key of [...open.keys()]) close(key, perRun.length);
119
+ return out.sort((left, right) => left.startRun - right.startRun || left.endRun - right.endRun);
120
+ }
121
+ //#endregion
122
+ exports.NO_REVISION = NO_REVISION;
123
+ exports.RTF_SOURCE_FORMAT = RTF_SOURCE_FORMAT;
124
+ exports.bookmarkAnchorDescriptor = bookmarkAnchorDescriptor;
125
+ exports.bookmarkResidueControlWords = bookmarkResidueControlWords;
126
+ exports.coalesceRunConstructs = coalesceRunConstructs;
127
+ exports.dttmFromIso = dttmFromIso;
128
+ exports.hasRevision = hasRevision;
129
+ exports.isBookmarkAnchor = isBookmarkAnchor;
130
+ exports.isoFromDttm = isoFromDttm;
131
+ exports.provenanceDescriptors = provenanceDescriptors;
@@ -0,0 +1,31 @@
1
+ import { AnchorDescriptor, ConstructDescriptor, ProvenanceDescriptor, RunConstructExtent } from "document-schema.js";
2
+ //#region src/constructs.d.ts
3
+ declare const RTF_SOURCE_FORMAT: "rtf";
4
+ interface BookmarkColumnRange {
5
+ readonly first: number | undefined;
6
+ readonly last: number | undefined;
7
+ }
8
+ declare function bookmarkAnchorDescriptor(name: string, columns: BookmarkColumnRange | undefined): AnchorDescriptor;
9
+ declare function bookmarkResidueControlWords(descriptor: AnchorDescriptor): string;
10
+ declare function isBookmarkAnchor(descriptor: ConstructDescriptor): descriptor is AnchorDescriptor;
11
+ interface RevisionState {
12
+ readonly revised: boolean;
13
+ readonly revisedAuthor: number | undefined;
14
+ readonly revisedDateTime: number | undefined;
15
+ readonly deleted: boolean;
16
+ readonly deletedAuthor: number | undefined;
17
+ readonly deletedDateTime: number | undefined;
18
+ readonly moved: "moveFrom" | "moveTo" | undefined;
19
+ readonly movedAuthor: number | undefined;
20
+ readonly movedDateTime: number | undefined;
21
+ readonly formatAuthor: number | undefined;
22
+ readonly formatDateTime: number | undefined;
23
+ }
24
+ declare const NO_REVISION: RevisionState;
25
+ declare function hasRevision(state: RevisionState): boolean;
26
+ declare function provenanceDescriptors(state: RevisionState, authors: readonly string[]): ProvenanceDescriptor[];
27
+ declare function isoFromDttm(value: number): string | undefined;
28
+ declare function dttmFromIso(dateIso: string): number | undefined;
29
+ declare function coalesceRunConstructs(perRun: readonly (readonly ConstructDescriptor[])[]): RunConstructExtent[];
30
+ //#endregion
31
+ export { BookmarkColumnRange, NO_REVISION, RTF_SOURCE_FORMAT, RevisionState, bookmarkAnchorDescriptor, bookmarkResidueControlWords, coalesceRunConstructs, dttmFromIso, hasRevision, isBookmarkAnchor, isoFromDttm, provenanceDescriptors };
@@ -0,0 +1,31 @@
1
+ import { AnchorDescriptor, ConstructDescriptor, ProvenanceDescriptor, RunConstructExtent } from "document-schema.js";
2
+ //#region src/constructs.d.ts
3
+ declare const RTF_SOURCE_FORMAT: "rtf";
4
+ interface BookmarkColumnRange {
5
+ readonly first: number | undefined;
6
+ readonly last: number | undefined;
7
+ }
8
+ declare function bookmarkAnchorDescriptor(name: string, columns: BookmarkColumnRange | undefined): AnchorDescriptor;
9
+ declare function bookmarkResidueControlWords(descriptor: AnchorDescriptor): string;
10
+ declare function isBookmarkAnchor(descriptor: ConstructDescriptor): descriptor is AnchorDescriptor;
11
+ interface RevisionState {
12
+ readonly revised: boolean;
13
+ readonly revisedAuthor: number | undefined;
14
+ readonly revisedDateTime: number | undefined;
15
+ readonly deleted: boolean;
16
+ readonly deletedAuthor: number | undefined;
17
+ readonly deletedDateTime: number | undefined;
18
+ readonly moved: "moveFrom" | "moveTo" | undefined;
19
+ readonly movedAuthor: number | undefined;
20
+ readonly movedDateTime: number | undefined;
21
+ readonly formatAuthor: number | undefined;
22
+ readonly formatDateTime: number | undefined;
23
+ }
24
+ declare const NO_REVISION: RevisionState;
25
+ declare function hasRevision(state: RevisionState): boolean;
26
+ declare function provenanceDescriptors(state: RevisionState, authors: readonly string[]): ProvenanceDescriptor[];
27
+ declare function isoFromDttm(value: number): string | undefined;
28
+ declare function dttmFromIso(dateIso: string): number | undefined;
29
+ declare function coalesceRunConstructs(perRun: readonly (readonly ConstructDescriptor[])[]): RunConstructExtent[];
30
+ //#endregion
31
+ export { BookmarkColumnRange, NO_REVISION, RTF_SOURCE_FORMAT, RevisionState, bookmarkAnchorDescriptor, bookmarkResidueControlWords, coalesceRunConstructs, dttmFromIso, hasRevision, isBookmarkAnchor, isoFromDttm, provenanceDescriptors };
@@ -0,0 +1,121 @@
1
+ //#region src/constructs.ts
2
+ const RTF_SOURCE_FORMAT = "rtf";
3
+ function bookmarkAnchorDescriptor(name, columns) {
4
+ const residue = bookmarkColumnResidue(columns);
5
+ return {
6
+ kind: "anchor",
7
+ anchorType: "bookmark",
8
+ name,
9
+ ...residue === void 0 ? {} : { source: {
10
+ format: "rtf",
11
+ xml: residue
12
+ } }
13
+ };
14
+ }
15
+ function bookmarkColumnResidue(columns) {
16
+ if (columns === void 0) return;
17
+ const parts = [columns.first === void 0 ? "" : `\\bkmkcolf${String(columns.first)}`, columns.last === void 0 ? "" : `\\bkmkcoll${String(columns.last)}`].join("");
18
+ return parts.length === 0 ? void 0 : parts;
19
+ }
20
+ function bookmarkResidueControlWords(descriptor) {
21
+ const source = descriptor.source;
22
+ return source?.format === "rtf" ? source.xml : "";
23
+ }
24
+ function isBookmarkAnchor(descriptor) {
25
+ return descriptor.kind === "anchor" && descriptor.anchorType === "bookmark";
26
+ }
27
+ const NO_REVISION = {
28
+ revised: false,
29
+ revisedAuthor: void 0,
30
+ revisedDateTime: void 0,
31
+ deleted: false,
32
+ deletedAuthor: void 0,
33
+ deletedDateTime: void 0,
34
+ moved: void 0,
35
+ movedAuthor: void 0,
36
+ movedDateTime: void 0,
37
+ formatAuthor: void 0,
38
+ formatDateTime: void 0
39
+ };
40
+ function hasRevision(state) {
41
+ return state.revised || state.deleted || state.moved !== void 0 || state.formatAuthor !== void 0;
42
+ }
43
+ function provenanceDescriptors(state, authors) {
44
+ const out = [];
45
+ if (state.revised) out.push(provenanceDescriptor("insertion", state.revisedAuthor, state.revisedDateTime, authors));
46
+ if (state.deleted) out.push(provenanceDescriptor("deletion", state.deletedAuthor, state.deletedDateTime, authors));
47
+ if (state.moved !== void 0) out.push(provenanceDescriptor(state.moved, state.movedAuthor, state.movedDateTime, authors));
48
+ if (state.formatAuthor !== void 0) out.push(provenanceDescriptor("formatChange", state.formatAuthor, state.formatDateTime, authors));
49
+ return out;
50
+ }
51
+ function provenanceDescriptor(change, authorIndex, dateTime, authors) {
52
+ const author = authorIndex === void 0 ? void 0 : authors[authorIndex];
53
+ const dateIso = dateTime === void 0 ? void 0 : isoFromDttm(dateTime);
54
+ return {
55
+ kind: "provenance",
56
+ change,
57
+ ...author === void 0 || author.length === 0 ? {} : { author },
58
+ ...dateIso === void 0 ? {} : { dateIso }
59
+ };
60
+ }
61
+ const DTTM_MINUTE_MASK = 63;
62
+ const DTTM_HOUR_SHIFT = 6;
63
+ const DTTM_HOUR_MASK = 31;
64
+ const DTTM_DAY_SHIFT = 11;
65
+ const DTTM_DAY_MASK = 31;
66
+ const DTTM_MONTH_SHIFT = 16;
67
+ const DTTM_MONTH_MASK = 15;
68
+ const DTTM_YEAR_SHIFT = 20;
69
+ const DTTM_YEAR_MASK = 511;
70
+ const DTTM_YEAR_EPOCH = 1900;
71
+ function isoFromDttm(value) {
72
+ const bits = value >>> 0;
73
+ const minute = bits & DTTM_MINUTE_MASK;
74
+ const hour = bits >>> DTTM_HOUR_SHIFT & DTTM_HOUR_MASK;
75
+ const day = bits >>> DTTM_DAY_SHIFT & DTTM_DAY_MASK;
76
+ const month = bits >>> DTTM_MONTH_SHIFT & DTTM_MONTH_MASK;
77
+ const year = (bits >>> DTTM_YEAR_SHIFT & DTTM_YEAR_MASK) + DTTM_YEAR_EPOCH;
78
+ if (day === 0 || month === 0 || month > 12 || day > 31) return;
79
+ return `${pad(year, 4)}-${pad(month, 2)}-${pad(day, 2)}T${pad(hour, 2)}:${pad(minute, 2)}:00`;
80
+ }
81
+ const ISO_DATE_TIME = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::\d{2}(?:\.\d+)?)?)?/;
82
+ function dttmFromIso(dateIso) {
83
+ const match = ISO_DATE_TIME.exec(dateIso);
84
+ if (match === null) return;
85
+ const year = Number(match[1]) - DTTM_YEAR_EPOCH;
86
+ const month = Number(match[2]);
87
+ const day = Number(match[3]);
88
+ const hour = match[4] === void 0 ? 0 : Number(match[4]);
89
+ const minute = match[5] === void 0 ? 0 : Number(match[5]);
90
+ if (year < 0 || year > DTTM_YEAR_MASK) return;
91
+ return minute & DTTM_MINUTE_MASK | (hour & DTTM_HOUR_MASK) << DTTM_HOUR_SHIFT | (day & DTTM_DAY_MASK) << DTTM_DAY_SHIFT | (month & DTTM_MONTH_MASK) << DTTM_MONTH_SHIFT | (year & DTTM_YEAR_MASK) << DTTM_YEAR_SHIFT | 0;
92
+ }
93
+ function pad(value, width) {
94
+ return String(value).padStart(width, "0");
95
+ }
96
+ function coalesceRunConstructs(perRun) {
97
+ const open = /* @__PURE__ */ new Map();
98
+ const out = [];
99
+ const close = (key, end) => {
100
+ const entry = open.get(key);
101
+ if (entry === void 0) return;
102
+ out.push({
103
+ descriptor: entry.descriptor,
104
+ startRun: entry.start,
105
+ endRun: end
106
+ });
107
+ open.delete(key);
108
+ };
109
+ for (const [index, descriptors] of perRun.entries()) {
110
+ const present = new Map(descriptors.map((descriptor) => [JSON.stringify(descriptor), descriptor]));
111
+ for (const key of [...open.keys()]) if (!present.has(key)) close(key, index);
112
+ for (const [key, descriptor] of present) if (!open.has(key)) open.set(key, {
113
+ descriptor,
114
+ start: index
115
+ });
116
+ }
117
+ for (const key of [...open.keys()]) close(key, perRun.length);
118
+ return out.sort((left, right) => left.startRun - right.startRun || left.endRun - right.endRun);
119
+ }
120
+ //#endregion
121
+ export { NO_REVISION, RTF_SOURCE_FORMAT, bookmarkAnchorDescriptor, bookmarkResidueControlWords, coalesceRunConstructs, dttmFromIso, hasRevision, isBookmarkAnchor, isoFromDttm, provenanceDescriptors };
@@ -18,10 +18,11 @@ declare const RtfDiagnosticCodes: {
18
18
  readonly TABLE_ROW_WITHOUT_DEFINITION: "rtf/table-row-without-definition";
19
19
  readonly TABLE_COLUMN_WIDTH_INVALID: "rtf/table-column-width-invalid";
20
20
  readonly NESTED_TABLE_FLATTENED: "rtf/nested-table-flattened";
21
+ readonly SECTION_BREAK_UNREPRESENTED: "rtf/section-break-unrepresented";
22
+ readonly BOOKMARK_UNPAIRED: "rtf/bookmark-unpaired";
21
23
  readonly CONSTRUCT_UNREPRESENTED: "rtf/construct-unrepresented";
22
24
  readonly EMBEDDED_OBJECT_DROPPED: "rtf/embedded-object-dropped";
23
25
  readonly PACKAGE_TABLE_DROPPED: "rtf/package-table-dropped";
24
- readonly CELL_BORDER_DROPPED: "rtf/cell-border-dropped";
25
26
  };
26
27
  declare class RtfParseError extends Error {
27
28
  readonly code: string;
@@ -18,10 +18,11 @@ declare const RtfDiagnosticCodes: {
18
18
  readonly TABLE_ROW_WITHOUT_DEFINITION: "rtf/table-row-without-definition";
19
19
  readonly TABLE_COLUMN_WIDTH_INVALID: "rtf/table-column-width-invalid";
20
20
  readonly NESTED_TABLE_FLATTENED: "rtf/nested-table-flattened";
21
+ readonly SECTION_BREAK_UNREPRESENTED: "rtf/section-break-unrepresented";
22
+ readonly BOOKMARK_UNPAIRED: "rtf/bookmark-unpaired";
21
23
  readonly CONSTRUCT_UNREPRESENTED: "rtf/construct-unrepresented";
22
24
  readonly EMBEDDED_OBJECT_DROPPED: "rtf/embedded-object-dropped";
23
25
  readonly PACKAGE_TABLE_DROPPED: "rtf/package-table-dropped";
24
- readonly CELL_BORDER_DROPPED: "rtf/cell-border-dropped";
25
26
  };
26
27
  declare class RtfParseError extends Error {
27
28
  readonly code: string;
@@ -11,10 +11,11 @@ const RtfDiagnosticCodes = {
11
11
  TABLE_ROW_WITHOUT_DEFINITION: "rtf/table-row-without-definition",
12
12
  TABLE_COLUMN_WIDTH_INVALID: "rtf/table-column-width-invalid",
13
13
  NESTED_TABLE_FLATTENED: "rtf/nested-table-flattened",
14
+ SECTION_BREAK_UNREPRESENTED: "rtf/section-break-unrepresented",
15
+ BOOKMARK_UNPAIRED: "rtf/bookmark-unpaired",
14
16
  CONSTRUCT_UNREPRESENTED: "rtf/construct-unrepresented",
15
17
  EMBEDDED_OBJECT_DROPPED: "rtf/embedded-object-dropped",
16
- PACKAGE_TABLE_DROPPED: "rtf/package-table-dropped",
17
- CELL_BORDER_DROPPED: "rtf/cell-border-dropped"
18
+ PACKAGE_TABLE_DROPPED: "rtf/package-table-dropped"
18
19
  };
19
20
  var RtfParseError = class extends Error {
20
21
  code;
@@ -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-DdDFJLNO.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-BgG_KAiN.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-DdDFJLNO.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-BgG_KAiN.js";
2
2
  export { NOOP_RTF_DIAGNOSTIC_SINK, RtfDiagnostic, RtfDiagnosticCodes, RtfDiagnosticSeverity, RtfDiagnosticSink, RtfInputTooLargeError, RtfNestingLimitExceededError, RtfNotAnRtfDocumentError, RtfParseError, RtfUnsupportedDocumentKindError, RtfWriteError };
@@ -10,10 +10,11 @@ const RtfDiagnosticCodes = {
10
10
  TABLE_ROW_WITHOUT_DEFINITION: "rtf/table-row-without-definition",
11
11
  TABLE_COLUMN_WIDTH_INVALID: "rtf/table-column-width-invalid",
12
12
  NESTED_TABLE_FLATTENED: "rtf/nested-table-flattened",
13
+ SECTION_BREAK_UNREPRESENTED: "rtf/section-break-unrepresented",
14
+ BOOKMARK_UNPAIRED: "rtf/bookmark-unpaired",
13
15
  CONSTRUCT_UNREPRESENTED: "rtf/construct-unrepresented",
14
16
  EMBEDDED_OBJECT_DROPPED: "rtf/embedded-object-dropped",
15
- PACKAGE_TABLE_DROPPED: "rtf/package-table-dropped",
16
- CELL_BORDER_DROPPED: "rtf/cell-border-dropped"
17
+ PACKAGE_TABLE_DROPPED: "rtf/package-table-dropped"
17
18
  };
18
19
  var RtfParseError = class extends Error {
19
20
  code;
package/dist/header.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_bytes = require("./bytes.cjs");
3
+ const require_units = require("./units.cjs");
3
4
  const require_codepage = require("./codepage.cjs");
4
5
  const require_group = require("./group.cjs");
5
- const require_units = require("./units.cjs");
6
6
  //#region src/header.ts
7
7
  const RGB_MAX = 255;
8
8
  const FONT_FAMILIES = /* @__PURE__ */ new Set([
@@ -16,6 +16,10 @@ const FONT_FAMILIES = /* @__PURE__ */ new Set([
16
16
  "fbidi"
17
17
  ]);
18
18
  const HEADING_STYLE_NAME = /^heading[ -]?([1-9])$/i;
19
+ const DEFAULT_LIST_LEVEL = {
20
+ numberFormat: 0,
21
+ startAt: 1
22
+ };
19
23
  const HEADER_DESTINATIONS = /* @__PURE__ */ new Set([
20
24
  "fonttbl",
21
25
  "colortbl",
@@ -242,17 +246,63 @@ function parseListOverrideTable(tokens, contentStart, end, overrides) {
242
246
  const entryEnd = Math.min(require_group.matchingGroupEnd(tokens, index), end);
243
247
  let listId;
244
248
  let overrideIndex;
249
+ const levelOverrides = [];
245
250
  for (let inner = index + 1; inner < entryEnd; inner += 1) {
246
251
  const child = tokens[inner];
247
252
  if (child?.kind === "groupStart") {
248
- inner = Math.min(require_group.matchingGroupEnd(tokens, inner), entryEnd);
253
+ const childEnd = Math.min(require_group.matchingGroupEnd(tokens, inner), entryEnd);
254
+ if (require_group.groupHead(tokens, inner).destination === "lfolevel") levelOverrides.push(readLevelOverride(tokens, inner, childEnd));
255
+ inner = childEnd;
249
256
  continue;
250
257
  }
251
258
  if (child?.kind !== "controlWord" || child.param === void 0) continue;
252
259
  if (child.name === "listid") listId = child.param;
253
260
  else if (child.name === "ls") overrideIndex = child.param;
254
261
  }
255
- if (listId !== void 0 && overrideIndex !== void 0) overrides.set(overrideIndex, listId);
262
+ if (listId !== void 0 && overrideIndex !== void 0) overrides.set(overrideIndex, {
263
+ listId,
264
+ levelOverrides
265
+ });
266
+ index = entryEnd;
267
+ }
268
+ }
269
+ function readLevelOverride(tokens, start, end) {
270
+ let level;
271
+ let startAt;
272
+ for (let index = start + 1; index < end; index += 1) {
273
+ const token = tokens[index];
274
+ if (token === void 0) break;
275
+ if (token.kind === "groupStart") {
276
+ const inner = Math.min(require_group.matchingGroupEnd(tokens, index), end);
277
+ if (require_group.groupHead(tokens, index).destination === "listlevel") level = readListLevel(tokens, index, inner);
278
+ index = inner;
279
+ continue;
280
+ }
281
+ if (token.kind === "controlWord" && token.name === "levelstartat" && token.param !== void 0) startAt = token.param;
282
+ }
283
+ return {
284
+ ...level === void 0 ? {} : { level },
285
+ ...startAt === void 0 ? {} : { startAt }
286
+ };
287
+ }
288
+ function applyListOverride(list, levelOverrides) {
289
+ if (levelOverrides.length === 0) return list;
290
+ const levels = [...list.levels];
291
+ for (const [index, override] of levelOverrides.entries()) {
292
+ const base = override.level ?? levels[index] ?? DEFAULT_LIST_LEVEL;
293
+ levels[index] = override.level === void 0 && override.startAt !== void 0 ? {
294
+ ...base,
295
+ startAt: override.startAt
296
+ } : base;
297
+ }
298
+ return { levels };
299
+ }
300
+ function parseRevisionTable(tokens, contentStart, end, codepage, authors, sink) {
301
+ for (let index = contentStart; index < end; index += 1) {
302
+ if (tokens[index]?.kind !== "groupStart") continue;
303
+ const entryEnd = Math.min(require_group.matchingGroupEnd(tokens, index), end);
304
+ const value = collectPlainText(tokens, index + 1, entryEnd, codepage, sink);
305
+ authors.push(value.split("\0")[0]?.trim() ?? "");
256
306
  index = entryEnd;
257
307
  }
258
308
  }
@@ -280,6 +330,7 @@ function readRtfHeader(tokens, sink) {
280
330
  const styles = /* @__PURE__ */ new Map();
281
331
  const listsById = /* @__PURE__ */ new Map();
282
332
  const overrides = /* @__PURE__ */ new Map();
333
+ const revisionAuthors = [];
283
334
  const page = {
284
335
  paperWidthTwips: require_units.DEFAULT_PAPER_WIDTH_TWIPS,
285
336
  paperHeightTwips: require_units.DEFAULT_PAPER_HEIGHT_TWIPS,
@@ -351,15 +402,18 @@ function readRtfHeader(tokens, sink) {
351
402
  case "listoverridetable":
352
403
  parseListOverrideTable(tokens, head.contentStart, groupEnd, overrides);
353
404
  break;
405
+ case "revtbl":
406
+ parseRevisionTable(tokens, head.contentStart, groupEnd, codepage, revisionAuthors, sink);
407
+ break;
354
408
  case "info": metadata = parseInfoGroup(tokens, head.contentStart, groupEnd, codepage, sink);
355
409
  }
356
410
  if (head.destination !== void 0 && HEADER_DESTINATIONS.has(head.destination)) bodyStartIndex = Math.max(bodyStartIndex, groupEnd + 1);
357
411
  index = groupEnd;
358
412
  }
359
413
  const lists = /* @__PURE__ */ new Map();
360
- for (const [overrideIndex, listId] of overrides) {
361
- const list = listsById.get(listId);
362
- if (list !== void 0) lists.set(overrideIndex, list);
414
+ for (const [overrideIndex, override] of overrides) {
415
+ const list = listsById.get(override.listId);
416
+ if (list !== void 0) lists.set(overrideIndex, applyListOverride(list, override.levelOverrides));
363
417
  }
364
418
  return {
365
419
  codepage,
@@ -368,6 +422,7 @@ function readRtfHeader(tokens, sink) {
368
422
  colors,
369
423
  styles,
370
424
  lists,
425
+ revisionAuthors,
371
426
  page,
372
427
  metadata,
373
428
  bodyStartIndex
package/dist/header.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as RtfDiagnosticSink } from "./diagnostics-DdDFJLNO.cjs";
1
+ import { a as RtfDiagnosticSink } from "./diagnostics-BgG_KAiN.cjs";
2
2
  import { RtfToken } from "./tokenize.cjs";
3
3
  import { Color, LayoutMetadata } from "document-schema.js";
4
4
  //#region src/header.d.ts
@@ -33,6 +33,7 @@ interface RtfHeader {
33
33
  readonly colors: readonly (Color | undefined)[];
34
34
  readonly styles: ReadonlyMap<number, RtfStyleEntry>;
35
35
  readonly lists: ReadonlyMap<number, RtfListEntry>;
36
+ readonly revisionAuthors: readonly string[];
36
37
  readonly page: RtfPageGeometry;
37
38
  readonly metadata: LayoutMetadata;
38
39
  readonly bodyStartIndex: number;
package/dist/header.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as RtfDiagnosticSink } from "./diagnostics-DdDFJLNO.js";
1
+ import { a as RtfDiagnosticSink } from "./diagnostics-BgG_KAiN.js";
2
2
  import { RtfToken } from "./tokenize.js";
3
3
  import { Color, LayoutMetadata } from "document-schema.js";
4
4
  //#region src/header.d.ts
@@ -33,6 +33,7 @@ interface RtfHeader {
33
33
  readonly colors: readonly (Color | undefined)[];
34
34
  readonly styles: ReadonlyMap<number, RtfStyleEntry>;
35
35
  readonly lists: ReadonlyMap<number, RtfListEntry>;
36
+ readonly revisionAuthors: readonly string[];
36
37
  readonly page: RtfPageGeometry;
37
38
  readonly metadata: LayoutMetadata;
38
39
  readonly bodyStartIndex: number;
package/dist/header.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { appendBytes } from "./bytes.js";
2
+ import { DEFAULT_MARGIN_BOTTOM_TWIPS, DEFAULT_MARGIN_LEFT_TWIPS, DEFAULT_MARGIN_RIGHT_TWIPS, DEFAULT_MARGIN_TOP_TWIPS, DEFAULT_PAPER_HEIGHT_TWIPS, DEFAULT_PAPER_WIDTH_TWIPS } from "./units.js";
2
3
  import { DEFAULT_CODEPAGE, DOCUMENT_CHARSET_CODEPAGES, codepageForFontCharset, decodeCodepageBytes } from "./codepage.js";
3
4
  import { groupHead, matchingGroupEnd } from "./group.js";
4
- import { DEFAULT_MARGIN_BOTTOM_TWIPS, DEFAULT_MARGIN_LEFT_TWIPS, DEFAULT_MARGIN_RIGHT_TWIPS, DEFAULT_MARGIN_TOP_TWIPS, DEFAULT_PAPER_HEIGHT_TWIPS, DEFAULT_PAPER_WIDTH_TWIPS } from "./units.js";
5
5
  //#region src/header.ts
6
6
  const RGB_MAX = 255;
7
7
  const FONT_FAMILIES = /* @__PURE__ */ new Set([
@@ -15,6 +15,10 @@ const FONT_FAMILIES = /* @__PURE__ */ new Set([
15
15
  "fbidi"
16
16
  ]);
17
17
  const HEADING_STYLE_NAME = /^heading[ -]?([1-9])$/i;
18
+ const DEFAULT_LIST_LEVEL = {
19
+ numberFormat: 0,
20
+ startAt: 1
21
+ };
18
22
  const HEADER_DESTINATIONS = /* @__PURE__ */ new Set([
19
23
  "fonttbl",
20
24
  "colortbl",
@@ -241,17 +245,63 @@ function parseListOverrideTable(tokens, contentStart, end, overrides) {
241
245
  const entryEnd = Math.min(matchingGroupEnd(tokens, index), end);
242
246
  let listId;
243
247
  let overrideIndex;
248
+ const levelOverrides = [];
244
249
  for (let inner = index + 1; inner < entryEnd; inner += 1) {
245
250
  const child = tokens[inner];
246
251
  if (child?.kind === "groupStart") {
247
- inner = Math.min(matchingGroupEnd(tokens, inner), entryEnd);
252
+ const childEnd = Math.min(matchingGroupEnd(tokens, inner), entryEnd);
253
+ if (groupHead(tokens, inner).destination === "lfolevel") levelOverrides.push(readLevelOverride(tokens, inner, childEnd));
254
+ inner = childEnd;
248
255
  continue;
249
256
  }
250
257
  if (child?.kind !== "controlWord" || child.param === void 0) continue;
251
258
  if (child.name === "listid") listId = child.param;
252
259
  else if (child.name === "ls") overrideIndex = child.param;
253
260
  }
254
- if (listId !== void 0 && overrideIndex !== void 0) overrides.set(overrideIndex, listId);
261
+ if (listId !== void 0 && overrideIndex !== void 0) overrides.set(overrideIndex, {
262
+ listId,
263
+ levelOverrides
264
+ });
265
+ index = entryEnd;
266
+ }
267
+ }
268
+ function readLevelOverride(tokens, start, end) {
269
+ let level;
270
+ let startAt;
271
+ for (let index = start + 1; index < end; index += 1) {
272
+ const token = tokens[index];
273
+ if (token === void 0) break;
274
+ if (token.kind === "groupStart") {
275
+ const inner = Math.min(matchingGroupEnd(tokens, index), end);
276
+ if (groupHead(tokens, index).destination === "listlevel") level = readListLevel(tokens, index, inner);
277
+ index = inner;
278
+ continue;
279
+ }
280
+ if (token.kind === "controlWord" && token.name === "levelstartat" && token.param !== void 0) startAt = token.param;
281
+ }
282
+ return {
283
+ ...level === void 0 ? {} : { level },
284
+ ...startAt === void 0 ? {} : { startAt }
285
+ };
286
+ }
287
+ function applyListOverride(list, levelOverrides) {
288
+ if (levelOverrides.length === 0) return list;
289
+ const levels = [...list.levels];
290
+ for (const [index, override] of levelOverrides.entries()) {
291
+ const base = override.level ?? levels[index] ?? DEFAULT_LIST_LEVEL;
292
+ levels[index] = override.level === void 0 && override.startAt !== void 0 ? {
293
+ ...base,
294
+ startAt: override.startAt
295
+ } : base;
296
+ }
297
+ return { levels };
298
+ }
299
+ function parseRevisionTable(tokens, contentStart, end, codepage, authors, sink) {
300
+ for (let index = contentStart; index < end; index += 1) {
301
+ if (tokens[index]?.kind !== "groupStart") continue;
302
+ const entryEnd = Math.min(matchingGroupEnd(tokens, index), end);
303
+ const value = collectPlainText(tokens, index + 1, entryEnd, codepage, sink);
304
+ authors.push(value.split("\0")[0]?.trim() ?? "");
255
305
  index = entryEnd;
256
306
  }
257
307
  }
@@ -279,6 +329,7 @@ function readRtfHeader(tokens, sink) {
279
329
  const styles = /* @__PURE__ */ new Map();
280
330
  const listsById = /* @__PURE__ */ new Map();
281
331
  const overrides = /* @__PURE__ */ new Map();
332
+ const revisionAuthors = [];
282
333
  const page = {
283
334
  paperWidthTwips: DEFAULT_PAPER_WIDTH_TWIPS,
284
335
  paperHeightTwips: DEFAULT_PAPER_HEIGHT_TWIPS,
@@ -350,15 +401,18 @@ function readRtfHeader(tokens, sink) {
350
401
  case "listoverridetable":
351
402
  parseListOverrideTable(tokens, head.contentStart, groupEnd, overrides);
352
403
  break;
404
+ case "revtbl":
405
+ parseRevisionTable(tokens, head.contentStart, groupEnd, codepage, revisionAuthors, sink);
406
+ break;
353
407
  case "info": metadata = parseInfoGroup(tokens, head.contentStart, groupEnd, codepage, sink);
354
408
  }
355
409
  if (head.destination !== void 0 && HEADER_DESTINATIONS.has(head.destination)) bodyStartIndex = Math.max(bodyStartIndex, groupEnd + 1);
356
410
  index = groupEnd;
357
411
  }
358
412
  const lists = /* @__PURE__ */ new Map();
359
- for (const [overrideIndex, listId] of overrides) {
360
- const list = listsById.get(listId);
361
- if (list !== void 0) lists.set(overrideIndex, list);
413
+ for (const [overrideIndex, override] of overrides) {
414
+ const list = listsById.get(override.listId);
415
+ if (list !== void 0) lists.set(overrideIndex, applyListOverride(list, override.levelOverrides));
362
416
  }
363
417
  return {
364
418
  codepage,
@@ -367,6 +421,7 @@ function readRtfHeader(tokens, sink) {
367
421
  colors,
368
422
  styles,
369
423
  lists,
424
+ revisionAuthors,
370
425
  page,
371
426
  metadata,
372
427
  bodyStartIndex