use crate::build_common::make_span;
use crate::define_function::{FunctionDefSpec, FunctionPropSpec};
use crate::dom_tree::HtmlDomNode;
use crate::mathml_tree::MathDomNode;
use crate::options::Options;
use crate::parser::parse_node::{AnyParseNode, NodeType, ParseNodeOrdGroup};
use crate::types::{ParseError, ParseErrorKind};
use crate::{KatexContext, build_html, build_mathml, make_fragment};
pub fn define_ordgroup(ctx: &mut KatexContext) {
ctx.define_function(FunctionDefSpec {
node_type: Some(NodeType::OrdGroup),
names: &["ordgroup"],
props: FunctionPropSpec::default(),
handler: Some(|context, args, _opt_args| {
let body = args[0].clone();
let semisimple = context.func_name == "ordgroup";
Ok(AnyParseNode::OrdGroup(ParseNodeOrdGroup {
mode: context.parser.mode,
loc: context.loc(),
body: vec![body],
semisimple: Some(semisimple),
}))
}),
html_builder: Some(html_builder),
mathml_builder: Some(mathml_builder),
});
}
fn html_builder(
node: &AnyParseNode,
options: &Options,
ctx: &KatexContext,
) -> Result<HtmlDomNode, ParseError> {
let AnyParseNode::OrdGroup(group) = node else {
return Err(ParseError::new(ParseErrorKind::ExpectedNode {
node: NodeType::OrdGroup,
}));
};
if group.semisimple.unwrap_or(false) {
let body = build_html::build_expression(
ctx,
&group.body,
options,
build_html::GroupType::False,
(None, None),
)?;
Ok(make_fragment(body).into())
} else {
let body = build_html::build_expression(
ctx,
&group.body,
options,
build_html::GroupType::True,
(None, None),
)?;
let span = make_span("mord", body, Some(options), None);
Ok(span.into())
}
}
fn mathml_builder(
node: &AnyParseNode,
options: &Options,
ctx: &KatexContext,
) -> Result<MathDomNode, ParseError> {
let AnyParseNode::OrdGroup(group) = node else {
return Err(ParseError::new(ParseErrorKind::ExpectedNode {
node: NodeType::OrdGroup,
}));
};
let body = build_mathml::build_expression_row(ctx, &group.body, options, Some(true))?;
Ok(body)
}