Generate multiple pages & metadata collection
Signed-off-by: prescientmoon <git@moonythm.dev>
This commit is contained in:
parent
10769956cf
commit
ec65fafa1a
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1 +1,3 @@
|
|||
/target
|
||||
target
|
||||
dist
|
||||
oldicons
|
||||
|
|
624
Cargo.lock
generated
624
Cargo.lock
generated
|
@ -2,48 +2,12 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.16.0"
|
||||
|
@ -51,193 +15,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cached"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4d73155ae6b28cf5de4cfc29aeb02b8a1c6dab883cb015d15cd514e42766846"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"cached_proc_macro",
|
||||
"cached_proc_macro_types",
|
||||
"directories",
|
||||
"hashbrown",
|
||||
"once_cell",
|
||||
"rmp-serde",
|
||||
"serde",
|
||||
"sled",
|
||||
"thiserror",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cached_proc_macro"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f42a145ed2d10dce2191e1dcf30cfccfea9026660e143662ba5eec4017d5daa"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cached_proc_macro_types"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.20.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.20.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "directories"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "fs2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fxhash"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"allocator-api2",
|
||||
]
|
||||
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
name = "indexmap"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
|
||||
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -247,63 +43,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "19fa1db3b285830176c8a940d4e3376679772bee9f58a83dd9285a4a54e30f6e"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.72"
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.159"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "moonythm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cached",
|
||||
"jotdown",
|
||||
"once_cell",
|
||||
"pulldown-latex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"serde",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -312,48 +66,11 @@ version = "1.20.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||
|
||||
[[package]]
|
||||
name = "option-ext"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.87"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a"
|
||||
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -376,68 +93,20 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libredox",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rmp"
|
||||
version = "0.8.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"num-traits",
|
||||
"paste",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rmp-serde"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"rmp",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.210"
|
||||
version = "1.0.214"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
|
||||
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.210"
|
||||
version = "1.0.214"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
|
||||
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -445,38 +114,19 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "sled"
|
||||
version = "0.34.7"
|
||||
name = "serde_spanned"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935"
|
||||
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
"fs2",
|
||||
"fxhash",
|
||||
"libc",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.79"
|
||||
version = "2.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
|
||||
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -484,23 +134,37 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.64"
|
||||
name = "toml"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
|
||||
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.64"
|
||||
name = "toml_datetime"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
|
||||
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -510,186 +174,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
name = "winnow"
|
||||
version = "0.6.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
|
||||
checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
|
||||
|
||||
[[package]]
|
||||
name = "web-time"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"memchr",
|
||||
]
|
||||
|
|
|
@ -5,6 +5,11 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0.89"
|
||||
cached = { version = "0.53.1", features = ["disk_store"] }
|
||||
jotdown = "0.6.0"
|
||||
pulldown-latex = "0.7.0"
|
||||
serde = { version = "1.0.214", features = ["derive"] }
|
||||
toml = "0.8.19"
|
||||
|
||||
# Waiting for https://github.com/rust-lang/rust/issues/109737
|
||||
# before switching to the std version.
|
||||
once_cell = "1.20.2"
|
||||
|
|
16
build.py
16
build.py
|
@ -1,16 +0,0 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -p python3 -i python3
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
shutil.rmtree("dist", ignore_errors=True)
|
||||
shutil.copytree("public", "dist")
|
||||
|
||||
with open("dist/index.html", "r") as file:
|
||||
template = file.read()
|
||||
|
||||
output = subprocess.check_output("cargo run", shell=True).decode("utf-8")
|
||||
result = template.replace("$CONTENT", output)
|
||||
|
||||
with open("dist/index.html", "w") as file:
|
||||
file.write(result)
|
14
content/index.dj
Normal file
14
content/index.dj
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Hiii
|
||||
|
||||
Welcome to my ethereal realm (read: website). This place is still being conjured (read: under construction), so some things might be startlingly empty. Enjoy your stay on the moon!
|
||||
|
||||
I'm known as `prescientmoon`, or sometimes `PGW`. I study mathematics, but I also really like coding and all computer-related sorcery. I love games of all kinds, although rhythm games have a special place in my heart.
|
||||
|
||||
{ title="Contact me" character="canyou" }
|
||||
::: aside
|
||||
You can message me in the following places \^-\^
|
||||
|
||||
- via email at `hi@thisdomain`
|
||||
- on discord as `@prescientmoon`
|
||||
- on the ~ IRC network as `prescientmoon`
|
||||
:::
|
|
@ -1,5 +1,5 @@
|
|||
``` =toml
|
||||
created-at: 2024-10-31 15:28
|
||||
created-at = "2024-10-31T15:28:OO"
|
||||
```
|
||||
|
||||
# Why I love arcaea
|
1
content/posts/games.dj
Normal file
1
content/posts/games.dj
Normal file
|
@ -0,0 +1 @@
|
|||
# My game tier list
|
15
content/posts/the-realm-s-secrets.dj
Normal file
15
content/posts/the-realm-s-secrets.dj
Normal file
|
@ -0,0 +1,15 @@
|
|||
# The realm's secrets
|
||||
|
||||
## Djot (why not markdown?)
|
||||
- extensionability
|
||||
- writing my own html generator
|
||||
- templating
|
||||
- metadata
|
||||
|
||||
## Hosting
|
||||
- hosted on my nixos server
|
||||
- there's interesting stuff happening there too, but that deserves it's own post
|
||||
|
||||
## LaTeX
|
||||
- tried using `cached` with `latexmlmath`, but results were slow.
|
||||
- ended up using the `pulldown-latex` crate.
|
|
@ -16,8 +16,7 @@
|
|||
pkgs.clippy
|
||||
pkgs.rust-analyzer
|
||||
pkgs.rustfmt
|
||||
pkgs.ruff
|
||||
pkgs.perl538Packages.LaTeXML
|
||||
pkgs.imagemagick
|
||||
];
|
||||
|
||||
buildInputs = with pkgs; [ ];
|
||||
|
|
|
@ -6,6 +6,7 @@ html {
|
|||
max-width: 70ch;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
|
@ -28,19 +29,11 @@ ol {
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
.aside-summary > .aside-title {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.aside-summary > * {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
img.aside-icon {
|
||||
/* display: inline-block; */
|
||||
height: 1.75rem;
|
||||
margin-right: 0.5rem;
|
||||
transform: translateY(-2px);
|
||||
/* transform: translateY(-100px); */
|
||||
}
|
||||
|
||||
.aside {
|
||||
|
@ -53,6 +46,7 @@ img.aside-icon {
|
|||
.aside-summary {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.aside-summary::marker {
|
||||
|
@ -66,6 +60,15 @@ img.aside-icon {
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.aside-summary > .aside-title {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.aside-summary > * {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.aside[open] .aside_summary:before {
|
||||
content: "▼";
|
||||
}
|
||||
|
|
79
src/html.rs
79
src/html.rs
|
@ -12,66 +12,26 @@ use jotdown::OrderedListNumbering::*;
|
|||
use jotdown::SpanLinkType;
|
||||
|
||||
use crate::template;
|
||||
use crate::template::Template;
|
||||
use crate::template::TemplateRenderer;
|
||||
|
||||
// {{{ Renderer
|
||||
/// Render events into a string.
|
||||
pub fn render_to_string<'s, I>(events: I) -> anyhow::Result<String>
|
||||
where
|
||||
I: Iterator<Item = Event<'s>>,
|
||||
{
|
||||
let mut s = String::new();
|
||||
Renderer::new()?.push(events, &mut s)?;
|
||||
Ok(s)
|
||||
}
|
||||
/// Render djot content as HTML.
|
||||
pub fn render_html<'s>(
|
||||
mut events: impl Iterator<Item = Event<'s>>,
|
||||
mut out: impl std::fmt::Write,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut w = Writer::new();
|
||||
events.try_for_each(|e| w.render_event(&e, &mut out))?;
|
||||
w.render_epilogue(&mut out)?;
|
||||
|
||||
/// [`Render`] implementor that writes HTML output.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Renderer {
|
||||
templates: BuiltinTempaltes,
|
||||
}
|
||||
|
||||
impl Renderer {
|
||||
pub fn new() -> anyhow::Result<Self> {
|
||||
Ok(Self {
|
||||
templates: BuiltinTempaltes::new()?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn push<'s>(
|
||||
&self,
|
||||
mut events: impl Iterator<Item = Event<'s>>,
|
||||
mut out: impl std::fmt::Write,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut w = Writer::new(self);
|
||||
events.try_for_each(|e| w.render_event(&e, &mut out))?;
|
||||
w.render_epilogue(&mut out)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ Bring in templates
|
||||
#[derive(Clone, Debug)]
|
||||
struct BuiltinTempaltes {
|
||||
aside_template: Template,
|
||||
}
|
||||
|
||||
impl BuiltinTempaltes {
|
||||
fn new() -> anyhow::Result<Self> {
|
||||
Ok(BuiltinTempaltes {
|
||||
aside_template: template!("./templates/aside.html")?,
|
||||
})
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
// }}}
|
||||
|
||||
struct Writer<'s> {
|
||||
pub struct Writer<'s> {
|
||||
list_tightness: Vec<bool>,
|
||||
states: Vec<State<'s>>,
|
||||
footnotes: Footnotes<'s>,
|
||||
renderer: &'s Renderer,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -84,20 +44,20 @@ enum State<'s> {
|
|||
}
|
||||
|
||||
impl<'s> Writer<'s> {
|
||||
fn new(renderer: &'s Renderer) -> Self {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
list_tightness: Vec::new(),
|
||||
states: Vec::new(),
|
||||
footnotes: Footnotes::default(),
|
||||
renderer,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::single_match)]
|
||||
fn render_event<W>(&mut self, e: &Event<'s>, mut out: W) -> anyhow::Result<()>
|
||||
where
|
||||
W: std::fmt::Write,
|
||||
{
|
||||
pub fn render_event(
|
||||
&mut self,
|
||||
e: &Event<'s>,
|
||||
mut out: impl std::fmt::Write,
|
||||
) -> anyhow::Result<()> {
|
||||
// {{{ Handle footnotes
|
||||
if let Event::Start(Container::Footnote { label }, ..) = e {
|
||||
self.footnotes.start(label, Vec::new());
|
||||
|
@ -157,7 +117,7 @@ impl<'s> Writer<'s> {
|
|||
}
|
||||
|
||||
match &c {
|
||||
Container::RawBlock { .. } => unreachable!(),
|
||||
Container::RawBlock { .. } => {}
|
||||
Container::RawInline { .. } => unreachable!(),
|
||||
Container::Footnote { .. } => unreachable!(),
|
||||
// {{{ List
|
||||
|
@ -226,7 +186,7 @@ impl<'s> Writer<'s> {
|
|||
})?;
|
||||
|
||||
let mut renderer =
|
||||
TemplateRenderer::new(&self.renderer.templates.aside_template);
|
||||
TemplateRenderer::new(template!("templates/aside.html")?);
|
||||
|
||||
while let Some(label) = renderer.current(&mut out)? {
|
||||
if label == "character" {
|
||||
|
@ -378,7 +338,7 @@ impl<'s> Writer<'s> {
|
|||
}
|
||||
|
||||
match c {
|
||||
Container::RawBlock { .. } => unreachable!(),
|
||||
Container::RawBlock { .. } => {}
|
||||
Container::RawInline { .. } => unreachable!(),
|
||||
Container::Footnote { .. } => unreachable!(),
|
||||
// {{{ List
|
||||
|
@ -463,7 +423,6 @@ impl<'s> Writer<'s> {
|
|||
Some(State::TextOnly) => write_attr(s, &mut out)?,
|
||||
Some(State::Raw) => out.write_str(s)?,
|
||||
Some(State::Math(display)) => {
|
||||
// let string: String = format!("{}{s}{}", delim, delim);
|
||||
let config = pulldown_latex::RenderConfig {
|
||||
display_mode: {
|
||||
use pulldown_latex::config::DisplayMode::*;
|
||||
|
|
93
src/main.rs
93
src/main.rs
|
@ -1,14 +1,15 @@
|
|||
use std::fs::{self};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::Context;
|
||||
use html::Renderer;
|
||||
use anyhow::{anyhow, Context};
|
||||
use html::render_html;
|
||||
use template::TemplateRenderer;
|
||||
|
||||
mod html;
|
||||
mod metadata;
|
||||
mod template;
|
||||
mod tex;
|
||||
|
||||
fn copy_recursively(from: &Path, to: &Path) -> anyhow::Result<()> {
|
||||
Command::new("cp").arg("-r").arg(from).arg(to).output()?;
|
||||
|
@ -16,9 +17,68 @@ fn copy_recursively(from: &Path, to: &Path) -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// {{{ Generate single page
|
||||
fn generate_page(path: &Path) -> anyhow::Result<()> {
|
||||
let content_path = PathBuf::from_str("content")?.join(path);
|
||||
|
||||
let djot_input = std::fs::read_to_string(content_path).unwrap();
|
||||
let mut out = String::new();
|
||||
|
||||
let page_template = template!("templates/page.html")?;
|
||||
let mut page_renderer = TemplateRenderer::new(page_template);
|
||||
|
||||
// let events = jotdown::Parser::new(&djot_input);
|
||||
// let meta = PageMetadata::new(events)?;
|
||||
// println!("Metadata: {meta:?}");
|
||||
|
||||
while let Some(label) = page_renderer.next(&mut out)? {
|
||||
if label == "content" {
|
||||
let events = jotdown::Parser::new(&djot_input);
|
||||
render_html(events, &mut out)?;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
page_renderer.finish(&mut out)?;
|
||||
|
||||
let mut out_path = PathBuf::from_str("dist")?.join(path);
|
||||
out_path.set_file_name(format!(
|
||||
"{}.html",
|
||||
path.file_stem()
|
||||
.ok_or_else(|| anyhow!("Empty filestem encountered"))?
|
||||
.to_str()
|
||||
.unwrap()
|
||||
));
|
||||
std::fs::write(out_path, out).with_context(|| "Failed to write `arcaea.html` post")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// }}}
|
||||
// {{{ Generate an entire directory
|
||||
fn generate_dir(path: &Path) -> anyhow::Result<()> {
|
||||
let content_path = PathBuf::from_str("content")?.join(path);
|
||||
let out_path = PathBuf::from_str("dist")?.join(path);
|
||||
fs::create_dir_all(out_path)
|
||||
.with_context(|| format!("Could not generate directory {path:?}"))?;
|
||||
|
||||
for file in fs::read_dir(content_path)? {
|
||||
let file_path = file?.path();
|
||||
let path = path.join(file_path.file_name().unwrap());
|
||||
if file_path.is_dir() {
|
||||
generate_dir(&path)?;
|
||||
} else {
|
||||
generate_page(&path)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// }}}
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let dist_path = PathBuf::from_str("dist")?;
|
||||
let public_path = PathBuf::from_str("public")?;
|
||||
let dist_path = PathBuf::from_str("dist")?;
|
||||
|
||||
if dist_path.exists() {
|
||||
std::fs::remove_dir_all(&dist_path).with_context(|| "Cannot delete `dist` directory")?;
|
||||
|
@ -31,30 +91,7 @@ fn main() -> anyhow::Result<()> {
|
|||
.with_context(|| "Cannot copy `public` -> `dist`")?;
|
||||
}
|
||||
|
||||
// {{{ Generate contents
|
||||
let djot_input = std::fs::read_to_string("content/arcaea.dj").unwrap();
|
||||
let mut out = String::new();
|
||||
let page_template = template!("templates/page.html")?;
|
||||
let mut page_renderer = TemplateRenderer::new(&page_template);
|
||||
|
||||
while let Some(label) = page_renderer.next(&mut out)? {
|
||||
if label == "content" {
|
||||
let events = jotdown::Parser::new(&djot_input);
|
||||
let html = Renderer::new()?;
|
||||
html.push(events, &mut out)?;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
page_renderer.finish(&mut out)?;
|
||||
// }}}
|
||||
|
||||
let posts_dir = dist_path.join("posts");
|
||||
std::fs::create_dir(&posts_dir).with_context(|| "Cannot create `dist/posts` directory")?;
|
||||
|
||||
std::fs::write(posts_dir.join("arcaea.html"), out)
|
||||
.with_context(|| "Failed to write `arcaea.html` post")?;
|
||||
generate_dir(&PathBuf::new())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
138
src/metadata.rs
Normal file
138
src/metadata.rs
Normal file
|
@ -0,0 +1,138 @@
|
|||
#![allow(dead_code)]
|
||||
use std::fmt::Write;
|
||||
|
||||
use anyhow::{anyhow, bail, Context};
|
||||
use jotdown::{Container, Event};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::html;
|
||||
|
||||
#[derive(Deserialize, Debug, Default)]
|
||||
pub struct PageConfig {
|
||||
created_at: Option<String>,
|
||||
}
|
||||
|
||||
impl PageConfig {
|
||||
/// Merge another config into the current one. Might error out on duplicate values.
|
||||
fn merge(&mut self, other: PageConfig) -> anyhow::Result<()> {
|
||||
match &self.created_at {
|
||||
None => self.created_at = other.created_at,
|
||||
Some(first_created) => {
|
||||
if let Some(second_created) = other.created_at {
|
||||
if second_created != *first_created {
|
||||
bail!("Conflicting values for `created_at` page attribute: {first_created} and {second_created}");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PageMetadata {
|
||||
title: Heading,
|
||||
config: PageConfig,
|
||||
toc: Vec<Heading>,
|
||||
}
|
||||
|
||||
impl PageMetadata {
|
||||
pub fn new<'s>(mut events: impl Iterator<Item = Event<'s>>) -> anyhow::Result<Self> {
|
||||
let mut w = Writer::new();
|
||||
events.try_for_each(|e| w.render_event(&e))?;
|
||||
|
||||
let title = w
|
||||
.toc
|
||||
.first()
|
||||
.ok_or_else(|| anyhow!("No heading found to infer title from"))?;
|
||||
|
||||
Ok(Self {
|
||||
title: title.to_owned(),
|
||||
config: w.config,
|
||||
toc: w.toc,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Heading {
|
||||
pub level: u8,
|
||||
pub id: String,
|
||||
pub text: String,
|
||||
pub html: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
enum State {
|
||||
Toplevel,
|
||||
Heading,
|
||||
Toml,
|
||||
}
|
||||
|
||||
struct Writer<'s> {
|
||||
html_renderer: html::Writer<'s>,
|
||||
config: PageConfig,
|
||||
toc: Vec<Heading>,
|
||||
toml_text: String,
|
||||
state: State,
|
||||
}
|
||||
|
||||
impl<'s> Writer<'s> {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
html_renderer: html::Writer::new(),
|
||||
config: PageConfig::default(),
|
||||
toc: Vec::new(),
|
||||
toml_text: String::new(),
|
||||
state: State::Toplevel,
|
||||
}
|
||||
}
|
||||
|
||||
fn render_event(&mut self, e: &jotdown::Event<'s>) -> anyhow::Result<()> {
|
||||
match e {
|
||||
Event::Start(Container::Heading { level, id, .. }, _) => {
|
||||
assert_eq!(self.state, State::Toplevel);
|
||||
self.state = State::Heading;
|
||||
self.toc.push(Heading {
|
||||
level: *level as u8,
|
||||
id: id.to_string(),
|
||||
text: String::new(),
|
||||
html: String::new(),
|
||||
})
|
||||
}
|
||||
Event::End(Container::Heading { .. }) => {
|
||||
assert_eq!(self.state, State::Heading);
|
||||
self.state = State::Toplevel;
|
||||
}
|
||||
Event::Start(Container::RawBlock { format: "toml" }, _) => {
|
||||
assert_eq!(self.state, State::Toplevel);
|
||||
self.state = State::Toml
|
||||
}
|
||||
Event::End(Container::RawBlock { format: "toml" }) => {
|
||||
assert_eq!(self.state, State::Toml);
|
||||
self.state = State::Toplevel;
|
||||
|
||||
let config: PageConfig = toml::from_str(&self.toml_text)
|
||||
.with_context(|| "Failed to parse page config in TOML format")?;
|
||||
self.config.merge(config)?;
|
||||
|
||||
self.toml_text.clear();
|
||||
}
|
||||
Event::Str(str) if self.state == State::Toml => {
|
||||
self.toml_text.write_str(str)?;
|
||||
}
|
||||
other if self.state == State::Heading => {
|
||||
let last_heading = self.toc.last_mut().unwrap();
|
||||
self.html_renderer.render_event(e, &mut last_heading.html)?;
|
||||
|
||||
if let Event::Str(str) = other {
|
||||
last_heading.text.write_str(str)?;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,25 +1,23 @@
|
|||
use std::fmt::Write;
|
||||
|
||||
use anyhow::bail;
|
||||
|
||||
// {{{ Templates & stops
|
||||
#[derive(Clone, Debug)]
|
||||
struct Stop {
|
||||
label: String,
|
||||
struct Stop<'s> {
|
||||
label: &'s str,
|
||||
start: usize,
|
||||
length: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Template {
|
||||
text: String,
|
||||
stops: Vec<Stop>,
|
||||
pub struct Template<'s> {
|
||||
text: &'s str,
|
||||
stops: Vec<Stop<'s>>,
|
||||
}
|
||||
|
||||
impl Template {
|
||||
impl<'s> Template<'s> {
|
||||
// {{{ Parse template
|
||||
#[allow(clippy::iter_nth_zero)]
|
||||
pub fn parse(text: String) -> anyhow::Result<Template> {
|
||||
pub fn parse(text: &'s str) -> anyhow::Result<Template<'s>> {
|
||||
let mut stops = Vec::new();
|
||||
|
||||
let open_stop = "{{";
|
||||
|
@ -27,25 +25,23 @@ impl Template {
|
|||
|
||||
let mut current_stop: Option<Stop> = None;
|
||||
let mut prev_ix = None;
|
||||
for (ix, c) in text.char_indices() {
|
||||
for (ix, _) in text.char_indices() {
|
||||
if let Some(prev) = prev_ix {
|
||||
// This char, together with the previous one
|
||||
let last_two = &text[prev..=ix];
|
||||
if close_stop == last_two {
|
||||
if let Some(mut stop) = current_stop.take() {
|
||||
stop.label.pop().unwrap();
|
||||
// I think this is safe, as } is ascii
|
||||
// I think this is safe, as { and } are ascii
|
||||
stop.label = &text[stop.start + 2..=ix - 2];
|
||||
stop.length = ix + 1 - stop.start;
|
||||
stops.push(stop);
|
||||
}
|
||||
} else if open_stop == last_two && current_stop.is_none() {
|
||||
current_stop = Some(Stop {
|
||||
label: String::new(),
|
||||
label: "",
|
||||
start: prev,
|
||||
length: 0,
|
||||
});
|
||||
} else if let Some(stop) = current_stop.as_mut() {
|
||||
stop.label.write_char(c)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +63,7 @@ enum RendererState {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TemplateRenderer<'a> {
|
||||
template: &'a Template,
|
||||
template: &'a Template<'a>,
|
||||
state: RendererState,
|
||||
}
|
||||
|
||||
|
@ -84,7 +80,7 @@ impl<'a> TemplateRenderer<'a> {
|
|||
pub fn current(&mut self, w: impl std::fmt::Write) -> anyhow::Result<Option<&'a str>> {
|
||||
let current_label = match self.state {
|
||||
RendererState::Started => self.next(w)?,
|
||||
RendererState::InStop(ix) => Some(self.template.stops[ix].label.as_str()),
|
||||
RendererState::InStop(ix) => Some(self.template.stops[ix].label),
|
||||
RendererState::Finished => None,
|
||||
};
|
||||
|
||||
|
@ -125,7 +121,7 @@ impl<'a> TemplateRenderer<'a> {
|
|||
w.write_str(&self.template.text[current_pos..next_pos])?;
|
||||
|
||||
let current_label = match self.state {
|
||||
RendererState::InStop(ix) => Some(self.template.stops[ix].label.as_str()),
|
||||
RendererState::InStop(ix) => Some(self.template.stops[ix].label),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
|
@ -150,8 +146,13 @@ impl<'a> TemplateRenderer<'a> {
|
|||
#[macro_export]
|
||||
macro_rules! template {
|
||||
($path:literal) => {{
|
||||
use once_cell::sync::OnceCell;
|
||||
use $crate::template::Template;
|
||||
|
||||
static TEMPLATE_TEXT: &str = include_str!($path);
|
||||
$crate::template::Template::parse(TEMPLATE_TEXT.to_owned())
|
||||
static CELL: OnceCell<Template<'static>> = OnceCell::new();
|
||||
|
||||
CELL.get_or_try_init(|| Template::parse(TEMPLATE_TEXT))
|
||||
}};
|
||||
}
|
||||
// }}}
|
||||
|
|
32
src/tex.rs
32
src/tex.rs
|
@ -1,32 +0,0 @@
|
|||
use anyhow::anyhow;
|
||||
use cached::{proc_macro::io_cached, DiskCache};
|
||||
|
||||
fn make_cache() -> DiskCache<&'static str, String> {
|
||||
DiskCache::new("tex-cache")
|
||||
.set_disk_directory("/home/moon/.cache/moonythm")
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[io_cached(
|
||||
disk = true,
|
||||
map_error = r##"|err| anyhow::Error::from(err)"##,
|
||||
create = r"{ make_cache() }"
|
||||
)]
|
||||
pub fn compile_tex(string: &str) -> Result<String, anyhow::Error> {
|
||||
let res = std::process::Command::new("latexmlmath")
|
||||
.arg("--preload=amsfonts")
|
||||
.arg("--strict")
|
||||
.arg("--quiet")
|
||||
.arg(string)
|
||||
.output()
|
||||
.expect("failed to execute latexmathml process");
|
||||
|
||||
if res.status.success() {
|
||||
let output = String::from_utf8_lossy(&res.stdout);
|
||||
Ok(output.trim().to_owned())
|
||||
} else {
|
||||
let output = String::from_utf8_lossy(&res.stderr);
|
||||
Err(anyhow!("{}", output.trim()))
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue