-fn get_heading_wrapper(heading_stack: &mut Vec<u8>, line_type: &LineType) -> String {
- let mut string = String::new();
- let current_heading: u8 = match line_type {
- LineType::Heading1 => 1,
- LineType::Heading2 => 2,
- LineType::Heading3 => 3,
- _ => 255
- };
-
- if current_heading < 255 {
- while let Some(open_heading) = heading_stack.pop() {
- // You just encountered a more important heading.
- // Put it back. Desist.
- if open_heading < current_heading {
- heading_stack.push(open_heading);
- break;
- }
-
- string.push_str("</div>");
-
- if open_heading == current_heading {
- break;
- }
- }
- heading_stack.push(current_heading);
- string.push_str(&format!("<div class=\"h{}\">", current_heading));
- }
-
- return string;
-}
-
-fn close_heading_wrapper(heading_stack: &mut Vec<u8>) -> String {
- let mut string = String::new();
- while let Some(_open_heading) = heading_stack.pop() {
- string.push_str("</div>");
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_headings() {
+ assert_eq!(parse_line("### Heading"), GeminiLine::Heading(3, " Heading".to_string()));
+ assert_eq!(parse_line("## Heading"), GeminiLine::Heading(2, " Heading".to_string()));
+ assert_eq!(parse_line("# Heading"), GeminiLine::Heading(1, " Heading".to_string()));
+ assert_eq!(parse_line("###"), GeminiLine::Heading(3, "".to_string()));
+ assert_eq!(parse_line("#####"), GeminiLine::Heading(3, "##".to_string()));
+ assert_eq!(parse_line("# "), GeminiLine::Heading(1, " ".to_string()));
+
+ assert_eq!(parse_preformatted_line("### Heading"), GeminiLine::Text("### Heading".to_string(), true));
+ assert_eq!(parse_preformatted_line("## Heading"), GeminiLine::Text("## Heading".to_string(), true));
+ assert_eq!(parse_preformatted_line("# Heading"), GeminiLine::Text("# Heading".to_string(), true));
+ }
+
+ #[test]
+ fn test_links() {
+ assert_eq!(
+ parse_line("=> https://example.com Link text"),
+ GeminiLine::Link("https://example.com".to_string(), "Link text".to_string())
+ );
+ assert_eq!(
+ parse_line("=> /local/path"),
+ GeminiLine::Link("/local/path".to_string(), "".to_string())
+ );
+
+ assert_eq!(
+ parse_line("=>"),
+ GeminiLine::Link("".to_string(), "".to_string())
+ );
+ assert_eq!(
+ parse_line("=> "),
+ GeminiLine::Link("".to_string(), "".to_string())
+ );
+ assert_eq!(
+ parse_line("=> multiple spaces in text"),
+ GeminiLine::Link("multiple".to_string(), "spaces in text".to_string())
+ );
+
+ assert_eq!(
+ parse_preformatted_line("=> https://example.com Link text"),
+ GeminiLine::Text("=> https://example.com Link text".to_string(), true)
+ );
+ }
+
+ #[test]
+ fn test_list_items() {
+ assert_eq!(
+ parse_line("* List item"),
+ GeminiLine::ListItem("List item".to_string())
+ );
+
+ assert_eq!(parse_line("* "), GeminiLine::ListItem("".to_string()));
+ assert_eq!(parse_line("*"), GeminiLine::Text("*".to_string(), false));
+ assert_eq!(parse_line("*WithText"), GeminiLine::Text("*WithText".to_string(), false));
+ assert_eq!(parse_line("* Multiple spaces"), GeminiLine::ListItem(" Multiple spaces".to_string()));
+ }
+
+ #[test]
+ fn test_quotes() {
+ assert_eq!(
+ parse_line(">Quote text"),
+ GeminiLine::Quote("Quote text".to_string())
+ );
+
+ assert_eq!(parse_line(">"), GeminiLine::Quote("".to_string()));
+ assert_eq!(parse_line("> "), GeminiLine::Quote(" ".to_string()));
+ assert_eq!(parse_line(">>Nested"), GeminiLine::Quote(">Nested".to_string()));
+ }
+
+ #[test]
+ fn test_preformatted() {
+ assert_eq!(
+ parse_line("```alt-text"),
+ GeminiLine::PreformattedToggle(true, "alt-text".to_string())
+ );
+
+ assert_eq!(parse_line("```"), GeminiLine::PreformattedToggle(true, "".to_string()));
+ assert_eq!(parse_line("``` "), GeminiLine::PreformattedToggle(true, " ".to_string()));
+ assert_eq!(parse_line("````"), GeminiLine::PreformattedToggle(true, "`".to_string()));
+
+ assert_eq!(
+ parse_preformatted_line("```alt-text"),
+ GeminiLine::PreformattedToggle(false, "".to_string())
+ );
+ assert_eq!(
+ parse_preformatted_line("```"),
+ GeminiLine::PreformattedToggle(false, "".to_string())
+ );
+
+ }
+
+ #[test]
+ fn test_text() {
+ // Normal case
+ assert_eq!(
+ parse_line("Regular text"),
+ GeminiLine::Text("Regular text".to_string(), false)
+ );
+
+ // Edge cases
+ assert_eq!(parse_line(""), GeminiLine::Text("".to_string(), false));
+ assert_eq!(parse_line(" "), GeminiLine::Text(" ".to_string(), false));
+ assert_eq!(parse_line(" "), GeminiLine::Text(" ".to_string(), false));
+ }
+
+ #[test]
+ fn test_malformed_input() {
+ assert_eq!(parse_line("= >Not a link"), GeminiLine::Text("= >Not a link".to_string(), false));
+ assert_eq!(parse_line("``Not preformatted"), GeminiLine::Text("``Not preformatted".to_string(), false));
+ assert_eq!(parse_line("** Not a list"), GeminiLine::Text("** Not a list".to_string(), false));
+ }
+
+ #[test]
+ fn test_full_document() {
+ let input = "\
+# Heading 1
+## Heading 2
+### Heading 3
+Regular text
+=> https://example.com Link text
+* List item
+>Quote
+```alt
+code
+# Heading 1
+## Heading 2
+### Heading 3
+=> https://example.com Link text
+* List item
+>Quote
+```trailing alt";
+ let result = parse(input);
+ assert_eq!(result, vec![
+ GeminiLine::Heading(1, " Heading 1".to_string()),
+ GeminiLine::Heading(2, " Heading 2".to_string()),
+ GeminiLine::Heading(3, " Heading 3".to_string()),
+ GeminiLine::Text("Regular text".to_string(), false),
+ GeminiLine::Link("https://example.com".to_string(), "Link text".to_string()),
+ GeminiLine::ListItem("List item".to_string()),
+ GeminiLine::Quote("Quote".to_string()),
+ GeminiLine::PreformattedToggle(true, "alt".to_string()),
+ GeminiLine::Text("code".to_string(), true),
+ GeminiLine::Text("# Heading 1".to_string(), true),
+ GeminiLine::Text("## Heading 2".to_string(), true),
+ GeminiLine::Text("### Heading 3".to_string(), true),
+ GeminiLine::Text("=> https://example.com Link text".to_string(), true),
+ GeminiLine::Text("* List item".to_string(), true),
+ GeminiLine::Text(">Quote".to_string(), true),
+ GeminiLine::PreformattedToggle(false, "".to_string()),
+ ]);