Skip to content

WIP on ePub #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/book/mdbook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::process::Command;

use {BookConfig, BookItem, theme, parse, utils};
use book::BookItems;
use renderer::{Renderer, HtmlHandlebars};
use renderer::{Renderer, HtmlHandlebars, Pandoc};


pub struct MDBook {
Expand Down Expand Up @@ -38,7 +38,7 @@ impl MDBook {
.set_src(&root.join("src"))
.set_dest(&root.join("book"))
.to_owned(),
renderer: Box::new(HtmlHandlebars::new()),
renderer: Box::new(Pandoc::new()),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just temporary to make local testing easier, but curious how we see this playing out long term. Should the mdbook command line support a new argument? Default to using all the available renderers?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the long term I guess it would be nice if the user could choose a couple of formats in his book.json and on build all formats would be exported. This needs a little bit of thinking to come up with a good design:

  • How to handle the automatic switching of renderers
  • Where to export, currently the html version is exported in book dir but where would pdf, epub, ... go?

}
}

Expand Down
4 changes: 3 additions & 1 deletion src/renderer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
pub use self::renderer::Renderer;
pub use self::html_handlebars::HtmlHandlebars;
pub use self::pandoc::Pandoc;

pub mod renderer;
mod html_handlebars;
mod pandoc;
mod html_handlebars;
42 changes: 42 additions & 0 deletions src/renderer/pandoc/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use renderer::Renderer;
use book::MDBook;
use book::bookitem::BookItem;

use std::error::Error;
use std::process::Command;

pub struct Pandoc;

impl Pandoc {
pub fn new() -> Pandoc {
Pandoc
}
}

impl Renderer for Pandoc {
fn render(&self, book: &MDBook) -> Result<(), Box<Error>> {
let mut paths = vec!();

for item in book.iter() {
match *item {
BookItem::Chapter(_, ref ch) => {
paths.push(book.get_src().join(&ch.path).into_os_string());
},
_ => println!("FIXME: don't understand this kind of BookItem")
}
}

let output = Command::new("pandoc")
.arg("-S")
.arg("-osample.epub")
.args(&paths)
.output();

match output {
Ok(_) => Ok(()),
Err(e) => Err(Box::new(e))
}
// FIXME: why doesn't this work
// output.map(|_| ()).map_err(|e| Box::new(e))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why the output of match and map/map_err here are different.

In the map/map_err version, the compiler complains:

 expected `core::result::Result<(), Box<std::error::Error + 'static>>`,
    found `core::result::Result<(), Box<std::io::error::Error>>`

But it seems to me like both the types and the lifetimes should be the same in both?

(Update: ok, I bet it's because map_err takes a FnOnce. So in this case, is the match version idiomatic rust?(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to be afraid to use the match statement, it is not considered "a last resort bazooka" that should be avoided when possible. Generally there are multiple ways to handle a certain pattern, in this case the match works. You could also have written:

if let Err(e) = output {
    return Err(Box::new(e))
}

Ok(())

Maybe there are other solutions, but it is generally a matter of personal preference :)

}
}