From 8bda4b1efad28227a2aea5ca95f8ef88cca07b49 Mon Sep 17 00:00:00 2001 From: Evie Viau Date: Tue, 11 Feb 2025 19:46:39 -0800 Subject: [PATCH] Compile IL to HTML PoC --- iresine-il/src/convert/html.rs | 42 ++++++++++++++++++++++++++++++ iresine-il/src/convert/markdown.rs | 30 ++++++++++++++++++--- iresine-il/src/convert/mod.rs | 3 ++- iresine-il/src/lib.rs | 29 +++++++++++++++++++-- iresine-il/src/nodes.rs | 13 +++++++++ 5 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 iresine-il/src/convert/html.rs diff --git a/iresine-il/src/convert/html.rs b/iresine-il/src/convert/html.rs new file mode 100644 index 0000000..88e728d --- /dev/null +++ b/iresine-il/src/convert/html.rs @@ -0,0 +1,42 @@ +use crate::nodes::{Document, Nodes}; +use crate::SUPPORTED_FORMAT_VERSION; + +fn build_html(node: &Nodes) -> String { + match node { + Nodes::Literal(node) => { + node.clone() + } + Nodes::Text(node) => { + format!("

{}

", node.value.iter().map(build_html).collect::()) + } + Nodes::Link(node) => { + format!("{}", node.url, node.value.iter().map(build_html).collect::()) + + } + Nodes::Image(node) => { + format!("", node.url) + } + Nodes::Header(node) => { + format!("{}", node.level, node.value.iter().map(build_html).collect::(), node.level) + } + Nodes::Divider => { + "
".to_string() + } + Nodes::Emphasis(node) => { + format!("{}", node.value.iter().map(build_html).collect::()) + } + Nodes::Strong(node) => { + format!("{}", node.value.iter().map(build_html).collect::()) + } + } +} + +impl Document { + pub fn to_html(&self) -> Result { + if self.version > SUPPORTED_FORMAT_VERSION { + return Err(anyhow::anyhow!("Unsupported version")); + } + + Ok(self.value.iter().map(build_html).collect::()) + } +} \ No newline at end of file diff --git a/iresine-il/src/convert/markdown.rs b/iresine-il/src/convert/markdown.rs index 4cf1aa8..76c1204 100644 --- a/iresine-il/src/convert/markdown.rs +++ b/iresine-il/src/convert/markdown.rs @@ -1,6 +1,6 @@ use anyhow::anyhow; use markdown::mdast::Node; -use crate::nodes::{Document, Header, Image, Link, Nodes, Text}; +use crate::nodes::{Document, Emphasis, Header, Image, Link, Nodes, Strong, Text}; use crate::SUPPORTED_FORMAT_VERSION; fn do_parse(input: &Node) -> Nodes { @@ -8,6 +8,9 @@ fn do_parse(input: &Node) -> Nodes { Node::Break(_) => { Nodes::Divider } + Node::ThematicBreak(_) => { + Nodes::Divider + } Node::Image(node) => { let node = node.clone(); @@ -40,8 +43,18 @@ fn do_parse(input: &Node) -> Nodes { value: vec![], }) } + Node::Emphasis(_) => { + Nodes::Emphasis(Emphasis { + value: vec![], + }) + } + Node::Strong(_) => { + Nodes::Strong(Strong { + value: vec![], + }) + } _ => { - Nodes::Literal(format!("{:#?}", input)) + Nodes::Literal(input.to_string()) } }; @@ -54,10 +67,13 @@ fn do_parse(input: &Node) -> Nodes { Nodes::Link(node) => { node.value.push(do_parse(i)) } - Nodes::Image(node) => { + Nodes::Header(node) => { node.value.push(do_parse(i)) } - Nodes::Header(node) => { + Nodes::Emphasis(node) => { + node.value.push(do_parse(i)) + } + Nodes::Strong(node) => { node.value.push(do_parse(i)) } _ => { @@ -83,4 +99,10 @@ pub fn from_markdown(value: &str) -> Result { } Ok(document) +} + +impl Document { + pub fn to_markdown(&self) -> Result { + todo!() + } } \ No newline at end of file diff --git a/iresine-il/src/convert/mod.rs b/iresine-il/src/convert/mod.rs index d7c69bb..acf25f1 100644 --- a/iresine-il/src/convert/mod.rs +++ b/iresine-il/src/convert/mod.rs @@ -1 +1,2 @@ -pub mod markdown; \ No newline at end of file +pub mod markdown; +pub mod html; \ No newline at end of file diff --git a/iresine-il/src/lib.rs b/iresine-il/src/lib.rs index c19402e..09f4c37 100644 --- a/iresine-il/src/lib.rs +++ b/iresine-il/src/lib.rs @@ -25,7 +25,32 @@ pub fn parse(value: &str) -> Result { #[cfg(test)] mod tests { use super::*; + + #[test] + fn markdown_to_html() { + let test_md = r#"# Hi! +This is a *test* of **[Markdown](https://en.wikipedia.org/wiki/Markdown)** to **[Iresine](https://forge.gaycatgirl.sex/evie/iresine) IL** and then to **[HTML](https://en.wikipedia.org/wiki/HTML)**. + +--- + +### free penguin pictures below! + +[![cool penguin image](https://upload.wikimedia.org/wikipedia/commons/b/be/SGI-2016-South_Georgia_%28Fortuna_Bay%29–King_penguin_%28Aptenodytes_patagonicus%29_04.jpg)](https://commons.wikimedia.org/wiki/File:SGI-2016-South_Georgia_(Fortuna_Bay)–King_penguin_(Aptenodytes_patagonicus)_04.jpg) + "#; + + let test_html = r#"

Hi!

This is a test of Markdown to Iresine IL and then to HTML.


free penguin pictures below!

"#; + + let result = convert::markdown::from_markdown(test_md); + + assert!(result.is_ok()); + + let html = result.unwrap().to_html(); + + assert!(html.is_ok()); + assert_eq!(test_html, html.unwrap()); + } + #[test] fn test_markdown_conversion() { let test_doc = Document { @@ -99,7 +124,7 @@ This is a test of [Markdown](https://en.wikipedia.org/wiki/Markdown) to [Iresine Nodes::Literal("Iresine".to_string()) ], }), - Nodes::Literal(" Markup Language.".to_string()) + Nodes::Literal(" IL.".to_string()) ], }) ], @@ -157,7 +182,7 @@ This is a test of [Markdown](https://en.wikipedia.org/wiki/Markdown) to [Iresine } }, { - "Literal": " Markup Language." + "Literal": " IL." } ] } diff --git a/iresine-il/src/nodes.rs b/iresine-il/src/nodes.rs index e0828be..d6cf5c9 100644 --- a/iresine-il/src/nodes.rs +++ b/iresine-il/src/nodes.rs @@ -4,6 +4,8 @@ use serde::{Deserialize, Serialize}; pub enum Nodes { Literal(String), Text(Text), + Emphasis(Emphasis), + Strong(Strong), Link(Link), Image(Image), Header(Header), @@ -14,6 +16,16 @@ pub struct Text { pub value: Vec } +#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)] +pub struct Emphasis { + pub value: Vec +} + +#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)] +pub struct Strong { + pub value: Vec +} + #[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)] pub struct Header { pub level: String, @@ -36,6 +48,7 @@ pub struct Link { pub value: Vec, } + #[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)] pub struct Document { pub version: u64,