diff --git a/Cargo.lock b/Cargo.lock index 5af7513..6fc7192 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,6 +69,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -357,8 +358,9 @@ dependencies = [ [[package]] name = "snekdown" -version = "0.3.0" +version = "0.3.1" dependencies = [ + "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "htmlescape 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "minify 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -454,6 +456,15 @@ dependencies = [ "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "unicode-segmentation" version = "1.6.0" @@ -586,6 +597,7 @@ dependencies = [ "checksum syntect 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83b43a6ca1829ccb0c933b615c9ea83ffc8793ae240cecbd15119b13d741161d" "checksum termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" "checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" diff --git a/Cargo.toml b/Cargo.toml index a4fca26..d015370 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "snekdown" -version = "0.3.0" +version = "0.3.1" authors = ["trivernis "] edition = "2018" license-file = "LICENSE" @@ -24,4 +24,5 @@ structopt = "0.3.14" termion = "1.5.5" minify = "1.1.1" htmlescape = "0.3.1" -syntect = "4.2.0" \ No newline at end of file +syntect = "4.2.0" +chrono = "0.4.11" \ No newline at end of file diff --git a/src/format/html.rs b/src/format/html.rs index cc7fe61..5b75040 100644 --- a/src/format/html.rs +++ b/src/format/html.rs @@ -1,4 +1,4 @@ -use crate::elements::*; +use crate::parsing::elements::*; use htmlescape::{encode_attribute, encode_minimal}; use minify::html::minify; use std::cell::RefCell; diff --git a/src/lib.rs b/src/lib.rs index b74ec28..4abc7c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,3 @@ -pub mod elements; pub mod format; -pub mod parser; -pub mod tokens; +pub mod parsing; +pub use parsing::parser::Parser; diff --git a/src/main.rs b/src/main.rs index 358a9ef..ad91428 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use snekdown::format::html::ToHtml; -use snekdown::parser::Parser; +use snekdown::Parser; use std::fs::write; use std::time::Instant; use termion::style; diff --git a/src/elements.rs b/src/parsing/elements.rs similarity index 95% rename from src/elements.rs rename to src/parsing/elements.rs index bcc34ff..6d4654c 100644 --- a/src/elements.rs +++ b/src/parsing/elements.rs @@ -244,28 +244,23 @@ impl Document { pub fn create_toc(&self) -> List { let mut list = List::new(); list.ordered = true; - self.elements.iter().for_each(|e| { - if let Block::Section(sec) = e { + self.elements.iter().for_each(|e| match e { + Block::Section(sec) => { let mut item = ListItem::new(sec.header.line.clone(), 1, true); item.children.append(&mut sec.get_toc_list().items); list.add_item(item); } + Block::Import(imp) => { + let anchor = imp.anchor.lock().unwrap(); + if let Some(doc) = &anchor.document { + list.items.append(&mut doc.create_toc().items) + } + } + _ => {} }); list } - - pub fn parse_placeholders(&mut self) { - self.placeholders.iter().for_each(|p| { - let mut pholder = p.lock().unwrap(); - match pholder.name.to_ascii_lowercase().as_str() { - "toc" => { - pholder.set_value(Element::Block(Box::new(Block::List(self.create_toc())))) - } - _ => {} - } - }) - } } impl Section { diff --git a/src/parsing/mod.rs b/src/parsing/mod.rs new file mode 100644 index 0000000..e7f1a24 --- /dev/null +++ b/src/parsing/mod.rs @@ -0,0 +1,4 @@ +pub mod elements; +pub mod parser; +pub mod placeholders; +pub mod tokens; diff --git a/src/parser.rs b/src/parsing/parser.rs similarity index 99% rename from src/parser.rs rename to src/parsing/parser.rs index 45d0add..445590b 100644 --- a/src/parser.rs +++ b/src/parsing/parser.rs @@ -1,5 +1,6 @@ -use crate::elements::*; -use crate::tokens::*; +use super::elements::*; +use super::tokens::*; +use crate::parsing::placeholders::ProcessPlaceholders; use crossbeam_utils::sync::WaitGroup; use std::error::Error; use std::fmt; @@ -362,8 +363,8 @@ impl Parser { let wg = self.wg.clone(); self.wg = WaitGroup::new(); - self.document.parse_placeholders(); wg.wait(); + self.document.process_placeholders(); let document = self.document.clone(); self.document = Document::new(!self.is_child); diff --git a/src/parsing/placeholders.rs b/src/parsing/placeholders.rs new file mode 100644 index 0000000..7345e26 --- /dev/null +++ b/src/parsing/placeholders.rs @@ -0,0 +1,62 @@ +use super::elements::*; +use chrono::prelude::*; + +macro_rules! block { + ($inner:expr) => { + Element::Block(Box::new($inner)) + }; +} + +#[allow(unused)] +macro_rules! inline { + ($inner:expr) => { + Element::Inline(Box::new($inner)) + }; +} + +macro_rules! subtext { + ($inner:expr) => { + Element::SubText(Box::new($inner)) + }; +} + +pub(crate) trait ProcessPlaceholders { + fn process_placeholders(&mut self); +} + +const P_TOC: &str = "toc"; +const P_DATE: &str = "date"; +const P_TIME: &str = "time"; +const P_DATETIME: &str = "datetime"; + +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.lock().unwrap(); + match pholder.name.to_ascii_lowercase().as_str() { + P_TOC => pholder.set_value(block!(Block::List(self.create_toc()))), + P_DATE => pholder.set_value(subtext!(SubText::Plain(PlainText { + value: get_date_string() + }))), + P_TIME => pholder.set_value(subtext!(SubText::Plain(PlainText { + value: get_time_string() + }))), + P_DATETIME => pholder.set_value(subtext!(SubText::Plain(PlainText { + value: format!("{} {}", get_date_string(), get_time_string()) + }))), + _ => {} + } + }) + } +} + +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()) +} diff --git a/src/tokens.rs b/src/parsing/tokens.rs similarity index 100% rename from src/tokens.rs rename to src/parsing/tokens.rs