update docs in the source

This commit is contained in:
Gambhiro 2017-01-18 16:18:41 +00:00
parent 8441bb99d2
commit 4fe0e8d2a4
10 changed files with 121 additions and 258 deletions

View File

@ -15,10 +15,6 @@ fn main() {
.build("data.rs") .build("data.rs")
.unwrap(); .unwrap();
// TODO this using cargo as a Makefile. This is only for development, it
// doesn't have to be part of the production auto-build. Use either a
// Makefile or an npm command if stylus comes from npm anyway.
if let Ok(_) = env::var("CARGO_FEATURE_REGENERATE_CSS") { if let Ok(_) = env::var("CARGO_FEATURE_REGENERATE_CSS") {
// Compile stylus stylesheet to css // Compile stylus stylesheet to css

View File

@ -35,7 +35,7 @@ impl Book {
book book
} }
/// Parses in the SUMMARY.md or creates one /// Parses the SUMMARY.md or creates one
pub fn parse_or_create_summary_file(&mut self, first_as_index: bool) -> Result<&mut Self, String> { pub fn parse_or_create_summary_file(&mut self, first_as_index: bool) -> Result<&mut Self, String> {
let summary_path = self.config.src.join("SUMMARY.md"); let summary_path = self.config.src.join("SUMMARY.md");
@ -81,7 +81,7 @@ impl Book {
content content
} }
// TODO update // These don't seem to be used.
// /// This method takes a slice `&[x, y, z]` as parameter and returns the corresponding chapter. // /// This method takes a slice `&[x, y, z]` as parameter and returns the corresponding chapter.
// /// For example, to retrieve chapter 2.3 we would use: // /// For example, to retrieve chapter 2.3 we would use:

View File

@ -16,8 +16,6 @@ pub struct BookConfig {
// Paths // Paths
// TODO test if dest and src behaves correctly when mdbook.dest_base and mdbook.src_base is not 'book' and 'src'
pub dest: PathBuf, pub dest: PathBuf,
pub src: PathBuf, pub src: PathBuf,
@ -25,8 +23,9 @@ pub struct BookConfig {
/// The title of the book. /// The title of the book.
pub title: String, pub title: String,
/// The subtitle, when titles are in the form of "The Immense Journey: An /// The subtitle, when the book's full title is in the form of "The Immense
/// Imaginative Naturalist Explores the Mysteries of Man and Nature" /// Journey: An Imaginative Naturalist Explores the Mysteries of Man and
/// Nature"
pub subtitle: Option<String>, pub subtitle: Option<String>,
/// A brief description or summary of the book. /// A brief description or summary of the book.
pub description: Option<String>, pub description: Option<String>,
@ -94,7 +93,7 @@ impl BookConfig {
/// write data back to it. /// write data back to it.
/// ///
/// Parses author when given as an array, or when given as a hash key to /// Parses author when given as an array, or when given as a hash key to
/// make declaring just an author name easy. /// make declaring a single author easy.
/// ///
/// Both of these express a single author: /// Both of these express a single author:
/// ///

View File

@ -21,7 +21,7 @@ use utils::fs::create_with_str;
/// If the markdown file starts with a TOML header, it will be parsed to set the /// If the markdown file starts with a TOML header, it will be parsed to set the
/// chapter's properties. A TOML header should start and end with `+++` lines: /// chapter's properties. A TOML header should start and end with `+++` lines:
/// ///
/// ``` /// ```text
/// +++ /// +++
/// title = "The Library of Babel" /// title = "The Library of Babel"
/// author = "Jorge Luis Borges" /// author = "Jorge Luis Borges"
@ -81,8 +81,6 @@ pub struct Chapter {
/// The description of the chapter. /// The description of the chapter.
pub description: Option<String>, pub description: Option<String>,
/// TODO use this in the template
/// CSS class that will be added to the page-level wrap div to allow /// CSS class that will be added to the page-level wrap div to allow
/// customized chapter styles. /// customized chapter styles.
pub css_class: Option<String>, pub css_class: Option<String>,
@ -235,43 +233,6 @@ impl Chapter {
self self
} }
// TODO not being used?
// /// Reads in the chapter's content from the markdown file. Chapter doesn't
// /// know the book's src folder, hence the `book_src_dir` argument.
// pub fn read_content_using(&self, book_src_dir: &PathBuf) -> Result<String, Box<Error>> {
// let p = match self.get_src_path() {
// Some(x) => x,
// None => {
// return Err(Box::new(io::Error::new(
// io::ErrorKind::Other,
// format!("src_path is None"))
// ));
// }
// };
// let src_path = book_src_dir.join(&p);
// if !src_path.exists() {
// return Err(Box::new(io::Error::new(
// io::ErrorKind::Other,
// format!("Doesn't exist: {:?}", src_path))
// ));
// }
// debug!("[*]: Opening file: {:?}", src_path);
// let mut f = try!(File::open(&src_path));
// let mut content: String = String::new();
// debug!("[*]: Reading file");
// try!(f.read_to_string(&mut content));
// content = utils::strip_toml_header(&content);
// Ok(content)
// }
pub fn get_src_path(&self) -> Option<PathBuf> { pub fn get_src_path(&self) -> Option<PathBuf> {
self.src_path.clone() self.src_path.clone()
} }

View File

@ -63,8 +63,8 @@ pub struct MDBook {
/// folder with the chapter files. /// folder with the chapter files.
/// ///
/// In the case of a single language, it is the sole item in the HashMap, /// In the case of a single language, it is the sole item in the HashMap,
/// and its source is not expected to be under a sub-folder, just simply in /// and its Markdown files are not expected to be under a sub-folder, just
/// `./src`. /// simply in `./src`.
/// ///
/// Translations have to be declared in `book.toml` in their separate /// Translations have to be declared in `book.toml` in their separate
/// blocks. The first in the TOML config will be recognized as the main /// blocks. The first in the TOML config will be recognized as the main
@ -82,25 +82,24 @@ pub struct MDBook {
/// author = "Lewis Carroll" /// author = "Lewis Carroll"
/// ``` /// ```
/// ///
/// For multiple languages, declare them in blocks: /// For multiple languages, declare them in blocks. The translation key will
/// be the language code. Optionally, the language name can be set as well.
/// ///
/// ```toml /// ```toml
/// [[translations.en]] /// [[translations.en]]
/// title = "Alice in Wonderland" /// title = "Alice in Wonderland"
/// author = "Lewis Carroll" /// author = "Lewis Carroll"
/// language = { name = "English", code = "en" }
/// ///
/// [[translations.fr]] /// [[translations.fr]]
/// title = "Alice au pays des merveilles" /// title = "Alice au pays des merveilles"
/// author = "Lewis Carroll" /// author = "Lewis Carroll"
/// translator = "Henri Bué" /// translator = "Henri Bué"
/// language = { name = "Français", code = "fr" } /// language_name = "Français"
/// ///
/// [[translations.hu]] /// [[translations.hu]]
/// title = "Alice Csodaországban" /// title = "Alice Csodaországban"
/// author = "Lewis Carroll" /// author = "Lewis Carroll"
/// translator = "Kosztolányi Dezső" /// translator = "Kosztolányi Dezső"
/// language = { name = "Hungarian", code = "hu" }
/// ``` /// ```
pub translations: HashMap<String, Book>, pub translations: HashMap<String, Book>,
@ -175,12 +174,12 @@ impl MDBook {
/// The `book.toml` file should be in the root directory of the book project. /// The `book.toml` file should be in the root directory of the book project.
/// The project root directory is the one specified when creating a new `MDBook` /// The project root directory is the one specified when creating a new `MDBook`
/// ///
/// ```no_run /// ```ignore
/// # extern crate mdbook; /// # extern crate mdbook;
/// # use mdbook::MDBook; /// # use mdbook::MDBook;
/// # use std::path::Path; /// # use std::path::PathBuf;
/// # fn main() { /// # fn main() {
/// let mut book = MDBook::new(Path::new("project_root_dir")); /// let mut book = MDBook::new(&PathBuf::from("project_root_dir"));
/// # } /// # }
/// ``` /// ```
/// ///
@ -247,12 +246,6 @@ impl MDBook {
/// block will be interpreted as properties of the main book. /// block will be interpreted as properties of the main book.
/// ///
/// `project_root` is ignored. /// `project_root` is ignored.
///
/// - dest_base
/// - render_intent
/// - template_dir
/// - indent_spaces
/// - livereload
pub fn parse_from_btreemap(&mut self, conf: &BTreeMap<String, toml::Value>) -> &mut Self { pub fn parse_from_btreemap(&mut self, conf: &BTreeMap<String, toml::Value>) -> &mut Self {
let mut config = conf.clone(); let mut config = conf.clone();
@ -398,8 +391,6 @@ impl MDBook {
for key in self.translations.clone().keys() { for key in self.translations.clone().keys() {
if let Some(mut b) = self.translations.clone().get_mut(key) { if let Some(mut b) = self.translations.clone().get_mut(key) {
// TODO error handling could be better here
let first_as_index = match self.render_intent { let first_as_index = match self.render_intent {
RenderIntent::HtmlHandlebars => true, RenderIntent::HtmlHandlebars => true,
}; };
@ -617,76 +608,5 @@ impl MDBook {
self self
} }
// TODO update
// pub fn test(&mut self) -> Result<(), Box<Error>> {
// // read in the chapters
// try!(self.parse_summary());
// for item in self.iter() {
// match *item {
// BookItem::Chapter(_, ref ch) => {
// if ch.path != PathBuf::new() {
// let path = self.get_src().join(&ch.path);
// println!("[*]: Testing file: {:?}", path);
// let output_result = Command::new("rustdoc")
// .arg(&path)
// .arg("--test")
// .output();
// let output = try!(output_result);
// if !output.status.success() {
// return Err(Box::new(io::Error::new(ErrorKind::Other, format!(
// "{}\n{}",
// String::from_utf8_lossy(&output.stdout),
// String::from_utf8_lossy(&output.stderr)))) as Box<Error>);
// }
// }
// },
// _ => {},
// }
// }
// Ok(())
// }
// /// Returns a flat depth-first iterator over the elements of the book, it returns an [BookItem enum](bookitem.html):
// /// `(section: String, bookitem: &BookItem)`
// ///
// /// ```no_run
// /// # extern crate mdbook;
// /// # use mdbook::MDBook;
// /// # use mdbook::BookItem;
// /// # use std::path::Path;
// /// # fn main() {
// /// # let mut book = MDBook::new(Path::new("mybook"));
// /// for item in book.iter() {
// /// match item {
// /// &BookItem::Chapter(ref section, ref chapter) => {},
// /// &BookItem::Affix(ref chapter) => {},
// /// &BookItem::Spacer => {},
// /// }
// /// }
// ///
// /// // would print something like this:
// /// // 1. Chapter 1
// /// // 1.1 Sub Chapter
// /// // 1.2 Sub Chapter
// /// // 2. Chapter 2
// /// //
// /// // etc.
// /// # }
// /// ```
// pub fn iter(&self) -> BookItems {
// BookItems {
// items: &self.content[..],
// current_index: 0,
// stack: Vec::new(),
// }
// }
} }

View File

@ -101,7 +101,7 @@ impl TocContent {
false false
} }
// TODO update // This doesn't seem to be used.
// /// This function takes a slice `&[x,y,z]` and returns the corresponding sub-chapter if it exists. // /// This function takes a slice `&[x,y,z]` and returns the corresponding sub-chapter if it exists.
// /// // ///

View File

@ -5,7 +5,7 @@
//! //!
//! This is the API doc, but you can find a [less "low-level" documentation here](../index.html) that //! This is the API doc, but you can find a [less "low-level" documentation here](../index.html) that
//! contains information about the command line tool, format, structure etc. //! contains information about the command line tool, format, structure etc.
//! It is also rendered with mdBook to showcase the features and default theme. //! It is also rendered with mdBook to showcase the features and default html template.
//! //!
//! Some reasons why you would want to use the crate (over the cli): //! Some reasons why you would want to use the crate (over the cli):
//! //!
@ -17,57 +17,49 @@
//! //!
//! ## Example //! ## Example
//! //!
//! ```no_run //! Building a book by the path to its directory:
//!
//! ```ignore
//! extern crate mdbook; //! extern crate mdbook;
//! //!
//! use mdbook::MDBook; //! use mdbook::MDBook;
//! use std::path::Path; //! use mdbook::renderer::HtmlHandlebars;
//! use std::path::PathBuf;
//! //!
//! fn main() { //! fn main() {
//! let mut book = MDBook::new(Path::new("my-book")) // Path to root //! let path = PathBuf::from("my-book"); // Path to the book project's root
//! .set_src(Path::new("src")) // Path from root to source directory //! let renderer = HtmlHandlebars::new();
//! .set_dest(Path::new("book")) // Path from root to output directory //! try!(renderer.build(&path)); // Build the book
//! .read_config(); // Parse book.json file for configuration //! }
//! ```
//! //!
//! book.build().unwrap(); // Render the book //! Or, preparing an `MDBook` struct step-by-step and passing it to a renderer:
//!
//! ```ignore
//! extern crate mdbook;
//!
//! use mdbook::MDBook;
//! use mdbook::renderer::HtmlHandlebars;
//! use std::path::PathBuf;
//!
//! fn main() {
//! let path = PathBuf::from("my-book"); // Path to the book project's root
//! let mut book_project = MDBook::new(&path);
//! book_project.read_config(); // Parse book.toml file for configuration
//! book_project.parse_books(); // Parse SUMMARY.md, build TOC, parse chapters
//! book_project.link_translations(); // Identity links between translations
//!
//! let renderer = HtmlHandlebars::new();
//! try!(renderer.render(&book_project)); // Render the book
//! } //! }
//! ``` //! ```
//! //!
//! ## Implementing a new Renderer //! ## Implementing a new Renderer
//! //!
//! If you want to create a new renderer for mdBook, the only thing you have to do is to implement //! If you want to create a new renderer for mdBook, implement the [Renderer
//! the [Renderer trait](renderer/renderer/trait.Renderer.html) //! trait](renderer/renderer/trait.Renderer.html), which is composed of two
//! //! functions, `.build()` and `.render()`.
//! And then you can swap in your renderer like this:
//!
//! ```no_run
//! # extern crate mdbook;
//! #
//! # use mdbook::MDBook;
//! # use mdbook::renderer::HtmlHandlebars;
//! # use std::path::Path;
//! #
//! # fn main() {
//! # let your_renderer = HtmlHandlebars::new();
//! #
//! let book = MDBook::new(Path::new("my-book")).set_renderer(Box::new(your_renderer));
//! # }
//! ``` //! ```
//! If you make a renderer, you get the book constructed in form of `Vec<BookItems>` and you get
//! the book config in a `BookConfig` struct.
//!
//! It's your responsability to create the necessary files in the correct directories.
//!
//! ## utils
//!
//! I have regrouped some useful functions in the [utils](utils/index.html) module, like the following function
//!
//! ```ignore
//! utils::fs::create_path(path: &Path)
//! ```
//! This function creates all the directories in a given path if they do not exist
//!
//! Make sure to take a look at it.
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;

View File

@ -47,8 +47,13 @@ impl Renderer for HtmlHandlebars {
try!(utils::fs::clean_output_dir(&book_project.get_dest_base())); try!(utils::fs::clean_output_dir(&book_project.get_dest_base()));
// TODO talk to the user match self.render(&book_project) {
try!(self.render(&book_project)); Ok(_) => {},
Err(e) => {
println!("Error: {:#?}", e);
return Err(e);
}
}
Ok(()) Ok(())
} }

View File

@ -1,11 +1,14 @@
#[cfg(test)] #[cfg(test)]
extern crate tempdir;
use std; use std;
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::Read; use std::io::Read;
use std::path::Path; use std::path::Path;
use utils; use utils;
use utils::fs::copy_files_except_ext;
#[test] #[test]
fn it_copies_data_file() { fn it_copies_data_file() {
@ -79,3 +82,65 @@ fn it_doesnt_delete_toplevel_dotfiles() {
fs::remove_dir_all(dest_base); fs::remove_dir_all(dest_base);
} }
} }
#[test]
fn copy_files_except_ext_test() {
let tmp = match tempdir::TempDir::new("") {
Ok(t) => t,
Err(_) => panic!("Could not create a temp dir"),
};
// Create a couple of files
if let Err(_) = fs::File::create(&tmp.path().join("file.txt")) {
panic!("Could not create file.txt")
}
if let Err(_) = fs::File::create(&tmp.path().join("file.md")) {
panic!("Could not create file.md")
}
if let Err(_) = fs::File::create(&tmp.path().join("file.png")) {
panic!("Could not create file.png")
}
if let Err(_) = fs::create_dir(&tmp.path().join("sub_dir")) {
panic!("Could not create sub_dir")
}
if let Err(_) = fs::File::create(&tmp.path().join("sub_dir/file.png")) {
panic!("Could not create sub_dir/file.png")
}
if let Err(_) = fs::create_dir(&tmp.path().join("sub_dir_exists")) {
panic!("Could not create sub_dir_exists")
}
if let Err(_) = fs::File::create(&tmp.path().join("sub_dir_exists/file.txt")) {
panic!("Could not create sub_dir_exists/file.txt")
}
// Create output dir
if let Err(_) = fs::create_dir(&tmp.path().join("output")) {
panic!("Could not create output")
}
if let Err(_) = fs::create_dir(&tmp.path().join("output/sub_dir_exists")) {
panic!("Could not create output/sub_dir_exists")
}
match copy_files_except_ext(&tmp.path(), &tmp.path().join("output"), true, &["md"]) {
Err(e) => panic!("Error while executing the function:\n{:?}", e),
Ok(_) => {},
}
// Check if the correct files where created
if !(&tmp.path().join("output/file.txt")).exists() {
panic!("output/file.txt should exist")
}
if (&tmp.path().join("output/file.md")).exists() {
panic!("output/file.md should not exist")
}
if !(&tmp.path().join("output/file.png")).exists() {
panic!("output/file.png should exist")
}
if !(&tmp.path().join("output/sub_dir/file.png")).exists() {
panic!("output/sub_dir/file.png should exist")
}
if !(&tmp.path().join("output/sub_dir_exists/file.txt")).exists() {
panic!("output/sub_dir/file.png should exist")
}
}

View File

@ -68,7 +68,7 @@ pub fn copy_data_file(src_path: &str, dest_path: &Path) -> Result<(), Box<Error>
/// I.e. "data/_html-template/css/book.css" will be written to /// I.e. "data/_html-template/css/book.css" will be written to
/// "assets/css/book.css". /// "assets/css/book.css".
/// ///
/// ```no_run /// ```ignore
/// utils::fs::copy_data("data/_html-template/**/*", /// utils::fs::copy_data("data/_html-template/**/*",
/// "data/_html-template/", /// "data/_html-template/",
/// vec!["data/_html-template/_*"], /// vec!["data/_html-template/_*"],
@ -378,78 +378,3 @@ pub fn create_gitignore(proj: &MDBook) {
f.write_all(&text.into_bytes()).expect("Could not write to file."); f.write_all(&text.into_bytes()).expect("Could not write to file.");
} }
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
// tests
#[cfg(test)]
mod tests {
extern crate tempdir;
use super::copy_files_except_ext;
use std::fs;
#[test]
fn copy_files_except_ext_test() {
let tmp = match tempdir::TempDir::new("") {
Ok(t) => t,
Err(_) => panic!("Could not create a temp dir"),
};
// Create a couple of files
if let Err(_) = fs::File::create(&tmp.path().join("file.txt")) {
panic!("Could not create file.txt")
}
if let Err(_) = fs::File::create(&tmp.path().join("file.md")) {
panic!("Could not create file.md")
}
if let Err(_) = fs::File::create(&tmp.path().join("file.png")) {
panic!("Could not create file.png")
}
if let Err(_) = fs::create_dir(&tmp.path().join("sub_dir")) {
panic!("Could not create sub_dir")
}
if let Err(_) = fs::File::create(&tmp.path().join("sub_dir/file.png")) {
panic!("Could not create sub_dir/file.png")
}
if let Err(_) = fs::create_dir(&tmp.path().join("sub_dir_exists")) {
panic!("Could not create sub_dir_exists")
}
if let Err(_) = fs::File::create(&tmp.path().join("sub_dir_exists/file.txt")) {
panic!("Could not create sub_dir_exists/file.txt")
}
// Create output dir
if let Err(_) = fs::create_dir(&tmp.path().join("output")) {
panic!("Could not create output")
}
if let Err(_) = fs::create_dir(&tmp.path().join("output/sub_dir_exists")) {
panic!("Could not create output/sub_dir_exists")
}
match copy_files_except_ext(&tmp.path(), &tmp.path().join("output"), true, &["md"]) {
Err(e) => panic!("Error while executing the function:\n{:?}", e),
Ok(_) => {},
}
// Check if the correct files where created
if !(&tmp.path().join("output/file.txt")).exists() {
panic!("output/file.txt should exist")
}
if (&tmp.path().join("output/file.md")).exists() {
panic!("output/file.md should not exist")
}
if !(&tmp.path().join("output/file.png")).exists() {
panic!("output/file.png should exist")
}
if !(&tmp.path().join("output/sub_dir/file.png")).exists() {
panic!("output/sub_dir/file.png should exist")
}
if !(&tmp.path().join("output/sub_dir_exists/file.txt")).exists() {
panic!("output/sub_dir/file.png should exist")
}
}
}