From 22280bbb169b6c3bce1c54a6397bb971e6d703ba Mon Sep 17 00:00:00 2001 From: Mathieu David Date: Mon, 3 Aug 2015 18:06:01 +0200 Subject: [PATCH] Add debug! macro that can be activated using the "debug" feature. #19 --- Cargo.toml | 3 +++ src/book/bookconfig.rs | 11 +++++--- src/book/mdbook.rs | 8 ++++++ src/lib.rs | 2 ++ src/macros.rs | 11 ++++++++ src/parse/summary.rs | 29 +++++++++++++++----- src/renderer/html_handlebars/mod.rs | 41 ++++++++++++++++++----------- src/utils/path.rs | 24 +++++++++++------ 8 files changed, 96 insertions(+), 33 deletions(-) create mode 100644 src/macros.rs diff --git a/Cargo.toml b/Cargo.toml index 441081af..c0b84656 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,6 @@ clap = "*" handlebars = "*" rustc-serialize = "*" pulldown-cmark = "*" + +[features] +debug = [] diff --git a/src/book/bookconfig.rs b/src/book/bookconfig.rs index 6c82760d..c6af9d99 100644 --- a/src/book/bookconfig.rs +++ b/src/book/bookconfig.rs @@ -4,8 +4,6 @@ use std::fs::File; use std::io::Read; use std::path::{Path, PathBuf}; -use utils; - #[derive(Debug, Clone)] pub struct BookConfig { pub title: String, @@ -31,12 +29,18 @@ impl BookConfig { pub fn read_config(&mut self) -> &mut Self { + debug!("[fn]: read_config"); + // If the file does not exist, return early let mut config_file = match File::open(self.src.join("book.json")) { Ok(f) => f, - Err(_) => return self, + Err(_) => { + debug!("[*]: Failed to open {:?}", self.src.join("book.json")); + return self + }, }; + debug!("[*]: Reading config"); let mut data = String::new(); config_file.read_to_string(&mut data).unwrap(); @@ -45,6 +49,7 @@ impl BookConfig { // 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("\"", "") } diff --git a/src/book/mdbook.rs b/src/book/mdbook.rs index 6fa45e2b..a158cf7e 100644 --- a/src/book/mdbook.rs +++ b/src/book/mdbook.rs @@ -49,6 +49,8 @@ impl MDBook { pub fn init(&self) -> Result<(), Box> { + debug!("[fn]: init"); + let dest = self.config.dest(); let src = self.config.src(); @@ -57,6 +59,7 @@ impl MDBook { 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", dest); fs::create_dir(&dest).unwrap(); }, Ok(_) => { /* If there is no error, the directory / file does exist */ } @@ -67,6 +70,7 @@ impl MDBook { 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", src); fs::create_dir(&src).unwrap(); }, Ok(_) => { /* If there is no error, the directory / file does exist */ } @@ -77,6 +81,7 @@ impl MDBook { 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 SUMMARY.md", src.join("SUMMARY.md")); Ok(File::create(&src.join("SUMMARY.md")).unwrap()) }, Ok(_) => { @@ -86,6 +91,8 @@ impl MDBook { }; if let Ok(mut f) = summary { + debug!("[*]: Writing to SUMMARY.md"); + try!(writeln!(f, "# Summary")); try!(writeln!(f, "")); try!(writeln!(f, "- [Chapter 1](./chapter_1.md)")); @@ -98,6 +105,7 @@ impl MDBook { } pub fn build(&mut self) -> Result<(), Box> { + debug!("[fn]: build"); try!(self.parse_summary()); diff --git a/src/lib.rs b/src/lib.rs index 6fcdc70e..8cd77a85 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +#[macro_use] +pub mod macros; mod book; mod parse; pub mod renderer; diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 00000000..bb5271e3 --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,11 @@ +#[cfg(feature = "debug")] +macro_rules! debug { + ($fmt:expr) => (println!($fmt)); + ($fmt:expr, $($arg:tt)*) => (println!($fmt, $($arg)*)); +} + +#[cfg(not(feature = "debug"))] +macro_rules! debug { + ($fmt:expr) => (); + ($fmt:expr, $($arg:tt)*) => (); +} diff --git a/src/parse/summary.rs b/src/parse/summary.rs index ef4ff1db..973524b8 100644 --- a/src/parse/summary.rs +++ b/src/parse/summary.rs @@ -14,18 +14,18 @@ pub enum LineType { */ pub fn construct_bookitems(path: &PathBuf) -> Result> { + debug!("[fn]: construct_bookitems"); let mut summary = String::new(); try!(try!(File::open(path)).read_to_string(&mut summary)); + debug!("[*]: Parse SUMMARY.md"); let top_items = try!(parse_level(&mut summary.split('\n').collect(), 0)); - - Ok(top_items) } fn parse_level(summary: &mut Vec<&str>, current_level: i32) -> Result> { - + debug!("[fn]: parse_level"); let mut items: Vec = vec![]; loop { @@ -50,6 +50,7 @@ fn parse_level(summary: &mut Vec<&str>, current_level: i32) -> Result Result { + debug!("[fn]: level"); let mut spaces = 0; let mut level = 0; @@ -67,9 +68,12 @@ fn level(line: &str, spaces_in_tab: i32) -> Result { // If there are spaces left, there is an indentation error if spaces > 0 { + debug!("[SUMMARY.md]:"); + debug!("\t[line]: {}", line); + debug!("[*]: There is an indentation error on this line. Indentation should be {} spaces", spaces_in_tab); return Err(Error::new( ErrorKind::Other, - format!("There is an indentation error on line:\n\n{}", line) + format!("Indentation error on line:\n\n{}", line) ) ) } @@ -79,6 +83,7 @@ fn level(line: &str, spaces_in_tab: i32) -> Result { fn parse_line(l: &str) -> Option { + debug!("[fn]: parse_line"); let mut name; let mut path; // Remove leading and trailing spaces or tabs @@ -88,18 +93,25 @@ fn parse_line(l: &str) -> Option { match c { // List item '-' | '*' => { + debug!("[*]: Line is list element"); let mut start_delimitor; let mut end_delimitor; // In the future, support for list item that is not a link // Not sure if I should error on line I can't parse or just ignore them... if let Some(i) = line.find('[') { start_delimitor = i; } - else { return None } + else { + debug!("[*]: '[' not found, this line is not a link. Ignoring..."); + return None + } if let Some(i) = line[start_delimitor..].find("](") { end_delimitor = start_delimitor +i; } - else { return None } + else { + debug!("[*]: '](' not found, this line is not a link. Ignoring..."); + return None + } name = line[start_delimitor + 1 .. end_delimitor].to_string(); @@ -107,7 +119,10 @@ fn parse_line(l: &str) -> Option { if let Some(i) = line[start_delimitor..].find(')') { end_delimitor = start_delimitor + i; } - else { return None } + else { + debug!("[*]: ')' not found, this line is not a link. Ignoring..."); + return None + } path = PathBuf::from(line[start_delimitor + 1 .. end_delimitor].to_string()); diff --git a/src/renderer/html_handlebars/mod.rs b/src/renderer/html_handlebars/mod.rs index 65acadc6..8273a317 100644 --- a/src/renderer/html_handlebars/mod.rs +++ b/src/renderer/html_handlebars/mod.rs @@ -24,16 +24,18 @@ pub struct HtmlHandlebars; impl Renderer for HtmlHandlebars { fn render(&self, book: BookItems, config: &BookConfig) -> Result<(), Box> { - + debug!("[fn]: render"); let mut handlebars = Handlebars::new(); // Load template let t = theme::get_index_hbs(); // Register template + debug!("[*]: Register handlebars template"); try!(handlebars.register_template_string("index", t.to_owned())); // Register helpers + debug!("[*]: Register handlebars helpers"); handlebars.register_helper("toc", Box::new(RenderToc)); handlebars.register_helper("previous", Box::new(hbs_navigation_helper::previous)); handlebars.register_helper("next", Box::new(hbs_navigation_helper::next)); @@ -41,6 +43,7 @@ impl Renderer for HtmlHandlebars { let mut data = try!(make_data(book.clone(), config)); // Check if dest directory exists + debug!("[*]: Check if destination directory exists"); match utils::path::create_path(config.dest()) { Err(_) => return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Unexcpected error when constructing destination path"))), _ => {}, @@ -54,9 +57,11 @@ impl Renderer for HtmlHandlebars { let path = config.src().join(&item.path); + debug!("[*]: Opening file: {:?}", path); let mut f = try!(File::open(&path)); let mut content: String = String::new(); + debug!("[*]: Reading file"); try!(f.read_to_string(&mut content)); // Render markdown using the pulldown-cmark crate @@ -75,25 +80,26 @@ impl Renderer for HtmlHandlebars { data.insert("path_to_root".to_string(), utils::path::path_to_root(&item.path).to_json()); // Rendere the handlebars template with the data + debug!("[*]: Render template"); let rendered = try!(handlebars.render("index", &data)); - println!("Write file..."); + debug!("[*] Write to file"); // Write to file let mut file = try!(create_file(config.dest(), &item.path)); try!(file.write_all(&rendered.into_bytes())); // Create an index.html from the first element in SUMMARY.md if index { - print!( - "Creating index.html from {:?}", - config.dest().join(&item.path.with_extension("html")) - ); - + debug!("[*] index.html"); try!(fs::copy( config.dest().join(&item.path.with_extension("html")), config.dest().join("index.html") )); - println!(" ✓"); + + println!( + "[*] Creating index.html from {:?} ✓", + config.dest().join(&item.path.with_extension("html")) + ); index = false; } } @@ -101,6 +107,7 @@ impl Renderer for HtmlHandlebars { // Copy static files (js, css, images, ...) + debug!("[*] Copy static files"); // JavaScript let mut js_file = try!(File::create(config.dest().join("book.js"))); try!(js_file.write_all(theme::get_js())); @@ -118,18 +125,19 @@ impl HtmlHandlebars { HtmlHandlebars } - fn _load_template(&self, path: &Path) -> Result> { + /*fn _load_template(&self, path: &Path) -> Result> { let mut file = try!(File::open(path)); let mut s = String::new(); try!(file.read_to_string(&mut s)); Ok(s) - } + }*/ } fn create_file(working_directory: &Path, path: &Path) -> Result> { - println!("[fn]: create_file"); + debug!("[fn]: create_file"); + debug!("[*]: extract filename"); // Extract filename let mut file_name; if let Some(name) = path.file_stem() { @@ -160,31 +168,33 @@ fn create_file(working_directory: &Path, path: &Path) -> Result match metadata(&constructed_path) { // Any way to combine the Err and first Ok branch ?? Err(_) => { + debug!("[*]: Create {:?}", constructed_path); try!(fs::create_dir(&constructed_path)) }, Ok(f) => { if !f.is_dir() { + debug!("[*]: Create {:?}", constructed_path); try!(fs::create_dir(&constructed_path)) } else { - println!("[*]: {:?} --> exists", constructed_path); + debug!("[*]: Directory exists: {:?}", constructed_path); continue } }, } } - - print!("Create file: {:?}", constructed_path.join(&file_name)); + debug!("[*]: Create {:?}", constructed_path.join(&file_name)); let file = try!(File::create( constructed_path.join(&file_name) )); - println!(" ✓"); + println!("[*] Create file: {:?} ✓", constructed_path.join(&file_name)); Ok(file) } fn make_data(book: BookItems, config: &BookConfig) -> Result, Box> { + debug!("[fn]: make_data"); let mut data = BTreeMap::new(); data.insert("language".to_string(), "en".to_json()); @@ -203,6 +213,7 @@ fn make_data(book: BookItems, config: &BookConfig) -> Result String { + debug!("[fn]: path_to_root"); // Remove filename and add "../" for every directory path.to_path_buf().parent().expect("") .components().fold(String::new(), |mut s, c| { match c { Component::Normal(_) => s.push_str("../"), - _ => {} + _ => { + debug!("[*]: Other path component... {:?}", c); + } } s }) @@ -17,8 +20,7 @@ pub fn path_to_root(path: &Path) -> String { pub fn create_path(path: &Path) -> Result<(), Box> { - - println!("[fn]: create_path"); + debug!("[fn]: create_path"); // Create directories if they do not exist let mut constructed_path = PathBuf::new(); @@ -28,32 +30,38 @@ pub fn create_path(path: &Path) -> Result<(), Box> { let mut dir; match component { Component::Normal(_) => { dir = PathBuf::from(component.as_os_str()); }, - Component::RootDir => { constructed_path.push("/"); continue }, + Component::RootDir => { + debug!("[*]: Root directory"); + // This doesn't look very compatible with Windows... + constructed_path.push("/"); + continue + }, _ => continue, } constructed_path.push(&dir); + debug!("[*]: {:?}", constructed_path); // Check if path exists match metadata(&constructed_path) { // Any way to combine the Err and first Ok branch ?? Err(_) => { try!(fs::create_dir(&constructed_path)); - println!("[*]: Directory created {:?}", constructed_path); + debug!("[*]: Directory created {:?}", constructed_path); }, Ok(f) => { if !f.is_dir() { try!(fs::create_dir(&constructed_path)); - println!("[*]: Directory created {:?}", constructed_path); + debug!("[*]: Directory created {:?}", constructed_path); } else { - println!("[*]: Directory exists {:?}", constructed_path); + debug!("[*]: Directory exists {:?}", constructed_path); continue } }, } } - println!("[*]: Constructed path: {:?}", constructed_path); + debug!("[*]: Constructed path: {:?}", constructed_path); Ok(()) }