Merge pull request #77 from Keats/next

v0.0.7
This commit is contained in:
Vincent Prouillet 2017-06-18 20:04:28 +09:00 committed by GitHub
commit 264d1e3742
31 changed files with 615 additions and 264 deletions

View file

@ -1,5 +1,15 @@
# Changelog # 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) ## 0.0.6 (2017-05-24)
- Fix missing serialized data for sections - Fix missing serialized data for sections

261
Cargo.lock generated
View file

@ -2,7 +2,7 @@
name = "gutenberg" name = "gutenberg"
version = "0.0.6" version = "0.0.6"
dependencies = [ 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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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]] [[package]]
@ -54,8 +54,8 @@ name = "backtrace"
version = "0.3.2" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"backtrace-sys 0.1.10 (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.0 (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)", "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)", "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)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
@ -65,10 +65,10 @@ dependencies = [
[[package]] [[package]]
name = "backtrace-sys" name = "backtrace-sys"
version = "0.1.10" version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -81,14 +81,22 @@ dependencies = [
] ]
[[package]] [[package]]
name = "bincode" name = "base64"
version = "0.6.1" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "safemem 0.2.0 (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)",
[[package]]
name = "bincode"
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.39 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -106,11 +114,6 @@ name = "bitflags"
version = "0.8.2" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.0.0" version = "1.0.0"
@ -123,7 +126,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "0.4.3" version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -132,24 +135,15 @@ dependencies = [
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.0" 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 = "chrono"
version = "0.2.25"
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]] [[package]]
name = "chrono" name = "chrono"
version = "0.3.1" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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)", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -170,10 +164,10 @@ dependencies = [
[[package]] [[package]]
name = "cmake" name = "cmake"
version = "0.1.23" version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
@ -257,7 +251,7 @@ dependencies = [
[[package]] [[package]]
name = "gcc" name = "gcc"
version = "0.3.46" version = "0.3.50"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -272,7 +266,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "httparse" name = "httparse"
version = "1.2.2" version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -282,21 +276,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.10.10" version = "0.10.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "mime 0.2.6 (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)",
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"time 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)",
"traitobject 0.1.0 (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)", "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)", "unicase 1.4.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]] [[package]]
@ -304,8 +297,8 @@ name = "idna"
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"
dependencies = [ 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)",
"unicode-bidi 0.3.2 (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)", "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 = [ dependencies = [
"conduit-mime-types 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "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)", "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)", "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)", "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]] [[package]]
@ -384,7 +377,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "matches" name = "matches"
version = "0.1.4" version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -397,7 +390,7 @@ dependencies = [
[[package]] [[package]]
name = "mime" name = "mime"
version = "0.2.4" version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -408,7 +401,7 @@ name = "miniz-sys"
version = "0.1.9" version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -430,7 +423,7 @@ dependencies = [
[[package]] [[package]]
name = "mio" name = "mio"
version = "0.6.7" version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -485,7 +478,7 @@ name = "net2"
version = "0.2.29" version = "0.2.29"
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.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)", "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)", "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)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -520,12 +513,12 @@ dependencies = [
[[package]] [[package]]
name = "num" name = "num"
version = "0.1.37" version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "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-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]] [[package]]
@ -533,7 +526,7 @@ name = "num-integer"
version = "0.1.34" version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
@ -542,17 +535,17 @@ version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.1.37" version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "num_cpus" name = "num_cpus"
version = "1.4.0" version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
@ -560,21 +553,21 @@ dependencies = [
[[package]] [[package]]
name = "onig" name = "onig"
version = "1.2.2" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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]] [[package]]
name = "onig_sys" name = "onig_sys"
version = "61.3.0" version = "63.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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)", "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)", "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]] [[package]]
name = "plist" name = "plist"
version = "0.1.3" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.15 (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.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "xml-rs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -633,7 +626,7 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.1.17" version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -664,12 +657,9 @@ version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "rustc_version" name = "safemem"
version = "0.1.7" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "same-file" name = "same-file"
@ -680,26 +670,11 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "sequence_trie" name = "sequence_trie"
version = "0.2.1" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "serde" name = "serde"
version = "1.0.8" version = "1.0.8"
@ -731,7 +706,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "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)", "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)", "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]] [[package]]
@ -794,18 +769,20 @@ dependencies = [
[[package]] [[package]]
name = "syntect" name = "syntect"
version = "1.3.0" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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)", "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)", "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)", "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)", "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)", "onig 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"plist 0.1.3 (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)", "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)", "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)", "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 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)", "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)", "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]] [[package]]
@ -888,7 +865,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"kernel32-sys 0.2.2 (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)", "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)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -915,23 +892,23 @@ name = "typemap"
version = "0.3.3" version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
name = "unicase" name = "unicase"
version = "1.4.0" version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.2" version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
@ -969,7 +946,7 @@ dependencies = [
[[package]] [[package]]
name = "unsafe-any" name = "unsafe-any"
version = "0.4.1" version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -977,11 +954,11 @@ dependencies = [
[[package]] [[package]]
name = "url" name = "url"
version = "1.4.0" version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"idna 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
@ -994,6 +971,11 @@ name = "vec_map"
version = "0.8.0" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "void" name = "void"
version = "1.0.2" version = "1.0.2"
@ -1030,18 +1012,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "ws" name = "ws"
version = "0.7.1" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "bytes 0.4.4 (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)",
"log 0.3.8 (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)", "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)", "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)", "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]] [[package]]
@ -1055,7 +1037,7 @@ dependencies = [
[[package]] [[package]]
name = "xml-rs" name = "xml-rs"
version = "0.3.6" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "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 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 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 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 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.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.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 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 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.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 bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8b24f16593f445422331a5eed46b72f7f171f910fead4f2ea8f17e727e9c5c14"
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" "checksum cfg-if 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c47d456a36ebf0536a6705c83c1cbbcb9255fbc1d905a6ded104f479268a29"
"checksum chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9213f7cd7c27e95c2b57c49f0e69b1ea65b27138da84a170133fd21b07659c00"
"checksum chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d9123be86fd2a8f627836c235ecdf331fdd067ecf7ac05aa1a68fbcf2429f056" "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 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 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 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" "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 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 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 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 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 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 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 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 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" "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 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 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 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 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 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.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.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 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" "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 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 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 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-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-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-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "1708c0628602a98b52fad936cf3edb9a107af06e52e49fdf0707e884456a6af6"
"checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167" "checksum num_cpus 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6e416ba127a4bb3ff398cb19546a8d0414f73352efe2857f4060d36f5fe5983a"
"checksum onig 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1f59adfdb1810e061fcd1cf5dd2792730f8226e5d23c51a52f243714cc8fe676" "checksum onig 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee619da9cf707b167098e84fb00f10db61d5a662d1d29b59822bcac3a81553dd"
"checksum onig_sys 61.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "be2eb43cab0eed1bdeec174b96967cf5636634adc2b6ba8fcc875aa3d5fc4118" "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 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 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 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 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 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 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 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 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-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-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 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 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 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 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" "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 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 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 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 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 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" "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 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 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 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 unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
"checksum unicode-bidi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "916219eb752dd865717c9b21064401c6ee843dc91ed659c144591e0c87c56d59" "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-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-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-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 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 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 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 unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f"
"checksum url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ba8a749fb4479b043733416c244fa9d1d3af3d7c23804944651c8a448cb87e" "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 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 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 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 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 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 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 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 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" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992"

View file

@ -30,7 +30,7 @@ syntect = { version = "1", features = ["static-onig"] }
chrono = "0.3" chrono = "0.3"
toml = "0.4" toml = "0.4"
term-painter = "0.2" term-painter = "0.2"
base64 = "0.5" base64 = "0.6"
# Below is for the serve cmd # Below is for the serve cmd
staticfile = "0.4" staticfile = "0.4"

View file

@ -91,6 +91,7 @@ A front-matter has only optional variables:
- category: only one category is allowed - category: only one category is allowed
- draft: whether the post is a draft or not - draft: whether the post is a draft or not
- template: if you want to change the template used to render that specific page - 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 `+++`. 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. 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. 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). 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
<ul>
{% for h1 in page.toc %}
<li>
<a href="{{h1.permalink}}">{{ h1.title }}</a>
{% if h1.children %}
<ul>
{% for h2 in h1.children %}
<li>
<a href="{{h2.permalink}}">{{ h2.title }}</a>
</li>
{% endfor %}
</ul>
{% endfor %}
</li>
{% endfor %}
</ul>
```
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 themes
Code highlighting can be turned on by setting `highlight_code = true` in `config.toml`. 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` - YouTube: embeds a YouTube player for the given YouTube `id`. Also takes an optional `autoplay` argument that can be set to `true`
if wanted if wanted
- Vimeo: embeds a Vimeo player for the given Vimeo `id` - 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 #### Defining a shortcode
All shortcodes need to be in the `templates/shortcodes` folder and their files to end with `.html`. 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 ## Example sites
- [vincent.is](https://vincent.is): https://gitlab.com/Keats/vincent.is - [vincent.is](https://vincent.is): https://gitlab.com/Keats/vincent.is
- [code<future](http://www.codelessfuture.com/)
## Adding syntax highlighting languages and themes ## Adding syntax highlighting languages and themes
### Adding a syntax ### Adding a syntax
Syntax highlighting depends on submodules so ensure you load them first: Syntax highlighting depends on submodules so ensure you load them first:
```bash ```bash

View file

@ -35,10 +35,7 @@ install:
test_script: test_script:
# we don't run the "test phase" when doing deploys # we don't run the "test phase" when doing deploys
- if [%APPVEYOR_REPO_TAG%]==[false] ( - if [%APPVEYOR_REPO_TAG%]==[false] (
cargo build --target %TARGET% && cargo test --target %TARGET%
cargo build --target %TARGET% --release &&
cargo test --target %TARGET% &&
cargo test --target %TARGET% --release
) )
before_deploy: before_deploy:

View file

@ -1,3 +1,26 @@
// Contains an embedded version of livereload-js
//
// Copyright (c) 2010-2012 Andrey Tarantsov
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
use std::env; use std::env;
use std::path::Path; use std::path::Path;
use std::sync::mpsc::channel; use std::sync::mpsc::channel;

View file

@ -172,9 +172,9 @@ pub fn after_content_change(site: &mut Site, path: &Path) -> Result<()> {
// Updating a page // Updating a page
let current = site.pages[path].clone(); let current = site.pages[path].clone();
// Front matter didn't change, only content did // 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 { if current.meta == prev.meta {
return site.render_page(&site.pages[path]); return site.render_page(&current, find_parent_section(site, &current));
} }
// Front matter changed // Front matter changed
@ -199,7 +199,7 @@ pub fn after_content_change(site: &mut Site, path: &Path) -> Result<()> {
site.render_index()?; site.render_index()?;
}, },
PageChangesNeeded::Render => { PageChangesNeeded::Render => {
site.render_page(&site.pages[path])?; site.render_page(&site.pages[path], find_parent_section(site, &current))?;
}, },
}; };
} }

View file

@ -90,12 +90,20 @@ impl Config {
/// Makes a url, taking into account that the base url might have a trailing slash /// Makes a url, taking into account that the base url might have a trailing slash
pub fn make_permalink(&self, path: &str) -> String { pub fn make_permalink(&self, path: &str) -> String {
if self.base_url.ends_with('/') && path.starts_with('/') { let trailing_bit = if path.ends_with('/') { "" } else { "/" };
format!("{}{}", self.base_url, &path[1..])
// 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('/') { } else if self.base_url.ends_with('/') {
format!("{}{}", self.base_url, path) format!("{}{}{}", self.base_url, path, trailing_bit)
} else { } 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() { fn can_make_url_with_non_trailing_slash_base_url() {
let mut config = Config::default(); let mut config = Config::default();
config.base_url = "http://vincent.is".to_string(); 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] #[test]
fn can_make_url_with_trailing_slash_path() { fn can_make_url_with_trailing_slash_path() {
let mut config = Config::default(); let mut config = Config::default();
config.base_url = "http://vincent.is/".to_string(); 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/");
} }
} }

View file

@ -5,10 +5,12 @@ mod sorting;
mod utils; mod utils;
mod file_info; mod file_info;
mod taxonomies; mod taxonomies;
mod table_of_contents;
pub use self::page::{Page}; pub use self::page::{Page};
pub use self::section::{Section}; pub use self::section::{Section};
pub use self::pagination::{Paginator, Pager}; pub use self::pagination::{Paginator, Pager};
pub use self::sorting::{SortBy, sort_pages, populate_previous_and_next_pages}; pub use self::sorting::{SortBy, sort_pages, populate_previous_and_next_pages};
pub use self::taxonomies::{Taxonomy, TaxonomyItem}; pub use self::taxonomies::{Taxonomy, TaxonomyItem};
pub use self::table_of_contents::{TempHeader, Header, make_table_of_contents};

View file

@ -16,6 +16,7 @@ use rendering::context::Context;
use fs::{read_file}; use fs::{read_file};
use content::utils::{find_related_assets, get_reading_analytics}; use content::utils::{find_related_assets, get_reading_analytics};
use content::file_info::FileInfo; use content::file_info::FileInfo;
use content::{Header, Section};
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -45,6 +46,8 @@ pub struct Page {
pub previous: Option<Box<Page>>, pub previous: Option<Box<Page>>,
/// The next page, by whatever sorting is used for the index/section /// The next page, by whatever sorting is used for the index/section
pub next: Option<Box<Page>>, pub next: Option<Box<Page>>,
/// Toc made from the headers of the markdown file
pub toc: Vec<Header>,
} }
@ -64,6 +67,7 @@ impl Page {
summary: None, summary: None,
previous: None, previous: None,
next: None, next: None,
toc: vec![],
} }
} }
@ -91,6 +95,9 @@ impl Page {
format!("{}/{}", page.file.components.join("/"), page.slug) format!("{}/{}", page.file.components.join("/"), page.slug)
}; };
} }
if !page.path.ends_with('/') {
page.path = format!("{}/", page.path);
}
page.permalink = config.make_permalink(&page.path); page.permalink = config.make_permalink(&page.path);
Ok(page) Ok(page)
@ -114,12 +121,14 @@ impl Page {
/// We need access to all pages url to render links relative to content /// We need access to all pages url to render links relative to content
/// so that can't happen at the same time as parsing /// so that can't happen at the same time as parsing
pub fn render_markdown(&mut self, permalinks: &HashMap<String, String>, tera: &Tera, config: &Config, anchor_insert: InsertAnchor) -> Result<()> { pub fn render_markdown(&mut self, permalinks: &HashMap<String, String>, tera: &Tera, config: &Config, anchor_insert: InsertAnchor) -> Result<()> {
let context = Context::new(tera, config, permalinks, anchor_insert); let context = Context::new(tera, config, &self.permalink, permalinks, anchor_insert);
self.content = markdown_to_html(&self.raw_content, &context)?; let res = markdown_to_html(&self.raw_content, &context)?;
self.content = res.0;
self.toc = res.1;
if self.raw_content.contains("<!-- more -->") { if self.raw_content.contains("<!-- more -->") {
self.summary = Some({ self.summary = Some({
let summary = self.raw_content.splitn(2, "<!-- more -->").collect::<Vec<&str>>()[0]; let summary = self.raw_content.splitn(2, "<!-- more -->").collect::<Vec<&str>>()[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 /// Renders the page using the default layout, unless specified in front-matter
pub fn render_html(&self, tera: &Tera, config: &Config) -> Result<String> { pub fn render_html(&self, tera: &Tera, config: &Config, section: Option<&Section>) -> Result<String> {
let tpl_name = match self.meta.template { let tpl_name = match self.meta.template {
Some(ref l) => l.to_string(), Some(ref l) => l.to_string(),
None => "page.html".to_string() None => "page.html".to_string()
@ -138,6 +147,7 @@ impl Page {
context.add("page", self); context.add("page", self);
context.add("current_url", &self.permalink); context.add("current_url", &self.permalink);
context.add("current_path", &self.path); context.add("current_path", &self.path);
context.add("section", &section);
tera.render(&tpl_name, &context) tera.render(&tpl_name, &context)
.chain_err(|| format!("Failed to render page '{}'", self.file.path.display())) .chain_err(|| format!("Failed to render page '{}'", self.file.path.display()))
@ -158,13 +168,14 @@ impl Default for Page {
summary: None, summary: None,
previous: None, previous: None,
next: None, next: None,
toc: vec![],
} }
} }
} }
impl ser::Serialize for Page { impl ser::Serialize for Page {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error> where S: ser::Serializer { fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error> 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("content", &self.content)?;
state.serialize_field("title", &self.meta.title)?; state.serialize_field("title", &self.meta.title)?;
state.serialize_field("description", &self.meta.description)?; 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("reading_time", &reading_time)?;
state.serialize_field("previous", &self.previous)?; state.serialize_field("previous", &self.previous)?;
state.serialize_field("next", &self.next)?; state.serialize_field("next", &self.next)?;
state.serialize_field("toc", &self.toc)?;
state.end() state.end()
} }
} }
@ -231,8 +243,8 @@ Hello world"#;
let res = Page::parse(Path::new("content/posts/intro/start.md"), content, &conf); let res = Page::parse(Path::new("content/posts/intro/start.md"), content, &conf);
assert!(res.is_ok()); assert!(res.is_ok());
let page = res.unwrap(); let page = res.unwrap();
assert_eq!(page.path, "posts/intro/hello-world"); assert_eq!(page.path, "posts/intro/hello-world/");
assert_eq!(page.permalink, "http://hello.com/posts/intro/hello-world"); assert_eq!(page.permalink, "http://hello.com/posts/intro/hello-world/");
} }
#[test] #[test]
@ -246,7 +258,7 @@ Hello world"#;
let res = Page::parse(Path::new("start.md"), content, &config); let res = Page::parse(Path::new("start.md"), content, &config);
assert!(res.is_ok()); assert!(res.is_ok());
let page = res.unwrap(); 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")); assert_eq!(page.permalink, config.make_permalink("hello-world"));
} }

View file

@ -74,17 +74,18 @@ impl<'a> Paginator<'a> {
continue; continue;
} }
let page_path = format!("{}/{}", paginate_path, index + 1); let page_path = format!("{}/{}/", paginate_path, index + 1);
let permalink = if section.permalink.ends_with('/') { let permalink = format!("{}{}", section.permalink, page_path);
format!("{}{}", section.permalink, page_path) let pager_path = if section.is_index() {
page_path
} else { } else {
format!("{}/{}", section.permalink, page_path) format!("{}{}", section.path, page_path)
}; };
pagers.push(Pager::new( pagers.push(Pager::new(
index + 1, index + 1,
page.clone(), page.clone(),
permalink, permalink,
if section.is_index() { page_path } else { format!("{}/{}", section.path, page_path) } pager_path,
)); ));
} }
@ -94,10 +95,10 @@ impl<'a> Paginator<'a> {
} }
Paginator { Paginator {
all_pages: all_pages, all_pages,
pagers: pagers, pagers,
paginate_by: paginate_by, paginate_by,
section: section, section,
} }
} }
@ -164,11 +165,11 @@ mod tests {
f.paginate_path = Some("page".to_string()); f.paginate_path = Some("page".to_string());
let mut s = Section::new("content/_index.md", f); let mut s = Section::new("content/_index.md", f);
if !is_index { if !is_index {
s.path = "posts".to_string(); s.path = "posts/".to_string();
s.permalink = "https://vincent.is/posts".to_string(); s.permalink = "https://vincent.is/posts/".to_string();
s.file.components = vec!["posts".to_string()]; s.file.components = vec!["posts".to_string()];
} else { } else {
s.permalink = "https://vincent.is".to_string(); s.permalink = "https://vincent.is/".to_string();
} }
s s
} }
@ -186,13 +187,13 @@ mod tests {
assert_eq!(paginator.pagers[0].index, 1); assert_eq!(paginator.pagers[0].index, 1);
assert_eq!(paginator.pagers[0].pages.len(), 2); assert_eq!(paginator.pagers[0].pages.len(), 2);
assert_eq!(paginator.pagers[0].permalink, "https://vincent.is/posts"); assert_eq!(paginator.pagers[0].permalink, "https://vincent.is/posts/");
assert_eq!(paginator.pagers[0].path, "posts"); assert_eq!(paginator.pagers[0].path, "posts/");
assert_eq!(paginator.pagers[1].index, 2); assert_eq!(paginator.pagers[1].index, 2);
assert_eq!(paginator.pagers[1].pages.len(), 1); 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].permalink, "https://vincent.is/posts/page/2/");
assert_eq!(paginator.pagers[1].path, "posts/page/2"); assert_eq!(paginator.pagers[1].path, "posts/page/2/");
} }
#[test] #[test]
@ -208,13 +209,13 @@ mod tests {
assert_eq!(paginator.pagers[0].index, 1); assert_eq!(paginator.pagers[0].index, 1);
assert_eq!(paginator.pagers[0].pages.len(), 2); 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[0].path, "");
assert_eq!(paginator.pagers[1].index, 2); assert_eq!(paginator.pagers[1].index, 2);
assert_eq!(paginator.pagers[1].pages.len(), 1); assert_eq!(paginator.pagers[1].pages.len(), 1);
assert_eq!(paginator.pagers[1].permalink, "https://vincent.is/page/2"); assert_eq!(paginator.pagers[1].permalink, "https://vincent.is/page/2/");
assert_eq!(paginator.pagers[1].path, "page/2"); assert_eq!(paginator.pagers[1].path, "page/2/");
} }
#[test] #[test]
@ -230,18 +231,18 @@ mod tests {
let context = paginator.build_paginator_context(&paginator.pagers[0]); let context = paginator.build_paginator_context(&paginator.pagers[0]);
assert_eq!(context["paginate_by"], to_value(2).unwrap()); assert_eq!(context["paginate_by"], to_value(2).unwrap());
assert_eq!(context["first"], to_value("https://vincent.is/posts").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["last"], to_value("https://vincent.is/posts/page/2/").unwrap());
assert_eq!(context["previous"], to_value::<Option<()>>(None).unwrap()); assert_eq!(context["previous"], to_value::<Option<()>>(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()); assert_eq!(context["current_index"], to_value(1).unwrap());
let context = paginator.build_paginator_context(&paginator.pagers[1]); let context = paginator.build_paginator_context(&paginator.pagers[1]);
assert_eq!(context["paginate_by"], to_value(2).unwrap()); assert_eq!(context["paginate_by"], to_value(2).unwrap());
assert_eq!(context["first"], to_value("https://vincent.is/posts").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["last"], to_value("https://vincent.is/posts/page/2/").unwrap());
assert_eq!(context["next"], to_value::<Option<()>>(None).unwrap()); assert_eq!(context["next"], to_value::<Option<()>>(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()); assert_eq!(context["current_index"], to_value(2).unwrap());
} }
} }

View file

@ -13,6 +13,7 @@ use rendering::markdown::markdown_to_html;
use rendering::context::Context; use rendering::context::Context;
use content::Page; use content::Page;
use content::file_info::FileInfo; use content::file_info::FileInfo;
use content::Header;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -35,6 +36,8 @@ pub struct Section {
pub ignored_pages: Vec<Page>, pub ignored_pages: Vec<Page>,
/// All direct subsections /// All direct subsections
pub subsections: Vec<Section>, pub subsections: Vec<Section>,
/// Toc made from the headers of the markdown file
pub toc: Vec<Header>,
} }
impl Section { impl Section {
@ -51,6 +54,7 @@ impl Section {
pages: vec![], pages: vec![],
ignored_pages: vec![], ignored_pages: vec![],
subsections: vec![], subsections: vec![],
toc: vec![],
} }
} }
@ -58,7 +62,7 @@ impl Section {
let (meta, content) = split_section_content(file_path, content)?; let (meta, content) = split_section_content(file_path, content)?;
let mut section = Section::new(file_path, meta); let mut section = Section::new(file_path, meta);
section.raw_content = content.clone(); section.raw_content = content.clone();
section.path = section.file.components.join("/"); section.path = format!("{}/", section.file.components.join("/"));
section.permalink = config.make_permalink(&section.path); section.permalink = config.make_permalink(&section.path);
Ok(section) Ok(section)
} }
@ -86,8 +90,10 @@ impl Section {
/// We need access to all pages url to render links relative to content /// We need access to all pages url to render links relative to content
/// so that can't happen at the same time as parsing /// so that can't happen at the same time as parsing
pub fn render_markdown(&mut self, permalinks: &HashMap<String, String>, tera: &Tera, config: &Config) -> Result<()> { pub fn render_markdown(&mut self, permalinks: &HashMap<String, String>, tera: &Tera, config: &Config) -> Result<()> {
let context = Context::new(tera, config, permalinks, self.meta.insert_anchor.unwrap()); let context = Context::new(tera, config, &self.permalink, permalinks, self.meta.insert_anchor.unwrap());
self.content = markdown_to_html(&self.raw_content, &context)?; let res = markdown_to_html(&self.raw_content, &context)?;
self.content = res.0;
self.toc = res.1;
Ok(()) Ok(())
} }
@ -129,7 +135,7 @@ impl Section {
impl ser::Serialize for Section { impl ser::Serialize for Section {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error> where S: ser::Serializer { fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error> 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("content", &self.content)?;
state.serialize_field("permalink", &self.permalink)?; state.serialize_field("permalink", &self.permalink)?;
state.serialize_field("title", &self.meta.title)?; 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("permalink", &self.permalink)?;
state.serialize_field("pages", &self.pages)?; state.serialize_field("pages", &self.pages)?;
state.serialize_field("subsections", &self.subsections)?; state.serialize_field("subsections", &self.subsections)?;
state.serialize_field("toc", &self.toc)?;
state.end() state.end()
} }
} }
@ -156,6 +163,7 @@ impl Default for Section {
pages: vec![], pages: vec![],
ignored_pages: vec![], ignored_pages: vec![],
subsections: vec![], subsections: vec![],
toc: vec![],
} }
} }
} }

View file

@ -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<Header>,
}
impl Header {
pub fn from_temp_header(tmp: &TempHeader, children: Vec<Header>) -> 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<Header>) {
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<TempHeader>) -> Vec<Header> {
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);
}
}

View file

@ -6,6 +6,7 @@ use tera::{Context, Tera};
use config::Config; use config::Config;
use errors::{Result, ResultExt}; use errors::{Result, ResultExt};
use content::Page; use content::Page;
use content::sorting::{SortBy, sort_pages};
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -24,10 +25,12 @@ pub struct TaxonomyItem {
impl TaxonomyItem { impl TaxonomyItem {
pub fn new(name: &str, pages: Vec<Page>) -> TaxonomyItem { pub fn new(name: &str, pages: Vec<Page>) -> TaxonomyItem {
// We shouldn't have any pages without dates there
let (sorted_pages, _) = sort_pages(pages, SortBy::Date);
TaxonomyItem { TaxonomyItem {
name: name.to_string(), name: name.to_string(),
slug: slugify(name), slug: slugify(name),
pages, pages: sorted_pages,
} }
} }
} }
@ -48,6 +51,14 @@ impl Taxonomy {
// Find all the tags/categories first // Find all the tags/categories first
for page in all_pages { 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 { if let Some(ref category) = page.meta.category {
categories categories
.entry(category.to_string()) .entry(category.to_string())
@ -109,10 +120,6 @@ impl Taxonomy {
let name = self.get_single_item_name(); let name = self.get_single_item_name();
let mut context = Context::new(); let mut context = Context::new();
context.add("config", config); 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(&name, item);
context.add("current_url", &config.make_permalink(&format!("{}/{}", name, item.slug))); context.add("current_url", &config.make_permalink(&format!("{}/{}", name, item.slug)));
context.add("current_path", &format!("/{}/{}", name, item.slug)); context.add("current_path", &format!("/{}/{}", name, item.slug));

View file

@ -28,6 +28,9 @@ pub struct PageFrontMatter {
pub category: Option<String>, pub category: Option<String>,
/// Integer to use to order content. Lowest is at the bottom, highest first /// Integer to use to order content. Lowest is at the bottom, highest first
pub order: Option<usize>, pub order: Option<usize>,
/// All aliases for that page. Gutenberg will create HTML templates that will
#[serde(skip_serializing)]
pub aliases: Option<Vec<String>>,
/// Specify a template different from `page.html` to use for that page /// Specify a template different from `page.html` to use for that page
#[serde(skip_serializing)] #[serde(skip_serializing)]
pub template: Option<String>, pub template: Option<String>,
@ -100,6 +103,7 @@ impl Default for PageFrontMatter {
tags: None, tags: None,
category: None, category: None,
order: None, order: None,
aliases: None,
template: None, template: None,
extra: None, extra: None,
} }

View file

@ -12,14 +12,22 @@ pub struct Context<'a> {
pub tera: &'a Tera, pub tera: &'a Tera,
pub highlight_code: bool, pub highlight_code: bool,
pub highlight_theme: String, pub highlight_theme: String,
pub current_page_permalink: String,
pub permalinks: &'a HashMap<String, String>, pub permalinks: &'a HashMap<String, String>,
pub insert_anchor: InsertAnchor, pub insert_anchor: InsertAnchor,
} }
impl<'a> Context<'a> { impl<'a> Context<'a> {
pub fn new(tera: &'a Tera, config: &'a Config, permalinks: &'a HashMap<String, String>, insert_anchor: InsertAnchor) -> Context<'a> { pub fn new(
tera: &'a Tera,
config: &'a Config,
current_page_permalink: &str,
permalinks: &'a HashMap<String, String>,
insert_anchor: InsertAnchor,
) -> Context<'a> {
Context { Context {
tera, tera,
current_page_permalink: current_page_permalink.to_string(),
permalinks, permalinks,
insert_anchor, insert_anchor,
highlight_code: config.highlight_code.unwrap(), highlight_code: config.highlight_code.unwrap(),

View file

@ -16,6 +16,7 @@ use front_matter::InsertAnchor;
use rendering::context::Context; use rendering::context::Context;
use rendering::highlighting::THEME_SET; use rendering::highlighting::THEME_SET;
use rendering::short_code::{ShortCode, parse_shortcode, render_simple_shortcode}; 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 // We need to put those in a struct to impl Send and sync
pub struct Setup { pub struct Setup {
@ -37,7 +38,7 @@ lazy_static!{
} }
pub fn markdown_to_html(content: &str, context: &Context) -> Result<String> { pub fn markdown_to_html(content: &str, context: &Context) -> Result<(String, Vec<Header>)> {
// We try to be smart about highlighting code as it can be time-consuming // 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 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 // 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<String> {
// pulldown_cmark can send several text events for a title if there are markdown // 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 // specific characters like `!` in them. We only want to insert the anchor the first time
let mut header_already_inserted = false; let mut header_already_inserted = false;
let mut anchors: Vec<String> = vec![];
// the rendered html // the rendered html
let mut html = String::new(); let mut html = String::new();
let mut anchors: Vec<String> = vec![];
// We might have cases where the slug is already present in our list of anchor // 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 // for example an article could have several titles named Example
@ -83,6 +85,11 @@ pub fn markdown_to_html(content: &str, context: &Context) -> Result<String> {
find_anchor(anchors, name, level + 1) 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(); let mut opts = Options::empty();
opts.insert(OPTION_ENABLE_TABLES); opts.insert(OPTION_ENABLE_TABLES);
opts.insert(OPTION_ENABLE_FOOTNOTES); opts.insert(OPTION_ENABLE_FOOTNOTES);
@ -158,6 +165,13 @@ pub fn markdown_to_html(content: &str, context: &Context) -> Result<String> {
} else { } else {
String::new() 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; header_already_inserted = true;
let event = match context.insert_anchor { let event = match context.insert_anchor {
InsertAnchor::Left => Event::Html(Owned(format!(r#"id="{}">{}{}"#, id, anchor_link, text))), 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<String> {
}, },
Event::Start(Tag::Header(num)) => { Event::Start(Tag::Header(num)) => {
in_header = true; in_header = true;
temp_header = TempHeader::new(num);
// ugly eh // ugly eh
Event::Html(Owned(format!("<h{} ", num))) Event::Html(Owned(format!("<h{} ", num)))
}, },
@ -264,7 +279,7 @@ pub fn markdown_to_html(content: &str, context: &Context) -> Result<String> {
match error { match error {
Some(e) => Err(e), Some(e) => Err(e),
None => Ok(html.replace("<p></p>", "")), None => Ok((html.replace("<p></p>", ""), make_table_of_contents(headers))),
} }
} }
@ -287,9 +302,9 @@ mod tests {
let tera_ctx = Tera::default(); let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); 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(); let res = markdown_to_html("hello", &context).unwrap();
assert_eq!(res, "<p>hello</p>\n"); assert_eq!(res.0, "<p>hello</p>\n");
} }
#[test] #[test]
@ -297,11 +312,11 @@ mod tests {
let tera_ctx = Tera::default(); let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); 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; context.highlight_code = false;
let res = markdown_to_html("```\n$ gutenberg server\n```", &context).unwrap(); let res = markdown_to_html("```\n$ gutenberg server\n```", &context).unwrap();
assert_eq!( assert_eq!(
res, res.0,
"<pre><code>$ gutenberg server\n</code></pre>\n" "<pre><code>$ gutenberg server\n</code></pre>\n"
); );
} }
@ -311,10 +326,10 @@ mod tests {
let tera_ctx = Tera::default(); let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); 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(); let res = markdown_to_html("```\n$ gutenberg server\n$ ping\n```", &context).unwrap();
assert_eq!( assert_eq!(
res, res.0,
"<pre style=\"background-color:#2b303b\">\n<span style=\"background-color:#2b303b;color:#c0c5ce;\">$ gutenberg server\n</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">$ ping\n</span></pre>" "<pre style=\"background-color:#2b303b\">\n<span style=\"background-color:#2b303b;color:#c0c5ce;\">$ gutenberg server\n</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">$ ping\n</span></pre>"
); );
} }
@ -324,10 +339,10 @@ mod tests {
let tera_ctx = Tera::default(); let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); 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(); let res = markdown_to_html("```python\nlist.append(1)\n```", &context).unwrap();
assert_eq!( assert_eq!(
res, res.0,
"<pre style=\"background-color:#2b303b\">\n<span style=\"background-color:#2b303b;color:#c0c5ce;\">list</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">.</span><span style=\"background-color:#2b303b;color:#bf616a;\">append</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">(</span><span style=\"background-color:#2b303b;color:#d08770;\">1</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">)</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">\n</span></pre>" "<pre style=\"background-color:#2b303b\">\n<span style=\"background-color:#2b303b;color:#c0c5ce;\">list</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">.</span><span style=\"background-color:#2b303b;color:#bf616a;\">append</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">(</span><span style=\"background-color:#2b303b;color:#d08770;\">1</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">)</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">\n</span></pre>"
); );
} }
@ -337,11 +352,11 @@ mod tests {
let tera_ctx = Tera::default(); let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); 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(); let res = markdown_to_html("```yolo\nlist.append(1)\n```", &context).unwrap();
// defaults to plain text // defaults to plain text
assert_eq!( assert_eq!(
res, res.0,
"<pre style=\"background-color:#2b303b\">\n<span style=\"background-color:#2b303b;color:#c0c5ce;\">list.append(1)\n</span></pre>" "<pre style=\"background-color:#2b303b\">\n<span style=\"background-color:#2b303b;color:#c0c5ce;\">list.append(1)\n</span></pre>"
); );
} }
@ -350,21 +365,21 @@ mod tests {
fn can_render_shortcode() { fn can_render_shortcode() {
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); 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#" let res = markdown_to_html(r#"
Hello Hello
{{ youtube(id="ub36ffWAqgQ") }} {{ youtube(id="ub36ffWAqgQ") }}
"#, &context).unwrap(); "#, &context).unwrap();
assert!(res.contains("<p>Hello</p>\n<div >")); assert!(res.0.contains("<p>Hello</p>\n<div >"));
assert!(res.contains(r#"<iframe src="https://www.youtube.com/embed/ub36ffWAqgQ""#)); assert!(res.0.contains(r#"<iframe src="https://www.youtube.com/embed/ub36ffWAqgQ""#));
} }
#[test] #[test]
fn can_render_several_shortcode_in_row() { fn can_render_several_shortcode_in_row() {
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); 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#" let res = markdown_to_html(r#"
Hello Hello
@ -374,22 +389,25 @@ Hello
{{ vimeo(id="210073083") }} {{ vimeo(id="210073083") }}
{{ streamable(id="c0ic") }}
{{ gist(url="https://gist.github.com/Keats/32d26f699dcc13ebd41b") }} {{ gist(url="https://gist.github.com/Keats/32d26f699dcc13ebd41b") }}
"#, &context).unwrap(); "#, &context).unwrap();
assert!(res.contains("<p>Hello</p>\n<div >")); assert!(res.0.contains("<p>Hello</p>\n<div >"));
assert!(res.contains(r#"<iframe src="https://www.youtube.com/embed/ub36ffWAqgQ""#)); assert!(res.0.contains(r#"<iframe src="https://www.youtube.com/embed/ub36ffWAqgQ""#));
assert!(res.contains(r#"<iframe src="https://www.youtube.com/embed/ub36ffWAqgQ?autoplay=1""#)); assert!(res.0.contains(r#"<iframe src="https://www.youtube.com/embed/ub36ffWAqgQ?autoplay=1""#));
assert!(res.contains(r#"//player.vimeo.com/video/210073083""#)); assert!(res.0.contains(r#"<iframe src="https://www.streamable.com/e/c0ic""#));
assert!(res.0.contains(r#"//player.vimeo.com/video/210073083""#));
} }
#[test] #[test]
fn doesnt_render_shortcode_in_code_block() { fn doesnt_render_shortcode_in_code_block() {
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); 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#"```{{ youtube(id="w7Ft2ymGmfc") }}```"#, &context).unwrap(); let res = markdown_to_html(r#"```{{ youtube(id="w7Ft2ymGmfc") }}```"#, &context).unwrap();
assert_eq!(res, "<p><code>{{ youtube(id=&quot;w7Ft2ymGmfc&quot;) }}</code></p>\n"); assert_eq!(res.0, "<p><code>{{ youtube(id=&quot;w7Ft2ymGmfc&quot;) }}</code></p>\n");
} }
#[test] #[test]
@ -399,7 +417,7 @@ Hello
tera.add_raw_template("shortcodes/quote.html", "<blockquote>{{ body }} - {{ author}}</blockquote>").unwrap(); tera.add_raw_template("shortcodes/quote.html", "<blockquote>{{ body }} - {{ author}}</blockquote>").unwrap();
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); let config_ctx = Config::default();
let context = Context::new(&tera, &config_ctx, &permalinks_ctx, InsertAnchor::None); let context = Context::new(&tera, &config_ctx, "", &permalinks_ctx, InsertAnchor::None);
let res = markdown_to_html(r#" let res = markdown_to_html(r#"
Hello Hello
@ -407,7 +425,7 @@ Hello
A quote A quote
{% end %} {% end %}
"#, &context).unwrap(); "#, &context).unwrap();
assert_eq!(res, "<p>Hello\n</p><blockquote>A quote - Keats</blockquote>"); assert_eq!(res.0, "<p>Hello\n</p><blockquote>A quote - Keats</blockquote>");
} }
#[test] #[test]
@ -415,7 +433,7 @@ A quote
let tera_ctx = Tera::default(); let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); 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(flash=true) }}", &context); let res = markdown_to_html("{{ hello(flash=true) }}", &context);
assert!(res.is_err()); assert!(res.is_err());
} }
@ -426,14 +444,14 @@ A quote
permalinks.insert("pages/about.md".to_string(), "https://vincent.is/about".to_string()); permalinks.insert("pages/about.md".to_string(), "https://vincent.is/about".to_string());
let tera_ctx = Tera::default(); let tera_ctx = Tera::default();
let config_ctx = Config::default(); let config_ctx = Config::default();
let context = Context::new(&tera_ctx, &config_ctx, &permalinks, InsertAnchor::None); let context = Context::new(&tera_ctx, &config_ctx, "", &permalinks, InsertAnchor::None);
let res = markdown_to_html( let res = markdown_to_html(
r#"[rel link](./pages/about.md), [abs link](https://vincent.is/about)"#, r#"[rel link](./pages/about.md), [abs link](https://vincent.is/about)"#,
&context &context
).unwrap(); ).unwrap();
assert!( assert!(
res.contains(r#"<p><a href="https://vincent.is/about">rel link</a>, <a href="https://vincent.is/about">abs link</a></p>"#) res.0.contains(r#"<p><a href="https://vincent.is/about">rel link</a>, <a href="https://vincent.is/about">abs link</a></p>"#)
); );
} }
@ -443,11 +461,11 @@ A quote
permalinks.insert("pages/about.md".to_string(), "https://vincent.is/about".to_string()); permalinks.insert("pages/about.md".to_string(), "https://vincent.is/about".to_string());
let tera_ctx = Tera::default(); let tera_ctx = Tera::default();
let config_ctx = Config::default(); let config_ctx = Config::default();
let context = Context::new(&tera_ctx, &config_ctx, &permalinks, InsertAnchor::None); let context = Context::new(&tera_ctx, &config_ctx, "", &permalinks, InsertAnchor::None);
let res = markdown_to_html(r#"[rel link](./pages/about.md#cv)"#, &context).unwrap(); let res = markdown_to_html(r#"[rel link](./pages/about.md#cv)"#, &context).unwrap();
assert!( assert!(
res.contains(r#"<p><a href="https://vincent.is/about#cv">rel link</a></p>"#) res.0.contains(r#"<p><a href="https://vincent.is/about#cv">rel link</a></p>"#)
); );
} }
@ -456,7 +474,7 @@ A quote
let tera_ctx = Tera::default(); let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); 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("[rel link](./pages/about.md)", &context); let res = markdown_to_html("[rel link](./pages/about.md)", &context);
assert!(res.is_err()); assert!(res.is_err());
} }
@ -466,9 +484,9 @@ A quote
let tera_ctx = Tera::default(); let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); 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(r#"# Hello"#, &context).unwrap(); let res = markdown_to_html(r#"# Hello"#, &context).unwrap();
assert_eq!(res, "<h1 id=\"hello\">Hello</h1>\n"); assert_eq!(res.0, "<h1 id=\"hello\">Hello</h1>\n");
} }
#[test] #[test]
@ -476,19 +494,19 @@ A quote
let tera_ctx = Tera::default(); let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); 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\n# Hello", &context).unwrap(); let res = markdown_to_html("# Hello\n# Hello", &context).unwrap();
assert_eq!(res, "<h1 id=\"hello\">Hello</h1>\n<h1 id=\"hello-1\">Hello</h1>\n"); assert_eq!(res.0, "<h1 id=\"hello\">Hello</h1>\n<h1 id=\"hello-1\">Hello</h1>\n");
} }
#[test] #[test]
fn can_insert_anchor_left() { fn can_insert_anchor_left() {
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); let config_ctx = Config::default();
let context = Context::new(&GUTENBERG_TERA, &config_ctx, &permalinks_ctx, InsertAnchor::Left); let context = Context::new(&GUTENBERG_TERA, &config_ctx, "", &permalinks_ctx, InsertAnchor::Left);
let res = markdown_to_html("# Hello", &context).unwrap(); let res = markdown_to_html("# Hello", &context).unwrap();
assert_eq!( assert_eq!(
res, res.0,
"<h1 id=\"hello\"><a class=\"gutenberg-anchor\" href=\"#hello\" aria-label=\"Anchor link for: hello\">🔗</a>\nHello</h1>\n" "<h1 id=\"hello\"><a class=\"gutenberg-anchor\" href=\"#hello\" aria-label=\"Anchor link for: hello\">🔗</a>\nHello</h1>\n"
); );
} }
@ -497,10 +515,10 @@ A quote
fn can_insert_anchor_right() { fn can_insert_anchor_right() {
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); let config_ctx = Config::default();
let context = Context::new(&GUTENBERG_TERA, &config_ctx, &permalinks_ctx, InsertAnchor::Right); let context = Context::new(&GUTENBERG_TERA, &config_ctx, "", &permalinks_ctx, InsertAnchor::Right);
let res = markdown_to_html("# Hello", &context).unwrap(); let res = markdown_to_html("# Hello", &context).unwrap();
assert_eq!( assert_eq!(
res, res.0,
"<h1 id=\"hello\">Hello<a class=\"gutenberg-anchor\" href=\"#hello\" aria-label=\"Anchor link for: hello\">🔗</a>\n</h1>\n" "<h1 id=\"hello\">Hello<a class=\"gutenberg-anchor\" href=\"#hello\" aria-label=\"Anchor link for: hello\">🔗</a>\n</h1>\n"
); );
} }
@ -510,10 +528,10 @@ A quote
fn can_insert_anchor_with_exclamation_mark() { fn can_insert_anchor_with_exclamation_mark() {
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); let config_ctx = Config::default();
let context = Context::new(&GUTENBERG_TERA, &config_ctx, &permalinks_ctx, InsertAnchor::Left); let context = Context::new(&GUTENBERG_TERA, &config_ctx, "", &permalinks_ctx, InsertAnchor::Left);
let res = markdown_to_html("# Hello!", &context).unwrap(); let res = markdown_to_html("# Hello!", &context).unwrap();
assert_eq!( assert_eq!(
res, res.0,
"<h1 id=\"hello\"><a class=\"gutenberg-anchor\" href=\"#hello\" aria-label=\"Anchor link for: hello\">🔗</a>\nHello!</h1>\n" "<h1 id=\"hello\"><a class=\"gutenberg-anchor\" href=\"#hello\" aria-label=\"Anchor link for: hello\">🔗</a>\nHello!</h1>\n"
); );
} }
@ -523,10 +541,10 @@ A quote
fn can_insert_anchor_with_link() { fn can_insert_anchor_with_link() {
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); let config_ctx = Config::default();
let context = Context::new(&GUTENBERG_TERA, &config_ctx, &permalinks_ctx, InsertAnchor::Left); let context = Context::new(&GUTENBERG_TERA, &config_ctx, "", &permalinks_ctx, InsertAnchor::Left);
let res = markdown_to_html("## [](#xresources)Xresources", &context).unwrap(); let res = markdown_to_html("## [](#xresources)Xresources", &context).unwrap();
assert_eq!( assert_eq!(
res, res.0,
"<h2 id=\"xresources\"><a class=\"gutenberg-anchor\" href=\"#xresources\" aria-label=\"Anchor link for: xresources\">🔗</a>\nXresources</h2>\n" "<h2 id=\"xresources\"><a class=\"gutenberg-anchor\" href=\"#xresources\" aria-label=\"Anchor link for: xresources\">🔗</a>\nXresources</h2>\n"
); );
} }
@ -535,11 +553,40 @@ A quote
fn can_insert_anchor_with_other_special_chars() { fn can_insert_anchor_with_other_special_chars() {
let permalinks_ctx = HashMap::new(); let permalinks_ctx = HashMap::new();
let config_ctx = Config::default(); let config_ctx = Config::default();
let context = Context::new(&GUTENBERG_TERA, &config_ctx, &permalinks_ctx, InsertAnchor::Left); let context = Context::new(&GUTENBERG_TERA, &config_ctx, "", &permalinks_ctx, InsertAnchor::Left);
let res = markdown_to_html("# Hello*_()", &context).unwrap(); let res = markdown_to_html("# Hello*_()", &context).unwrap();
assert_eq!( assert_eq!(
res, res.0,
"<h1 id=\"hello\"><a class=\"gutenberg-anchor\" href=\"#hello\" aria-label=\"Anchor link for: hello\">🔗</a>\nHello*_()</h1>\n" "<h1 id=\"hello\"><a class=\"gutenberg-anchor\" href=\"#hello\" aria-label=\"Anchor link for: hello\">🔗</a>\nHello*_()</h1>\n"
); );
} }
#[test]
fn can_make_toc() {
let permalinks_ctx = HashMap::new();
let config_ctx = Config::default();
let context = Context::new(
&GUTENBERG_TERA,
&config_ctx,
"https://mysite.com/something",
&permalinks_ctx,
InsertAnchor::Left
);
let res = markdown_to_html(r#"
# Header 1
## Header 2
## Another Header 2
### Last one
"#, &context).unwrap();
let toc = res.1;
assert_eq!(toc.len(), 1);
assert_eq!(toc[0].children.len(), 2);
assert_eq!(toc[0].children[1].children.len(), 1);
}
} }

View file

@ -304,7 +304,7 @@ impl Site {
} }
/// Renders a single content page /// Renders a single content page
pub fn render_page(&self, page: &Page) -> Result<()> { pub fn render_page(&self, page: &Page, section: Option<&Section>) -> Result<()> {
ensure_directory_exists(&self.output_path)?; ensure_directory_exists(&self.output_path)?;
// Copy the nesting of the content directory if we have sections for that page // Copy the nesting of the content directory if we have sections for that page
@ -322,7 +322,7 @@ impl Site {
create_directory(&current_path)?; create_directory(&current_path)?;
// Finally, create a index.html file there with the page rendered // Finally, create a index.html file there with the page rendered
let output = page.render_html(&self.tera, &self.config)?; let output = page.render_html(&self.tera, &self.config, section)?;
create_file(&current_path.join("index.html"), &self.inject_livereload(output))?; create_file(&current_path.join("index.html"), &self.inject_livereload(output))?;
// Copy any asset we found previously into the same directory as the index.html // Copy any asset we found previously into the same directory as the index.html
@ -337,6 +337,8 @@ impl Site {
/// Deletes the `public` directory and builds the site /// Deletes the `public` directory and builds the site
pub fn build(&self) -> Result<()> { pub fn build(&self) -> Result<()> {
self.clean()?; self.clean()?;
// Render aliases first to allow overwriting
self.render_aliases()?;
self.render_sections()?; self.render_sections()?;
self.render_orphan_pages()?; self.render_orphan_pages()?;
self.render_sitemap()?; self.render_sitemap()?;
@ -352,6 +354,25 @@ impl Site {
self.copy_static_directory() self.copy_static_directory()
} }
pub fn render_aliases(&self) -> Result<()> {
for page in self.pages.values() {
if let Some(ref aliases) = page.meta.aliases {
for alias in aliases {
let mut output_path = self.output_path.to_path_buf();
for component in alias.split("/") {
output_path.push(&component);
if !output_path.exists() {
create_directory(&output_path)?;
}
}
create_file(&output_path.join("index.html"), &render_redirect_template(&page.permalink, &self.tera)?)?;
}
}
}
Ok(())
}
/// Renders robots.txt /// Renders robots.txt
pub fn render_robots(&self) -> Result<()> { pub fn render_robots(&self) -> Result<()> {
ensure_directory_exists(&self.output_path)?; ensure_directory_exists(&self.output_path)?;
@ -380,6 +401,10 @@ impl Site {
} }
fn render_taxonomy(&self, taxonomy: &Taxonomy) -> Result<()> { fn render_taxonomy(&self, taxonomy: &Taxonomy) -> Result<()> {
if taxonomy.items.is_empty() {
return Ok(())
}
ensure_directory_exists(&self.output_path)?; ensure_directory_exists(&self.output_path)?;
let output_path = self.output_path.join(&taxonomy.get_list_name()); let output_path = self.output_path.join(&taxonomy.get_list_name());
@ -497,7 +522,7 @@ impl Site {
if render_pages { if render_pages {
for page in &section.pages { for page in &section.pages {
self.render_page(page)?; self.render_page(page, Some(section))?;
} }
} }
@ -536,7 +561,7 @@ impl Site {
ensure_directory_exists(&self.output_path)?; ensure_directory_exists(&self.output_path)?;
for page in self.get_all_orphan_pages() { for page in self.get_all_orphan_pages() {
self.render_page(page)?; self.render_page(page, None)?;
} }
Ok(()) Ok(())

View file

@ -0,0 +1,7 @@
<div {% if class %}class="{{class}}"{% endif %}>
<iframe src="https://www.streamable.com/e/{{id}}"
scrolling="no"
frameborder="0"
allowfullscreen mozallowfullscreen webkitallowfullscreen>
</iframe>
</div>

View file

@ -17,6 +17,7 @@ lazy_static! {
("shortcodes/youtube.html", include_str!("builtins/shortcodes/youtube.html")), ("shortcodes/youtube.html", include_str!("builtins/shortcodes/youtube.html")),
("shortcodes/vimeo.html", include_str!("builtins/shortcodes/vimeo.html")), ("shortcodes/vimeo.html", include_str!("builtins/shortcodes/vimeo.html")),
("shortcodes/gist.html", include_str!("builtins/shortcodes/gist.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")), ("internal/alias.html", include_str!("builtins/internal/alias.html")),
]).unwrap(); ]).unwrap();

@ -1 +1 @@
Subproject commit ea36395b5191cfac1cef60e44c4ec1eacf8b648c Subproject commit 6bbbca9ccd0bd3131575217b3780fa59d059fcba

@ -1 +1 @@
Subproject commit da05d942464943c27884e174a580fc5f879b0b60 Subproject commit ea597da94a17928019e05c3a177f1e972484eec0

@ -1 +1 @@
Subproject commit a10df6e24f90f5cd532a242c1be05416f846db02 Subproject commit 303816f09fe5534487c010082bcd96c408823671

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -2,6 +2,5 @@ title = "My site"
base_url = "https://replace-this-with-your-url.com" base_url = "https://replace-this-with-your-url.com"
highlight_code = true highlight_code = true
[extra.author] [extra.author]
name = "Vincent Prouillet" name = "Vincent Prouillet"

View file

@ -3,6 +3,7 @@ title = "Fixed slug"
description = "" description = ""
slug = "something-else" slug = "something-else"
date = "2017-01-01" date = "2017-01-01"
aliases = ["/an-old-url/old-page"]
+++ +++
A simple page with a slug defined A simple page with a slug defined

View file

@ -11,4 +11,6 @@ A simple page
{{ vimeo(id="210073083") }} {{ vimeo(id="210073083") }}
{{ streamable(id="c0ic") }}
{{ gist(url="https://gist.github.com/Keats/32d26f699dcc13ebd41b") }} {{ gist(url="https://gist.github.com/Keats/32d26f699dcc13ebd41b") }}

View file

@ -1,6 +1,7 @@
{% extends "index.html" %} {% extends "index.html" %}
{% block content %} {% block content %}
{% if section %}Section:{{ section.permalink }}{% endif %}
{{ page.content | safe }} {{ page.content | safe }}
{% if page.previous %}Previous article: {{ page.previous.permalink }}{% endif %} {% if page.previous %}Previous article: {{ page.previous.permalink }}{% endif %}

View file

@ -28,7 +28,7 @@ fn can_parse_site() {
// Make sure the page with a url doesn't have any sections // Make sure the page with a url doesn't have any sections
let url_post = &site.pages[&posts_path.join("fixed-url.md")]; 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 // 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")]; 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")); assert!(file_exists!(public, "posts/tutorials/programming/index.html"));
// TODO: add assertion for syntax highlighting // 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 // No tags or categories
assert_eq!(file_exists!(public, "categories/index.html"), false); assert_eq!(file_exists!(public, "categories/index.html"), false);
assert_eq!(file_exists!(public, "tags/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); assert_eq!(file_contains!(public, "index.html", "/livereload.js?port=1112&mindelay=10"), false);
// Both pages and sections are in the sitemap // Both pages and sections are in the sitemap
assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/posts/simple</loc>")); assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/posts/simple/</loc>"));
assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/posts</loc>")); assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/posts/</loc>"));
// section is in the page context
assert!(file_contains!(public, "posts/python/index.html", "Section:"));
} }
#[test] #[test]
@ -216,8 +223,8 @@ fn can_build_site_with_categories() {
assert_eq!(file_exists!(public, "tags/index.html"), false); assert_eq!(file_exists!(public, "tags/index.html"), false);
// Categories are in the sitemap // Categories are in the sitemap
assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/categories</loc>")); assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/categories/</loc>"));
assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/categories/a</loc>")); assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/categories/a/</loc>"));
} }
#[test] #[test]
@ -268,8 +275,8 @@ fn can_build_site_with_tags() {
// Categories aren't // Categories aren't
assert_eq!(file_exists!(public, "categories/index.html"), false); assert_eq!(file_exists!(public, "categories/index.html"), false);
// Tags are in the sitemap // Tags are in the sitemap
assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/tags</loc>")); assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/tags/</loc>"));
assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/tags/tag-with-space</loc>")); assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/tags/tag-with-space/</loc>"));
} }
#[test] #[test]
@ -327,14 +334,14 @@ fn can_build_site_with_pagination_for_section() {
assert!(file_contains!( assert!(file_contains!(
public, public,
"posts/page/1/index.html", "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", "Num pagers: 3"));
assert!(file_contains!(public, "posts/index.html", "Page size: 2")); 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", "Current index: 1"));
assert!(file_contains!(public, "posts/index.html", "has_next")); 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", "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", "Last: https://replace-this-with-your-url.com/posts/page/3/"));
assert_eq!(file_contains!(public, "posts/index.html", "has_prev"), false); assert_eq!(file_contains!(public, "posts/index.html", "has_prev"), false);
assert!(file_exists!(public, "posts/page/2/index.html")); 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", "Current index: 2"));
assert!(file_contains!(public, "posts/page/2/index.html", "has_prev")); 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", "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", "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", "Last: https://replace-this-with-your-url.com/posts/page/3/"));
} }
#[test] #[test]