From 2948d141c264e983eec8d48f24049d535c64d6a9 Mon Sep 17 00:00:00 2001 From: Zoey Date: Tue, 17 Aug 2021 09:59:34 -0700 Subject: [PATCH] Initial commit --- .gitignore | 1 + .rustfmt.toml | 1 + .vscode/tasks.json | 15 + Cargo.lock | 866 +++++++++++++++++++++++++++++++++++++ Cargo.toml | 16 + site/build/index.html | 15 + site/build/static/site.css | 4 + site/config.yaml | 3 + site/pages/index.md | 3 + site/static/site.css | 4 + site/templates/base.hbs | 13 + site/test.md | 7 + src/lib.rs | 242 +++++++++++ src/main.rs | 12 + 14 files changed, 1202 insertions(+) create mode 100644 .gitignore create mode 100644 .rustfmt.toml create mode 100644 .vscode/tasks.json create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 site/build/index.html create mode 100644 site/build/static/site.css create mode 100644 site/config.yaml create mode 100644 site/pages/index.md create mode 100644 site/static/site.css create mode 100644 site/templates/base.hbs create mode 100644 site/test.md create mode 100644 src/lib.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000..218e203 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1 @@ +hard_tabs = true diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..aebe34d --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "cargo", + "command": "run", + "problemMatcher": ["$rustc"], + "label": "rust: cargo run", + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..4577a41 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,866 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" + +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "cssparser" +version = "0.25.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbe18ca4efb9ba3716c6da66cc3d7e673bf59fa576353011f48c4cfddbdd740e" +dependencies = [ + "autocfg", + "cssparser-macros", + "dtoa-short", + "itoa", + "matches", + "phf", + "proc-macro2", + "procedural-masquerade", + "quote", + "smallvec", + "syn", +] + +[[package]] +name = "cssparser-macros" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb1c84e87c717666564ec056105052331431803d606bd45529b28547b611eef" +dependencies = [ + "phf_codegen", + "proc-macro2", + "procedural-masquerade", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "dtoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" + +[[package]] +name = "dtoa-short" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03329ae10e79ede66c9ce4dc930aa8599043b0743008548680f25b91502d6" +dependencies = [ + "dtoa", +] + +[[package]] +name = "encoding_rs" +version = "0.8.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "extract-frontmatter" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b4c6ac125f7d6663c9bee567645050c9a164c4dbf5689bd5bdf344a1b39356" + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fs_extra" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "gray_matter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deed89f803cf559d60ec5cf204f35a9a803dbdf39182b431791b3f0a36a2b9f2" +dependencies = [ + "json", + "regex", + "serde", + "serde_json", + "toml", + "yaml-rust", +] + +[[package]] +name = "handlebars" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd85ecabdb47308d28d3a4113224fefcab2510ccb4e463aee0a1362eb84c756a" +dependencies = [ + "log", + "pest", + "pest_derive", + "quick-error", + "serde", + "serde_json", +] + +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +dependencies = [ + "ahash", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" + +[[package]] +name = "linked-hash-map" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "lol_html" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b59f94556144354f6abfb3fe175e8f2da290329f254ab4019e5096875f6056e3" +dependencies = [ + "bitflags", + "cfg-if 0.1.10", + "cssparser", + "encoding_rs", + "hashbrown", + "lazy_static", + "lazycell", + "memchr", + "safemem", + "selectors", + "thiserror", +] + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "memchr" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +dependencies = [ + "maplit", + "pest", + "sha-1", +] + +[[package]] +name = "phf" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" +dependencies = [ + "siphasher", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "procedural-masquerade" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1383dff4092fe903ac180e391a8d4121cc48f08ccf850614b0290c6673b69d" + +[[package]] +name = "pulldown-cmark" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8" +dependencies = [ + "bitflags", + "memchr", + "unicase", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg", + "libc", + "rand_chacha", + "rand_core 0.4.2", + "rand_hc", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg", + "rand_core 0.3.1", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "safemem" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "selectors" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b86b100bede4f651059740afc3b6cb83458d7401cb7c1ad96d8a11e91742c86" +dependencies = [ + "bitflags", + "cssparser", + "fxhash", + "log", + "matches", + "phf", + "phf_codegen", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + +[[package]] +name = "serde" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.8.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15654ed4ab61726bf918a39cb8d98a2e2995b002387807fa6ba58fdf7f59bb23" +dependencies = [ + "dtoa", + "linked-hash-map", + "serde", + "yaml-rust", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha-1" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" +dependencies = [ + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", +] + +[[package]] +name = "siphasher" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" + +[[package]] +name = "smallvec" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" +dependencies = [ + "maybe-uninit", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "syn" +version = "1.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "typenum" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "zoey" +version = "0.1.0" +dependencies = [ + "anyhow", + "extract-frontmatter", + "fs_extra", + "gray_matter", + "handlebars", + "lol_html", + "pulldown-cmark", + "serde", + "serde_yaml", + "walkdir", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f24079c --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "zoey" +version = "0.1.0" +edition = "2018" + +[dependencies] +anyhow = "1" +extract-frontmatter = "2.1" +fs_extra = "1.2" +gray_matter = "0.1" +handlebars = "4.1" +lol_html = "0.3" +pulldown-cmark = { version = "0.8", default-features = false, features = ["simd"] } +serde = { version = "1", features = ["derive"] } +serde_yaml = "0.8" +walkdir = "2" diff --git a/site/build/index.html b/site/build/index.html new file mode 100644 index 0000000..677956d --- /dev/null +++ b/site/build/index.html @@ -0,0 +1,15 @@ + + + + + + +zoey.dev + + +

Welcome

+

Welcome to the site!

+ + + + diff --git a/site/build/static/site.css b/site/build/static/site.css new file mode 100644 index 0000000..2b8ee27 --- /dev/null +++ b/site/build/static/site.css @@ -0,0 +1,4 @@ +body { + font-family: sans-serif; + margin: 0; +} diff --git a/site/config.yaml b/site/config.yaml new file mode 100644 index 0000000..7f3005e --- /dev/null +++ b/site/config.yaml @@ -0,0 +1,3 @@ +base_url: "https://zoey.dev" +title: zoey.dev +description: "Zoey's site." diff --git a/site/pages/index.md b/site/pages/index.md new file mode 100644 index 0000000..ae1b3c6 --- /dev/null +++ b/site/pages/index.md @@ -0,0 +1,3 @@ +# Welcome + +Welcome to the site! diff --git a/site/static/site.css b/site/static/site.css new file mode 100644 index 0000000..2b8ee27 --- /dev/null +++ b/site/static/site.css @@ -0,0 +1,4 @@ +body { + font-family: sans-serif; + margin: 0; +} diff --git a/site/templates/base.hbs b/site/templates/base.hbs new file mode 100644 index 0000000..1c1b170 --- /dev/null +++ b/site/templates/base.hbs @@ -0,0 +1,13 @@ + + + + + {{{head}}} + + + + + {{{page}}} + + + diff --git a/site/test.md b/site/test.md new file mode 100644 index 0000000..98288e0 --- /dev/null +++ b/site/test.md @@ -0,0 +1,7 @@ +--- +title: Test Page +--- + +# Heading + +_Hi_ there. diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..94ffa55 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,242 @@ +#![feature(path_try_exists)] + +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; + +use anyhow::Context; +use gray_matter::{engine::yaml::YAML, matter::Matter}; +use handlebars::Handlebars; +use lol_html::{element, html_content::ContentType, HtmlRewriter, Settings}; +use pulldown_cmark::{Options, Parser}; +use serde::{Deserialize, Serialize}; +use walkdir::WalkDir; + +/// Struct for the site's configuration. +#[derive(Debug, Deserialize)] +pub struct SiteConfig { + /// The location the site is at. + pub base_url: String, + /// The site's title. + pub title: String, + /// The site's description? Not sure if this will actually be used or not + pub description: String, +} + +/// Struct for the front matter in templates. (nothing here yet) +#[derive(Debug, Deserialize)] +pub struct TemplateMetadata {} + +/// Struct containing data to be sent to templates when rendering them. +#[derive(Debug, Serialize)] +struct TemplateData<'a> { + /// The rendered page. + pub page: &'a str, +} + +/// Struct for the front matter in pages. +#[derive(Debug, Deserialize)] +pub struct PageMetadata { + /// The page's title. + pub title: Option, + /// The template to use for the page. If not specified, it defaults to "base". + pub template: Option, +} + +/// Struct containing information about the site. +#[derive(Debug)] +pub struct Site { + /// The path to the site. + pub site_path: PathBuf, + /// The site's configuration. + pub config: SiteConfig, + /// An index of available templates. + pub template_index: HashMap, + /// An index of available pages. + pub page_index: HashMap, +} + +impl Site { + /// Creates a new site from the given path. + pub fn new(site_path: &Path) -> anyhow::Result { + let config: SiteConfig = serde_yaml::from_str( + &std::fs::read_to_string(site_path.join("config.yaml")) + .context("Failed to read site config")?, + ) + .context("Failed to parse site config")?; + + let mut template_index = HashMap::new(); + let templates_path = site_path.join("templates"); + for entry in WalkDir::new(&templates_path).into_iter() { + let entry = entry.context("Failed to read template entry")?; + let path = entry.path(); + + if let Some(ext) = path.extension() { + if ext == "hbs" && entry.file_type().is_file() { + template_index.insert( + path.strip_prefix(&templates_path) + .context("This really shouldn't have happened")? + .with_extension("") + .to_string_lossy() + .to_string(), + path.to_owned(), + ); + } + } + } + + let mut page_index = HashMap::new(); + let pages_path = site_path.join("pages"); + for entry in WalkDir::new(&pages_path).into_iter() { + let entry = entry.context("Failed to read page entry")?; + let path = entry.path(); + + if let Some(ext) = path.extension() { + if ext == "md" && entry.file_type().is_file() { + page_index.insert( + path.strip_prefix(&pages_path) + .context("This really shouldn't have happened")? + .with_extension("") + .to_string_lossy() + .to_string(), + path.to_owned(), + ); + } + } + } + + Ok(Self { + site_path: site_path.to_owned(), + config, + template_index, + page_index, + }) + } + + /// Builds the site once. + pub fn build_once(&self) -> anyhow::Result<()> { + let builder = SiteBuilder::new(self, None).prepare()?; + + for page_name in self.page_index.keys() { + builder.build_page(page_name)?; + } + + Ok(()) + } +} + +/// Struct used to build the site. +struct SiteBuilder<'a> { + /// The matter instance used to extract front matter. + matter: Matter, + /// The Handlebars registry used to render templates. + reg: Handlebars<'a>, + /// The site info used to build the site. + site: &'a Site, + /// The path to the build directory. + build_path: PathBuf, + /// Whether the site should be build for viewing locally without a server. + local_mode: Option, +} + +impl<'a> SiteBuilder<'a> { + /// Creates a new site builder. + pub fn new(site: &'a Site, local_mode: Option) -> Self { + let build_path = site.site_path.join("build"); + + Self { + matter: Matter::new(), + reg: Handlebars::new(), + site, + build_path, + local_mode, + } + } + + /// Prepares the site builder for use. + pub fn prepare(mut self) -> anyhow::Result { + if std::fs::try_exists(&self.build_path) + .context("Failed check if build directory exists")? + { + std::fs::remove_dir_all(&self.build_path) + .context("Failed to remove old build directory")?; + } + std::fs::create_dir(&self.build_path).context("Failed to create build directory")?; + + for (template_name, template_path) in &self.site.template_index { + self.reg + .register_template_file(template_name, template_path) + .context("Failed to register template file")?; + } + + fs_extra::copy_items( + &[self.site.site_path.join("static")], + &self.build_path, + &fs_extra::dir::CopyOptions::default(), + ) + .context("Failed to copy static directory")?; + + Ok(self) + } + + /// Builds a page. + pub fn build_page(&self, page_name: &str) -> anyhow::Result<()> { + let page_path = self.site.page_index.get(page_name).unwrap(); + + let input = std::fs::read_to_string(page_path) + .with_context(|| format!("Failed to read page at {}", page_path.display()))?; + let page = self.matter.matter_struct::(input); + + let parser = Parser::new_ext(&page.content, Options::all()); + let mut page_html = String::new(); + pulldown_cmark::html::push_html(&mut page_html, parser); + + let out = self.reg.render( + &page.data.template.unwrap_or_else(|| "base".to_string()), + &TemplateData { page: &page_html }, + )?; + + let title = match &page.data.title { + Some(page_title) => format!("{} / {}", self.site.config.title, page_title), + _ => self.site.config.title.clone(), + }; + + let mut output = Vec::new(); + let mut rewriter = HtmlRewriter::new( + Settings { + element_content_handlers: vec![element!("head", |el| { + el.prepend(r#""#, ContentType::Html); + el.append(&format!("{}", title), ContentType::Html); + let base = self + .local_mode + .as_ref() + .unwrap_or(&self.site.config.base_url); + el.append(&format!(r#""#, base), ContentType::Html); + + Ok(()) + })], + ..Default::default() + }, + |c: &[u8]| output.extend_from_slice(c), + ); + + rewriter.write(out.as_bytes())?; + rewriter.end()?; + + let out = String::from_utf8(output)?; + + let out_path = self.build_path.join(page_name).with_extension("html"); + std::fs::create_dir_all(out_path.parent().unwrap()) + .with_context(|| format!("Failed to create directory for page {}", page_name))?; + std::fs::write(&out_path, out).with_context(|| { + format!( + "Failed to create page file at {} for page {}", + out_path.display(), + page_name + ) + })?; + + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..61ae114 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,12 @@ +use std::path::Path; + +use zoey::Site; + +fn main() -> anyhow::Result<()> { + let builder = Site::new(Path::new("site"))?; + builder.build_once()?; + + println!("Build complete!"); + + Ok(()) +}