From 367bade807fe3505a58da0ebb54c7e684e0ff56e Mon Sep 17 00:00:00 2001 From: trivernis Date: Tue, 4 Aug 2020 17:50:30 +0200 Subject: [PATCH 1/7] Add ToMathML trait and implementation for greek letters --- src/format/mathml.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++ src/format/mod.rs | 1 + src/lib.rs | 1 + 3 files changed, 52 insertions(+) create mode 100644 src/format/mathml.rs create mode 100644 src/format/mod.rs diff --git a/src/format/mathml.rs b/src/format/mathml.rs new file mode 100644 index 0000000..9051e4c --- /dev/null +++ b/src/format/mathml.rs @@ -0,0 +1,50 @@ +use crate::tokens::Greek; + +pub trait ToMathML { + fn to_mathml(&self) -> String; +} + +impl ToMathML for Greek { + fn to_mathml(&self) -> String { + let inner = match self { + Greek::Alpha => "α", + Greek::Beta => "β", + Greek::Gamma => "γ", + Greek::BigGamma => "Γ", + Greek::Delta => "δ", + Greek::BigDelta => "Δ", + Greek::Epsilon => "ε", + Greek::VarEpsilon => "ε", + Greek::Zeta => "ζ", + Greek::Eta => "η", + Greek::Theta => "θ", + Greek::BigTheta => "Θ", + Greek::VarTheta => "θ", + Greek::Iota => "ι", + Greek::Kappa => "κ", + Greek::Lambda => "λ", + Greek::BigLambda => "Λ", + Greek::Mu => "μ", + Greek::Nu => "ν", + Greek::Xi => "ξ", + Greek::BigXi => "Ξ", + Greek::Pi => "π", + Greek::BigPi => "Π", + Greek::Rho => "ρ", + Greek::Sigma => "σ", + Greek::BigSigma => "Σ", + Greek::Tau => "τ", + Greek::Upsilon => "υ", + Greek::Phi => "φ", + Greek::BigPhi => "Φ", + Greek::VarPhi => "φ", + Greek::Chi => "χ", + Greek::Psi => "ψ", + Greek::BigPsi => "Ψ", + Greek::Omega => "ω", + Greek::BigOmega => "Ω", + }; + + format!("{}", inner) + } +} diff --git a/src/format/mod.rs b/src/format/mod.rs new file mode 100644 index 0000000..6b8555d --- /dev/null +++ b/src/format/mod.rs @@ -0,0 +1 @@ +pub mod mathml; diff --git a/src/lib.rs b/src/lib.rs index 6481938..472c9c0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,7 @@ use crate::parsing::tokenizer::Tokenizer; use crate::parsing::tree_parser::TreeParser; pub mod elements; +pub mod format; pub mod parsing; pub mod tokens; pub(crate) mod utils; From 1308360780b62e37bc1d859c270e10093039d322 Mon Sep 17 00:00:00 2001 From: trivernis Date: Wed, 5 Aug 2020 10:56:49 +0200 Subject: [PATCH 2/7] Add MSep Token --- src/lib.rs | 27 +++++++++++++++++++++++++++ src/parsing/tokenizer.rs | 2 ++ src/tokens/constants/grouping.rs | 2 ++ src/tokens/mappings.rs | 1 + src/tokens/mod.rs | 5 +++++ 5 files changed, 37 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 9d7f4dc..698c6d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,6 +102,33 @@ mod tests { ); } + #[test] + fn it_tokenizes_expressions3() { + let expression = "[[1, 2],[3, 4]]"; + let mut tokenizer = Tokenizer::new(expression.to_string()); + let tokens = tokenizer.parse(); + assert_eq!( + tokens, + vec![ + Token::Grouping(Grouping::RBracket), + Token::Grouping(Grouping::RBracket), + Token::Text(Text::Number("1".to_string())), + Token::Grouping(Grouping::MSep), + Token::Text(Text::Whitespace), + Token::Text(Text::Number("2".to_string())), + Token::Grouping(Grouping::LBracket), + Token::Grouping(Grouping::MSep), + Token::Grouping(Grouping::RBracket), + Token::Text(Text::Number("3".to_string())), + Token::Grouping(Grouping::MSep), + Token::Text(Text::Whitespace), + Token::Text(Text::Number("4".to_string())), + Token::Grouping(Grouping::LBracket), + Token::Grouping(Grouping::LBracket), + ] + ); + } + #[test] fn it_tokenizes_text1() { let expression = "\"just plain text\""; diff --git a/src/parsing/tokenizer.rs b/src/parsing/tokenizer.rs index 69f4872..0b22645 100644 --- a/src/parsing/tokenizer.rs +++ b/src/parsing/tokenizer.rs @@ -1,3 +1,4 @@ +use crate::elements::Element; use crate::tokens::constants::accents::G_COLOR; use crate::tokens::constants::grouping::T_LPAREN; use crate::tokens::constants::misc::{A_TEXT, G_NUMALLOWED}; @@ -7,6 +8,7 @@ use crate::tokens::mappings::{ get_greek_mappings, get_grouping_mappings, get_logical_mappings, get_misc_mappings, get_operation_mappings, get_relation_mapping, }; +use crate::tokens::Grouping::MatrixEnd; use crate::tokens::{ Accent, Arrow, FontCommand, Function, Greek, Grouping, Logical, Misc, Operation, Relation, Text, Token, diff --git a/src/tokens/constants/grouping.rs b/src/tokens/constants/grouping.rs index 9b2e00b..24b3769 100644 --- a/src/tokens/constants/grouping.rs +++ b/src/tokens/constants/grouping.rs @@ -16,4 +16,6 @@ pub const G_FLOOR: &'static [&str] = &["floor"]; pub const G_CEIL: &'static [&str] = &["ceil"]; pub const G_NORM: &'static [&str] = &["norm"]; +pub const G_MATRIX_SEP: &'static [&str] = &[","]; + pub const T_LPAREN: char = ')'; diff --git a/src/tokens/mappings.rs b/src/tokens/mappings.rs index 0681781..32c3afa 100644 --- a/src/tokens/mappings.rs +++ b/src/tokens/mappings.rs @@ -159,6 +159,7 @@ pub fn get_grouping_mappings() -> Vec> { G_RANGLE => Grouping::RAngle, G_RXPAR => Grouping::RXPar, G_LXPAR => Grouping::LXPar, + G_MATRIX_SEP => Grouping::MSep, }, hashmap! { G_RPAREN => Grouping::RParen, diff --git a/src/tokens/mod.rs b/src/tokens/mod.rs index 6964d4a..6698dd9 100644 --- a/src/tokens/mod.rs +++ b/src/tokens/mod.rs @@ -152,6 +152,11 @@ pub enum Grouping { Floor, Ceil, Norm, + MatrixBegin, + MatrixEnd, + VecBegin, + VecEnd, + MSep, } #[derive(Debug, Clone, PartialOrd, PartialEq)] From afe8169f5daef9bcb9063f8fb0e14b24e9e6b1d0 Mon Sep 17 00:00:00 2001 From: trivernis Date: Wed, 5 Aug 2020 12:24:22 +0200 Subject: [PATCH 3/7] Add matrices parsing --- src/elements/group.rs | 7 +++ src/elements/special.rs | 2 +- src/lib.rs | 97 ++++++++++++++++++++++++++++++++++++-- src/parsing/tree_parser.rs | 66 +++++++++++++++++++++++++- 4 files changed, 166 insertions(+), 6 deletions(-) diff --git a/src/elements/group.rs b/src/elements/group.rs index 4b47cf2..b7f9ced 100644 --- a/src/elements/group.rs +++ b/src/elements/group.rs @@ -2,6 +2,7 @@ use crate::elements::special::Expression; #[derive(Debug, Clone, PartialOrd, PartialEq)] pub enum Group { + MSep, Parentheses(Parentheses), Brackets(Brackets), Braces(Braces), @@ -11,6 +12,7 @@ pub enum Group { Floor(Floor), Ceil(Ceil), Norm(Norm), + Matrix(Matrix), } #[derive(Debug, Clone, PartialOrd, PartialEq)] @@ -57,3 +59,8 @@ pub struct Ceil { pub struct Norm { pub inner: Box, } + +#[derive(Debug, Clone, PartialOrd, PartialEq)] +pub struct Matrix { + pub inner: Vec>, +} diff --git a/src/elements/special.rs b/src/elements/special.rs index 89ae407..d83616b 100644 --- a/src/elements/special.rs +++ b/src/elements/special.rs @@ -3,7 +3,7 @@ use crate::utils::Boxed; #[derive(Debug, Clone, PartialOrd, PartialEq)] pub struct Expression { - children: Vec, + pub children: Vec, } #[derive(Debug, Clone, PartialOrd, PartialEq)] diff --git a/src/lib.rs b/src/lib.rs index 698c6d1..fbbb8f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,12 +28,14 @@ pub fn parse(content: String) -> Expression { #[cfg(test)] mod tests { + use crate::elements::group::{Brackets, Group, Matrix}; use crate::elements::literal::{Literal, Number}; use crate::elements::special::{Expression, Special, Sum}; use crate::elements::Element; use crate::parse; use crate::parsing::tokenizer::Tokenizer; use crate::parsing::tree_parser::TreeParser; + use crate::tokens::Function::Exp; use crate::tokens::{Function, Grouping, Misc, Operation, Relation, Text, Token}; use crate::utils::Boxed; use std::fs; @@ -186,11 +188,100 @@ mod tests { assert_eq!(expression, test_expression) } - //#[test] - fn it_parses_into_a_tree2() { + #[test] + fn it_parses_matrices() { + assert_eq!( + parse("[[1, 2],[3,4]]".to_string()), + Expression { + children: vec![Element::Group(Group::Matrix(Matrix { + inner: vec![ + vec![ + Expression { + children: vec![Element::Literal(Literal::Number(Number { + number: "1".to_string() + })),] + }, + Expression { + children: vec![Element::Literal(Literal::Number(Number { + number: "2".to_string() + })),] + } + ], + vec![ + Expression { + children: vec![Element::Literal(Literal::Number(Number { + number: "3".to_string() + })),] + }, + Expression { + children: vec![Element::Literal(Literal::Number(Number { + number: "4".to_string() + })),] + } + ] + ] + }))] + } + ); + } + + #[test] + fn it_rejects_invalid_matrices() { + assert_eq!( + parse("[[1, 3, 4],[3,4]]".to_string()), + Expression { + children: vec![Element::Group(Group::Brackets(Brackets { + inner: Expression { + children: vec![ + Element::Group(Group::Brackets(Brackets { + inner: Expression { + children: vec![ + Element::Literal(Literal::Number(Number { + number: "1".to_string() + })), + Element::Group(Group::MSep), + Element::Literal(Literal::Number(Number { + number: "3".to_string() + })), + Element::Group(Group::MSep), + Element::Literal(Literal::Number(Number { + number: "4".to_string() + })) + ] + } + .boxed() + })), + Element::Group(Group::MSep), + Element::Group(Group::Brackets(Brackets { + inner: Expression { + children: vec![ + Element::Literal(Literal::Number(Number { + number: "3".to_string() + })), + Element::Group(Group::MSep), + Element::Literal(Literal::Number(Number { + number: "4".to_string() + })) + ] + } + .boxed() + })) + ] + } + .boxed() + }))] + } + ); + } + + #[test] + fn it_parses_into_a_tree3() { fs::write( "test-files/test.txt", - format!("{:#?}", parse("color(red)(a) * b^4 - c(c-2)".to_string())), + format!( + "{:#?}", + parse("color(red)(a) * b^4 - c(c-2) [[1, 3, 2 + 2],[3 - x, 4]".to_string()) + ), ); } diff --git a/src/parsing/tree_parser.rs b/src/parsing/tree_parser.rs index db37653..0545386 100644 --- a/src/parsing/tree_parser.rs +++ b/src/parsing/tree_parser.rs @@ -1,6 +1,6 @@ use crate::elements::accent::{Color, ExpressionAccent, GenericAccent, OverSet, UnderSet}; use crate::elements::group::{ - Abs, Angles, Braces, Brackets, Ceil, Floor, Group, Norm, Parentheses, XGroup, + Abs, Angles, Braces, Brackets, Ceil, Floor, Group, Matrix, Norm, Parentheses, XGroup, }; use crate::elements::literal::{Literal, Number, PlainText, Symbol}; use crate::elements::special::{ @@ -102,7 +102,9 @@ impl TreeParser { Token::Operation(op) => Some(self.parse_operation(op)), Token::Misc(m) => Some(self.parse_misc(m)), Token::Grouping(g) => { - if let Some(group) = self.parse_group(g) { + if let Some(group) = self.parse_matrix() { + Some(Element::Group(group)) + } else if let Some(group) = self.parse_group(g) { Some(Element::Group(group)) } else { None @@ -254,6 +256,65 @@ impl TreeParser { } } + fn parse_matrix(&mut self) -> Option { + let token = self.current_token().clone(); + let start_index = self.index; + if let Token::Grouping(Grouping::RBracket) = token { + let mut expressions = Vec::new(); + + while !self.end_reached() { + if let Some(Token::Grouping(Grouping::RBracket)) = self.peek() { + self.step(); + self.step(); + expressions.push(self.parse_expression()); + self.step(); + + if let Token::Grouping(Grouping::LBracket) = self.current_token() { + self.step(); + } + if let Token::Grouping(Grouping::LBracket) = self.current_token() { + break; + } + } else { + break; + } + } + // Remapping the expression into a matrix + let expression_matrix = expressions + .iter() + .map(|e| { + let children = e.children.clone(); + let mut expressions = Vec::new(); + + for elements in children.split(|e| e == &Element::Group(Group::MSep)) { + expressions.push(Expression { + children: elements.to_vec(), + }) + } + expressions + }) + .collect::>>(); + + // a matrix with no elements is invalid + if expression_matrix.len() == 0 { + self.index = start_index; + return None; + } + /// a matrix with rows of different lengths is invalid + let first_length = expression_matrix.first().unwrap().len(); + if !expression_matrix.iter().all(|e| e.len() == first_length) { + self.index = start_index; + return None; + } + + Some(Group::Matrix(Matrix { + inner: expression_matrix, + })) + } else { + None + } + } + fn parse_group(&mut self, token: Grouping) -> Option { match token { Grouping::RParen => { @@ -309,6 +370,7 @@ impl TreeParser { let inner = self.parse_expression().boxed(); Some(Group::Norm(Norm { inner })) } + Grouping::MSep => Some(Group::MSep), _ => { self.group_return = true; None From bd89f6863fff974bc56ceb73a3f2940be37098ee Mon Sep 17 00:00:00 2001 From: trivernis Date: Wed, 5 Aug 2020 12:44:31 +0200 Subject: [PATCH 4/7] Add vector parsing --- src/elements/group.rs | 6 +++++ src/lib.rs | 29 ++++++++++++++++++++-- src/parsing/tree_parser.rs | 49 +++++++++++++++++++++++++++++++++----- 3 files changed, 76 insertions(+), 8 deletions(-) diff --git a/src/elements/group.rs b/src/elements/group.rs index b7f9ced..a82f330 100644 --- a/src/elements/group.rs +++ b/src/elements/group.rs @@ -13,6 +13,7 @@ pub enum Group { Ceil(Ceil), Norm(Norm), Matrix(Matrix), + Vector(Vector), } #[derive(Debug, Clone, PartialOrd, PartialEq)] @@ -64,3 +65,8 @@ pub struct Norm { pub struct Matrix { pub inner: Vec>, } + +#[derive(Debug, Clone, PartialOrd, PartialEq)] +pub struct Vector { + pub inner: Vec, +} diff --git a/src/lib.rs b/src/lib.rs index fbbb8f2..22bad8d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,7 +28,7 @@ pub fn parse(content: String) -> Expression { #[cfg(test)] mod tests { - use crate::elements::group::{Brackets, Group, Matrix}; + use crate::elements::group::{Brackets, Group, Matrix, Vector}; use crate::elements::literal::{Literal, Number}; use crate::elements::special::{Expression, Special, Sum}; use crate::elements::Element; @@ -275,12 +275,37 @@ mod tests { } #[test] + fn it_parses_vectors() { + assert_eq!( + parse("((1), (2))".to_string()), + Expression { + children: vec![Element::Group(Group::Vector(Vector { + inner: vec![ + Expression { + children: vec![Element::Literal(Literal::Number(Number { + number: "1".to_string() + }))] + }, + Expression { + children: vec![Element::Literal(Literal::Number(Number { + number: "2".to_string() + }))] + } + ] + }))] + } + ) + } + + //#[test] fn it_parses_into_a_tree3() { fs::write( "test-files/test.txt", format!( "{:#?}", - parse("color(red)(a) * b^4 - c(c-2) [[1, 3, 2 + 2],[3 - x, 4]".to_string()) + parse( + "color(red)(a) * b^4 - c(c-2) [[1, 3, 2 + 2],[3 - x, 4] ((2),(3))".to_string() + ) ), ); } diff --git a/src/parsing/tree_parser.rs b/src/parsing/tree_parser.rs index 0545386..9820806 100644 --- a/src/parsing/tree_parser.rs +++ b/src/parsing/tree_parser.rs @@ -1,6 +1,6 @@ use crate::elements::accent::{Color, ExpressionAccent, GenericAccent, OverSet, UnderSet}; use crate::elements::group::{ - Abs, Angles, Braces, Brackets, Ceil, Floor, Group, Matrix, Norm, Parentheses, XGroup, + Abs, Angles, Braces, Brackets, Ceil, Floor, Group, Matrix, Norm, Parentheses, Vector, XGroup, }; use crate::elements::literal::{Literal, Number, PlainText, Symbol}; use crate::elements::special::{ @@ -104,6 +104,8 @@ impl TreeParser { Token::Grouping(g) => { if let Some(group) = self.parse_matrix() { Some(Element::Group(group)) + } else if let Some(group) = self.parse_vector() { + Some(Element::Group(group)) } else if let Some(group) = self.parse_group(g) { Some(Element::Group(group)) } else { @@ -259,6 +261,7 @@ impl TreeParser { fn parse_matrix(&mut self) -> Option { let token = self.current_token().clone(); let start_index = self.index; + if let Token::Grouping(Grouping::RBracket) = token { let mut expressions = Vec::new(); @@ -296,7 +299,7 @@ impl TreeParser { .collect::>>(); // a matrix with no elements is invalid - if expression_matrix.len() == 0 { + if expression_matrix.is_empty() { self.index = start_index; return None; } @@ -304,12 +307,46 @@ impl TreeParser { let first_length = expression_matrix.first().unwrap().len(); if !expression_matrix.iter().all(|e| e.len() == first_length) { self.index = start_index; - return None; + None + } else { + Some(Group::Matrix(Matrix { + inner: expression_matrix, + })) } + } else { + None + } + } - Some(Group::Matrix(Matrix { - inner: expression_matrix, - })) + fn parse_vector(&mut self) -> Option { + let token = self.current_token().clone(); + let start_index = self.index; + + if let Token::Grouping(Grouping::RParen) = token { + let mut expressions = Vec::new(); + + while !self.end_reached() { + if let Some(Token::Grouping(Grouping::RParen)) = self.peek() { + self.step(); + self.step(); + expressions.push(self.parse_expression()); + + if let Token::Grouping(Grouping::LParen) = self.current_token() { + self.step(); + } + if let Token::Grouping(Grouping::LParen) = self.current_token() { + break; + } + } else { + break; + } + } + if expressions.is_empty() { + self.index = start_index; + None + } else { + Some(Group::Vector(Vector { inner: expressions })) + } } else { None } From 386412f021cae924e2dc121bd34cfac28a632ccb Mon Sep 17 00:00:00 2001 From: trivernis Date: Wed, 5 Aug 2020 12:59:01 +0200 Subject: [PATCH 5/7] Change vector parsing to allow matrix vectors --- src/elements/group.rs | 2 +- src/lib.rs | 41 +++++++++++++++++++--- src/parsing/tree_parser.rs | 60 +++++++++++++++++++------------- src/tokens/constants/grouping.rs | 11 +++--- src/tokens/mappings.rs | 8 ++--- 5 files changed, 85 insertions(+), 37 deletions(-) diff --git a/src/elements/group.rs b/src/elements/group.rs index a82f330..8667ece 100644 --- a/src/elements/group.rs +++ b/src/elements/group.rs @@ -68,5 +68,5 @@ pub struct Matrix { #[derive(Debug, Clone, PartialOrd, PartialEq)] pub struct Vector { - pub inner: Vec, + pub inner: Vec>, } diff --git a/src/lib.rs b/src/lib.rs index 22bad8d..2442074 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -281,16 +281,49 @@ mod tests { Expression { children: vec![Element::Group(Group::Vector(Vector { inner: vec![ - Expression { + vec![Expression { children: vec![Element::Literal(Literal::Number(Number { number: "1".to_string() }))] - }, - Expression { + }], + vec![Expression { children: vec![Element::Literal(Literal::Number(Number { number: "2".to_string() }))] - } + }] + ] + }))] + } + ); + assert_eq!( + parse("((1, 3), (2, 5))".to_string()), + Expression { + children: vec![Element::Group(Group::Vector(Vector { + inner: vec![ + vec![ + Expression { + children: vec![Element::Literal(Literal::Number(Number { + number: "1".to_string() + }))] + }, + Expression { + children: vec![Element::Literal(Literal::Number(Number { + number: "3".to_string() + }))] + } + ], + vec![ + Expression { + children: vec![Element::Literal(Literal::Number(Number { + number: "2".to_string() + }))] + }, + Expression { + children: vec![Element::Literal(Literal::Number(Number { + number: "5".to_string() + }))] + } + ] ] }))] } diff --git a/src/parsing/tree_parser.rs b/src/parsing/tree_parser.rs index 9820806..5551456 100644 --- a/src/parsing/tree_parser.rs +++ b/src/parsing/tree_parser.rs @@ -283,29 +283,9 @@ impl TreeParser { } } // Remapping the expression into a matrix - let expression_matrix = expressions - .iter() - .map(|e| { - let children = e.children.clone(); - let mut expressions = Vec::new(); - - for elements in children.split(|e| e == &Element::Group(Group::MSep)) { - expressions.push(Expression { - children: elements.to_vec(), - }) - } - expressions - }) - .collect::>>(); + let expression_matrix = self.transform_vec_to_matrix(expressions); - // a matrix with no elements is invalid - if expression_matrix.is_empty() { - self.index = start_index; - return None; - } - /// a matrix with rows of different lengths is invalid - let first_length = expression_matrix.first().unwrap().len(); - if !expression_matrix.iter().all(|e| e.len() == first_length) { + if !self.validate_matrix(&expression_matrix) { self.index = start_index; None } else { @@ -341,11 +321,15 @@ impl TreeParser { break; } } - if expressions.is_empty() { + let expression_matrix = self.transform_vec_to_matrix(expressions); + + if !self.validate_matrix(&expression_matrix) { self.index = start_index; None } else { - Some(Group::Vector(Vector { inner: expressions })) + Some(Group::Vector(Vector { + inner: expression_matrix, + })) } } else { None @@ -442,4 +426,32 @@ impl TreeParser { None } } + + /// Remaps an expresion vector into a matrix of expressions by splitting on each MSep token + fn transform_vec_to_matrix(&self, expressions: Vec) -> Vec> { + expressions + .iter() + .map(|e| { + let children = e.children.clone(); + let mut expressions = Vec::new(); + + for elements in children.split(|e| e == &Element::Group(Group::MSep)) { + expressions.push(Expression { + children: elements.to_vec(), + }) + } + expressions + }) + .collect::>>() + } + + /// Validates a matrix of expressions if every row has the same length + fn validate_matrix(&self, matrix: &Vec>) -> bool { + if matrix.is_empty() { + false + } else { + let first_length = matrix.first().unwrap().len(); + matrix.iter().all(|e| e.len() == first_length) + } + } } diff --git a/src/tokens/constants/grouping.rs b/src/tokens/constants/grouping.rs index 24b3769..a77371e 100644 --- a/src/tokens/constants/grouping.rs +++ b/src/tokens/constants/grouping.rs @@ -1,11 +1,14 @@ pub const G_RPAREN: &'static [&str] = &["("]; pub const G_LPAREN: &'static [&str] = &[")"]; -pub const G_RBRAC: &'static [&str] = &["["]; -pub const G_LBRAC: &'static [&str] = &["]"]; +pub const G_RBRACKET: &'static [&str] = &["["]; +pub const G_LBRACKET: &'static [&str] = &["]"]; -pub const G_RCURL: &'static [&str] = &["{"]; -pub const G_LCURL: &'static [&str] = &["}"]; +pub const G_RBRACE: &'static [&str] = &["{"]; +pub const G_LBRACE: &'static [&str] = &["}"]; + +pub const G_RBRACE_HIDDEN: &'static [&str] = &["{:"]; +pub const G_LBRACE_HIDDEN: &'static [&str] = &[":}"]; pub const G_LANGLE: &'static [&str] = &["(:", "<<", "langle"]; pub const G_RANGLE: &'static [&str] = &[":)", ">>", "rangle"]; diff --git a/src/tokens/mappings.rs b/src/tokens/mappings.rs index 32c3afa..1ac381f 100644 --- a/src/tokens/mappings.rs +++ b/src/tokens/mappings.rs @@ -164,10 +164,10 @@ pub fn get_grouping_mappings() -> Vec> { hashmap! { G_RPAREN => Grouping::RParen, G_LPAREN => Grouping::LParen, - G_RBRAC => Grouping::RBracket, - G_LBRAC => Grouping::LBracket, - G_RCURL => Grouping::RBrace, - G_LCURL => Grouping::LBrace, + G_RBRACKET => Grouping::RBracket, + G_LBRACKET => Grouping::LBracket, + G_RBRACE => Grouping::RBrace, + G_LBRACE => Grouping::LBrace, G_ABS => Grouping::Abs, G_FLOOR => Grouping::Floor, G_CEIL => Grouping::Ceil, From 19ed9e918b862564d115ae043888e751681c0b70 Mon Sep 17 00:00:00 2001 From: trivernis Date: Wed, 5 Aug 2020 13:11:03 +0200 Subject: [PATCH 6/7] Change matrices to be at least 1x2 or 2x1 --- src/lib.rs | 22 ++++++++++++++++++++-- src/parsing/tokenizer.rs | 2 -- src/parsing/tree_parser.rs | 6 +++++- src/tokens/mod.rs | 4 ---- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2442074..138b74a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,7 +35,6 @@ mod tests { use crate::parse; use crate::parsing::tokenizer::Tokenizer; use crate::parsing::tree_parser::TreeParser; - use crate::tokens::Function::Exp; use crate::tokens::{Function, Grouping, Misc, Operation, Relation, Text, Token}; use crate::utils::Boxed; use std::fs; @@ -272,6 +271,24 @@ mod tests { }))] } ); + assert_eq!( + parse("[[1]]".to_string()), + Expression { + children: vec![Element::Group(Group::Brackets(Brackets { + inner: Expression { + children: vec![Element::Group(Group::Brackets(Brackets { + inner: Expression { + children: vec![Element::Literal(Literal::Number(Number { + number: "1".to_string() + })),] + } + .boxed() + })),] + } + .boxed() + }))] + } + ); } #[test] @@ -340,7 +357,8 @@ mod tests { "color(red)(a) * b^4 - c(c-2) [[1, 3, 2 + 2],[3 - x, 4] ((2),(3))".to_string() ) ), - ); + ) + .unwrap(); } #[bench] diff --git a/src/parsing/tokenizer.rs b/src/parsing/tokenizer.rs index 0b22645..69f4872 100644 --- a/src/parsing/tokenizer.rs +++ b/src/parsing/tokenizer.rs @@ -1,4 +1,3 @@ -use crate::elements::Element; use crate::tokens::constants::accents::G_COLOR; use crate::tokens::constants::grouping::T_LPAREN; use crate::tokens::constants::misc::{A_TEXT, G_NUMALLOWED}; @@ -8,7 +7,6 @@ use crate::tokens::mappings::{ get_greek_mappings, get_grouping_mappings, get_logical_mappings, get_misc_mappings, get_operation_mappings, get_relation_mapping, }; -use crate::tokens::Grouping::MatrixEnd; use crate::tokens::{ Accent, Arrow, FontCommand, Function, Greek, Grouping, Logical, Misc, Operation, Relation, Text, Token, diff --git a/src/parsing/tree_parser.rs b/src/parsing/tree_parser.rs index 5551456..6ddf84b 100644 --- a/src/parsing/tree_parser.rs +++ b/src/parsing/tree_parser.rs @@ -451,7 +451,11 @@ impl TreeParser { false } else { let first_length = matrix.first().unwrap().len(); - matrix.iter().all(|e| e.len() == first_length) + if first_length * matrix.len() == 1 { + false + } else { + matrix.iter().all(|e| e.len() == first_length) + } } } } diff --git a/src/tokens/mod.rs b/src/tokens/mod.rs index 6698dd9..914fde2 100644 --- a/src/tokens/mod.rs +++ b/src/tokens/mod.rs @@ -152,10 +152,6 @@ pub enum Grouping { Floor, Ceil, Norm, - MatrixBegin, - MatrixEnd, - VecBegin, - VecEnd, MSep, } From d6538d1d4539119cf07d2a87457a5a0644e55442 Mon Sep 17 00:00:00 2001 From: trivernis Date: Wed, 5 Aug 2020 13:13:32 +0200 Subject: [PATCH 7/7] Update version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a85033e..0d58a2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "asciimath-rs" description = "AsciiMath parser" repository = "https://github.com/trivernis/asciimath-rs" -version = "0.2.0" +version = "0.3.0" authors = ["trivernis "] edition = "2018" readme = "README.md"