You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
snekdown/src/references/placeholders.rs

138 lines
4.5 KiB
Rust

/*
* Snekdown - Custom Markdown flavour and parser
* Copyright (C) 2021 Trivernis
* See LICENSE for more information.
*/
use crate::elements::*;
use crate::references::bibliography::create_bib_list;
use chrono::prelude::*;
use regex::Regex;
macro_rules! block {
($inner:expr) => {
Element::Block(Box::new($inner))
};
}
#[allow(unused)]
macro_rules! line {
($inner:expr) => {
Element::Line(Box::new($inner))
};
}
macro_rules! inline {
($inner:expr) => {
Element::Inline(Box::new($inner))
};
}
pub(crate) trait ProcessPlaceholders {
fn process_placeholders(&mut self);
fn process_definitions(&mut self);
}
const S_VALUE: &str = "value";
const P_TOC: &str = "toc";
const P_BIB: &str = "bib";
const P_GLS: &str = "gls";
const P_DATE: &str = "date";
const P_TIME: &str = "time";
const P_DATETIME: &str = "datetime";
const P_AUTHOR: &str = "author";
const P_TITLE: &str = "title";
impl ProcessPlaceholders for Document {
/// parses all placeholders and assigns values to them
fn process_placeholders(&mut self) {
self.placeholders.iter().for_each(|p| {
let mut pholder = p.write().unwrap();
match pholder.name.to_lowercase().as_str() {
P_TOC => {
let ordered = if let Some(meta) = &pholder.metadata {
meta.get_bool("ordered")
} else {
false
};
pholder.set_value(block!(Block::List(self.create_toc(ordered))))
}
P_BIB => pholder.set_value(block!(Block::List(create_bib_list(
self.bibliography.get_entry_list_by_occurrence()
)))),
P_GLS => pholder.set_value(block!(Block::List(
self.glossary.lock().create_glossary_list()
))),
P_DATE => pholder.set_value(inline!(Inline::Plain(PlainText {
value: get_date_string()
}))),
P_TIME => pholder.set_value(inline!(Inline::Plain(PlainText {
value: get_time_string()
}))),
P_DATETIME => pholder.set_value(inline!(Inline::Plain(PlainText {
value: format!("{} {}", get_date_string(), get_time_string())
}))),
P_AUTHOR => {
if let Some(value) = self.config.lock().metadata.author.clone() {
pholder.set_value(inline!(Inline::Plain(PlainText { value })))
}
}
P_TITLE => {
if let Some(value) = self.config.lock().metadata.title.clone() {
pholder.set_value(inline!(Inline::Plain(PlainText { value })))
}
}
_ => {
if let Some(value) = self
.config
.lock()
.custom_attributes
.get(pholder.name.to_lowercase().as_str())
.cloned()
{
pholder.set_value(inline!(Inline::Plain(PlainText { value })))
}
}
}
})
}
fn process_definitions(&mut self) {
lazy_static::lazy_static! {
static ref RE_SET: Regex = Regex::new(r"^set:(.*)$").unwrap();
}
let placeholders = self.placeholders.clone();
placeholders.iter().for_each(|p| {
let mut pholder = p.write().unwrap();
let name = pholder.name.clone();
if let Some(cap) = RE_SET.captures(&name) {
if let Some(key) = cap.get(1) {
let key: &str = key.as_str();
pholder.value = Some(inline!(Inline::Plain(PlainText {
value: "".to_string()
})));
if let Some(meta) = &pholder.metadata {
if let Some(value) = meta.data.get(S_VALUE) {
self.config.lock().set_from_meta(key, value.clone())
}
}
}
return;
}
});
}
}
fn get_time_string() -> String {
let now = Local::now();
format!("{:02}:{:02}:{:02}", now.hour(), now.minute(), now.second())
}
fn get_date_string() -> String {
let now = Local::now();
format!("{:02}.{:02}.{:04}", now.day(), now.month(), now.year())
}