summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2025-08-03 07:47:58 +0100
committerMichael Williamson <mike@zwobble.org>2025-08-03 07:47:58 +0100
commit033466fcb57ba2f4c0f876ed8dec705de5c68333 (patch)
tree60522f1c52d017eb9451d9be12eab357fceace45
parent67761754e4333fcb0ddccf06508a8631ce016c09 (diff)
Ignore style definitions using a style ID that has already been used
-rw-r--r--NEWS4
-rw-r--r--lib/docx/styles-reader.js13
-rw-r--r--test/docx/styles-reader.tests.js10
3 files changed, 26 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 3025eea..f2ce8bb 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+# 1.11.0
+
+* Ignore style definitions using a style ID that has already been used.
+
# 1.10.0
* Add "Heading" and "Body" styles, as found in documents created by Apple Pages,
diff --git a/lib/docx/styles-reader.js b/lib/docx/styles-reader.js
index bff859f..28c809b 100644
--- a/lib/docx/styles-reader.js
+++ b/lib/docx/styles-reader.js
@@ -37,7 +37,18 @@ function readStylesXml(root) {
root.getElementsByTagName("w:style").forEach(function(styleElement) {
var style = readStyleElement(styleElement);
var styleSet = styles[style.type];
- if (styleSet) {
+
+ // Per 17.7.4.17 style (Style Definition) of ECMA-376 4th edition Part 1:
+ //
+ // > If multiple style definitions each declare the same value for their
+ // > styleId, then the first such instance shall keep its current
+ // > identifier with all other instances being reassigned in any manner
+ // > desired.
+ //
+ // For the purpose of conversion, there's no point holding onto styles
+ // with reassigned style IDs, so we ignore such style definitions.
+
+ if (styleSet && styleSet[style.styleId] === undefined) {
styleSet[style.styleId] = style;
}
});
diff --git a/test/docx/styles-reader.tests.js b/test/docx/styles-reader.tests.js
index 0997d2c..b63bb6a 100644
--- a/test/docx/styles-reader.tests.js
+++ b/test/docx/styles-reader.tests.js
@@ -110,6 +110,16 @@ test('numbering style has numId read from paragraph properties', function() {
assert.equal(styles.findNumberingStyleById("List1").numId, "42");
});
+test('when multiple style elements have same style ID then only first element is used', function() {
+ var styles = readStylesXml(
+ new XmlElement("w:styles", {}, [
+ tableStyleElement("TableNormal", "Normal Table"),
+ tableStyleElement("TableNormal", "Table Normal")
+ ])
+ );
+ assert.equal(styles.findTableStyleById("TableNormal").name, "Normal Table");
+});
+
function paragraphStyleElement(id, name) {
return styleElement("paragraph", id, name);
}