rtf-codec 3.0.0 → 3.0.2

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.
package/README.md CHANGED
@@ -148,23 +148,24 @@ A `contentControl` construct mints a real `\*\formfield` only for the three cont
148
148
 
149
149
  Each of these is reported through a diagnostic rather than dropped silently — see [Diagnostics](#diagnostics).
150
150
 
151
- | Construct | Why |
152
- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
153
- | Headers, footers, footnotes, endnotes, annotations | `ContentDocument`'s flat form has no page-furniture or note position for them. A footnote's real home is `document-schema.js`'s tree-only `definitions` table, which a codec producing the flat form cannot reach. |
154
- | Content controls beyond RTF's own form-field vocabulary (richText, comboBox, date, picture, repeatingSection, button, index, group) | **RTF 1.9.1 specifies nothing for these.** It predates OOXML's `w:sdt`: its "Custom XML Tags" (`\xmlopen`/`\xmlclose`) are a bare namespace/name tag with no type, lock, alias or value, and `\*\datastore` is an opaque blob whose "format ... is unknown to RTF" by the spec's own words. `\*\formfield` (see the Scope table above) is the one real analogue RTF has, and covers plainText/checkbox/dropDown only. |
155
- | East Asian DBCS code pages (932, 936, 949, 950, 1361) | Each needs a ~20k-entry table and its own lead-byte state machine. A document declaring one decodes through cp1252 and says so. |
156
- | Code page 42 (`SYMBOL_CHARSET`) | Not an encoding: its bytes are glyph indices into whichever symbol font the run names, so there is no correct Unicode for them without that font's own cmap. |
157
- | Metafile and bitmap pictures (`\wmetafileN`, `\emfblip`, `\dibitmapN`, `\wbitmapN`, `\macpict`) | `ContentImageBlock` carries PNG and JPEG only. |
158
- | A picture with no stated size | `ContentImageBlock` requires a positive width and height, and deriving them from the payload would need an image decoder this package deliberately does not carry. |
159
- | Nested tables (`\nestcell`/`\nestrow`) | Read as ordinary cell content; the inner table's own structure is not reconstructed. |
160
- | Drawing objects (`\do`, `\shp`) | **A schema gap, not a container one.** These are Word's own native in-document vector-drawing layer, not an OLE embed -- there is no raw drawing-shape `ContentBlock` for a wordprocessing section's block flow to land in (only `ContentEmbeddedObjectBlock`, which names a whole embedded document, not a shape), so a `\do`/`\shp` construct is dropped regardless of the container work [Embedded objects](#embedded-objects) below did for `\object`. |
161
- | A real, foreign `\object`'s OLE data | This package's own `\objdata` payload round-trips fully (see [Embedded objects](#embedded-objects)); a real Word-authored OLESaveToStream structure (an actual embedded `.xls`/`.doc`/OLE-control payload) has no decoder here and degrades with a diagnostic, recovering `\result`'s own fallback paragraphs when present instead of the real object. |
162
- | Superscript/subscript (`\super`, `\sub`, `\upN`, `\dnN`), character scaling, kerning, background colour | **A schema gap, not an RTF one.** `ContentRun` carries no vertical-alignment field at all -- `epub-codec` reports the identical gap for its own `<sub>`/`<sup>`, and `ooxml.js`'s docx reader has no `w:vertAlign` handling either. Closing it is a change to `document-schema.js` and every codec that would then carry it, not to this one. |
163
- | Right-to-left text (`\rtlch`, `\ltrch`, `\rtlpar`, `\rtlrow`, `\rtldoc`) | The same shape of gap: no `ContentDocument` field carries text direction, at any of the four scopes RTF states it at. |
164
- | Cell vertical alignment (`\clvertalt`/`\clvertalc`/`\clvertalb`), diagonal cell borders (`\cldglu`/`\cldgll`), `\clshdngN` | `ContentTableCell.borders` has no diagonal member, so a diagonal rule is not a side; `\clshdngN`'s own shading percentage names a genuine two-colour pattern fill, which `document-schema.js`'s `ContentCellFill` can now express (ExaDev/documents.js#951) but this package does not yet resolve either `\clcbpatN`'s own foreground colour or `\clshdngN`'s percentage into one -- `\clcbpatN`'s background colour alone still reads and writes as a `'solid'` fill. |
165
- | A bookmark whose two halves straddle a table cell wall | `document-schema.js` ratifies this as a drop rather than a shape to repair: each block list is its own bracket scope, and pairing across two of them would need the marker ids its contract deliberately refuses. |
166
- | A contentControl extent that crosses another contentControl extent in the same paragraph | RTF's `\*\formfield` destination can only nest, never cross: a `{\field...}` group nests cleanly inside another one's own `\fldrslt`, but two extents that start-before/end-after each other have no valid brace sequence, since whichever closes second would close the other's own braces instead of its own. |
167
- | A `table` or `pageBreak` block placed directly inside a table cell | `writeCellBlocks` writes a cell's own content as a run of `\intbl` `<pict>`/`<obj>`/paragraph groups, plus any bracketing `constructStart`/`constructEnd` markers spliced in inline exactly as `writeBlock` does at the top level; an `image`/`embeddedObject` block borrows the identical `\intbl` shell a paragraph gets (a `\pict`/`\object` group inside an ordinary `\intbl` paragraph is a real, already-round-trippable shape -- see the tests around it), but a nested `table` needs its own `\itapN` row grammar this writer does not build, and a mid-row `\page` would `\pard`-reset the row's own `\intbl` state, so those two kinds are still dropped. |
151
+ | Construct | Why |
152
+ | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
153
+ | Headers, footers, footnotes, endnotes, annotations | `ContentDocument`'s flat form has no page-furniture or note position for them. A footnote's real home is `document-schema.js`'s tree-only `definitions` table, which a codec producing the flat form cannot reach. |
154
+ | Content controls beyond RTF's own form-field vocabulary (richText, comboBox, date, picture, repeatingSection, button, index, group) | **RTF 1.9.1 specifies nothing for these.** It predates OOXML's `w:sdt`: its "Custom XML Tags" (`\xmlopen`/`\xmlclose`) are a bare namespace/name tag with no type, lock, alias or value, and `\*\datastore` is an opaque blob whose "format ... is unknown to RTF" by the spec's own words. `\*\formfield` (see the Scope table above) is the one real analogue RTF has, and covers plainText/checkbox/dropDown only. |
155
+ | East Asian DBCS code pages (932, 936, 949, 950, 1361) | Each needs a ~20k-entry table and its own lead-byte state machine. A document declaring one decodes through cp1252 and says so. |
156
+ | Code page 42 (`SYMBOL_CHARSET`) | Not an encoding: its bytes are glyph indices into whichever symbol font the run names, so there is no correct Unicode for them without that font's own cmap. |
157
+ | Metafile and bitmap pictures (`\wmetafileN`, `\emfblip`, `\dibitmapN`, `\wbitmapN`, `\macpict`) | `ContentImageBlock` carries PNG and JPEG only. |
158
+ | A picture with no stated size | `ContentImageBlock` requires a positive width and height, and deriving them from the payload would need an image decoder this package deliberately does not carry. |
159
+ | Nested tables (`\nestcell`/`\nestrow`) | Read as ordinary cell content; the inner table's own structure is not reconstructed. |
160
+ | Drawing objects (`\do`, `\shp`) | **A schema gap, not a container one.** These are Word's own native in-document vector-drawing layer, not an OLE embed -- there is no raw drawing-shape `ContentBlock` for a wordprocessing section's block flow to land in (only `ContentEmbeddedObjectBlock`, which names a whole embedded document, not a shape), so a `\do`/`\shp` construct is dropped regardless of the container work [Embedded objects](#embedded-objects) below did for `\object`. |
161
+ | A real, foreign `\object`'s OLE data | This package's own `\objdata` payload round-trips fully (see [Embedded objects](#embedded-objects)); a real Word-authored OLESaveToStream structure (an actual embedded `.xls`/`.doc`/OLE-control payload) has no decoder here and degrades with a diagnostic, recovering `\result`'s own fallback paragraphs when present instead of the real object. |
162
+ | Superscript/subscript (`\super`, `\sub`, `\upN`, `\dnN`), character scaling, kerning, background colour | **A schema gap, not an RTF one.** `ContentRun` carries no vertical-alignment field at all -- `epub-codec` reports the identical gap for its own `<sub>`/`<sup>`, and `ooxml.js`'s docx reader has no `w:vertAlign` handling either. Closing it is a change to `document-schema.js` and every codec that would then carry it, not to this one. |
163
+ | Right-to-left text (`\rtlch`, `\ltrch`, `\rtlpar`, `\rtlrow`, `\rtldoc`) | The same shape of gap: no `ContentDocument` field carries text direction, at any of the four scopes RTF states it at. |
164
+ | Cell vertical alignment (`\clvertalt`/`\clvertalc`/`\clvertalb`), diagonal cell borders (`\cldglu`/`\cldgll`), `\clshdngN` | `ContentTableCell.borders` has no diagonal member, so a diagonal rule is not a side; `\clshdngN`'s own shading percentage names a genuine two-colour pattern fill, which `document-schema.js`'s `ContentCellFill` can now express (ExaDev/documents.js#951) but this package does not yet resolve either `\clcbpatN`'s own foreground colour or `\clshdngN`'s percentage into one -- `\clcbpatN`'s background colour alone still reads and writes as a `'solid'` fill. |
165
+ | A bookmark whose two halves straddle a table cell wall | `document-schema.js` ratifies this as a drop rather than a shape to repair: each block list is its own bracket scope, and pairing across two of them would need the marker ids its contract deliberately refuses. |
166
+ | A contentControl extent that crosses another contentControl extent in the same paragraph | RTF's `\*\formfield` destination can only nest, never cross: a `{\field...}` group nests cleanly inside another one's own `\fldrslt`, but two extents that start-before/end-after each other have no valid brace sequence, since whichever closes second would close the other's own braces instead of its own. |
167
+ | Two block-scoped bookmarks whose real ranges are disjoint but whose halves both land in the same paragraph (one's `\bkmkend`, the other's `\bkmkstart`) | A paragraph is this reader's finest addressable block-extent unit, so the shared paragraph's own block index gets claimed by both bookmarks' extents even though their real text never overlapped -- a genuine crossing pair, not a nesting one, and `document-schema.js`'s own construct group has no shape for that (a tree would need two subtrees crossing, which no tree holds). The later-starting bookmark is dropped with a diagnostic; the earlier one keeps its extent intact. |
168
+ | A `table` or `pageBreak` block placed directly inside a table cell | `writeCellBlocks` writes a cell's own content as a run of `\intbl` `<pict>`/`<obj>`/paragraph groups, plus any bracketing `constructStart`/`constructEnd` markers spliced in inline exactly as `writeBlock` does at the top level; an `image`/`embeddedObject` block borrows the identical `\intbl` shell a paragraph gets (a `\pict`/`\object` group inside an ordinary `\intbl` paragraph is a real, already-round-trippable shape -- see the tests around it), but a nested `table` needs its own `\itapN` row grammar this writer does not build, and a mid-row `\page` would `\pard`-reset the row's own `\intbl` state, so those two kinds are still dropped. |
168
169
 
169
170
  ## Embedded objects
170
171
 
package/dist/codec.d.cts CHANGED
@@ -1425,10 +1425,10 @@ declare const rtfContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, U
1425
1425
  endColumn: z.ZodNumber;
1426
1426
  }, z.core.$strip>>;
1427
1427
  type: z.ZodEnum<{
1428
- date: "date";
1429
- custom: "custom";
1430
1428
  decimal: "decimal";
1431
1429
  list: "list";
1430
+ date: "date";
1431
+ custom: "custom";
1432
1432
  time: "time";
1433
1433
  whole: "whole";
1434
1434
  textLength: "textLength";
package/dist/codec.d.ts CHANGED
@@ -1425,10 +1425,10 @@ declare const rtfContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, U
1425
1425
  endColumn: z.ZodNumber;
1426
1426
  }, z.core.$strip>>;
1427
1427
  type: z.ZodEnum<{
1428
- date: "date";
1429
- custom: "custom";
1430
1428
  decimal: "decimal";
1431
1429
  list: "list";
1430
+ date: "date";
1431
+ custom: "custom";
1432
1432
  time: "time";
1433
1433
  whole: "whole";
1434
1434
  textLength: "textLength";
@@ -1,4 +1,4 @@
1
- import { a as RtfDiagnosticSink } from "./diagnostics-CjMoO7x1.cjs";
1
+ import { a as RtfDiagnosticSink } from "./diagnostics-DWEjJXeQ.cjs";
2
2
  //#region src/codepage.d.ts
3
3
  declare const DEFAULT_CODEPAGE = 1252;
4
4
  declare const UTF8_CODEPAGE = 65001;
@@ -1,4 +1,4 @@
1
- import { a as RtfDiagnosticSink } from "./diagnostics-CjMoO7x1.js";
1
+ import { a as RtfDiagnosticSink } from "./diagnostics-DWEjJXeQ.js";
2
2
  //#region src/codepage.d.ts
3
3
  declare const DEFAULT_CODEPAGE = 1252;
4
4
  declare const UTF8_CODEPAGE = 65001;
@@ -21,6 +21,7 @@ declare const RtfDiagnosticCodes: {
21
21
  readonly NESTED_TABLE_FLATTENED: "rtf/nested-table-flattened";
22
22
  readonly SECTION_BREAK_UNREPRESENTED: "rtf/section-break-unrepresented";
23
23
  readonly BOOKMARK_UNPAIRED: "rtf/bookmark-unpaired";
24
+ readonly BLOCK_CONSTRUCT_EXTENTS_CROSSED: "rtf/block-construct-extents-crossed";
24
25
  readonly FORM_FIELD_SPAN_DROPPED: "rtf/form-field-span-dropped";
25
26
  readonly FORM_FIELD_KEYWORD_LOST: "rtf/form-field-keyword-lost";
26
27
  readonly CONSTRUCT_UNREPRESENTED: "rtf/construct-unrepresented";
@@ -21,6 +21,7 @@ declare const RtfDiagnosticCodes: {
21
21
  readonly NESTED_TABLE_FLATTENED: "rtf/nested-table-flattened";
22
22
  readonly SECTION_BREAK_UNREPRESENTED: "rtf/section-break-unrepresented";
23
23
  readonly BOOKMARK_UNPAIRED: "rtf/bookmark-unpaired";
24
+ readonly BLOCK_CONSTRUCT_EXTENTS_CROSSED: "rtf/block-construct-extents-crossed";
24
25
  readonly FORM_FIELD_SPAN_DROPPED: "rtf/form-field-span-dropped";
25
26
  readonly FORM_FIELD_KEYWORD_LOST: "rtf/form-field-keyword-lost";
26
27
  readonly CONSTRUCT_UNREPRESENTED: "rtf/construct-unrepresented";
@@ -14,6 +14,7 @@ const RtfDiagnosticCodes = {
14
14
  NESTED_TABLE_FLATTENED: "rtf/nested-table-flattened",
15
15
  SECTION_BREAK_UNREPRESENTED: "rtf/section-break-unrepresented",
16
16
  BOOKMARK_UNPAIRED: "rtf/bookmark-unpaired",
17
+ BLOCK_CONSTRUCT_EXTENTS_CROSSED: "rtf/block-construct-extents-crossed",
17
18
  FORM_FIELD_SPAN_DROPPED: "rtf/form-field-span-dropped",
18
19
  FORM_FIELD_KEYWORD_LOST: "rtf/form-field-keyword-lost",
19
20
  CONSTRUCT_UNREPRESENTED: "rtf/construct-unrepresented",
@@ -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-CjMoO7x1.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-DWEjJXeQ.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-CjMoO7x1.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-DWEjJXeQ.js";
2
2
  export { NOOP_RTF_DIAGNOSTIC_SINK, RtfDiagnostic, RtfDiagnosticCodes, RtfDiagnosticSeverity, RtfDiagnosticSink, RtfInputTooLargeError, RtfNestingLimitExceededError, RtfNotAnRtfDocumentError, RtfParseError, RtfUnsupportedDocumentKindError, RtfWriteError };
@@ -13,6 +13,7 @@ const RtfDiagnosticCodes = {
13
13
  NESTED_TABLE_FLATTENED: "rtf/nested-table-flattened",
14
14
  SECTION_BREAK_UNREPRESENTED: "rtf/section-break-unrepresented",
15
15
  BOOKMARK_UNPAIRED: "rtf/bookmark-unpaired",
16
+ BLOCK_CONSTRUCT_EXTENTS_CROSSED: "rtf/block-construct-extents-crossed",
16
17
  FORM_FIELD_SPAN_DROPPED: "rtf/form-field-span-dropped",
17
18
  FORM_FIELD_KEYWORD_LOST: "rtf/form-field-keyword-lost",
18
19
  CONSTRUCT_UNREPRESENTED: "rtf/construct-unrepresented",
package/dist/header.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as RtfDiagnosticSink } from "./diagnostics-CjMoO7x1.cjs";
1
+ import { a as RtfDiagnosticSink } from "./diagnostics-DWEjJXeQ.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-CjMoO7x1.js";
1
+ import { a as RtfDiagnosticSink } from "./diagnostics-DWEjJXeQ.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-CjMoO7x1.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-DWEjJXeQ.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-CjMoO7x1.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-DWEjJXeQ.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-CjMoO7x1.cjs";
1
+ import { a as RtfDiagnosticSink } from "./diagnostics-DWEjJXeQ.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-CjMoO7x1.js";
1
+ import { a as RtfDiagnosticSink } from "./diagnostics-DWEjJXeQ.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;
package/dist/read.cjs CHANGED
@@ -275,9 +275,24 @@ function skipUnicodeFallback(tokens, from, count) {
275
275
  textOffset
276
276
  };
277
277
  }
278
- function insertConstructMarkers(blocks, extents) {
278
+ function dropCrossingExtents(ordered, sink) {
279
+ const kept = [];
280
+ for (const candidate of ordered) {
281
+ if (kept.some((extent) => candidate.startIndex < extent.endIndex && candidate.endIndex > extent.endIndex)) {
282
+ sink({
283
+ code: require_diagnostics.RtfDiagnosticCodes.BLOCK_CONSTRUCT_EXTENTS_CROSSED,
284
+ severity: "warning",
285
+ message: `a '${candidate.descriptor.kind}' construct's own block extent crosses an already-open one instead of nesting inside or sitting disjoint from it -- both bookmarks likely closed and opened within the same paragraph, which this reader cannot express as two separate extents, so this one is dropped`
286
+ });
287
+ continue;
288
+ }
289
+ kept.push(candidate);
290
+ }
291
+ return kept;
292
+ }
293
+ function insertConstructMarkers(blocks, extents, sink) {
279
294
  if (extents.length === 0) return [...blocks];
280
- const ordered = [...extents].sort((left, right) => left.startIndex - right.startIndex || right.endIndex - left.endIndex);
295
+ const ordered = dropCrossingExtents([...extents].sort((left, right) => left.startIndex - right.startIndex || right.endIndex - left.endIndex), sink);
281
296
  const closing = [...ordered].reverse();
282
297
  const out = [];
283
298
  for (let index = 0; index <= blocks.length; index += 1) {
@@ -560,7 +575,7 @@ var ContentBuilder = class {
560
575
  endCell(para) {
561
576
  this.endParagraph(para, false);
562
577
  this.flushClosingBookmarks(true, this.cellBlocks.length);
563
- this.rowCells.push({ blocks: insertConstructMarkers(this.cellBlocks, this.cellBlockExtents) });
578
+ this.rowCells.push({ blocks: insertConstructMarkers(this.cellBlocks, this.cellBlockExtents, this.sink) });
564
579
  this.cellBlocks = [];
565
580
  this.cellBlockExtents = [];
566
581
  }
@@ -742,7 +757,7 @@ var ContentBuilder = class {
742
757
  this.closeTable();
743
758
  this.flushClosingBookmarks(false, this.blocks.length);
744
759
  this.reportUnclosedBookmarks();
745
- const blocks = insertConstructMarkers(this.blocks, this.sectionBlockExtents);
760
+ const blocks = insertConstructMarkers(this.blocks, this.sectionBlockExtents, this.sink);
746
761
  this.sectionBlockExtents = [];
747
762
  if (blocks.length === 0 && this.sections.length > 0) {
748
763
  this.blocks = [];
package/dist/read.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as RtfDiagnostic } from "./diagnostics-CjMoO7x1.cjs";
1
+ import { n as RtfDiagnostic } from "./diagnostics-DWEjJXeQ.cjs";
2
2
  import { ReadRtfOptions } from "./options.cjs";
3
3
  import { ContentDocument, DocumentTree } from "document-schema.js";
4
4
  //#region src/read.d.ts
package/dist/read.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as RtfDiagnostic } from "./diagnostics-CjMoO7x1.js";
1
+ import { n as RtfDiagnostic } from "./diagnostics-DWEjJXeQ.js";
2
2
  import { ReadRtfOptions } from "./options.js";
3
3
  import { ContentDocument, DocumentTree } from "document-schema.js";
4
4
  //#region src/read.d.ts
package/dist/read.js CHANGED
@@ -274,9 +274,24 @@ function skipUnicodeFallback(tokens, from, count) {
274
274
  textOffset
275
275
  };
276
276
  }
277
- function insertConstructMarkers(blocks, extents) {
277
+ function dropCrossingExtents(ordered, sink) {
278
+ const kept = [];
279
+ for (const candidate of ordered) {
280
+ if (kept.some((extent) => candidate.startIndex < extent.endIndex && candidate.endIndex > extent.endIndex)) {
281
+ sink({
282
+ code: RtfDiagnosticCodes.BLOCK_CONSTRUCT_EXTENTS_CROSSED,
283
+ severity: "warning",
284
+ message: `a '${candidate.descriptor.kind}' construct's own block extent crosses an already-open one instead of nesting inside or sitting disjoint from it -- both bookmarks likely closed and opened within the same paragraph, which this reader cannot express as two separate extents, so this one is dropped`
285
+ });
286
+ continue;
287
+ }
288
+ kept.push(candidate);
289
+ }
290
+ return kept;
291
+ }
292
+ function insertConstructMarkers(blocks, extents, sink) {
278
293
  if (extents.length === 0) return [...blocks];
279
- const ordered = [...extents].sort((left, right) => left.startIndex - right.startIndex || right.endIndex - left.endIndex);
294
+ const ordered = dropCrossingExtents([...extents].sort((left, right) => left.startIndex - right.startIndex || right.endIndex - left.endIndex), sink);
280
295
  const closing = [...ordered].reverse();
281
296
  const out = [];
282
297
  for (let index = 0; index <= blocks.length; index += 1) {
@@ -559,7 +574,7 @@ var ContentBuilder = class {
559
574
  endCell(para) {
560
575
  this.endParagraph(para, false);
561
576
  this.flushClosingBookmarks(true, this.cellBlocks.length);
562
- this.rowCells.push({ blocks: insertConstructMarkers(this.cellBlocks, this.cellBlockExtents) });
577
+ this.rowCells.push({ blocks: insertConstructMarkers(this.cellBlocks, this.cellBlockExtents, this.sink) });
563
578
  this.cellBlocks = [];
564
579
  this.cellBlockExtents = [];
565
580
  }
@@ -741,7 +756,7 @@ var ContentBuilder = class {
741
756
  this.closeTable();
742
757
  this.flushClosingBookmarks(false, this.blocks.length);
743
758
  this.reportUnclosedBookmarks();
744
- const blocks = insertConstructMarkers(this.blocks, this.sectionBlockExtents);
759
+ const blocks = insertConstructMarkers(this.blocks, this.sectionBlockExtents, this.sink);
745
760
  this.sectionBlockExtents = [];
746
761
  if (blocks.length === 0 && this.sections.length > 0) {
747
762
  this.blocks = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rtf-codec",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "Hand-written Rich Text Format (RTF 1.9.1) reader and writer against the shared document-schema.js content pivot.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -80,8 +80,8 @@
80
80
  "license": "MIT",
81
81
  "packageManager": "pnpm@11.6.0",
82
82
  "dependencies": {
83
- "archive-codec": "^1.6.0",
84
- "document-schema.js": "^6.1.0",
83
+ "archive-codec": "^1.6.2",
84
+ "document-schema.js": "^6.2.1",
85
85
  "zod": "^4.4.3"
86
86
  },
87
87
  "devDependencies": {