diff --git a/Cargo.lock b/Cargo.lock index 166524f..e5b2ef9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,6 +52,15 @@ name = "base64" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bibliographix" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "chrono 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono-english 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bincode" version = "1.3.1" @@ -98,7 +107,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "chrono" -version = "0.4.13" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", @@ -106,6 +115,16 @@ dependencies = [ "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "chrono-english" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "chrono 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)", + "scanlex 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "clap" version = "2.33.2" @@ -843,7 +862,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "line-wrap 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1034,6 +1053,11 @@ dependencies = [ "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "scanlex" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "schannel" version = "0.1.19" @@ -1121,8 +1145,9 @@ version = "0.23.0" dependencies = [ "asciimath-rs 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bibliographix 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "charred 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)", "colored 1.9.3 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "gh-emoji 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1563,6 +1588,7 @@ dependencies = [ "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" "checksum base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" +"checksum bibliographix 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba3bc8793948a3de7d106d5f855afb085b998585c5f407ae59cd5489d3ed97c8" "checksum bincode 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" @@ -1571,7 +1597,8 @@ dependencies = [ "checksum cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum charred 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1e01302bf6a3d92a90baa965f84a735938520ab9fd896f0694a71e8dec5405ce" -"checksum chrono 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6" +"checksum chrono 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b" +"checksum chrono-english 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4233ee19352739cfdcb5d7c2085005b166f6170ef2845ed9eef27a8fa5f95206" "checksum clap 2.33.2 (registry+https://github.com/rust-lang/crates.io-index)" = "10040cdf04294b565d9e0319955430099ec3813a64c952b86a41200ad714ae48" "checksum colored 1.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" "checksum core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" @@ -1678,6 +1705,7 @@ dependencies = [ "checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" "checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" "checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +"checksum scanlex 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e6a2c84b697bc9496978f7457b17039a22b5d89c674964e8a480de4d5ddd55dc" "checksum schannel 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" "checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" "checksum security-framework 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535" diff --git a/Cargo.toml b/Cargo.toml index 9bf6e60..d062611 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,8 @@ path = "src/main.rs" [dependencies] charred = "0.3.3" +asciimath-rs = "0.5.7" +bibliographix = "0.2.0" crossbeam-utils = "0.7.2" structopt = "0.3.14" minify = "1.1.1" @@ -32,9 +34,8 @@ notify = "4.0.12" toml = "0.5.6" serde ="1.0.111" serde_derive = "1.0.111" -asciimath-rs = "0.5.7" reqwest = {version = "0.10", features=["blocking"]} mime_guess = "2.0.3" mime = "0.3.16" base64 = "0.12.3" -rayon = "1.3.1" \ No newline at end of file +rayon = "1.3.1" diff --git a/src/elements/mod.rs b/src/elements/mod.rs index 87264ce..f35098b 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -1,15 +1,18 @@ pub mod tokens; -use crate::references::bibliography::{BibEntry, BibReference, Bibliography}; -use crate::references::configuration::Configuration; +use crate::format::PlaceholderTemplate; +use crate::references::configuration::{ConfigRefEntry, Configuration}; use crate::references::placeholders::ProcessPlaceholders; use crate::references::templates::{Template, TemplateVariable}; use asciimath_rs::elements::special::Expression; +use bibliographix::bib_manager::BibManager; +use bibliographix::bibliography::bibliography_entry::BibliographyEntryReference; +use bibliographix::references::bib_reference::BibRefAnchor; use std::collections::HashMap; use std::fs::read; use std::path::PathBuf; use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, RwLock}; +use std::sync::{Arc, Mutex, RwLock}; pub const SECTION: &str = "section"; pub const PARAGRAPH: &str = "paragraph"; @@ -56,7 +59,7 @@ pub enum Line { Ruler(Ruler), Anchor(Anchor), Centered(Centered), - BibEntry(Arc>), + BibEntry(BibEntry), } #[derive(Clone, Debug)] @@ -66,7 +69,7 @@ pub struct Document { pub(crate) path: Option, pub(crate) placeholders: Vec>>, pub config: Configuration, - pub bibliography: Bibliography, + pub bibliography: BibManager, pub stylesheets: Vec, } @@ -284,7 +287,19 @@ impl Document { path: None, placeholders: Vec::new(), config: Configuration::default(), - bibliography: Bibliography::new(), + bibliography: BibManager::new(), + stylesheets: Vec::new(), + } + } + + pub fn new_with_manager(is_root: bool, bibliography: BibManager) -> Self { + Self { + elements: Vec::new(), + is_root, + path: None, + placeholders: Vec::new(), + config: Configuration::default(), + bibliography, stylesheets: Vec::new(), } } @@ -352,7 +367,6 @@ impl Document { if let Some(doc) = &mut anchor.document { self.placeholders.append(&mut doc.placeholders); - self.bibliography.combine(&mut doc.bibliography); doc.elements.reverse(); self.elements.append(&mut doc.elements); anchor.document = None; @@ -381,7 +395,7 @@ impl Document { self.postprocess_imports(); if self.is_root { self.process_definitions(); - self.bibliography.assign_entry_data(); + self.bibliography.assign_entries_to_references(); self.process_placeholders(); } } @@ -604,6 +618,7 @@ impl Placeholder { pub trait Metadata { fn get_bool(&self, key: &str) -> bool; fn get_string(&self, key: &str) -> Option; + fn get_string_map(&self) -> HashMap; } impl Metadata for InlineMetadata { @@ -622,6 +637,21 @@ impl Metadata for InlineMetadata { None } } + + fn get_string_map(&self) -> HashMap { + let mut string_map = HashMap::new(); + for (k, v) in &self.data { + match v { + MetadataValue::String(s) => string_map.insert(k.clone(), s.clone()), + MetadataValue::Bool(b) => string_map.insert(k.clone(), b.to_string()), + MetadataValue::Float(f) => string_map.insert(k.clone(), f.to_string()), + MetadataValue::Integer(i) => string_map.insert(k.clone(), i.to_string()), + _ => None, + }; + } + + string_map + } } impl Image { @@ -650,3 +680,47 @@ impl Image { } } } + +#[derive(Clone, Debug)] +pub struct BibEntry { + pub key: String, + pub entry: BibliographyEntryReference, +} + +#[derive(Clone, Debug)] +pub struct BibReference { + pub(crate) key: String, + pub(crate) entry_anchor: Arc>, + pub(crate) display: Option, +} + +impl BibReference { + pub fn new( + key: String, + display: Option, + anchor: Arc>, + ) -> Self { + Self { + key: key.to_string(), + display, + entry_anchor: anchor, + } + } + + pub(crate) fn get_formatted(&self) -> String { + if let Some(entry) = &self.entry_anchor.lock().unwrap().entry { + let entry = entry.lock().unwrap(); + if let Some(display) = &self.display { + let display = display.read().unwrap(); + let mut template = PlaceholderTemplate::new(display.get().as_string()); + let mut value_map = HashMap::new(); + value_map.insert("key".to_string(), entry.key()); + template.set_replacements(value_map); + return template.render(); + } + return format!("{}", entry.key()); + } + + return "citation needed".to_string(); + } +} diff --git a/src/format/html.rs b/src/format/html.rs index 88353f3..6bbb22f 100644 --- a/src/format/html.rs +++ b/src/format/html.rs @@ -1,7 +1,5 @@ use crate::elements::*; use crate::format::PlaceholderTemplate; -use crate::references::bibliography::{BibEntry, BibReference}; -use crate::references::configuration::Value; use crate::references::templates::{Template, TemplateVariable}; use asciimath_rs::format::mathml::ToMathML; use htmlescape::{encode_attribute, encode_minimal}; @@ -43,7 +41,7 @@ impl ToHtml for Line { Line::Ruler(ruler) => ruler.to_html(), Line::Anchor(anchor) => anchor.to_html(), Line::Centered(centered) => centered.to_html(), - Line::BibEntry(bib) => bib.read().unwrap().to_html(), + Line::BibEntry(_) => "".to_string(), } } } @@ -569,55 +567,6 @@ impl ToHtml for BibReference { } } -impl ToHtml for BibEntry { - fn to_html(&self) -> String { - if !self.is_visible() { - return "".to_string(); - } - if let Some(display) = &self.display { - let display = display.read().unwrap(); - if let Value::Template(template) = display.get() { - let replacements = self - .as_map() - .iter() - .map(|(k, v)| { - ( - k.clone(), - Element::Inline(Box::new(Inline::Plain(PlainText { - value: v.clone(), - }))), - ) - }) - .collect(); - return template - .render(replacements) - .iter() - .fold("".to_string(), |a, b| format!("{}{}", a, b.to_html())); - } - let mut template = PlaceholderTemplate::new(display.get().as_string()); - template.set_replacements(self.as_map()); - format!( - "{}", - encode_attribute(self.key.as_str()), - encode_minimal(template.render().as_str()) - ) - } else { - if let Some(url) = &self.url { - format!( - "{1}", - encode_attribute(url.as_str()), - encode_minimal(self.key.as_str()) - ) - } else { - format!( - "{0}", - encode_attribute(self.key.as_str()) - ) - } - } - } -} - impl ToHtml for Template { fn to_html(&self) -> String { self.text diff --git a/src/parser/inline.rs b/src/parser/inline.rs index 6307d38..ce64b81 100644 --- a/src/parser/inline.rs +++ b/src/parser/inline.rs @@ -1,11 +1,12 @@ use super::{ParseError, ParseResult}; use crate::elements::tokens::*; +use crate::elements::BibReference; use crate::elements::*; use crate::parser::block::ParseBlock; -use crate::references::bibliography::BibReference; use crate::references::configuration::keys::BIB_REF_DISPLAY; use crate::references::templates::{GetTemplateVariables, Template, TemplateVariable}; use crate::Parser; +use bibliographix::references::bib_reference::BibRef; use std::collections::HashMap; use std::sync::{Arc, RwLock}; @@ -301,13 +302,18 @@ impl ParseInline for Parser { self.ctm .get_string_until_any_or_rewind(&[BIBREF_CLOSE], &[SPACE, LB], start_index)?; self.ctm.seek_one()?; + let bib_ref = BibRef::new(key.clone()); let ref_entry = Arc::new(RwLock::new(BibReference::new( key, self.document.config.get_ref_entry(BIB_REF_DISPLAY), + bib_ref.anchor(), ))); self.document .bibliography - .add_ref_entry(Arc::clone(&ref_entry)); + .root_ref_anchor() + .lock() + .unwrap() + .insert(bib_ref); Ok(ref_entry) } diff --git a/src/parser/line.rs b/src/parser/line.rs index e9373b8..4640d01 100644 --- a/src/parser/line.rs +++ b/src/parser/line.rs @@ -1,10 +1,13 @@ use super::ParseResult; use crate::elements::tokens::*; +use crate::elements::{BibEntry, Metadata}; use crate::elements::{Cell, Centered, Header, Inline, Line, ListItem, Row, Ruler, TextLine}; use crate::parser::inline::ParseInline; -use crate::references::bibliography::BibEntry; use crate::Parser; -use std::sync::{Arc, RwLock}; +use bibliographix::bibliography::bibliography_entry::BibliographyEntry; +use bibliographix::bibliography::keys::{K_KEY, K_TYPE, K_URL, T_WEBSITE}; +use bibliographix::bibliography::FromHashMap; +use std::collections::HashMap; pub(crate) trait ParseLine { fn parse_line(&mut self) -> ParseResult; @@ -14,7 +17,7 @@ pub(crate) trait ParseLine { fn parse_centered(&mut self) -> ParseResult; fn parse_ruler(&mut self) -> ParseResult; fn parse_text_line(&mut self) -> ParseResult; - fn parse_bib_entry(&mut self) -> ParseResult>>; + fn parse_bib_entry(&mut self) -> ParseResult; } impl ParseLine for Parser { @@ -174,7 +177,7 @@ impl ParseLine for Parser { } } - fn parse_bib_entry(&mut self) -> ParseResult>> { + fn parse_bib_entry(&mut self) -> ParseResult { let start_index = self.ctm.get_index(); self.ctm.seek_any(&INLINE_WHITESPACE)?; self.ctm.assert_char(&BIB_KEY_OPEN, Some(start_index))?; @@ -188,18 +191,49 @@ impl ParseLine for Parser { self.ctm.seek_any(&INLINE_WHITESPACE)?; let entry = if let Ok(meta) = self.parse_inline_metadata() { - BibEntry::from_metadata(key, Box::new(meta), &self.document.config) + let mut string_map = meta.get_string_map(); + string_map.insert(K_KEY.to_string(), key.clone()); + + if let Some(entry) = BibliographyEntry::from_hash_map(&string_map) { + *entry + } else { + eprintln!("Failed to parse bib entry with key {}", key); + return Err(self.ctm.rewind_with_error(start_index)); + } } else { let url = self .ctm .get_string_until_any_or_rewind(&[LB], &[], start_index)?; - BibEntry::from_url(key, url, &self.document.config) + let mut map = HashMap::new(); + map.insert(K_TYPE.to_string(), T_WEBSITE.to_string()); + map.insert(K_URL.to_string(), url); + map.insert(K_KEY.to_string(), key.clone()); + + if let Some(entry) = BibliographyEntry::from_hash_map(&map) { + *entry + } else { + eprintln!("Failed to parse bib entry with key {}", key); + return Err(self.ctm.rewind_with_error(start_index)); + } }; - let entry_ref = Arc::new(RwLock::new(entry)); + self.document .bibliography - .add_bib_entry(Arc::clone(&entry_ref)); - - Ok(entry_ref) + .entry_dictionary() + .lock() + .unwrap() + .insert(entry); + + Ok(BibEntry { + entry: self + .document + .bibliography + .entry_dictionary() + .lock() + .unwrap() + .get(&key) + .unwrap(), + key, + }) } } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index c8b1cac..3280fd6 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -5,6 +5,7 @@ pub(crate) mod line; use self::block::ParseBlock; use crate::elements::{Document, ImportAnchor}; use crate::references::configuration::Configuration; +use bibliographix::bib_manager::BibManager; use charred::tapemachine::{CharTapeMachine, TapeError, TapeResult}; use colored::*; use crossbeam_utils::sync::WaitGroup; @@ -42,6 +43,7 @@ impl Parser { Arc::new(Mutex::new(Vec::new())), false, Box::new(BufReader::new(f)), + BibManager::new(), )) } @@ -58,17 +60,24 @@ impl Parser { Arc::new(Mutex::new(Vec::new())), false, Box::new(Cursor::new(text_bytes.to_vec())), + BibManager::new(), ) } /// Creates a child parser from string text - pub fn child(text: String, path: PathBuf, paths: Arc>>) -> Self { + pub fn child( + text: String, + path: PathBuf, + paths: Arc>>, + bib_manager: BibManager, + ) -> Self { let text_bytes = text.as_bytes(); Self::create( Some(PathBuf::from(path)), paths, true, Box::new(Cursor::new(text_bytes.to_vec())), + bib_manager, ) } @@ -76,6 +85,7 @@ impl Parser { pub fn child_from_file( path: PathBuf, paths: Arc>>, + bib_manager: BibManager, ) -> Result { let f = File::open(&path)?; Ok(Self::create( @@ -83,6 +93,7 @@ impl Parser { paths, true, Box::new(BufReader::new(f)), + bib_manager, )) } @@ -91,6 +102,7 @@ impl Parser { paths: Arc>>, is_child: bool, mut reader: Box, + bib_manager: BibManager, ) -> Self { if let Some(path) = path.clone() { paths.lock().unwrap().push(path.clone()) @@ -103,7 +115,7 @@ impl Parser { text.push('\n'); } - let document = Document::new(!is_child); + let document = Document::new_with_manager(!is_child, bib_manager); Self { sections: Vec::new(), section_nesting: 0, @@ -178,9 +190,10 @@ impl Parser { let wg = self.wg.clone(); let paths = Arc::clone(&self.paths); let config = self.document.config.clone(); + let bibliography = self.document.bibliography.create_child(); let _ = thread::spawn(move || { - let mut parser = Parser::child_from_file(path, paths).unwrap(); + let mut parser = Parser::child_from_file(path, paths, bibliography).unwrap(); parser.set_config(config); let document = parser.parse(); anchor_clone.write().unwrap().set_document(document); diff --git a/src/references/bibliography.rs b/src/references/bibliography.rs index d27a65b..8b13789 100644 --- a/src/references/bibliography.rs +++ b/src/references/bibliography.rs @@ -1,200 +1 @@ -use crate::elements::Metadata; -use crate::format::PlaceholderTemplate; -use crate::references::configuration::keys::{BIB_DISPLAY, BIB_HIDE_UNUSED}; -use crate::references::configuration::{ConfigRefEntry, Configuration, Value}; -use std::collections::HashMap; -use std::sync::{Arc, RwLock}; -const B_NUMBER: &str = "number"; -const B_AUTHOR: &str = "author"; -const B_DATE: &str = "date"; -const B_URL: &str = "url"; -const B_TITLE: &str = "title"; -const B_PUBLISHER: &str = "publisher"; -const B_NOTES: &str = "notes"; - -#[derive(Clone, Debug)] -pub struct BibEntry { - pub(crate) number: usize, - pub(crate) ref_count: usize, - pub key: String, - pub author: Option, - pub date: Option, - pub url: Option, - pub title: Option, - pub publisher: Option, - pub notes: Option, - pub display: Option, - pub hide_unused: Option, -} - -#[derive(Clone, Debug)] -pub struct BibReference { - pub(crate) key: String, - pub(crate) reference_entry: Option>>, - pub(crate) display: Option, -} - -#[derive(Clone, Debug)] -pub struct Bibliography { - entries: HashMap>>, - references: Vec>>, -} - -impl BibEntry { - pub fn as_map(&self) -> HashMap { - let mut map = HashMap::new(); - map.insert(B_NUMBER.to_string(), format!("{}", self.number)); - map.insert("key".to_string(), self.key.clone()); - if let Some(author) = &self.author { - map.insert(B_AUTHOR.to_string(), author.clone()); - } - if let Some(date) = &self.date { - map.insert(B_DATE.to_string(), date.clone()); - } - if let Some(url) = &self.url { - map.insert(B_URL.to_string(), url.clone()); - } - if let Some(title) = &self.title { - map.insert(B_TITLE.to_string(), title.clone()); - } - if let Some(publisher) = &self.publisher { - map.insert(B_PUBLISHER.to_string(), publisher.clone()); - } - if let Some(notes) = &self.notes { - map.insert(B_NOTES.to_string(), notes.clone()); - } - - map - } - - pub fn from_metadata(key: String, data: Box, config: &Configuration) -> Self { - BibEntry { - number: 0, - ref_count: 0, - key, - author: data.get_string(B_AUTHOR), - date: data.get_string(B_DATE), - url: data.get_string(B_URL), - title: data.get_string(B_TITLE), - publisher: data.get_string(B_PUBLISHER), - notes: data.get_string(B_NOTES), - display: config.get_ref_entry(BIB_DISPLAY), - hide_unused: config.get_ref_entry(BIB_HIDE_UNUSED), - } - } - - pub fn from_url(key: String, url: String, config: &Configuration) -> Self { - BibEntry { - number: 0, - ref_count: 0, - key, - author: None, - date: None, - url: Some(url), - title: None, - publisher: None, - notes: None, - display: config.get_ref_entry(BIB_DISPLAY), - hide_unused: config.get_ref_entry(BIB_HIDE_UNUSED), - } - } - - pub fn set_number(&mut self, number: usize) { - self.number = number - } - - pub fn set_ref_count(&mut self, number: usize) { - self.ref_count = number - } - - pub fn is_visible(&self) -> bool { - if let Some(hide_cfg) = &self.hide_unused { - let hide_cfg = hide_cfg.read().unwrap(); - if let Value::Bool(b) = hide_cfg.get() { - if *b && self.ref_count == 0 { - return false; - } - } - } - - true - } -} - -impl BibReference { - pub fn new(key: String, display: Option) -> Self { - Self { - key: key.to_string(), - display, - reference_entry: None, - } - } - - /// sets the reference to the bib entry - pub(crate) fn set_entry(&mut self, entry: Arc>) { - self.reference_entry = Some(entry) - } - - pub(crate) fn get_formatted(&self) -> String { - if let Some(entry) = &self.reference_entry { - let entry = entry.read().unwrap(); - if let Some(display) = &self.display { - let display = display.read().unwrap(); - let mut template = PlaceholderTemplate::new(display.get().as_string()); - template.set_replacements(entry.as_map()); - return template.render(); - } - return format!("{}", entry.number); - } - - return "citation needed".to_string(); - } -} - -impl Bibliography { - pub fn new() -> Self { - Self { - entries: HashMap::new(), - references: Vec::new(), - } - } - - pub(crate) fn assign_entry_data(&mut self) { - let mut count = 0; - self.references.iter().for_each(|e| { - let mut reference = e.write().unwrap(); - if let Some(entry) = self.entries.get(&reference.key) { - { - let mut entry_raw = entry.write().unwrap(); - let ref_count = entry_raw.ref_count; - entry_raw.set_ref_count(ref_count + 1); - } - reference.set_entry(Arc::clone(entry)); - } - }); - self.entries.iter().for_each(|(_, e)| { - let mut entry = e.write().unwrap(); - if entry.is_visible() { - count += 1; - entry.set_number(count) - } - }); - } - - pub fn add_ref_entry(&mut self, entry: Arc>) { - self.references.push(entry) - } - - pub fn add_bib_entry(&mut self, entry: Arc>) { - let key = entry.read().unwrap().key.clone(); - self.entries.insert(key, entry); - } - - pub fn combine(&mut self, other: &mut Bibliography) { - let other_entries = other.entries.clone(); - other.entries = HashMap::new(); - self.entries.extend(other_entries.into_iter()); - self.references.append(&mut other.references); - } -} diff --git a/src/references/configuration/default.toml b/src/references/configuration/default.toml index f6257e6..614c89a 100644 --- a/src/references/configuration/default.toml +++ b/src/references/configuration/default.toml @@ -1,4 +1,4 @@ [bibliography] entry_display = "{{number}}: {{author}} - {{title}} - {{date}} - {{url}}" -reference_display = "{{number}}" +reference_display = "{{key}}" hide_unused = true \ No newline at end of file