use crate::extraction::math_symbols::render_run_text;
use crate::extractors::security::{SecurityBudget, SecurityError};
use quick_xml::Reader;
use quick_xml::events::Event;
#[derive(Debug, Clone)]
enum FracType {
Bar,
NoBar,
Linear,
Skewed,
}
#[cfg_attr(alef, alef(skip))]
#[derive(Debug, Clone)]
enum MathNode {
Run(String),
SSup { base: Vec<MathNode>, sup: Vec<MathNode> },
SSub { base: Vec<MathNode>, sub: Vec<MathNode> },
SSubSup {
base: Vec<MathNode>,
sub: Vec<MathNode>,
sup: Vec<MathNode>,
},
Frac {
num: Vec<MathNode>,
den: Vec<MathNode>,
frac_type: FracType,
},
Rad {
deg: Vec<MathNode>,
body: Vec<MathNode>,
deg_hide: bool,
},
Nary {
chr: String,
sub: Vec<MathNode>,
sup: Vec<MathNode>,
body: Vec<MathNode>,
sub_hide: bool,
sup_hide: bool,
},
Delim {
begin_chr: String,
end_chr: String,
sep_chr: String,
elements: Vec<Vec<MathNode>>,
},
Func { name: Vec<MathNode>, body: Vec<MathNode> },
Acc { chr: String, body: Vec<MathNode> },
EqArr { rows: Vec<Vec<MathNode>> },
LimLow { body: Vec<MathNode>, lim: Vec<MathNode> },
LimUpp { body: Vec<MathNode>, lim: Vec<MathNode> },
Bar { body: Vec<MathNode>, top: bool },
BorderBox { body: Vec<MathNode> },
Matrix { rows: Vec<Vec<Vec<MathNode>>> },
Group { children: Vec<MathNode> },
SPre {
base: Vec<MathNode>,
sub: Vec<MathNode>,
sup: Vec<MathNode>,
},
}
pub(crate) fn collect_and_convert_omath_para(
reader: &mut Reader<&[u8]>,
budget: &mut SecurityBudget,
) -> Result<String, SecurityError> {
let children = collect_children(reader, "m:oMathPara", budget)?;
let mut parts = Vec::new();
for child in &children {
if let MathNode::Group { children: inner } = child {
let rendered = render_nodes(inner);
if !rendered.is_empty() {
parts.push(rendered);
}
}
}
if parts.is_empty() {
Ok(render_nodes(&children))
} else {
Ok(parts.join(" \\\\ "))
}
}
pub(crate) fn collect_and_convert_omath(
reader: &mut Reader<&[u8]>,
budget: &mut SecurityBudget,
) -> Result<String, SecurityError> {
let children = collect_children(reader, "m:oMath", budget)?;
Ok(render_nodes(&children))
}
mod collect;
mod elements;
mod render;
use collect::collect_children;
use render::render_nodes;
#[cfg(test)]
mod tests;