Add link rendering for references

pull/1/head
trivernis 4 years ago
parent 5dacef285c
commit 8daa6bb70c

2
Cargo.lock generated

@ -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)",

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

@ -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!("<a href='#{}'>{}</a>", ref_id, template.render())
}
}
} else {
format!("<a href='#{}'>{}</a>", 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!(
"<div id='{}'>{}</div>",
encode_attribute(val.get_ref_id().as_str()),
val.to_html()
)
} else {
"Unknown reference".to_string()
}

@ -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| {

@ -235,6 +235,7 @@ pub struct Centered {
pub struct Reference {
pub(crate) value: Option<RefValue>,
pub(crate) metadata: Option<InlineMetadata>,
pub(crate) display: Option<Arc<Mutex<ConfigValue>>>,
}
#[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
}
}
}
}

@ -39,7 +39,7 @@ const B_NOTES: &str = "notes";
#[derive(Clone, Debug)]
pub struct BibEntry {
key: String,
pub(crate) key: String,
author: Option<String>,
date: Option<String>,
url: Option<String>,
@ -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")
})))
}
}

Loading…
Cancel
Save