basic svg output

This commit is contained in:
Jack
2023-08-25 19:14:55 +01:00
parent dbea4342b1
commit 05b1a9a9a0
8 changed files with 340 additions and 188 deletions

283
compiler/Cargo.lock generated
View File

@ -10,9 +10,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "1.0.2" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -115,9 +115,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.3.3" version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
dependencies = [ dependencies = [
"serde", "serde",
] ]
@ -142,9 +142,12 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.79" version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@ -308,6 +311,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d7439c3735f405729d52c3fbbe4de140eaf938a1fe47d227c27f8254d4302a5" checksum = "8d7439c3735f405729d52c3fbbe4de140eaf938a1fe47d227c27f8254d4302a5"
[[package]]
name = "deranged"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
[[package]] [[package]]
name = "displaydoc" name = "displaydoc"
version = "0.2.4" version = "0.2.4"
@ -316,14 +325,20 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.29",
] ]
[[package]] [[package]]
name = "ecow" name = "downcast-rs"
version = "0.1.1" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5c5051925c54d9a42c8652313b5358a7432eed209466b443ed5220431243a14" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]]
name = "ecow"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d1990d053cf6edf3f030682dba3b0eb65ef01fabb2686072765d8a17d6728e8"
dependencies = [ dependencies = [
"serde", "serde",
] ]
@ -344,14 +359,14 @@ dependencies = [
"num-traits", "num-traits",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.29",
] ]
[[package]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.0" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]] [[package]]
name = "exr" name = "exr"
@ -371,9 +386,9 @@ dependencies = [
[[package]] [[package]]
name = "fancy-regex" name = "fancy-regex"
version = "0.7.1" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6b8560a05112eb52f04b00e5d3790c0dd75d9d980eb8a122fb23b92a623ccf" checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2"
dependencies = [ dependencies = [
"bit-set", "bit-set",
"regex", "regex",
@ -400,9 +415,9 @@ dependencies = [
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.26" version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"miniz_oxide", "miniz_oxide",
@ -679,9 +694,9 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
[[package]] [[package]]
name = "image" name = "image"
version = "0.24.6" version = "0.24.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"byteorder", "byteorder",
@ -723,6 +738,18 @@ dependencies = [
"hashbrown 0.14.0", "hashbrown 0.14.0",
] ]
[[package]]
name = "indexmap-nostd"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590"
[[package]]
name = "intx"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f38a50a899dc47a6d0ed5508e7f601a2e34c3a85303514b5d137f3c10a0c75"
[[package]] [[package]]
name = "isolang" name = "isolang"
version = "2.3.0" version = "2.3.0"
@ -734,9 +761,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.8" version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]] [[package]]
name = "jpeg-decoder" name = "jpeg-decoder"
@ -832,9 +859,9 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.19" version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]] [[package]]
name = "memchr" name = "memchr"
@ -881,9 +908,9 @@ dependencies = [
[[package]] [[package]]
name = "num-bigint" name = "num-bigint"
version = "0.4.3" version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"num-integer", "num-integer",
@ -913,9 +940,9 @@ dependencies = [
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.15" version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"libm", "libm",
@ -972,9 +999,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]] [[package]]
name = "paste" name = "paste"
version = "1.0.13" version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]] [[package]]
name = "pdf-writer" name = "pdf-writer"
@ -1034,14 +1061,14 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.29",
] ]
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.10" version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05"
[[package]] [[package]]
name = "pixglyph" name = "pixglyph"
@ -1068,9 +1095,9 @@ dependencies = [
[[package]] [[package]]
name = "png" name = "png"
version = "0.17.9" version = "0.17.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
"crc32fast", "crc32fast",
@ -1081,9 +1108,9 @@ dependencies = [
[[package]] [[package]]
name = "postcard" name = "postcard"
version = "1.0.4" version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfa512cd0d087cc9f99ad30a1bf64795b67871edbead083ffc3a4dfafa59aa00" checksum = "c9ee729232311d3cd113749948b689627618133b1c5012b77342c1950b25eaeb"
dependencies = [ dependencies = [
"cobs", "cobs",
"serde", "serde",
@ -1097,9 +1124,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.63" version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -1133,9 +1160,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.29" version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -1195,26 +1222,32 @@ checksum = "3b42e27ef78c35d3998403c1d26f3efd9e135d3e5121b0a4845cc5cc27547f4f"
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.8.4" version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
"regex-syntax 0.7.2", "regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
] ]
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.6.29" version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
[[package]]
name = "regex-syntax"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
[[package]] [[package]]
name = "resvg" name = "resvg"
@ -1266,9 +1299,9 @@ dependencies = [
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.13" version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]] [[package]]
name = "rustybuzz" name = "rustybuzz"
@ -1288,9 +1321,9 @@ dependencies = [
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.14" version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]] [[package]]
name = "safemem" name = "safemem"
@ -1315,9 +1348,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.166" version = "1.0.186"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8" checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
@ -1335,20 +1368,20 @@ dependencies = [
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.166" version = "1.0.186"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6" checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.29",
] ]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.99" version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@ -1378,9 +1411,9 @@ dependencies = [
[[package]] [[package]]
name = "simd-adler32" name = "simd-adler32"
version = "0.3.5" version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]] [[package]]
name = "simplecss" name = "simplecss"
@ -1393,9 +1426,9 @@ dependencies = [
[[package]] [[package]]
name = "siphasher" name = "siphasher"
version = "0.3.10" version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
[[package]] [[package]]
name = "slotmap" name = "slotmap"
@ -1408,9 +1441,9 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.10.0" version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]] [[package]]
name = "spin" name = "spin"
@ -1512,9 +1545,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.23" version = "2.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1535,21 +1568,19 @@ dependencies = [
[[package]] [[package]]
name = "syntect" name = "syntect"
version = "5.0.0" version = "5.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6c454c27d9d7d9a84c7803aaa3c50cd088d2906fe3c6e42da3209aa623576a8" checksum = "e02b4b303bf8d08bfeb0445cba5068a3d306b6baece1d5582171a9bf49188f91"
dependencies = [ dependencies = [
"bincode", "bincode",
"bitflags 1.3.2", "bitflags 1.3.2",
"fancy-regex", "fancy-regex",
"flate2", "flate2",
"fnv", "fnv",
"lazy_static",
"once_cell", "once_cell",
"plist", "plist",
"regex-syntax 0.6.29", "regex-syntax",
"serde", "serde",
"serde_derive",
"serde_json", "serde_json",
"thiserror", "thiserror",
"walkdir", "walkdir",
@ -1558,29 +1589,29 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.40" version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.40" version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.29",
] ]
[[package]] [[package]]
name = "tiff" name = "tiff"
version = "0.8.1" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211"
dependencies = [ dependencies = [
"flate2", "flate2",
"jpeg-decoder", "jpeg-decoder",
@ -1589,10 +1620,11 @@ dependencies = [
[[package]] [[package]]
name = "time" name = "time"
version = "0.3.22" version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" checksum = "0bb39ee79a6d8de55f48f2293a830e040392f1c5f16e336bdd1788cd0aadce07"
dependencies = [ dependencies = [
"deranged",
"itoa", "itoa",
"serde", "serde",
"time-core", "time-core",
@ -1607,9 +1639,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
[[package]] [[package]]
name = "time-macros" name = "time-macros"
version = "0.2.9" version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" checksum = "733d258752e9303d392b94b75230d07b0b9c489350c69b851fc6c065fde3e8f9"
dependencies = [ dependencies = [
"time-core", "time-core",
] ]
@ -1668,9 +1700,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.7.5" version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240" checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542"
dependencies = [ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned",
@ -1689,9 +1721,9 @@ dependencies = [
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.19.11" version = "0.19.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7" checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
dependencies = [ dependencies = [
"indexmap 2.0.0", "indexmap 2.0.0",
"serde", "serde",
@ -1720,7 +1752,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.29",
] ]
[[package]] [[package]]
@ -1747,9 +1779,10 @@ checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
[[package]] [[package]]
name = "typst" name = "typst"
version = "0.7.0" version = "0.7.0"
source = "git+https://github.com/typst/typst.git?tag=v0.7.0#da8367e189b02918a8fe1a98fd3059fd11a82cd9" source = "git+https://github.com/typst/typst.git?rev=522708b#522708b9df0b9b2f8265938aa1f0aeda8e6e6c1f"
dependencies = [ dependencies = [
"bitflags 2.3.3", "base64",
"bitflags 2.4.0",
"bytemuck", "bytemuck",
"comemo", "comemo",
"ecow", "ecow",
@ -1786,13 +1819,16 @@ dependencies = [
"unicode-segmentation", "unicode-segmentation",
"unscanny", "unscanny",
"usvg", "usvg",
"wasmi",
"xmlparser",
"xmlwriter",
"xmp-writer", "xmp-writer",
] ]
[[package]] [[package]]
name = "typst-library" name = "typst-library"
version = "0.7.0" version = "0.7.0"
source = "git+https://github.com/typst/typst.git?tag=v0.7.0#da8367e189b02918a8fe1a98fd3059fd11a82cd9" source = "git+https://github.com/typst/typst.git?rev=522708b#522708b9df0b9b2f8265938aa1f0aeda8e6e6c1f"
dependencies = [ dependencies = [
"az", "az",
"chinese-number", "chinese-number",
@ -1831,18 +1867,18 @@ dependencies = [
[[package]] [[package]]
name = "typst-macros" name = "typst-macros"
version = "0.7.0" version = "0.7.0"
source = "git+https://github.com/typst/typst.git?tag=v0.7.0#da8367e189b02918a8fe1a98fd3059fd11a82cd9" source = "git+https://github.com/typst/typst.git?rev=522708b#522708b9df0b9b2f8265938aa1f0aeda8e6e6c1f"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.29",
] ]
[[package]] [[package]]
name = "typst-syntax" name = "typst-syntax"
version = "0.7.0" version = "0.7.0"
source = "git+https://github.com/typst/typst.git?tag=v0.7.0#da8367e189b02918a8fe1a98fd3059fd11a82cd9" source = "git+https://github.com/typst/typst.git?rev=522708b#522708b9df0b9b2f8265938aa1f0aeda8e6e6c1f"
dependencies = [ dependencies = [
"comemo", "comemo",
"ecow", "ecow",
@ -1899,9 +1935,9 @@ checksum = "2281c8c1d221438e373249e065ca4989c4c36952c211ff21a0ee91c44a3869e7"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.10" version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]] [[package]]
name = "unicode-math-class" name = "unicode-math-class"
@ -2074,7 +2110,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.29",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -2108,7 +2144,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.29",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -2119,6 +2155,47 @@ version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
[[package]]
name = "wasmi"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51fb5c61993e71158abf5bb863df2674ca3ec39ed6471c64f07aeaf751d67b4"
dependencies = [
"intx",
"smallvec",
"spin",
"wasmi_arena",
"wasmi_core",
"wasmparser-nostd",
]
[[package]]
name = "wasmi_arena"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "401c1f35e413fac1846d4843745589d9ec678977ab35a384db8ae7830525d468"
[[package]]
name = "wasmi_core"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624e6333e861ef49095d2d678b76ebf30b06bf37effca845be7e5b87c90071b7"
dependencies = [
"downcast-rs",
"libm",
"num-traits",
"paste",
]
[[package]]
name = "wasmparser-nostd"
version = "0.100.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9157cab83003221bfd385833ab587a039f5d6fa7304854042ba358a3b09e0724"
dependencies = [
"indexmap-nostd",
]
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.64" version = "0.3.64"
@ -2168,9 +2245,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.4.7" version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]

View File

@ -12,8 +12,8 @@ crate-type = ["cdylib"]
[dependencies] [dependencies]
# Everything to do with Typst # Everything to do with Typst
typst = { git = "https://github.com/typst/typst.git", tag = "v0.7.0" } typst = { git = "https://github.com/typst/typst.git", rev = "522708b" }
typst-library = { git = "https://github.com/typst/typst.git", tag = "v0.7.0" } typst-library = { git = "https://github.com/typst/typst.git", rev = "522708b" }
comemo = "0.3" comemo = "0.3"
@ -21,7 +21,7 @@ comemo = "0.3"
wasm-bindgen = "^0.2" wasm-bindgen = "^0.2"
js-sys = "^0.3" js-sys = "^0.3"
wasm-bindgen-futures = "^0.4" wasm-bindgen-futures = "^0.4"
serde = { version = "^1.0", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde-wasm-bindgen = "^0.5" serde-wasm-bindgen = "^0.5"
web-sys = { version = "^0.3", features = [ web-sys = { version = "^0.3", features = [
"console", "console",

View File

@ -7,7 +7,8 @@ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
use typst::{ use typst::{
diag::{EcoString, FileError, FileResult, PackageError, PackageResult}, diag::{FileError, FileResult, PackageError, PackageResult},
doc::Document,
eval::{Bytes, Datetime, Library, Tracer}, eval::{Bytes, Datetime, Library, Tracer},
font::{Font, FontBook}, font::{Font, FontBook},
syntax::Source, syntax::Source,
@ -71,9 +72,8 @@ impl SystemWorld {
} }
} }
pub fn compile( pub fn compile_image(
&mut self, &mut self,
// command: CompileCommand,
text: String, text: String,
path: String, path: String,
pixel_per_pt: f32, pixel_per_pt: f32,
@ -81,27 +81,32 @@ impl SystemWorld {
size: u32, size: u32,
display: bool, display: bool,
) -> Result<ImageData, JsValue> { ) -> Result<ImageData, JsValue> {
let document = self.compile(text, path)?;
render::to_image(
&mut self.resizer,
document,
fill,
pixel_per_pt,
size,
display,
)
}
pub fn compile_svg(&mut self, text: String, path: String) -> Result<String, JsValue> {
self.compile(text, path)
.map(|document| render::to_svg(document))
}
fn compile(&mut self, text: String, path: String) -> Result<Document, JsValue> {
self.reset(); self.reset();
self.main = FileId::new(None, &PathBuf::from(&path)); self.main = FileId::new(None, &PathBuf::from(&path));
self.files.borrow_mut().insert( self.files
self.main, .borrow_mut()
FileEntry::new(self.main, text), // bytes: OnceCell::new(), .insert(self.main, FileEntry::new(self.main, text));
// source: Source::new(self.main, text),
// },
);
let mut tracer = Tracer::default(); let mut tracer = Tracer::default();
match typst::compile(self, &mut tracer) { typst::compile(self, &mut tracer)
Ok(document) => render::to_image( .map_err(|errors| format_diagnostic(self.files.borrow(), &errors).into())
&mut self.resizer,
document,
fill,
pixel_per_pt,
size,
display,
),
Err(errors) => Err(format_diagnostic(self.files.borrow(), &errors).into()),
}
} }
pub fn add_font(&mut self, data: Vec<u8>) { pub fn add_font(&mut self, data: Vec<u8>) {

View File

@ -1,7 +1,6 @@
use std::{cell::Ref, collections::HashMap, num::NonZeroU32, str::FromStr}; use std::{cell::Ref, collections::HashMap, num::NonZeroU32, str::FromStr};
use ariadne::{Cache, Config, Fmt, FnCache, Label, Report, ReportKind, Source}; use ariadne::{Config, FnCache, Label, Report, ReportKind};
// use ariadne::{Report, ReportKind};
use fast_image_resize as fr; use fast_image_resize as fr;
use fr::Resizer; use fr::Resizer;
use typst::{ use typst::{
@ -11,7 +10,7 @@ use typst::{
syntax::FileId, syntax::FileId,
}; };
use wasm_bindgen::Clamped; use wasm_bindgen::Clamped;
use web_sys::{console, ImageData}; use web_sys::ImageData;
use crate::file_entry::FileEntry; use crate::file_entry::FileEntry;
@ -76,6 +75,10 @@ pub fn to_image(
); );
} }
pub fn to_svg(document: Document) -> String {
typst::export::svg(&document.pages[0])
}
pub fn format_diagnostic( pub fn format_diagnostic(
sources: Ref<HashMap<FileId, FileEntry>>, sources: Ref<HashMap<FileId, FileEntry>>,
diagnostics: &[SourceDiagnostic], diagnostics: &[SourceDiagnostic],

View File

@ -3,7 +3,7 @@ import wasmBin from '../pkg/obsidian_typst_bg.wasm'
import * as typst from '../pkg' import * as typst from '../pkg'
import { CompileCommand } from "src/types"; import { CompileImageCommand, CompileSvgCommand } from "src/types";
typst.initSync(wasmBin); typst.initSync(wasmBin);
@ -29,14 +29,18 @@ function requestData(path: string): string {
const compiler = new typst.SystemWorld("", requestData) const compiler = new typst.SystemWorld("", requestData)
onmessage = (ev: MessageEvent<CompileCommand | true>) => { onmessage = (ev: MessageEvent<CompileImageCommand | CompileSvgCommand | true>) => {
if (ev.data == true) { if (ev.data == true) {
canUseSharedArrayBuffer = ev.data canUseSharedArrayBuffer = ev.data
} else if (ev.data instanceof Array) { } else if (ev.data instanceof Array) {
ev.data.forEach(font => compiler.add_font(new Uint8Array(font))) ev.data.forEach(font => compiler.add_font(new Uint8Array(font)))
} else if ("source" in ev.data) { } else if ("format" in ev.data) {
const data: CompileCommand = ev.data; if (ev.data.format == "image") {
postMessage(compiler.compile(data.source, data.path, data.pixel_per_pt, data.fill, data.size, data.display)) const data: CompileImageCommand = ev.data;
postMessage(compiler.compile_image(data.source, data.path, data.pixel_per_pt, data.fill, data.size, data.display))
} else if (ev.data.format == "svg") {
postMessage(compiler.compile_svg(ev.data.source, ev.data.path))
}
// postMessage(compile(ev.data)) // postMessage(compile(ev.data))
} else { } else {

View File

@ -3,10 +3,11 @@ import { App, renderMath, HexString, Platform, Plugin, PluginSettingTab, Setting
// @ts-ignore // @ts-ignore
import CompilerWorker from "./compiler.worker.ts" import CompilerWorker from "./compiler.worker.ts"
import TypstCanvasElement from './typst-canvas-element'; import TypstRenderElement from './typst-render-element.js';
import { WorkerRequest } from './types'; import { WorkerRequest } from './types';
interface TypstPluginSettings { interface TypstPluginSettings {
format: string,
noFill: boolean, noFill: boolean,
fill: HexString, fill: HexString,
pixel_per_pt: number, pixel_per_pt: number,
@ -21,6 +22,7 @@ interface TypstPluginSettings {
} }
const DEFAULT_SETTINGS: TypstPluginSettings = { const DEFAULT_SETTINGS: TypstPluginSettings = {
format: "image",
noFill: true, noFill: true,
fill: "#ffffff", fill: "#ffffff",
pixel_per_pt: 3, pixel_per_pt: 3,
@ -66,9 +68,9 @@ export default class TypstPlugin extends Plugin {
this.compilerWorker.postMessage(fonts, fonts) this.compilerWorker.postMessage(fonts, fonts)
// Setup cutom canvas // Setup cutom canvas
TypstCanvasElement.compile = (a, b, c, d, e) => this.processThenCompileTypst(a, b, c, d, e) TypstRenderElement.compile = (a, b, c, d, e) => this.processThenCompileTypst(a, b, c, d, e)
if (customElements.get("typst-renderer") == undefined) { if (customElements.get("typst-renderer") == undefined) {
customElements.define("typst-renderer", TypstCanvasElement, { extends: "canvas" }) customElements.define("typst-renderer", TypstRenderElement)
} }
// Setup MathJax // Setup MathJax
@ -89,7 +91,7 @@ export default class TypstPlugin extends Plugin {
// Code blocks // Code blocks
this.registerMarkdownCodeBlockProcessor("typst", async (source, el, ctx) => { this.registerMarkdownCodeBlockProcessor("typst", async (source, el, ctx) => {
el.appendChild(this.createTypstCanvas("/" + ctx.sourcePath, `${this.settings.preamable.code}\n${source}`, true, false)) el.appendChild(this.createTypstRenderElement("/" + ctx.sourcePath, `${this.settings.preamable.code}\n${source}`, true, false))
}) })
@ -99,16 +101,25 @@ export default class TypstPlugin extends Plugin {
async compileToTypst(path: string, source: string, size: number, display: boolean): Promise<ImageData> { async compileToTypst(path: string, source: string, size: number, display: boolean): Promise<ImageData> {
return await navigator.locks.request("typst renderer compiler", async (lock) => { return await navigator.locks.request("typst renderer compiler", async (lock) => {
this.compilerWorker.postMessage({ if (this.settings.format == "svg") {
source, this.compilerWorker.postMessage({
path, format: "svg",
pixel_per_pt: this.settings.pixel_per_pt, path,
fill: `${this.settings.fill}${this.settings.noFill ? "00" : "ff"}`, source
size, })
display } else if (this.settings.format == "image") {
}); this.compilerWorker.postMessage({
format: "image",
source,
path,
pixel_per_pt: this.settings.pixel_per_pt,
fill: `${this.settings.fill}${this.settings.noFill ? "00" : "ff"}`,
size,
display
});
}
while (true) { while (true) {
let result: ImageData | WorkerRequest = await new Promise((resolve, reject) => { let result: ImageData | string | WorkerRequest = await new Promise((resolve, reject) => {
const listener = (ev: MessageEvent<ImageData>) => { const listener = (ev: MessageEvent<ImageData>) => {
remove(); remove();
resolve(ev.data); resolve(ev.data);
@ -125,7 +136,7 @@ export default class TypstPlugin extends Plugin {
this.compilerWorker.addEventListener("error", errorListener); this.compilerWorker.addEventListener("error", errorListener);
}) })
if (result instanceof ImageData) { if (result instanceof ImageData || typeof result == "string") {
return result return result
} }
// Cannot reach this point when in mobile app as the worker should // Cannot reach this point when in mobile app as the worker should
@ -143,8 +154,6 @@ export default class TypstPlugin extends Plugin {
: this.getFileString(path) : this.getFileString(path)
); );
if (s) { if (s) {
let buffer = Int32Array.from(this.textEncoder.encode( let buffer = Int32Array.from(this.textEncoder.encode(
s s
)); ));
@ -231,20 +240,21 @@ export default class TypstPlugin extends Plugin {
) )
} }
createTypstCanvas(path: string, source: string, display: boolean, math: boolean) { createTypstRenderElement(path: string, source: string, display: boolean, math: boolean) {
let canvas = new TypstCanvasElement(); let renderer = new TypstRenderElement();
canvas.source = source renderer.format = this.settings.format
canvas.path = path renderer.source = source
canvas.display = display renderer.path = path
canvas.math = math renderer.display = display
return canvas renderer.math = math
return renderer
} }
createTypstMath(source: string, r: { display: boolean }) { createTypstMath(source: string, r: { display: boolean }) {
const display = r.display; const display = r.display;
source = `${this.settings.preamable.math}\n${display ? `$ ${source} $` : `$${source}$`}` source = `${this.settings.preamable.math}\n${display ? `$ ${source} $` : `$${source}$`}`
return this.createTypstCanvas("/586f8912-f3a8-4455-8a4a-3729469c2cc1.typ", source, display, true) return this.createTypstRenderElement("/586f8912-f3a8-4455-8a4a-3729469c2cc1.typ", source, display, true)
} }
onunload() { onunload() {
@ -288,9 +298,34 @@ class TypstSettingTab extends PluginSettingTab {
containerEl.empty(); containerEl.empty();
new Setting(containerEl) new Setting(containerEl)
.setName("Render Format")
.addDropdown(dropdown => {
dropdown.addOptions({
svg: "SVG",
image: "Image"
})
.setValue(this.plugin.settings.format)
.onChange(async value => {
this.plugin.settings.format = value;
await this.plugin.saveSettings();
if (value == "svg") {
no_fill.setDisabled(true)
fill_color.setDisabled(true)
pixel_per_pt.setDisabled(true)
} else {
no_fill.setDisabled(false)
fill_color.setDisabled(this.plugin.settings.noFill)
pixel_per_pt.setDisabled(false)
}
})
})
let no_fill = new Setting(containerEl)
.setName("No Fill (Transparent)") .setName("No Fill (Transparent)")
.setDisabled(this.plugin.settings.format == "svg")
.addToggle((toggle) => { .addToggle((toggle) => {
toggle.setValue(this.plugin.settings.noFill) toggle.setValue(this.plugin.settings.noFill)
.onChange( .onChange(
@ -304,7 +339,7 @@ class TypstSettingTab extends PluginSettingTab {
let fill_color = new Setting(containerEl) let fill_color = new Setting(containerEl)
.setName("Fill Color") .setName("Fill Color")
.setDisabled(this.plugin.settings.noFill) .setDisabled(this.plugin.settings.noFill || this.plugin.settings.format == "svg")
.addColorPicker((picker) => { .addColorPicker((picker) => {
picker.setValue(this.plugin.settings.fill) picker.setValue(this.plugin.settings.fill)
.onChange( .onChange(
@ -315,8 +350,9 @@ class TypstSettingTab extends PluginSettingTab {
) )
}) })
new Setting(containerEl) let pixel_per_pt = new Setting(containerEl)
.setName("Pixel Per Point") .setName("Pixel Per Point")
.setDisabled(this.plugin.settings.format == "svg")
.addSlider((slider) => .addSlider((slider) =>
slider.setValue(this.plugin.settings.pixel_per_pt) slider.setValue(this.plugin.settings.pixel_per_pt)
.setLimits(1, 5, 1) .setLimits(1, 5, 1)
@ -381,7 +417,7 @@ class TypstSettingTab extends PluginSettingTab {
fontTagsDiv.innerHTML = '' fontTagsDiv.innerHTML = ''
this.plugin.settings.font_families.forEach((fontFamily) => { this.plugin.settings.font_families.forEach((fontFamily) => {
const fontTag = fontTagsDiv.createEl('span', { cls: "font-tag" }) const fontTag = fontTagsDiv.createEl('span', { cls: "font-tag" })
fontTag.createEl('span', { text: fontFamily, cls: "font-tag-text" }) fontTag.createEl('span', { text: fontFamily, cls: "font-tag-text", attr: { style: `font-family: ${fontFamily};` } })
const removeBtn = fontTag.createEl('span', { text: "x", cls: "tag-btn" }) const removeBtn = fontTag.createEl('span', { text: "x", cls: "tag-btn" })
removeBtn.addEventListener('click', async () => { removeBtn.addEventListener('click', async () => {
this.plugin.settings.font_families.remove(fontFamily) this.plugin.settings.font_families.remove(fontFamily)

9
src/types.d.ts vendored
View File

@ -1,4 +1,5 @@
export interface CompileCommand { export interface CompileImageCommand {
format: "image";
source: string; source: string;
path: string; path: string;
pixel_per_pt: number; pixel_per_pt: number;
@ -7,6 +8,12 @@ export interface CompileCommand {
display: boolean; display: boolean;
} }
export interface CompileSvgCommand {
format: "svg";
source: string;
path: string;
}
export interface WorkerRequest { export interface WorkerRequest {
buffer: Int32Array, buffer: Int32Array,
path: string path: string

View File

@ -1,10 +1,11 @@
export default class TypstCanvasElement extends HTMLCanvasElement { export default class TypstRenderElement extends HTMLElement {
static compile: (path: string, source: string, size: number, display: boolean, fontSize: number) => Promise<ImageData>; static compile: (path: string, source: string, size: number, display: boolean, fontSize: number) => Promise<ImageData | string>;
static nextId = 0; static nextId = 0;
static prevHeight = 0; static prevHeight = 0;
id: string id: string
abortController: AbortController abortController: AbortController
format: string
source: string source: string
path: string path: string
display: boolean display: boolean
@ -12,6 +13,8 @@ export default class TypstCanvasElement extends HTMLCanvasElement {
size: number size: number
math: boolean math: boolean
canvas: HTMLCanvasElement
async connectedCallback() { async connectedCallback() {
if (!this.isConnected) { if (!this.isConnected) {
console.warn("Typst Renderer: Canvas element has been called before connection"); console.warn("Typst Renderer: Canvas element has been called before connection");
@ -19,26 +22,35 @@ export default class TypstCanvasElement extends HTMLCanvasElement {
} }
// if (this.display && this.math) { // if (this.display && this.math) {
this.height = TypstCanvasElement.prevHeight; // this.style.height = TypstRenderElement.prevHeight;
// } // }
this.id = "TypstCanvasElement-" + TypstCanvasElement.nextId.toString() if (this.format == "image") {
TypstCanvasElement.nextId += 1 console.log("got a canvas");
this.canvas = this.appendChild(createEl("canvas", { attr: { height: TypstRenderElement.prevHeight } }))
}
this.id = "TypstRenderElement-" + TypstRenderElement.nextId.toString()
TypstRenderElement.nextId += 1
this.abortController = new AbortController() this.abortController = new AbortController()
if (this.display) { if (this.display) {
this.style.display = "block"
this.resizeObserver = new ResizeObserver((entries) => { this.resizeObserver = new ResizeObserver((entries) => {
if (entries[0]?.contentBoxSize[0].inlineSize !== this.size) { if (entries[0]?.contentBoxSize[0].inlineSize !== this.size) {
this.draw() this.draw()
} }
}) })
this.resizeObserver.observe(this.parentElement!.parentElement!) this.resizeObserver.observe(this)
} }
await this.draw() await this.draw()
} }
disconnectedCallback() { disconnectedCallback() {
TypstCanvasElement.prevHeight = this.height if (this.format == "image") {
TypstRenderElement.prevHeight = this.canvas.height
}
if (this.display && this.resizeObserver != undefined) { if (this.display && this.resizeObserver != undefined) {
this.resizeObserver.disconnect() this.resizeObserver.disconnect()
} }
@ -49,20 +61,24 @@ export default class TypstCanvasElement extends HTMLCanvasElement {
this.abortController = new AbortController() this.abortController = new AbortController()
try { try {
await navigator.locks.request(this.id, { signal: this.abortController.signal }, async () => { await navigator.locks.request(this.id, { signal: this.abortController.signal }, async () => {
let fontSize = parseFloat(this.getCssPropertyValue("--font-text-size")) let fontSize = parseFloat(document.body.getCssPropertyValue("--font-text-size"))
this.size = this.display ? this.parentElement!.parentElement!.innerWidth : parseFloat(this.getCssPropertyValue("--line-height-normal")) * fontSize this.size = this.display ? this.clientWidth : parseFloat(document.body.getCssPropertyValue("--line-height-normal")) * fontSize
// resizeObserver can trigger before the element gets disconnected which can cause the size to be 0 // resizeObserver can trigger before the element gets disconnected which can cause the size to be 0
// which causes a NaN. size can also sometimes be -ve so wait for resize to draw it again // which causes a NaN. size can also sometimes be -ve so wait for resize to draw it again
if (this.size <= 0) { if (this.size <= 0) {
return; return;
} }
let image: ImageData; let image: ImageData;
let ctx = this.getContext("2d")!;
try { try {
image = let result = await TypstRenderElement.compile(this.path, this.source, this.size, this.display, fontSize)
await TypstCanvasElement.compile(this.path, this.source, this.size, this.display, fontSize) if (result instanceof ImageData && this.format == "image") {
this.drawToCanvas(result)
} else if (typeof result == "string" && this.format == "svg") {
this.innerHTML = result
}
} catch (error) { } catch (error) {
// For some reason it is uncaught so remove "Uncaught " // For some reason it is uncaught so remove "Uncaught "
error = error.slice(9) error = error.slice(9)
@ -74,27 +90,31 @@ export default class TypstCanvasElement extends HTMLCanvasElement {
})//"<pre> </pre>" })//"<pre> </pre>"
pre.textContent = error pre.textContent = error
this.outerHTML = pre.outerHTML this.outerHTML = pre.outerHTML
// this.innerText = error
return return
} }
if (this.display) {
this.style.width = "100%"
this.style.height = ""
} else {
this.style.verticalAlign = "bottom"
this.style.height = `${this.size}px`
}
this.width = image.width
this.height = image.height
ctx.imageSmoothingEnabled = true
ctx.imageSmoothingQuality = "high"
ctx.putImageData(image, 0, 0);
}) })
} catch (error) { } catch (error) {
return return
} }
} }
drawToCanvas(image: ImageData) {
let ctx = this.canvas.getContext("2d")!;
if (this.display) {
this.style.width = "100%"
this.style.height = ""
} else {
this.style.verticalAlign = "bottom"
this.style.height = `${this.size}px`
}
this.canvas.width = image.width
this.canvas.height = image.height
ctx.imageSmoothingEnabled = true
ctx.imageSmoothingQuality = "high"
ctx.putImageData(image, 0, 0);
}
} }