diff --git a/src/citeproc/mod.rs b/src/citeproc/mod.rs index e42958923..8feba22b4 100644 --- a/src/citeproc/mod.rs +++ b/src/citeproc/mod.rs @@ -6,15 +6,29 @@ use crate::formatting::bibtex::{format_entry, format_string, BibtexFormattingPar use crate::syntax::*; use bibutils::{InputFormat, OutputFormat}; use citeproc::prelude::*; -use citeproc::Processor; use citeproc_db::PredefinedLocales; -use citeproc_io::Reference; -use lsp_types::*; +use lsp_types::{MarkupContent, MarkupKind}; use std::sync::Arc; static APA_STYLE: &str = include_str!("apa.csl"); pub fn render_citation(tree: &BibtexSyntaxTree, key: &str) -> Option { + let reference: Reference = convert_to_ris(tree, key)?.into(); + + let html = generate_bibliography(reference)?; + let markdown = html2md::parse_html(&html).trim().to_owned(); + if markdown == "" { + return None; + } + + let content = MarkupContent { + kind: MarkupKind::Markdown, + value: markdown, + }; + Some(content) +} + +fn convert_to_ris(tree: &BibtexSyntaxTree, key: &str) -> Option { let bib_params = BibtexFormattingParams::default(); let mut bib_code = String::new(); @@ -24,16 +38,9 @@ pub fn render_citation(tree: &BibtexSyntaxTree, key: &str) -> Option Option Option { let locales = Arc::new(PredefinedLocales::bundled_en_us()); let mut processor = Processor::new(APA_STYLE, locales, false, SupportedFormat::Html).unwrap(); - let mut clusters = Vec::new(); - let cite = Cite::basic(&csl_ref.id); - clusters.push(Cluster2::Note { + let cite = Cite::basic(&reference.id); + let cluster = Cluster2::Note { id: 1, note: IntraNote::Single(1), cites: vec![cite], - }); - processor.insert_reference(csl_ref); - processor.init_clusters(clusters); - let html = processor.get_bibliography().pop().unwrap(); - let markdown = html2md::parse_html(&html).trim().to_owned(); - if markdown == "" { - return None; - } - - Some(MarkupContent { - kind: MarkupKind::Markdown, - value: markdown, - }) + }; + processor.insert_reference(reference); + processor.init_clusters(vec![cluster]); + processor.get_bibliography().pop() } diff --git a/src/citeproc/name/parser.lalrpop b/src/citeproc/name/parser.lalrpop index 9e4e36938..556e3bd36 100644 --- a/src/citeproc/name/parser.lalrpop +++ b/src/citeproc/name/parser.lalrpop @@ -1,3 +1,6 @@ +// Ported from: https://github.com/michel-kraemer/citeproc-java/blob/master/citeproc-java/grammars/InternalName.g4 +// Michel Kraemer +// Apache License 2.0 use citeproc_io::{Name, PersonName}; use itertools::Itertools; @@ -5,7 +8,7 @@ grammar; pub Names: Vec = And; -And: Vec = { // (1) +And: Vec = { "and")*> => match e { None => v, Some(e) => { diff --git a/src/syntax/bibtex/mod.rs b/src/syntax/bibtex/mod.rs index ed2350834..9910390fe 100644 --- a/src/syntax/bibtex/mod.rs +++ b/src/syntax/bibtex/mod.rs @@ -47,6 +47,17 @@ impl BibtexSyntaxTree { .into_iter() .find(|entry| entry.key.as_ref().map(BibtexToken::text) == Some(key)) } + + pub fn resolve_crossref(&self, entry: &BibtexEntry) -> Option<&BibtexEntry> { + if let Some(field) = entry.find_field("crossref") { + if let Some(BibtexContent::BracedContent(content)) = &field.content { + if let Some(BibtexContent::Word(name)) = content.children.get(0) { + return self.find_entry(name.token.text()); + } + } + } + None + } } impl From for BibtexSyntaxTree {