Init work on IL for content

Add parsing from a String and converting from Markdown
This commit is contained in:
Evie Viau-Chow-Stuart 2025-02-11 02:17:04 -08:00
parent 2eea1c7f08
commit c6e47572ac
Signed by: evie
GPG key ID: 928652CDFCEC8099
17 changed files with 512 additions and 3 deletions

9
.idea/iresine.iml generated
View file

@ -1,7 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/iresine-ap/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/iresine-cli/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/iresine-common/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/iresine-il/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/iresine/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>

135
Cargo.lock generated Normal file
View file

@ -0,0 +1,135 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "anyhow"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
[[package]]
name = "iresine"
version = "0.1.0"
[[package]]
name = "iresine-ap"
version = "0.1.0"
[[package]]
name = "iresine-cli"
version = "0.1.0"
[[package]]
name = "iresine-common"
version = "0.1.0"
[[package]]
name = "iresine-il"
version = "0.1.0"
dependencies = [
"anyhow",
"markdown",
"serde",
"serde_json",
]
[[package]]
name = "itoa"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
[[package]]
name = "markdown"
version = "1.0.0-alpha.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "790c11786cb51d02938e3eb38276575e1658b1dd8555875f5788a40670a33934"
dependencies = [
"unicode-id",
]
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "proc-macro2"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ryu"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
[[package]]
name = "serde"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "2.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-id"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10103c57044730945224467c09f71a4db0071c123a0648cc3e818913bde6b561"
[[package]]
name = "unicode-ident"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"

View file

@ -1,2 +1,3 @@
[workspace]
resolver = "2"
resolver = "2"
members = [ "iresine", "iresine-ap", "iresine-cli","iresine-common" , "iresine-il"]

View file

@ -1 +1 @@
# Iresine
# Iresine

6
iresine-ap/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "iresine-ap"
version = "0.1.0"
edition = "2021"
[dependencies]

3
iresine-ap/src/main.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

6
iresine-cli/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "iresine-cli"
version = "0.1.0"
edition = "2021"
[dependencies]

3
iresine-cli/src/main.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

View file

@ -0,0 +1,6 @@
[package]
name = "iresine-common"
version = "0.1.0"
edition = "2021"
[dependencies]

14
iresine-common/src/lib.rs Normal file
View file

@ -0,0 +1,14 @@
pub fn add(left: u64, right: u64) -> u64 {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}

14
iresine-il/Cargo.toml Normal file
View file

@ -0,0 +1,14 @@
[package]
name = "iresine-il"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1.0.217", features = ["derive"] }
serde_json = "1.0.138"
anyhow = "1.0.95"
markdown = "1.0.0-alpha.22"
[dev-dependencies]

View file

@ -0,0 +1,86 @@
use anyhow::anyhow;
use markdown::mdast::Node;
use crate::nodes::{Document, Header, Image, Link, Nodes, Text};
use crate::SUPPORTED_FORMAT_VERSION;
fn do_parse(input: &Node) -> Nodes {
let mut il_node: Nodes = match input {
Node::Break(_) => {
Nodes::Divider
}
Node::Image(node) => {
let node = node.clone();
Nodes::Image(Image {
url: node.url,
alt: Some(node.alt),
blur_hash: None,
width: None,
height: None,
value: vec![],
})
}
Node::Link(node) => {
Nodes::Link(Link {
url: node.clone().url,
value: vec![],
})
}
Node::Text(node) => {
Nodes::Literal(node.clone().value)
}
Node::Heading(node) => {
Nodes::Header(Header {
level: node.depth.to_string(),
value: vec![],
})
}
Node::Paragraph(_) => {
Nodes::Text(Text {
value: vec![],
})
}
_ => {
Nodes::Literal(format!("{:#?}", input))
}
};
if let Some(children) = input.children() {
for i in children {
match &mut il_node {
Nodes::Text(node) => {
node.value.push(do_parse(i))
}
Nodes::Link(node) => {
node.value.push(do_parse(i))
}
Nodes::Image(node) => {
node.value.push(do_parse(i))
}
Nodes::Header(node) => {
node.value.push(do_parse(i))
}
_ => {
eprintln!("Cannot have children?")
}
}
}
}
il_node
}
pub fn from_markdown(value: &str) -> Result<Document, anyhow::Error> {
let root = markdown::to_mdast(value, &markdown::ParseOptions::default()).expect("MDX?");
let mut document = Document {
version: SUPPORTED_FORMAT_VERSION,
value: vec![],
};
for i in root.children().ok_or(anyhow!("Empty?"))? {
document.value.push(do_parse(i));
}
Ok(document)
}

View file

@ -0,0 +1 @@
pub mod markdown;

175
iresine-il/src/lib.rs Normal file
View file

@ -0,0 +1,175 @@
use crate::nodes::{Document, Header, Image, Nodes, Text, Link};
pub mod nodes;
pub mod convert;
static SUPPORTED_FORMAT_VERSION: u64 = 0;
pub fn parse(value: &str) -> Result<Document, anyhow::Error> {
let res: Result<Document, serde_json::Error> = serde_json::from_str(value);
match res {
Ok(res) => {
if res.version > SUPPORTED_FORMAT_VERSION {
Err(anyhow::anyhow!("Unsupported document version: {}", res.version))
} else {
Ok(res)
}
}
Err(res) => {
Err(anyhow::Error::from(res))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_markdown_conversion() {
let test_doc = Document {
version: 0,
value: vec![
Nodes::Header(Header {
level: "1".to_string(),
value: vec![Nodes::Literal("Hi!".to_string())],
}),
Nodes::Text(Text {
value: vec![
Nodes::Literal("This is a test of ".to_string()),
Nodes::Link(Link {
url: "https://en.wikipedia.org/wiki/Markdown".to_string(),
value: vec![
Nodes::Literal("Markdown".to_string())
],
}),
Nodes::Literal(" to ".to_string()),
Nodes::Link(Link {
url: "https://forge.gaycatgirl.sex/evie/iresine".to_string(),
value: vec![
Nodes::Literal("Iresine".to_string())
],
}),
Nodes::Literal(" IL.".to_string())
],
})
],
};
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.
"#;
let result = convert::markdown::from_markdown(test_md);
assert!(result.is_ok());
assert_eq!(test_doc, result.unwrap());
}
#[test]
fn test_string_parse() {
let test_doc = Document {
version: 0,
value: vec![
Nodes::Header(Header {
level: "1".to_string(),
value: vec![Nodes::Literal("Hi!".to_string())],
}),
Nodes::Image(Image {
url: "https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png".to_string(),
alt: Some("Example Image".to_string()),
blur_hash: Some("L6R{-$oI^bx@O_WB?DtSm$ozafV@".to_string()),
width: None,
height: None,
value: vec![
Nodes::Text(Text {
value: vec![Nodes::Literal("Hello, world!".to_string())],
})
],
}),
Nodes::Divider,
Nodes::Text(Text {
value: vec![
Nodes::Literal("This is a test of the ".to_string()),
Nodes::Link(Link {
url: "https://forge.gaycatgirl.sex/evie/iresine".to_string(),
value: vec![
Nodes::Literal("Iresine".to_string())
],
}),
Nodes::Literal(" Markup Language.".to_string())
],
})
],
};
let test_str = r#"
{
"version": 0,
"value": [
{
"Header": {
"level": "1",
"value": [
{
"Literal": "Hi!"
}
]
}
},
{
"Image": {
"url": "https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png",
"alt": "Example Image",
"blur_hash": "L6R{-$oI^bx@O_WB?DtSm$ozafV@",
"width": null,
"height": null,
"value": [
{
"Text": {
"value": [
{
"Literal": "Hello, world!"
}
]
}
}
]
}
},
"Divider",
{
"Text": {
"value": [
{
"Literal": "This is a test of the "
},
{
"Link": {
"url": "https://forge.gaycatgirl.sex/evie/iresine",
"value": [
{
"Literal": "Iresine"
}
]
}
},
{
"Literal": " Markup Language."
}
]
}
}
]
}
"#;
let result: Result<Document, anyhow::Error> = parse(test_str);
assert!(result.is_ok());
assert_eq!(test_doc, result.unwrap());
}
}

43
iresine-il/src/nodes.rs Normal file
View file

@ -0,0 +1,43 @@
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub enum Nodes {
Literal(String),
Text(Text),
Link(Link),
Image(Image),
Header(Header),
Divider,
}
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
pub struct Text {
pub value: Vec<Nodes>
}
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
pub struct Header {
pub level: String,
pub value: Vec<Nodes>
}
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
pub struct Image {
pub url: String,
pub alt: Option<String>,
pub blur_hash: Option<String>,
pub width: Option<u64>,
pub height: Option<u64>,
pub value: Vec<Nodes>,
}
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
pub struct Link {
pub url: String,
pub value: Vec<Nodes>,
}
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
pub struct Document {
pub version: u64,
pub value: Vec<Nodes>
}

6
iresine/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "iresine"
version = "0.1.0"
edition = "2021"
[dependencies]

3
iresine/src/main.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}