diff options
| author | Fuwn <[email protected]> | 2022-06-02 07:31:20 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2022-06-02 07:31:20 +0000 |
| commit | 53f1753db91fe9347155f8192052e30baaad9cbc (patch) | |
| tree | f7053185a4a2e20a9a086ab96153bc074f7e5672 | |
| parent | docs(cargo): bump 0.2.3 -> 0.2.4 (diff) | |
| download | germ-53f1753db91fe9347155f8192052e30baaad9cbc.tar.xz germ-53f1753db91fe9347155f8192052e30baaad9cbc.zip | |
feat(ast): Ast::to_gemtext
| -rw-r--r-- | examples/ast_to_gemtext.rs | 53 | ||||
| -rw-r--r-- | src/ast.rs | 58 | ||||
| -rw-r--r-- | src/convert/markdown.rs | 2 | ||||
| -rw-r--r-- | tests/ast.rs | 39 |
4 files changed, 151 insertions, 1 deletions
diff --git a/examples/ast_to_gemtext.rs b/examples/ast_to_gemtext.rs new file mode 100644 index 0000000..5ceef21 --- /dev/null +++ b/examples/ast_to_gemtext.rs @@ -0,0 +1,53 @@ +// This file is part of Germ <https://github.com/gemrest/germ>. +// Copyright (C) 2022-2022 Fuwn <[email protected]> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// Copyright (C) 2022-2022 Fuwn <[email protected]> +// SPDX-License-Identifier: GPL-3.0-only + +const EXAMPLE_GEMTEXT: &str = r#"```This is alt-text +Here goes the pre-formatted text. + +This continues the pre-formatted text on a new line after a blank line. +``` + +# This is a heading + +This is some text. + +This is more text after a blank line. + +* This is a single list item. +* This is the next list item. + +* This is a new list. +* This is the next item on the new list. + +## This is a sub-heading + +> This is a blockquote. + +### This is a sub-sub-heading. + +=> gemini://gem.rest/ This is a link to GemRest +=> /somewhere + +That was a link without text."#; + +fn main() { + println!( + "{}", + germ::ast::Ast::from_string(EXAMPLE_GEMTEXT).to_gemtext() + ); +} @@ -215,6 +215,64 @@ impl Ast { } } + #[must_use] + pub fn to_gemtext(&self) -> String { + let mut gemtext = "".to_string(); + + for node in &self.inner { + match node { + Node::Text(text) => gemtext.push_str(&format!("{}\n", text)), + Node::Link { + to, + text, + } => + gemtext.push_str(&format!( + "=> {}{}\n", + to, + text + .clone() + .map_or_else(|| "".to_string(), |text| format!(" {}", text)), + )), + Node::Heading { + level, + text, + } => + gemtext.push_str(&format!( + "{} {}\n", + match level { + 1 => "#", + 2 => "##", + 3 => "###", + _ => "", + }, + text + )), + Node::List(items) => + gemtext.push_str(&format!( + "{}\n", + items + .iter() + .map(|i| format!("* {}", i)) + .collect::<Vec<String>>() + .join("\n"), + )), + Node::Blockquote(text) => gemtext.push_str(&format!("> {}\n", text)), + Node::PreformattedText { + alt_text, + text, + } => + gemtext.push_str(&format!( + "```{}\n{}```\n", + alt_text.clone().unwrap_or_else(|| "".to_string()), + text + )), + Node::Whitespace => gemtext.push('\n'), + } + } + + gemtext + } + /// The actual AST of `Ast` /// /// # Example diff --git a/src/convert/markdown.rs b/src/convert/markdown.rs index c6899b7..a38da9f 100644 --- a/src/convert/markdown.rs +++ b/src/convert/markdown.rs @@ -69,7 +69,7 @@ pub fn convert(source: &[Node]) -> String { text )); } - Node::Whitespace => markdown.push_str("\n"), + Node::Whitespace => markdown.push('\n'), } } diff --git a/tests/ast.rs b/tests/ast.rs index 8b3882d..5f6cd5c 100644 --- a/tests/ast.rs +++ b/tests/ast.rs @@ -20,6 +20,35 @@ mod test { use germ::ast::{Ast, Node}; + const EXAMPLE_GEMTEXT: &str = r#"```This is alt-text +Here goes the pre-formatted text. + +This continues the pre-formatted text on a new line after a blank line. +``` + +# This is a heading + +This is some text. + +This is more text after a blank line. + +* This is a single list item. +* This is the next list item. + +* This is a new list. +* This is the next item on the new list. + +## This is a sub-heading + +> This is a blockquote. + +### This is a sub-sub-heading. + +=> gemini://gem.rest/ This is a link to GemRest +=> /somewhere + +That was a link without text."#; + #[test] fn build_multi_line_list_with_text() { assert_eq!( @@ -67,4 +96,14 @@ mod test { }, ); } + + #[test] + fn gemtext_to_ast_then_ast_to_gemtext() { + assert_eq!( + Ast::from_string(EXAMPLE_GEMTEXT).to_gemtext(), + // `to_gemtext` appends a newline to all responses, so let's make sure we + // account for that. + format!("{}\n", EXAMPLE_GEMTEXT), + ); + } } |