wpd-codec 1.0.1 → 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.
Files changed (42) hide show
  1. package/README.md +71 -28
  2. package/dist/container/summary.cjs +78 -0
  3. package/dist/container/summary.d.cts +6 -0
  4. package/dist/container/summary.d.ts +6 -0
  5. package/dist/container/summary.js +76 -0
  6. package/dist/diagnostics-CR0pXOyb.d.cts +25 -0
  7. package/dist/diagnostics-CR0pXOyb.d.ts +25 -0
  8. package/dist/diagnostics.cjs +11 -1
  9. package/dist/diagnostics.d.cts +1 -1
  10. package/dist/diagnostics.d.ts +1 -1
  11. package/dist/diagnostics.js +11 -1
  12. package/dist/index.cjs +48 -0
  13. package/dist/index.d.cts +8 -2
  14. package/dist/index.d.ts +8 -2
  15. package/dist/index.js +7 -1
  16. package/dist/read.cjs +286 -36
  17. package/dist/read.d.cts +1 -1
  18. package/dist/read.d.ts +1 -1
  19. package/dist/read.js +287 -37
  20. package/dist/stream/page.cjs +47 -0
  21. package/dist/stream/page.d.cts +20 -0
  22. package/dist/stream/page.d.ts +20 -0
  23. package/dist/stream/page.js +35 -0
  24. package/dist/stream/style.cjs +80 -0
  25. package/dist/stream/style.d.cts +16 -0
  26. package/dist/stream/style.d.ts +16 -0
  27. package/dist/stream/style.js +71 -0
  28. package/dist/stream/tab.cjs +33 -0
  29. package/dist/stream/tab.d.cts +12 -0
  30. package/dist/stream/tab.d.ts +12 -0
  31. package/dist/stream/tab.js +31 -0
  32. package/dist/stream/table.cjs +160 -0
  33. package/dist/stream/table.d.cts +43 -0
  34. package/dist/stream/table.d.ts +43 -0
  35. package/dist/stream/table.js +146 -0
  36. package/dist/stream/units.cjs +11 -0
  37. package/dist/stream/units.d.cts +6 -0
  38. package/dist/stream/units.d.ts +6 -0
  39. package/dist/stream/units.js +8 -0
  40. package/package.json +2 -2
  41. package/dist/diagnostics-Cp0HKphg.d.cts +0 -15
  42. package/dist/diagnostics-Cp0HKphg.d.ts +0 -15
package/dist/index.d.ts CHANGED
@@ -1,13 +1,19 @@
1
- import { i as WpdDiagnosticSink, n as WpdDiagnostic, r as WpdDiagnosticCodes, t as NOOP_WPD_DIAGNOSTIC_SINK } from "./diagnostics-Cp0HKphg.js";
1
+ import { i as WpdDiagnosticSink, n as WpdDiagnostic, r as WpdDiagnosticCodes, t as NOOP_WPD_DIAGNOSTIC_SINK } from "./diagnostics-CR0pXOyb.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";
5
5
  import { PACKET_TYPE_DESIRED_FONT_DESCRIPTOR, WPD_INDEX_RECORD_SIZE, WpdPrefixPacket, packetByPrefixId, readPrefixPackets, readTypefaceName } from "./container/prefix.js";
6
6
  import { PERFECT_OFFICE_MAIN_STREAM, PERFECT_OFFICE_OBJECTS_STORAGE, WpdDocumentContainer, openWpdDocument } from "./container/container.js";
7
+ import { PACKET_TYPE_EXTENDED_DOCUMENT_SUMMARY, readDocumentSummary } from "./container/summary.js";
7
8
  import { WpdEncryptedDocumentError, WpdFormatError, WpdNotAWordPerfectFileError, WpdUnsupportedVersionError } from "./errors.js";
8
9
  import { WPD_FILE_EXTENSION, WPD_MEDIA_TYPE } from "./format.js";
9
10
  import { FIRST_FIXED_FUNCTION, FIRST_SINGLE_BYTE_FUNCTION, FIRST_VARIABLE_FUNCTION, WpdCharacterToken, WpdFixedFunctionToken, WpdSingleByteFunctionToken, WpdToken, WpdVariableFunctionToken, tokeniseDocumentArea } from "./stream/tokenise.js";
10
11
  import { EOL_GROUP, FIRST_SINGLE_BYTE_EOL, LAST_SINGLE_BYTE_EOL, WpdEolMapping, eolMappingForSubfunction, isSingleByteEol, subfunctionForSingleByteEol } from "./stream/eol.js";
11
12
  import { ATTRIBUTE_OFF, ATTRIBUTE_ON, WpdAttribute, WpdAttributeCode, WpdRunAttributes, decodeAttributeByte, runAttributesFrom } from "./stream/attributes.js";
12
13
  import { FIRST_ASCII_CHARACTER, LAST_CHARACTER, UNMAPPED_CHARACTER, decodeSingleByteCharacter, decodeWordString, decodeWpCharacter } from "./stream/characters.js";
13
- export { ATTRIBUTE_OFF, ATTRIBUTE_ON, EOL_GROUP, FIRST_ASCII_CHARACTER, FIRST_FIXED_FUNCTION, FIRST_SINGLE_BYTE_EOL, FIRST_SINGLE_BYTE_FUNCTION, FIRST_VARIABLE_FUNCTION, LAST_CHARACTER, LAST_SINGLE_BYTE_EOL, NOOP_WPD_DIAGNOSTIC_SINK, PACKET_TYPE_DESIRED_FONT_DESCRIPTOR, PERFECT_OFFICE_MAIN_STREAM, PERFECT_OFFICE_OBJECTS_STORAGE, type ReadWpdOptions, UNMAPPED_CHARACTER, WPD_FILE_EXTENSION, WPD_FILE_ID, WPD_INDEX_RECORD_SIZE, WPD_MEDIA_TYPE, WPD_PREFIX_HEADER_SIZE, WpdAttribute, type WpdAttributeCode, WpdBytesSchema, type WpdCharacterToken, type WpdDiagnostic, WpdDiagnosticCodes, type WpdDiagnosticSink, type WpdDocumentContainer, WpdEncryptedDocumentError, type WpdEolMapping, type WpdFileHeader, type WpdFixedFunctionToken, WpdFormatError, WpdNotAWordPerfectFileError, type WpdPrefixPacket, type WpdRunAttributes, type WpdSingleByteFunctionToken, type WpdToken, WpdUnsupportedVersionError, type WpdVariableFunctionToken, decodeAttributeByte, decodeSingleByteCharacter, decodeWordString, decodeWpCharacter, eolMappingForSubfunction, hasWordPerfectFileId, isSingleByteEol, openWpdDocument, packetByPrefixId, readFileHeader, readPrefixPackets, readTypefaceName, readWpd, readWpdContent, runAttributesFrom, subfunctionForSingleByteEol, tokeniseDocumentArea, wpdContentCodec };
14
+ import { POINTS_PER_INCH, WPU_PER_INCH, pointsFromWpu } from "./stream/units.js";
15
+ import { COLUMN_GROUP, COLUMN_LEFT_MARGIN_SET, COLUMN_RIGHT_MARGIN_SET, DEFAULT_MARGIN_PT, DEFAULT_PAGE_HEIGHT_PT, DEFAULT_PAGE_WIDTH_PT, PAGE_BOTTOM_MARGIN_SET, PAGE_FORM, PAGE_GROUP, PAGE_TOP_MARGIN_SET, WpdPageForm, readMarginPt, readPageForm } from "./stream/page.js";
16
+ import { TAB_GROUP, WpdTabEffect, tabEffectFor } from "./stream/tab.js";
17
+ import { DISPLAY_NUMBER_GROUP, STYLE_GROUP, WpdStyleSemantics, isParagraphNumberDisplayOff, isParagraphNumberDisplayOn, isStyleScopeCloser, isStyleScopeOpener, readDisplayNumberLevel, readSystemStyleNumber, styleSemanticsFor } from "./stream/style.js";
18
+ import { CELL_FILL_COLORS_SUBFUNCTION, CELL_INFORMATION_SUBFUNCTION, CELL_SPANNING_SUBFUNCTION, CHARACTER_DEFINE_TABLE_END, CHARACTER_TABLE_COLUMN, CHARACTER_TABLE_DEFINITION, ROW_INFORMATION_SUBFUNCTION, WpdCellFill, WpdCellInformation, WpdCellSpanning, WpdEmbeddedSubfunction, WpdEmbeddedSubfunctions, WpdRowInformation, findEmbeddedSubfunction, readCellFill, readCellInformation, readCellSpanning, readEmbeddedSubfunctions, readRowInformation, readTableColumnWidthPt } from "./stream/table.js";
19
+ export { ATTRIBUTE_OFF, ATTRIBUTE_ON, CELL_FILL_COLORS_SUBFUNCTION, CELL_INFORMATION_SUBFUNCTION, CELL_SPANNING_SUBFUNCTION, CHARACTER_DEFINE_TABLE_END, CHARACTER_TABLE_COLUMN, CHARACTER_TABLE_DEFINITION, COLUMN_GROUP, COLUMN_LEFT_MARGIN_SET, COLUMN_RIGHT_MARGIN_SET, DEFAULT_MARGIN_PT, DEFAULT_PAGE_HEIGHT_PT, DEFAULT_PAGE_WIDTH_PT, DISPLAY_NUMBER_GROUP, EOL_GROUP, FIRST_ASCII_CHARACTER, FIRST_FIXED_FUNCTION, FIRST_SINGLE_BYTE_EOL, FIRST_SINGLE_BYTE_FUNCTION, FIRST_VARIABLE_FUNCTION, LAST_CHARACTER, LAST_SINGLE_BYTE_EOL, NOOP_WPD_DIAGNOSTIC_SINK, PACKET_TYPE_DESIRED_FONT_DESCRIPTOR, PACKET_TYPE_EXTENDED_DOCUMENT_SUMMARY, PAGE_BOTTOM_MARGIN_SET, PAGE_FORM, PAGE_GROUP, PAGE_TOP_MARGIN_SET, PERFECT_OFFICE_MAIN_STREAM, PERFECT_OFFICE_OBJECTS_STORAGE, POINTS_PER_INCH, ROW_INFORMATION_SUBFUNCTION, type ReadWpdOptions, STYLE_GROUP, TAB_GROUP, UNMAPPED_CHARACTER, WPD_FILE_EXTENSION, WPD_FILE_ID, WPD_INDEX_RECORD_SIZE, WPD_MEDIA_TYPE, WPD_PREFIX_HEADER_SIZE, WPU_PER_INCH, WpdAttribute, type WpdAttributeCode, WpdBytesSchema, type WpdCellFill, type WpdCellInformation, type WpdCellSpanning, type WpdCharacterToken, type WpdDiagnostic, WpdDiagnosticCodes, type WpdDiagnosticSink, type WpdDocumentContainer, type WpdEmbeddedSubfunction, type WpdEmbeddedSubfunctions, WpdEncryptedDocumentError, type WpdEolMapping, type WpdFileHeader, type WpdFixedFunctionToken, WpdFormatError, WpdNotAWordPerfectFileError, type WpdPageForm, type WpdPrefixPacket, type WpdRowInformation, type WpdRunAttributes, type WpdSingleByteFunctionToken, type WpdStyleSemantics, type WpdTabEffect, type WpdToken, WpdUnsupportedVersionError, type WpdVariableFunctionToken, decodeAttributeByte, decodeSingleByteCharacter, decodeWordString, decodeWpCharacter, eolMappingForSubfunction, findEmbeddedSubfunction, hasWordPerfectFileId, isParagraphNumberDisplayOff, isParagraphNumberDisplayOn, isSingleByteEol, isStyleScopeCloser, isStyleScopeOpener, openWpdDocument, packetByPrefixId, pointsFromWpu, readCellFill, readCellInformation, readCellSpanning, readDisplayNumberLevel, readDocumentSummary, readEmbeddedSubfunctions, readFileHeader, readMarginPt, readPageForm, readPrefixPackets, readRowInformation, readSystemStyleNumber, readTableColumnWidthPt, readTypefaceName, readWpd, readWpdContent, runAttributesFrom, styleSemanticsFor, subfunctionForSingleByteEol, tabEffectFor, tokeniseDocumentArea, wpdContentCodec };
package/dist/index.js CHANGED
@@ -3,11 +3,17 @@ import { WPD_FILE_ID, WPD_PREFIX_HEADER_SIZE, hasWordPerfectFileId, readFileHead
3
3
  import { FIRST_ASCII_CHARACTER, LAST_CHARACTER, UNMAPPED_CHARACTER, decodeSingleByteCharacter, decodeWordString, decodeWpCharacter } from "./stream/characters.js";
4
4
  import { PACKET_TYPE_DESIRED_FONT_DESCRIPTOR, WPD_INDEX_RECORD_SIZE, packetByPrefixId, readPrefixPackets, readTypefaceName } from "./container/prefix.js";
5
5
  import { PERFECT_OFFICE_MAIN_STREAM, PERFECT_OFFICE_OBJECTS_STORAGE, openWpdDocument } from "./container/container.js";
6
+ import { PACKET_TYPE_EXTENDED_DOCUMENT_SUMMARY, readDocumentSummary } from "./container/summary.js";
6
7
  import { NOOP_WPD_DIAGNOSTIC_SINK, WpdDiagnosticCodes } from "./diagnostics.js";
7
8
  import { ATTRIBUTE_OFF, ATTRIBUTE_ON, WpdAttribute, decodeAttributeByte, runAttributesFrom } from "./stream/attributes.js";
8
9
  import { EOL_GROUP, FIRST_SINGLE_BYTE_EOL, LAST_SINGLE_BYTE_EOL, eolMappingForSubfunction, isSingleByteEol, subfunctionForSingleByteEol } from "./stream/eol.js";
10
+ import { POINTS_PER_INCH, WPU_PER_INCH, pointsFromWpu } from "./stream/units.js";
11
+ import { COLUMN_GROUP, COLUMN_LEFT_MARGIN_SET, COLUMN_RIGHT_MARGIN_SET, DEFAULT_MARGIN_PT, DEFAULT_PAGE_HEIGHT_PT, DEFAULT_PAGE_WIDTH_PT, PAGE_BOTTOM_MARGIN_SET, PAGE_FORM, PAGE_GROUP, PAGE_TOP_MARGIN_SET, readMarginPt, readPageForm } from "./stream/page.js";
12
+ import { DISPLAY_NUMBER_GROUP, STYLE_GROUP, isParagraphNumberDisplayOff, isParagraphNumberDisplayOn, isStyleScopeCloser, isStyleScopeOpener, readDisplayNumberLevel, readSystemStyleNumber, styleSemanticsFor } from "./stream/style.js";
13
+ import { CELL_FILL_COLORS_SUBFUNCTION, CELL_INFORMATION_SUBFUNCTION, CELL_SPANNING_SUBFUNCTION, CHARACTER_DEFINE_TABLE_END, CHARACTER_TABLE_COLUMN, CHARACTER_TABLE_DEFINITION, ROW_INFORMATION_SUBFUNCTION, findEmbeddedSubfunction, readCellFill, readCellInformation, readCellSpanning, readEmbeddedSubfunctions, readRowInformation, readTableColumnWidthPt } from "./stream/table.js";
14
+ import { TAB_GROUP, tabEffectFor } from "./stream/tab.js";
9
15
  import { FIRST_FIXED_FUNCTION, FIRST_SINGLE_BYTE_FUNCTION, FIRST_VARIABLE_FUNCTION, tokeniseDocumentArea } from "./stream/tokenise.js";
10
16
  import { readWpd, readWpdContent } from "./read.js";
11
17
  import { WpdBytesSchema, wpdContentCodec } from "./codec.js";
12
18
  import { WPD_FILE_EXTENSION, WPD_MEDIA_TYPE } from "./format.js";
13
- export { ATTRIBUTE_OFF, ATTRIBUTE_ON, EOL_GROUP, FIRST_ASCII_CHARACTER, FIRST_FIXED_FUNCTION, FIRST_SINGLE_BYTE_EOL, FIRST_SINGLE_BYTE_FUNCTION, FIRST_VARIABLE_FUNCTION, LAST_CHARACTER, LAST_SINGLE_BYTE_EOL, NOOP_WPD_DIAGNOSTIC_SINK, PACKET_TYPE_DESIRED_FONT_DESCRIPTOR, PERFECT_OFFICE_MAIN_STREAM, PERFECT_OFFICE_OBJECTS_STORAGE, UNMAPPED_CHARACTER, WPD_FILE_EXTENSION, WPD_FILE_ID, WPD_INDEX_RECORD_SIZE, WPD_MEDIA_TYPE, WPD_PREFIX_HEADER_SIZE, WpdAttribute, WpdBytesSchema, WpdDiagnosticCodes, WpdEncryptedDocumentError, WpdFormatError, WpdNotAWordPerfectFileError, WpdUnsupportedVersionError, decodeAttributeByte, decodeSingleByteCharacter, decodeWordString, decodeWpCharacter, eolMappingForSubfunction, hasWordPerfectFileId, isSingleByteEol, openWpdDocument, packetByPrefixId, readFileHeader, readPrefixPackets, readTypefaceName, readWpd, readWpdContent, runAttributesFrom, subfunctionForSingleByteEol, tokeniseDocumentArea, wpdContentCodec };
19
+ export { ATTRIBUTE_OFF, ATTRIBUTE_ON, CELL_FILL_COLORS_SUBFUNCTION, CELL_INFORMATION_SUBFUNCTION, CELL_SPANNING_SUBFUNCTION, CHARACTER_DEFINE_TABLE_END, CHARACTER_TABLE_COLUMN, CHARACTER_TABLE_DEFINITION, COLUMN_GROUP, COLUMN_LEFT_MARGIN_SET, COLUMN_RIGHT_MARGIN_SET, DEFAULT_MARGIN_PT, DEFAULT_PAGE_HEIGHT_PT, DEFAULT_PAGE_WIDTH_PT, DISPLAY_NUMBER_GROUP, EOL_GROUP, FIRST_ASCII_CHARACTER, FIRST_FIXED_FUNCTION, FIRST_SINGLE_BYTE_EOL, FIRST_SINGLE_BYTE_FUNCTION, FIRST_VARIABLE_FUNCTION, LAST_CHARACTER, LAST_SINGLE_BYTE_EOL, NOOP_WPD_DIAGNOSTIC_SINK, PACKET_TYPE_DESIRED_FONT_DESCRIPTOR, PACKET_TYPE_EXTENDED_DOCUMENT_SUMMARY, PAGE_BOTTOM_MARGIN_SET, PAGE_FORM, PAGE_GROUP, PAGE_TOP_MARGIN_SET, PERFECT_OFFICE_MAIN_STREAM, PERFECT_OFFICE_OBJECTS_STORAGE, POINTS_PER_INCH, ROW_INFORMATION_SUBFUNCTION, STYLE_GROUP, TAB_GROUP, UNMAPPED_CHARACTER, WPD_FILE_EXTENSION, WPD_FILE_ID, WPD_INDEX_RECORD_SIZE, WPD_MEDIA_TYPE, WPD_PREFIX_HEADER_SIZE, WPU_PER_INCH, WpdAttribute, WpdBytesSchema, WpdDiagnosticCodes, WpdEncryptedDocumentError, WpdFormatError, WpdNotAWordPerfectFileError, WpdUnsupportedVersionError, decodeAttributeByte, decodeSingleByteCharacter, decodeWordString, decodeWpCharacter, eolMappingForSubfunction, findEmbeddedSubfunction, hasWordPerfectFileId, isParagraphNumberDisplayOff, isParagraphNumberDisplayOn, isSingleByteEol, isStyleScopeCloser, isStyleScopeOpener, openWpdDocument, packetByPrefixId, pointsFromWpu, readCellFill, readCellInformation, readCellSpanning, readDisplayNumberLevel, readDocumentSummary, readEmbeddedSubfunctions, readFileHeader, readMarginPt, readPageForm, readPrefixPackets, readRowInformation, readSystemStyleNumber, readTableColumnWidthPt, readTypefaceName, readWpd, readWpdContent, runAttributesFrom, styleSemanticsFor, subfunctionForSingleByteEol, tabEffectFor, tokeniseDocumentArea, wpdContentCodec };
package/dist/read.cjs CHANGED
@@ -3,9 +3,14 @@ const require_bytes_view = require("./bytes/view.cjs");
3
3
  const require_stream_characters = require("./stream/characters.cjs");
4
4
  const require_container_prefix = require("./container/prefix.cjs");
5
5
  const require_container_container = require("./container/container.cjs");
6
+ const require_container_summary = require("./container/summary.cjs");
6
7
  const require_diagnostics = require("./diagnostics.cjs");
7
8
  const require_stream_attributes = require("./stream/attributes.cjs");
8
9
  const require_stream_eol = require("./stream/eol.cjs");
10
+ const require_stream_page = require("./stream/page.cjs");
11
+ const require_stream_style = require("./stream/style.cjs");
12
+ const require_stream_table = require("./stream/table.cjs");
13
+ const require_stream_tab = require("./stream/tab.cjs");
9
14
  const require_stream_tokenise = require("./stream/tokenise.cjs");
10
15
  let document_schema_js = require("document-schema.js");
11
16
  //#region src/read.ts
@@ -21,6 +26,11 @@ const SOFT_END_OF_CENTER_ALIGN = 136;
21
26
  const HARD_END_OF_CENTER_ALIGN = 137;
22
27
  const START_OF_TEXT_TO_SKIP = 141;
23
28
  const END_OF_TEXT_TO_SKIP = 142;
29
+ const CROSS_REFERENCE_GROUP = 213;
30
+ const HEADER_FOOTER_GROUP = 214;
31
+ const FOOTNOTE_ENDNOTE_GROUP = 215;
32
+ const MERGE_GROUP = 222;
33
+ const BOX_GROUP = 223;
24
34
  const PARAGRAPH_GROUP = 211;
25
35
  const PARAGRAPH_SET_JUSTIFICATION = 5;
26
36
  const CHARACTER_GROUP = 212;
@@ -38,10 +48,18 @@ const JUSTIFICATION = [
38
48
  ];
39
49
  const THREE_THOUSAND_SIX_HUNDREDTHS_PER_POINT = 50;
40
50
  const COLOR_COMPONENT_MAX = 255;
41
- const DEFAULT_MARGIN_PT = 72;
51
+ const NO_SPAN = 1;
42
52
  function sameAttributes(a, b) {
43
53
  return a.bold === b.bold && a.italic === b.italic && a.underline === b.underline && a.strike === b.strike;
44
54
  }
55
+ function reportOnce(state, sink, code, message) {
56
+ if (state.reported.has(code)) return;
57
+ state.reported.add(code);
58
+ sink({
59
+ code,
60
+ message
61
+ });
62
+ }
45
63
  function buildRun(state) {
46
64
  return {
47
65
  text: state.text,
@@ -59,20 +77,104 @@ function flushRun(state) {
59
77
  state.runs.push(buildRun(state));
60
78
  state.text = "";
61
79
  }
80
+ function targetBlocks(state) {
81
+ return state.table === void 0 ? state.blocks : state.table.cellBlocks;
82
+ }
62
83
  function flushParagraph(state) {
63
84
  flushRun(state);
85
+ const alignment = state.pendingAlignment ?? state.alignment;
64
86
  const paragraph = {
65
87
  kind: "paragraph",
66
88
  runs: state.runs.splice(0, state.runs.length),
67
- ...state.alignment === void 0 ? {} : { alignment: state.alignment }
89
+ ...alignment === void 0 ? {} : { alignment },
90
+ ...state.pendingHeadingLevel === void 0 ? {} : { headingLevel: state.pendingHeadingLevel },
91
+ ...state.pendingListLevel === void 0 ? {} : { list: { level: state.pendingListLevel } }
68
92
  };
69
- state.blocks.push(paragraph);
93
+ state.pendingHeadingLevel = void 0;
94
+ state.pendingListLevel = void 0;
95
+ state.pendingAlignment = void 0;
96
+ targetBlocks(state).push(paragraph);
97
+ }
98
+ function flushParagraphIfContent(state) {
99
+ if (state.text.length === 0 && state.runs.length === 0) return;
100
+ flushParagraph(state);
101
+ }
102
+ function effectiveStyle(state) {
103
+ for (let index = state.styleScopes.length - 1; index >= 0; index -= 1) {
104
+ const scope = state.styleScopes[index];
105
+ if (scope !== void 0) return scope;
106
+ }
70
107
  }
71
108
  function appendText(state, text) {
72
- if (state.skipDepth > 0) return;
109
+ if (state.skipDepth > 0 || state.numberDisplayDepth > 0) return;
110
+ if (state.pendingHeadingLevel === void 0 && state.pendingListLevel === void 0) {
111
+ const style = effectiveStyle(state);
112
+ if (style !== void 0) {
113
+ state.pendingHeadingLevel = style.headingLevel;
114
+ state.pendingListLevel = style.listLevel;
115
+ }
116
+ }
73
117
  state.text += text;
74
118
  }
75
- function applyEolMapping(state, mapping, sink) {
119
+ function readCellAttributes(state, nonDeletable, sink) {
120
+ const { subfunctions, truncated } = require_stream_table.readEmbeddedSubfunctions(nonDeletable);
121
+ if (truncated) reportOnce(state, sink, require_diagnostics.WpdDiagnosticCodes.TableAttributesTruncated, "A cell's embedded attribute list held a record of undocumented length, so the attributes after it were not read.");
122
+ const information = require_stream_table.findEmbeddedSubfunction(subfunctions, 132);
123
+ const spanning = require_stream_table.findEmbeddedSubfunction(subfunctions, 133);
124
+ const fill = require_stream_table.findEmbeddedSubfunction(subfunctions, 134);
125
+ const row = require_stream_table.findEmbeddedSubfunction(subfunctions, 128);
126
+ const cellSpanning = spanning === void 0 ? void 0 : require_stream_table.readCellSpanning(spanning);
127
+ const cellFill = fill === void 0 ? void 0 : require_stream_table.readCellFill(fill);
128
+ if (cellFill?.blended === true) reportOnce(state, sink, require_diagnostics.WpdDiagnosticCodes.CellFillBlended, "A cell is filled with a shaded blend of two colours; its background colour is used and the blend is not reproduced.");
129
+ return {
130
+ attributes: {
131
+ alignment: information === void 0 ? void 0 : require_stream_table.readCellInformation(information)?.alignment,
132
+ background: cellFill?.background,
133
+ columnSpan: cellSpanning?.columnSpan ?? NO_SPAN,
134
+ rowSpan: cellSpanning?.rowSpan ?? NO_SPAN,
135
+ covered: cellSpanning?.coveredFromLeft === true || cellSpanning?.coveredFromAbove === true
136
+ },
137
+ rowHeightPt: row === void 0 ? void 0 : require_stream_table.readRowInformation(row)?.heightPt
138
+ };
139
+ }
140
+ function closeCell(state, table, attributes) {
141
+ flushParagraphIfContent(state);
142
+ const blocks = table.cellBlocks;
143
+ table.cellBlocks = [];
144
+ if (attributes.covered) return;
145
+ if (attributes.alignment !== void 0) {
146
+ for (const block of blocks) if (block.kind === "paragraph") block.alignment = attributes.alignment;
147
+ }
148
+ const cell = {
149
+ blocks,
150
+ ...attributes.columnSpan > NO_SPAN ? { colSpan: attributes.columnSpan } : {},
151
+ ...attributes.rowSpan > NO_SPAN ? { rowSpan: attributes.rowSpan } : {},
152
+ ...attributes.background === void 0 ? {} : { background: attributes.background }
153
+ };
154
+ table.cells.push(cell);
155
+ }
156
+ function closeRow(table) {
157
+ if (table.cells.length === 0) return;
158
+ const row = {
159
+ cells: table.cells,
160
+ ...table.rowHeightPt === void 0 ? {} : { heightPt: table.rowHeightPt }
161
+ };
162
+ table.cells = [];
163
+ table.rowHeightPt = void 0;
164
+ table.rows.push(row);
165
+ }
166
+ function closeTable(state) {
167
+ const table = state.table;
168
+ if (table === void 0) return;
169
+ state.table = void 0;
170
+ if (table.rows.length === 0) return;
171
+ targetBlocks(state).push({
172
+ kind: "table",
173
+ rows: table.rows,
174
+ columnWidthsPt: table.columnWidthsPt
175
+ });
176
+ }
177
+ function applyEolMapping(state, mapping, nonDeletable, sink) {
76
178
  switch (mapping) {
77
179
  case "ignore": return;
78
180
  case "space":
@@ -82,35 +184,38 @@ function applyEolMapping(state, mapping, sink) {
82
184
  flushParagraph(state);
83
185
  return;
84
186
  case "hardEndOfColumn":
85
- sink({
86
- code: require_diagnostics.WpdDiagnosticCodes.ColumnBreakFlattened,
87
- message: "A column break became a paragraph break."
88
- });
187
+ reportOnce(state, sink, require_diagnostics.WpdDiagnosticCodes.ColumnBreakFlattened, "A column break became a paragraph break.");
89
188
  flushParagraph(state);
90
189
  return;
91
190
  case "hardEndOfPage":
92
191
  flushParagraph(state);
93
- state.blocks.push({ kind: "pageBreak" });
192
+ targetBlocks(state).push({ kind: "pageBreak" });
94
193
  return;
95
194
  case "tableCell":
96
195
  case "tableRow":
97
196
  case "hardTableRow":
98
- case "tableOff":
99
- if (!state.tableReported) {
100
- state.tableReported = true;
101
- sink({
102
- code: require_diagnostics.WpdDiagnosticCodes.TableFlattened,
103
- message: "This document contains a table; its cells and rows became paragraphs, and the table structure was not reconstructed."
104
- });
197
+ case "tableOff": {
198
+ const table = state.table;
199
+ if (table === void 0) {
200
+ reportOnce(state, sink, require_diagnostics.WpdDiagnosticCodes.TableFlattened, "A table cell or row boundary appeared with no table definition open; its text became a paragraph.");
201
+ flushParagraph(state);
202
+ return;
105
203
  }
106
- flushParagraph(state);
204
+ const { attributes, rowHeightPt } = readCellAttributes(state, nonDeletable, sink);
205
+ if (rowHeightPt !== void 0) table.rowHeightPt = rowHeightPt;
206
+ const cellIsOpen = state.text.length > 0 || state.runs.length > 0 || table.cellBlocks.length > 0;
207
+ if (mapping !== "tableOff" || cellIsOpen) closeCell(state, table, attributes);
208
+ if (mapping === "tableCell") return;
209
+ closeRow(table);
210
+ if (mapping === "tableOff") closeTable(state);
107
211
  return;
212
+ }
108
213
  }
109
214
  }
110
215
  function applySingleByteFunction(state, code, sink) {
111
216
  if (require_stream_eol.isSingleByteEol(code)) {
112
217
  const mapping = require_stream_eol.eolMappingForSubfunction(require_stream_eol.subfunctionForSingleByteEol(code));
113
- if (mapping !== void 0) applyEolMapping(state, mapping, sink);
218
+ if (mapping !== void 0) applyEolMapping(state, mapping, /* @__PURE__ */ new Uint8Array(0), sink);
114
219
  return;
115
220
  }
116
221
  switch (code) {
@@ -162,19 +267,82 @@ function applyFontFaceChange(state, prefixIds, container, sink) {
162
267
  flushRun(state);
163
268
  state.fontFamily = typeface;
164
269
  }
165
- function applyVariableFunction(state, token, container, sink) {
166
- if (token.group === 208) {
167
- const mapping = require_stream_eol.eolMappingForSubfunction(token.subgroup);
168
- if (mapping !== void 0) applyEolMapping(state, mapping, sink);
270
+ function setPageDimension(state, field, value, sink) {
271
+ const current = state.page[field];
272
+ if (current === void 0) {
273
+ state.page[field] = value;
274
+ return;
275
+ }
276
+ if (current !== value && !state.page.changeReported) {
277
+ state.page.changeReported = true;
278
+ sink({
279
+ code: require_diagnostics.WpdDiagnosticCodes.PageGeometryChanged,
280
+ message: "This document changes its page size or margins partway through; the section carries the geometry the document opens with."
281
+ });
282
+ }
283
+ }
284
+ function applyPageGroup(state, token, sink) {
285
+ if (token.subgroup === 17) {
286
+ const form = require_stream_page.readPageForm(token.nonDeletable);
287
+ if (form === void 0) return;
288
+ if (form.landscape) reportOnce(state, sink, require_diagnostics.WpdDiagnosticCodes.LandscapeOrientationUnmapped, "The document's form declares a landscape orientation; the form's own stated width and length are used as written, since a page size carries no orientation.");
289
+ setPageDimension(state, "widthPt", form.widthPt, sink);
290
+ setPageDimension(state, "heightPt", form.heightPt, sink);
169
291
  return;
170
292
  }
171
- if (token.group === PARAGRAPH_GROUP && token.subgroup === PARAGRAPH_SET_JUSTIFICATION) {
172
- const mode = token.nonDeletable[0];
173
- if (mode !== void 0) state.alignment = JUSTIFICATION[mode];
293
+ const margin = require_stream_page.readMarginPt(token.nonDeletable);
294
+ if (margin === void 0) return;
295
+ if (token.subgroup === 0) setPageDimension(state, "topPt", margin, sink);
296
+ else if (token.subgroup === 1) setPageDimension(state, "bottomPt", margin, sink);
297
+ }
298
+ function applyColumnGroup(state, token, sink) {
299
+ const margin = require_stream_page.readMarginPt(token.nonDeletable);
300
+ if (margin === void 0) return;
301
+ if (token.subgroup === 0) setPageDimension(state, "leftPt", margin, sink);
302
+ else if (token.subgroup === 1) setPageDimension(state, "rightPt", margin, sink);
303
+ }
304
+ function applyStyleGroup(state, token) {
305
+ if (require_stream_style.isStyleScopeOpener(token.subgroup)) {
306
+ const systemStyleNumber = require_stream_style.readSystemStyleNumber(token.nonDeletable);
307
+ state.styleScopes.push(systemStyleNumber === void 0 ? void 0 : require_stream_style.styleSemanticsFor(systemStyleNumber));
174
308
  return;
175
309
  }
176
- if (token.group !== CHARACTER_GROUP) return;
310
+ if (require_stream_style.isStyleScopeCloser(token.subgroup)) state.styleScopes.pop();
311
+ }
312
+ function applyDisplayNumberGroup(state, token, sink) {
313
+ if (require_stream_style.isParagraphNumberDisplayOn(token.subgroup)) {
314
+ const level = require_stream_style.readDisplayNumberLevel(token.nonDeletable);
315
+ if (level !== void 0 && state.pendingListLevel === void 0) state.pendingListLevel = level;
316
+ state.numberDisplayDepth += 1;
317
+ reportOnce(state, sink, require_diagnostics.WpdDiagnosticCodes.OutlineNumberRegenerated, "An outline number's rendered digits were replaced by the list membership that regenerates them.");
318
+ return;
319
+ }
320
+ if (require_stream_style.isParagraphNumberDisplayOff(token.subgroup)) state.numberDisplayDepth = Math.max(0, state.numberDisplayDepth - 1);
321
+ }
322
+ function applyCharacterGroup(state, token, container, sink) {
177
323
  switch (token.subgroup) {
324
+ case 42:
325
+ closeTable(state);
326
+ flushParagraphIfContent(state);
327
+ state.table = {
328
+ columnWidthsPt: [],
329
+ rows: [],
330
+ cells: [],
331
+ cellBlocks: [],
332
+ definingColumns: true,
333
+ rowHeightPt: void 0
334
+ };
335
+ return;
336
+ case 44: {
337
+ const table = state.table;
338
+ if (!table?.definingColumns) return;
339
+ const widthPt = require_stream_table.readTableColumnWidthPt(token.nonDeletable);
340
+ if (widthPt !== void 0) table.columnWidthsPt.push(widthPt);
341
+ return;
342
+ }
343
+ case 43:
344
+ if (state.table !== void 0) state.table.definingColumns = false;
345
+ return;
178
346
  case CHARACTER_FONT_FACE_CHANGE:
179
347
  applyFontFaceChange(state, token.prefixIds, container, sink);
180
348
  return;
@@ -200,6 +368,59 @@ function applyVariableFunction(state, token, container, sink) {
200
368
  default: return;
201
369
  }
202
370
  }
371
+ function applyVariableFunction(state, token, container, sink) {
372
+ switch (token.group) {
373
+ case 208: {
374
+ const mapping = require_stream_eol.eolMappingForSubfunction(token.subgroup);
375
+ if (mapping !== void 0) applyEolMapping(state, mapping, token.nonDeletable, sink);
376
+ return;
377
+ }
378
+ case 209:
379
+ applyPageGroup(state, token, sink);
380
+ return;
381
+ case 210:
382
+ applyColumnGroup(state, token, sink);
383
+ return;
384
+ case PARAGRAPH_GROUP: {
385
+ if (token.subgroup !== PARAGRAPH_SET_JUSTIFICATION) return;
386
+ const mode = token.nonDeletable[0];
387
+ if (mode !== void 0) state.alignment = JUSTIFICATION[mode];
388
+ return;
389
+ }
390
+ case CHARACTER_GROUP:
391
+ applyCharacterGroup(state, token, container, sink);
392
+ return;
393
+ case 224: {
394
+ const effect = require_stream_tab.tabEffectFor(token.subgroup);
395
+ if (effect === void 0) return;
396
+ if (effect.kind === "tab") appendText(state, " ");
397
+ else state.pendingAlignment = effect.alignment;
398
+ return;
399
+ }
400
+ case 221:
401
+ applyStyleGroup(state, token);
402
+ return;
403
+ case 218:
404
+ applyDisplayNumberGroup(state, token, sink);
405
+ return;
406
+ case CROSS_REFERENCE_GROUP:
407
+ reportOnce(state, sink, require_diagnostics.WpdDiagnosticCodes.CrossReferenceFlattened, "This document contains a cross-reference; its displayed text survives as ordinary text, and the reference's own target binding does not.");
408
+ return;
409
+ case HEADER_FOOTER_GROUP:
410
+ reportOnce(state, sink, require_diagnostics.WpdDiagnosticCodes.HeaderFooterDropped, "This document declares a header, footer, or watermark, which the flat content model has no page-furniture position for.");
411
+ return;
412
+ case FOOTNOTE_ENDNOTE_GROUP:
413
+ reportOnce(state, sink, require_diagnostics.WpdDiagnosticCodes.NoteDropped, "This document contains a footnote or endnote; its text lives in a prefix packet the flat content model has nowhere to put.");
414
+ return;
415
+ case MERGE_GROUP:
416
+ reportOnce(state, sink, require_diagnostics.WpdDiagnosticCodes.MergeCodeDropped, "This document contains merge codes, which are a form-letter template's placeholders rather than text.");
417
+ return;
418
+ case BOX_GROUP:
419
+ reportOnce(state, sink, require_diagnostics.WpdDiagnosticCodes.BoxDropped, "This document contains a box -- a figure, text box, equation, or graphic -- whose contents were not read.");
420
+ return;
421
+ default: return;
422
+ }
423
+ }
203
424
  function applyFixedFunction(state, token, sink) {
204
425
  if (token.code === EXTENDED_CHARACTER) {
205
426
  const characterNumber = token.data[0];
@@ -241,7 +462,22 @@ function foldTokens(tokens, container, sink) {
241
462
  color: void 0,
242
463
  alignment: void 0,
243
464
  skipDepth: 0,
244
- tableReported: false
465
+ styleScopes: [],
466
+ pendingHeadingLevel: void 0,
467
+ pendingListLevel: void 0,
468
+ pendingAlignment: void 0,
469
+ numberDisplayDepth: 0,
470
+ page: {
471
+ widthPt: void 0,
472
+ heightPt: void 0,
473
+ topPt: void 0,
474
+ rightPt: void 0,
475
+ bottomPt: void 0,
476
+ leftPt: void 0,
477
+ changeReported: false
478
+ },
479
+ table: void 0,
480
+ reported: /* @__PURE__ */ new Set()
245
481
  };
246
482
  for (const token of tokens) switch (token.kind) {
247
483
  case "character": {
@@ -267,22 +503,36 @@ function foldTokens(tokens, container, sink) {
267
503
  }
268
504
  flushRun(state);
269
505
  if (state.runs.length > 0) flushParagraph(state);
270
- return state.blocks;
506
+ if (state.table !== void 0) {
507
+ closeRow(state.table);
508
+ closeTable(state);
509
+ }
510
+ return {
511
+ blocks: state.blocks,
512
+ page: state.page
513
+ };
514
+ }
515
+ function readMetadata(container) {
516
+ const packet = container.packets.find((candidate) => candidate.packetType === 18);
517
+ return packet === void 0 ? {} : require_container_summary.readDocumentSummary(packet.bytes);
271
518
  }
272
519
  function readWpdContent(bytes, options = {}) {
273
520
  const sink = options.sink ?? require_diagnostics.NOOP_WPD_DIAGNOSTIC_SINK;
274
521
  const container = require_container_container.openWpdDocument(bytes);
275
- const blocks = foldTokens(require_stream_tokenise.tokeniseDocumentArea(container.bytes, container.documentAreaOffset, container.documentAreaEnd), container, sink);
522
+ const { blocks, page } = foldTokens(require_stream_tokenise.tokeniseDocumentArea(container.bytes, container.documentAreaOffset, container.documentAreaEnd), container, sink);
276
523
  return {
277
524
  kind: "wordprocessing",
278
- metadata: {},
525
+ metadata: readMetadata(container),
279
526
  sections: [{
280
- pageSize: document_schema_js.PAGE_SIZE_LETTER,
527
+ pageSize: {
528
+ widthPt: page.widthPt ?? 612,
529
+ heightPt: page.heightPt ?? 792
530
+ },
281
531
  margins: {
282
- topPt: DEFAULT_MARGIN_PT,
283
- rightPt: DEFAULT_MARGIN_PT,
284
- bottomPt: DEFAULT_MARGIN_PT,
285
- leftPt: DEFAULT_MARGIN_PT
532
+ topPt: page.topPt ?? 72,
533
+ rightPt: page.rightPt ?? 72,
534
+ bottomPt: page.bottomPt ?? 72,
535
+ leftPt: page.leftPt ?? 72
286
536
  },
287
537
  blocks
288
538
  }]
package/dist/read.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as WpdDiagnosticSink } from "./diagnostics-Cp0HKphg.cjs";
1
+ import { i as WpdDiagnosticSink } from "./diagnostics-CR0pXOyb.cjs";
2
2
  import { ContentDocument, DocumentTree } from "document-schema.js";
3
3
  //#region src/read.d.ts
4
4
  interface ReadWpdOptions {
package/dist/read.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as WpdDiagnosticSink } from "./diagnostics-Cp0HKphg.js";
1
+ import { i as WpdDiagnosticSink } from "./diagnostics-CR0pXOyb.js";
2
2
  import { ContentDocument, DocumentTree } from "document-schema.js";
3
3
  //#region src/read.d.ts
4
4
  interface ReadWpdOptions {