honzo_chunks/data/
math.rs1use std::str;
2use std::string::String;
3
4use quick_xml::Reader;
5
6use honzo_core::{HonzoError, MathType};
7use pulldown_latex::{push_mathml, Parser as LatexParser, RenderConfig, Storage as LatexStorage};
8
9pub const MATH_TAG: [u8; 4] = *b"MATH";
10
11pub fn validate_mathml(bytes: &[u8]) -> Result<(), HonzoError> {
12 let mut reader = Reader::from_reader(bytes);
13 let mut buf = Vec::new();
14 loop {
15 match reader.read_event_into(&mut buf) {
16 Ok(quick_xml::events::Event::Eof) => break,
17 Ok(_) => buf.clear(),
18 Err(_) => return Err(HonzoError::InvalidMathML),
19 }
20 }
21 Ok(())
22}
23
24pub fn latex_to_mathml(bytes: &[u8]) -> Result<String, HonzoError> {
25 let s = match str::from_utf8(bytes) {
26 Ok(v) => v,
27 Err(_) => return Err(HonzoError::Truncated),
28 };
29
30 let storage = LatexStorage::new();
32 let parser = LatexParser::new(s, &storage);
33 let mut out = String::new();
34 let cfg = RenderConfig {
35 xml: true,
36 ..Default::default()
37 };
38 push_mathml(&mut out, parser, cfg).map_err(|_| HonzoError::InvalidMathML)?;
39 Ok(out)
40}
41
42pub fn render_math(bytes: &[u8], math_type: MathType) -> Result<String, HonzoError> {
43 match math_type {
44 MathType::MathML => {
45 validate_mathml(bytes)?;
46 let s = str::from_utf8(bytes).map_err(|_| HonzoError::Truncated)?;
47 Ok(s.to_string())
48 }
49 MathType::LaTeX => latex_to_mathml(bytes),
50 }
51}
52
53fn map_honzo_error_code(err: HonzoError) -> u8 {
56 match err {
57 HonzoError::InvalidMathML => 6,
58 HonzoError::Truncated => 7,
59 _ => 255,
60 }
61}
62
63pub fn latex_to_mathml_bytes(bytes: &[u8]) -> Result<Vec<u8>, u8> {
64 match latex_to_mathml(bytes) {
65 Ok(s) => Ok(s.into_bytes()),
66 Err(e) => Err(map_honzo_error_code(e)),
67 }
68}
69
70pub fn render_math_bytes(bytes: &[u8], math_type: u8) -> Result<Vec<u8>, u8> {
71 let math_type = match MathType::from_u8(math_type) {
72 Ok(value) => value,
73 Err(err) => return Err(map_honzo_error_code(err)),
74 };
75 match render_math(bytes, math_type) {
76 Ok(s) => Ok(s.into_bytes()),
77 Err(e) => Err(map_honzo_error_code(e)),
78 }
79}
80
81pub fn validate_mathml_bytes(bytes: &[u8]) -> Result<(), u8> {
82 match validate_mathml(bytes) {
83 Ok(()) => Ok(()),
84 Err(e) => Err(map_honzo_error_code(e)),
85 }
86}