diff options
author | James Campos <james.r.campos@gmail.com> | 2020-04-19 11:58:59 -0700 |
---|---|---|
committer | James Campos <james.r.campos@gmail.com> | 2020-04-19 11:58:59 -0700 |
commit | f504e7984a35da4fbac142e64f00b3a7512f8198 (patch) | |
tree | 27d175b89d0e9893a28573bf2dd3ec4d5bb35126 /src | |
parent | bf7a71500a2ef057cb0f0db47ad672df6289c72a (diff) | |
download | bk-f504e7984a35da4fbac142e64f00b3a7512f8198.tar.gz |
spine
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 53 |
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() } |