Compare commits

..

37 Commits

Author SHA1 Message Date
Mathieu David
8b84b8fa82 (cargo-release) version 0.0.20 2017-04-26 19:22:37 +02:00
Corey Farwell
a4a708bdda Merge pull request #254 from frewsxcv/frewsxcv-no-create
Implement new 'no-create' build flag.
2017-04-21 23:03:23 -04:00
Steve Klabnik
a3b925e3ab Merge pull request #256 from steveklabnik/master
bump for 0.0.19
2017-04-18 10:52:33 -04:00
steveklabnik
cba988f009 bump for 0.0.19 2017-04-18 10:50:58 -04:00
Corey Farwell
4525810737 Rewrite an emptiness check. 2017-04-17 21:58:34 -04:00
Corey Farwell
5d72d966ad Wrap long line. 2017-04-17 21:56:01 -04:00
Corey Farwell
15dcca87d8 Refactor to prevent excessive indentation. 2017-04-17 21:55:32 -04:00
Corey Farwell
c6e81337fb Implement new 'no-create' build flag.
Fixes https://github.com/azerupi/mdBook/issues/253.
2017-04-17 21:53:27 -04:00
Steve Klabnik
9602acce80 Merge pull request #252 from crazymerlyn/fix-runnable-files
Remove the extra run button on runnable rust files
2017-04-16 11:58:07 -04:00
CrazyMerlyn
65d7e86024 Remove the extra run button on runnable rust files
The playpen helper now uses a simple pre block instead of a pre block
with class playpen as it led to nested playpens.
2017-04-16 18:17:59 +05:30
Mathieu David
b5ec813d2f Merge pull request #250 from regexident/master
Added monospace font with support for box-drawing chars
2017-04-15 20:37:17 +02:00
Vincent Esche
41735b4579 Added monospace font with support for box-drawing chars 2017-04-15 14:16:28 +02:00
Steve Klabnik
9cb232058b Merge pull request #243 from steveklabnik/gh241
Accept nightly examples.
2017-04-14 15:19:07 -04:00
Mathieu David
ef402c16e8 Merge pull request #248 from mthh/master
Fix alignement of chapters with three digit numbering
2017-04-14 20:25:21 +02:00
mthh
df5472ab5a Should fix sections created with chapter of more than two digits 2017-04-07 12:46:28 +02:00
mthh
d768963c30 Revert "should fix sections created with chapter of more than two digits"
This reverts commit 8e7ec6e1fd.
2017-04-07 10:47:45 +02:00
mthh
8e7ec6e1fd should fix sections created with chapter of more than two digits 2017-04-07 02:37:46 +02:00
steveklabnik
80f01d70c6 Accept nightly examples.
This also brings us to parity with rustdoc regarding attributes in
general; while this PR was focused on enabling nightly, that was a
happy accident.
2017-03-31 17:06:03 -04:00
Mathieu David
40f275bf21 Merge pull request #236 from steveklabnik/master
add a .gitattributes to ensure proper line ending settings
2017-03-31 15:27:11 +02:00
Mathieu David
af8300c0b4 Merge pull request #239 from tshepang/misplaced
move misplaced example
2017-03-31 15:26:00 +02:00
Tshepang Lekhonkhobe
793a88260c move misplaced example 2017-03-30 14:09:14 +02:00
Steve Klabnik
1ec776244d Merge pull request #238 from tshepang/misc
typos
2017-03-29 14:17:44 -04:00
Tshepang Lekhonkhobe
4af107b0ca typos 2017-03-29 16:42:55 +02:00
steveklabnik
35e2807138 add a .gitattributes to ensure proper line ending settings 2017-03-28 09:50:57 -04:00
Mathieu David
1632d2e339 Merge pull request #230 from crazymerlyn/ignore_arrow_keys_with_modifier
Fix keyboard navigation to trigger only if no modifier key is pressed
2017-03-26 18:49:27 +02:00
Steve Klabnik
7c3932cef9 Merge pull request #231 from crazymerlyn/fix-header-link-id
Fix header links
2017-03-24 10:24:53 -04:00
CrazyMerlyn
ed1a216121 Fix header links
Header fragment links now use "id" attribute instead of the depreciated
"name" attribute.

Similar headers are given numbered ids to avoid id collisions.
For instance, if there are three headers named "Example", their ids
would be "#example", "#example-1", and "#example-2" respectively.
2017-03-23 23:24:26 +05:30
CrazyMerlyn
f814e96459 Fix keyboard navigation to trigger only if no modifier key is pressed 2017-03-23 13:29:04 +05:30
Steve Klabnik
a7272e0ff5 Merge pull request #226 from steveklabnik/master
bump version
2017-03-10 10:40:21 -08:00
steveklabnik
1cf4774737 bump version 2017-03-10 13:39:35 -05:00
Steve Klabnik
c6a5d12002 Merge pull request #222 from steveklabnik/gh29
Implement playpen support for ```rust
2017-03-10 08:59:15 -08:00
steveklabnik
b120ce7397 inject allow(unused_variables) 2017-03-10 09:46:11 -05:00
Steve Klabnik
c7916c4818 Merge pull request #225 from integer32llc/update-hljs
Update to highlight.js 9.10.0
2017-03-10 05:53:10 -08:00
Carol (Nichols || Goulding)
56f597b90c Update to highlight.js 9.10.0 2017-03-09 22:45:59 -05:00
steveklabnik
c5f9625feb inject main 2017-03-06 13:27:25 -05:00
steveklabnik
79f00eeea3 Implement playpen support for ```rust
Fixes #29
2017-03-06 12:23:15 -05:00
Mathieu David
677fa42458 (cargo-release) start next development iteration 0.0.18-pre 2017-02-28 17:22:51 +01:00
14 changed files with 168 additions and 102 deletions

4
.gitattributes vendored Normal file
View File

@@ -0,0 +1,4 @@
[attr]rust text eol=lf whitespace=tab-in-indent,trailing-space,tabwidth=4
* text=auto eol=lf
*.rs rust

View File

@@ -1,6 +1,6 @@
[package]
name = "mdbook"
version = "0.0.17"
version = "0.0.20"
authors = ["Mathieu David <mathieudavid@mathieudavid.org>"]
description = "create books from markdown files (like Gitbook)"
documentation = "http://azerupi.github.io/mdBook/index.html"

View File

@@ -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

View File

@@ -63,6 +63,7 @@ fn main() {
.about("Build the book from the markdown files")
.arg_from_usage("-o, --open 'Open the compiled book in a web browser'")
.arg_from_usage("-d, --dest-dir=[dest-dir] 'The output directory for your book{n}(Defaults to ./book when omitted)'")
.arg_from_usage("--no-create 'Will not create non-existent files linked from SUMMARY.md'")
.arg_from_usage("[dir] 'A directory for your book{n}(Defaults to Current Directory when omitted)'"))
.subcommand(SubCommand::with_name("watch")
.about("Watch the files for changes")
@@ -174,6 +175,10 @@ fn build(args: &ArgMatches) -> Result<(), Box<Error>> {
None => book
};
if args.is_present("no-create") {
book.create_missing = false;
}
try!(book.build());
if args.is_present("open") {

View File

@@ -32,11 +32,29 @@ pub struct MDBook {
renderer: Box<Renderer>,
livereload: Option<String>,
/// Should `mdbook build` create files referenced from SUMMARY.md if they
/// don't exist
pub create_missing: bool,
}
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`
@@ -65,6 +83,7 @@ impl MDBook {
renderer: Box::new(HtmlHandlebars::new()),
livereload: None,
create_missing: true,
}
}
@@ -161,23 +180,27 @@ impl MDBook {
debug!("[*]: constructing paths for missing files");
for item in self.iter() {
debug!("[*]: item: {:?}", item);
match *item {
let ch = match *item {
BookItem::Spacer => continue,
BookItem::Chapter(_, ref ch) |
BookItem::Affix(ref ch) => {
if ch.path != PathBuf::new() {
let path = self.src.join(&ch.path);
BookItem::Affix(ref ch) => ch,
};
if ch.path.as_os_str().is_empty() {
let path = self.src.join(&ch.path);
if !path.exists() {
debug!("[*]: {:?} does not exist, trying to create file", path);
try!(::std::fs::create_dir_all(path.parent().unwrap()));
let mut f = try!(File::create(path));
// debug!("[*]: Writing to {:?}", path);
try!(writeln!(f, "# {}", ch.name));
}
if !path.exists() {
if !self.create_missing {
return Err(format!(
"'{}' referenced from SUMMARY.md does not exist.",
path.to_string_lossy()).into());
}
},
debug!("[*]: {:?} does not exist, trying to create file", path);
try!(::std::fs::create_dir_all(path.parent().unwrap()));
let mut f = try!(File::create(path));
// debug!("[*]: Writing to {:?}", path);
try!(writeln!(f, "# {}", ch.name));
}
}
}
@@ -286,18 +309,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 {

View File

@@ -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;
@@ -97,12 +98,11 @@ impl Renderer for HtmlHandlebars {
let filename = Path::new(&ch.path).with_extension("html");
// create links for headers and fix anchors
// Do several kinds of post-processing
let rendered = build_header_links(rendered, filename.to_str().unwrap_or(""));
let rendered = fix_anchor_links(rendered, filename.to_str().unwrap_or(""));
// fix code blocks
let rendered = fix_code_blocks(rendered);
let rendered = add_playpen_pre(rendered);
// Write to file
info!("[*] Creating {:?} ✓", filename.display());
@@ -146,11 +146,12 @@ impl Renderer for HtmlHandlebars {
debug!("[*]: Render template");
let rendered = try!(handlebars.render("index", &data));
// do several kinds of post-processing
let rendered = build_header_links(rendered, "print.html");
let rendered = fix_anchor_links(rendered, "print.html");
// fix code blocks
let rendered = fix_code_blocks(rendered);
let rendered = add_playpen_pre(rendered);
try!(book.write_file(Path::new("print").with_extension("html"), &rendered.into_bytes()));
info!("[*] Creating print.html ✓");
@@ -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()
}
@@ -292,3 +303,52 @@ fn fix_code_blocks(html: String) -> String {
format!("<code{before}class=\"{classes}\"{after}>", before=before, classes=classes, after=after)
}).into_owned()
}
fn add_playpen_pre(html: String) -> String {
let regex = Regex::new(r##"((?s)<code[^>]?class="([^"]+)".*?>(.*?)</code>)"##).unwrap();
regex.replace_all(&html, |caps: &Captures| {
let text = &caps[1];
let classes = &caps[2];
let code = &caps[3];
if classes.contains("language-rust") && !classes.contains("ignore") {
// wrap the contents in an external pre block
if text.contains("fn main") {
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() {{
{}
#}}</code></pre>", classes, attrs, code)
}
} else {
// not language-rust, so no-op
format!("{}", text)
}
}).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)
}

View File

@@ -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]);

View File

@@ -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
};

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -12,96 +12,59 @@
/* Atelier-Dune Comment */
.hljs-comment {
.hljs-comment,
.hljs-quote {
color: #AAA;
}
/* Atelier-Dune Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-regexp,
.hljs-name,
.ruby .hljs-constant,
.xml .hljs-tag .hljs-title,
.xml .hljs-pi,
.xml .hljs-doctype,
.html .hljs-doctype,
.css .hljs-id,
.css .hljs-class,
.css .hljs-pseudo {
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #d73737;
}
/* Atelier-Dune Orange */
.hljs-number,
.hljs-preprocessor,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-params,
.hljs-attribute,
.hljs-constant {
.hljs-type,
.hljs-params {
color: #b65611;
}
/* Atelier-Dune Yellow */
.ruby .hljs-class .hljs-title,
.css .hljs-rule .hljs-attribute {
color: #ae9513;
}
/* Atelier-Dune Green */
.hljs-string,
.hljs-value,
.hljs-inheritance,
.ruby .hljs-symbol,
.xml .hljs-cdata {
color: #2a9292;
}
/* Atelier-Dune Aqua */
.hljs-title,
.css .hljs-hexcolor {
color: #1fad83;
.hljs-symbol,
.hljs-bullet {
color: #60ac39;
}
/* Atelier-Dune Blue */
.hljs-function,
.python .hljs-decorator,
.python .hljs-title,
.ruby .hljs-function .hljs-title,
.ruby .hljs-title .hljs-keyword,
.perl .hljs-sub,
.javascript .hljs-title,
.coffeescript .hljs-title {
.hljs-title,
.hljs-section {
color: #6684e1;
}
/* Atelier-Dune Purple */
.hljs-keyword,
.javascript .hljs-function {
.hljs-selector-tag {
color: #b854d4;
}
.coffeescript .javascript,
.javascript .xml,
.tex .hljs-formula,
.xml .javascript,
.xml .vbscript,
.xml .css,
.xml .hljs-cdata {
opacity: 0.5;
.hljs-emphasis {
font-style: italic;
}
/* markdown */
.hljs-header {
color: #A30000;
}
.hljs-link_label {
color: #33CCCC;
}
.hljs-link_url {
color: #CC66FF;
.hljs-strong {
font-weight: bold;
}

File diff suppressed because one or more lines are too long

View File

@@ -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 }}">

View File

@@ -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
}