Adding for content to book.toml on init (#627)

* Obtaining author name from gitconfig

* Writing theme to config on init

* Addressing a FIXME came across

* Add request for book title.
This commit is contained in:
Dylan Maccora 2018-03-15 02:27:56 +11:00 committed by Michael Bryan
parent cc92d665ca
commit 07719a8e0e
3 changed files with 70 additions and 12 deletions

View File

@ -1,8 +1,11 @@
use std::io; use std::io;
use std::io::Write; use std::io::Write;
use std::env;
use clap::{App, ArgMatches, SubCommand}; use clap::{App, ArgMatches, SubCommand};
use mdbook::MDBook; use mdbook::MDBook;
use mdbook::errors::Result; use mdbook::errors::Result;
use mdbook::utils;
use mdbook::config;
use get_book_dir; use get_book_dir;
// Create clap subcommand arguments // Create clap subcommand arguments
@ -20,9 +23,11 @@ pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
pub fn execute(args: &ArgMatches) -> Result<()> { pub fn execute(args: &ArgMatches) -> Result<()> {
let book_dir = get_book_dir(args); let book_dir = get_book_dir(args);
let mut builder = MDBook::init(&book_dir); let mut builder = MDBook::init(&book_dir);
let mut config = config::Config::default();
// If flag `--theme` is present, copy theme to src // If flag `--theme` is present, copy theme to src
if args.is_present("theme") { if args.is_present("theme") {
config.set("output.html.theme", "src/theme")?;
// Skip this if `--force` is present // Skip this if `--force` is present
if !args.is_present("force") { if !args.is_present("force") {
// Print warning // Print warning
@ -38,6 +43,8 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
if confirm() { if confirm() {
builder.copy_theme(true); builder.copy_theme(true);
} }
} else {
builder.copy_theme(true);
} }
} }
@ -47,13 +54,54 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
builder.create_gitignore(true); builder.create_gitignore(true);
} }
config.book.title = request_book_title();
if let Some(author) = get_author_name() {
debug!("Obtained user name from gitconfig: {:?}", author);
config.book.authors.push(author);
builder.with_config(config);
}
builder.build()?; builder.build()?;
println!("\nAll done, no errors..."); println!("\nAll done, no errors...");
Ok(()) Ok(())
} }
// Simple function that user comfirmation /// Obtains author name from git config file if it can be located.
fn get_author_name() -> Option<String> {
if let Some(home) = env::home_dir() {
let git_config_path = home.join(".gitconfig");
let content = utils::fs::file_to_string(git_config_path).unwrap();
let user_name = content
.lines()
.filter(|x| !x.starts_with("#"))
.map(|x| x.trim_left())
.filter(|x| x.starts_with("name"))
.next();
user_name
.and_then(|x| x.rsplit("=").next())
.map(|x| x.trim().to_owned())
} else {
None
}
}
/// Request book title from user and return if provided.
fn request_book_title() -> Option<String> {
println!("What title would you like to give the book? ");
io::stdout().flush().unwrap();
let mut resp = String::new();
io::stdin().read_line(&mut resp).unwrap();
let resp = resp.trim();
if resp.is_empty() {
None
} else {
Some(resp.into())
}
}
// Simple function for user confirmation
fn confirm() -> bool { fn confirm() -> bool {
io::stdout().flush().unwrap(); io::stdout().flush().unwrap();
let mut s = String::new(); let mut s = String::new();

View File

@ -288,13 +288,12 @@ impl MDBook {
self.root.join(&self.config.book.src) self.root.join(&self.config.book.src)
} }
// FIXME: This really belongs as part of the `HtmlConfig`. /// Get the directory containing the theme resources for the book.
#[doc(hidden)]
pub fn theme_dir(&self) -> PathBuf { pub fn theme_dir(&self) -> PathBuf {
match self.config.html_config().and_then(|h| h.theme) { self.config
Some(d) => self.root.join(d), .html_config()
None => self.root.join("theme"), .unwrap_or_default()
} .theme_dir(&self.root)
} }
} }

View File

@ -383,7 +383,6 @@ pub struct BuildConfig {
pub create_missing: bool, pub create_missing: bool,
/// Which preprocessors should be applied /// Which preprocessors should be applied
pub preprocess: Option<Vec<String>>, pub preprocess: Option<Vec<String>>,
} }
impl Default for BuildConfig { impl Default for BuildConfig {
@ -429,6 +428,17 @@ pub struct HtmlConfig {
pub search: Option<Search>, pub search: Option<Search>,
} }
impl HtmlConfig {
/// Returns the directory of theme from the provided root directory. If the
/// directory is not present it will append the default directory of "theme"
pub fn theme_dir(&self, root: &PathBuf) -> PathBuf {
match self.theme {
Some(ref d) => root.join(d),
None => root.join("theme"),
}
}
}
/// Configuration for tweaking how the the HTML renderer handles the playpen. /// Configuration for tweaking how the the HTML renderer handles the playpen.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(default, rename_all = "kebab-case")] #[serde(default, rename_all = "kebab-case")]
@ -497,7 +507,6 @@ impl Default for Search {
} }
} }
/// Allows you to "update" any arbitrary field in a struct by round-tripping via /// Allows you to "update" any arbitrary field in a struct by round-tripping via
/// a `toml::Value`. /// a `toml::Value`.
/// ///
@ -570,8 +579,10 @@ mod tests {
let build_should_be = BuildConfig { let build_should_be = BuildConfig {
build_dir: PathBuf::from("outputs"), build_dir: PathBuf::from("outputs"),
create_missing: false, create_missing: false,
preprocess: Some(vec!["first_preprocessor".to_string(), preprocess: Some(vec![
"second_preprocessor".to_string()]), "first_preprocessor".to_string(),
"second_preprocessor".to_string(),
]),
}; };
let playpen_should_be = Playpen { let playpen_should_be = Playpen {
editable: true, editable: true,