polymath_rs/
lib.rs

1use ast::predictive::convert;
2use cst::predictive::parse;
3use mathml::to_mathml;
4use tracing::debug;
5use transformations::transform;
6
7use crate::tokens::tokenize;
8
9pub mod ast;
10pub mod cst;
11pub mod mathml;
12pub mod transformations;
13pub mod tokens;
14
15pub fn to_math_ml(content: &str) -> String {
16    let tokens = tokenize(content);
17    debug!("Tokens: {tokens:#?}");
18    let cst = parse(&tokens);
19    debug!("CST: {cst:#?}");
20    let ast = convert(&cst);
21    debug!("AST: {ast:#?}");
22    let t_ast = transform(ast);
23    debug!("AST after transformation: {t_ast:#?}");
24
25    to_mathml(&t_ast)
26}
27
28#[cfg(test)]
29mod test {
30    // use tracing::Level;
31    use crate::to_math_ml;
32
33    macro_rules! test_parse {
34        ($name:ident, $input:expr, $expected:expr) => {
35            #[test]
36            fn $name() {
37                // tracing_subscriber::FmtSubscriber::builder().with_max_level(Level::DEBUG).init();
38                let mathml = to_math_ml($input);
39                assert_eq!(mathml, $expected);
40            }
41        };
42    }
43
44    test_parse!(
45        test_parse1,
46        "sum_b^a",
47        "<math display=\"block\"><munderover><mo>&#x2211;</mo><mi>b</mi><mi>a</mi></munderover></math>"
48    );
49
50    test_parse!(
51        test_frac,
52        "(a+b)/6",
53        "<math display=\"block\"><mfrac><mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow><mn>6</mn></mfrac></math>"
54    );
55
56    test_parse!(
57        test_vector,
58        "[[1,2], [2, 23]]",
59        "<math display=\"block\"><mrow><mo>[</mo><mtable columnlines=\"none\"><mtr><mtd><mn>1</mn></mtd><mtd><mn>2</mn></mtd></mtr><mtr><mtd><mn>2</mn></mtd><mtd><mn>23</mn></mtd></mtr></mtable><mo>]</mo></mrow></math>"
60    );
61
62   test_parse!(
63        test_vector_sum,
64        "[[1],[sum_1^2a]]",
65        "<math display=\"block\"><mrow><mo>[</mo><mtable columnlines=\"\"><mtr><mtd><mn>1</mn></mtd></mtr><mtr><mtd><munderover><mo>&#x2211;</mo><mn>1</mn><mn>2</mn></munderover><mi>a</mi></mtd></mtr></mtable><mo>]</mo></mrow></math>"
66    );
67
68    test_parse!(
69        test_sum,
70        "sum_1^2a",
71        "<math display=\"block\"><munderover><mo>&#x2211;</mo><mn>1</mn><mn>2</mn></munderover><mi>a</mi></math>"
72    );
73
74    test_parse!(
75        test_recusrsive_matrices, 
76        "[[[[1],[2]]], [[[a], [b]]]]", 
77        "<math display=\"block\"><mrow><mo>[</mo><mtable columnlines=\"\"><mtr><mtd><mrow><mo>[</mo><mtable columnlines=\"\"><mtr><mtd><mn>1</mn></mtd></mtr><mtr><mtd><mn>2</mn></mtd></mtr></mtable><mo>]</mo></mrow></mtd></mtr><mtr><mtd><mrow><mo>[</mo><mtable columnlines=\"\"><mtr><mtd><mi>a</mi></mtd></mtr><mtr><mtd><mi>b</mi></mtd></mtr></mtable><mo>]</mo></mrow></mtd></mtr></mtable><mo>]</mo></mrow></math>"
78    );
79
80    test_parse!(
81        test_table_bar, 
82        "[[1, |, 2], [a, b, c]]", 
83        "<math display=\"block\"><mrow><mo>[</mo><mtable columnlines=\"solid none\"><mtr><mtd><mn>1</mn></mtd><mtd><mn>2</mn></mtd><mtd></mtd></mtr><mtr><mtd><mi>a</mi></mtd><mtd><mi>b</mi></mtd><mtd><mi>c</mi></mtd></mtr></mtable><mo>]</mo></mrow></math>"
84    );
85
86    test_parse!(
87        test_table_complex,
88        "{:[log_2 16 = 4,], [(2*5-3)/6, ]}",
89        "<math display=\"block\"><mrow><mtable columnlines=\"none\"><mtr><mtd><msub><mi>log</mi><mn>2</mn></msub><mn>16</mn><mo>=</mo><mn>4</mn></mtd><mtd></mtd></mtr><mtr><mtd><mfrac><mrow><mn>2</mn><mo>&#x22C5;</mo><mn>5</mn><mo>-</mo><mn>3</mn></mrow><mn>6</mn></mfrac></mtd><mtd></mtd></mtr></mtable><mo>}</mo></mrow></math>"
90    );
91    
92    test_parse!(
93        test_text, 
94        "\"b la  \"", 
95        "<math display=\"block\"><mtext>b la  </mtext></math>"
96    );
97
98    test_parse!(
99        test_operations, 
100        "a=2", 
101        "<math display=\"block\"><mi>a</mi><mo>=</mo><mn>2</mn></math>"
102    );
103
104    test_parse!(
105        test_parse_group,
106        "(s)",
107        "<math display=\"block\"><mrow><mo>(</mo><mi>s</mi><mo>)</mo></mrow></math>"
108    );
109
110    test_parse!(
111        test_function,
112        "log_2 16 = 4",
113        "<math display=\"block\"><msub><mi>log</mi><mn>2</mn></msub><mn>16</mn><mo>=</mo><mn>4</mn></math>"
114    );
115
116    test_parse!(
117        test_fuzz_1,
118        "ȳ?",
119        "<math display=\"block\"><mi>ȳ</mi><mi>?</mi></math>"
120    );
121
122    test_parse!(
123        test_fuzz_2,
124        "{Ц\"2",
125        "<math display=\"block\"><mi>{</mi><mi>Ц</mi><mi>\"</mi><mn>2</mn></math>"
126    );
127    
128    test_parse!(
129        test_fuzz_3,
130        "{]!(",
131        "<math display=\"block\"><mrow><mo>{</mo><mo>]</mo></mrow><mi>!</mi><mi>(</mi></math>"
132    );
133
134    test_parse!(
135        test_fuzz_4,
136        r#"Y{]
137        ]{:}]]]"#,
138        "<math display=\"block\"><mi>Y</mi><mrow><mo>{</mo><mo>]</mo></mrow><mi>\n</mi><mi>]</mi><mrow><mo>}</mo></mrow><mi>]</mi><mi>]</mi><mi>]</mi></math>"
139    );
140
141    test_parse!(
142        test_ubrace_with_nested_group,
143        "ubrace({(2x,+,17y,=,23),(x,-,y,=,5):})_(\"equation system\")",
144        "<math display=\"block\"><munder><munder><munder><mrow><mrow><mo>{</mo><mtable columnlines=\"none none none none\"><mtr><mtd><mn>2</mn><mi>x</mi></mtd><mtd><mo>+</mo></mtd><mtd><mn>17</mn><mi>y</mi></mtd><mtd><mo>=</mo></mtd><mtd><mn>23</mn></mtd></mtr><mtr><mtd><mi>x</mi></mtd><mtd><mo>-</mo></mtd><mtd><mi>y</mi></mtd><mtd><mo>=</mo></mtd><mtd><mn>5</mn></mtd></mtr></mtable></mrow></mrow><mo>&#x23DF;</mo></munder></munder><mrow><mtext>equation system</mtext></mrow></munder></math>"
145    );
146
147    test_parse!(
148        test_ubrace_with_appended_expression,
149        "obrace(ubrace(t)_(a))^ba",
150        "<math display=\"block\"><mover><mover><mover><mrow><munder><munder><munder><mrow><mi>t</mi></mrow><mo>&#x23DF;</mo></munder></munder><mrow><mi>a</mi></mrow></munder></mrow><mo>&#x23DE;</mo></mover></mover><mi>b</mi></mover><mi>a</mi></math>"
151    );
152
153    test_parse!(
154        test_div_symbol,
155        "-:",
156        "<math display=\"block\"><mo>&#xF7;</mo></math>"
157    );
158
159    test_parse!(
160        test_root,
161        "root (abc)(d) ",
162        "<math display=\"block\"><mroot><mrow><mi>d</mi></mrow><mrow><mi>a</mi><mi>b</mi><mi>c</mi></mrow></mroot></math>"
163    );
164}