-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmain.rs
More file actions
117 lines (108 loc) · 3.96 KB
/
Copy pathmain.rs
File metadata and controls
117 lines (108 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
mod frontmatter;
mod post;
use post::Post;
use std::path::{Path, PathBuf};
fn load_posts<P: AsRef<Path>>(src: P) -> Result<Vec<Post>, Box<dyn std::error::Error>> {
let mut posts: Vec<Post> = Vec::default();
for entry in src.as_ref().read_dir()? {
let entry = entry?;
let path = entry.path();
if let Some("md") = path.extension().map(std::ffi::OsStr::to_str).flatten() {
let name = path.file_stem().map(std::ffi::OsStr::to_str).flatten();
if name.is_none() {
continue;
}
match Post::load(&path) {
Ok(Some(p)) => posts.push(p),
Ok(None) => (),
Err(e) => eprintln!(
"skipping `{}` as it failed to parse: {:?}",
path.display(),
e
),
};
}
}
posts.sort_by(|a, b| b.front.date.cmp(&a.front.date));
Ok(posts)
}
fn main() {
use rayon::prelude::*;
let outdir: PathBuf = PathBuf::from("docs").join("posts");
std::fs::create_dir_all(&outdir).expect("can create docs/posts/ folder");
let posts = load_posts("posts").expect("can load posts from posts/ folder");
println!("Found {} posts, rendering them...", posts.len());
let errors: Vec<String> = posts
.par_iter()
.filter_map(|post| {
let html = match post.render() {
Ok(h) => h,
Err(e) => {
return Some(format!(
"failed to render `{}`: {:?}",
post.source.display(),
e
));
}
};
let outdir = outdir.join(&post.front.slug);
std::fs::create_dir_all(&outdir).expect("can create dir for post");
let outfile = outdir.join("index.html");
std::fs::write(outfile, html).expect("can write post to index.html file");
return None;
})
.collect();
if errors.len() > 0 {
eprintln!("Failed to render some posts:");
for error in errors.iter() {
eprintln!(" {}", error);
}
} else {
println!("Posts rendered!");
}
println!("Generating index...");
{
let mut context = tera::Context::new();
context.insert("title", "Kenton Hamaluik");
context.insert("posts", &posts);
context.insert("include_katex_css", &false);
let rendered = post::TEMPLATES
.render("index.html", &context)
.expect("can render index");
let minified = html_minifier::HTMLMinifier::minify(rendered).expect("can minify index");
let outpath = PathBuf::from("docs").join("index.html");
std::fs::write(outpath, minified).expect("can write index to index.html file");
}
println!("Index generated!");
println!("Copying assets...");
let outdir = PathBuf::from("docs");
let mut paths: Vec<PathBuf> = Vec::default();
for entry in ignore::Walk::new("assets") {
let entry = entry.expect("can get path entry");
if let Some(t) = entry.file_type() {
if t.is_file() {
if let Some("md") = entry
.path()
.extension()
.map(std::ffi::OsStr::to_str)
.flatten()
{
// ignore markdown files
} else {
// we found an asset to copy!
paths.push(entry.path().to_owned());
}
}
}
}
paths.par_iter().for_each(|path| {
let dest_path: PathBuf =
outdir.join(path.iter().skip(1).map(PathBuf::from).collect::<PathBuf>());
if let Some(parent) = dest_path.parent() {
if !parent.exists() {
std::fs::create_dir_all(parent).expect("can create directory");
}
}
std::fs::copy(path, &dest_path).expect("can copy file");
});
}