wpd-codec 1.0.2 → 1.1.1

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