ooxml.js 1.2.1 → 1.3.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.
package/dist/index.cjs CHANGED
@@ -310,6 +310,82 @@ function encodePackage(pkg) {
310
310
  return zod.z.encode(packageCodec, pkg);
311
311
  }
312
312
  //#endregion
313
+ //#region src/typed/util.ts
314
+ function* walk(nodes) {
315
+ for (const node of nodes) {
316
+ yield node;
317
+ if (node.type === "element") yield* walk(node.children);
318
+ }
319
+ }
320
+ function elementsWithTag(nodes, tag) {
321
+ const out = [];
322
+ for (const node of walk(nodes)) if (node.type === "element" && node.tag === tag) out.push(node);
323
+ return out;
324
+ }
325
+ function childrenWithTag(element, tag) {
326
+ const out = [];
327
+ for (const child of element.children) if (child.type === "element" && child.tag === tag) out.push(child);
328
+ return out;
329
+ }
330
+ function attr(element, name) {
331
+ for (const a of element.attributes) if (a.name === name) return a.value;
332
+ }
333
+ function rootElement(part) {
334
+ if (part?.kind !== "xml") return;
335
+ for (const node of part.nodes) if (node.type === "element") return node;
336
+ }
337
+ function decodeEntities(value) {
338
+ return value.replace(/&(?:amp|lt|gt|quot|apos);/g, (entity) => {
339
+ switch (entity) {
340
+ case "&": return "&";
341
+ case "&lt;": return "<";
342
+ case "&gt;": return ">";
343
+ case "&quot;": return "\"";
344
+ case "&apos;": return "'";
345
+ default: return entity;
346
+ }
347
+ });
348
+ }
349
+ function textContent(element) {
350
+ let text = "";
351
+ for (const node of walk(element.children)) if (node.type === "text" || node.type === "cdata") text += node.value;
352
+ return decodeEntities(text);
353
+ }
354
+ function relsPathFor(partPath) {
355
+ const lastSlash = partPath.lastIndexOf("/");
356
+ return `${lastSlash === -1 ? "" : partPath.slice(0, lastSlash)}/_rels/${lastSlash === -1 ? partPath : partPath.slice(lastSlash + 1)}.rels`;
357
+ }
358
+ function resolveRelTarget$1(partPath, target) {
359
+ if (target.startsWith("/")) return target.slice(1);
360
+ const lastSlash = partPath.lastIndexOf("/");
361
+ const baseDir = lastSlash === -1 ? "" : partPath.slice(0, lastSlash);
362
+ const resolved = [];
363
+ for (const segment of `${baseDir}/${target}`.split("/")) {
364
+ if (segment === "" || segment === ".") continue;
365
+ if (segment === "..") resolved.pop();
366
+ else resolved.push(segment);
367
+ }
368
+ return resolved.join("/");
369
+ }
370
+ function resolveRelationships(pkg, partPath) {
371
+ const map = /* @__PURE__ */ new Map();
372
+ const rels = rootElement(pkg.parts[relsPathFor(partPath)]);
373
+ if (rels === void 0) return map;
374
+ for (const rel of childrenWithTag(rels, "Relationship")) {
375
+ const id = attr(rel, "Id");
376
+ const type = attr(rel, "Type");
377
+ const target = attr(rel, "Target");
378
+ if (id === void 0 || type === void 0 || target === void 0) continue;
379
+ const targetMode = attr(rel, "TargetMode");
380
+ map.set(id, {
381
+ type,
382
+ target: targetMode === "External" ? target : resolveRelTarget$1(partPath, target),
383
+ targetMode
384
+ });
385
+ }
386
+ return map;
387
+ }
388
+ //#endregion
313
389
  //#region src/compact.ts
314
390
  function isUnknownArray(value) {
315
391
  return Array.isArray(value);
@@ -458,82 +534,6 @@ function encodeCompactPackage(cpkg) {
458
534
  return zod.z.encode(compactPackageCodec, cpkg);
459
535
  }
460
536
  //#endregion
461
- //#region src/typed/util.ts
462
- function* walk(nodes) {
463
- for (const node of nodes) {
464
- yield node;
465
- if (node.type === "element") yield* walk(node.children);
466
- }
467
- }
468
- function elementsWithTag(nodes, tag) {
469
- const out = [];
470
- for (const node of walk(nodes)) if (node.type === "element" && node.tag === tag) out.push(node);
471
- return out;
472
- }
473
- function childrenWithTag(element, tag) {
474
- const out = [];
475
- for (const child of element.children) if (child.type === "element" && child.tag === tag) out.push(child);
476
- return out;
477
- }
478
- function attr(element, name) {
479
- for (const a of element.attributes) if (a.name === name) return a.value;
480
- }
481
- function rootElement(part) {
482
- if (part?.kind !== "xml") return;
483
- for (const node of part.nodes) if (node.type === "element") return node;
484
- }
485
- function decodeEntities(value) {
486
- return value.replace(/&(?:amp|lt|gt|quot|apos);/g, (entity) => {
487
- switch (entity) {
488
- case "&amp;": return "&";
489
- case "&lt;": return "<";
490
- case "&gt;": return ">";
491
- case "&quot;": return "\"";
492
- case "&apos;": return "'";
493
- default: return entity;
494
- }
495
- });
496
- }
497
- function textContent(element) {
498
- let text = "";
499
- for (const node of walk(element.children)) if (node.type === "text" || node.type === "cdata") text += node.value;
500
- return decodeEntities(text);
501
- }
502
- function relsPathFor(partPath) {
503
- const lastSlash = partPath.lastIndexOf("/");
504
- return `${lastSlash === -1 ? "" : partPath.slice(0, lastSlash)}/_rels/${lastSlash === -1 ? partPath : partPath.slice(lastSlash + 1)}.rels`;
505
- }
506
- function resolveRelTarget$1(partPath, target) {
507
- if (target.startsWith("/")) return target.slice(1);
508
- const lastSlash = partPath.lastIndexOf("/");
509
- const baseDir = lastSlash === -1 ? "" : partPath.slice(0, lastSlash);
510
- const resolved = [];
511
- for (const segment of `${baseDir}/${target}`.split("/")) {
512
- if (segment === "" || segment === ".") continue;
513
- if (segment === "..") resolved.pop();
514
- else resolved.push(segment);
515
- }
516
- return resolved.join("/");
517
- }
518
- function resolveRelationships(pkg, partPath) {
519
- const map = /* @__PURE__ */ new Map();
520
- const rels = rootElement(pkg.parts[relsPathFor(partPath)]);
521
- if (rels === void 0) return map;
522
- for (const rel of childrenWithTag(rels, "Relationship")) {
523
- const id = attr(rel, "Id");
524
- const type = attr(rel, "Type");
525
- const target = attr(rel, "Target");
526
- if (id === void 0 || type === void 0 || target === void 0) continue;
527
- const targetMode = attr(rel, "TargetMode");
528
- map.set(id, {
529
- type,
530
- target: targetMode === "External" ? target : resolveRelTarget$1(partPath, target),
531
- targetMode
532
- });
533
- }
534
- return map;
535
- }
536
- //#endregion
537
537
  //#region src/typed/docx.ts
538
538
  const RunSchema = zod.z.object({
539
539
  text: zod.z.string(),
@@ -612,6 +612,17 @@ function readRow(row) {
612
612
  function readTable$1(table) {
613
613
  return { rows: childrenWithTag(table, "w:tr").map(readRow) };
614
614
  }
615
+ function* walkExcludingTables(nodes) {
616
+ for (const node of nodes) {
617
+ yield node;
618
+ if (node.type === "element" && node.tag !== "w:tbl") yield* walkExcludingTables(node.children);
619
+ }
620
+ }
621
+ function bodyParagraphElements(nodes) {
622
+ const out = [];
623
+ for (const node of walkExcludingTables(nodes)) if (node.type === "element" && node.tag === "w:p") out.push(node);
624
+ return out;
625
+ }
615
626
  function readHyperlink(hyperlink, rels) {
616
627
  const text = elementsWithTag(hyperlink.children, "w:t").map(textContent).join("");
617
628
  const rid = attr(hyperlink, "r:id");
@@ -664,7 +675,7 @@ function readDocx(pkg) {
664
675
  if (part.kind !== "xml") throw new Error("readDocx: word/document.xml is not an XML part");
665
676
  const rels = resolveRelationships(pkg, "word/document.xml");
666
677
  return {
667
- paragraphs: elementsWithTag(part.nodes, "w:p").map(readParagraph),
678
+ paragraphs: bodyParagraphElements(part.nodes).map(readParagraph),
668
679
  tables: elementsWithTag(part.nodes, "w:tbl").map(readTable$1),
669
680
  hyperlinks: elementsWithTag(part.nodes, "w:hyperlink").map((h) => readHyperlink(h, rels)),
670
681
  comments: readComments(pkg),
@@ -919,13 +930,17 @@ exports.XmlNodeSchema = XmlNodeSchema;
919
930
  exports.XmlPartSchema = XmlPartSchema;
920
931
  exports.XmlPiSchema = XmlPiSchema;
921
932
  exports.XmlTextSchema = XmlTextSchema;
933
+ exports.attr = attr;
922
934
  exports.base64ToBytes = base64ToBytes;
923
935
  exports.buildXml = buildXml;
924
936
  exports.bytesToBase64 = bytesToBase64;
937
+ exports.childrenWithTag = childrenWithTag;
925
938
  exports.compactCodec = compactCodec;
926
939
  exports.compactPackageCodec = compactPackageCodec;
927
940
  exports.decodeCompactPackage = decodeCompactPackage;
941
+ exports.decodeEntities = decodeEntities;
928
942
  exports.decodePackage = decodePackage;
943
+ exports.elementsWithTag = elementsWithTag;
929
944
  exports.encodeCompactPackage = encodeCompactPackage;
930
945
  exports.encodePackage = encodePackage;
931
946
  exports.fromCompact = fromCompact;
@@ -937,8 +952,12 @@ exports.parseXml = parseXml;
937
952
  exports.readDocx = readDocx;
938
953
  exports.readPptx = readPptx;
939
954
  exports.readXlsx = readXlsx;
955
+ exports.resolveRelationships = resolveRelationships;
956
+ exports.rootElement = rootElement;
940
957
  exports.serializePackage = serializePackage;
958
+ exports.textContent = textContent;
941
959
  exports.toCompact = toCompact;
942
960
  exports.unzipPackage = unzipPackage;
961
+ exports.walk = walk;
943
962
  exports.xmlCodec = xmlCodec;
944
963
  exports.zipPackage = zipPackage;
package/dist/index.d.cts CHANGED
@@ -279,6 +279,21 @@ declare function zipPackage(parts: Record<string, Uint8Array<ArrayBuffer>>): Uin
279
279
  declare function bytesToBase64(bytes: Uint8Array<ArrayBuffer>): string;
280
280
  declare function base64ToBytes(b64: string): Uint8Array<ArrayBuffer>;
281
281
  //#endregion
282
+ //#region src/typed/util.d.ts
283
+ declare function walk(nodes: XmlNode[]): Generator<XmlNode>;
284
+ declare function elementsWithTag(nodes: XmlNode[], tag: string): XmlElement[];
285
+ declare function childrenWithTag(element: XmlElement, tag: string): XmlElement[];
286
+ declare function attr(element: XmlElement, name: string): string | undefined;
287
+ declare function rootElement(part: Part | undefined): XmlElement | undefined;
288
+ declare function decodeEntities(value: string): string;
289
+ declare function textContent(element: XmlElement): string;
290
+ interface Relationship {
291
+ type: string;
292
+ target: string;
293
+ targetMode?: string;
294
+ }
295
+ declare function resolveRelationships(pkg: Package, partPath: string): Map<string, Relationship>;
296
+ //#endregion
282
297
  //#region src/compact.d.ts
283
298
  type CompactAttrPairs = number[];
284
299
  type CompactElement = [0, number, CompactAttrPairs, CompactXmlNode[]];
@@ -578,4 +593,4 @@ declare const XlsxWorkbookSchema: z.ZodObject<{
578
593
  type XlsxWorkbook = z.infer<typeof XlsxWorkbookSchema>;
579
594
  declare function readXlsx(pkg: Package): XlsxWorkbook;
580
595
  //#endregion
581
- export { type Attribute, AttributeSchema, type BinaryPart, BinaryPartSchema, type Comment, CommentSchema, type CompactAttrPairs, type CompactPackage, CompactPackageSchema, type CompactPart, CompactPartSchema, type CompactXmlNode, CompactXmlNodeSchema, type DefinedName, DefinedNameSchema, type DocxDocument, DocxDocumentSchema, type Footnote, FootnoteSchema, type Hyperlink, HyperlinkSchema, type ListMembership, ListMembershipSchema, type Package, PackageSchema, type Paragraph, ParagraphSchema, type Part, PartSchema, type PptxPresentation, PptxPresentationSchema, type PptxTable, type PptxTableCell, PptxTableCellSchema, type PptxTableRow, PptxTableRowSchema, PptxTableSchema, type Run, RunSchema, type Shape, ShapeSchema, type Slide, SlideSchema, type Table, type TableCell, TableCellSchema, type TableRow, TableRowSchema, TableSchema, type XlsxCell, XlsxCellSchema, type XlsxSheet, XlsxSheetSchema, type XlsxWorkbook, XlsxWorkbookSchema, type XmlCdata, XmlCdataSchema, type XmlComment, XmlCommentSchema, type XmlDeclaration, XmlDeclarationSchema, type XmlElement, XmlElementSchema, type XmlNode, XmlNodeSchema, type XmlPart, XmlPartSchema, type XmlPi, XmlPiSchema, type XmlText, XmlTextSchema, base64ToBytes, buildXml, bytesToBase64, compactCodec, compactPackageCodec, decodeCompactPackage, decodePackage, encodeCompactPackage, encodePackage, fromCompact, isCompactXmlNode, isXmlNode, packageCodec, parsePackage, parseXml, readDocx, readPptx, readXlsx, serializePackage, toCompact, unzipPackage, xmlCodec, zipPackage };
596
+ export { type Attribute, AttributeSchema, type BinaryPart, BinaryPartSchema, type Comment, CommentSchema, type CompactAttrPairs, type CompactPackage, CompactPackageSchema, type CompactPart, CompactPartSchema, type CompactXmlNode, CompactXmlNodeSchema, type DefinedName, DefinedNameSchema, type DocxDocument, DocxDocumentSchema, type Footnote, FootnoteSchema, type Hyperlink, HyperlinkSchema, type ListMembership, ListMembershipSchema, type Package, PackageSchema, type Paragraph, ParagraphSchema, type Part, PartSchema, type PptxPresentation, PptxPresentationSchema, type PptxTable, type PptxTableCell, PptxTableCellSchema, type PptxTableRow, PptxTableRowSchema, PptxTableSchema, type Relationship, type Run, RunSchema, type Shape, ShapeSchema, type Slide, SlideSchema, type Table, type TableCell, TableCellSchema, type TableRow, TableRowSchema, TableSchema, type XlsxCell, XlsxCellSchema, type XlsxSheet, XlsxSheetSchema, type XlsxWorkbook, XlsxWorkbookSchema, type XmlCdata, XmlCdataSchema, type XmlComment, XmlCommentSchema, type XmlDeclaration, XmlDeclarationSchema, type XmlElement, XmlElementSchema, type XmlNode, XmlNodeSchema, type XmlPart, XmlPartSchema, type XmlPi, XmlPiSchema, type XmlText, XmlTextSchema, attr, base64ToBytes, buildXml, bytesToBase64, childrenWithTag, compactCodec, compactPackageCodec, decodeCompactPackage, decodeEntities, decodePackage, elementsWithTag, encodeCompactPackage, encodePackage, fromCompact, isCompactXmlNode, isXmlNode, packageCodec, parsePackage, parseXml, readDocx, readPptx, readXlsx, resolveRelationships, rootElement, serializePackage, textContent, toCompact, unzipPackage, walk, xmlCodec, zipPackage };
package/dist/index.d.ts CHANGED
@@ -279,6 +279,21 @@ declare function zipPackage(parts: Record<string, Uint8Array<ArrayBuffer>>): Uin
279
279
  declare function bytesToBase64(bytes: Uint8Array<ArrayBuffer>): string;
280
280
  declare function base64ToBytes(b64: string): Uint8Array<ArrayBuffer>;
281
281
  //#endregion
282
+ //#region src/typed/util.d.ts
283
+ declare function walk(nodes: XmlNode[]): Generator<XmlNode>;
284
+ declare function elementsWithTag(nodes: XmlNode[], tag: string): XmlElement[];
285
+ declare function childrenWithTag(element: XmlElement, tag: string): XmlElement[];
286
+ declare function attr(element: XmlElement, name: string): string | undefined;
287
+ declare function rootElement(part: Part | undefined): XmlElement | undefined;
288
+ declare function decodeEntities(value: string): string;
289
+ declare function textContent(element: XmlElement): string;
290
+ interface Relationship {
291
+ type: string;
292
+ target: string;
293
+ targetMode?: string;
294
+ }
295
+ declare function resolveRelationships(pkg: Package, partPath: string): Map<string, Relationship>;
296
+ //#endregion
282
297
  //#region src/compact.d.ts
283
298
  type CompactAttrPairs = number[];
284
299
  type CompactElement = [0, number, CompactAttrPairs, CompactXmlNode[]];
@@ -578,4 +593,4 @@ declare const XlsxWorkbookSchema: z.ZodObject<{
578
593
  type XlsxWorkbook = z.infer<typeof XlsxWorkbookSchema>;
579
594
  declare function readXlsx(pkg: Package): XlsxWorkbook;
580
595
  //#endregion
581
- export { type Attribute, AttributeSchema, type BinaryPart, BinaryPartSchema, type Comment, CommentSchema, type CompactAttrPairs, type CompactPackage, CompactPackageSchema, type CompactPart, CompactPartSchema, type CompactXmlNode, CompactXmlNodeSchema, type DefinedName, DefinedNameSchema, type DocxDocument, DocxDocumentSchema, type Footnote, FootnoteSchema, type Hyperlink, HyperlinkSchema, type ListMembership, ListMembershipSchema, type Package, PackageSchema, type Paragraph, ParagraphSchema, type Part, PartSchema, type PptxPresentation, PptxPresentationSchema, type PptxTable, type PptxTableCell, PptxTableCellSchema, type PptxTableRow, PptxTableRowSchema, PptxTableSchema, type Run, RunSchema, type Shape, ShapeSchema, type Slide, SlideSchema, type Table, type TableCell, TableCellSchema, type TableRow, TableRowSchema, TableSchema, type XlsxCell, XlsxCellSchema, type XlsxSheet, XlsxSheetSchema, type XlsxWorkbook, XlsxWorkbookSchema, type XmlCdata, XmlCdataSchema, type XmlComment, XmlCommentSchema, type XmlDeclaration, XmlDeclarationSchema, type XmlElement, XmlElementSchema, type XmlNode, XmlNodeSchema, type XmlPart, XmlPartSchema, type XmlPi, XmlPiSchema, type XmlText, XmlTextSchema, base64ToBytes, buildXml, bytesToBase64, compactCodec, compactPackageCodec, decodeCompactPackage, decodePackage, encodeCompactPackage, encodePackage, fromCompact, isCompactXmlNode, isXmlNode, packageCodec, parsePackage, parseXml, readDocx, readPptx, readXlsx, serializePackage, toCompact, unzipPackage, xmlCodec, zipPackage };
596
+ export { type Attribute, AttributeSchema, type BinaryPart, BinaryPartSchema, type Comment, CommentSchema, type CompactAttrPairs, type CompactPackage, CompactPackageSchema, type CompactPart, CompactPartSchema, type CompactXmlNode, CompactXmlNodeSchema, type DefinedName, DefinedNameSchema, type DocxDocument, DocxDocumentSchema, type Footnote, FootnoteSchema, type Hyperlink, HyperlinkSchema, type ListMembership, ListMembershipSchema, type Package, PackageSchema, type Paragraph, ParagraphSchema, type Part, PartSchema, type PptxPresentation, PptxPresentationSchema, type PptxTable, type PptxTableCell, PptxTableCellSchema, type PptxTableRow, PptxTableRowSchema, PptxTableSchema, type Relationship, type Run, RunSchema, type Shape, ShapeSchema, type Slide, SlideSchema, type Table, type TableCell, TableCellSchema, type TableRow, TableRowSchema, TableSchema, type XlsxCell, XlsxCellSchema, type XlsxSheet, XlsxSheetSchema, type XlsxWorkbook, XlsxWorkbookSchema, type XmlCdata, XmlCdataSchema, type XmlComment, XmlCommentSchema, type XmlDeclaration, XmlDeclarationSchema, type XmlElement, XmlElementSchema, type XmlNode, XmlNodeSchema, type XmlPart, XmlPartSchema, type XmlPi, XmlPiSchema, type XmlText, XmlTextSchema, attr, base64ToBytes, buildXml, bytesToBase64, childrenWithTag, compactCodec, compactPackageCodec, decodeCompactPackage, decodeEntities, decodePackage, elementsWithTag, encodeCompactPackage, encodePackage, fromCompact, isCompactXmlNode, isXmlNode, packageCodec, parsePackage, parseXml, readDocx, readPptx, readXlsx, resolveRelationships, rootElement, serializePackage, textContent, toCompact, unzipPackage, walk, xmlCodec, zipPackage };
package/dist/index.js CHANGED
@@ -309,6 +309,82 @@ function encodePackage(pkg) {
309
309
  return z.encode(packageCodec, pkg);
310
310
  }
311
311
  //#endregion
312
+ //#region src/typed/util.ts
313
+ function* walk(nodes) {
314
+ for (const node of nodes) {
315
+ yield node;
316
+ if (node.type === "element") yield* walk(node.children);
317
+ }
318
+ }
319
+ function elementsWithTag(nodes, tag) {
320
+ const out = [];
321
+ for (const node of walk(nodes)) if (node.type === "element" && node.tag === tag) out.push(node);
322
+ return out;
323
+ }
324
+ function childrenWithTag(element, tag) {
325
+ const out = [];
326
+ for (const child of element.children) if (child.type === "element" && child.tag === tag) out.push(child);
327
+ return out;
328
+ }
329
+ function attr(element, name) {
330
+ for (const a of element.attributes) if (a.name === name) return a.value;
331
+ }
332
+ function rootElement(part) {
333
+ if (part?.kind !== "xml") return;
334
+ for (const node of part.nodes) if (node.type === "element") return node;
335
+ }
336
+ function decodeEntities(value) {
337
+ return value.replace(/&(?:amp|lt|gt|quot|apos);/g, (entity) => {
338
+ switch (entity) {
339
+ case "&amp;": return "&";
340
+ case "&lt;": return "<";
341
+ case "&gt;": return ">";
342
+ case "&quot;": return "\"";
343
+ case "&apos;": return "'";
344
+ default: return entity;
345
+ }
346
+ });
347
+ }
348
+ function textContent(element) {
349
+ let text = "";
350
+ for (const node of walk(element.children)) if (node.type === "text" || node.type === "cdata") text += node.value;
351
+ return decodeEntities(text);
352
+ }
353
+ function relsPathFor(partPath) {
354
+ const lastSlash = partPath.lastIndexOf("/");
355
+ return `${lastSlash === -1 ? "" : partPath.slice(0, lastSlash)}/_rels/${lastSlash === -1 ? partPath : partPath.slice(lastSlash + 1)}.rels`;
356
+ }
357
+ function resolveRelTarget$1(partPath, target) {
358
+ if (target.startsWith("/")) return target.slice(1);
359
+ const lastSlash = partPath.lastIndexOf("/");
360
+ const baseDir = lastSlash === -1 ? "" : partPath.slice(0, lastSlash);
361
+ const resolved = [];
362
+ for (const segment of `${baseDir}/${target}`.split("/")) {
363
+ if (segment === "" || segment === ".") continue;
364
+ if (segment === "..") resolved.pop();
365
+ else resolved.push(segment);
366
+ }
367
+ return resolved.join("/");
368
+ }
369
+ function resolveRelationships(pkg, partPath) {
370
+ const map = /* @__PURE__ */ new Map();
371
+ const rels = rootElement(pkg.parts[relsPathFor(partPath)]);
372
+ if (rels === void 0) return map;
373
+ for (const rel of childrenWithTag(rels, "Relationship")) {
374
+ const id = attr(rel, "Id");
375
+ const type = attr(rel, "Type");
376
+ const target = attr(rel, "Target");
377
+ if (id === void 0 || type === void 0 || target === void 0) continue;
378
+ const targetMode = attr(rel, "TargetMode");
379
+ map.set(id, {
380
+ type,
381
+ target: targetMode === "External" ? target : resolveRelTarget$1(partPath, target),
382
+ targetMode
383
+ });
384
+ }
385
+ return map;
386
+ }
387
+ //#endregion
312
388
  //#region src/compact.ts
313
389
  function isUnknownArray(value) {
314
390
  return Array.isArray(value);
@@ -457,82 +533,6 @@ function encodeCompactPackage(cpkg) {
457
533
  return z.encode(compactPackageCodec, cpkg);
458
534
  }
459
535
  //#endregion
460
- //#region src/typed/util.ts
461
- function* walk(nodes) {
462
- for (const node of nodes) {
463
- yield node;
464
- if (node.type === "element") yield* walk(node.children);
465
- }
466
- }
467
- function elementsWithTag(nodes, tag) {
468
- const out = [];
469
- for (const node of walk(nodes)) if (node.type === "element" && node.tag === tag) out.push(node);
470
- return out;
471
- }
472
- function childrenWithTag(element, tag) {
473
- const out = [];
474
- for (const child of element.children) if (child.type === "element" && child.tag === tag) out.push(child);
475
- return out;
476
- }
477
- function attr(element, name) {
478
- for (const a of element.attributes) if (a.name === name) return a.value;
479
- }
480
- function rootElement(part) {
481
- if (part?.kind !== "xml") return;
482
- for (const node of part.nodes) if (node.type === "element") return node;
483
- }
484
- function decodeEntities(value) {
485
- return value.replace(/&(?:amp|lt|gt|quot|apos);/g, (entity) => {
486
- switch (entity) {
487
- case "&amp;": return "&";
488
- case "&lt;": return "<";
489
- case "&gt;": return ">";
490
- case "&quot;": return "\"";
491
- case "&apos;": return "'";
492
- default: return entity;
493
- }
494
- });
495
- }
496
- function textContent(element) {
497
- let text = "";
498
- for (const node of walk(element.children)) if (node.type === "text" || node.type === "cdata") text += node.value;
499
- return decodeEntities(text);
500
- }
501
- function relsPathFor(partPath) {
502
- const lastSlash = partPath.lastIndexOf("/");
503
- return `${lastSlash === -1 ? "" : partPath.slice(0, lastSlash)}/_rels/${lastSlash === -1 ? partPath : partPath.slice(lastSlash + 1)}.rels`;
504
- }
505
- function resolveRelTarget$1(partPath, target) {
506
- if (target.startsWith("/")) return target.slice(1);
507
- const lastSlash = partPath.lastIndexOf("/");
508
- const baseDir = lastSlash === -1 ? "" : partPath.slice(0, lastSlash);
509
- const resolved = [];
510
- for (const segment of `${baseDir}/${target}`.split("/")) {
511
- if (segment === "" || segment === ".") continue;
512
- if (segment === "..") resolved.pop();
513
- else resolved.push(segment);
514
- }
515
- return resolved.join("/");
516
- }
517
- function resolveRelationships(pkg, partPath) {
518
- const map = /* @__PURE__ */ new Map();
519
- const rels = rootElement(pkg.parts[relsPathFor(partPath)]);
520
- if (rels === void 0) return map;
521
- for (const rel of childrenWithTag(rels, "Relationship")) {
522
- const id = attr(rel, "Id");
523
- const type = attr(rel, "Type");
524
- const target = attr(rel, "Target");
525
- if (id === void 0 || type === void 0 || target === void 0) continue;
526
- const targetMode = attr(rel, "TargetMode");
527
- map.set(id, {
528
- type,
529
- target: targetMode === "External" ? target : resolveRelTarget$1(partPath, target),
530
- targetMode
531
- });
532
- }
533
- return map;
534
- }
535
- //#endregion
536
536
  //#region src/typed/docx.ts
537
537
  const RunSchema = z.object({
538
538
  text: z.string(),
@@ -611,6 +611,17 @@ function readRow(row) {
611
611
  function readTable$1(table) {
612
612
  return { rows: childrenWithTag(table, "w:tr").map(readRow) };
613
613
  }
614
+ function* walkExcludingTables(nodes) {
615
+ for (const node of nodes) {
616
+ yield node;
617
+ if (node.type === "element" && node.tag !== "w:tbl") yield* walkExcludingTables(node.children);
618
+ }
619
+ }
620
+ function bodyParagraphElements(nodes) {
621
+ const out = [];
622
+ for (const node of walkExcludingTables(nodes)) if (node.type === "element" && node.tag === "w:p") out.push(node);
623
+ return out;
624
+ }
614
625
  function readHyperlink(hyperlink, rels) {
615
626
  const text = elementsWithTag(hyperlink.children, "w:t").map(textContent).join("");
616
627
  const rid = attr(hyperlink, "r:id");
@@ -663,7 +674,7 @@ function readDocx(pkg) {
663
674
  if (part.kind !== "xml") throw new Error("readDocx: word/document.xml is not an XML part");
664
675
  const rels = resolveRelationships(pkg, "word/document.xml");
665
676
  return {
666
- paragraphs: elementsWithTag(part.nodes, "w:p").map(readParagraph),
677
+ paragraphs: bodyParagraphElements(part.nodes).map(readParagraph),
667
678
  tables: elementsWithTag(part.nodes, "w:tbl").map(readTable$1),
668
679
  hyperlinks: elementsWithTag(part.nodes, "w:hyperlink").map((h) => readHyperlink(h, rels)),
669
680
  comments: readComments(pkg),
@@ -883,4 +894,4 @@ function readXlsx(pkg) {
883
894
  };
884
895
  }
885
896
  //#endregion
886
- export { AttributeSchema, BinaryPartSchema, CommentSchema, CompactPackageSchema, CompactPartSchema, CompactXmlNodeSchema, DefinedNameSchema, DocxDocumentSchema, FootnoteSchema, HyperlinkSchema, ListMembershipSchema, PackageSchema, ParagraphSchema, PartSchema, PptxPresentationSchema, PptxTableCellSchema, PptxTableRowSchema, PptxTableSchema, RunSchema, ShapeSchema, SlideSchema, TableCellSchema, TableRowSchema, TableSchema, XlsxCellSchema, XlsxSheetSchema, XlsxWorkbookSchema, XmlCdataSchema, XmlCommentSchema, XmlDeclarationSchema, XmlElementSchema, XmlNodeSchema, XmlPartSchema, XmlPiSchema, XmlTextSchema, base64ToBytes, buildXml, bytesToBase64, compactCodec, compactPackageCodec, decodeCompactPackage, decodePackage, encodeCompactPackage, encodePackage, fromCompact, isCompactXmlNode, isXmlNode, packageCodec, parsePackage, parseXml, readDocx, readPptx, readXlsx, serializePackage, toCompact, unzipPackage, xmlCodec, zipPackage };
897
+ export { AttributeSchema, BinaryPartSchema, CommentSchema, CompactPackageSchema, CompactPartSchema, CompactXmlNodeSchema, DefinedNameSchema, DocxDocumentSchema, FootnoteSchema, HyperlinkSchema, ListMembershipSchema, PackageSchema, ParagraphSchema, PartSchema, PptxPresentationSchema, PptxTableCellSchema, PptxTableRowSchema, PptxTableSchema, RunSchema, ShapeSchema, SlideSchema, TableCellSchema, TableRowSchema, TableSchema, XlsxCellSchema, XlsxSheetSchema, XlsxWorkbookSchema, XmlCdataSchema, XmlCommentSchema, XmlDeclarationSchema, XmlElementSchema, XmlNodeSchema, XmlPartSchema, XmlPiSchema, XmlTextSchema, attr, base64ToBytes, buildXml, bytesToBase64, childrenWithTag, compactCodec, compactPackageCodec, decodeCompactPackage, decodeEntities, decodePackage, elementsWithTag, encodeCompactPackage, encodePackage, fromCompact, isCompactXmlNode, isXmlNode, packageCodec, parsePackage, parseXml, readDocx, readPptx, readXlsx, resolveRelationships, rootElement, serializePackage, textContent, toCompact, unzipPackage, walk, xmlCodec, zipPackage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ooxml.js",
3
- "version": "1.2.1",
3
+ "version": "1.3.1",
4
4
  "description": "Type-safe, lossless round-trip conversion between OOXML packages (docx, pptx, xlsx) and JSON, built on Zod 4 codecs.",
5
5
  "type": "module",
6
6
  "repository": {