diff --git a/crates/engine/src/cmd/slide.rs b/crates/engine/src/cmd/slide.rs index b203f083..cf8e92ad 100644 --- a/crates/engine/src/cmd/slide.rs +++ b/crates/engine/src/cmd/slide.rs @@ -627,6 +627,17 @@ fn from_outline(s: &mut Session, p: &Value) -> Result { for (k, sl) in new.into_iter().enumerate() { doc.slides.insert(at + k, sl); } + // Join the section of the slide before, as slide.new does. + let ids: Vec = doc.slides.iter().skip(at).take(n).map(|x| x.id).collect(); + let prev = at.checked_sub(1).and_then(|i| doc.slides.get(i)).map(|x| x.id); + let section = prev.and_then(|p| doc.section_of(p)); + if let Some(sec) = section.and_then(|si| doc.sections.get_mut(si)) { + let pos = prev.and_then(|p| sec.slides.iter().position(|x| *x == p)).map(|k| k + 1).unwrap_or(sec.slides.len()); + let pos = pos.min(sec.slides.len()); + sec.slides.splice(pos..pos, ids); + } else if let Some(first) = doc.sections.first_mut() { + first.slides.splice(0..0, ids); + } Ok(json!({"slides": n})) }) } diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index a464fd8b..ce7daf83 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -3623,3 +3623,21 @@ fn table_column_width_of_a_huge_column_is_ignored() { assert_eq!(table_of(&s, id).cols, vec![100.0, 100.0], "no column changes"); } } + +/// Slides imported from an outline join the section of the slide they follow, like `slide.new`. +#[test] +fn slides_from_outline_join_the_section_of_the_slide_they_follow() { + for markdown in [false, true] { + let mut s = session(); + s.execute("slide.new", &json!({"title": "A"})).unwrap(); + s.execute("section.add", &json!({"name": "B", "at": 1})).unwrap(); + let text = if markdown { "# Imported\n- bullet" } else { "Imported\n\tbullet" }; + s.execute("slide.fromOutline", &json!({"text": text, "markdown": markdown})).unwrap(); + let doc = s.doc().unwrap().doc.clone(); + let orphans: Vec<_> = doc.slides.iter().map(|x| x.id).filter(|id| doc.section_of(*id).is_none()).collect(); + assert!(orphans.is_empty(), "markdown={markdown}: slides in no section: {orphans:?}; sections {:?}", doc.sections); + let order: Vec<_> = doc.sections.iter().flat_map(|x| x.slides.iter().copied()).collect(); + let slides: Vec<_> = doc.slides.iter().map(|x| x.id).collect(); + assert_eq!(order, slides, "markdown={markdown}: sections follow the slide order"); + } +}