summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2025-09-11 15:07:41 +0100
committerMichael Williamson <mike@zwobble.org>2025-09-11 15:07:41 +0100
commitcee62eea4e52484a473128f342e2a497e32261b7 (patch)
treec2d38753571a59f38c337edaac76d185a7e3601d /lib
parent660da135c950031097269f5d610e771698f99eb3 (diff)
Handle numbering levels defined without an index
Diffstat (limited to 'lib')
-rw-r--r--lib/docx/body-reader.js7
-rw-r--r--lib/docx/numbering-xml.js29
2 files changed, 31 insertions, 5 deletions
diff --git a/lib/docx/body-reader.js b/lib/docx/body-reader.js
index 5cdb4ef..826424b 100644
--- a/lib/docx/body-reader.js
+++ b/lib/docx/body-reader.js
@@ -670,6 +670,13 @@ function readNumberingProperties(styleId, element, numbering) {
}
}
+ // Some malformed documents define numbering levels without an index, and
+ // reference the numbering using a w:numPr element without a w:ilvl child.
+ // To handle such cases, we assume a level of 0 as a fallback.
+ if (numId !== undefined) {
+ return numbering.findLevel(numId, "0");
+ }
+
return null;
}
diff --git a/lib/docx/numbering-xml.js b/lib/docx/numbering-xml.js
index 7e368ac..c41477e 100644
--- a/lib/docx/numbering-xml.js
+++ b/lib/docx/numbering-xml.js
@@ -64,18 +64,37 @@ function readAbstractNums(root) {
function readAbstractNum(element) {
var levels = {};
+
+ // Some malformed documents define numbering levels without an index, and
+ // reference the numbering using a w:numPr element without a w:ilvl child.
+ // To handle such cases, we assume a level of 0 as a fallback.
+ var levelWithoutIndex = null;
+
element.getElementsByTagName("w:lvl").forEach(function(levelElement) {
var levelIndex = levelElement.attributes["w:ilvl"];
var numFmt = levelElement.firstOrEmpty("w:numFmt").attributes["w:val"];
+ var isOrdered = numFmt !== "bullet";
var paragraphStyleId = levelElement.firstOrEmpty("w:pStyle").attributes["w:val"];
- levels[levelIndex] = {
- isOrdered: numFmt !== "bullet",
- level: levelIndex,
- paragraphStyleId: paragraphStyleId
- };
+ if (levelIndex === undefined) {
+ levelWithoutIndex = {
+ isOrdered: isOrdered,
+ level: "0",
+ paragraphStyleId: paragraphStyleId
+ };
+ } else {
+ levels[levelIndex] = {
+ isOrdered: isOrdered,
+ level: levelIndex,
+ paragraphStyleId: paragraphStyleId
+ };
+ }
});
+ if (levels["0"] === undefined && levelWithoutIndex !== null) {
+ levels["0"] = levelWithoutIndex;
+ }
+
var numStyleLink = element.firstOrEmpty("w:numStyleLink").attributes["w:val"];
return {levels: levels, numStyleLink: numStyleLink};