Skip to content

Commit

Permalink
Default to a simpler static site generation
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Brue <[email protected]>
  • Loading branch information
ryanabx committed Dec 14, 2024
1 parent 1053b18 commit a7026cd
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 7 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target
/test
/docs-out
/docs-out
/out
2 changes: 1 addition & 1 deletion docs/command_reference.dj → docs/command_reference.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Djot command reference

[Back to main page](./index.dj)
[Back to main page](./index.md)

## Installation

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[Back to home page](../index.dj)
[Back to home page](../index.md)

# Contact Ryanabx

Expand Down
2 changes: 1 addition & 1 deletion docs/notes/djot-example.dj → docs/notes/djot-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ This is a simple djot example to showcase this static site generator! It gets pu

---

For more, see the [Markdown example](./markdown-example.md) and go to the command reference at [../command_reference.dj](../command_reference.dj)
For more, see the [Markdown example](./markdown-example.md) and go to the command reference at [../command_reference.md](../command_reference.md)
4 changes: 2 additions & 2 deletions docs/notes/markdown-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This static site generator also supports Markdown, using [pulldown-cmark](https://github.com/pulldown-cmark/pulldown-cmark)!

This provides an example of using markdown alongside djot documents in the same static site! See: [../index.dj](../index.dj) for the home page, and [../command_reference](../command_reference.dj) for the command reference!
This provides an example of using markdown alongside djot documents in the same static site! See: [../index.md](../index.md) for the home page, and [../command_reference](../command_reference.md) for the command reference!


Contact me [here](contact-ryanabx.dj)
Contact me [here](contact-ryanabx.md)
108 changes: 107 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use jotdown::{Container, Event};
use pulldown_cmark::{CowStr, Options};
use std::{
env,
fs::{self, read_dir},
path::{Path, PathBuf},
};
use templates::BuiltInTemplate;
Expand All @@ -17,6 +18,8 @@ mod templates;
mod tests;
mod utils;

mod markdown;

/// Djot static site generator
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
Expand All @@ -40,13 +43,37 @@ struct ConsoleArgs {
/// directories.
#[arg(short, long)]
template: Option<BuiltInTemplate>,
/// Try the legacy method of generating a static site
#[arg(long)]
legacy: bool,
}

fn main() -> anyhow::Result<()> {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init();
log::trace!("Begin simple-ssg::main()");
let args = ConsoleArgs::parse();
run_program(args)
if args.legacy {
run_program(args)
} else {
run_program_2(args)
}
}

fn run_program_2(args: ConsoleArgs) -> anyhow::Result<()> {
if args.directory.is_none()
|| args.file.is_some()
|| args.template.is_some()
|| args.output_path.is_none()
{
log::error!("Args incorrect");
anyhow::bail!("Args incorrect");
}
generate_site_2(
&args.directory.unwrap(),
&args.output_path.unwrap(),
args.web_prefix.as_deref(),
)?;
Ok(())
}

fn run_program(args: ConsoleArgs) -> anyhow::Result<()> {
Expand Down Expand Up @@ -112,6 +139,85 @@ pub enum FirstPassResult {
},
}

fn generate_site_2(
root_dir: &Path,
output_dir: &Path,
web_prefix: Option<&str>,
) -> anyhow::Result<()> {
let root_dir = root_dir.canonicalize()?;
let _ = fs::create_dir_all(&output_dir);
let output_dir = output_dir.canonicalize()?;

for x in WalkDir::new(&root_dir) {
let x = x?;
let x_path = x.path();
log::info!("{:?}", x_path);
if x_path.is_dir() {
if !x_path.join("index.md").exists() {
let mut directory_index = String::new();
if x.depth() > 0 {
// let parent_dir = x_path.parent().unwrap();

directory_index.push_str("[../](..)\n");
}
directory_index.push_str(&create_directory_index(x_path)?);
log::info!("{}", &directory_index);
let html = markdown::md_to_html(&directory_index, x_path, web_prefix)?;
let result_path =
output_dir.join(x_path.join("index.html").strip_prefix(&root_dir)?);
log::info!("Result path: {:?}", &result_path);
let _ = std::fs::create_dir_all(result_path.parent().unwrap());
std::fs::write(&result_path, html.as_bytes())?;
}
} else if x_path.is_file() {
let result_path =
output_dir.join(x_path.with_extension("html").strip_prefix(&root_dir)?);
if x_path.extension().is_some_and(|ext| ext == "md") {
let md = fs::read_to_string(x_path)?;
let html = markdown::md_to_html(&md, x_path.parent().unwrap(), web_prefix)?;
std::fs::write(&result_path, html.as_bytes())?;
} else {
std::fs::copy(x_path, &result_path)?;
}
}
}

Ok(())
}

fn get_relative_url(root_path: &Path, target_path: &Path) -> String {
log::info!("{:?}.strip({:?})", target_path, root_path);
target_path
.strip_prefix(root_path)
.unwrap()
.to_string_lossy()
.to_string()
}

fn create_directory_index(folder: &Path) -> anyhow::Result<String> {
let mut result = String::new();

for x in read_dir(folder)? {
let x_path = &x?.path();
result.push_str(&directory_string(
folder,
&x_path,
&x_path.file_name().unwrap().to_string_lossy(),
));
result.push_str("\n");
}

Ok(result)
}

fn directory_string(root_path: &Path, target_path: &Path, name: &str) -> String {
format!(
"[{}](./{})\n",
name,
get_relative_url(root_path, target_path)
)
}

fn generate_site(
target_path: &Path,
output_path: &Path,
Expand Down
71 changes: 71 additions & 0 deletions src/markdown.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use std::path::Path;

use pulldown_cmark::{CowStr, Options};


/// Take markdown input, and change links if necessary
pub fn md_to_html(
markdown: &str,
file_parent_dir: &Path,
web_prefix: Option<&str>,
) -> anyhow::Result<String> {
log::info!("Markdown to html: {:?}", file_parent_dir);
let mut options = Options::empty();
options.insert(Options::ENABLE_GFM);
let events = pulldown_cmark::Parser::new_ext(markdown, options)
.map(|event| -> anyhow::Result<pulldown_cmark::Event> {
match event {
pulldown_cmark::Event::Start(pulldown_cmark::Tag::Link {
link_type,
dest_url,
title,
id,
}) => {
let inner = dest_url.to_string();
let referenced_path = file_parent_dir.join(&inner);
if referenced_path
.extension()
.is_some_and(|ext| ext == "md")
{
let new_path = Path::new(&inner).with_extension("html");
log::info!("Path: {:?} -> {:?}", &inner, &new_path);
if !referenced_path.exists() {
log::warn!("Path {:?} doesn't exist!", referenced_path);
Ok(pulldown_cmark::Event::Start(pulldown_cmark::Tag::Link {
link_type,
dest_url,
title,
id,
}))
}
else {
// Create destination url
let dest_url = CowStr::Boxed(
format!("{}{}", web_prefix.unwrap_or(""), new_path.to_string_lossy())
.into_boxed_str(),
);
Ok(pulldown_cmark::Event::Start(pulldown_cmark::Tag::Link {
link_type,
dest_url,
title,
id,
}))
}
} else {
Ok(pulldown_cmark::Event::Start(pulldown_cmark::Tag::Link {
link_type,
dest_url,
title,
id,
}))
}
}
_ => Ok(event),
}
})
.collect::<Result<Vec<pulldown_cmark::Event>, _>>()?;
log::info!("Done");
let mut html = String::new();
pulldown_cmark::html::push_html(&mut html, events.iter().cloned());
Ok(html)
}
2 changes: 2 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ fn site_with_links() -> anyhow::Result<()> {
clean: false,
web_prefix: None,
template: Some(crate::templates::BuiltInTemplate::ForceNone),
legacy: true
};
log::trace!("Running program");
crate::run_program(args)?;
Expand Down Expand Up @@ -103,6 +104,7 @@ fn site_warn_without_index() -> anyhow::Result<()> {
web_prefix: None,
template: Some(crate::templates::BuiltInTemplate::ForceNone),
file: None,
legacy: true,
};
crate::run_program(args)?;
Ok(())
Expand Down

0 comments on commit a7026cd

Please sign in to comment.