added watch command with optional auto-reload

master
Kenton Hamaluik 5 years ago
parent 5b0cc03ac8
commit 8b25596a8a

379
Cargo.lock generated

@ -169,6 +169,23 @@ name = "byteorder"
version = "1.3.2" version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bytes"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "c2-chacha"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.47" version = "1.0.47"
@ -221,6 +238,16 @@ dependencies = [
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "colored"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "comrak" name = "comrak"
version = "0.6.2" version = "0.6.2"
@ -283,6 +310,27 @@ name = "fake-simd"
version = "0.1.2" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fern"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"colored 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "filetime"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.13" version = "1.0.13"
@ -299,6 +347,37 @@ name = "fnv"
version = "1.0.6" version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fsevent"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fsevent-sys"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "fxhash" name = "fxhash"
version = "0.2.1" version = "0.2.1"
@ -315,6 +394,16 @@ dependencies = [
"typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "getrandom"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "glob" name = "glob"
version = "0.3.0" version = "0.3.0"
@ -328,6 +417,11 @@ dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "httparse"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "humansize" name = "humansize"
version = "1.1.0" version = "1.1.0"
@ -341,11 +435,56 @@ dependencies = [
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "idna"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "inotify"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "inotify-sys"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "iovec"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "0.4.4" version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@ -389,6 +528,7 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -396,6 +536,11 @@ name = "maplit"
version = "1.0.2" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "matches"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.2.1" version = "2.2.1"
@ -409,6 +554,46 @@ dependencies = [
"adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "mio"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio-extras"
version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miow"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "mkbook" name = "mkbook"
version = "0.3.0" version = "0.3.0"
@ -417,11 +602,25 @@ dependencies = [
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"comrak 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "comrak 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fern 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"sass-rs 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "sass-rs 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
"syntect 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntect 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ws 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "net2"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -433,6 +632,24 @@ dependencies = [
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "notify"
version = "4.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "num-integer" name = "num-integer"
version = "0.1.41" version = "0.1.41"
@ -490,6 +707,11 @@ name = "peeking_take_while"
version = "0.1.2" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "pest" name = "pest"
version = "2.1.2" version = "2.1.2"
@ -547,6 +769,11 @@ dependencies = [
"xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "ppv-lite86"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "0.4.30" version = "0.4.30"
@ -584,6 +811,43 @@ dependencies = [
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "rand"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_chacha"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.1.56" version = "0.1.56"
@ -692,6 +956,16 @@ name = "shlex"
version = "0.1.1" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "slab"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "smallvec"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.8.0" version = "0.8.0"
@ -817,6 +1091,22 @@ name = "unchecked-index"
version = "0.2.2" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-bidi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-normalization"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.6" version = "0.1.6"
@ -837,6 +1127,16 @@ name = "unicode_categories"
version = "0.1.1" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "url"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "vec_map" name = "vec_map"
version = "0.8.1" version = "0.8.1"
@ -857,6 +1157,11 @@ dependencies = [
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "wasi"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "which" name = "which"
version = "2.0.1" version = "2.0.1"
@ -866,6 +1171,11 @@ dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.8" version = "0.3.8"
@ -875,6 +1185,11 @@ dependencies = [
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "winapi-i686-pc-windows-gnu" name = "winapi-i686-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"
@ -902,6 +1217,32 @@ dependencies = [
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "ws"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ws2_32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "xml-rs" name = "xml-rs"
version = "0.8.0" version = "0.8.0"
@ -935,12 +1276,15 @@ dependencies = [
"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" "checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
"checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8" "checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8"
"checksum cexpr 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d" "checksum cexpr 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" "checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01"
"checksum clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853" "checksum clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum colored 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "433e7ac7d511768127ed85b0c4947f47a254131e37864b2dc13f52aa32cd37e5"
"checksum comrak 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea4c29f52463abf5c7a3ae33dd9b404e2031af82f547cfe65bfac17ba785ea2e" "checksum comrak 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea4c29f52463abf5c7a3ae33dd9b404e2031af82f547cfe65bfac17ba785ea2e"
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
@ -948,15 +1292,28 @@ dependencies = [
"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" "checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3"
"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum fern 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e69ab0d5aca163e388c3a49d284fed6c3d0810700e77c5ae2756a50ec1a4daaa"
"checksum filetime 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1ff6d4dab0aa0c8e6346d46052e93b13a16cf847b54ed357087c35011048cc7d"
"checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" "checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
"checksum fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
"checksum fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
"checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120" "checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120"
"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" "checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e"
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" "checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
"checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718"
"checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0"
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" "checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8"
@ -965,9 +1322,15 @@ dependencies = [
"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" "checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625" "checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625"
"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
"checksum notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "199628fc33b21bc767baa057490b00b382ecbae030803a7b36292422d15b778b"
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" "checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72" "checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
@ -975,17 +1338,23 @@ dependencies = [
"checksum onig_sys 69.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a8d4efbf5f59cece01f539305191485b651acb3785b9d5eef05749f0496514e" "checksum onig_sys 69.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a8d4efbf5f59cece01f539305191485b651acb3785b9d5eef05749f0496514e"
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
"checksum pest 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e4fb201c5c22a55d8b24fef95f78be52738e5e1361129be1b5e862ecdb6894a" "checksum pest 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e4fb201c5c22a55d8b24fef95f78be52738e5e1361129be1b5e862ecdb6894a"
"checksum pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" "checksum pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
"checksum pest_generator 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9fcf299b5712d06ee128a556c94709aaa04512c4dffb8ead07c5c998447fc0" "checksum pest_generator 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9fcf299b5712d06ee128a556c94709aaa04512c4dffb8ead07c5c998447fc0"
"checksum pest_meta 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df43fd99896fd72c485fe47542c7b500e4ac1e8700bf995544d1317a60ded547" "checksum pest_meta 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df43fd99896fd72c485fe47542c7b500e4ac1e8700bf995544d1317a60ded547"
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
"checksum plist 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a9f075f6394100e7c105ed1af73fb1859d6fd14e49d4290d578120beb167f" "checksum plist 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a9f075f6394100e7c105ed1af73fb1859d6fd14e49d4290d578120beb167f"
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" "checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
@ -1000,6 +1369,8 @@ dependencies = [
"checksum serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)" = "1a3351dcbc1f067e2c92ab7c3c1f288ad1a4cffc470b5aaddb4c2e0a3ae80043" "checksum serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)" = "1a3351dcbc1f067e2c92ab7c3c1f288ad1a4cffc470b5aaddb4c2e0a3ae80043"
"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" "checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
"checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92" "checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92"
@ -1015,18 +1386,26 @@ dependencies = [
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" "checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
"checksum ucd-trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8f00ed7be0c1ff1e24f46c3d2af4859f7e863672ba3a6e92e7cff702bf9f06c2" "checksum ucd-trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8f00ed7be0c1ff1e24f46c3d2af4859f7e863672ba3a6e92e7cff702bf9f06c2"
"checksum unchecked-index 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" "checksum unchecked-index 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf"
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" "checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" "checksum unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
"checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" "checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9" "checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9"
"checksum ws 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a2c47b5798ccc774ffb93ff536aec7c4275d722fd9c740c83cdd1af1f2d94"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
"checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5" "checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5"
"checksum yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d" "checksum yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d"

@ -28,6 +28,10 @@ serde = { version = "1.0", features = ["derive"] }
toml = "0.5" toml = "0.5"
lazy_static = "1.4" lazy_static = "1.4"
chrono = "0.4" chrono = "0.4"
notify = "4.0"
ws = "0.9"
fern = { version = "0.5", features = ["colored"] }
log = { version = "0.4", features = ["max_level_debug", "release_max_level_info", "std", "serde"] }
[build-dependencies] [build-dependencies]
sass-rs = "0.2" sass-rs = "0.2"

@ -35,6 +35,7 @@ SUBCOMMANDS:
build build the book build build the book
help Prints this message or the help of the given subcommand(s) help Prints this message or the help of the given subcommand(s)
init initialize a mkbook directory tree init initialize a mkbook directory tree
watch build the book and continually rebuild whenever the source changes
``` ```
### The Init Command ### The Init Command
@ -77,3 +78,24 @@ OPTIONS:
-i, --in <in> an optional directory to take the book sources from [default: src] -i, --in <in> an optional directory to take the book sources from [default: src]
-o, --out <out> an optional directory to render the contents into [default: book] -o, --out <out> an optional directory to render the contents into [default: book]
``` ```
### The Watch Command
The watch command is basically the same as the `build` command, however after building it continues to monitor the source directory and if _any_ changes are made (a file is saved, renamed, removed, created, etc), the entire book is re-built. In the future, this will hopefully be smarter but for now it just the whole thing at once. Stop watching using <kbd>Ctrl+C</kbd> or sending `SIGINT`.
```sh
$ mkbook build --help
mkbook-watch
build the book and continually rebuild whenever the source changes
USAGE:
mkbook watch [OPTIONS]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-i, --in <in> an optional directory to take the book sources from [default: src]
-o, --out <out> an optional directory to render the contents into [default: book]
```

@ -12,7 +12,7 @@
<meta property="og:url" content="https://hamaluik.github.io/mkbook//01-introduction/index.html" /> <meta property="og:url" content="https://hamaluik.github.io/mkbook//01-introduction/index.html" />
<meta property="book:author" content="Kenton Hamaluik" /> <meta property="book:author" content="Kenton Hamaluik" />
<meta property="book:release_date" content="2019-12-01T18:55:05.215513238+00:00" /> <meta property="book:release_date" content="2019-12-02T20:05:16.402897505+00:00" />
</head> </head>
<body> <body>
@ -124,6 +124,7 @@
</span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">build</span><span style="color:#d3d0c8;"> build the book </span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">build</span><span style="color:#d3d0c8;"> build the book
</span><span style="color:#d3d0c8;"> </span><span style="color:#66cccc;">help</span><span style="color:#d3d0c8;"> Prints this message or the help of the given subcommand(s) </span><span style="color:#d3d0c8;"> </span><span style="color:#66cccc;">help</span><span style="color:#d3d0c8;"> Prints this message or the help of the given subcommand(s)
</span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">init</span><span style="color:#d3d0c8;"> initialize a mkbook directory tree </span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">init</span><span style="color:#d3d0c8;"> initialize a mkbook directory tree
</span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">watch</span><span style="color:#d3d0c8;"> build the book and continually rebuild whenever the source changes
</span></pre> </span></pre>
<h3><a href="#the-init-command" aria-hidden="true" class="anchor" id="headerthe-init-command"></a>The Init Command</h3> <h3><a href="#the-init-command" aria-hidden="true" class="anchor" id="headerthe-init-command"></a>The Init Command</h3>
<p>The init command is a tool to help you get started, and will create an initial <code>README.md</code> file and a stub of your first chapter.</p> <p>The init command is a tool to help you get started, and will create an initial <code>README.md</code> file and a stub of your first chapter.</p>
@ -160,6 +161,24 @@
</span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">-i,</span><span style="color:#f2777a;"> --in </span><span style="color:#d3d0c8;">&lt;in&gt; an optional directory to take the book sources from </span><span style="color:#cc99cc;">[</span><span style="color:#d3d0c8;">default: src</span><span style="color:#cc99cc;">] </span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">-i,</span><span style="color:#f2777a;"> --in </span><span style="color:#d3d0c8;">&lt;in&gt; an optional directory to take the book sources from </span><span style="color:#cc99cc;">[</span><span style="color:#d3d0c8;">default: src</span><span style="color:#cc99cc;">]
</span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">-o,</span><span style="color:#f2777a;"> --out </span><span style="color:#d3d0c8;">&lt;out&gt; an optional directory to render the contents into </span><span style="color:#cc99cc;">[</span><span style="color:#d3d0c8;">default: book</span><span style="color:#cc99cc;">] </span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">-o,</span><span style="color:#f2777a;"> --out </span><span style="color:#d3d0c8;">&lt;out&gt; an optional directory to render the contents into </span><span style="color:#cc99cc;">[</span><span style="color:#d3d0c8;">default: book</span><span style="color:#cc99cc;">]
</span></pre> </span></pre>
<h3><a href="#the-watch-command" aria-hidden="true" class="anchor" id="headerthe-watch-command"></a>The Watch Command</h3>
<p>The watch command is basically the same as the <code>build</code> command, however after building it continues to monitor the source directory and if <em>any</em> changes are made (a file is saved, renamed, removed, created, etc), the entire book is re-built. In the future, this will hopefully be smarter but for now it just the whole thing at once. Stop watching using <kbd>Ctrl+C</kbd> or sending <code>SIGINT</code>.</p>
<pre style="background-color:#2d2d2d;">
<span style="color:#6699cc;">$</span><span style="color:#d3d0c8;"> mkbook build</span><span style="color:#f2777a;"> --help
</span><span style="color:#6699cc;">mkbook-watch
</span><span style="color:#6699cc;">build</span><span style="color:#d3d0c8;"> the book and continually rebuild whenever the source changes
</span><span style="color:#d3d0c8;">
</span><span style="color:#6699cc;">USAGE:
</span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">mkbook</span><span style="color:#d3d0c8;"> watch </span><span style="color:#cc99cc;">[</span><span style="color:#d3d0c8;">OPTIONS</span><span style="color:#cc99cc;">]
</span><span style="color:#d3d0c8;">
</span><span style="color:#6699cc;">FLAGS:
</span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">-h,</span><span style="color:#f2777a;"> --help</span><span style="color:#d3d0c8;"> Prints help information
</span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">-V,</span><span style="color:#f2777a;"> --version</span><span style="color:#d3d0c8;"> Prints version information
</span><span style="color:#d3d0c8;">
</span><span style="color:#6699cc;">OPTIONS:
</span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">-i,</span><span style="color:#f2777a;"> --in </span><span style="color:#d3d0c8;">&lt;in&gt; an optional directory to take the book sources from </span><span style="color:#cc99cc;">[</span><span style="color:#d3d0c8;">default: src</span><span style="color:#cc99cc;">]
</span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">-o,</span><span style="color:#f2777a;"> --out </span><span style="color:#d3d0c8;">&lt;out&gt; an optional directory to render the contents into </span><span style="color:#cc99cc;">[</span><span style="color:#d3d0c8;">default: book</span><span style="color:#cc99cc;">]
</span></pre>
@ -176,5 +195,6 @@
<footer><p>&copy; 2019 Kenton Hamaluik</p></footer> <footer><p>&copy; 2019 Kenton Hamaluik</p></footer>
</article> </article>
</body> </body>
</html> </html>

@ -12,7 +12,7 @@
<meta property="og:url" content="https://hamaluik.github.io/mkbook//02-markdown/01-commonmark.html" /> <meta property="og:url" content="https://hamaluik.github.io/mkbook//02-markdown/01-commonmark.html" />
<meta property="book:author" content="Kenton Hamaluik" /> <meta property="book:author" content="Kenton Hamaluik" />
<meta property="book:release_date" content="2019-12-01T18:55:05.215513238+00:00" /> <meta property="book:release_date" content="2019-12-02T20:05:16.402897505+00:00" />
</head> </head>
<body> <body>
@ -164,5 +164,6 @@
<footer><p>&copy; 2019 Kenton Hamaluik</p></footer> <footer><p>&copy; 2019 Kenton Hamaluik</p></footer>
</article> </article>
</body> </body>
</html> </html>

@ -12,7 +12,7 @@
<meta property="og:url" content="https://hamaluik.github.io/mkbook//02-markdown/02-syntax-highlighting.html" /> <meta property="og:url" content="https://hamaluik.github.io/mkbook//02-markdown/02-syntax-highlighting.html" />
<meta property="book:author" content="Kenton Hamaluik" /> <meta property="book:author" content="Kenton Hamaluik" />
<meta property="book:release_date" content="2019-12-01T18:55:05.215513238+00:00" /> <meta property="book:release_date" content="2019-12-02T20:05:16.402897505+00:00" />
</head> </head>
<body> <body>
@ -625,5 +625,6 @@
<footer><p>&copy; 2019 Kenton Hamaluik</p></footer> <footer><p>&copy; 2019 Kenton Hamaluik</p></footer>
</article> </article>
</body> </body>
</html> </html>

@ -12,7 +12,7 @@
<meta property="og:url" content="https://hamaluik.github.io/mkbook//02-markdown/03-plantuml-diagrams.html" /> <meta property="og:url" content="https://hamaluik.github.io/mkbook//02-markdown/03-plantuml-diagrams.html" />
<meta property="book:author" content="Kenton Hamaluik" /> <meta property="book:author" content="Kenton Hamaluik" />
<meta property="book:release_date" content="2019-12-01T18:55:05.215513238+00:00" /> <meta property="book:release_date" content="2019-12-02T20:05:16.402897505+00:00" />
</head> </head>
<body> <body>
@ -137,5 +137,6 @@
<footer><p>&copy; 2019 Kenton Hamaluik</p></footer> <footer><p>&copy; 2019 Kenton Hamaluik</p></footer>
</article> </article>
</body> </body>
</html> </html>

@ -12,7 +12,7 @@
<meta property="og:url" content="https://hamaluik.github.io/mkbook//02-markdown/04-katex-formulas.html" /> <meta property="og:url" content="https://hamaluik.github.io/mkbook//02-markdown/04-katex-formulas.html" />
<meta property="book:author" content="Kenton Hamaluik" /> <meta property="book:author" content="Kenton Hamaluik" />
<meta property="book:release_date" content="2019-12-01T18:55:05.215513238+00:00" /> <meta property="book:release_date" content="2019-12-02T20:05:16.402897505+00:00" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous">
</head> </head>
<body> <body>
@ -145,5 +145,6 @@ M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">
<footer><p>&copy; 2019 Kenton Hamaluik</p></footer> <footer><p>&copy; 2019 Kenton Hamaluik</p></footer>
</article> </article>
</body> </body>
</html> </html>

@ -12,7 +12,7 @@
<meta property="og:url" content="https://hamaluik.github.io/mkbook//02-markdown/index.html" /> <meta property="og:url" content="https://hamaluik.github.io/mkbook//02-markdown/index.html" />
<meta property="book:author" content="Kenton Hamaluik" /> <meta property="book:author" content="Kenton Hamaluik" />
<meta property="book:release_date" content="2019-12-01T18:55:05.215513238+00:00" /> <meta property="book:release_date" content="2019-12-02T20:05:16.402897505+00:00" />
</head> </head>
<body> <body>
@ -132,5 +132,6 @@
<footer><p>&copy; 2019 Kenton Hamaluik</p></footer> <footer><p>&copy; 2019 Kenton Hamaluik</p></footer>
</article> </article>
</body> </body>
</html> </html>

@ -12,7 +12,7 @@
<meta property="og:url" content="https://hamaluik.github.io/mkbook//03-frontmatter/index.html" /> <meta property="og:url" content="https://hamaluik.github.io/mkbook//03-frontmatter/index.html" />
<meta property="book:author" content="Kenton Hamaluik" /> <meta property="book:author" content="Kenton Hamaluik" />
<meta property="book:release_date" content="2019-12-01T18:55:05.215513238+00:00" /> <meta property="book:release_date" content="2019-12-02T20:05:16.402897505+00:00" />
</head> </head>
<body> <body>
@ -162,5 +162,6 @@
<footer><p>&copy; 2019 Kenton Hamaluik</p></footer> <footer><p>&copy; 2019 Kenton Hamaluik</p></footer>
</article> </article>
</body> </body>
</html> </html>

@ -12,7 +12,7 @@
<meta property="og:url" content="https://hamaluik.github.io/mkbook//04-structure/index.html" /> <meta property="og:url" content="https://hamaluik.github.io/mkbook//04-structure/index.html" />
<meta property="book:author" content="Kenton Hamaluik" /> <meta property="book:author" content="Kenton Hamaluik" />
<meta property="book:release_date" content="2019-12-01T18:55:05.215513238+00:00" /> <meta property="book:release_date" content="2019-12-02T20:05:16.402897505+00:00" />
</head> </head>
<body> <body>
@ -199,5 +199,6 @@
<footer><p>&copy; 2019 Kenton Hamaluik</p></footer> <footer><p>&copy; 2019 Kenton Hamaluik</p></footer>
</article> </article>
</body> </body>
</html> </html>

@ -12,7 +12,7 @@
<meta property="og:url" content="https://hamaluik.github.io/mkbook//05-customization/index.html" /> <meta property="og:url" content="https://hamaluik.github.io/mkbook//05-customization/index.html" />
<meta property="book:author" content="Kenton Hamaluik" /> <meta property="book:author" content="Kenton Hamaluik" />
<meta property="book:release_date" content="2019-12-01T18:55:05.215513238+00:00" /> <meta property="book:release_date" content="2019-12-02T20:05:16.402897505+00:00" />
</head> </head>
<body> <body>
@ -123,5 +123,6 @@
<footer><p>&copy; 2019 Kenton Hamaluik</p></footer> <footer><p>&copy; 2019 Kenton Hamaluik</p></footer>
</article> </article>
</body> </body>
</html> </html>

@ -12,7 +12,7 @@
<meta property="og:url" content="https://hamaluik.github.io/mkbook//06-how-it-works/index.html" /> <meta property="og:url" content="https://hamaluik.github.io/mkbook//06-how-it-works/index.html" />
<meta property="book:author" content="Kenton Hamaluik" /> <meta property="book:author" content="Kenton Hamaluik" />
<meta property="book:release_date" content="2019-12-01T18:55:05.215513238+00:00" /> <meta property="book:release_date" content="2019-12-02T20:05:16.402897505+00:00" />
</head> </head>
<body> <body>
@ -124,5 +124,6 @@
<footer><p>&copy; 2019 Kenton Hamaluik</p></footer> <footer><p>&copy; 2019 Kenton Hamaluik</p></footer>
</article> </article>
</body> </body>
</html> </html>

@ -14,14 +14,14 @@
&lt;p&gt;This tool aims to work somewhat similarly to &lt;em&gt;mdbook&lt;&#x2f;em&gt;, but is generally intended to be a more minimal alternative that is customized more towards my needs and desires than anything else.&lt;&#x2f;p&gt; &lt;p&gt;This tool aims to work somewhat similarly to &lt;em&gt;mdbook&lt;&#x2f;em&gt;, but is generally intended to be a more minimal alternative that is customized more towards my needs and desires than anything else.&lt;&#x2f;p&gt;
" /> " />
<meta property="book:author" content="Kenton Hamaluik" /> <meta property="book:author" content="Kenton Hamaluik" />
<meta property="book:release_date" content="2019-12-01T18:55:05.215513238+00:00" /> <meta property="book:release_date" content="2019-12-02T20:05:16.402897505+00:00" />
</head> </head>
<body class="toc"> <body class="toc">
<header> <header>
<h1>The mkbook Book</h1> <h1>The mkbook Book</h1>
<h2>by Kenton Hamaluik</h2> <h2>by Kenton Hamaluik</h2>
<time datetime="2019-12-01T18:55:05.215513238+00:00">Dec 1, 2019</time> <time datetime="2019-12-02T20:05:16.402897505+00:00">Dec 2, 2019</time>
</header> </header>
<article> <article>
<p><em>mkbook</em> is my simpler alternative to <a href="https://crates.io/crates/mdbook">mdbook</a> which is a great tool, but for which I really dislike some of the decisions they took, such as relying on javascript for highlighting and navigation, and including a lot of bells and whistles such as javascript-based search.</p> <p><em>mkbook</em> is my simpler alternative to <a href="https://crates.io/crates/mdbook">mdbook</a> which is a great tool, but for which I really dislike some of the decisions they took, such as relying on javascript for highlighting and navigation, and including a lot of bells and whistles such as javascript-based search.</p>
@ -77,5 +77,6 @@
</ol> </ol>
</nav> </nav>
<footer><p>&copy; 2019 Kenton Hamaluik</p></footer> <footer><p>&copy; 2019 Kenton Hamaluik</p></footer>
</body> </body>
</html> </html>

File diff suppressed because one or more lines are too long

@ -29,4 +29,24 @@ pub fn build_cli() -> App<'static, 'static> {
.help("an optional directory to render the contents into") .help("an optional directory to render the contents into")
) )
) )
.subcommand(SubCommand::with_name("watch")
.about("build the book and continually rebuild whenever the source changes")
.arg(Arg::with_name("in")
.short("i")
.long("in")
.default_value("src")
.help("an optional directory to take the book sources from")
)
.arg(Arg::with_name("out")
.short("o")
.long("out")
.default_value("book")
.help("an optional directory to render the contents into")
)
.arg(Arg::with_name("reload")
.short("r")
.long("reload")
.help("inject live-reload code so that the page automatically reloads on regeneration")
)
)
} }

@ -1,7 +1,7 @@
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
use std::path::PathBuf; use std::path::{PathBuf, Path};
use std::{fs, io}; use std::{fs, io};
use comrak::ComrakOptions; use comrak::ComrakOptions;
use syntect::{parsing::SyntaxSet, highlighting::{ThemeSet, Theme}}; use syntect::{parsing::SyntaxSet, highlighting::{ThemeSet, Theme}};
@ -85,7 +85,7 @@ fn create_katex_inline(src: &str) -> Result<String, Box<dyn std::error::Error>>
.spawn() { .spawn() {
Ok(c) => c, Ok(c) => c,
Err(e) => { Err(e) => {
eprintln!("[WARNING] failed to launch katex, not rendering math block: {:?}", e); log::warn!("failed to launch katex, not rendering math block: {:?}", e);
return Ok(format_code("", src)?.output); return Ok(format_code("", src)?.output);
} }
}; };
@ -95,12 +95,12 @@ fn create_katex_inline(src: &str) -> Result<String, Box<dyn std::error::Error>>
let output = child.wait_with_output()?; let output = child.wait_with_output()?;
if !output.status.success() { if !output.status.success() {
eprintln!("failed to generate katex, exit code: {:?}", output.status.code()); log::error!("failed to generate katex, exit code: {:?}", output.status.code());
eprintln!("katex STDOUT:"); log::error!("katex STDOUT:");
eprintln!("{}", String::from_utf8_lossy(output.stdout.as_ref())); log::error!("{}", String::from_utf8_lossy(output.stdout.as_ref()));
eprintln!("katex STDERR:"); log::error!("katex STDERR:");
eprintln!("{}", String::from_utf8_lossy(output.stdout.as_ref())); log::error!("{}", String::from_utf8_lossy(output.stdout.as_ref()));
eprintln!("/katex output"); log::error!("/katex output");
return Ok(format_code("", src)?.output); return Ok(format_code("", src)?.output);
} }
let rendered: String = String::from_utf8(output.stdout)?; let rendered: String = String::from_utf8(output.stdout)?;
@ -122,7 +122,7 @@ fn create_plantuml_svg(src: &str) -> Result<String, Box<dyn std::error::Error>>
.spawn() { .spawn() {
Ok(c) => c, Ok(c) => c,
Err(e) => { Err(e) => {
eprintln!("[WARNING] failed to launch plantuml, not rendering plantuml block: {:?}", e); log::warn!("failed to launch plantuml, not rendering plantuml block: {:?}", e);
return Ok(format_code("", src)?.output); return Ok(format_code("", src)?.output);
} }
}; };
@ -132,12 +132,12 @@ fn create_plantuml_svg(src: &str) -> Result<String, Box<dyn std::error::Error>>
let output = child.wait_with_output()?; let output = child.wait_with_output()?;
if !output.status.success() { if !output.status.success() {
eprintln!("failed to generate plantuml, exit code: {:?}", output.status.code()); log::error!("failed to generate plantuml, exit code: {:?}", output.status.code());
eprintln!("plantuml STDOUT:"); log::error!("plantuml STDOUT:");
eprintln!("{}", String::from_utf8_lossy(output.stdout.as_ref())); log::error!("{}", String::from_utf8_lossy(output.stdout.as_ref()));
eprintln!("plantuml STDERR:"); log::error!("plantuml STDERR:");
eprintln!("{}", String::from_utf8_lossy(output.stdout.as_ref())); log::error!("{}", String::from_utf8_lossy(output.stdout.as_ref()));
eprintln!("/plantuml output"); log::error!("/plantuml output");
return Ok(format_code("", src)?.output); return Ok(format_code("", src)?.output);
} }
let svg: String = String::from_utf8(output.stdout)?; let svg: String = String::from_utf8(output.stdout)?;
@ -278,15 +278,17 @@ struct IndexTemplate<'a, 'b, 'c> {
chapters: &'b Vec<Chapter>, chapters: &'b Vec<Chapter>,
book_description: &'c str, book_description: &'c str,
include_katex_css: bool, include_katex_css: bool,
include_reload_script: bool,
} }
fn generate_index<W: io::Write>(book: &FrontMatter, content: String, include_katex_css: bool, chapters: &Vec<Chapter>, mut output: W) -> Result<(), Box<dyn std::error::Error>> { fn generate_index<W: io::Write>(book: &FrontMatter, content: String, include_katex_css: bool, chapters: &Vec<Chapter>, mut output: W, include_reload_script: bool) -> Result<(), Box<dyn std::error::Error>> {
// fill out our template // fill out our template
let template = IndexTemplate { let template = IndexTemplate {
book, book,
chapters, chapters,
book_description: &content, book_description: &content,
include_katex_css, include_katex_css,
include_reload_script,
}; };
// and render! // and render!
@ -306,9 +308,10 @@ struct PageTemplate<'a, 'b, 'c, 'd, 'e, 'g> {
next_chapter: Option<&'e Chapter>, next_chapter: Option<&'e Chapter>,
book: &'g FrontMatter, book: &'g FrontMatter,
include_katex_css: bool, include_katex_css: bool,
include_reload_script: bool,
} }
fn format_page<W: io::Write>(book: &FrontMatter, chapter: &Chapter, chapters: &Vec<Chapter>, prev_chapter: Option<&Chapter>, next_chapter: Option<&Chapter>, content: &str, include_katex_css: bool, mut output: W) -> Result<(), Box<dyn std::error::Error>> { fn format_page<W: io::Write>(book: &FrontMatter, chapter: &Chapter, chapters: &Vec<Chapter>, prev_chapter: Option<&Chapter>, next_chapter: Option<&Chapter>, content: &str, include_katex_css: bool, mut output: W, include_reload_script: bool) -> Result<(), Box<dyn std::error::Error>> {
// fill out our template // fill out our template
let template = PageTemplate { let template = PageTemplate {
chapter, chapter,
@ -318,6 +321,7 @@ fn format_page<W: io::Write>(book: &FrontMatter, chapter: &Chapter, chapters: &V
next_chapter, next_chapter,
book, book,
include_katex_css, include_katex_css,
include_reload_script,
}; };
// and render! // and render!
@ -327,27 +331,278 @@ fn format_page<W: io::Write>(book: &FrontMatter, chapter: &Chapter, chapters: &V
Ok(()) Ok(())
} }
fn build<PIn: AsRef<Path>, POut: AsRef<Path>>(src: PIn, dest: POut, include_reload_script: bool) -> Result<(), Box<dyn std::error::Error>> {
let src = PathBuf::from(src.as_ref());
let dest = PathBuf::from(dest.as_ref());
std::fs::create_dir_all(&dest)?;
// load our book
let book_readme_path = src.join("README.md");
let (book_front, book_description) = if book_readme_path.exists() {
let contents = fs::read_to_string(&book_readme_path)?;
let (front, contents) = extract_frontmatter(&contents)?;
(front, contents)
}
else {
let content = String::new();
(None, content)
};
let book_front = FrontMatter::from_root(book_front.unwrap_or_default());
let FormatResponse { output, include_katex_css } = format_markdown(&book_description)?;
let book_description = output;
// load all our chapters
let mut chapters: Vec<Chapter> = Vec::default();
for entry in src.read_dir()? {
let entry = entry?;
let path = entry.path();
if entry.file_type()?.is_dir() {
// try to find a `README.md` file and parse it to get the chapter's title, fall back to the directory
// name if we can't do that
let chapter_name = path.file_name().map(std::ffi::OsStr::to_str).flatten().unwrap_or_default();
let index_path = path.join("README.md");
let (front, contents) = if index_path.exists() {
let contents = fs::read_to_string(&index_path)?;
let (front, contents) = extract_frontmatter(&contents)?;
let front = front.unwrap_or_default().into_front(&book_front, chapter_name, &format!("{}/index.html", chapter_name));
(front, contents)
}
else {
(ParsedFrontMatter::default().into_front(&book_front, chapter_name, &format!("{}/index.html", chapter_name)), String::new())
};
let mut chapter: Chapter = Chapter {
front,
sections: Vec::default(),
source: path.clone(),
contents,
};
for entry in path.read_dir()? {
let entry = entry?;
let path = entry.path();
if let Some("md") = path.extension().map(std::ffi::OsStr::to_str).flatten() {
let name = path.file_stem().map(std::ffi::OsStr::to_str).flatten();
if name.is_none() { continue; }
let name = name.unwrap();
if name == "README" {
continue;
}
let contents = fs::read_to_string(&path)?;
let (front, contents) = extract_frontmatter(&contents)?;
let front = front.unwrap_or_default().into_front(&book_front, name, &format!("{}/{}.html", chapter_name, name));
chapter.sections.push(Chapter {
front,
sections: Vec::new(),
source: path,
contents,
});
}
}
chapters.push(chapter);
}
else if let Some("md") = path.extension().map(std::ffi::OsStr::to_str).flatten() {
let name = path.file_stem().map(std::ffi::OsStr::to_str).flatten();
if name.is_none() { continue; }
let name = name.unwrap();
if name == "README" {
continue;
}
let contents = fs::read_to_string(&path)?;
let (front, contents) = extract_frontmatter(&contents)?;
let front = front.unwrap_or_default().into_front(&book_front, name, &format!("{}/index.html", name));
chapters.push(Chapter {
front,
sections: Vec::new(),
source: path,
contents,
});
}
}
// sort all the chapters
chapters.sort_by(|a, b| a.front.url.cmp(&b.front.url));
for chapter in chapters.iter_mut() {
chapter.sections.sort_by(|a, b| a.front.url.cmp(&b.front.url));
}
// generate our index
let index_out_path = dest.join("index.html");
let index_out = fs::File::create(&index_out_path)?;
let index_out = io::BufWriter::new(index_out);
generate_index(&book_front, book_description, include_katex_css, &chapters, index_out, include_reload_script)?;
log::info!("Rendered index into `{}`", index_out_path.display());
// compile markdown and write the actual pages
let mut prev_chapter = None;
for (chapter_index, chapter) in chapters.iter().enumerate() {
// render the index
let chapter_root = dest.join(chapter.source.file_stem().map(std::ffi::OsStr::to_str).flatten().unwrap());
let out = chapter_root.join("index.html");
log::info!("Rendering `{}` into `{}`...", chapter.source.display(), out.display());
fs::create_dir_all(&chapter_root)?;
let outfile = fs::File::create(&out)?;
let outfile = io::BufWriter::new(outfile);
let FormatResponse { output, include_katex_css } = format_markdown(&chapter.contents)?;
let next_chapter =
if chapter.sections.len() > 0 {
Some(chapter.sections.iter().nth(0).expect("section 0 exists"))
}
else if chapter_index < chapters.len() - 1 {
Some(chapters.iter().nth(chapter_index + 1).expect("chapter n+1 exists"))
}
else {
None
};
format_page(&book_front, &chapter, &chapters, prev_chapter, next_chapter, &output, include_katex_css, outfile, include_reload_script)?;
prev_chapter = Some(chapter);
// now the sections
for (section_index, section) in chapter.sections.iter().enumerate() {
let name = section.source.file_stem().map(std::ffi::OsStr::to_str).flatten().unwrap();
let out = chapter_root.join(&format!("{}.html", name));
log::info!("Rendering `{}` into `{}`...", section.source.display(), out.display());
let outfile = fs::File::create(&out)?;
let outfile = io::BufWriter::new(outfile);
let FormatResponse { output, include_katex_css } = format_markdown(&section.contents)?;
let next_chapter = if section_index < chapter.sections.len() - 1 {
Some(chapter.sections.iter().nth(section_index + 1).expect("chapter n+1 exists"))
}
else if chapter_index < chapters.len() - 1 {
Some(chapters.iter().nth(chapter_index + 1).expect("chapter n+1 exists"))
}
else {
None
};
format_page(&book_front, &section, &chapters, prev_chapter, next_chapter, &output, include_katex_css, outfile, include_reload_script)?;
prev_chapter = Some(section);
}
}
// save the assets
fs::write(dest.join("style.css"), STYLESHEET)?;
log::info!("Wrote {}", dest.join("style.css").display());
fs::write(dest.join("favicon.ico"), ASSET_FAVICON)?;
log::info!("Wrote {}", dest.join("favicon.ico").display());
fs::write(dest.join("icons.svg"), ASSET_ICONS)?;
log::info!("Wrote {}", dest.join("icons.svg").display());
log::info!("Done!");
Ok(())
}
struct ReloadClient {
sender: std::sync::Arc<ws::Sender>,
reload: std::sync::Arc<std::sync::atomic::AtomicBool>,
quitloop: std::sync::Arc<std::sync::atomic::AtomicBool>,
}
impl ReloadClient {
pub fn new(sender: ws::Sender, reload: std::sync::Arc<std::sync::atomic::AtomicBool>) -> ReloadClient {
ReloadClient {
sender: std::sync::Arc::new(sender),
reload,
quitloop: std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)),
}
}
}
impl ws::Handler for ReloadClient {
fn on_open(&mut self, _: ws::Handshake) -> ws::Result<()> {
log::info!("reload client connected");
let out = self.sender.clone();
let reload = self.reload.clone();
let quitloop = self.quitloop.clone();
std::thread::spawn(move || {
'sendloop: loop {
let send_reload = reload.load(std::sync::atomic::Ordering::SeqCst);
if send_reload {
log::debug!("sending reload signal...");
out.send("reload").expect("can send reload signal");
log::debug!(" ok!");
}
let quit = quitloop.load(std::sync::atomic::Ordering::SeqCst);
if quit {
break 'sendloop;
}
// check at 10 Hz
std::thread::sleep(std::time::Duration::from_millis(100));
}
log::warn!("shutting down reload connection");
if let Err(e) = out.shutdown() {
log::error!("failed to shut down reload connection: {:?}", e);
}
});
Ok(())
}
fn on_close(&mut self, code: ws::CloseCode, reason: &str) {
log::debug!("reload connection closed: {:?}: {}", code, reason);
//self.quitloop.store(true, std::sync::atomic::Ordering::SeqCst);
}
fn on_shutdown(&mut self) {
log::debug!("reload connection shutdown");
self.quitloop.store(true, std::sync::atomic::Ordering::SeqCst);
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
let matches = cli::build_cli().get_matches(); let matches = cli::build_cli().get_matches();
use fern::colors::{Color, ColoredLevelConfig};
let colors_level = ColoredLevelConfig::new()
.error(Color::Red)
.warn(Color::Yellow)
.info(Color::Cyan)
.debug(Color::Magenta)
.trace(Color::BrightBlack);
fern::Dispatch::new()
.format(move |out, message, record| {
out.finish(format_args!(
"[{date}][\x1B[96m{target}\x1B[0m][{level}\x1B[0m] {message}",
date = chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
target = record.target(),
level = colors_level.color(record.level()),
message = message,
));
})
.level_for("ws", log::LevelFilter::Info)
.chain(std::io::stdout())
.apply()?;
if let Some(submatches) = matches.subcommand_matches("init") { if let Some(submatches) = matches.subcommand_matches("init") {
let dest = submatches.value_of("directory").expect("directory value"); let dest = submatches.value_of("directory").expect("directory value");
let dest = PathBuf::from(dest); let dest = PathBuf::from(dest);
println!("Initializing a book into {}...", dest.display()); log::info!("Initializing a book into {}...", dest.display());
fs::create_dir_all(&dest)?; fs::create_dir_all(&dest)?;
let book_readme_path = dest.join("README.md"); let book_readme_path = dest.join("README.md");
fs::write(&book_readme_path, ASSET_DEFAULT_README)?; fs::write(&book_readme_path, ASSET_DEFAULT_README)?;
let intro_path = dest.join("01-introduction.md"); let intro_path = dest.join("01-introduction.md");
fs::write(&intro_path, ASSET_DEFAULT_INTRODUCTION)?; fs::write(&intro_path, ASSET_DEFAULT_INTRODUCTION)?;
println!("Done!"); log::info!("Done!");
println!("You can now build your book by running:"); log::info!("You can now build your book by running:");
if dest.display().to_string() != "src" { if dest.display().to_string() != "src" {
println!("mkbook build -i {}", dest.display()); log::info!("mkbook build -i {}", dest.display());
} }
else { else {
println!("mkbook build"); log::info!("mkbook build");
} }
Ok(()) Ok(())
@ -355,179 +610,45 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
else if let Some(submatches) = matches.subcommand_matches("build") { else if let Some(submatches) = matches.subcommand_matches("build") {
let src = submatches.value_of("in").expect("in value"); let src = submatches.value_of("in").expect("in value");
let dest = submatches.value_of("out").expect("out value"); let dest = submatches.value_of("out").expect("out value");
build(src, dest, false)
let src = PathBuf::from(src); }
let dest = PathBuf::from(dest); else if let Some(submatches) = matches.subcommand_matches("watch") {
std::fs::create_dir_all(&dest)?; let reload_trigger = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
let do_reload = submatches.is_present("reload");
// load our book
let book_readme_path = src.join("README.md");
let (book_front, book_description) = if book_readme_path.exists() {
let contents = fs::read_to_string(&book_readme_path)?;
let (front, contents) = extract_frontmatter(&contents)?;
(front, contents)
}
else {
let content = String::new();
(None, content)
};
let book_front = FrontMatter::from_root(book_front.unwrap_or_default());
let FormatResponse { output, include_katex_css } = format_markdown(&book_description)?;
let book_description = output;
// load all our chapters
let mut chapters: Vec<Chapter> = Vec::default();
for entry in src.read_dir()? {
let entry = entry?;
let path = entry.path();
if entry.file_type()?.is_dir() {
// try to find a `README.md` file and parse it to get the chapter's title, fall back to the directory
// name if we can't do that
let chapter_name = path.file_name().map(std::ffi::OsStr::to_str).flatten().unwrap_or_default();
let index_path = path.join("README.md");
let (front, contents) = if index_path.exists() {
let contents = fs::read_to_string(&index_path)?;
let (front, contents) = extract_frontmatter(&contents)?;
let front = front.unwrap_or_default().into_front(&book_front, chapter_name, &format!("{}/index.html", chapter_name));
(front, contents)
}
else {
(ParsedFrontMatter::default().into_front(&book_front, chapter_name, &format!("{}/index.html", chapter_name)), String::new())
};
let mut chapter: Chapter = Chapter {
front,
sections: Vec::default(),
source: path.clone(),
contents,
};
for entry in path.read_dir()? {
let entry = entry?;
let path = entry.path();
if let Some("md") = path.extension().map(std::ffi::OsStr::to_str).flatten() {
let name = path.file_stem().map(std::ffi::OsStr::to_str).flatten();
if name.is_none() { continue; }
let name = name.unwrap();
if name == "README" {
continue;
}
let contents = fs::read_to_string(&path)?; if do_reload {
let (front, contents) = extract_frontmatter(&contents)?; let reload_trigger = reload_trigger.clone();
let front = front.unwrap_or_default().into_front(&book_front, name, &format!("{}/{}.html", chapter_name, name)); std::thread::spawn(move || {
chapter.sections.push(Chapter { log::info!("starting livereload service");
front, ws::listen("127.0.0.1:3456", |out| ReloadClient::new(out, reload_trigger.clone())).expect("can launch livereload service");
sections: Vec::new(), });
source: path,
contents,
});
}
}
chapters.push(chapter);
}
else if let Some("md") = path.extension().map(std::ffi::OsStr::to_str).flatten() {
let name = path.file_stem().map(std::ffi::OsStr::to_str).flatten();
if name.is_none() { continue; }
let name = name.unwrap();
if name == "README" {
continue;
}
let contents = fs::read_to_string(&path)?;
let (front, contents) = extract_frontmatter(&contents)?;
let front = front.unwrap_or_default().into_front(&book_front, name, &format!("{}/index.html", name));
chapters.push(Chapter {
front,
sections: Vec::new(),
source: path,
contents,
});
}
}
// sort all the chapters
chapters.sort_by(|a, b| a.front.url.cmp(&b.front.url));
for chapter in chapters.iter_mut() {
chapter.sections.sort_by(|a, b| a.front.url.cmp(&b.front.url));
} }
// generate our index use notify::{RecommendedWatcher, RecursiveMode, Watcher};
let index_out_path = dest.join("index.html");
let index_out = fs::File::create(&index_out_path)?;
let index_out = io::BufWriter::new(index_out);
generate_index(&book_front, book_description, include_katex_css, &chapters, index_out)?;
println!("Rendered index into `{}`", index_out_path.display());
// compile markdown and write the actual pages
let mut prev_chapter = None;
for (chapter_index, chapter) in chapters.iter().enumerate() {
// render the index
let chapter_root = dest.join(chapter.source.file_stem().map(std::ffi::OsStr::to_str).flatten().unwrap());
let out = chapter_root.join("index.html");
print!("Rendering `{}` into `{}`...", chapter.source.display(), out.display());
fs::create_dir_all(&chapter_root)?;
let outfile = fs::File::create(&out)?;
let outfile = io::BufWriter::new(outfile);
let FormatResponse { output, include_katex_css } = format_markdown(&chapter.contents)?;
let next_chapter =
if chapter.sections.len() > 0 {
Some(chapter.sections.iter().nth(0).expect("section 0 exists"))
}
else if chapter_index < chapters.len() - 1 {
Some(chapters.iter().nth(chapter_index + 1).expect("chapter n+1 exists"))
}
else {
None
};
format_page(&book_front, &chapter, &chapters, prev_chapter, next_chapter, &output, include_katex_css, outfile)?;
prev_chapter = Some(chapter);
println!(" done!"); let src = submatches.value_of("in").expect("in value");
let dest = submatches.value_of("out").expect("out value");
// now the sections build(src, dest, do_reload)?;
for (section_index, section) in chapter.sections.iter().enumerate() {
let name = section.source.file_stem().map(std::ffi::OsStr::to_str).flatten().unwrap(); let (tx, rx) = std::sync::mpsc::channel();
let out = chapter_root.join(&format!("{}.html", name)); let mut watcher: RecommendedWatcher = Watcher::new(tx, std::time::Duration::from_secs(1))?;
print!("Rendering `{}` into `{}`...", section.source.display(), out.display()); watcher.watch(src, RecursiveMode::Recursive)?;
let outfile = fs::File::create(&out)?; loop {
let outfile = io::BufWriter::new(outfile); match rx.recv() {
Ok(notify::DebouncedEvent::NoticeWrite(_)) | Ok(notify::DebouncedEvent::NoticeRemove(_)) => {},
let FormatResponse { output, include_katex_css } = format_markdown(&section.contents)?; Ok(_) => {
build(src, dest, do_reload)?;
let next_chapter = if section_index < chapter.sections.len() - 1 { reload_trigger.store(true, std::sync::atomic::Ordering::SeqCst);
Some(chapter.sections.iter().nth(section_index + 1).expect("chapter n+1 exists")) std::thread::sleep(std::time::Duration::from_millis(150));
} reload_trigger.store(false, std::sync::atomic::Ordering::SeqCst);
else if chapter_index < chapters.len() - 1 { },
Some(chapters.iter().nth(chapter_index + 1).expect("chapter n+1 exists")) Err(e) => {
log::error!("watch error: {:?}", e);
return Err(Box::from(e));
} }
else {
None
};
format_page(&book_front, &section, &chapters, prev_chapter, next_chapter, &output, include_katex_css, outfile)?;
prev_chapter = Some(section);
println!(" done!");
} }
} }
// save the assets
fs::write(dest.join("style.css"), STYLESHEET)?;
println!("Wrote {}", dest.join("style.css").display());
fs::write(dest.join("favicon.ico"), ASSET_FAVICON)?;
println!("Wrote {}", dest.join("favicon.ico").display());
fs::write(dest.join("icons.svg"), ASSET_ICONS)?;
println!("Wrote {}", dest.join("icons.svg").display());
println!("Done!");
Ok(())
} }
else { else {
cli::build_cli().print_long_help()?; cli::build_cli().print_long_help()?;

@ -50,6 +50,7 @@ body {
font-family: $font-sansserif; font-family: $font-sansserif;
margin-bottom: 0; margin-bottom: 0;
text-align: right; text-align: right;
color: #eeeeee;
} }
} }

@ -3,5 +3,5 @@
@import 'layout'; @import 'layout';
@import 'toc'; @import 'toc';
@import 'icons'; @import 'icons';
@import 'darktheme'; //@import 'darktheme';
@import 'print'; @import 'print';

@ -42,5 +42,8 @@
</ol> </ol>
</nav> </nav>
<footer><p>&copy; {{ book.pubdate|year }} {{ book.author }}</p></footer> <footer><p>&copy; {{ book.pubdate|year }} {{ book.author }}</p></footer>
{% if include_reload_script %}
{% include "reload.html" %}
{% endif %}
</body> </body>
</html> </html>

@ -99,5 +99,8 @@
{% endmatch %} {% endmatch %}
<footer><p>&copy; {{ book.pubdate|year }} {{ book.author }}</p></footer> <footer><p>&copy; {{ book.pubdate|year }} {{ book.author }}</p></footer>
</article> </article>
{% if include_reload_script %}
{% include "reload.html" %}
{% endif %}
</body> </body>
</html> </html>

@ -0,0 +1,17 @@
<script>
console.info("connecting to reload server...");
var reloadSocket = new WebSocket("ws://127.0.0.1:3456");
reloadSocket.onopen = function(event) {
console.info("connected to reload server");
};
reloadSocket.onclose = function(event) {
console.info("reload server hung up!");
};
reloadSocket.onerror = function(event) {
console.error("reload server connection error:", event);
};
reloadSocket.onmessage = function(event) {
console.info("recieved reload command");
window.location.reload();
};
</script>
Loading…
Cancel
Save