diff --git a/crates/idml/src/model/mod.rs b/crates/idml/src/model/mod.rs index dc599d96c..54cf11e44 100644 --- a/crates/idml/src/model/mod.rs +++ b/crates/idml/src/model/mod.rs @@ -45,9 +45,9 @@ pub use spread::{ TextWrapPreference, spreads, }; pub use story::{ - Ace, AnchoredObjectValues, CONTAINERS, Cell, CellOptions, Container, ContainerKind, ContentPart, IndexCrossReferenceValues, IndexValues, - PageReference, Range, SavedCrossReference, SavedCrossReferencePart, Story, StoryAnchor, StoryPreference, Table, TableChild, TableColumn, - TableLayout, TableRow, TextNode, TrackedChangeKind, stories, + Ace, AnchoredObjectSetting, AnchoredObjectValues, CONTAINERS, Cell, CellOptions, Container, ContainerKind, ContentPart, + IndexCrossReferenceValues, IndexValues, PageReference, Range, SavedCrossReference, SavedCrossReferencePart, Story, StoryAnchor, StoryPreference, + Table, TableChild, TableColumn, TableLayout, TableRow, TextNode, TrackedChangeKind, stories, }; use crate::value::{matrix, nums}; diff --git a/crates/idml/src/model/story.rs b/crates/idml/src/model/story.rs index a1d1384d8..a5e1b23ff 100644 --- a/crates/idml/src/model/story.rs +++ b/crates/idml/src/model/story.rs @@ -22,6 +22,69 @@ pub struct AnchoredObjectValues { pub y_offset: f64, } +/// An IDML `AnchoredObjectSetting` element. +#[derive(Clone, Debug, PartialEq)] +pub struct AnchoredObjectSetting { + attributes: Vec<(String, String)>, +} + +impl AnchoredObjectSetting { + pub fn inline_position(y_offset: f64) -> Self { + Self { attributes: vec![("AnchoredPosition".into(), "InlinePosition".into()), ("AnchorYoffset".into(), crate::value::num(y_offset))] } + } + + pub fn above_line(horizontal_alignment: &str, space_above: f64, y_offset: f64) -> Self { + Self { + attributes: vec![ + ("AnchoredPosition".into(), "AboveLine".into()), + ("HorizontalAlignment".into(), horizontal_alignment.into()), + ("AnchorSpaceAbove".into(), crate::value::num(space_above)), + ("AnchorYoffset".into(), crate::value::num(y_offset)), + ], + } + } + + #[allow(clippy::too_many_arguments)] + pub fn anchored( + anchor_point: &str, + horizontal_reference: &str, + vertical_reference: &str, + horizontal_alignment: &str, + vertical_alignment: &str, + x_offset: f64, + y_offset: f64, + pin_position: bool, + spine_relative: bool, + ) -> Self { + Self { + attributes: vec![ + ("AnchoredPosition".into(), "Anchored".into()), + ("AnchorPoint".into(), anchor_point.into()), + ("HorizontalReferencePoint".into(), horizontal_reference.into()), + ("VerticalReferencePoint".into(), vertical_reference.into()), + ("HorizontalAlignment".into(), horizontal_alignment.into()), + ("VerticalAlignment".into(), vertical_alignment.into()), + ("AnchorXoffset".into(), crate::value::num(x_offset)), + ("AnchorYoffset".into(), crate::value::num(y_offset)), + ("PinPosition".into(), bool_string(pin_position)), + ("SpineRelative".into(), bool_string(spine_relative)), + ], + } + } + + pub fn to_el(&self) -> El { + let mut element = El::new("AnchoredObjectSetting"); + for (key, value) in &self.attributes { + element.set_attr(key, value); + } + element + } +} + +fn bool_string(value: bool) -> String { + if value { "true" } else { "false" }.into() +} + impl AnchoredObjectValues { /// Resolves attributes item-first from `AnchoredObjectSetting` children. pub fn from_elements(elements: &[&El]) -> Self {