Model IDML story marker nodes

This commit is contained in:
Dylan M. Taylor committed 2026-11-13 09:05:19 -05:00
1 parent 986ad52889
commit 622950ccce
2 files changed
+45 -2

No files matched your search

+2 -2
View File
@@ -28,8 +28,8 @@ pub use spread::{
spreads,
};
pub use story::{
Ace, CONTAINERS, Cell, CellOptions, Container, ContentPart, Range, Story, StoryPreference, Table, TableChild, TableColumn, TableLayout, TableRow,
TextNode, stories,
Ace, CONTAINERS, Cell, CellOptions, Container, ContentPart, PageReference, Range, Story, StoryAnchor, StoryPreference, Table, TableChild,
TableColumn, TableLayout, TableRow, TextNode, stories,
};
use crate::value::{matrix, nums};
+43
View File
@@ -48,6 +48,9 @@ pub enum TextNode {
/// XML element, a cross-reference's source, a footnote, a note.
Container(Container),
Table(Table),
Anchor(StoryAnchor),
PageReference(PageReference),
TextVariable(Values),
/// A page item anchored in the text.
Item(PageItem),
/// Anything else (`StoryPreference`, `HyperlinkTextDestination`, `TextVariableInstance`, …),
@@ -55,6 +58,38 @@ pub enum TextNode {
Other(El),
}
#[derive(Clone, Debug, PartialEq)]
pub struct StoryAnchor {
pub name: String,
pub values: Values,
}
impl StoryAnchor {
pub fn self_id(&self) -> Option<&str> {
self.values.self_id()
}
pub fn label(&self) -> Option<&str> {
self.values.name()
}
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct PageReference {
pub values: Values,
}
impl PageReference {
pub fn referenced_topic(&self) -> Option<&str> {
self.values.get("ReferencedTopic")
}
pub fn reference_type(&self) -> Option<&str> {
self.values.get("PageReferenceType")
}
pub fn limit(&self) -> Option<f64> {
self.values.num("PageReferenceLimit")
}
}
/// The elements read as [`TextNode::Container`].
pub const CONTAINERS: [&str; 7] = ["HyperlinkTextSource", "Change", "XMLElement", "CrossReferenceSource", "Footnote", "Note", "EndnoteRange"];
@@ -232,6 +267,11 @@ impl TextNode {
"Content" => TextNode::Content(content_parts(el)),
"Br" => TextNode::Break,
"Table" => TextNode::Table(Table::from_el(el)),
"HyperlinkTextDestination" | "ParagraphDestination" => {
TextNode::Anchor(StoryAnchor { name: el.local().to_string(), values: Values::of(el) })
}
"PageReference" => TextNode::PageReference(PageReference { values: Values::of(el) }),
"TextVariableInstance" => TextNode::TextVariable(Values::of(el)),
n if CONTAINERS.contains(&n) => TextNode::Container(Container { name: n.to_string(), values: Values::of(el), children: nodes(el) }),
_ => PageItem::from_el(el).map_or_else(|| TextNode::Other(tidy(el)), TextNode::Item),
}
@@ -256,6 +296,9 @@ impl TextNode {
TextNode::Break => El::new("Br"),
TextNode::Container(c) => with_children(c.values.element(&c.name), &c.children),
TextNode::Table(t) => t.to_el(),
TextNode::Anchor(a) => a.values.element(&a.name),
TextNode::PageReference(r) => r.values.element("PageReference"),
TextNode::TextVariable(v) => v.element("TextVariableInstance"),
TextNode::Item(i) => i.to_el(),
TextNode::Other(e) => e.clone(),
}