diff --git a/CHANGELOG.md b/CHANGELOG.md index 0011ef9..c9a78f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.0.7 (unreleased) + +- Sort individual tag/category pages by date +- Add extra builtin shortcode for Streamable videos +- `path` and `permalink` now end with a `/` +- Generate table of contents for each page +- Add `section` to a page Tera context if there is one +- Add `aliases` to pages for when you are changing urls but want to redirect +to the new one + ## 0.0.6 (2017-05-24) - Fix missing serialized data for sections diff --git a/Cargo.lock b/Cargo.lock index 29d1264..4bc3da3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,7 +2,7 @@ name = "gutenberg" version = "0.0.6" dependencies = [ - "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -17,13 +17,13 @@ dependencies = [ "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "slug 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "staticfile 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntect 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntect 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "tera 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", "term-painter 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "ws 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ws 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -54,8 +54,8 @@ name = "backtrace" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "dbghelp-sys 0.2.0 (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.23 (registry+https://github.com/rust-lang/crates.io-index)", @@ -65,10 +65,10 @@ dependencies = [ [[package]] name = "backtrace-sys" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -80,15 +80,23 @@ dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "base64" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bincode" -version = "0.6.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -106,11 +114,6 @@ name = "bitflags" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "byteorder" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "byteorder" version = "1.0.0" @@ -123,7 +126,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bytes" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -132,24 +135,15 @@ dependencies = [ [[package]] name = "cfg-if" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "chrono" -version = "0.2.25" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "chrono" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -170,10 +164,10 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -257,7 +251,7 @@ dependencies = [ [[package]] name = "gcc" -version = "0.3.46" +version = "0.3.50" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -272,7 +266,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "httparse" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -282,21 +276,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hyper" -version = "0.10.10" +version = "0.10.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -304,8 +297,8 @@ name = "idna" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -333,14 +326,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "conduit-mime-types 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "error 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.10.12 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "modifier 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -384,7 +377,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "matches" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -397,7 +390,7 @@ dependencies = [ [[package]] name = "mime" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -408,7 +401,7 @@ name = "miniz-sys" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -430,7 +423,7 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.7" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -485,7 +478,7 @@ name = "net2" version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.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.23 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -520,12 +513,12 @@ dependencies = [ [[package]] name = "num" -version = "0.1.37" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -533,7 +526,7 @@ name = "num-integer" version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -542,17 +535,17 @@ version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.1.37" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.4.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", @@ -560,21 +553,21 @@ dependencies = [ [[package]] name = "onig" -version = "1.2.2" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", - "onig_sys 61.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "onig_sys 63.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "onig_sys" -version = "61.3.0" +version = "63.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -591,14 +584,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "plist" -version = "0.1.3" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", - "xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -633,7 +626,7 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -664,12 +657,9 @@ version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "rustc_version" -version = "0.1.7" +name = "safemem" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "same-file" @@ -680,26 +670,11 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "semver" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "sequence_trie" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "serde" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "serde" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "serde" version = "1.0.8" @@ -731,7 +706,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -766,7 +741,7 @@ dependencies = [ "iron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "mount 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -794,18 +769,20 @@ dependencies = [ [[package]] name = "syntect" -version = "1.3.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bincode 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "onig 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "plist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "onig 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "plist 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -833,7 +810,7 @@ dependencies = [ "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "slug 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -888,7 +865,7 @@ 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)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -915,23 +892,23 @@ name = "typemap" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unsafe-any 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unicase" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unicode-bidi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -969,7 +946,7 @@ dependencies = [ [[package]] name = "unsafe-any" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -977,11 +954,11 @@ dependencies = [ [[package]] name = "url" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -994,6 +971,11 @@ name = "vec_map" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "version_check" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "void" version = "1.0.2" @@ -1030,18 +1012,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ws" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1055,7 +1037,7 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1071,21 +1053,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159" "checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76" -"checksum backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d192fd129132fbc97497c1f2ec2c2c5174e376b95f535199ef4fe0a293d33842" +"checksum backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0d842ea781ce92be2bf78a9b38883948542749640b8378b3b2f03d1fd9f1ff" "checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557" -"checksum bincode 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "55eb0b7fd108527b0c77860f75eca70214e11a8b4c6ef05148c54c05a25d48ad" +"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" +"checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e" "checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4" -"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" "checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8" "checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27" -"checksum bytes 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9edb851115d67d1f18680f9326901768a91d37875b87015518357c6ce22b553" -"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" -"checksum chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9213f7cd7c27e95c2b57c49f0e69b1ea65b27138da84a170133fd21b07659c00" +"checksum bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8b24f16593f445422331a5eed46b72f7f171f910fead4f2ea8f17e727e9c5c14" +"checksum cfg-if 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c47d456a36ebf0536a6705c83c1cbbcb9255fbc1d905a6ded104f479268a29" "checksum chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d9123be86fd2a8f627836c235ecdf331fdd067ecf7ac05aa1a68fbcf2429f056" "checksum clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b8f69e518f967224e628896b54e41ff6acfb4dcfefc5076325c36525dac900f" -"checksum cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "92278eb79412c8f75cfc89e707a1bb3a6490b68f7f2e78d15c774f30fe701122" +"checksum cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ebbb35d3dc9cd09497168f33de1acb79b265d350ab0ac34133b98f8509af1f" "checksum conduit-mime-types 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "95ca30253581af809925ef68c2641cc140d6183f43e12e0af4992d53768bd7b8" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" @@ -1096,12 +1077,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" "checksum fsevent 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfe593ebcfc76884138b25426999890b10da8e6a46d01b499d7c54c604672c38" "checksum fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a772d36c338d07a032d5375a36f15f9a7043bf0cb8ce7cee658e037c6032874" -"checksum gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)" = "181e3cebba1d663bd92eb90e2da787e10597e027eb00de8d742b260a7850948f" +"checksum gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)" = "5f837c392f2ea61cb1576eac188653df828c861b7137d74ea4a5caa89621f9e6" "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum httparse 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77f756bed9ee3a83ce98774f4155b42a31b787029013f3a7d83eca714e500e21" +"checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" "checksum humansize 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "92d211e6e70b05749dce515b47684f29a3c8c38bbbb21c50b30aff9eca1b0bd3" -"checksum hyper 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)" = "36e108e0b1fa2d17491cbaac4bc460dc0956029d10ccf83c913dd0e5db3e7f07" +"checksum hyper 0.10.12 (registry+https://github.com/rust-lang/crates.io-index)" = "0f01e4a20f5dfa5278d7762b7bdb7cab96e24378b9eca3889fbd4b5e94dc7063" "checksum idna 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2233d4940b1f19f0418c158509cd7396b8d70a5db5705ce410914dc8fa603b37" "checksum inotify 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887fcc180136e77a85e6a6128579a719027b1bab9b1c38ea4444244fe262c20c" "checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be" @@ -1113,12 +1094,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce12306c4739d86ee97c23139f3a34ddf0387bbf181bc7929d287025a8c3ef6b" "checksum libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)" = "e7eb6b826bfc1fdea7935d46556250d1799b7fe2d9f7951071f4291710665e3e" "checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" -"checksum matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efd7622e3022e1a6eaa602c4cea8912254e5582c9c692e9167714182244801b1" +"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" -"checksum mime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d69889cdc6336ed56b174514ce876c4c3dc564cc23dd872e7bca589bb2a36c8" +"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "28eaee17666671fa872e567547e8428e83308ebe5808cdf6a0e28397dbe2c726" "checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e" -"checksum mio 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6d19442734abd7d780b981c590c325680d933e99795fe1f693f0686c9ed48022" +"checksum mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9e965267d4d58496fc4f740e9861118367f13570cadf66316ed2c3f2f14d87c7" "checksum miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3e690c5df6b2f60acd45d56378981e827ff8295562fc8d34f573deb267a59cd1" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum modifier 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41f5c9112cb662acd3b204077e0de5bc66305fa8df65c8019d5adb10e9ab6e58" @@ -1126,31 +1107,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum net2 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "bc01404e7568680f1259aa5729539f221cb1e6d047a0d9053cab4be8a73b5d67" "checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79" "checksum notify 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "298d4401ff2c6cebb7f8944c90288647c89ce59029d43b439444cf1067df55e1" -"checksum num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "98b15ba84e910ea7a1973bccd3df7b31ae282bf9d8bd2897779950c9b8303d40" +"checksum num 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "2c3a3dc9f30bf824141521b30c908a859ab190b76e20435fcd89f35eb6583887" "checksum num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "ef1a4bf6f9174aa5783a9b4cc892cacd11aebad6c69ad027a0b65c6ca5f8aa37" "checksum num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d1891bd7b936f12349b7d1403761c8a0b85a18b148e9da4429d5d102c1a41e" -"checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99" -"checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167" -"checksum onig 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1f59adfdb1810e061fcd1cf5dd2792730f8226e5d23c51a52f243714cc8fe676" -"checksum onig_sys 61.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "be2eb43cab0eed1bdeec174b96967cf5636634adc2b6ba8fcc875aa3d5fc4118" +"checksum num-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "1708c0628602a98b52fad936cf3edb9a107af06e52e49fdf0707e884456a6af6" +"checksum num_cpus 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6e416ba127a4bb3ff398cb19546a8d0414f73352efe2857f4060d36f5fe5983a" +"checksum onig 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee619da9cf707b167098e84fb00f10db61d5a662d1d29b59822bcac3a81553dd" +"checksum onig_sys 63.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "531682ab45a2cd40eff91f29340dae975f25336d2b61e624adabed39e61d7fb3" "checksum pest 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e823a5967bb4cdc6d3e46f47baaf4ecfeae44413a642b74ad44e59e49c7f6" "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" -"checksum plist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0f6c4f04356eb9ad7fb1d004eb19369324daa46db1fc7ee89246a2fc224a9ce9" +"checksum plist 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e2f7e9574aabcf57bc5e9f602caabdffffa8179b0c130a039f7895fea3dbdb5" "checksum plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a6a0dc3910bc8db877ffed8e457763b317cf880df4ae19109b9f77d277cf6e0" "checksum pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab1e588ef8efd702c7ed9d2bd774db5e6f4d878bb5a1a9f371828fbdff6973" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" -"checksum redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "29dbdfd4b9df8ab31dec47c6087b7b13cbf4a776f335e4de8efba8288dda075b" +"checksum redox_syscall 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "3041aeb6000db123d2c9c751433f526e1f404b23213bd733167ab770c3989b4d" "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" -"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" +"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" -"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" "checksum sequence_trie 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c915714ca833b1d4d6b8f6a9d72a3ff632fe45b40a8d184ef79c81bec6327eed" -"checksum serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" -"checksum serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34b623917345a631dc9608d5194cc206b3fe6c3554cd1c75b937e55e285254af" "checksum serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f530d36fb84ec48fb7146936881f026cdbf4892028835fd9398475f82c1bb4" "checksum serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "10552fad5500771f3902d0c5ba187c5881942b811b7ba0d8fbbfbf84d80806d3" "checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a" @@ -1163,7 +1141,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -"checksum syntect 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24204b1f4bdd49f84e5f4b219d0bf1dc45ac2fd7fc46320ab6627b537d6d4b69" +"checksum syntect 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fed7a5661c5c42fe998c561efb12137381a4486702f41c95a1d7269f3cc8ca6a" "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" "checksum tera 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c931ade2857155d5e55115375d4d2b8a441536e2b9e44643a8b67e235e09030" "checksum term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d168af3930b369cfe245132550579d47dfd873d69470755a19c2c6568dbbd989" @@ -1176,24 +1154,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" -"checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764" -"checksum unicode-bidi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "916219eb752dd865717c9b21064401c6ee843dc91ed659c144591e0c87c56d59" +"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" +"checksum unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a6a2c4e3710edd365cd7e78383153ed739fa31af19f9172f72d3575060f5a43a" "checksum unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e28fa37426fceeb5cf8f41ee273faa7c82c47dc8fba5853402841e665fcd86ff" "checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unidecode 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2adb95ee07cd579ed18131f2d9e7a17c25a4b76022935c7f2460d2bfae89fd2" "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" -"checksum unsafe-any 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b351086021ebc264aea3ab4f94d61d889d98e5e9ec2d985d993f50133537fd3a" -"checksum url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ba8a749fb4479b043733416c244fa9d1d3af3d7c23804944651c8a448cb87e" +"checksum unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" +"checksum url 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2ba3456fbe5c0098cb877cf08b92b76c3e18e0be9e47c35b487220d377d24e" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" +"checksum version_check 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2bb3950bf29e36796dea723df1747619dd331881aefef75b7cf1c58fdd738afe" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c66c0b9792f0a765345452775f3adbd28dde9d33f30d13e5dcc5ae17cf6f3780" "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum ws 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d639380f50ad271c719cec5c9f78f09dd9d5c064b2c2231784c45f4ae70b87ae" +"checksum ws 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "89c48c53bf9dee34411a08993c10b879c36e105d609b46e25673befe3a5c1320" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec6c39eaa68382c8e31e35239402c0a9489d4141a8ceb0c716099a0b515b562" +"checksum xml-rs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b46ee689ba7a669c08a1170c2348d2516c62dc461135c9e86b2f1f476e07be4a" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" diff --git a/Cargo.toml b/Cargo.toml index 3407406..7304779 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ syntect = { version = "1", features = ["static-onig"] } chrono = "0.3" toml = "0.4" term-painter = "0.2" -base64 = "0.5" +base64 = "0.6" # Below is for the serve cmd staticfile = "0.4" diff --git a/README.md b/README.md index 8d7bf8d..d64f980 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ A front-matter has only optional variables: - category: only one category is allowed - draft: whether the post is a draft or not - template: if you want to change the template used to render that specific page +- aliases: which URL to redirect to the new: useful when you changed a page URL and don't want to 404 Even if your front-matter is empty, you will need to put the `+++`. You can also, like in the config, add your own variables in a `[extra]` table. @@ -135,6 +136,38 @@ You can also paginate section, including the index by setting the `paginate_by` This represents the number of pages for each pager of the paginator. You will need to access pages through the `paginator` object. (TODO: document that). +### Table of contents + +Each page/section will generate a table of content based on the title. It is accessible through `section.toc` and +`page.toc`. It is a list of headers that contains a `permalink`, a `title` and `children`. +Here is an example on how to make a ToC using that: + +```jinja2 + +``` + +While headers are neatly ordered in that example, you can a table of contents looking like h2, h2, h1, h3 without +any issues. + +### Taxonomies: tags and categories + +Individual tag/category pages are only supported for pages having a date. + ### Code highlighting themes Code highlighting can be turned on by setting `highlight_code = true` in `config.toml`. @@ -208,7 +241,8 @@ Gutenberg comes with a few built-in shortcodes: - YouTube: embeds a YouTube player for the given YouTube `id`. Also takes an optional `autoplay` argument that can be set to `true` if wanted - Vimeo: embeds a Vimeo player for the given Vimeo `id` -- Gist: embeds a Github gist from the `url` given. Also takes an optional `file` argument if you only want to show one of the files. +- Streamable: embeds a Streamable player for the given Streamable `id` +- Gist: embeds a Github gist from the `url` given. Also takes an optional `file` argument if you only want to show one of the files #### Defining a shortcode All shortcodes need to be in the `templates/shortcodes` folder and their files to end with `.html`. @@ -220,9 +254,11 @@ In case of shortcodes with a body, the body will be passed as the `body` variabl ## Example sites - [vincent.is](https://vincent.is): https://gitlab.com/Keats/vincent.is +- [code Result<()> { // Updating a page let current = site.pages[path].clone(); // Front matter didn't change, only content did - // so we render only the section page, not its pages + // so we render only the section page, not its content if current.meta == prev.meta { - return site.render_page(&site.pages[path]); + return site.render_page(¤t, find_parent_section(site, ¤t)); } // Front matter changed @@ -199,7 +199,7 @@ pub fn after_content_change(site: &mut Site, path: &Path) -> Result<()> { site.render_index()?; }, PageChangesNeeded::Render => { - site.render_page(&site.pages[path])?; + site.render_page(&site.pages[path], find_parent_section(site, ¤t))?; }, }; } diff --git a/src/config.rs b/src/config.rs index ec73d16..6f7fd1f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -90,12 +90,20 @@ impl Config { /// Makes a url, taking into account that the base url might have a trailing slash pub fn make_permalink(&self, path: &str) -> String { - if self.base_url.ends_with('/') && path.starts_with('/') { - format!("{}{}", self.base_url, &path[1..]) + let trailing_bit = if path.ends_with('/') { "" } else { "/" }; + + // Index section with a base url that has a trailing slash + if self.base_url.ends_with('/') && path == "/" { + self.base_url.clone() + } else if path == "/" { + // index section with a base url that doesn't have a trailing slash + format!("{}/", self.base_url) + } else if self.base_url.ends_with('/') && path.starts_with('/') { + format!("{}{}{}", self.base_url, &path[1..], trailing_bit) } else if self.base_url.ends_with('/') { - format!("{}{}", self.base_url, path) + format!("{}{}{}", self.base_url, path, trailing_bit) } else { - format!("{}/{}", self.base_url, path) + format!("{}/{}{}", self.base_url, path, trailing_bit) } } } @@ -192,13 +200,13 @@ hello = "world" fn can_make_url_with_non_trailing_slash_base_url() { let mut config = Config::default(); config.base_url = "http://vincent.is".to_string(); - assert_eq!(config.make_permalink("hello"), "http://vincent.is/hello"); + assert_eq!(config.make_permalink("hello"), "http://vincent.is/hello/"); } #[test] fn can_make_url_with_trailing_slash_path() { let mut config = Config::default(); config.base_url = "http://vincent.is/".to_string(); - assert_eq!(config.make_permalink("/hello"), "http://vincent.is/hello"); + assert_eq!(config.make_permalink("/hello"), "http://vincent.is/hello/"); } } diff --git a/src/content/mod.rs b/src/content/mod.rs index b7f9fd7..1aa8521 100644 --- a/src/content/mod.rs +++ b/src/content/mod.rs @@ -5,10 +5,12 @@ mod sorting; mod utils; mod file_info; mod taxonomies; +mod table_of_contents; pub use self::page::{Page}; pub use self::section::{Section}; pub use self::pagination::{Paginator, Pager}; pub use self::sorting::{SortBy, sort_pages, populate_previous_and_next_pages}; pub use self::taxonomies::{Taxonomy, TaxonomyItem}; +pub use self::table_of_contents::{TempHeader, Header, make_table_of_contents}; diff --git a/src/content/page.rs b/src/content/page.rs index 667b88c..390044e 100644 --- a/src/content/page.rs +++ b/src/content/page.rs @@ -16,6 +16,7 @@ use rendering::context::Context; use fs::{read_file}; use content::utils::{find_related_assets, get_reading_analytics}; use content::file_info::FileInfo; +use content::{Header, Section}; #[derive(Clone, Debug, PartialEq)] @@ -45,6 +46,8 @@ pub struct Page { pub previous: Option>, /// The next page, by whatever sorting is used for the index/section pub next: Option>, + /// Toc made from the headers of the markdown file + pub toc: Vec
, } @@ -64,6 +67,7 @@ impl Page { summary: None, previous: None, next: None, + toc: vec![], } } @@ -91,6 +95,9 @@ impl Page { format!("{}/{}", page.file.components.join("/"), page.slug) }; } + if !page.path.ends_with('/') { + page.path = format!("{}/", page.path); + } page.permalink = config.make_permalink(&page.path); Ok(page) @@ -114,12 +121,14 @@ impl Page { /// We need access to all pages url to render links relative to content /// so that can't happen at the same time as parsing pub fn render_markdown(&mut self, permalinks: &HashMap, tera: &Tera, config: &Config, anchor_insert: InsertAnchor) -> Result<()> { - let context = Context::new(tera, config, permalinks, anchor_insert); - self.content = markdown_to_html(&self.raw_content, &context)?; + let context = Context::new(tera, config, &self.permalink, permalinks, anchor_insert); + let res = markdown_to_html(&self.raw_content, &context)?; + self.content = res.0; + self.toc = res.1; if self.raw_content.contains("") { self.summary = Some({ let summary = self.raw_content.splitn(2, "").collect::>()[0]; - markdown_to_html(summary, &context)? + markdown_to_html(summary, &context)?.0 }) } @@ -127,7 +136,7 @@ impl Page { } /// Renders the page using the default layout, unless specified in front-matter - pub fn render_html(&self, tera: &Tera, config: &Config) -> Result { + pub fn render_html(&self, tera: &Tera, config: &Config, section: Option<&Section>) -> Result { let tpl_name = match self.meta.template { Some(ref l) => l.to_string(), None => "page.html".to_string() @@ -138,6 +147,7 @@ impl Page { context.add("page", self); context.add("current_url", &self.permalink); context.add("current_path", &self.path); + context.add("section", §ion); tera.render(&tpl_name, &context) .chain_err(|| format!("Failed to render page '{}'", self.file.path.display())) @@ -158,13 +168,14 @@ impl Default for Page { summary: None, previous: None, next: None, + toc: vec![], } } } impl ser::Serialize for Page { fn serialize(&self, serializer: S) -> StdResult where S: ser::Serializer { - let mut state = serializer.serialize_struct("page", 15)?; + let mut state = serializer.serialize_struct("page", 16)?; state.serialize_field("content", &self.content)?; state.serialize_field("title", &self.meta.title)?; state.serialize_field("description", &self.meta.description)?; @@ -181,6 +192,7 @@ impl ser::Serialize for Page { state.serialize_field("reading_time", &reading_time)?; state.serialize_field("previous", &self.previous)?; state.serialize_field("next", &self.next)?; + state.serialize_field("toc", &self.toc)?; state.end() } } @@ -231,8 +243,8 @@ Hello world"#; let res = Page::parse(Path::new("content/posts/intro/start.md"), content, &conf); assert!(res.is_ok()); let page = res.unwrap(); - assert_eq!(page.path, "posts/intro/hello-world"); - assert_eq!(page.permalink, "http://hello.com/posts/intro/hello-world"); + assert_eq!(page.path, "posts/intro/hello-world/"); + assert_eq!(page.permalink, "http://hello.com/posts/intro/hello-world/"); } #[test] @@ -246,7 +258,7 @@ Hello world"#; let res = Page::parse(Path::new("start.md"), content, &config); assert!(res.is_ok()); let page = res.unwrap(); - assert_eq!(page.path, "hello-world"); + assert_eq!(page.path, "hello-world/"); assert_eq!(page.permalink, config.make_permalink("hello-world")); } diff --git a/src/content/pagination.rs b/src/content/pagination.rs index 1270175..0c3159b 100644 --- a/src/content/pagination.rs +++ b/src/content/pagination.rs @@ -74,17 +74,18 @@ impl<'a> Paginator<'a> { continue; } - let page_path = format!("{}/{}", paginate_path, index + 1); - let permalink = if section.permalink.ends_with('/') { - format!("{}{}", section.permalink, page_path) + let page_path = format!("{}/{}/", paginate_path, index + 1); + let permalink = format!("{}{}", section.permalink, page_path); + let pager_path = if section.is_index() { + page_path } else { - format!("{}/{}", section.permalink, page_path) + format!("{}{}", section.path, page_path) }; pagers.push(Pager::new( index + 1, page.clone(), permalink, - if section.is_index() { page_path } else { format!("{}/{}", section.path, page_path) } + pager_path, )); } @@ -94,10 +95,10 @@ impl<'a> Paginator<'a> { } Paginator { - all_pages: all_pages, - pagers: pagers, - paginate_by: paginate_by, - section: section, + all_pages, + pagers, + paginate_by, + section, } } @@ -164,11 +165,11 @@ mod tests { f.paginate_path = Some("page".to_string()); let mut s = Section::new("content/_index.md", f); if !is_index { - s.path = "posts".to_string(); - s.permalink = "https://vincent.is/posts".to_string(); + s.path = "posts/".to_string(); + s.permalink = "https://vincent.is/posts/".to_string(); s.file.components = vec!["posts".to_string()]; } else { - s.permalink = "https://vincent.is".to_string(); + s.permalink = "https://vincent.is/".to_string(); } s } @@ -186,13 +187,13 @@ mod tests { assert_eq!(paginator.pagers[0].index, 1); assert_eq!(paginator.pagers[0].pages.len(), 2); - assert_eq!(paginator.pagers[0].permalink, "https://vincent.is/posts"); - assert_eq!(paginator.pagers[0].path, "posts"); + assert_eq!(paginator.pagers[0].permalink, "https://vincent.is/posts/"); + assert_eq!(paginator.pagers[0].path, "posts/"); assert_eq!(paginator.pagers[1].index, 2); assert_eq!(paginator.pagers[1].pages.len(), 1); - assert_eq!(paginator.pagers[1].permalink, "https://vincent.is/posts/page/2"); - assert_eq!(paginator.pagers[1].path, "posts/page/2"); + assert_eq!(paginator.pagers[1].permalink, "https://vincent.is/posts/page/2/"); + assert_eq!(paginator.pagers[1].path, "posts/page/2/"); } #[test] @@ -208,13 +209,13 @@ mod tests { assert_eq!(paginator.pagers[0].index, 1); assert_eq!(paginator.pagers[0].pages.len(), 2); - assert_eq!(paginator.pagers[0].permalink, "https://vincent.is"); + assert_eq!(paginator.pagers[0].permalink, "https://vincent.is/"); assert_eq!(paginator.pagers[0].path, ""); assert_eq!(paginator.pagers[1].index, 2); assert_eq!(paginator.pagers[1].pages.len(), 1); - assert_eq!(paginator.pagers[1].permalink, "https://vincent.is/page/2"); - assert_eq!(paginator.pagers[1].path, "page/2"); + assert_eq!(paginator.pagers[1].permalink, "https://vincent.is/page/2/"); + assert_eq!(paginator.pagers[1].path, "page/2/"); } #[test] @@ -230,18 +231,18 @@ mod tests { let context = paginator.build_paginator_context(&paginator.pagers[0]); assert_eq!(context["paginate_by"], to_value(2).unwrap()); - assert_eq!(context["first"], to_value("https://vincent.is/posts").unwrap()); - assert_eq!(context["last"], to_value("https://vincent.is/posts/page/2").unwrap()); + assert_eq!(context["first"], to_value("https://vincent.is/posts/").unwrap()); + assert_eq!(context["last"], to_value("https://vincent.is/posts/page/2/").unwrap()); assert_eq!(context["previous"], to_value::>(None).unwrap()); - assert_eq!(context["next"], to_value("https://vincent.is/posts/page/2").unwrap()); + assert_eq!(context["next"], to_value("https://vincent.is/posts/page/2/").unwrap()); assert_eq!(context["current_index"], to_value(1).unwrap()); let context = paginator.build_paginator_context(&paginator.pagers[1]); assert_eq!(context["paginate_by"], to_value(2).unwrap()); - assert_eq!(context["first"], to_value("https://vincent.is/posts").unwrap()); - assert_eq!(context["last"], to_value("https://vincent.is/posts/page/2").unwrap()); + assert_eq!(context["first"], to_value("https://vincent.is/posts/").unwrap()); + assert_eq!(context["last"], to_value("https://vincent.is/posts/page/2/").unwrap()); assert_eq!(context["next"], to_value::>(None).unwrap()); - assert_eq!(context["previous"], to_value("https://vincent.is/posts").unwrap()); + assert_eq!(context["previous"], to_value("https://vincent.is/posts/").unwrap()); assert_eq!(context["current_index"], to_value(2).unwrap()); } } diff --git a/src/content/section.rs b/src/content/section.rs index 4468bce..5f21b4e 100644 --- a/src/content/section.rs +++ b/src/content/section.rs @@ -13,6 +13,7 @@ use rendering::markdown::markdown_to_html; use rendering::context::Context; use content::Page; use content::file_info::FileInfo; +use content::Header; #[derive(Clone, Debug, PartialEq)] @@ -35,6 +36,8 @@ pub struct Section { pub ignored_pages: Vec, /// All direct subsections pub subsections: Vec
, + /// Toc made from the headers of the markdown file + pub toc: Vec
, } impl Section { @@ -51,6 +54,7 @@ impl Section { pages: vec![], ignored_pages: vec![], subsections: vec![], + toc: vec![], } } @@ -58,7 +62,7 @@ impl Section { let (meta, content) = split_section_content(file_path, content)?; let mut section = Section::new(file_path, meta); section.raw_content = content.clone(); - section.path = section.file.components.join("/"); + section.path = format!("{}/", section.file.components.join("/")); section.permalink = config.make_permalink(§ion.path); Ok(section) } @@ -86,8 +90,10 @@ impl Section { /// We need access to all pages url to render links relative to content /// so that can't happen at the same time as parsing pub fn render_markdown(&mut self, permalinks: &HashMap, tera: &Tera, config: &Config) -> Result<()> { - let context = Context::new(tera, config, permalinks, self.meta.insert_anchor.unwrap()); - self.content = markdown_to_html(&self.raw_content, &context)?; + let context = Context::new(tera, config, &self.permalink, permalinks, self.meta.insert_anchor.unwrap()); + let res = markdown_to_html(&self.raw_content, &context)?; + self.content = res.0; + self.toc = res.1; Ok(()) } @@ -129,7 +135,7 @@ impl Section { impl ser::Serialize for Section { fn serialize(&self, serializer: S) -> StdResult where S: ser::Serializer { - let mut state = serializer.serialize_struct("section", 9)?; + let mut state = serializer.serialize_struct("section", 10)?; state.serialize_field("content", &self.content)?; state.serialize_field("permalink", &self.permalink)?; state.serialize_field("title", &self.meta.title)?; @@ -139,6 +145,7 @@ impl ser::Serialize for Section { state.serialize_field("permalink", &self.permalink)?; state.serialize_field("pages", &self.pages)?; state.serialize_field("subsections", &self.subsections)?; + state.serialize_field("toc", &self.toc)?; state.end() } } @@ -156,6 +163,7 @@ impl Default for Section { pages: vec![], ignored_pages: vec![], subsections: vec![], + toc: vec![], } } } diff --git a/src/content/table_of_contents.rs b/src/content/table_of_contents.rs new file mode 100644 index 0000000..dcd9ba8 --- /dev/null +++ b/src/content/table_of_contents.rs @@ -0,0 +1,166 @@ + +#[derive(Debug, PartialEq, Clone, Serialize)] +pub struct Header { + #[serde(skip_serializing)] + pub level: i32, + pub id: String, + pub title: String, + pub permalink: String, + pub children: Vec
, +} + +impl Header { + pub fn from_temp_header(tmp: &TempHeader, children: Vec
) -> Header { + Header { + level: tmp.level, + id: tmp.id.clone(), + title: tmp.title.clone(), + permalink: tmp.permalink.clone(), + children, + } + } +} + +/// Used in +#[derive(Debug, PartialEq, Clone)] +pub struct TempHeader { + pub level: i32, + pub id: String, + pub permalink: String, + pub title: String, +} + +impl TempHeader { + pub fn new(level: i32) -> TempHeader { + TempHeader { + level, + id: String::new(), + permalink: String::new(), + title: String::new(), + } + } +} + +impl Default for TempHeader { + fn default() -> Self { + TempHeader::new(0) + } +} + + +/// Recursively finds children of a header +fn find_children(parent_level: i32, start_at: usize, temp_headers: &[TempHeader]) -> (usize, Vec
) { + let mut headers = vec![]; + + let mut start_at = start_at; + // If we have children, we will need to skip some headers since they are already inserted + let mut to_skip = 0; + + for h in &temp_headers[start_at..] { + // stop when we encounter a title at the same level or higher + // than the parent one. Here a lower integer is considered higher as we are talking about + // HTML headers: h1, h2, h3, h4, h5 and h6 + if h.level <= parent_level { + return (start_at, headers); + } + + // Do we need to skip some headers? + if to_skip > 0 { + to_skip -= 1; + continue; + } + + let (end, children) = find_children(h.level, start_at + 1, &temp_headers); + headers.push(Header::from_temp_header(h, children)); + + // we didn't find any children + if end == start_at { + start_at += 1; + to_skip = 0; + } else { + // calculates how many we need to skip. Since the find_children start_at starts at 1, + // we need to remove 1 to ensure correctness + to_skip = end - start_at - 1; + start_at = end; + } + + // we don't want to index out of bounds + if start_at + 1 > temp_headers.len() { + return (start_at, headers); + } + } + + (start_at, headers) +} + + +/// Converts the flat temp headers into a nested set of headers +/// representing the hierarchy +pub fn make_table_of_contents(temp_headers: Vec) -> Vec
{ + let mut toc = vec![]; + let mut start_idx = 0; + for (i, h) in temp_headers.iter().enumerate() { + if i < start_idx { + continue; + } + let (end_idx, children) = find_children(h.level, start_idx + 1, &temp_headers); + start_idx = end_idx; + toc.push(Header::from_temp_header(h, children)); + } + + toc +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn can_make_basic_toc() { + let input = vec![ + TempHeader::new(1), + TempHeader::new(1), + TempHeader::new(1), + ]; + let toc = make_table_of_contents(input); + assert_eq!(toc.len(), 3); + } + + #[test] + fn can_make_more_complex_toc() { + let input = vec![ + TempHeader::new(1), + TempHeader::new(2), + TempHeader::new(2), + TempHeader::new(3), + TempHeader::new(2), + TempHeader::new(1), + TempHeader::new(2), + TempHeader::new(3), + TempHeader::new(3), + ]; + let toc = make_table_of_contents(input); + assert_eq!(toc.len(), 2); + assert_eq!(toc[0].children.len(), 3); + assert_eq!(toc[1].children.len(), 1); + assert_eq!(toc[0].children[1].children.len(), 1); + assert_eq!(toc[1].children[0].children.len(), 2); + } + + #[test] + fn can_make_messy_toc() { + let input = vec![ + TempHeader::new(3), + TempHeader::new(2), + TempHeader::new(2), + TempHeader::new(3), + TempHeader::new(2), + TempHeader::new(1), + TempHeader::new(4), + ]; + let toc = make_table_of_contents(input); + assert_eq!(toc.len(), 5); + assert_eq!(toc[2].children.len(), 1); + assert_eq!(toc[4].children.len(), 1); + } +} diff --git a/src/content/taxonomies.rs b/src/content/taxonomies.rs index 1f507ae..efef01f 100644 --- a/src/content/taxonomies.rs +++ b/src/content/taxonomies.rs @@ -6,6 +6,7 @@ use tera::{Context, Tera}; use config::Config; use errors::{Result, ResultExt}; use content::Page; +use content::sorting::{SortBy, sort_pages}; #[derive(Debug, Copy, Clone, PartialEq)] @@ -24,10 +25,12 @@ pub struct TaxonomyItem { impl TaxonomyItem { pub fn new(name: &str, pages: Vec) -> TaxonomyItem { + // We shouldn't have any pages without dates there + let (sorted_pages, _) = sort_pages(pages, SortBy::Date); TaxonomyItem { name: name.to_string(), slug: slugify(name), - pages, + pages: sorted_pages, } } } @@ -48,6 +51,14 @@ impl Taxonomy { // Find all the tags/categories first for page in all_pages { + // Don't consider pages without pages for tags/categories as that's the only thing + // we can sort pages with across sections + // If anyone sees that comment and wonder wtf, please open an issue as I can't think of + // usecases other than blog posts for built-in taxonomies + if page.meta.date.is_none() { + continue; + } + if let Some(ref category) = page.meta.category { categories .entry(category.to_string()) @@ -109,10 +120,6 @@ impl Taxonomy { let name = self.get_single_item_name(); let mut context = Context::new(); context.add("config", config); - // TODO: how to sort categories and tag content? - // Have a setting in config.toml or a _category.md and _tag.md - // The latter is more in line with the rest of Gutenberg but order ordering - // doesn't really work across sections. context.add(&name, item); context.add("current_url", &config.make_permalink(&format!("{}/{}", name, item.slug))); context.add("current_path", &format!("/{}/{}", name, item.slug)); diff --git a/src/front_matter/page.rs b/src/front_matter/page.rs index 9613c8f..67a1c9e 100644 --- a/src/front_matter/page.rs +++ b/src/front_matter/page.rs @@ -28,6 +28,9 @@ pub struct PageFrontMatter { pub category: Option, /// Integer to use to order content. Lowest is at the bottom, highest first pub order: Option, + /// All aliases for that page. Gutenberg will create HTML templates that will + #[serde(skip_serializing)] + pub aliases: Option>, /// Specify a template different from `page.html` to use for that page #[serde(skip_serializing)] pub template: Option, @@ -100,6 +103,7 @@ impl Default for PageFrontMatter { tags: None, category: None, order: None, + aliases: None, template: None, extra: None, } diff --git a/src/rendering/context.rs b/src/rendering/context.rs index d7f77c4..63eafbd 100644 --- a/src/rendering/context.rs +++ b/src/rendering/context.rs @@ -12,14 +12,22 @@ pub struct Context<'a> { pub tera: &'a Tera, pub highlight_code: bool, pub highlight_theme: String, + pub current_page_permalink: String, pub permalinks: &'a HashMap, pub insert_anchor: InsertAnchor, } impl<'a> Context<'a> { - pub fn new(tera: &'a Tera, config: &'a Config, permalinks: &'a HashMap, insert_anchor: InsertAnchor) -> Context<'a> { + pub fn new( + tera: &'a Tera, + config: &'a Config, + current_page_permalink: &str, + permalinks: &'a HashMap, + insert_anchor: InsertAnchor, + ) -> Context<'a> { Context { tera, + current_page_permalink: current_page_permalink.to_string(), permalinks, insert_anchor, highlight_code: config.highlight_code.unwrap(), diff --git a/src/rendering/markdown.rs b/src/rendering/markdown.rs index 44172a4..19826ff 100644 --- a/src/rendering/markdown.rs +++ b/src/rendering/markdown.rs @@ -16,6 +16,7 @@ use front_matter::InsertAnchor; use rendering::context::Context; use rendering::highlighting::THEME_SET; use rendering::short_code::{ShortCode, parse_shortcode, render_simple_shortcode}; +use content::{TempHeader, Header, make_table_of_contents}; // We need to put those in a struct to impl Send and sync pub struct Setup { @@ -37,7 +38,7 @@ lazy_static!{ } -pub fn markdown_to_html(content: &str, context: &Context) -> Result { +pub fn markdown_to_html(content: &str, context: &Context) -> Result<(String, Vec
)> { // We try to be smart about highlighting code as it can be time-consuming // If the global config disables it, then we do nothing. However, // if we see a code block in the content, we assume that this page needs @@ -62,9 +63,10 @@ pub fn markdown_to_html(content: &str, context: &Context) -> Result { // pulldown_cmark can send several text events for a title if there are markdown // specific characters like `!` in them. We only want to insert the anchor the first time let mut header_already_inserted = false; + let mut anchors: Vec = vec![]; + // the rendered html let mut html = String::new(); - let mut anchors: Vec = vec![]; // We might have cases where the slug is already present in our list of anchor // for example an article could have several titles named Example @@ -83,6 +85,11 @@ pub fn markdown_to_html(content: &str, context: &Context) -> Result { find_anchor(anchors, name, level + 1) } + let mut headers = vec![]; + // Defaults to a 0 level so not a real header + // It should be an Option ideally but not worth the hassle to update + let mut temp_header = TempHeader::default(); + let mut opts = Options::empty(); opts.insert(OPTION_ENABLE_TABLES); opts.insert(OPTION_ENABLE_FOOTNOTES); @@ -158,6 +165,13 @@ pub fn markdown_to_html(content: &str, context: &Context) -> Result { } else { String::new() }; + // update the header and add it to the list + temp_header.id = id.clone(); + temp_header.title = text.clone().into_owned(); + temp_header.permalink = format!("{}#{}", context.current_page_permalink, id); + headers.push(temp_header.clone()); + temp_header = TempHeader::default(); + header_already_inserted = true; let event = match context.insert_anchor { InsertAnchor::Left => Event::Html(Owned(format!(r#"id="{}">{}{}"#, id, anchor_link, text))), @@ -230,6 +244,7 @@ pub fn markdown_to_html(content: &str, context: &Context) -> Result { }, Event::Start(Tag::Header(num)) => { in_header = true; + temp_header = TempHeader::new(num); // ugly eh Event::Html(Owned(format!(" Result { match error { Some(e) => Err(e), - None => Ok(html.replace("

", "")), + None => Ok((html.replace("

", ""), make_table_of_contents(headers))), } } @@ -287,9 +302,9 @@ mod tests { let tera_ctx = Tera::default(); let permalinks_ctx = HashMap::new(); let config_ctx = Config::default(); - let context = Context::new(&tera_ctx, &config_ctx, &permalinks_ctx, InsertAnchor::None); + let context = Context::new(&tera_ctx, &config_ctx, "", &permalinks_ctx, InsertAnchor::None); let res = markdown_to_html("hello", &context).unwrap(); - assert_eq!(res, "

hello

\n"); + assert_eq!(res.0, "

hello

\n"); } #[test] @@ -297,11 +312,11 @@ mod tests { let tera_ctx = Tera::default(); let permalinks_ctx = HashMap::new(); let config_ctx = Config::default(); - let mut context = Context::new(&tera_ctx, &config_ctx, &permalinks_ctx, InsertAnchor::None); + let mut context = Context::new(&tera_ctx, &config_ctx, "", &permalinks_ctx, InsertAnchor::None); context.highlight_code = false; let res = markdown_to_html("```\n$ gutenberg server\n```", &context).unwrap(); assert_eq!( - res, + res.0, "
$ gutenberg server\n
\n" ); } @@ -311,10 +326,10 @@ mod tests { let tera_ctx = Tera::default(); let permalinks_ctx = HashMap::new(); let config_ctx = Config::default(); - let context = Context::new(&tera_ctx, &config_ctx, &permalinks_ctx, InsertAnchor::None); + let context = Context::new(&tera_ctx, &config_ctx, "", &permalinks_ctx, InsertAnchor::None); let res = markdown_to_html("```\n$ gutenberg server\n$ ping\n```", &context).unwrap(); assert_eq!( - res, + res.0, "
\n$ gutenberg server\n$ ping\n
" ); } @@ -324,10 +339,10 @@ mod tests { let tera_ctx = Tera::default(); let permalinks_ctx = HashMap::new(); let config_ctx = Config::default(); - let context = Context::new(&tera_ctx, &config_ctx, &permalinks_ctx, InsertAnchor::None); + let context = Context::new(&tera_ctx, &config_ctx, "", &permalinks_ctx, InsertAnchor::None); let res = markdown_to_html("```python\nlist.append(1)\n```", &context).unwrap(); assert_eq!( - res, + res.0, "
\nlist.append(1)\n
" ); } @@ -337,11 +352,11 @@ mod tests { let tera_ctx = Tera::default(); let permalinks_ctx = HashMap::new(); let config_ctx = Config::default(); - let context = Context::new(&tera_ctx, &config_ctx, &permalinks_ctx, InsertAnchor::None); + let context = Context::new(&tera_ctx, &config_ctx, "", &permalinks_ctx, InsertAnchor::None); let res = markdown_to_html("```yolo\nlist.append(1)\n```", &context).unwrap(); // defaults to plain text assert_eq!( - res, + res.0, "
\nlist.append(1)\n
" ); } @@ -350,21 +365,21 @@ mod tests { fn can_render_shortcode() { let permalinks_ctx = HashMap::new(); let config_ctx = Config::default(); - let context = Context::new(&GUTENBERG_TERA, &config_ctx, &permalinks_ctx, InsertAnchor::None); + let context = Context::new(&GUTENBERG_TERA, &config_ctx, "", &permalinks_ctx, InsertAnchor::None); let res = markdown_to_html(r#" Hello {{ youtube(id="ub36ffWAqgQ") }} "#, &context).unwrap(); - assert!(res.contains("

Hello

\n
")); - assert!(res.contains(r#" +
diff --git a/src/templates/mod.rs b/src/templates/mod.rs index ac8d272..53f1cbe 100644 --- a/src/templates/mod.rs +++ b/src/templates/mod.rs @@ -17,6 +17,7 @@ lazy_static! { ("shortcodes/youtube.html", include_str!("builtins/shortcodes/youtube.html")), ("shortcodes/vimeo.html", include_str!("builtins/shortcodes/vimeo.html")), ("shortcodes/gist.html", include_str!("builtins/shortcodes/gist.html")), + ("shortcodes/streamable.html", include_str!("builtins/shortcodes/streamable.html")), ("internal/alias.html", include_str!("builtins/internal/alias.html")), ]).unwrap(); diff --git a/sublime_syntaxes/Elm.tmLanguage b/sublime_syntaxes/Elm.tmLanguage index ea36395..6bbbca9 160000 --- a/sublime_syntaxes/Elm.tmLanguage +++ b/sublime_syntaxes/Elm.tmLanguage @@ -1 +1 @@ -Subproject commit ea36395b5191cfac1cef60e44c4ec1eacf8b648c +Subproject commit 6bbbca9ccd0bd3131575217b3780fa59d059fcba diff --git a/sublime_syntaxes/Julia-sublime b/sublime_syntaxes/Julia-sublime index da05d94..ea597da 160000 --- a/sublime_syntaxes/Julia-sublime +++ b/sublime_syntaxes/Julia-sublime @@ -1 +1 @@ -Subproject commit da05d942464943c27884e174a580fc5f879b0b60 +Subproject commit ea597da94a17928019e05c3a177f1e972484eec0 diff --git a/sublime_syntaxes/Packages b/sublime_syntaxes/Packages index a10df6e..303816f 160000 --- a/sublime_syntaxes/Packages +++ b/sublime_syntaxes/Packages @@ -1 +1 @@ -Subproject commit a10df6e24f90f5cd532a242c1be05416f846db02 +Subproject commit 303816f09fe5534487c010082bcd96c408823671 diff --git a/sublime_syntaxes/newlines.packdump b/sublime_syntaxes/newlines.packdump index c0c92a9..6a81f70 100644 Binary files a/sublime_syntaxes/newlines.packdump and b/sublime_syntaxes/newlines.packdump differ diff --git a/sublime_syntaxes/nonewlines.packdump b/sublime_syntaxes/nonewlines.packdump index 38a427f..e756137 100644 Binary files a/sublime_syntaxes/nonewlines.packdump and b/sublime_syntaxes/nonewlines.packdump differ diff --git a/sublime_themes/all.themedump b/sublime_themes/all.themedump index 3af3d02..a831c73 100644 Binary files a/sublime_themes/all.themedump and b/sublime_themes/all.themedump differ diff --git a/test_site/config.toml b/test_site/config.toml index ba0629c..4d058c3 100644 --- a/test_site/config.toml +++ b/test_site/config.toml @@ -2,6 +2,5 @@ title = "My site" base_url = "https://replace-this-with-your-url.com" highlight_code = true - [extra.author] name = "Vincent Prouillet" diff --git a/test_site/content/posts/fixed-slug.md b/test_site/content/posts/fixed-slug.md index f28cfc3..ccba64a 100644 --- a/test_site/content/posts/fixed-slug.md +++ b/test_site/content/posts/fixed-slug.md @@ -3,6 +3,7 @@ title = "Fixed slug" description = "" slug = "something-else" date = "2017-01-01" +aliases = ["/an-old-url/old-page"] +++ A simple page with a slug defined diff --git a/test_site/content/posts/simple.md b/test_site/content/posts/simple.md index ee8367f..2d4e612 100644 --- a/test_site/content/posts/simple.md +++ b/test_site/content/posts/simple.md @@ -11,4 +11,6 @@ A simple page {{ vimeo(id="210073083") }} +{{ streamable(id="c0ic") }} + {{ gist(url="https://gist.github.com/Keats/32d26f699dcc13ebd41b") }} diff --git a/test_site/templates/page.html b/test_site/templates/page.html index 25e0455..25bdbf8 100644 --- a/test_site/templates/page.html +++ b/test_site/templates/page.html @@ -1,6 +1,7 @@ {% extends "index.html" %} {% block content %} + {% if section %}Section:{{ section.permalink }}{% endif %} {{ page.content | safe }} {% if page.previous %}Previous article: {{ page.previous.permalink }}{% endif %} diff --git a/tests/site.rs b/tests/site.rs index d1d6598..d247fd5 100644 --- a/tests/site.rs +++ b/tests/site.rs @@ -28,7 +28,7 @@ fn can_parse_site() { // Make sure the page with a url doesn't have any sections let url_post = &site.pages[&posts_path.join("fixed-url.md")]; - assert_eq!(url_post.path, "a-fixed-url"); + assert_eq!(url_post.path, "a-fixed-url/"); // Make sure the article in a folder with only asset doesn't get counted as a section let asset_folder_post = &site.pages[&posts_path.join("with-assets").join("index.md")]; @@ -118,6 +118,10 @@ fn can_build_site_without_live_reload() { assert!(file_exists!(public, "posts/tutorials/programming/index.html")); // TODO: add assertion for syntax highlighting + // aliases work + assert!(file_exists!(public, "an-old-url/old-page/index.html")); + assert!(file_contains!(public, "an-old-url/old-page/index.html", "something-else")); + // No tags or categories assert_eq!(file_exists!(public, "categories/index.html"), false); assert_eq!(file_exists!(public, "tags/index.html"), false); @@ -126,8 +130,11 @@ fn can_build_site_without_live_reload() { assert_eq!(file_contains!(public, "index.html", "/livereload.js?port=1112&mindelay=10"), false); // Both pages and sections are in the sitemap - assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/posts/simple")); - assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/posts")); + assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/posts/simple/")); + assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/posts/")); + + // section is in the page context + assert!(file_contains!(public, "posts/python/index.html", "Section:")); } #[test] @@ -216,8 +223,8 @@ fn can_build_site_with_categories() { assert_eq!(file_exists!(public, "tags/index.html"), false); // Categories are in the sitemap - assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/categories")); - assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/categories/a")); + assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/categories/")); + assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/categories/a/")); } #[test] @@ -268,8 +275,8 @@ fn can_build_site_with_tags() { // Categories aren't assert_eq!(file_exists!(public, "categories/index.html"), false); // Tags are in the sitemap - assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/tags")); - assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/tags/tag-with-space")); + assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/tags/")); + assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/tags/tag-with-space/")); } #[test] @@ -327,14 +334,14 @@ fn can_build_site_with_pagination_for_section() { assert!(file_contains!( public, "posts/page/1/index.html", - "http-equiv=\"refresh\" content=\"0;url=https://replace-this-with-your-url.com/posts\"" + "http-equiv=\"refresh\" content=\"0;url=https://replace-this-with-your-url.com/posts/\"" )); assert!(file_contains!(public, "posts/index.html", "Num pagers: 3")); assert!(file_contains!(public, "posts/index.html", "Page size: 2")); assert!(file_contains!(public, "posts/index.html", "Current index: 1")); assert!(file_contains!(public, "posts/index.html", "has_next")); - assert!(file_contains!(public, "posts/index.html", "First: https://replace-this-with-your-url.com/posts")); - assert!(file_contains!(public, "posts/index.html", "Last: https://replace-this-with-your-url.com/posts/page/3")); + assert!(file_contains!(public, "posts/index.html", "First: https://replace-this-with-your-url.com/posts/")); + assert!(file_contains!(public, "posts/index.html", "Last: https://replace-this-with-your-url.com/posts/page/3/")); assert_eq!(file_contains!(public, "posts/index.html", "has_prev"), false); assert!(file_exists!(public, "posts/page/2/index.html")); @@ -343,8 +350,8 @@ fn can_build_site_with_pagination_for_section() { assert!(file_contains!(public, "posts/page/2/index.html", "Current index: 2")); assert!(file_contains!(public, "posts/page/2/index.html", "has_prev")); assert!(file_contains!(public, "posts/page/2/index.html", "has_next")); - assert!(file_contains!(public, "posts/page/2/index.html", "First: https://replace-this-with-your-url.com/posts")); - assert!(file_contains!(public, "posts/page/2/index.html", "Last: https://replace-this-with-your-url.com/posts/page/3")); + assert!(file_contains!(public, "posts/page/2/index.html", "First: https://replace-this-with-your-url.com/posts/")); + assert!(file_contains!(public, "posts/page/2/index.html", "Last: https://replace-this-with-your-url.com/posts/page/3/")); } #[test]