diff options
| author | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-01-09 22:02:19 +0100 |
|---|---|---|
| committer | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-01-09 22:02:19 +0100 |
| commit | f5ac7b8efb4e0d1dd197ddecbad2b46fd19f5ddb (patch) | |
| tree | 8859ed7bc7b1caf8d18d04ea438d6114b06eea78 /src/html_renderer.rs | |
| parent | f08e8d64dce087201089d2b3276b3dfcdb000173 (diff) | |
Remove no longer necessary code
Diffstat (limited to 'src/html_renderer.rs')
| -rw-r--r-- | src/html_renderer.rs | 256 |
1 files changed, 0 insertions, 256 deletions
diff --git a/src/html_renderer.rs b/src/html_renderer.rs deleted file mode 100644 index 6b9ce38..0000000 --- a/src/html_renderer.rs +++ /dev/null @@ -1,256 +0,0 @@ -use crate::gemini_parser::GeminiLine; - -/// Renders HTML from a vector of `GeminiLine` elements. -/// -/// # Arguments -/// * `lines` - Vector of `GeminiLine` elements to render -/// -/// # Returns -/// A String containing the rendered HTML. -pub fn render_html(lines: &[GeminiLine]) -> String { - let mut heading_stack = Vec::new(); - let mut last_line: Option<&GeminiLine> = None; - let mut result = String::new(); - - for line in lines { - result.push_str(&line_preamble(line, last_line, &mut heading_stack)); - result.push_str(&line_content(line)); - result.push('\n'); - last_line = Some(line); - } - - result.push_str(&finalize_html(&heading_stack, last_line)); - result -} - -fn line_preamble( - line: &GeminiLine, - last_line: Option<&GeminiLine>, - heading_stack: &mut Vec<u8>, -) -> String { - let mut html = String::new(); - - if let Some(last_line) = last_line { - match last_line { - GeminiLine::ListItem(_) => match line { - GeminiLine::ListItem(_) => {} - _ => html.push_str("</ul>\n"), - }, - GeminiLine::Quote(_) => match line { - GeminiLine::Quote(_) => {} - _ => html.push_str("</blockquote>\n"), - }, - _ => {} - } - } - - match line { - GeminiLine::Heading(level, _) => { - while let Some(open_heading) = heading_stack.pop() { - // You just encountered a more important heading. - // Put it back. Desist. - if open_heading < *level { - heading_stack.push(open_heading); - break; - } - - html.push_str("</section>\n"); - - if open_heading == *level { - break; - } - } - heading_stack.push(*level); - html.push_str(&format!("<section class=\"h{level}\">\n")); - } - GeminiLine::ListItem(_) => match last_line { - Some(GeminiLine::ListItem(_)) => {} - _ => html.push_str("<ul>\n"), - }, - GeminiLine::Quote(_) => match last_line { - Some(GeminiLine::Quote(_)) => {} - _ => html.push_str("<blockquote>\n"), - }, - _ => {} - } - - html -} - -fn line_content(line: &GeminiLine) -> String { - match line { - GeminiLine::Text(content, false) => format!("<p>{content}</p>"), - GeminiLine::Link(url, text) => { - let display = if text.is_empty() { url } else { text }; - format!("<p class=\"a\"><a href=\"{url}\">{display}</a></p>") - } - GeminiLine::Heading(level, content) => format!("<h{level}>{content}</h{level}>"), - GeminiLine::ListItem(content) => format!("<li>{content}</li>"), - GeminiLine::PreformattedToggle(true, alt_text) => { - format!("<pre aria-label=\"{alt_text}\">") - } - GeminiLine::PreformattedToggle(false, _) => "</pre>".to_string(), - GeminiLine::Text(content, true) | GeminiLine::Quote(content) => content.to_string(), - } -} - -fn finalize_html(heading_stack: &[u8], last_line: Option<&GeminiLine>) -> String { - let mut html = String::new(); - - match last_line { - Some(GeminiLine::ListItem(_)) => html.push_str("</ul>\n"), - Some(GeminiLine::Quote(_)) => html.push_str("</blockquote>\n"), - _ => {} - } - - for _ in heading_stack { - html.push_str("</section>\n"); - } - - html -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_simple_text() { - let input = vec![GeminiLine::Text("Hello world".to_string(), false)]; - assert_eq!(render_html(&input), "<p>Hello world</p>\n"); - } - - #[test] - fn test_heading_nesting() { - let input = vec![ - GeminiLine::Heading(1, "Top".to_string()), - GeminiLine::Heading(2, "Sub".to_string()), - GeminiLine::Heading(3, "SubSub".to_string()), - GeminiLine::Heading(2, "Another Sub".to_string()), - ]; - assert_eq!( - render_html(&input), - "<section class=\"h1\">\n\ - <h1>Top</h1>\n\ - <section class=\"h2\">\n\ - <h2>Sub</h2>\n\ - <section class=\"h3\">\n\ - <h3>SubSub</h3>\n\ - </section>\n\ - </section>\n\ - <section class=\"h2\">\n\ - <h2>Another Sub</h2>\n\ - </section>\n\ - </section>\n" - ); - } - - #[test] - fn test_list_transitions() { - let input = vec![ - GeminiLine::ListItem("First".to_string()), - GeminiLine::ListItem("Second".to_string()), - GeminiLine::Text("Break".to_string(), false), - GeminiLine::ListItem("New list".to_string()), - ]; - assert_eq!( - render_html(&input), - "<ul>\n\ - <li>First</li>\n\ - <li>Second</li>\n\ - </ul>\n\ - <p>Break</p>\n\ - <ul>\n\ - <li>New list</li>\n\ - </ul>\n" - ); - } - - #[test] - fn test_quote_transitions() { - let input = vec![ - GeminiLine::Quote("First quote".to_string()), - GeminiLine::Quote("Still quoting".to_string()), - GeminiLine::Text("Normal text".to_string(), false), - GeminiLine::Quote("New quote".to_string()), - ]; - assert_eq!( - render_html(&input), - "<blockquote>\n\ - First quote\n\ - Still quoting\n\ - </blockquote>\n\ - <p>Normal text</p>\n\ - <blockquote>\n\ - New quote\n\ - </blockquote>\n" - ); - } - - #[test] - fn test_preformatted() { - let input = vec![ - GeminiLine::PreformattedToggle(true, "code".to_string()), - GeminiLine::Text("let x = 42;".to_string(), true), - GeminiLine::PreformattedToggle(false, String::new()), - ]; - assert_eq!( - render_html(&input), - "<pre aria-label=\"code\">\n\ - let x = 42;\n\ - </pre>\n" - ); - } - - #[test] - fn test_links() { - let input = vec![ - GeminiLine::Link("https://example.com".to_string(), "Example".to_string()), - GeminiLine::Link("https://rust-lang.org".to_string(), String::new()), - ]; - assert_eq!( - render_html(&input), - "<p class=\"a\"><a href=\"https://example.com\">Example</a></p>\n\ - <p class=\"a\"><a href=\"https://rust-lang.org\">https://rust-lang.org</a></p>\n" - ); - } - - #[test] - fn test_complex_nesting() { - let input = vec![ - GeminiLine::Heading(1, "Title".to_string()), - GeminiLine::Text("Intro".to_string(), false), - GeminiLine::Heading(2, "Section".to_string()), - GeminiLine::ListItem("Point 1".to_string()), - GeminiLine::ListItem("Point 2".to_string()), - GeminiLine::Quote("Important quote".to_string()), - GeminiLine::Heading(2, "Another Section".to_string()), - ]; - assert_eq!( - render_html(&input), - "<section class=\"h1\">\n\ - <h1>Title</h1>\n\ - <p>Intro</p>\n\ - <section class=\"h2\">\n\ - <h2>Section</h2>\n\ - <ul>\n\ - <li>Point 1</li>\n\ - <li>Point 2</li>\n\ - </ul>\n\ - <blockquote>\n\ - Important quote\n\ - </blockquote>\n\ - </section>\n\ - <section class=\"h2\">\n\ - <h2>Another Section</h2>\n\ - </section>\n\ - </section>\n" - ); - } - - #[test] - fn test_empty_input() { - let input = Vec::new(); - assert_eq!(render_html(&input), ""); - } -} |