odf.js 1.7.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,9 +18,11 @@ This package is under active development. What's built and shipped:
18
18
  - **Namespaces, media types, mimetype, manifest** (`src/ns.ts`, `src/media-type.ts`, `src/mimetype.ts`, `src/manifest.ts`) — full read *and* write, including `META-INF/manifest.xml`'s exhaustive per-part enumeration and the mimetype part's mandatory first-entry/stored/uncompressed byte layout, verified against real LibreOffice-produced output.
19
19
  - **Style interning** (`src/styles/`) — `StyleRegistry`: adopts a part's existing automatic styles on construction, finds-or-mints on `intern()`, fingerprints on canonical serialized properties plus parent style name (never `JSON.stringify`), and is collision-checked across all four style containers a document can have.
20
20
  - **Shared typed primitives** (`src/typed/shared/`) — ODF length-unit parsing (`cm`/`mm`/`in`/`pt`/`pc`/`px`), A1-style spreadsheet cell-reference computation with repeat-count cursor advancement, colour/geometry/master-page-size parsing into `document-content-model`'s own types, ODF's `text:s`/`text:tab`/`text:line-break` whitespace-run decoding, the read-side style cascade (`style:default-style` → parent chain → the referenced style — one layer shorter than OOXML's, since ODF has no separate direct-formatting layer on top), the `draw:transform`/`draw:g` group-flattening geometry resolver, an `svg:d`/`draw:points` vector-path grammar parser, and `meta.xml` reading.
21
- - **Typed readers** — `readOdt` (wordprocessing), `readOdp` (presentation slides: `draw:frame`/`draw:g` text/image/table content), and `readOdg` (drawing pages: every vector primitive — `draw:rect`/`draw:ellipse`/`draw:circle`/`draw:line`/`draw:path`/`draw:polygon`/`draw:polyline`, plus a recognised `draw:custom-shape` preset subset — in real `draw:z-index`-aware paint order) each resolve a `Package` into `document-content-model`'s own `ContentSection`/`ContentSlide`/`ContentDrawPage` shapes.
21
+ - **Typed readers** — `readOdt` (wordprocessing), `readOdp` (presentation slides: `draw:frame`/`draw:g` text/image/table content), `readOdg` (drawing pages: every vector primitive — `draw:rect`/`draw:ellipse`/`draw:circle`/`draw:line`/`draw:path`/`draw:polygon`/`draw:polyline`, plus a recognised `draw:custom-shape` preset subset — in real `draw:z-index`-aware paint order), and `readOds` (spreadsheets: geometry- and print-settings-rich, every `office:value-type` variant with its own OpenFormula string) each resolve a `Package` into `document-content-model`'s own `ContentSection`/`ContentSlide`/`ContentDrawPage`/`ContentSheet` shapes.
22
+ - **`readOdfFormula`** resolves a standalone or embedded `.odf` formula's `content.xml` — bare MathML with no `office:document-content` wrapper, confirmed against real LibreOffice output — into its raw MathML nodes plus, when present, the formula's own native StarMath annotation string. There is no `document-content-model` pivot type for MathML, so this reader's own output type is its own.
23
+ - **`readOdm`** resolves a `.odm` master document's own `content.xml` into an ordered list of chapter references (`{ name, href, filterName? }`, one per top-level linked `text:section`) without opening the external `.odt` files those references point at. A master document's chapters are genuinely external files by ODF design, not embedded package sub-documents — confirmed against real LibreOffice output, which never caches a chapter's own content inside the master document itself (see `src/typed/odm/read.ts`'s own top-of-file note).
22
24
 
23
- Not yet built: `readOds`, `readOdfFormula`, `readOdbInventory`, live-view editors, and the `.odm` master-document/`.odb` database-table-export subsystems. This section will be replaced with real usage examples once those land — see the [Architecture](#architecture) section below for the intended shape, and this repository's own commit history/releases for current progress.
25
+ Not yet built: `readOdbInventory`, live-view editors, and the `.odb` database-table-export subsystem. This section will be replaced with real usage examples once those land — see the [Architecture](#architecture) section below for the intended shape, and this repository's own commit history/releases for current progress.
24
26
 
25
27
  ## Getting started
26
28
 
@@ -76,7 +78,7 @@ Layered from a lossless core outward, mirroring `ooxml.js`'s own structure:
76
78
  - **`src/manifest.ts`** — unlike `ooxml.js` (which only ever *reads* OPC relationships, leaving writing to `documents.js`), `odf.js` owns manifest read **and** write, since the manifest is ODF's one mandatory part and its correctness is exhaustive.
77
79
  - **`src/styles/`** — `properties.ts` (the property-bag shape + real ODF attribute parsing), `serialize.ts` (canonical, deterministic property-bag → XML attributes), `registry.ts` (`StyleRegistry`, ODF's mandatory style-interning layer, no OOXML equivalent), `span.ts` (character-range wrapping into a formattable `text:span`, correctly splitting `text:s`/`text:tab` elements that straddle a boundary).
78
80
  - **`src/typed/shared/`** — the ODF-specific typed primitives every future format reader builds on: `units.ts`, `a1.ts`, `color.ts`/`geometry.ts` (parsing into `document-content-model`'s own types, never redefining them), `style.ts` (a thin re-export — ODF's style-properties concern is fully covered by `styles/properties.ts` and the cascade below), `text.ts` (whitespace-run decoding), `cascade.ts` (the read-side style-resolution walk), `metadata.ts` (`meta.xml` reading).
79
- - **`src/typed/odt/`, `src/typed/odp/`, `src/typed/odg/`** — the built `readOdt`/`readOdp`/`readOdg` readers; **`src/typed/draw/`** — the `draw:frame`/`draw:g`/vector-primitive shape vocabulary `readOdp` and `readOdg` both share; **`src/typed/ods.ts`, `src/typed/formula/`** — not yet built (see [Status](#status)).
81
+ - **`src/typed/odt/`, `src/typed/odp/`, `src/typed/odg/`, `src/typed/ods/`** — the built `readOdt`/`readOdp`/`readOdg`/`readOds` readers; **`src/typed/draw/`** — the `draw:frame`/`draw:g`/vector-primitive shape vocabulary `readOdp` and `readOdg` both share; **`src/typed/formula/`, `src/typed/odm/`** — `readOdfFormula` (raw MathML, no `document-content-model` pivot) and `readOdm` (a `.odm` master document's own external chapter references — name/href/filter-name per linked `text:section`, never the linked content itself).
80
82
 
81
83
  ## Why no `ooxml.js` dependency
82
84
 
package/dist/index.cjs CHANGED
@@ -2484,7 +2484,7 @@ function readDrawPageContent(children, pkg) {
2484
2484
  }
2485
2485
  //#endregion
2486
2486
  //#region src/typed/odp/read.ts
2487
- const CONTENT_PART$3 = "content.xml";
2487
+ const CONTENT_PART$5 = "content.xml";
2488
2488
  function readSlideSize(page, pkg) {
2489
2489
  return resolveDrawPageSize(page, pkg) ?? document_content_model.SLIDE_SIZE_WIDESCREEN;
2490
2490
  }
@@ -2503,7 +2503,7 @@ function readSlide(page, pkg) {
2503
2503
  };
2504
2504
  }
2505
2505
  function readOdp(pkg) {
2506
- const contentPart = pkg.parts[CONTENT_PART$3];
2506
+ const contentPart = pkg.parts[CONTENT_PART$5];
2507
2507
  const root = contentPart?.kind === "xml" ? rootElement(contentPart.nodes) : void 0;
2508
2508
  const body = root === void 0 ? void 0 : findChildElement(root.children, "office:body");
2509
2509
  const presentation = body === void 0 ? void 0 : findChildElement(body.children, "office:presentation");
@@ -2515,9 +2515,9 @@ function readOdp(pkg) {
2515
2515
  }
2516
2516
  //#endregion
2517
2517
  //#region src/typed/odt/read.ts
2518
- const CONTENT_PART$2 = "content.xml";
2518
+ const CONTENT_PART$4 = "content.xml";
2519
2519
  const STYLES_PART = "styles.xml";
2520
- const AUTOMATIC_STYLE_PARTS = [CONTENT_PART$2, STYLES_PART];
2520
+ const AUTOMATIC_STYLE_PARTS = [CONTENT_PART$4, STYLES_PART];
2521
2521
  function readOutlineLevel(headingElement) {
2522
2522
  const raw = attrValue(headingElement, "text:outline-level");
2523
2523
  if (raw === void 0) return 1;
@@ -2600,12 +2600,12 @@ function readFirstMasterPageGeometry(pkg) {
2600
2600
  };
2601
2601
  }
2602
2602
  function readOdt(pkg) {
2603
- const contentPart = pkg.parts[CONTENT_PART$2];
2604
- if (contentPart?.kind !== "xml") throw new Error(`readOdt: package has no ${CONTENT_PART$2} part`);
2603
+ const contentPart = pkg.parts[CONTENT_PART$4];
2604
+ if (contentPart?.kind !== "xml") throw new Error(`readOdt: package has no ${CONTENT_PART$4} part`);
2605
2605
  const contentRoot = rootElement(contentPart.nodes);
2606
2606
  const body = contentRoot === void 0 ? void 0 : findChildElement(contentRoot.children, "office:body");
2607
2607
  const textElement = body === void 0 ? void 0 : findChildElement(body.children, "office:text");
2608
- if (textElement === void 0) throw new Error(`readOdt: ${CONTENT_PART$2} has no office:body/office:text element`);
2608
+ if (textElement === void 0) throw new Error(`readOdt: ${CONTENT_PART$4} has no office:body/office:text element`);
2609
2609
  const metadata = readOdfMetadata(pkg);
2610
2610
  const { pageSize, margins } = readFirstMasterPageGeometry(pkg);
2611
2611
  return {
@@ -2619,7 +2619,7 @@ function readOdt(pkg) {
2619
2619
  }
2620
2620
  //#endregion
2621
2621
  //#region src/typed/odg/read.ts
2622
- const CONTENT_PART$1 = "content.xml";
2622
+ const CONTENT_PART$3 = "content.xml";
2623
2623
  const DEFAULT_PAGE_SIZE$1 = document_content_model.PAGE_SIZE_A4;
2624
2624
  function readPage(page, pkg) {
2625
2625
  const size = resolveDrawPageSize(page, pkg) ?? DEFAULT_PAGE_SIZE$1;
@@ -2631,7 +2631,7 @@ function readPage(page, pkg) {
2631
2631
  };
2632
2632
  }
2633
2633
  function readOdg(pkg) {
2634
- const contentPart = pkg.parts[CONTENT_PART$1];
2634
+ const contentPart = pkg.parts[CONTENT_PART$3];
2635
2635
  const root = contentPart?.kind === "xml" ? rootElement(contentPart.nodes) : void 0;
2636
2636
  const body = root === void 0 ? void 0 : findChildElement(root.children, "office:body");
2637
2637
  const drawing = body === void 0 ? void 0 : findChildElement(body.children, "office:drawing");
@@ -2643,7 +2643,7 @@ function readOdg(pkg) {
2643
2643
  }
2644
2644
  //#endregion
2645
2645
  //#region src/typed/ods/read.ts
2646
- const CONTENT_PART = "content.xml";
2646
+ const CONTENT_PART$2 = "content.xml";
2647
2647
  function parseKnownOdfLength(value) {
2648
2648
  const parsed = parseOdfLength(value);
2649
2649
  if (parsed === void 0) throw new Error(`readOds: internal error -- "${value}" is not a valid ODF length literal`);
@@ -2933,7 +2933,7 @@ function readSheet(tableElement, pkg) {
2933
2933
  };
2934
2934
  }
2935
2935
  function readOds(pkg) {
2936
- const contentPart = pkg.parts[CONTENT_PART];
2936
+ const contentPart = pkg.parts[CONTENT_PART$2];
2937
2937
  const root = contentPart?.kind === "xml" ? rootElement(contentPart.nodes) : void 0;
2938
2938
  const body = root === void 0 ? void 0 : findChildElement(root.children, "office:body");
2939
2939
  const spreadsheet = body === void 0 ? void 0 : findChildElement(body.children, "office:spreadsheet");
@@ -2949,6 +2949,83 @@ function readOds(pkg) {
2949
2949
  };
2950
2950
  }
2951
2951
  //#endregion
2952
+ //#region src/typed/formula/read.ts
2953
+ const CONTENT_PART$1 = "content.xml";
2954
+ const MATH_ROOT_TAGS = ["math", "math:math"];
2955
+ const ANNOTATION_TAGS = ["annotation", "math:annotation"];
2956
+ const STARMATH_ENCODING_PREFIX = "StarMath";
2957
+ function findMathRoot(nodes) {
2958
+ const root = rootElement(nodes);
2959
+ if (root === void 0) return;
2960
+ if (MATH_ROOT_TAGS.includes(root.tag)) return root;
2961
+ for (const tag of MATH_ROOT_TAGS) {
2962
+ const [found] = elementsWithTag(root.children, tag);
2963
+ if (found !== void 0) return found;
2964
+ }
2965
+ }
2966
+ function annotationText(element) {
2967
+ let text = "";
2968
+ for (const child of element.children) if (child.type === "text") text += decodeXmlText(child.value);
2969
+ return text;
2970
+ }
2971
+ function findStarMathAnnotation(mathRoot) {
2972
+ for (const tag of ANNOTATION_TAGS) for (const annotation of elementsWithTag(mathRoot.children, tag)) {
2973
+ if (!attrValue(annotation, "encoding")?.startsWith(STARMATH_ENCODING_PREFIX)) continue;
2974
+ const text = annotationText(annotation);
2975
+ if (text.length > 0) return text;
2976
+ }
2977
+ }
2978
+ function readOdfFormula(pkg) {
2979
+ const contentPart = pkg.parts[CONTENT_PART$1];
2980
+ if (contentPart?.kind !== "xml") throw new Error(`readOdfFormula: package has no ${CONTENT_PART$1} part`);
2981
+ const mathRoot = findMathRoot(contentPart.nodes);
2982
+ if (mathRoot === void 0) throw new Error(`readOdfFormula: ${CONTENT_PART$1} has no MathML root element`);
2983
+ const metadata = readOdfMetadata(pkg);
2984
+ const starMath = findStarMathAnnotation(mathRoot);
2985
+ return starMath === void 0 ? {
2986
+ mathml: mathRoot.children,
2987
+ metadata
2988
+ } : {
2989
+ starMath,
2990
+ mathml: mathRoot.children,
2991
+ metadata
2992
+ };
2993
+ }
2994
+ //#endregion
2995
+ //#region src/typed/odm/read.ts
2996
+ const CONTENT_PART = "content.xml";
2997
+ function readSection(element) {
2998
+ const sourceElement = findChildElement(element.children, "text:section-source");
2999
+ if (sourceElement === void 0) return;
3000
+ const name = attrValue(element, "text:name");
3001
+ const href = attrValue(sourceElement, "xlink:href");
3002
+ if (name === void 0 || href === void 0) return;
3003
+ const filterName = attrValue(sourceElement, "text:filter-name");
3004
+ return filterName === void 0 ? {
3005
+ name,
3006
+ href
3007
+ } : {
3008
+ name,
3009
+ href,
3010
+ filterName
3011
+ };
3012
+ }
3013
+ function readOdm(pkg) {
3014
+ const contentPart = pkg.parts[CONTENT_PART];
3015
+ if (contentPart?.kind !== "xml") throw new Error(`readOdm: package has no ${CONTENT_PART} part`);
3016
+ const contentRoot = rootElement(contentPart.nodes);
3017
+ const body = contentRoot === void 0 ? void 0 : findChildElement(contentRoot.children, "office:body");
3018
+ const textElement = body === void 0 ? void 0 : findChildElement(body.children, "office:text");
3019
+ if (textElement === void 0) throw new Error(`readOdm: ${CONTENT_PART} has no office:body/office:text element`);
3020
+ const sections = [];
3021
+ for (const node of textElement.children) {
3022
+ if (node.type !== "element" || node.tag !== "text:section") continue;
3023
+ const section = readSection(node);
3024
+ if (section !== void 0) sections.push(section);
3025
+ }
3026
+ return { sections };
3027
+ }
3028
+ //#endregion
2952
3029
  Object.defineProperty(exports, "AlignmentSchema", {
2953
3030
  enumerable: true,
2954
3031
  get: function() {
@@ -3037,10 +3114,12 @@ exports.readDrawFrame = readDrawFrame;
3037
3114
  exports.readDrawPageContent = readDrawPageContent;
3038
3115
  exports.readManifest = readManifest;
3039
3116
  exports.readMimetype = readMimetype;
3117
+ exports.readOdfFormula = readOdfFormula;
3040
3118
  exports.readOdfMetadata = readOdfMetadata;
3041
3119
  exports.readOdfParagraph = readOdfParagraph;
3042
3120
  exports.readOdfTable = readOdfTable;
3043
3121
  exports.readOdg = readOdg;
3122
+ exports.readOdm = readOdm;
3044
3123
  exports.readOdp = readOdp;
3045
3124
  exports.readOds = readOds;
3046
3125
  exports.readOdt = readOdt;
package/dist/index.d.cts CHANGED
@@ -642,4 +642,24 @@ interface OdsDocument {
642
642
  }
643
643
  declare function readOds(pkg: Package): OdsDocument;
644
644
  //#endregion
645
- export { type Alignment, AlignmentSchema, type Attribute, AttributeSchema, type BinaryPart, BinaryPartSchema, type BuildManifestOptions, type CascadeDiagnostic, type DrawPageContent, type ImageFormat, type InternRequest, type LengthUnit, MANIFEST_PART, META_PART, MIMETYPE_PART, type Manifest, type ManifestEntry, ManifestEntrySchema, type ManifestProblem, ManifestProblemSchema, ManifestSchema, ODF_MEDIA_TYPES, ODF_NAMESPACES, type OdfExtension, type OdfNamespacePrefix, type OdfPoint, type OdfRawPoint, type OdfRawSegment, type OdfRawSubpath, type OdfShapeGeometry, type OdfTransformFunction, type OdfViewBox, type OdgDocument, type OdpDocument, type OdsDocument, type OdtDocument, type OtherPartRef, type Package, PackageSchema, type ParsedProperties, type Part, PartSchema, STYLE_FAMILIES, type StyleCascadeResult, type StyleElementChainResult, type StyleFamily, type StyleProperties, StylePropertiesSchema, StyleRegistry, type StyleRegistryOptions, TableCursor, type XmlCdata, XmlCdataSchema, type XmlComment, XmlCommentSchema, type XmlDeclaration, XmlDeclarationSchema, type XmlElement, XmlElementSchema, type XmlNode, XmlNodeSchema, type XmlPart, XmlPartSchema, type XmlPi, XmlPiSchema, type XmlText, XmlTextSchema, type ZipEntry, applyOdfTransform, attrValue, base64ToBytes, buildManifest, buildOdfSubpaths, buildStylePropertyElements, buildXml, bytesToBase64, canonicalPropertiesString, cellReference, childrenWithTag, columnIndexToLetters, columnLettersToIndex, composeOdfGroupTransform, decodeOdfText, decodePackage, decodeXmlText, el, elementsWithTag, encodePackage, encodeXmlText, ensureSpan, findChildElement, findStyleElement, formatOdfColor, formatOdfLength, formatPercentageMultiplier, formatPt, getOdfSpaceCount, isStyleFamily, isXmlNode, measureOdfNodeLength, mediaTypeForExtension, netRotationDeg, packageCodec, paragraphPropertiesToAttributes, parseBox, parseCellReference, parseLength, parseLinePoints, parseMargins, parseOdfColor, parseOdfLength, parseOdfPathData, parseOdfPointsList, parseOdfTransform, parseOdfViewBox, parsePackage, parsePageSize, parseParagraphProperties, parseStyleElementProperties, parseTextProperties, parseXml, rawSubpathFromPoints, readDrawFrame, readDrawPageContent, readManifest, readMimetype, readOdfMetadata, readOdfParagraph, readOdfTable, readOdg, readOdp, readOds, readOdt, resolveDrawPageSize, resolveOdfShapeGeometry, resolvePageLayoutProperties, resolveStyle, resolveStyleElementChain, rootElement, scaleOdfRawPoint, serializePackage, setDocumentMediaType, sniffImageFormat, sumOdfNodeLength, syncManifest, textPropertiesToAttributes, txt, unzipPackage, validateManifest, walkDrawShapes, writeManifest, writeMimetype, xmlCodec, xmlnsAttributes, zipPackage };
645
+ //#region src/typed/formula/read.d.ts
646
+ interface OdfFormulaDocument {
647
+ starMath?: string;
648
+ mathml: XmlNode[];
649
+ metadata: LayoutMetadata;
650
+ }
651
+ declare function readOdfFormula(pkg: Package): OdfFormulaDocument;
652
+ //#endregion
653
+ //#region src/typed/odm/read.d.ts
654
+ interface OdmSection {
655
+ name: string;
656
+ href: string;
657
+ filterName?: string;
658
+ inlineContent?: readonly XmlNode[];
659
+ }
660
+ interface OdmDocument {
661
+ sections: readonly OdmSection[];
662
+ }
663
+ declare function readOdm(pkg: Package): OdmDocument;
664
+ //#endregion
665
+ export { type Alignment, AlignmentSchema, type Attribute, AttributeSchema, type BinaryPart, BinaryPartSchema, type BuildManifestOptions, type CascadeDiagnostic, type DrawPageContent, type ImageFormat, type InternRequest, type LengthUnit, MANIFEST_PART, META_PART, MIMETYPE_PART, type Manifest, type ManifestEntry, ManifestEntrySchema, type ManifestProblem, ManifestProblemSchema, ManifestSchema, ODF_MEDIA_TYPES, ODF_NAMESPACES, type OdfExtension, type OdfFormulaDocument, type OdfNamespacePrefix, type OdfPoint, type OdfRawPoint, type OdfRawSegment, type OdfRawSubpath, type OdfShapeGeometry, type OdfTransformFunction, type OdfViewBox, type OdgDocument, type OdmDocument, type OdmSection, type OdpDocument, type OdsDocument, type OdtDocument, type OtherPartRef, type Package, PackageSchema, type ParsedProperties, type Part, PartSchema, STYLE_FAMILIES, type StyleCascadeResult, type StyleElementChainResult, type StyleFamily, type StyleProperties, StylePropertiesSchema, StyleRegistry, type StyleRegistryOptions, TableCursor, type XmlCdata, XmlCdataSchema, type XmlComment, XmlCommentSchema, type XmlDeclaration, XmlDeclarationSchema, type XmlElement, XmlElementSchema, type XmlNode, XmlNodeSchema, type XmlPart, XmlPartSchema, type XmlPi, XmlPiSchema, type XmlText, XmlTextSchema, type ZipEntry, applyOdfTransform, attrValue, base64ToBytes, buildManifest, buildOdfSubpaths, buildStylePropertyElements, buildXml, bytesToBase64, canonicalPropertiesString, cellReference, childrenWithTag, columnIndexToLetters, columnLettersToIndex, composeOdfGroupTransform, decodeOdfText, decodePackage, decodeXmlText, el, elementsWithTag, encodePackage, encodeXmlText, ensureSpan, findChildElement, findStyleElement, formatOdfColor, formatOdfLength, formatPercentageMultiplier, formatPt, getOdfSpaceCount, isStyleFamily, isXmlNode, measureOdfNodeLength, mediaTypeForExtension, netRotationDeg, packageCodec, paragraphPropertiesToAttributes, parseBox, parseCellReference, parseLength, parseLinePoints, parseMargins, parseOdfColor, parseOdfLength, parseOdfPathData, parseOdfPointsList, parseOdfTransform, parseOdfViewBox, parsePackage, parsePageSize, parseParagraphProperties, parseStyleElementProperties, parseTextProperties, parseXml, rawSubpathFromPoints, readDrawFrame, readDrawPageContent, readManifest, readMimetype, readOdfFormula, readOdfMetadata, readOdfParagraph, readOdfTable, readOdg, readOdm, readOdp, readOds, readOdt, resolveDrawPageSize, resolveOdfShapeGeometry, resolvePageLayoutProperties, resolveStyle, resolveStyleElementChain, rootElement, scaleOdfRawPoint, serializePackage, setDocumentMediaType, sniffImageFormat, sumOdfNodeLength, syncManifest, textPropertiesToAttributes, txt, unzipPackage, validateManifest, walkDrawShapes, writeManifest, writeMimetype, xmlCodec, xmlnsAttributes, zipPackage };
package/dist/index.d.ts CHANGED
@@ -642,4 +642,24 @@ interface OdsDocument {
642
642
  }
643
643
  declare function readOds(pkg: Package): OdsDocument;
644
644
  //#endregion
645
- export { type Alignment, AlignmentSchema, type Attribute, AttributeSchema, type BinaryPart, BinaryPartSchema, type BuildManifestOptions, type CascadeDiagnostic, type DrawPageContent, type ImageFormat, type InternRequest, type LengthUnit, MANIFEST_PART, META_PART, MIMETYPE_PART, type Manifest, type ManifestEntry, ManifestEntrySchema, type ManifestProblem, ManifestProblemSchema, ManifestSchema, ODF_MEDIA_TYPES, ODF_NAMESPACES, type OdfExtension, type OdfNamespacePrefix, type OdfPoint, type OdfRawPoint, type OdfRawSegment, type OdfRawSubpath, type OdfShapeGeometry, type OdfTransformFunction, type OdfViewBox, type OdgDocument, type OdpDocument, type OdsDocument, type OdtDocument, type OtherPartRef, type Package, PackageSchema, type ParsedProperties, type Part, PartSchema, STYLE_FAMILIES, type StyleCascadeResult, type StyleElementChainResult, type StyleFamily, type StyleProperties, StylePropertiesSchema, StyleRegistry, type StyleRegistryOptions, TableCursor, type XmlCdata, XmlCdataSchema, type XmlComment, XmlCommentSchema, type XmlDeclaration, XmlDeclarationSchema, type XmlElement, XmlElementSchema, type XmlNode, XmlNodeSchema, type XmlPart, XmlPartSchema, type XmlPi, XmlPiSchema, type XmlText, XmlTextSchema, type ZipEntry, applyOdfTransform, attrValue, base64ToBytes, buildManifest, buildOdfSubpaths, buildStylePropertyElements, buildXml, bytesToBase64, canonicalPropertiesString, cellReference, childrenWithTag, columnIndexToLetters, columnLettersToIndex, composeOdfGroupTransform, decodeOdfText, decodePackage, decodeXmlText, el, elementsWithTag, encodePackage, encodeXmlText, ensureSpan, findChildElement, findStyleElement, formatOdfColor, formatOdfLength, formatPercentageMultiplier, formatPt, getOdfSpaceCount, isStyleFamily, isXmlNode, measureOdfNodeLength, mediaTypeForExtension, netRotationDeg, packageCodec, paragraphPropertiesToAttributes, parseBox, parseCellReference, parseLength, parseLinePoints, parseMargins, parseOdfColor, parseOdfLength, parseOdfPathData, parseOdfPointsList, parseOdfTransform, parseOdfViewBox, parsePackage, parsePageSize, parseParagraphProperties, parseStyleElementProperties, parseTextProperties, parseXml, rawSubpathFromPoints, readDrawFrame, readDrawPageContent, readManifest, readMimetype, readOdfMetadata, readOdfParagraph, readOdfTable, readOdg, readOdp, readOds, readOdt, resolveDrawPageSize, resolveOdfShapeGeometry, resolvePageLayoutProperties, resolveStyle, resolveStyleElementChain, rootElement, scaleOdfRawPoint, serializePackage, setDocumentMediaType, sniffImageFormat, sumOdfNodeLength, syncManifest, textPropertiesToAttributes, txt, unzipPackage, validateManifest, walkDrawShapes, writeManifest, writeMimetype, xmlCodec, xmlnsAttributes, zipPackage };
645
+ //#region src/typed/formula/read.d.ts
646
+ interface OdfFormulaDocument {
647
+ starMath?: string;
648
+ mathml: XmlNode[];
649
+ metadata: LayoutMetadata;
650
+ }
651
+ declare function readOdfFormula(pkg: Package): OdfFormulaDocument;
652
+ //#endregion
653
+ //#region src/typed/odm/read.d.ts
654
+ interface OdmSection {
655
+ name: string;
656
+ href: string;
657
+ filterName?: string;
658
+ inlineContent?: readonly XmlNode[];
659
+ }
660
+ interface OdmDocument {
661
+ sections: readonly OdmSection[];
662
+ }
663
+ declare function readOdm(pkg: Package): OdmDocument;
664
+ //#endregion
665
+ export { type Alignment, AlignmentSchema, type Attribute, AttributeSchema, type BinaryPart, BinaryPartSchema, type BuildManifestOptions, type CascadeDiagnostic, type DrawPageContent, type ImageFormat, type InternRequest, type LengthUnit, MANIFEST_PART, META_PART, MIMETYPE_PART, type Manifest, type ManifestEntry, ManifestEntrySchema, type ManifestProblem, ManifestProblemSchema, ManifestSchema, ODF_MEDIA_TYPES, ODF_NAMESPACES, type OdfExtension, type OdfFormulaDocument, type OdfNamespacePrefix, type OdfPoint, type OdfRawPoint, type OdfRawSegment, type OdfRawSubpath, type OdfShapeGeometry, type OdfTransformFunction, type OdfViewBox, type OdgDocument, type OdmDocument, type OdmSection, type OdpDocument, type OdsDocument, type OdtDocument, type OtherPartRef, type Package, PackageSchema, type ParsedProperties, type Part, PartSchema, STYLE_FAMILIES, type StyleCascadeResult, type StyleElementChainResult, type StyleFamily, type StyleProperties, StylePropertiesSchema, StyleRegistry, type StyleRegistryOptions, TableCursor, type XmlCdata, XmlCdataSchema, type XmlComment, XmlCommentSchema, type XmlDeclaration, XmlDeclarationSchema, type XmlElement, XmlElementSchema, type XmlNode, XmlNodeSchema, type XmlPart, XmlPartSchema, type XmlPi, XmlPiSchema, type XmlText, XmlTextSchema, type ZipEntry, applyOdfTransform, attrValue, base64ToBytes, buildManifest, buildOdfSubpaths, buildStylePropertyElements, buildXml, bytesToBase64, canonicalPropertiesString, cellReference, childrenWithTag, columnIndexToLetters, columnLettersToIndex, composeOdfGroupTransform, decodeOdfText, decodePackage, decodeXmlText, el, elementsWithTag, encodePackage, encodeXmlText, ensureSpan, findChildElement, findStyleElement, formatOdfColor, formatOdfLength, formatPercentageMultiplier, formatPt, getOdfSpaceCount, isStyleFamily, isXmlNode, measureOdfNodeLength, mediaTypeForExtension, netRotationDeg, packageCodec, paragraphPropertiesToAttributes, parseBox, parseCellReference, parseLength, parseLinePoints, parseMargins, parseOdfColor, parseOdfLength, parseOdfPathData, parseOdfPointsList, parseOdfTransform, parseOdfViewBox, parsePackage, parsePageSize, parseParagraphProperties, parseStyleElementProperties, parseTextProperties, parseXml, rawSubpathFromPoints, readDrawFrame, readDrawPageContent, readManifest, readMimetype, readOdfFormula, readOdfMetadata, readOdfParagraph, readOdfTable, readOdg, readOdm, readOdp, readOds, readOdt, resolveDrawPageSize, resolveOdfShapeGeometry, resolvePageLayoutProperties, resolveStyle, resolveStyleElementChain, rootElement, scaleOdfRawPoint, serializePackage, setDocumentMediaType, sniffImageFormat, sumOdfNodeLength, syncManifest, textPropertiesToAttributes, txt, unzipPackage, validateManifest, walkDrawShapes, writeManifest, writeMimetype, xmlCodec, xmlnsAttributes, zipPackage };
package/dist/index.js CHANGED
@@ -2483,7 +2483,7 @@ function readDrawPageContent(children, pkg) {
2483
2483
  }
2484
2484
  //#endregion
2485
2485
  //#region src/typed/odp/read.ts
2486
- const CONTENT_PART$3 = "content.xml";
2486
+ const CONTENT_PART$5 = "content.xml";
2487
2487
  function readSlideSize(page, pkg) {
2488
2488
  return resolveDrawPageSize(page, pkg) ?? SLIDE_SIZE_WIDESCREEN;
2489
2489
  }
@@ -2502,7 +2502,7 @@ function readSlide(page, pkg) {
2502
2502
  };
2503
2503
  }
2504
2504
  function readOdp(pkg) {
2505
- const contentPart = pkg.parts[CONTENT_PART$3];
2505
+ const contentPart = pkg.parts[CONTENT_PART$5];
2506
2506
  const root = contentPart?.kind === "xml" ? rootElement(contentPart.nodes) : void 0;
2507
2507
  const body = root === void 0 ? void 0 : findChildElement(root.children, "office:body");
2508
2508
  const presentation = body === void 0 ? void 0 : findChildElement(body.children, "office:presentation");
@@ -2514,9 +2514,9 @@ function readOdp(pkg) {
2514
2514
  }
2515
2515
  //#endregion
2516
2516
  //#region src/typed/odt/read.ts
2517
- const CONTENT_PART$2 = "content.xml";
2517
+ const CONTENT_PART$4 = "content.xml";
2518
2518
  const STYLES_PART = "styles.xml";
2519
- const AUTOMATIC_STYLE_PARTS = [CONTENT_PART$2, STYLES_PART];
2519
+ const AUTOMATIC_STYLE_PARTS = [CONTENT_PART$4, STYLES_PART];
2520
2520
  function readOutlineLevel(headingElement) {
2521
2521
  const raw = attrValue(headingElement, "text:outline-level");
2522
2522
  if (raw === void 0) return 1;
@@ -2599,12 +2599,12 @@ function readFirstMasterPageGeometry(pkg) {
2599
2599
  };
2600
2600
  }
2601
2601
  function readOdt(pkg) {
2602
- const contentPart = pkg.parts[CONTENT_PART$2];
2603
- if (contentPart?.kind !== "xml") throw new Error(`readOdt: package has no ${CONTENT_PART$2} part`);
2602
+ const contentPart = pkg.parts[CONTENT_PART$4];
2603
+ if (contentPart?.kind !== "xml") throw new Error(`readOdt: package has no ${CONTENT_PART$4} part`);
2604
2604
  const contentRoot = rootElement(contentPart.nodes);
2605
2605
  const body = contentRoot === void 0 ? void 0 : findChildElement(contentRoot.children, "office:body");
2606
2606
  const textElement = body === void 0 ? void 0 : findChildElement(body.children, "office:text");
2607
- if (textElement === void 0) throw new Error(`readOdt: ${CONTENT_PART$2} has no office:body/office:text element`);
2607
+ if (textElement === void 0) throw new Error(`readOdt: ${CONTENT_PART$4} has no office:body/office:text element`);
2608
2608
  const metadata = readOdfMetadata(pkg);
2609
2609
  const { pageSize, margins } = readFirstMasterPageGeometry(pkg);
2610
2610
  return {
@@ -2618,7 +2618,7 @@ function readOdt(pkg) {
2618
2618
  }
2619
2619
  //#endregion
2620
2620
  //#region src/typed/odg/read.ts
2621
- const CONTENT_PART$1 = "content.xml";
2621
+ const CONTENT_PART$3 = "content.xml";
2622
2622
  const DEFAULT_PAGE_SIZE$1 = PAGE_SIZE_A4;
2623
2623
  function readPage(page, pkg) {
2624
2624
  const size = resolveDrawPageSize(page, pkg) ?? DEFAULT_PAGE_SIZE$1;
@@ -2630,7 +2630,7 @@ function readPage(page, pkg) {
2630
2630
  };
2631
2631
  }
2632
2632
  function readOdg(pkg) {
2633
- const contentPart = pkg.parts[CONTENT_PART$1];
2633
+ const contentPart = pkg.parts[CONTENT_PART$3];
2634
2634
  const root = contentPart?.kind === "xml" ? rootElement(contentPart.nodes) : void 0;
2635
2635
  const body = root === void 0 ? void 0 : findChildElement(root.children, "office:body");
2636
2636
  const drawing = body === void 0 ? void 0 : findChildElement(body.children, "office:drawing");
@@ -2642,7 +2642,7 @@ function readOdg(pkg) {
2642
2642
  }
2643
2643
  //#endregion
2644
2644
  //#region src/typed/ods/read.ts
2645
- const CONTENT_PART = "content.xml";
2645
+ const CONTENT_PART$2 = "content.xml";
2646
2646
  function parseKnownOdfLength(value) {
2647
2647
  const parsed = parseOdfLength(value);
2648
2648
  if (parsed === void 0) throw new Error(`readOds: internal error -- "${value}" is not a valid ODF length literal`);
@@ -2932,7 +2932,7 @@ function readSheet(tableElement, pkg) {
2932
2932
  };
2933
2933
  }
2934
2934
  function readOds(pkg) {
2935
- const contentPart = pkg.parts[CONTENT_PART];
2935
+ const contentPart = pkg.parts[CONTENT_PART$2];
2936
2936
  const root = contentPart?.kind === "xml" ? rootElement(contentPart.nodes) : void 0;
2937
2937
  const body = root === void 0 ? void 0 : findChildElement(root.children, "office:body");
2938
2938
  const spreadsheet = body === void 0 ? void 0 : findChildElement(body.children, "office:spreadsheet");
@@ -2948,4 +2948,81 @@ function readOds(pkg) {
2948
2948
  };
2949
2949
  }
2950
2950
  //#endregion
2951
- export { AlignmentSchema, AttributeSchema, BinaryPartSchema, MANIFEST_PART, META_PART, MIMETYPE_PART, ManifestEntrySchema, ManifestProblemSchema, ManifestSchema, ODF_MEDIA_TYPES, ODF_NAMESPACES, PackageSchema, PartSchema, STYLE_FAMILIES, StylePropertiesSchema, StyleRegistry, TableCursor, XmlCdataSchema, XmlCommentSchema, XmlDeclarationSchema, XmlElementSchema, XmlNodeSchema, XmlPartSchema, XmlPiSchema, XmlTextSchema, applyOdfTransform, attrValue, base64ToBytes, buildManifest, buildOdfSubpaths, buildStylePropertyElements, buildXml, bytesToBase64, canonicalPropertiesString, cellReference, childrenWithTag, columnIndexToLetters, columnLettersToIndex, composeOdfGroupTransform, decodeOdfText, decodePackage, decodeXmlText, el, elementsWithTag, encodePackage, encodeXmlText, ensureSpan, findChildElement, findStyleElement, formatOdfColor, formatOdfLength, formatPercentageMultiplier, formatPt, getOdfSpaceCount, isStyleFamily, isXmlNode, measureOdfNodeLength, mediaTypeForExtension, netRotationDeg, packageCodec, paragraphPropertiesToAttributes, parseBox, parseCellReference, parseLength, parseLinePoints, parseMargins, parseOdfColor, parseOdfLength, parseOdfPathData, parseOdfPointsList, parseOdfTransform, parseOdfViewBox, parsePackage, parsePageSize, parseParagraphProperties, parseStyleElementProperties, parseTextProperties, parseXml, rawSubpathFromPoints, readDrawFrame, readDrawPageContent, readManifest, readMimetype, readOdfMetadata, readOdfParagraph, readOdfTable, readOdg, readOdp, readOds, readOdt, resolveDrawPageSize, resolveOdfShapeGeometry, resolvePageLayoutProperties, resolveStyle, resolveStyleElementChain, rootElement, scaleOdfRawPoint, serializePackage, setDocumentMediaType, sniffImageFormat, sumOdfNodeLength, syncManifest, textPropertiesToAttributes, txt, unzipPackage, validateManifest, walkDrawShapes, writeManifest, writeMimetype, xmlCodec, xmlnsAttributes, zipPackage };
2951
+ //#region src/typed/formula/read.ts
2952
+ const CONTENT_PART$1 = "content.xml";
2953
+ const MATH_ROOT_TAGS = ["math", "math:math"];
2954
+ const ANNOTATION_TAGS = ["annotation", "math:annotation"];
2955
+ const STARMATH_ENCODING_PREFIX = "StarMath";
2956
+ function findMathRoot(nodes) {
2957
+ const root = rootElement(nodes);
2958
+ if (root === void 0) return;
2959
+ if (MATH_ROOT_TAGS.includes(root.tag)) return root;
2960
+ for (const tag of MATH_ROOT_TAGS) {
2961
+ const [found] = elementsWithTag(root.children, tag);
2962
+ if (found !== void 0) return found;
2963
+ }
2964
+ }
2965
+ function annotationText(element) {
2966
+ let text = "";
2967
+ for (const child of element.children) if (child.type === "text") text += decodeXmlText(child.value);
2968
+ return text;
2969
+ }
2970
+ function findStarMathAnnotation(mathRoot) {
2971
+ for (const tag of ANNOTATION_TAGS) for (const annotation of elementsWithTag(mathRoot.children, tag)) {
2972
+ if (!attrValue(annotation, "encoding")?.startsWith(STARMATH_ENCODING_PREFIX)) continue;
2973
+ const text = annotationText(annotation);
2974
+ if (text.length > 0) return text;
2975
+ }
2976
+ }
2977
+ function readOdfFormula(pkg) {
2978
+ const contentPart = pkg.parts[CONTENT_PART$1];
2979
+ if (contentPart?.kind !== "xml") throw new Error(`readOdfFormula: package has no ${CONTENT_PART$1} part`);
2980
+ const mathRoot = findMathRoot(contentPart.nodes);
2981
+ if (mathRoot === void 0) throw new Error(`readOdfFormula: ${CONTENT_PART$1} has no MathML root element`);
2982
+ const metadata = readOdfMetadata(pkg);
2983
+ const starMath = findStarMathAnnotation(mathRoot);
2984
+ return starMath === void 0 ? {
2985
+ mathml: mathRoot.children,
2986
+ metadata
2987
+ } : {
2988
+ starMath,
2989
+ mathml: mathRoot.children,
2990
+ metadata
2991
+ };
2992
+ }
2993
+ //#endregion
2994
+ //#region src/typed/odm/read.ts
2995
+ const CONTENT_PART = "content.xml";
2996
+ function readSection(element) {
2997
+ const sourceElement = findChildElement(element.children, "text:section-source");
2998
+ if (sourceElement === void 0) return;
2999
+ const name = attrValue(element, "text:name");
3000
+ const href = attrValue(sourceElement, "xlink:href");
3001
+ if (name === void 0 || href === void 0) return;
3002
+ const filterName = attrValue(sourceElement, "text:filter-name");
3003
+ return filterName === void 0 ? {
3004
+ name,
3005
+ href
3006
+ } : {
3007
+ name,
3008
+ href,
3009
+ filterName
3010
+ };
3011
+ }
3012
+ function readOdm(pkg) {
3013
+ const contentPart = pkg.parts[CONTENT_PART];
3014
+ if (contentPart?.kind !== "xml") throw new Error(`readOdm: package has no ${CONTENT_PART} part`);
3015
+ const contentRoot = rootElement(contentPart.nodes);
3016
+ const body = contentRoot === void 0 ? void 0 : findChildElement(contentRoot.children, "office:body");
3017
+ const textElement = body === void 0 ? void 0 : findChildElement(body.children, "office:text");
3018
+ if (textElement === void 0) throw new Error(`readOdm: ${CONTENT_PART} has no office:body/office:text element`);
3019
+ const sections = [];
3020
+ for (const node of textElement.children) {
3021
+ if (node.type !== "element" || node.tag !== "text:section") continue;
3022
+ const section = readSection(node);
3023
+ if (section !== void 0) sections.push(section);
3024
+ }
3025
+ return { sections };
3026
+ }
3027
+ //#endregion
3028
+ export { AlignmentSchema, AttributeSchema, BinaryPartSchema, MANIFEST_PART, META_PART, MIMETYPE_PART, ManifestEntrySchema, ManifestProblemSchema, ManifestSchema, ODF_MEDIA_TYPES, ODF_NAMESPACES, PackageSchema, PartSchema, STYLE_FAMILIES, StylePropertiesSchema, StyleRegistry, TableCursor, XmlCdataSchema, XmlCommentSchema, XmlDeclarationSchema, XmlElementSchema, XmlNodeSchema, XmlPartSchema, XmlPiSchema, XmlTextSchema, applyOdfTransform, attrValue, base64ToBytes, buildManifest, buildOdfSubpaths, buildStylePropertyElements, buildXml, bytesToBase64, canonicalPropertiesString, cellReference, childrenWithTag, columnIndexToLetters, columnLettersToIndex, composeOdfGroupTransform, decodeOdfText, decodePackage, decodeXmlText, el, elementsWithTag, encodePackage, encodeXmlText, ensureSpan, findChildElement, findStyleElement, formatOdfColor, formatOdfLength, formatPercentageMultiplier, formatPt, getOdfSpaceCount, isStyleFamily, isXmlNode, measureOdfNodeLength, mediaTypeForExtension, netRotationDeg, packageCodec, paragraphPropertiesToAttributes, parseBox, parseCellReference, parseLength, parseLinePoints, parseMargins, parseOdfColor, parseOdfLength, parseOdfPathData, parseOdfPointsList, parseOdfTransform, parseOdfViewBox, parsePackage, parsePageSize, parseParagraphProperties, parseStyleElementProperties, parseTextProperties, parseXml, rawSubpathFromPoints, readDrawFrame, readDrawPageContent, readManifest, readMimetype, readOdfFormula, readOdfMetadata, readOdfParagraph, readOdfTable, readOdg, readOdm, readOdp, readOds, readOdt, resolveDrawPageSize, resolveOdfShapeGeometry, resolvePageLayoutProperties, resolveStyle, resolveStyleElementChain, rootElement, scaleOdfRawPoint, serializePackage, setDocumentMediaType, sniffImageFormat, sumOdfNodeLength, syncManifest, textPropertiesToAttributes, txt, unzipPackage, validateManifest, walkDrawShapes, writeManifest, writeMimetype, xmlCodec, xmlnsAttributes, zipPackage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "odf.js",
3
- "version": "1.7.0",
3
+ "version": "1.9.0",
4
4
  "description": "Type-safe, lossless round-trip conversion between OpenDocument Format packages (odt, ods, odp) and JSON, hand-written and dependency-minimal, built on Zod 4 codecs.",
5
5
  "type": "module",
6
6
  "repository": {