Add hiding of sections with metadata

pull/1/head
trivernis 4 years ago
parent 0d6eb1d1a7
commit 018960db0e

2
Cargo.lock generated

@ -358,7 +358,7 @@ dependencies = [
[[package]] [[package]]
name = "snekdown" name = "snekdown"
version = "0.5.0" version = "0.5.1"
dependencies = [ dependencies = [
"chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",

@ -1,6 +1,6 @@
[package] [package]
name = "snekdown" name = "snekdown"
version = "0.5.0" version = "0.5.1"
authors = ["trivernis <trivernis@protonmail.com>"] authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018" edition = "2018"
license-file = "LICENSE" license-file = "LICENSE"

@ -107,4 +107,17 @@ Placeholder
Formatting Formatting
[author = "The Great snek" date = [[date]] time = [[time]] display = "author - date at time"] [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
``` ```

@ -287,22 +287,36 @@ impl ToHtml for Text {
impl ToHtml for Image { impl ToHtml for Image {
fn to_html(&self) -> String { 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() { if let Some(description) = self.url.description.clone() {
minify( minify(
format!( format!(
"<div class='figure'>\ "<div class='figure'>\
<a href={0}>\ <a href={0}>\
<img src='{0}' alt='{1}'/>\ <img src='{0}' alt='{1}' style='{2}'/>\
</a>\ </a>\
<label class='imageDescription'>{1}</label>\ <label class='imageDescription'>{1}</label>\
</div>", </div>",
encode_attribute(self.url.url.clone().as_str()), encode_attribute(self.url.url.clone().as_str()),
encode_attribute(description.as_str()) encode_attribute(description.as_str()),
style
) )
.as_str(), .as_str(),
) )
} else { } else {
format!("<a href={0}><img src='{0}'/></a>", self.url.url.clone(),) format!(
"<a href={0}><img src='{0}' style='{1}'/></a>",
self.url.url.clone(),
style
)
} }
} }
} }

@ -71,6 +71,7 @@ pub struct Document {
pub struct Section { pub struct Section {
pub(crate) header: Header, pub(crate) header: Header,
pub(crate) elements: Vec<Block>, pub(crate) elements: Vec<Block>,
pub(crate) metadata: Option<InlineMetadata>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -264,9 +265,11 @@ impl Document {
list.ordered = true; list.ordered = true;
self.elements.iter().for_each(|e| match e { self.elements.iter().for_each(|e| match e {
Block::Section(sec) => { Block::Section(sec) => {
let mut item = ListItem::new(Inline::Anchor(sec.header.get_anchor()), 1, true); if !sec.get_hide_in_toc() {
item.children.append(&mut sec.get_toc_list().items); let mut item = ListItem::new(Inline::Anchor(sec.header.get_anchor()), 1, true);
list.add_item(item); item.children.append(&mut sec.get_toc_list().items);
list.add_item(item);
}
} }
Block::Import(imp) => { Block::Import(imp) => {
let anchor = imp.anchor.lock().unwrap(); let anchor = imp.anchor.lock().unwrap();
@ -286,6 +289,7 @@ impl Section {
Self { Self {
header, header,
elements: Vec::new(), elements: Vec::new(),
metadata: None,
} }
} }
@ -317,14 +321,24 @@ impl Section {
let mut list = List::new(); let mut list = List::new();
self.elements.iter().for_each(|e| { self.elements.iter().for_each(|e| {
if let Block::Section(sec) = e { if let Block::Section(sec) = e {
let mut item = ListItem::new(Inline::Anchor(sec.header.get_anchor()), 1, true); if !sec.get_hide_in_toc() {
item.children.append(&mut sec.get_toc_list().items); let mut item = ListItem::new(Inline::Anchor(sec.header.get_anchor()), 1, true);
list.add_item(item); item.children.append(&mut sec.get_toc_list().items);
list.add_item(item);
}
} }
}); });
list 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 { impl Header {
@ -463,3 +477,13 @@ impl Placeholder {
self.value = Some(value); 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
}
}
}

@ -418,11 +418,14 @@ impl Parser {
if self.check_special(&HASH) { if self.check_special(&HASH) {
let mut size = 1; let mut size = 1;
while let Some(_) = self.next_char() { while let Some(_) = self.next_char() {
if self.check_special(&HASH) { if !self.check_special(&HASH) {
size += 1;
} else {
break; 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 || !self.current_char.is_whitespace() {
if size <= self.section_nesting { if size <= self.section_nesting {
@ -436,6 +439,7 @@ impl Parser {
self.section_nesting = size; self.section_nesting = size;
self.sections.push(size); self.sections.push(size);
let mut section = Section::new(header); let mut section = Section::new(header);
section.metadata = metadata;
self.seek_whitespace(); self.seek_whitespace();
while let Ok(block) = self.parse_block() { while let Ok(block) = self.parse_block() {
@ -542,6 +546,9 @@ impl Parser {
break; break;
} }
} }
if self.check_special(&META_CLOSE) {
let _ = self.next_char();
}
if self.check_linebreak() || values.len() == 0 { if self.check_linebreak() || values.len() == 0 {
// if there was a linebreak (the metadata wasn't closed) or there is no inner data // if there was a linebreak (the metadata wasn't closed) or there is no inner data
// return an error // return an error

Loading…
Cancel
Save