Compare commits
184 Commits
396b91be10
...
v0.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b06798f23f | ||
|
|
35dff5cdaf | ||
|
|
d641c8d638 | ||
|
|
7e2fd70212 | ||
|
|
4fb08bc7d0 | ||
|
|
01b55b7256 | ||
|
|
bd68681e44 | ||
|
|
27ff13e675 | ||
|
|
2914e42ba1 | ||
|
|
a8969f141d | ||
|
|
6f049e00d4 | ||
|
|
45a1076d18 | ||
|
|
775c88d67a | ||
|
|
efbf6cfc0c | ||
|
|
5af4a372ae | ||
|
|
72952adb6b | ||
|
|
8b85c02ef1 | ||
|
|
2ae4839ce0 | ||
|
|
5654c40d03 | ||
|
|
b538750287 | ||
|
|
65ed754bfe | ||
|
|
80cdf5166b | ||
|
|
3968121d54 | ||
|
|
a29b625631 | ||
|
|
e193fcc2ba | ||
|
|
050b426f6f | ||
|
|
da81f93e4a | ||
|
|
1581e5c401 | ||
|
|
2e1c979127 | ||
|
|
d4b290ebe6 | ||
|
|
4bb1f9983a | ||
|
|
261fe8a1a2 | ||
|
|
add267d616 | ||
|
|
cb3278aba5 | ||
|
|
94d9a95967 | ||
|
|
6511115b95 | ||
|
|
53cd55932b | ||
|
|
cbe2010407 | ||
|
|
2ba4a5e3d7 | ||
|
|
c3482cf1e4 | ||
|
|
fdf84e3d0b | ||
|
|
0a4376dfb8 | ||
|
|
e8ed4a4f4a | ||
|
|
60555999db | ||
|
|
6968a5b02c | ||
|
|
c84cfdc02b | ||
|
|
c98489cacb | ||
|
|
35dbab0ceb | ||
|
|
1ff41940a5 | ||
|
|
884215a7e1 | ||
|
|
20c55f0708 | ||
|
|
9e3d72972c | ||
|
|
806c45a453 | ||
|
|
270c42a509 | ||
|
|
e8963e107b | ||
|
|
0b64551a23 | ||
|
|
b654ca4859 | ||
|
|
386af57ce6 | ||
|
|
ef4d315bf2 | ||
|
|
2142b01967 | ||
|
|
159d8fb72a | ||
|
|
0fae417610 | ||
|
|
ae933b491e | ||
|
|
5e476e189a | ||
|
|
533997dbf5 | ||
|
|
8695cf17c5 | ||
|
|
e2f9938437 | ||
|
|
ada11816fb | ||
|
|
ff57242434 | ||
|
|
0da37b25e3 | ||
|
|
ff03140007 | ||
|
|
0ae492f8d3 | ||
|
|
613d49c6ec | ||
|
|
0f7e5eea25 | ||
|
|
2e7cfd5637 | ||
|
|
afe62de2b6 | ||
|
|
1f3b5262b8 | ||
|
|
f63620b547 | ||
|
|
671159cb82 | ||
|
|
f1e985fb32 | ||
|
|
a966be8122 | ||
|
|
24b9782146 | ||
|
|
3d44d20384 | ||
|
|
f98a09bc59 | ||
|
|
ba511b7f9e | ||
|
|
3720558d93 | ||
|
|
b66ec507ef | ||
|
|
645ae26701 | ||
|
|
6109902945 | ||
|
|
cd27869122 | ||
|
|
795945f0da | ||
|
|
cb7c28c1ae | ||
|
|
52ca300de3 | ||
|
|
06dcd22e69 | ||
|
|
f87c453459 | ||
|
|
e42edb3f49 | ||
|
|
6d83828012 | ||
|
|
eaea37f448 | ||
|
|
fb99fd2b39 | ||
|
|
313313ae53 | ||
|
|
d9a3b13780 | ||
|
|
8d9a50226a | ||
|
|
f164838953 | ||
|
|
fe3f2642fe | ||
|
|
3d89492518 | ||
|
|
793789bdf2 | ||
|
|
dbea9318e9 | ||
|
|
4adaeb0341 | ||
|
|
bfc9e3ed80 | ||
|
|
62ffc76376 | ||
|
|
5bbb12327b | ||
|
|
f6c475c80c | ||
|
|
4c3bea06d1 | ||
|
|
0e9d74b2c8 | ||
|
|
6bf1480366 | ||
|
|
c279bad13a | ||
|
|
bd982fb62d | ||
|
|
53a531f568 | ||
|
|
67b60087af | ||
|
|
8a3b85d5fa | ||
|
|
b0ac14ee58 | ||
|
|
23713a934c | ||
|
|
860b601f62 | ||
|
|
354d24cf69 | ||
|
|
5891ac7fb7 | ||
|
|
f9377d7609 | ||
|
|
4a6948cde7 | ||
|
|
5b34942b64 | ||
|
|
7b01230234 | ||
|
|
c6cf5f75ac | ||
|
|
e3b5f7f74f | ||
|
|
1ac39c2a6f | ||
|
|
744d3e50fb | ||
|
|
4c59011389 | ||
|
|
ba2756c762 | ||
|
|
31a3efe417 | ||
|
|
2b7a19a1d4 | ||
|
|
3b472a9e96 | ||
|
|
77f8375d7a | ||
|
|
3cfcae25a9 | ||
|
|
448e9bb8c6 | ||
|
|
2413923b3f | ||
|
|
ab36a60545 | ||
|
|
68cae57f16 | ||
|
|
11bfb6836f | ||
|
|
3ac7826d2c | ||
|
|
178ce877bc | ||
|
|
2b6f86d4e9 | ||
|
|
dc233d26b1 | ||
|
|
e543a5db74 | ||
|
|
199621b6f1 | ||
|
|
586fd8a066 | ||
|
|
043cc5eda4 | ||
|
|
58aba8efd5 | ||
|
|
ce0819e85b | ||
|
|
fc5342adce | ||
|
|
aed88cf05a | ||
|
|
24bac982f1 | ||
|
|
5f34cb2dd5 | ||
|
|
0b6900eeca | ||
|
|
b72aec9d20 | ||
|
|
a510d0809f | ||
|
|
87d32323f2 | ||
|
|
a0c5b2d852 | ||
|
|
a9fbb4cd63 | ||
|
|
07e4209048 | ||
|
|
2f0f3ab346 | ||
|
|
d8fc49797e | ||
|
|
816780589f | ||
|
|
acaa12cb6e | ||
|
|
051e86e65a | ||
|
|
273734c9ff | ||
|
|
4314937d26 | ||
|
|
672ca07a0e | ||
|
|
6668af2025 | ||
|
|
2350390148 | ||
|
|
933387eb6f | ||
|
|
5f82d7a469 | ||
|
|
63b0619094 | ||
|
|
8b5930f277 | ||
|
|
179b07388a | ||
|
|
a1f4600483 | ||
|
|
1b189cf15c | ||
|
|
7418d4fd81 |
693
Cargo.lock
generated
693
Cargo.lock
generated
@@ -2,6 +2,370 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "addr2line"
|
||||||
|
version = "0.21.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
|
||||||
|
dependencies = [
|
||||||
|
"gimli",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrayvec"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace"
|
||||||
|
version = "0.3.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
|
||||||
|
dependencies = [
|
||||||
|
"addr2line",
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"miniz_oxide",
|
||||||
|
"object",
|
||||||
|
"rustc-demangle",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitvec"
|
||||||
|
version = "0.19.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55f93d0ef3363c364d5976646a38f04cf67cfe1d4c8d160cdea02cab2c116b33"
|
||||||
|
dependencies = [
|
||||||
|
"funty",
|
||||||
|
"radium",
|
||||||
|
"tap",
|
||||||
|
"wyz",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
"clap_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "duster"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17d19cdf8e1ae4aead0978a30e99817af1c36abaf22f81901952b1310abb6989"
|
||||||
|
dependencies = [
|
||||||
|
"nom 6.1.2",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "funty"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures"
|
||||||
|
version = "0.3.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-executor",
|
||||||
|
"futures-io",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-channel"
|
||||||
|
version = "0.3.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-core"
|
||||||
|
version = "0.3.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-executor"
|
||||||
|
version = "0.3.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-io"
|
||||||
|
version = "0.3.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-macro"
|
||||||
|
version = "0.3.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-sink"
|
||||||
|
version = "0.3.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-task"
|
||||||
|
version = "0.3.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-util"
|
||||||
|
version = "0.3.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
|
"futures-macro",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-task",
|
||||||
|
"memchr",
|
||||||
|
"pin-project-lite",
|
||||||
|
"pin-utils",
|
||||||
|
"slab",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gimli"
|
||||||
|
version = "0.28.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.14.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "include_dir"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e"
|
||||||
|
dependencies = [
|
||||||
|
"include_dir_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "include_dir_macros"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lexical-core"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"bitflags",
|
||||||
|
"cfg-if",
|
||||||
|
"ryu",
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.149"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.6.4"
|
version = "2.6.4"
|
||||||
@@ -14,6 +378,44 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
|
||||||
|
dependencies = [
|
||||||
|
"adler",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "natter"
|
||||||
|
version = "0.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"duster",
|
||||||
|
"futures",
|
||||||
|
"include_dir",
|
||||||
|
"organic",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tokio",
|
||||||
|
"toml",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "6.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2"
|
||||||
|
dependencies = [
|
||||||
|
"bitvec",
|
||||||
|
"funty",
|
||||||
|
"lexical-core",
|
||||||
|
"memchr",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "7.1.3"
|
version = "7.1.3"
|
||||||
@@ -25,15 +427,82 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "organic"
|
name = "num_cpus"
|
||||||
version = "0.1.12"
|
version = "1.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a3f0f8a2a6d31c3cac7ebf543d8cb2e8f648300462fc2f6b1a09cac10daf0387"
|
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nom",
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "object"
|
||||||
|
version = "0.32.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "organic"
|
||||||
|
version = "0.1.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c61b01691695303b42f9a2ff318bec83853fbeb65c96569f2fb391e7636801c6"
|
||||||
|
dependencies = [
|
||||||
|
"nom 7.1.3",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "radium"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-demangle"
|
||||||
|
version = "0.1.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "same-file"
|
name = "same-file"
|
||||||
version = "1.0.6"
|
version = "1.0.6"
|
||||||
@@ -43,6 +512,142 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.189"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.189"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.107"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slab"
|
||||||
|
version = "0.4.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.38"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tap"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "1.33.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace",
|
||||||
|
"bytes",
|
||||||
|
"num_cpus",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.20.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
|
[[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"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.4.0"
|
version = "2.4.0"
|
||||||
@@ -85,8 +690,82 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "writer"
|
name = "windows-sys"
|
||||||
version = "0.0.1"
|
version = "0.48.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"organic",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.5.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wyz"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
|
||||||
|
|||||||
31
Cargo.toml
31
Cargo.toml
@@ -1,9 +1,34 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "writer"
|
name = "natter"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
authors = ["Tom Alexander <tom@fizz.buzz>"]
|
||||||
|
description = "A static site generator using org source files."
|
||||||
|
license = "0BSD"
|
||||||
|
repository = "https://code.fizz.buzz/talexander/natter"
|
||||||
|
readme = "README.md"
|
||||||
|
keywords = ["static", "site", "generator"]
|
||||||
|
categories = ["command-line-utilities"]
|
||||||
|
resolver = "2"
|
||||||
|
include = [
|
||||||
|
"LICENSE",
|
||||||
|
"**/*.rs",
|
||||||
|
"Cargo.toml",
|
||||||
|
"Cargo.lock",
|
||||||
|
"default_environment/"
|
||||||
|
]
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
organic = "0.1.12"
|
clap = { version = "4.4.6", default-features = false, features = ["std", "color", "help", "derive"] }
|
||||||
|
duster = "0.1.1"
|
||||||
|
futures = "0.3.29"
|
||||||
|
include_dir = "0.7.3"
|
||||||
|
# TODO: This is temporary to work on the latest organic code. Eventually switch back to using the published crate.
|
||||||
|
# organic = { path = "../organic" }
|
||||||
|
organic = "0.1.13"
|
||||||
|
serde = { version = "1.0.189", default-features = false, features = ["std", "derive"] }
|
||||||
|
serde_json = "1.0.107"
|
||||||
|
tokio = { version = "1.30.0", default-features = false, features = ["rt", "rt-multi-thread", "fs", "io-util"] }
|
||||||
|
toml = "0.8.2"
|
||||||
|
walkdir = "2.4.0"
|
||||||
|
|||||||
10
LICENSE
Normal file
10
LICENSE
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
PERFORMANCE OF THIS SOFTWARE.
|
||||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Natter
|
||||||
|
|
||||||
|
Natter is a static site generator for blogs using org as an input format. It is at a very early stage, and will have deep sweeping changes.
|
||||||
187
default_environment/stylesheet/main.css
Normal file
187
default_environment/stylesheet/main.css
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
:root {
|
||||||
|
--main-max-width: 800px;
|
||||||
|
--site-background-color: #0a0a0a;
|
||||||
|
--site-text-color: #fffffc;
|
||||||
|
--header-divider-color: #6a687a;
|
||||||
|
|
||||||
|
--stream-divider-color: #6ccff6;
|
||||||
|
|
||||||
|
--src-font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace;
|
||||||
|
|
||||||
|
--src-block-background-color: #141414;
|
||||||
|
--src-block-border-color: #84828f;
|
||||||
|
--src-block-language-color: #0a0a0a;
|
||||||
|
--src-block-language-background: #84828f;
|
||||||
|
|
||||||
|
--quote-block-border-color: #84828f;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
color: var(--site-text-color);
|
||||||
|
background-color: var(--site-background-color);
|
||||||
|
font-family: source-sans-pro, Seravek, 'Gill Sans Nova', Ubuntu, Calibri, 'DejaVu Sans', sans-serif;
|
||||||
|
|
||||||
|
a:link, a:visited {
|
||||||
|
/* TODO: Should I use a different color for links? */
|
||||||
|
color: var(--site-text-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.page_centering {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page_header {
|
||||||
|
width: 100%;
|
||||||
|
max-width: var(--main-max-width);
|
||||||
|
border-bottom: 0.1rem solid var(--header-divider-color);
|
||||||
|
|
||||||
|
.home_link {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:link, &:visited {
|
||||||
|
color: var(--site-text-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.main_content {
|
||||||
|
width: 100%;
|
||||||
|
max-width: var(--main-max-width);
|
||||||
|
font-size: 1.2rem;
|
||||||
|
line-height: 1.2;
|
||||||
|
|
||||||
|
/* A stand-alone blog post (not in a blog stream). */
|
||||||
|
.blog_post {
|
||||||
|
padding: 1rem 0 3rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog_stream {
|
||||||
|
.stream_divider {
|
||||||
|
color: var(--stream-divider-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A blog post in a blog stream (for example, the homepage). */
|
||||||
|
.blog_stream_post {
|
||||||
|
background: #1F1F1F;
|
||||||
|
padding: 1rem 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog_post_title {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.src_block {
|
||||||
|
background: var(--src-block-background-color);
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid var(--src-block-border-color);
|
||||||
|
font-size: 1rem;
|
||||||
|
font-family: var(--src-font-family);
|
||||||
|
margin: 1rem 0;
|
||||||
|
|
||||||
|
.src_language {
|
||||||
|
display: inline-block;
|
||||||
|
color: var(--src-block-language-color);
|
||||||
|
background: var(--src-block-language-background);
|
||||||
|
border-radius: 0 0 3px 0;
|
||||||
|
padding: 0.1rem 0.5rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.src_body {
|
||||||
|
margin: 0.5rem;
|
||||||
|
|
||||||
|
.src_line {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline_source_block {
|
||||||
|
font-family: var(--src-font-family);
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code, .verbatim {
|
||||||
|
font-family: var(--src-font-family);
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quote_block {
|
||||||
|
border-left: 1px solid var(--quote-block-border-color);
|
||||||
|
padding: 0 0 0 1rem;
|
||||||
|
margin: 1rem 0 1rem 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2, h3 {
|
||||||
|
margin: 1rem 0;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 2.3rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 2.1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plain_list {
|
||||||
|
&.unordered {
|
||||||
|
list-style-type: disc;
|
||||||
|
padding-left: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ordered {
|
||||||
|
list-style-type: decimal;
|
||||||
|
padding-left: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.descriptive {
|
||||||
|
font-size: 1rem;
|
||||||
|
> dt {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
> dd {
|
||||||
|
padding-left: 2.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footnote_reference {
|
||||||
|
vertical-align: super;
|
||||||
|
font-size: 80%;
|
||||||
|
> a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footnote_definition {
|
||||||
|
.label {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.definition {
|
||||||
|
display: inline;
|
||||||
|
|
||||||
|
> p {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
48
default_environment/stylesheet/reset.css
Normal file
48
default_environment/stylesheet/reset.css
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/* http://meyerweb.com/eric/tools/css/reset/
|
||||||
|
v2.0 | 20110126
|
||||||
|
License: none (public domain)
|
||||||
|
*/
|
||||||
|
|
||||||
|
html, body, div, span, applet, object, iframe,
|
||||||
|
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||||
|
a, abbr, acronym, address, big, cite, code,
|
||||||
|
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||||
|
small, strike, strong, sub, sup, tt, var,
|
||||||
|
b, u, i, center,
|
||||||
|
dl, dt, dd, ol, ul, li,
|
||||||
|
fieldset, form, label, legend,
|
||||||
|
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||||
|
article, aside, canvas, details, embed,
|
||||||
|
figure, figcaption, footer, header, hgroup,
|
||||||
|
menu, nav, output, ruby, section, summary,
|
||||||
|
time, mark, audio, video {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
font: inherit;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
/* HTML5 display-role reset for older browsers */
|
||||||
|
article, aside, details, figcaption, figure,
|
||||||
|
footer, header, hgroup, menu, nav, section {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
ol, ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
blockquote, q {
|
||||||
|
quotes: none;
|
||||||
|
}
|
||||||
|
blockquote:before, blockquote:after,
|
||||||
|
q:before, q:after {
|
||||||
|
content: '';
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
1
default_environment/templates/html/angle_link.dust
Normal file
1
default_environment/templates/html/angle_link.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! angle_link
|
||||||
57
default_environment/templates/html/ast_node.dust
Normal file
57
default_environment/templates/html/ast_node.dust
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
{@select key=.type}
|
||||||
|
{@eq value="heading"}{>heading/}{/eq}
|
||||||
|
{@eq value="section"}{>section/}{/eq}
|
||||||
|
{@eq value="paragraph"}{>paragraph/}{/eq}
|
||||||
|
{@eq value="plain_list"}{>plain_list/}{/eq}
|
||||||
|
{@eq value="center_block"}{>center_block/}{/eq}
|
||||||
|
{@eq value="quote_block"}{>quote_block/}{/eq}
|
||||||
|
{@eq value="special_block"}{>special_block/}{/eq}
|
||||||
|
{@eq value="dynamic_block"}{>dynamic_block/}{/eq}
|
||||||
|
{@eq value="footnote_definition"}{>footnote_definition/}{/eq}
|
||||||
|
{@eq value="comment"}{>comment/}{/eq}
|
||||||
|
{@eq value="drawer"}{>drawer/}{/eq}
|
||||||
|
{@eq value="property_drawer"}{>property_drawer/}{/eq}
|
||||||
|
{@eq value="table"}{>table/}{/eq}
|
||||||
|
{@eq value="verse_block"}{>verse_block/}{/eq}
|
||||||
|
{@eq value="comment_block"}{>comment_block/}{/eq}
|
||||||
|
{@eq value="example_block"}{>example_block/}{/eq}
|
||||||
|
{@eq value="export_block"}{>export_block/}{/eq}
|
||||||
|
{@eq value="src_block"}{>src_block/}{/eq}
|
||||||
|
{@eq value="clock"}{>clock/}{/eq}
|
||||||
|
{@eq value="diary_sexp"}{>diary_sexp/}{/eq}
|
||||||
|
{@eq value="planning"}{>planning/}{/eq}
|
||||||
|
{@eq value="fixed_width_area"}{>fixed_width_area/}{/eq}
|
||||||
|
{@eq value="horizontal_rule"}{>horizontal_rule/}{/eq}
|
||||||
|
{@eq value="keyword"}{>keyword/}{/eq}
|
||||||
|
{@eq value="babel_call"}{>babel_call/}{/eq}
|
||||||
|
{@eq value="latex_environment"}{>latex_environment/}{/eq}
|
||||||
|
{@eq value="bold"}{>bold/}{/eq}
|
||||||
|
{@eq value="italic"}{>italic/}{/eq}
|
||||||
|
{@eq value="underline"}{>underline/}{/eq}
|
||||||
|
{@eq value="strike_through"}{>strike_through/}{/eq}
|
||||||
|
{@eq value="code"}{>code/}{/eq}
|
||||||
|
{@eq value="verbatim"}{>verbatim/}{/eq}
|
||||||
|
{@eq value="plain_text"}{>plain_text/}{/eq}
|
||||||
|
{@eq value="regular_link"}{>regular_link/}{/eq}
|
||||||
|
{@eq value="radio_link"}{>radio_link/}{/eq}
|
||||||
|
{@eq value="radio_target"}{>radio_target/}{/eq}
|
||||||
|
{@eq value="plain_link"}{>plain_link/}{/eq}
|
||||||
|
{@eq value="angle_link"}{>angle_link/}{/eq}
|
||||||
|
{@eq value="org_macro"}{>org_macro/}{/eq}
|
||||||
|
{@eq value="entity"}{>entity/}{/eq}
|
||||||
|
{@eq value="latex_fragment"}{>latex_fragment/}{/eq}
|
||||||
|
{@eq value="export_snippet"}{>export_snippet/}{/eq}
|
||||||
|
{@eq value="footnote_reference"}{>footnote_reference/}{/eq}
|
||||||
|
{@eq value="citation"}{>citation/}{/eq}
|
||||||
|
{@eq value="citation_reference"}{>citation_reference/}{/eq}
|
||||||
|
{@eq value="inline_babel_call"}{>inline_babel_call/}{/eq}
|
||||||
|
{@eq value="inline_source_block"}{>inline_source_block/}{/eq}
|
||||||
|
{@eq value="line_break"}{>line_break/}{/eq}
|
||||||
|
{@eq value="target"}{>target/}{/eq}
|
||||||
|
{@eq value="statistics_cookie"}{>statistics_cookie/}{/eq}
|
||||||
|
{@eq value="subscript"}{>subscript/}{/eq}
|
||||||
|
{@eq value="superscript"}{>superscript/}{/eq}
|
||||||
|
{@eq value="timestamp"}{>timestamp/}{/eq}
|
||||||
|
{@none}{!TODO: make this panic!}ERROR: Unrecognized type {.type}.{/none}
|
||||||
|
{/select}
|
||||||
|
{! TODO: Maybe the final space should be conditional on end blank in the org source !}
|
||||||
1
default_environment/templates/html/babel_call.dust
Normal file
1
default_environment/templates/html/babel_call.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! babel_call
|
||||||
19
default_environment/templates/html/blog_post_page.dust
Normal file
19
default_environment/templates/html/blog_post_page.dust
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<article class="blog_post">
|
||||||
|
{?.title}<h1 class="blog_post_title"><span>{.title}</span></h1>{/.title}
|
||||||
|
{! TODO: date? !}
|
||||||
|
|
||||||
|
{! TODO: Table of contents? !}
|
||||||
|
|
||||||
|
<div class="blog_post_body">
|
||||||
|
{#.children}
|
||||||
|
{>document_element/}
|
||||||
|
{/.children}
|
||||||
|
|
||||||
|
{?.footnotes}
|
||||||
|
<h2>Footnotes:</h2>
|
||||||
|
{#.footnotes}
|
||||||
|
{>real_footnote_definition/}
|
||||||
|
{/.footnotes}
|
||||||
|
{/.footnotes}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
32
default_environment/templates/html/blog_stream.dust
Normal file
32
default_environment/templates/html/blog_stream.dust
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<div class="blog_stream">
|
||||||
|
{#.children}
|
||||||
|
{@gt key=$idx value=0}<hr class="stream_divider" />{/gt}
|
||||||
|
<div class="blog_stream_post">
|
||||||
|
<div class="blog_post_intro">
|
||||||
|
{?.title}{?.self_link}<a class="blog_post_title" href="{.self_link}">{.title}</a>{:else}<div class="blog_post_title">{.title}</div>{/.self_link}{/.title}
|
||||||
|
{! TODO: date? !}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{! TODO: Table of contents? !}
|
||||||
|
|
||||||
|
<div class="blog_post_body">
|
||||||
|
{#.children}
|
||||||
|
{>document_element/}
|
||||||
|
{/.children}
|
||||||
|
|
||||||
|
{?.footnotes}
|
||||||
|
<h2>Footnotes:</h2>
|
||||||
|
{#.footnotes}
|
||||||
|
{>real_footnote_definition/}
|
||||||
|
{/.footnotes}
|
||||||
|
{/.footnotes}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/.children}
|
||||||
|
{#.stream_pagination}
|
||||||
|
<div class="stream_nav">
|
||||||
|
{?.older_link}<a href="{.older_link}">Older</a>{/.older_link}
|
||||||
|
{?.newer_link}<a href="{.newer_link}">Newer</a>{/.newer_link}
|
||||||
|
</div>
|
||||||
|
{/.stream_pagination}
|
||||||
|
</div>
|
||||||
3
default_environment/templates/html/bold.dust
Normal file
3
default_environment/templates/html/bold.dust
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<b>{#.children}
|
||||||
|
{>object/}
|
||||||
|
{/.children}</b>
|
||||||
1
default_environment/templates/html/center_block.dust
Normal file
1
default_environment/templates/html/center_block.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! center_block
|
||||||
1
default_environment/templates/html/citation.dust
Normal file
1
default_environment/templates/html/citation.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! citation
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! citation_reference
|
||||||
1
default_environment/templates/html/clock.dust
Normal file
1
default_environment/templates/html/clock.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! clock
|
||||||
1
default_environment/templates/html/code.dust
Normal file
1
default_environment/templates/html/code.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<code class="code">{.contents}</code>
|
||||||
1
default_environment/templates/html/comment.dust
Normal file
1
default_environment/templates/html/comment.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{! noop !}
|
||||||
1
default_environment/templates/html/comment_block.dust
Normal file
1
default_environment/templates/html/comment_block.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{! noop !}
|
||||||
1
default_environment/templates/html/diary_sexp.dust
Normal file
1
default_environment/templates/html/diary_sexp.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! diary_sexp
|
||||||
5
default_environment/templates/html/document_element.dust
Normal file
5
default_environment/templates/html/document_element.dust
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{@select key=.type}
|
||||||
|
{@eq value="heading"}{>heading/}{/eq}
|
||||||
|
{@eq value="section"}{>section/}{/eq}
|
||||||
|
{@none}{!TODO: make this panic!}ERROR: Unrecognized type {.type}.{/none}
|
||||||
|
{/select}
|
||||||
1
default_environment/templates/html/drawer.dust
Normal file
1
default_environment/templates/html/drawer.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! drawer
|
||||||
1
default_environment/templates/html/dynamic_block.dust
Normal file
1
default_environment/templates/html/dynamic_block.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! dynamic_block
|
||||||
28
default_environment/templates/html/element.dust
Normal file
28
default_environment/templates/html/element.dust
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{@select key=.type}
|
||||||
|
{@eq value="paragraph"}{>paragraph/}{/eq}
|
||||||
|
{@eq value="plain_list"}{>plain_list/}{/eq}
|
||||||
|
{@eq value="plain_list_simple_item"}{>plain_list_simple_item/}{/eq}
|
||||||
|
{@eq value="center_block"}{>center_block/}{/eq}
|
||||||
|
{@eq value="quote_block"}{>quote_block/}{/eq}
|
||||||
|
{@eq value="special_block"}{>special_block/}{/eq}
|
||||||
|
{@eq value="dynamic_block"}{>dynamic_block/}{/eq}
|
||||||
|
{@eq value="footnote_definition"}{>footnote_definition/}{/eq}
|
||||||
|
{@eq value="comment"}{>comment/}{/eq}
|
||||||
|
{@eq value="drawer"}{>drawer/}{/eq}
|
||||||
|
{@eq value="property_drawer"}{>property_drawer/}{/eq}
|
||||||
|
{@eq value="table"}{>table/}{/eq}
|
||||||
|
{@eq value="verse_block"}{>verse_block/}{/eq}
|
||||||
|
{@eq value="comment_block"}{>comment_block/}{/eq}
|
||||||
|
{@eq value="example_block"}{>example_block/}{/eq}
|
||||||
|
{@eq value="export_block"}{>export_block/}{/eq}
|
||||||
|
{@eq value="src_block"}{>src_block/}{/eq}
|
||||||
|
{@eq value="clock"}{>clock/}{/eq}
|
||||||
|
{@eq value="diary_sexp"}{>diary_sexp/}{/eq}
|
||||||
|
{@eq value="planning"}{>planning/}{/eq}
|
||||||
|
{@eq value="fixed_width_area"}{>fixed_width_area/}{/eq}
|
||||||
|
{@eq value="horizontal_rule"}{>horizontal_rule/}{/eq}
|
||||||
|
{@eq value="keyword"}{>keyword/}{/eq}
|
||||||
|
{@eq value="babel_call"}{>babel_call/}{/eq}
|
||||||
|
{@eq value="latex_environment"}{>latex_environment/}{/eq}
|
||||||
|
{@none}{!TODO: make this panic!}ERROR: Unrecognized type {.type}.{/none}
|
||||||
|
{/select}
|
||||||
1
default_environment/templates/html/entity.dust
Normal file
1
default_environment/templates/html/entity.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{.html|s}
|
||||||
1
default_environment/templates/html/example_block.dust
Normal file
1
default_environment/templates/html/example_block.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! example_block
|
||||||
1
default_environment/templates/html/export_block.dust
Normal file
1
default_environment/templates/html/export_block.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! export_block
|
||||||
1
default_environment/templates/html/export_snippet.dust
Normal file
1
default_environment/templates/html/export_snippet.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! export_snippet
|
||||||
1
default_environment/templates/html/fixed_width_area.dust
Normal file
1
default_environment/templates/html/fixed_width_area.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! fixed_width_area
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{! noop !}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<sup class="footnote_reference"><a id="{.reference_id}" href="{.definition_link}">{.label}</a></sup>
|
||||||
1
default_environment/templates/html/global_settings.dust
Normal file
1
default_environment/templates/html/global_settings.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! global_settings
|
||||||
11
default_environment/templates/html/heading.dust
Normal file
11
default_environment/templates/html/heading.dust
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{@lte key=.level value=4}
|
||||||
|
<h{.level}>{#.title}{>object/}{/.title}</h{.level}>
|
||||||
|
{:else}
|
||||||
|
<ol>
|
||||||
|
<li>{#.title}{>object/}{/.title}</li>
|
||||||
|
</ol>
|
||||||
|
{/lte}
|
||||||
|
|
||||||
|
{#.children}
|
||||||
|
{>document_element/}
|
||||||
|
{/.children}
|
||||||
1
default_environment/templates/html/horizontal_rule.dust
Normal file
1
default_environment/templates/html/horizontal_rule.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! horizontal_rule
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! inline_babel_call
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<code class="inline_source_block">{.value}</code>
|
||||||
3
default_environment/templates/html/italic.dust
Normal file
3
default_environment/templates/html/italic.dust
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<i>{#.children}
|
||||||
|
{>object/}
|
||||||
|
{/.children}</i>
|
||||||
1
default_environment/templates/html/keyword.dust
Normal file
1
default_environment/templates/html/keyword.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{! noop !}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! latex_environment
|
||||||
2
default_environment/templates/html/latex_fragment.dust
Normal file
2
default_environment/templates/html/latex_fragment.dust
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
{! TODO: Should I be including MathJax somewhere? !}
|
||||||
|
{.value}
|
||||||
1
default_environment/templates/html/line_break.dust
Normal file
1
default_environment/templates/html/line_break.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<br/>
|
||||||
19
default_environment/templates/html/main.dust
Normal file
19
default_environment/templates/html/main.dust
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
{#global_settings.css_files}<link rel="stylesheet" href="{.}">{/global_settings.css_files}
|
||||||
|
{#global_settings.js_files}<script type="text/javascript" src="{.}"></script>{/global_settings.js_files}
|
||||||
|
{?global_settings.page_title}<title>{global_settings.page_title}</title>{/global_settings.page_title}
|
||||||
|
</head>
|
||||||
|
<body class="page_centering">
|
||||||
|
{#.page_header}{>page_header/}{/.page_header}
|
||||||
|
<main class="main_content">
|
||||||
|
{@select key=.type}
|
||||||
|
{@eq value="blog_post_page"}{>blog_post_page/}{/eq}
|
||||||
|
{@eq value="blog_stream"}{>blog_stream/}{/eq}
|
||||||
|
{@none}{!TODO: make this panic!}ERROR: Unrecognized page content type{/none}
|
||||||
|
{/select}
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
30
default_environment/templates/html/object.dust
Normal file
30
default_environment/templates/html/object.dust
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{@select key=.type}
|
||||||
|
{@eq value="bold"}{>bold/}{/eq}
|
||||||
|
{@eq value="italic"}{>italic/}{/eq}
|
||||||
|
{@eq value="underline"}{>underline/}{/eq}
|
||||||
|
{@eq value="strike_through"}{>strike_through/}{/eq}
|
||||||
|
{@eq value="code"}{>code/}{/eq}
|
||||||
|
{@eq value="verbatim"}{>verbatim/}{/eq}
|
||||||
|
{@eq value="plain_text"}{>plain_text/}{/eq}
|
||||||
|
{@eq value="regular_link"}{>regular_link/}{/eq}
|
||||||
|
{@eq value="radio_link"}{>radio_link/}{/eq}
|
||||||
|
{@eq value="radio_target"}{>radio_target/}{/eq}
|
||||||
|
{@eq value="plain_link"}{>plain_link/}{/eq}
|
||||||
|
{@eq value="angle_link"}{>angle_link/}{/eq}
|
||||||
|
{@eq value="org_macro"}{>org_macro/}{/eq}
|
||||||
|
{@eq value="entity"}{>entity/}{/eq}
|
||||||
|
{@eq value="latex_fragment"}{>latex_fragment/}{/eq}
|
||||||
|
{@eq value="export_snippet"}{>export_snippet/}{/eq}
|
||||||
|
{@eq value="footnote_reference"}{>footnote_reference/}{/eq}
|
||||||
|
{@eq value="citation"}{>citation/}{/eq}
|
||||||
|
{@eq value="citation_reference"}{>citation_reference/}{/eq}
|
||||||
|
{@eq value="inline_babel_call"}{>inline_babel_call/}{/eq}
|
||||||
|
{@eq value="inline_source_block"}{>inline_source_block/}{/eq}
|
||||||
|
{@eq value="line_break"}{>line_break/}{/eq}
|
||||||
|
{@eq value="target"}{>target/}{/eq}
|
||||||
|
{@eq value="statistics_cookie"}{>statistics_cookie/}{/eq}
|
||||||
|
{@eq value="subscript"}{>subscript/}{/eq}
|
||||||
|
{@eq value="superscript"}{>superscript/}{/eq}
|
||||||
|
{@eq value="timestamp"}{>timestamp/}{/eq}
|
||||||
|
{@none}{!TODO: make this panic!}ERROR: Unrecognized type {.type}.{/none}
|
||||||
|
{/select}{@gt key=.post_blank value=0}{~s}{/gt}
|
||||||
1
default_environment/templates/html/org_macro.dust
Normal file
1
default_environment/templates/html/org_macro.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! org_macro
|
||||||
4
default_environment/templates/html/page_header.dust
Normal file
4
default_environment/templates/html/page_header.dust
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<header class="page_header">
|
||||||
|
<a class="home_link" href="{.home_link}">{.website_title}</a>
|
||||||
|
{! TODO: Additional links? Probably using the nav semantic element. !}
|
||||||
|
</header>
|
||||||
3
default_environment/templates/html/paragraph.dust
Normal file
3
default_environment/templates/html/paragraph.dust
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<p>{#.children}
|
||||||
|
{>object/}
|
||||||
|
{/.children}</p>
|
||||||
1
default_environment/templates/html/plain_link.dust
Normal file
1
default_environment/templates/html/plain_link.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! plain_link
|
||||||
6
default_environment/templates/html/plain_list.dust
Normal file
6
default_environment/templates/html/plain_list.dust
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{@select key=.list_type}
|
||||||
|
{@eq value="unordered"}<ul class="plain_list unordered">{#.children}{>plain_list_item/}{/.children}</ul>{/eq}
|
||||||
|
{@eq value="ordered"}<ol class="plain_list ordered">{#.children}{>plain_list_item/}{/.children}</ol>{/eq}
|
||||||
|
{@eq value="descriptive"}<dl class="plain_list descriptive">{#.children}{>plain_list_item/}{/.children}</dl>{/eq}
|
||||||
|
{@none}{!TODO: make this panic!}ERROR: Unrecognized list type {.list_type}.{/none}
|
||||||
|
{/select}
|
||||||
6
default_environment/templates/html/plain_list_item.dust
Normal file
6
default_environment/templates/html/plain_list_item.dust
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{@select key=list_type}
|
||||||
|
{@eq value="unordered"}<li>{#.children}{>element/}{/.children}</li>{/eq}
|
||||||
|
{@eq value="ordered"}<li>{#.children}{>element/}{/.children}</li>{/eq}
|
||||||
|
{@eq value="descriptive"}<dt>{#.tag}{>object/}{/.tag}</dt><dd>{#.children}{>element/}{/.children}</dd>{/eq}
|
||||||
|
{@none}{!TODO: make this panic!}ERROR: Unrecognized list type {.list_type}.{/none}
|
||||||
|
{/select}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{#.children}
|
||||||
|
{>object/}
|
||||||
|
{/.children}
|
||||||
1
default_environment/templates/html/plain_text.dust
Normal file
1
default_environment/templates/html/plain_text.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{.source}
|
||||||
1
default_environment/templates/html/planning.dust
Normal file
1
default_environment/templates/html/planning.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! planning
|
||||||
1
default_environment/templates/html/property_drawer.dust
Normal file
1
default_environment/templates/html/property_drawer.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! property_drawer
|
||||||
3
default_environment/templates/html/quote_block.dust
Normal file
3
default_environment/templates/html/quote_block.dust
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<blockquote class="quote_block">{#.children}
|
||||||
|
{>element/}
|
||||||
|
{/.children}</blockquote>
|
||||||
1
default_environment/templates/html/radio_link.dust
Normal file
1
default_environment/templates/html/radio_link.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! radio_link
|
||||||
1
default_environment/templates/html/radio_target.dust
Normal file
1
default_environment/templates/html/radio_target.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! radio_target
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<div class="footnote_definition"><a id="{.definition_id}" href="{.reference_link}" class="label">{.label}.</a> <div class="definition">{#.contents}{>ast_node/}{/.contents}</div></div>
|
||||||
1
default_environment/templates/html/regular_link.dust
Normal file
1
default_environment/templates/html/regular_link.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<a href="{.raw_link}">{#.children}{>object/}{/.children}</a>
|
||||||
3
default_environment/templates/html/section.dust
Normal file
3
default_environment/templates/html/section.dust
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{#.children}
|
||||||
|
{>element/}
|
||||||
|
{/.children}
|
||||||
1
default_environment/templates/html/special_block.dust
Normal file
1
default_environment/templates/html/special_block.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! special_block
|
||||||
12
default_environment/templates/html/src_block.dust
Normal file
12
default_environment/templates/html/src_block.dust
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<div class="src_block">
|
||||||
|
{?.language}<div class="src_language">{.language}</div>{/.language}
|
||||||
|
<table class="src_body">
|
||||||
|
<tbody>
|
||||||
|
{#.lines}
|
||||||
|
<tr>
|
||||||
|
<td><code class="src_line">{.}</code></td>
|
||||||
|
</tr>
|
||||||
|
{/.lines}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! statistics_cookie
|
||||||
3
default_environment/templates/html/strike_through.dust
Normal file
3
default_environment/templates/html/strike_through.dust
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<del>{#.children}
|
||||||
|
{>object/}
|
||||||
|
{/.children}</del>
|
||||||
1
default_environment/templates/html/subscript.dust
Normal file
1
default_environment/templates/html/subscript.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! subscript
|
||||||
1
default_environment/templates/html/superscript.dust
Normal file
1
default_environment/templates/html/superscript.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! superscript
|
||||||
1
default_environment/templates/html/table.dust
Normal file
1
default_environment/templates/html/table.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<table>{#.children}{>table_row/}{/.children}</table>
|
||||||
1
default_environment/templates/html/table_cell.dust
Normal file
1
default_environment/templates/html/table_cell.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<td>{#.children}{>object/}{/.children}</td>
|
||||||
1
default_environment/templates/html/table_row.dust
Normal file
1
default_environment/templates/html/table_row.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<tr>{#.children}{>table_cell/}{/.children}</tr>
|
||||||
1
default_environment/templates/html/target.dust
Normal file
1
default_environment/templates/html/target.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<a id="{.id}"></a>
|
||||||
1
default_environment/templates/html/timestamp.dust
Normal file
1
default_environment/templates/html/timestamp.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! timestamp
|
||||||
3
default_environment/templates/html/underline.dust
Normal file
3
default_environment/templates/html/underline.dust
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<u>{#.children}
|
||||||
|
{>object/}
|
||||||
|
{/.children}</u>
|
||||||
1
default_environment/templates/html/verbatim.dust
Normal file
1
default_environment/templates/html/verbatim.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<code class="verbatim">{.contents}</code>
|
||||||
1
default_environment/templates/html/verse_block.dust
Normal file
1
default_environment/templates/html/verse_block.dust
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!!!!!!!! verse_block
|
||||||
21
org_test_documents/footnote/reference_in_definition.org
Normal file
21
org_test_documents/footnote/reference_in_definition.org
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# This test shows that footnote references only count if the definition containing them is rendered.
|
||||||
|
|
||||||
|
foo[fn:a:bar]
|
||||||
|
|
||||||
|
[fn:a] lorem
|
||||||
|
|
||||||
|
[fn:b] ipsum
|
||||||
|
|
||||||
|
[fn:d] fizz
|
||||||
|
|
||||||
|
[fn:c] dolar
|
||||||
|
|
||||||
|
yo[fn:b]
|
||||||
|
|
||||||
|
|
||||||
|
hello[fn:c]
|
||||||
|
|
||||||
|
|
||||||
|
[fn:e] buzz
|
||||||
|
|
||||||
|
sup[fn:d]
|
||||||
25
org_test_documents/footnote/simple.org
Normal file
25
org_test_documents/footnote/simple.org
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Test proves that:
|
||||||
|
#
|
||||||
|
# - Anonymous references with identical content get unique IDs.
|
||||||
|
# - Unreferenced footnote definitions are dropped.
|
||||||
|
# - Footnote definitions that come before their first reference are dropped.
|
||||||
|
|
||||||
|
foo[fn:2:something]
|
||||||
|
|
||||||
|
bar[fn::something]
|
||||||
|
|
||||||
|
baz[fn::something]
|
||||||
|
|
||||||
|
cat[fn::something]
|
||||||
|
|
||||||
|
dog[fn:3]
|
||||||
|
|
||||||
|
[fn:3] ipsum
|
||||||
|
|
||||||
|
[fn:4] lorem
|
||||||
|
|
||||||
|
[fn:3] dolar
|
||||||
|
|
||||||
|
[fn:5] not referenced
|
||||||
|
|
||||||
|
stuff[fn:4] and things
|
||||||
36
org_test_documents/latex_fragment/notes.org
Normal file
36
org_test_documents/latex_fragment/notes.org
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
* Double dollar
|
||||||
|
#+begin_src org
|
||||||
|
$$CONTENTS$$
|
||||||
|
#+end_src
|
||||||
|
becomes
|
||||||
|
#+begin_src text
|
||||||
|
\[CONTENTS\]
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src org
|
||||||
|
$$1+1=2$$
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src text
|
||||||
|
\[1+1=2\]
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
This gets interpreted by mathjax.
|
||||||
|
* Single Dollar
|
||||||
|
#+begin_src org
|
||||||
|
PRE$BORDER1 BODY BORDER2$POST
|
||||||
|
#+end_src
|
||||||
|
becomes
|
||||||
|
#+begin_src text
|
||||||
|
\(BORDER1 BODY BORDER2\)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src org
|
||||||
|
foo$a bar b$.
|
||||||
|
#+end_src
|
||||||
|
becomes
|
||||||
|
#+begin_src text
|
||||||
|
foo\(a bar b\).
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
This gets interpreted by mathjax.
|
||||||
1
src/cli/mod.rs
Normal file
1
src/cli/mod.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub(crate) mod parameters;
|
||||||
48
src/cli/parameters.rs
Normal file
48
src/cli/parameters.rs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
use clap::Args;
|
||||||
|
use clap::Parser;
|
||||||
|
use clap::Subcommand;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
#[command(name = "Natter")]
|
||||||
|
#[command(version = env!("CARGO_PKG_VERSION"))]
|
||||||
|
#[command(about = "Generate a static site.", long_about = None)]
|
||||||
|
#[command(propagate_version = true)]
|
||||||
|
pub(crate) struct Cli {
|
||||||
|
#[command(subcommand)]
|
||||||
|
pub(crate) command: Commands,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand, Debug)]
|
||||||
|
pub(crate) enum Commands {
|
||||||
|
/// Initialize an empty website folder.
|
||||||
|
Init(InitArgs),
|
||||||
|
|
||||||
|
/// Build the static site.
|
||||||
|
Build(BuildArgs),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Args, Debug)]
|
||||||
|
pub(crate) struct InitArgs {
|
||||||
|
/// Path where you want the initial natter structure to be located.
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub(crate) path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Args, Debug)]
|
||||||
|
pub(crate) struct BuildArgs {
|
||||||
|
/// Path to the natter config file.
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub(crate) config: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn verify_cli() {
|
||||||
|
use clap::CommandFactory;
|
||||||
|
Cli::command().debug_assert()
|
||||||
|
}
|
||||||
|
}
|
||||||
0
src/command/add_post/mod.rs
Normal file
0
src/command/add_post/mod.rs
Normal file
5
src/command/build/mod.rs
Normal file
5
src/command/build/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
mod render;
|
||||||
|
mod runner;
|
||||||
|
mod stylesheet;
|
||||||
|
|
||||||
|
pub(crate) use runner::build_site;
|
||||||
212
src/command/build/render.rs
Normal file
212
src/command/build/render.rs
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
use std::ffi::OsStr;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use include_dir::include_dir;
|
||||||
|
use include_dir::Dir;
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
|
use crate::context::RenderBlogPostPage;
|
||||||
|
use crate::context::RenderBlogPostPageInput;
|
||||||
|
use crate::context::RenderBlogStream;
|
||||||
|
use crate::context::RenderBlogStreamInput;
|
||||||
|
use crate::context::RenderContext;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::intermediate::get_web_path;
|
||||||
|
use crate::intermediate::BlogPost;
|
||||||
|
use crate::render::DusterRenderer;
|
||||||
|
use crate::render::RendererIntegration;
|
||||||
|
|
||||||
|
use super::stylesheet::Stylesheet;
|
||||||
|
|
||||||
|
static MAIN_TEMPLATES: Dir = include_dir!("$CARGO_MANIFEST_DIR/default_environment/templates/html");
|
||||||
|
|
||||||
|
pub(crate) struct SiteRenderer {
|
||||||
|
output_directory: PathBuf,
|
||||||
|
blog_posts: Vec<BlogPost>,
|
||||||
|
stylesheets: Vec<Stylesheet>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SiteRenderer {
|
||||||
|
pub(crate) fn new<P: Into<PathBuf>>(
|
||||||
|
output_directory: P,
|
||||||
|
blog_posts: Vec<BlogPost>,
|
||||||
|
stylesheets: Vec<Stylesheet>,
|
||||||
|
) -> SiteRenderer {
|
||||||
|
SiteRenderer {
|
||||||
|
output_directory: output_directory.into(),
|
||||||
|
blog_posts,
|
||||||
|
stylesheets,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_renderer_integration(&self) -> Result<DusterRenderer<'_>, CustomError> {
|
||||||
|
let mut renderer_integration = DusterRenderer::new();
|
||||||
|
|
||||||
|
let sources: Vec<_> = MAIN_TEMPLATES
|
||||||
|
.files()
|
||||||
|
.filter(|f| f.path().extension() == Some(OsStr::new("dust")))
|
||||||
|
.collect();
|
||||||
|
if sources
|
||||||
|
.iter()
|
||||||
|
.filter(|f| f.path().file_stem() == Some(OsStr::new("main")))
|
||||||
|
.count()
|
||||||
|
!= 1
|
||||||
|
{
|
||||||
|
return Err("Expect exactly 1 main.dust template file.".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let decoded_templates = {
|
||||||
|
let mut decoded_templates = Vec::with_capacity(sources.len());
|
||||||
|
for entry in sources {
|
||||||
|
decoded_templates.push(build_name_contents_pairs(entry)?);
|
||||||
|
}
|
||||||
|
decoded_templates
|
||||||
|
};
|
||||||
|
|
||||||
|
for (name, contents) in decoded_templates {
|
||||||
|
renderer_integration.load_template(name, contents)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(renderer_integration)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn render_blog_posts(&self, config: &Config) -> Result<(), CustomError> {
|
||||||
|
let renderer_integration = self.init_renderer_integration()?;
|
||||||
|
|
||||||
|
for blog_post in &self.blog_posts {
|
||||||
|
for blog_post_page in &blog_post.pages {
|
||||||
|
let output_path = self
|
||||||
|
.output_directory
|
||||||
|
.join(config.get_relative_path_to_post(&blog_post.id))
|
||||||
|
.join(blog_post_page.get_output_path());
|
||||||
|
|
||||||
|
let convert_input = RenderBlogPostPageInput::new(blog_post, blog_post_page);
|
||||||
|
let render_context = RenderContext::new(
|
||||||
|
config,
|
||||||
|
self.output_directory.as_path(),
|
||||||
|
output_path.as_path(),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
let render_context = RenderBlogPostPage::new(render_context, &convert_input)?;
|
||||||
|
let rendered_output = renderer_integration.render(render_context)?;
|
||||||
|
let parent_directory = output_path
|
||||||
|
.parent()
|
||||||
|
.ok_or("Output file should have a containing directory.")?;
|
||||||
|
tokio::fs::create_dir_all(parent_directory).await?;
|
||||||
|
tokio::fs::write(output_path, rendered_output).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn render_blog_stream(&self, config: &Config) -> Result<(), CustomError> {
|
||||||
|
let renderer_integration = self.init_renderer_integration()?;
|
||||||
|
|
||||||
|
// Sort blog posts by date, newest first.
|
||||||
|
let sorted_blog_posts = {
|
||||||
|
let mut sorted_blog_posts: Vec<_> = self.blog_posts.iter().collect();
|
||||||
|
sorted_blog_posts
|
||||||
|
.sort_by_key(|blog_post| (blog_post.get_date(), blog_post.id.as_str()));
|
||||||
|
sorted_blog_posts.reverse();
|
||||||
|
sorted_blog_posts
|
||||||
|
};
|
||||||
|
|
||||||
|
for blog_post in &sorted_blog_posts {
|
||||||
|
if blog_post.get_date().is_none() {
|
||||||
|
return Err(format!("Blog post {} does not have a date.", blog_post.id).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group blog posts based on # of posts per page.
|
||||||
|
let stream_chunks: Vec<_> = sorted_blog_posts
|
||||||
|
.chunks(config.get_stream_entries_per_page())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// For each group, create a RenderBlogStream.
|
||||||
|
let num_stream_pages = stream_chunks.len();
|
||||||
|
for (page_num, chunk) in stream_chunks.into_iter().enumerate() {
|
||||||
|
let output_file = if page_num == 0 {
|
||||||
|
self.output_directory.join("index.html")
|
||||||
|
} else {
|
||||||
|
self.output_directory
|
||||||
|
.join("stream")
|
||||||
|
.join(format!("{}.html", page_num))
|
||||||
|
};
|
||||||
|
let newer_link = if page_num == 0 {
|
||||||
|
None
|
||||||
|
} else if page_num == 1 {
|
||||||
|
Some(get_web_path(
|
||||||
|
config,
|
||||||
|
&self.output_directory,
|
||||||
|
&output_file,
|
||||||
|
"index.html",
|
||||||
|
)?)
|
||||||
|
} else {
|
||||||
|
Some(get_web_path(
|
||||||
|
config,
|
||||||
|
&self.output_directory,
|
||||||
|
&output_file,
|
||||||
|
format!("stream/{}.html", page_num - 1),
|
||||||
|
)?)
|
||||||
|
};
|
||||||
|
let older_link = if page_num == (num_stream_pages - 1) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(get_web_path(
|
||||||
|
config,
|
||||||
|
&self.output_directory,
|
||||||
|
&output_file,
|
||||||
|
format!("stream/{}.html", page_num + 1),
|
||||||
|
)?)
|
||||||
|
};
|
||||||
|
|
||||||
|
let convert_input = RenderBlogStreamInput::new(chunk, older_link, newer_link);
|
||||||
|
let render_context = RenderContext::new(
|
||||||
|
config,
|
||||||
|
self.output_directory.as_path(),
|
||||||
|
output_file.as_path(),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
let blog_stream = RenderBlogStream::new(render_context, &convert_input)?;
|
||||||
|
|
||||||
|
// Pass each RenderBlogStream to dust as the context to render index.html and any additional stream pages.
|
||||||
|
let rendered_output = renderer_integration.render(blog_stream)?;
|
||||||
|
let parent_directory = output_file
|
||||||
|
.parent()
|
||||||
|
.ok_or("Output file should have a containing directory.")?;
|
||||||
|
tokio::fs::create_dir_all(parent_directory).await?;
|
||||||
|
tokio::fs::write(output_file, rendered_output).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn render_stylesheets(&self) -> Result<(), CustomError> {
|
||||||
|
let stylesheet_output_directory = self.output_directory.join("stylesheet");
|
||||||
|
if !stylesheet_output_directory.exists() {
|
||||||
|
tokio::fs::create_dir(&stylesheet_output_directory).await?;
|
||||||
|
}
|
||||||
|
for stylesheet in &self.stylesheets {
|
||||||
|
let file_output_path = stylesheet_output_directory.join(&stylesheet.path);
|
||||||
|
let parent_directory = file_output_path
|
||||||
|
.parent()
|
||||||
|
.ok_or("Output file should have a containing directory.")?;
|
||||||
|
tokio::fs::create_dir_all(parent_directory).await?;
|
||||||
|
tokio::fs::write(file_output_path, stylesheet.contents.as_bytes()).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_name_contents_pairs<'a>(
|
||||||
|
entry: &'a include_dir::File<'_>,
|
||||||
|
) -> Result<(&'a str, &'a str), CustomError> {
|
||||||
|
let path = entry.path();
|
||||||
|
let name = path
|
||||||
|
.file_stem()
|
||||||
|
.ok_or("All templates should have a stem.")?
|
||||||
|
.to_str()
|
||||||
|
.ok_or("All template filenames should be valid utf-8.")?;
|
||||||
|
let contents = std::str::from_utf8(entry.contents())?;
|
||||||
|
Ok((name, contents))
|
||||||
|
}
|
||||||
89
src/command/build/runner.rs
Normal file
89
src/command/build/runner.rs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
use std::ffi::OsStr;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use super::stylesheet::Stylesheet;
|
||||||
|
use crate::cli::parameters::BuildArgs;
|
||||||
|
use crate::command::build::render::SiteRenderer;
|
||||||
|
use crate::config::Config;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::intermediate::BlogPost;
|
||||||
|
use include_dir::include_dir;
|
||||||
|
use include_dir::Dir;
|
||||||
|
|
||||||
|
static DEFAULT_STYLESHEETS: Dir =
|
||||||
|
include_dir!("$CARGO_MANIFEST_DIR/default_environment/stylesheet");
|
||||||
|
|
||||||
|
pub(crate) async fn build_site(args: BuildArgs) -> Result<(), CustomError> {
|
||||||
|
let config = Config::load_from_file(args.config).await?;
|
||||||
|
let blog_posts = load_blog_posts(&config).await?;
|
||||||
|
let stylesheets = load_stylesheets().await?;
|
||||||
|
let renderer = SiteRenderer::new(
|
||||||
|
get_output_directory(&config).await?,
|
||||||
|
blog_posts,
|
||||||
|
stylesheets,
|
||||||
|
);
|
||||||
|
renderer.render_blog_posts(&config).await?;
|
||||||
|
renderer.render_blog_stream(&config).await?;
|
||||||
|
renderer.render_stylesheets().await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delete everything inside the output directory and return the path to that directory.
|
||||||
|
async fn get_output_directory(config: &Config) -> Result<PathBuf, CustomError> {
|
||||||
|
let output_directory = config.get_output_directory();
|
||||||
|
if !output_directory.exists() {
|
||||||
|
tokio::fs::create_dir(&output_directory).await?;
|
||||||
|
} else {
|
||||||
|
let mut existing_entries = tokio::fs::read_dir(&output_directory).await?;
|
||||||
|
while let Some(entry) = existing_entries.next_entry().await? {
|
||||||
|
let file_type = entry.file_type().await?;
|
||||||
|
if file_type.is_dir() {
|
||||||
|
tokio::fs::remove_dir_all(entry.path()).await?;
|
||||||
|
} else {
|
||||||
|
tokio::fs::remove_file(entry.path()).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(output_directory)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_post_directories(config: &Config) -> Result<Vec<PathBuf>, CustomError> {
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
let mut entries = tokio::fs::read_dir(config.get_posts_directory()).await?;
|
||||||
|
while let Some(entry) = entries.next_entry().await? {
|
||||||
|
let file_type = entry.file_type().await?;
|
||||||
|
if file_type.is_dir() {
|
||||||
|
ret.push(entry.path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn load_blog_posts(config: &Config) -> Result<Vec<BlogPost>, CustomError> {
|
||||||
|
let root_directory = config.get_root_directory().to_owned();
|
||||||
|
let post_directories = get_post_directories(&config).await?;
|
||||||
|
let load_jobs = post_directories
|
||||||
|
.into_iter()
|
||||||
|
.map(|path| tokio::spawn(BlogPost::load_blog_post(root_directory.clone(), path)));
|
||||||
|
let mut blog_posts = Vec::new();
|
||||||
|
for job in load_jobs {
|
||||||
|
blog_posts.push(job.await??);
|
||||||
|
}
|
||||||
|
Ok(blog_posts)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn load_stylesheets() -> Result<Vec<Stylesheet>, CustomError> {
|
||||||
|
let sources: Vec<_> = DEFAULT_STYLESHEETS
|
||||||
|
.files()
|
||||||
|
.filter(|f| f.path().extension() == Some(OsStr::new("css")))
|
||||||
|
.collect();
|
||||||
|
let mut ret = Vec::with_capacity(sources.len());
|
||||||
|
for entry in sources {
|
||||||
|
let path = entry.path().to_path_buf();
|
||||||
|
let contents = String::from_utf8(entry.contents().to_vec())?;
|
||||||
|
let stylesheet = Stylesheet::new(path, contents).await?;
|
||||||
|
ret.push(stylesheet);
|
||||||
|
}
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
15
src/command/build/stylesheet.rs
Normal file
15
src/command/build/stylesheet.rs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use crate::error::CustomError;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct Stylesheet {
|
||||||
|
pub(crate) path: PathBuf,
|
||||||
|
pub(crate) contents: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stylesheet {
|
||||||
|
pub(crate) async fn new(path: PathBuf, contents: String) -> Result<Stylesheet, CustomError> {
|
||||||
|
Ok(Stylesheet { path, contents })
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/command/init/mod.rs
Normal file
3
src/command/init/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
mod runner;
|
||||||
|
|
||||||
|
pub(crate) use runner::init_natter_folder;
|
||||||
23
src/command/init/runner.rs
Normal file
23
src/command/init/runner.rs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
use crate::cli::parameters::InitArgs;
|
||||||
|
use crate::config::Config;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
|
||||||
|
pub(crate) async fn init_natter_folder(args: InitArgs) -> Result<(), CustomError> {
|
||||||
|
if args.path.exists() && !args.path.is_dir() {
|
||||||
|
return Err("The supplied path exists but is not a directory. Aborting.".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if !args.path.exists() {
|
||||||
|
tokio::fs::create_dir_all(&args.path).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut existing_entries = tokio::fs::read_dir(&args.path).await?;
|
||||||
|
let first_entry = existing_entries.next_entry().await?;
|
||||||
|
if let Some(_) = first_entry {
|
||||||
|
return Err("The directory is not empty. Aborting.".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_config = Config::new(args.path)?;
|
||||||
|
new_config.write_to_disk().await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
3
src/command/mod.rs
Normal file
3
src/command/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
pub(crate) mod add_post;
|
||||||
|
pub(crate) mod build;
|
||||||
|
pub(crate) mod init;
|
||||||
93
src/config/full.rs
Normal file
93
src/config/full.rs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use tokio::fs::File;
|
||||||
|
use tokio::io::AsyncWriteExt;
|
||||||
|
|
||||||
|
use crate::error::CustomError;
|
||||||
|
|
||||||
|
use super::raw::RawConfig;
|
||||||
|
|
||||||
|
/// This is the config struct used by most of the code, which is an interpreted version of the RawConfig struct which is the raw disk-representation of the config.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct Config {
|
||||||
|
raw: RawConfig,
|
||||||
|
config_path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub(crate) fn new<P: AsRef<Path>>(root_dir: P) -> Result<Config, CustomError> {
|
||||||
|
fn inner(root_dir: &Path) -> Result<Config, CustomError> {
|
||||||
|
let file_path = root_dir.join("natter.toml");
|
||||||
|
Ok(Config {
|
||||||
|
raw: RawConfig::default(),
|
||||||
|
config_path: file_path,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
inner(root_dir.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn load_from_file<P: Into<PathBuf>>(path: P) -> Result<Config, CustomError> {
|
||||||
|
async fn inner(path: PathBuf) -> Result<Config, CustomError> {
|
||||||
|
let contents = tokio::fs::read_to_string(&path).await?;
|
||||||
|
let parsed_contents: RawConfig = toml::from_str(contents.as_str())?;
|
||||||
|
Ok(Config {
|
||||||
|
raw: parsed_contents,
|
||||||
|
config_path: path,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
inner(path.into()).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn write_to_disk(&self) -> Result<(), CustomError> {
|
||||||
|
let mut config_file = File::create(&self.config_path).await?;
|
||||||
|
config_file
|
||||||
|
.write_all(toml::to_string(&self.raw)?.as_bytes())
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_root_directory(&self) -> &Path {
|
||||||
|
&self
|
||||||
|
.config_path
|
||||||
|
.parent()
|
||||||
|
.expect("Config file must exist inside a directory.")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_posts_directory(&self) -> PathBuf {
|
||||||
|
self.get_root_directory().join("posts")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the relative path to the folder containing a blog post.
|
||||||
|
///
|
||||||
|
/// This could be appended to the output root directory to get the
|
||||||
|
/// blog post output folder or it could be used to generate a link
|
||||||
|
/// to the blog post.
|
||||||
|
pub(crate) fn get_relative_path_to_post<P: AsRef<Path>>(&self, post_id: P) -> PathBuf {
|
||||||
|
Path::new("posts").join(post_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_output_directory(&self) -> PathBuf {
|
||||||
|
self.get_root_directory().join("output")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn use_relative_paths(&self) -> bool {
|
||||||
|
self.raw.use_relative_paths.unwrap_or(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_web_root(&self) -> Option<&str> {
|
||||||
|
self.raw.web_root.as_deref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_site_title(&self) -> Option<&str> {
|
||||||
|
self.raw.site_title.as_deref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_stream_entries_per_page(&self) -> usize {
|
||||||
|
self.raw
|
||||||
|
.stream
|
||||||
|
.as_ref()
|
||||||
|
.map(|stream| stream.entries_per_page)
|
||||||
|
.flatten()
|
||||||
|
.unwrap_or(5)
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/config/mod.rs
Normal file
3
src/config/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
mod full;
|
||||||
|
mod raw;
|
||||||
|
pub(crate) use full::Config;
|
||||||
39
src/config/raw.rs
Normal file
39
src/config/raw.rs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
/// This is the struct for the natter.toml config file that ends up in each site's root directory.
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub(crate) struct RawConfig {
|
||||||
|
pub(super) site_title: Option<String>,
|
||||||
|
author: Option<String>,
|
||||||
|
email: Option<String>,
|
||||||
|
pub(super) use_relative_paths: Option<bool>,
|
||||||
|
pub(super) web_root: Option<String>,
|
||||||
|
pub(super) stream: Option<RawConfigStream>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for RawConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
RawConfig {
|
||||||
|
site_title: None,
|
||||||
|
author: None,
|
||||||
|
email: None,
|
||||||
|
use_relative_paths: None,
|
||||||
|
web_root: None,
|
||||||
|
stream: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub(crate) struct RawConfigStream {
|
||||||
|
pub(super) entries_per_page: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for RawConfigStream {
|
||||||
|
fn default() -> Self {
|
||||||
|
RawConfigStream {
|
||||||
|
entries_per_page: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/context/angle_link.rs
Normal file
16
src/context/angle_link.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::render_context::RenderContext;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::intermediate::IAngleLink;
|
||||||
|
|
||||||
|
use super::macros::rnoop;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
#[serde(rename = "angle_link")]
|
||||||
|
pub(crate) struct RenderAngleLink {
|
||||||
|
post_blank: organic::types::PostBlank,
|
||||||
|
}
|
||||||
|
|
||||||
|
rnoop!(RenderAngleLink, IAngleLink);
|
||||||
327
src/context/ast_node.rs
Normal file
327
src/context/ast_node.rs
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::intermediate::IAstNode;
|
||||||
|
|
||||||
|
use super::angle_link::RenderAngleLink;
|
||||||
|
use super::babel_call::RenderBabelCall;
|
||||||
|
use super::bold::RenderBold;
|
||||||
|
use super::center_block::RenderCenterBlock;
|
||||||
|
use super::citation::RenderCitation;
|
||||||
|
use super::citation_reference::RenderCitationReference;
|
||||||
|
use super::clock::RenderClock;
|
||||||
|
use super::code::RenderCode;
|
||||||
|
use super::comment::RenderComment;
|
||||||
|
use super::comment_block::RenderCommentBlock;
|
||||||
|
use super::diary_sexp::RenderDiarySexp;
|
||||||
|
use super::drawer::RenderDrawer;
|
||||||
|
use super::dynamic_block::RenderDynamicBlock;
|
||||||
|
use super::entity::RenderEntity;
|
||||||
|
use super::example_block::RenderExampleBlock;
|
||||||
|
use super::export_block::RenderExportBlock;
|
||||||
|
use super::export_snippet::RenderExportSnippet;
|
||||||
|
use super::fixed_width_area::RenderFixedWidthArea;
|
||||||
|
use super::footnote_definition::RenderFootnoteDefinition;
|
||||||
|
use super::footnote_reference::RenderFootnoteReference;
|
||||||
|
use super::horizontal_rule::RenderHorizontalRule;
|
||||||
|
use super::inline_babel_call::RenderInlineBabelCall;
|
||||||
|
use super::inline_source_block::RenderInlineSourceBlock;
|
||||||
|
use super::italic::RenderItalic;
|
||||||
|
use super::keyword::RenderKeyword;
|
||||||
|
use super::latex_environment::RenderLatexEnvironment;
|
||||||
|
use super::latex_fragment::RenderLatexFragment;
|
||||||
|
use super::line_break::RenderLineBreak;
|
||||||
|
use super::org_macro::RenderOrgMacro;
|
||||||
|
use super::paragraph::RenderParagraph;
|
||||||
|
use super::plain_link::RenderPlainLink;
|
||||||
|
use super::plain_list::RenderPlainList;
|
||||||
|
use super::plain_text::RenderPlainText;
|
||||||
|
use super::planning::RenderPlanning;
|
||||||
|
use super::property_drawer::RenderPropertyDrawer;
|
||||||
|
use super::quote_block::RenderQuoteBlock;
|
||||||
|
use super::radio_link::RenderRadioLink;
|
||||||
|
use super::radio_target::RenderRadioTarget;
|
||||||
|
use super::regular_link::RenderRegularLink;
|
||||||
|
use super::render_context::RenderContext;
|
||||||
|
use super::special_block::RenderSpecialBlock;
|
||||||
|
use super::src_block::RenderSrcBlock;
|
||||||
|
use super::statistics_cookie::RenderStatisticsCookie;
|
||||||
|
use super::strike_through::RenderStrikeThrough;
|
||||||
|
use super::subscript::RenderSubscript;
|
||||||
|
use super::superscript::RenderSuperscript;
|
||||||
|
use super::table::RenderTable;
|
||||||
|
use super::target::RenderTarget;
|
||||||
|
use super::timestamp::RenderTimestamp;
|
||||||
|
use super::underline::RenderUnderline;
|
||||||
|
use super::verbatim::RenderVerbatim;
|
||||||
|
use super::verse_block::RenderVerseBlock;
|
||||||
|
use super::RenderHeading;
|
||||||
|
use super::RenderSection;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub(crate) enum RenderAstNode {
|
||||||
|
Heading(RenderHeading),
|
||||||
|
Section(RenderSection),
|
||||||
|
Paragraph(RenderParagraph),
|
||||||
|
PlainList(RenderPlainList),
|
||||||
|
CenterBlock(RenderCenterBlock),
|
||||||
|
QuoteBlock(RenderQuoteBlock),
|
||||||
|
SpecialBlock(RenderSpecialBlock),
|
||||||
|
DynamicBlock(RenderDynamicBlock),
|
||||||
|
FootnoteDefinition(RenderFootnoteDefinition),
|
||||||
|
Comment(RenderComment),
|
||||||
|
Drawer(RenderDrawer),
|
||||||
|
PropertyDrawer(RenderPropertyDrawer),
|
||||||
|
Table(RenderTable),
|
||||||
|
VerseBlock(RenderVerseBlock),
|
||||||
|
CommentBlock(RenderCommentBlock),
|
||||||
|
ExampleBlock(RenderExampleBlock),
|
||||||
|
ExportBlock(RenderExportBlock),
|
||||||
|
SrcBlock(RenderSrcBlock),
|
||||||
|
Clock(RenderClock),
|
||||||
|
DiarySexp(RenderDiarySexp),
|
||||||
|
Planning(RenderPlanning),
|
||||||
|
FixedWidthArea(RenderFixedWidthArea),
|
||||||
|
HorizontalRule(RenderHorizontalRule),
|
||||||
|
Keyword(RenderKeyword),
|
||||||
|
BabelCall(RenderBabelCall),
|
||||||
|
LatexEnvironment(RenderLatexEnvironment),
|
||||||
|
Bold(RenderBold),
|
||||||
|
Italic(RenderItalic),
|
||||||
|
Underline(RenderUnderline),
|
||||||
|
StrikeThrough(RenderStrikeThrough),
|
||||||
|
Code(RenderCode),
|
||||||
|
Verbatim(RenderVerbatim),
|
||||||
|
PlainText(RenderPlainText),
|
||||||
|
RegularLink(RenderRegularLink),
|
||||||
|
RadioLink(RenderRadioLink),
|
||||||
|
RadioTarget(RenderRadioTarget),
|
||||||
|
PlainLink(RenderPlainLink),
|
||||||
|
AngleLink(RenderAngleLink),
|
||||||
|
OrgMacro(RenderOrgMacro),
|
||||||
|
Entity(RenderEntity),
|
||||||
|
LatexFragment(RenderLatexFragment),
|
||||||
|
ExportSnippet(RenderExportSnippet),
|
||||||
|
FootnoteReference(RenderFootnoteReference),
|
||||||
|
Citation(RenderCitation),
|
||||||
|
CitationReference(RenderCitationReference),
|
||||||
|
InlineBabelCall(RenderInlineBabelCall),
|
||||||
|
InlineSourceBlock(RenderInlineSourceBlock),
|
||||||
|
LineBreak(RenderLineBreak),
|
||||||
|
Target(RenderTarget),
|
||||||
|
StatisticsCookie(RenderStatisticsCookie),
|
||||||
|
Subscript(RenderSubscript),
|
||||||
|
Superscript(RenderSuperscript),
|
||||||
|
Timestamp(RenderTimestamp),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) trait IntoRenderAstNode {
|
||||||
|
fn into_render_ast_node(
|
||||||
|
&self,
|
||||||
|
render_context: RenderContext<'_>,
|
||||||
|
) -> Result<RenderAstNode, CustomError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoRenderAstNode for IAstNode {
|
||||||
|
fn into_render_ast_node(
|
||||||
|
&self,
|
||||||
|
render_context: RenderContext<'_>,
|
||||||
|
) -> Result<RenderAstNode, CustomError> {
|
||||||
|
match self {
|
||||||
|
IAstNode::Heading(inner) => Ok(RenderAstNode::Heading(RenderHeading::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::Section(inner) => Ok(RenderAstNode::Section(RenderSection::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::Paragraph(inner) => Ok(RenderAstNode::Paragraph(RenderParagraph::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::PlainList(inner) => Ok(RenderAstNode::PlainList(RenderPlainList::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::CenterBlock(inner) => Ok(RenderAstNode::CenterBlock(RenderCenterBlock::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::QuoteBlock(inner) => Ok(RenderAstNode::QuoteBlock(RenderQuoteBlock::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::SpecialBlock(inner) => Ok(RenderAstNode::SpecialBlock(
|
||||||
|
RenderSpecialBlock::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::DynamicBlock(inner) => Ok(RenderAstNode::DynamicBlock(
|
||||||
|
RenderDynamicBlock::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::FootnoteDefinition(inner) => Ok(RenderAstNode::FootnoteDefinition(
|
||||||
|
RenderFootnoteDefinition::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::Comment(inner) => Ok(RenderAstNode::Comment(RenderComment::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::Drawer(inner) => Ok(RenderAstNode::Drawer(RenderDrawer::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::PropertyDrawer(inner) => Ok(RenderAstNode::PropertyDrawer(
|
||||||
|
RenderPropertyDrawer::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::Table(inner) => Ok(RenderAstNode::Table(RenderTable::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::VerseBlock(inner) => Ok(RenderAstNode::VerseBlock(RenderVerseBlock::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::CommentBlock(inner) => Ok(RenderAstNode::CommentBlock(
|
||||||
|
RenderCommentBlock::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::ExampleBlock(inner) => Ok(RenderAstNode::ExampleBlock(
|
||||||
|
RenderExampleBlock::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::ExportBlock(inner) => Ok(RenderAstNode::ExportBlock(RenderExportBlock::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::SrcBlock(inner) => Ok(RenderAstNode::SrcBlock(RenderSrcBlock::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::Clock(inner) => Ok(RenderAstNode::Clock(RenderClock::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::DiarySexp(inner) => Ok(RenderAstNode::DiarySexp(RenderDiarySexp::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::Planning(inner) => Ok(RenderAstNode::Planning(RenderPlanning::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::FixedWidthArea(inner) => Ok(RenderAstNode::FixedWidthArea(
|
||||||
|
RenderFixedWidthArea::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::HorizontalRule(inner) => Ok(RenderAstNode::HorizontalRule(
|
||||||
|
RenderHorizontalRule::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::Keyword(inner) => Ok(RenderAstNode::Keyword(RenderKeyword::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::BabelCall(inner) => Ok(RenderAstNode::BabelCall(RenderBabelCall::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::LatexEnvironment(inner) => Ok(RenderAstNode::LatexEnvironment(
|
||||||
|
RenderLatexEnvironment::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::Bold(inner) => {
|
||||||
|
Ok(RenderAstNode::Bold(RenderBold::new(render_context, inner)?))
|
||||||
|
}
|
||||||
|
IAstNode::Italic(inner) => Ok(RenderAstNode::Italic(RenderItalic::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::Underline(inner) => Ok(RenderAstNode::Underline(RenderUnderline::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::StrikeThrough(inner) => Ok(RenderAstNode::StrikeThrough(
|
||||||
|
RenderStrikeThrough::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::Code(inner) => {
|
||||||
|
Ok(RenderAstNode::Code(RenderCode::new(render_context, inner)?))
|
||||||
|
}
|
||||||
|
IAstNode::Verbatim(inner) => Ok(RenderAstNode::Verbatim(RenderVerbatim::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::PlainText(inner) => Ok(RenderAstNode::PlainText(RenderPlainText::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::RegularLink(inner) => Ok(RenderAstNode::RegularLink(RenderRegularLink::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::RadioLink(inner) => Ok(RenderAstNode::RadioLink(RenderRadioLink::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::RadioTarget(inner) => Ok(RenderAstNode::RadioTarget(RenderRadioTarget::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::PlainLink(inner) => Ok(RenderAstNode::PlainLink(RenderPlainLink::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::AngleLink(inner) => Ok(RenderAstNode::AngleLink(RenderAngleLink::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::OrgMacro(inner) => Ok(RenderAstNode::OrgMacro(RenderOrgMacro::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::Entity(inner) => Ok(RenderAstNode::Entity(RenderEntity::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::LatexFragment(inner) => Ok(RenderAstNode::LatexFragment(
|
||||||
|
RenderLatexFragment::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::ExportSnippet(inner) => Ok(RenderAstNode::ExportSnippet(
|
||||||
|
RenderExportSnippet::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::FootnoteReference(inner) => Ok(RenderAstNode::FootnoteReference(
|
||||||
|
RenderFootnoteReference::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::Citation(inner) => Ok(RenderAstNode::Citation(RenderCitation::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::CitationReference(inner) => Ok(RenderAstNode::CitationReference(
|
||||||
|
RenderCitationReference::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::InlineBabelCall(inner) => Ok(RenderAstNode::InlineBabelCall(
|
||||||
|
RenderInlineBabelCall::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::InlineSourceBlock(inner) => Ok(RenderAstNode::InlineSourceBlock(
|
||||||
|
RenderInlineSourceBlock::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::LineBreak(inner) => Ok(RenderAstNode::LineBreak(RenderLineBreak::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::Target(inner) => Ok(RenderAstNode::Target(RenderTarget::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::StatisticsCookie(inner) => Ok(RenderAstNode::StatisticsCookie(
|
||||||
|
RenderStatisticsCookie::new(render_context, inner)?,
|
||||||
|
)),
|
||||||
|
IAstNode::Subscript(inner) => Ok(RenderAstNode::Subscript(RenderSubscript::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::Superscript(inner) => Ok(RenderAstNode::Superscript(RenderSuperscript::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
IAstNode::Timestamp(inner) => Ok(RenderAstNode::Timestamp(RenderTimestamp::new(
|
||||||
|
render_context,
|
||||||
|
inner,
|
||||||
|
)?)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/context/babel_call.rs
Normal file
16
src/context/babel_call.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::render_context::RenderContext;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::intermediate::IBabelCall;
|
||||||
|
|
||||||
|
use super::macros::rnoop;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
#[serde(rename = "babel_call")]
|
||||||
|
pub(crate) struct RenderBabelCall {
|
||||||
|
post_blank: organic::types::PostBlank,
|
||||||
|
}
|
||||||
|
|
||||||
|
rnoop!(RenderBabelCall, IBabelCall);
|
||||||
123
src/context/blog_post_page.rs
Normal file
123
src/context/blog_post_page.rs
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::render_context::RenderContext;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::intermediate::get_web_path;
|
||||||
|
use crate::intermediate::BlogPost;
|
||||||
|
use crate::intermediate::BlogPostPage;
|
||||||
|
|
||||||
|
use super::footnote_definition::RenderRealFootnoteDefinition;
|
||||||
|
use super::macros::render;
|
||||||
|
use super::GlobalSettings;
|
||||||
|
use super::PageHeader;
|
||||||
|
use super::RenderDocumentElement;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct RenderBlogPostPageInput<'a> {
|
||||||
|
post: &'a BlogPost,
|
||||||
|
page: &'a BlogPostPage,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> RenderBlogPostPageInput<'a> {
|
||||||
|
pub(crate) fn new(post: &'a BlogPost, page: &'a BlogPostPage) -> RenderBlogPostPageInput<'a> {
|
||||||
|
RenderBlogPostPageInput { post, page }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
#[serde(rename = "blog_post_page")]
|
||||||
|
pub(crate) struct RenderBlogPostPage {
|
||||||
|
global_settings: GlobalSettings,
|
||||||
|
|
||||||
|
page_header: Option<PageHeader>,
|
||||||
|
|
||||||
|
/// The title that will be shown visibly on the page.
|
||||||
|
title: Option<String>,
|
||||||
|
|
||||||
|
self_link: Option<String>,
|
||||||
|
|
||||||
|
children: Vec<RenderDocumentElement>,
|
||||||
|
|
||||||
|
footnotes: Vec<RenderRealFootnoteDefinition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
render!(
|
||||||
|
RenderBlogPostPage,
|
||||||
|
RenderBlogPostPageInput,
|
||||||
|
original,
|
||||||
|
render_context,
|
||||||
|
{
|
||||||
|
let css_files = vec![
|
||||||
|
get_web_path(
|
||||||
|
render_context.config,
|
||||||
|
render_context.output_root_directory,
|
||||||
|
render_context.output_file,
|
||||||
|
"stylesheet/reset.css",
|
||||||
|
)?,
|
||||||
|
get_web_path(
|
||||||
|
render_context.config,
|
||||||
|
render_context.output_root_directory,
|
||||||
|
render_context.output_file,
|
||||||
|
"stylesheet/main.css",
|
||||||
|
)?,
|
||||||
|
];
|
||||||
|
let js_files = vec![get_web_path(
|
||||||
|
render_context.config,
|
||||||
|
render_context.output_root_directory,
|
||||||
|
render_context.output_file,
|
||||||
|
"blog_post.js",
|
||||||
|
)?];
|
||||||
|
let global_settings = GlobalSettings::new(original.page.title.clone(), css_files, js_files);
|
||||||
|
let page_header = PageHeader::new(
|
||||||
|
render_context.config.get_site_title().map(str::to_string),
|
||||||
|
Some(get_web_path(
|
||||||
|
render_context.config,
|
||||||
|
render_context.output_root_directory,
|
||||||
|
render_context.output_file,
|
||||||
|
"",
|
||||||
|
)?),
|
||||||
|
);
|
||||||
|
let link_to_blog_post = get_web_path(
|
||||||
|
render_context.config,
|
||||||
|
render_context.output_root_directory,
|
||||||
|
render_context.output_file,
|
||||||
|
render_context
|
||||||
|
.output_file
|
||||||
|
.strip_prefix(render_context.output_root_directory)?,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let children = {
|
||||||
|
let mut children = Vec::new();
|
||||||
|
|
||||||
|
for child in original.page.children.iter() {
|
||||||
|
children.push(RenderDocumentElement::new(render_context.clone(), child)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
children
|
||||||
|
};
|
||||||
|
|
||||||
|
let footnotes = {
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
|
||||||
|
for footnote in original.page.footnotes.iter() {
|
||||||
|
ret.push(RenderRealFootnoteDefinition::new(
|
||||||
|
render_context.clone(),
|
||||||
|
footnote,
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret
|
||||||
|
};
|
||||||
|
|
||||||
|
let ret = RenderBlogPostPage {
|
||||||
|
global_settings,
|
||||||
|
page_header: Some(page_header),
|
||||||
|
title: original.page.title.clone(),
|
||||||
|
self_link: Some(link_to_blog_post),
|
||||||
|
children,
|
||||||
|
footnotes,
|
||||||
|
};
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
|
);
|
||||||
213
src/context/blog_stream.rs
Normal file
213
src/context/blog_stream.rs
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::macros::render;
|
||||||
|
use super::render_context::RenderContext;
|
||||||
|
use crate::context::RenderDocumentElement;
|
||||||
|
use crate::context::RenderRealFootnoteDefinition;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::intermediate::get_web_path;
|
||||||
|
use crate::intermediate::BlogPost;
|
||||||
|
|
||||||
|
use super::GlobalSettings;
|
||||||
|
use super::PageHeader;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct RenderBlogStreamInput<'a, 'b> {
|
||||||
|
original: &'a [&'b BlogPost],
|
||||||
|
older_link: Option<String>,
|
||||||
|
newer_link: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b> RenderBlogStreamInput<'a, 'b> {
|
||||||
|
pub(crate) fn new(
|
||||||
|
original: &'a [&'b BlogPost],
|
||||||
|
older_link: Option<String>,
|
||||||
|
newer_link: Option<String>,
|
||||||
|
) -> RenderBlogStreamInput<'a, 'b> {
|
||||||
|
RenderBlogStreamInput {
|
||||||
|
original,
|
||||||
|
older_link,
|
||||||
|
newer_link,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
#[serde(rename = "blog_stream")]
|
||||||
|
pub(crate) struct RenderBlogStream {
|
||||||
|
global_settings: GlobalSettings,
|
||||||
|
page_header: Option<PageHeader>,
|
||||||
|
children: Vec<RenderBlogStreamEntry>,
|
||||||
|
stream_pagination: Option<RenderBlogStreamPagination>,
|
||||||
|
}
|
||||||
|
|
||||||
|
render!(
|
||||||
|
RenderBlogStream,
|
||||||
|
RenderBlogStreamInput,
|
||||||
|
original,
|
||||||
|
render_context,
|
||||||
|
{
|
||||||
|
let css_files = vec![
|
||||||
|
get_web_path(
|
||||||
|
render_context.config,
|
||||||
|
render_context.output_root_directory,
|
||||||
|
render_context.output_file,
|
||||||
|
"stylesheet/reset.css",
|
||||||
|
)?,
|
||||||
|
get_web_path(
|
||||||
|
render_context.config,
|
||||||
|
render_context.output_root_directory,
|
||||||
|
render_context.output_file,
|
||||||
|
"stylesheet/main.css",
|
||||||
|
)?,
|
||||||
|
];
|
||||||
|
let js_files = vec![get_web_path(
|
||||||
|
render_context.config,
|
||||||
|
render_context.output_root_directory,
|
||||||
|
render_context.output_file,
|
||||||
|
"blog_post.js",
|
||||||
|
)?];
|
||||||
|
let global_settings = GlobalSettings::new(
|
||||||
|
render_context.config.get_site_title().map(str::to_string),
|
||||||
|
css_files,
|
||||||
|
js_files,
|
||||||
|
);
|
||||||
|
let page_header = PageHeader::new(
|
||||||
|
render_context.config.get_site_title().map(str::to_string),
|
||||||
|
Some(get_web_path(
|
||||||
|
render_context.config,
|
||||||
|
render_context.output_root_directory,
|
||||||
|
render_context.output_file,
|
||||||
|
"",
|
||||||
|
)?),
|
||||||
|
);
|
||||||
|
|
||||||
|
let children = original
|
||||||
|
.original
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, blog_post)| {
|
||||||
|
RenderBlogStreamEntry::new(
|
||||||
|
render_context.clone(),
|
||||||
|
&RenderBlogStreamEntryInput::new(blog_post, i),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
let stream_pagination = if original.older_link.is_some() || original.newer_link.is_some() {
|
||||||
|
Some(RenderBlogStreamPagination::new(
|
||||||
|
original.older_link.clone(),
|
||||||
|
original.newer_link.clone(),
|
||||||
|
)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(RenderBlogStream {
|
||||||
|
global_settings,
|
||||||
|
page_header: Some(page_header),
|
||||||
|
children,
|
||||||
|
stream_pagination,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct RenderBlogStreamEntryInput<'a> {
|
||||||
|
original: &'a BlogPost,
|
||||||
|
offset: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> RenderBlogStreamEntryInput<'a> {
|
||||||
|
fn new(original: &'a BlogPost, offset: usize) -> RenderBlogStreamEntryInput<'a> {
|
||||||
|
RenderBlogStreamEntryInput { original, offset }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub(crate) struct RenderBlogStreamEntry {
|
||||||
|
/// The title that will be shown visibly on the page.
|
||||||
|
title: Option<String>,
|
||||||
|
|
||||||
|
self_link: Option<String>,
|
||||||
|
|
||||||
|
children: Vec<RenderDocumentElement>,
|
||||||
|
|
||||||
|
footnotes: Vec<RenderRealFootnoteDefinition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
render!(
|
||||||
|
RenderBlogStreamEntry,
|
||||||
|
RenderBlogStreamEntryInput,
|
||||||
|
original,
|
||||||
|
render_context,
|
||||||
|
{
|
||||||
|
let offset_string = original.offset.to_string();
|
||||||
|
let render_context = {
|
||||||
|
let mut render_context = render_context.clone();
|
||||||
|
render_context.id_addition = Some(offset_string.as_str());
|
||||||
|
render_context
|
||||||
|
};
|
||||||
|
let link_to_blog_post = get_web_path(
|
||||||
|
render_context.config,
|
||||||
|
render_context.output_root_directory,
|
||||||
|
render_context.output_file,
|
||||||
|
render_context
|
||||||
|
.config
|
||||||
|
.get_relative_path_to_post(&original.original.id),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// TODO: Should I guess an index page instead of erroring out?
|
||||||
|
let index_page = original
|
||||||
|
.original
|
||||||
|
.get_index_page()
|
||||||
|
.ok_or_else(|| format!("Blog post {} needs an index page.", original.original.id))?;
|
||||||
|
|
||||||
|
let title = index_page.title.clone();
|
||||||
|
|
||||||
|
let children = index_page
|
||||||
|
.children
|
||||||
|
.iter()
|
||||||
|
.map(|child| RenderDocumentElement::new(render_context.clone(), child))
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
let footnotes = {
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
|
||||||
|
for footnote in index_page.footnotes.iter() {
|
||||||
|
ret.push(RenderRealFootnoteDefinition::new(
|
||||||
|
render_context.clone(),
|
||||||
|
footnote,
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(RenderBlogStreamEntry {
|
||||||
|
title,
|
||||||
|
self_link: Some(link_to_blog_post),
|
||||||
|
children,
|
||||||
|
footnotes,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub(crate) struct RenderBlogStreamPagination {
|
||||||
|
older_link: Option<String>,
|
||||||
|
newer_link: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderBlogStreamPagination {
|
||||||
|
fn new(
|
||||||
|
older_link: Option<String>,
|
||||||
|
newer_link: Option<String>,
|
||||||
|
) -> Result<RenderBlogStreamPagination, CustomError> {
|
||||||
|
Ok(RenderBlogStreamPagination {
|
||||||
|
older_link,
|
||||||
|
newer_link,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/context/bold.rs
Normal file
31
src/context/bold.rs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::intermediate::IBold;
|
||||||
|
|
||||||
|
use super::macros::render;
|
||||||
|
use super::render_context::RenderContext;
|
||||||
|
use super::RenderObject;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
#[serde(rename = "bold")]
|
||||||
|
pub(crate) struct RenderBold {
|
||||||
|
children: Vec<RenderObject>,
|
||||||
|
post_blank: organic::types::PostBlank,
|
||||||
|
}
|
||||||
|
|
||||||
|
render!(RenderBold, IBold, original, render_context, {
|
||||||
|
let children = {
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
for obj in original.children.iter() {
|
||||||
|
ret.push(RenderObject::new(render_context.clone(), obj)?);
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(RenderBold {
|
||||||
|
children,
|
||||||
|
post_blank: original.post_blank,
|
||||||
|
})
|
||||||
|
});
|
||||||
16
src/context/center_block.rs
Normal file
16
src/context/center_block.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::render_context::RenderContext;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::intermediate::ICenterBlock;
|
||||||
|
|
||||||
|
use super::macros::rnoop;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
#[serde(rename = "center_block")]
|
||||||
|
pub(crate) struct RenderCenterBlock {
|
||||||
|
post_blank: organic::types::PostBlank,
|
||||||
|
}
|
||||||
|
|
||||||
|
rnoop!(RenderCenterBlock, ICenterBlock);
|
||||||
16
src/context/citation.rs
Normal file
16
src/context/citation.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::render_context::RenderContext;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::intermediate::ICitation;
|
||||||
|
|
||||||
|
use super::macros::rnoop;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
#[serde(rename = "citation")]
|
||||||
|
pub(crate) struct RenderCitation {
|
||||||
|
post_blank: organic::types::PostBlank,
|
||||||
|
}
|
||||||
|
|
||||||
|
rnoop!(RenderCitation, ICitation);
|
||||||
16
src/context/citation_reference.rs
Normal file
16
src/context/citation_reference.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::render_context::RenderContext;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::intermediate::ICitationReference;
|
||||||
|
|
||||||
|
use super::macros::rnoop;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
#[serde(rename = "citation_reference")]
|
||||||
|
pub(crate) struct RenderCitationReference {
|
||||||
|
post_blank: organic::types::PostBlank,
|
||||||
|
}
|
||||||
|
|
||||||
|
rnoop!(RenderCitationReference, ICitationReference);
|
||||||
16
src/context/clock.rs
Normal file
16
src/context/clock.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::render_context::RenderContext;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::intermediate::IClock;
|
||||||
|
|
||||||
|
use super::macros::rnoop;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
#[serde(rename = "clock")]
|
||||||
|
pub(crate) struct RenderClock {
|
||||||
|
post_blank: organic::types::PostBlank,
|
||||||
|
}
|
||||||
|
|
||||||
|
rnoop!(RenderClock, IClock);
|
||||||
22
src/context/code.rs
Normal file
22
src/context/code.rs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::render_context::RenderContext;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::intermediate::ICode;
|
||||||
|
|
||||||
|
use super::macros::render;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
#[serde(rename = "code")]
|
||||||
|
pub(crate) struct RenderCode {
|
||||||
|
contents: String,
|
||||||
|
post_blank: organic::types::PostBlank,
|
||||||
|
}
|
||||||
|
|
||||||
|
render!(RenderCode, ICode, original, _render_context, {
|
||||||
|
Ok(RenderCode {
|
||||||
|
contents: original.contents.clone(),
|
||||||
|
post_blank: original.post_blank,
|
||||||
|
})
|
||||||
|
});
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user