Expand description
§mathlex
A mathematical expression parser for LaTeX and plain text notation, producing a language-agnostic Abstract Syntax Tree (AST).
§Overview
mathlex is a pure parsing library that converts mathematical expressions in LaTeX or plain text format into a well-defined AST. The library does NOT perform any evaluation or mathematical operations - interpretation of the AST is entirely the responsibility of consuming libraries.
§Features
- LaTeX Parsing: Parse mathematical LaTeX notation
- Plain Text Parsing: Parse standard mathematical expressions
- Rich AST: Comprehensive AST for algebra, calculus, linear algebra, set theory, logic
- Vector Calculus: Gradient, divergence, curl, Laplacian operators
- Multiple Integrals: Double, triple, and closed path integrals
- Set Theory: Union, intersection, quantifiers, logical connectives
- Quaternions: Support for quaternion algebra with basis vectors i, j, k
- Vector Notation: Multiple styles (bold, arrow, hat) with context awareness
- Utilities: Variable extraction, substitution, string conversion
§Quick Start
§Basic Parsing
use mathlex::{parse, parse_latex, Expression, ExprKind, BinaryOp};
// Parse plain text
let expr = parse("2*x + sin(y)").unwrap();
// Parse LaTeX
let expr = parse_latex(r"\frac{1}{2}").unwrap();
// Verify the parsed structure
if let ExprKind::Binary { op: BinaryOp::Div, .. } = expr.kind {
println!("Parsed as division");
}§Vector Calculus
use mathlex::{parse_latex, Expression, ExprKind};
// Gradient operator
let grad = parse_latex(r"\nabla f").unwrap();
assert!(matches!(grad.kind, ExprKind::Gradient { .. }));
// Divergence of a vector field
let div = parse_latex(r"\nabla \cdot \mathbf{F}").unwrap();
assert!(matches!(div.kind, ExprKind::Divergence { .. }));
// Curl (cross product with nabla)
let curl = parse_latex(r"\nabla \times \mathbf{F}").unwrap();
assert!(matches!(curl.kind, ExprKind::Curl { .. }));
// Laplacian
let laplacian = parse_latex(r"\nabla^2 f").unwrap();
assert!(matches!(laplacian.kind, ExprKind::Laplacian { .. }));§Vector Notation Styles
use mathlex::{parse_latex, Expression, ExprKind, VectorNotation};
// Bold vectors
let bold = parse_latex(r"\mathbf{v}").unwrap();
if let ExprKind::MarkedVector { notation, .. } = bold.kind {
assert_eq!(notation, VectorNotation::Bold);
}
// Arrow vectors
let arrow = parse_latex(r"\vec{a}").unwrap();
if let ExprKind::MarkedVector { notation, .. } = arrow.kind {
assert_eq!(notation, VectorNotation::Arrow);
}
// Hat notation (unit vectors)
let hat = parse_latex(r"\hat{n}").unwrap();
if let ExprKind::MarkedVector { notation, .. } = hat.kind {
assert_eq!(notation, VectorNotation::Hat);
}§Set Theory
use mathlex::{parse_latex, Expression, ExprKind};
// Set union
let union = parse_latex(r"A \cup B").unwrap();
assert!(matches!(union.kind, ExprKind::SetOperation { .. }));
// Set membership
let membership = parse_latex(r"x \in A").unwrap();
assert!(matches!(membership.kind, ExprKind::SetRelationExpr { .. }));
// Universal quantifier
let forall = parse_latex(r"\forall x P").unwrap();
assert!(matches!(forall.kind, ExprKind::ForAll { .. }));
// Logical connectives
let and = parse_latex(r"P \land Q").unwrap();
assert!(matches!(and.kind, ExprKind::Logical { .. }));§Multiple Integrals
use mathlex::{parse_latex, Expression, ExprKind};
// Double integral
let double = parse_latex(r"\iint_R f dA").unwrap();
if let ExprKind::MultipleIntegral { dimension, .. } = double.kind {
assert_eq!(dimension, 2);
}
// Triple integral
let triple = parse_latex(r"\iiint_V f dV").unwrap();
if let ExprKind::MultipleIntegral { dimension, .. } = triple.kind {
assert_eq!(dimension, 3);
}
// Closed path integral
let closed = parse_latex(r"\oint_C F dr").unwrap();
assert!(matches!(closed.kind, ExprKind::ClosedIntegral { .. }));§Quaternions
use mathlex::{Expression, ExprKind, MathConstant};
// Quaternion basis vectors are available as constants
let i = Expression::constant(MathConstant::I);
let j = Expression::constant(MathConstant::J);
let k = Expression::constant(MathConstant::K);
// Create quaternion expression programmatically
// 1 + 2i + 3j + 4k
let quat = ExprKind::Quaternion {
real: Box::new(Expression::integer(1)),
i: Box::new(Expression::integer(2)),
j: Box::new(Expression::integer(3)),
k: Box::new(Expression::integer(4)),
};§Configuration
For advanced parsing options, use ParserConfig:
use mathlex::{parse_with_config, ParserConfig, NumberSystem};
use std::collections::HashSet;
let config = ParserConfig {
implicit_multiplication: true,
number_system: NumberSystem::Complex,
..Default::default()
};
// Parse with custom configuration
let expr = parse_with_config("2*x + 3", &config).unwrap();§Context-Aware Parsing
The parser uses context awareness for certain symbols:
e: Parsed as Euler’s constant unless it appears in an exponent (where it’s treated as a variable for scientific notation)i,j,k: Interpreted based onNumberSystemsetting:- In
Real: treated as variables - In
Complex:iis the imaginary unit,jandkare variables - In
Quaternion:i,j,kare quaternion basis vectors
- In
use mathlex::{parse_latex, Expression, MathConstant};
// 'e' as Euler's constant
let euler = parse_latex(r"e").unwrap();
assert_eq!(euler, Expression::constant(MathConstant::E));
// 'i' as imaginary unit (when explicitly marked)
let imag = parse_latex(r"\mathrm{i}").unwrap();
assert_eq!(imag, Expression::constant(MathConstant::I));§Parser Features
§Expression Subscripts
The LaTeX parser supports complex expression subscripts that are flattened into variable names:
use mathlex::{parse_latex, Expression};
// Simple subscript: x_i
let simple = parse_latex(r"x_i").unwrap();
assert_eq!(simple, Expression::variable("x_i".to_string()));
// Expression subscript: x_{i+1}
let expr_sub = parse_latex(r"x_{i+1}").unwrap();
assert_eq!(expr_sub, Expression::variable("x_iplus1".to_string()));
// Complex subscript: a_{n-1}
let complex = parse_latex(r"a_{n-1}").unwrap();
assert_eq!(complex, Expression::variable("a_nminus1".to_string()));Supported subscript operators: + (plus), - (minus), * (times), / (div), ^ (pow)
§Derivative Notation
Both explicit and standard derivative notations are supported:
use mathlex::{parse_latex, Expression, ExprKind};
// Standard notation: d/dx followed by expression
let standard = parse_latex(r"\frac{d}{dx}f").unwrap();
assert!(matches!(standard.kind, ExprKind::Derivative { .. }));
// Explicit multiplication marker: d/d*x (when variable needs explicit marker)
let explicit = parse_latex(r"\frac{d}{d*x}f").unwrap();
assert!(matches!(explicit.kind, ExprKind::Derivative { .. }));
// Partial derivatives: ∂/∂x followed by expression
let partial = parse_latex(r"\frac{\partial}{\partial x}f").unwrap();
assert!(matches!(partial.kind, ExprKind::PartialDerivative { .. }));
// Higher order: d²/dx² followed by expression
let second = parse_latex(r"\frac{d^2}{dx^2}f").unwrap();
if let ExprKind::Derivative { order, .. } = second.kind {
assert_eq!(order, 2);
}§Design Philosophy
mathlex follows the principle of single responsibility:
- Parse text into AST
- Convert AST back to text (plain or LaTeX)
- Query AST (find variables, functions)
- Transform AST (substitution)
What mathlex does NOT do:
- Evaluate expressions
- Simplify expressions
- Solve equations
- Perform any mathematical computation
This design allows mathlex to serve as a shared foundation for both symbolic computation systems (like thales) and numerical libraries (like NumericSwift) without creating dependencies between them.
Re-exports§
pub use ast::AnnotationSet;pub use ast::BinaryOp;pub use ast::Direction;pub use ast::ExprKind;pub use ast::Expression;pub use ast::IndexType;pub use ast::InequalityOp;pub use ast::IntegralBounds;pub use ast::LogicalOp;pub use ast::MathConstant;pub use ast::MathFloat;pub use ast::MultipleBounds;pub use ast::NumberSet;pub use ast::RelationOp;pub use ast::SetOp;pub use ast::SetRelation;pub use ast::TensorIndex;pub use ast::UnaryOp;pub use ast::VectorNotation;pub use context::parse_system;pub use context::ExpressionContext;pub use context::InputFormat;pub use error::ParseError;pub use error::ParseErrorKind;pub use error::ParseOutput;pub use error::ParseResult;pub use error::Position;pub use error::Span;pub use latex::ToLatex;pub use metadata::ContextSource;pub use metadata::ExpressionMetadata;pub use metadata::MathType;pub use parser::parse;pub use parser::parse_equation_system;pub use parser::parse_latex;pub use parser::parse_latex_equation_system;pub use parser::parse_latex_lenient;pub use parser::parse_lenient;pub use parser::parse_lenient_with_config;
Modules§
- ast
- Abstract Syntax Tree (AST) Types
- context
- Context engine for multi-expression parsing.
- display
- Display Trait Implementations for AST (Plain Text)
- error
- Error types for mathlex parsing operations.
- latex
- LaTeX Conversion for AST
- metadata
- Expression metadata and type inference types.
- parser
- Parser module for mathlex.
- util
- AST Utility Functions
Structs§
- Parser
Config - Configuration options for the mathematical expression parser.
Enums§
- Index
Convention - Index convention for tensor notation.
- Number
System - Number system context for parsing.
Constants§
- VERSION
- Placeholder for library version
Functions§
- parse_
with_ config - Parses a plain text mathematical expression with custom configuration.