Replace the old book structure with the new one
This commit is contained in:
parent
170bf8b1eb
commit
d3ae2eda56
|
@ -129,7 +129,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.get_source());
|
||||
println!("could potentially overwrite files already present in that directory.");
|
||||
print!("\nAre you sure you want to continue? (y/n) ");
|
||||
|
||||
|
@ -148,7 +148,9 @@ fn init(args: &ArgMatches) -> Result<(), Box<Error>> {
|
|||
}
|
||||
|
||||
// Because of `src/book/mdbook.rs#L37-L39`, `dest` will always start with `root`
|
||||
let is_dest_inside_root = book.get_dest().starts_with(book.get_root());
|
||||
let is_dest_inside_root = book.get_destination()
|
||||
.map(|p| p.starts_with(book.get_root()))
|
||||
.unwrap_or(false);
|
||||
|
||||
if !args.is_present("force") && is_dest_inside_root {
|
||||
println!("\nDo you want a .gitignore to be created? (y/n)");
|
||||
|
@ -168,10 +170,10 @@ fn init(args: &ArgMatches) -> Result<(), Box<Error>> {
|
|||
// Build command implementation
|
||||
fn build(args: &ArgMatches) -> Result<(), Box<Error>> {
|
||||
let book_dir = get_book_dir(args);
|
||||
let book = MDBook::new(&book_dir).read_config();
|
||||
let book = MDBook::new(&book_dir).read_config()?;
|
||||
|
||||
let mut book = match args.value_of("dest-dir") {
|
||||
Some(dest_dir) => book.set_dest(Path::new(dest_dir)),
|
||||
Some(dest_dir) => book.with_destination(Path::new(dest_dir)),
|
||||
None => book,
|
||||
};
|
||||
|
||||
|
@ -181,8 +183,10 @@ fn build(args: &ArgMatches) -> Result<(), Box<Error>> {
|
|||
|
||||
book.build()?;
|
||||
|
||||
if args.is_present("open") {
|
||||
open(book.get_dest().join("index.html"));
|
||||
if let Some(d) = book.get_destination() {
|
||||
if args.is_present("open") {
|
||||
open(d.join("index.html"));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -193,16 +197,18 @@ fn build(args: &ArgMatches) -> Result<(), Box<Error>> {
|
|||
#[cfg(feature = "watch")]
|
||||
fn watch(args: &ArgMatches) -> Result<(), Box<Error>> {
|
||||
let book_dir = get_book_dir(args);
|
||||
let book = MDBook::new(&book_dir).read_config();
|
||||
let book = MDBook::new(&book_dir).read_config()?;
|
||||
|
||||
let mut book = match args.value_of("dest-dir") {
|
||||
Some(dest_dir) => book.set_dest(Path::new(dest_dir)),
|
||||
Some(dest_dir) => book.with_destination(Path::new(dest_dir)),
|
||||
None => book,
|
||||
};
|
||||
|
||||
if args.is_present("open") {
|
||||
book.build()?;
|
||||
open(book.get_dest().join("index.html"));
|
||||
if let Some(d) = book.get_destination() {
|
||||
open(d.join("index.html"));
|
||||
}
|
||||
}
|
||||
|
||||
trigger_on_change(&mut book, |path, book| {
|
||||
|
@ -223,13 +229,18 @@ fn serve(args: &ArgMatches) -> Result<(), Box<Error>> {
|
|||
const RELOAD_COMMAND: &'static str = "reload";
|
||||
|
||||
let book_dir = get_book_dir(args);
|
||||
let book = MDBook::new(&book_dir).read_config();
|
||||
let book = MDBook::new(&book_dir).read_config()?;
|
||||
|
||||
let mut book = match args.value_of("dest-dir") {
|
||||
Some(dest_dir) => book.set_dest(Path::new(dest_dir)),
|
||||
Some(dest_dir) => book.with_destination(Path::new(dest_dir)),
|
||||
None => book,
|
||||
};
|
||||
|
||||
if let None = book.get_destination() {
|
||||
println!("The HTML renderer is not set up, impossible to serve the files.");
|
||||
std::process::exit(2);
|
||||
}
|
||||
|
||||
let port = args.value_of("port").unwrap_or("3000");
|
||||
let ws_port = args.value_of("websocket-port").unwrap_or("3001");
|
||||
let interface = args.value_of("interface").unwrap_or("localhost");
|
||||
|
@ -260,7 +271,7 @@ fn serve(args: &ArgMatches) -> Result<(), Box<Error>> {
|
|||
|
||||
book.build()?;
|
||||
|
||||
let staticfile = staticfile::Static::new(book.get_dest());
|
||||
let staticfile = staticfile::Static::new(book.get_destination().expect("destination is present, checked before"));
|
||||
let iron = iron::Iron::new(staticfile);
|
||||
let _iron = iron.http(&*address).unwrap();
|
||||
|
||||
|
@ -292,7 +303,7 @@ fn serve(args: &ArgMatches) -> Result<(), Box<Error>> {
|
|||
|
||||
fn test(args: &ArgMatches) -> Result<(), Box<Error>> {
|
||||
let book_dir = get_book_dir(args);
|
||||
let mut book = MDBook::new(&book_dir).read_config();
|
||||
let mut book = MDBook::new(&book_dir).read_config()?;
|
||||
|
||||
book.test()?;
|
||||
|
||||
|
@ -341,8 +352,8 @@ fn trigger_on_change<F>(book: &mut MDBook, closure: F) -> ()
|
|||
};
|
||||
|
||||
// Add the source directory to the watcher
|
||||
if let Err(e) = watcher.watch(book.get_src(), Recursive) {
|
||||
println!("Error while watching {:?}:\n {:?}", book.get_src(), e);
|
||||
if let Err(e) = watcher.watch(book.get_source(), Recursive) {
|
||||
println!("Error while watching {:?}:\n {:?}", book.get_source(), e);
|
||||
::std::process::exit(0);
|
||||
};
|
||||
|
||||
|
|
264
src/book/mod.rs
264
src/book/mod.rs
|
@ -4,29 +4,24 @@ pub mod bookconfig;
|
|||
pub mod bookconfig_test;
|
||||
|
||||
pub use self::bookitem::{BookItem, BookItems};
|
||||
pub use self::bookconfig::BookConfig;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::fs::{self, File};
|
||||
use std::error::Error;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use std::io::{Read, Write};
|
||||
use std::io::ErrorKind;
|
||||
use std::process::Command;
|
||||
|
||||
use {theme, parse, utils};
|
||||
use renderer::{Renderer, HtmlHandlebars};
|
||||
|
||||
use config::{BookConfig, HtmlConfig};
|
||||
use config::tomlconfig::TomlConfig;
|
||||
|
||||
|
||||
pub struct MDBook {
|
||||
root: PathBuf,
|
||||
dest: PathBuf,
|
||||
src: PathBuf,
|
||||
theme_path: PathBuf,
|
||||
|
||||
pub title: String,
|
||||
pub author: String,
|
||||
pub description: String,
|
||||
config: BookConfig,
|
||||
|
||||
pub content: Vec<BookItem>,
|
||||
renderer: Box<Renderer>,
|
||||
|
@ -50,7 +45,7 @@ impl MDBook {
|
|||
/// # use mdbook::MDBook;
|
||||
/// # use std::path::Path;
|
||||
/// # fn main() {
|
||||
/// let book = MDBook::new(Path::new("root_dir"));
|
||||
/// let book = MDBook::new("root_dir");
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
|
@ -75,14 +70,7 @@ impl MDBook {
|
|||
}
|
||||
|
||||
MDBook {
|
||||
root: root.to_owned(),
|
||||
dest: root.join("book"),
|
||||
src: root.join("src"),
|
||||
theme_path: root.join("theme"),
|
||||
|
||||
title: String::new(),
|
||||
author: String::new(),
|
||||
description: String::new(),
|
||||
config: BookConfig::new(root),
|
||||
|
||||
content: vec![],
|
||||
renderer: Box::new(HtmlHandlebars::new()),
|
||||
|
@ -149,31 +137,33 @@ impl MDBook {
|
|||
|
||||
debug!("[fn]: init");
|
||||
|
||||
if !self.root.exists() {
|
||||
fs::create_dir_all(&self.root).unwrap();
|
||||
info!("{:?} created", &self.root);
|
||||
if !self.config.get_root().exists() {
|
||||
fs::create_dir_all(&self.config.get_root()).unwrap();
|
||||
info!("{:?} created", &self.config.get_root());
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
if !self.dest.exists() {
|
||||
debug!("[*]: {:?} does not exist, trying to create directory", self.dest);
|
||||
fs::create_dir_all(&self.dest)?;
|
||||
if let Some(htmlconfig) = self.config.get_html_config() {
|
||||
if !htmlconfig.get_destination().exists() {
|
||||
debug!("[*]: {:?} does not exist, trying to create directory", htmlconfig.get_destination());
|
||||
fs::create_dir_all(htmlconfig.get_destination())?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if !self.config.get_source().exists() {
|
||||
debug!("[*]: {:?} does not exist, trying to create directory", self.config.get_source());
|
||||
fs::create_dir_all(self.config.get_source())?;
|
||||
}
|
||||
|
||||
if !self.src.exists() {
|
||||
debug!("[*]: {:?} does not exist, trying to create directory", self.src);
|
||||
fs::create_dir_all(&self.src)?;
|
||||
}
|
||||
|
||||
let summary = self.src.join("SUMMARY.md");
|
||||
let summary = self.config.get_source().join("SUMMARY.md");
|
||||
|
||||
if !summary.exists() {
|
||||
|
||||
// Summary does not exist, create it
|
||||
|
||||
debug!("[*]: {:?} does not exist, trying to create SUMMARY.md", self.src.join("SUMMARY.md"));
|
||||
let mut f = File::create(&self.src.join("SUMMARY.md"))?;
|
||||
debug!("[*]: {:?} does not exist, trying to create SUMMARY.md", &summary);
|
||||
let mut f = File::create(&summary)?;
|
||||
|
||||
debug!("[*]: Writing to SUMMARY.md");
|
||||
|
||||
|
@ -195,7 +185,7 @@ impl MDBook {
|
|||
BookItem::Affix(ref ch) => ch,
|
||||
};
|
||||
if !ch.path.as_os_str().is_empty() {
|
||||
let path = self.src.join(&ch.path);
|
||||
let path = self.config.get_source().join(&ch.path);
|
||||
|
||||
if !path.exists() {
|
||||
if !self.create_missing {
|
||||
|
@ -219,22 +209,23 @@ impl MDBook {
|
|||
pub fn create_gitignore(&self) {
|
||||
let gitignore = self.get_gitignore();
|
||||
|
||||
if !gitignore.exists() {
|
||||
// Gitignore does not exist, create it
|
||||
// If the HTML renderer is not set, return
|
||||
if self.config.get_html_config().is_none() { return; }
|
||||
|
||||
let destination = self.config.get_html_config()
|
||||
.expect("The HtmlConfig does exist, checked just before")
|
||||
.get_destination();
|
||||
|
||||
// Check that the gitignore does not extist and that the destination path begins with the root path
|
||||
// We assume tha if it does begin with the root path it is contained within. This assumption
|
||||
// will not hold true for paths containing double dots to go back up e.g. `root/../destination`
|
||||
if !gitignore.exists() && destination.starts_with(self.config.get_root()) {
|
||||
|
||||
// Because of `src/book/mdbook.rs#L37-L39`,
|
||||
// `dest` will always start with `root`.
|
||||
// If it is not, `strip_prefix` will return an Error.
|
||||
if !self.get_dest().starts_with(&self.root) {
|
||||
return;
|
||||
}
|
||||
|
||||
let relative = self.get_dest()
|
||||
.strip_prefix(&self.root)
|
||||
.expect("Destination is not relative to root.");
|
||||
let relative = relative
|
||||
let relative = destination
|
||||
.strip_prefix(self.config.get_root())
|
||||
.expect("Could not strip the root prefix, path is not relative to root")
|
||||
.to_str()
|
||||
.expect("Path could not be yielded into a string slice.");
|
||||
.expect("Could not convert to &str");
|
||||
|
||||
debug!("[*]: {:?} does not exist, trying to create .gitignore", gitignore);
|
||||
|
||||
|
@ -258,8 +249,10 @@ impl MDBook {
|
|||
self.init()?;
|
||||
|
||||
// Clean output directory
|
||||
utils::fs::remove_dir_content(&self.dest)?;
|
||||
|
||||
if let Some(htmlconfig) = self.config.get_html_config() {
|
||||
utils::fs::remove_dir_content(htmlconfig.get_destination())?;
|
||||
}
|
||||
|
||||
self.renderer.render(&self)?;
|
||||
|
||||
Ok(())
|
||||
|
@ -267,51 +260,56 @@ impl MDBook {
|
|||
|
||||
|
||||
pub fn get_gitignore(&self) -> PathBuf {
|
||||
self.root.join(".gitignore")
|
||||
self.config.get_root().join(".gitignore")
|
||||
}
|
||||
|
||||
pub fn copy_theme(&self) -> Result<(), Box<Error>> {
|
||||
debug!("[fn]: copy_theme");
|
||||
|
||||
let theme_dir = self.src.join("theme");
|
||||
if let Some(themedir) = self.config.get_html_config().and_then(HtmlConfig::get_theme) {
|
||||
|
||||
if !theme_dir.exists() {
|
||||
debug!("[*]: {:?} does not exist, trying to create directory", theme_dir);
|
||||
fs::create_dir(&theme_dir)?;
|
||||
if !themedir.exists() {
|
||||
debug!("[*]: {:?} does not exist, trying to create directory", themedir);
|
||||
fs::create_dir(&themedir)?;
|
||||
}
|
||||
|
||||
// index.hbs
|
||||
let mut index = File::create(&themedir.join("index.hbs"))?;
|
||||
index.write_all(theme::INDEX)?;
|
||||
|
||||
// book.css
|
||||
let mut css = File::create(&themedir.join("book.css"))?;
|
||||
css.write_all(theme::CSS)?;
|
||||
|
||||
// favicon.png
|
||||
let mut favicon = File::create(&themedir.join("favicon.png"))?;
|
||||
favicon.write_all(theme::FAVICON)?;
|
||||
|
||||
// book.js
|
||||
let mut js = File::create(&themedir.join("book.js"))?;
|
||||
js.write_all(theme::JS)?;
|
||||
|
||||
// highlight.css
|
||||
let mut highlight_css = File::create(&themedir.join("highlight.css"))?;
|
||||
highlight_css.write_all(theme::HIGHLIGHT_CSS)?;
|
||||
|
||||
// highlight.js
|
||||
let mut highlight_js = File::create(&themedir.join("highlight.js"))?;
|
||||
highlight_js.write_all(theme::HIGHLIGHT_JS)?;
|
||||
}
|
||||
|
||||
// index.hbs
|
||||
let mut index = File::create(&theme_dir.join("index.hbs"))?;
|
||||
index.write_all(theme::INDEX)?;
|
||||
|
||||
// book.css
|
||||
let mut css = File::create(&theme_dir.join("book.css"))?;
|
||||
css.write_all(theme::CSS)?;
|
||||
|
||||
// favicon.png
|
||||
let mut favicon = File::create(&theme_dir.join("favicon.png"))?;
|
||||
favicon.write_all(theme::FAVICON)?;
|
||||
|
||||
// book.js
|
||||
let mut js = File::create(&theme_dir.join("book.js"))?;
|
||||
js.write_all(theme::JS)?;
|
||||
|
||||
// highlight.css
|
||||
let mut highlight_css = File::create(&theme_dir.join("highlight.css"))?;
|
||||
highlight_css.write_all(theme::HIGHLIGHT_CSS)?;
|
||||
|
||||
// highlight.js
|
||||
let mut highlight_js = File::create(&theme_dir.join("highlight.js"))?;
|
||||
highlight_js.write_all(theme::HIGHLIGHT_JS)?;
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_file<P: AsRef<Path>>(&self, filename: P, content: &[u8]) -> Result<(), Box<Error>> {
|
||||
let path = self.get_dest().join(filename);
|
||||
let path = self.get_destination()
|
||||
.ok_or(String::from("HtmlConfig not set, could not find a destination"))?
|
||||
.join(filename);
|
||||
|
||||
utils::fs::create_file(&path)
|
||||
.and_then(|mut file| file.write_all(content))
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Could not create {}: {}", path.display(), e)))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -320,21 +318,23 @@ impl MDBook {
|
|||
/// 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`
|
||||
|
||||
pub fn read_config(mut self) -> Self {
|
||||
pub fn read_config(mut self) -> Result<Self, Box<Error>> {
|
||||
|
||||
let config = BookConfig::new(&self.root)
|
||||
.read_config(&self.root)
|
||||
.to_owned();
|
||||
let toml = self.get_root().join("book.toml");
|
||||
let json = self.get_root().join("book.json");
|
||||
|
||||
self.title = config.title;
|
||||
self.description = config.description;
|
||||
self.author = config.author;
|
||||
if toml.exists() {
|
||||
let mut file = File::open(toml)?;
|
||||
let mut content = String::new();
|
||||
file.read_to_string(&mut content)?;
|
||||
|
||||
self.dest = config.dest;
|
||||
self.src = config.src;
|
||||
self.theme_path = config.theme_path;
|
||||
let parsed_config = TomlConfig::from_toml(&content)?;
|
||||
self.config.fill_from_tomlconfig(parsed_config);
|
||||
} else if json.exists() {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
self
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// You can change the default renderer to another one
|
||||
|
@ -374,7 +374,7 @@ impl MDBook {
|
|||
if let BookItem::Chapter(_, ref ch) = *item {
|
||||
if ch.path != PathBuf::new() {
|
||||
|
||||
let path = self.get_src().join(&ch.path);
|
||||
let path = self.get_source().join(&ch.path);
|
||||
|
||||
println!("[*]: Testing file: {:?}", path);
|
||||
|
||||
|
@ -395,52 +395,49 @@ impl MDBook {
|
|||
}
|
||||
|
||||
pub fn get_root(&self) -> &Path {
|
||||
&self.root
|
||||
self.config.get_root()
|
||||
}
|
||||
|
||||
pub fn set_dest(mut self, dest: &Path) -> Self {
|
||||
|
||||
// Handle absolute and relative paths
|
||||
if dest.is_absolute() {
|
||||
self.dest = dest.to_owned();
|
||||
|
||||
pub fn with_destination<T: Into<PathBuf>>(mut self, destination: T) -> Self {
|
||||
let root = self.config.get_root().to_owned();
|
||||
if let Some(htmlconfig) = self.config.get_mut_html_config() {
|
||||
htmlconfig.set_destination(&root, &destination.into());
|
||||
} else {
|
||||
let dest = self.root.join(dest).to_owned();
|
||||
self.dest = dest;
|
||||
error!("There is no HTML renderer set...");
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
pub fn get_dest(&self) -> &Path {
|
||||
&self.dest
|
||||
}
|
||||
|
||||
pub fn set_src(mut self, src: &Path) -> Self {
|
||||
|
||||
// Handle absolute and relative paths
|
||||
if src.is_absolute() {
|
||||
self.src = src.to_owned();
|
||||
} else {
|
||||
let src = self.root.join(src).to_owned();
|
||||
self.src = src;
|
||||
pub fn get_destination(&self) -> Option<&Path> {
|
||||
if let Some(htmlconfig) = self.config.get_html_config() {
|
||||
return Some(htmlconfig.get_destination());
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn with_source<T: Into<PathBuf>>(mut self, source: T) -> Self {
|
||||
self.config.set_source(source);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_src(&self) -> &Path {
|
||||
&self.src
|
||||
pub fn get_source(&self) -> &Path {
|
||||
self.config.get_source()
|
||||
}
|
||||
|
||||
pub fn set_title(mut self, title: &str) -> Self {
|
||||
self.title = title.to_owned();
|
||||
pub fn with_title<T: Into<String>>(mut self, title: T) -> Self {
|
||||
self.config.set_title(title);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_title(&self) -> &str {
|
||||
&self.title
|
||||
self.config.get_title()
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn set_author(mut self, author: &str) -> Self {
|
||||
self.author = author.to_owned();
|
||||
self
|
||||
|
@ -449,14 +446,14 @@ impl MDBook {
|
|||
pub fn get_author(&self) -> &str {
|
||||
&self.author
|
||||
}
|
||||
|
||||
pub fn set_description(mut self, description: &str) -> Self {
|
||||
self.description = description.to_owned();
|
||||
*/
|
||||
pub fn with_description<T: Into<String>>(mut self, description: T) -> Self {
|
||||
self.config.set_description(description);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_description(&self) -> &str {
|
||||
&self.description
|
||||
self.config.get_description()
|
||||
}
|
||||
|
||||
pub fn set_livereload(&mut self, livereload: String) -> &mut Self {
|
||||
|
@ -473,23 +470,28 @@ impl MDBook {
|
|||
self.livereload.as_ref()
|
||||
}
|
||||
|
||||
pub fn set_theme_path(mut self, theme_path: &Path) -> Self {
|
||||
self.theme_path = if theme_path.is_absolute() {
|
||||
theme_path.to_owned()
|
||||
pub fn with_theme_path<T: Into<PathBuf>>(mut self, theme_path: T) -> Self {
|
||||
let root = self.config.get_root().to_owned();
|
||||
if let Some(htmlconfig) = self.config.get_mut_html_config() {
|
||||
htmlconfig.set_theme(&root, &theme_path.into());
|
||||
} else {
|
||||
self.root.join(theme_path).to_owned()
|
||||
};
|
||||
error!("There is no HTML renderer set...");
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_theme_path(&self) -> &Path {
|
||||
&self.theme_path
|
||||
pub fn get_theme_path(&self) -> Option<&PathBuf> {
|
||||
if let Some(htmlconfig) = self.config.get_html_config() {
|
||||
return htmlconfig.get_theme();
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
// Construct book
|
||||
fn parse_summary(&mut self) -> Result<(), Box<Error>> {
|
||||
// When append becomes stable, use self.content.append() ...
|
||||
self.content = parse::construct_bookitems(&self.src.join("SUMMARY.md"))?;
|
||||
self.content = parse::construct_bookitems(&self.get_source().join("SUMMARY.md"))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,14 +102,45 @@ impl BookConfig {
|
|||
}
|
||||
|
||||
if let Some(tomlhtmlconfig) = tomlconfig.output.and_then(|o| o.html) {
|
||||
let source = config.get_source().to_owned();
|
||||
let mut htmlconfig = config.get_mut_html_config().expect("We just created a new config and it creates a default HtmlConfig");
|
||||
htmlconfig.fill_from_tomlconfig(&root, &source, tomlhtmlconfig);
|
||||
htmlconfig.fill_from_tomlconfig(&root, tomlhtmlconfig);
|
||||
}
|
||||
|
||||
config
|
||||
}
|
||||
|
||||
pub fn fill_from_tomlconfig(&mut self, tomlconfig: TomlConfig) -> &mut Self {
|
||||
|
||||
if let Some(s) = tomlconfig.source {
|
||||
self.set_source(s);
|
||||
}
|
||||
|
||||
if let Some(t) = tomlconfig.title {
|
||||
self.set_title(t);
|
||||
}
|
||||
|
||||
if let Some(d) = tomlconfig.description {
|
||||
self.set_description(d);
|
||||
}
|
||||
|
||||
if let Some(a) = tomlconfig.authors {
|
||||
self.set_authors(a);
|
||||
}
|
||||
|
||||
if let Some(a) = tomlconfig.author {
|
||||
self.set_authors(vec![a]);
|
||||
}
|
||||
|
||||
if let Some(tomlhtmlconfig) = tomlconfig.output.and_then(|o| o.html) {
|
||||
let root = self.root.clone();
|
||||
if let Some(htmlconfig) = self.get_mut_html_config() {
|
||||
htmlconfig.fill_from_tomlconfig(root, tomlhtmlconfig);
|
||||
}
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_root<T: Into<PathBuf>>(&mut self, root: T) -> &mut Self {
|
||||
self.root = root.into();
|
||||
self
|
||||
|
|
|
@ -29,10 +29,12 @@ impl HtmlConfig {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn fill_from_tomlconfig<T: Into<PathBuf>>(&mut self, root: T, source: T, tomlconfig: TomlHtmlConfig) -> &mut Self {
|
||||
pub fn fill_from_tomlconfig<T: Into<PathBuf>>(&mut self, root: T, tomlconfig: TomlHtmlConfig) -> &mut Self {
|
||||
let root = root.into();
|
||||
|
||||
if let Some(d) = tomlconfig.destination {
|
||||
if d.is_relative() {
|
||||
self.destination = root.into().join(d);
|
||||
self.destination = root.join(d);
|
||||
} else {
|
||||
self.destination = d;
|
||||
}
|
||||
|
@ -40,7 +42,7 @@ impl HtmlConfig {
|
|||
|
||||
if let Some(t) = tomlconfig.theme {
|
||||
if t.is_relative() {
|
||||
self.theme = Some(source.into().join(t));
|
||||
self.theme = Some(root.join(t));
|
||||
} else {
|
||||
self.theme = Some(t);
|
||||
}
|
||||
|
@ -53,6 +55,17 @@ impl HtmlConfig {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn set_destination<T: Into<PathBuf>>(&mut self, root: T, destination: T) -> &mut Self {
|
||||
let d = destination.into();
|
||||
if d.is_relative() {
|
||||
self.destination = root.into().join(d);
|
||||
} else {
|
||||
self.destination = d;
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_destination(&self) -> &Path {
|
||||
&self.destination
|
||||
}
|
||||
|
@ -61,4 +74,15 @@ impl HtmlConfig {
|
|||
pub fn get_theme(&self) -> Option<&PathBuf> {
|
||||
self.theme.as_ref()
|
||||
}
|
||||
|
||||
pub fn set_theme<T: Into<PathBuf>>(&mut self, root: T, theme: T) -> &mut Self {
|
||||
let d = theme.into();
|
||||
if d.is_relative() {
|
||||
self.theme = Some(root.into().join(d));
|
||||
} else {
|
||||
self.theme = Some(d);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,5 +89,4 @@ pub mod utils;
|
|||
|
||||
pub use book::MDBook;
|
||||
pub use book::BookItem;
|
||||
pub use book::BookConfig;
|
||||
pub use renderer::Renderer;
|
||||
|
|
|
@ -33,7 +33,7 @@ impl Renderer for HtmlHandlebars {
|
|||
let mut handlebars = Handlebars::new();
|
||||
|
||||
// Load theme
|
||||
let theme = theme::Theme::new(book.get_theme_path());
|
||||
let theme = theme::Theme::new(book.get_theme_path().expect("If the HTML renderer is called, one would assume the HtmlConfig is set..."));
|
||||
|
||||
// Register template
|
||||
debug!("[*]: Register handlebars template");
|
||||
|
@ -53,7 +53,7 @@ impl Renderer for HtmlHandlebars {
|
|||
|
||||
// Check if dest directory exists
|
||||
debug!("[*]: Check if destination directory exists");
|
||||
if fs::create_dir_all(book.get_dest()).is_err() {
|
||||
if fs::create_dir_all(book.get_destination().expect("If the HTML renderer is called, one would assume the HtmlConfig is set...")).is_err() {
|
||||
return Err(Box::new(io::Error::new(io::ErrorKind::Other,
|
||||
"Unexpected error when constructing destination path")));
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ impl Renderer for HtmlHandlebars {
|
|||
BookItem::Affix(ref ch) => {
|
||||
if ch.path != PathBuf::new() {
|
||||
|
||||
let path = book.get_src().join(&ch.path);
|
||||
let path = book.get_source().join(&ch.path);
|
||||
|
||||
debug!("[*]: Opening file: {:?}", path);
|
||||
let mut f = File::open(&path)?;
|
||||
|
@ -116,8 +116,12 @@ impl Renderer for HtmlHandlebars {
|
|||
debug!("[*]: index.html");
|
||||
|
||||
let mut content = String::new();
|
||||
let _source = File::open(book.get_dest().join(&ch.path.with_extension("html")))?
|
||||
.read_to_string(&mut content);
|
||||
|
||||
let _source = File::open(
|
||||
book.get_destination()
|
||||
.expect("If the HTML renderer is called, one would assume the HtmlConfig is set...")
|
||||
.join(&ch.path.with_extension("html"))
|
||||
)?.read_to_string(&mut content);
|
||||
|
||||
// This could cause a problem when someone displays
|
||||
// code containing <base href=...>
|
||||
|
@ -131,7 +135,10 @@ impl Renderer for HtmlHandlebars {
|
|||
book.write_file("index.html", content.as_bytes())?;
|
||||
|
||||
info!("[*] Creating index.html from {:?} ✓",
|
||||
book.get_dest().join(&ch.path.with_extension("html")));
|
||||
book.get_destination()
|
||||
.expect("If the HTML renderer is called, one would assume the HtmlConfig is set...")
|
||||
.join(&ch.path.with_extension("html"))
|
||||
);
|
||||
index = false;
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +188,12 @@ impl Renderer for HtmlHandlebars {
|
|||
book.write_file("_FontAwesome/fonts/FontAwesome.ttf", theme::FONT_AWESOME_TTF)?;
|
||||
|
||||
// Copy all remaining files
|
||||
utils::fs::copy_files_except_ext(book.get_src(), book.get_dest(), true, &["md"])?;
|
||||
utils::fs::copy_files_except_ext(
|
||||
book.get_source(),
|
||||
book.get_destination()
|
||||
.expect("If the HTML renderer is called, one would assume the HtmlConfig is set..."), true, &["md"]
|
||||
)?;
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue