use crate::gemini_parser::GeminiLine;
+use std::path::Path;
/// Renders HTML from a vector of `GeminiLine` elements.
///
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>")
+ let path = Path::new(url);
+ let processed_url = if !url.starts_with("gemini:")
+ && path
+ .extension()
+ .map_or(false, |ext| ext.eq_ignore_ascii_case("gmi"))
+ {
+ url.replace(".gmi", ".html")
+ } else {
+ url.to_string()
+ };
+
+ let display = if text.is_empty() {
+ &processed_url
+ } else {
+ text
+ };
+ format!("<p class=\"a\"><a href=\"{processed_url}\">{display}</a></p>")
}
GeminiLine::Heading(level, content) => format!("<h{level}>{content}</h{level}>"),
GeminiLine::ListItem(content) => format!("<li>{content}</li>"),
#[test]
fn test_links() {
let input = vec![
+ GeminiLine::Link("gemini://hi.gmi".to_string(), "Example".to_string()),
+ GeminiLine::Link("/hi.gmi/kidding".to_string(), "Example".to_string()),
+ GeminiLine::Link("/hi.gmi".to_string(), "Example".to_string()),
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=\"gemini://hi.gmi\">Example</a></p>\n\
+ <p class=\"a\"><a href=\"/hi.gmi/kidding\">Example</a></p>\n\
+ <p class=\"a\"><a href=\"/hi.html\">Example</a></p>\n\
+ <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"
);
}