content: lambda calculus
This commit is contained in:
parent
bf3341850b
commit
95e060567e
453
Cargo.lock
generated
453
Cargo.lock
generated
|
@ -29,12 +29,6 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "aligned-vec"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "allocator-api2"
|
name = "allocator-api2"
|
||||||
version = "0.2.18"
|
version = "0.2.18"
|
||||||
|
@ -105,70 +99,18 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anyhow"
|
|
||||||
version = "1.0.86"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arbitrary"
|
|
||||||
version = "1.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arg_enum_proc_macro"
|
|
||||||
version = "0.3.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.53",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arraydeque"
|
name = "arraydeque"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236"
|
checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arrayvec"
|
|
||||||
version = "0.7.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "av1-grain"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"arrayvec",
|
|
||||||
"log",
|
|
||||||
"nom",
|
|
||||||
"num-rational",
|
|
||||||
"v_frame",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "avif-serialize"
|
|
||||||
version = "0.8.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2"
|
|
||||||
dependencies = [
|
|
||||||
"arrayvec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.22.1"
|
version = "0.22.1"
|
||||||
|
@ -206,12 +148,6 @@ version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bitstream-io"
|
|
||||||
version = "2.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3dcde5f311c85b8ca30c2e4198d4326bc342c76541590106f5fa4a50946ea499"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
|
@ -221,12 +157,6 @@ dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "built"
|
|
||||||
version = "0.7.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "236e6289eda5a812bc6b53c3b024039382a2895fbbeef2d748b2931546d392c4"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.16.0"
|
version = "3.16.0"
|
||||||
|
@ -245,12 +175,6 @@ version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "byteorder-lite"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
|
@ -271,21 +195,6 @@ name = "cc"
|
||||||
version = "1.0.96"
|
version = "1.0.96"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd"
|
checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd"
|
||||||
dependencies = [
|
|
||||||
"jobserver",
|
|
||||||
"libc",
|
|
||||||
"once_cell",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-expr"
|
|
||||||
version = "0.15.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
|
|
||||||
dependencies = [
|
|
||||||
"smallvec",
|
|
||||||
"target-lexicon",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
@ -956,43 +865,22 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "image"
|
name = "image"
|
||||||
version = "0.25.2"
|
version = "0.24.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10"
|
checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"byteorder-lite",
|
"byteorder",
|
||||||
"color_quant",
|
"color_quant",
|
||||||
"exr",
|
"exr",
|
||||||
"gif",
|
"gif",
|
||||||
"image-webp",
|
"jpeg-decoder",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"png",
|
"png",
|
||||||
"qoi",
|
"qoi",
|
||||||
"ravif",
|
|
||||||
"rayon",
|
|
||||||
"rgb",
|
|
||||||
"tiff",
|
"tiff",
|
||||||
"zune-core",
|
|
||||||
"zune-jpeg",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "image-webp"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904"
|
|
||||||
dependencies = [
|
|
||||||
"byteorder-lite",
|
|
||||||
"quick-error",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "imgref"
|
|
||||||
version = "1.10.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.2.6"
|
version = "2.2.6"
|
||||||
|
@ -1024,17 +912,6 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "interpolate_name"
|
|
||||||
version = "0.2.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.53",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is_terminal_polyfill"
|
name = "is_terminal_polyfill"
|
||||||
version = "1.70.0"
|
version = "1.70.0"
|
||||||
|
@ -1050,35 +927,20 @@ dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itertools"
|
|
||||||
version = "0.12.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
|
||||||
dependencies = [
|
|
||||||
"either",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.10"
|
version = "1.0.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "jobserver"
|
|
||||||
version = "0.1.32"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jpeg-decoder"
|
name = "jpeg-decoder"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0"
|
checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0"
|
||||||
|
dependencies = [
|
||||||
|
"rayon",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
|
@ -1132,7 +994,7 @@ checksum = "4bdbc7a1823f188f56ac9486993536b70a2686a58d47095dcc10507a7d242bf5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"derive_builder",
|
"derive_builder",
|
||||||
"itertools 0.10.5",
|
"itertools",
|
||||||
"quick-js",
|
"quick-js",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
@ -1184,17 +1046,6 @@ version = "0.2.153"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libfuzzer-sys"
|
|
||||||
version = "0.4.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7"
|
|
||||||
dependencies = [
|
|
||||||
"arbitrary",
|
|
||||||
"cc",
|
|
||||||
"once_cell",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libquickjs-sys"
|
name = "libquickjs-sys"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
@ -1221,36 +1072,12 @@ version = "0.4.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "loop9"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062"
|
|
||||||
dependencies = [
|
|
||||||
"imgref",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "maybe-rayon"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.1"
|
version = "2.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "minimal-lexical"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.7.4"
|
version = "0.7.4"
|
||||||
|
@ -1273,28 +1100,6 @@ dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "new_debug_unreachable"
|
|
||||||
version = "1.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom"
|
|
||||||
version = "7.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
"minimal-lexical",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "noop_proc_macro"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "notify"
|
name = "notify"
|
||||||
version = "6.1.1"
|
version = "6.1.1"
|
||||||
|
@ -1335,47 +1140,6 @@ dependencies = [
|
||||||
"tree-sitter",
|
"tree-sitter",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-bigint"
|
|
||||||
version = "0.4.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
|
|
||||||
dependencies = [
|
|
||||||
"num-integer",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-derive"
|
|
||||||
version = "0.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.53",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-integer"
|
|
||||||
version = "0.1.46"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
|
|
||||||
dependencies = [
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-rational"
|
|
||||||
version = "0.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
|
|
||||||
dependencies = [
|
|
||||||
"num-bigint",
|
|
||||||
"num-integer",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.18"
|
version = "0.2.18"
|
||||||
|
@ -1451,12 +1215,6 @@ dependencies = [
|
||||||
"siphasher",
|
"siphasher",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pkg-config"
|
|
||||||
version = "0.3.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "png"
|
name = "png"
|
||||||
version = "0.17.13"
|
version = "0.17.13"
|
||||||
|
@ -1520,25 +1278,6 @@ dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "profiling"
|
|
||||||
version = "1.0.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58"
|
|
||||||
dependencies = [
|
|
||||||
"profiling-procmacros",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "profiling-procmacros"
|
|
||||||
version = "1.0.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd"
|
|
||||||
dependencies = [
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.53",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pulldown-cmark"
|
name = "pulldown-cmark"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
|
@ -1567,12 +1306,6 @@ dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quick-error"
|
|
||||||
version = "2.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quick-js"
|
name = "quick-js"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
|
@ -1632,55 +1365,6 @@ dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rav1e"
|
|
||||||
version = "0.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9"
|
|
||||||
dependencies = [
|
|
||||||
"arbitrary",
|
|
||||||
"arg_enum_proc_macro",
|
|
||||||
"arrayvec",
|
|
||||||
"av1-grain",
|
|
||||||
"bitstream-io",
|
|
||||||
"built",
|
|
||||||
"cfg-if",
|
|
||||||
"interpolate_name",
|
|
||||||
"itertools 0.12.1",
|
|
||||||
"libc",
|
|
||||||
"libfuzzer-sys",
|
|
||||||
"log",
|
|
||||||
"maybe-rayon",
|
|
||||||
"new_debug_unreachable",
|
|
||||||
"noop_proc_macro",
|
|
||||||
"num-derive",
|
|
||||||
"num-traits",
|
|
||||||
"once_cell",
|
|
||||||
"paste",
|
|
||||||
"profiling",
|
|
||||||
"rand",
|
|
||||||
"rand_chacha",
|
|
||||||
"simd_helpers",
|
|
||||||
"system-deps",
|
|
||||||
"thiserror",
|
|
||||||
"v_frame",
|
|
||||||
"wasm-bindgen",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ravif"
|
|
||||||
version = "0.11.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5797d09f9bd33604689e87e8380df4951d4912f01b63f71205e2abd4ae25e6b6"
|
|
||||||
dependencies = [
|
|
||||||
"avif-serialize",
|
|
||||||
"imgref",
|
|
||||||
"loop9",
|
|
||||||
"quick-error",
|
|
||||||
"rav1e",
|
|
||||||
"rgb",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "rayon"
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
|
@ -1739,15 +1423,6 @@ version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rgb"
|
|
||||||
version = "0.8.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ade4539f42266ded9e755c605bdddf546242b2c961b03b06a7375260788a0523"
|
|
||||||
dependencies = [
|
|
||||||
"bytemuck",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rstml"
|
name = "rstml"
|
||||||
version = "0.11.2"
|
version = "0.11.2"
|
||||||
|
@ -1820,15 +1495,6 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_spanned"
|
|
||||||
version = "0.6.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_yaml"
|
name = "serde_yaml"
|
||||||
version = "0.9.33"
|
version = "0.9.33"
|
||||||
|
@ -1870,15 +1536,6 @@ 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 = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "simd_helpers"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6"
|
|
||||||
dependencies = [
|
|
||||||
"quote",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "siphasher"
|
name = "siphasher"
|
||||||
version = "0.3.11"
|
version = "0.3.11"
|
||||||
|
@ -1968,25 +1625,6 @@ dependencies = [
|
||||||
"syn 2.0.53",
|
"syn 2.0.53",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "system-deps"
|
|
||||||
version = "6.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-expr",
|
|
||||||
"heck 0.5.0",
|
|
||||||
"pkg-config",
|
|
||||||
"toml",
|
|
||||||
"version-compare",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "target-lexicon"
|
|
||||||
version = "0.12.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.59"
|
version = "1.0.59"
|
||||||
|
@ -2042,40 +1680,6 @@ version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml"
|
|
||||||
version = "0.8.19"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
"serde_spanned",
|
|
||||||
"toml_datetime",
|
|
||||||
"toml_edit",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml_datetime"
|
|
||||||
version = "0.6.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml_edit"
|
|
||||||
version = "0.22.20"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
|
|
||||||
dependencies = [
|
|
||||||
"indexmap",
|
|
||||||
"serde",
|
|
||||||
"serde_spanned",
|
|
||||||
"toml_datetime",
|
|
||||||
"winnow",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tree-sitter"
|
name = "tree-sitter"
|
||||||
version = "0.22.6"
|
version = "0.22.6"
|
||||||
|
@ -2344,23 +1948,6 @@ version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "v_frame"
|
|
||||||
version = "0.3.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b"
|
|
||||||
dependencies = [
|
|
||||||
"aligned-vec",
|
|
||||||
"num-traits",
|
|
||||||
"wasm-bindgen",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version-compare"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
|
@ -2615,15 +2202,6 @@ version = "0.52.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winnow"
|
|
||||||
version = "0.6.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yaml-rust2"
|
name = "yaml-rust2"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
@ -2655,12 +2233,6 @@ dependencies = [
|
||||||
"syn 2.0.53",
|
"syn 2.0.53",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zune-core"
|
|
||||||
version = "0.4.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zune-inflate"
|
name = "zune-inflate"
|
||||||
version = "0.2.54"
|
version = "0.2.54"
|
||||||
|
@ -2669,12 +2241,3 @@ checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"simd-adler32",
|
"simd-adler32",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zune-jpeg"
|
|
||||||
version = "0.4.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768"
|
|
||||||
dependencies = [
|
|
||||||
"zune-core",
|
|
||||||
]
|
|
||||||
|
|
10
content/posts/lambda-calculus/index.bib
Normal file
10
content/posts/lambda-calculus/index.bib
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
@book{DBLP:books/daglib/0005958,
|
||||||
|
author = {Benjamin C. Pierce},
|
||||||
|
title = {Types and programming languages},
|
||||||
|
publisher = {{MIT} Press},
|
||||||
|
year = {2002},
|
||||||
|
isbn = {978-0-262-16209-8},
|
||||||
|
timestamp = {Thu, 03 Feb 2011 10:51:35 +0100},
|
||||||
|
biburl = {https://dblp.org/rec/books/daglib/0005958.bib},
|
||||||
|
bibsource = {dblp computer science bibliography, https://dblp.org}
|
||||||
|
}
|
85
content/posts/lambda-calculus/index.md
Normal file
85
content/posts/lambda-calculus/index.md
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
---
|
||||||
|
title: Lambda calculus is the DNA of all computation
|
||||||
|
date: 2024-09-07T20:32:00.281Z
|
||||||
|
desc: >
|
||||||
|
Lambda calculus can be used to express any computation, but what does it entail? As it turns out first class functions are the single most powerful abstraction.
|
||||||
|
---
|
||||||
|
|
||||||
|
In lambda calculus the entire grammar of the language comprises of just three kinds of expressions
|
||||||
|
|
||||||
|
1. variables
|
||||||
|
2. lambda abstraction
|
||||||
|
3. application
|
||||||
|
|
||||||
|
The grammar can be formulated recursively as
|
||||||
|
|
||||||
|
```
|
||||||
|
t ::=
|
||||||
|
x // variable
|
||||||
|
λx.t // lambda abstraction
|
||||||
|
t t // application
|
||||||
|
```
|
||||||
|
|
||||||
|
In lambda calculus functions accept only a single argument, but they can be nested, this is referred to as currying in the literature. For example, we can have a simple function that just returns its argument $\lambda x. x$ which is generally known as the identity function.
|
||||||
|
|
||||||
|
Any language that has first class functions with closures can be used to simulate lambda calculus. As an example I will use my own custom toy language.
|
||||||
|
|
||||||
|
```
|
||||||
|
// variable declaration
|
||||||
|
let a = 10;
|
||||||
|
|
||||||
|
// function declaration (id)
|
||||||
|
let f x = x;
|
||||||
|
|
||||||
|
// anonymous function (id)
|
||||||
|
let g = fn x -> x;
|
||||||
|
|
||||||
|
// function application
|
||||||
|
f g 1
|
||||||
|
```
|
||||||
|
|
||||||
|
The result of evaluating `f g 1` is `1`, because `f g` → `g` and `g 1` → `1`.
|
||||||
|
|
||||||
|
As we can see the language can be used to express every single term we have in lambda calculus. Can these terms be used to express any computation? As it turns out yes, in fact we can encode data type using just functions. These encodings are called [Church encodings](https://en.wikipedia.org/wiki/Church_encoding) in the literature.
|
||||||
|
|
||||||
|
Let's start with booleans, they can be defined as follows:
|
||||||
|
|
||||||
|
$$
|
||||||
|
\begin{align}
|
||||||
|
\text{tru} = \lambda \text{t}.\: \lambda \text{f}.\: \text{t}; \\
|
||||||
|
\text{fls} = \lambda \text{t}.\: \lambda \text{f}.\: \text{f};
|
||||||
|
\end{align}
|
||||||
|
$$
|
||||||
|
|
||||||
|
```
|
||||||
|
let tru t f = t;
|
||||||
|
let fls t f = f;
|
||||||
|
```
|
||||||
|
|
||||||
|
And then we can defined a function that will work just like `if ... then ... else ...` in general purpose programming languages.
|
||||||
|
|
||||||
|
$$\text{test} = \lambda \text{l}.\: \lambda \text{m}.\: \lambda \text{n}.\: \text{l}\, \text{m}\, \text{n};$$
|
||||||
|
|
||||||
|
```
|
||||||
|
let test l m n = l m n;
|
||||||
|
```
|
||||||
|
|
||||||
|
Let's also defined the `and` combinator which checks if two values are true.
|
||||||
|
|
||||||
|
$$\text{and} = \lambda \text{b}.\: \lambda \text{c}.\: \text{b}\, \text{c}\, \text{fls};$$
|
||||||
|
|
||||||
|
```
|
||||||
|
let and_ b c = b c fls;
|
||||||
|
```
|
||||||
|
|
||||||
|
Let's see if this works! Feel free to play around with the code...
|
||||||
|
|
||||||
|
<pre class="flox-eval">
|
||||||
|
let tru t f = t;
|
||||||
|
let fls t f = f;
|
||||||
|
|
||||||
|
let test l m n = l m n;
|
||||||
|
let and_ b c = b c fls;
|
||||||
|
|
||||||
|
test (and_ tru tru) "both true!" "nope"
|
||||||
|
</pre>
|
36
js/flox/lambda.ts
Normal file
36
js/flox/lambda.ts
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import { EditorState } from "@codemirror/state";
|
||||||
|
import { EditorView, keymap, lineNumbers } from "@codemirror/view";
|
||||||
|
import { defaultKeymap } from "@codemirror/commands";
|
||||||
|
import { init, evaluate } from "./wasm";
|
||||||
|
|
||||||
|
function instantiate(element: HTMLElement): EditorView {
|
||||||
|
const divEditor = document.createElement("div");
|
||||||
|
const divOutput = document.createElement("pre");
|
||||||
|
const initState = element.innerText.trim();
|
||||||
|
|
||||||
|
element.innerText = "";
|
||||||
|
element.appendChild(divEditor);
|
||||||
|
element.appendChild(divOutput);
|
||||||
|
divEditor.className = "editor";
|
||||||
|
divOutput.className = "output";
|
||||||
|
init.then((_) => (divOutput.innerText = evaluate(initState)));
|
||||||
|
|
||||||
|
const state = EditorState.create({
|
||||||
|
doc: initState,
|
||||||
|
extensions: [
|
||||||
|
keymap.of(defaultKeymap),
|
||||||
|
lineNumbers(),
|
||||||
|
EditorView.updateListener.of((update) => {
|
||||||
|
if (update.docChanged) {
|
||||||
|
divOutput.innerText = evaluate(update.state.doc.toString());
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
return new EditorView({ state, parent: divEditor });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const el of document.getElementsByClassName("flox-eval")) {
|
||||||
|
const editor = instantiate(el as HTMLElement);
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import { EditorState } from '@codemirror/state';
|
import { EditorState } from "@codemirror/state";
|
||||||
import { EditorView, keymap, lineNumbers } from '@codemirror/view';
|
import { EditorView, keymap, lineNumbers } from "@codemirror/view";
|
||||||
import { defaultKeymap } from '@codemirror/commands';
|
import { defaultKeymap } from "@codemirror/commands";
|
||||||
import * as wasm from './pkg/flox_wasm';
|
import { evaluate } from "./wasm";
|
||||||
|
|
||||||
const doc = `
|
const doc = `
|
||||||
let n1 = 2;
|
let n1 = 2;
|
||||||
|
@ -15,27 +15,17 @@ let add a b = a + b;
|
||||||
|> fn n -> n * -1
|
|> fn n -> n * -1
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const htmlEditor = document.getElementById('editor')!;
|
const htmlEditor = document.getElementById("editor")!;
|
||||||
const htmlOutput = document.getElementById('output')!;
|
const htmlOutput = document.getElementById("output")!;
|
||||||
const htmlRun = document.getElementById('run')!;
|
const htmlRun = document.getElementById("run")!;
|
||||||
|
|
||||||
const state = EditorState.create({
|
const state = EditorState.create({
|
||||||
doc,
|
doc,
|
||||||
extensions: [
|
extensions: [keymap.of(defaultKeymap), lineNumbers()],
|
||||||
keymap.of(defaultKeymap),
|
|
||||||
lineNumbers()
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const view = new EditorView({ state, parent: htmlEditor });
|
const view = new EditorView({ state, parent: htmlEditor });
|
||||||
|
|
||||||
WebAssembly.compileStreaming(fetch('flox_wasm_bg.wasm')).then((asm) => wasm.initSync(asm));
|
htmlRun.addEventListener("click", () => {
|
||||||
|
htmlOutput.textContent = evaluate(view.state.doc.toString());
|
||||||
function run(code: string) {
|
|
||||||
return wasm.eval_expression(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
htmlRun.addEventListener('click', () => {
|
|
||||||
const code = view.state.doc.toString();
|
|
||||||
htmlOutput.textContent = run(code);
|
|
||||||
});
|
});
|
||||||
|
|
10
js/flox/wasm.ts
Normal file
10
js/flox/wasm.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import * as wasm from "./pkg/flox_wasm";
|
||||||
|
|
||||||
|
const PATH = "/static/flox_wasm_bg.wasm";
|
||||||
|
const INIT = WebAssembly.compileStreaming(fetch(PATH)).then(wasm.initSync);
|
||||||
|
|
||||||
|
export const init = INIT;
|
||||||
|
|
||||||
|
export function evaluate(source: string): string {
|
||||||
|
return wasm.eval_expression(source);
|
||||||
|
}
|
144
src/html/post.rs
144
src/html/post.rs
|
@ -8,54 +8,56 @@ use serde::Deserialize;
|
||||||
/// Represents a simple post.
|
/// Represents a simple post.
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
pub(crate) struct Post {
|
pub(crate) struct Post {
|
||||||
pub(crate) title: String,
|
pub(crate) title: String,
|
||||||
#[serde(with = "super::isodate")]
|
#[serde(with = "super::isodate")]
|
||||||
pub(crate) date: DateTime<Utc>,
|
pub(crate) date: DateTime<Utc>,
|
||||||
pub(crate) desc: Option<String>,
|
pub(crate) desc: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Content for Post {
|
impl Content for Post {
|
||||||
fn parse_content(
|
fn parse_content(
|
||||||
content: &str,
|
content: &str,
|
||||||
sack: &Sack,
|
sack: &Sack,
|
||||||
path: &Utf8Path,
|
path: &Utf8Path,
|
||||||
library: Option<&Library>,
|
library: Option<&Library>,
|
||||||
) -> (String, Outline, Bibliography) {
|
) -> (String, Outline, Bibliography) {
|
||||||
crate::text::md::parse(content, sack, path, library)
|
crate::text::md::parse(content, sack, path, library)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_html(
|
fn as_html(
|
||||||
&self,
|
&self,
|
||||||
parsed: &str,
|
parsed: &str,
|
||||||
sack: &Sack,
|
sack: &Sack,
|
||||||
outline: Outline,
|
outline: Outline,
|
||||||
bibliography: Bibliography,
|
bibliography: Bibliography,
|
||||||
) -> String {
|
) -> String {
|
||||||
post(self, parsed, sack, outline, bibliography).render().into()
|
post(self, parsed, sack, outline, bibliography)
|
||||||
}
|
.render()
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
fn as_link(&self, path: Utf8PathBuf) -> Option<Linkable> {
|
fn as_link(&self, path: Utf8PathBuf) -> Option<Linkable> {
|
||||||
Some(Linkable::Date(LinkDate {
|
Some(Linkable::Date(LinkDate {
|
||||||
link: Link {
|
link: Link {
|
||||||
path,
|
path,
|
||||||
name: self.title.to_owned(),
|
name: self.title.to_owned(),
|
||||||
desc: self.desc.to_owned(),
|
desc: self.desc.to_owned(),
|
||||||
},
|
},
|
||||||
date: self.date.to_owned(),
|
date: self.date.to_owned(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn post<'s, 'p, 'html>(
|
pub fn post<'s, 'p, 'html>(
|
||||||
metadata: &'p Post,
|
metadata: &'p Post,
|
||||||
parsed: &'p str,
|
parsed: &'p str,
|
||||||
sack: &'s Sack,
|
sack: &'s Sack,
|
||||||
outline: Outline,
|
outline: Outline,
|
||||||
bibliography: Bibliography,
|
bibliography: Bibliography,
|
||||||
) -> impl Renderable + 'html
|
) -> impl Renderable + 'html
|
||||||
where
|
where
|
||||||
's: 'html,
|
's: 'html,
|
||||||
'p: 'html,
|
'p: 'html,
|
||||||
{
|
{
|
||||||
let main = maud_move!(
|
let main = maud_move!(
|
||||||
main {
|
main {
|
||||||
|
@ -63,46 +65,48 @@ where
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
crate::html::page(sack, main, metadata.title.clone())
|
crate::html::page(sack, main, metadata.title.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn article<'p, 's, 'html>(
|
pub fn article<'p, 's, 'html>(
|
||||||
title: &'p str,
|
title: &'p str,
|
||||||
parsed: &'p str,
|
parsed: &'p str,
|
||||||
_: &'s Sack,
|
_: &'s Sack,
|
||||||
outline: Outline,
|
outline: Outline,
|
||||||
bibliography: Bibliography,
|
bibliography: Bibliography,
|
||||||
) -> impl Renderable + 'html
|
) -> impl Renderable + 'html
|
||||||
where
|
where
|
||||||
's: 'html,
|
's: 'html,
|
||||||
'p: 'html,
|
'p: 'html,
|
||||||
{
|
{
|
||||||
maud_move!(
|
maud_move!(
|
||||||
div .wiki-main {
|
div .wiki-main {
|
||||||
|
|
||||||
// Slide in/out for mobile
|
// Slide in/out for mobile
|
||||||
input #wiki-aside-shown type="checkbox" hidden;
|
input #wiki-aside-shown type="checkbox" hidden;
|
||||||
|
|
||||||
aside .wiki-aside {
|
aside .wiki-aside {
|
||||||
// Slide button
|
// Slide button
|
||||||
label .wiki-aside__slider for="wiki-aside-shown" {
|
label .wiki-aside__slider for="wiki-aside-shown" {
|
||||||
img .wiki-icon src="/static/svg/double-arrow.svg" width="24" height="24";
|
img .wiki-icon src="/static/svg/double-arrow.svg" width="24" height="24";
|
||||||
}
|
}
|
||||||
(crate::html::misc::show_outline(outline))
|
(crate::html::misc::show_outline(outline))
|
||||||
}
|
}
|
||||||
|
|
||||||
article .wiki-article /*class:list={classlist)*/ {
|
article .wiki-article /*class:list={classlist)*/ {
|
||||||
header class="markdown" {
|
header class="markdown" {
|
||||||
h1 #top { (title) }
|
h1 #top { (title) }
|
||||||
}
|
}
|
||||||
section .wiki-article__markdown.markdown {
|
section .wiki-article__markdown.markdown {
|
||||||
(Raw(parsed))
|
(Raw(parsed))
|
||||||
}
|
}
|
||||||
|
|
||||||
@if let Some(bib) = bibliography.0 {
|
@if let Some(bib) = bibliography.0 {
|
||||||
(crate::html::misc::show_bibliography(bib))
|
(crate::html::misc::show_bibliography(bib))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
script type="module" {(Raw(r#"import "lambda";"#))}
|
||||||
)
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ fn main() {
|
||||||
.js("photos", "./js/vanilla/photos.js")
|
.js("photos", "./js/vanilla/photos.js")
|
||||||
.js("reveal", "./js/vanilla/reveal.js")
|
.js("reveal", "./js/vanilla/reveal.js")
|
||||||
.js("editor", "./js/flox/main.ts")
|
.js("editor", "./js/flox/main.ts")
|
||||||
|
.js("lambda", "./js/flox/lambda.ts")
|
||||||
.add_virtual(
|
.add_virtual(
|
||||||
|sack| crate::html::map(sack).render().to_owned().into(),
|
|sack| crate::html::map(sack).render().to_owned().into(),
|
||||||
"map/index.html".into(),
|
"map/index.html".into(),
|
||||||
|
|
567
src/text/md.rs
567
src/text/md.rs
|
@ -3,10 +3,10 @@ use std::collections::HashMap;
|
||||||
use camino::{Utf8Path, Utf8PathBuf};
|
use camino::{Utf8Path, Utf8PathBuf};
|
||||||
use hauchiwa::{Bibliography, Outline, Sack};
|
use hauchiwa::{Bibliography, Outline, Sack};
|
||||||
use hayagriva::{
|
use hayagriva::{
|
||||||
archive::ArchivedStyle,
|
archive::ArchivedStyle,
|
||||||
citationberg::{IndependentStyle, Locale, Style},
|
citationberg::{IndependentStyle, Locale, Style},
|
||||||
BibliographyDriver, BibliographyRequest, BufWriteFormat, CitationItem, CitationRequest,
|
BibliographyDriver, BibliographyRequest, BufWriteFormat, CitationItem, CitationRequest,
|
||||||
Library,
|
Library,
|
||||||
};
|
};
|
||||||
use hypertext::Renderable;
|
use hypertext::Renderable;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
@ -16,370 +16,369 @@ use regex::Regex;
|
||||||
use crate::ts;
|
use crate::ts;
|
||||||
|
|
||||||
static OPTS: Lazy<Options> = Lazy::new(|| {
|
static OPTS: Lazy<Options> = Lazy::new(|| {
|
||||||
Options::empty()
|
Options::empty()
|
||||||
.union(Options::ENABLE_MATH)
|
.union(Options::ENABLE_MATH)
|
||||||
.union(Options::ENABLE_TABLES)
|
.union(Options::ENABLE_TABLES)
|
||||||
.union(Options::ENABLE_TASKLISTS)
|
.union(Options::ENABLE_TASKLISTS)
|
||||||
.union(Options::ENABLE_STRIKETHROUGH)
|
.union(Options::ENABLE_STRIKETHROUGH)
|
||||||
.union(Options::ENABLE_SMART_PUNCTUATION)
|
.union(Options::ENABLE_SMART_PUNCTUATION)
|
||||||
});
|
});
|
||||||
|
|
||||||
static KATEX_I: Lazy<katex::Opts> = Lazy::new(|| {
|
static KATEX_I: Lazy<katex::Opts> = Lazy::new(|| {
|
||||||
katex::opts::Opts::builder()
|
katex::opts::Opts::builder()
|
||||||
.output_type(katex::OutputType::Mathml)
|
.output_type(katex::OutputType::Mathml)
|
||||||
.build()
|
.build()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static KATEX_B: Lazy<katex::Opts> = Lazy::new(|| {
|
static KATEX_B: Lazy<katex::Opts> = Lazy::new(|| {
|
||||||
katex::opts::Opts::builder()
|
katex::opts::Opts::builder()
|
||||||
.output_type(katex::OutputType::Mathml)
|
.output_type(katex::OutputType::Mathml)
|
||||||
.display_mode(true)
|
.display_mode(true)
|
||||||
.build()
|
.build()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static LOCALE: Lazy<Vec<Locale>> = Lazy::new(hayagriva::archive::locales);
|
static LOCALE: Lazy<Vec<Locale>> = Lazy::new(hayagriva::archive::locales);
|
||||||
|
|
||||||
static STYLE: Lazy<IndependentStyle> =
|
static STYLE: Lazy<IndependentStyle> =
|
||||||
Lazy::new(|| match ArchivedStyle::InstituteOfPhysicsNumeric.get() {
|
Lazy::new(
|
||||||
Style::Independent(style) => style,
|
|| match ArchivedStyle::InstituteOfElectricalAndElectronicsEngineers.get() {
|
||||||
Style::Dependent(_) => unreachable!(),
|
Style::Independent(style) => style,
|
||||||
});
|
Style::Dependent(_) => unreachable!(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
pub fn parse(
|
pub fn parse(
|
||||||
content: &str,
|
content: &str,
|
||||||
sack: &Sack,
|
sack: &Sack,
|
||||||
path: &Utf8Path,
|
path: &Utf8Path,
|
||||||
library: Option<&Library>,
|
library: Option<&Library>,
|
||||||
) -> (String, Outline, Bibliography) {
|
) -> (String, Outline, Bibliography) {
|
||||||
let (outline, stream) = {
|
let (outline, stream) = {
|
||||||
let stream = Parser::new_ext(content, *OPTS);
|
let stream = Parser::new_ext(content, *OPTS);
|
||||||
let mut stream: Vec<_> = TextMergeStream::new(stream).collect();
|
let mut stream: Vec<_> = TextMergeStream::new(stream).collect();
|
||||||
let outline = set_heading_ids(&mut stream);
|
let outline = set_heading_ids(&mut stream);
|
||||||
(outline, stream)
|
(outline, stream)
|
||||||
};
|
};
|
||||||
|
|
||||||
let stream = stream
|
let stream = stream
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(make_math)
|
.map(make_math)
|
||||||
.map(make_emoji)
|
.map(make_emoji)
|
||||||
.map(swap_hashed_image(path, sack))
|
.map(swap_hashed_image(path, sack))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let stream = make_code(stream)
|
let stream = make_code(stream)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(make_ruby)
|
.flat_map(make_ruby)
|
||||||
.flat_map(make_cite)
|
.flat_map(make_cite)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let (stream, bib) = match library {
|
let (stream, bib) = match library {
|
||||||
Some(lib) => make_bib(stream, lib),
|
Some(lib) => make_bib(stream, lib),
|
||||||
None => (stream, None),
|
None => (stream, None),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut parsed = String::new();
|
let mut parsed = String::new();
|
||||||
pulldown_cmark::html::push_html(&mut parsed, stream.into_iter());
|
pulldown_cmark::html::push_html(&mut parsed, stream.into_iter());
|
||||||
|
|
||||||
(parsed, outline, Bibliography(bib))
|
(parsed, outline, Bibliography(bib))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_bib<'a, 'b>(
|
fn make_bib<'a, 'b>(
|
||||||
stream: Vec<Event<'a>>,
|
stream: Vec<Event<'a>>,
|
||||||
lib: &'b Library,
|
lib: &'b Library,
|
||||||
) -> (Vec<Event<'a>>, Option<Vec<String>>) {
|
) -> (Vec<Event<'a>>, Option<Vec<String>>) {
|
||||||
let mut driver = BibliographyDriver::new();
|
let mut driver = BibliographyDriver::new();
|
||||||
|
|
||||||
for event in stream.iter() {
|
for event in stream.iter() {
|
||||||
match event {
|
match event {
|
||||||
Event::InlineMath(ref text) => match lib.get(text) {
|
Event::InlineMath(ref text) => match lib.get(text) {
|
||||||
Some(entry) => driver.citation(CitationRequest::from_items(
|
Some(entry) => driver.citation(CitationRequest::from_items(
|
||||||
vec![CitationItem::with_entry(entry)],
|
vec![CitationItem::with_entry(entry)],
|
||||||
&STYLE,
|
&STYLE,
|
||||||
&LOCALE,
|
&LOCALE,
|
||||||
)),
|
)),
|
||||||
None => (),
|
None => (),
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add fake citation to make all entries show up
|
// add fake citation to make all entries show up
|
||||||
driver.citation(CitationRequest::from_items(
|
driver.citation(CitationRequest::from_items(
|
||||||
lib.iter().map(CitationItem::with_entry).collect(),
|
lib.iter().map(CitationItem::with_entry).collect(),
|
||||||
&STYLE,
|
&STYLE,
|
||||||
&LOCALE,
|
&LOCALE,
|
||||||
));
|
));
|
||||||
|
|
||||||
let res = driver.finish(BibliographyRequest {
|
let res = driver.finish(BibliographyRequest {
|
||||||
style: &STYLE,
|
style: &STYLE,
|
||||||
locale: None,
|
locale: None,
|
||||||
locale_files: &LOCALE,
|
locale_files: &LOCALE,
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
let stream = stream
|
let stream = stream
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|event| match event {
|
.map(|event| match event {
|
||||||
Event::InlineMath(name) => {
|
Event::InlineMath(name) => {
|
||||||
let mut buffer = String::from("<cite>");
|
let mut buffer = String::from("<cite>");
|
||||||
match res.citations.get(n) {
|
match res.citations.get(n) {
|
||||||
Some(rf) => rf
|
Some(rf) => rf
|
||||||
.citation
|
.citation
|
||||||
.write_buf(&mut buffer, BufWriteFormat::Html)
|
.write_buf(&mut buffer, BufWriteFormat::Html)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
None => buffer.push_str(&name),
|
None => buffer.push_str(&name),
|
||||||
};
|
};
|
||||||
buffer.push_str("</cite>");
|
buffer.push_str("</cite>");
|
||||||
n += 1;
|
n += 1;
|
||||||
Event::InlineHtml(buffer.into())
|
Event::InlineHtml(buffer.into())
|
||||||
}
|
}
|
||||||
_ => event,
|
_ => event,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let bib = res.bibliography.map(|bib| {
|
let bib = res.bibliography.map(|bib| {
|
||||||
bib.items
|
bib.items
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
x.content
|
x.content
|
||||||
.write_buf(&mut buffer, BufWriteFormat::Html)
|
.write_buf(&mut buffer, BufWriteFormat::Html)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
buffer
|
buffer
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
});
|
});
|
||||||
|
|
||||||
(stream, bib)
|
(stream, bib)
|
||||||
}
|
}
|
||||||
|
|
||||||
static RE_CITE: Lazy<Regex> = Lazy::new(|| Regex::new(r":cite\[([^\]]+)\]").unwrap());
|
static RE_CITE: Lazy<Regex> = Lazy::new(|| Regex::new(r":cite\[([^\]]+)\]").unwrap());
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Annotated_<'a> {
|
enum Annotated_<'a> {
|
||||||
Text(&'a str),
|
Text(&'a str),
|
||||||
Cite(&'a str),
|
Cite(&'a str),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn annotate_(input: &str) -> Vec<Annotated_> {
|
fn annotate_(input: &str) -> Vec<Annotated_> {
|
||||||
let mut parts: Vec<Annotated_> = Vec::new();
|
let mut parts: Vec<Annotated_> = Vec::new();
|
||||||
let mut last_index = 0;
|
let mut last_index = 0;
|
||||||
|
|
||||||
for cap in RE_CITE.captures_iter(input) {
|
for cap in RE_CITE.captures_iter(input) {
|
||||||
let cite = cap.get(1).unwrap().as_str();
|
let cite = cap.get(1).unwrap().as_str();
|
||||||
let index = cap.get(0).unwrap().start();
|
let index = cap.get(0).unwrap().start();
|
||||||
|
|
||||||
if index > last_index {
|
if index > last_index {
|
||||||
parts.push(Annotated_::Text(&input[last_index..index]));
|
parts.push(Annotated_::Text(&input[last_index..index]));
|
||||||
}
|
}
|
||||||
|
|
||||||
parts.push(Annotated_::Cite(cite));
|
parts.push(Annotated_::Cite(cite));
|
||||||
last_index = cap.get(0).unwrap().end();
|
last_index = cap.get(0).unwrap().end();
|
||||||
}
|
}
|
||||||
|
|
||||||
if last_index < input.len() {
|
if last_index < input.len() {
|
||||||
parts.push(Annotated_::Text(&input[last_index..]));
|
parts.push(Annotated_::Text(&input[last_index..]));
|
||||||
}
|
}
|
||||||
|
|
||||||
parts
|
parts
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_cite(event: Event) -> Vec<Event> {
|
fn make_cite(event: Event) -> Vec<Event> {
|
||||||
match event {
|
match event {
|
||||||
Event::Text(ref text) => annotate_(text)
|
Event::Text(ref text) => annotate_(text)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|e| match e {
|
.map(|e| match e {
|
||||||
Annotated_::Text(text) => Event::Text(text.to_owned().into()),
|
Annotated_::Text(text) => Event::Text(text.to_owned().into()),
|
||||||
Annotated_::Cite(cite) => Event::InlineMath(cite.to_owned().into()),
|
Annotated_::Cite(cite) => Event::InlineMath(cite.to_owned().into()),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
_ => vec![event],
|
_ => vec![event],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_heading_ids(events: &mut [Event]) -> Outline {
|
fn set_heading_ids(events: &mut [Event]) -> Outline {
|
||||||
let mut cnt = HashMap::<String, i32>::new();
|
let mut cnt = HashMap::<String, i32>::new();
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
let mut ptr = None;
|
let mut ptr = None;
|
||||||
|
|
||||||
for event in events {
|
for event in events {
|
||||||
match event {
|
match event {
|
||||||
Event::Start(ref mut tag @ Tag::Heading { .. }) => {
|
Event::Start(ref mut tag @ Tag::Heading { .. }) => {
|
||||||
ptr = Some(tag);
|
ptr = Some(tag);
|
||||||
}
|
}
|
||||||
Event::Text(ref text) if ptr.is_some() => buf.push_str(text),
|
Event::Text(ref text) if ptr.is_some() => buf.push_str(text),
|
||||||
Event::End(TagEnd::Heading(..)) => {
|
Event::End(TagEnd::Heading(..)) => {
|
||||||
let txt = std::mem::take(&mut buf);
|
let txt = std::mem::take(&mut buf);
|
||||||
let url = txt.to_lowercase().replace(' ', "-");
|
let url = txt.to_lowercase().replace(' ', "-");
|
||||||
let url = match cnt.get_mut(&url) {
|
let url = match cnt.get_mut(&url) {
|
||||||
Some(ptr) => {
|
Some(ptr) => {
|
||||||
*ptr += 1;
|
*ptr += 1;
|
||||||
format!("{url}-{ptr}")
|
format!("{url}-{ptr}")
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
cnt.insert(url.clone(), 0);
|
cnt.insert(url.clone(), 0);
|
||||||
url
|
url
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match ptr.take().unwrap() {
|
match ptr.take().unwrap() {
|
||||||
Tag::Heading { ref mut id, .. } => *id = Some(url.clone().into()),
|
Tag::Heading { ref mut id, .. } => *id = Some(url.clone().into()),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
out.push((txt, url));
|
out.push((txt, url));
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Outline(out)
|
Outline(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_math(event: Event) -> Event {
|
fn make_math(event: Event) -> Event {
|
||||||
match event {
|
match event {
|
||||||
Event::InlineMath(math) => {
|
Event::InlineMath(math) => {
|
||||||
Event::InlineHtml(katex::render_with_opts(&math, &*KATEX_I).unwrap().into())
|
Event::InlineHtml(katex::render_with_opts(&math, &*KATEX_I).unwrap().into())
|
||||||
}
|
}
|
||||||
Event::DisplayMath(math) => {
|
Event::DisplayMath(math) => {
|
||||||
Event::Html(katex::render_with_opts(&math, &*KATEX_B).unwrap().into())
|
Event::Html(katex::render_with_opts(&math, &*KATEX_B).unwrap().into())
|
||||||
}
|
}
|
||||||
_ => event,
|
_ => event,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_code(es: Vec<Event>) -> Vec<Event> {
|
fn make_code(es: Vec<Event>) -> Vec<Event> {
|
||||||
let mut buff = Vec::new();
|
let mut buff = Vec::new();
|
||||||
let mut lang = None;
|
let mut lang = None;
|
||||||
let mut code = String::new();
|
let mut code = String::new();
|
||||||
|
|
||||||
for event in es {
|
for event in es {
|
||||||
match event {
|
match event {
|
||||||
Event::Start(Tag::CodeBlock(kind)) => match kind {
|
Event::Start(Tag::CodeBlock(kind)) => match kind {
|
||||||
CodeBlockKind::Indented => (),
|
CodeBlockKind::Indented => (),
|
||||||
CodeBlockKind::Fenced(name) => lang = Some(name),
|
CodeBlockKind::Fenced(name) => lang = Some(name),
|
||||||
},
|
},
|
||||||
Event::End(TagEnd::CodeBlock) => {
|
Event::End(TagEnd::CodeBlock) => {
|
||||||
let lang = lang.take().unwrap_or("".into());
|
let lang = lang.take().unwrap_or("".into());
|
||||||
let html = ts::highlight(&lang, &code).render().as_str().to_owned();
|
let html = ts::highlight(&lang, &code).render().as_str().to_owned();
|
||||||
buff.push(Event::Html(html.into()));
|
buff.push(Event::Html(html.into()));
|
||||||
code.clear();
|
code.clear();
|
||||||
}
|
}
|
||||||
Event::Text(text) => match lang {
|
Event::Text(text) => match lang {
|
||||||
None => buff.push(Event::Text(text)),
|
None => buff.push(Event::Text(text)),
|
||||||
Some(_) => code.push_str(&text),
|
Some(_) => code.push_str(&text),
|
||||||
},
|
},
|
||||||
_ => buff.push(event),
|
_ => buff.push(event),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buff
|
buff
|
||||||
}
|
}
|
||||||
|
|
||||||
static RE_RUBY: Lazy<Regex> = Lazy::new(|| Regex::new(r"\[([^\]]+)\]\{([^}]+)\}").unwrap());
|
static RE_RUBY: Lazy<Regex> = Lazy::new(|| Regex::new(r"\[([^\]]+)\]\{([^}]+)\}").unwrap());
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Annotated<'a> {
|
enum Annotated<'a> {
|
||||||
Text(&'a str),
|
Text(&'a str),
|
||||||
Ruby(&'a str, &'a str),
|
Ruby(&'a str, &'a str),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn annotate(input: &str) -> Vec<Annotated> {
|
fn annotate(input: &str) -> Vec<Annotated> {
|
||||||
let mut parts: Vec<Annotated> = Vec::new();
|
let mut parts: Vec<Annotated> = Vec::new();
|
||||||
let mut last_index = 0;
|
let mut last_index = 0;
|
||||||
|
|
||||||
for cap in RE_RUBY.captures_iter(input) {
|
for cap in RE_RUBY.captures_iter(input) {
|
||||||
let text = cap.get(1).unwrap().as_str();
|
let text = cap.get(1).unwrap().as_str();
|
||||||
let ruby = cap.get(2).unwrap().as_str();
|
let ruby = cap.get(2).unwrap().as_str();
|
||||||
let index = cap.get(0).unwrap().start();
|
let index = cap.get(0).unwrap().start();
|
||||||
|
|
||||||
if index > last_index {
|
if index > last_index {
|
||||||
parts.push(Annotated::Text(&input[last_index..index]));
|
parts.push(Annotated::Text(&input[last_index..index]));
|
||||||
}
|
}
|
||||||
|
|
||||||
parts.push(Annotated::Ruby(text, ruby));
|
parts.push(Annotated::Ruby(text, ruby));
|
||||||
last_index = cap.get(0).unwrap().end();
|
last_index = cap.get(0).unwrap().end();
|
||||||
}
|
}
|
||||||
|
|
||||||
if last_index < input.len() {
|
if last_index < input.len() {
|
||||||
parts.push(Annotated::Text(&input[last_index..]));
|
parts.push(Annotated::Text(&input[last_index..]));
|
||||||
}
|
}
|
||||||
|
|
||||||
parts
|
parts
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_ruby(event: Event) -> Vec<Event> {
|
fn make_ruby(event: Event) -> Vec<Event> {
|
||||||
match event {
|
match event {
|
||||||
Event::Text(ref text) => annotate(text)
|
Event::Text(ref text) => annotate(text)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|el| match el {
|
.map(|el| match el {
|
||||||
Annotated::Text(text) => Event::Text(text.to_owned().into()),
|
Annotated::Text(text) => Event::Text(text.to_owned().into()),
|
||||||
Annotated::Ruby(t, f) => Event::InlineHtml(
|
Annotated::Ruby(t, f) => Event::InlineHtml(
|
||||||
format!("<ruby>{t}<rp>(</rp><rt>{f}</rt><rp>)</rp></ruby>").into(),
|
format!("<ruby>{t}<rp>(</rp><rt>{f}</rt><rp>)</rp></ruby>").into(),
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
_ => vec![event],
|
_ => vec![event],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_emoji(event: Event) -> Event {
|
fn make_emoji(event: Event) -> Event {
|
||||||
match event {
|
match event {
|
||||||
Event::Text(ref text) => {
|
Event::Text(ref text) => {
|
||||||
let mut buf = None;
|
let mut buf = None;
|
||||||
let mut top = 0;
|
let mut top = 0;
|
||||||
let mut old = 0;
|
let mut old = 0;
|
||||||
|
|
||||||
for (idx, _) in text.match_indices(':') {
|
for (idx, _) in text.match_indices(':') {
|
||||||
let key = &text[old..idx];
|
let key = &text[old..idx];
|
||||||
|
|
||||||
if let Some(emoji) = emojis::get_by_shortcode(key) {
|
if let Some(emoji) = emojis::get_by_shortcode(key) {
|
||||||
let buf = buf.get_or_insert_with(|| String::with_capacity(text.len()));
|
let buf = buf.get_or_insert_with(|| String::with_capacity(text.len()));
|
||||||
buf.push_str(&text[top..old - 1]);
|
buf.push_str(&text[top..old - 1]);
|
||||||
buf.push_str(emoji.as_str());
|
buf.push_str(emoji.as_str());
|
||||||
top = idx + 1;
|
top = idx + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
old = idx + 1;
|
old = idx + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref mut buf) = buf {
|
if let Some(ref mut buf) = buf {
|
||||||
buf.push_str(&text[top..]);
|
buf.push_str(&text[top..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
match buf {
|
match buf {
|
||||||
None => event,
|
None => event,
|
||||||
Some(buf) => Event::Text(buf.into()),
|
Some(buf) => Event::Text(buf.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => event,
|
_ => event,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn swap_hashed_image<'a>(
|
fn swap_hashed_image<'a>(dir: &'a Utf8Path, sack: &'a Sack) -> impl Fn(Event) -> Event + 'a {
|
||||||
dir: &'a Utf8Path,
|
move |event| match event {
|
||||||
sack: &'a Sack,
|
Event::Start(start) => match start {
|
||||||
) -> impl Fn(Event) -> Event + 'a {
|
Tag::Image {
|
||||||
move |event| match event {
|
dest_url,
|
||||||
Event::Start(start) => match start {
|
link_type,
|
||||||
Tag::Image {
|
title,
|
||||||
dest_url,
|
id,
|
||||||
link_type,
|
} => {
|
||||||
title,
|
let rel = dir.join(dest_url.as_ref());
|
||||||
id,
|
let img = sack.get_image(&rel);
|
||||||
} => {
|
let hashed = img.map(|path| path.as_str().to_owned().into());
|
||||||
let rel = dir.join(dest_url.as_ref());
|
Event::Start(Tag::Image {
|
||||||
let img = sack.get_image(&rel);
|
link_type,
|
||||||
let hashed = img.map(|path| path.as_str().to_owned().into());
|
dest_url: hashed.unwrap_or(dest_url),
|
||||||
Event::Start(Tag::Image {
|
title,
|
||||||
link_type,
|
id,
|
||||||
dest_url: hashed.unwrap_or(dest_url),
|
})
|
||||||
title,
|
}
|
||||||
id,
|
_ => Event::Start(start),
|
||||||
})
|
},
|
||||||
}
|
_ => event,
|
||||||
_ => Event::Start(start),
|
}
|
||||||
},
|
|
||||||
_ => event,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,43 @@
|
||||||
|
|
||||||
.flox-playground {
|
.flox-playground {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
grid-template-rows: max(24rem, 0.5vh);
|
grid-template-rows: max(24rem, 0.5vh);
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
margin-block: 0.5em;
|
margin-block: 0.5em;
|
||||||
padding: 1em;
|
|
||||||
|
|
||||||
.editor, #output {
|
|
||||||
height: calc(100% - 4em);
|
|
||||||
overflow-y: auto;
|
|
||||||
border: 1px dashed black;
|
|
||||||
border-radius: 0.5em;
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
#run {
|
|
||||||
position: absolute;
|
|
||||||
right: 0.5em;
|
|
||||||
bottom: 0.5em;
|
|
||||||
padding: 0.25em 0.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#output {
|
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
}
|
|
||||||
|
.editor,
|
||||||
|
#output {
|
||||||
|
height: calc(100% - 4em);
|
||||||
|
overflow-y: auto;
|
||||||
|
border: 1px dashed black;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
#run {
|
||||||
|
position: absolute;
|
||||||
|
right: 0.5em;
|
||||||
|
bottom: 0.5em;
|
||||||
|
padding: 0.25em 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#output {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.flox-eval {
|
||||||
|
border-radius: 0.5em;
|
||||||
|
border: 1px solid black;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
> .output {
|
||||||
|
padding: 0.25em 0.5em;
|
||||||
|
border-top: 1px solid black;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue