diff --git a/Cargo.lock b/Cargo.lock index 0de36ff..d95dbf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -358,7 +358,7 @@ dependencies = [ [[package]] name = "snekdown" -version = "0.5.0" +version = "0.5.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)", diff --git a/Cargo.toml b/Cargo.toml index a821ca3..8f17312 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "snekdown" -version = "0.5.0" +version = "0.5.1" authors = ["trivernis "] edition = "2018" license-file = "LICENSE" diff --git a/README.md b/README.md index 8bc6dae..7342e6b 100644 --- a/README.md +++ b/README.md @@ -107,4 +107,17 @@ Placeholder Formatting [author = "The Great snek" date = [[date]] time = [[time]] display = "author - date at time"] +``` + +#### Usage + +``` +Hide a section (including subsections) in the TOC +#[toc-hidden] Section + +Set the size of an image +!(url)[width = 42% height=auto] + +Set the source of a quote +[author=Me date=[[date]] display="author - date"]> It's me ``` \ No newline at end of file diff --git a/src/format/html.rs b/src/format/html.rs index bd1b959..55e14aa 100644 --- a/src/format/html.rs +++ b/src/format/html.rs @@ -287,22 +287,36 @@ impl ToHtml for Text { impl ToHtml for Image { fn to_html(&self) -> String { + let mut style = String::new(); + if let Some(meta) = &self.metadata { + if let Some(width) = meta.data.get("width") { + style = format!("{}width: {};", style, width.to_html()) + } + if let Some(height) = meta.data.get("height") { + style = format!("{}height: {};", style, height.to_html()) + } + } if let Some(description) = self.url.description.clone() { minify( format!( "
\ \ - {1}\ + {1}\ \ \
", encode_attribute(self.url.url.clone().as_str()), - encode_attribute(description.as_str()) + encode_attribute(description.as_str()), + style ) .as_str(), ) } else { - format!("", self.url.url.clone(),) + format!( + "", + self.url.url.clone(), + style + ) } } } diff --git a/src/parsing/elements.rs b/src/parsing/elements.rs index 241aef5..8bb9410 100644 --- a/src/parsing/elements.rs +++ b/src/parsing/elements.rs @@ -71,6 +71,7 @@ pub struct Document { pub struct Section { pub(crate) header: Header, pub(crate) elements: Vec, + pub(crate) metadata: Option, } #[derive(Clone, Debug)] @@ -264,9 +265,11 @@ impl Document { list.ordered = true; self.elements.iter().for_each(|e| match e { Block::Section(sec) => { - let mut item = ListItem::new(Inline::Anchor(sec.header.get_anchor()), 1, true); - item.children.append(&mut sec.get_toc_list().items); - list.add_item(item); + if !sec.get_hide_in_toc() { + let mut item = ListItem::new(Inline::Anchor(sec.header.get_anchor()), 1, true); + item.children.append(&mut sec.get_toc_list().items); + list.add_item(item); + } } Block::Import(imp) => { let anchor = imp.anchor.lock().unwrap(); @@ -286,6 +289,7 @@ impl Section { Self { header, elements: Vec::new(), + metadata: None, } } @@ -317,14 +321,24 @@ impl Section { let mut list = List::new(); self.elements.iter().for_each(|e| { if let Block::Section(sec) = e { - let mut item = ListItem::new(Inline::Anchor(sec.header.get_anchor()), 1, true); - item.children.append(&mut sec.get_toc_list().items); - list.add_item(item); + if !sec.get_hide_in_toc() { + let mut item = ListItem::new(Inline::Anchor(sec.header.get_anchor()), 1, true); + item.children.append(&mut sec.get_toc_list().items); + list.add_item(item); + } } }); list } + + pub(crate) fn get_hide_in_toc(&self) -> bool { + if let Some(meta) = &self.metadata { + meta.get_bool("toc-hidden") + } else { + false + } + } } impl Header { @@ -463,3 +477,13 @@ impl Placeholder { self.value = Some(value); } } + +impl InlineMetadata { + pub fn get_bool(&self, key: &str) -> bool { + if let Some(MetadataValue::Bool(value)) = self.data.get(key) { + *value + } else { + false + } + } +} diff --git a/src/parsing/parser.rs b/src/parsing/parser.rs index e9934cc..8fc6419 100644 --- a/src/parsing/parser.rs +++ b/src/parsing/parser.rs @@ -418,11 +418,14 @@ impl Parser { if self.check_special(&HASH) { let mut size = 1; while let Some(_) = self.next_char() { - if self.check_special(&HASH) { - size += 1; - } else { + if !self.check_special(&HASH) { break; } + size += 1; + } + let mut metadata = None; + if let Ok(meta) = self.parse_inline_metadata() { + metadata = Some(meta); } if size <= self.section_nesting || !self.current_char.is_whitespace() { if size <= self.section_nesting { @@ -436,6 +439,7 @@ impl Parser { self.section_nesting = size; self.sections.push(size); let mut section = Section::new(header); + section.metadata = metadata; self.seek_whitespace(); while let Ok(block) = self.parse_block() { @@ -542,6 +546,9 @@ impl Parser { break; } } + if self.check_special(&META_CLOSE) { + let _ = self.next_char(); + } if self.check_linebreak() || values.len() == 0 { // if there was a linebreak (the metadata wasn't closed) or there is no inner data // return an error