sorta working
This commit is contained in:
parent
ac03c35eb6
commit
9c3f35dda0
7 changed files with 630 additions and 244 deletions
349
Cargo.lock
generated
349
Cargo.lock
generated
|
|
@ -154,12 +154,6 @@ dependencies = [
|
|||
"backtrace",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "bigdecimal"
|
||||
version = "0.4.10"
|
||||
|
|
@ -358,13 +352,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.5.0"
|
||||
name = "countme"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
|
|
@ -375,6 +366,25 @@ dependencies = [
|
|||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.12"
|
||||
|
|
@ -484,22 +494,6 @@ version = "0.1.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "fsevent-sys"
|
||||
version = "4.1.0"
|
||||
|
|
@ -788,7 +782,6 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown 0.12.3",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -801,30 +794,6 @@ dependencies = [
|
|||
"hashbrown 0.16.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indextree"
|
||||
version = "4.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f80a9409db2176ff13877276660f5149fee32592698d2100afe8b52043d4405"
|
||||
dependencies = [
|
||||
"indextree-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indextree-macros"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f85dac6c239acc85fd61934c572292d93adfd2de459d9c032aa22b553506e915"
|
||||
dependencies = [
|
||||
"either",
|
||||
"itertools",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strum",
|
||||
"syn",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify"
|
||||
version = "0.11.1"
|
||||
|
|
@ -857,15 +826,6 @@ version = "1.70.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
|
|
@ -926,12 +886,6 @@ version = "1.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[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.183"
|
||||
|
|
@ -944,12 +898,6 @@ version = "0.2.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.12.1"
|
||||
|
|
@ -1002,6 +950,15 @@ version = "2.8.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miette"
|
||||
version = "7.6.0"
|
||||
|
|
@ -1045,7 +1002,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1183,28 +1139,6 @@ version = "1.70.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||
|
||||
[[package]]
|
||||
name = "onig"
|
||||
version = "6.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"onig_sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "onig_sys"
|
||||
version = "69.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7f86c6eef3d6df15f23bcfb6af487cbd2fed4e5581d58d5bf1f5f8b7f6727dc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "5.3.0"
|
||||
|
|
@ -1222,34 +1156,37 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"jetscii",
|
||||
"lazy_static",
|
||||
"miette",
|
||||
"notify",
|
||||
"orgize",
|
||||
"pretty_assertions",
|
||||
"rayon",
|
||||
"rowan 0.16.1",
|
||||
"serde",
|
||||
"slugify",
|
||||
"steel-core",
|
||||
"tracing",
|
||||
"tracing-log",
|
||||
"tracing-subscriber",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "orgize"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e4998a8f863c00c06e18f83ed3c4de39e01f5a7ee5bddd072f0fb31bacfd7fa"
|
||||
version = "0.10.0-alpha.10"
|
||||
source = "git+https://github.com/PoiScript/orgize.git?branch=v0.10#5f26c94dcec2a33b37b1c880ace053b29b5d021e"
|
||||
dependencies = [
|
||||
"bytecount",
|
||||
"cfg-if",
|
||||
"chrono",
|
||||
"indexmap 1.9.3",
|
||||
"indextree",
|
||||
"indexmap 2.13.0",
|
||||
"jetscii",
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
"nom",
|
||||
"serde",
|
||||
"serde_indextree",
|
||||
"syntect",
|
||||
"rowan 0.15.17",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1287,25 +1224,6 @@ version = "0.2.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "plist"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"indexmap 2.13.0",
|
||||
"quick-xml",
|
||||
"serde",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "3.11.0"
|
||||
|
|
@ -1376,15 +1294,6 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.38.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.45"
|
||||
|
|
@ -1457,6 +1366,26 @@ dependencies = [
|
|||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.18"
|
||||
|
|
@ -1474,27 +1403,52 @@ checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
|||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax 0.8.10",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
||||
|
||||
[[package]]
|
||||
name = "rowan"
|
||||
version = "0.15.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4f1e4a001f863f41ea8d0e6a0c34b356d5b733db50dadab3efef640bafb779b"
|
||||
dependencies = [
|
||||
"countme",
|
||||
"hashbrown 0.14.5",
|
||||
"memoffset",
|
||||
"rustc-hash 1.1.0",
|
||||
"text-size",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rowan"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "417a3a9f582e349834051b8a10c8d71ca88da4211e4093528e36b9845f6b5f21"
|
||||
dependencies = [
|
||||
"countme",
|
||||
"hashbrown 0.14.5",
|
||||
"rustc-hash 1.1.0",
|
||||
"text-size",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.2"
|
||||
|
|
@ -1571,16 +1525,6 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_indextree"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a70e7d58005454b0ba863a8775df0c4391a8128c3a34974001de556d661bf74f"
|
||||
dependencies = [
|
||||
"indextree",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.149"
|
||||
|
|
@ -1618,12 +1562,6 @@ version = "1.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
|
||||
|
||||
[[package]]
|
||||
name = "sized-chunks"
|
||||
version = "0.6.5"
|
||||
|
|
@ -1640,6 +1578,15 @@ version = "0.4.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
|
||||
|
||||
[[package]]
|
||||
name = "slugify"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6b8cf203d2088b831d7558f8e5151bfa420c57a34240b28cee29d0ae5f2ac8b"
|
||||
dependencies = [
|
||||
"unidecode",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.1"
|
||||
|
|
@ -1694,7 +1641,7 @@ dependencies = [
|
|||
"parking_lot",
|
||||
"polling",
|
||||
"rand 0.9.2",
|
||||
"rustc-hash",
|
||||
"rustc-hash 2.1.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"shared_vector",
|
||||
|
|
@ -1744,7 +1691,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"ordered-float",
|
||||
"pretty",
|
||||
"rustc-hash",
|
||||
"rustc-hash 2.1.2",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"thin-vec",
|
||||
|
|
@ -1765,27 +1712,6 @@ version = "0.11.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
|
||||
dependencies = [
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "supports-color"
|
||||
version = "3.0.2"
|
||||
|
|
@ -1829,28 +1755,6 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syntect"
|
||||
version = "4.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b20815bbe80ee0be06e6957450a841185fcf690fe0178f14d77a05ce2caa031"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bitflags 1.3.2",
|
||||
"flate2",
|
||||
"fnv",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"onig",
|
||||
"plist",
|
||||
"regex-syntax 0.6.29",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"walkdir",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.1"
|
||||
|
|
@ -1870,6 +1774,12 @@ dependencies = [
|
|||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "text-size"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.16.2"
|
||||
|
|
@ -1889,26 +1799,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.9"
|
||||
|
|
@ -2061,6 +1951,12 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
||||
|
||||
[[package]]
|
||||
name = "unidecode"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "402bb19d8e03f1d1a7450e2bd613980869438e0666331be3e073089124aa1adc"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
|
|
@ -2333,15 +2229,6 @@ version = "3.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fb433233f2df9344722454bc7e96465c9d03bff9d77c248f9e7523fe79585b5"
|
||||
|
||||
[[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 = "yansi"
|
||||
version = "1.0.1"
|
||||
|
|
|
|||
|
|
@ -11,7 +11,13 @@ serde = { version = "1.0.213", features = ["derive"] }
|
|||
tracing = "0.1.40"
|
||||
tracing-log = "0.2.0"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["fmt", "std", "chrono", "time", "local-time", "env-filter"] }
|
||||
orgize = { version = "0.9.0", features = ["chrono", "indexmap", "syntect"] }
|
||||
orgize = { git="https://github.com/PoiScript/orgize.git", branch = "v0.10", features = ["chrono", "indexmap", "tracing"] }
|
||||
steel-core = { git="https://github.com/mattwparas/steel.git", branch = "master" }
|
||||
chrono = "0.4.44"
|
||||
notify = "8.2.0"
|
||||
walkdir = "2.5.0"
|
||||
jetscii = "0.5.3"
|
||||
lazy_static = "1.5.0"
|
||||
rowan = "0.16.1"
|
||||
slugify = "0.1.0"
|
||||
rayon = "1.11.0"
|
||||
|
|
|
|||
6
justfile
6
justfile
|
|
@ -1,4 +1,4 @@
|
|||
file := "-f ~/docs/site/content/"
|
||||
path := "-p ~/docs/site/"
|
||||
verbose := "-v"
|
||||
|
||||
# export RUSTC_WRAPPER := "sccache"
|
||||
|
|
@ -11,7 +11,7 @@ build:
|
|||
build-release:
|
||||
cargo build --release
|
||||
run:
|
||||
cargo run -- {{verbose}} {{file}}
|
||||
cargo run -- {{verbose}} {{path}}
|
||||
run-release:
|
||||
cargo run --release
|
||||
clean:
|
||||
|
|
@ -22,7 +22,7 @@ bench:
|
|||
export NEXTEST_EXPERIMENTAL_BENCHMARKS=1
|
||||
cargo nextest bench
|
||||
profile:
|
||||
samply record cargo run --release -- {{verbose}} {{file}}
|
||||
samply record cargo run --release -- {{verbose}} {{path}}
|
||||
|
||||
alias b := build
|
||||
alias r := run
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
pub mod org;
|
||||
pub mod publish;
|
||||
pub mod watcher;
|
||||
|
||||
|
|
@ -32,11 +33,10 @@ fn main() -> Result<()> {
|
|||
.parse_lossy(default_directive);
|
||||
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.pretty()
|
||||
.with_line_number(true)
|
||||
.with_level(true)
|
||||
.with_env_filter(filter)
|
||||
.with_target(true)
|
||||
// .with_line_number(true)
|
||||
.with_level(true)
|
||||
.with_target(false)
|
||||
.with_timer(timer)
|
||||
.init();
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1,353 @@
|
|||
use orgize::ast::Token;
|
||||
use rowan::NodeOrToken;
|
||||
use slugify::slugify;
|
||||
use std::cmp::min;
|
||||
use std::fmt;
|
||||
use std::fmt::Write as _;
|
||||
|
||||
use orgize::export::{Container, Event, TraversalContext, Traverser};
|
||||
use orgize::{SyntaxElement, SyntaxKind, SyntaxNode};
|
||||
|
||||
/// A wrapper for escaping sensitive characters in html.
|
||||
///
|
||||
/// ```rust
|
||||
/// use orgize::export::HtmlEscape as Escape;
|
||||
///
|
||||
/// assert_eq!(format!("{}", Escape("< < <")), "< < <");
|
||||
/// assert_eq!(
|
||||
/// format!("{}", Escape("<script>alert('Hello XSS')</script>")),
|
||||
/// "<script>alert('Hello XSS')</script>"
|
||||
/// );
|
||||
/// ```
|
||||
pub struct HtmlEscape<S: AsRef<str>>(pub S);
|
||||
|
||||
impl<S: AsRef<str>> fmt::Display for HtmlEscape<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut pos = 0;
|
||||
|
||||
let content = self.0.as_ref();
|
||||
let bytes = content.as_bytes();
|
||||
|
||||
while let Some(off) = jetscii::bytes!(b'<', b'>', b'&', b'\'', b'"').find(&bytes[pos..]) {
|
||||
write!(f, "{}", &content[pos..pos + off])?;
|
||||
|
||||
pos += off + 1;
|
||||
|
||||
match bytes[pos - 1] {
|
||||
b'<' => write!(f, "<")?,
|
||||
b'>' => write!(f, ">")?,
|
||||
b'&' => write!(f, "&")?,
|
||||
b'\'' => write!(f, "'")?,
|
||||
b'"' => write!(f, """)?,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
write!(f, "{}", &content[pos..])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OrgHtmlExporter {
|
||||
output: String,
|
||||
|
||||
in_descriptive_list: Vec<bool>,
|
||||
|
||||
table_row: TableRow,
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Eq)]
|
||||
enum TableRow {
|
||||
#[default]
|
||||
HeaderRule,
|
||||
Header,
|
||||
BodyRule,
|
||||
Body,
|
||||
}
|
||||
|
||||
impl OrgHtmlExporter {
|
||||
pub fn push_str(&mut self, s: impl AsRef<str>) {
|
||||
self.output += s.as_ref();
|
||||
}
|
||||
|
||||
pub fn finish(self) -> String {
|
||||
self.output
|
||||
}
|
||||
|
||||
/// Render syntax node to html string
|
||||
///
|
||||
/// ```rust
|
||||
/// use orgize::{Org, ast::Bold, export::HtmlExport, rowan::ast::AstNode};
|
||||
///
|
||||
/// let org = Org::parse("* /hello/ *world*");
|
||||
/// let bold = org.first_node::<Bold>().unwrap();
|
||||
/// let mut html = HtmlExport::default();
|
||||
/// html.render(bold.syntax());
|
||||
/// assert_eq!(html.finish(), "<b>world</b>");
|
||||
/// ```
|
||||
pub fn render(&mut self, node: &SyntaxNode) {
|
||||
let mut ctx = TraversalContext::default();
|
||||
self.element(SyntaxElement::Node(node.clone()), &mut ctx);
|
||||
}
|
||||
}
|
||||
|
||||
impl Traverser for OrgHtmlExporter {
|
||||
fn event(&mut self, event: Event, ctx: &mut TraversalContext) {
|
||||
match event {
|
||||
Event::Enter(Container::Document(_)) => self.output += "<main>",
|
||||
Event::Leave(Container::Document(_)) => self.output += "</main>",
|
||||
|
||||
Event::Enter(Container::Headline(headline)) => {
|
||||
let level = min(headline.level() + 1, 6);
|
||||
let _ = write!(&mut self.output, "<h{level}>");
|
||||
let title = headline.title().map(|h| h.to_string()).collect::<String>();
|
||||
let _ = write!(
|
||||
&mut self.output,
|
||||
"<a id=\"{0}\" href=\"#{0}\">",
|
||||
slugify!(&title)
|
||||
);
|
||||
for elem in headline.title() {
|
||||
self.element(elem, ctx);
|
||||
}
|
||||
self.output += "</a>";
|
||||
let _ = write!(&mut self.output, "</h{level}>");
|
||||
}
|
||||
Event::Leave(Container::Headline(_)) => {}
|
||||
|
||||
Event::Enter(Container::Paragraph(_)) => self.output += "<p>",
|
||||
Event::Leave(Container::Paragraph(_)) => self.output += "</p>",
|
||||
|
||||
Event::Enter(Container::Section(_)) => self.output += "<section>",
|
||||
Event::Leave(Container::Section(_)) => self.output += "</section>",
|
||||
|
||||
Event::Enter(Container::Italic(_)) => self.output += "<i>",
|
||||
Event::Leave(Container::Italic(_)) => self.output += "</i>",
|
||||
|
||||
Event::Enter(Container::Bold(_)) => self.output += "<b>",
|
||||
Event::Leave(Container::Bold(_)) => self.output += "</b>",
|
||||
|
||||
Event::Enter(Container::Strike(_)) => self.output += "<s>",
|
||||
Event::Leave(Container::Strike(_)) => self.output += "</s>",
|
||||
|
||||
Event::Enter(Container::Underline(_)) => self.output += "<u>",
|
||||
Event::Leave(Container::Underline(_)) => self.output += "</u>",
|
||||
|
||||
Event::Enter(Container::Verbatim(_)) => self.output += "<code>",
|
||||
Event::Leave(Container::Verbatim(_)) => self.output += "</code>",
|
||||
|
||||
Event::Enter(Container::Code(_)) => self.output += "<code>",
|
||||
Event::Leave(Container::Code(_)) => self.output += "</code>",
|
||||
|
||||
Event::Enter(Container::SourceBlock(block)) => {
|
||||
if let Some(language) = block.language() {
|
||||
let _ = write!(
|
||||
&mut self.output,
|
||||
r#"<pre><code class="language-{}">"#,
|
||||
HtmlEscape(&language)
|
||||
);
|
||||
} else {
|
||||
self.output += r#"<pre><code>"#
|
||||
}
|
||||
}
|
||||
Event::Leave(Container::SourceBlock(_)) => self.output += "</code></pre>",
|
||||
|
||||
Event::Enter(Container::QuoteBlock(_)) => self.output += "<blockquote>",
|
||||
Event::Leave(Container::QuoteBlock(_)) => self.output += "</blockquote>",
|
||||
|
||||
Event::Enter(Container::VerseBlock(_)) => self.output += "<p class=\"verse\">",
|
||||
Event::Leave(Container::VerseBlock(_)) => self.output += "</p>",
|
||||
|
||||
Event::Enter(Container::ExampleBlock(_)) => self.output += "<pre class=\"example\">",
|
||||
Event::Leave(Container::ExampleBlock(_)) => self.output += "</pre>",
|
||||
|
||||
Event::Enter(Container::CenterBlock(_)) => self.output += "<div class=\"center\">",
|
||||
Event::Leave(Container::CenterBlock(_)) => self.output += "</div>",
|
||||
|
||||
Event::Enter(Container::CommentBlock(_)) => self.output += "<!--",
|
||||
Event::Leave(Container::CommentBlock(_)) => self.output += "-->",
|
||||
|
||||
Event::Enter(Container::Comment(_)) => self.output += "<!--",
|
||||
Event::Leave(Container::Comment(_)) => self.output += "-->",
|
||||
|
||||
Event::Enter(Container::Subscript(_)) => self.output += "<sub>",
|
||||
Event::Leave(Container::Subscript(_)) => self.output += "</sub>",
|
||||
|
||||
Event::Enter(Container::Superscript(_)) => self.output += "<sup>",
|
||||
Event::Leave(Container::Superscript(_)) => self.output += "</sup>",
|
||||
|
||||
Event::Enter(Container::List(list)) => {
|
||||
self.output += if list.is_ordered() {
|
||||
self.in_descriptive_list.push(false);
|
||||
"<ol>"
|
||||
} else if list.is_descriptive() {
|
||||
self.in_descriptive_list.push(true);
|
||||
"<dl>"
|
||||
} else {
|
||||
self.in_descriptive_list.push(false);
|
||||
"<ul>"
|
||||
};
|
||||
}
|
||||
Event::Leave(Container::List(list)) => {
|
||||
self.output += if list.is_ordered() {
|
||||
"</ol>"
|
||||
} else if let Some(true) = self.in_descriptive_list.last() {
|
||||
"</dl>"
|
||||
} else {
|
||||
"</ul>"
|
||||
};
|
||||
self.in_descriptive_list.pop();
|
||||
}
|
||||
Event::Enter(Container::ListItem(list_item)) => {
|
||||
if let Some(&true) = self.in_descriptive_list.last() {
|
||||
self.output += "<dt>";
|
||||
for elem in list_item.tag() {
|
||||
self.element(elem, ctx);
|
||||
}
|
||||
self.output += "</dt><dd>";
|
||||
} else {
|
||||
self.output += "<li>";
|
||||
}
|
||||
}
|
||||
Event::Leave(Container::ListItem(_)) => {
|
||||
if let Some(&true) = self.in_descriptive_list.last() {
|
||||
self.output += "</dd>";
|
||||
} else {
|
||||
self.output += "</li>";
|
||||
}
|
||||
}
|
||||
|
||||
Event::Enter(Container::OrgTable(table)) => {
|
||||
self.output += "<table>";
|
||||
self.table_row = if table.has_header() {
|
||||
TableRow::HeaderRule
|
||||
} else {
|
||||
TableRow::BodyRule
|
||||
}
|
||||
}
|
||||
Event::Leave(Container::OrgTable(_)) => {
|
||||
match self.table_row {
|
||||
TableRow::Body => self.output += "</tbody>",
|
||||
TableRow::Header => self.output += "</thead>",
|
||||
_ => {}
|
||||
}
|
||||
self.output += "</table>";
|
||||
}
|
||||
Event::Enter(Container::OrgTableRow(row)) => {
|
||||
if row.is_rule() {
|
||||
match self.table_row {
|
||||
TableRow::Body => {
|
||||
self.output += "</tbody>";
|
||||
self.table_row = TableRow::BodyRule;
|
||||
}
|
||||
TableRow::Header => {
|
||||
self.output += "</thead>";
|
||||
self.table_row = TableRow::BodyRule;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
ctx.skip();
|
||||
} else {
|
||||
match self.table_row {
|
||||
TableRow::HeaderRule => {
|
||||
self.table_row = TableRow::Header;
|
||||
self.output += "<thead>";
|
||||
}
|
||||
TableRow::BodyRule => {
|
||||
self.table_row = TableRow::Body;
|
||||
self.output += "<tbody>";
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
self.output += "<tr>";
|
||||
}
|
||||
}
|
||||
Event::Leave(Container::OrgTableRow(row)) => {
|
||||
if row.is_rule() {
|
||||
match self.table_row {
|
||||
TableRow::Body => {
|
||||
self.output += "</tbody>";
|
||||
self.table_row = TableRow::BodyRule;
|
||||
}
|
||||
TableRow::Header => {
|
||||
self.output += "</thead>";
|
||||
self.table_row = TableRow::BodyRule;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
ctx.skip();
|
||||
} else {
|
||||
self.output += "</tr>";
|
||||
}
|
||||
}
|
||||
Event::Enter(Container::OrgTableCell(_)) => self.output += "<td>",
|
||||
Event::Leave(Container::OrgTableCell(_)) => self.output += "</td>",
|
||||
|
||||
Event::Enter(Container::Link(link)) => {
|
||||
let path = link.path();
|
||||
let path = path.trim_start_matches("file:");
|
||||
|
||||
if link.is_image() {
|
||||
let _ = write!(&mut self.output, r#"<img src="{}">"#, HtmlEscape(&path));
|
||||
return ctx.skip();
|
||||
}
|
||||
|
||||
let _ = write!(&mut self.output, r#"<a href="{}">"#, HtmlEscape(&path));
|
||||
|
||||
if !link.has_description() {
|
||||
let _ = write!(&mut self.output, "{}</a>", HtmlEscape(&path));
|
||||
ctx.skip();
|
||||
}
|
||||
}
|
||||
Event::Leave(Container::Link(_)) => self.output += "</a>",
|
||||
|
||||
Event::Text(text) => {
|
||||
let _ = write!(&mut self.output, "{}", HtmlEscape(text));
|
||||
}
|
||||
|
||||
Event::LineBreak(_) => self.output += "<br/>",
|
||||
|
||||
Event::Snippet(snippet) => {
|
||||
if snippet.backend().eq_ignore_ascii_case("html") {
|
||||
self.output += &snippet.value();
|
||||
}
|
||||
}
|
||||
|
||||
Event::Rule(_) => self.output += "<hr/>",
|
||||
|
||||
Event::Timestamp(timestamp) => {
|
||||
self.output += r#"<span class="timestamp-wrapper"><span class="timestamp">"#;
|
||||
// for e in timestamp.syntax.children_with_tokens() {
|
||||
// match e {
|
||||
// NodeOrToken::Token(t) if t.kind() == SyntaxKind::MINUS2 => {
|
||||
// self.output += "–";
|
||||
// }
|
||||
// NodeOrToken::Token(t) => {
|
||||
// self.output += t.text();
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
// }
|
||||
self.output += r#"</span></span>"#;
|
||||
}
|
||||
|
||||
Event::LatexFragment(latex) => {
|
||||
// let _ = write!(&mut self.output, "{}", &latex.syntax);
|
||||
}
|
||||
Event::LatexEnvironment(latex) => {
|
||||
// let _ = write!(&mut self.output, "{}", &latex.syntax);
|
||||
}
|
||||
|
||||
Event::Enter(Container::Keyword(keyword)) => {
|
||||
if keyword.key().to_uppercase() == "TITLE" {
|
||||
self.output += r#"<h1 class="title">"#;
|
||||
self.output += &keyword.value();
|
||||
self.output += r#"</h1>"#;
|
||||
}
|
||||
}
|
||||
|
||||
Event::Entity(entity) => self.output += entity.html(),
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,15 @@
|
|||
use orgize::ast::Keyword;
|
||||
use rayon::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::io::Error as IOError;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tracing::{debug, error};
|
||||
use walkdir::{DirEntry, Error as WDError, WalkDir};
|
||||
|
||||
use crate::org::exporter::OrgHtmlExporter;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Project {
|
||||
name: String,
|
||||
base_directory: PathBuf,
|
||||
|
|
@ -19,6 +29,7 @@ pub struct Project {
|
|||
html_validation_link: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Action {
|
||||
Org,
|
||||
Attach,
|
||||
|
|
@ -30,8 +41,122 @@ pub enum Error {
|
|||
ParseError(PathBuf),
|
||||
InternalError,
|
||||
IO(IOError),
|
||||
WalkDir(WDError),
|
||||
NotDirectory,
|
||||
}
|
||||
|
||||
pub fn build_site(path: impl AsRef<Path>) -> Result<(), Error> {
|
||||
todo!()
|
||||
pub fn build_site(
|
||||
base_path: impl AsRef<Path>,
|
||||
publish_path: impl AsRef<Path>,
|
||||
) -> Result<(), Error> {
|
||||
let base_path = base_path.as_ref().to_path_buf();
|
||||
let publish_path = publish_path.as_ref().to_path_buf();
|
||||
if !publish_path.exists() {
|
||||
if let Err(e) = fs::create_dir_all(&publish_path) {
|
||||
error!("Couldn't create publish directory, check permissions: {e}");
|
||||
}
|
||||
}
|
||||
if base_path.is_dir() {
|
||||
WalkDir::new(&base_path)
|
||||
.follow_links(true)
|
||||
.into_iter()
|
||||
.collect::<Vec<Result<walkdir::DirEntry, WDError>>>()
|
||||
.into_par_iter()
|
||||
.filter_map(|res| res.ok())
|
||||
.for_each(|entry| {
|
||||
let path = entry.path();
|
||||
let file_name = path.file_name().unwrap_or_default().to_string_lossy();
|
||||
if path.is_file() && !path.ends_with("~") && !file_name.starts_with(".#") {
|
||||
let mut handler = OrgHtmlExporter::default();
|
||||
debug!(?path);
|
||||
if path
|
||||
.extension()
|
||||
.iter()
|
||||
.filter_map(|s| s.to_str())
|
||||
.collect::<String>()
|
||||
== "org"
|
||||
{
|
||||
debug!("It ends with org");
|
||||
let org_string = fs::read_to_string(path).unwrap_or_default();
|
||||
let org = orgize::Org::parse(&org_string);
|
||||
let mut keywords = org.keywords();
|
||||
let keywords = extract_keywords(&mut keywords);
|
||||
org.traverse(&mut handler);
|
||||
|
||||
let html = build_html(handler.finish(), keywords);
|
||||
if let Ok(stripped_path) = path.strip_prefix(base_path.clone()) {
|
||||
let mut final_dest = publish_path.clone();
|
||||
final_dest.push(stripped_path);
|
||||
final_dest.set_extension("html");
|
||||
if let Err(e) = fs::write(final_dest, html) {
|
||||
error!("Error writing html: {e}");
|
||||
}
|
||||
} else {
|
||||
error!(?path, "This file is not in content directory");
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::NotDirectory)
|
||||
}
|
||||
}
|
||||
|
||||
fn build_html(inner_html: String, keywords: HashMap<String, String>) -> String {
|
||||
let title = if let Some(title) = keywords.get("TITLE") {
|
||||
format!("<title>{}</title>", title)
|
||||
} else {
|
||||
"<title>My Site</title>".to_string()
|
||||
};
|
||||
let author = if let Some(author) = keywords.get("AUTHOR") {
|
||||
format!("<meta name=\"author\" content=\"{}\" />", author)
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
let description = if let Some(author) = keywords.get("AUTHOR") {
|
||||
format!("<meta name=\"description\" content=\"{}\" />", author)
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
let build_time = chrono::Local::now()
|
||||
.naive_local()
|
||||
.format("%Y-%m-%d %H:%M")
|
||||
.to_string();
|
||||
let time_comment = format!("<!-- {} -->", build_time);
|
||||
let doctype_html = "<!DOCTYPE html>
|
||||
<html lang=\"en\">";
|
||||
let charset = r#"<meta charset="utf-8" />"#;
|
||||
let style = r#"<link rel="stylesheet" href="./static/pico.snazzy.css" type="text/css"/>"#;
|
||||
let viewport = r#"<meta name="viewport" content="width=device-width, initial-scale=1" />"#;
|
||||
let generator = r#"<meta name="generator" content="Organic" />"#;
|
||||
let mut head = format!("{}\n<head>", doctype_html);
|
||||
head.push_str(&time_comment);
|
||||
head.push_str(&charset);
|
||||
head.push_str(&viewport);
|
||||
head.push_str(&title);
|
||||
head.push_str(&description);
|
||||
head.push_str(&generator);
|
||||
head.push_str(&author);
|
||||
head.push_str(&style);
|
||||
head.push_str("</head>");
|
||||
let other_style = r#"<style>
|
||||
li:nth-child(n+7) {
|
||||
display: none;
|
||||
}
|
||||
</style>"#;
|
||||
format!("{}\n<body>\n{}\n</body></html>", head, inner_html)
|
||||
}
|
||||
|
||||
fn extract_keywords<I>(keywords: &mut I) -> HashMap<String, String>
|
||||
where
|
||||
I: Iterator<Item = Keyword>,
|
||||
{
|
||||
let mut map = HashMap::new();
|
||||
for keyword in keywords {
|
||||
map.entry(keyword.key().to_uppercase())
|
||||
.or_insert(keyword.value().to_string());
|
||||
}
|
||||
map
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use notify::{Event, EventKind, Result};
|
||||
use tracing::debug;
|
||||
use notify::{Event, EventKind};
|
||||
use tracing::{debug, info};
|
||||
|
||||
pub fn watch(event: Event, path: impl AsRef<Path>) -> Result<()> {
|
||||
use crate::publish::publish::{Error, build_site};
|
||||
|
||||
pub fn watch(event: Event, path: impl AsRef<Path>) -> Result<(), Error> {
|
||||
if event
|
||||
.paths
|
||||
.clone()
|
||||
|
|
@ -30,6 +32,20 @@ pub fn watch(event: Event, path: impl AsRef<Path>) -> Result<()> {
|
|||
debug!("file deleted");
|
||||
}
|
||||
}
|
||||
let begin = chrono::Local::now();
|
||||
let mut base_path = path.as_ref().to_path_buf();
|
||||
base_path.push("content");
|
||||
let mut publish_path = path.as_ref().to_path_buf();
|
||||
publish_path.push("public");
|
||||
build_site(base_path, publish_path)?;
|
||||
let end = chrono::Local::now();
|
||||
let elapsed = end - begin;
|
||||
info!(
|
||||
"Time to build: {:?} minutes, {:?} seconds, and {:?} nanoseconds",
|
||||
elapsed.num_minutes(),
|
||||
elapsed.num_seconds(),
|
||||
elapsed.num_nanoseconds()
|
||||
);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue