diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..e00467b
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,113 @@
+//! # nyf
+//!
+//! _glyph's static site generator_
+//!
+//! This is an opinionated, custom-built HTML splicer. It reads HTML templates, splices
+//! them into a base template and writes the output.
+//!
+//! Templates are expected at `./templates` and output is written to `./site`. The `./site`
+//! directory will be created if it doesn't exist.
+//!
+//! A base template is expected at `./templates/base.html`. It must contain two tags:
+//! `[[ title ]]` and `[[ content ]]`.
+//!
+//! The root index template is expected at `./templates/index.html`. All other templates are
+//! expected to be in sub-directories; for example: `./templates/plants/index.html` or
+//! `./templates/fungi/entomopathogens.html`.
+//!
+//! The splicer crawls the sub-directories of `./templates`, reads each HTML file, splices
+//! it into the `[[ content ]]` tag of the base HTML template and writes the output to the
+//! `./site` directory (preserving the sub-directory structure). The contents of the `
`
+//! element are spliced into the `[[ title ]]` tag of the base HTML template for each
+//! sub-directory template.
+//!
+use std::{fs, io, path::Path};
+
+// define the path for the template directory
+const TEMPLATE_DIR: &str = "./templates";
+// define the path for the generated site output
+const SITE_DIR: &str = "./site";
+
+pub fn run() -> Result<(), &'static str> {
+ // read the base html template to a string
+ let base = format!("{}/base.html", TEMPLATE_DIR);
+ let base_path = Path::new(&base);
+ let base_html = fs::read_to_string(base_path)
+ .map_err(|_| "couldn't read from templates/base.html; does it exist?")?;
+
+ // read the index html template to a string
+ let index = format!("{}/index.html", TEMPLATE_DIR);
+ let index_path = Path::new(&index);
+ let index_html = fs::read_to_string(index_path)
+ .map_err(|_| "couldn't read from templates/index.html; does it exist?")?;
+
+ // create site directory if it doesn't already exist
+ let site_dir_path = Path::new(&SITE_DIR);
+ if !site_dir_path.is_dir() {
+ fs::create_dir(site_dir_path).map_err(|_| "failed to create site output directory")?;
+ }
+
+ // integrate the content from the index template into the base template
+ let mut index_output = base_html.replace("[[ content ]]", &index_html);
+ // set the page title
+ index_output = index_output.replace("[[ title ]]", "mycelial technology");
+ let index_output_path = format!("{}/index.html", SITE_DIR);
+ // write the generated index html to file
+ fs::write(index_output_path, index_output.trim())
+ .map_err(|_| "failed to write the root index.html file")?;
+
+ // walk the template directory and collect paths for all files and sub-directories
+ let template_files: Vec<_> = fs::read_dir(TEMPLATE_DIR)
+ .map_err(|_| "failed to read template directory")?
+ .map(|res| res.map(|e| e.path()))
+ .collect::, io::Error>>()
+ .map_err(|_| "failed to collect template file paths")?;
+
+ // loop through each file and sub-directory
+ for entry in template_files {
+ if entry.is_dir() {
+ // replicate templates sub-directory structure in site output directory
+ let template_sub_dir_suffix = entry
+ .strip_prefix(TEMPLATE_DIR)
+ .map_err(|_| "failed to strip prefix from template directory path")?;
+ let site_sub_dir = Path::new(SITE_DIR).join(template_sub_dir_suffix);
+ // create the sub-directory if it doesn't already exist
+ if !site_sub_dir.is_dir() {
+ fs::create_dir(site_sub_dir)
+ .map_err(|_| "failed to create a site output sub-directory")?;
+ }
+ // read each file from the sub-directory
+ for file in fs::read_dir(entry)
+ .map_err(|_| "failed to enumerate template sub-directory files")?
+ {
+ let file = file.map_err(|_| "failed to obtain sub-directory file data")?;
+ let file_path = file.path();
+ let file_html = fs::read_to_string(&file_path)
+ .map_err(|_| "failed to read template html file to string")?;
+ // find the index of the h2 tag (represents the page title)
+ let mut title_start = file_html.find("").ok_or(" tag not found in html")?;
+ // increment the index to represent the start of the title text
+ title_start += 4;
+ // find the index of the h2 closing tag
+ let title_end = file_html
+ .find("
")
+ .ok_or("
tag not found in html")?;
+ // obtain the title text as a string slice
+ let title = &file_html[title_start..title_end];
+ // integrate the content from the template into the base template
+ let mut file_output = base_html.replace("[[ content ]]", &file_html);
+ // integrate the title of the page into the file output
+ file_output = file_output.replace("[[ title ]]", title);
+ // define the path to which the output html file will be written
+ let file_output_path = file_path.to_string_lossy();
+ // replace the template directory path with the site output path
+ let output_path = file_output_path.replace(TEMPLATE_DIR, SITE_DIR);
+ // trim whitespace from the end of the generated html and write to file
+ fs::write(output_path, file_output.trim())
+ .map_err(|_| "failed to write html file to site directory")?
+ }
+ }
+ }
+
+ Ok(())
+}
diff --git a/src/main.rs b/src/main.rs
index 20e58ef..3bae31a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,107 +1,8 @@
-//! # nyf
-//!
-//! _glyph's static site generator_
-//!
-//! This is an opinionated, custom-built HTML splicer. It reads HTML templates, splices
-//! them into a base template and writes the output.
-//!
-//! Templates are expected at `./templates` and output is written to `./site`. The `./site`
-//! directory will be created if it doesn't exist.
-//!
-//! A base template is expected at `./templates/base.html`. It must contain two tags:
-//! `[[ title ]]` and `[[ content ]]`.
-//!
-//! The root index template is expected at `./templates/index.html`. All other templates are
-//! expected to be in sub-directories; for example: `./templates/plants/index.html` or
-//! `./templates/fungi/entomopathogens.html`.
-//!
-//! The splicer crawls the sub-directories of `./templates`, reads each HTML file, splices
-//! it into the `[[ content ]]` tag of the base HTML template and writes the output to the
-//! `./site` directory (preserving the sub-directory structure). The contents of the ``
-//! element are spliced into the `[[ title ]]` tag of the base HTML template for each
-//! sub-directory template.
-//!
-use std::{fs, io, path::Path};
-
-// define the path for the template directory
-const TEMPLATE_DIR: &str = "./templates";
-// define the path for the generated site output
-const SITE_DIR: &str = "./site";
+use std::process;
fn main() {
- // read the base html template to a string
- let base = format!("{}/base.html", TEMPLATE_DIR);
- let base_path = Path::new(&base);
- let base_html = fs::read_to_string(base_path)
- .expect("couldn't read from templates/base.html; does it exist?");
-
- // read the index html template to a string
- let index = format!("{}/index.html", TEMPLATE_DIR);
- let index_path = Path::new(&index);
- let index_html = fs::read_to_string(index_path)
- .expect("couldn't read from templates/index.html; does it exist?");
-
- // create site directory if it doesn't already exist
- let site_dir_path = Path::new(&SITE_DIR);
- if !site_dir_path.is_dir() {
- fs::create_dir(site_dir_path).expect("failed to create site output directory");
- }
-
- // integrate the content from the index template into the base template
- let mut index_output = base_html.replace("[[ content ]]", &index_html);
- // set the page title
- index_output = index_output.replace("[[ title ]]", "mycelial technology");
- let index_output_path = format!("{}/index.html", SITE_DIR);
- // write the generated index html to file
- fs::write(index_output_path, index_output.trim())
- .expect("failed to write the root index.html file");
-
- // walk the template directory and collect paths for all files and sub-directories
- let template_files: Vec<_> = fs::read_dir(TEMPLATE_DIR)
- .expect("failed to read template directory")
- .map(|res| res.map(|e| e.path()))
- .collect::, io::Error>>()
- .expect("failed to collect template file paths");
-
- // loop through each file and sub-directory
- for entry in template_files {
- if entry.is_dir() {
- // replicate templates sub-directory structure in site output directory
- let template_sub_dir_suffix = entry
- .strip_prefix(TEMPLATE_DIR)
- .expect("failed to strip prefix from template directory path");
- let site_sub_dir = Path::new(SITE_DIR).join(template_sub_dir_suffix);
- // create the sub-directory if it doesn't already exist
- if !site_sub_dir.is_dir() {
- fs::create_dir(site_sub_dir).expect("failed to create a site output sub-directory");
- }
- // read each file from the sub-diretory
- for file in fs::read_dir(entry).expect("failed to read file in template sub-directory")
- {
- let file = file.unwrap();
- let file_path = file.path();
- let file_html = fs::read_to_string(&file_path)
- .expect("failed to read template html file to string");
- // find the index of the h2 tag (represents the page title)
- let mut title_start = file_html.find("").expect(" tag not found");
- // increment the index to represent the start of the title text
- title_start += 4;
- // find the index of the h2 closing tag
- let title_end = file_html.find("
").expect("
tag not found");
- // obtain the title text as a string slice
- let title = &file_html[title_start..title_end];
- // integrate the content from the template into the base template
- let mut file_output = base_html.replace("[[ content ]]", &file_html);
- // integrate the title of the page into the file output
- file_output = file_output.replace("[[ title ]]", title);
- // define the path to which the output html file will be written
- let file_output_path = file_path.to_string_lossy();
- // replace the template directory path with the site output path
- let output_path = file_output_path.replace(TEMPLATE_DIR, SITE_DIR);
- // trim whitespace from the end of the generated html and write to file
- fs::write(output_path, file_output.trim())
- .expect("failed to write html file to site directory")
- }
- }
+ if let Err(e) = nyf::run() {
+ eprintln!("error: {}", e);
+ process::exit(1);
}
}