//! Speaker notes keep their run and paragraph formatting: a bold heading, indented points with
//! custom bullets, plain lines.
mod common;
use std::sync::Arc;
use common::{export, import, part, rewrite};
use craft_pptx::text::{Bullet, ParaProps, TextBody};
const NOTES: &str = "ppt/notesSlides/notesSlide1.xml";
/// A notes slide written the way PowerPoint writes one (Slovak text): a bold heading, a plain
/// line, two level-2 points with a hanging indent and a Wingdings square bullet (one mixing a bold
/// label and plain text), a level-2 paragraph with buNone, and a closing plain line.
const NOTES_XML: &str = r#"
Metodický prehľadŽiaci pracujú vo dvojiciach.Cieľ: vysvetliť cyklusReflexiaBez odrážkyPomôcky: počítač"#;
/// A deck with one notes slide, its notes replaced by [`NOTES_XML`].
fn deck() -> Vec {
let mut p = common::deck();
Arc::make_mut(&mut p.slides[0]).notes = TextBody::from_text("placeholder");
let bytes = export(&p);
assert!(part(&bytes, NOTES).contains("placeholder"), "the export has no {NOTES}");
rewrite(&bytes, |name, data| Some(if name == NOTES { NOTES_XML.as_bytes().to_vec() } else { data.to_vec() }), &[])
}
fn assert_formatted(notes: &TextBody) {
assert_eq!(notes.text(), "Metodický prehľad\nŽiaci pracujú vo dvojiciach.\nCieľ: vysvetliť cyklus\nReflexia\nBez odrážky\nPomôcky: počítač");
let [head, plain, goal, reflect, unbulleted, closing] = notes.paragraphs.as_slice() else { panic!("six paragraphs: {notes:?}") };
assert_eq!(head.runs[0].props.bold, Some(true), "bold heading");
for para in [head, plain, closing] {
assert_eq!((para.level, ¶.props), (0, &ParaProps::default()), "{:?}", para.text());
}
assert_eq!(plain.runs[0].props.bold, None);
for para in [goal, reflect] {
assert_eq!(para.level, 1, "level 2");
assert_eq!(para.props.margin_left, Some(22.5), "marL 285750 EMU");
assert_eq!(para.props.indent, Some(-22.5), "hanging indent");
assert_eq!(para.props.bullet, Some(Bullet::Char { char: "§".into() }));
assert_eq!(para.props.bullet_font.as_deref(), Some("Wingdings"));
}
assert_eq!((goal.runs[0].text.as_str(), goal.runs[0].props.bold), ("Cieľ: ", Some(true)), "bold label");
assert_eq!((goal.runs[1].text.as_str(), goal.runs[1].props.bold), ("vysvetliť cyklus", None), "then plain");
assert_eq!(reflect.runs[0].props.italic, Some(true));
assert_eq!((unbulleted.level, unbulleted.props.bullet.clone(), unbulleted.props.margin_left), (1, Some(Bullet::None), Some(22.5)));
}
#[test]
fn notes_import_keeps_bold_levels_and_indents() {
let p = import(&deck());
assert_formatted(&p.slides[0].notes);
}
#[test]
fn notes_formatting_survives_a_round_trip() {
let p = import(&deck());
let again = import(&export(&p));
assert_formatted(&again.slides[0].notes);
// And the written XML says so, for PowerPoint.
let xml = part(&export(&again), NOTES);
assert!(xml.contains(r#"b="1""#), "{xml}");
assert!(xml.contains(r#"lvl="1""#) && xml.contains(r#"marL="285750""#) && xml.contains(r#"indent="-285750""#), "{xml}");
assert!(xml.contains(r#""), "{xml}");
}