aboutsummaryrefslogtreecommitdiffstats
path: root/src/epub.rs
diff options
context:
space:
mode:
authorJames Campos <james.r.campos@gmail.com>2020-09-03 21:24:27 -0700
committerJames Campos <james.r.campos@gmail.com>2020-09-03 21:24:27 -0700
commit7b7b6dd040dbc471c42221643c4b3339ea75910d (patch)
tree66224a7835cd3b2b8aa8d7f05888b7c63f5ceebe /src/epub.rs
parentba363bfaad9ed2166f4f0bd4114b58cea0113c42 (diff)
downloadbk-7b7b6dd040dbc471c42221643c4b3339ea75910d.tar.gz
misc fixes, img placeholder
Diffstat (limited to 'src/epub.rs')
-rw-r--r--src/epub.rs31
1 files changed, 18 insertions, 13 deletions
diff --git a/src/epub.rs b/src/epub.rs
index aba0568..ab727b0 100644
--- a/src/epub.rs
+++ b/src/epub.rs
@@ -17,9 +17,10 @@ pub struct Chapter {
pub struct Epub {
container: zip::ZipArchive<File>,
+ rootdir: String,
pub chapters: Vec<Chapter>,
- pub meta: String,
pub links: HashMap<String, (usize, usize)>,
+ pub meta: String,
}
impl Epub {
@@ -27,9 +28,10 @@ impl Epub {
let file = File::open(path)?;
let mut epub = Epub {
container: zip::ZipArchive::new(file)?,
+ rootdir: String::new(),
chapters: Vec::new(),
- meta: String::new(),
links: HashMap::new(),
+ meta: String::new(),
};
let chapters = epub.get_spine()?;
if !meta {
@@ -48,7 +50,7 @@ impl Epub {
}
fn get_chapters(&mut self, spine: Vec<(String, String)>) {
for (title, path) in spine {
- let xml = self.get_text(&path);
+ let xml = self.get_text(&format!("{}{}", self.rootdir, path));
// https://github.com/RazrFalcon/roxmltree/issues/12
// UnknownEntityReference for HTML entities
let doc = Document::parse(&xml).unwrap();
@@ -64,9 +66,7 @@ impl Epub {
frag: Vec::new(),
};
render(body, &mut c);
- if c.text.is_empty() {
- continue;
- }
+ self.links.insert(path.to_string(), (self.chapters.len(), 0));
for (id, pos) in c.frag.drain(..) {
let name = path.rsplit('/').next().unwrap();
let url = format!("{}#{}", name, id);
@@ -88,10 +88,10 @@ impl Epub {
let doc = Document::parse(&xml)?;
// zip expects unix path even on windows
- let rootdir = match path.rfind('/') {
+ self.rootdir = match path.rfind('/') {
Some(n) => &path[..=n],
None => "",
- };
+ }.to_string();
let mut manifest = HashMap::new();
let mut nav = HashMap::new();
let mut children = doc.root_element().children().filter(Node::is_element);
@@ -120,13 +120,13 @@ impl Epub {
.unwrap()
.attribute("href")
.unwrap();
- let xml = self.get_text(&format!("{}{}", rootdir, path));
+ let xml = self.get_text(&format!("{}{}", self.rootdir, path));
let doc = Document::parse(&xml)?;
epub3(doc, &mut nav);
} else {
let id = spine_node.attribute("toc").unwrap_or("ncx");
let path = manifest.get(id).unwrap();
- let xml = self.get_text(&format!("{}{}", rootdir, path));
+ let xml = self.get_text(&format!("{}{}", self.rootdir, path));
let doc = Document::parse(&xml)?;
epub2(doc, &mut nav);
}
@@ -138,8 +138,7 @@ impl Epub {
let id = n.attribute("idref").unwrap();
let path = manifest.remove(id).unwrap();
let label = nav.remove(path).unwrap_or_else(|| i.to_string());
- let path = format!("{}{}", rootdir, path);
- (label, path)
+ (label, path.to_string())
})
.collect())
}
@@ -169,6 +168,7 @@ fn render(n: Node, c: &mut Chapter) {
match n.tag_name().name() {
"br" => c.text.push('\n'),
"hr" => c.text.push_str("\n* * *\n"),
+ "img" => c.text.push_str("\n[IMG]\n"),
"a" => {
if let Some(url) = n.attribute("href") {
let start = c.text.len();
@@ -220,6 +220,9 @@ fn epub2(doc: Document, nav: &mut HashMap<String, String>) {
.unwrap()
.attribute("src")
.unwrap()
+ .split('#')
+ .next()
+ .unwrap()
.to_string();
let text = n
.descendants()
@@ -235,10 +238,12 @@ fn epub3(doc: Document, nav: &mut HashMap<String, String>) {
doc.descendants()
.find(|n| n.has_tag_name("nav"))
.unwrap()
+ .children()
+ .find(|n| n.has_tag_name("ol"))
+ .unwrap()
.descendants()
.filter(|n| n.has_tag_name("a"))
.for_each(|n| {
- // TODO see if we can work w/o nav
let path = n
.attribute("href")
.unwrap()