Some clean-up + initial implementation of '--theme' flag for init. Still needs some work
This commit is contained in:
parent
909953d877
commit
835c61c7f3
|
@ -6,7 +6,7 @@ description = "create books from markdown files (like Gitbook)"
|
|||
documentation = "http://azerupi.github.io/mdBook/index.html"
|
||||
repository = "https://github.com/azerupi/mdBook"
|
||||
keywords = ["book", "gitbook", "rustbook", "markdown"]
|
||||
license = "MPL"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
exclude = [
|
||||
"book-example/*",
|
||||
|
|
|
@ -24,9 +24,9 @@ fn main() {
|
|||
.after_help("For more information about a specific command, try `mdbook <command> --help`")
|
||||
.subcommand(SubCommand::with_name("init")
|
||||
.about("Create boilerplate structure and files in the directory")
|
||||
// the {n} denotes a newline which will properly aligned in all help
|
||||
// messages
|
||||
.arg_from_usage("[dir] 'A directory for your book{n}(Defaults to Current Directory when ommitted)'"))
|
||||
// the {n} denotes a newline which will properly aligned in all help messages
|
||||
.arg_from_usage("[dir] 'A directory for your book{n}(Defaults to Current Directory when ommitted)'")
|
||||
.arg_from_usage("--theme 'Copies the default theme into your source folder'"))
|
||||
.subcommand(SubCommand::with_name("build")
|
||||
.about("Build the book from the markdown files")
|
||||
.arg_from_usage("[dir] 'A directory for your book{n}(Defaults to Current Directory when ommitted)'"))
|
||||
|
@ -43,22 +43,47 @@ fn main() {
|
|||
};
|
||||
|
||||
if let Err(e) = res {
|
||||
writeln!(&mut io::stderr(), "Error: {}", e).ok();
|
||||
writeln!(&mut io::stderr(), "An error occured:\n{}", e).ok();
|
||||
}
|
||||
}
|
||||
|
||||
fn init(args: &ArgMatches) -> Result<(), Box<Error>> {
|
||||
|
||||
let book_dir = get_book_dir(args);
|
||||
let book = MDBook::new(&book_dir);
|
||||
|
||||
book.init()
|
||||
// Call the function that does the initialization
|
||||
try!(book.init());
|
||||
|
||||
// If flag `--theme` is present, copy theme to src
|
||||
if args.is_present("theme") {
|
||||
|
||||
// Print warning
|
||||
print!("\nCopying the default theme to {:?}", book.get_src());
|
||||
println!("could potentially overwrite files already present in that directory.");
|
||||
print!("\nAre you sure you want to continue? (y/n) ");
|
||||
|
||||
// Read answer from user
|
||||
|
||||
// Joke while I don't read user response, has to be deleted when merged into master !!!
|
||||
println!("\n\nI am doing it anyways... (at the moment)");
|
||||
|
||||
// Call the function that copies the theme
|
||||
try!(book.copy_theme());
|
||||
|
||||
println!("");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build(args: &ArgMatches) -> Result<(), Box<Error>> {
|
||||
let book_dir = get_book_dir(args);
|
||||
let mut book = MDBook::new(&book_dir).read_config();
|
||||
|
||||
book.build()
|
||||
try!(book.build());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_book_dir(args: &ArgMatches) -> PathBuf {
|
||||
|
|
|
@ -22,7 +22,7 @@ impl BookConfig {
|
|||
author: String::new(),
|
||||
dest: PathBuf::from("book"),
|
||||
src: PathBuf::from("src"),
|
||||
indent_spaces: 4,
|
||||
indent_spaces: 4, // indentation used for SUMMARY.md
|
||||
multilingual: false,
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ impl BookConfig {
|
|||
|
||||
// If path is relative make it absolute from the parent directory of src
|
||||
if dest.is_relative() {
|
||||
let dest = &self.src().parent().unwrap().join(&dest);
|
||||
let dest = &self.get_src().parent().unwrap().join(&dest);
|
||||
self.set_dest(dest);
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ impl BookConfig {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn dest(&self) -> &Path {
|
||||
pub fn get_dest(&self) -> &Path {
|
||||
&self.dest
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ impl BookConfig {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn src(&self) -> &Path {
|
||||
pub fn get_src(&self) -> &Path {
|
||||
&self.src
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ use std::error::Error;
|
|||
use {BookConfig, BookItem};
|
||||
use book::BookItems;
|
||||
use parse;
|
||||
use theme;
|
||||
use renderer::Renderer;
|
||||
use renderer::HtmlHandlebars;
|
||||
|
||||
|
@ -96,8 +97,8 @@ impl MDBook {
|
|||
|
||||
debug!("[fn]: init");
|
||||
|
||||
let dest = self.config.dest();
|
||||
let src = self.config.src();
|
||||
let dest = self.config.get_dest();
|
||||
let src = self.config.get_src();
|
||||
|
||||
// Hacky way to check if the directory exists... Until PathExt moves to stable
|
||||
match metadata(&dest) {
|
||||
|
@ -169,6 +170,45 @@ impl MDBook {
|
|||
}
|
||||
|
||||
|
||||
pub fn copy_theme(&self) -> Result<(), Box<Error>> {
|
||||
debug!("[fn]: copy_theme");
|
||||
|
||||
let theme_dir = self.config.get_src().join("theme");
|
||||
|
||||
// Hacky way to check if the directory exists... Until PathExt moves to stable
|
||||
match metadata(&theme_dir) {
|
||||
Err(_) => {
|
||||
// There is a very high chance that the error is due to the fact that
|
||||
// the directory / file does not exist
|
||||
debug!("[*]: {:?} does not exist, trying to create directory", theme_dir);
|
||||
fs::create_dir(&theme_dir).unwrap();
|
||||
},
|
||||
Ok(_) => { /* If there is no error, the directory / file does exist */ }
|
||||
}
|
||||
|
||||
// index.hbs
|
||||
let mut index = try!(File::create(&theme_dir.join("index.hbs")));
|
||||
try!(index.write_all(theme::INDEX));
|
||||
|
||||
// book.css
|
||||
let mut css = try!(File::create(&theme_dir.join("book.css")));
|
||||
try!(css.write_all(theme::CSS));
|
||||
|
||||
// book.js
|
||||
let mut js = try!(File::create(&theme_dir.join("book.js")));
|
||||
try!(js.write_all(theme::JS));
|
||||
|
||||
// highlight.css
|
||||
let mut highlight_css = try!(File::create(&theme_dir.join("highlight.css")));
|
||||
try!(highlight_css.write_all(theme::HIGHLIGHT_CSS));
|
||||
|
||||
// highlight.js
|
||||
let mut highlight_js = try!(File::create(&theme_dir.join("highlight.js")));
|
||||
try!(highlight_js.write_all(theme::HIGHLIGHT_JS));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses the `book.json` file (if it exists) to extract the configuration parameters.
|
||||
/// The `book.json` file should be in the root directory of the book.
|
||||
/// The root directory is the one specified when creating a new `MDBook`
|
||||
|
@ -220,11 +260,19 @@ impl MDBook {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn get_dest(&self) -> &Path {
|
||||
self.config.get_dest()
|
||||
}
|
||||
|
||||
pub fn set_src(mut self, src: &Path) -> Self {
|
||||
self.config.set_src(&self.root.join(src));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_src(&self) -> &Path {
|
||||
self.config.get_src()
|
||||
}
|
||||
|
||||
pub fn set_title(mut self, title: &str) -> Self {
|
||||
self.config.title = title.to_owned();
|
||||
self
|
||||
|
@ -240,7 +288,7 @@ impl MDBook {
|
|||
fn parse_summary(&mut self) -> Result<(), Box<Error>> {
|
||||
|
||||
// When append becomes stable, use self.content.append() ...
|
||||
let book_items = try!(parse::construct_bookitems(&self.config.src().join("SUMMARY.md")));
|
||||
let book_items = try!(parse::construct_bookitems(&self.config.get_src().join("SUMMARY.md")));
|
||||
|
||||
for item in book_items {
|
||||
self.content.push(item)
|
||||
|
|
|
@ -31,11 +31,11 @@ impl Renderer for HtmlHandlebars {
|
|||
let mut handlebars = Handlebars::new();
|
||||
|
||||
// Load theme
|
||||
let theme = theme::Theme::new(&config.src());
|
||||
let theme = theme::Theme::new(&config.get_src());
|
||||
|
||||
// Register template
|
||||
debug!("[*]: Register handlebars template");
|
||||
try!(handlebars.register_template_string("index", theme.index.to_owned()));
|
||||
try!(handlebars.register_template_string("index", try!(String::from_utf8(theme.index))));
|
||||
|
||||
// Register helpers
|
||||
debug!("[*]: Register handlebars helpers");
|
||||
|
@ -47,7 +47,7 @@ impl Renderer for HtmlHandlebars {
|
|||
|
||||
// Check if dest directory exists
|
||||
debug!("[*]: Check if destination directory exists");
|
||||
match utils::create_path(config.dest()) {
|
||||
match utils::create_path(config.get_dest()) {
|
||||
Err(_) => return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Unexcpected error when constructing destination path"))),
|
||||
_ => {},
|
||||
};
|
||||
|
@ -58,7 +58,7 @@ impl Renderer for HtmlHandlebars {
|
|||
|
||||
if item.path != PathBuf::new() {
|
||||
|
||||
let path = config.src().join(&item.path);
|
||||
let path = config.get_src().join(&item.path);
|
||||
|
||||
debug!("[*]: Opening file: {:?}", path);
|
||||
let mut f = try!(File::open(&path));
|
||||
|
@ -86,10 +86,10 @@ impl Renderer for HtmlHandlebars {
|
|||
debug!("[*]: Render template");
|
||||
let rendered = try!(handlebars.render("index", &data));
|
||||
|
||||
debug!("[*]: Create file {:?}", &config.dest().join(&item.path).with_extension("html"));
|
||||
debug!("[*]: Create file {:?}", &config.get_dest().join(&item.path).with_extension("html"));
|
||||
// Write to file
|
||||
let mut file = try!(utils::create_file(&config.dest().join(&item.path).with_extension("html")));
|
||||
output!("[*] Creating {:?} ✓", &config.dest().join(&item.path).with_extension("html"));
|
||||
let mut file = try!(utils::create_file(&config.get_dest().join(&item.path).with_extension("html")));
|
||||
output!("[*] Creating {:?} ✓", &config.get_dest().join(&item.path).with_extension("html"));
|
||||
|
||||
try!(file.write_all(&rendered.into_bytes()));
|
||||
|
||||
|
@ -97,13 +97,13 @@ impl Renderer for HtmlHandlebars {
|
|||
if index {
|
||||
debug!("[*]: index.html");
|
||||
try!(fs::copy(
|
||||
config.dest().join(&item.path.with_extension("html")),
|
||||
config.dest().join("index.html")
|
||||
config.get_dest().join(&item.path.with_extension("html")),
|
||||
config.get_dest().join("index.html")
|
||||
));
|
||||
|
||||
output!(
|
||||
"[*] Creating index.html from {:?} ✓",
|
||||
config.dest().join(&item.path.with_extension("html"))
|
||||
config.get_dest().join(&item.path.with_extension("html"))
|
||||
);
|
||||
index = false;
|
||||
}
|
||||
|
@ -114,17 +114,17 @@ impl Renderer for HtmlHandlebars {
|
|||
|
||||
debug!("[*] Copy static files");
|
||||
// JavaScript
|
||||
let mut js_file = try!(File::create(config.dest().join("book.js")));
|
||||
let mut js_file = try!(File::create(config.get_dest().join("book.js")));
|
||||
try!(js_file.write_all(&theme.js));
|
||||
|
||||
// Css
|
||||
let mut css_file = try!(File::create(config.dest().join("book.css")));
|
||||
let mut css_file = try!(File::create(config.get_dest().join("book.css")));
|
||||
try!(css_file.write_all(&theme.css));
|
||||
|
||||
// syntax highlighting
|
||||
let mut highlight_css = try!(File::create(config.dest().join("highlight.css")));
|
||||
let mut highlight_css = try!(File::create(config.get_dest().join("highlight.css")));
|
||||
try!(highlight_css.write_all(&theme.highlight_css));
|
||||
let mut highlight_js = try!(File::create(config.dest().join("highlight.js")));
|
||||
let mut highlight_js = try!(File::create(config.get_dest().join("highlight.js")));
|
||||
try!(highlight_js.write_all(&theme.highlight_js));
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -2,14 +2,20 @@ use std::path::Path;
|
|||
use std::fs::{File, metadata};
|
||||
use std::io::Read;
|
||||
|
||||
static INDEX: &'static str = include_str!("index.hbs");
|
||||
static CSS: &'static [u8] = include_bytes!("book.css");
|
||||
static JS: &'static [u8] = include_bytes!("book.js");
|
||||
static HIGHLIGHT_JS: &'static [u8] = include_bytes!("highlight.js");
|
||||
static HIGHLIGHT_CSS: &'static [u8] = include_bytes!("highlight.css");
|
||||
pub static INDEX: &'static [u8] = include_bytes!("index.hbs");
|
||||
pub static CSS: &'static [u8] = include_bytes!("book.css");
|
||||
pub static JS: &'static [u8] = include_bytes!("book.js");
|
||||
pub static HIGHLIGHT_JS: &'static [u8] = include_bytes!("highlight.js");
|
||||
pub static HIGHLIGHT_CSS: &'static [u8] = include_bytes!("highlight.css");
|
||||
|
||||
/// The `Theme` struct should be used instead of the static variables because the `new()` method
|
||||
/// will look if the user has a theme directory in his source folder and use the users theme instead
|
||||
/// of the default.
|
||||
///
|
||||
/// You should exceptionnaly use the static variables only if you need the default theme even if the
|
||||
/// user has specified another theme.
|
||||
pub struct Theme {
|
||||
pub index: String,
|
||||
pub index: Vec<u8>,
|
||||
pub css: Vec<u8>,
|
||||
pub js: Vec<u8>,
|
||||
pub highlight_css: Vec<u8>,
|
||||
|
@ -56,8 +62,8 @@ impl Theme {
|
|||
// index.hbs
|
||||
match File::open(&src.join("index.hbs")) {
|
||||
Ok(mut f) => {
|
||||
theme.index = String::new(); // Reset the value, because read_to_string appends...
|
||||
f.read_to_string(&mut theme.index).unwrap();
|
||||
theme.index.clear(); // Reset the value, because read_to_string appends...
|
||||
f.read_to_end(&mut theme.index).unwrap();
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue