aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Campos <james.r.campos@gmail.com>2020-04-19 11:58:59 -0700
committerJames Campos <james.r.campos@gmail.com>2020-04-19 11:58:59 -0700
commitf504e7984a35da4fbac142e64f00b3a7512f8198 (patch)
tree27d175b89d0e9893a28573bf2dd3ec4d5bb35126
parentbf7a71500a2ef057cb0f0db47ad672df6289c72a (diff)
downloadbk-f504e7984a35da4fbac142e64f00b3a7512f8198.tar.gz
spine
-rw-r--r--src/main.rs53
1 files changed, 30 insertions, 23 deletions
diff --git a/src/main.rs b/src/main.rs
index a20531b..fd09913 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,4 @@
+use std::collections::HashMap;
use std::fs::File;
use std::io::{stdout, Read, Write};
@@ -21,46 +22,52 @@ struct Bk {
}
fn get_toc(container: &mut zip::ZipArchive<File>) -> Vec<String> {
- // container.xml -> <rootfile> -> opf -> <manifest>
- let mut container_xml = String::new();
+ // container.xml -> <rootfile> -> opf -> <manifest> + <spine>
+ let mut xml = String::new();
container
.by_name("META-INF/container.xml")
.unwrap()
- .read_to_string(&mut container_xml)
+ .read_to_string(&mut xml)
.unwrap();
- let opf_doc = roxmltree::Document::parse(&container_xml).unwrap();
- let opf_path = opf_doc
+ let doc = roxmltree::Document::parse(&xml).unwrap();
+ let path = doc
.descendants()
.find(|n| n.has_tag_name("rootfile"))
.unwrap()
.attribute("full-path")
.unwrap();
- let mut opf_xml = String::new();
+ let mut xml = String::new();
container
- .by_name(opf_path)
+ .by_name(path)
.unwrap()
- .read_to_string(&mut opf_xml)
+ .read_to_string(&mut xml)
.unwrap();
-
- let parent_path = std::path::Path::new(&opf_path).parent().unwrap();
- roxmltree::Document::parse(&opf_xml)
- .unwrap()
- .descendants()
+ let doc = roxmltree::Document::parse(&xml).unwrap();
+ let mut manifest = HashMap::new();
+ doc.root_element()
+ .children()
.find(|n| n.has_tag_name("manifest"))
.unwrap()
.children()
- .filter(|n| {
- n.is_element()
- && n.attribute("media-type").unwrap()
- == "application/xhtml+xml"
- })
+ .filter(|n| n.is_element())
+ .for_each(|n| {
+ manifest.insert(
+ n.attribute("id").unwrap(),
+ n.attribute("href").unwrap(),
+ );
+ });
+
+ let path = std::path::Path::new(&path).parent().unwrap();
+ doc.root_element()
+ .children()
+ .find(|n| n.has_tag_name("spine"))
+ .unwrap()
+ .children()
+ .filter(|n| n.is_element())
.map(|n| {
- parent_path
- .join(n.attribute("href").unwrap())
- .to_str()
- .unwrap()
- .to_string()
+ let name = manifest.get(n.attribute("idref").unwrap()).unwrap();
+ path.join(name).to_str().unwrap().to_string()
})
.collect()
}