diff options
Diffstat (limited to 'support/texlab/src/syntax/bibtex/mod.rs')
-rw-r--r-- | support/texlab/src/syntax/bibtex/mod.rs | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/support/texlab/src/syntax/bibtex/mod.rs b/support/texlab/src/syntax/bibtex/mod.rs new file mode 100644 index 0000000000..9910390fe7 --- /dev/null +++ b/support/texlab/src/syntax/bibtex/mod.rs @@ -0,0 +1,75 @@ +mod ast; +mod finder; +mod lexer; +mod parser; + +use self::lexer::BibtexLexer; +use self::parser::BibtexParser; + +pub use self::ast::*; +pub use self::finder::*; +use lsp_types::Position; + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct BibtexSyntaxTree { + pub root: BibtexRoot, +} + +impl BibtexSyntaxTree { + pub fn entries(&self) -> Vec<&BibtexEntry> { + let mut entries: Vec<&BibtexEntry> = Vec::new(); + for declaration in &self.root.children { + if let BibtexDeclaration::Entry(entry) = declaration { + entries.push(&entry); + } + } + entries + } + + pub fn strings(&self) -> Vec<&BibtexString> { + let mut strings: Vec<&BibtexString> = Vec::new(); + for declaration in &self.root.children { + if let BibtexDeclaration::String(string) = declaration { + strings.push(&string); + } + } + strings + } + + pub fn find(&self, position: Position) -> Vec<BibtexNode> { + let mut finder = BibtexFinder::new(position); + finder.visit_root(&self.root); + finder.results + } + + pub fn find_entry(&self, key: &str) -> Option<&BibtexEntry> { + self.entries() + .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<BibtexRoot> for BibtexSyntaxTree { + fn from(root: BibtexRoot) -> Self { + BibtexSyntaxTree { root } + } +} + +impl From<&str> for BibtexSyntaxTree { + fn from(text: &str) -> Self { + let lexer = BibtexLexer::new(text); + let mut parser = BibtexParser::new(lexer); + parser.root().into() + } +} |