use crate::KatexContext;
use crate::dom_tree::HtmlDomNode;
use crate::options::Options;
use crate::parser::Parser;
use crate::parser::parse_node::NodeType;
use crate::parser::parse_node::ParseNode;
use crate::tree::MathDomNode;
use crate::types::{ArgType, BreakToken, ErrorLocationProvider as _, SourceLocation};
use crate::types::{ParseError, Token};
pub struct FunctionContext<'name, 'parser, 'token> {
pub func_name: &'name str,
pub parser: &'parser mut Parser<'token>,
pub token: Option<&'parser Token>,
pub break_on_token_text: Option<&'parser BreakToken>,
}
impl FunctionContext<'_, '_, '_> {
#[must_use]
pub fn loc(&self) -> Option<SourceLocation> {
let t = self.token?;
t.loc().cloned()
}
}
pub type FunctionHandler = for<'name, 'parser, 'token> fn(
FunctionContext<'name, 'parser, 'token>,
args: Vec<ParseNode>,
opt_args: Vec<Option<ParseNode>>,
) -> Result<ParseNode, ParseError>;
pub type HtmlBuilder = fn(&ParseNode, &Options, &KatexContext) -> Result<HtmlDomNode, ParseError>;
pub type MathMLBuilder = fn(&ParseNode, &Options, &KatexContext) -> Result<MathDomNode, ParseError>;
#[derive(Debug, Clone)]
pub struct FunctionPropSpec {
pub num_args: usize,
pub arg_types: Option<Vec<ArgType>>,
pub allowed_in_argument: bool,
pub allowed_in_text: bool,
pub allowed_in_math: bool,
pub num_optional_args: usize,
pub infix: bool,
pub primitive: bool,
}
impl Default for FunctionPropSpec {
fn default() -> Self {
Self {
num_args: 0,
arg_types: None,
allowed_in_argument: false,
allowed_in_text: false,
allowed_in_math: true,
num_optional_args: 0,
infix: false,
primitive: false,
}
}
}
pub struct FunctionDefSpec<'b> {
pub node_type: Option<NodeType>,
pub names: &'b [&'b str],
pub props: FunctionPropSpec,
pub handler: Option<FunctionHandler>,
pub html_builder: Option<HtmlBuilder>,
pub mathml_builder: Option<MathMLBuilder>,
}
#[derive(Debug, Clone)]
pub struct FunctionSpec {
pub node_type: Option<NodeType>,
pub num_args: usize,
pub arg_types: Option<Vec<ArgType>>,
pub allowed_in_argument: bool,
pub allowed_in_text: bool,
pub allowed_in_math: bool,
pub num_optional_args: usize,
pub infix: bool,
pub primitive: bool,
pub handler: Option<FunctionHandler>,
}
#[must_use]
pub fn normalize_argument(arg: &ParseNode) -> &ParseNode {
if let ParseNode::OrdGroup(ord) = arg
&& ord.body.len() == 1
{
return &ord.body[0];
}
arg
}
#[must_use]
pub fn ord_argument(arg: &ParseNode) -> Vec<ParseNode> {
if let ParseNode::OrdGroup(ord) = arg {
return ord.body.clone();
}
vec![arg.clone()]
}