`mdbook init` will stub out chapters if SUMMARY already exists

This commit is contained in:
Michael Bryan 2017-08-31 21:20:09 +08:00
parent f8cec4cef3
commit e89e6a04cd
2 changed files with 92 additions and 25 deletions

View File

@ -14,6 +14,7 @@ use tempdir::TempDir;
use {theme, utils}; use {theme, utils};
use renderer::{HtmlHandlebars, Renderer}; use renderer::{HtmlHandlebars, Renderer};
use self::summary::SummaryItem;
use preprocess; use preprocess;
use errors::*; use errors::*;
@ -174,12 +175,19 @@ impl MDBook {
let src = self.config.get_source(); let src = self.config.get_source();
let summary = src.join("SUMMARY.md"); let summary = src.join("SUMMARY.md");
if !summary.exists() { if summary.exists() && self.create_missing {
debug!("[*]: Creating SUMMARY.md"); // As a special case, if we run "mdbook init" on a book which
let mut f = File::create(&summary)?; // already has a summary we'll read that summary and create
writeln!(f, "{}", STUB_SUMMARY_CONTENTS)?; // stubs for any files which don't already exist (@azerupi likes
// having access to this shortcut).
return create_files_from_summary(&src, &summary);
} }
// We need to create the summary file
debug!("[*]: Creating SUMMARY.md");
let mut f = File::create(&summary)?;
writeln!(f, "{}", STUB_SUMMARY_CONTENTS)?;
let ch_1 = src.join("chapter_1.md"); let ch_1 = src.join("chapter_1.md");
if !ch_1.exists() { if !ch_1.exists() {
debug!("[*] Creating {}", ch_1.display()); debug!("[*] Creating {}", ch_1.display());
@ -443,61 +451,56 @@ impl MDBook {
pub fn with_theme_path<T: Into<PathBuf>>(mut self, theme_path: T) -> Self { pub fn with_theme_path<T: Into<PathBuf>>(mut self, theme_path: T) -> Self {
let root = self.config.get_root().to_owned(); let root = self.config.get_root().to_owned();
self.config.get_mut_html_config() self.config
.get_mut_html_config()
.set_theme(&root, &theme_path.into()); .set_theme(&root, &theme_path.into());
self self
} }
pub fn get_theme_path(&self) -> &Path { pub fn get_theme_path(&self) -> &Path {
self.config.get_html_config() self.config.get_html_config().get_theme()
.get_theme()
} }
pub fn with_curly_quotes(mut self, curly_quotes: bool) -> Self { pub fn with_curly_quotes(mut self, curly_quotes: bool) -> Self {
self.config.get_mut_html_config() self.config
.get_mut_html_config()
.set_curly_quotes(curly_quotes); .set_curly_quotes(curly_quotes);
self self
} }
pub fn get_curly_quotes(&self) -> bool { pub fn get_curly_quotes(&self) -> bool {
self.config.get_html_config() self.config.get_html_config().get_curly_quotes()
.get_curly_quotes()
} }
pub fn with_mathjax_support(mut self, mathjax_support: bool) -> Self { pub fn with_mathjax_support(mut self, mathjax_support: bool) -> Self {
self.config.get_mut_html_config() self.config
.get_mut_html_config()
.set_mathjax_support(mathjax_support); .set_mathjax_support(mathjax_support);
self self
} }
pub fn get_mathjax_support(&self) -> bool { pub fn get_mathjax_support(&self) -> bool {
self.config.get_html_config() self.config.get_html_config().get_mathjax_support()
.get_mathjax_support()
} }
pub fn get_google_analytics_id(&self) -> Option<String> { pub fn get_google_analytics_id(&self) -> Option<String> {
self.config.get_html_config() self.config.get_html_config().get_google_analytics_id()
.get_google_analytics_id()
} }
pub fn has_additional_js(&self) -> bool { pub fn has_additional_js(&self) -> bool {
self.config.get_html_config() self.config.get_html_config().has_additional_js()
.has_additional_js()
} }
pub fn get_additional_js(&self) -> &[PathBuf] { pub fn get_additional_js(&self) -> &[PathBuf] {
self.config.get_html_config() self.config.get_html_config().get_additional_js()
.get_additional_js()
} }
pub fn has_additional_css(&self) -> bool { pub fn has_additional_css(&self) -> bool {
self.config.get_html_config() self.config.get_html_config().has_additional_css()
.has_additional_css()
} }
pub fn get_additional_css(&self) -> &[PathBuf] { pub fn get_additional_css(&self) -> &[PathBuf] {
self.config.get_html_config() self.config.get_html_config().get_additional_css()
.get_additional_css()
} }
pub fn get_html_config(&self) -> &HtmlConfig { pub fn get_html_config(&self) -> &HtmlConfig {
@ -513,3 +516,47 @@ impl MDBook {
Ok(()) Ok(())
} }
} }
fn create_files_from_summary(src: &Path, summary_path: &Path) -> Result<()> {
debug!("[fn]: create_files_from_summary");
let summary = summary::parse_summary(&utils::fs::file_to_string(summary_path)?)?;
debug!("[*]: parsed existing summary");
trace!("[*]: {:#?}", summary);
create_list_of_stub_chapters(&summary.prefix_chapters, src)?;
create_list_of_stub_chapters(&summary.numbered_chapters, src)?;
create_list_of_stub_chapters(&summary.suffix_chapters, src)?;
debug!("[*]: Finished creating stub chapters using for a SUMMARY.md");
Ok(())
}
fn create_list_of_stub_chapters(chapters: &[SummaryItem], src_dir: &Path) -> Result<()> {
for summary_item in chapters {
if let SummaryItem::Link(ref ch) = *summary_item {
let location = src_dir.join(&ch.location);
debug!("{} + {} => {}", src_dir.display(), ch.location.display(), location.display());
create_stub_chapter(&ch.name, &location)?;
create_list_of_stub_chapters(&ch.nested_items, src_dir)?;
}
}
Ok(())
}
fn create_stub_chapter(name: &str, path: &Path) -> Result<()> {
debug!("[*]: Creating stub for \"{}\" at {}", name, path.display());
if let Some(parent) = path.parent() {
if !parent.exists() {
fs::create_dir_all(parent)?;
}
}
if !path.exists() {
let mut f = File::create(path)?;
writeln!(f, "# {}", name)?;
}
Ok(())
}

View File

@ -1,3 +1,4 @@
extern crate env_logger;
extern crate mdbook; extern crate mdbook;
extern crate tempdir; extern crate tempdir;
@ -77,14 +78,14 @@ fn check_correct_cross_links_in_nested_dir() {
assert_contains_strings( assert_contains_strings(
first.join("index.html"), first.join("index.html"),
&[ &[
r##"href="./first/index.html#some-section" id="some-section""## r##"href="./first/index.html#some-section" id="some-section""##,
], ],
); );
assert_contains_strings( assert_contains_strings(
first.join("nested.html"), first.join("nested.html"),
&[ &[
r##"href="./first/nested.html#some-section" id="some-section""## r##"href="./first/nested.html#some-section" id="some-section""##,
], ],
); );
} }
@ -106,6 +107,8 @@ fn rendered_code_has_playpen_stuff() {
#[test] #[test]
fn chapter_content_appears_in_rendered_document() { fn chapter_content_appears_in_rendered_document() {
env_logger::init().ok();
let content = vec![ let content = vec![
("index.html", "Here's some interesting text"), ("index.html", "Here's some interesting text"),
("second.html", "Second Chapter"), ("second.html", "Second Chapter"),
@ -125,3 +128,20 @@ fn chapter_content_appears_in_rendered_document() {
assert_contains_strings(path, &[text]); assert_contains_strings(path, &[text]);
} }
} }
#[test]
fn chapter_1_file_not_created_if_summary_already_exists() {
let temp = DummyBook::default().build();
let src = temp.path().join("src");
let summary = src.join("SUMMARY.md");
let chapter_1 = src.join("chapter_1.md");
assert!(summary.exists());
assert!(!chapter_1.exists());
let mut md = MDBook::new(temp.path());
md.build().unwrap();
assert!(!chapter_1.exists());
}