diff --git a/src/formats/odf/mod.rs b/src/formats/odf/mod.rs
index e4a64553..85d95910 100644
--- a/src/formats/odf/mod.rs
+++ b/src/formats/odf/mod.rs
@@ -236,6 +236,50 @@ mod tests {
);
}
+ #[test]
+ fn continued_sublist_restarts_when_its_parent_advances() {
+ // Word saves nested lists as ODT with continue-numbering on every
+ // level; item 2's sublist must read 2.1, not 2.3.
+ let content = r#"
+
+
+
+
+
+
+ Subject
+ Duty A
+ Duty B
+
+ Price
+ Payment
+
+
+ "#;
+ let md = crate::document_to_markdown(&parse(&odt_with_content(content)).unwrap());
+ assert!(md.contains("1.2. Duty B"), "{md}");
+ assert!(md.contains("2.1. Payment"), "{md}");
+
+ // The same when each sublist names its own list style.
+ let styled = content
+ .replace(
+ "",
+ r#"
+
+ "#,
+ )
+ .replace(
+ r#""#,
+ r#""#,
+ );
+ let md = crate::document_to_markdown(&parse(&odt_with_content(&styled)).unwrap());
+ assert!(md.contains("1. Payment"), "{md}");
+ assert!(!md.contains("3. Payment"), "{md}");
+ }
+
#[test]
fn repeated_rows_parse_content_once() {
// A note inside a repeated row must register once, not per copy.
diff --git a/src/formats/odf/text.rs b/src/formats/odf/text.rs
index da64da40..bf888826 100644
--- a/src/formats/odf/text.rs
+++ b/src/formats/odf/text.rs
@@ -195,6 +195,12 @@ fn parse_list(
}
}
let number = current.start.saturating_add(current.items.len() as u64);
+ if !header {
+ // A new item at this level restarts the levels below it, so a
+ // `continue-numbering` sublist under it starts afresh.
+ // Every style: a sublist may name its own list style.
+ ctx.list_counters.borrow_mut().retain(|(_, d), _| *d <= depth);
+ }
let mut chain = ancestors.to_vec();
chain.push(number);
let mut item_blocks = Vec::new();