Compare commits

..

36 Commits

Author SHA1 Message Date
Matt Ickstadt
91ffca1bbc (cargo-release) version 0.2.0 2018-08-02 19:17:40 -05:00
Matt Ickstadt
6f963bbe3c Run AppVeyor on version tags 2018-08-02 19:10:41 -05:00
Matt Ickstadt
93af92910a Remove travis github_pages deploy
Since it doesn't work at the moment and it takes a lot of time.
2018-08-02 19:10:11 -05:00
Matt Ickstadt
f30ce0184d Fix escaped link preprocessor 2018-08-02 19:04:35 -05:00
Matt Ickstadt
ccb2340fbe Update dependencies 2018-08-02 17:33:56 -05:00
Matt Ickstadt
bbe6e324d0 Merge pull request #757 from mattico/improve-argparse
Improve command-line argument parsing
2018-08-02 17:28:45 -05:00
Matt Ickstadt
a776aa9783 Update documentation for commands 2018-08-02 17:01:47 -05:00
Matt Ickstadt
b8f8e76899 Improve command-line argument parsing 2018-08-02 16:52:41 -05:00
Matt Ickstadt
ac4e00c7c6 Begin development for the 0.2.0 release 2018-08-02 13:31:58 -05:00
Matt Ickstadt
67fde37030 Merge pull request #756 from mattico/test-dir
Fix relative paths in index.html
2018-08-02 13:12:34 -05:00
Matt Ickstadt
b2eb1ace08 Fix relative paths in index.html 2018-08-02 12:43:40 -05:00
Matt Ickstadt
b5fd170008 Merge pull request #755 from mattico/test-dir
Add directory argument to `mdbook test`
2018-08-01 23:11:32 -05:00
Matt Ickstadt
b3665c287d Add directory argument to mdbook test 2018-08-01 17:59:40 -05:00
Matt Ickstadt
436c084b9e Merge pull request #754 from mattico/playpen-api
Use stable rust playground API
2018-08-01 15:22:06 -05:00
Matt Ickstadt
47f85e71a8 Use stable rust playground API
and also add timeouts to these fetches.
2018-08-01 12:38:36 -05:00
Matt Ickstadt
1d448fc8cc (cargo-release) start next development iteration 0.1.11-alpha.0 2018-07-30 19:23:20 -05:00
Matt Ickstadt
add23a43c2 (cargo-release) version 0.1.10 2018-07-30 19:21:18 -05:00
Matt Ickstadt
8ba1830750 Merge pull request #752 from mattico/icon-margin-padding
Icon button hit-test dead-space fix
2018-07-30 19:19:31 -05:00
Matt Ickstadt
76c1c9e0a8 Merge pull request #751 from mattico/update-playpen-bt
Fix rust playground execute API
2018-07-30 19:18:18 -05:00
Matt Ickstadt
d054140117 Fix rust playground execute API 2018-07-30 19:17:53 -05:00
Matt Ickstadt
512826c465 Fix hiding theme menu 2018-07-30 19:06:50 -05:00
Matt Ickstadt
99019b74aa Remove hit-test dead space between buttons 2018-07-30 19:03:29 -05:00
Matt Ickstadt
d87e77edd0 Merge pull request #744 from eminence/noplaypen_class
Add a "noplaypen" class for rust code samples.
2018-07-28 19:18:30 -05:00
Andrew Chin
abfc3009fc Add a "noplaypen" class for rust code samples.
This class will supress the "play" button in the html backend (which you
can also do with the "ignore" class), but it will still let the code be
tested via `mdbook test` (which is not possible with the "ignore" class).

This is useful for code examples that don't really do much (and so the
user doesn't gain much from running them), but as an author you still
want to test them to guard against syntax errors and typos and the like.
2018-07-26 17:55:14 -04:00
Matt Ickstadt
028c8b0f75 Merge pull request #743 from mattico/remove-stylus-redux
Convert Stylus to CSS
2018-07-26 15:37:52 -05:00
Matt Ickstadt
05f3c693a7 Ensure theme selection button is the full-width of the menu 2018-07-26 15:28:09 -05:00
Matt Ickstadt
8b3038e3ef Remove unconditional searchindex.js load
which should have been included in #707
2018-07-26 15:28:09 -05:00
Matt Ickstadt
bc432c8f42 Fix favicon in subfolders 2018-07-26 15:28:09 -05:00
Matt Ickstadt
e88970d172 Don't use CSS variables in media queries
since they don't work :'(
2018-07-26 15:28:09 -05:00
Matt Ickstadt
4c87a0b5f0 Remove stylus support 2018-07-26 15:28:09 -05:00
Matt Ickstadt
ac38f05bb6 Change template to use new CSS 2018-07-26 15:28:05 -05:00
Matt Ickstadt
3119a7e4bf Fix several CSS bugs 2018-07-26 13:49:57 -05:00
Matt Ickstadt
cc745d04f2 Merge css files 2018-07-26 13:37:22 -05:00
Matt Ickstadt
d1a23109e2 Convert stylus files to CSS 2018-07-26 13:37:22 -05:00
Matt Ickstadt
b3e0942bc9 Fix travis deploy out of disk space error 2018-07-26 13:18:33 -05:00
Matt Ickstadt
3e998eb766 (cargo-release) start next development iteration 0.1.10-alpha.0 2018-07-26 12:50:07 -05:00
51 changed files with 1228 additions and 2789 deletions

View File

@@ -21,9 +21,6 @@ script:
- cargo build --verbose
- cargo test --verbose
after_success:
- bash ci/github_pages.sh
before_deploy:
- sh ci/before_deploy.sh
@@ -40,8 +37,8 @@ deploy:
branches:
only:
- "/^v\\d+\\.\\d+\\.\\d+.*$/"
- master
- /^v\d+\.\d+\.\d+.*$/
notifications:
email:

View File

@@ -48,30 +48,6 @@ mdBook builds on stable Rust, if you want to build mdBook from source, here are
The resulting binary can be found in `mdBook/target/debug/` under the name `mdBook` or `mdBook.exe`.
### Making changes to the style
mdBook doesn't use CSS directly but uses [Stylus](http://stylus-lang.com/), a CSS-preprocessor which compiles to CSS.
When you want to change the style, it is important to not change the CSS directly because any manual modification to
the CSS files will be overwritten when compiling the stylus files. Instead, you should make your changes directly in the
[stylus files](https://github.com/rust-lang-nursery/mdBook/tree/master/src/theme/stylus) and regenerate the CSS.
For this to work, you first need [Node and NPM](https://nodejs.org/en/) installed on your machine.
Then run the following command to install both [stylus](http://stylus-lang.com/) and [nib](https://tj.github.io/nib/), you might need `sudo` to install successfully.
```
npm install -g stylus nib
```
When that finished, you can simply regenerate the CSS files by building mdBook with the following command:
```
cargo build --features=regenerate-css
```
This should automatically call the appropriate stylus command to recompile the files to CSS and include them in the project.
### Making a pull-request
When you feel comfortable that your changes could be integrated into mdBook, you can create a pull-request on GitHub.

40
Cargo.lock generated
View File

@@ -63,7 +63,7 @@ name = "base64"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -102,7 +102,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.2.3"
version = "1.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -115,7 +115,7 @@ name = "bytes"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -131,7 +131,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "chrono"
version = "0.4.4"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -503,10 +503,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "mdbook"
version = "0.1.9"
version = "0.2.0"
dependencies = [
"ammonia 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"elasticlunr-rs 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -754,7 +754,7 @@ name = "phf_shared"
version = "0.7.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -956,7 +956,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -981,7 +981,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "siphasher"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1072,7 +1072,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1097,7 +1097,7 @@ dependencies = [
[[package]]
name = "syn"
version = "0.14.5"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1132,7 +1132,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"utf-8 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1142,7 +1142,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"utf-8 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1305,7 +1305,7 @@ dependencies = [
[[package]]
name = "utf-8"
version = "0.7.2"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1379,7 +1379,7 @@ name = "ws"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1413,12 +1413,12 @@ dependencies = [
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
"checksum byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8389c509ec62b9fe8eca58c502a0acaf017737355615243496cde4994f8fa4f9"
"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27"
"checksum bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e178b8e0e239e844b083d5a0d4a156b2654e67f9f80144d48398fcd736a24fb8"
"checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275"
"checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e"
"checksum chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6962c635d530328acc53ac6a955e83093fedc91c5809dfac1fa60fa470830a37"
"checksum chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e48d85528df61dc964aa43c5f6ca681a19cfa74939b2348d204bd08a981f2fb0"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3"
@@ -1515,7 +1515,7 @@ dependencies = [
"checksum serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c6908c7b925cd6c590358a4034de93dbddb20c45e1d021931459fd419bf0e2"
"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
"checksum slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d807fd58c4181bbabed77cb3b891ba9748241a552bcc5be698faaebefc54f46e"
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
"checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d"
@@ -1529,7 +1529,7 @@ dependencies = [
"checksum strum_macros 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1292d85e688e4696ecb69b2db2648994fb8af266974e89be53cefdf003861a5d"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b"
"checksum syn 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4bad7abdf6633f07c7046b90484f1d9dc055eca39f8c991177b1046ce61dba9a"
"checksum syn 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4b5274d4a0a3d2749d5c158dc64d3403e60554dc61194648787ada5212473d"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4b103c6d08d323b92ff42c8ce62abcd83ca8efa7fd5bf7927efefec75f58c76"
"checksum tendril 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1b72f8e2f5b73b65c315b1a70c730f24b9d7a25f39e98de8acbe2bb795caea"
@@ -1555,7 +1555,7 @@ dependencies = [
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f"
"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"
"checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c"
"checksum utf-8 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bab35f71693630bb1953dce0f2bcd780e7cde025027124a202ac08a45ba25141"
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051"

View File

@@ -1,18 +1,18 @@
[package]
name = "mdbook"
version = "0.1.9"
authors = ["Mathieu David <mathieudavid@mathieudavid.org>", "Michael-F-Bryan <michaelfbryan@gmail.com>"]
version = "0.2.0"
authors = [
"Mathieu David <mathieudavid@mathieudavid.org>",
"Michael-F-Bryan <michaelfbryan@gmail.com>",
"Matt Ickstadt <mattico8@gmail.com>"
]
description = "Create books from markdown files"
documentation = "http://rust-lang-nursery.github.io/mdBook/index.html"
repository = "https://github.com/rust-lang-nursery/mdBook"
keywords = ["book", "gitbook", "rustbook", "markdown"]
license = "MPL-2.0"
readme = "README.md"
build = "build.rs"
exclude = [
"book-example/*",
"src/theme/stylus/**",
]
exclude = ["book-example/*"]
[dependencies]
clap = "2.24"
@@ -47,9 +47,6 @@ ws = { version = "0.7", optional = true}
elasticlunr-rs = { version = "2.3", optional = true, default-features = false }
ammonia = { version = "1.1", optional = true }
[build-dependencies]
error-chain = "0.12"
[dev-dependencies]
select = "0.4"
pretty_assertions = "0.5"
@@ -60,7 +57,6 @@ pulldown-cmark-to-cmark = "1.1.0"
default = ["output", "watch", "serve", "search"]
debug = []
output = []
regenerate-css = []
watch = ["notify"]
serve = ["iron", "staticfile", "ws"]
search = ["elasticlunr-rs", "ammonia"]

View File

@@ -1,7 +1,6 @@
environment:
global:
PROJECT_NAME: mdBook
nodejs_version: "6"
matrix:
# Stable channel
- TARGET: i686-pc-windows-msvc
@@ -32,17 +31,12 @@ install:
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
- rustc -Vv
- cargo -V
- ps: Install-Product node $env:nodejs_version
- node --version
- npm --version
- npm install -g stylus nib
build: false
# Equivalent to Travis' `script` phase
test_script:
- cargo build --verbose
- cargo build --verbose --features=regenerate-css
- cargo test --verbose
before_deploy:
@@ -67,3 +61,4 @@ deploy:
branches:
only:
- master
- /^v\d+\.\d+\.\d+.*$/

View File

@@ -14,8 +14,8 @@ convenience. Large books will therefore remain structured when rendered.
#### Specify a directory
Like `init`, the `build` command can take a directory as an argument to use
instead of the current working directory.
The `build` command can take a directory as an argument to use as the book's
root instead of the current working directory.
```bash
mdbook build path/to/book
@@ -23,13 +23,16 @@ mdbook build path/to/book
#### --open
When you use the `--open` (`-o`) option, mdbook will open the rendered book in
When you use the `--open` (`-o`) flag, mdbook will open the rendered book in
your default web browser after building it.
#### --dest-dir
The `--dest-dir` (`-d`) option allows you to change the output directory for your book.
The `--dest-dir` (`-d`) option allows you to change the output directory for
the book. If not specified it will default to the value of the
`build.build-dir` key in `book.toml`, or to `./book` relative to the book's
root directory.
-------------------
***note:*** *make sure to run the build command in the root directory and not in the source directory*
***Note:*** *Make sure to run the build command in the root directory and not in the source directory*

View File

@@ -7,12 +7,21 @@ artifacts.
mdbook clean
```
It will try to delete the built book. If a path is provided, it will be used.
#### Specify a directory
Like `init`, the `clean` command can take a directory as an argument to use
instead of the normal build directory.
The `clean` command can take a directory as an argument to use as the book's
root instead of the current working directory.
```bash
mdbook clean path/to/book
```
#### --dest-dir
The `--dest-dir` (`-d`) option allows you to override the book's output
directory, which will be deleted by this command. If not specified it
will default to the value of the `build.build-dir` key in `book.toml`, or to
`./book` relative to the book's root directory.
```bash
mdbook clean --dest-dir=path/to/book

View File

@@ -1,5 +1,7 @@
# The init command
There is some minimal boilerplate that is the same for every new book. It's for this purpose that mdBook includes an `init` command.
There is some minimal boilerplate that is the same for every new book. It's for this purpose
that mdBook includes an `init` command.
The `init` command is used like this:
@@ -22,23 +24,27 @@ configuration files, etc.
- The `book` directory is where your book is rendered. All the output is ready to be uploaded
to a server to be seen by your audience.
- The `SUMMARY.md` file is the most important file, it's the skeleton of your book and is discussed in more detail in another [chapter](../format/summary.md)
- The `SUMMARY.md` file is the most important file, it's the skeleton of your book and is
discussed in more detail [in another chapter](../format/summary.md)
#### Tip & Trick: Hidden Feature
When a `SUMMARY.md` file already exists, the `init` command will first parse it and generate the missing files according to the paths used in the `SUMMARY.md`. This allows you to think and create the whole structure of your book and then let mdBook generate it for you.
#### Tip: Generate chapters from SUMMARY.md
When a `SUMMARY.md` file already exists, the `init` command will first parse it and generate the
missing files according to the paths used in the `SUMMARY.md`. This allows you to think and create
the whole structure of your book and then let mdBook generate it for you.
#### Specify a directory
When using the `init` command, you can also specify a directory, instead of using the current working directory,
by appending a path to the command:
The `init` command can take a directory as an argument to use as the book's
root instead of the current working directory.
```bash
mdbook init path/to/book
```
## --theme
#### --theme
When you use the `--theme` argument, the default theme will be copied into a directory
When you use the `--theme` flag, the default theme will be copied into a directory
called `theme` in your source directory so that you can modify it.
The theme is selectively overwritten, this means that if you don't want to overwrite a

View File

@@ -1,40 +1,50 @@
# The serve command
The `serve` command is useful when you want to preview your book. It also does hot reloading of the webpage whenever a file changes.
It achieves this by serving the books content over `localhost:3000` (unless otherwise configured, see below) and runs a websocket server on `localhost:3001` which triggers the reloads.
This preferred by many for writing books with mdbook because it allows for you to see the result of your work instantly after every file change.
The serve command is used to preview a book by serving it over HTTP at
`localhost:3000` by default. Additionally it watches the book's directory
for changes, rebuilding the book and refreshing clients for each change.
A websocket connection is used to trigger the client-side refresh.
#### Specify a directory
Like `watch`, `serve` can take a directory as an argument to use instead of
the current working directory.
The `serve` command can take a directory as an argument to use as the book's
root instead of the current working directory.
```bash
mdbook serve path/to/book
```
#### Server options
`serve` has four options: the http port, the websocket port, the interface to serve on, and the public address of the server so that the browser may reach the websocket server.
`serve` has four options: the HTTP port, the WebSocket port, the HTTP hostname
to listen on, and the hostname for the browser to connect to for WebSockets.
For example: suppose you had an nginx server for SSL termination which has a public address of 192.168.1.100 on port 80 and proxied that to 127.0.0.1 on port 8000. To run use the nginx proxy do:
For example: suppose you have an nginx server for SSL termination which has a
public address of 192.168.1.100 on port 80 and proxied that to 127.0.0.1 on
port 8000. To run use the nginx proxy do:
```bash
mdbook serve path/to/book -p 8000 -i 127.0.0.1 -a 192.168.1.100
mdbook serve path/to/book -p 8000 -n 127.0.0.1 --websocket-hostname 192.168.1.100
```
If you were to want live reloading for this you would need to proxy the websocket calls through nginx as well from `192.168.1.100:<WS_PORT>` to `127.0.0.1:<WS_PORT>`. The `-w` flag allows for the websocket port to be configured.
If you were to want live reloading for this you would need to proxy the
websocket calls through nginx as well from `192.168.1.100:<WS_PORT>` to
`127.0.0.1:<WS_PORT>`. The `-w` flag allows for the websocket port to be
configured.
#### --open
When you use the `--open` (`-o`) option, mdbook will open the book in your
When you use the `--open` (`-o`) flag, mdbook will open the book in your
your default web browser after starting the server.
#### --dest-dir
The `--dest-dir` (`-d`) option allows you to change the output directory for your book.
The `--dest-dir` (`-d`) option allows you to change the output directory for
the book. If not specified it will default to the value of the
`build.build-dir` key in `book.toml`, or to `./book` relative to the book's
root directory.
-----
***note:*** *the `serve` command has not gotten a lot of testing yet, there could be some rough edges. If you discover a problem, please report it [on Github](https://github.com/rust-lang-nursery/mdBook/issues)*
***Note:*** *The `serve` command is for testing, and is not intended
to be a complete HTTP server for a website.*

View File

@@ -1,19 +1,53 @@
# The test command
When writing a book, you sometimes need to automate some tests. For example, [The Rust Programming Book](https://doc.rust-lang.org/stable/book/) uses a lot of code examples that could get outdated.
Therefore it is very important for them to be able to automatically test these code examples.
When writing a book, you sometimes need to automate some tests. For example,
[The Rust Programming Book](https://doc.rust-lang.org/stable/book/) uses a lot
of code examples that could get outdated. Therefore it is very important for
them to be able to automatically test these code examples.
mdBook supports a `test` command that will run all available tests in mdBook. At the moment, only one test is available:
*"Test Rust code examples using Rustdoc"*, but I hope this will be expanded in the future to include more tests like:
mdBook supports a `test` command that will run all available tests in a book.
At the moment, only rustdoc tests are supported, but this may be expanded upon
in the future.
- checking for broken links
- checking for unused files
- ...
#### Disable tests on a code block
In the future I would like the user to be able to enable / disable test from the `book.toml` configuration file and support custom tests.
rustdoc doesn't test code blocks which contain the `ignore` attribute:
```rust,ignore
fn main() {}
```
rustdoc also doesn't test code blocks which specify a language other than Rust:
```markdown
**Foo**: _bar_
```
rustdoc *does* test code blocks which have no language specified:
```
This is going to cause an error!
```
#### Specify a directory
The `test` command can take a directory as an argument to use as the book's
root instead of the current working directory.
**How to use it:**
```bash
$ mdbook test
[*]: Testing file: "/mdBook/book-example/src/README.md”
mdbook test path/to/book
```
#### --library-path
The `--library-path` (`-L`) option allows you to add directories to the library
search path used by `rustdoc` when it builds and tests the examples. Multiple
directories can be specified with multiple options (`-L foo -L bar`) or with a
comma-delimited list (`-L foo,bar`).
#### --dest-dir
The `--dest-dir` (`-d`) option allows you to change the output directory for
the book. If not specified it will default to the value of the
`build.build-dir` key in `book.toml`, or to `./book` relative to the book's
root directory.

View File

@@ -1,12 +1,14 @@
# The watch command
The `watch` command is useful when you want your book to be rendered on every file change.
You could repeatedly issue `mdbook build` every time a file is changed. But using `mdbook watch` once will watch your files and will trigger a build automatically whenever you modify a file.
The `watch` command is useful when you want your book to be rendered on every
file change. You could repeatedly issue `mdbook build` every time a file is
changed. But using `mdbook watch` once will watch your files and will trigger
a build automatically whenever you modify a file.
#### Specify a directory
Like `init` and `build`, `watch` can take a directory as an argument to use
instead of the current working directory.
The `watch` command can take a directory as an argument to use as the book's
root instead of the current working directory.
```bash
mdbook watch path/to/book
@@ -19,8 +21,7 @@ your default web browser.
#### --dest-dir
The `--dest-dir` (`-d`) option allows you to change the output directory for your book.
-----
***note:*** *the `watch` command has not gotten a lot of testing yet, there could be some rough edges. If you discover a problem, please report it [on Github](https://github.com/rust-lang-nursery/mdBook/issues)*
The `--dest-dir` (`-d`) option allows you to change the output directory for
the book. If not specified it will default to the value of the
`build.build-dir` key in `book.toml`, or to `./book` relative to the book's
root directory.

View File

@@ -37,7 +37,7 @@ Since the original directory structure is maintained, it is useful to prepend re
In addition to the properties you can access, there are some handlebars helpers at your disposal.
1. ### toc
### 1. toc
The toc helper is used like this
@@ -68,7 +68,7 @@ In addition to the properties you can access, there are some handlebars helpers
</script>
```
2. ### previous / next
### 2. previous / next
The previous and next helpers expose a `link` and `name` property to the previous and next chapters.
@@ -87,5 +87,4 @@ In addition to the properties you can access, there are some handlebars helpers
------
*If you would like me to expose other properties or helpers, please [create a new issue](https://github.com/rust-lang-nursery/mdBook/issues)
and I will consider it.*
*If you would like other properties or helpers exposed, please [create a new issue](https://github.com/rust-lang-nursery/mdBook/issues)*

100
build.rs
View File

@@ -1,100 +0,0 @@
// build.rs
use std::env;
use std::path::Path;
#[macro_use]
extern crate error_chain;
#[cfg(windows)]
mod execs {
use std::process::Command;
pub fn cmd(program: &str) -> Command {
let mut cmd = Command::new("cmd");
cmd.args(&["/c", program]);
cmd
}
}
#[cfg(not(windows))]
mod execs {
use std::process::Command;
pub fn cmd(program: &str) -> Command {
Command::new(program)
}
}
error_chain!{
foreign_links {
Io(std::io::Error);
}
}
fn program_exists(program: &str) -> Result<()> {
execs::cmd(program)
.arg("-v")
.output()
.chain_err(|| format!("Please install '{}'!", program))?;
Ok(())
}
fn npm_package_exists(package: &str) -> Result<()> {
let status = execs::cmd("npm")
.args(&["list", "-g"])
.arg(package)
.output();
match status {
Ok(ref out) if out.status.success() => Ok(()),
_ => bail!(
"Missing npm package '{0}' install with: 'npm -g install {0}'",
package
),
}
}
pub enum Resource<'a> {
Program(&'a str),
Package(&'a str),
}
use Resource::{Package, Program};
impl<'a> Resource<'a> {
pub fn exists(&self) -> Result<()> {
match *self {
Program(name) => program_exists(name),
Package(name) => npm_package_exists(name),
}
}
}
fn run() -> Result<()> {
if let Ok(_) = env::var("CARGO_FEATURE_REGENERATE_CSS") {
// Check dependencies
Program("npm").exists()?;
Program("node").exists().or(Program("nodejs").exists())?;
Package("nib").exists()?;
Package("stylus").exists()?;
// Compile stylus stylesheet to css
let manifest_dir = env::var("CARGO_MANIFEST_DIR")
.chain_err(|| "Please run the script with: 'cargo build'!")?;
let theme_dir = Path::new(&manifest_dir).join("src/theme/");
let stylus_dir = theme_dir.join("stylus/book.styl");
if !execs::cmd("stylus")
.arg(stylus_dir)
.arg("--out")
.arg(theme_dir)
.arg("--use")
.arg("nib")
.status()?
.success()
{
bail!("Stylus encountered an error");
}
}
Ok(())
}
quick_main!(run);

View File

@@ -15,6 +15,9 @@ main() {
;;
esac
# This will slow down the build, but is necessary to not run out of disk space
cargo clean
cargo rustc --bin mdbook --target $TARGET --release -- -C lto
cp target/$TARGET/release/mdbook $stage/

View File

@@ -1,50 +0,0 @@
#!/bin/bash
# Deploys the `book-example` to GitHub Pages
set -ex
# Only run this on the master branch for stable
if [ "$TRAVIS_PULL_REQUEST" != "false" ] ||
[ "$TRAVIS_BRANCH" != "master" ] ||
[ "$TRAVIS_RUST_VERSION" != "stable" ] ||
[ "$TARGET" != "x86_64-unknown-linux-gnu" ]; then
exit 0
fi
# Make sure we have the css dependencies
npm install -g stylus nib
NC='\033[39m'
CYAN='\033[36m'
GREEN='\033[32m'
rev=$(git rev-parse --short HEAD)
echo -e "${CYAN}Running cargo doc${NC}"
cargo doc --features regenerate-css > /dev/null
echo -e "${CYAN}Running mdbook build${NC}"
cargo run -- build book-example/
echo -e "${CYAN}Copying book to target/doc${NC}"
cp -R book-example/book/* target/doc/
cd target/doc
echo -e "${CYAN}Initializing Git${NC}"
git init
git config user.name "Michael Bryan"
git config user.email "michaelfbryan@gmail.com"
git remote add upstream "https://$GH_TOKEN@github.com/rust-lang-nursery/mdBook.git"
git fetch upstream --quiet
git reset upstream/gh-pages --quiet
touch .
echo -e "${CYAN}Pushing changes to gh-pages${NC}"
git add -A .
git commit -m "rebuild pages at ${rev}" --quiet
git push -q upstream HEAD:gh-pages --quiet
echo -e "${GREEN}Deployed docs to GitHub Pages${NC}"

View File

@@ -127,8 +127,20 @@ impl BookBuilder {
let mut index = File::create(themedir.join("index.hbs"))?;
index.write_all(theme::INDEX)?;
let mut css = File::create(themedir.join("book.css"))?;
css.write_all(theme::CSS)?;
let cssdir = themedir.join("css");
fs::create_dir(&cssdir)?;
let mut general_css = File::create(cssdir.join("general.css"))?;
general_css.write_all(theme::GENERAL_CSS)?;
let mut chrome_css = File::create(cssdir.join("chrome.css"))?;
chrome_css.write_all(theme::CHROME_CSS)?;
let mut print_css = File::create(cssdir.join("print.css"))?;
print_css.write_all(theme::PRINT_CSS)?;
let mut variables_css = File::create(cssdir.join("variables.css"))?;
variables_css.write_all(theme::VARIABLES_CSS)?;
let mut favicon = File::create(themedir.join("favicon.png"))?;
favicon.write_all(theme::FAVICON)?;

View File

@@ -1,21 +1,21 @@
use clap::{App, ArgMatches, SubCommand};
use mdbook::errors::Result;
use mdbook::MDBook;
use std::path::PathBuf;
use {get_book_dir, open};
// Create clap subcommand arguments
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name("build")
.about("Build the book from the markdown files")
.arg_from_usage("-o, --open 'Open the compiled book in a web browser'")
.about("Builds a book from its markdown files")
.arg_from_usage(
"-d, --dest-dir=[dest-dir] 'The output directory for your book{n}(Defaults to ./book \
when omitted)'",
"-d, --dest-dir=[dest-dir] 'Output directory for the book{n}\
(If omitted, uses build.build-dir from book.toml or defaults to ./book)'",
)
.arg_from_usage(
"[dir] 'A directory for your book{n}(Defaults to Current Directory when omitted)'",
"[dir] 'Root directory for the book{n}\
(Defaults to the Current Directory when omitted)'",
)
.arg_from_usage("-o, --open 'Opens the compiled book in a web browser'")
}
// Build command implementation
@@ -24,7 +24,7 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
let mut book = MDBook::load(&book_dir)?;
if let Some(dest_dir) = args.value_of("dest-dir") {
book.config.build.build_dir = PathBuf::from(dest_dir);
book.config.build.build_dir = dest_dir.into();
}
book.build()?;

View File

@@ -3,15 +3,18 @@ use get_book_dir;
use mdbook::errors::*;
use mdbook::MDBook;
use std::fs;
use std::path::PathBuf;
// Create clap subcommand arguments
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name("clean")
.about("Delete built book")
.about("Deletes a built book")
.arg_from_usage(
"-d, --dest-dir=[dest-dir] 'The directory of built book{n}(Defaults to ./book when \
omitted)'",
"-d, --dest-dir=[dest-dir] 'Output directory for the book{n}\
(If omitted, uses build.build-dir from book.toml or defaults to ./book)'",
)
.arg_from_usage(
"[dir] 'Root directory for the book{n}\
(Defaults to the Current Directory when omitted)'",
)
}
@@ -21,7 +24,7 @@ pub fn execute(args: &ArgMatches) -> ::mdbook::errors::Result<()> {
let book = MDBook::load(&book_dir)?;
let dir_to_remove = match args.value_of("dest-dir") {
Some(dest_dir) => PathBuf::from(dest_dir),
Some(dest_dir) => dest_dir.into(),
None => book.root.join(&book.config.build.build_dir),
};
fs::remove_dir_all(&dir_to_remove).chain_err(|| "Unable to remove the build directory")?;

View File

@@ -10,12 +10,12 @@ use std::process::Command;
// Create clap subcommand arguments
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name("init")
.about("Create boilerplate structure and files in the directory")
.about("Creates the boilerplate structure and files for a new book")
// the {n} denotes a newline which will properly aligned in all help messages
.arg_from_usage("[dir] 'A directory for your book{n}(Defaults to Current Directory \
when omitted)'")
.arg_from_usage("[dir] 'Directory to create the book in{n}\
(Defaults to the Current Directory when omitted)'")
.arg_from_usage("--theme 'Copies the default theme into your source folder'")
.arg_from_usage("--force 'skip confirmation prompts'")
.arg_from_usage("--force 'Skips confirmation prompts'")
}
// Init command implementation

View File

@@ -7,7 +7,7 @@ use self::iron::{
};
#[cfg(feature = "watch")]
use super::watch;
use clap::{App, ArgMatches, SubCommand};
use clap::{App, Arg, ArgMatches, SubCommand};
use mdbook::errors::*;
use mdbook::utils;
use mdbook::MDBook;
@@ -19,23 +19,52 @@ struct ErrorRecover;
// Create clap subcommand arguments
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name("serve")
.about("Serve the book at http://localhost:3000. Rebuild and reload on change.")
.about("Serves a book at http://localhost:3000, and rebuilds it on changes")
.arg_from_usage(
"[dir] 'A directory for your book{n}(Defaults to Current Directory when omitted)'",
)
.arg_from_usage("-p, --port=[port] 'Use another port{n}(Defaults to 3000)'")
.arg_from_usage(
"-w, --websocket-port=[ws-port] 'Use another port for the websocket connection \
(livereload){n}(Defaults to 3001)'",
"-d, --dest-dir=[dest-dir] 'Output directory for the book{n}\
(If omitted, uses build.build-dir from book.toml or defaults to ./book)'",
)
.arg_from_usage(
"-i, --interface=[interface] 'Interface to listen on{n}(Defaults to localhost)'",
"[dir] 'Root directory for the book{n}\
(Defaults to the Current Directory when omitted)'",
)
.arg_from_usage(
"-a, --address=[address] 'Address that the browser can reach the websocket server \
from{n}(Defaults to the interface address)'",
.arg(
Arg::with_name("hostname")
.short("n")
.long("hostname")
.takes_value(true)
.default_value("localhost")
.empty_values(false)
.help("Hostname to listen on for HTTP connections"),
)
.arg_from_usage("-o, --open 'Open the book server in a web browser'")
.arg(
Arg::with_name("port")
.short("p")
.long("port")
.takes_value(true)
.default_value("3000")
.empty_values(false)
.help("Port to use for HTTP connections"),
)
.arg(
Arg::with_name("websocket-hostname")
.long("websocket-hostname")
.takes_value(true)
.empty_values(false)
.help(
"Hostname to connect to for WebSockets connections (Defaults to the HTTP hostname)",
),
)
.arg(
Arg::with_name("websocket-port")
.short("w")
.long("websocket-port")
.takes_value(true)
.default_value("3001")
.empty_values(false)
.help("Port to use for WebSockets livereload connections"),
)
.arg_from_usage("-o, --open 'Opens the book server in a web browser'")
}
// Watch command implementation
@@ -43,19 +72,23 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
let book_dir = get_book_dir(args);
let mut book = MDBook::load(&book_dir)?;
let port = args.value_of("port").unwrap_or("3000");
let ws_port = args.value_of("websocket-port").unwrap_or("3001");
let interface = args.value_of("interface").unwrap_or("localhost");
let public_address = args.value_of("address").unwrap_or(interface);
let port = args.value_of("port").unwrap();
let ws_port = args.value_of("websocket-port").unwrap();
let hostname = args.value_of("hostname").unwrap();
let public_address = args.value_of("websocket-address").unwrap_or(hostname);
let open_browser = args.is_present("open");
let address = format!("{}:{}", interface, port);
let ws_address = format!("{}:{}", interface, ws_port);
let address = format!("{}:{}", hostname, port);
let ws_address = format!("{}:{}", hostname, ws_port);
let livereload_url = format!("ws://{}:{}", public_address, ws_port);
book.config
.set("output.html.livereload-url", &livereload_url)?;
if let Some(dest_dir) = args.value_of("dest-dir") {
book.config.build.build_dir = dest_dir.into();
}
book.build()?;
let mut chain = Chain::new(staticfile::Static::new(book.build_dir_for("html")));
@@ -87,10 +120,8 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
// FIXME: This area is really ugly because we need to re-set livereload :(
let livereload_url = livereload_url.clone();
let result = MDBook::load(&book_dir)
.and_then(move |mut b| {
.and_then(|mut b| {
b.config.set("output.html.livereload-url", &livereload_url)?;
Ok(b)
})

View File

@@ -1,4 +1,4 @@
use clap::{App, ArgMatches, SubCommand};
use clap::{App, Arg, ArgMatches, SubCommand};
use get_book_dir;
use mdbook::errors::Result;
use mdbook::MDBook;
@@ -6,8 +6,24 @@ use mdbook::MDBook;
// Create clap subcommand arguments
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name("test")
.about("Test that code samples compile")
.arg_from_usage("-L, --library-path [DIR]... 'directory to add to crate search path'")
.about("Tests that a book's Rust code samples compile")
.arg_from_usage(
"-d, --dest-dir=[dest-dir] 'Output directory for the book{n}\
(If omitted, uses build.build-dir from book.toml or defaults to ./book)'",
)
.arg_from_usage(
"[dir] 'Root directory for the book{n}\
(Defaults to the Current Directory when omitted)'",
)
.arg(Arg::with_name("library-path")
.short("L")
.long("library-path")
.value_name("dir")
.takes_value(true)
.require_delimiter(true)
.multiple(true)
.empty_values(false)
.help("A comma-separated list of directories to add to {n}the crate search path when building tests"))
}
// test command implementation
@@ -18,6 +34,10 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
let book_dir = get_book_dir(args);
let mut book = MDBook::load(&book_dir)?;
if let Some(dest_dir) = args.value_of("dest-dir") {
book.config.build.build_dir = dest_dir.into();
}
book.test(library_paths)?;
Ok(())

View File

@@ -13,11 +13,16 @@ use {get_book_dir, open};
// Create clap subcommand arguments
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name("watch")
.about("Watch the files for changes")
.arg_from_usage("-o, --open 'Open the compiled book in a web browser'")
.about("Watches a book's files and rebuilds it on changes")
.arg_from_usage(
"[dir] 'A directory for your book{n}(Defaults to Current Directory when omitted)'",
"-d, --dest-dir=[dest-dir] 'Output directory for the book{n}\
(If omitted, uses build.build-dir from book.toml or defaults to ./book)'",
)
.arg_from_usage(
"[dir] 'Root directory for the book{n}\
(Defaults to the Current Directory when omitted)'",
)
.arg_from_usage("-o, --open 'Open the compiled book in a web browser'")
}
// Watch command implementation

View File

@@ -20,26 +20,27 @@ use std::path::{Path, PathBuf};
mod cmd;
const NAME: &'static str = "mdbook";
const NAME: &'static str = "mdBook";
const VERSION: &'static str = concat!("v", crate_version!());
fn main() {
init_logger();
// Create a list of valid arguments and sub-commands
let app = App::new(NAME)
.about("Create a book in form of a static website from markdown files")
.author("Mathieu David <mathieudavid@mathieudavid.org>")
// Get the version from our Cargo.toml using clap's crate_version!() macro
.version(concat!("v",crate_version!()))
.setting(AppSettings::ArgRequiredElseHelp)
.after_help("For more information about a specific command, \
try `mdbook <command> --help`\n\
Source code for mdbook available \
at: https://github.com/rust-lang-nursery/mdBook")
.subcommand(cmd::init::make_subcommand())
.subcommand(cmd::build::make_subcommand())
.subcommand(cmd::test::make_subcommand())
.subcommand(cmd::clean::make_subcommand());
.about("Creates a book from markdown files")
.author("Mathieu David <mathieudavid@mathieudavid.org>")
.version(VERSION)
.setting(AppSettings::GlobalVersion)
.setting(AppSettings::ArgRequiredElseHelp)
.after_help(
"For more information about a specific command, try `mdbook <command> --help`\n\
The source code for mdBook is available at: https://github.com/rust-lang-nursery/mdBook",
)
.subcommand(cmd::init::make_subcommand())
.subcommand(cmd::build::make_subcommand())
.subcommand(cmd::test::make_subcommand())
.subcommand(cmd::clean::make_subcommand());
#[cfg(feature = "watch")]
let app = app.subcommand(cmd::watch::make_subcommand());

View File

@@ -32,7 +32,8 @@ impl Preprocessor for LinkPreprocessor {
book.for_each_mut(|section: &mut BookItem| {
if let BookItem::Chapter(ref mut ch) = *section {
let base = ch.path
let base = ch
.path
.parent()
.map(|dir| src_dir.join(dir))
.expect("All book items have a parent");
@@ -46,7 +47,11 @@ impl Preprocessor for LinkPreprocessor {
}
}
fn replace_all<P: AsRef<Path>>(s: &str, path: P, source: &P, depth: usize) -> String {
fn replace_all<P1, P2>(s: &str, path: P1, source: P2, depth: usize) -> String
where
P1: AsRef<Path>,
P2: AsRef<Path>,
{
// When replacing one thing in a string by something with a different length,
// the indices after that will not correspond,
// we therefore have to store the difference to correct this
@@ -62,12 +67,9 @@ fn replace_all<P: AsRef<Path>>(s: &str, path: P, source: &P, depth: usize) -> St
Ok(new_content) => {
if depth < MAX_LINK_NESTED_DEPTH {
if let Some(rel_path) = playpen.link.relative_path(path) {
replaced.push_str(&replace_all(
&new_content,
rel_path,
&source.to_path_buf(),
depth + 1,
));
replaced.push_str(&replace_all(&new_content, rel_path, source, depth + 1));
} else {
replaced.push_str(&new_content);
}
} else {
error!(
@@ -265,6 +267,21 @@ fn find_links(contents: &str) -> LinkIter {
mod tests {
use super::*;
#[test]
fn test_replace_all_escaped() {
let start = r"
Some text over here.
```hbs
\{{#include file.rs}} << an escaped link!
```";
let end = r"
Some text over here.
```hbs
{{#include file.rs}} << an escaped link!
```";
assert_eq!(replace_all(start, "", "", 0), end);
}
#[test]
fn test_find_links_no_link() {
let s = "Some random text without link...";

View File

@@ -1,4 +1,4 @@
use book::{Book, BookItem, Chapter};
use book::{Book, BookItem};
use config::{Config, HtmlConfig, Playpen};
use errors::*;
use renderer::html_handlebars::helpers;
@@ -8,8 +8,7 @@ use utils;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::fs::{self, File};
use std::io::Read;
use std::fs;
use std::path::{Path, PathBuf};
use handlebars::Handlebars;
@@ -74,11 +73,21 @@ impl HtmlHandlebars {
let rendered = self.post_process(rendered, &ctx.html_config.playpen);
// Write to file
debug!("Creating {}", filepath.display());
utils::fs::write_file(&ctx.destination, &filepath, &rendered.into_bytes())?;
debug!("Creating {}", filepath.display());
utils::fs::write_file(&ctx.destination, &filepath, rendered.as_bytes())?;
if ctx.is_index {
self.render_index(ch, &ctx.destination)?;
ctx.data.insert("path".to_owned(), json!("index.html"));
ctx.data.insert("path_to_root".to_owned(), json!(""));
let rendered_index = ctx.handlebars.render("index", &ctx.data)?;
let rendered_index =
self.post_process(rendered_index, &ctx.html_config.playpen);
debug!("Creating index.html from {}", path);
utils::fs::write_file(
&ctx.destination,
"index.html",
rendered_index.as_bytes(),
)?;
}
}
_ => {}
@@ -87,34 +96,6 @@ impl HtmlHandlebars {
Ok(())
}
/// Create an index.html from the first element in SUMMARY.md
fn render_index(&self, ch: &Chapter, destination: &Path) -> Result<()> {
debug!("index.html");
let mut content = String::new();
File::open(destination.join(&ch.path.with_extension("html")))?
.read_to_string(&mut content)?;
// This could cause a problem when someone displays
// code containing <base href=...>
// on the front page, however this case should be very very rare...
content = content
.lines()
.filter(|line| !line.contains("<base href="))
.collect::<Vec<&str>>()
.join("\n");
utils::fs::write_file(destination, "index.html", content.as_bytes())?;
debug!(
"Creating index.html from {} ✓",
destination.join(&ch.path.with_extension("html")).display()
);
Ok(())
}
#[cfg_attr(feature = "cargo-clippy", allow(let_and_return))]
fn post_process(&self, rendered: String, playpen_config: &Playpen) -> String {
let rendered = build_header_links(&rendered);
@@ -139,7 +120,10 @@ impl HtmlHandlebars {
)?;
write_file(destination, "book.js", &theme.js)?;
write_file(destination, "book.css", &theme.css)?;
write_file(destination, "css/general.css", &theme.general_css)?;
write_file(destination, "css/chrome.css", &theme.chrome_css)?;
write_file(destination, "css/print.css", &theme.print_css)?;
write_file(destination, "css/variables.css", &theme.variables_css)?;
write_file(destination, "favicon.png", &theme.favicon)?;
write_file(destination, "highlight.css", &theme.highlight_css)?;
write_file(destination, "tomorrow-night.css", &theme.tomorrow_night_css)?;
@@ -360,7 +344,7 @@ impl Renderer for HtmlHandlebars {
let rendered = self.post_process(rendered, &html_config.playpen);
utils::fs::write_file(&destination, "print.html", &rendered.into_bytes())?;
utils::fs::write_file(&destination, "print.html", rendered.as_bytes())?;
debug!("Creating print.html ✓");
debug!("Copy static files");
@@ -577,7 +561,9 @@ fn add_playpen_pre(html: &str, playpen_config: &Playpen) -> String {
let classes = &caps[2];
let code = &caps[3];
if (classes.contains("language-rust") && !classes.contains("ignore"))
if (classes.contains("language-rust")
&& !classes.contains("ignore")
&& !classes.contains("noplaypen"))
|| classes.contains("mdbook-runnable")
{
// wrap the contents in an external pre block

File diff suppressed because it is too large Load Diff

View File

@@ -19,9 +19,16 @@ function playpen_text(playpen) {
// Hide Rust code lines prepended with a specific character
var hiding_character = "#";
function fetch_with_timeout(url, options, timeout = 6000) {
return Promise.race([
fetch(url, options),
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout))
]);
}
var playpens = Array.from(document.querySelectorAll(".playpen"));
if (playpens.length > 0) {
fetch("https://play.rust-lang.org/meta/crates", {
fetch_with_timeout("https://play.rust-lang.org/meta/crates", {
headers: {
'Content-Type': "application/json",
},
@@ -96,32 +103,28 @@ function playpen_text(playpen) {
let text = playpen_text(code_block);
var params = {
channel: "stable",
mode: "debug",
crateType: "bin",
tests: false,
code: text,
}
version: "stable",
optimize: "0",
code: text
};
if (text.indexOf("#![feature") !== -1) {
params.channel = "nightly";
params.version = "nightly";
}
result_block.innerText = "Running...";
var request = fetch("https://play.rust-lang.org/execute", {
fetch_with_timeout("https://play.rust-lang.org/evaluate.json", {
headers: {
'Content-Type': "application/json",
},
method: 'POST',
mode: 'cors',
body: JSON.stringify(params)
});
request
.then(function (response) { return response.json(); })
.then(function (response) { result_block.innerText = response.success ? response.stdout : response.stderr; })
.catch(function (error) { result_block.innerText = "Playground communication" + error.message; });
})
.then(response => response.json())
.then(response => result_block.innerText = response.result)
.catch(error => result_block.innerText = "Playground Communication: " + error.message);
}
// Syntax highlighting Configuration
@@ -380,7 +383,7 @@ function playpen_text(playpen) {
themePopup.addEventListener('focusout', function(e) {
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
if (!!e.relatedTarget && !themePopup.contains(e.relatedTarget)) {
if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) {
hideThemes();
}
});

417
src/theme/css/chrome.css Normal file
View File

@@ -0,0 +1,417 @@
/* CSS for UI elements (a.k.a. chrome) */
@import 'variables.css';
::-webkit-scrollbar {
background: var(--bg);
}
::-webkit-scrollbar-thumb {
background: var(--scrollbar);
}
#searchresults a,
.content a:link,
a:visited,
a > .hljs {
color: var(--links);
}
/* Menu Bar */
#menu-bar {
position: -webkit-sticky;
position: sticky;
top: 0;
z-index: 101;
margin: auto calc(0px - var(--page-padding));
}
#menu-bar > #menu-bar-sticky-container {
display: flex;
flex-wrap: wrap;
background-color: var(--bg);
border-bottom-color: var(--bg);
border-bottom-width: 1px;
border-bottom-style: solid;
}
.js #menu-bar > #menu-bar-sticky-container {
transition: transform 0.3s;
}
#menu-bar.bordered > #menu-bar-sticky-container {
border-bottom-color: var(--table-border-color);
}
#menu-bar i, #menu-bar .icon-button {
position: relative;
padding: 0 8px;
z-index: 10;
line-height: 50px;
cursor: pointer;
transition: color 0.5s;
}
@media only screen and (max-width: 420px) {
#menu-bar i, #menu-bar .icon-button {
padding: 0 5px;
}
}
.icon-button {
border: none;
background: none;
padding: 0;
color: inherit;
}
.icon-button i {
margin: 0;
}
#print-button {
margin: 0 15px;
}
html:not(.sidebar-visible) #menu-bar:not(:hover).folded > #menu-bar-sticky-container {
transform: translateY(-60px);
}
.left-buttons {
display: flex;
margin: 0 5px;
}
.no-js .left-buttons {
display: none;
}
.menu-title {
display: inline-block;
font-weight: 200;
font-size: 20px;
line-height: 50px;
text-align: center;
margin: 0;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.js .menu-title {
cursor: pointer;
}
.menu-bar,
.menu-bar:visited,
.nav-chapters,
.nav-chapters:visited,
.mobile-nav-chapters,
.mobile-nav-chapters:visited,
.menu-bar .icon-button,
.menu-bar a i {
color: var(--icons);
}
.menu-bar i:hover,
.menu-bar .icon-button:hover,
.nav-chapters:hover,
.mobile-nav-chapters i:hover {
color: var(--icons-hover);
}
/* Nav Icons */
.nav-chapters {
font-size: 2.5em;
text-align: center;
text-decoration: none;
position: fixed;
top: 50px; /* Height of menu-bar */
bottom: 0;
margin: 0;
max-width: 150px;
min-width: 90px;
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
transition: color 0.5s;
}
.nav-chapters:hover { text-decoration: none; }
.nav-wrapper {
margin-top: 50px;
display: none;
}
.mobile-nav-chapters {
font-size: 2.5em;
text-align: center;
text-decoration: none;
width: 90px;
border-radius: 5px;
background-color: var(--sidebar-bg);
}
.previous {
float: left;
}
.next {
float: right;
right: var(--page-padding);
}
@media only screen and (max-width: 1080px) {
.nav-wide-wrapper { display: none; }
.nav-wrapper { display: block; }
}
@media only screen and (max-width: 1380px) {
.sidebar-visible .nav-wide-wrapper { display: none; }
.sidebar-visible .nav-wrapper { display: block; }
}
/* Inline code */
:not(pre) > .hljs {
display: inline-block;
vertical-align: middle;
padding: 0.1em 0.3em;
border-radius: 3px;
color: var(--inline-code-color);
}
a:hover > .hljs {
text-decoration: underline;
}
pre {
position: relative;
}
pre > .buttons {
position: absolute;
z-index: 100;
right: 5px;
top: 5px;
color: var(--sidebar-fg);
cursor: pointer;
}
pre > .buttons :hover {
color: var(--sidebar-active);
}
pre > .buttons i {
margin-left: 8px;
}
pre > .buttons button {
color: inherit;
background: transparent;
border: none;
cursor: inherit;
}
pre > .result {
margin-top: 10px;
}
/* Search */
#searchresults a {
text-decoration: none;
}
mark {
border-radius: 2px;
padding: 0 3px 1px 3px;
margin: 0 -3px -1px -3px;
background-color: var(--search-mark-bg);
transition: background-color 300ms linear;
cursor: pointer;
}
mark.fade-out {
background-color: rgba(0,0,0,0) !important;
cursor: auto;
}
.searchbar-outer {
margin-left: auto;
margin-right: auto;
max-width: var(--content-max-width);
}
#searchbar {
width: 100%;
margin: 5px auto 0px auto;
padding: 10px 16px;
transition: box-shadow 300ms ease-in-out;
border: 1px solid var(--searchbar-border-color);
border-radius: 3px;
background-color: var(--searchbar-bg);
color: var(--searchbar-fg);
}
#searchbar:focus,
#searchbar.active {
box-shadow: 0 0 3px var(--searchbar-shadow-color);
}
.searchresults-header {
font-weight: bold;
font-size: 1em;
padding: 18px 0 0 5px;
color: var(--searchresults-header-fg);
}
.searchresults-outer {
margin-left: auto;
margin-right: auto;
max-width: var(--content-max-width);
border-bottom: 1px dashed var(--searchresults-border-color);
}
ul#searchresults {
list-style: none;
padding-left: 20px;
}
ul#searchresults li {
margin: 10px 0px;
padding: 2px;
border-radius: 2px;
}
ul#searchresults li.focus {
background-color: var(--searchresults-li-bg);
}
ul#searchresults span.teaser {
display: block;
clear: both;
margin: 5px 0 0 20px;
font-size: 0.8em;
}
ul#searchresults span.teaser em {
font-weight: bold;
font-style: normal;
}
/* Sidebar */
.sidebar {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: var(--sidebar-width);
overflow-y: auto;
padding: 10px 10px;
font-size: 0.875em;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
overscroll-behavior-y: contain;
background-color: var(--sidebar-bg);
color: var(--sidebar-fg);
}
.js .sidebar {
transition: transform 0.3s; /* Animation: slide away */
}
.sidebar code {
line-height: 2em;
}
.sidebar-hidden .sidebar {
transform: translateX(calc(0px - var(--sidebar-width)));
}
.sidebar::-webkit-scrollbar {
background: var(--sidebar-bg);
}
.sidebar::-webkit-scrollbar-thumb {
background: var(--scrollbar);
}
.sidebar-visible .page-wrapper {
transform: translateX(var(--sidebar-width));
}
@media only screen and (min-width: 620px) {
.sidebar-visible .page-wrapper {
transform: none;
margin-left: var(--sidebar-width);
}
}
.chapter {
list-style: none outside none;
padding-left: 0;
line-height: 2.2em;
}
.chapter li {
color: var(--sidebar-non-existant);
}
.chapter li a {
color: var(--sidebar-fg);
display: block;
padding: 0;
text-decoration: none;
}
.chapter li a:hover { text-decoration: none }
.chapter li .active,
a:hover {
/* Animate color change */
color: var(--sidebar-active);
}
.spacer {
width: 100%;
height: 3px;
margin: 5px 0px;
}
.chapter .spacer {
background-color: var(--sidebar-spacer);
}
@media (-moz-touch-enabled: 1), (pointer: coarse) {
.chapter li a { padding: 5px 0; }
.spacer { margin: 10px 0; }
}
.section {
list-style: none outside none;
padding-left: 20px;
line-height: 1.9em;
}
/* Theme Menu Popup */
.theme-popup {
position: absolute;
left: 10px;
top: 50px;
z-index: 1000;
border-radius: 4px;
font-size: 0.7em;
color: var(--fg);
background: var(--theme-popup-bg);
border: 1px solid var(--theme-popup-border);
margin: 0;
padding: 0;
list-style: none;
display: none;
}
.theme-popup .default {
color: var(--icons);
}
.theme-popup .theme {
width: 100%;
border: 0;
margin: 0;
padding: 2px 10px;
line-height: 25px;
white-space: nowrap;
text-align: left;
cursor: pointer;
color: inherit;
background: inherit;
font-size: inherit;
}
.theme-popup .theme:hover {
background-color: var(--theme-hover);
}
.theme-popup .theme:hover:first-child,
.theme-popup .theme:hover:last-child {
border-top-left-radius: inherit;
border-top-right-radius: inherit;
}

144
src/theme/css/general.css Normal file
View File

@@ -0,0 +1,144 @@
/* Base styles and content styles */
@import 'variables.css';
html {
font-family: "Open Sans", sans-serif;
color: var(--fg);
background-color: var(--bg);
text-size-adjust: none;
}
body {
margin: 0;
font-size: 1rem;
overflow-x: hidden;
}
code {
font-family: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace;
font-size: 0.875em; /* please adjust the ace font size accordingly in editor.js */
}
.left { float: left; }
.right { float: right; }
.hidden { display: none; }
.play-button.hidden { display: none; }
h2, h3 { margin-top: 2.5em; }
h4, h5 { margin-top: 2em; }
.header + .header h3,
.header + .header h4,
.header + .header h5 {
margin-top: 1em;
}
a.header:target h1:before,
a.header:target h2:before,
a.header:target h3:before,
a.header:target h4:before {
display: inline-block;
content: "»";
margin-left: -30px;
width: 30px;
}
.page {
outline: 0;
padding: 0 var(--page-padding);
}
.page-wrapper {
box-sizing: border-box;
}
.js .page-wrapper {
transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */
}
.content {
overflow-y: auto;
padding: 0 15px;
padding-bottom: 50px;
}
.content main {
margin-left: auto;
margin-right: auto;
max-width: var(--content-max-width);
}
.content a { text-decoration: none; }
.content a:hover { text-decoration: underline; }
.content img { max-width: 100%; }
.content .header:link,
.content .header:visited {
color: var(--fg);
}
.content .header:link,
.content .header:visited:hover {
text-decoration: none;
}
table {
margin: 0 auto;
border-collapse: collapse;
}
table td {
padding: 3px 20px;
border: 1px var(--table-border-color) solid;
}
table thead {
background: var(--table-header-bg);
}
table thead td {
font-weight: 700;
border: none;
}
table thead tr {
border: 1px var(--table-header-bg) solid;
}
/* Alternate background colors for rows */
table tbody tr:nth-child(2n) {
background: var(--table-alternate-bg);
}
blockquote {
margin: 20px 0;
padding: 0 20px;
color: var(--fg);
background-color: var(--quote-bg);
border-top: .1em solid var(--quote-border);
border-bottom: .1em solid var(--quote-border);
}
:not(.footnote-definition) + .footnote-definition,
.footnote-definition + :not(.footnote-definition) {
margin-top: 2em;
}
.footnote-definition {
font-size: 0.9em;
margin: 0.5em 0;
}
.footnote-definition p {
display: inline;
}
.tooltiptext {
position: absolute;
visibility: hidden;
color: #fff;
background-color: #333;
transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */
left: -8px; /* Half of the width of the icon */
top: -35px;
font-size: 0.8em;
text-align: center;
border-radius: 6px;
padding: 5px 8px;
margin: 5px;
z-index: 1000;
}
.tooltipped .tooltiptext {
visibility: visible;
}

54
src/theme/css/print.css Normal file
View File

@@ -0,0 +1,54 @@
#sidebar,
#menu-bar,
.nav-chapters,
.mobile-nav-chapters {
display: none;
}
#page-wrapper.page-wrapper {
transform: none;
margin-left: 0px;
overflow-y: initial;
}
#content {
max-width: none;
margin: 0;
padding: 0;
}
.page {
overflow-y: initial;
}
code {
background-color: #666666;
border-radius: 5px;
/* Force background to be printed in Chrome */
-webkit-print-color-adjust: exact;
}
pre > .buttons {
z-index: 2;
}
a, a:visited, a:active, a:hover {
color: #4183c4;
text-decoration: none;
}
h1, h2, h3, h4, h5, h6 {
page-break-inside: avoid;
page-break-after: avoid;
}
pre, code {
page-break-inside: avoid;
white-space: pre-wrap;
}
.fa {
display: none !important;
}

210
src/theme/css/variables.css Normal file
View File

@@ -0,0 +1,210 @@
/* Globals */
:root {
--sidebar-width: 300px;
--page-padding: 15px;
--content-max-width: 750px;
}
/* Themes */
.ayu {
--bg: #0f1419;
--fg: #c5c5c5;
--sidebar-bg: #14191f;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #5c6773;
--sidebar-active: #ffb454;
--sidebar-spacer: #2d334f;
--scrollbar: var(--sidebar-fg);
--icons: #737480;
--icons-hover: #b7b9cc;
--links: #0096cf;
--inline-code-color: #ffb454;
--theme-popup-bg: #14191f;
--theme-popup-border: #5c6773;
--theme-hover: #191f26;
--quote-bg: #262933;
--quote-border: lighten(var(--quote-bg), 5%);
--table-border-color: lighten(var(--bg), 5%);
--table-header-bg: lighten(var(--bg), 20%);
--table-alternate-bg: lighten(var(--bg), 3%);
--searchbar-border-color: #848484;
--searchbar-bg: #424242;
--searchbar-fg: #fff;
--searchbar-shadow-color: #d4c89f;
--searchresults-header-fg: #666;
--searchresults-border-color: #888;
--searchresults-li-bg: #252932;
--search-mark-bg: #e3b171;
}
.coal {
--bg: #141617;
--fg: #98a3ad;
--sidebar-bg: #292c2f;
--sidebar-fg: #a1adb8;
--sidebar-non-existant: #505254;
--sidebar-active: #3473ad;
--sidebar-spacer: #393939;
--scrollbar: var(--sidebar-fg);
--icons: #43484d;
--icons-hover: #b3c0cc;
--links: #2b79a2;
--inline-code-color: #c5c8c6;;
--theme-popup-bg: #141617;
--theme-popup-border: #43484d;
--theme-hover: #1f2124;
--quote-bg: #242637;
--quote-border: lighten(var(--quote-bg), 5%);
--table-border-color: lighten(var(--bg), 5%);
--table-header-bg: lighten(var(--bg), 20%);
--table-alternate-bg: lighten(var(--bg), 3%);
--searchbar-border-color: #aaa;
--searchbar-bg: #b7b7b7;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #666;
--searchresults-border-color: #98a3ad;
--searchresults-li-bg: #2b2b2f;
--search-mark-bg: #355c7d;
}
.light {
--bg: #ffffff;
--fg: #333333;
--sidebar-bg: #fafafa;
--sidebar-fg: #364149;
--sidebar-non-existant: #aaaaaa;
--sidebar-active: #008cff;
--sidebar-spacer: #f4f4f4;
--scrollbar: #cccccc;
--icons: #cccccc;
--icons-hover: #333333;
--links: #4183c4;
--inline-code-color: #6e6b5e;
--theme-popup-bg: #fafafa;
--theme-popup-border: #cccccc;
--theme-hover: #e6e6e6;
--quote-bg: #f2f7f9;
--quote-border: darken(var(--quote-bg), 5%);
--table-border-color: darken(var(--bg), 5%);
--table-header-bg: darken(var(--bg), 20%);
--table-alternate-bg: darken(var(--bg), 3%);
--searchbar-border-color: #aaa;
--searchbar-bg: #fafafa;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #666;
--searchresults-border-color: #888;
--searchresults-li-bg: #e4f2fe;
--search-mark-bg: #a2cff5;
}
.navy {
--bg: #161923;
--fg: #bcbdd0;
--sidebar-bg: #282d3f;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #505274;
--sidebar-active: #2b79a2;
--sidebar-spacer: #2d334f;
--scrollbar: var(--sidebar-fg);
--icons: #737480;
--icons-hover: #b7b9cc;
--links: #2b79a2;
--inline-code-color: #c5c8c6;;
--theme-popup-bg: #161923;
--theme-popup-border: #737480;
--theme-hover: #282e40;
--quote-bg: #262933;
--quote-border: lighten(var(--quote-bg), 5%);
--table-border-color: lighten(var(--bg), 5%);
--table-header-bg: lighten(var(--bg), 20%);
--table-alternate-bg: lighten(var(--bg), 3%);
--searchbar-border-color: #aaa;
--searchbar-bg: #aeaec6;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #5f5f71;
--searchresults-border-color: #5c5c68;
--searchresults-li-bg: #242430;
--search-mark-bg: #a2cff5;
}
.rust {
--bg: #e1e1db;
--fg: #262625;
--sidebar-bg: #3b2e2a;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #505254;
--sidebar-active: #e69f67;
--sidebar-spacer: #45373a;
--scrollbar: var(--sidebar-fg);
--icons: #737480;
--icons-hover: #262625;
--links: #2b79a2;
--inline-code-color: #6e6b5e;
--theme-popup-bg: #e1e1db;
--theme-popup-border: #b38f6b;
--theme-hover: #99908a;
--quote-bg: #c1c1bb;
--quote-border: darken(var(--quote-bg), 5%);
--table-border-color: darken(var(--bg), 5%);
--table-header-bg: #b3a497;
--table-alternate-bg: darken(var(--bg), 3%);
--searchbar-border-color: #aaa;
--searchbar-bg: #fafafa;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #666;
--searchresults-border-color: #888;
--searchresults-li-bg: #dec2a2;
--search-mark-bg: #e69f67;
}

View File

@@ -9,31 +9,36 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="stylesheet" href="{{ path_to_root }}book.css">
<link rel="shortcut icon" href="{{ path_to_root }}{{ favicon }}">
<link rel="stylesheet" href="{{ path_to_root }}css/variables.css">
<link rel="stylesheet" href="{{ path_to_root }}css/general.css">
<link rel="stylesheet" href="{{ path_to_root }}css/chrome.css">
<link rel="stylesheet" href="{{ path_to_root }}css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css">
<link rel="shortcut icon" href="{{ favicon }}">
<!-- Font Awesome -->
<link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="{{ path_to_root }}highlight.css">
<link rel="stylesheet" href="{{ path_to_root }}tomorrow-night.css">
<link rel="stylesheet" href="{{ path_to_root }}ayu-highlight.css">
<!-- Custom theme stylesheets -->
{{#each additional_css}}
<link rel="stylesheet" href="{{this}}">
<link rel="stylesheet" href="{{ this }}">
{{/each}}
{{#if mathjax_support}}
<!-- MathJax -->
<script async type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
{{/if}}
</head>
<body class="light">
<!-- Provide site root to javascript -->
<script type="text/javascript">var path_to_root = "{{ path_to_root }}";</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
@@ -218,12 +223,6 @@
<script src="{{ path_to_root }}theme-tomorrow_night.js" type="text/javascript" charset="utf-8"></script>
{{/if}}
{{#if search_enabled}}
<script src="{{ path_to_root }}searchindex.js" type="text/javascript" charset="utf-8"></script>
<script>
var path_to_root = "{{path_to_root}}";
</script>
{{/if}}
{{#if search_js}}
<script src="{{ path_to_root }}elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}mark.min.js" type="text/javascript" charset="utf-8"></script>

View File

@@ -13,7 +13,10 @@ use errors::*;
pub static INDEX: &'static [u8] = include_bytes!("index.hbs");
pub static HEADER: &'static [u8] = include_bytes!("header.hbs");
pub static CSS: &'static [u8] = include_bytes!("book.css");
pub static CHROME_CSS: &'static [u8] = include_bytes!("css/chrome.css");
pub static GENERAL_CSS: &'static [u8] = include_bytes!("css/general.css");
pub static PRINT_CSS: &'static [u8] = include_bytes!("css/print.css");
pub static VARIABLES_CSS: &'static [u8] = include_bytes!("css/variables.css");
pub static FAVICON: &'static [u8] = include_bytes!("favicon.png");
pub static JS: &'static [u8] = include_bytes!("book.js");
pub static HIGHLIGHT_JS: &'static [u8] = include_bytes!("highlight.js");
@@ -44,7 +47,10 @@ pub static FONT_AWESOME_OTF: &'static [u8] = include_bytes!("FontAwesome/fonts/F
pub struct Theme {
pub index: Vec<u8>,
pub header: Vec<u8>,
pub css: Vec<u8>,
pub chrome_css: Vec<u8>,
pub general_css: Vec<u8>,
pub print_css: Vec<u8>,
pub variables_css: Vec<u8>,
pub favicon: Vec<u8>,
pub js: Vec<u8>,
pub highlight_css: Vec<u8>,
@@ -72,7 +78,13 @@ impl Theme {
(theme_dir.join("index.hbs"), &mut theme.index),
(theme_dir.join("header.hbs"), &mut theme.header),
(theme_dir.join("book.js"), &mut theme.js),
(theme_dir.join("book.css"), &mut theme.css),
(theme_dir.join("css/chrome.css"), &mut theme.chrome_css),
(theme_dir.join("css/general.css"), &mut theme.general_css),
(theme_dir.join("css/print.css"), &mut theme.print_css),
(
theme_dir.join("css/variables.css"),
&mut theme.variables_css,
),
(theme_dir.join("favicon.png"), &mut theme.favicon),
(theme_dir.join("highlight.js"), &mut theme.highlight_js),
(theme_dir.join("clipboard.min.js"), &mut theme.clipboard_js),
@@ -107,7 +119,10 @@ impl Default for Theme {
Theme {
index: INDEX.to_owned(),
header: HEADER.to_owned(),
css: CSS.to_owned(),
chrome_css: CHROME_CSS.to_owned(),
general_css: GENERAL_CSS.to_owned(),
print_css: PRINT_CSS.to_owned(),
variables_css: VARIABLES_CSS.to_owned(),
favicon: FAVICON.to_owned(),
js: JS.to_owned(),
highlight_css: HIGHLIGHT_CSS.to_owned(),
@@ -138,6 +153,7 @@ fn load_file_contents<P: AsRef<Path>>(filename: P, dest: &mut Vec<u8>) -> Result
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use std::path::PathBuf;
use tempfile::Builder as TempFileBuilder;
@@ -154,21 +170,28 @@ mod tests {
#[test]
fn theme_dir_overrides_defaults() {
// Get all the non-Rust files in the theme directory
let special_files = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("src/theme")
.read_dir()
.unwrap()
.filter_map(|f| f.ok())
.map(|f| f.path())
.filter(|p| p.is_file() && !p.ends_with(".rs"));
let files = [
"index.hbs",
"header.hbs",
"favicon.png",
"css/chrome.css",
"css/general.css",
"css/print.css",
"css/variables.css",
"book.js",
"highlight.js",
"tomorrow-night.css",
"highlight.css",
"ayu-highlight.css",
"clipboard.min.js",
];
let temp = TempFileBuilder::new().prefix("mdbook").tempdir().unwrap();
let temp = TempFileBuilder::new().prefix("mdbook-").tempdir().unwrap();
fs::create_dir(temp.path().join("css")).unwrap();
// "touch" all of the special files so we have empty copies
for special_file in special_files {
let filename = temp.path().join(special_file.file_name().unwrap());
let _ = File::create(&filename);
for file in &files {
File::create(&temp.path().join(file)).unwrap();
}
let got = Theme::new(temp.path());
@@ -176,7 +199,10 @@ mod tests {
let empty = Theme {
index: Vec::new(),
header: Vec::new(),
css: Vec::new(),
chrome_css: Vec::new(),
general_css: Vec::new(),
print_css: Vec::new(),
variables_css: Vec::new(),
favicon: Vec::new(),
js: Vec::new(),
highlight_css: Vec::new(),

View File

@@ -1,12 +0,0 @@
@import "nib"
@import 'general'
@import 'sidebar'
@import 'page'
@import 'menu'
@import 'nav-icons'
@import 'theme-popup'
@import 'themes'
@import 'print'
@import 'tooltip'
@import 'searchbar'

View File

@@ -1,73 +0,0 @@
html {
font-family: "Open Sans", sans-serif
color: #333
text-size-adjust: none
}
body {
margin: 0;
font-size: 1rem;
overflow-x: hidden;
}
code {
font-family: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace;
font-size: 0.875em; // please adjust the ace font size accordingly in editor.js
}
.left {
float: left
}
.right {
float: right
}
.hidden {
display: none;
}
.play-button.hidden {
display: none;
}
h2, h3 { margin-top: 2.5em }
h4, h5 { margin-top: 2em }
.header + .header h3, .header + .header h4, .header + .header h5 { margin-top: 1em }
a.header:target h1:before,
a.header:target h2:before,
a.header:target h3:before,
a.header:target h4:before {
display: inline-block;
content: "»";
margin-left: -30px;
width: 30px;
}
table {
margin: 0 auto;
border-collapse: collapse;
td {
padding: 3px 20px;
border: 1px solid;
}
thead {
td { font-weight: 700; }
}
}
:not(.footnote-definition) + .footnote-definition,
.footnote-definition + :not(.footnote-definition) {
margin-top: 2em;
}
.footnote-definition {
font-size: 0.9em;
margin: 0.5em 0;
p { display: inline; }
}

View File

@@ -1,55 +0,0 @@
#menu-bar {
position: -webkit-sticky
position: sticky
top: 0
z-index: 101
& > #menu-bar-sticky-container {
display: flex
flex-wrap: wrap
.js & {
transition: transform 0.3s
}
}
i, .icon-button {
position: relative
margin: 0 8px
@media only screen and (max-width: $narrow-device-max-width) {
margin: 0 5px
}
z-index: 10
line-height: 50px
cursor: pointer
transition: color 0.5s
}
#print-button {
margin: 0 15px
}
}
html:not(.sidebar-visible) #menu-bar:not(:hover).folded > #menu-bar-sticky-container {
transform: translateY(-60px);
}
.left-buttons {
.no-js & { display: none }
margin: 0 5px
}
.menu-title {
display: inline-block
font-weight: 200
font-size: 20px
line-height: 50px
text-align: center
margin: 0
flex: 1
white-space: nowrap
overflow: hidden
text-overflow: ellipsis
.js & {
cursor: pointer
}
}

View File

@@ -1,55 +0,0 @@
.nav-chapters {
font-size: 2.5em
text-align: center
text-decoration: none
position: fixed
top: 50px /* Height of menu-bar */
bottom: 0
margin: 0
max-width: 150px
min-width: 90px
display: flex
justify-content: center
align-content: center
flex-direction: column
transition: color 0.5s
}
.nav-chapters:hover { text-decoration: none }
.nav-wrapper {
margin-top: 50px
display: none
}
.mobile-nav-chapters {
font-size: 2.5em
text-align: center
text-decoration: none
width: 90px
border-radius: 5px
}
.previous {
float: left
}
.next {
float: right
right: $page-padding
}
@media only screen and (max-width: $page-plus-sidebar-width) {
.nav-wide-wrapper { display: none }
.nav-wrapper { display: block }
}
@media only screen and (max-width: $page-plus-sidebar-width + $sidebar-width) {
.sidebar-visible {
.nav-wide-wrapper { display: none }
.nav-wrapper { display: block }
}
}

View File

@@ -1,43 +0,0 @@
@require 'variables'
.page-wrapper {
box-sizing: border-box
// Animation: slide away
.js & {
transition: margin-left 0.3s ease, transform 0.3s ease
}
}
.sidebar-visible .page-wrapper {
transform: translateX($sidebar-width)
@media only screen and (min-width: $sidebar-reflow-width) {
transform: none
margin-left: $sidebar-width
}
}
.page {
outline: 0
padding: 0 $page-padding
}
.content {
overflow-y: auto
padding: 0 15px
padding-bottom: 50px
main {
margin-left: auto
margin-right: auto
max-width: $content-max-width
}
a {
text-decoration: none;
&:hover { text-decoration: underline; }
}
img { max-width: 100%; }
}

View File

@@ -1,56 +0,0 @@
@media only print {
#sidebar,
#menu-bar,
.nav-chapters,
.mobile-nav-chapters {
display: none
}
#page-wrapper.page-wrapper {
transform: none;
margin-left: 0px;
overflow-y: initial;
}
#content {
max-width: none;
margin: 0;
padding: 0;
}
.page {
overflow-y: initial;
}
code {
background-color: #666666
border-radius: 5px
/* Force background to be printed in Chrome */
-webkit-print-color-adjust: exact
}
pre > .buttons {
z-index: 2;
}
a, a:visited, a:active, a:hover {
color: #4183c4
text-decoration: none
}
h1, h2, h3, h4, h5, h6 {
page-break-inside: avoid
page-break-after: avoid
}
pre, code {
page-break-inside: avoid
white-space: pre-wrap
}
.fa {
display: none !important
}
}

View File

@@ -1,66 +0,0 @@
@require 'variables'
#searchresults a {
text-decoration: none;
}
mark {
border-radius: 2px;
padding: 0 3px 1px 3px;
margin: 0 -3px -1px -3px;
transition: background-color 300ms linear;
cursor: pointer;
}
mark.fade-out {
background-color: rgba(0,0,0,0) !important;
cursor: auto;
}
.searchbar-outer {
margin-left: auto;
margin-right: auto;
max-width: $content-max-width;
}
#searchbar {
width: 100%;
margin: 5px auto 0px auto;
padding: 10px 16px;
transition: box-shadow 300ms ease-in-out;
}
.searchresults-header {
font-weight: bold;
font-size: 1em;
padding: 18px 0 0 5px;
}
.searchresults-outer {
margin-left: auto;
margin-right: auto;
max-width: $content-max-width;
}
ul#searchresults {
list-style: none;
padding-left: 20px;
li {
margin: 10px 0px;
padding: 2px;
border-radius: 2px;
}
span.teaser {
display: block;
clear: both;
margin: 5px 0 0 20px;
font-size: 0.8em;
}
span.teaser em {
font-weight: bold;
font-style: normal;
}
}

View File

@@ -1,56 +0,0 @@
@require 'variables'
.sidebar {
position: fixed
left: 0
top: 0
bottom: 0
width: $sidebar-width
overflow-y: auto
padding: 10px 10px
font-size: 0.875em
box-sizing: border-box
-webkit-overflow-scrolling: touch
overscroll-behavior-y: contain;
// Animation: slide away
.js & {
transition: transform 0.3s
}
code {
line-height: 2em;
}
}
.sidebar-hidden .sidebar {
transform: translateX(- $sidebar-width)
}
.chapter {
list-style: none outside none
padding-left: 0
line-height: 2.2em
li a {
display: block;
padding: 0
text-decoration: none
@media (-moz-touch-enabled: 1), (pointer: coarse) { padding: 5px 0; }
&:hover { text-decoration: none }
}
.spacer {
width: 100%
height: 3px
margin: 5px 0px
@media (-moz-touch-enabled: 1), (pointer: coarse) { margin: 10px 0; }
}
}
.section {
list-style: none outside none
padding-left: 20px
line-height: 1.9em
}

View File

@@ -1,31 +0,0 @@
.theme-popup {
position: absolute
left: 10px
z-index: 1000;
border-radius: 4px
font-size: 0.7em
.theme {
display: inline
border: 0
margin: 0
padding: 2px 10px
line-height: 25px
width: 100%
white-space: nowrap
text-align: left
cursor: pointer
color inherit
background: inherit;
font-size: inherit;
&:hover:first-child,
&:hover:last-child {
border-top-left-radius: inherit;
border-top-right-radius: inherit;
}
}
}

View File

@@ -1,41 +0,0 @@
$theme-name = 'ayu'
$bg = #0f1419
$fg = #c5c5c5
$sidebar-bg = #14191f
$sidebar-fg = #c8c9db
$sidebar-non-existant = #5c6773
$sidebar-active = #ffb454
$sidebar-spacer = #2d334f
$scrollbar = $sidebar-fg
$icons = #737480
$icons-hover = #b7b9cc
$links = #0096cf
$inline-code-color = #ffb454
$theme-popup-bg = #14191f
$theme-popup-border = #5c6773
$theme-hover = #191f26
$quote-bg = #262933
$quote-border = lighten($quote-bg, 5%)
$table-border-color = lighten($bg, 5%)
$table-header-bg = lighten($bg, 20%)
$table-alternate-bg = lighten($bg, 3%)
$searchbar-border-color = #848484
$searchbar-bg = #424242
$searchbar-fg = #fff
$searchbar-shadow-color = #d4c89f
$searchresults-header-fg = #666
$searchresults-border-color = #888
$searchresults-li-bg = #252932
$search-mark-bg = #e3b171
@import 'base'

View File

@@ -1,221 +0,0 @@
.{unquote($theme-name)} {
color: $fg
background-color: $bg
.content .header:link, .content .header:visited {
color: $fg;
&:hover {
text-decoration: none;
}
}
.menu-bar {
margin: auto (- $page-padding);
& > #menu-bar-sticky-container {
background-color: $bg
border-bottom-color: $bg
border-bottom-width: 1px
border-bottom-style: solid
}
&.bordered > #menu-bar-sticky-container {
border-bottom-color: $table-border-color
}
}
$table-border-color
.sidebar {
background-color: $sidebar-bg
color: $sidebar-fg
&::-webkit-scrollbar {
background: $sidebar-bg;
}
&::-webkit-scrollbar-thumb {
background: $scrollbar;
}
}
.chapter li {
color: $sidebar-non-existant
a { color: $sidebar-fg }
.active,
a:hover, {
/* Animate color change */
color: $sidebar-active
}
}
.chapter .spacer {
background-color: $sidebar-spacer
}
.menu-bar,
.menu-bar:visited,
.nav-chapters,
.nav-chapters:visited,
.mobile-nav-chapters,
.mobile-nav-chapters:visited,
.menu-bar .icon-button,
.menu-bar a i {
color: $icons
}
.menu-bar i:hover,
.menu-bar .icon-button:hover,
.nav-chapters:hover,
.mobile-nav-chapters i:hover {
color: $icons-hover
}
.mobile-nav-chapters i:hover {
color: $sidebar-fg
}
.mobile-nav-chapters {
background-color: $sidebar-bg
}
#searchresults a,
.content a:link,
a:visited,
a > .hljs {
color: $links
}
.theme-popup {
color: $fg
background: $theme-popup-bg
border: 1px solid $theme-popup-border
margin: 0;
padding: 0;
list-style: none;
display: none;
.theme:hover { background-color: $theme-hover }
.default { color: $icons }
}
blockquote {
margin: 20px 0;
padding: 0 20px;
color: $fg;
background-color: $quote-bg;
border-top: .1em solid $quote-border;
border-bottom: .1em solid $quote-border;
}
table {
td {
border-color: $table-border-color;
}
// Alternate background colors for rows
tbody tr:nth-child(2n) {
background: $table-alternate-bg;
}
thead {
background: $table-header-bg;
td { border: none; }
tr { border: 1px $table-header-bg solid; }
}
}
/* Inline code */
:not(pre) > .hljs {
display: inline-block;
vertical-align: middle;
padding: 0.1em 0.3em;
border-radius: 3px;
color: $inline-code-color;
}
a:hover > .hljs {
text-decoration: underline;
}
pre {
position: relative;
& > .buttons {
position: absolute;
z-index: 100;
right: 5px;
top: 5px;
color: $sidebar-fg;
cursor: pointer;
:hover { color: $sidebar-active; }
i { margin-left: 8px; }
button {
color: inherit;
background: transparent;
border: none;
cursor: inherit;
}
}
& > .result { margin-top: 10px; }
}
.icon-button {
border: none;
background: none;
padding: 0;
color: inherit;
i {
margin: 0;
}
}
::-webkit-scrollbar {
background: $bg;
}
::-webkit-scrollbar-thumb {
background: $scrollbar;
}
/* Search */
#searchbar {
border: 1px solid $searchbar-border-color;
border-radius: 3px;
background-color: $searchbar-bg;
color: $searchbar-fg
&:focus, &.active {
box-shadow: 0 0 3px $searchbar-shadow-color;
}
}
.searchresults-header {
color: $searchresults-header-fg;
}
.searchresults-outer {
border-bottom: 1px dashed $searchresults-border-color;
}
ul#searchresults li.focus {
background-color: $searchresults-li-bg;
}
mark {
background-color: $search-mark-bg;
}
}

View File

@@ -1,41 +0,0 @@
$theme-name = 'coal'
$bg = #141617
$fg = #98a3ad
$sidebar-bg = #292c2f
$sidebar-fg = #a1adb8
$sidebar-non-existant = #505254
$sidebar-active = #3473ad
$sidebar-spacer = #393939
$scrollbar = $sidebar-fg
$icons = #43484d
$icons-hover = #b3c0cc
$links = #2b79a2
$inline-code-color = #c5c8c6;
$theme-popup-bg = #141617
$theme-popup-border = #43484d
$theme-hover = #1f2124
$quote-bg = #242637
$quote-border = lighten($quote-bg, 5%)
$table-border-color = lighten($bg, 5%)
$table-header-bg = lighten($bg, 20%)
$table-alternate-bg = lighten($bg, 3%)
$searchbar-border-color = #aaa
$searchbar-bg = #b7b7b7
$searchbar-fg = #000
$searchbar-shadow-color = #aaa
$searchresults-header-fg = #666
$searchresults-border-color = #98a3ad
$searchresults-li-bg = #2b2b2f
$search-mark-bg = #355c7d
@import 'base'

View File

@@ -1,5 +0,0 @@
@import 'light'
@import 'coal'
@import 'navy'
@import 'rust'
@import 'ayu'

View File

@@ -1,41 +0,0 @@
$theme-name = 'light'
$bg = #ffffff
$fg = #333333
$sidebar-bg = #fafafa
$sidebar-fg = #364149
$sidebar-non-existant = #aaaaaa
$sidebar-active = #008cff
$sidebar-spacer = #f4f4f4
$scrollbar = #cccccc
$icons = #cccccc
$icons-hover = #333333
$links = #4183c4
$inline-code-color = #6e6b5e
$theme-popup-bg = #fafafa
$theme-popup-border = #cccccc
$theme-hover = #e6e6e6
$quote-bg = #f2f7f9
$quote-border = darken($quote-bg, 5%)
$table-border-color = darken($bg, 5%)
$table-header-bg = darken($bg, 20%)
$table-alternate-bg = darken($bg, 3%)
$searchbar-border-color = #aaa
$searchbar-bg = #fafafa
$searchbar-fg = #000
$searchbar-shadow-color = #aaa
$searchresults-header-fg = #666
$searchresults-border-color = #888
$searchresults-li-bg = #e4f2fe
$search-mark-bg = #a2cff5
@import 'base'

View File

@@ -1,41 +0,0 @@
$theme-name = 'navy'
$bg = #161923
$fg = #bcbdd0
$sidebar-bg = #282d3f
$sidebar-fg = #c8c9db
$sidebar-non-existant = #505274
$sidebar-active = #2b79a2
$sidebar-spacer = #2d334f
$scrollbar = $sidebar-fg
$icons = #737480
$icons-hover = #b7b9cc
$links = #2b79a2
$inline-code-color = #c5c8c6;
$theme-popup-bg = #161923
$theme-popup-border = #737480
$theme-hover = #282e40
$quote-bg = #262933
$quote-border = lighten($quote-bg, 5%)
$table-border-color = lighten($bg, 5%)
$table-header-bg = lighten($bg, 20%)
$table-alternate-bg = lighten($bg, 3%)
$searchbar-border-color = #aaa
$searchbar-bg = #aeaec6
$searchbar-fg = #000
$searchbar-shadow-color = #aaa
$searchresults-header-fg = #5f5f71
$searchresults-border-color = #5c5c68
$searchresults-li-bg = #242430
$search-mark-bg = #a2cff5
@import 'base'

View File

@@ -1,41 +0,0 @@
$theme-name = 'rust'
$bg = #e1e1db
$fg = #262625
$sidebar-bg = #3b2e2a
$sidebar-fg = #c8c9db
$sidebar-non-existant = #505254
$sidebar-active = #e69f67
$sidebar-spacer = #45373a
$scrollbar = $sidebar-fg
$icons = #737480
$icons-hover = #262625
$links = #2b79a2
$inline-code-color = #6e6b5e;
$theme-popup-bg = #e1e1db
$theme-popup-border = #b38f6b
$theme-hover = #99908a
$quote-bg = #c1c1bb
$quote-border = darken($quote-bg, 5%)
$table-border-color = darken($bg, 5%)
$table-header-bg = #b3a497
$table-alternate-bg = darken($bg, 3%)
$searchbar-border-color = #aaa
$searchbar-bg = #fafafa
$searchbar-fg = #000
$searchbar-shadow-color = #aaa
$searchresults-header-fg = #666
$searchresults-border-color = #888
$searchresults-li-bg = #dec2a2
$search-mark-bg = #e69f67
@import 'base'

View File

@@ -1,18 +0,0 @@
.tooltiptext {
position: absolute;
visibility: hidden;
color: #fff;
background-color: #333;
transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */
left: -8px; /* Half of the width of the icon */
top: -35px;
font-size: 0.8em;
text-align: center;
border-radius: 6px;
padding: 5px 8px;
margin: 5px;
z-index: 1000;
}
.tooltipped .tooltiptext {
visibility: visible;
}

View File

@@ -1,7 +0,0 @@
$sidebar-width = 300px
$page-padding = 15px
$content-max-width = 750px
$content-min-width = 320px
$page-plus-sidebar-width = $content-max-width + $sidebar-width + $page-padding * 2
$sidebar-reflow-width = $sidebar-width + $content-min-width
$narrow-device-max-width = 420px