wpd-codec 3.1.0 → 3.2.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.
- package/README.md +30 -26
- package/dist/bytes/view.cjs +5 -0
- package/dist/bytes/view.d.cts +2 -1
- package/dist/bytes/view.d.ts +2 -1
- package/dist/bytes/view.js +5 -1
- package/dist/container/prefix.cjs +15 -0
- package/dist/container/prefix.d.cts +3 -1
- package/dist/container/prefix.d.ts +3 -1
- package/dist/container/prefix.js +14 -1
- package/dist/{diagnostics-CR0pXOyb.d.cts → diagnostics-Dtb2uPw4.d.cts} +5 -0
- package/dist/{diagnostics-CR0pXOyb.d.ts → diagnostics-Dtb2uPw4.d.ts} +5 -0
- package/dist/diagnostics.cjs +6 -1
- package/dist/diagnostics.d.cts +1 -1
- package/dist/diagnostics.d.ts +1 -1
- package/dist/diagnostics.js +6 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/read.cjs +213 -48
- package/dist/read.d.cts +1 -1
- package/dist/read.d.ts +1 -1
- package/dist/read.js +215 -50
- package/dist/stream/box.cjs +122 -0
- package/dist/stream/box.d.cts +20 -0
- package/dist/stream/box.d.ts +20 -0
- package/dist/stream/box.js +117 -0
- package/dist/stream/formula.cjs +286 -0
- package/dist/stream/formula.d.cts +4 -0
- package/dist/stream/formula.d.ts +4 -0
- package/dist/stream/formula.js +285 -0
- package/dist/stream/style.cjs +19 -0
- package/dist/stream/style.d.cts +3 -1
- package/dist/stream/style.d.ts +3 -1
- package/dist/stream/style.js +18 -1
- package/dist/stream/table.cjs +2 -1
- package/dist/stream/table.d.cts +2 -1
- package/dist/stream/table.d.ts +2 -1
- package/dist/stream/table.js +2 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -77,26 +77,28 @@ Structural nonconformance is not a diagnostic — it throws. `WpdNotAWordPerfect
|
|
|
77
77
|
|
|
78
78
|
Every module is importable by package-relative path as well as through the barrel — `tsdown` builds one dist file per src module (`root: 'src'`, the layout `archive-codec` and `ooxml.js` also ship), and `package.json`'s `./*` exports wildcard maps each subpath onto it. The smoke suite is the guard on that advertisement: it loads each module below from the built `dist/` in both module systems.
|
|
79
79
|
|
|
80
|
-
| Module | Exports
|
|
81
|
-
| --------------------- |
|
|
82
|
-
| `read` | `readWpdContent` (bytes to `ContentDocument`), `readWpd` (bytes to `DocumentTree`), `ReadWpdOptions`
|
|
83
|
-
| `codec` | `wpdContentCodec` (`ContentCodec`), `WpdBytesSchema`
|
|
84
|
-
| `format` | `WPD_MEDIA_TYPE`, `WPD_FILE_EXTENSION`
|
|
85
|
-
| `diagnostics` | `WpdDiagnostic`, `WpdDiagnosticSink`, `WpdDiagnosticCodes`, `NOOP_WPD_DIAGNOSTIC_SINK`
|
|
86
|
-
| `errors` | `WpdFormatError` and its three subclasses
|
|
87
|
-
| `container/container` | `openWpdDocument` (container, header, packets, and document-area bounds in one), `PERFECT_OFFICE_MAIN_STREAM`, `PERFECT_OFFICE_OBJECTS_STORAGE`
|
|
88
|
-
| `container/header` | `readFileHeader`, `hasWordPerfectFileId`, `WPD_FILE_ID`, `WPD_PREFIX_HEADER_SIZE`
|
|
89
|
-
| `container/prefix` | `readPrefixPackets`, `packetByPrefixId`, `readTypefaceName`, `WPD_INDEX_RECORD_SIZE`, `PACKET_TYPE_DESIRED_FONT_DESCRIPTOR`
|
|
90
|
-
| `container/summary` | `readDocumentSummary` (the Extended Document Summary packet as a `LayoutMetadata`), `PACKET_TYPE_EXTENDED_DOCUMENT_SUMMARY`
|
|
91
|
-
| `stream/tokenise` | `tokeniseDocumentArea` and the four token types
|
|
92
|
-
| `stream/characters` | `decodeWpCharacter`, `decodeSingleByteCharacter`, `decodeWordString`, `UNMAPPED_CHARACTER`
|
|
93
|
-
| `stream/eol` | `eolMappingForSubfunction`, `subfunctionForSingleByteEol`, `isSingleByteEol`
|
|
94
|
-
| `stream/attributes` | `decodeAttributeByte`, `runAttributesFrom`, `WpdAttribute`
|
|
95
|
-
| `stream/units` | `pointsFromWpu`, `WPU_PER_INCH`, `POINTS_PER_INCH`
|
|
96
|
-
| `stream/page` | `readPageForm`, `readMarginPt`, the Page and Column group constants, and the WordPerfect default page
|
|
97
|
-
| `stream/style` | `styleSemanticsFor`, `readSystemStyleNumber`, the style scope predicates, and the Display Number group's paragraph-number pair
|
|
98
|
-
| `stream/table` | `readEmbeddedSubfunctions`, `readTableColumnWidthPt`, `readRowInformation`, `readCellInformation`, `readCellSpanning`, `readCellFill`
|
|
99
|
-
| `stream/
|
|
80
|
+
| Module | Exports |
|
|
81
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
82
|
+
| `read` | `readWpdContent` (bytes to `ContentDocument`), `readWpd` (bytes to `DocumentTree`), `ReadWpdOptions` |
|
|
83
|
+
| `codec` | `wpdContentCodec` (`ContentCodec`), `WpdBytesSchema` |
|
|
84
|
+
| `format` | `WPD_MEDIA_TYPE`, `WPD_FILE_EXTENSION` |
|
|
85
|
+
| `diagnostics` | `WpdDiagnostic`, `WpdDiagnosticSink`, `WpdDiagnosticCodes`, `NOOP_WPD_DIAGNOSTIC_SINK` |
|
|
86
|
+
| `errors` | `WpdFormatError` and its three subclasses |
|
|
87
|
+
| `container/container` | `openWpdDocument` (container, header, packets, and document-area bounds in one), `PERFECT_OFFICE_MAIN_STREAM`, `PERFECT_OFFICE_OBJECTS_STORAGE` |
|
|
88
|
+
| `container/header` | `readFileHeader`, `hasWordPerfectFileId`, `WPD_FILE_ID`, `WPD_PREFIX_HEADER_SIZE` |
|
|
89
|
+
| `container/prefix` | `readPrefixPackets`, `packetByPrefixId`, `readTypefaceName`, `readGeneralWpTextBlocks`, `WPD_INDEX_RECORD_SIZE`, `PACKET_TYPE_DESIRED_FONT_DESCRIPTOR`, `PACKET_TYPE_GENERAL_WP_TEXT` |
|
|
90
|
+
| `container/summary` | `readDocumentSummary` (the Extended Document Summary packet as a `LayoutMetadata`), `PACKET_TYPE_EXTENDED_DOCUMENT_SUMMARY` |
|
|
91
|
+
| `stream/tokenise` | `tokeniseDocumentArea` and the four token types |
|
|
92
|
+
| `stream/characters` | `decodeWpCharacter`, `decodeSingleByteCharacter`, `decodeWordString`, `UNMAPPED_CHARACTER` |
|
|
93
|
+
| `stream/eol` | `eolMappingForSubfunction`, `subfunctionForSingleByteEol`, `isSingleByteEol` |
|
|
94
|
+
| `stream/attributes` | `decodeAttributeByte`, `runAttributesFrom`, `WpdAttribute` |
|
|
95
|
+
| `stream/units` | `pointsFromWpu`, `WPU_PER_INCH`, `POINTS_PER_INCH` |
|
|
96
|
+
| `stream/page` | `readPageForm`, `readMarginPt`, the Page and Column group constants, and the WordPerfect default page |
|
|
97
|
+
| `stream/style` | `styleSemanticsFor`, `readSystemStyleNumber`, `readStyleBeginBlock`, the style scope predicates, `PACKET_TYPE_NORMAL_STYLE`, and the Display Number group's paragraph-number pair |
|
|
98
|
+
| `stream/table` | `readEmbeddedSubfunctions`, `readTableColumnWidthPt`, `readRowInformation`, `readCellInformation`, `readCellSpanning`, `readCellFill`, `CELL_FORMULA_SUBFUNCTION` |
|
|
99
|
+
| `stream/formula` | `readTableFormula` (a New Cell Formula embedded subfunction's own tokenised formula to its own linear text) |
|
|
100
|
+
| `stream/box` | `readBoxContent` (a box function's own override-flag walk to its content type, content prefix ID, and frame), the box content type constants |
|
|
101
|
+
| `stream/tab` | `tabEffectFor`, `TAB_GROUP`, `WpdTabEffect` |
|
|
100
102
|
|
|
101
103
|
The container and stream layers are public deliberately, not by accident: a consumer inspecting a WordPerfect file — a migration audit, a forensic tool, a reader for a construct this package does not yet lift into the shared schema — needs the parsed prefix and the raw function stream, not only the document they fold into.
|
|
102
104
|
|
|
@@ -163,18 +165,20 @@ This is a bet against libwpd's _code_, not against citing its _data_: the charac
|
|
|
163
165
|
- **Outline numbering**, from the Display Number group's Paragraph Number Display pair: the level becomes a list membership and the pair's rendered digits are dropped in favour of it, since a counter's display is generated content rather than typed text.
|
|
164
166
|
- **Document metadata**, from the Extended Document Summary prefix packet (type 0x12): the Descriptive Name as the title, plus author, subject, keywords, and the creation and revision dates.
|
|
165
167
|
- **Tabs and line-scoped alignment**, from the Tab group (0xE0), whose byte in the subfunction position is the tab definition itself rather than a subfunction number. A type that advances to a tab stop becomes a tab character; centre-on-margins, centre-on-current-position and flush-right instead begin the line-scoped alignment the single-byte End of Center Align functions already terminate.
|
|
168
|
+
- **Style packets** (the 0xDD group's own type-0x30 definitions), beyond their system style numbers: a style scope opened with a prefix ID resolves that packet and applies its own "beginning style text" block — font face/size/colour changes, attribute on/off — exactly as if the author had typed those codes at the point the scope opened, restoring the pre-scope formatting when the scope closes. See `src/stream/style.ts`'s own `readStyleBeginBlock`.
|
|
169
|
+
- **Boxes** whose content resolves to a General WP Text packet (type 0x08): a text or linked-text box lifts into an embedded `wordprocessing` document (`ContentEmbeddedObjectBlock`), read through the identical tokeniser and fold the main document area uses; an equation box's own notation — WordPerfect's own equation-editor syntax, neither MathML nor LaTeX — is carried verbatim as `ContentFormula`'s quarantined residue (`source: { format: 'wpd', xml }`) rather than mistranslated into either. A box's real content is always named by its own function-level override (the box override-flag walk in `src/stream/box.ts`), never by its template, so a box with no content override genuinely has nothing to lift. Frame position and size are read from that same override when it states an absolute page-space offset and an explicit width/height; a box relying on its template's own inherited geometry is not lifted (see Remaining scope).
|
|
170
|
+
- **Merge fields** (the Merge group's FIELD On/Off pair, 0xDE 0x4C/0x4D): tagged as a `field` construct (document-schema.js's `RunConstructExtent`/`FieldDescriptor`) on the paragraph the field sits in, `instruction` being the field's own displayed placeholder text — which stays in the run flow exactly as WordPerfect itself displays a template's own field codes, now tagged as a placeholder rather than indistinguishable prose.
|
|
171
|
+
- **Table formulas** (`WPFF_TableFormulas`): a New Cell Formula embedded subfunction's own tokenised formula decodes to its own linear text on `ContentTableCell.formula`, carried verbatim in a spreadsheet-style cell-reference spelling (`A1`, `$A$1:B3`) — the same "structure yes, formula content no" boundary `ContentSheetCell.formula` already draws elsewhere in the family. See `src/stream/formula.ts`'s own top-of-file comment for why this is a linear substitution rather than an RPN evaluation, and for the honest-or-nothing contract that aborts the whole formula rather than guessing at an undocumented code.
|
|
166
172
|
|
|
167
173
|
### Remaining scope
|
|
168
174
|
|
|
169
175
|
Everything below is recognised by the tokeniser and skipped by the fold, so a document containing it still reads — losing that construct's own structure, never the surrounding text. Each is reported through the diagnostic sink rather than passed over in silence.
|
|
170
176
|
|
|
171
|
-
- **
|
|
172
|
-
- **
|
|
173
|
-
- **
|
|
174
|
-
- **Styles** (the 0xDD group) beyond their system style numbers: a run's directly-applied attributes are read and a style region's own heading or outline level is recovered, but a style packet's own definitions (type 0x30) are not resolved onto the runs that reference them.
|
|
177
|
+
- **Headers, footers, footnotes, and endnotes** (the 0xD6 and 0xD7 groups). Reported through `wpd/header-footer-dropped` and `wpd/note-dropped`. The text is genuinely recoverable — each function names a General WP Text packet (type 0x08) holding its own function-code stream, which this package's tokeniser and fold would read (the same packet type boxes now resolve their own text content through) — but the flat `ContentDocument` has no page-furniture position for a header or footer and no note position for a footnote body. That body's real home is `document-schema.js`'s tree-only `definitions` table, which a codec producing the flat form cannot reach; it is the same gap `rtf-codec` documents for its own equivalent constructs, and it closes at the schema boundary rather than here — the one gap in this list that stays blocked pending a DocumentTree-producing wpd-codec, distinct from every other entry, which is a parsing-effort gap rather than a schema-shape one.
|
|
178
|
+
- **A box whose content is an image, presentation, video, macro, sound, or external payload**, and a box relying on its own template's inherited geometry rather than an explicit function-level position/size override. Reported through `wpd/box-content-unresolved` and `wpd/box-frame-unresolved` respectively. An image box's own content resolves to a Graphics Filename prefix packet (type 0x40) whose children carry either WPG vector graphics (a distinct binary graphics format `ContentImageBlock`'s `png`/`jpeg`/`svg`/`gif` set cannot hold as recovered, and which this package does not decode — a project on the scale of this package's own WordPerfect reader, not a wiring job) or a native OLE object (see the next bullet). A box with no function-level content override at all — relying entirely on its template's own rendering defaults — is reported through `wpd/box-dropped`, unchanged from before.
|
|
179
|
+
- **Embedded OLE objects**, stored under the compound file's `PerfectOffice_OBJECTS` storage and named by an image box's Graphics Filename packet's own `0x70`/`0x71` (OLE Object Descriptor / OLE Object Data) children. `archive-codec`'s compound-file reader already reaches that storage, which is how `ooxml.js` recovers a ZIP-payload embedded object — but a WordPerfect OLE object's payload is a native OLE server's own stream rather than a nested document package (`ooxml.js`'s own equivalent case, a classic OLE1 `.bin` payload with no `Package` stream, stays opaque by the identical scope boundary), so recovering one generically is a project in its own right, not a wiring job.
|
|
175
180
|
- **The counter groups** (0xD8, 0xD9, 0xDB, 0xDC): setting, numbering-method, increment and decrement carry no text and change no structure this reader models, so only the Display Number group's own paragraph-number pair is read.
|
|
176
|
-
- **
|
|
177
|
-
- **Table formulas** (`WPFF_TableFormulas`): the New Cell Formula embedded subfunction is walked past by its own length so the cells around it still read, but its tokenised formula is not decoded.
|
|
181
|
+
- **Every merge subfunction other than FIELD** (ASSIGN, CALL, IF, FOR, CASE, and the rest of WordPerfect's own merge scripting language) and **cross-references** (0xD5). A cross-reference's displayed text survives as ordinary text; its target binding does not. Reported through `wpd/merge-code-dropped` and `wpd/cross-reference-flattened`. Unlike FIELD, these can legitimately wrap whole paragraphs of body text as control flow, which the run-scoped field construct's own one-paragraph extent cannot express regardless — a schema gap for a scripting language's control flow, not a parsing gap.
|
|
178
182
|
- **Encrypted documents**, which throw: the specification states that nothing beyond the file header is intelligible without the password, so there is no partial read to offer.
|
|
179
183
|
|
|
180
184
|
## Evidence
|
package/dist/bytes/view.cjs
CHANGED
|
@@ -9,6 +9,10 @@ function byteAt(bytes, offset) {
|
|
|
9
9
|
function uint16At(bytes, offset) {
|
|
10
10
|
return byteAt(bytes, offset) | byteAt(bytes, offset + 1) << 8;
|
|
11
11
|
}
|
|
12
|
+
function int16At(bytes, offset) {
|
|
13
|
+
const value = uint16At(bytes, offset);
|
|
14
|
+
return value > 32767 ? value - 65536 : value;
|
|
15
|
+
}
|
|
12
16
|
function uint32At(bytes, offset) {
|
|
13
17
|
return byteAt(bytes, offset) + byteAt(bytes, offset + 1) * 256 + byteAt(bytes, offset + 2) * 65536 + byteAt(bytes, offset + 3) * 16777216;
|
|
14
18
|
}
|
|
@@ -18,6 +22,7 @@ function sliceAt(bytes, offset, length) {
|
|
|
18
22
|
}
|
|
19
23
|
//#endregion
|
|
20
24
|
exports.byteAt = byteAt;
|
|
25
|
+
exports.int16At = int16At;
|
|
21
26
|
exports.sliceAt = sliceAt;
|
|
22
27
|
exports.uint16At = uint16At;
|
|
23
28
|
exports.uint32At = uint32At;
|
package/dist/bytes/view.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
//#region src/bytes/view.d.ts
|
|
2
2
|
declare function byteAt(bytes: Uint8Array, offset: number): number;
|
|
3
3
|
declare function uint16At(bytes: Uint8Array, offset: number): number;
|
|
4
|
+
declare function int16At(bytes: Uint8Array, offset: number): number;
|
|
4
5
|
declare function uint32At(bytes: Uint8Array, offset: number): number;
|
|
5
6
|
declare function sliceAt(bytes: Uint8Array, offset: number, length: number): Uint8Array;
|
|
6
7
|
//#endregion
|
|
7
|
-
export { byteAt, sliceAt, uint16At, uint32At };
|
|
8
|
+
export { byteAt, int16At, sliceAt, uint16At, uint32At };
|
package/dist/bytes/view.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
//#region src/bytes/view.d.ts
|
|
2
2
|
declare function byteAt(bytes: Uint8Array, offset: number): number;
|
|
3
3
|
declare function uint16At(bytes: Uint8Array, offset: number): number;
|
|
4
|
+
declare function int16At(bytes: Uint8Array, offset: number): number;
|
|
4
5
|
declare function uint32At(bytes: Uint8Array, offset: number): number;
|
|
5
6
|
declare function sliceAt(bytes: Uint8Array, offset: number, length: number): Uint8Array;
|
|
6
7
|
//#endregion
|
|
7
|
-
export { byteAt, sliceAt, uint16At, uint32At };
|
|
8
|
+
export { byteAt, int16At, sliceAt, uint16At, uint32At };
|
package/dist/bytes/view.js
CHANGED
|
@@ -8,6 +8,10 @@ function byteAt(bytes, offset) {
|
|
|
8
8
|
function uint16At(bytes, offset) {
|
|
9
9
|
return byteAt(bytes, offset) | byteAt(bytes, offset + 1) << 8;
|
|
10
10
|
}
|
|
11
|
+
function int16At(bytes, offset) {
|
|
12
|
+
const value = uint16At(bytes, offset);
|
|
13
|
+
return value > 32767 ? value - 65536 : value;
|
|
14
|
+
}
|
|
11
15
|
function uint32At(bytes, offset) {
|
|
12
16
|
return byteAt(bytes, offset) + byteAt(bytes, offset + 1) * 256 + byteAt(bytes, offset + 2) * 65536 + byteAt(bytes, offset + 3) * 16777216;
|
|
13
17
|
}
|
|
@@ -16,4 +20,4 @@ function sliceAt(bytes, offset, length) {
|
|
|
16
20
|
return bytes.subarray(offset, offset + length);
|
|
17
21
|
}
|
|
18
22
|
//#endregion
|
|
19
|
-
export { byteAt, sliceAt, uint16At, uint32At };
|
|
23
|
+
export { byteAt, int16At, sliceAt, uint16At, uint32At };
|
|
@@ -50,6 +50,19 @@ function packetByPrefixId(packets, prefixId) {
|
|
|
50
50
|
}
|
|
51
51
|
const TYPEFACE_NAME_LENGTH_OFFSET = 22;
|
|
52
52
|
const TYPEFACE_NAME_OFFSET = 24;
|
|
53
|
+
const PACKET_TYPE_GENERAL_WP_TEXT = 8;
|
|
54
|
+
function readGeneralWpTextBlocks(bytes) {
|
|
55
|
+
if (bytes.length < 4) return;
|
|
56
|
+
const blockCount = require_bytes_view.uint16At(bytes, 0);
|
|
57
|
+
const firstBlockOffset = require_bytes_view.uint16At(bytes, 2);
|
|
58
|
+
if (blockCount === 0) return;
|
|
59
|
+
if (4 + blockCount * 2 > bytes.length) return;
|
|
60
|
+
let totalSize = 0;
|
|
61
|
+
for (let index = 0; index < blockCount; index += 1) totalSize += require_bytes_view.uint16At(bytes, 4 + index * 2);
|
|
62
|
+
const end = firstBlockOffset + totalSize;
|
|
63
|
+
if (firstBlockOffset < 0 || end > bytes.length) return;
|
|
64
|
+
return bytes.subarray(firstBlockOffset, end);
|
|
65
|
+
}
|
|
53
66
|
function readTypefaceName(packet) {
|
|
54
67
|
if (packet.length < TYPEFACE_NAME_OFFSET) return;
|
|
55
68
|
const nameLength = require_bytes_view.uint16At(packet, TYPEFACE_NAME_LENGTH_OFFSET);
|
|
@@ -60,7 +73,9 @@ function readTypefaceName(packet) {
|
|
|
60
73
|
}
|
|
61
74
|
//#endregion
|
|
62
75
|
exports.PACKET_TYPE_DESIRED_FONT_DESCRIPTOR = PACKET_TYPE_DESIRED_FONT_DESCRIPTOR;
|
|
76
|
+
exports.PACKET_TYPE_GENERAL_WP_TEXT = PACKET_TYPE_GENERAL_WP_TEXT;
|
|
63
77
|
exports.WPD_INDEX_RECORD_SIZE = WPD_INDEX_RECORD_SIZE;
|
|
64
78
|
exports.packetByPrefixId = packetByPrefixId;
|
|
79
|
+
exports.readGeneralWpTextBlocks = readGeneralWpTextBlocks;
|
|
65
80
|
exports.readPrefixPackets = readPrefixPackets;
|
|
66
81
|
exports.readTypefaceName = readTypefaceName;
|
|
@@ -13,6 +13,8 @@ interface WpdPrefixPacket {
|
|
|
13
13
|
}
|
|
14
14
|
declare function readPrefixPackets(bytes: Uint8Array, header: WpdFileHeader): WpdPrefixPacket[];
|
|
15
15
|
declare function packetByPrefixId(packets: readonly WpdPrefixPacket[], prefixId: number): WpdPrefixPacket | undefined;
|
|
16
|
+
declare const PACKET_TYPE_GENERAL_WP_TEXT = 8;
|
|
17
|
+
declare function readGeneralWpTextBlocks(bytes: Uint8Array): Uint8Array | undefined;
|
|
16
18
|
declare function readTypefaceName(packet: Uint8Array): string | undefined;
|
|
17
19
|
//#endregion
|
|
18
|
-
export { PACKET_TYPE_DESIRED_FONT_DESCRIPTOR, WPD_INDEX_RECORD_SIZE, WpdPrefixPacket, packetByPrefixId, readPrefixPackets, readTypefaceName };
|
|
20
|
+
export { PACKET_TYPE_DESIRED_FONT_DESCRIPTOR, PACKET_TYPE_GENERAL_WP_TEXT, WPD_INDEX_RECORD_SIZE, WpdPrefixPacket, packetByPrefixId, readGeneralWpTextBlocks, readPrefixPackets, readTypefaceName };
|
|
@@ -13,6 +13,8 @@ interface WpdPrefixPacket {
|
|
|
13
13
|
}
|
|
14
14
|
declare function readPrefixPackets(bytes: Uint8Array, header: WpdFileHeader): WpdPrefixPacket[];
|
|
15
15
|
declare function packetByPrefixId(packets: readonly WpdPrefixPacket[], prefixId: number): WpdPrefixPacket | undefined;
|
|
16
|
+
declare const PACKET_TYPE_GENERAL_WP_TEXT = 8;
|
|
17
|
+
declare function readGeneralWpTextBlocks(bytes: Uint8Array): Uint8Array | undefined;
|
|
16
18
|
declare function readTypefaceName(packet: Uint8Array): string | undefined;
|
|
17
19
|
//#endregion
|
|
18
|
-
export { PACKET_TYPE_DESIRED_FONT_DESCRIPTOR, WPD_INDEX_RECORD_SIZE, WpdPrefixPacket, packetByPrefixId, readPrefixPackets, readTypefaceName };
|
|
20
|
+
export { PACKET_TYPE_DESIRED_FONT_DESCRIPTOR, PACKET_TYPE_GENERAL_WP_TEXT, WPD_INDEX_RECORD_SIZE, WpdPrefixPacket, packetByPrefixId, readGeneralWpTextBlocks, readPrefixPackets, readTypefaceName };
|
package/dist/container/prefix.js
CHANGED
|
@@ -49,6 +49,19 @@ function packetByPrefixId(packets, prefixId) {
|
|
|
49
49
|
}
|
|
50
50
|
const TYPEFACE_NAME_LENGTH_OFFSET = 22;
|
|
51
51
|
const TYPEFACE_NAME_OFFSET = 24;
|
|
52
|
+
const PACKET_TYPE_GENERAL_WP_TEXT = 8;
|
|
53
|
+
function readGeneralWpTextBlocks(bytes) {
|
|
54
|
+
if (bytes.length < 4) return;
|
|
55
|
+
const blockCount = uint16At(bytes, 0);
|
|
56
|
+
const firstBlockOffset = uint16At(bytes, 2);
|
|
57
|
+
if (blockCount === 0) return;
|
|
58
|
+
if (4 + blockCount * 2 > bytes.length) return;
|
|
59
|
+
let totalSize = 0;
|
|
60
|
+
for (let index = 0; index < blockCount; index += 1) totalSize += uint16At(bytes, 4 + index * 2);
|
|
61
|
+
const end = firstBlockOffset + totalSize;
|
|
62
|
+
if (firstBlockOffset < 0 || end > bytes.length) return;
|
|
63
|
+
return bytes.subarray(firstBlockOffset, end);
|
|
64
|
+
}
|
|
52
65
|
function readTypefaceName(packet) {
|
|
53
66
|
if (packet.length < TYPEFACE_NAME_OFFSET) return;
|
|
54
67
|
const nameLength = uint16At(packet, TYPEFACE_NAME_LENGTH_OFFSET);
|
|
@@ -58,4 +71,4 @@ function readTypefaceName(packet) {
|
|
|
58
71
|
return text.length > 0 ? text : void 0;
|
|
59
72
|
}
|
|
60
73
|
//#endregion
|
|
61
|
-
export { PACKET_TYPE_DESIRED_FONT_DESCRIPTOR, WPD_INDEX_RECORD_SIZE, packetByPrefixId, readPrefixPackets, readTypefaceName };
|
|
74
|
+
export { PACKET_TYPE_DESIRED_FONT_DESCRIPTOR, PACKET_TYPE_GENERAL_WP_TEXT, WPD_INDEX_RECORD_SIZE, packetByPrefixId, readGeneralWpTextBlocks, readPrefixPackets, readTypefaceName };
|
|
@@ -19,6 +19,11 @@ declare const WpdDiagnosticCodes: {
|
|
|
19
19
|
readonly HeaderFooterDropped: "wpd/header-footer-dropped";
|
|
20
20
|
readonly CrossReferenceFlattened: "wpd/cross-reference-flattened";
|
|
21
21
|
readonly MergeCodeDropped: "wpd/merge-code-dropped";
|
|
22
|
+
readonly TableFormulaUnresolved: "wpd/table-formula-unresolved";
|
|
23
|
+
readonly StyleResolutionDepthExceeded: "wpd/style-resolution-depth-exceeded";
|
|
24
|
+
readonly MergeFieldSpansParagraphs: "wpd/merge-field-spans-paragraphs";
|
|
25
|
+
readonly BoxContentUnresolved: "wpd/box-content-unresolved";
|
|
26
|
+
readonly BoxFrameUnresolved: "wpd/box-frame-unresolved";
|
|
22
27
|
};
|
|
23
28
|
declare const NOOP_WPD_DIAGNOSTIC_SINK: WpdDiagnosticSink;
|
|
24
29
|
//#endregion
|
|
@@ -19,6 +19,11 @@ declare const WpdDiagnosticCodes: {
|
|
|
19
19
|
readonly HeaderFooterDropped: "wpd/header-footer-dropped";
|
|
20
20
|
readonly CrossReferenceFlattened: "wpd/cross-reference-flattened";
|
|
21
21
|
readonly MergeCodeDropped: "wpd/merge-code-dropped";
|
|
22
|
+
readonly TableFormulaUnresolved: "wpd/table-formula-unresolved";
|
|
23
|
+
readonly StyleResolutionDepthExceeded: "wpd/style-resolution-depth-exceeded";
|
|
24
|
+
readonly MergeFieldSpansParagraphs: "wpd/merge-field-spans-paragraphs";
|
|
25
|
+
readonly BoxContentUnresolved: "wpd/box-content-unresolved";
|
|
26
|
+
readonly BoxFrameUnresolved: "wpd/box-frame-unresolved";
|
|
22
27
|
};
|
|
23
28
|
declare const NOOP_WPD_DIAGNOSTIC_SINK: WpdDiagnosticSink;
|
|
24
29
|
//#endregion
|
package/dist/diagnostics.cjs
CHANGED
|
@@ -14,7 +14,12 @@ const WpdDiagnosticCodes = {
|
|
|
14
14
|
NoteDropped: "wpd/note-dropped",
|
|
15
15
|
HeaderFooterDropped: "wpd/header-footer-dropped",
|
|
16
16
|
CrossReferenceFlattened: "wpd/cross-reference-flattened",
|
|
17
|
-
MergeCodeDropped: "wpd/merge-code-dropped"
|
|
17
|
+
MergeCodeDropped: "wpd/merge-code-dropped",
|
|
18
|
+
TableFormulaUnresolved: "wpd/table-formula-unresolved",
|
|
19
|
+
StyleResolutionDepthExceeded: "wpd/style-resolution-depth-exceeded",
|
|
20
|
+
MergeFieldSpansParagraphs: "wpd/merge-field-spans-paragraphs",
|
|
21
|
+
BoxContentUnresolved: "wpd/box-content-unresolved",
|
|
22
|
+
BoxFrameUnresolved: "wpd/box-frame-unresolved"
|
|
18
23
|
};
|
|
19
24
|
const NOOP_WPD_DIAGNOSTIC_SINK = () => {};
|
|
20
25
|
//#endregion
|
package/dist/diagnostics.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as WpdDiagnosticSink, n as WpdDiagnostic, r as WpdDiagnosticCodes, t as NOOP_WPD_DIAGNOSTIC_SINK } from "./diagnostics-
|
|
1
|
+
import { i as WpdDiagnosticSink, n as WpdDiagnostic, r as WpdDiagnosticCodes, t as NOOP_WPD_DIAGNOSTIC_SINK } from "./diagnostics-Dtb2uPw4.cjs";
|
|
2
2
|
export { NOOP_WPD_DIAGNOSTIC_SINK, WpdDiagnostic, WpdDiagnosticCodes, WpdDiagnosticSink };
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as WpdDiagnosticSink, n as WpdDiagnostic, r as WpdDiagnosticCodes, t as NOOP_WPD_DIAGNOSTIC_SINK } from "./diagnostics-
|
|
1
|
+
import { i as WpdDiagnosticSink, n as WpdDiagnostic, r as WpdDiagnosticCodes, t as NOOP_WPD_DIAGNOSTIC_SINK } from "./diagnostics-Dtb2uPw4.js";
|
|
2
2
|
export { NOOP_WPD_DIAGNOSTIC_SINK, WpdDiagnostic, WpdDiagnosticCodes, WpdDiagnosticSink };
|
package/dist/diagnostics.js
CHANGED
|
@@ -13,7 +13,12 @@ const WpdDiagnosticCodes = {
|
|
|
13
13
|
NoteDropped: "wpd/note-dropped",
|
|
14
14
|
HeaderFooterDropped: "wpd/header-footer-dropped",
|
|
15
15
|
CrossReferenceFlattened: "wpd/cross-reference-flattened",
|
|
16
|
-
MergeCodeDropped: "wpd/merge-code-dropped"
|
|
16
|
+
MergeCodeDropped: "wpd/merge-code-dropped",
|
|
17
|
+
TableFormulaUnresolved: "wpd/table-formula-unresolved",
|
|
18
|
+
StyleResolutionDepthExceeded: "wpd/style-resolution-depth-exceeded",
|
|
19
|
+
MergeFieldSpansParagraphs: "wpd/merge-field-spans-paragraphs",
|
|
20
|
+
BoxContentUnresolved: "wpd/box-content-unresolved",
|
|
21
|
+
BoxFrameUnresolved: "wpd/box-frame-unresolved"
|
|
17
22
|
};
|
|
18
23
|
const NOOP_WPD_DIAGNOSTIC_SINK = () => {};
|
|
19
24
|
//#endregion
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as WpdDiagnosticSink, n as WpdDiagnostic, r as WpdDiagnosticCodes, t as NOOP_WPD_DIAGNOSTIC_SINK } from "./diagnostics-
|
|
1
|
+
import { i as WpdDiagnosticSink, n as WpdDiagnostic, r as WpdDiagnosticCodes, t as NOOP_WPD_DIAGNOSTIC_SINK } from "./diagnostics-Dtb2uPw4.cjs";
|
|
2
2
|
import { ReadWpdOptions, readWpd, readWpdContent } from "./read.cjs";
|
|
3
3
|
import { WpdBytesSchema, wpdContentCodec } from "./codec.cjs";
|
|
4
4
|
import { WPD_FILE_ID, WPD_PREFIX_HEADER_SIZE, WpdFileHeader, hasWordPerfectFileId, readFileHeader } from "./container/header.cjs";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as WpdDiagnosticSink, n as WpdDiagnostic, r as WpdDiagnosticCodes, t as NOOP_WPD_DIAGNOSTIC_SINK } from "./diagnostics-
|
|
1
|
+
import { i as WpdDiagnosticSink, n as WpdDiagnostic, r as WpdDiagnosticCodes, t as NOOP_WPD_DIAGNOSTIC_SINK } from "./diagnostics-Dtb2uPw4.js";
|
|
2
2
|
import { ReadWpdOptions, readWpd, readWpdContent } from "./read.js";
|
|
3
3
|
import { WpdBytesSchema, wpdContentCodec } from "./codec.js";
|
|
4
4
|
import { WPD_FILE_ID, WPD_PREFIX_HEADER_SIZE, WpdFileHeader, hasWordPerfectFileId, readFileHeader } from "./container/header.js";
|