From 4b19440655ea75bd05404e188db40bda2907729b Mon Sep 17 00:00:00 2001 From: Maciej Jur Date: Sat, 4 May 2024 13:48:51 +0200 Subject: [PATCH] feat: websocket watch --- Cargo.lock | 480 ++++++++++++++++++++++++++++- Cargo.toml | 6 + Makefile | 9 +- src/build.rs | 7 + src/html/base.rs | 33 +- src/main.rs | 37 ++- src/watch.rs | 94 ++++++ styles/_markdown.scss | 41 +-- styles/shortcodes/_marginnote.scss | 2 +- 9 files changed, 661 insertions(+), 48 deletions(-) create mode 100644 src/build.rs create mode 100644 src/watch.rs diff --git a/Cargo.lock b/Cargo.lock index 4b65688..9ddd40d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,55 @@ 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" @@ -57,18 +106,45 @@ 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" @@ -98,7 +174,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-targets", + "windows-targets 0.52.4", ] [[package]] @@ -138,12 +214,58 @@ 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" @@ -159,12 +281,46 @@ 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" @@ -185,7 +341,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] @@ -200,6 +356,12 @@ 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" @@ -231,6 +393,16 @@ 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" @@ -263,6 +435,18 @@ 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" @@ -278,6 +462,25 @@ 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" @@ -390,6 +593,12 @@ 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" @@ -399,6 +608,23 @@ 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" @@ -475,6 +701,32 @@ 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" @@ -512,6 +764,26 @@ 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" @@ -555,6 +827,48 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +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", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -685,7 +999,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", + "bitflags 2.5.0", "getopts", "memchr", "pulldown-cmark-escape", @@ -756,6 +1070,15 @@ 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" @@ -864,6 +1187,17 @@ 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" @@ -876,6 +1210,7 @@ version = "0.1.0" dependencies = [ "camino", "chrono", + "clap", "emojis", "glob", "grass", @@ -883,6 +1218,8 @@ dependencies = [ "hayagriva", "hypertext", "katex", + "notify", + "notify-debouncer-mini", "once_cell", "pulldown-cmark", "regex", @@ -901,6 +1238,7 @@ dependencies = [ "tree-sitter-scheme", "tree-sitter-toml", "tree-sitter-typescript", + "tungstenite", ] [[package]] @@ -909,6 +1247,12 @@ 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" @@ -924,7 +1268,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", @@ -1147,6 +1491,31 @@ dependencies = [ "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" @@ -1232,12 +1601,24 @@ 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" @@ -1351,7 +1732,40 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets", + "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", ] [[package]] @@ -1360,51 +1774,93 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" 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", + "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", ] +[[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" diff --git a/Cargo.toml b/Cargo.toml index df1fb17..e696ef0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,11 @@ 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" } @@ -37,3 +42,4 @@ tree-sitter-rust = "0.20" tree-sitter-scheme = { git = "https://github.com/6cdh/tree-sitter-scheme", rev = "85b6188fb77c03dfb01d13e58e2844450506860c" } tree-sitter-toml = "0.20" tree-sitter-typescript = "0.20" +clap = { version = "4.5.4", features = ["derive"] } diff --git a/Makefile b/Makefile index aee8caf..f57dc6b 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,11 @@ build: - cargo run + cargo run --release -deploy: build - rsync -Pavzq ./dist/ kamoshi:/var/www/kamoshi.org --delete +watch: + cargo run --release -- watch serve: python -m http.server -d ./dist + +deploy: build + rsync -Pavzq ./dist/ kamoshi:/var/www/kamoshi.org --delete diff --git a/src/build.rs b/src/build.rs new file mode 100644 index 0000000..5f7ef86 --- /dev/null +++ b/src/build.rs @@ -0,0 +1,7 @@ +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(); +} diff --git a/src/html/base.rs b/src/html/base.rs index 45b95e3..c7ca53d 100644 --- a/src/html/base.rs +++ b/src/html/base.rs @@ -4,6 +4,25 @@ use hypertext::{html_elements, maud, maud_move, GlobalAttributes, Raw, Renderabl 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); @@ -14,16 +33,6 @@ 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"; @@ -34,6 +43,10 @@ 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)) } ) } diff --git a/src/main.rs b/src/main.rs index 9a5fba6..aa02412 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,10 @@ -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 hayagriva::Library; use html::{Link, LinkDate, Linkable}; @@ -13,6 +14,7 @@ use serde::Deserialize; use text::md::Outline; use crate::gen::Dynamic; +use crate::build::build_styles; mod md; mod html; @@ -20,6 +22,21 @@ 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)] @@ -254,7 +271,7 @@ fn to_bundle(item: PipelineItem) -> PipelineItem { } -fn main() { +fn build() { if fs::metadata("dist").is_ok() { println!("Cleaning dist"); fs::remove_dir_all("dist").unwrap(); @@ -340,8 +357,7 @@ fn main() { utils::copy_recursively(std::path::Path::new("public"), std::path::Path::new("dist")).unwrap(); - let css = grass::from_path("styles/styles.scss", &grass::Options::default()).unwrap(); - fs::write("dist/styles.css", css).unwrap(); + build_styles(); let res = Command::new("pagefind") .args(["--site", "dist"]) @@ -362,4 +378,17 @@ fn main() { .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() + }, + } } diff --git a/src/watch.rs b/src/watch.rs new file mode 100644 index 0000000..cff837d --- /dev/null +++ b/src/watch.rs @@ -0,0 +1,94 @@ +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>>>, +) -> 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>>>, +) -> (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(()) +} diff --git a/styles/_markdown.scss b/styles/_markdown.scss index 4e0f46c..5f44c28 100644 --- a/styles/_markdown.scss +++ b/styles/_markdown.scss @@ -1,28 +1,40 @@ .markdown { - > h1 { - font-size: 2.0274rem; + h1 { + font-size: 2.5rem; } - > h2 { - font-size: 1.802rem; + h2 { + font-size: 1.8rem; } - > h3 { - font-size: 1.602rem; + h3 { + font-size: 1.5rem; } - > h4, > h5, > h6 { - font-size: 1.424rem; + h4, > h5, > h6 { + font-size: 1.2rem; } - > p { + p { margin: 0.5em 0; - line-height: 1.5em; hyphens: auto; text-align: justify; + line-height: 1.5em; } - a:not([class]) { + ul, ol { + padding-left: 1em; + + ul, ol { + padding-left: 1em; + } + } + + li { + line-height: 1.5em; + } + + a { color: var(--c-primary); font-family: var(--serif); font-weight: 500; @@ -44,13 +56,6 @@ } } - > ul, ol { - padding-left: 1em; - - ul, ol { - padding-left: 1em; - } - } img:not([class]) { max-width: 100%; diff --git a/styles/shortcodes/_marginnote.scss b/styles/shortcodes/_marginnote.scss index ef93744..12958f6 100644 --- a/styles/shortcodes/_marginnote.scss +++ b/styles/shortcodes/_marginnote.scss @@ -25,4 +25,4 @@ $border: 1px dashed gray; border-left: $border; border-style: none none none dashed; } -} \ No newline at end of file +}