fix(api): fix markdown rendering to properly handle code blocks and other elements

This commit is contained in:
xfy 2026-06-02 18:30:26 +08:00
parent 14e4a26dc0
commit 5ff58fec59

View File

@ -225,10 +225,16 @@ fn render_markdown_enhanced(md: &str) -> RenderedContent {
let mut html = String::new(); let mut html = String::new();
let mut heading_idx = 0; let mut heading_idx = 0;
let mut in_heading = false; let mut in_heading = false;
let mut non_heading_events: Vec<Event> = Vec::new();
for event in parser { for event in parser {
match event { match event {
Event::Start(Tag::Heading { level, .. }) => { Event::Start(Tag::Heading { level, .. }) => {
// Flush non-heading events first
if !non_heading_events.is_empty() {
pulldown_cmark::html::push_html(&mut html, non_heading_events.into_iter());
non_heading_events = Vec::new();
}
in_heading = true; in_heading = true;
if heading_idx < headings.len() { if heading_idx < headings.len() {
let (_, _, ref id) = headings[heading_idx]; let (_, _, ref id) = headings[heading_idx];
@ -241,11 +247,9 @@ fn render_markdown_enhanced(md: &str) -> RenderedContent {
HeadingLevel::H6 => "h6", HeadingLevel::H6 => "h6",
}; };
html.push_str(&format!("<{} id=\"{}\">", tag, id)); html.push_str(&format!("<{} id=\"{}\">", tag, id));
continue;
} }
} }
Event::End(TagEnd::Heading(level)) => { Event::End(TagEnd::Heading(level)) => {
in_heading = false;
if heading_idx < headings.len() { if heading_idx < headings.len() {
let (_, _, ref id) = headings[heading_idx]; let (_, _, ref id) = headings[heading_idx];
let tag = match level { let tag = match level {
@ -261,26 +265,31 @@ fn render_markdown_enhanced(md: &str) -> RenderedContent {
id, tag id, tag
)); ));
heading_idx += 1; heading_idx += 1;
continue; }
in_heading = false;
}
_ => {
if in_heading {
// Manually render heading content
match event {
Event::Text(text) => html.push_str(&ammonia::clean(&text)),
Event::Code(code) => {
html.push_str("<code>");
html.push_str(&ammonia::clean(&code));
html.push_str("</code>");
}
_ => {}
}
} else {
non_heading_events.push(event);
} }
} }
_ => {}
} }
}
if in_heading { // Flush remaining non-heading events
// Manually render heading content if !non_heading_events.is_empty() {
match event { pulldown_cmark::html::push_html(&mut html, non_heading_events.into_iter());
Event::Text(text) => html.push_str(&ammonia::clean(&text)),
Event::Code(code) => {
html.push_str("<code>");
html.push_str(&ammonia::clean(&code));
html.push_str("</code>");
}
_ => {}
}
} else {
pulldown_cmark::html::push_html(&mut html, std::iter::once(event));
}
} }
// 4. Count words (Chinese characters + English words) // 4. Count words (Chinese characters + English words)