From 5321e27220d7ad64853c37bb26d79b1edfc605dd Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Sat, 31 Oct 2026 00:32:37 +0100 Subject: [PATCH] Keep text of nested inline elements in file.importXml Found while testing crates/engine/src/cmd/xml.rs:~215-245 (parse: the Start/Text/End depth handling; text at depth >= 4 matches no arm) Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/engine/src/cmd/xml.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/crates/engine/src/cmd/xml.rs b/crates/engine/src/cmd/xml.rs index f3d55099b..81b57b5b3 100644 --- a/crates/engine/src/cmd/xml.rs +++ b/crates/engine/src/cmd/xml.rs @@ -168,7 +168,7 @@ fn parse(xml: &str) -> std::result::Result, String> { _ => String::new(), }; match (depth, child.as_mut(), out.last_mut()) { - (3, Some(c), _) => c.1.push_str(&s), + (3.., Some(c), _) => c.1.push_str(&s), (2, _, Some(el)) => el.text.push_str(&s), _ => {} } @@ -518,6 +518,34 @@ mod tests { assert_eq!(s.doc().unwrap().doc.xml.style_map.len(), 1); } + #[test] + fn import_xml_keeps_text_of_inline_tags_in_mapped_paragraphs() { + let mut s = Session::new(); + s.execute("file.new", &json!({})).unwrap(); + s.execute("style.paragraph.create", &json!({"name": "Head"})).unwrap(); + let a = s + .execute("frame.create", &json!({"rect": [72, 72, 400, 150], "content": "text", "text": "See the glossary entry", "caret": false})) + .unwrap(); + s.execute("text.select", &json!({"story": a["story"], "anchor": 0, "focus": 0})).unwrap(); + s.execute("style.paragraph.apply", &json!({"name": "Head"})).unwrap(); + s.execute("xml.tag", &json!({"tag": "story", "ids": [a["id"]]})).unwrap(); + s.execute("xml.mapStyle", &json!({"style": "Head", "tag": "title"})).unwrap(); + s.execute("text.select", &json!({"story": a["story"], "anchor": 8, "focus": 16})).unwrap(); + s.execute("xml.tagText", &json!({"tag": "term"})).unwrap(); + let x = s.execute("file.exportXml", &json!({})).unwrap()["text"].as_str().unwrap().to_string(); + assert!(x.contains("See the <term>glossary</term> entry"), "{x}"); + s.execute("file.importXml", &json!({"text": x})).unwrap(); + let d = &s.doc().unwrap().doc; + assert_eq!(d.stories[&designcraft_doc::StoryId(a["story"].as_u64().unwrap())].text, "See the glossary entry"); + } + + #[test] + fn parse_keeps_text_nested_below_a_child_element() { + let els = super::parse("See the x y").unwrap(); + assert_eq!(els.len(), 1); + assert_eq!(els[0].children, vec![("note".to_string(), "See the x y".to_string())]); + } + #[test] fn tag_export_and_import_xml() { let mut s = Session::new();