summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs125
1 files changed, 60 insertions, 65 deletions
diff --git a/src/main.rs b/src/main.rs
index 25d1528..1ea25d2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,55 +11,60 @@ use vagabond::*;
use std::collections::HashSet;
use std::time::SystemTime;
+use log::{info, warn, error, fatal};
+use switchboard::{Switchboard, SwitchQuery};
-const NORMAL: &str = "\x1b[0m";
-const BOLD: &str = "\x1b[1m";
-const WHITE: &str = "\x1b[37m";
-const RED: &str = "\x1b[31m";
-const YELLOW: &str = "\x1b[33m";
-const BLUE: &str = "\x1b[34m";
-static mut VERBOSE: bool = false;
-#[macro_export] macro_rules! verbose {
- ($($tokens:tt)*) => { if unsafe { VERBOSE } {
- eprint!("{BOLD}{BLUE}[INFO]{NORMAL}: "); eprint!($($tokens)*);
- eprintln!("{NORMAL}");
- } };
-}
-#[macro_export] macro_rules! warn {
- ($($tokens:tt)*) => {{
- eprint!("{BOLD}{YELLOW}[WARNING]{NORMAL}{WHITE}: "); eprint!($($tokens)*);
- eprintln!("{NORMAL}");
- }};
+fn print_help() -> ! {
+ eprintln!("\
+Usage: toaster <source> <destination>
+
+Generate a website from a structured directory of markdown files.
+
+Arguments:
+ source Source directory with markdown files
+ destination Path to output directory
+
+Switches:
+ --delete Delete the destination directory first if it exists
+ --html Generate HTML output
+ --version, -v Print information as each file is parsed
+ --version Print the program version and exit
+ --help, -h Print help
+");
+ std::process::exit(0);
}
-#[macro_export] macro_rules! error {
- ($($tokens:tt)*) => {{
- eprint!("{BOLD}{RED}[ERROR]{WHITE}: "); eprint!($($tokens)*);
- eprintln!("{NORMAL}"); std::process::exit(1);
- }};
+
+fn print_version() -> ! {
+ let version = env!("CARGO_PKG_VERSION");
+ eprintln!("toaster, version {version}");
+ eprintln!("written by ben bridle");
+ std::process::exit(0);
}
+
fn main() {
- let args = Arguments::from_env_or_exit();
- if args.version {
- let version = env!("CARGO_PKG_VERSION");
- eprintln!("toaster, version {version}");
- std::process::exit(0);
+ let mut args = Switchboard::from_env();
+ if args.named("help").short('h').as_bool() {
+ print_help();
}
- if args.verbose {
- unsafe { VERBOSE = true; }
+ if args.named("version").as_bool() {
+ print_version();
}
- if args.source.is_none() || args.destination.is_none() {
- error!("Provide a source directory and a destination directory.")
+ if args.named("verbose").short('v').as_bool() {
+ log::set_log_level(log::LogLevel::Info);
}
- let source_directory = match args.source.as_ref().unwrap().canonicalize() {
- Ok(source_directory) => source_directory,
- Err(err) => error!("{:?}: {err}", args.source.unwrap()),
- };
- let destination_directory = args.destination.unwrap();
+ let source = args.positional("source").as_path();
+ let destination = args.positional("destination").as_path();
+ let delete_existing = args.named("delete").as_bool();
+ let export_html = args.named("html").as_bool();
+ let source = match source.canonicalize() {
+ Ok(source) => source,
+ Err(err) => fatal!("{source:?}: {err}"),
+ };
- let website = Website::from_path(&source_directory);
+ let website = Website::from_path(&source);
// Check for duplicate output paths for pages.
let mut destinations: HashSet<&str> = HashSet::new();
@@ -80,11 +85,11 @@ fn main() {
}
}
- let mut destination = destination_directory.clone();
+ let mut destination = destination;
destination.push(make_url_safe(&website.name));
- if args.delete && Entry::from_path(&destination).is_ok() {
- verbose!("Deleting existing destination directory {destination:?}");
+ if delete_existing && Entry::from_path(&destination).is_ok() {
+ info!("Deleting existing destination directory {destination:?}");
remove(&destination).unwrap_or_else(|_|
error!("Failed to delete existing destination directory {destination:?}"));
}
@@ -94,13 +99,13 @@ fn main() {
let mut destination = destination.clone();
destination.push(&page.full_url);
// Convert document to different formats.
- if args.html {
+ if export_html {
let html = generate_html(&page.document, page, &website);
write_file(&html, &destination, "html", page.last_modified);
}
// Copy original markdown file.
destination.add_extension("md");
- verbose!("Copying original markdown file to {destination:?}");
+ info!("Copying original markdown file to {destination:?}");
copy(&page.source_path, &destination).unwrap_or_else(|_|
error!("Failed to copy original markdown file {:?} to {:?}",
page.source_path, destination));
@@ -109,7 +114,7 @@ fn main() {
for static_file in &website.static_files {
let mut destination = destination.clone();
destination.push(&static_file.full_url);
- verbose!("Copying static file to {destination:?}");
+ info!("Copying static file to {destination:?}");
make_parent_directory(&destination).unwrap();
copy(&static_file.source_path, &destination).unwrap_or_else(|_|
error!("Failed to copy static file {:?} to {:?}",
@@ -122,7 +127,7 @@ fn main() {
let mut destination = destination.clone();
destination.push(&redirect.full_url);
let path = &redirect.redirect;
- if args.html {
+ if export_html {
if !path.contains("://") {
if let Some(path) = website.has_page(redirect, &path, "html") {
write_file(&generate_html_redirect(&path), &destination, "html", redirect.last_modified);
@@ -141,7 +146,7 @@ fn main() {
pub fn write_file(text: &str, destination: &PathBuf, ext: &str, last_modified: Option<SystemTime>) {
let mut destination = destination.clone();
destination.add_extension(ext);
- verbose!("Generating {destination:?}");
+ info!("Generating {destination:?}");
make_parent_directory(&destination).unwrap_or_else(|_|
error!("Failed to create parent directories for {destination:?}"));
write_to_file(&destination, text).unwrap_or_else(|_|
@@ -162,24 +167,14 @@ pub fn make_url_safe(text: &str) -> String {
.collect()
}
-
-
-xflags::xflags! {
- /// Generate a website from a structured directory of markdown files.
- cmd arguments {
- /// Source directory with markdown files
- optional source: PathBuf
- /// Path to output directory
- optional destination: PathBuf
- /// Delete the destination directory first if it exists
- optional --delete
- /// Generate HTML output
- optional --html
- /// Generate Gemtext output
- optional --gmi
- /// Print information as each file is parsed
- optional -v, --verbose
- /// Print the program version and exit
- optional --version
+pub fn url_encode(text: &str) -> String {
+ let mut output = String::new();
+ for c in text.chars() {
+ match c {
+ '"' => output.push_str("%22"),
+ '\'' => output.push_str("%27"),
+ _ => output.push(c),
+ }
}
+ return output;
}