From 138df11710454ef89363a1e4c948775217279ce2 Mon Sep 17 00:00:00 2001 From: Joakim Hulthe Date: Fri, 13 Jun 2025 22:08:53 +0200 Subject: [PATCH] wip --- Cargo.lock | 211 +++++++++++++++++++++++++++++++++++ Cargo.toml | 4 + build.rs | 6 + src/lib.rs | 1 + src/markdown/ast.rs | 54 +++++++++ src/markdown/grammar.lalrpop | 10 ++ src/markdown/mod.rs | 4 + src/markdown/span.rs | 42 +++++++ 8 files changed, 332 insertions(+) create mode 100644 build.rs create mode 100644 src/markdown/ast.rs create mode 100644 src/markdown/grammar.lalrpop create mode 100644 src/markdown/mod.rs create mode 100644 src/markdown/span.rs diff --git a/Cargo.lock b/Cargo.lock index 7b2cb7d..aed241c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -169,6 +169,15 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "ascii-canvas" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" +dependencies = [ + "term", +] + [[package]] name = "ash" version = "0.38.0+1.3.281" @@ -250,6 +259,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "block2" version = "0.5.1" @@ -496,6 +514,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.4.2" @@ -517,12 +544,32 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "cursor-icon" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -730,6 +777,12 @@ dependencies = [ "winit", ] +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "emath" version = "0.31.1" @@ -739,6 +792,15 @@ dependencies = [ "serde", ] +[[package]] +name = "ena" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +dependencies = [ + "log", +] + [[package]] name = "encode_unicode" version = "1.0.0" @@ -843,6 +905,12 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + [[package]] name = "flate2" version = "1.1.1" @@ -925,6 +993,16 @@ dependencies = [ "system-deps", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "gethostname" version = "0.4.3" @@ -1355,6 +1433,8 @@ dependencies = [ "getrandom 0.3.2", "half", "insta", + "lalrpop", + "lalrpop-util", "log", "rand", "rfd", @@ -1382,6 +1462,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "jiff" version = "0.2.10" @@ -1454,6 +1543,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + [[package]] name = "khronos-egl" version = "6.0.0" @@ -1471,6 +1569,38 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +[[package]] +name = "lalrpop" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" +dependencies = [ + "ascii-canvas", + "bit-set", + "ena", + "itertools", + "lalrpop-util", + "petgraph", + "pico-args", + "regex", + "regex-syntax", + "sha3", + "string_cache", + "term", + "unicode-xid", + "walkdir", +] + +[[package]] +name = "lalrpop-util" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" +dependencies = [ + "regex-automata", + "rustversion", +] + [[package]] name = "libc" version = "0.2.172" @@ -1651,6 +1781,12 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "nohash-hasher" version = "0.2.0" @@ -2047,6 +2183,31 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "petgraph" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project" version = "1.1.10" @@ -2131,6 +2292,12 @@ dependencies = [ "zerocopy 0.8.25", ] +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + [[package]] name = "proc-macro-crate" version = "3.3.0" @@ -2378,6 +2545,16 @@ dependencies = [ "serde", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2396,6 +2573,12 @@ version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + [[package]] name = "slab" version = "0.4.9" @@ -2486,6 +2669,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared", + "precomputed-hash", +] + [[package]] name = "strum" version = "0.26.3" @@ -2549,6 +2744,16 @@ version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +[[package]] +name = "term" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a984c8d058c627faaf5e8e2ed493fa3c51771889196de1016cf9c1c6e90d750" +dependencies = [ + "home", + "windows-sys 0.59.0", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -2684,6 +2889,12 @@ dependencies = [ "rustc-hash", ] +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + [[package]] name = "unicode-ident" version = "1.0.18" diff --git a/Cargo.toml b/Cargo.toml index d38fa8c..6b82bdf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ eyre = "0.6.12" half = "2.6.0" zerocopy = { version = "0.8.25", features = ["derive", "std"] } base64 = "0.22.1" +lalrpop-util = { version = "0.22.2", features = ["lexer"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] env_logger = "0.11.8" @@ -41,6 +42,9 @@ web-sys = "0.3.77" egui = { git = "https://github.com/emilk/egui", rev = "f2ce6424f3a32f47308fb9871d540c01377b2cd9" } eframe = { git = "https://github.com/emilk/egui", rev = "f2ce6424f3a32f47308fb9871d540c01377b2cd9" } +[build-dependencies] +lalrpop = "0.22.2" + [dev-dependencies] insta = { version = "1.43.1", features = ["yaml"] } # egui = { path = "../egui/crates/egui" } diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..8e2ef83 --- /dev/null +++ b/build.rs @@ -0,0 +1,6 @@ +fn main() { + lalrpop::Configuration::new() + .set_in_dir("./src/markdown") + .process() + .unwrap(); +} diff --git a/src/lib.rs b/src/lib.rs index 38ec018..5e29bd6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ pub mod constants; pub mod custom_code_block; pub mod easy_mark; pub mod file_editor; +pub mod markdown; pub mod painting; pub mod preferences; pub mod rasterizer; diff --git a/src/markdown/ast.rs b/src/markdown/ast.rs new file mode 100644 index 0000000..719d90f --- /dev/null +++ b/src/markdown/ast.rs @@ -0,0 +1,54 @@ +use super::span::Span; + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum Heading { + H1, + H2, + H3, + H4, + H5, + H6, +} + +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] +pub struct Style { + /// # heading (large text) + pub heading: Option, + + /// > quoted (slightly dimmer color or other font style) + pub quoted: bool, + + /// `code` (monospace, some other color) + pub code: bool, + + /// self.strong* (emphasized, e.g. bold) + pub strong: bool, + + /// _underline_ + pub underline: bool, + + /// ~strikethrough~ + pub strikethrough: bool, + + /// /italics/ + pub italics: bool, + + /// $small$ + pub small: bool, + + /// ^raised^ + pub raised: bool, +} + +pub enum MarkdownItem<'a> { + Text { + span: Span<'a>, + style: Style, + }, + + CodeBlock { + all: Span<'a>, + language: Span<'a>, + code: Span<'a>, + }, +} diff --git a/src/markdown/grammar.lalrpop b/src/markdown/grammar.lalrpop new file mode 100644 index 0000000..85e7d3f --- /dev/null +++ b/src/markdown/grammar.lalrpop @@ -0,0 +1,10 @@ +use std::str::FromStr; + +grammar; + +pub Term: i32 = { + => n, + "(" ")" => t, +}; + +Num: i32 = => i32::from_str(s).unwrap(); diff --git a/src/markdown/mod.rs b/src/markdown/mod.rs new file mode 100644 index 0000000..5c98f85 --- /dev/null +++ b/src/markdown/mod.rs @@ -0,0 +1,4 @@ +pub mod ast; +pub mod span; + +lalrpop_util::lalrpop_mod!(grammar); diff --git a/src/markdown/span.rs b/src/markdown/span.rs new file mode 100644 index 0000000..106fc2a --- /dev/null +++ b/src/markdown/span.rs @@ -0,0 +1,42 @@ +use std::ops::{Deref, Range}; + +#[derive(Clone, Eq, PartialEq)] +pub struct Span<'a> { + complete_str: &'a str, + range: Range, +} + +impl<'a> Span<'a> { + pub fn new(complete_str: &'a str) -> Self { + Self { + complete_str, + range: 0..complete_str.len(), + } + } + + pub fn get(&self, slice: Range) -> Option { + let start = self.range.start.checked_add(slice.start)?; + let end = self.range.start.checked_add(slice.end)?; + + if end > self.range.end || end < start { + return None; + } + + Some(Self { + complete_str: self.complete_str, + range: Range { start, end }, + }) + } + + pub fn complete_str(&self) -> Self { + Self::new(self.complete_str) + } +} + +impl Deref for Span<'_> { + type Target = str; + + fn deref(&self) -> &Self::Target { + &self.complete_str[self.range.clone()] + } +}