diff --git a/crates/mq-markdown/src/html_to_markdown/converter.rs b/crates/mq-markdown/src/html_to_markdown/converter.rs index 911d82cf8..1262d7599 100644 --- a/crates/mq-markdown/src/html_to_markdown/converter.rs +++ b/crates/mq-markdown/src/html_to_markdown/converter.rs @@ -605,6 +605,66 @@ fn handle_dl_element(element: &HtmlElement, options: &ConversionOptions) -> miet } } +/// Converts a ``s. +fn handle_select_element(element: &HtmlElement) -> miette::Result { + let mut items = Vec::new(); + collect_select_options(&element.children, &mut items, 0)?; + Ok(items.join("\n")) +} + +fn collect_select_options(nodes: &[HtmlNode], items: &mut Vec, indent_level: usize) -> miette::Result<()> { + let indent = " ".repeat(indent_level); + for node in nodes { + if let HtmlNode::Element(el) = node { + match el.tag_name.as_str() { + "option" => { + let text = convert_children_to_string(&el.children)?; + let text = text.trim(); + let label = if !text.is_empty() { + text.to_string() + } else if let Some(Some(label_attr)) = el.attributes.get("label") { + label_attr.clone() + } else { + String::new() + }; + if label.is_empty() { + continue; + } + let marker = if el.attributes.contains_key("selected") { + "[x]" + } else { + "[ ]" + }; + items.push(format!("{}* {} {}", indent, marker, label)); + } + "optgroup" => { + if let Some(Some(group_label)) = el.attributes.get("label") + && !group_label.is_empty() + { + items.push(format!("{}* **{}**", indent, group_label)); + } + collect_select_options(&el.children, items, indent_level + 1)?; + } + _ => {} + } + } + } + Ok(()) +} + +/// Converts `", + ConversionOptions::default(), + "```\nline1\nline2\n```" +)] +#[case::textarea_empty("", ConversionOptions::default(), "")] +#[case::fieldset_legend( + "
Contact

Name

", + ConversionOptions::default(), + "**Contact**\n\nName" +)] +#[case::form_with_label_and_input( + "
", + ConversionOptions::default(), + "Name: World" +)] #[case::dl_simple( "
Term 1
Definition 1
", ConversionOptions::default(),