This repository has been archived on 2023-12-14. You can view files and clone it, but cannot push or open issues or pull requests.
plaque/src/main.rs

141 lines
3.4 KiB
Rust

/*
* Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This file is part of Plaque.
*
* Plaque is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Plaque is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
mod config;
mod parse;
use std::{
env::args,
io::Write,
fs::{ File, read_dir },
};
use config::*;
use parse::*;
use pulldown_cmark::{ Parser, Options, html };
use tl::Node;
use yacexits::*;
fn main() {
let argv = args().collect::<Vec<String>>();
let mut options = Options::empty();
options.insert(Options::all());
let config_path = match get_path("XDG_CONFIG_DIR") {
Ok(path) => path,
Err((err, code)) => {
eprintln!("{}: {}", argv[0], err);
exit(code);
},
};
let config = match Config::read_config(config_path) {
Ok(val) => val,
Err((err, code)) => {
eprintln!("{}: {}", argv[0], err);
exit(code);
}
};
let template_files = match read_dir(&config.template_dir) {
Ok(files) => files,
Err(_) => {
eprintln!("{}: {}: Directory not found.", argv[0], &config.template_dir);
exit(EX_UNAVAILABLE);
},
};
let content_files = match read_dir(&config.content_dir) {
Ok(files) => files,
Err(_) => {
eprintln!("{}: {}: Directory not found.", argv[0], &config.content_dir);
exit(EX_UNAVAILABLE);
},
};
let mut files = match get_contents(content_files) {
Ok(files) => files,
Err((err, code)) => {
eprintln!("{}: {}", argv[0], err);
exit(code);
},
};
let mut templates = match get_templates(template_files) {
Ok(templates) => templates,
Err((err, code)) => {
eprintln!("{}: {}", argv[0], err);
exit(code);
},
};
for content_file in files.drain() {
let (content_name, (md, toml)) = content_file;
let mut output = String::new();
html::push_html(&mut output, Parser::new_ext(&md, options));
let meta_info = match PageMeta::read_meta(toml.to_owned()) {
Ok(info) => info,
Err((err, code)) => {
eprintln!("{}: {}", argv[0], err);
exit(code);
},
};
let template = match templates.get_mut(&meta_info.template) {
Some(template) => template,
None => {
eprintln!(
"{}: {}: No such template “{}”.",
argv[0],
content_name,
meta_info.template,
);
exit(EX_UNAVAILABLE);
},
};
let mut html_file = match File::create(format!(
"{}/{}.html",
config.output_dir,
meta_info.template,
)) {
Ok(file) => file,
Err(_) => {
eprintln!(
"{}: {}: Unable to create output file.",
argv[0],
config.output_dir,
);
exit(EX_OSERR);
},
};
match html_file.write(output.as_bytes()) {
Ok(_) => {},
Err(err) => {
eprintln!("{}: {}", argv[0], err);
exit(EX_SOFTWARE);
},
};
}
}