diff --git a/crates/idml/src/export/designmap.rs b/crates/idml/src/export/designmap.rs index adce1cbd0..6dc907c64 100644 --- a/crates/idml/src/export/designmap.rs +++ b/crates/idml/src/export/designmap.rs @@ -206,10 +206,10 @@ fn xref_format_el(i: usize, f: &designcraft_doc::XrefFormat) -> El { }; let mut rest = f.definition.as_str(); while let Some(a) = rest.find('<') { + let Some(b) = rest[a..].find('>') else { break }; if a > 0 { block(&mut el, "CustomStringBuildingBlock", &rest[..a], "", false); } - let Some(b) = rest[a..].find('>') else { break }; let tag = rest[a + 1..a + b].trim().trim_end_matches('/').trim(); let attr = |k: &str| tag.find(&format!("{k}=\"")).and_then(|i| tag[i + k.len() + 2..].split('"').next()).unwrap_or("").to_string(); match tag.split_whitespace().next().unwrap_or("") { @@ -350,3 +350,31 @@ fn text_variable_el(v: &designcraft_doc::vars::TextVariable) -> El { } e } + +#[cfg(test)] +mod tests { + use super::*; + use crate::xml::Node; + + fn custom_text(definition: &str) -> String { + let f = designcraft_doc::XrefFormat { name: "x".into(), definition: definition.into() }; + xref_format_el(0, &f) + .children + .iter() + .filter_map(|n| match n { + Node::El(e) if e.get("BlockType") == Some("CustomStringBuildingBlock") => e.get("CustomText").map(str::to_string), + _ => None, + }) + .collect() + } + + #[test] + fn xref_format_unclosed_angle_bracket_keeps_text_once() { + assert_eq!(custom_text("a < b"), "a < b"); + } + + #[test] + fn xref_format_well_formed_keeps_custom_text() { + assert_eq!(custom_text("p of "), "p of "); + } +}