···1919//! This example demonstrates Germ's capabilities for parsing Gemtext into an
2020//! abstract syntax tree.
21212222-const EXAMPLE_GEMTEXT: &str = r#"```This is alt-text
2323-Here goes the pre-formatted text.
2424-2525-This continues the pre-formatted text on a new line after a blank line.
2626-```
2727-2828-# This is a heading
2929-3030-This is some text.
3131-3232-This is more text after a blank line.
3333-3434-* This is a single list item.
3535-* This is the next list item.
3636-3737-* This is a new list.
3838-* This is the next item on the new list.
3939-4040-## This is a sub-heading
4141-4242-> This is a blockquote.
4343-4444-### This is a sub-sub-heading.
4545-4646-=> gemini://gem.rest/ This is a link to GemRest
4747-=> /somewhere
4848-4949-That was a link without text."#;
5050-5122fn main() {
5223 // Parse `EXAMPLE_GEMTEXT` into an abstract syntax tree
5353- let ast = germ::ast::Ast::from_string(EXAMPLE_GEMTEXT);
2424+ let ast = germ::ast::Ast::from_string(germ::EXAMPLE_GEMTEXT);
5425 // Get the nodes of the abstract syntax tree
5526 let ast_nodes = ast.inner();
5627
+1-30
examples/ast_to_gemtext.rs
···1919//! This example converts Gemtext into an abstract syntax tree and then back
2020//! into Gemtext, demonstrating both Germ's parsing and generation capabilities.
21212222-const EXAMPLE_GEMTEXT: &str = r#"```This is alt-text
2323-Here goes the pre-formatted text.
2424-2525-This continues the pre-formatted text on a new line after a blank line.
2626-```
2727-2828-# This is a heading
2929-3030-This is some text.
3131-3232-This is more text after a blank line.
3333-3434-* This is a single list item.
3535-* This is the next list item.
3636-3737-* This is a new list.
3838-* This is the next item on the new list.
3939-4040-## This is a sub-heading
4141-4242-> This is a blockquote.
4343-4444-### This is a sub-sub-heading.
4545-4646-=> gemini://gem.rest/ This is a link to GemRest
4747-=> /somewhere
4848-4949-That was a link without text."#;
5050-5122fn main() {
5223 // Parse `EXAMPLE_GEMTEXT` into an abstract syntax tree
5353- let ast = germ::ast::Ast::from_string(EXAMPLE_GEMTEXT);
2424+ let ast = germ::ast::Ast::from_string(germ::EXAMPLE_GEMTEXT);
5425 // Convert the abstract syntax tree back to Gemtext
5526 let gemtext = ast.to_gemtext();
5627
+4-31
examples/html.rs
···1919//! This example demonstrates Germ's capabilities for converting Gemtext to
2020//! HTML.
21212222-const EXAMPLE_GEMTEXT: &str = r#"```This is alt-text
2323-Here goes the pre-formatted text.
2424-2525-This continues the pre-formatted text on a new line after a blank line.
2626-```
2727-2828-# This is a heading
2929-3030-This is some text.
3131-3232-This is more text after a blank line.
3333-3434-* This is a single list item.
3535-* This is the next list item.
3636-3737-* This is a new list.
3838-* This is the next item on the new list.
3939-4040-## This is a sub-heading
4141-4242-> This is a blockquote.
4343-4444-### This is a sub-sub-heading.
4545-4646-=> gemini://gem.rest/ This is a link to GemRest
4747-=> /somewhere
4848-4949-That was a link without text."#;
5050-5122fn main() {
5223 // Convert the Gemtext to HTML
5353- let html =
5454- germ::convert::from_string(EXAMPLE_GEMTEXT, &germ::convert::Target::HTML);
2424+ let html = germ::convert::from_string(
2525+ germ::EXAMPLE_GEMTEXT,
2626+ &germ::convert::Target::HTML,
2727+ );
55285629 // Write the HTML to a file
5730 std::fs::write("examples/convert.html", html)
+1-30
examples/markdown.rs
···1919//! This example demonstrates Germ's capabilities for converting Gemtext to
2020//! Markdown.
21212222-const EXAMPLE_GEMTEXT: &str = r#"```This is alt-text
2323-Here goes the pre-formatted text.
2424-2525-This continues the pre-formatted text on a new line after a blank line.
2626-```
2727-2828-# This is a heading
2929-3030-This is some text.
3131-3232-This is more text after a blank line.
3333-3434-* This is a single list item.
3535-* This is the next list item.
3636-3737-* This is a new list.
3838-* This is the next item on the new list.
3939-4040-## This is a sub-heading
4141-4242-> This is a blockquote.
4343-4444-### This is a sub-sub-heading.
4545-4646-=> gemini://gem.rest/ This is a link to GemRest
4747-=> /somewhere
4848-4949-That was a link without text."#;
5050-5122fn main() {
5223 // Convert the Gemtext to Markdown
5324 let html = germ::convert::from_string(
5454- EXAMPLE_GEMTEXT,
2525+ germ::EXAMPLE_GEMTEXT,
5526 &germ::convert::Target::Markdown,
5627 );
5728
+6-6
src/ast/container.rs
···190190 // Match the first character of the Gemtext line to understand the line
191191 // type
192192 match line.get(0..1).unwrap_or("") {
193193- "=" => {
193193+ "=" if !*in_preformatted => {
194194 // If the Gemtext line starts with an "=" ("=>"), it is a link line,
195195 // so splitting it up should be easy enough.
196196 let line = line.get(2..).unwrap();
···211211212212 break;
213213 }
214214- "#" => {
214214+ "#" if !*in_preformatted => {
215215 // If the Gemtext line starts with an "#", it is a heading, so let's
216216 // find out how deep it goes.
217217 let level =
···234234235235 break;
236236 }
237237- "*" => {
237237+ "*" if !*in_preformatted => {
238238 // If the Gemtext line starts with an asterisk, it is a list item, so
239239 // let's enter a list context.
240240 if !*in_list {
···249249 break;
250250 }
251251 }
252252- ">" => {
252252+ ">" if !*in_preformatted => {
253253 // If the Gemtext line starts with an ">", it is a blockquote, so
254254 // let's just clip off the line identifier.
255255 nodes.push(Node::Blockquote(
···259259 break;
260260 }
261261 "`" => {
262262- // If the Gemtext line starts with a backtick, it is a list item, so
263263- // let's enter a preformatted text context.
262262+ // If the Gemtext line starts with a backtick, it's a preformatted
263263+ // toggle, so let's enter a preformatted text context.
264264 *in_preformatted = !*in_preformatted;
265265266266 if *in_preformatted {
+44
src/lib.rs
···3838#[cfg(feature = "meta")] pub mod meta;
39394040#[cfg(feature = "quick")] pub mod quick;
4141+4242+#[cfg(feature = "example-gemtext")]
4343+pub const EXAMPLE_GEMTEXT: &str = r"```This is alt-text
4444+Here goes the pre-formatted text.
4545+4646+This continues the pre-formatted text on a new line after a blank line.
4747+```
4848+4949+# This is a heading
5050+5151+This is some text.
5252+5353+This is more text after a blank line.
5454+5555+* This is a single list item.
5656+* This is the next list item.
5757+5858+* This is a new list.
5959+* This is the next item on the new list.
6060+6161+## This is a sub-heading
6262+6363+> This is a blockquote.
6464+6565+### This is a sub-sub-heading.
6666+6767+=> gemini://gem.rest/ This is a link to GemRest
6868+=> /somewhere
6969+7070+```This is a preformatted block containing inner Gemtext.
7171+=> gemini://fuwn.me/ This is a link.
7272+7373+* This is a list item.
7474+7575+> This is a blockquote.
7676+7777+# This is a heading.
7878+7979+## This is a sub-heading.
8080+8181+### This is a sub-sub-heading.
8282+```
8383+8484+That was a link without text.";
+17-52
tests/ast.rs
···18181919#[cfg(test)]
2020mod test {
2121- use germ::ast::{Ast, Node};
2222-2323- const EXAMPLE_GEMTEXT: &str = r#"```This is alt-text
2424-Here goes the pre-formatted text.
2525-2626-This continues the pre-formatted text on a new line after a blank line.
2727-```
2828-2929-# This is a heading
3030-3131-This is some text.
3232-3333-This is more text after a blank line.
3434-3535-* This is a single list item.
3636-* This is the next list item.
3737-3838-* This is a new list.
3939-* This is the next item on the new list.
4040-4141-## This is a sub-heading
4242-4343-> This is a blockquote.
4444-4545-### This is a sub-sub-heading.
4646-4747-=> gemini://gem.rest/ This is a link to GemRest
4848-=> /somewhere
4949-5050-That was a link without text."#;
2121+ use germ::{
2222+ ast::{Ast, Node},
2323+ EXAMPLE_GEMTEXT,
2424+ };
51255226 #[test]
5327 fn build_multi_line_list_with_text() {
5454- assert_eq!(
5555- *Ast::from_string("* item1\n* 2\nhi text").inner(),
5656- vec![
5757- Node::List(vec!["item1".to_string(), "2".to_string()]),
5858- Node::Text("hi text".to_string()),
5959- ],
6060- );
2828+ assert_eq!(*Ast::from_string("* item1\n* 2\nhi text").inner(), vec![
2929+ Node::List(vec!["item1".to_string(), "2".to_string()]),
3030+ Node::Text("hi text".to_string()),
3131+ ],);
6132 }
62336334 #[test]
6435 fn build_multi_line_vec() {
6565- assert_eq!(
6666- *Ast::from_string("=> /test hi\nhi there\n> hi").inner(),
6767- vec![
6868- Node::Link { to: "/test".to_string(), text: Some("hi".to_string()) },
6969- Node::Text("hi there".to_string()),
7070- Node::Blockquote("hi".to_string()),
7171- ],
7272- );
3636+ assert_eq!(*Ast::from_string("=> /test hi\nhi there\n> hi").inner(), vec![
3737+ Node::Link { to: "/test".to_string(), text: Some("hi".to_string()) },
3838+ Node::Text("hi there".to_string()),
3939+ Node::Blockquote("hi".to_string()),
4040+ ],);
7341 }
74427543 #[test]
7644 fn build_single_0th_from_vec() {
7777- assert_eq!(
7878- Ast::from_string("=> /test hi").inner(),
7979- &vec![Node::Link {
8080- to: "/test".to_string(),
8181- text: Some("hi".to_string()),
8282- }],
8383- );
4545+ assert_eq!(Ast::from_string("=> /test hi").inner(), &vec![Node::Link {
4646+ to: "/test".to_string(),
4747+ text: Some("hi".to_string()),
4848+ }],);
8449 }
85508651 #[test]