use html_compare_rs::assert_html_eq; use pulldown_cmark::Parser; use pulldown_html_ext::*; use std::collections::HashMap; fn render_with_config(input: &str, config: &HtmlConfig) -> String { let mut output = String::new(); let handler = DefaultHtmlWriter::new(&mut output, config.clone()); let mut renderer = HtmlRenderer::new(handler); let _ = renderer.run(Parser::new(input)); output } // Individual HTML options tests #[test] #[ignore = "TODO: Fix/define escape_html handling in renderer"] fn test_escape_html_option() { let mut config = HtmlConfig::default(); // With HTML escaping (default) config.html.escape_html = true; assert_html_eq!( render_with_config("
test
", &config), "

<div>test</div>

" ); // Without HTML escaping config.html.escape_html = false; assert_html_eq!( render_with_config("
test
", &config), "

test

" ); } #[test] fn test_break_on_newline_option() { let mut config = HtmlConfig::default(); // With break on newline (default) config.html.break_on_newline = true; assert_html_eq!( render_with_config("Line 1\nLine 2", &config), "

Line 1
Line 2

" ); // Without break on newline config.html.break_on_newline = false; assert_html_eq!( render_with_config("Line 1\nLine 2", &config), "

Line 1\nLine 2

" ); } #[test] fn test_xhtml_style_option() { let mut config = HtmlConfig::default(); // Without XHTML style (default) config.html.xhtml_style = false; assert_html_eq!( render_with_config("![Alt](image.jpg)", &config), "

\"Alt\"

" ); // With XHTML style config.html.xhtml_style = true; assert_html_eq!( render_with_config("![Alt](image.jpg)", &config), "

\"Alt\"

" ); } // Individual element options tests #[test] fn test_heading_id_option() { let mut config = HtmlConfig::default(); // With heading IDs (default) config.elements.headings.add_ids = true; assert_html_eq!( render_with_config("# Test Heading", &config), "

Test Heading

" ); // Without heading IDs config.elements.headings.add_ids = false; assert_html_eq!( render_with_config("# Test Heading", &config), "

Test Heading

" ); } #[test] fn test_heading_id_prefix_option() { let mut config = HtmlConfig::default(); config.elements.headings.id_prefix = "section-".to_string(); assert_html_eq!( render_with_config("# Test Heading", &config), "

Test Heading

" ); } #[test] fn test_heading_level_classes() { let mut config = HtmlConfig::default(); let mut level_classes = HashMap::new(); level_classes.insert(1, "title".to_string()); level_classes.insert(2, "subtitle".to_string()); config.elements.headings.level_classes = level_classes; assert_html_eq!( render_with_config("# Heading 1\n## Heading 2", &config), "

Heading 1

\

Heading 2

" ); } #[test] fn test_link_options() { let mut config = HtmlConfig::default(); config.elements.links.nofollow_external = true; config.elements.links.open_external_blank = true; assert_html_eq!( render_with_config( "[Internal](/test) and [External](https://example.com)", &config ), "

Internal and \ External

" ); } #[test] fn test_code_block_options() { let mut config = HtmlConfig::default(); config.elements.code_blocks.default_language = Some("text".to_string()); // Explicit language should override default assert_html_eq!( render_with_config("```python\nprint('hello')\n```", &config), "
print('hello')
" ); // No language specified should use default assert_html_eq!( render_with_config("```\nhello\n```", &config), "
hello
" ); } #[test] fn test_custom_attributes() { let mut config = HtmlConfig::default(); let mut element_attributes = HashMap::new(); // Add attributes for paragraphs let mut p_attrs = HashMap::new(); p_attrs.insert("class".to_string(), "content".to_string()); element_attributes.insert("p".to_string(), p_attrs); // Add attributes for code blocks let mut pre_attrs = HashMap::new(); pre_attrs.insert("data-type".to_string(), "code".to_string()); element_attributes.insert("pre".to_string(), pre_attrs); config.attributes.element_attributes = element_attributes; assert_html_eq!( render_with_config("Regular paragraph\n\n```\nCode block\n```", &config), "

Regular paragraph

\
Code block
" ); } // Mixed configuration tests #[test] fn test_mixed_config_blog_style() { let mut config = HtmlConfig::default(); // Configure for blog-style output config.html.break_on_newline = false; config.elements.headings.add_ids = true; config.elements.links.open_external_blank = true; config.elements.links.nofollow_external = false; let mut heading_classes = HashMap::new(); heading_classes.insert(1, "post-title".to_string()); config.elements.headings.level_classes = heading_classes; let input = "# Blog Post Title\n\ Some text with an [external link](https://example.com).\n\n\ Multiple paragraphs look better\n\ without forced line breaks."; assert_html_eq!( render_with_config(input, &config), "

Blog Post Title

\

Some text with an external link.

\

Multiple paragraphs look better\nwithout forced line breaks.

" ); } #[test] fn test_mixed_config_documentation_style() { let mut config = HtmlConfig::default(); // Configure for documentation-style output config.elements.headings.id_prefix = "doc-".to_string(); config.elements.code_blocks.default_language = Some("text".to_string()); config.elements.links.nofollow_external = true; config.elements.links.open_external_blank = false; let mut element_attrs = HashMap::new(); let mut pre_attrs = HashMap::new(); pre_attrs.insert("class".to_string(), "documentation-code".to_string()); element_attrs.insert("pre".to_string(), pre_attrs); config.attributes.element_attributes = element_attrs; let input = "# Documentation\n\ Check the [reference](https://example.com).\n\n\ ```python\ndef example():\n pass\n```\n\n\ ```\nPlain text example\n```"; assert_html_eq!( render_with_config(input, &config), "

Documentation

\

Check the reference.

\
def example():\n    pass
\
Plain text example
" ); } #[test] fn test_mixed_config_presentation_style() { let mut config = HtmlConfig::default(); // Configure for presentation-style output config.html.xhtml_style = true; config.html.break_on_newline = true; let mut heading_classes = HashMap::new(); heading_classes.insert(1, "slide-title".to_string()); heading_classes.insert(2, "slide-subtitle".to_string()); config.elements.headings.level_classes = heading_classes; let mut element_attrs = HashMap::new(); let mut p_attrs = HashMap::new(); p_attrs.insert("class".to_string(), "slide-content".to_string()); element_attrs.insert("p".to_string(), p_attrs); config.attributes.element_attributes = element_attrs; let input = "# Slide Title\n\ ## Subtitle\n\n\ Content line 1\n\ Content line 2\n\n\ ![Diagram](image.jpg)"; assert_html_eq!( render_with_config(input, &config), "

Slide Title

\

Subtitle

\

Content line 1
Content line 2

\

\"Diagram\"

" ); }