diff --git a/crates/doc/src/numbering.rs b/crates/doc/src/numbering.rs index db3228a61..ffdea365c 100644 --- a/crates/doc/src/numbering.rs +++ b/crates/doc/src/numbering.rs @@ -240,10 +240,14 @@ impl Numbering { } /// A new `num` that restarts numbering of an existing list. pub fn restart(&mut self, num: u32) -> Option { - let a = self.num(num)?.abstract_id; + let source = self.num(num)?; + let a = source.abstract_id; + let level_overrides = source.level_overrides.clone(); let nid = self.nums.iter().map(|n| n.id + 1).max().unwrap_or(1).max(1); - let starts = self.abstracts.iter().find(|x| x.id == a).map(|x| x.levels.iter().enumerate().map(|(i, l)| (i as u8, l.start)).collect()); - self.nums.push(Num { id: nid, abstract_id: a, start_overrides: starts.unwrap_or_default(), ..Default::default() }); + // Every level starts again at its own effective start, so a level this list defines itself keeps its start. + let levels = self.abstracts.iter().find(|x| x.id == a).map_or(0, |x| x.levels.len()); + let start_overrides = (0..levels).filter_map(|i| self.level(num, i as u8).map(|l| (i as u8, l.start))).collect(); + self.nums.push(Num { id: nid, abstract_id: a, start_overrides, level_overrides }); Some(nid) } /// Find an existing list whose first level matches `kind`, so consecutive bullet clicks reuse it. @@ -449,4 +453,19 @@ mod tests { assert_eq!(c.next_label(&n, b, 0).unwrap().0, "•"); assert_eq!(n.find_kind(ListKind::Bullet), Some(b)); } + + #[test] + fn restart_keeps_the_list_s_own_level_definitions() { + let mut n = Numbering::default(); + let id = n.add_list(ListKind::Numbered); + let own = Level { format: NumFormat::UpperRoman, text: "Part %1".into(), indent: 90.0, hanging: 40.0, start: 5, ..Level::default() }; + if let Some(num) = n.nums.iter_mut().find(|x| x.id == id) { + num.level_overrides.push((0, own.clone())); + } + let r = n.restart(id).unwrap(); + assert_eq!(n.num(r).unwrap().level_overrides, vec![(0, own.clone())]); + assert_eq!(n.level(r, 0), Some(&own)); + let mut c = Counters::default(); + assert_eq!(c.next_label(&n, r, 0).unwrap().0, "Part V"); + } }