From 8daa6bb70c5bcd612ee77c81e86f3cc612254f2d Mon Sep 17 00:00:00 2001 From: trivernis Date: Mon, 1 Jun 2020 21:12:49 +0200 Subject: [PATCH] Add link rendering for references --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/format/html.rs | 21 ++++++++++++-- src/format/mod.rs | 10 ++++++- src/parsing/elements.rs | 25 ++++++++++++++++- src/parsing/placeholders.rs | 56 ++++++++++++++++++++++--------------- 6 files changed, 87 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34f5334..0621983 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -382,7 +382,7 @@ dependencies = [ [[package]] name = "snekdown" -version = "0.8.1" +version = "0.8.2" 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 b6d8bf5..2bd861a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "snekdown" -version = "0.8.1" +version = "0.8.2" authors = ["trivernis "] edition = "2018" license-file = "LICENSE" diff --git a/src/format/html.rs b/src/format/html.rs index 209dce2..317972c 100644 --- a/src/format/html.rs +++ b/src/format/html.rs @@ -428,7 +428,20 @@ impl ToHtml for Centered { impl ToHtml for Reference { fn to_html(&self) -> String { if let Some(value) = &self.value { - value.to_html() + let ref_id = value.get_ref_id(); + if let Some(display) = &self.display { + match value { + RefValue::BibEntry(bib) => { + let bib = bib.lock().unwrap(); + let mut template = bib.get_template(); + template.set_value(display.lock().unwrap().value.to_html()); + + format!("{}", ref_id, template.render()) + } + } + } else { + format!("{}", ref_id, value.to_html()) + } } else { "Unknown reference".to_string() } @@ -446,7 +459,11 @@ impl ToHtml for RefValue { impl ToHtml for ReferenceEntry { fn to_html(&self) -> String { if let Some(val) = &self.value { - val.to_html() + format!( + "
{}
", + encode_attribute(val.get_ref_id().as_str()), + val.to_html() + ) } else { "Unknown reference".to_string() } diff --git a/src/format/mod.rs b/src/format/mod.rs index 3541019..c2cf5b7 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -9,6 +9,10 @@ pub struct Template { } impl Template { + pub fn empty() -> Self { + Self::new(String::new()) + } + pub fn new(value: String) -> Self { Self { value, @@ -16,6 +20,10 @@ impl Template { } } + pub fn set_value(&mut self, value: String) { + self.value = value; + } + pub fn add_replacement(&mut self, name: &str, val: &str) { self.replacements.insert(name.to_string(), val.to_string()); } @@ -24,7 +32,7 @@ impl Template { self.replacements = replacements; } - pub fn render(&mut self) -> String { + pub fn render(&self) -> String { lazy_static::lazy_static! { static ref RE_REP: Regex = Regex::new(r"\{\{([^}]*)}}").unwrap(); } let mut ret_string = self.value.clone(); RE_REP.find_iter(&self.value).for_each(|m| { diff --git a/src/parsing/elements.rs b/src/parsing/elements.rs index fdc91ad..3fae1dd 100644 --- a/src/parsing/elements.rs +++ b/src/parsing/elements.rs @@ -235,6 +235,7 @@ pub struct Centered { pub struct Reference { pub(crate) value: Option, pub(crate) metadata: Option, + pub(crate) display: Option>>, } #[derive(Clone, Debug)] @@ -266,7 +267,15 @@ impl Document { config.insert( "bib-display".to_string(), Arc::new(Mutex::new(ConfigValue { - value: MetadataValue::String("title - author - year - (notes)".to_string()), + value: MetadataValue::String( + "{{title}} - {{author}} - {{date}} - {{url}} - ({{notes}})".to_string(), + ), + })), + ); + config.insert( + "ref-display".to_string(), + Arc::new(Mutex::new(ConfigValue { + value: MetadataValue::String("[{{key}}]".to_string()), })), ); @@ -575,3 +584,17 @@ impl InlineMetadata { } } } + +impl RefValue { + pub fn get_ref_id(&self) -> String { + match self { + RefValue::BibEntry(bib) => { + let bib = bib.lock().unwrap(); + let mut key = bib.key.clone(); + key.retain(|c| !c.is_whitespace()); + + key + } + } + } +} diff --git a/src/parsing/placeholders.rs b/src/parsing/placeholders.rs index 9e5003e..cc408a1 100644 --- a/src/parsing/placeholders.rs +++ b/src/parsing/placeholders.rs @@ -39,7 +39,7 @@ const B_NOTES: &str = "notes"; #[derive(Clone, Debug)] pub struct BibEntry { - key: String, + pub(crate) key: String, author: Option, date: Option, url: Option, @@ -50,30 +50,38 @@ pub struct BibEntry { } impl BibEntry { + pub fn get_template(&self) -> Template { + let mut template = Template::empty(); + template.add_replacement("key", &self.key); + + if let Some(author) = &self.author { + template.add_replacement(B_AUTHOR, author.as_str()); + } + if let Some(date) = &self.date { + template.add_replacement(B_DATE, date.as_str()); + } + if let Some(url) = &self.url { + template.add_replacement(B_URL, url.as_str()); + } + if let Some(title) = &self.title { + template.add_replacement(B_TITLE, title.as_str()); + } + if let Some(publisher) = &self.publisher { + template.add_replacement(B_PUBLISHER, publisher.as_str()); + } + if let Some(notes) = &self.notes { + template.add_replacement(B_NOTES, notes.as_str()); + } + + template + } + pub fn get_formatted(&self) -> String { if let Some(display) = &self.display { let value = display.lock().unwrap(); if let MetadataValue::String(format) = &value.value { - let mut template = Template::new(format.clone()); - - if let Some(author) = &self.author { - template.add_replacement(B_AUTHOR, author.as_str()); - } - if let Some(date) = &self.date { - template.add_replacement(B_DATE, date.as_str()); - } - if let Some(url) = &self.url { - template.add_replacement(B_URL, url.as_str()); - } - if let Some(title) = &self.title { - template.add_replacement(B_TITLE, title.as_str()); - } - if let Some(publisher) = &self.publisher { - template.add_replacement(B_PUBLISHER, publisher.as_str()); - } - if let Some(notes) = &self.notes { - template.add_replacement(B_NOTES, notes.as_str()); - } + let mut template = self.get_template(); + template.set_value(format.clone()); template.render() } else { @@ -104,12 +112,14 @@ impl ProcessPlaceholders for Document { if let Some(entry) = self.bib_entries.get(key.as_str()) { pholder.value = Some(inline!(Inline::Reference(Reference { value: Some(RefValue::BibEntry(entry.clone())), - metadata: pholder.metadata.clone() + metadata: pholder.metadata.clone(), + display: self.get_config_param("ref-display") }))) } else { pholder.value = Some(inline!(Inline::Reference(Reference { value: None, - metadata: pholder.metadata.clone() + metadata: pholder.metadata.clone(), + display: self.get_config_param("ref-display") }))) } }