Merge branch 'master' into watch-command
This commit is contained in:
commit
b40688c880
20
Cargo.toml
20
Cargo.toml
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "mdbook"
|
name = "mdbook"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["Mathieu David <mathieudavid@mathieudavid.org>"]
|
authors = ["Mathieu David <mathieudavid@mathieudavid.org>"]
|
||||||
description = "create books from markdown files (like Gitbook)"
|
description = "create books from markdown files (like Gitbook)"
|
||||||
documentation = "http://azerupi.github.io/mdBook/index.html"
|
documentation = "http://azerupi.github.io/mdBook/index.html"
|
||||||
|
@ -15,11 +15,11 @@ exclude = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "*"
|
clap = "~1.5.3"
|
||||||
handlebars = "*"
|
handlebars = "~0.12.0"
|
||||||
rustc-serialize = "*"
|
rustc-serialize = "~0.3.16"
|
||||||
pulldown-cmark = "*"
|
pulldown-cmark = "~0.0.3"
|
||||||
crossbeam = "^0.1.5"
|
|
||||||
|
|
||||||
# Watch feature
|
# Watch feature
|
||||||
[dependencies.notify]
|
[dependencies.notify]
|
||||||
|
@ -30,9 +30,13 @@ optional = true
|
||||||
time = "^0.1.33"
|
time = "^0.1.33"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
|
[dependencies.crossbeam]
|
||||||
|
time = "^0.2.0"
|
||||||
|
optional = true
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempdir = "*"
|
tempdir = "~0.3.4"
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
@ -40,7 +44,7 @@ default = ["output", "watch"]
|
||||||
debug = []
|
debug = []
|
||||||
output = []
|
output = []
|
||||||
regenerate-css = []
|
regenerate-css = []
|
||||||
watch = ["notify", "time"]
|
watch = ["notify", "time", "crossbeam"]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
doc = false
|
doc = false
|
||||||
|
|
|
@ -13,14 +13,10 @@ To have an idea of what a rendered book looks like,take a look at the [**Documen
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone --depth=1 https://github.com/azerupi/mdBook.git
|
cargo install mdbook
|
||||||
cd mdBook
|
|
||||||
cargo build --release
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The executable `mdbook` will be in the `./target/release` folder, this should be added to the path.
|
If you want to regenerate the css (stylesheet), clone the git repo locally and make sure that you installed `stylus` and `nib` from `npm` because it is used to compile the stylesheets
|
||||||
|
|
||||||
If you want to regenerate the css (stylesheet), make sure that you installed `stylus` and `nib` from `npm` because it is used to compile the stylesheets
|
|
||||||
|
|
||||||
Install [node.js](https://nodejs.org/en/)
|
Install [node.js](https://nodejs.org/en/)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#[macro_use]
|
||||||
extern crate mdbook;
|
extern crate mdbook;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
|
@ -49,6 +50,8 @@ fn main() {
|
||||||
.subcommand(SubCommand::with_name("watch")
|
.subcommand(SubCommand::with_name("watch")
|
||||||
.about("Watch the files for changes")
|
.about("Watch the files for changes")
|
||||||
.arg_from_usage("[dir] 'A directory for your book{n}(Defaults to Current Directory when ommitted)'"))
|
.arg_from_usage("[dir] 'A directory for your book{n}(Defaults to Current Directory when ommitted)'"))
|
||||||
|
.subcommand(SubCommand::with_name("test")
|
||||||
|
.about("Test that code samples compile"))
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
// Check which subcomamnd the user ran...
|
// Check which subcomamnd the user ran...
|
||||||
|
@ -57,6 +60,7 @@ fn main() {
|
||||||
("build", Some(sub_matches)) => build(sub_matches),
|
("build", Some(sub_matches)) => build(sub_matches),
|
||||||
#[cfg(feature = "watch")]
|
#[cfg(feature = "watch")]
|
||||||
("watch", Some(sub_matches)) => watch(sub_matches),
|
("watch", Some(sub_matches)) => watch(sub_matches),
|
||||||
|
("test", Some(sub_matches)) => test(sub_matches),
|
||||||
(_, _) => unreachable!()
|
(_, _) => unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -142,8 +146,17 @@ fn watch(args: &ArgMatches) -> Result<(), Box<Error>> {
|
||||||
match w {
|
match w {
|
||||||
Ok(mut watcher) => {
|
Ok(mut watcher) => {
|
||||||
|
|
||||||
watcher.watch(book.get_src()).unwrap();
|
// Add the source directory to the watcher
|
||||||
watcher.watch(book_dir.join("book.json")).unwrap();
|
if let Err(e) = watcher.watch(book.get_src()) {
|
||||||
|
println!("Error while watching {:?}:\n {:?}", book.get_src(), e);
|
||||||
|
::std::process::exit(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add the book.json file to the watcher if it exists, because it's not
|
||||||
|
// located in the source directory
|
||||||
|
if let Err(_) = watcher.watch(book_dir.join("book.json")) {
|
||||||
|
// do nothing if book.json is not found
|
||||||
|
}
|
||||||
|
|
||||||
let previous_time = time::get_time().sec;
|
let previous_time = time::get_time().sec;
|
||||||
|
|
||||||
|
@ -184,11 +197,22 @@ fn watch(args: &ArgMatches) -> Result<(), Box<Error>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn test(args: &ArgMatches) -> Result<(), Box<Error>> {
|
||||||
|
let book_dir = get_book_dir(args);
|
||||||
|
let mut book = MDBook::new(&book_dir).read_config();
|
||||||
|
|
||||||
|
try!(book.test());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Helper function that returns the right path if either a relative or absolute path is passed
|
|
||||||
fn get_book_dir(args: &ArgMatches) -> PathBuf {
|
fn get_book_dir(args: &ArgMatches) -> PathBuf {
|
||||||
if let Some(dir) = args.value_of("dir") {
|
if let Some(dir) = args.value_of("dir") {
|
||||||
// Check if path is relative from current dir, or absolute...
|
// Check if path is relative from current dir, or absolute...
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::Write;
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::io;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::io::ErrorKind;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
use {BookConfig, BookItem, theme, parse, utils};
|
use {BookConfig, BookItem, theme, parse, utils};
|
||||||
use book::BookItems;
|
use book::BookItems;
|
||||||
|
@ -257,6 +260,39 @@ impl MDBook {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn test(&mut self) -> Result<(), Box<Error>> {
|
||||||
|
// read in the chapters
|
||||||
|
try!(self.parse_summary());
|
||||||
|
for item in self.iter() {
|
||||||
|
|
||||||
|
match *item {
|
||||||
|
BookItem::Chapter(_, ref ch) => {
|
||||||
|
if ch.path != PathBuf::new() {
|
||||||
|
|
||||||
|
let path = self.get_src().join(&ch.path);
|
||||||
|
|
||||||
|
println!("[*]: Testing file: {:?}", path);
|
||||||
|
|
||||||
|
let output_result = Command::new("rustdoc")
|
||||||
|
.arg(&path)
|
||||||
|
.arg("--test")
|
||||||
|
.output();
|
||||||
|
let output = try!(output_result);
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
return Err(Box::new(io::Error::new(ErrorKind::Other, format!(
|
||||||
|
"{}\n{}",
|
||||||
|
String::from_utf8_lossy(&output.stdout),
|
||||||
|
String::from_utf8_lossy(&output.stderr)))) as Box<Error>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_dest(mut self, dest: &Path) -> Self {
|
pub fn set_dest(mut self, dest: &Path) -> Self {
|
||||||
|
|
||||||
// Handle absolute and relative paths
|
// Handle absolute and relative paths
|
||||||
|
|
|
@ -114,7 +114,7 @@ impl Renderer for HtmlHandlebars {
|
||||||
|
|
||||||
// This could cause a problem when someone displays code containing <base href=...>
|
// This could cause a problem when someone displays code containing <base href=...>
|
||||||
// on the front page, however this case should be very very rare...
|
// on the front page, however this case should be very very rare...
|
||||||
content = content.lines().filter(|line| !line.contains("<base href=")).collect();
|
content = content.lines().filter(|line| !line.contains("<base href=")).collect::<Vec<&str>>().join("\n");
|
||||||
|
|
||||||
try!(index_file.write_all(content.as_bytes()));
|
try!(index_file.write_all(content.as_bytes()));
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub fn previous(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext
|
||||||
// Decode json format
|
// Decode json format
|
||||||
let decoded: Vec<BTreeMap<String, String>> = match json::decode(&chapters.to_string()) {
|
let decoded: Vec<BTreeMap<String, String>> = match json::decode(&chapters.to_string()) {
|
||||||
Ok(data) => data,
|
Ok(data) => data,
|
||||||
Err(_) => return Err(RenderError{ desc: "Could not decode the JSON data"}),
|
Err(_) => return Err(RenderError{ desc: "Could not decode the JSON data".to_owned()}),
|
||||||
};
|
};
|
||||||
let mut previous: Option<BTreeMap<String, String>> = None;
|
let mut previous: Option<BTreeMap<String, String>> = None;
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ pub fn previous(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
debug!("[*]: No title found for chapter");
|
debug!("[*]: No title found for chapter");
|
||||||
return Err(RenderError{ desc: "No title found for chapter in JSON data" })
|
return Err(RenderError{ desc: "No title found for chapter in JSON data".to_owned() })
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,10 +68,10 @@ pub fn previous(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext
|
||||||
|
|
||||||
match path.to_str() {
|
match path.to_str() {
|
||||||
Some(p) => { previous_chapter.insert("link".to_owned(), p.to_json()); },
|
Some(p) => { previous_chapter.insert("link".to_owned(), p.to_json()); },
|
||||||
None => return Err(RenderError{ desc: "Link could not be converted to str" })
|
None => return Err(RenderError{ desc: "Link could not be converted to str".to_owned() })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => return Err(RenderError{ desc: "No path found for chapter in JSON data" })
|
None => return Err(RenderError{ desc: "No path found for chapter in JSON data".to_owned() })
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("[*]: Inject in context");
|
debug!("[*]: Inject in context");
|
||||||
|
@ -84,7 +84,7 @@ pub fn previous(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
try!(t.render(&updated_context, r, rc));
|
try!(t.render(&updated_context, r, rc));
|
||||||
},
|
},
|
||||||
None => return Err(RenderError{ desc: "Error with the handlebars template" })
|
None => return Err(RenderError{ desc: "Error with the handlebars template".to_owned() })
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ pub fn next(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext) ->
|
||||||
// Decode json format
|
// Decode json format
|
||||||
let decoded: Vec<BTreeMap<String, String>> = match json::decode(&chapters.to_string()) {
|
let decoded: Vec<BTreeMap<String, String>> = match json::decode(&chapters.to_string()) {
|
||||||
Ok(data) => data,
|
Ok(data) => data,
|
||||||
Err(_) => return Err(RenderError{ desc: "Could not decode the JSON data"}),
|
Err(_) => return Err(RenderError{ desc: "Could not decode the JSON data".to_owned() }),
|
||||||
};
|
};
|
||||||
let mut previous: Option<BTreeMap<String, String>> = None;
|
let mut previous: Option<BTreeMap<String, String>> = None;
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ pub fn next(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext) ->
|
||||||
|
|
||||||
let previous_path = match previous.get("path") {
|
let previous_path = match previous.get("path") {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => return Err(RenderError{ desc: "No path found for chapter in JSON data"})
|
None => return Err(RenderError{ desc: "No path found for chapter in JSON data".to_owned() })
|
||||||
};
|
};
|
||||||
|
|
||||||
if previous_path == ¤t {
|
if previous_path == ¤t {
|
||||||
|
@ -155,7 +155,7 @@ pub fn next(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext) ->
|
||||||
debug!("[*]: Inserting title: {}", n);
|
debug!("[*]: Inserting title: {}", n);
|
||||||
next_chapter.insert("title".to_owned(), n.to_json());
|
next_chapter.insert("title".to_owned(), n.to_json());
|
||||||
}
|
}
|
||||||
None => return Err(RenderError{ desc: "No title found for chapter in JSON data"})
|
None => return Err(RenderError{ desc: "No title found for chapter in JSON data".to_owned() })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ pub fn next(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext) ->
|
||||||
|
|
||||||
match link.to_str() {
|
match link.to_str() {
|
||||||
Some(l) => { next_chapter.insert("link".to_owned(), l.to_json()); },
|
Some(l) => { next_chapter.insert("link".to_owned(), l.to_json()); },
|
||||||
None => return Err(RenderError{ desc: "Link could not converted to str"})
|
None => return Err(RenderError{ desc: "Link could not converted to str".to_owned() })
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("[*]: Inject in context");
|
debug!("[*]: Inject in context");
|
||||||
|
@ -178,7 +178,7 @@ pub fn next(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext) ->
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
try!(t.render(&updated_context, r, rc));
|
try!(t.render(&updated_context, r, rc));
|
||||||
},
|
},
|
||||||
None => return Err(RenderError{ desc: "Error with the handlebars template" })
|
None => return Err(RenderError{ desc: "Error with the handlebars template".to_owned() })
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
|
@ -9,6 +9,9 @@ body {
|
||||||
.right {
|
.right {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
h2,
|
h2,
|
||||||
h3 {
|
h3 {
|
||||||
margin-top: 2.5em;
|
margin-top: 2.5em;
|
||||||
|
@ -222,7 +225,7 @@ h3 {
|
||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
.next {
|
.next {
|
||||||
right: 0;
|
right: 15px;
|
||||||
}
|
}
|
||||||
.theme-popup {
|
.theme-popup {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
@ -270,9 +273,30 @@ h3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.light {
|
.light {
|
||||||
|
/* Inline code */
|
||||||
color: #333;
|
color: #333;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
.light :not(pre) > .hljs {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
padding: 0.1em 0.3em;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.light pre {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.light pre > i {
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
top: 5px;
|
||||||
|
color: #364149;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.light pre > i :hover {
|
||||||
|
color: #008cff;
|
||||||
|
}
|
||||||
.light .sidebar {
|
.light .sidebar {
|
||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
color: #364149;
|
color: #364149;
|
||||||
|
@ -307,7 +331,7 @@ h3 {
|
||||||
.light .mobile-nav-chapters {
|
.light .mobile-nav-chapters {
|
||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
}
|
}
|
||||||
.light .content a {
|
.light .content a:link {
|
||||||
color: #4183c4;
|
color: #4183c4;
|
||||||
}
|
}
|
||||||
.light .theme-popup {
|
.light .theme-popup {
|
||||||
|
@ -318,9 +342,30 @@ h3 {
|
||||||
background-color: #e6e6e6;
|
background-color: #e6e6e6;
|
||||||
}
|
}
|
||||||
.coal {
|
.coal {
|
||||||
|
/* Inline code */
|
||||||
color: #98a3ad;
|
color: #98a3ad;
|
||||||
background-color: #141617;
|
background-color: #141617;
|
||||||
}
|
}
|
||||||
|
.coal :not(pre) > .hljs {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
padding: 0.1em 0.3em;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.coal pre {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.coal pre > i {
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
top: 5px;
|
||||||
|
color: #a1adb8;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.coal pre > i :hover {
|
||||||
|
color: #3473ad;
|
||||||
|
}
|
||||||
.coal .sidebar {
|
.coal .sidebar {
|
||||||
background-color: #292c2f;
|
background-color: #292c2f;
|
||||||
color: #a1adb8;
|
color: #a1adb8;
|
||||||
|
@ -355,7 +400,7 @@ h3 {
|
||||||
.coal .mobile-nav-chapters {
|
.coal .mobile-nav-chapters {
|
||||||
background-color: #292c2f;
|
background-color: #292c2f;
|
||||||
}
|
}
|
||||||
.coal .content a {
|
.coal .content a:link {
|
||||||
color: #2b79a2;
|
color: #2b79a2;
|
||||||
}
|
}
|
||||||
.coal .theme-popup {
|
.coal .theme-popup {
|
||||||
|
@ -366,9 +411,30 @@ h3 {
|
||||||
background-color: #1f2124;
|
background-color: #1f2124;
|
||||||
}
|
}
|
||||||
.navy {
|
.navy {
|
||||||
|
/* Inline code */
|
||||||
color: #bcbdd0;
|
color: #bcbdd0;
|
||||||
background-color: #161923;
|
background-color: #161923;
|
||||||
}
|
}
|
||||||
|
.navy :not(pre) > .hljs {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
padding: 0.1em 0.3em;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.navy pre {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.navy pre > i {
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
top: 5px;
|
||||||
|
color: #c8c9db;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.navy pre > i :hover {
|
||||||
|
color: #2b79a2;
|
||||||
|
}
|
||||||
.navy .sidebar {
|
.navy .sidebar {
|
||||||
background-color: #282d3f;
|
background-color: #282d3f;
|
||||||
color: #c8c9db;
|
color: #c8c9db;
|
||||||
|
@ -403,7 +469,7 @@ h3 {
|
||||||
.navy .mobile-nav-chapters {
|
.navy .mobile-nav-chapters {
|
||||||
background-color: #282d3f;
|
background-color: #282d3f;
|
||||||
}
|
}
|
||||||
.navy .content a {
|
.navy .content a:link {
|
||||||
color: #2b79a2;
|
color: #2b79a2;
|
||||||
}
|
}
|
||||||
.navy .theme-popup {
|
.navy .theme-popup {
|
||||||
|
@ -414,9 +480,30 @@ h3 {
|
||||||
background-color: #282e40;
|
background-color: #282e40;
|
||||||
}
|
}
|
||||||
.rust {
|
.rust {
|
||||||
|
/* Inline code */
|
||||||
color: #262625;
|
color: #262625;
|
||||||
background-color: #e1e1db;
|
background-color: #e1e1db;
|
||||||
}
|
}
|
||||||
|
.rust :not(pre) > .hljs {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
padding: 0.1em 0.3em;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.rust pre {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.rust pre > i {
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
top: 5px;
|
||||||
|
color: #c8c9db;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.rust pre > i :hover {
|
||||||
|
color: #e69f67;
|
||||||
|
}
|
||||||
.rust .sidebar {
|
.rust .sidebar {
|
||||||
background-color: #3b2e2a;
|
background-color: #3b2e2a;
|
||||||
color: #c8c9db;
|
color: #c8c9db;
|
||||||
|
@ -451,7 +538,7 @@ h3 {
|
||||||
.rust .mobile-nav-chapters {
|
.rust .mobile-nav-chapters {
|
||||||
background-color: #3b2e2a;
|
background-color: #3b2e2a;
|
||||||
}
|
}
|
||||||
.rust .content a {
|
.rust .content a:link {
|
||||||
color: #2b79a2;
|
color: #2b79a2;
|
||||||
}
|
}
|
||||||
.rust .theme-popup {
|
.rust .theme-popup {
|
||||||
|
|
|
@ -8,7 +8,7 @@ $( document ).ready(function() {
|
||||||
|
|
||||||
// Set theme
|
// Set theme
|
||||||
var theme = localStorage.getItem('theme');
|
var theme = localStorage.getItem('theme');
|
||||||
if (theme == null) { theme = 'light'; }
|
if (theme === null) { theme = 'light'; }
|
||||||
|
|
||||||
set_theme(theme);
|
set_theme(theme);
|
||||||
|
|
||||||
|
@ -28,6 +28,15 @@ $( document ).ready(function() {
|
||||||
var html = $("html");
|
var html = $("html");
|
||||||
var sidebar = $("#sidebar");
|
var sidebar = $("#sidebar");
|
||||||
var page_wrapper = $("#page-wrapper");
|
var page_wrapper = $("#page-wrapper");
|
||||||
|
var content = $("#content");
|
||||||
|
|
||||||
|
|
||||||
|
// Add anchors for all content headers
|
||||||
|
content.find("h1, h2, h3, h4, h5").wrap(function(){
|
||||||
|
var wrapper = $("<a>");
|
||||||
|
wrapper.attr("name", $(this).text());
|
||||||
|
return wrapper;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Toggle sidebar
|
// Toggle sidebar
|
||||||
|
@ -50,6 +59,13 @@ $( document ).ready(function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Scroll sidebar to current active section
|
||||||
|
var activeSection = sidebar.find(".active");
|
||||||
|
if(activeSection.length) {
|
||||||
|
sidebar.scrollTop(activeSection.offset().top);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Print button
|
// Print button
|
||||||
$("#print-button").click(function(){
|
$("#print-button").click(function(){
|
||||||
var printWindow = window.open("print.html");
|
var printWindow = window.open("print.html");
|
||||||
|
@ -77,7 +93,7 @@ $( document ).ready(function() {
|
||||||
$('.theme').click(function(){
|
$('.theme').click(function(){
|
||||||
var theme = $(this).attr('id');
|
var theme = $(this).attr('id');
|
||||||
|
|
||||||
set_theme(theme)
|
set_theme(theme);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,4 +112,54 @@ $( document ).ready(function() {
|
||||||
|
|
||||||
$('body').removeClass().addClass(theme);
|
$('body').removeClass().addClass(theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Hide Rust code lines prepended with a specific character
|
||||||
|
var hiding_character = "#";
|
||||||
|
|
||||||
|
$("code.language-rust").each(function(i, block){
|
||||||
|
|
||||||
|
// hide lines
|
||||||
|
var lines = $(this).html().split("\n");
|
||||||
|
var first_non_hidden_line = false;
|
||||||
|
var lines_hidden = false;
|
||||||
|
|
||||||
|
for(var n = 0; n < lines.length; n++){
|
||||||
|
if($.trim(lines[n])[0] == hiding_character){
|
||||||
|
if(first_non_hidden_line){
|
||||||
|
lines[n] = "<span class=\"hidden\">" + "\n" + lines[n].substr(1) + "</span>";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lines[n] = "<span class=\"hidden\">" + lines[n].substr(1) + "\n" + "</span>";
|
||||||
|
}
|
||||||
|
lines_hidden = true;
|
||||||
|
}
|
||||||
|
else if(first_non_hidden_line) {
|
||||||
|
lines[n] = "\n" + lines[n];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
first_non_hidden_line = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$(this).html(lines.join(""));
|
||||||
|
|
||||||
|
// If no lines were hidden, return
|
||||||
|
if(!lines_hidden) { return; }
|
||||||
|
|
||||||
|
// add expand button
|
||||||
|
$(this).parent().prepend("<i class=\"fa fa-expand\"></i>");
|
||||||
|
|
||||||
|
$(this).parent().find("i").click(function(e){
|
||||||
|
if( $(this).hasClass("fa-expand") ) {
|
||||||
|
$(this).removeClass("fa-expand").addClass("fa-compress");
|
||||||
|
$(this).parent().find("span.hidden").removeClass("hidden").addClass("unhidden");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(this).removeClass("fa-compress").addClass("fa-expand");
|
||||||
|
$(this).parent().find("span.unhidden").removeClass("unhidden").addClass("hidden");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,14 +10,6 @@
|
||||||
-webkit-text-size-adjust: none;
|
-webkit-text-size-adjust: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inline code */
|
|
||||||
:not(pre) > .hljs {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
padding: 0.1em 0.3em;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Atelier-Dune Comment */
|
/* Atelier-Dune Comment */
|
||||||
.hljs-comment {
|
.hljs-comment {
|
||||||
|
|
|
@ -11,4 +11,8 @@ html, body {
|
||||||
float: right
|
float: right
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
h2, h3 { margin-top: 2.5em }
|
h2, h3 { margin-top: 2.5em }
|
||||||
|
|
|
@ -20,4 +20,4 @@
|
||||||
.mobile-nav-chapters { display: none }
|
.mobile-nav-chapters { display: none }
|
||||||
.nav-chapters:hover { text-decoration: none }
|
.nav-chapters:hover { text-decoration: none }
|
||||||
.previous { left: 0 }
|
.previous { left: 0 }
|
||||||
.next { right: 0 }
|
.next { right: 15px }
|
||||||
|
|
|
@ -1,4 +1,28 @@
|
||||||
.{unquote($theme-name)} {
|
.{unquote($theme-name)} {
|
||||||
|
/* Inline code */
|
||||||
|
:not(pre) > .hljs {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
padding: 0.1em 0.3em;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
pre > i {
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
top: 5px;
|
||||||
|
|
||||||
|
color: $sidebar-fg;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
:hover {
|
||||||
|
color: $sidebar-active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
color: $fg
|
color: $fg
|
||||||
background-color: $bg
|
background-color: $bg
|
||||||
|
|
||||||
|
@ -43,7 +67,7 @@
|
||||||
background-color: $sidebar-bg
|
background-color: $sidebar-bg
|
||||||
}
|
}
|
||||||
|
|
||||||
.content a {
|
.content a:link {
|
||||||
color: $links
|
color: $links
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue