fix: write w:next at XML level so self-referential next styles persist

python-docx's next_paragraph_style setter drops self-references (WA Nrml
Pgr -> itself, WA TOC -> itself), which would make Word continue those
paragraphs as Normal; the test now asserts the w:next element.
This commit is contained in:
bm
2026-09-24 08:01:09 -07:00
parent a820e60361
commit 03945796bb
2 changed files with 21 additions and 6 deletions

View File

@@ -959,13 +959,22 @@ class WAStyleFamilyTests(unittest.TestCase):
def test_wa_style_bases_and_next_styles(self):
st = self._format().styles
def next_id(sid):
# Assert the w:next ELEMENT exists — the python-docx getter falls
# back to the default style when w:next is absent, which would
# otherwise let self-referential next styles pass vacuously.
el = st[sid].element.find(qn("w:next"))
return el.get(qn("w:val")) if el is not None else None
self.assertEqual(st["WA Chapter"].base_style.name, "Heading 1")
self.assertEqual(st["WA Section"].base_style.name, "Normal")
self.assertEqual(st["WA Thkng"].base_style.name, "WA Nrml Pgr")
self.assertEqual(st["WA Chapter"].next_paragraph_style.name, "WA NChp Pgr")
self.assertEqual(st["WA Section"].next_paragraph_style.name, "WA NChp Pgr")
self.assertEqual(st["WA NChp Pgr"].next_paragraph_style.name, "WA Nrml Pgr")
self.assertEqual(st["WA Nrml Pgr"].next_paragraph_style.name, "WA Nrml Pgr")
self.assertEqual(next_id("WAChapter"), "WANChpPgr")
self.assertEqual(next_id("WASection"), "WANChpPgr")
self.assertEqual(next_id("WANChpPgr"), "WANrmlPgr")
self.assertEqual(next_id("WANrmlPgr"), "WANrmlPgr")
self.assertEqual(next_id("WATOC"), "WATOC")
def test_wa_chapter_outline_level_and_automatic_color(self):
el = self._format().styles["WA Chapter"].element

View File

@@ -374,10 +374,16 @@ def _create_wa_styles(doc):
color_el.set(qn('w:val'), props["color"])
if "next_style" in props:
# Write w:next at the XML level: the python-docx property setter
# silently drops self-referential next styles (WA Nrml Pgr ->
# itself, WA TOC -> itself), which would make Word continue those
# paragraphs as Normal instead of the WA style.
try:
style.next_paragraph_style = doc.styles[props["next_style"]]
target = doc.styles[props["next_style"]]
except KeyError:
pass
target = None
if target is not None:
style.element.get_or_add_next().val = target.style_id
if props["type"] == "paragraph" and style.paragraph_format:
if "outline_level" in props: