Finalize new page -command
This commit is contained in:
parent
5b69245697
commit
cb09cb694b
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -71,6 +71,11 @@ dependencies = [
|
|||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pathdiff"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
@ -193,6 +198,7 @@ name = "teascade-generator"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pathdiff 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -304,6 +310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
|
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
|
||||||
"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b"
|
"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b"
|
||||||
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
|
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
|
||||||
|
"checksum pathdiff 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a3bf70094d203e07844da868b634207e71bfab254fe713171fae9a6e751ccf31"
|
||||||
"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
|
"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
|
||||||
"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
|
"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
|
||||||
"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
|
"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
|
||||||
|
@ -11,3 +11,4 @@ serde = "*"
|
|||||||
serde_derive = "*"
|
serde_derive = "*"
|
||||||
regex = "*"
|
regex = "*"
|
||||||
ansi_term = "*"
|
ansi_term = "*"
|
||||||
|
pathdiff = "*"
|
@ -9,13 +9,13 @@ use std::collections::HashMap;
|
|||||||
use logger::LogLevel;
|
use logger::LogLevel;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
|
|
||||||
#[derive(Deserialize, Clone, Debug)]
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
pub struct GlobalConfigToml {
|
pub struct GlobalConfigToml {
|
||||||
pub website: WebsiteConfig,
|
pub website: WebsiteConfig,
|
||||||
pub navbar: Option<NavbarConfig>,
|
pub navbar: Option<NavbarConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Clone, Debug)]
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
pub struct WebsiteConfig {
|
pub struct WebsiteConfig {
|
||||||
pub website_name: String,
|
pub website_name: String,
|
||||||
pub built_pages: Vec<String>,
|
pub built_pages: Vec<String>,
|
||||||
@ -31,14 +31,14 @@ pub struct WebsiteConfig {
|
|||||||
pub google_site_verification: Option<String>,
|
pub google_site_verification: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Clone, Debug)]
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
pub struct NavbarConfig {
|
pub struct NavbarConfig {
|
||||||
pub items: Vec<String>,
|
pub items: Vec<String>,
|
||||||
#[serde(rename = "item")]
|
#[serde(rename = "item")]
|
||||||
pub item_map: HashMap<String, NavbarItem>,
|
pub item_map: HashMap<String, NavbarItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Clone, Debug)]
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
pub struct NavbarItem {
|
pub struct NavbarItem {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub link: String,
|
pub link: String,
|
||||||
@ -69,7 +69,7 @@ impl GlobalConfigToml {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Clone, Debug)]
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
pub struct PageConfigToml {
|
pub struct PageConfigToml {
|
||||||
pub page: PageConfig,
|
pub page: PageConfig,
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ impl PageConfigToml {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Clone, Debug)]
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
pub struct PageConfig {
|
pub struct PageConfig {
|
||||||
pub html_path: String,
|
pub html_path: String,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
|
@ -8,7 +8,6 @@ use logger::LogLevel;
|
|||||||
pub fn add_to_beginning<T: Into<String>>(path: PathBuf, to_add: T) -> Result<PathBuf, Error> {
|
pub fn add_to_beginning<T: Into<String>>(path: PathBuf, to_add: T) -> Result<PathBuf, Error> {
|
||||||
if let (Some(parent), Some(file_name)) = (path.clone().parent(), path.clone().file_name()) {
|
if let (Some(parent), Some(file_name)) = (path.clone().parent(), path.clone().file_name()) {
|
||||||
let parent = Path::new(&to_add.into()).join(parent);
|
let parent = Path::new(&to_add.into()).join(parent);
|
||||||
create_dir_all(parent.clone())?;
|
|
||||||
Ok(parent.join(file_name))
|
Ok(parent.join(file_name))
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
@ -23,6 +22,15 @@ pub fn write_file<T: Into<String>>(
|
|||||||
content: T,
|
content: T,
|
||||||
overwrite: bool,
|
overwrite: bool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
if let Some(parent) = path.clone().parent() {
|
||||||
|
create_dir_all(parent.clone())?;
|
||||||
|
} else {
|
||||||
|
return Err(Error::new(
|
||||||
|
LogLevel::SEVERE,
|
||||||
|
format!("Could not find parent folder for {:?}", path),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
let content = content.into();
|
let content = content.into();
|
||||||
if path.exists() && !overwrite {
|
if path.exists() && !overwrite {
|
||||||
Err(Error::new(
|
Err(Error::new(
|
||||||
|
23
src/main.rs
23
src/main.rs
@ -1,4 +1,5 @@
|
|||||||
extern crate ansi_term;
|
extern crate ansi_term;
|
||||||
|
extern crate pathdiff;
|
||||||
extern crate pulldown_cmark;
|
extern crate pulldown_cmark;
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -15,6 +16,7 @@ mod config;
|
|||||||
mod template;
|
mod template;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
mod builder;
|
mod builder;
|
||||||
|
mod new_page;
|
||||||
mod file_writer;
|
mod file_writer;
|
||||||
|
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
@ -36,16 +38,15 @@ fn main() {
|
|||||||
logger.log(LogLevel::SEVERE, "Aborting building due to error.");
|
logger.log(LogLevel::SEVERE, "Aborting building due to error.");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Subcommands::New(ops) => {
|
Subcommands::New(ops) => match new_page::generate_new_page(ops, &logger) {
|
||||||
logger.log(
|
Ok(_) => logger.log(
|
||||||
LogLevel::DETAIL,
|
LogLevel::DETAILER,
|
||||||
format!("Creating a new .toml file at {:?}", ops.toml_path),
|
"Generating the new page finished successfully.",
|
||||||
);
|
),
|
||||||
|
Err(err) => {
|
||||||
match file_writer::write_file(ops.toml_path, "Hello!", ops.overwrite) {
|
logger.log(err.severity(), err.description());
|
||||||
Ok(_) => logger.log(LogLevel::INFO, "Done."),
|
logger.log(LogLevel::SEVERE, "Aborting building due to error.");
|
||||||
Err(err) => logger.log(err.severity(), err.description()),
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
133
src/new_page.rs
Normal file
133
src/new_page.rs
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
use std::path::PathBuf;
|
||||||
|
use std::error::Error as STDError;
|
||||||
|
|
||||||
|
use options::NewOps;
|
||||||
|
use logger::{LogLevel, Logger};
|
||||||
|
use file_writer;
|
||||||
|
use error::Error;
|
||||||
|
use config_toml::{PageConfig, PageConfigToml};
|
||||||
|
|
||||||
|
use toml;
|
||||||
|
use pathdiff;
|
||||||
|
|
||||||
|
const PLACEHOLDER_MARKDOWN: &'static str =
|
||||||
|
r#"# Placeholder title
|
||||||
|
This is the markdown file, where you will insert this page's contents.
|
||||||
|
- This is an example list
|
||||||
|
- And in lists
|
||||||
|
- You can even make inner lists, as well as **bold**, and _italics_
|
||||||
|
|
||||||
|
See [CommonMark](http://commonmark.org/help/) for reference."#;
|
||||||
|
|
||||||
|
pub fn generate_new_page(ops: NewOps, logger: &Logger) -> Result<(), Error> {
|
||||||
|
logger.log(
|
||||||
|
LogLevel::DETAILER,
|
||||||
|
format!("Starting to create paths for given files"),
|
||||||
|
);
|
||||||
|
|
||||||
|
let toml_path = ensure_extension(ops.toml_path, "toml", false)?;
|
||||||
|
|
||||||
|
let markdown_path;
|
||||||
|
if let Some(markdown) = ops.markdown_path {
|
||||||
|
markdown_path = ensure_extension(markdown, "md", false)?;
|
||||||
|
} else {
|
||||||
|
markdown_path = ensure_extension(toml_path.clone(), "md", true)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.log(
|
||||||
|
LogLevel::DETAIL,
|
||||||
|
format!("Creating a new .toml file at {:?}", toml_path),
|
||||||
|
);
|
||||||
|
|
||||||
|
let html_path;
|
||||||
|
if let Some(path) = ops.html_path {
|
||||||
|
html_path = ensure_extension(path, "html", false)?;
|
||||||
|
} else {
|
||||||
|
html_path = ensure_extension(toml_path.clone(), "html", true)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let title: String;
|
||||||
|
if let Some(t) = ops.title {
|
||||||
|
title = t;
|
||||||
|
} else {
|
||||||
|
let mut parts = toml_path.file_name().unwrap().to_str().unwrap().split(".");
|
||||||
|
title = parts.next().unwrap().to_owned();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut relative_markdown_path = markdown_path.clone();
|
||||||
|
if let Some(toml_parent) = toml_path.parent() {
|
||||||
|
if let Some(relative) = pathdiff::diff_paths(markdown_path.as_path(), toml_parent) {
|
||||||
|
relative_markdown_path = relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let page_config = PageConfigToml {
|
||||||
|
page: PageConfig {
|
||||||
|
html_path: html_path.to_str().unwrap().to_owned(),
|
||||||
|
title: title,
|
||||||
|
description: String::new(),
|
||||||
|
content_path: relative_markdown_path.to_str().unwrap().to_owned(),
|
||||||
|
favicon: None,
|
||||||
|
before_navbar_url: None,
|
||||||
|
before_content_url: None,
|
||||||
|
after_content_url: None,
|
||||||
|
javascript: None,
|
||||||
|
css: None,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
match toml::ser::to_string_pretty(&page_config) {
|
||||||
|
Ok(text) => file_writer::write_file(toml_path.clone(), text, ops.overwrite)?,
|
||||||
|
Err(err) => {
|
||||||
|
return Err(Error::new(
|
||||||
|
LogLevel::SEVERE,
|
||||||
|
format!(
|
||||||
|
"Failed to serialize page config: {}",
|
||||||
|
err.description().to_owned()
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.log(
|
||||||
|
LogLevel::DETAIL,
|
||||||
|
format!("Creating a new .md file at {:?}", markdown_path),
|
||||||
|
);
|
||||||
|
|
||||||
|
file_writer::write_file(markdown_path, PLACEHOLDER_MARKDOWN, ops.overwrite)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ensure_extension<T: Into<String>>(
|
||||||
|
mut path: PathBuf,
|
||||||
|
extension: T,
|
||||||
|
replace_extension: bool,
|
||||||
|
) -> Result<PathBuf, Error> {
|
||||||
|
let extension = extension.into();
|
||||||
|
|
||||||
|
if let (Some(parent), Some(file_name)) = (path.clone().parent(), path.clone().file_name()) {
|
||||||
|
let mut filename = file_name.to_str().unwrap().to_owned();
|
||||||
|
let clone = filename.clone();
|
||||||
|
let mut split = clone.split(".");
|
||||||
|
if split.clone().count() == 1 as usize {
|
||||||
|
path = parent.join(format!("{}.{}", filename, extension));
|
||||||
|
} else if replace_extension {
|
||||||
|
let amount = split.clone().count() - 1;
|
||||||
|
filename = split
|
||||||
|
.clone()
|
||||||
|
.take(amount)
|
||||||
|
.map(|i| format!("{}.", i))
|
||||||
|
.collect::<String>();
|
||||||
|
|
||||||
|
path = parent.join(format!("{}{}", filename, extension));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(path)
|
||||||
|
} else {
|
||||||
|
Err(Error::new(
|
||||||
|
LogLevel::SEVERE,
|
||||||
|
format!("Could not find parent/file_name for {:?}", path),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
@ -41,6 +41,12 @@ pub struct NewOps {
|
|||||||
/// File path for the markdown file created
|
/// File path for the markdown file created
|
||||||
#[structopt(short = "m", long = "markdown", parse(from_os_str))]
|
#[structopt(short = "m", long = "markdown", parse(from_os_str))]
|
||||||
pub markdown_path: Option<PathBuf>,
|
pub markdown_path: Option<PathBuf>,
|
||||||
|
/// Outpuh html file path of the generated page
|
||||||
|
#[structopt(short = "h", long = "html", parse(from_os_str))]
|
||||||
|
pub html_path: Option<PathBuf>,
|
||||||
|
/// Sets the title of the generated page
|
||||||
|
#[structopt(short = "t", long = "title")]
|
||||||
|
pub title: Option<String>,
|
||||||
/// Overwrites existing .toml / .md files
|
/// Overwrites existing .toml / .md files
|
||||||
#[structopt(short = "o", long = "overwrite")]
|
#[structopt(short = "o", long = "overwrite")]
|
||||||
pub overwrite: bool,
|
pub overwrite: bool,
|
||||||
|
@ -1 +0,0 @@
|
|||||||
Hello!
|
|
Loading…
Reference in New Issue
Block a user