Compile IL to HTML PoC

This commit is contained in:
Evie Viau-Chow-Stuart 2025-02-11 19:46:39 -08:00
parent c6e47572ac
commit 8bda4b1efa
Signed by: evie
GPG key ID: 928652CDFCEC8099
5 changed files with 110 additions and 7 deletions

View file

@ -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!("<p>{}</p>", node.value.iter().map(build_html).collect::<String>())
}
Nodes::Link(node) => {
format!("<a href=\"{}\">{}</a>", node.url, node.value.iter().map(build_html).collect::<String>())
}
Nodes::Image(node) => {
format!("<img src=\"{}\" />", node.url)
}
Nodes::Header(node) => {
format!("<h{}>{}</h{}>", node.level, node.value.iter().map(build_html).collect::<String>(), node.level)
}
Nodes::Divider => {
"<hr />".to_string()
}
Nodes::Emphasis(node) => {
format!("<em>{}</em>", node.value.iter().map(build_html).collect::<String>())
}
Nodes::Strong(node) => {
format!("<strong>{}</strong>", node.value.iter().map(build_html).collect::<String>())
}
}
}
impl Document {
pub fn to_html(&self) -> Result<String, anyhow::Error> {
if self.version > SUPPORTED_FORMAT_VERSION {
return Err(anyhow::anyhow!("Unsupported version"));
}
Ok(self.value.iter().map(build_html).collect::<String>())
}
}

View file

@ -1,6 +1,6 @@
use anyhow::anyhow; use anyhow::anyhow;
use markdown::mdast::Node; 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; use crate::SUPPORTED_FORMAT_VERSION;
fn do_parse(input: &Node) -> Nodes { fn do_parse(input: &Node) -> Nodes {
@ -8,6 +8,9 @@ fn do_parse(input: &Node) -> Nodes {
Node::Break(_) => { Node::Break(_) => {
Nodes::Divider Nodes::Divider
} }
Node::ThematicBreak(_) => {
Nodes::Divider
}
Node::Image(node) => { Node::Image(node) => {
let node = node.clone(); let node = node.clone();
@ -40,8 +43,18 @@ fn do_parse(input: &Node) -> Nodes {
value: vec![], 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) => { Nodes::Link(node) => {
node.value.push(do_parse(i)) node.value.push(do_parse(i))
} }
Nodes::Image(node) => { Nodes::Header(node) => {
node.value.push(do_parse(i)) 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)) node.value.push(do_parse(i))
} }
_ => { _ => {
@ -83,4 +99,10 @@ pub fn from_markdown(value: &str) -> Result<Document, anyhow::Error> {
} }
Ok(document) Ok(document)
}
impl Document {
pub fn to_markdown(&self) -> Result<Document, anyhow::Error> {
todo!()
}
} }

View file

@ -1 +1,2 @@
pub mod markdown; pub mod markdown;
pub mod html;

View file

@ -25,7 +25,32 @@ pub fn parse(value: &str) -> Result<Document, anyhow::Error> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; 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%29King_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#"<h1>Hi!</h1><p>This is a <em>test</em> of <strong><a href="https://en.wikipedia.org/wiki/Markdown">Markdown</a></strong> to <strong><a href="https://forge.gaycatgirl.sex/evie/iresine">Iresine</a> IL</strong> and then to <strong><a href="https://en.wikipedia.org/wiki/HTML">HTML</a></strong>.</p><hr /><h3>free penguin pictures below!</h3><p><a href="https://commons.wikimedia.org/wiki/File:SGI-2016-South_Georgia_(Fortuna_Bay)King_penguin_(Aptenodytes_patagonicus)_04.jpg"><img src="https://upload.wikimedia.org/wikipedia/commons/b/be/SGI-2016-South_Georgia_%28Fortuna_Bay%29King_penguin_%28Aptenodytes_patagonicus%29_04.jpg" /></a></p>"#;
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] #[test]
fn test_markdown_conversion() { fn test_markdown_conversion() {
let test_doc = Document { 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("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."
} }
] ]
} }

View file

@ -4,6 +4,8 @@ use serde::{Deserialize, Serialize};
pub enum Nodes { pub enum Nodes {
Literal(String), Literal(String),
Text(Text), Text(Text),
Emphasis(Emphasis),
Strong(Strong),
Link(Link), Link(Link),
Image(Image), Image(Image),
Header(Header), Header(Header),
@ -14,6 +16,16 @@ pub struct Text {
pub value: Vec<Nodes> pub value: Vec<Nodes>
} }
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
pub struct Emphasis {
pub value: Vec<Nodes>
}
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
pub struct Strong {
pub value: Vec<Nodes>
}
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
pub struct Header { pub struct Header {
pub level: String, pub level: String,
@ -36,6 +48,7 @@ pub struct Link {
pub value: Vec<Nodes>, pub value: Vec<Nodes>,
} }
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
pub struct Document { pub struct Document {
pub version: u64, pub version: u64,