mirror of
https://github.com/rust-lang/mdBook.git
synced 2025-12-28 13:51:10 -05:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cba988f009 | ||
|
|
9602acce80 | ||
|
|
65d7e86024 | ||
|
|
b5ec813d2f | ||
|
|
41735b4579 | ||
|
|
9cb232058b | ||
|
|
ef402c16e8 | ||
|
|
df5472ab5a | ||
|
|
d768963c30 | ||
|
|
8e7ec6e1fd | ||
|
|
80f01d70c6 | ||
|
|
40f275bf21 | ||
|
|
af8300c0b4 | ||
|
|
793a88260c | ||
|
|
1ec776244d | ||
|
|
4af107b0ca | ||
|
|
35e2807138 | ||
|
|
1632d2e339 | ||
|
|
7c3932cef9 | ||
|
|
ed1a216121 | ||
|
|
f814e96459 |
4
.gitattributes
vendored
Normal file
4
.gitattributes
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[attr]rust text eol=lf whitespace=tab-in-indent,trailing-space,tabwidth=4
|
||||
|
||||
* text=auto eol=lf
|
||||
*.rs rust
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mdbook"
|
||||
version = "0.0.18"
|
||||
version = "0.0.19"
|
||||
authors = ["Mathieu David <mathieudavid@mathieudavid.org>"]
|
||||
description = "create books from markdown files (like Gitbook)"
|
||||
documentation = "http://azerupi.github.io/mdBook/index.html"
|
||||
|
||||
@@ -72,7 +72,7 @@ There are multiple ways to install mdBook.
|
||||
|
||||
## Usage
|
||||
|
||||
mdBook will primaraly be used as a command line tool, even though it exposes all its functionality as a Rust crate for integration in other projects.
|
||||
mdBook will primarily be used as a command line tool, even though it exposes all its functionality as a Rust crate for integration in other projects.
|
||||
|
||||
Here are the main commands you will want to run. For a more exhaustive explanation, check out the [documentation](http://azerupi.github.io/mdBook/).
|
||||
|
||||
@@ -88,7 +88,7 @@ Here are the main commands you will want to run. For a more exhaustive explanati
|
||||
└── SUMMARY.md
|
||||
```
|
||||
|
||||
`book` and `src` are both directories. `src` contains the markdown files that will be used to render the ouput to the `book` directory.
|
||||
`book` and `src` are both directories. `src` contains the markdown files that will be used to render the output to the `book` directory.
|
||||
|
||||
Please, take a look at the [**Documentation**](http://azerupi.github.io/mdBook/cli/init.html) for more information and some neat tricks.
|
||||
|
||||
@@ -102,7 +102,7 @@ Here are the main commands you will want to run. For a more exhaustive explanati
|
||||
|
||||
- `mdbook serve`
|
||||
|
||||
Does the same thing as `mdbook watch` but additionally serves the book at `http://localhost:3000` (port is changeable) and reloads the browser when a change occures.
|
||||
Does the same thing as `mdbook watch` but additionally serves the book at `http://localhost:3000` (port is changeable) and reloads the browser when a change occurs.
|
||||
|
||||
### As a library
|
||||
|
||||
|
||||
@@ -37,6 +37,20 @@ pub struct MDBook {
|
||||
impl MDBook {
|
||||
/// Create a new `MDBook` struct with root directory `root`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate mdbook;
|
||||
/// # use mdbook::MDBook;
|
||||
/// # use std::path::Path;
|
||||
/// # fn main() {
|
||||
/// let book = MDBook::new(Path::new("root_dir"));
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// In this example, `root_dir` will be the root directory of our book and is specified in function
|
||||
/// of the current working directory by using a relative path instead of an absolute path.
|
||||
///
|
||||
/// Default directory paths:
|
||||
///
|
||||
/// - source: `root/src`
|
||||
@@ -286,18 +300,6 @@ impl MDBook {
|
||||
/// Parses the `book.json` file (if it exists) to extract the configuration parameters.
|
||||
/// The `book.json` file should be in the root directory of the book.
|
||||
/// The root directory is the one specified when creating a new `MDBook`
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate mdbook;
|
||||
/// # use mdbook::MDBook;
|
||||
/// # use std::path::Path;
|
||||
/// # fn main() {
|
||||
/// let mut book = MDBook::new(Path::new("root_dir"));
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// In this example, `root_dir` will be the root directory of our book and is specified in function
|
||||
/// of the current working directory by using a relative path instead of an absolute path.
|
||||
|
||||
pub fn read_config(mut self) -> Self {
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ use std::fs::{self, File};
|
||||
use std::error::Error;
|
||||
use std::io::{self, Read};
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use handlebars::Handlebars;
|
||||
|
||||
@@ -229,6 +230,7 @@ fn make_data(book: &MDBook) -> Result<serde_json::Map<String, serde_json::Value>
|
||||
|
||||
fn build_header_links(html: String, filename: &str) -> String {
|
||||
let regex = Regex::new(r"<h(\d)>(.*?)</h\d>").unwrap();
|
||||
let mut id_counter = HashMap::new();
|
||||
|
||||
regex.replace_all(&html, |caps: &Captures| {
|
||||
let level = &caps[1];
|
||||
@@ -254,7 +256,16 @@ fn build_header_links(html: String, filename: &str) -> String {
|
||||
}
|
||||
}).collect::<String>();
|
||||
|
||||
format!("<a class=\"header\" href=\"{filename}#{id}\" name=\"{id}\"><h{level}>{text}</h{level}></a>",
|
||||
let id_count = *id_counter.get(&id).unwrap_or(&0);
|
||||
id_counter.insert(id.clone(), id_count + 1);
|
||||
|
||||
let id = if id_count > 0 {
|
||||
format!("{}-{}", id, id_count)
|
||||
} else {
|
||||
id
|
||||
};
|
||||
|
||||
format!("<a class=\"header\" href=\"{filename}#{id}\" id=\"{id}\"><h{level}>{text}</h{level}></a>",
|
||||
level=level, id=id, text=text, filename=filename)
|
||||
}).into_owned()
|
||||
}
|
||||
@@ -307,11 +318,11 @@ fn add_playpen_pre(html: String) -> String {
|
||||
format!("<pre class=\"playpen\">{}</pre>", text)
|
||||
} else {
|
||||
// we need to inject our own main
|
||||
let (attrs, code) = partition_source(code);
|
||||
format!("<pre class=\"playpen\"><code class=\"{}\"># #![allow(unused_variables)]
|
||||
#
|
||||
#fn main() {{
|
||||
{}#fn main() {{
|
||||
{}
|
||||
#}}</code></pre>", classes, code)
|
||||
#}}</code></pre>", classes, attrs, code)
|
||||
}
|
||||
} else {
|
||||
// not language-rust, so no-op
|
||||
@@ -319,3 +330,25 @@ fn add_playpen_pre(html: String) -> String {
|
||||
}
|
||||
}).into_owned()
|
||||
}
|
||||
|
||||
fn partition_source(s: &str) -> (String, String) {
|
||||
let mut after_header = false;
|
||||
let mut before = String::new();
|
||||
let mut after = String::new();
|
||||
|
||||
for line in s.lines() {
|
||||
let trimline = line.trim();
|
||||
let header = trimline.chars().all(|c| c.is_whitespace()) ||
|
||||
trimline.starts_with("#![");
|
||||
if !header || after_header {
|
||||
after_header = true;
|
||||
after.push_str(line);
|
||||
after.push_str("\n");
|
||||
} else {
|
||||
before.push_str(line);
|
||||
before.push_str("\n");
|
||||
}
|
||||
}
|
||||
|
||||
(before, after)
|
||||
}
|
||||
@@ -35,7 +35,7 @@ pub fn render_playpen(s: &str, path: &Path) -> String {
|
||||
continue;
|
||||
};
|
||||
|
||||
let replacement = String::new() + "<pre class=\"playpen\"><code class=\"language-rust\">" + &file_content +
|
||||
let replacement = String::new() + "<pre><code class=\"language-rust\">" + &file_content +
|
||||
"</code></pre>";
|
||||
|
||||
replaced.push_str(&s[previous_end_index..playpen.start_index]);
|
||||
|
||||
@@ -33,7 +33,7 @@ impl HelperDef for RenderToc {
|
||||
}
|
||||
|
||||
let level = if let Some(s) = item.get("section") {
|
||||
s.len() / 2
|
||||
s.matches(".").count()
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
@@ -3,6 +3,10 @@ body {
|
||||
font-family: "Open Sans", sans-serif;
|
||||
color: #333;
|
||||
}
|
||||
code {
|
||||
font-family: "Source Code Pro", "Menlo", "DejaVu Sans Mono", monospace;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
.left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ $( document ).ready(function() {
|
||||
};
|
||||
|
||||
$(document).on('keydown', function (e) {
|
||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
||||
switch (e.keyCode) {
|
||||
case KEY_CODES.NEXT_KEY:
|
||||
e.preventDefault();
|
||||
@@ -207,6 +208,18 @@ function run_rust_code(code_block) {
|
||||
result_block = code_block.find(".result");
|
||||
}
|
||||
|
||||
let text = code_block.find(".language-rust").text();
|
||||
|
||||
let params = {
|
||||
version: "stable",
|
||||
optimize: "0",
|
||||
code: text,
|
||||
};
|
||||
|
||||
if(text.includes("#![feature")) {
|
||||
params.version = "nightly";
|
||||
}
|
||||
|
||||
result_block.text("Running...");
|
||||
|
||||
$.ajax({
|
||||
@@ -215,7 +228,7 @@ function run_rust_code(code_block) {
|
||||
crossDomain: true,
|
||||
dataType: "json",
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify({version: "stable", optimize: "0", code: code_block.find(".language-rust").text() }),
|
||||
data: JSON.stringify(params),
|
||||
success: function(response){
|
||||
result_block.text(response.result);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
<base href="{{ path_to_root }}">
|
||||
|
||||
<link rel="stylesheet" href="book.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=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 }}">
|
||||
|
||||
|
||||
@@ -3,6 +3,11 @@ html, body {
|
||||
color: #333
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "Source Code Pro", "Menlo", "DejaVu Sans Mono", monospace;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
.left {
|
||||
float: left
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user