doc-codec 2.8.6 → 2.10.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/dist/index.cjs CHANGED
@@ -28,6 +28,7 @@ const require_prop_sep = require("./prop/sep.cjs");
28
28
  const require_prop_sep_write = require("./prop/sep-write.cjs");
29
29
  const require_style_fonts = require("./style/fonts.cjs");
30
30
  const require_list_numbering = require("./list/numbering.cjs");
31
+ const require_subdocument_write = require("./subdocument-write.cjs");
31
32
  const require_notes = require("./notes.cjs");
32
33
  const require_read = require("./read.cjs");
33
34
  const require_write = require("./write.cjs");
@@ -56,6 +57,7 @@ exports.FIB_W_IDENT = require_fib_offsets.FIB_W_IDENT;
56
57
  exports.FIELD_BEGIN = require_text_special.FIELD_BEGIN;
57
58
  exports.FIELD_END = require_text_special.FIELD_END;
58
59
  exports.FIELD_SEPARATOR = require_text_special.FIELD_SEPARATOR;
60
+ exports.FIXED_SEPARATOR_STORY_COUNT = require_headers_footers.FIXED_SEPARATOR_STORY_COUNT;
59
61
  exports.FKP_PAGE_SIZE = require_prop_fkp.FKP_PAGE_SIZE;
60
62
  exports.FOOTNOTE_REFERENCE = require_text_special.FOOTNOTE_REFERENCE;
61
63
  exports.INLINE_PICTURE = require_text_special.INLINE_PICTURE;
@@ -66,6 +68,7 @@ exports.PARAGRAPH_MARK = require_text_special.PARAGRAPH_MARK;
66
68
  exports.PropertyBinTable = require_prop_fkp.PropertyBinTable;
67
69
  exports.SECTION_MARK = require_text_special.SECTION_MARK;
68
70
  exports.SGC = require_prop_sprm.SGC;
71
+ exports.SLOT_ORDER = require_headers_footers.SLOT_ORDER;
69
72
  exports.STI_USER_DEFINED = require_style_stsh.STI_USER_DEFINED;
70
73
  exports.STK = require_style_stsh.STK;
71
74
  exports.SUMMARY_INFORMATION_STREAM = require_detect.SUMMARY_INFORMATION_STREAM;
@@ -78,10 +81,13 @@ exports.base64ToBytes = require_base64.base64ToBytes;
78
81
  exports.buildChpxPages = require_prop_fkp_write.buildChpxPages;
79
82
  exports.buildFib = require_fib_write.buildFib;
80
83
  exports.buildFontTable = require_style_fonts.buildFontTable;
84
+ exports.buildHeaderSubdocument = require_subdocument_write.buildHeaderSubdocument;
85
+ exports.buildNoteSubdocument = require_subdocument_write.buildNoteSubdocument;
81
86
  exports.buildPapxPages = require_prop_fkp_write.buildPapxPages;
82
87
  exports.buildPlcfSed = require_prop_sep_write.buildPlcfSed;
83
88
  exports.buildPropertyBinTable = require_prop_fkp_write.buildPropertyBinTable;
84
89
  exports.buildSepx = require_prop_sep_write.buildSepx;
90
+ exports.buildStorySubdocuments = require_subdocument_write.buildStorySubdocuments;
85
91
  exports.buildStshForStyles = require_style_stsh.buildStshForStyles;
86
92
  exports.buildTextClx = require_text_piece_table_write.buildTextClx;
87
93
  exports.bytesToBase64 = require_base64.bytesToBase64;
@@ -101,6 +107,7 @@ exports.isAnchorOnly = require_text_special.isAnchorOnly;
101
107
  exports.isDocBytes = require_detect.isDocBytes;
102
108
  exports.layoutMetadataToSummaryInformation = require_metadata.layoutMetadataToSummaryInformation;
103
109
  exports.operandSize = require_prop_sprm.operandSize;
110
+ exports.paragraphCharacters = require_subdocument_write.paragraphCharacters;
104
111
  exports.parseChpxFkp = require_prop_fkp.parseChpxFkp;
105
112
  exports.parseClx = require_text_piece_table.parseClx;
106
113
  exports.parseFib = require_fib_fib.parseFib;
package/dist/index.d.cts CHANGED
@@ -13,7 +13,7 @@ import { n as applyParagraphSprms, t as ParagraphProperties } from "./pap-BQ2E17
13
13
  import { a as StyleSheet, c as parseStsh, i as Style, l as resolveStyleFormatting, n as STI_USER_DEFINED, o as buildStshForStyles, r as STK, s as headingLevelFromIstd, t as ResolvedStyleFormatting } from "./stsh-CK59x6XG.cjs";
14
14
  import { i as splitEntriesByBoundaries, n as ReadContext, r as readParagraphs, t as ParagraphEntry } from "./paragraphs-DQUp8_HB.cjs";
15
15
  import { a as parseClx, i as characterSize, n as PieceTable, r as characterOffset, t as Piece } from "./piece-table-CA18mhjv.cjs";
16
- import { HeaderFooterSlot, HeaderFooterStories, HeaderFooterStory, readHeaderFooterStories } from "./headers-footers.cjs";
16
+ import { FIXED_SEPARATOR_STORY_COUNT, HeaderFooterSlot, HeaderFooterStories, HeaderFooterStory, SLOT_ORDER, readHeaderFooterStories } from "./headers-footers.cjs";
17
17
  import { Plc, findLargestAtMost, parsePlc } from "./plc.cjs";
18
18
  import { layoutMetadataToSummaryInformation } from "./metadata.cjs";
19
19
  import { buildTextClx } from "./text/piece-table-write.cjs";
@@ -27,7 +27,8 @@ import { buildPlcfSed, buildSepx, encodeSectionGrpprl } from "./prop/sep-write.c
27
27
  import { buildFontTable, parseFontTable } from "./style/fonts.cjs";
28
28
  import { NUMBER_FORMAT_BY_NFC, NumberingDefinition, NumberingDefinitions, NumberingLevel, readNumberingDefinitions } from "./list/numbering.cjs";
29
29
  import { readSubdocumentStories, storyText } from "./subdocument.cjs";
30
+ import { StorySubdocument, StorySubdocuments, buildHeaderSubdocument, buildNoteSubdocument, buildStorySubdocuments, paragraphCharacters } from "./subdocument-write.cjs";
30
31
  import { Comment, Footnote, NoteBodies, readNoteBodies } from "./notes.cjs";
31
32
  import { DocContent, DocStreams, readDocContent, readDocStreams } from "./read.cjs";
32
- import { WriteDocContentOptions, writeDocContent } from "./write.cjs";
33
- export { ANNOTATION_REFERENCE, CELL_MARK, COMPRESSED_CHARACTER_MAP, CharacterProperties, ChpxFkp, ChpxRunToWrite, Comment, DATA_STREAM, DRAWN_OBJECT, DataStreamBuilder, DocContent, DocFormatError, DocSectionProperties, DocStreams, DocUnsupportedError, FC_LCB_VALUE_INDEX, FIB_BASE_FLAG, FIB_BASE_SIZE, FIB_CB_RG_FC_LCB_OFFSET, FIB_CSLW_OFFSET, FIB_CSLW_REQUIRED, FIB_CSW_REQUIRED, FIB_FC_LCB_BLOB_OFFSET, FIB_LKEY_OFFSET, FIB_RG_LW_OFFSET, FIB_RG_LW_SIZE, FIB_RG_W_OFFSET, FIB_RG_W_SIZE, FIB_W_IDENT, FIELD_BEGIN, FIELD_END, FIELD_SEPARATOR, FKP_PAGE_SIZE, FOOTNOTE_REFERENCE, Fib, FibWriteSpec, Footnote, HeaderFooterSlot, HeaderFooterStories, HeaderFooterStory, INLINE_PICTURE, LINE_BREAK, LW_OFFSET, NUMBER_FORMAT_BY_NFC, NoteBodies, NumberingDefinition, NumberingDefinitions, NumberingLevel, PARAGRAPH_MARK, PapxFkp, PapxLookup, PapxParagraphToWrite, PapxRecord, ParagraphEntry, ParagraphProperties, Piece, PieceTable, Plc, Prl, PropertyBinTable, ReadContext, ResolvedStyleFormatting, SECTION_MARK, SGC, STI_USER_DEFINED, STK, SUMMARY_INFORMATION_STREAM, SYMBOL_ANCHOR, SectionProperties, Sprm, Style, StyleSheet, TextRange, WORD_DOCUMENT_STREAM, WriteDocContentOptions, applyCharacterSprms, applyParagraphSprms, applySectionSprms, base64ToBytes, buildChpxPages, buildFib, buildFontTable, buildPapxPages, buildPlcfSed, buildPropertyBinTable, buildSepx, buildStshForStyles, buildTextClx, bytesToBase64, characterIstdFromGrpprl, characterOffset, characterSize, decodeSprm, encodeCharacterGrpprl, encodeParagraphGrpprl, encodeSectionGrpprl, endsParagraph, findLargestAtMost, firstFcOfPage, fitsAloneOnPapxPage, headingLevelFromIstd, isAnchorOnly, isDocBytes, layoutMetadataToSummaryInformation, operandSize, parseChpxFkp, parseClx, parseFib, parseFontTable, parsePapxFkp, parsePlc, parseStsh, peekFibBaseFlags, readAllSectionProperties, readDocContent, readDocStreams, readGrpprl, readHeaderFooterStories, readInt16LE, readInt32LE, readNoteBodies, readNumberingDefinitions, readParagraphs, readSubdocumentStories, readTextRange, readUint16LE, readUint32LE, readUint8, resolveStyleFormatting, slice, splitEntriesByBoundaries, storyText, tableStreamName, writeDocContent };
33
+ import { WritableDocContent, WriteDocContentOptions, writeDocContent } from "./write.cjs";
34
+ export { ANNOTATION_REFERENCE, CELL_MARK, COMPRESSED_CHARACTER_MAP, CharacterProperties, ChpxFkp, ChpxRunToWrite, Comment, DATA_STREAM, DRAWN_OBJECT, DataStreamBuilder, DocContent, DocFormatError, DocSectionProperties, DocStreams, DocUnsupportedError, FC_LCB_VALUE_INDEX, FIB_BASE_FLAG, FIB_BASE_SIZE, FIB_CB_RG_FC_LCB_OFFSET, FIB_CSLW_OFFSET, FIB_CSLW_REQUIRED, FIB_CSW_REQUIRED, FIB_FC_LCB_BLOB_OFFSET, FIB_LKEY_OFFSET, FIB_RG_LW_OFFSET, FIB_RG_LW_SIZE, FIB_RG_W_OFFSET, FIB_RG_W_SIZE, FIB_W_IDENT, FIELD_BEGIN, FIELD_END, FIELD_SEPARATOR, FIXED_SEPARATOR_STORY_COUNT, FKP_PAGE_SIZE, FOOTNOTE_REFERENCE, Fib, FibWriteSpec, Footnote, HeaderFooterSlot, HeaderFooterStories, HeaderFooterStory, INLINE_PICTURE, LINE_BREAK, LW_OFFSET, NUMBER_FORMAT_BY_NFC, NoteBodies, NumberingDefinition, NumberingDefinitions, NumberingLevel, PARAGRAPH_MARK, PapxFkp, PapxLookup, PapxParagraphToWrite, PapxRecord, ParagraphEntry, ParagraphProperties, Piece, PieceTable, Plc, Prl, PropertyBinTable, ReadContext, ResolvedStyleFormatting, SECTION_MARK, SGC, SLOT_ORDER, STI_USER_DEFINED, STK, SUMMARY_INFORMATION_STREAM, SYMBOL_ANCHOR, SectionProperties, Sprm, StorySubdocument, StorySubdocuments, Style, StyleSheet, TextRange, WORD_DOCUMENT_STREAM, WritableDocContent, WriteDocContentOptions, applyCharacterSprms, applyParagraphSprms, applySectionSprms, base64ToBytes, buildChpxPages, buildFib, buildFontTable, buildHeaderSubdocument, buildNoteSubdocument, buildPapxPages, buildPlcfSed, buildPropertyBinTable, buildSepx, buildStorySubdocuments, buildStshForStyles, buildTextClx, bytesToBase64, characterIstdFromGrpprl, characterOffset, characterSize, decodeSprm, encodeCharacterGrpprl, encodeParagraphGrpprl, encodeSectionGrpprl, endsParagraph, findLargestAtMost, firstFcOfPage, fitsAloneOnPapxPage, headingLevelFromIstd, isAnchorOnly, isDocBytes, layoutMetadataToSummaryInformation, operandSize, paragraphCharacters, parseChpxFkp, parseClx, parseFib, parseFontTable, parsePapxFkp, parsePlc, parseStsh, peekFibBaseFlags, readAllSectionProperties, readDocContent, readDocStreams, readGrpprl, readHeaderFooterStories, readInt16LE, readInt32LE, readNoteBodies, readNumberingDefinitions, readParagraphs, readSubdocumentStories, readTextRange, readUint16LE, readUint32LE, readUint8, resolveStyleFormatting, slice, splitEntriesByBoundaries, storyText, tableStreamName, writeDocContent };
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ import { n as applyParagraphSprms, t as ParagraphProperties } from "./pap-iWFIpC
13
13
  import { a as StyleSheet, c as parseStsh, i as Style, l as resolveStyleFormatting, n as STI_USER_DEFINED, o as buildStshForStyles, r as STK, s as headingLevelFromIstd, t as ResolvedStyleFormatting } from "./stsh-Bj0YSEOp.js";
14
14
  import { i as splitEntriesByBoundaries, n as ReadContext, r as readParagraphs, t as ParagraphEntry } from "./paragraphs-s2lJ6w2I.js";
15
15
  import { a as parseClx, i as characterSize, n as PieceTable, r as characterOffset, t as Piece } from "./piece-table-CA18mhjv.js";
16
- import { HeaderFooterSlot, HeaderFooterStories, HeaderFooterStory, readHeaderFooterStories } from "./headers-footers.js";
16
+ import { FIXED_SEPARATOR_STORY_COUNT, HeaderFooterSlot, HeaderFooterStories, HeaderFooterStory, SLOT_ORDER, readHeaderFooterStories } from "./headers-footers.js";
17
17
  import { Plc, findLargestAtMost, parsePlc } from "./plc.js";
18
18
  import { layoutMetadataToSummaryInformation } from "./metadata.js";
19
19
  import { buildTextClx } from "./text/piece-table-write.js";
@@ -27,7 +27,8 @@ import { buildPlcfSed, buildSepx, encodeSectionGrpprl } from "./prop/sep-write.j
27
27
  import { buildFontTable, parseFontTable } from "./style/fonts.js";
28
28
  import { NUMBER_FORMAT_BY_NFC, NumberingDefinition, NumberingDefinitions, NumberingLevel, readNumberingDefinitions } from "./list/numbering.js";
29
29
  import { readSubdocumentStories, storyText } from "./subdocument.js";
30
+ import { StorySubdocument, StorySubdocuments, buildHeaderSubdocument, buildNoteSubdocument, buildStorySubdocuments, paragraphCharacters } from "./subdocument-write.js";
30
31
  import { Comment, Footnote, NoteBodies, readNoteBodies } from "./notes.js";
31
32
  import { DocContent, DocStreams, readDocContent, readDocStreams } from "./read.js";
32
- import { WriteDocContentOptions, writeDocContent } from "./write.js";
33
- export { ANNOTATION_REFERENCE, CELL_MARK, COMPRESSED_CHARACTER_MAP, CharacterProperties, ChpxFkp, ChpxRunToWrite, Comment, DATA_STREAM, DRAWN_OBJECT, DataStreamBuilder, DocContent, DocFormatError, DocSectionProperties, DocStreams, DocUnsupportedError, FC_LCB_VALUE_INDEX, FIB_BASE_FLAG, FIB_BASE_SIZE, FIB_CB_RG_FC_LCB_OFFSET, FIB_CSLW_OFFSET, FIB_CSLW_REQUIRED, FIB_CSW_REQUIRED, FIB_FC_LCB_BLOB_OFFSET, FIB_LKEY_OFFSET, FIB_RG_LW_OFFSET, FIB_RG_LW_SIZE, FIB_RG_W_OFFSET, FIB_RG_W_SIZE, FIB_W_IDENT, FIELD_BEGIN, FIELD_END, FIELD_SEPARATOR, FKP_PAGE_SIZE, FOOTNOTE_REFERENCE, Fib, FibWriteSpec, Footnote, HeaderFooterSlot, HeaderFooterStories, HeaderFooterStory, INLINE_PICTURE, LINE_BREAK, LW_OFFSET, NUMBER_FORMAT_BY_NFC, NoteBodies, NumberingDefinition, NumberingDefinitions, NumberingLevel, PARAGRAPH_MARK, PapxFkp, PapxLookup, PapxParagraphToWrite, PapxRecord, ParagraphEntry, ParagraphProperties, Piece, PieceTable, Plc, Prl, PropertyBinTable, ReadContext, ResolvedStyleFormatting, SECTION_MARK, SGC, STI_USER_DEFINED, STK, SUMMARY_INFORMATION_STREAM, SYMBOL_ANCHOR, SectionProperties, Sprm, Style, StyleSheet, TextRange, WORD_DOCUMENT_STREAM, WriteDocContentOptions, applyCharacterSprms, applyParagraphSprms, applySectionSprms, base64ToBytes, buildChpxPages, buildFib, buildFontTable, buildPapxPages, buildPlcfSed, buildPropertyBinTable, buildSepx, buildStshForStyles, buildTextClx, bytesToBase64, characterIstdFromGrpprl, characterOffset, characterSize, decodeSprm, encodeCharacterGrpprl, encodeParagraphGrpprl, encodeSectionGrpprl, endsParagraph, findLargestAtMost, firstFcOfPage, fitsAloneOnPapxPage, headingLevelFromIstd, isAnchorOnly, isDocBytes, layoutMetadataToSummaryInformation, operandSize, parseChpxFkp, parseClx, parseFib, parseFontTable, parsePapxFkp, parsePlc, parseStsh, peekFibBaseFlags, readAllSectionProperties, readDocContent, readDocStreams, readGrpprl, readHeaderFooterStories, readInt16LE, readInt32LE, readNoteBodies, readNumberingDefinitions, readParagraphs, readSubdocumentStories, readTextRange, readUint16LE, readUint32LE, readUint8, resolveStyleFormatting, slice, splitEntriesByBoundaries, storyText, tableStreamName, writeDocContent };
33
+ import { WritableDocContent, WriteDocContentOptions, writeDocContent } from "./write.js";
34
+ export { ANNOTATION_REFERENCE, CELL_MARK, COMPRESSED_CHARACTER_MAP, CharacterProperties, ChpxFkp, ChpxRunToWrite, Comment, DATA_STREAM, DRAWN_OBJECT, DataStreamBuilder, DocContent, DocFormatError, DocSectionProperties, DocStreams, DocUnsupportedError, FC_LCB_VALUE_INDEX, FIB_BASE_FLAG, FIB_BASE_SIZE, FIB_CB_RG_FC_LCB_OFFSET, FIB_CSLW_OFFSET, FIB_CSLW_REQUIRED, FIB_CSW_REQUIRED, FIB_FC_LCB_BLOB_OFFSET, FIB_LKEY_OFFSET, FIB_RG_LW_OFFSET, FIB_RG_LW_SIZE, FIB_RG_W_OFFSET, FIB_RG_W_SIZE, FIB_W_IDENT, FIELD_BEGIN, FIELD_END, FIELD_SEPARATOR, FIXED_SEPARATOR_STORY_COUNT, FKP_PAGE_SIZE, FOOTNOTE_REFERENCE, Fib, FibWriteSpec, Footnote, HeaderFooterSlot, HeaderFooterStories, HeaderFooterStory, INLINE_PICTURE, LINE_BREAK, LW_OFFSET, NUMBER_FORMAT_BY_NFC, NoteBodies, NumberingDefinition, NumberingDefinitions, NumberingLevel, PARAGRAPH_MARK, PapxFkp, PapxLookup, PapxParagraphToWrite, PapxRecord, ParagraphEntry, ParagraphProperties, Piece, PieceTable, Plc, Prl, PropertyBinTable, ReadContext, ResolvedStyleFormatting, SECTION_MARK, SGC, SLOT_ORDER, STI_USER_DEFINED, STK, SUMMARY_INFORMATION_STREAM, SYMBOL_ANCHOR, SectionProperties, Sprm, StorySubdocument, StorySubdocuments, Style, StyleSheet, TextRange, WORD_DOCUMENT_STREAM, WritableDocContent, WriteDocContentOptions, applyCharacterSprms, applyParagraphSprms, applySectionSprms, base64ToBytes, buildChpxPages, buildFib, buildFontTable, buildHeaderSubdocument, buildNoteSubdocument, buildPapxPages, buildPlcfSed, buildPropertyBinTable, buildSepx, buildStorySubdocuments, buildStshForStyles, buildTextClx, bytesToBase64, characterIstdFromGrpprl, characterOffset, characterSize, decodeSprm, encodeCharacterGrpprl, encodeParagraphGrpprl, encodeSectionGrpprl, endsParagraph, findLargestAtMost, firstFcOfPage, fitsAloneOnPapxPage, headingLevelFromIstd, isAnchorOnly, isDocBytes, layoutMetadataToSummaryInformation, operandSize, paragraphCharacters, parseChpxFkp, parseClx, parseFib, parseFontTable, parsePapxFkp, parsePlc, parseStsh, peekFibBaseFlags, readAllSectionProperties, readDocContent, readDocStreams, readGrpprl, readHeaderFooterStories, readInt16LE, readInt32LE, readNoteBodies, readNumberingDefinitions, readParagraphs, readSubdocumentStories, readTextRange, readUint16LE, readUint32LE, readUint8, resolveStyleFormatting, slice, splitEntriesByBoundaries, storyText, tableStreamName, writeDocContent };
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import { readParagraphs, splitEntriesByBoundaries } from "./text/paragraphs.js";
15
15
  import { characterOffset, characterSize, parseClx } from "./text/piece-table.js";
16
16
  import { COMPRESSED_CHARACTER_MAP, readTextRange } from "./text/characters.js";
17
17
  import { readSubdocumentStories, storyText } from "./subdocument.js";
18
- import { readHeaderFooterStories } from "./headers-footers.js";
18
+ import { FIXED_SEPARATOR_STORY_COUNT, SLOT_ORDER, readHeaderFooterStories } from "./headers-footers.js";
19
19
  import { parseFib, peekFibBaseFlags, tableStreamName } from "./fib/fib.js";
20
20
  import { buildFib } from "./fib/write.js";
21
21
  import { layoutMetadataToSummaryInformation } from "./metadata.js";
@@ -27,7 +27,8 @@ import { applySectionSprms, readAllSectionProperties } from "./prop/sep.js";
27
27
  import { buildPlcfSed, buildSepx, encodeSectionGrpprl } from "./prop/sep-write.js";
28
28
  import { buildFontTable, parseFontTable } from "./style/fonts.js";
29
29
  import { NUMBER_FORMAT_BY_NFC, readNumberingDefinitions } from "./list/numbering.js";
30
+ import { buildHeaderSubdocument, buildNoteSubdocument, buildStorySubdocuments, paragraphCharacters } from "./subdocument-write.js";
30
31
  import { readNoteBodies } from "./notes.js";
31
32
  import { readDocContent, readDocStreams } from "./read.js";
32
33
  import { writeDocContent } from "./write.js";
33
- export { ANNOTATION_REFERENCE, CELL_MARK, COMPRESSED_CHARACTER_MAP, DATA_STREAM, DRAWN_OBJECT, DataStreamBuilder, DocFormatError, DocUnsupportedError, FC_LCB_VALUE_INDEX, FIB_BASE_FLAG, FIB_BASE_SIZE, FIB_CB_RG_FC_LCB_OFFSET, FIB_CSLW_OFFSET, FIB_CSLW_REQUIRED, FIB_CSW_REQUIRED, FIB_FC_LCB_BLOB_OFFSET, FIB_LKEY_OFFSET, FIB_RG_LW_OFFSET, FIB_RG_LW_SIZE, FIB_RG_W_OFFSET, FIB_RG_W_SIZE, FIB_W_IDENT, FIELD_BEGIN, FIELD_END, FIELD_SEPARATOR, FKP_PAGE_SIZE, FOOTNOTE_REFERENCE, INLINE_PICTURE, LINE_BREAK, LW_OFFSET, NUMBER_FORMAT_BY_NFC, PARAGRAPH_MARK, PropertyBinTable, SECTION_MARK, SGC, STI_USER_DEFINED, STK, SUMMARY_INFORMATION_STREAM, SYMBOL_ANCHOR, WORD_DOCUMENT_STREAM, applyCharacterSprms, applyParagraphSprms, applySectionSprms, base64ToBytes, buildChpxPages, buildFib, buildFontTable, buildPapxPages, buildPlcfSed, buildPropertyBinTable, buildSepx, buildStshForStyles, buildTextClx, bytesToBase64, characterIstdFromGrpprl, characterOffset, characterSize, decodeSprm, encodeCharacterGrpprl, encodeParagraphGrpprl, encodeSectionGrpprl, endsParagraph, findLargestAtMost, firstFcOfPage, fitsAloneOnPapxPage, headingLevelFromIstd, isAnchorOnly, isDocBytes, layoutMetadataToSummaryInformation, operandSize, parseChpxFkp, parseClx, parseFib, parseFontTable, parsePapxFkp, parsePlc, parseStsh, peekFibBaseFlags, readAllSectionProperties, readDocContent, readDocStreams, readGrpprl, readHeaderFooterStories, readInt16LE, readInt32LE, readNoteBodies, readNumberingDefinitions, readParagraphs, readSubdocumentStories, readTextRange, readUint16LE, readUint32LE, readUint8, resolveStyleFormatting, slice, splitEntriesByBoundaries, storyText, tableStreamName, writeDocContent };
34
+ export { ANNOTATION_REFERENCE, CELL_MARK, COMPRESSED_CHARACTER_MAP, DATA_STREAM, DRAWN_OBJECT, DataStreamBuilder, DocFormatError, DocUnsupportedError, FC_LCB_VALUE_INDEX, FIB_BASE_FLAG, FIB_BASE_SIZE, FIB_CB_RG_FC_LCB_OFFSET, FIB_CSLW_OFFSET, FIB_CSLW_REQUIRED, FIB_CSW_REQUIRED, FIB_FC_LCB_BLOB_OFFSET, FIB_LKEY_OFFSET, FIB_RG_LW_OFFSET, FIB_RG_LW_SIZE, FIB_RG_W_OFFSET, FIB_RG_W_SIZE, FIB_W_IDENT, FIELD_BEGIN, FIELD_END, FIELD_SEPARATOR, FIXED_SEPARATOR_STORY_COUNT, FKP_PAGE_SIZE, FOOTNOTE_REFERENCE, INLINE_PICTURE, LINE_BREAK, LW_OFFSET, NUMBER_FORMAT_BY_NFC, PARAGRAPH_MARK, PropertyBinTable, SECTION_MARK, SGC, SLOT_ORDER, STI_USER_DEFINED, STK, SUMMARY_INFORMATION_STREAM, SYMBOL_ANCHOR, WORD_DOCUMENT_STREAM, applyCharacterSprms, applyParagraphSprms, applySectionSprms, base64ToBytes, buildChpxPages, buildFib, buildFontTable, buildHeaderSubdocument, buildNoteSubdocument, buildPapxPages, buildPlcfSed, buildPropertyBinTable, buildSepx, buildStorySubdocuments, buildStshForStyles, buildTextClx, bytesToBase64, characterIstdFromGrpprl, characterOffset, characterSize, decodeSprm, encodeCharacterGrpprl, encodeParagraphGrpprl, encodeSectionGrpprl, endsParagraph, findLargestAtMost, firstFcOfPage, fitsAloneOnPapxPage, headingLevelFromIstd, isAnchorOnly, isDocBytes, layoutMetadataToSummaryInformation, operandSize, paragraphCharacters, parseChpxFkp, parseClx, parseFib, parseFontTable, parsePapxFkp, parsePlc, parseStsh, peekFibBaseFlags, readAllSectionProperties, readDocContent, readDocStreams, readGrpprl, readHeaderFooterStories, readInt16LE, readInt32LE, readNoteBodies, readNumberingDefinitions, readParagraphs, readSubdocumentStories, readTextRange, readUint16LE, readUint32LE, readUint8, resolveStyleFormatting, slice, splitEntriesByBoundaries, storyText, tableStreamName, writeDocContent };
@@ -74,9 +74,7 @@ const NUMBER_FORMAT_BY_NFC = {
74
74
  const NFC_NONE = 255;
75
75
  function numberFormatFor(nfc) {
76
76
  if (nfc === NFC_NONE) return "none";
77
- const format = NUMBER_FORMAT_BY_NFC[nfc];
78
- if (format === void 0) throw new require_errors.DocFormatError(`LVLF.nfc is 0x${nfc.toString(16).padStart(2, "0")}, not a recognised MSONFC value ([MS-OSHARED] 2.2.1.3)`);
79
- return format;
77
+ return NUMBER_FORMAT_BY_NFC[nfc] ?? "decimal";
80
78
  }
81
79
  /** LSTF ([MS-DOC] 2.9.147): lsid(4) + tplc(4, ignored -- UI-only) + rgistdPara(18, ignored -- this reader has no per-level style cascade to link into) + a flags byte (only fSimpleList, bit 0, acted on) + grfhic(1, ignored -- HTML-export-only incompatibility flags). Fixed 28 bytes. */
82
80
  function readLstf(bytes, offset) {
@@ -73,9 +73,7 @@ const NUMBER_FORMAT_BY_NFC = {
73
73
  const NFC_NONE = 255;
74
74
  function numberFormatFor(nfc) {
75
75
  if (nfc === NFC_NONE) return "none";
76
- const format = NUMBER_FORMAT_BY_NFC[nfc];
77
- if (format === void 0) throw new DocFormatError(`LVLF.nfc is 0x${nfc.toString(16).padStart(2, "0")}, not a recognised MSONFC value ([MS-OSHARED] 2.2.1.3)`);
78
- return format;
76
+ return NUMBER_FORMAT_BY_NFC[nfc] ?? "decimal";
79
77
  }
80
78
  /** LSTF ([MS-DOC] 2.9.147): lsid(4) + tplc(4, ignored -- UI-only) + rgistdPara(18, ignored -- this reader has no per-level style cascade to link into) + a flags byte (only fSimpleList, bit 0, acted on) + grfhic(1, ignored -- HTML-export-only incompatibility flags). Fixed 28 bytes. */
81
79
  function readLstf(bytes, offset) {
package/dist/read.cjs CHANGED
@@ -5,6 +5,7 @@ const require_detect = require("./detect.cjs");
5
5
  const require_encryption = require("./encryption.cjs");
6
6
  const require_prop_fkp = require("./prop/fkp.cjs");
7
7
  const require_style_stsh = require("./style/stsh.cjs");
8
+ require("./text/special.cjs");
8
9
  const require_text_paragraphs = require("./text/paragraphs.cjs");
9
10
  const require_text_piece_table = require("./text/piece-table.cjs");
10
11
  const require_text_characters = require("./text/characters.cjs");
@@ -70,7 +71,7 @@ function readDocContent(bytes, password) {
70
71
  const entries = require_text_paragraphs.readParagraphs(range.text, range.fcs, context);
71
72
  const numbering = require_list_numbering.readNumberingDefinitions(table, fib);
72
73
  const sectionProperties = require_prop_sep.readAllSectionProperties(wordDocument, table, fib);
73
- const entriesBySection = splitIntoSections(entries, sectionProperties);
74
+ const entriesBySection = splitIntoSections(markManualPageBreaks(entries, sectionProperties), sectionProperties);
74
75
  const { footnotes, endnotes, comments } = require_notes.readNoteBodies(wordDocument, table, pieceTable, context, fib);
75
76
  const headerFooterStories = require_headers_footers.readHeaderFooterStories(wordDocument, table, pieceTable, context, fib, sectionProperties.length);
76
77
  return {
@@ -87,7 +88,7 @@ function readDocContent(bytes, password) {
87
88
  topPt: properties.marginTopPt ?? DEFAULT_MARGINS.topPt,
88
89
  bottomPt: properties.marginBottomPt ?? DEFAULT_MARGINS.bottomPt
89
90
  },
90
- blocks: require_table_read.assembleBlocks(entriesBySection[index] ?? [])
91
+ blocks: require_table_read.assembleBlocks(entriesBySection[index] ?? [], index === sectionProperties.length - 1)
91
92
  })),
92
93
  numbering,
93
94
  footnotes,
@@ -96,6 +97,22 @@ function readDocContent(bytes, password) {
96
97
  headerFooterStories
97
98
  };
98
99
  }
100
+ /** The single block a manual page break reads as -- no fields of its own, exactly the shape every other codec in this family emits for one. */
101
+ const PAGE_BREAK_BLOCK = { kind: "pageBreak" };
102
+ function markManualPageBreaks(entries, sections) {
103
+ const sectionEndCps = /* @__PURE__ */ new Set();
104
+ for (let index = 1; index < sections.length; index += 1) {
105
+ const startCp = sections[index]?.startCp;
106
+ if (startCp !== void 0) sectionEndCps.add(startCp);
107
+ }
108
+ return entries.map((entry) => {
109
+ if (entry.terminator !== 12 || sectionEndCps.has(entry.endCp)) return entry;
110
+ return {
111
+ ...entry,
112
+ blocks: [...entry.blocks, PAGE_BREAK_BLOCK]
113
+ };
114
+ });
115
+ }
99
116
  function splitIntoSections(entries, sections) {
100
117
  const groups = sections.map(() => []);
101
118
  let sectionIndex = 0;
package/dist/read.js CHANGED
@@ -4,6 +4,7 @@ import { DATA_STREAM, SUMMARY_INFORMATION_STREAM, WORD_DOCUMENT_STREAM } from ".
4
4
  import { decryptDocStreams } from "./encryption.js";
5
5
  import { PropertyBinTable } from "./prop/fkp.js";
6
6
  import { parseStsh } from "./style/stsh.js";
7
+ import "./text/special.js";
7
8
  import { readParagraphs } from "./text/paragraphs.js";
8
9
  import { parseClx } from "./text/piece-table.js";
9
10
  import { readTextRange } from "./text/characters.js";
@@ -69,7 +70,7 @@ function readDocContent(bytes, password) {
69
70
  const entries = readParagraphs(range.text, range.fcs, context);
70
71
  const numbering = readNumberingDefinitions(table, fib);
71
72
  const sectionProperties = readAllSectionProperties(wordDocument, table, fib);
72
- const entriesBySection = splitIntoSections(entries, sectionProperties);
73
+ const entriesBySection = splitIntoSections(markManualPageBreaks(entries, sectionProperties), sectionProperties);
73
74
  const { footnotes, endnotes, comments } = readNoteBodies(wordDocument, table, pieceTable, context, fib);
74
75
  const headerFooterStories = readHeaderFooterStories(wordDocument, table, pieceTable, context, fib, sectionProperties.length);
75
76
  return {
@@ -86,7 +87,7 @@ function readDocContent(bytes, password) {
86
87
  topPt: properties.marginTopPt ?? DEFAULT_MARGINS.topPt,
87
88
  bottomPt: properties.marginBottomPt ?? DEFAULT_MARGINS.bottomPt
88
89
  },
89
- blocks: assembleBlocks(entriesBySection[index] ?? [])
90
+ blocks: assembleBlocks(entriesBySection[index] ?? [], index === sectionProperties.length - 1)
90
91
  })),
91
92
  numbering,
92
93
  footnotes,
@@ -95,6 +96,22 @@ function readDocContent(bytes, password) {
95
96
  headerFooterStories
96
97
  };
97
98
  }
99
+ /** The single block a manual page break reads as -- no fields of its own, exactly the shape every other codec in this family emits for one. */
100
+ const PAGE_BREAK_BLOCK = { kind: "pageBreak" };
101
+ function markManualPageBreaks(entries, sections) {
102
+ const sectionEndCps = /* @__PURE__ */ new Set();
103
+ for (let index = 1; index < sections.length; index += 1) {
104
+ const startCp = sections[index]?.startCp;
105
+ if (startCp !== void 0) sectionEndCps.add(startCp);
106
+ }
107
+ return entries.map((entry) => {
108
+ if (entry.terminator !== 12 || sectionEndCps.has(entry.endCp)) return entry;
109
+ return {
110
+ ...entry,
111
+ blocks: [...entry.blocks, PAGE_BREAK_BLOCK]
112
+ };
113
+ });
114
+ }
98
115
  function splitIntoSections(entries, sections) {
99
116
  const groups = sections.map(() => []);
100
117
  let sectionIndex = 0;
@@ -0,0 +1,108 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_errors = require("./errors.cjs");
3
+ require("./text/special.cjs");
4
+ const require_headers_footers = require("./headers-footers.cjs");
5
+ const require_table_write = require("./table/write.cjs");
6
+ //#region src/subdocument-write.ts
7
+ /** A plain one-run text run: no character formatting, no extra grpprl -- a note body's own text carries no modelled formatting to state. */
8
+ function textRun(text) {
9
+ return {
10
+ run: { text },
11
+ extraGrpprl: []
12
+ };
13
+ }
14
+ /** The bare paragraph mark every non-empty story ends with -- no runs, no properties, the "not considered part of the story contents" guard itself. */
15
+ function guardParagraph() {
16
+ return {
17
+ runs: [],
18
+ properties: {},
19
+ extraGrpprl: [],
20
+ terminator: 13
21
+ };
22
+ }
23
+ /** One paragraph's own character footprint in the text stream: every run's own characters plus the paragraph's own terminator. Exported because write.ts counts the main document's own ccpText with the identical arithmetic -- one source, so the two can never disagree about what a paragraph costs. */
24
+ function paragraphCharacters(paragraph) {
25
+ return 1 + paragraph.runs.reduce((count, run) => count + run.run.text.length, 0);
26
+ }
27
+ /** A CP-only plex (element size 0, [MS-DOC] 2.2.2's own "the data thus has a size of 0 bytes" shape PlcffndTxt/PlcfandTxt/PlcfendTxt/PlcfHdd all share): just the aCP array, one 4-byte little-endian value per key. */
28
+ function buildCpOnlyPlex(keys) {
29
+ const bytes = new Uint8Array(keys.length * 4);
30
+ const view = new DataView(bytes.buffer);
31
+ keys.forEach((key, index) => {
32
+ view.setUint32(index * 4, key, true);
33
+ });
34
+ return bytes;
35
+ }
36
+ function finishSubdocument(paragraphs, storyStarts, characters) {
37
+ paragraphs.push(guardParagraph());
38
+ const ccp = characters + 1;
39
+ return {
40
+ paragraphs,
41
+ plex: buildCpOnlyPlex([
42
+ ...storyStarts,
43
+ characters,
44
+ ccp
45
+ ]),
46
+ ccp
47
+ };
48
+ }
49
+ function buildNoteSubdocument(notes) {
50
+ const paragraphs = [];
51
+ const storyStarts = [];
52
+ let characters = 0;
53
+ for (const note of notes) {
54
+ storyStarts.push(characters);
55
+ const story = note.text.split("\n").map((line) => ({
56
+ runs: line === "" ? [] : [textRun(line)],
57
+ properties: {},
58
+ extraGrpprl: [],
59
+ terminator: 13
60
+ }));
61
+ story.push(guardParagraph());
62
+ for (const paragraph of story) characters += paragraphCharacters(paragraph);
63
+ paragraphs.push(...story);
64
+ }
65
+ return finishSubdocument(paragraphs, storyStarts, characters);
66
+ }
67
+ function buildHeaderSubdocument(stories, sectionCount, dataStream, onWarning) {
68
+ const bySlot = /* @__PURE__ */ new Map();
69
+ for (const story of stories) {
70
+ if (!Number.isInteger(story.section) || story.section < 0 || story.section >= sectionCount) throw new require_errors.DocFormatError(`a header/footer story names section ${String(story.section)}, but this document has ${String(sectionCount)} sections`);
71
+ const key = `${String(story.section)}:${story.slot}`;
72
+ if (bySlot.has(key)) throw new require_errors.DocFormatError(`more than one header/footer story was given for section ${String(story.section)}'s ${story.slot} slot; a slot holds one story`);
73
+ bySlot.set(key, story);
74
+ }
75
+ const paragraphs = [];
76
+ const storyStarts = [];
77
+ let characters = 0;
78
+ for (let count = 0; count < 6; count += 1) storyStarts.push(0);
79
+ for (let section = 0; section < sectionCount; section += 1) for (const slot of require_headers_footers.SLOT_ORDER) {
80
+ storyStarts.push(characters);
81
+ const story = bySlot.get(`${String(section)}:${slot}`);
82
+ if (story === void 0) continue;
83
+ let content = require_table_write.flattenSectionBlocks(story.blocks, dataStream, onWarning);
84
+ if (content.length === 0) content = [{
85
+ runs: [],
86
+ properties: {},
87
+ extraGrpprl: [],
88
+ terminator: 13
89
+ }];
90
+ content.push(guardParagraph());
91
+ for (const paragraph of content) characters += paragraphCharacters(paragraph);
92
+ paragraphs.push(...content);
93
+ }
94
+ return finishSubdocument(paragraphs, storyStarts, characters);
95
+ }
96
+ function buildStorySubdocuments(document, dataStream, onWarning) {
97
+ return {
98
+ footnote: document.footnotes !== void 0 && document.footnotes.length > 0 ? buildNoteSubdocument(document.footnotes) : void 0,
99
+ header: document.headerFooterStories !== void 0 && document.headerFooterStories.length > 0 ? buildHeaderSubdocument(document.headerFooterStories, document.sections.length, dataStream, onWarning) : void 0,
100
+ comment: document.comments !== void 0 && document.comments.length > 0 ? buildNoteSubdocument(document.comments) : void 0,
101
+ endnote: document.endnotes !== void 0 && document.endnotes.length > 0 ? buildNoteSubdocument(document.endnotes) : void 0
102
+ };
103
+ }
104
+ //#endregion
105
+ exports.buildHeaderSubdocument = buildHeaderSubdocument;
106
+ exports.buildNoteSubdocument = buildNoteSubdocument;
107
+ exports.buildStorySubdocuments = buildStorySubdocuments;
108
+ exports.paragraphCharacters = paragraphCharacters;
@@ -0,0 +1,42 @@
1
+ import { t as DataStreamBuilder } from "./data-stream-BLCj4-V1.cjs";
2
+ import { HeaderFooterStory } from "./headers-footers.cjs";
3
+ import { r as WriteWarning, t as WriteParagraph } from "./write-CMB3qF4i.cjs";
4
+ import { ContentDocument } from "document-schema.js";
5
+ //#region src/subdocument-write.d.ts
6
+ /** One written subdocument: its paragraphs (to be appended after the main document's own, in [MS-DOC]'s own subdocument order), the CP-only plex dividing them into stories, and the ccp the FIB states for it. `undefined` never appears here -- a subdocument with no stories is not written at all (write.ts leaves its ccp and fc/lcb pairs zero, exactly what the reader treats as "absent"). */
7
+ interface StorySubdocument {
8
+ readonly paragraphs: readonly WriteParagraph[];
9
+ readonly plex: Uint8Array<ArrayBuffer>;
10
+ readonly ccp: number;
11
+ }
12
+ /** One paragraph's own character footprint in the text stream: every run's own characters plus the paragraph's own terminator. Exported because write.ts counts the main document's own ccpText with the identical arithmetic -- one source, so the two can never disagree about what a paragraph costs. */
13
+ declare function paragraphCharacters(paragraph: WriteParagraph): number;
14
+ declare function buildNoteSubdocument(notes: readonly {
15
+ readonly text: string;
16
+ }[]): StorySubdocument;
17
+ declare function buildHeaderSubdocument(stories: readonly HeaderFooterStory[], sectionCount: number, dataStream: DataStreamBuilder, onWarning?: WriteWarning): StorySubdocument;
18
+ /** Every story subdocument a document carries, in [MS-DOC]'s own concatenation order (footnote, header, comment, endnote -- the same order notes.ts/read.ts count ccp boundaries in), each undefined when the document carries none of that kind. */
19
+ interface StorySubdocuments {
20
+ readonly footnote: StorySubdocument | undefined;
21
+ readonly header: StorySubdocument | undefined;
22
+ readonly comment: StorySubdocument | undefined;
23
+ readonly endnote: StorySubdocument | undefined;
24
+ }
25
+ /** The input type's own optional story fields, isolated here so buildStorySubdocuments states its shape once -- writeDocContent's WritableDocContent satisfies it directly. */
26
+ interface StorySources {
27
+ readonly footnotes?: readonly {
28
+ readonly text: string;
29
+ }[];
30
+ readonly endnotes?: readonly {
31
+ readonly text: string;
32
+ }[];
33
+ readonly comments?: readonly {
34
+ readonly text: string;
35
+ }[];
36
+ readonly headerFooterStories?: readonly HeaderFooterStory[];
37
+ }
38
+ declare function buildStorySubdocuments(document: StorySources & Pick<Extract<ContentDocument, {
39
+ kind: "wordprocessing";
40
+ }>, "sections">, dataStream: DataStreamBuilder, onWarning?: WriteWarning): StorySubdocuments;
41
+ //#endregion
42
+ export { StorySubdocument, StorySubdocuments, buildHeaderSubdocument, buildNoteSubdocument, buildStorySubdocuments, paragraphCharacters };
@@ -0,0 +1,42 @@
1
+ import { t as DataStreamBuilder } from "./data-stream-BLCj4-V1.js";
2
+ import { HeaderFooterStory } from "./headers-footers.js";
3
+ import { r as WriteWarning, t as WriteParagraph } from "./write-t4rFgnA-.js";
4
+ import { ContentDocument } from "document-schema.js";
5
+ //#region src/subdocument-write.d.ts
6
+ /** One written subdocument: its paragraphs (to be appended after the main document's own, in [MS-DOC]'s own subdocument order), the CP-only plex dividing them into stories, and the ccp the FIB states for it. `undefined` never appears here -- a subdocument with no stories is not written at all (write.ts leaves its ccp and fc/lcb pairs zero, exactly what the reader treats as "absent"). */
7
+ interface StorySubdocument {
8
+ readonly paragraphs: readonly WriteParagraph[];
9
+ readonly plex: Uint8Array<ArrayBuffer>;
10
+ readonly ccp: number;
11
+ }
12
+ /** One paragraph's own character footprint in the text stream: every run's own characters plus the paragraph's own terminator. Exported because write.ts counts the main document's own ccpText with the identical arithmetic -- one source, so the two can never disagree about what a paragraph costs. */
13
+ declare function paragraphCharacters(paragraph: WriteParagraph): number;
14
+ declare function buildNoteSubdocument(notes: readonly {
15
+ readonly text: string;
16
+ }[]): StorySubdocument;
17
+ declare function buildHeaderSubdocument(stories: readonly HeaderFooterStory[], sectionCount: number, dataStream: DataStreamBuilder, onWarning?: WriteWarning): StorySubdocument;
18
+ /** Every story subdocument a document carries, in [MS-DOC]'s own concatenation order (footnote, header, comment, endnote -- the same order notes.ts/read.ts count ccp boundaries in), each undefined when the document carries none of that kind. */
19
+ interface StorySubdocuments {
20
+ readonly footnote: StorySubdocument | undefined;
21
+ readonly header: StorySubdocument | undefined;
22
+ readonly comment: StorySubdocument | undefined;
23
+ readonly endnote: StorySubdocument | undefined;
24
+ }
25
+ /** The input type's own optional story fields, isolated here so buildStorySubdocuments states its shape once -- writeDocContent's WritableDocContent satisfies it directly. */
26
+ interface StorySources {
27
+ readonly footnotes?: readonly {
28
+ readonly text: string;
29
+ }[];
30
+ readonly endnotes?: readonly {
31
+ readonly text: string;
32
+ }[];
33
+ readonly comments?: readonly {
34
+ readonly text: string;
35
+ }[];
36
+ readonly headerFooterStories?: readonly HeaderFooterStory[];
37
+ }
38
+ declare function buildStorySubdocuments(document: StorySources & Pick<Extract<ContentDocument, {
39
+ kind: "wordprocessing";
40
+ }>, "sections">, dataStream: DataStreamBuilder, onWarning?: WriteWarning): StorySubdocuments;
41
+ //#endregion
42
+ export { StorySubdocument, StorySubdocuments, buildHeaderSubdocument, buildNoteSubdocument, buildStorySubdocuments, paragraphCharacters };
@@ -0,0 +1,104 @@
1
+ import { DocFormatError } from "./errors.js";
2
+ import "./text/special.js";
3
+ import { SLOT_ORDER } from "./headers-footers.js";
4
+ import { flattenSectionBlocks } from "./table/write.js";
5
+ //#region src/subdocument-write.ts
6
+ /** A plain one-run text run: no character formatting, no extra grpprl -- a note body's own text carries no modelled formatting to state. */
7
+ function textRun(text) {
8
+ return {
9
+ run: { text },
10
+ extraGrpprl: []
11
+ };
12
+ }
13
+ /** The bare paragraph mark every non-empty story ends with -- no runs, no properties, the "not considered part of the story contents" guard itself. */
14
+ function guardParagraph() {
15
+ return {
16
+ runs: [],
17
+ properties: {},
18
+ extraGrpprl: [],
19
+ terminator: 13
20
+ };
21
+ }
22
+ /** One paragraph's own character footprint in the text stream: every run's own characters plus the paragraph's own terminator. Exported because write.ts counts the main document's own ccpText with the identical arithmetic -- one source, so the two can never disagree about what a paragraph costs. */
23
+ function paragraphCharacters(paragraph) {
24
+ return 1 + paragraph.runs.reduce((count, run) => count + run.run.text.length, 0);
25
+ }
26
+ /** A CP-only plex (element size 0, [MS-DOC] 2.2.2's own "the data thus has a size of 0 bytes" shape PlcffndTxt/PlcfandTxt/PlcfendTxt/PlcfHdd all share): just the aCP array, one 4-byte little-endian value per key. */
27
+ function buildCpOnlyPlex(keys) {
28
+ const bytes = new Uint8Array(keys.length * 4);
29
+ const view = new DataView(bytes.buffer);
30
+ keys.forEach((key, index) => {
31
+ view.setUint32(index * 4, key, true);
32
+ });
33
+ return bytes;
34
+ }
35
+ function finishSubdocument(paragraphs, storyStarts, characters) {
36
+ paragraphs.push(guardParagraph());
37
+ const ccp = characters + 1;
38
+ return {
39
+ paragraphs,
40
+ plex: buildCpOnlyPlex([
41
+ ...storyStarts,
42
+ characters,
43
+ ccp
44
+ ]),
45
+ ccp
46
+ };
47
+ }
48
+ function buildNoteSubdocument(notes) {
49
+ const paragraphs = [];
50
+ const storyStarts = [];
51
+ let characters = 0;
52
+ for (const note of notes) {
53
+ storyStarts.push(characters);
54
+ const story = note.text.split("\n").map((line) => ({
55
+ runs: line === "" ? [] : [textRun(line)],
56
+ properties: {},
57
+ extraGrpprl: [],
58
+ terminator: 13
59
+ }));
60
+ story.push(guardParagraph());
61
+ for (const paragraph of story) characters += paragraphCharacters(paragraph);
62
+ paragraphs.push(...story);
63
+ }
64
+ return finishSubdocument(paragraphs, storyStarts, characters);
65
+ }
66
+ function buildHeaderSubdocument(stories, sectionCount, dataStream, onWarning) {
67
+ const bySlot = /* @__PURE__ */ new Map();
68
+ for (const story of stories) {
69
+ if (!Number.isInteger(story.section) || story.section < 0 || story.section >= sectionCount) throw new DocFormatError(`a header/footer story names section ${String(story.section)}, but this document has ${String(sectionCount)} sections`);
70
+ const key = `${String(story.section)}:${story.slot}`;
71
+ if (bySlot.has(key)) throw new DocFormatError(`more than one header/footer story was given for section ${String(story.section)}'s ${story.slot} slot; a slot holds one story`);
72
+ bySlot.set(key, story);
73
+ }
74
+ const paragraphs = [];
75
+ const storyStarts = [];
76
+ let characters = 0;
77
+ for (let count = 0; count < 6; count += 1) storyStarts.push(0);
78
+ for (let section = 0; section < sectionCount; section += 1) for (const slot of SLOT_ORDER) {
79
+ storyStarts.push(characters);
80
+ const story = bySlot.get(`${String(section)}:${slot}`);
81
+ if (story === void 0) continue;
82
+ let content = flattenSectionBlocks(story.blocks, dataStream, onWarning);
83
+ if (content.length === 0) content = [{
84
+ runs: [],
85
+ properties: {},
86
+ extraGrpprl: [],
87
+ terminator: 13
88
+ }];
89
+ content.push(guardParagraph());
90
+ for (const paragraph of content) characters += paragraphCharacters(paragraph);
91
+ paragraphs.push(...content);
92
+ }
93
+ return finishSubdocument(paragraphs, storyStarts, characters);
94
+ }
95
+ function buildStorySubdocuments(document, dataStream, onWarning) {
96
+ return {
97
+ footnote: document.footnotes !== void 0 && document.footnotes.length > 0 ? buildNoteSubdocument(document.footnotes) : void 0,
98
+ header: document.headerFooterStories !== void 0 && document.headerFooterStories.length > 0 ? buildHeaderSubdocument(document.headerFooterStories, document.sections.length, dataStream, onWarning) : void 0,
99
+ comment: document.comments !== void 0 && document.comments.length > 0 ? buildNoteSubdocument(document.comments) : void 0,
100
+ endnote: document.endnotes !== void 0 && document.endnotes.length > 0 ? buildNoteSubdocument(document.endnotes) : void 0
101
+ };
102
+ }
103
+ //#endregion
104
+ export { buildHeaderSubdocument, buildNoteSubdocument, buildStorySubdocuments, paragraphCharacters };
@@ -1,15 +1,32 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_errors = require("./errors.cjs");
2
3
  const require_bytes = require("./bytes.cjs");
3
- const require_plc = require("./plc.cjs");
4
4
  const require_text_paragraphs = require("./text/paragraphs.cjs");
5
5
  const require_text_characters = require("./text/characters.cjs");
6
6
  //#region src/subdocument.ts
7
+ function readStoryPlexKeys(bytes, subdocLength, what) {
8
+ if (bytes.length < 4 || !Number.isInteger((bytes.length - 4) / 4)) throw new require_errors.DocFormatError(`${what} is ${bytes.length} bytes, which does not yield a whole number of 4-byte keys`);
9
+ const keys = [];
10
+ for (let offset = 0; offset < bytes.length; offset += 4) {
11
+ const raw = require_bytes.readInt32LE(bytes, offset);
12
+ const previous = keys[keys.length - 1] ?? 0;
13
+ keys.push(raw < 0 || raw > subdocLength ? previous : Math.max(raw, previous));
14
+ }
15
+ return keys;
16
+ }
7
17
  function readSubdocumentStories(wordDocument, table, pieceTable, context, subdocStartCp, subdocLength, boundaryFc, boundaryLcb, what) {
8
18
  if (subdocLength <= 0 || boundaryLcb <= 0) return [];
9
19
  const range = require_text_characters.readTextRange(wordDocument, pieceTable, subdocStartCp, subdocStartCp + subdocLength);
10
20
  const entries = require_text_paragraphs.readParagraphs(range.text, range.fcs, context);
11
- const plc = require_plc.parsePlc(require_bytes.slice(table, boundaryFc, boundaryLcb, `${what} in the Table stream`), 0, what);
12
- return require_text_paragraphs.splitEntriesByBoundaries(entries, plc.keys).slice(0, -1).map((story) => story.slice(0, -1));
21
+ const keys = readStoryPlexKeys(require_bytes.slice(table, boundaryFc, boundaryLcb, `${what} in the Table stream`), subdocLength, what);
22
+ return require_text_paragraphs.splitEntriesByBoundaries(entries, keys).slice(0, -1).map((story) => endsWithGuardParagraph(story) ? story.slice(0, -1) : story);
23
+ }
24
+ function endsWithGuardParagraph(story) {
25
+ const last = story[story.length - 1];
26
+ if (last === void 0) return false;
27
+ if (last.blocks.length !== 1) return false;
28
+ const only = last.blocks[0];
29
+ return only?.kind === "paragraph" && only.runs.length === 0;
13
30
  }
14
31
  /** Joins a story's own paragraphs into plain text -- one line per paragraph, matching how ooxml.js's own Footnote/Comment reading concatenates a footnote or comment body's `w:t` runs rather than preserving paragraph/run structure. A footnote, endnote, or comment in this family is carried as text alone; only a header or footer keeps real block flow (headers-footers.ts). Non-paragraph blocks a story's own entries produced (an inline picture split out of one of its paragraphs) contribute no text of their own here, the same way an image has no plain-text spelling in ooxml.js's own footnote/comment reading either. */
15
32
  function storyText(entries) {
@@ -1,14 +1,31 @@
1
- import { slice } from "./bytes.js";
2
- import { parsePlc } from "./plc.js";
1
+ import { DocFormatError } from "./errors.js";
2
+ import { readInt32LE, slice } from "./bytes.js";
3
3
  import { readParagraphs, splitEntriesByBoundaries } from "./text/paragraphs.js";
4
4
  import { readTextRange } from "./text/characters.js";
5
5
  //#region src/subdocument.ts
6
+ function readStoryPlexKeys(bytes, subdocLength, what) {
7
+ if (bytes.length < 4 || !Number.isInteger((bytes.length - 4) / 4)) throw new DocFormatError(`${what} is ${bytes.length} bytes, which does not yield a whole number of 4-byte keys`);
8
+ const keys = [];
9
+ for (let offset = 0; offset < bytes.length; offset += 4) {
10
+ const raw = readInt32LE(bytes, offset);
11
+ const previous = keys[keys.length - 1] ?? 0;
12
+ keys.push(raw < 0 || raw > subdocLength ? previous : Math.max(raw, previous));
13
+ }
14
+ return keys;
15
+ }
6
16
  function readSubdocumentStories(wordDocument, table, pieceTable, context, subdocStartCp, subdocLength, boundaryFc, boundaryLcb, what) {
7
17
  if (subdocLength <= 0 || boundaryLcb <= 0) return [];
8
18
  const range = readTextRange(wordDocument, pieceTable, subdocStartCp, subdocStartCp + subdocLength);
9
19
  const entries = readParagraphs(range.text, range.fcs, context);
10
- const plc = parsePlc(slice(table, boundaryFc, boundaryLcb, `${what} in the Table stream`), 0, what);
11
- return splitEntriesByBoundaries(entries, plc.keys).slice(0, -1).map((story) => story.slice(0, -1));
20
+ const keys = readStoryPlexKeys(slice(table, boundaryFc, boundaryLcb, `${what} in the Table stream`), subdocLength, what);
21
+ return splitEntriesByBoundaries(entries, keys).slice(0, -1).map((story) => endsWithGuardParagraph(story) ? story.slice(0, -1) : story);
22
+ }
23
+ function endsWithGuardParagraph(story) {
24
+ const last = story[story.length - 1];
25
+ if (last === void 0) return false;
26
+ if (last.blocks.length !== 1) return false;
27
+ const only = last.blocks[0];
28
+ return only?.kind === "paragraph" && only.runs.length === 0;
12
29
  }
13
30
  /** Joins a story's own paragraphs into plain text -- one line per paragraph, matching how ooxml.js's own Footnote/Comment reading concatenates a footnote or comment body's `w:t` runs rather than preserving paragraph/run structure. A footnote, endnote, or comment in this family is carried as text alone; only a header or footer keeps real block flow (headers-footers.ts). Non-paragraph blocks a story's own entries produced (an inline picture split out of one of its paragraphs) contribute no text of their own here, the same way an image has no plain-text spelling in ooxml.js's own footnote/comment reading either. */
14
31
  function storyText(entries) {