use crate::util::escape_html;
pub fn render_math(src: &str, display: bool) -> String {
let opts = katex::Opts::builder()
.display_mode(display)
.throw_on_error(true)
.build()
.expect("katex opts build");
match katex::render_with_opts(src, &opts) {
Ok(html) => html,
Err(e) => {
eprintln!("docgen: KaTeX failed to render math `{src}`: {e}");
let escaped = escape_html(src);
if display {
format!("<div class=\"katex-display docgen-math-error\">{escaped}</div>")
} else {
format!("<code class=\"docgen-math-error\">{escaped}</code>")
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn renders_inline_math_to_katex_html() {
let html = render_math("E=mc^2", false);
assert!(html.contains("katex"));
assert!(!html.contains("katex-display")); }
#[test]
fn renders_display_math_with_display_wrapper() {
let html = render_math("\\int_0^1 x\\,dx", true);
assert!(html.contains("katex-display"));
}
#[test]
fn bad_expression_degrades_to_escaped_code() {
let html = render_math("\\frac{", false);
assert!(html.contains("docgen-math-error"));
assert!(html.contains("<code")); assert!(!html.contains("<script"));
}
#[test]
fn bad_display_expression_degrades_to_block() {
let html = render_math("\\frac{", true);
assert!(html.contains("docgen-math-error"));
assert!(html.contains("katex-display")); assert!(html.contains("<div")); assert!(!html.contains("<code"));
}
#[test]
fn bad_expression_escapes_html_metacharacters() {
let html = render_math("<script>\\frac{", false);
assert!(html.contains("<script>"));
assert!(!html.contains("<script>"));
}
}