Swap out the old config code for the new toml based config

This commit is contained in:
Mathieu David 2016-02-22 09:28:31 +01:00
parent e4e2f41172
commit d2d58b3581
7 changed files with 117 additions and 220 deletions

View File

@ -97,7 +97,7 @@ fn init(args: &ArgMatches) -> Result<(), Box<Error>> {
// Skip this if `--force` is present
if !args.is_present("force") {
// Print warning
print!("\nCopying the default theme to {:?}", book.get_src());
print!("\nCopying the default theme to {:?}", book.source());
println!("could potentially overwrite files already present in that directory.");
print!("\nAre you sure you want to continue? (y/n) ");
@ -159,8 +159,8 @@ fn watch(args: &ArgMatches) -> Result<(), Box<Error>> {
Ok(mut watcher) => {
// Add the source directory to the watcher
if let Err(e) = watcher.watch(book.get_src()) {
println!("Error while watching {:?}:\n {:?}", book.get_src(), e);
if let Err(e) = watcher.watch(book.source()) {
println!("Error while watching {:?}:\n {:?}", book.source(), e);
::std::process::exit(0);
};

View File

@ -1,118 +0,0 @@
extern crate rustc_serialize;
use self::rustc_serialize::json::Json;
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone)]
pub struct BookConfig {
pub title: String,
pub author: String,
pub description: String,
root: PathBuf,
dest: PathBuf,
src: PathBuf,
pub indent_spaces: i32,
multilingual: bool,
}
impl BookConfig {
pub fn new(root: &Path) -> Self {
BookConfig {
title: String::new(),
author: String::new(),
description: String::new(),
root: root.to_owned(),
dest: PathBuf::from("book"),
src: PathBuf::from("src"),
indent_spaces: 4, // indentation used for SUMMARY.md
multilingual: false,
}
}
pub fn read_config(&mut self, root: &Path) -> &mut Self {
debug!("[fn]: read_config");
// If the file does not exist, return early
let mut config_file = match File::open(root.join("book.json")) {
Ok(f) => f,
Err(_) => {
debug!("[*]: Failed to open {:?}", root.join("book.json"));
return self;
},
};
debug!("[*]: Reading config");
let mut data = String::new();
// Just return if an error occured.
// I would like to propagate the error, but I have to return `&self`
if let Err(_) = config_file.read_to_string(&mut data) {
return self;
}
// Convert to JSON
if let Ok(config) = Json::from_str(&data) {
// Extract data
debug!("[*]: Extracting data from config");
// Title & author
if let Some(a) = config.find_path(&["title"]) {
self.title = a.to_string().replace("\"", "")
}
if let Some(a) = config.find_path(&["author"]) {
self.author = a.to_string().replace("\"", "")
}
if let Some(a) = config.find_path(&["description"]) {
self.description = a.to_string().replace("\"", "")
}
// Destination
if let Some(a) = config.find_path(&["dest"]) {
let dest = PathBuf::from(&a.to_string().replace("\"", ""));
// If path is relative make it absolute from the parent directory of src
match dest.is_relative() {
true => {
let dest = self.get_root().join(&dest).to_owned();
self.set_dest(&dest);
},
false => {
self.set_dest(&dest);
},
}
}
}
self
}
pub fn get_root(&self) -> &Path {
&self.root
}
pub fn set_root(&mut self, root: &Path) -> &mut Self {
self.root = root.to_owned();
self
}
pub fn get_dest(&self) -> &Path {
&self.dest
}
pub fn set_dest(&mut self, dest: &Path) -> &mut Self {
self.dest = dest.to_owned();
self
}
pub fn get_src(&self) -> &Path {
&self.src
}
pub fn set_src(&mut self, src: &Path) -> &mut Self {
self.src = src.to_owned();
self
}
}

View File

@ -6,13 +6,13 @@ use std::io::Write;
use std::io::ErrorKind;
use std::process::Command;
use {BookConfig, BookItem, theme, parse, utils};
use {BookItem, Config, theme, parse};
use book::BookItems;
use renderer::{Renderer, HtmlHandlebars};
pub struct MDBook {
config: BookConfig,
config: Config,
pub content: Vec<BookItem>,
renderer: Box<Renderer>,
}
@ -23,20 +23,18 @@ impl MDBook {
/// - The default source directory is set to `root/src`
/// - The default output directory is set to `root/book`
///
/// They can both be changed by using [`set_src()`](#method.set_src) and [`set_dest()`](#method.set_dest)
/// They can both be changed by using [`set_source()`](#method.set_source) and [`set_dest()`](#method.set_dest)
pub fn new(root: &Path) -> MDBook {
if !root.exists() || !root.is_dir() {
output!("{:?} No directory with that name", root);
}
let mut config = Config::new();
config.set_root(root)
.set_source(Path::new("src/"));
MDBook {
content: vec![],
config: BookConfig::new(root)
.set_src(&root.join("src"))
.set_dest(&root.join("book"))
.to_owned(),
config: config,
renderer: Box::new(HtmlHandlebars::new()),
}
}
@ -94,19 +92,13 @@ impl MDBook {
debug!("[fn]: init");
if !self.config.get_root().exists() {
fs::create_dir_all(self.config.get_root()).unwrap();
output!("{:?} created", self.config.get_root());
if !self.config.root().exists() {
fs::create_dir_all(self.config.root()).unwrap();
output!("{:?} created", self.config.root());
}
{
let dest = self.config.get_dest();
let src = self.config.get_src();
if !dest.exists() {
debug!("[*]: {:?} does not exist, trying to create directory", dest);
try!(fs::create_dir(&dest));
}
let src = self.config.source();
if !src.exists() {
debug!("[*]: {:?} does not exist, trying to create directory", src);
@ -140,7 +132,7 @@ impl MDBook {
BookItem::Spacer => continue,
BookItem::Chapter(_, ref ch) | BookItem::Affix(ref ch) => {
if ch.path != PathBuf::new() {
let path = self.config.get_src().join(&ch.path);
let path = self.config.source().join(&ch.path);
if !path.exists() {
debug!("[*]: {:?} does not exist, trying to create file", path);
@ -198,8 +190,7 @@ impl MDBook {
try!(self.init());
// Clean output directory
try!(utils::fs::remove_dir_content(&self.config.get_dest()));
// TODO: Clean output directory for all renderers
try!(self.renderer.render(&self));
@ -214,7 +205,7 @@ impl MDBook {
pub fn copy_theme(&self) -> Result<(), Box<Error>> {
debug!("[fn]: copy_theme");
let theme_dir = self.config.get_src().join("theme");
let theme_dir = self.config.source().join("theme");
if !theme_dir.exists() {
debug!("[*]: {:?} does not exist, trying to create directory", theme_dir);
@ -265,8 +256,12 @@ impl MDBook {
/// of the current working directory by using a relative path instead of an absolute path.
pub fn read_config(mut self) -> Self {
let root = self.config.get_root().to_owned();
self.config.read_config(&root);
let root = self.config.root().to_owned();
if let Err(e) = self.config.read_config(&root) {
output!("Error: could not read config\n {:?}", e);
};
self
}
@ -304,7 +299,7 @@ impl MDBook {
BookItem::Chapter(_, ref ch) => {
if ch.path != PathBuf::new() {
let path = self.get_src().join(&ch.path);
let path = self.source().join(&ch.path);
println!("[*]: Testing file: {:?}", path);
@ -328,67 +323,39 @@ impl MDBook {
Ok(())
}
pub fn get_root(&self) -> &Path {
self.config.get_root()
pub fn config(&self) -> &Config {
&self.config
}
pub fn set_dest(mut self, dest: &Path) -> Self {
// Handle absolute and relative paths
match dest.is_absolute() {
true => {
self.config.set_dest(dest);
},
false => {
let dest = self.config.get_root().join(dest).to_owned();
self.config.set_dest(&dest);
},
}
self
}
pub fn get_dest(&self) -> &Path {
self.config.get_dest()
}
pub fn set_src(mut self, src: &Path) -> Self {
pub fn set_source(mut self, src: &Path) -> Self {
// Handle absolute and relative paths
match src.is_absolute() {
true => {
self.config.set_src(src);
self.config.set_source(src);
},
false => {
let src = self.config.get_root().join(src).to_owned();
self.config.set_src(&src);
let src = self.config.root().join(src).to_owned();
self.config.set_source(&src);
},
}
self
}
pub fn get_src(&self) -> &Path {
self.config.get_src()
pub fn source(&self) -> &Path {
self.config.source()
}
pub fn set_title(mut self, title: &str) -> Self {
self.config.title = title.to_owned();
self.config.set_title(title);
self
}
pub fn get_title(&self) -> &str {
&self.config.title
self.config.title()
}
pub fn set_author(mut self, author: &str) -> Self {
self.config.author = author.to_owned();
self
}
pub fn get_author(&self) -> &str {
&self.config.author
}
pub fn set_description(mut self, description: &str) -> Self {
self.config.description = description.to_owned();
@ -402,7 +369,7 @@ impl MDBook {
// Construct book
fn parse_summary(&mut self) -> Result<(), Box<Error>> {
// When append becomes stable, use self.content.append() ...
self.content = try!(parse::construct_bookitems(&self.config.get_src().join("SUMMARY.md")));
self.content = try!(parse::construct_bookitems(&self.config.source().join("SUMMARY.md")));
Ok(())
}
}

View File

@ -1,7 +1,5 @@
pub mod mdbook;
pub mod bookitem;
pub mod bookconfig;
pub use self::bookitem::{BookItem, BookItems};
pub use self::bookconfig::BookConfig;
pub use self::mdbook::MDBook;

View File

@ -169,36 +169,81 @@ impl Config {
Ok(())
}
// Title
pub fn set_title(&mut self, title: &str) -> &mut Self {
self.title = String::from(title);
self
}
pub fn title(&self) -> &str {
&self.title
}
// Description
pub fn set_description(&mut self, description: &str) -> &mut Self {
self.description = String::from(description);
self
}
pub fn description(&self) -> &str {
&self.description
}
// Authors
pub fn add_author(&mut self, author: Author) -> &mut Self {
self.authors.push(author);
self
}
pub fn authors(&self) -> &[Author] {
&self.authors
}
// Root
pub fn set_root(&mut self, root: &Path) -> &mut Self {
self.root = PathBuf::from(root);
self
}
pub fn root(&self) -> &Path {
&self.root
}
// Source
pub fn set_source(&mut self, source: &Path) -> &mut Self {
if source.is_relative() {
self.source = self.root.join(self.source.clone());
} else {
self.source = PathBuf::from(source);
}
self
}
pub fn source(&self) -> &Path {
&self.source
}
pub fn outputs(&self) -> &[Output] {
&self.outputs
unimplemented!();
// &self.outputs
}
pub fn language(&self) -> &Language {
&self.language
unimplemented!();
// &self.language
}
pub fn translations(&self) -> &[Language] {
&self.translations
unimplemented!();
// &self.translations
}
pub fn plugins(&self) -> &[Plugin] {
&self.plugins
unimplemented!();
// &self.plugins
}
}

View File

@ -80,5 +80,5 @@ pub mod utils;
pub use book::MDBook;
pub use book::BookItem;
pub use book::BookConfig;
pub use config::Config;
pub use renderer::Renderer;

View File

@ -27,11 +27,16 @@ impl HtmlHandlebars {
impl Renderer for HtmlHandlebars {
fn render(&self, book: &MDBook) -> Result<(), Box<Error>> {
// Temporary fix while refactoring
// FIXME: When the new renderers are done, use the destination set in the renderer
let dest = book.config().root().join("book/");
debug!("[fn]: render");
let mut handlebars = Handlebars::new();
// Load theme
let theme = theme::Theme::new(book.get_src());
let theme = theme::Theme::new(book.source());
// Register template
debug!("[*]: Register handlebars template");
@ -50,7 +55,7 @@ impl Renderer for HtmlHandlebars {
// Check if dest directory exists
debug!("[*]: Check if destination directory exists");
if let Err(_) = fs::create_dir_all(book.get_dest()) {
if let Err(_) = fs::create_dir_all(dest.clone()) {
return Err(Box::new(io::Error::new(io::ErrorKind::Other,
"Unexpected error when constructing destination path")));
}
@ -63,7 +68,7 @@ impl Renderer for HtmlHandlebars {
BookItem::Chapter(_, ref ch) | BookItem::Affix(ref ch) => {
if ch.path != PathBuf::new() {
let path = book.get_src().join(&ch.path);
let path = book.source().join(&ch.path);
debug!("[*]: Opening file: {:?}", path);
let mut f = try!(File::open(&path));
@ -108,10 +113,10 @@ impl Renderer for HtmlHandlebars {
debug!("[*]: Create file {:?}", &book.get_dest().join(&ch.path).with_extension("html"));
// Write to file
let mut file = try!(utils::fs::create_file(&book.get_dest()
.join(&ch.path)
let mut file = try!(utils::fs::create_file(&dest.clone().join(&ch.path)
.with_extension("html")));
output!("[*] Creating {:?} ✓", &book.get_dest().join(&ch.path).with_extension("html"));
output!("[*] Creating {:?} ✓", dest.join(&ch.path).with_extension("html"));
try!(file.write_all(&rendered.into_bytes()));
@ -119,9 +124,9 @@ impl Renderer for HtmlHandlebars {
if index {
debug!("[*]: index.html");
let mut index_file = try!(File::create(book.get_dest().join("index.html")));
let mut index_file = try!(File::create(dest.join("index.html")));
let mut content = String::new();
let _source = try!(File::open(book.get_dest().join(&ch.path.with_extension("html"))))
let _source = try!(File::open(dest.join(&ch.path.with_extension("html"))))
.read_to_string(&mut content);
// This could cause a problem when someone displays code containing <base href=...>
@ -134,7 +139,7 @@ impl Renderer for HtmlHandlebars {
try!(index_file.write_all(content.as_bytes()));
output!("[*] Creating index.html from {:?} ✓",
book.get_dest().join(&ch.path.with_extension("html")));
dest.join(&ch.path.with_extension("html")));
index = false;
}
}
@ -160,7 +165,7 @@ impl Renderer for HtmlHandlebars {
// Rendere the handlebars template with the data
debug!("[*]: Render template");
let rendered = try!(handlebars.render("index", &data));
let mut file = try!(utils::fs::create_file(&book.get_dest().join("print").with_extension("html")));
let mut file = try!(utils::fs::create_file(&dest.join("print").with_extension("html")));
try!(file.write_all(&rendered.into_bytes()));
output!("[*] Creating print.html ✓");
@ -168,7 +173,7 @@ impl Renderer for HtmlHandlebars {
debug!("[*] Copy static files");
// JavaScript
let mut js_file = if let Ok(f) = File::create(book.get_dest().join("book.js")) {
let mut js_file = if let Ok(f) = File::create(dest.join("book.js")) {
f
} else {
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create book.js")));
@ -176,7 +181,7 @@ impl Renderer for HtmlHandlebars {
try!(js_file.write_all(&theme.js));
// Css
let mut css_file = if let Ok(f) = File::create(book.get_dest().join("book.css")) {
let mut css_file = if let Ok(f) = File::create(dest.join("book.css")) {
f
} else {
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create book.css")));
@ -190,7 +195,7 @@ impl Renderer for HtmlHandlebars {
try!(favicon_file.write_all(&theme.favicon));
// JQuery local fallback
let mut jquery = if let Ok(f) = File::create(book.get_dest().join("jquery.js")) {
let mut jquery = if let Ok(f) = File::create(dest.join("jquery.js")) {
f
} else {
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create jquery.js")));
@ -198,21 +203,21 @@ impl Renderer for HtmlHandlebars {
try!(jquery.write_all(&theme.jquery));
// syntax highlighting
let mut highlight_css = if let Ok(f) = File::create(book.get_dest().join("highlight.css")) {
let mut highlight_css = if let Ok(f) = File::create(dest.join("highlight.css")) {
f
} else {
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create highlight.css")));
};
try!(highlight_css.write_all(&theme.highlight_css));
let mut tomorrow_night_css = if let Ok(f) = File::create(book.get_dest().join("tomorrow-night.css")) {
let mut tomorrow_night_css = if let Ok(f) = File::create(dest.join("tomorrow-night.css")) {
f
} else {
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create tomorrow-night.css")));
};
try!(tomorrow_night_css.write_all(&theme.tomorrow_night_css));
let mut highlight_js = if let Ok(f) = File::create(book.get_dest().join("highlight.js")) {
let mut highlight_js = if let Ok(f) = File::create(dest.join("highlight.js")) {
f
} else {
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create highlight.js")));
@ -220,14 +225,14 @@ impl Renderer for HtmlHandlebars {
try!(highlight_js.write_all(&theme.highlight_js));
// Font Awesome local fallback
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&dest
.join("_FontAwesome/css/font-awesome.css")) {
f
} else {
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create font-awesome.css")));
};
try!(font_awesome.write_all(theme::FONT_AWESOME));
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&dest
.join("_FontAwesome/fonts/fontawesome-we\
bfont.eot")) {
f
@ -235,7 +240,7 @@ impl Renderer for HtmlHandlebars {
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.eot")));
};
try!(font_awesome.write_all(theme::FONT_AWESOME_EOT));
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&dest
.join("_FontAwesome/fonts/fontawesome-we\
bfont.svg")) {
f
@ -243,7 +248,7 @@ impl Renderer for HtmlHandlebars {
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.svg")));
};
try!(font_awesome.write_all(theme::FONT_AWESOME_SVG));
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&dest
.join("_FontAwesome/fonts/fontawesome-we\
bfont.ttf")) {
f
@ -251,7 +256,7 @@ impl Renderer for HtmlHandlebars {
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.ttf")));
};
try!(font_awesome.write_all(theme::FONT_AWESOME_TTF));
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&dest
.join("_FontAwesome/fonts/fontawesome-we\
bfont.woff")) {
f
@ -259,7 +264,7 @@ impl Renderer for HtmlHandlebars {
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.woff")));
};
try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF));
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&dest
.join("_FontAwesome/fonts/fontawesome-we\
bfont.woff2")) {
f
@ -267,7 +272,7 @@ impl Renderer for HtmlHandlebars {
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.woff2")));
};
try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF2));
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&dest
.join("_FontAwesome/fonts/FontAwesome.\
ttf")) {
f
@ -277,7 +282,7 @@ impl Renderer for HtmlHandlebars {
try!(font_awesome.write_all(theme::FONT_AWESOME_TTF));
// Copy all remaining files
try!(utils::fs::copy_files_except_ext(book.get_src(), book.get_dest(), true, &["md"]));
try!(utils::fs::copy_files_except_ext(book.source(), &dest, true, &["md"]));
Ok(())
}