Compare commits
No commits in common. "8314c2e48df978c1e55fa6e93e6f938917ba3da8" and "3a82e64901ca3eb84881af8a612b8f52767e1327" have entirely different histories.
8314c2e48d
...
3a82e64901
569
Cargo.lock
generated
569
Cargo.lock
generated
|
@ -38,55 +38,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
|
@ -106,45 +57,18 @@ dependencies = [
|
|||
"unscanny",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.15.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.1.6"
|
||||
|
@ -174,7 +98,7 @@ dependencies = [
|
|||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-targets 0.52.4",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -214,58 +138,12 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim 0.11.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||
|
||||
[[package]]
|
||||
name = "codemap"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e769b5c8c8283982a987c6e948e540254f1058d5a74b8794914d4ef5fc2a24"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
|
||||
|
||||
[[package]]
|
||||
name = "copy_dir"
|
||||
version = "0.1.3"
|
||||
|
@ -281,46 +159,12 @@ version = "0.8.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.14.4"
|
||||
|
@ -341,7 +185,7 @@ dependencies = [
|
|||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim 0.10.0",
|
||||
"strsim",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
|
@ -356,12 +200,6 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "data-encoding"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder"
|
||||
version = "0.12.0"
|
||||
|
@ -393,16 +231,6 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "displaydoc"
|
||||
version = "0.2.4"
|
||||
|
@ -435,18 +263,6 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
|
@ -462,25 +278,6 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fsevent-sys"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
|
@ -593,12 +390,6 @@ version = "0.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "html-escape"
|
||||
version = "0.2.13"
|
||||
|
@ -608,23 +399,6 @@ dependencies = [
|
|||
"utf8-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||
|
||||
[[package]]
|
||||
name = "hypertext"
|
||||
version = "0.5.0"
|
||||
|
@ -701,32 +475,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"inotify-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify-sys"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
|
@ -764,26 +512,6 @@ dependencies = [
|
|||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c"
|
||||
dependencies = [
|
||||
"kqueue-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue-sys"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lasso"
|
||||
version = "0.7.2"
|
||||
|
@ -834,45 +562,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
name = "npezza93-tree-sitter-haskell"
|
||||
version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
checksum = "cd44dfc09a37bafbed1c28622c662be9b8fb1aaaad0444688370eae11e3d54b0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "6.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"crossbeam-channel",
|
||||
"filetime",
|
||||
"fsevent-sys",
|
||||
"inotify",
|
||||
"kqueue",
|
||||
"libc",
|
||||
"log",
|
||||
"mio",
|
||||
"walkdir",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify-debouncer-mini"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d40b221972a1fc5ef4d858a2f671fb34c75983eb385463dff3780eeff6a9d43"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"log",
|
||||
"notify",
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1005,7 +701,7 @@ name = "pulldown-cmark"
|
|||
version = "0.10.0"
|
||||
source = "git+https://github.com/pulldown-cmark/pulldown-cmark.git?branch=branch_0.11#2540d4095d5f94fd972c93b927e9bec83b0c5079"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags",
|
||||
"getopts",
|
||||
"memchr",
|
||||
"pulldown-cmark-escape",
|
||||
|
@ -1076,15 +772,6 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.4"
|
||||
|
@ -1193,17 +880,6 @@ dependencies = [
|
|||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.11"
|
||||
|
@ -1216,7 +892,6 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"camino",
|
||||
"chrono",
|
||||
"clap",
|
||||
"emojis",
|
||||
"glob",
|
||||
"grass",
|
||||
|
@ -1224,27 +899,19 @@ dependencies = [
|
|||
"hayagriva",
|
||||
"hypertext",
|
||||
"katex",
|
||||
"notify",
|
||||
"notify-debouncer-mini",
|
||||
"npezza93-tree-sitter-haskell",
|
||||
"once_cell",
|
||||
"pulldown-cmark",
|
||||
"regex",
|
||||
"serde",
|
||||
"tree-sitter",
|
||||
"tree-sitter-css",
|
||||
"tree-sitter-haskell",
|
||||
"tree-sitter-highlight",
|
||||
"tree-sitter-html",
|
||||
"tree-sitter-javascript",
|
||||
"tree-sitter-md",
|
||||
"tree-sitter-python",
|
||||
"tree-sitter-query",
|
||||
"tree-sitter-regex",
|
||||
"tree-sitter-rust",
|
||||
"tree-sitter-scss",
|
||||
"tree-sitter-toml-ng",
|
||||
"tree-sitter-typescript",
|
||||
"tungstenite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1253,12 +920,6 @@ version = "0.10.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.26.2"
|
||||
|
@ -1274,7 +935,7 @@ version = "0.26.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946"
|
||||
dependencies = [
|
||||
"heck 0.4.1",
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
|
@ -1317,18 +978,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.59"
|
||||
version = "1.0.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
|
||||
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.59"
|
||||
version = "1.0.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
|
||||
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1361,39 +1022,19 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||
|
||||
[[package]]
|
||||
name = "tree-sitter"
|
||||
version = "0.22.6"
|
||||
version = "0.22.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df7cc499ceadd4dcdf7ec6d4cbc34ece92c3fa07821e287aedecd4416c516dca"
|
||||
checksum = "688200d842c76dd88f9a7719ecb0483f79f5a766fb1c100756d5d8a059abc71b"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-css"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2f806f96136762b0121f5fdd7172a3dcd8f42d37a2f23ed7f11b35895e20eb4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-haskell"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef25a7e6c73cc1cbe0c0b7dbd5406e7b3485b370bd61c5d8d852ae0781f9bf9a"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-highlight"
|
||||
version = "0.22.6"
|
||||
version = "0.22.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaca0fe34fa96eec6aaa8e63308dbe1bafe65a6317487c287f93938959b21907"
|
||||
checksum = "9442daef896b114ed618a5e11c9ba9663796ab3600e544d57f2dc980fa0d2d78"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"regex",
|
||||
|
@ -1401,21 +1042,11 @@ dependencies = [
|
|||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-html"
|
||||
version = "0.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95b3492b08a786bf5cc79feb0ef2ff3b115d5174364e0ddfd7860e0b9b088b53"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-javascript"
|
||||
version = "0.21.2"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "080880908cb6e8d03cb9ceaeecec9a3d3a2f4e122e74642509bbb22aaefd991b"
|
||||
checksum = "26eca1925fd9518f9439ea122e3f3395abb3fcfc4b0841ef94eeef934871ec59"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
|
@ -1444,17 +1075,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "tree-sitter-query"
|
||||
version = "0.2.1"
|
||||
source = "git+https://github.com/tree-sitter-grammars/tree-sitter-query?rev=87b1a3d#87b1a3dc6c5a76c5cedcdfc60efe75805468cb90"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-regex"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ff1286fe9651b2797484839ffa37aa76c8618d4ccb6836d7e31765dfd60c0d5"
|
||||
source = "git+https://github.com/tree-sitter-grammars/tree-sitter-query?rev=608c01187fb9f525a1e4cf585bb63d73dea280b7#608c01187fb9f525a1e4cf585bb63d73dea280b7"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
|
@ -1480,51 +1101,6 @@ dependencies = [
|
|||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-toml-ng"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "695d20cd83acf16c02c773f03e76d7b43b19883d4e2ce3652a8f06b5e0da7455"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-typescript"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f07523e51e3b88529360a89038c0cca7ee877db40a40141514eece8b4cddcbb4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tungstenite"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"data-encoding",
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
"rand",
|
||||
"sha1",
|
||||
"thiserror",
|
||||
"url",
|
||||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "unic-langid"
|
||||
version = "0.9.4"
|
||||
|
@ -1610,24 +1186,12 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf-8"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||
|
||||
[[package]]
|
||||
name = "utf8-width"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
|
@ -1741,40 +1305,7 @@ version = "0.52.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1783,93 +1314,51 @@ version = "0.52.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.4",
|
||||
"windows_aarch64_msvc 0.52.4",
|
||||
"windows_i686_gnu 0.52.4",
|
||||
"windows_i686_msvc 0.52.4",
|
||||
"windows_x86_64_gnu 0.52.4",
|
||||
"windows_x86_64_gnullvm 0.52.4",
|
||||
"windows_x86_64_msvc 0.52.4",
|
||||
"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_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
|
||||
|
||||
[[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_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
|
||||
|
||||
[[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_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
|
||||
|
||||
[[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_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.4"
|
||||
|
|
20
Cargo.toml
20
Cargo.toml
|
@ -6,7 +6,6 @@ edition = "2021"
|
|||
[dependencies]
|
||||
camino = "1.1.6"
|
||||
chrono = "0.4.35"
|
||||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
emojis = "0.6.1"
|
||||
glob = "0.3.1"
|
||||
grass = { version = "0.13.2", default-features = false, features = ["random"] }
|
||||
|
@ -18,11 +17,6 @@ once_cell = "1.19.0"
|
|||
regex = "1.10.4"
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
|
||||
# Watch
|
||||
notify = "6.1.1"
|
||||
notify-debouncer-mini = "0.4.1"
|
||||
tungstenite = "0.21.0"
|
||||
|
||||
# Markdown
|
||||
pulldown-cmark = { git = "https://github.com/pulldown-cmark/pulldown-cmark.git", branch = "branch_0.11" }
|
||||
|
||||
|
@ -32,15 +26,15 @@ tree-sitter-highlight = "0.22"
|
|||
|
||||
# Treesitter languages
|
||||
# tree-sitter-astro = { git = "https://github.com/virchau13/tree-sitter-astro.git", rev = "e924787e12e8a03194f36a113290ac11d6dc10f3" }
|
||||
tree-sitter-css = "0.21"
|
||||
tree-sitter-haskell = "0.21"
|
||||
tree-sitter-html = "0.20.3"
|
||||
# tree-sitter-css = "0.20.0"
|
||||
# tree-sitter-haskell = { git = "https://github.com/tree-sitter/tree-sitter-haskell", rev = "1da347c88599faad7964e63facead5d163ac7dba" }
|
||||
npezza93-tree-sitter-haskell = "0.15.1"
|
||||
tree-sitter-javascript = "0.21"
|
||||
tree-sitter-md = "0.2"
|
||||
tree-sitter-python = "0.21"
|
||||
tree-sitter-regex = "0.21"
|
||||
tree-sitter-query = { git = "https://github.com/tree-sitter-grammars/tree-sitter-query", rev = "608c01187fb9f525a1e4cf585bb63d73dea280b7" }
|
||||
# tree-sitter-regex = "0.20.0"
|
||||
tree-sitter-rust = "0.21"
|
||||
tree-sitter-scss = "1"
|
||||
tree-sitter-query = { git = "https://github.com/tree-sitter-grammars/tree-sitter-query", rev = "87b1a3d" }
|
||||
tree-sitter-toml-ng = "0.6"
|
||||
tree-sitter-typescript = "0.21"
|
||||
# tree-sitter-toml = "0.20.0"
|
||||
# tree-sitter-typescript = "0.20.5"
|
||||
|
|
11
Makefile
11
Makefile
|
@ -1,11 +1,8 @@
|
|||
build:
|
||||
cargo run --release
|
||||
|
||||
watch:
|
||||
cargo run --release -- watch
|
||||
|
||||
serve:
|
||||
python -m http.server -d ./dist
|
||||
cargo run
|
||||
|
||||
deploy: build
|
||||
rsync -Pavzq ./dist/ kamoshi:/var/www/kamoshi.org --delete
|
||||
|
||||
serve:
|
||||
python -m http.server -d ./dist
|
||||
|
|
|
@ -11,22 +11,22 @@ date: 2023-12-17T12:47:29.753Z
|
|||
あくる日、親に引かれている橇で乗っている嬉しそうな子供を見た。
|
||||
あらゆる公園が白くなって、白すぎて見えた。
|
||||
|
||||
![白すぎる公園](IMG_20231204_105929.jpg)
|
||||
![白すぎる公園](@assets/posts/hisasiburi-no-toukou/IMG_20231204_105929.jpg)
|
||||
|
||||
その時から雪が全部解けちゃった。
|
||||
|
||||
最近、ヴロツワフではクリスマスマーケットが始まっているので、見に行った。
|
||||
そこでたくさんの人がいて、いろんな出店もあり、色々なものを買って楽しむことができた。
|
||||
|
||||
![眩しいクリスマスライト](IMG_20231209_182036.jpg)
|
||||
![眩しいクリスマスライト](@assets/posts/hisasiburi-no-toukou/IMG_20231209_182036.jpg)
|
||||
|
||||
もっと進んでいくと、大きなレストランみたいなビルに出くわしたんだ。
|
||||
あのビルでは、「グジャニエッツ」という飲み物を買って楽しむことができた。
|
||||
|
||||
![グジャニエッツのビル](IMG_20231209_183410.jpg)
|
||||
![グジャニエッツのビル](@assets/posts/hisasiburi-no-toukou/IMG_20231209_183410.jpg)
|
||||
|
||||
グジャニエッツとは、ポーランドの伝統的な温かいスパイス入りの飲み物。
|
||||
通常は赤ワインやオレンジ、シナモン、クローブが使われる。
|
||||
|
||||
クリスマスマーケットってとても素晴らしいイベントの一つだけど、
|
||||
値段が高く過ぎるからあんまり買い物しなかったwww
|
||||
クリスマスマーケットってとても素晴らしいイベントの一つだけど、値段が高く過ぎるからあんまり買い物しなかったwww
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
---
|
||||
title: SSG that packs a punch
|
||||
date: 2024-05-02T21:17:43Z
|
||||
desc: >
|
||||
Let's create a yet another SSG from scratch, because that's just
|
||||
what this world needs!
|
||||
---
|
||||
|
||||
Long story short, I decided to write my own static site generator in Rust. The
|
||||
language choice is purely pragmatic and at first I considered using Haskell,
|
||||
but alas the Rust ecosystem seems better suited for this task. Rust is not only
|
||||
a very ergonomic and efficient language, but also has lots of high quality
|
||||
packages to choose from.
|
||||
|
||||
|
||||
## The why
|
||||
|
||||
I used many different SSGs made by other people, but over the years I realized
|
||||
that they simply can't cut it for me. I used simple generators like Hugo, which
|
||||
offer little to no support for JavaScript. Eventually I ended up using Astro,
|
||||
which treats JavaScript as a first class citizen.
|
||||
|
||||
The thing I didn't like the most about Hugo, was that it used some strange,
|
||||
clumsy templating language, which was quite annoying to use, but I enjoyed the
|
||||
fact that nearly everything was built in, and the generation speed was fast.
|
||||
When it comes to Astro, I enjoyed the fact that in templates you could write
|
||||
TypeScript, as well the great flexibility with which you could arrange the
|
||||
structure of the website. However, the JavaScript ecosystem is a mess, so using
|
||||
that was not that pleasant overall.
|
||||
|
||||
Astro was closer to what I wanted, but not quite there.
|
||||
|
||||
With time, I realized that what I truly need is the flexibility of Astro,
|
||||
coupled with a different language. Ideally a fun one like Haskell or Rust.
|
||||
|
||||
I started looking around and came across a couple of [blog
|
||||
posts](https://arne.me/blog/write-your-own-ssg) detailing how people made the
|
||||
move to their custom generator. This was the inspiration I needed.
|
||||
|
||||
I thought that even if it ends up quite bad in the end, at least I'll learn
|
||||
*something*. And it would be a good chance to learn more Rust, so that's a win
|
||||
right there. With Haskell it would be an ever bigger win, but hey, can't have
|
||||
everything in life.
|
||||
|
||||
|
||||
## The what
|
||||
|
||||
When trying to write a computer program it's a good idea to think about what it
|
||||
should ideally be able to do. We should at least know the sketch of the
|
||||
requirements before we start, so that we know if we are getting any closer to
|
||||
the goal as we keep writing it.
|
||||
|
||||
When it comes to my generator I think I would like for it to have these
|
||||
qualities:
|
||||
- The generator must be *simple* and *extensible*
|
||||
- HTML shouldn't be generated using some bespoke templating language, I should
|
||||
have the full ecosystem at my disposal.
|
||||
- Ideally I should not be limited to Markdown, I should be able to use
|
||||
different file text formats as needed, e.g. Djot, AsciiDoc.
|
||||
- Code snippets should be highlighted using Tree-sitter.
|
||||
- Math should be pre-rendered via MathML without any client-side JavaScript.
|
||||
- There should be a way to render different pages differently, some collections
|
||||
of Markdown files should output different looking pages.
|
||||
- I should be able to generate HTML pages that don't have any original source
|
||||
files related to them, think dynamically generated lists of pages, tags.
|
||||
|
||||
With these requirements in mind I decided to go with Rust, because Rust has
|
||||
lots of up-to-date parsers that can be used while building a generator. On top
|
||||
of that I can use Tree-sitter without any need for complicated FFI or using
|
||||
outdated libraries in other ecosystems.
|
||||
|
||||
When moving to a non-JavaScript backend for building SSG some issues related to
|
||||
JavaScript inevitably start to crop up. There is some friction with using tools
|
||||
like ESBuild, but I feel like the benefits far outweigh the challenges in the
|
||||
end.
|
||||
|
||||
|
||||
## The how
|
|
@ -241,3 +241,41 @@ scala
|
|||
### Rust
|
||||
|
||||
rust
|
||||
|
||||
|
||||
## Bibliography
|
||||
|
||||
:::bibtex
|
||||
@inproceedings{10.1145/1238844.1238856,
|
||||
author = {Hudak, Paul and Hughes, John and Peyton Jones, Simon and Wadler, Philip},
|
||||
title = {A History of Haskell: Being Lazy with Class},
|
||||
year = {2007},
|
||||
isbn = {9781595937667},
|
||||
publisher = {Association for Computing Machinery},
|
||||
address = {New York, NY, USA},
|
||||
url = {https://doi.org/10.1145/1238844.1238856},
|
||||
doi = {10.1145/1238844.1238856},
|
||||
abstract = {This paper describes the history of Haskell, including its genesis and principles, technical contributions, implementations and tools, and applications and impact.},
|
||||
booktitle = {Proceedings of the Third ACM SIGPLAN Conference on History of Programming Languages},
|
||||
pages = {12–1–12–55},
|
||||
location = {San Diego, California},
|
||||
series = {HOPL III}
|
||||
}
|
||||
|
||||
@online{youtube,
|
||||
title = {Escape from the ivory tower: the Haskell journey},
|
||||
date = {2017},
|
||||
organization = {Youtube},
|
||||
author = {Simon {Peyton Jones}},
|
||||
url = {https://youtu.be/re96UgMk6GQ},
|
||||
}
|
||||
|
||||
@book{skinner2023effective,
|
||||
title = {Effective Haskell: Solving Real-World Problems with Strongly Typed Functional Programming},
|
||||
author = {Skinner, R.},
|
||||
isbn = {9781680509342},
|
||||
series = {Pragmatic Bookshelf},
|
||||
year = {2023},
|
||||
publisher = {O'Reilly Media}
|
||||
}
|
||||
:::
|
|
@ -1,32 +0,0 @@
|
|||
@inproceedings{10.1145/1238844.1238856,
|
||||
author = {Hudak, Paul and Hughes, John and Peyton Jones, Simon and Wadler, Philip},
|
||||
title = {A History of Haskell: Being Lazy with Class},
|
||||
year = {2007},
|
||||
isbn = {9781595937667},
|
||||
publisher = {Association for Computing Machinery},
|
||||
address = {New York, NY, USA},
|
||||
url = {https://doi.org/10.1145/1238844.1238856},
|
||||
doi = {10.1145/1238844.1238856},
|
||||
abstract = {This paper describes the history of Haskell, including its genesis and principles, technical contributions, implementations and tools, and applications and impact.},
|
||||
booktitle = {Proceedings of the Third ACM SIGPLAN Conference on History of Programming Languages},
|
||||
pages = {12–1–12–55},
|
||||
location = {San Diego, California},
|
||||
series = {HOPL III}
|
||||
}
|
||||
|
||||
@online{youtube,
|
||||
title = {Escape from the ivory tower: the Haskell journey},
|
||||
date = {2017},
|
||||
organization = {Youtube},
|
||||
author = {Simon {Peyton Jones}},
|
||||
url = {https://youtu.be/re96UgMk6GQ},
|
||||
}
|
||||
|
||||
@book{skinner2023effective,
|
||||
title = {Effective Haskell: Solving Real-World Problems with Strongly Typed Functional Programming},
|
||||
author = {Skinner, R.},
|
||||
isbn = {9781680509342},
|
||||
series = {Pragmatic Bookshelf},
|
||||
year = {2023},
|
||||
publisher = {O'Reilly Media}
|
||||
}
|
|
@ -20,3 +20,46 @@ It's really powerful.
|
|||
## Summary
|
||||
|
||||
It was a pretty fun and interesting adventure, difficult at times, but worth it over all. In hindsight, I regret not paying more attention to mathematics right from the start. If I were to start over I would probably focus more on that and the theory of computation. If you're only just starting out then please remember, writing code is not computer science :cat:
|
||||
|
||||
|
||||
## Bibliography
|
||||
|
||||
:::bibtex
|
||||
@book{gamma1994design,
|
||||
title = {Design Patterns: Elements of Reusable Object-Oriented Software},
|
||||
author = {Gamma, E. and Helm, R. and Johnson, R. and Vlissides, J.},
|
||||
isbn = {9780321700698},
|
||||
lccn = {94034264},
|
||||
series = {Addison-Wesley Professional Computing Series},
|
||||
year = {1994},
|
||||
publisher = {Pearson Education}
|
||||
}
|
||||
|
||||
@book{chollet2021deep,
|
||||
title = {Deep Learning with Python, Second Edition},
|
||||
author = {Chollet, F.},
|
||||
isbn = {9781617296864},
|
||||
lccn = {2021425412},
|
||||
year = {2021},
|
||||
publisher = {Manning}
|
||||
}
|
||||
|
||||
@article{10.1145/360303.360308,
|
||||
author = {Tennent, R. D.},
|
||||
title = {The Denotational Semantics of Programming Languages},
|
||||
year = {1976},
|
||||
issue_date = {Aug. 1976},
|
||||
publisher = {Association for Computing Machinery},
|
||||
address = {New York, NY, USA},
|
||||
volume = {19},
|
||||
number = {8},
|
||||
issn = {0001-0782},
|
||||
url = {https://doi.org/10.1145/360303.360308},
|
||||
doi = {10.1145/360303.360308},
|
||||
journal = {Commun. ACM},
|
||||
month = {aug},
|
||||
pages = {437–453},
|
||||
numpages = {17},
|
||||
keywords = {semantics, GEDANKEN, store, environment, LOOP, continuation, applicative, higher-order function, imperative, programming language, theory of computation, recursive definition}
|
||||
}
|
||||
:::
|
|
@ -1,37 +0,0 @@
|
|||
@book{gamma1994design,
|
||||
title = {Design Patterns: Elements of Reusable Object-Oriented Software},
|
||||
author = {Gamma, E. and Helm, R. and Johnson, R. and Vlissides, J.},
|
||||
isbn = {9780321700698},
|
||||
lccn = {94034264},
|
||||
series = {Addison-Wesley Professional Computing Series},
|
||||
year = {1994},
|
||||
publisher = {Pearson Education}
|
||||
}
|
||||
|
||||
@book{chollet2021deep,
|
||||
title = {Deep Learning with Python, Second Edition},
|
||||
author = {Chollet, F.},
|
||||
isbn = {9781617296864},
|
||||
lccn = {2021425412},
|
||||
year = {2021},
|
||||
publisher = {Manning}
|
||||
}
|
||||
|
||||
@article{10.1145/360303.360308,
|
||||
author = {Tennent, R. D.},
|
||||
title = {The Denotational Semantics of Programming Languages},
|
||||
year = {1976},
|
||||
issue_date = {Aug. 1976},
|
||||
publisher = {Association for Computing Machinery},
|
||||
address = {New York, NY, USA},
|
||||
volume = {19},
|
||||
number = {8},
|
||||
issn = {0001-0782},
|
||||
url = {https://doi.org/10.1145/360303.360308},
|
||||
doi = {10.1145/360303.360308},
|
||||
journal = {Commun. ACM},
|
||||
month = {aug},
|
||||
pages = {437–453},
|
||||
numpages = {17},
|
||||
keywords = {semantics, GEDANKEN, store, environment, LOOP, continuation, applicative, higher-order function, imperative, programming language, theory of computation, recursive definition}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
title: 〜めが
|
||||
---
|
||||
|
||||
め and が can be used as pejorative suffixes at the end of a noun.
|
||||
|
||||
An example for め is:
|
||||
> [馬鹿]{ばか}め!
|
||||
|
||||
More can be read [here](https://japanese.stackexchange.com/questions/95851).
|
||||
|
||||
Similarly to め, が can be used as a suffix of insult:
|
||||
> この[小娘]{こむすめ}が(っ)!
|
||||
|
||||
More can be read [here](https://japanese.stackexchange.com/questions/60514).
|
||||
|
||||
Finally, the two can be used together as in:
|
||||
> あの…馬鹿者めが…
|
|
@ -1,7 +0,0 @@
|
|||
use std::fs;
|
||||
|
||||
|
||||
pub fn build_styles() {
|
||||
let css = grass::from_path("styles/styles.scss", &grass::Options::default()).unwrap();
|
||||
fs::write("dist/styles.css", css).unwrap();
|
||||
}
|
174
src/gen/load.rs
174
src/gen/load.rs
|
@ -1,111 +1,54 @@
|
|||
use std::collections::HashSet ;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
use camino::Utf8PathBuf;
|
||||
use glob::glob;
|
||||
use hayagriva::Library;
|
||||
|
||||
use crate::html::Linkable;
|
||||
|
||||
use super::Sack;
|
||||
|
||||
|
||||
/// Marks whether the item should be treated as a content page, converted into a standalone HTML
|
||||
/// page, or as a bundled asset.
|
||||
#[derive(Debug)]
|
||||
pub enum FileItemKind {
|
||||
/// Convert to `index.html`
|
||||
pub enum SourceKind {
|
||||
Index,
|
||||
/// Convert to a bundled asset
|
||||
Bundle,
|
||||
Asset,
|
||||
}
|
||||
|
||||
/// Metadata for a single item consumed by SSG.
|
||||
#[derive(Debug)]
|
||||
pub struct FileItem {
|
||||
/// Kind of an item
|
||||
pub kind: FileItemKind,
|
||||
/// Original source file location
|
||||
pub struct Source {
|
||||
pub kind: SourceKind,
|
||||
pub ext: String,
|
||||
pub dirs: Utf8PathBuf,
|
||||
pub path: Utf8PathBuf,
|
||||
}
|
||||
|
||||
/// Marks how the asset should be processed by the SSG
|
||||
pub enum AssetKind {
|
||||
/// Data renderable to HTML
|
||||
Html(Box<dyn Fn(&Sack) -> String>),
|
||||
/// Bibliographical data
|
||||
Bibtex(Library),
|
||||
/// Images
|
||||
Image,
|
||||
|
||||
fn to_source(path: Utf8PathBuf, exts: &HashSet<&'static str>) -> Source {
|
||||
let dir = path.parent().unwrap();
|
||||
let ext = path.extension().unwrap();
|
||||
|
||||
if !exts.contains(ext) {
|
||||
return Source {
|
||||
kind: SourceKind::Asset,
|
||||
ext: ext.to_owned(),
|
||||
dirs: dir.to_owned(),
|
||||
path,
|
||||
};
|
||||
}
|
||||
|
||||
/// Asset renderable by the SSG
|
||||
pub struct Asset {
|
||||
/// Kind of a processed asset
|
||||
pub kind: AssetKind,
|
||||
/// File metadata
|
||||
pub meta: FileItem,
|
||||
}
|
||||
let dirs = match path.file_stem().unwrap() {
|
||||
"index" => dir.to_owned(),
|
||||
name => dir.join(name),
|
||||
};
|
||||
|
||||
/// Dynamically generated asset not related to any disk file.
|
||||
pub struct Dynamic(pub Box<dyn Fn(&Sack) -> String>);
|
||||
|
||||
impl Dynamic {
|
||||
pub fn new(call: impl Fn(&Sack) -> String + 'static) -> Self {
|
||||
Self(Box::new(call))
|
||||
}
|
||||
}
|
||||
|
||||
pub enum OutputKind {
|
||||
Real(Asset),
|
||||
Fake(Dynamic),
|
||||
}
|
||||
|
||||
impl From<Asset> for OutputKind {
|
||||
fn from(value: Asset) -> Self {
|
||||
OutputKind::Real(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Dynamic> for OutputKind {
|
||||
fn from(value: Dynamic) -> Self {
|
||||
OutputKind::Fake(value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Renderable output
|
||||
pub struct Output {
|
||||
pub kind: OutputKind,
|
||||
pub path: Utf8PathBuf,
|
||||
/// Optional link to outputted page.
|
||||
pub link: Option<Linkable>,
|
||||
}
|
||||
|
||||
/// Variants used for filtering static assets.
|
||||
pub enum PipelineItem {
|
||||
/// Unclaimed file, unrecognized file extensions.
|
||||
Skip(FileItem),
|
||||
/// Data ready to be processed by SSG.
|
||||
Take(Output),
|
||||
}
|
||||
|
||||
impl From<FileItem> for PipelineItem {
|
||||
fn from(value: FileItem) -> Self {
|
||||
Self::Skip(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Output> for PipelineItem {
|
||||
fn from(value: Output) -> Self {
|
||||
Self::Take(value)
|
||||
Source {
|
||||
kind: SourceKind::Index,
|
||||
ext: ext.to_owned(),
|
||||
dirs,
|
||||
path,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn gather(pattern: &str, exts: &HashSet<&'static str>) -> Vec<PipelineItem> {
|
||||
pub fn gather(pattern: &str, exts: &HashSet<&'static str>) -> Vec<Source> {
|
||||
glob(pattern)
|
||||
.expect("Invalid glob pattern")
|
||||
.unwrap()
|
||||
.filter_map(|path| {
|
||||
let path = path.unwrap();
|
||||
let path = Utf8PathBuf::from_path_buf(path).expect("Filename is not valid UTF8");
|
||||
|
@ -115,62 +58,5 @@ pub fn gather(pattern: &str, exts: &HashSet<&'static str>) -> Vec<PipelineItem>
|
|||
false => Some(to_source(path, exts))
|
||||
}
|
||||
})
|
||||
.map(Into::into)
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
fn to_source(path: Utf8PathBuf, exts: &HashSet<&'static str>) -> FileItem {
|
||||
let hit = path.extension().map_or(false, |ext| exts.contains(ext));
|
||||
|
||||
let kind = match hit {
|
||||
true => FileItemKind::Index,
|
||||
false => FileItemKind::Bundle,
|
||||
};
|
||||
|
||||
FileItem {
|
||||
kind,
|
||||
path,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn render_all(items: &[Output]) {
|
||||
for item in items {
|
||||
let file = match &item.kind {
|
||||
OutputKind::Real(a) => Some(&a.meta.path),
|
||||
OutputKind::Fake(_) => None,
|
||||
};
|
||||
render(item, &Sack::new(items, &item.path, file));
|
||||
}
|
||||
}
|
||||
|
||||
fn render(item: &Output, sack: &Sack) {
|
||||
let o = Utf8Path::new("dist").join(&item.path);
|
||||
fs::create_dir_all(o.parent().unwrap()).unwrap();
|
||||
|
||||
match item.kind {
|
||||
OutputKind::Real(ref real) => {
|
||||
let i = &real.meta.path;
|
||||
|
||||
match &real.kind {
|
||||
AssetKind::Html(closure) => {
|
||||
let mut file = File::create(&o).unwrap();
|
||||
file.write_all(closure(sack).as_bytes()).unwrap();
|
||||
println!("HTML: {} -> {}", i, o);
|
||||
},
|
||||
AssetKind::Bibtex(_) => { },
|
||||
AssetKind::Image => {
|
||||
fs::create_dir_all(o.parent().unwrap()).unwrap();
|
||||
fs::copy(i, &o).unwrap();
|
||||
println!("Image: {} -> {}", i, o);
|
||||
},
|
||||
};
|
||||
},
|
||||
OutputKind::Fake(Dynamic(ref closure)) => {
|
||||
let mut file = File::create(&o).unwrap();
|
||||
file.write_all(closure(sack).as_bytes()).unwrap();
|
||||
println!("Virtual: -> {}", o);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
mod load;
|
||||
mod render;
|
||||
mod sack;
|
||||
|
||||
use camino::Utf8PathBuf;
|
||||
use hayagriva::Library;
|
||||
use hypertext::Renderable;
|
||||
|
||||
pub use load::{gather, render_all, FileItem, FileItemKind, Asset, AssetKind, PipelineItem, Dynamic, Output};
|
||||
pub use load::{gather, Source, SourceKind};
|
||||
pub use render::{render, Asset, AssetKind, Virtual, Item};
|
||||
pub use sack::{TreePage, Sack};
|
||||
|
||||
use crate::{html::Linkable, text::md::Outline};
|
||||
|
||||
|
||||
/// Represents a piece of content that can be rendered as a page.
|
||||
/// Represents a piece of content that can be rendered into a page.
|
||||
pub trait Content {
|
||||
fn transform<'f, 'm, 's, 'html, T>(
|
||||
&'f self,
|
||||
|
|
125
src/gen/render.rs
Normal file
125
src/gen/render.rs
Normal file
|
@ -0,0 +1,125 @@
|
|||
use std::fmt::Debug;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
|
||||
use crate::html::Linkable;
|
||||
use crate::Sack;
|
||||
|
||||
|
||||
pub enum AssetKind {
|
||||
Html(Box<dyn Fn(&Sack) -> String>),
|
||||
Image,
|
||||
Unknown,
|
||||
Bib(hayagriva::Library),
|
||||
}
|
||||
|
||||
impl Debug for AssetKind {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Html(ptr) => f.debug_tuple("Html").field(&format!("{:p}", *ptr)).finish(),
|
||||
Self::Image => write!(f, "Image"),
|
||||
Self::Unknown => write!(f, "Unknown"),
|
||||
Self::Bib(bib) => f.debug_tuple("Bib").field(bib).finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Asset {
|
||||
pub kind: AssetKind,
|
||||
pub out: Utf8PathBuf,
|
||||
pub link: Option<Linkable>,
|
||||
pub meta: super::Source,
|
||||
}
|
||||
|
||||
pub struct Virtual(pub Utf8PathBuf, pub Box<dyn Fn(&Sack) -> String>);
|
||||
|
||||
impl Virtual {
|
||||
pub fn new<P, F>(path: P, call: F) -> Self
|
||||
where
|
||||
P: AsRef<Utf8Path>,
|
||||
F: Fn(&Sack) -> String + 'static
|
||||
{
|
||||
Self(path.as_ref().into(), Box::new(call))
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Item {
|
||||
Real(Asset),
|
||||
Fake(Virtual),
|
||||
}
|
||||
|
||||
impl From<Asset> for Item {
|
||||
fn from(value: Asset) -> Self {
|
||||
Item::Real(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Virtual> for Item {
|
||||
fn from(value: Virtual) -> Self {
|
||||
Item::Fake(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn render(items: &[Item]) {
|
||||
let assets: Vec<&Asset> = items
|
||||
.iter()
|
||||
.filter_map(|item| match item {
|
||||
Item::Real(a) => Some(a),
|
||||
Item::Fake(_) => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
for item in items {
|
||||
match item {
|
||||
Item::Real(real) => render_real(real, &Sack::new(&assets, &real.out)),
|
||||
Item::Fake(fake) => render_fake(fake, &Sack::new(&assets, &fake.0)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn render_real(item: &Asset, sack: &Sack) {
|
||||
match &item.kind {
|
||||
AssetKind::Html(render) => {
|
||||
let i = &item.meta.path;
|
||||
let o = Utf8Path::new("dist").join(&item.out);
|
||||
|
||||
fs::create_dir_all(o.parent().unwrap()).unwrap();
|
||||
|
||||
let mut file = File::create(&o).unwrap();
|
||||
file.write_all(render(sack).as_bytes()).unwrap();
|
||||
|
||||
println!("HTML: {} -> {}", i, o);
|
||||
},
|
||||
AssetKind::Image => {
|
||||
let i = &item.meta.path;
|
||||
let o = Utf8Path::new("dist").join(&item.out);
|
||||
fs::create_dir_all(o.parent().unwrap()).unwrap();
|
||||
fs::copy(i, &o).unwrap();
|
||||
println!("Image: {} -> {}", i, o);
|
||||
},
|
||||
AssetKind::Bib(_) => (),
|
||||
AssetKind::Unknown => {
|
||||
let i = &item.meta.path;
|
||||
let o = Utf8Path::new("dist").join(&item.out);
|
||||
fs::create_dir_all(o.parent().unwrap()).unwrap();
|
||||
fs::copy(i, &o).unwrap();
|
||||
println!("Unknown: {} -> {}", i, o);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn render_fake(item: &Virtual, sack: &Sack) {
|
||||
let Virtual(out, render) = item;
|
||||
|
||||
let o = Utf8Path::new("dist").join(out);
|
||||
fs::create_dir_all(o.parent().unwrap()).unwrap();
|
||||
|
||||
let mut file = File::create(&o).unwrap();
|
||||
file.write_all(render(sack).as_bytes()).unwrap();
|
||||
println!("Virtual: -> {}", o);
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
use camino::Utf8PathBuf;
|
||||
use hayagriva::Library;
|
||||
|
||||
use crate::html::{Link, LinkDate, Linkable};
|
||||
|
||||
use super::{load::{Output, OutputKind}, AssetKind};
|
||||
use super::{Asset, AssetKind};
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -34,27 +34,23 @@ impl TreePage {
|
|||
}
|
||||
|
||||
|
||||
/// This struct allows for querying the website hierarchy. Separate instance of this struct is
|
||||
/// passed to each closure contained by some rendered assets.
|
||||
/// This struct allows for querying the website hierarchy.
|
||||
#[derive(Debug)]
|
||||
pub struct Sack<'a> {
|
||||
/// Literally everything
|
||||
hole: &'a [Output],
|
||||
/// Current path for page
|
||||
assets: &'a [&'a Asset],
|
||||
path: &'a Utf8PathBuf,
|
||||
/// Original file location
|
||||
file: Option<&'a Utf8PathBuf>,
|
||||
}
|
||||
|
||||
impl<'a> Sack<'a> {
|
||||
pub fn new(hole: &'a [Output], path: &'a Utf8PathBuf, file: Option<&'a Utf8PathBuf>) -> Self {
|
||||
Self { hole, path, file }
|
||||
pub fn new(assets: &'a [&'a Asset], path: &'a Utf8PathBuf) -> Self {
|
||||
Self { assets, path }
|
||||
}
|
||||
|
||||
pub fn get_links(&self, path: &str) -> Vec<LinkDate> {
|
||||
let pattern = glob::Pattern::new(path).expect("Bad glob pattern");
|
||||
self.hole.iter()
|
||||
.filter(|item| pattern.matches_path(item.path.as_ref()))
|
||||
.filter_map(|item| match &item.link {
|
||||
let pattern = glob::Pattern::new(path).unwrap();
|
||||
self.assets.iter()
|
||||
.filter(|f| pattern.matches_path(f.out.as_ref()))
|
||||
.filter_map(|f| match &f.link {
|
||||
Some(Linkable::Date(link)) => Some(link.clone()),
|
||||
_ => None,
|
||||
})
|
||||
|
@ -62,10 +58,10 @@ impl<'a> Sack<'a> {
|
|||
}
|
||||
|
||||
pub fn get_tree(&self, path: &str) -> TreePage {
|
||||
let glob = glob::Pattern::new(path).expect("Bad glob pattern");
|
||||
let list = self.hole.iter()
|
||||
.filter(|item| glob.matches_path(item.path.as_ref()))
|
||||
.filter_map(|item| match &item.link {
|
||||
let glob = glob::Pattern::new(path).unwrap();
|
||||
let list = self.assets.iter()
|
||||
.filter(|f| glob.matches_path(f.out.as_ref()))
|
||||
.filter_map(|f| match &f.link {
|
||||
Some(Linkable::Link(link)) => Some(link.clone()),
|
||||
_ => None,
|
||||
});
|
||||
|
@ -80,32 +76,18 @@ impl<'a> Sack<'a> {
|
|||
|
||||
pub fn get_library(&self) -> Option<&Library> {
|
||||
let glob = format!("{}/*.bib", self.path.parent()?);
|
||||
let glob = glob::Pattern::new(&glob).expect("Bad glob pattern");
|
||||
let glob = glob::Pattern::new(&glob).unwrap();
|
||||
let opts = glob::MatchOptions {
|
||||
case_sensitive: true,
|
||||
require_literal_separator: true,
|
||||
require_literal_leading_dot: false,
|
||||
};
|
||||
|
||||
self.hole.iter()
|
||||
.filter(|item| glob.matches_path_with(item.path.as_ref(), opts))
|
||||
.filter_map(|asset| match asset.kind {
|
||||
OutputKind::Real(ref real) => Some(real),
|
||||
_ => None,
|
||||
})
|
||||
self.assets.iter()
|
||||
.filter(|asset| glob.matches_path_with(asset.out.as_ref(), opts))
|
||||
.find_map(|asset| match asset.kind {
|
||||
AssetKind::Bibtex(ref lib) => Some(lib),
|
||||
_ => None,
|
||||
AssetKind::Bib(ref lib) => Some(lib),
|
||||
_ => None
|
||||
})
|
||||
}
|
||||
|
||||
/// Get the path for output
|
||||
pub fn get_path(&self) -> &'a Utf8Path {
|
||||
self.path.as_path()
|
||||
}
|
||||
|
||||
/// Get the path for original file location
|
||||
pub fn get_file(&self) -> Option<&'a Utf8Path> {
|
||||
self.file.map(Utf8PathBuf::as_ref)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,8 @@
|
|||
use camino::Utf8Path;
|
||||
use hypertext::{html_elements, maud, maud_move, GlobalAttributes, Raw, Renderable};
|
||||
|
||||
use crate::REPO;
|
||||
|
||||
|
||||
const JS_RELOAD: &str = r#"
|
||||
const socket = new WebSocket("ws://localhost:1337");
|
||||
socket.addEventListener("message", (event) => {
|
||||
console.log(event);
|
||||
window.location.reload();
|
||||
});
|
||||
"#;
|
||||
|
||||
const JS_IMPORTS: &str = r#"
|
||||
{
|
||||
"imports": {
|
||||
"splash": "/js/splash.js",
|
||||
"reveal": "/js/reveal.js",
|
||||
"photos": "/js/photos.js",
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
|
||||
pub fn head(title: &str) -> impl Renderable + '_ {
|
||||
let title = format!("{} | kamoshi.org", title);
|
||||
|
||||
|
@ -33,6 +13,16 @@ pub fn head(title: &str) -> impl Renderable + '_ {
|
|||
(title)
|
||||
}
|
||||
|
||||
script type="importmap" {(Raw(r#"
|
||||
{
|
||||
"imports": {
|
||||
"splash": "/js/splash.js",
|
||||
"reveal": "/js/reveal.js",
|
||||
"photos": "/js/photos.js"
|
||||
}
|
||||
}
|
||||
"#))}
|
||||
|
||||
// link rel="sitemap" href="/sitemap.xml";
|
||||
|
||||
link rel="stylesheet" href="/styles.css";
|
||||
|
@ -43,10 +33,6 @@ pub fn head(title: &str) -> impl Renderable + '_ {
|
|||
link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png";
|
||||
link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png";
|
||||
link rel="icon" href="/favicon.ico" sizes="any";
|
||||
|
||||
script type="importmap" {(Raw(JS_IMPORTS))}
|
||||
|
||||
script { (Raw(JS_RELOAD)) }
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -95,15 +81,11 @@ pub fn navbar() -> impl Renderable {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn footer(path: Option<&Utf8Path>) -> impl Renderable {
|
||||
pub fn footer() -> impl Renderable {
|
||||
let copy = format!("Copyright © {} Maciej Jur", &REPO.year);
|
||||
let mail = "maciej@kamoshi.org";
|
||||
let href = format!("mailto:{}", mail);
|
||||
let link = Utf8Path::new(&REPO.link).join("tree").join(&REPO.hash);
|
||||
let link = match path {
|
||||
Some(path) => link.join(path),
|
||||
None => link,
|
||||
};
|
||||
let repo = format!("{}/tree/{}", &REPO.link, &REPO.hash);
|
||||
|
||||
maud_move!(
|
||||
footer .footer {
|
||||
|
@ -116,7 +98,7 @@ pub fn footer(path: Option<&Utf8Path>) -> impl Renderable {
|
|||
}
|
||||
}
|
||||
div .repo {
|
||||
a href=(link.as_str()) {
|
||||
a href=(repo) {
|
||||
(&REPO.hash)
|
||||
}
|
||||
div {
|
||||
|
|
|
@ -73,5 +73,5 @@ pub fn home<'data, 'home, R>(main: R) -> impl Renderable + 'home
|
|||
}
|
||||
);
|
||||
|
||||
page("Home", main, None)
|
||||
page("Home", main)
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ pub fn list<'data, 'list>(
|
|||
}
|
||||
);
|
||||
|
||||
page(title, list, None)
|
||||
page(title, list)
|
||||
}
|
||||
|
||||
fn section(year: i32, group: &[LinkDate]) -> impl Renderable + '_ {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use camino::Utf8Path;
|
||||
use hypertext::{html_elements, maud_move, GlobalAttributes, Raw, Renderable};
|
||||
use crate::html::base::{head, navbar, footer};
|
||||
|
||||
|
@ -20,14 +19,10 @@ pub fn bare<'data, 'html, R>(title: &'data str, main: R) -> impl Renderable + 'h
|
|||
)
|
||||
}
|
||||
|
||||
pub fn page<'data, 'main, 'html, T>(
|
||||
title: &'data str,
|
||||
main: T,
|
||||
path: Option<&'data Utf8Path>,
|
||||
) -> impl Renderable + 'html
|
||||
pub fn page<'data, 'main, 'page, T>(title: &'data str, main: T) -> impl Renderable + 'page
|
||||
where
|
||||
'main : 'html,
|
||||
'data : 'html,
|
||||
'main : 'page,
|
||||
'data : 'page,
|
||||
T: Renderable + 'main
|
||||
{
|
||||
maud_move!(
|
||||
|
@ -38,7 +33,7 @@ pub fn page<'data, 'main, 'html, T>(
|
|||
body {
|
||||
(navbar())
|
||||
(main)
|
||||
(footer(path))
|
||||
(footer())
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,24 +1,21 @@
|
|||
use hypertext::{html_elements, maud_move, GlobalAttributes, Renderable};
|
||||
|
||||
use crate::gen::Sack;
|
||||
use crate::html::misc::{show_bibliography, show_outline};
|
||||
use crate::html::page;
|
||||
use crate::md::Post;
|
||||
use crate::text::md::Outline;
|
||||
|
||||
|
||||
pub fn post<'f, 'm, 's, 'html, T>(
|
||||
fm: &'f Post,
|
||||
pub fn post<'fm, 'md, 'post, T>(
|
||||
fm: &'fm Post,
|
||||
content: T,
|
||||
outline: Outline,
|
||||
bib: Option<Vec<String>>,
|
||||
sack: &'s Sack,
|
||||
) -> impl Renderable + 'html
|
||||
) -> impl Renderable + 'post
|
||||
where
|
||||
'f: 'html,
|
||||
'm: 'html,
|
||||
's: 'html,
|
||||
T: Renderable + 'm
|
||||
'fm: 'post,
|
||||
'md: 'post,
|
||||
T: Renderable + 'md
|
||||
{
|
||||
let main = maud_move!(
|
||||
main .wiki-main {
|
||||
|
@ -49,5 +46,5 @@ pub fn post<'f, 'm, 's, 'html, T>(
|
|||
}
|
||||
);
|
||||
|
||||
page(&fm.title, main, sack.get_file())
|
||||
page(&fm.title, main)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ pub fn map() -> impl Renderable {
|
|||
(Raw("import 'photos';"))
|
||||
}
|
||||
}
|
||||
), None)
|
||||
))
|
||||
}
|
||||
|
||||
pub fn search() -> impl Renderable {
|
||||
|
@ -20,5 +20,5 @@ pub fn search() -> impl Renderable {
|
|||
main {
|
||||
|
||||
}
|
||||
), None)
|
||||
))
|
||||
}
|
||||
|
|
|
@ -53,5 +53,5 @@ pub fn wiki<'data, 'html, 'sack, T>(
|
|||
}
|
||||
);
|
||||
|
||||
page(&fm.title, main, sack.get_file())
|
||||
page(&fm.title, main)
|
||||
}
|
||||
|
|
245
src/main.rs
245
src/main.rs
|
@ -1,42 +1,22 @@
|
|||
use std::process::Command;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
use chrono::Datelike;
|
||||
use clap::{Parser, ValueEnum};
|
||||
use gen::{Asset, AssetKind, Content, FileItemKind, Output, PipelineItem, Sack};
|
||||
use gen::{Asset, Sack, Content};
|
||||
use hayagriva::Library;
|
||||
use html::{Link, LinkDate, Linkable};
|
||||
use hypertext::{Raw, Renderable};
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::Deserialize;
|
||||
use text::md::Outline;
|
||||
|
||||
use crate::gen::Dynamic;
|
||||
use crate::build::build_styles;
|
||||
|
||||
mod md;
|
||||
mod html;
|
||||
mod ts;
|
||||
mod gen;
|
||||
mod utils;
|
||||
mod text;
|
||||
mod watch;
|
||||
mod build;
|
||||
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct Args {
|
||||
#[clap(value_enum, index = 1, default_value = "build")]
|
||||
mode: Mode,
|
||||
}
|
||||
|
||||
#[derive(ValueEnum, Debug, Clone, Copy)]
|
||||
enum Mode {
|
||||
Build,
|
||||
Watch,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -74,7 +54,7 @@ impl Content for md::Post {
|
|||
&'f self,
|
||||
content: T,
|
||||
outline: Outline,
|
||||
sack: &'s Sack,
|
||||
_: &'s Sack,
|
||||
bib: Option<Vec<String>>,
|
||||
) -> impl Renderable + 'html
|
||||
where
|
||||
|
@ -82,7 +62,7 @@ impl Content for md::Post {
|
|||
'm: 'html,
|
||||
's: 'html,
|
||||
T: Renderable + 'm {
|
||||
html::post(self, content, outline, bib, sack)
|
||||
html::post(self, content, outline, bib)
|
||||
}
|
||||
|
||||
fn as_link(&self, path: Utf8PathBuf) -> Option<Linkable> {
|
||||
|
@ -191,24 +171,19 @@ fn to_list(list: Vec<LinkDate>) -> String {
|
|||
html::list("", &groups).render().into()
|
||||
}
|
||||
|
||||
fn to_index<T>(item: PipelineItem) -> PipelineItem
|
||||
where
|
||||
T: for<'de> Deserialize<'de> + Content + 'static,
|
||||
{
|
||||
let meta = match item {
|
||||
PipelineItem::Skip(meta) if matches!(meta.kind, FileItemKind::Index) => meta,
|
||||
_ => return item,
|
||||
};
|
||||
|
||||
let dir = meta.path.parent().unwrap().strip_prefix("content").unwrap();
|
||||
let dir = match meta.path.file_stem().unwrap() {
|
||||
"index" => dir.to_owned(),
|
||||
name => dir.join(name),
|
||||
};
|
||||
fn transform<T>(meta: gen::Source) -> Asset
|
||||
where
|
||||
T: for<'de> serde::Deserialize<'de>,
|
||||
T: Content + 'static,
|
||||
{
|
||||
let dir = meta.dirs.strip_prefix("content").unwrap();
|
||||
|
||||
match meta.kind {
|
||||
gen::SourceKind::Index => match meta.ext.as_str() {
|
||||
"md" | "mdx" | "lhs" => {
|
||||
let path = dir.join("index.html");
|
||||
|
||||
match meta.path.extension() {
|
||||
Some("md" | "mdx" | "lhs") => {
|
||||
let data = fs::read_to_string(&meta.path).unwrap();
|
||||
let (fm, md) = md::preflight::<T>(&data);
|
||||
let link = T::as_link(&fm, Utf8Path::new("/").join(dir));
|
||||
|
@ -219,59 +194,52 @@ fn to_index<T>(item: PipelineItem) -> PipelineItem
|
|||
T::transform(&fm, Raw(html), outline, sack, bib).render().into()
|
||||
};
|
||||
|
||||
Output {
|
||||
kind: Asset {
|
||||
gen::Asset {
|
||||
kind: gen::AssetKind::Html(Box::new(call)),
|
||||
meta,
|
||||
}.into(),
|
||||
path,
|
||||
out: path,
|
||||
link,
|
||||
}.into()
|
||||
},
|
||||
_ => meta.into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn to_bundle(item: PipelineItem) -> PipelineItem {
|
||||
let meta = match item {
|
||||
PipelineItem::Skip(meta) if matches!(meta.kind, FileItemKind::Bundle) => meta,
|
||||
_ => return item,
|
||||
};
|
||||
|
||||
let path = meta.path.strip_prefix("content").unwrap().to_owned();
|
||||
|
||||
match meta.path.extension() {
|
||||
// any image
|
||||
Some("jpg" | "png" | "gif") => {
|
||||
Output {
|
||||
kind: Asset {
|
||||
kind: AssetKind::Image,
|
||||
meta,
|
||||
}.into(),
|
||||
path,
|
||||
link: None,
|
||||
}.into()
|
||||
}
|
||||
},
|
||||
// bibliography
|
||||
Some("bib") => {
|
||||
_ => gen::Asset {
|
||||
kind: gen::AssetKind::Unknown,
|
||||
out: dir.join(meta.path.file_name().unwrap()).to_owned(),
|
||||
link: None,
|
||||
meta,
|
||||
}
|
||||
},
|
||||
gen::SourceKind::Asset => {
|
||||
let loc = dir.join(meta.path.file_name().unwrap()).to_owned();
|
||||
match meta.ext.as_str() {
|
||||
"jpg" | "png" | "gif" => gen::Asset {
|
||||
kind: gen::AssetKind::Image,
|
||||
out: loc,
|
||||
link: None,
|
||||
meta,
|
||||
},
|
||||
"bib" => {
|
||||
let data = fs::read_to_string(&meta.path).unwrap();
|
||||
let data = hayagriva::io::from_biblatex_str(&data).unwrap();
|
||||
|
||||
Output {
|
||||
kind: Asset {
|
||||
kind: AssetKind::Bibtex(data),
|
||||
meta,
|
||||
}.into(),
|
||||
path,
|
||||
gen::Asset {
|
||||
kind: gen::AssetKind::Bib(data),
|
||||
out: loc,
|
||||
link: None,
|
||||
}.into()
|
||||
meta,
|
||||
}
|
||||
},
|
||||
_ => meta.into(),
|
||||
_ => gen::Asset {
|
||||
kind: gen::AssetKind::Unknown,
|
||||
out: loc,
|
||||
link: None,
|
||||
meta,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn build() {
|
||||
fn main() {
|
||||
if fs::metadata("dist").is_ok() {
|
||||
println!("Cleaning dist");
|
||||
fs::remove_dir_all("dist").unwrap();
|
||||
|
@ -279,85 +247,69 @@ fn build() {
|
|||
|
||||
fs::create_dir("dist").unwrap();
|
||||
|
||||
let assets: Vec<Output> = [
|
||||
gen::gather("content/about.md", &["md"].into())
|
||||
.into_iter()
|
||||
.map(to_index::<md::Post> as fn(PipelineItem) -> PipelineItem),
|
||||
gen::gather("content/posts/**/*", &["md", "mdx"].into())
|
||||
.into_iter()
|
||||
.map(to_index::<md::Post>),
|
||||
gen::gather("content/slides/**/*", &["md", "lhs"].into())
|
||||
.into_iter()
|
||||
.map(to_index::<md::Slide>),
|
||||
gen::gather("content/wiki/**/*", &["md"].into())
|
||||
.into_iter()
|
||||
.map(to_index::<md::Wiki>),
|
||||
]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(to_bundle)
|
||||
.filter_map(|item| match item {
|
||||
PipelineItem::Skip(skip) => {
|
||||
println!("Skipping {}", skip.path);
|
||||
None
|
||||
},
|
||||
PipelineItem::Take(take) => Some(take),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let assets: Vec<Output> = vec![
|
||||
assets,
|
||||
let assets: Vec<Vec<gen::Item>> = vec![
|
||||
vec![
|
||||
Output {
|
||||
kind: Dynamic::new(|_| html::map().render().to_owned().into()).into(),
|
||||
path: "map/index.html".into(),
|
||||
link: None,
|
||||
},
|
||||
Output {
|
||||
kind: Dynamic::new(|_| html::search().render().to_owned().into()).into(),
|
||||
path: "search/index.html".into(),
|
||||
link: None,
|
||||
},
|
||||
Output {
|
||||
kind: Asset {
|
||||
gen::Virtual::new("map/index.html", |_| html::map().render().to_owned().into()).into(),
|
||||
gen::Virtual::new("search/index.html", |_| html::search().render().to_owned().into()).into(),
|
||||
gen::Asset {
|
||||
kind: gen::AssetKind::Html(Box::new(|_| {
|
||||
let data = std::fs::read_to_string("content/index.md").unwrap();
|
||||
let (_, html, _) = text::md::parse(&data, None);
|
||||
let (_, html, bib) = text::md::parse(&data, None);
|
||||
html::home(Raw(html)).render().to_owned().into()
|
||||
})).into(),
|
||||
meta: gen::FileItem {
|
||||
kind: gen::FileItemKind::Index,
|
||||
})),
|
||||
out: "index.html".into(),
|
||||
link: None,
|
||||
meta: gen::Source {
|
||||
kind: gen::SourceKind::Index,
|
||||
ext: "md".into(),
|
||||
dirs: "".into(),
|
||||
path: "content/index.md".into()
|
||||
}
|
||||
}.into(),
|
||||
path: "index.html".into(),
|
||||
link: None,
|
||||
}.into(),
|
||||
Output {
|
||||
kind: Dynamic::new(|sack| to_list(sack.get_links("posts/**/*.html"))).into(),
|
||||
path: "posts/index.html".into(),
|
||||
link: None,
|
||||
},
|
||||
Output {
|
||||
kind: Dynamic::new(|sack| to_list(sack.get_links("slides/**/*.html"))).into(),
|
||||
path: "slides/index.html".into(),
|
||||
link: None,
|
||||
},
|
||||
gen::Virtual("posts/index.html".into(), Box::new(|all|
|
||||
to_list(all.get_links("posts/**/*.html"))
|
||||
)).into(),
|
||||
gen::Virtual("slides/index.html".into(), Box::new(|all|
|
||||
to_list(all.get_links("slides/**/*.html"))
|
||||
)).into(),
|
||||
],
|
||||
]
|
||||
gen::gather("content/about.md", &["md"].into())
|
||||
.into_iter()
|
||||
.map(transform::<md::Post>)
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
gen::gather("content/posts/**/*", &["md", "mdx"].into())
|
||||
.into_iter()
|
||||
.map(transform::<md::Post>)
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
gen::gather("content/slides/**/*", &["md", "lhs"].into())
|
||||
.into_iter()
|
||||
.map(transform::<md::Slide>)
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
gen::gather("content/wiki/**/*", &["md"].into())
|
||||
.into_iter()
|
||||
.map(transform::<md::Wiki>)
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
];
|
||||
|
||||
let all: Vec<gen::Item> = assets
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
{
|
||||
let now = std::time::Instant::now();
|
||||
gen::render_all(&assets);
|
||||
gen::render(&all);
|
||||
println!("Elapsed: {:.2?}", now.elapsed());
|
||||
}
|
||||
|
||||
utils::copy_recursively(std::path::Path::new("public"), std::path::Path::new("dist")).unwrap();
|
||||
|
||||
build_styles();
|
||||
let css = grass::from_path("styles/styles.scss", &grass::Options::default()).unwrap();
|
||||
fs::write("dist/styles.css", css).unwrap();
|
||||
|
||||
let res = Command::new("pagefind")
|
||||
.args(["--site", "dist"])
|
||||
|
@ -378,17 +330,4 @@ fn build() {
|
|||
.unwrap();
|
||||
|
||||
println!("{}", String::from_utf8(res.stderr).unwrap());
|
||||
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
|
||||
match args.mode {
|
||||
Mode::Build => build(),
|
||||
Mode::Watch => {
|
||||
build();
|
||||
watch::watch().unwrap()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,9 +88,6 @@ fn make_bib<'a, 'b>(stream: Vec<Event<'a>>, lib: &'b Library) -> (Vec<Event<'a>>
|
|||
}
|
||||
}
|
||||
|
||||
// add fake citation to make all entries show up
|
||||
driver.citation(CitationRequest::from_items(lib.iter().map(CitationItem::with_entry).collect(), &STYLE, &LOCALE));
|
||||
|
||||
let res = driver.finish(BibliographyRequest { style: &STYLE, locale: None, locale_files: &LOCALE });
|
||||
|
||||
let mut n = 0;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
use once_cell::sync::Lazy;
|
||||
use tree_sitter::Language;
|
||||
use tree_sitter_highlight::HighlightConfiguration;
|
||||
|
||||
use super::captures;
|
||||
|
@ -16,34 +17,6 @@ macro_rules! query {
|
|||
};
|
||||
}
|
||||
|
||||
macro_rules! insert {
|
||||
($_:tt $e:expr) => { $e };
|
||||
}
|
||||
|
||||
macro_rules! merge {
|
||||
([$($e:expr),+ $(,)?]) => { &format!(concat!($(insert!($e "{} ")),*), $($e),* ) };
|
||||
($e:expr) => { $e };
|
||||
}
|
||||
|
||||
macro_rules! language {
|
||||
($name:expr, $lang:expr, $highlights:expr, $injections:expr, $locals:expr $(,)?) => {
|
||||
(
|
||||
$name,
|
||||
{
|
||||
let mut config = HighlightConfiguration::new(
|
||||
$lang,
|
||||
$name,
|
||||
$highlights,
|
||||
$injections,
|
||||
$locals,
|
||||
).unwrap();
|
||||
config.configure(captures::NAMES);
|
||||
config
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
pub static EXTENSIONS: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
|
||||
HashMap::from([
|
||||
("hs", "haskell"),
|
||||
|
@ -51,12 +24,25 @@ pub static EXTENSIONS: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(||
|
|||
("md", "markdown"),
|
||||
("mdx", "markdown"),
|
||||
("py", "python"),
|
||||
("scm", "scheme"),
|
||||
("query", "query"),
|
||||
// ("scm", "scheme"),
|
||||
("scss", "scss"),
|
||||
("ts", "javascript"),
|
||||
("typescript", "javascript")
|
||||
])
|
||||
});
|
||||
|
||||
fn config_for(
|
||||
lang: Language,
|
||||
name: &str,
|
||||
highlights: &str,
|
||||
injections: &str,
|
||||
locals: &str,
|
||||
) -> HighlightConfiguration {
|
||||
let mut config = HighlightConfiguration::new(lang, name, highlights, injections, locals).unwrap();
|
||||
config.configure(captures::NAMES);
|
||||
config
|
||||
}
|
||||
|
||||
pub static CONFIGS: Lazy<HashMap<&'static str, HighlightConfiguration>> = Lazy::new(|| {
|
||||
HashMap::from([
|
||||
|
@ -69,129 +55,161 @@ pub static CONFIGS: Lazy<HashMap<&'static str, HighlightConfiguration>> = Lazy::
|
|||
// "",
|
||||
// )
|
||||
// ),
|
||||
language!(
|
||||
"css",
|
||||
tree_sitter_css::language(),
|
||||
tree_sitter_css::HIGHLIGHTS_QUERY,
|
||||
"",
|
||||
"",
|
||||
),
|
||||
language!(
|
||||
// (
|
||||
// "css",
|
||||
// config_for(
|
||||
// tree_sitter_css::language(),
|
||||
// query!("css/highlights"),
|
||||
// "",
|
||||
// "",
|
||||
// )
|
||||
// ),
|
||||
(
|
||||
"haskell",
|
||||
tree_sitter_haskell::language(),
|
||||
tree_sitter_haskell::HIGHLIGHTS_QUERY,
|
||||
config_for(
|
||||
npezza93_tree_sitter_haskell::language(),
|
||||
"haskell",
|
||||
npezza93_tree_sitter_haskell::HIGHLIGHTS_QUERY,
|
||||
"",
|
||||
tree_sitter_haskell::LOCALS_QUERY,
|
||||
npezza93_tree_sitter_haskell::LOCALS_QUERY,
|
||||
)
|
||||
),
|
||||
language!(
|
||||
"html",
|
||||
tree_sitter_html::language(),
|
||||
tree_sitter_html::HIGHLIGHTS_QUERY,
|
||||
tree_sitter_html::INJECTIONS_QUERY,
|
||||
"",
|
||||
),
|
||||
language!(
|
||||
// (
|
||||
// "html",
|
||||
// config_for(
|
||||
// tree_sitter_html::language(),
|
||||
// tree_sitter_html::HIGHLIGHTS_QUERY,
|
||||
// tree_sitter_html::INJECTIONS_QUERY,
|
||||
// "",
|
||||
// )
|
||||
// ),
|
||||
(
|
||||
"javascript",
|
||||
config_for(
|
||||
tree_sitter_javascript::language(),
|
||||
merge!([
|
||||
"javascript",
|
||||
&format!("{} {}",
|
||||
query!("ecma/highlights"),
|
||||
tree_sitter_javascript::HIGHLIGHT_QUERY,
|
||||
]),
|
||||
tree_sitter_javascript::INJECTIONS_QUERY,
|
||||
tree_sitter_javascript::LOCALS_QUERY,
|
||||
),
|
||||
language!(
|
||||
tree_sitter_javascript::INJECTION_QUERY,
|
||||
tree_sitter_javascript::LOCALS_QUERY,
|
||||
)
|
||||
),
|
||||
(
|
||||
"jsx",
|
||||
config_for(
|
||||
tree_sitter_javascript::language(),
|
||||
merge!([
|
||||
"jsx",
|
||||
&format!("{} {} {}",
|
||||
query!("ecma/highlights"),
|
||||
tree_sitter_javascript::HIGHLIGHT_QUERY,
|
||||
tree_sitter_javascript::JSX_HIGHLIGHT_QUERY,
|
||||
]),
|
||||
tree_sitter_javascript::INJECTIONS_QUERY,
|
||||
tree_sitter_javascript::LOCALS_QUERY,
|
||||
),
|
||||
language!(
|
||||
tree_sitter_javascript::INJECTION_QUERY,
|
||||
tree_sitter_javascript::LOCALS_QUERY,
|
||||
)
|
||||
),
|
||||
(
|
||||
"markdown",
|
||||
config_for(
|
||||
tree_sitter_md::language(),
|
||||
"markdown",
|
||||
tree_sitter_md::HIGHLIGHT_QUERY_BLOCK,
|
||||
tree_sitter_md::INJECTION_QUERY_BLOCK,
|
||||
"",
|
||||
)
|
||||
),
|
||||
language!(
|
||||
(
|
||||
"python",
|
||||
config_for(
|
||||
tree_sitter_python::language(),
|
||||
"python",
|
||||
tree_sitter_python::HIGHLIGHTS_QUERY,
|
||||
"",
|
||||
"",
|
||||
)
|
||||
),
|
||||
language!(
|
||||
"regex",
|
||||
tree_sitter_regex::language(),
|
||||
query!("regex/highlights"),
|
||||
"",
|
||||
(
|
||||
"query",
|
||||
config_for(
|
||||
tree_sitter_query::language(),
|
||||
"query",
|
||||
tree_sitter_query::HIGHLIGHTS_QUERY,
|
||||
tree_sitter_query::INJECTIONS_QUERY,
|
||||
"",
|
||||
)
|
||||
),
|
||||
language!(
|
||||
// (
|
||||
// "regex",
|
||||
// config_for(
|
||||
// tree_sitter_regex::language(),
|
||||
// query!("regex/highlights"),
|
||||
// "",
|
||||
// "",
|
||||
// )
|
||||
// ),
|
||||
(
|
||||
"rust",
|
||||
config_for(
|
||||
tree_sitter_rust::language(),
|
||||
"rust",
|
||||
tree_sitter_rust::HIGHLIGHTS_QUERY,
|
||||
tree_sitter_rust::INJECTIONS_QUERY,
|
||||
"",
|
||||
)
|
||||
),
|
||||
language!(
|
||||
"scss",
|
||||
tree_sitter_scss::language(),
|
||||
merge!([
|
||||
tree_sitter_css::HIGHLIGHTS_QUERY,
|
||||
tree_sitter_scss::HIGHLIGHTS_QUERY,
|
||||
]),
|
||||
"",
|
||||
"",
|
||||
),
|
||||
language!(
|
||||
"query",
|
||||
tree_sitter_query::language(),
|
||||
tree_sitter_query::HIGHLIGHTS_QUERY,
|
||||
"",
|
||||
"",
|
||||
),
|
||||
language!(
|
||||
"toml",
|
||||
tree_sitter_toml_ng::language(),
|
||||
tree_sitter_toml_ng::HIGHLIGHTS_QUERY,
|
||||
"",
|
||||
"",
|
||||
),
|
||||
language!(
|
||||
"typescript",
|
||||
tree_sitter_typescript::language_typescript(),
|
||||
merge!([
|
||||
query!("ecma/highlights"),
|
||||
tree_sitter_javascript::HIGHLIGHT_QUERY,
|
||||
tree_sitter_typescript::HIGHLIGHTS_QUERY,
|
||||
]),
|
||||
tree_sitter_javascript::INJECTIONS_QUERY,
|
||||
merge!([
|
||||
tree_sitter_javascript::LOCALS_QUERY,
|
||||
tree_sitter_typescript::LOCALS_QUERY,
|
||||
])
|
||||
),
|
||||
language!(
|
||||
"tsx",
|
||||
tree_sitter_typescript::language_tsx(),
|
||||
merge!([
|
||||
query!("ecma/highlights"),
|
||||
tree_sitter_javascript::HIGHLIGHT_QUERY,
|
||||
tree_sitter_javascript::JSX_HIGHLIGHT_QUERY,
|
||||
tree_sitter_typescript::HIGHLIGHTS_QUERY,
|
||||
]),
|
||||
tree_sitter_javascript::INJECTIONS_QUERY,
|
||||
merge!([
|
||||
tree_sitter_javascript::LOCALS_QUERY,
|
||||
tree_sitter_typescript::LOCALS_QUERY,
|
||||
]),
|
||||
),
|
||||
// (
|
||||
// "scheme",
|
||||
// config_for(
|
||||
// tree_sitter_scheme::language(),
|
||||
// tree_sitter_scheme::HIGHLIGHTS_QUERY,
|
||||
// "",
|
||||
// "",
|
||||
// )
|
||||
// ),
|
||||
// (
|
||||
// "toml",
|
||||
// config_for(
|
||||
// tree_sitter_toml::language(),
|
||||
// tree_sitter_toml::HIGHLIGHT_QUERY,
|
||||
// "",
|
||||
// "",
|
||||
// )
|
||||
// ),
|
||||
// (
|
||||
// "tsx",
|
||||
// config_for(
|
||||
// tree_sitter_typescript::language_tsx(),
|
||||
// &format!("{} {} {} {}",
|
||||
// query!("ecma/highlights"),
|
||||
// tree_sitter_javascript::HIGHLIGHT_QUERY,
|
||||
// tree_sitter_javascript::JSX_HIGHLIGHT_QUERY,
|
||||
// tree_sitter_typescript::HIGHLIGHT_QUERY,
|
||||
// ),
|
||||
// tree_sitter_javascript::INJECTION_QUERY,
|
||||
// &format!("{} {}",
|
||||
// tree_sitter_javascript::LOCALS_QUERY,
|
||||
// tree_sitter_typescript::LOCALS_QUERY
|
||||
// )
|
||||
// )
|
||||
// ),
|
||||
// (
|
||||
// "typescript",
|
||||
// config_for(
|
||||
// tree_sitter_typescript::language_typescript(),
|
||||
// &format!("{} {} {}",
|
||||
// query!("ecma/highlights"),
|
||||
// tree_sitter_javascript::HIGHLIGHT_QUERY,
|
||||
// tree_sitter_typescript::HIGHLIGHT_QUERY,
|
||||
// ),
|
||||
// tree_sitter_javascript::INJECTION_QUERY,
|
||||
// &format!("{} {}",
|
||||
// tree_sitter_javascript::LOCALS_QUERY,
|
||||
// tree_sitter_typescript::LOCALS_QUERY
|
||||
// ),
|
||||
// )
|
||||
// ),
|
||||
])
|
||||
});
|
||||
|
||||
|
|
94
src/watch.rs
94
src/watch.rs
|
@ -1,94 +0,0 @@
|
|||
use std::io::Result;
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::path::Path;
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread::JoinHandle;
|
||||
use std::time::Duration;
|
||||
|
||||
use notify::RecursiveMode;
|
||||
use notify_debouncer_mini::new_debouncer;
|
||||
use tungstenite::WebSocket;
|
||||
|
||||
use crate::build::build_styles;
|
||||
|
||||
|
||||
fn new_thread_ws_incoming(
|
||||
server: TcpListener,
|
||||
client: Arc<Mutex<Vec<WebSocket<TcpStream>>>>,
|
||||
) -> JoinHandle<()> {
|
||||
std::thread::spawn(move || {
|
||||
for stream in server.incoming() {
|
||||
let socket = tungstenite::accept(stream.unwrap()).unwrap();
|
||||
client.lock().unwrap().push(socket);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn new_thread_ws_reload(
|
||||
client: Arc<Mutex<Vec<WebSocket<TcpStream>>>>,
|
||||
) -> (Sender<()>, JoinHandle<()>) {
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
|
||||
let thread = std::thread::spawn(move || {
|
||||
while rx.recv().is_ok() {
|
||||
let mut clients = client.lock().unwrap();
|
||||
let mut broken = vec![];
|
||||
|
||||
for (i, socket) in clients.iter_mut().enumerate() {
|
||||
match socket.send("reload".into()) {
|
||||
Ok(_) => {}
|
||||
Err(tungstenite::error::Error::Io(e)) => {
|
||||
if e.kind() == std::io::ErrorKind::BrokenPipe {
|
||||
broken.push(i);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i in broken.into_iter().rev() {
|
||||
clients.remove(i);
|
||||
}
|
||||
|
||||
// Close all but the last 10 connections
|
||||
let len = clients.len();
|
||||
if len > 10 {
|
||||
for mut socket in clients.drain(0..len - 10) {
|
||||
socket.close(None).ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
(tx, thread)
|
||||
}
|
||||
|
||||
|
||||
pub fn watch() -> Result<()> {
|
||||
let server = TcpListener::bind("127.0.0.1:1337")?;
|
||||
let client = Arc::new(Mutex::new(vec![]));
|
||||
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
let mut debouncer = new_debouncer(Duration::from_secs(1), tx).unwrap();
|
||||
|
||||
debouncer
|
||||
.watcher()
|
||||
.watch(Path::new("./styles"), RecursiveMode::Recursive)
|
||||
.unwrap();
|
||||
|
||||
let thread_i = new_thread_ws_incoming(server, client.clone());
|
||||
let (tx_reload, thread_o) = new_thread_ws_reload(client.clone());
|
||||
|
||||
while let Ok(ev) = rx.recv().unwrap() {
|
||||
build_styles();
|
||||
tx_reload.send(()).unwrap();
|
||||
}
|
||||
|
||||
thread_i.join().unwrap();
|
||||
thread_o.join().unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,40 +1,28 @@
|
|||
.markdown {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
> h1 {
|
||||
font-size: 2.0274rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.8rem;
|
||||
> h2 {
|
||||
font-size: 1.802rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.5rem;
|
||||
> h3 {
|
||||
font-size: 1.602rem;
|
||||
}
|
||||
|
||||
h4, > h5, > h6 {
|
||||
font-size: 1.2rem;
|
||||
> h4, > h5, > h6 {
|
||||
font-size: 1.424rem;
|
||||
}
|
||||
|
||||
p {
|
||||
> p {
|
||||
margin: 0.5em 0;
|
||||
line-height: 1.5em;
|
||||
hyphens: auto;
|
||||
text-align: justify;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
padding-left: 1em;
|
||||
|
||||
ul, ol {
|
||||
padding-left: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
a:not([class]) {
|
||||
color: var(--c-primary);
|
||||
font-family: var(--serif);
|
||||
font-weight: 500;
|
||||
|
@ -56,6 +44,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
> ul, ol {
|
||||
padding-left: 1em;
|
||||
|
||||
ul, ol {
|
||||
padding-left: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
img:not([class]) {
|
||||
max-width: 100%;
|
||||
|
|
Loading…
Reference in a new issue