diff options
Diffstat (limited to 'support/texlab/src/syntax/latex/mod.rs')
-rw-r--r-- | support/texlab/src/syntax/latex/mod.rs | 686 |
1 files changed, 0 insertions, 686 deletions
diff --git a/support/texlab/src/syntax/latex/mod.rs b/support/texlab/src/syntax/latex/mod.rs deleted file mode 100644 index cee83ab04e..0000000000 --- a/support/texlab/src/syntax/latex/mod.rs +++ /dev/null @@ -1,686 +0,0 @@ -mod analysis; -mod ast; -mod lexer; -mod parser; - -pub use self::{analysis::*, ast::*}; - -use self::{lexer::Lexer, parser::Parser}; -use crate::{ - protocol::{Options, Uri}, - tex::Resolver, -}; -use std::path::Path; - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub struct OpenParams<'a> { - pub text: &'a str, - pub uri: &'a Uri, - pub resolver: &'a Resolver, - pub options: &'a Options, - pub current_dir: &'a Path, -} - -pub fn open(params: OpenParams) -> SymbolTable { - let OpenParams { - text, - uri, - resolver, - options, - current_dir, - } = params; - - let lexer = Lexer::new(text); - let parser = Parser::new(lexer); - let tree = parser.parse(); - - let params = SymbolTableParams { - tree, - uri, - resolver, - options, - current_dir, - }; - SymbolTable::analyze(params) -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - protocol::{Options, Range, RangeExt, Uri}, - syntax::{generic_ast::AstNodeIndex, text::SyntaxNode}, - tex::Resolver, - }; - use indoc::indoc; - use std::env; - - fn open_simple(text: &str) -> SymbolTable { - open(OpenParams { - text: text.trim(), - uri: &Uri::parse("http://www.foo.com/bar.tex").unwrap(), - resolver: &Resolver::default(), - options: &Options::default(), - current_dir: &env::current_dir().unwrap(), - }) - } - - #[derive(Debug, Default)] - struct TreeTraversal { - nodes: Vec<AstNodeIndex>, - } - - impl Visitor for TreeTraversal { - fn visit(&mut self, tree: &Tree, node: AstNodeIndex) { - self.nodes.push(node); - tree.walk(self, node); - } - } - - mod range { - use super::*; - - fn verify(expected_ranges: Vec<Range>, text: &str) { - let table = open_simple(text); - - let mut traversal = TreeTraversal::default(); - traversal.visit(&table.tree, table.tree.root); - let actual_ranges: Vec<_> = traversal - .nodes - .into_iter() - .map(|node| table[node].range()) - .collect(); - assert_eq!(actual_ranges, expected_ranges); - } - - #[test] - fn command() { - verify( - vec![ - Range::new_simple(0, 0, 2, 14), - Range::new_simple(0, 0, 0, 23), - Range::new_simple(0, 14, 0, 23), - Range::new_simple(0, 15, 0, 22), - Range::new_simple(1, 0, 1, 20), - Range::new_simple(1, 11, 1, 20), - Range::new_simple(1, 12, 1, 19), - Range::new_simple(2, 0, 2, 14), - Range::new_simple(2, 4, 2, 9), - Range::new_simple(2, 5, 2, 8), - Range::new_simple(2, 9, 2, 14), - Range::new_simple(2, 10, 2, 13), - ], - indoc!( - r#" - \documentclass{article} - \usepackage{amsmath} - \foo[bar]{baz} - "# - ), - ); - } - - #[test] - fn text() { - verify( - vec![ - Range::new_simple(0, 0, 0, 11), - Range::new_simple(0, 0, 0, 11), - ], - indoc!( - r#" - foo bar baz - "# - ), - ); - } - - #[test] - fn text_bracket() { - verify( - vec![Range::new_simple(0, 0, 0, 5), Range::new_simple(0, 0, 0, 5)], - indoc!( - r#" - ]foo[ - "# - ), - ); - } - - #[test] - fn group() { - verify( - vec![ - Range::new_simple(0, 0, 0, 15), - Range::new_simple(0, 0, 0, 15), - Range::new_simple(0, 2, 0, 5), - Range::new_simple(0, 6, 0, 13), - Range::new_simple(0, 8, 0, 11), - ], - indoc!( - r#" - { foo { bar } } - "# - ), - ); - } - - #[test] - fn group_incomplete() { - verify( - vec![Range::new_simple(0, 1, 0, 2), Range::new_simple(0, 1, 0, 2)], - indoc!( - r#" - }{ - "# - ), - ); - } - - #[test] - fn math() { - verify( - vec![ - Range::new_simple(0, 0, 0, 9), - Range::new_simple(0, 0, 0, 1), - Range::new_simple(0, 2, 0, 7), - Range::new_simple(0, 8, 0, 9), - ], - indoc!( - r#" - $ x = 1 $ - "# - ), - ); - } - - #[test] - fn comma() { - verify( - vec![ - Range::new_simple(0, 0, 0, 8), - Range::new_simple(0, 0, 0, 3), - Range::new_simple(0, 3, 0, 4), - Range::new_simple(0, 5, 0, 8), - ], - indoc!( - r#" - foo, bar - "# - ), - ); - } - } - - mod command { - use super::*; - - fn verify(expected_names: Vec<&str>, text: &str) { - let table = open(OpenParams { - text, - uri: &Uri::parse("http://www.foo.com/bar.tex").unwrap(), - resolver: &Resolver::default(), - options: &Options::default(), - current_dir: &env::current_dir().unwrap(), - }); - - let actual_names: Vec<_> = table - .commands - .iter() - .map(|node| table.tree.as_command(*node).unwrap().name.text()) - .collect(); - - assert_eq!(actual_names, expected_names); - } - - #[test] - fn basic() { - verify( - vec!["\\documentclass", "\\usepackage", "\\begin", "\\end"], - indoc!( - r#" - \documentclass{article} - \usepackage{amsmath} - \begin{document} - Hello World - \end{document} - "# - ), - ); - } - - #[test] - fn star() { - verify( - vec!["\\section*", "\\subsection*"], - indoc!( - r#" - \section*{Foo} - \subsection**{Bar} - "# - ), - ); - } - - #[test] - fn at() { - verify(vec!["\\foo@bar"], indoc!(r#"\foo@bar"#)); - } - - #[test] - fn escape() { - verify(vec!["\\%"], indoc!(r#"\%foo"#)) - } - } - - mod environment { - use super::*; - - fn verify(expected_names: Vec<(&str, &str)>, text: &str) { - let table = open_simple(text); - let actual_names: Vec<_> = table - .environments - .iter() - .map(|env| { - ( - env.left - .name(&table.tree) - .map(Token::text) - .unwrap_or_default(), - env.right - .name(&table.tree) - .map(Token::text) - .unwrap_or_default(), - ) - }) - .collect(); - - assert_eq!(actual_names, expected_names); - } - - #[test] - fn nested() { - verify( - vec![("b", "b"), ("a", "a")], - indoc!( - r#" - \begin{a} - \begin{b} - \end{b} - \end{a} - "# - ), - ); - } - - #[test] - fn empty_name() { - verify( - vec![("a", ""), ("", "b")], - indoc!( - r#" - \begin{a} - \end{} - \begin{} - \end{b} - "# - ), - ); - } - - #[test] - fn incomplete() { - verify( - Vec::new(), - indoc!( - r#" - \end{a} - \begin{a} - "# - ), - ); - } - - #[test] - fn standalone_true() { - let table = open_simple(r#"\begin{document}\end{document}"#); - assert!(table.is_standalone); - } - - #[test] - fn standalone_false() { - let table = open_simple(r#"\begin{doc}\end{doc}"#); - assert!(!table.is_standalone); - } - } - - mod include { - use super::*; - - fn verify(expected_targets: Vec<Vec<&str>>, resolver: Resolver, text: &str) { - let table = open(OpenParams { - text, - uri: &Uri::parse("http://www.foo.com/dir1/dir2/foo.tex").unwrap(), - resolver: &resolver, - options: &Options::default(), - current_dir: &env::current_dir().unwrap(), - }); - - assert_eq!(table.includes.len(), 1); - let include = &table.includes[0]; - let actual_targets: Vec<Vec<&str>> = include - .all_targets - .iter() - .map(|targets| targets.iter().map(|target| target.as_str()).collect()) - .collect(); - - assert_eq!(actual_targets, expected_targets); - } - - #[test] - fn same_directory() { - verify( - vec![vec![ - "http://www.foo.com/dir1/dir2/bar", - "http://www.foo.com/dir1/dir2/bar.tex", - ]], - Resolver::default(), - indoc!(r#"\include{bar}"#), - ); - } - - #[test] - fn two_paths() { - verify( - vec![ - vec![ - "http://www.foo.com/dir1/dir2/bar.tex", - "http://www.foo.com/dir1/dir2/bar.tex.tex", - ], - vec![ - "http://www.foo.com/dir1/dir2/baz.tex", - "http://www.foo.com/dir1/dir2/baz.tex.tex", - ], - ], - Resolver::default(), - indoc!(r#"\input{bar.tex, ./baz.tex}"#), - ); - } - - #[test] - fn sub_directory() { - verify( - vec![vec![ - "http://www.foo.com/dir1/dir2/dir3/bar", - "http://www.foo.com/dir1/dir2/dir3/bar.tex", - ]], - Resolver::default(), - indoc!(r#"\include{dir3/bar}"#), - ); - } - - #[test] - fn parent_directory() { - verify( - vec![vec![ - "http://www.foo.com/dir1/bar", - "http://www.foo.com/dir1/bar.tex", - ]], - Resolver::default(), - indoc!(r#"\include{../bar}"#), - ); - } - - #[test] - fn distro_file() { - let mut resolver = Resolver::default(); - let path = env::current_dir().unwrap().join("biblatex-examples.bib"); - resolver - .files_by_name - .insert("biblatex-examples.bib".into(), path.clone()); - verify( - vec![vec![ - "http://www.foo.com/dir1/dir2/biblatex-examples.bib", - "http://www.foo.com/dir1/dir2/biblatex-examples.bib.bib", - Uri::from_file_path(&path).unwrap().as_str(), - ]], - resolver, - indoc!(r#"\addbibresource{biblatex-examples.bib}"#), - ); - } - - #[test] - fn component() { - let table = open(OpenParams { - text: indoc!( - r#" - \documentclass{article} - \usepackage{amsmath} - \usepackage{geometry, lipsum} - "# - ), - uri: &Uri::parse("http://www.foo.com/bar.tex").unwrap(), - resolver: &Resolver::default(), - options: &Options::default(), - current_dir: &env::current_dir().unwrap(), - }); - assert_eq!( - table.components, - vec!["article.cls", "amsmath.sty", "geometry.sty", "lipsum.sty"] - ); - } - } - - #[test] - fn citation() { - let table = open_simple(indoc!( - r#" - \cite{key1} - \cite{key2, key3} - \nocite{*} - "# - )); - - let expected_keys = vec![vec!["key1"], vec!["key2", "key3"], vec!["*"]]; - - let actual_keys: Vec<Vec<&str>> = table - .citations - .iter() - .map(|cit| cit.keys(&table.tree).into_iter().map(Token::text).collect()) - .collect(); - - assert_eq!(actual_keys, expected_keys); - } - - #[test] - fn command_definition() { - let table = open_simple(indoc!( - r#" - \newcommand{\foo}{Foo} - \newcommand[2]{\bar}{Bar} - \renewcommand{\baz}{Baz} - \qux - "# - )); - - let expected_cmds = vec!["\\foo", "\\bar", "\\baz"]; - - let actual_cmds: Vec<&str> = table - .command_definitions - .iter() - .map(|def| def.definition_name(&table.tree)) - .collect(); - - assert_eq!(actual_cmds, expected_cmds); - } - - #[test] - fn glossary_entry() { - let table = open_simple(indoc!( - r#" - \newglossaryentry{foo}{...} - \newacronym{bar}{...} - "# - )); - - let expected_entries = vec!["foo", "bar"]; - - let actual_entries: Vec<&str> = table - .glossary_entries - .iter() - .map(|entry| entry.label(&table.tree).text()) - .collect(); - - assert_eq!(actual_entries, expected_entries); - } - - #[test] - fn equation() { - let table = open_simple(indoc!( - r#" - \[ - e^{i \pi} + 1 = 0 - \] - \] \[ - "# - )); - - assert_eq!(table.equations.len(), 1); - } - - #[test] - fn inline() { - let table = open_simple(indoc!( - r#" - $ x $ - $ - "# - )); - - assert_eq!(table.inlines.len(), 1); - } - - #[test] - fn math_operator() { - let table = open_simple(indoc!( - r#" - \DeclareMathOperator{\foo}{foo} - "# - )); - - assert_eq!(table.math_operators.len(), 1); - assert_eq!( - table.math_operators[0].definition_name(&table.tree), - "\\foo" - ); - } - - #[test] - fn theorem_definition() { - let table = open_simple(indoc!( - r#" - \newtheorem{lemma}{Lemma} - "# - )); - - assert_eq!(table.theorem_definitions.len(), 1); - assert_eq!( - table.theorem_definitions[0].name(&table.tree).text(), - "lemma" - ); - } - - #[test] - fn section() { - let table = open_simple(indoc!( - r#" - \section{Introduction to \LaTeX} - \subsection*{Foo - "# - )); - assert_eq!(table.sections.len(), 2); - assert_eq!( - table.sections[0].print(&table.tree).unwrap(), - "Introduction to \\LaTeX" - ); - assert_eq!(table.sections[1].print(&table.tree), None); - } - - #[test] - fn label() { - let table = open_simple(indoc!( - r#" - \label{foo} - \ref{bar, baz} - "# - )); - - let expected_names = vec![vec!["foo"], vec!["bar", "baz"]]; - - let actual_names: Vec<Vec<&str>> = table - .labels - .iter() - .map(|label| { - label - .names(&table.tree) - .into_iter() - .map(Token::text) - .collect() - }) - .collect(); - - assert_eq!(actual_names, expected_names); - } - - #[test] - fn label_numbering() { - let table = open_simple(indoc!( - r#" - \newlabel{foo}{{1}{1}} - "# - )); - - assert_eq!(table.label_numberings.len(), 1); - assert_eq!(table.label_numberings[0].name(&table.tree).text(), "foo"); - assert_eq!(table.label_numberings[0].number, "1"); - } - - #[test] - fn caption() { - let table = open_simple(indoc!( - r#" - \caption{Foo \LaTeX Bar} - "# - )); - - assert_eq!(table.captions.len(), 1); - assert_eq!( - table.captions[0].print(&table.tree).unwrap(), - "Foo \\LaTeX Bar" - ); - } - - #[test] - fn item_without_name() { - let table = open_simple(indoc!( - r#" - \item - "# - )); - - assert_eq!(table.items.len(), 1); - assert_eq!(table.items[0].name(&table.tree), None); - } - - #[test] - fn item_with_name() { - let table = open_simple(indoc!( - r#" - \item[foo bar] - "# - )); - - assert_eq!(table.items.len(), 1); - assert_eq!(table.items[0].name(&table.tree).unwrap(), "foo bar"); - } -} |