From 84f6223c686f2c557c318411b5884563f1236bbe Mon Sep 17 00:00:00 2001 From: xfy Date: Thu, 16 Jul 2026 14:12:20 +0800 Subject: [PATCH] =?UTF-8?q?feat(markdown):=20=E8=AF=84=E8=AE=BA=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=95=B0=E5=AD=A6=E5=85=AC=E5=BC=8F=E6=B8=B2=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - comments/markdown.rs: 开启 ENABLE_MATH,InlineMath/DisplayMath 事件 渲染成 katex HTML 注入事件流(评论不用块级
包裹,保持紧凑)
- sanitizer.rs: 评论路径 span 白名单加 style(KaTeX 内联定位 style 需保留,
与文章正文 sanitizer.rs:382 对齐)
- 新增 3 个评论公式测试(内联/块级/style 保留)
双 target 编译通过,24 个评论测试 + 36 个 sanitizer 测试全过。
---
src/api/comments/markdown.rs | 49 +++++++++++++++++++++++++++++++++++-
src/api/sanitizer.rs | 4 ++-
2 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/src/api/comments/markdown.rs b/src/api/comments/markdown.rs
index 68f7c04..09dd540 100644
--- a/src/api/comments/markdown.rs
+++ b/src/api/comments/markdown.rs
@@ -22,7 +22,7 @@ pub fn clean_comment_html(input: &str) -> String {
pub fn render_comment_markdown(md: &str) -> String {
use pulldown_cmark::{CodeBlockKind, Event, Options, Tag, TagEnd};
- let opts = Options::ENABLE_TABLES | Options::ENABLE_STRIKETHROUGH;
+ let opts = Options::ENABLE_TABLES | Options::ENABLE_STRIKETHROUGH | Options::ENABLE_MATH;
let parser = pulldown_cmark::Parser::new_ext(md, opts);
let mut events: Vec (评论渲染较紧凑,避免引入多余段间距)。
+ let html = crate::api::katex::render_display(&tex);
+ events.push(Event::Html(html.into()));
+ }
Event::Start(Tag::Heading { .. }) => {
// 评论中不保留标题层级,统一加粗。
events.push(Event::Start(Tag::Strong));
@@ -233,4 +244,40 @@ mod tests {
assert!(result.contains("foo()"));
assert!(!result.contains(""));
}
+
+ #[test]
+ fn render_comment_inline_math() {
+ // 评论里的 $...$ 内联公式:ENABLE_MATH 解析 → katex 渲染 → sanitizer 放行 span。
+ let result = render_comment_markdown("方程 $a^2 + b^2 = c^2$ 是勾股定理");
+ assert!(
+ result.contains("katex"),
+ "评论内联公式应渲染为 katex span, got: {}",
+ result
+ );
+ assert!(result.contains("方程"));
+ assert!(result.contains("勾股定理"));
+ }
+
+ #[test]
+ fn render_comment_display_math() {
+ // 评论里的 $$...$$ 块级公式。
+ let result = render_comment_markdown("$$\\int_0^1 x\\,dx$$");
+ assert!(
+ result.contains("katex-display"),
+ "评论块级公式应含 katex-display, got: {}",
+ result
+ );
+ }
+
+ #[test]
+ fn render_comment_math_span_style_preserved() {
+ // KaTeX 内联 style(垂直对齐)必须经 clean_comment_html 保留,
+ // 否则公式在评论里排版错位。验证 span 的 style 属性未被剥离。
+ let result = render_comment_markdown("$x^2$");
+ assert!(
+ result.contains("style=\""),
+ "评论 katex span 的 style 应保留, got: {}",
+ result
+ );
+ }
}
diff --git a/src/api/sanitizer.rs b/src/api/sanitizer.rs
index 3408fce..a6aae89 100644
--- a/src/api/sanitizer.rs
+++ b/src/api/sanitizer.rs
@@ -410,7 +410,9 @@ pub fn clean_comment_html(input: &str) -> String {
],
extra_tag_attrs: vec![
("a", vec!["class", "aria-hidden", "aria-label"]),
- ("span", vec!["class"]),
+ // span 的 style:KaTeX 服务端渲染产出的内联 style(元素垂直对齐/定位)
+ // 需保留,否则公式排版错位。与文章正文路径(sanitizer.rs:382)对齐。
+ ("span", vec!["class", "style"]),
],
allowed_schemes: &DEFAULT_ALLOWED_SCHEMES,
allow_data_uri: false,