Use shared IDML index parser

This commit is contained in:
Dylan M. Taylor committed 2026-11-13 09:33:26 -05:00
1 parent 6cea56ce01
commit 4fbe39af99
4 files changed
+42 -79

No files matched your search

Generated
+23 -23
View File
@@ -1242,20 +1242,20 @@ dependencies = [
[[package]]
name = "craft-idml"
version = "0.1.0"
source = "git+https://github.com/storytold/craft-libs?rev=7408ef8cc#7408ef8cc6e8ee6a9d4d87cbe3521cb0fd3b13a2"
source = "git+https://github.com/storytold/craft-libs?rev=eed3c28cf016723d004d6f2c79c61424c15d4558#eed3c28cf016723d004d6f2c79c61424c15d4558"
dependencies = [
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=7408ef8cc)",
"craft-zip 0.1.0 (git+https://github.com/storytold/craft-libs?rev=7408ef8cc)",
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=eed3c28cf016723d004d6f2c79c61424c15d4558)",
"craft-zip 0.1.0 (git+https://github.com/storytold/craft-libs?rev=eed3c28cf016723d004d6f2c79c61424c15d4558)",
"thiserror 2.0.21",
]
[[package]]
name = "craft-idml"
version = "0.1.0"
source = "git+https://github.com/storytold/craft-libs?rev=eed3c28cf016723d004d6f2c79c61424c15d4558#eed3c28cf016723d004d6f2c79c61424c15d4558"
source = "git+https://github.com/storytold/craft-libs?rev=ff0cbc3a1#ff0cbc3a137fac332b29a50fc1f5b954143ccc9c"
dependencies = [
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=eed3c28cf016723d004d6f2c79c61424c15d4558)",
"craft-zip 0.1.0 (git+https://github.com/storytold/craft-libs?rev=eed3c28cf016723d004d6f2c79c61424c15d4558)",
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=ff0cbc3a1)",
"craft-zip 0.1.0 (git+https://github.com/storytold/craft-libs?rev=ff0cbc3a1)",
"thiserror 2.0.21",
]
@@ -1653,15 +1653,6 @@ dependencies = [
"thiserror 2.0.21",
]
[[package]]
name = "craft-xml"
version = "0.1.0"
source = "git+https://github.com/storytold/craft-libs?rev=7408ef8cc#7408ef8cc6e8ee6a9d4d87cbe3521cb0fd3b13a2"
dependencies = [
"quick-xml 0.41.0",
"thiserror 2.0.21",
]
[[package]]
name = "craft-xml"
version = "0.1.0"
@@ -1718,13 +1709,12 @@ dependencies = [
]
[[package]]
name = "craft-zip"
name = "craft-xml"
version = "0.1.0"
source = "git+https://github.com/storytold/craft-libs?rev=7408ef8cc#7408ef8cc6e8ee6a9d4d87cbe3521cb0fd3b13a2"
source = "git+https://github.com/storytold/craft-libs?rev=ff0cbc3a1#ff0cbc3a137fac332b29a50fc1f5b954143ccc9c"
dependencies = [
"flate2",
"quick-xml 0.41.0",
"thiserror 2.0.21",
"zip 9.1.1",
]
[[package]]
@@ -1777,6 +1767,16 @@ dependencies = [
"zip 9.1.1",
]
[[package]]
name = "craft-zip"
version = "0.1.0"
source = "git+https://github.com/storytold/craft-libs?rev=ff0cbc3a1#ff0cbc3a137fac332b29a50fc1f5b954143ccc9c"
dependencies = [
"flate2",
"thiserror 2.0.21",
"zip 9.1.1",
]
[[package]]
name = "crc32fast"
version = "1.5.3"
@@ -2021,8 +2021,8 @@ dependencies = [
"craft-prepress",
"craft-print",
"craft-svg 0.1.0 (git+https://github.com/storytold/craft-libs?rev=cc23ffd4d26f3074808e2187d332564817624f8f)",
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=7408ef8cc)",
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=f23b0f33f0d00b157476533a43cbbcfd901aa1f1)",
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=ff0cbc3a1)",
"designcraft-color",
"designcraft-compose",
"designcraft-doc",
@@ -2103,9 +2103,9 @@ name = "designcraft-idml"
version = "0.20.1"
dependencies = [
"craft-file-formats",
"craft-idml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=7408ef8cc)",
"craft-idml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=ff0cbc3a1)",
"craft-svg 0.1.0 (git+https://github.com/storytold/craft-libs?rev=cc23ffd4d26f3074808e2187d332564817624f8f)",
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=7408ef8cc)",
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=ff0cbc3a1)",
"designcraft-color",
"designcraft-compose",
"designcraft-doc",
@@ -2222,7 +2222,7 @@ version = "0.20.1"
dependencies = [
"craft-docx",
"craft-file-formats",
"craft-idml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=7408ef8cc)",
"craft-idml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=ff0cbc3a1)",
"craft-rtf",
"craft-wordmodel",
"craft-xlsx",
+2 -2
View File
@@ -16,10 +16,10 @@ craft-pdf = { git = "https://github.com/storytold/craft-libs", rev = "4052591363
craft-designcraft-format = { git = "https://github.com/storytold/craft-libs", rev = "93d0998383aa150fa50a2ffbf49ef37786e37eca", version = "=0.1.0" }
craft-eps = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435adb3c81ad6057faf36365fbba736cf", version = "=0.1.0" }
craft-epub = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435adb3c81ad6057faf36365fbba736cf", version = "=0.1.0" }
craft-idml = { git = "https://github.com/storytold/craft-libs", rev = "7408ef8cc", version = "=0.1.0" }
craft-idml = { git = "https://github.com/storytold/craft-libs", rev = "ff0cbc3a1", version = "=0.1.0" }
craft-indd = { git = "https://github.com/storytold/craft-libs", rev = "47bf5650b0d503b97bfb5e841746c4957897d11f", version = "=0.1.0" }
craft-svg = { git = "https://github.com/storytold/craft-libs", rev = "cc23ffd4d26f3074808e2187d332564817624f8f", version = "=0.1.0", features = ["tree-render", "tree-text"] }
craft-xml = { git = "https://github.com/storytold/craft-libs", rev = "7408ef8cc", version = "=0.1.0" }
craft-xml = { git = "https://github.com/storytold/craft-libs", rev = "ff0cbc3a1", version = "=0.1.0" }
craft-xml-dtd = { package = "craft-xml", git = "https://github.com/storytold/craft-libs", rev = "f23b0f33f0d00b157476533a43cbbcfd901aa1f1", version = "=0.1.0" }
craft-rtf = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435adb3c81ad6057faf36365fbba736cf", version = "=0.1.0" }
craft-xlsx = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435adb3c81ad6057faf36365fbba736cf", version = "=0.1.0" }
+17 -3
View File
@@ -33,7 +33,6 @@ mod table;
mod text_attrs;
mod values;
use document::IndexTopic;
use frame::margins_of_el;
use package::Package;
#[cfg(test)]
@@ -233,7 +232,7 @@ struct Importer<'r> {
xref_format_names: HashMap<String, String>,
xref_formats: Vec<designcraft_doc::XrefFormat>,
/// Index topic Self → topic path and per-level sort keys; topic cross-references.
index_topics: HashMap<String, IndexTopic>,
index_topics: HashMap<String, craft_idml::model::IndexTopicPath>,
index_xrefs: Vec<designcraft_doc::IndexRef>,
/// The file's text variables (`None`: it defines none) and their Self → index.
text_vars: Option<Vec<designcraft_doc::vars::TextVariable>>,
@@ -516,7 +515,22 @@ impl<'r> Importer<'r> {
}
self.read_hyperlinks(top);
if let Some(ix) = top_els_of(top, TopKind::Index).next() {
self.index_topics_of(&ix, &IndexTopic::default());
let index = craft_idml::model::IndexDocument::from_el(&crate::xml::to_craft(&ix));
self.index_topics = index.topics;
for reference in index.cross_references {
let target = reference
.referenced_topic
.as_deref()
.and_then(|id| self.index_topics.get(id))
.map(|topic| topic.path.join(": "))
.unwrap_or_default();
use designcraft_doc::index::IndexRange as R;
let range = match reference.reference_type.as_deref() {
Some("SeeAlso") | Some("SeeAlsoHerein") => R::SeeAlso(target),
_ => R::See(target),
};
self.index_xrefs.push(designcraft_doc::IndexRef { topics: reference.from.path, sort: reference.from.sort, range });
}
}
for e in top_els_of(top, TopKind::TextVariable) {
self.text_variable(&e);
-51
View File
@@ -1,27 +1,6 @@
use super::values::tint;
use super::{BaselineGrid, El, GridRelative, Importer, PARA_BUILTINS, TopKind, TopLevelNode, names};
/// IDML stores a sort key on each topic, rather than on its page references.
#[derive(Clone, Default)]
pub(super) struct IndexTopic {
pub(super) path: Vec<String>,
pub(super) sort: Vec<String>,
}
impl IndexTopic {
fn child(&self, topic: &El) -> Self {
let mut path = self.path.clone();
path.push(topic.get("Name").unwrap_or("").to_string());
let mut sort = self.sort.clone();
if let Some(key) = topic.get("SortOrder").filter(|key| !key.is_empty()) {
// Keep empty positions before a child's key, but omit trailing defaults.
sort.resize(self.path.len(), String::new());
sort.push(key.to_string());
}
Self { path, sort }
}
}
impl<'r> Importer<'r> {
pub(super) fn doc_prefs(&mut self, e: &El) {
let s = &mut self.settings;
@@ -96,36 +75,6 @@ impl<'r> Importer<'r> {
}
}
/// Index topics (recursively); at the root, their See / See also cross-references too.
pub(super) fn index_topics_of(&mut self, e: &El, prefix: &IndexTopic) {
for t in e.find_all("Topic") {
let topic = prefix.child(t);
if let Some(me) = t.get("Self") {
self.index_topics.insert(me.to_string(), topic.clone());
}
self.index_topics_of(t, &topic);
}
if !prefix.path.is_empty() {
return;
}
let mut stack = vec![(e, IndexTopic::default())];
while let Some((el, prefix)) = stack.pop() {
for t in el.find_all("Topic") {
let topic = prefix.child(t);
for x in t.find_all("CrossReference") {
let target = x.get("ReferencedTopic").and_then(|r| self.index_topics.get(r)).map(|t| t.path.join(": ")).unwrap_or_default();
use designcraft_doc::index::IndexRange as R;
let range = match x.get("CrossReferenceType") {
Some("SeeAlso") | Some("SeeAlsoHerein") => R::SeeAlso(target),
_ => R::See(target),
};
self.index_xrefs.push(designcraft_doc::IndexRef { topics: topic.path.clone(), sort: topic.sort.clone(), range });
}
stack.push((t, topic));
}
}
}
/// `CrossReferenceFormat`: building blocks back to a format definition.
/// A `TextVariable` definition. Types that aren't computed here keep their settings and show
/// the result of their first instance.