diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs
index 810ba766..d7f47858 100644
--- a/src/renderer/html_handlebars/hbs_renderer.rs
+++ b/src/renderer/html_handlebars/hbs_renderer.rs
@@ -38,7 +38,9 @@ impl HtmlHandlebars {
BookItem::Chapter(ref ch) =>
{
let content = ch.content.clone();
- let base = ch.path.parent().expect("All chapters must have a parent directory");
+ let base = ch.path.parent()
+ .map(|dir| ctx.src_dir.join(dir))
+ .expect("All chapters must have a parent directory");
// Parse and expand links
let content = preprocess::links::replace_all(&content, base)?;
@@ -239,13 +241,14 @@ impl HtmlHandlebars {
impl Renderer for HtmlHandlebars {
fn render(&self, book: &MDBook) -> Result<()> {
let html_config = book.config.html_config().unwrap_or_default();
+ let src_dir = book.root.join(&book.config.book.src);
debug!("[fn]: render");
let mut handlebars = Handlebars::new();
let theme_dir = match html_config.theme {
- Some(ref theme) => theme,
- None => Path::new("theme"),
+ Some(ref theme) => theme.to_path_buf(),
+ None => src_dir.join("theme"),
};
let theme = theme::Theme::new(theme_dir);
@@ -282,6 +285,7 @@ impl Renderer for HtmlHandlebars {
book: book,
handlebars: &handlebars,
destination: destination.to_path_buf(),
+ src_dir: src_dir.clone(),
data: data.clone(),
is_index: i == 0,
html_config: html_config.clone(),
@@ -595,6 +599,7 @@ struct RenderItemContext<'a> {
handlebars: &'a Handlebars,
book: &'a MDBook,
destination: PathBuf,
+ src_dir: PathBuf,
data: serde_json::Map,
is_index: bool,
html_config: HtmlConfig,
diff --git a/tests/dummy_book/src/example.rs b/tests/dummy_book/src/example.rs
new file mode 100644
index 00000000..6b49705c
--- /dev/null
+++ b/tests/dummy_book/src/example.rs
@@ -0,0 +1,6 @@
+fn main() {
+ println!("Hello World!");
+#
+# // You can even hide lines! :D
+# println!("I am hidden! Expand the code snippet to see me");
+}
diff --git a/tests/dummy_book/src/second.md b/tests/dummy_book/src/second.md
index abeaa6af..539d17f8 100644
--- a/tests/dummy_book/src/second.md
+++ b/tests/dummy_book/src/second.md
@@ -1 +1,5 @@
-# Second Chapter
\ No newline at end of file
+# Second Chapter
+
+This makes sure you can insert runnable Rust files.
+
+{{#playpen example.rs}}
\ No newline at end of file
diff --git a/tests/init.rs b/tests/init.rs
index be3fc603..3515a7be 100644
--- a/tests/init.rs
+++ b/tests/init.rs
@@ -2,6 +2,7 @@ extern crate mdbook;
extern crate tempdir;
use std::path::PathBuf;
+use std::fs;
use mdbook::MDBook;
use mdbook::config::Config;
use tempdir::TempDir;
@@ -63,7 +64,7 @@ fn book_toml_isnt_required() {
let temp = TempDir::new("mdbook").unwrap();
let md = MDBook::init(temp.path()).build().unwrap();
- assert!(!temp.path().join("book.toml").exists());
+ let _ = fs::remove_file(temp.path().join("book.toml"));
md.read_config().unwrap().build().unwrap();
}
diff --git a/tests/rendered_output.rs b/tests/rendered_output.rs
index 0fcd07a5..7e595620 100644
--- a/tests/rendered_output.rs
+++ b/tests/rendered_output.rs
@@ -10,7 +10,6 @@ mod dummy_book;
use dummy_book::{assert_contains_strings, DummyBook};
use std::fs::{remove_file, File};
-use std::io::Write;
use std::path::Path;
use std::ffi::OsStr;
use walkdir::{DirEntry, WalkDir, WalkDirIterator};
@@ -256,46 +255,45 @@ fn check_spacers() {
/// not exist.
#[test]
fn failure_on_missing_file() {
- let (md, _temp) = create_missing_setup(Some(false));
+ let (mut md, _temp) = create_missing_setup(false);
// On failure, `build()` does not return a specific error, so assume
// any error is a failure due to a missing file.
- assert!(md.read_config().unwrap().build().is_err());
+ assert!(md.build().is_err());
}
/// Ensure a missing file is created if `create-missing` is true.
#[test]
fn create_missing_file_with_config() {
- let (md, temp) = create_missing_setup(Some(true));
+ let (mut md, temp) = create_missing_setup(true);
- md.read_config().unwrap().build().unwrap();
+ md.build().unwrap();
assert!(temp.path().join("src").join("intro.md").exists());
}
-/// Ensure a missing file is created if `create-missing` is not set (the default
-/// is true).
-#[test]
-fn create_missing_file_without_config() {
- let (md, temp) = create_missing_setup(None);
-
- md.read_config().unwrap().build().unwrap();
- assert!(temp.path().join("src").join("intro.md").exists());
-}
-
-fn create_missing_setup(create_missing: Option) -> (MDBook, TempDir) {
+fn create_missing_setup(create_missing: bool) -> (MDBook, TempDir) {
let temp = DummyBook::new().build().unwrap();
- let md = MDBook::load(temp.path()).unwrap();
-
- let mut file = File::create(temp.path().join("book.toml")).unwrap();
- match create_missing {
- Some(true) => file.write_all(b"[build]\ncreate-missing = true\n").unwrap(),
- Some(false) => file.write_all(b"[build]\ncreate-missing = false\n")
- .unwrap(),
- None => (),
- }
- file.flush().unwrap();
+ let mut md = MDBook::load(temp.path()).unwrap();
+ md.config.build.create_missing = create_missing;
remove_file(temp.path().join("src").join("intro.md")).unwrap();
(md, temp)
}
+
+/// This makes sure you can include a Rust file with `{{#playpen example.rs}}`.
+/// Specification is in `book-example/src/format/rust.md`
+#[test]
+fn able_to_include_rust_files_in_chapters() {
+ let temp = DummyBook::new().build().unwrap();
+ let mut md = MDBook::load(temp.path()).unwrap();
+ md.build().unwrap();
+
+ let second = temp.path().join("book/second.html");
+
+ let playpen_strings = &[
+ r#"class="playpen""#,
+ r#"println!("Hello World!");"#,
+ ];
+ assert_contains_strings(second, playpen_strings);
+}