use ox_content_ast::{BlockQuote, Node, Paragraph};
use super::super::callout::CalloutKind;
use super::HtmlRenderer;
impl HtmlRenderer {
fn render_paragraph_with_skipped_text_prefix<'a>(
&self,
paragraph: &Paragraph<'a>,
mut skip_chars: usize,
) -> String {
let mut renderer = HtmlRenderer::with_options(self.options.clone());
for child in ¶graph.children {
match child {
Node::Text(text) if skip_chars > 0 => {
if skip_chars >= text.value.len() {
skip_chars -= text.value.len();
continue;
}
renderer.write_escaped(&text.value[skip_chars..]);
skip_chars = 0;
}
_ => renderer.render_node(child),
}
}
renderer.output
}
fn detect_callout<'a>(paragraph: &Paragraph<'a>) -> Option<(CalloutKind, usize)> {
let mut iter = paragraph.children.iter();
let Node::Text(first_text) = iter.next()? else {
return None;
};
if first_text.value.as_bytes().first() != Some(&b'[') {
return None;
}
if let Some((kind, remainder)) = CalloutKind::parse_marker(first_text.value) {
let consumed = first_text.value.len().saturating_sub(remainder.len());
return Some((kind, consumed));
}
let mut prefix = String::from(first_text.value);
for child in iter {
let Node::Text(text) = child else {
return None;
};
prefix.push_str(text.value);
if let Some((kind, remainder)) = CalloutKind::parse_marker(&prefix) {
let consumed = prefix.len().saturating_sub(remainder.len());
return Some((kind, consumed));
}
}
None
}
pub(in crate::html::renderer) fn render_callout_block_quote<'a>(
&mut self,
block_quote: &BlockQuote<'a>,
) -> bool {
let Some(Node::Paragraph(first_paragraph)) = block_quote.children.first() else {
return false;
};
let Some((kind, consumed_chars)) = Self::detect_callout(first_paragraph) else {
return false;
};
self.write("<blockquote class=\"ox-callout ox-callout--");
self.write(kind.class_name());
self.write("\">\n");
self.write("<p class=\"ox-callout-title\">");
self.write(kind.label());
self.write("</p>\n");
let paragraph_body =
self.render_paragraph_with_skipped_text_prefix(first_paragraph, consumed_chars);
if !paragraph_body.trim().is_empty() {
self.write("<p>");
self.write(¶graph_body);
self.write("</p>\n");
}
for child in block_quote.children.iter().skip(1) {
self.render_node(child);
}
self.write("</blockquote>\n");
true
}
}