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 ");
+ }
+}