use dom_query::Selection;
use crate::elements::{blocks, code, headings, inline, lists, tables};
use crate::options::MarkdownOptions;
use crate::utils::{escape_markdown_text, get_tag_name};
pub(crate) fn convert_node(
sel: &Selection,
output: &mut String,
options: &MarkdownOptions,
depth: usize,
) {
let tag = get_tag_name(sel);
match tag.as_str() {
"h1" | "h2" | "h3" | "h4" | "h5" | "h6" if options.preserve_headings => {
if let Some(level) = tag.chars().nth(1).and_then(|c| c.to_digit(10)) {
headings::convert_heading(sel, output, options, level as usize, depth);
}
}
"p" => {
blocks::convert_paragraph(sel, output, options, depth);
}
"br" => {
blocks::convert_br(output);
}
"hr" => {
blocks::convert_hr(output);
}
"ul" if options.preserve_lists => {
lists::convert_list(sel, output, options, false, depth);
output.push('\n');
}
"ol" if options.preserve_lists => {
lists::convert_list(sel, output, options, true, depth);
output.push('\n');
}
"blockquote" if options.preserve_blockquotes => {
blocks::convert_blockquote(sel, output, options, depth);
}
"pre" if options.preserve_code => {
code::convert_code_block(sel, output);
}
"code" if options.preserve_code => {
inline::convert_inline_code(sel, output);
}
"strong" | "b" if options.preserve_emphasis => {
inline::convert_strong(sel, output, options, depth);
}
"em" | "i" if options.preserve_emphasis => {
inline::convert_emphasis(sel, output, options, depth);
}
"del" | "s" | "strike" if options.preserve_strikethrough && !options.commonmark => {
inline::convert_strikethrough(sel, output, options, depth);
}
"a" if options.include_links => {
inline::convert_link(sel, output, options, depth);
}
"img" if options.include_images => {
inline::convert_image(sel, output, options);
}
"table" if options.preserve_tables && !options.commonmark => {
tables::convert_table(sel, output);
output.push('\n');
}
_ => {
recurse_children(sel, output, options, depth);
}
}
}
fn recurse_children(
sel: &Selection,
output: &mut String,
options: &MarkdownOptions,
depth: usize,
) {
if let Some(node) = sel.nodes().first() {
for child in node.children() {
if child.is_text() {
let text = child.text();
if text.trim().is_empty() {
if !output.ends_with(' ') && !output.ends_with('\n') {
output.push(' ');
}
continue;
}
if options.escape_special_chars {
let line_start = output.is_empty()
|| output.ends_with('\n');
output.push_str(&escape_markdown_text(&text, line_start));
} else {
output.push_str(&text);
}
} else if child.is_element() {
let child_sel = Selection::from(child);
convert_node(&child_sel, output, options, depth);
}
}
}
}