fix(idml): preserve transforms and text variable values

This commit is contained in:
Dylan M. Taylor committed 2026-11-14 05:51:17 +00:00
1 parent 6c894be829
commit 07e89ad30a
4 files changed
+28 -3

No files matched your search

+3 -2
View File
@@ -346,11 +346,12 @@ impl TextVariableValues {
settings: preference.map(|child| child.attrs.clone()).unwrap_or_default(),
},
};
let text = |key: &str| preference.and_then(|child| child.attr(key)).or_else(|| values.get(key)).unwrap_or("").to_owned();
Self {
self_id: values.self_id().map(str::to_owned),
name: values.get("Name").unwrap_or("").to_owned(),
before: values.get("TextBefore").unwrap_or("").to_owned(),
after: values.get("TextAfter").unwrap_or("").to_owned(),
before: text("TextBefore"),
after: text("TextAfter"),
kind,
}
}
+9 -1
View File
@@ -30,7 +30,15 @@ pub fn nums(s: &str) -> Vec<f64> {
/// An `ItemTransform`: the six coefficients `a b c d tx ty`, or `None` when the value is not
/// six finite numbers.
pub fn matrix(s: &str) -> Option<[f64; 6]> {
<[f64; 6]>::try_from(nums(s)).ok()
let mut tokens = s.split_whitespace();
let mut matrix = [0.0_f64; 6];
for value in &mut matrix {
*value = tokens.next()?.parse().ok()?;
if !value.is_finite() {
return None;
}
}
tokens.next().is_none().then_some(matrix)
}
/// A transform as an `ItemTransform` value.
+14
View File
@@ -266,3 +266,17 @@ fn deeply_nested_groups_are_read_and_walked() {
let again = Spread::from_el(&parse_part(&part_xml(&s.to_el())).unwrap());
assert_eq!(again, s);
}
#[test]
fn text_variable_decoration_uses_preference_and_falls_back_to_legacy_root_values() {
let preferred = parse_part(
br#"<TextVariable Name="Last Page Number" VariableType="LastPageNumberType" TextBefore="legacy " TextAfter=" legacy"><PageNumberVariablePreference TextBefore="of " TextAfter=" pages" Scope="SectionScope"/></TextVariable>"#,
)
.unwrap();
let variable = craft_idml::model::TextVariableValues::from_el(&preferred);
assert_eq!((variable.before.as_str(), variable.after.as_str()), ("of ", " pages"));
let legacy = parse_part(br#"<TextVariable Name="Last Page Number" TextBefore="of " TextAfter=" pages"/>"#).unwrap();
let variable = craft_idml::model::TextVariableValues::from_el(&legacy);
assert_eq!((variable.before.as_str(), variable.after.as_str()), ("of ", " pages"));
}
+2
View File
@@ -25,6 +25,8 @@ fn transforms_and_points() {
assert_eq!(matrix("1 0 0 1 36"), None);
assert_eq!(matrix("1 0 0 1 36 72 9"), None);
assert_eq!(matrix("1 0 0 1 NaN 0"), None);
assert_eq!(matrix("0 1 x -1 0 0 5"), None, "invalid coefficients cannot shift later values");
assert_eq!(matrix("1e1000 0 0 1 0 0"), None, "non-finite coefficients are rejected");
assert_eq!(matrix_str(&[1.0, 0.0, 0.0, 1.0, 36.0, -72.5]), "1 0 0 1 36 -72.5");
assert_eq!(point("3 4"), Some((3.0, 4.0)));
assert_eq!(point("3 4 5"), Some((3.0, 4.0)));