website-risg/src/law.rs
philipp 98aed71ef5
Some checks are pending
CI/CD Pipeline / deploy-main (push) Waiting to run
clean with pedantic clippy
2024-02-21 14:28:16 +01:00

127 lines
3.7 KiB
Rust

use std::fs;
use risp::law::{Content, Heading, HeadingContent, Law, Section};
use crate::part::Parts;
fn print_content(content: Content) -> String {
let mut ret = String::new();
match content {
Content::Text(t) => ret.push_str(&format!("<span class='content'>{t}</span>")),
Content::List(l) => {
ret.push_str("<ul class='content list'>");
for item in l {
if let Content::List(_) = item {
ret.push_str(&print_content(item));
} else {
ret.push_str("<li>");
ret.push_str(&print_content(item));
ret.push_str("</li>");
}
}
ret.push_str("</ul>");
}
Content::Multi(l) => {
ret.push_str("<div class='multi'>");
for item in l {
ret.push_str(&print_content(item));
}
ret.push_str("</div>");
}
}
ret
}
fn print_paragraph(section: Section) -> String {
let mut ret = String::new();
ret.push_str("<div class='par'>");
ret.push_str(&format!("<span class='symb'>{}</span>", section.symb));
if let Some(par_header) = section.par_header {
ret.push_str(&format!("<span class='header'>{par_header}</span>"));
}
if let Some(note) = section.par_note {
ret.push_str(&format!("<span class='note'>Beachte: {note}</span>"));
}
ret.push_str(&print_content(section.content));
ret.push_str("</div>");
ret
}
fn print_header(header: Heading, level: usize) -> String {
let mut ret = String::new();
let mut header_title = header.name.clone();
if let Some(desc) = header.desc {
header_title.push_str(&format!(" ({desc})"));
}
ret.push_str(&format!(
"<details open='open'>\
<summary class='sticky'><h{0}>{1}</h{0}></summary>\n\
<div>",
level + 2,
header_title
));
for content in header.content {
match content {
HeadingContent::Paragraph(p) => {
ret.push_str(&print_paragraph(p));
}
HeadingContent::Heading(subheader) => {
ret.push_str(&print_header(subheader, level + 1));
}
}
}
ret.push_str("</div></details>");
ret
}
fn get_content(config_path: &str) -> (String, String) {
let law = Law::from_config(config_path).unwrap();
let lawname = law.name;
let mut ret = String::new();
for h in law.header {
ret.push_str(&print_header(h, 0));
}
(lawname, ret)
}
/// Reads configs in `./laws` and creates a `<lawname>.html` in the `output` folder.
pub(crate) fn create_law_files() -> String {
let mut configs: Vec<_> = fs::read_dir("./laws")
.unwrap()
.map(std::result::Result::unwrap)
.collect();
configs.sort_by_key(std::fs::DirEntry::path); // Order by name
let mut li_of_files = String::new();
for config in configs {
let filename = config.file_name().into_string().unwrap();
//TODO: use proper logic...
let law_filename = filename.replace(".toml", "");
let path = format!("{}", config.path().display());
let (lawname, content) = get_content(&path);
let template = fs::read_to_string("templates/law.html").unwrap();
let site = template
.replace("{{content}}", &content)
.replace("{{title}}", &lawname);
let site = Parts::new().perform(site);
li_of_files.push_str(&format!(
"<li><a href='./{law_filename}' title='{law_filename}' class='contrast'>{lawname}</a></li>"
));
fs::write(&format!("output/{law_filename}.html"), &site).expect("Unable to write file");
}
li_of_files
}