From cef62ec42efdaca9cc24467c2081e1b541b396ed Mon Sep 17 00:00:00 2001 From: Behnam Esfahbod Date: Fri, 1 Sep 2017 16:40:39 -0700 Subject: [PATCH 1/4] Fix build and test warnings Move non-test test module files into their own directories to prevent cargo from running them as tests. Then suppress the left-over warnings. Move *dummy book* code and data into a shared folder, and leave the rest of helper utilities (one function) in the original module. --- src/lib.rs | 2 + tests/{dummy-book => dummy/book}/SUMMARY.md | 0 .../{dummy-book => dummy/book}/conclusion.md | 0 .../{dummy-book => dummy/book}/first/index.md | 2 +- .../book}/first/nested.md | 0 tests/{dummy-book => dummy/book}/intro.md | 0 tests/{dummy-book => dummy/book}/second.md | 0 tests/{helpers.rs => dummy/mod.rs} | 44 +++++-------------- tests/helpers/mod.rs | 27 ++++++++++++ tests/rendered_output.rs | 28 +++++++----- tests/testing.rs | 12 ++--- 11 files changed, 65 insertions(+), 50 deletions(-) rename tests/{dummy-book => dummy/book}/SUMMARY.md (100%) rename tests/{dummy-book => dummy/book}/conclusion.md (100%) rename tests/{dummy-book => dummy/book}/first/index.md (60%) rename tests/{dummy-book => dummy/book}/first/nested.md (100%) rename tests/{dummy-book => dummy/book}/intro.md (100%) rename tests/{dummy-book => dummy/book}/second.md (100%) rename tests/{helpers.rs => dummy/mod.rs} (61%) create mode 100644 tests/helpers/mod.rs diff --git a/src/lib.rs b/src/lib.rs index fff77bbd..f1a0d235 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,6 +100,8 @@ pub use book::BookItem; pub use renderer::Renderer; /// The error types used through out this crate. +// TODO: Drop after error_chain is fixed +#[allow(unused_doc_comment)] pub mod errors { error_chain!{ foreign_links { diff --git a/tests/dummy-book/SUMMARY.md b/tests/dummy/book/SUMMARY.md similarity index 100% rename from tests/dummy-book/SUMMARY.md rename to tests/dummy/book/SUMMARY.md diff --git a/tests/dummy-book/conclusion.md b/tests/dummy/book/conclusion.md similarity index 100% rename from tests/dummy-book/conclusion.md rename to tests/dummy/book/conclusion.md diff --git a/tests/dummy-book/first/index.md b/tests/dummy/book/first/index.md similarity index 60% rename from tests/dummy-book/first/index.md rename to tests/dummy/book/first/index.md index d778d9db..215ebc71 100644 --- a/tests/dummy-book/first/index.md +++ b/tests/dummy/book/first/index.md @@ -1,3 +1,3 @@ # First Chapter -more text. \ No newline at end of file +more text. diff --git a/tests/dummy-book/first/nested.md b/tests/dummy/book/first/nested.md similarity index 100% rename from tests/dummy-book/first/nested.md rename to tests/dummy/book/first/nested.md diff --git a/tests/dummy-book/intro.md b/tests/dummy/book/intro.md similarity index 100% rename from tests/dummy-book/intro.md rename to tests/dummy/book/intro.md diff --git a/tests/dummy-book/second.md b/tests/dummy/book/second.md similarity index 100% rename from tests/dummy-book/second.md rename to tests/dummy/book/second.md diff --git a/tests/helpers.rs b/tests/dummy/mod.rs similarity index 61% rename from tests/helpers.rs rename to tests/dummy/mod.rs index b626ec46..ca561d86 100644 --- a/tests/helpers.rs +++ b/tests/dummy/mod.rs @@ -1,26 +1,23 @@ -//! Helpers for tests which exercise the overall application, in particular -//! the `MDBook` initialization and build/rendering process. -//! //! This will create an entire book in a temporary directory using some //! dummy contents from the `tests/dummy-book/` directory. +// Not all features are used in all test crates, so... +#![allow(dead_code, unused_extern_crates)] -#![allow(dead_code, unused_variables, unused_imports)] extern crate tempdir; -use std::path::Path; -use std::fs::{self, File}; -use std::io::{Read, Write}; +use std::fs::{create_dir_all, File}; +use std::io::Write; use tempdir::TempDir; -const SUMMARY_MD: &'static str = include_str!("dummy-book/SUMMARY.md"); -const INTRO: &'static str = include_str!("dummy-book/intro.md"); -const FIRST: &'static str = include_str!("dummy-book/first/index.md"); -const NESTED: &'static str = include_str!("dummy-book/first/nested.md"); -const SECOND: &'static str = include_str!("dummy-book/second.md"); -const CONCLUSION: &'static str = include_str!("dummy-book/conclusion.md"); +const SUMMARY_MD: &'static str = include_str!("book/SUMMARY.md"); +const INTRO: &'static str = include_str!("book/intro.md"); +const FIRST: &'static str = include_str!("book/first/index.md"); +const NESTED: &'static str = include_str!("book/first/nested.md"); +const SECOND: &'static str = include_str!("book/second.md"); +const CONCLUSION: &'static str = include_str!("book/conclusion.md"); /// Create a dummy book in a temporary directory, using the contents of @@ -58,10 +55,10 @@ impl DummyBook { let temp = TempDir::new("dummy_book").unwrap(); let src = temp.path().join("src"); - fs::create_dir_all(&src).unwrap(); + create_dir_all(&src).unwrap(); let first = src.join("first"); - fs::create_dir_all(&first).unwrap(); + create_dir_all(&first).unwrap(); let to_substitute = if self.passing_test { "true" } else { "false" }; let nested_text = NESTED.replace("$TEST_STATUS", to_substitute); @@ -91,20 +88,3 @@ impl Default for DummyBook { DummyBook { passing_test: true } } } - - -/// Read the contents of the provided file into memory and then iterate through -/// the list of strings asserting that the file contains all of them. -pub fn assert_contains_strings>(filename: P, strings: &[&str]) { - let filename = filename.as_ref(); - - let mut content = String::new(); - File::open(&filename) - .expect("Couldn't open the provided file") - .read_to_string(&mut content) - .expect("Couldn't read the file's contents"); - - for s in strings { - assert!(content.contains(s), "Searching for {:?} in {}\n\n{}", s, filename.display(), content); - } -} diff --git a/tests/helpers/mod.rs b/tests/helpers/mod.rs new file mode 100644 index 00000000..e0682d15 --- /dev/null +++ b/tests/helpers/mod.rs @@ -0,0 +1,27 @@ +//! Helpers for tests which exercise the overall application, in particular +//! the `MDBook` initialization and build/rendering process. +//! +//! This will create an entire book in a temporary directory using some +//! dummy contents from the `tests/dummy-book/` directory. + + +use std::path::Path; +use std::fs::File; +use std::io::Read; + + +/// Read the contents of the provided file into memory and then iterate through +/// the list of strings asserting that the file contains all of them. +pub fn assert_contains_strings>(filename: P, strings: &[&str]) { + let filename = filename.as_ref(); + + let mut content = String::new(); + File::open(&filename) + .expect("Couldn't open the provided file") + .read_to_string(&mut content) + .expect("Couldn't read the file's contents"); + + for s in strings { + assert!(content.contains(s), "Searching for {:?} in {}\n\n{}", s, filename.display(), content); + } +} diff --git a/tests/rendered_output.rs b/tests/rendered_output.rs index 84866f1a..6acdce7b 100644 --- a/tests/rendered_output.rs +++ b/tests/rendered_output.rs @@ -1,14 +1,18 @@ extern crate mdbook; extern crate tempdir; +mod dummy; mod helpers; + +use dummy::DummyBook; +use helpers::assert_contains_strings; use mdbook::MDBook; /// Make sure you can load the dummy book and build it without panicking. #[test] fn build_the_dummy_book() { - let temp = helpers::DummyBook::default().build(); + let temp = DummyBook::default().build(); let mut md = MDBook::new(temp.path()); md.build().unwrap(); @@ -16,7 +20,7 @@ fn build_the_dummy_book() { #[test] fn by_default_mdbook_generates_rendered_content_in_the_book_directory() { - let temp = helpers::DummyBook::default().build(); + let temp = DummyBook::default().build(); let mut md = MDBook::new(temp.path()); assert!(!temp.path().join("book").exists()); @@ -28,7 +32,7 @@ fn by_default_mdbook_generates_rendered_content_in_the_book_directory() { #[test] fn make_sure_bottom_level_files_contain_links_to_chapters() { - let temp = helpers::DummyBook::default().build(); + let temp = DummyBook::default().build(); let mut md = MDBook::new(temp.path()); md.build().unwrap(); @@ -44,13 +48,13 @@ fn make_sure_bottom_level_files_contain_links_to_chapters() { let files_in_bottom_dir = vec!["index.html", "intro.html", "second.html", "conclusion.html"]; for filename in files_in_bottom_dir { - helpers::assert_contains_strings(dest.join(filename), &links); + assert_contains_strings(dest.join(filename), &links); } } #[test] fn check_correct_cross_links_in_nested_dir() { - let temp = helpers::DummyBook::default().build(); + let temp = DummyBook::default().build(); let mut md = MDBook::new(temp.path()); md.build().unwrap(); @@ -67,23 +71,23 @@ fn check_correct_cross_links_in_nested_dir() { let files_in_nested_dir = vec!["index.html", "nested.html"]; for filename in files_in_nested_dir { - helpers::assert_contains_strings(first.join(filename), &links); + assert_contains_strings(first.join(filename), &links); } } #[test] fn rendered_code_has_playpen_stuff() { - let temp = helpers::DummyBook::default().build(); + let temp = DummyBook::default().build(); let mut md = MDBook::new(temp.path()); md.build().unwrap(); let nested = temp.path().join("book/first/nested.html"); let playpen_class = vec![r#"class="playpen""#]; - helpers::assert_contains_strings(nested, &playpen_class); + assert_contains_strings(nested, &playpen_class); let book_js = temp.path().join("book/book.js"); - helpers::assert_contains_strings(book_js, &[".playpen"]); + assert_contains_strings(book_js, &[".playpen"]); } #[test] @@ -96,7 +100,7 @@ fn chapter_content_appears_in_rendered_document() { ("conclusion.html", "Conclusion"), ]; - let temp = helpers::DummyBook::default().build(); + let temp = DummyBook::default().build(); let mut md = MDBook::new(temp.path()); md.build().unwrap(); @@ -104,6 +108,6 @@ fn chapter_content_appears_in_rendered_document() { for (filename, text) in content { let path = destination.join(filename); - helpers::assert_contains_strings(path, &[text]); + assert_contains_strings(path, &[text]); } -} \ No newline at end of file +} diff --git a/tests/testing.rs b/tests/testing.rs index b4d22394..e4cf8da5 100644 --- a/tests/testing.rs +++ b/tests/testing.rs @@ -1,13 +1,15 @@ -extern crate tempdir; extern crate mdbook; +extern crate tempdir; -mod helpers; +mod dummy; + +use dummy::DummyBook; use mdbook::MDBook; #[test] fn mdbook_can_correctly_test_a_passing_book() { - let temp = helpers::DummyBook::default() + let temp = DummyBook::default() .with_passing_test(true) .build(); let mut md = MDBook::new(temp.path()); @@ -17,10 +19,10 @@ fn mdbook_can_correctly_test_a_passing_book() { #[test] fn mdbook_detects_book_with_failing_tests() { - let temp = helpers::DummyBook::default() + let temp = DummyBook::default() .with_passing_test(false) .build(); let mut md: MDBook = MDBook::new(temp.path()); assert!(md.test(vec![]).is_err()); -} \ No newline at end of file +} From 956a5cc7fd417791c60cfc944909cba5fc570da4 Mon Sep 17 00:00:00 2001 From: Behnam Esfahbod Date: Fri, 1 Sep 2017 16:54:57 -0700 Subject: [PATCH 2/4] Fix heading links in nested pages Plus fixing the whitespace chars not being replaced by hyphen. Also expand tests for link creations, and add test for nested pages. Fixes Fixes --- build.rs | 2 + src/renderer/html_handlebars/hbs_renderer.rs | 82 ++++++++++++-------- tests/dummy/book/first/index.md | 2 + tests/dummy/book/first/nested.md | 4 +- tests/helpers/mod.rs | 3 - tests/rendered_output.rs | 34 +++++--- 6 files changed, 82 insertions(+), 45 deletions(-) diff --git a/build.rs b/build.rs index 261a7f2e..845f7b07 100644 --- a/build.rs +++ b/build.rs @@ -25,6 +25,8 @@ mod execs { } +// TODO: Drop after error_chain is fixed +#[allow(unused_doc_comment)] error_chain!{ foreign_links { Io(std::io::Error); diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index 9ace5dcc..2f79e71e 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -63,14 +63,14 @@ impl HtmlHandlebars { debug!("[*]: Render template"); let rendered = ctx.handlebars.render("index", &ctx.data)?; - let filename = Path::new(&ch.path).with_extension("html"); + let filepath = Path::new(&ch.path).with_extension("html"); let rendered = self.post_process(rendered, - filename.file_name().unwrap().to_str().unwrap_or(""), + filepath.to_str().unwrap_or(""), ctx.book.get_html_config().get_playpen_config()); // Write to file - info!("[*] Creating {:?} ✓", filename.display()); - ctx.book.write_file(filename, &rendered.into_bytes())?; + info!("[*] Creating {:?} ✓", filepath.display()); + ctx.book.write_file(filepath, &rendered.into_bytes())?; if ctx.is_index { self.render_index(ctx.book, ch, &ctx.destination)?; @@ -111,9 +111,9 @@ impl HtmlHandlebars { Ok(()) } - fn post_process(&self, rendered: String, filename: &str, playpen_config: &PlaypenConfig) -> String { - let rendered = build_header_links(&rendered, filename); - let rendered = fix_anchor_links(&rendered, filename); + fn post_process(&self, rendered: String, filepath: &str, playpen_config: &PlaypenConfig) -> String { + let rendered = build_header_links(&rendered, &filepath); + let rendered = fix_anchor_links(&rendered, &filepath); let rendered = fix_code_blocks(&rendered); let rendered = add_playpen_pre(&rendered, playpen_config); @@ -182,7 +182,7 @@ impl HtmlHandlebars { Ok(()) } - /// Helper function to write a file to the build directory, normalizing + /// Helper function to write a file to the build directory, normalizing /// the path to be relative to the book root. fn write_custom_file(&self, custom_file: &Path, book: &MDBook) -> Result<()> { let mut data = Vec::new(); @@ -284,7 +284,7 @@ impl Renderer for HtmlHandlebars { let rendered = self.post_process(rendered, "print.html", book.get_html_config().get_playpen_config()); - + book.write_file( Path::new("print").with_extension("html"), &rendered.into_bytes(), @@ -412,7 +412,7 @@ fn make_data(book: &MDBook) -> Result /// Goes through the rendered HTML, making sure all header tags are wrapped in /// an anchor so people can link to sections directly. -fn build_header_links(html: &str, filename: &str) -> String { +fn build_header_links(html: &str, filepath: &str) -> String { let regex = Regex::new(r"(.*?)").unwrap(); let mut id_counter = HashMap::new(); @@ -422,14 +422,14 @@ fn build_header_links(html: &str, filename: &str) -> String { "Regex should ensure we only ever get numbers here", ); - wrap_header_with_link(level, &caps[2], &mut id_counter, filename) + wrap_header_with_link(level, &caps[2], &mut id_counter, filepath) }) .into_owned() } /// Wraps a single header tag with a link, making sure each tag gets its own /// unique ID by appending an auto-incremented number (if necessary). -fn wrap_header_with_link(level: usize, content: &str, id_counter: &mut HashMap, filename: &str) +fn wrap_header_with_link(level: usize, content: &str, id_counter: &mut HashMap, filepath: &str) -> String { let raw_id = id_from_content(content); @@ -443,11 +443,11 @@ fn wrap_header_with_link(level: usize, content: &str, id_counter: &mut HashMap{text}"#, + r##"{text}"##, level = level, id = id, text = content, - filename = filename + filepath = filepath ) } @@ -457,7 +457,7 @@ fn id_from_content(content: &str) -> String { let mut content = content.to_string(); // Skip any tags or html-encoded stuff - let repl_sub = vec![ + static REPL_SUB: &[&str] = &[ "", "", "", @@ -470,27 +470,25 @@ fn id_from_content(content: &str) -> String { "'", """, ]; - for sub in repl_sub { + for sub in REPL_SUB { content = content.replace(sub, ""); } let mut id = String::new(); - for c in content.chars() { - if c.is_alphanumeric() || c == '-' || c == '_' { + if c.is_alphanumeric() || c == '_' { id.push(c.to_ascii_lowercase()); } else if c.is_whitespace() { - id.push(c); + id.push('-'); } } - id } // anchors to the same page (href="#anchor") do not work because of // pointing to the root folder. This function *fixes* // that in a very inelegant way -fn fix_anchor_links(html: &str, filename: &str) -> String { +fn fix_anchor_links(html: &str, filepath: &str) -> String { let regex = Regex::new(r##"]+)href="#([^"]+)"([^>]*)>"##).unwrap(); regex .replace_all(html, |caps: &Captures| { @@ -499,9 +497,9 @@ fn fix_anchor_links(html: &str, filename: &str) -> String { let after = &caps[3]; format!( - "", + "", before = before, - filename = filename, + filepath = filepath, anchor = anchor, after = after ) @@ -601,17 +599,39 @@ mod tests { #[test] fn original_build_header_links() { let inputs = vec![ - ("blah blah

Foo

", r#"blah blah

Foo

"#), - ("

Foo

", r#"

Foo

"#), - ("

Foo^bar

", r#"

Foo^bar

"#), - ("

", r#"

"#), - ("

", r#"

"#), - ("

Foo

Foo

", - r#"

Foo

Foo

"#), + ( + "blah blah

Foo

", + r##"blah blah

Foo

"##, + ), + ( + "

Foo

", + r##"

Foo

"##, + ), + ( + "

Foo^bar

", + r##"

Foo^bar

"##, + ), + ( + "

", + r##"

"## + ), + ( + "

", + r##"

"## + ), + ( + "

Foo

Foo

", + r##"

Foo

Foo

"## + ), ]; for (src, should_be) in inputs { - let got = build_header_links(src, "bar.rs"); + let filepath = "./some_chapter/some_section.html"; + let got = build_header_links(&src, filepath); + assert_eq!(got, should_be); + + // This is redundant for most cases + let got = fix_anchor_links(&got, filepath); assert_eq!(got, should_be); } } diff --git a/tests/dummy/book/first/index.md b/tests/dummy/book/first/index.md index 215ebc71..200672b9 100644 --- a/tests/dummy/book/first/index.md +++ b/tests/dummy/book/first/index.md @@ -1,3 +1,5 @@ # First Chapter more text. + +## Some Section diff --git a/tests/dummy/book/first/nested.md b/tests/dummy/book/first/nested.md index dc09383f..a7a1cdda 100644 --- a/tests/dummy/book/first/nested.md +++ b/tests/dummy/book/first/nested.md @@ -4,4 +4,6 @@ This file has some testable code. ```rust assert!($TEST_STATUS); -``` \ No newline at end of file +``` + +## Some Section diff --git a/tests/helpers/mod.rs b/tests/helpers/mod.rs index e0682d15..da6af35c 100644 --- a/tests/helpers/mod.rs +++ b/tests/helpers/mod.rs @@ -1,8 +1,5 @@ //! Helpers for tests which exercise the overall application, in particular //! the `MDBook` initialization and build/rendering process. -//! -//! This will create an entire book in a temporary directory using some -//! dummy contents from the `tests/dummy-book/` directory. use std::path::Path; diff --git a/tests/rendered_output.rs b/tests/rendered_output.rs index 6acdce7b..7de0838f 100644 --- a/tests/rendered_output.rs +++ b/tests/rendered_output.rs @@ -38,11 +38,11 @@ fn make_sure_bottom_level_files_contain_links_to_chapters() { let dest = temp.path().join("book"); let links = vec![ - "intro.html", - "first/index.html", - "first/nested.html", - "second.html", - "conclusion.html", + r#"href="intro.html""#, + r#"href="./first/index.html""#, + r#"href="./first/nested.html""#, + r#"href="./second.html""#, + r#"href="./conclusion.html""#, ]; let files_in_bottom_dir = vec!["index.html", "intro.html", "second.html", "conclusion.html"]; @@ -61,11 +61,11 @@ fn check_correct_cross_links_in_nested_dir() { let first = temp.path().join("book").join("first"); let links = vec![ r#""#, - "intro.html", - "first/index.html", - "first/nested.html", - "second.html", - "conclusion.html", + r#"href="intro.html""#, + r#"href="./first/index.html""#, + r#"href="./first/nested.html""#, + r#"href="./second.html""#, + r#"href="./conclusion.html""#, ]; let files_in_nested_dir = vec!["index.html", "nested.html"]; @@ -73,6 +73,20 @@ fn check_correct_cross_links_in_nested_dir() { for filename in files_in_nested_dir { assert_contains_strings(first.join(filename), &links); } + + assert_contains_strings( + first.join("index.html"), + &[ + r##"href="./first/index.html#some-section" id="some-section""## + ], + ); + + assert_contains_strings( + first.join("nested.html"), + &[ + r##"href="./first/nested.html#some-section" id="some-section""## + ], + ); } #[test] From 99945542ca4af0184f8544ea7516537077e04769 Mon Sep 17 00:00:00 2001 From: Behnam Esfahbod Date: Sat, 2 Sep 2017 13:19:24 -0700 Subject: [PATCH 3/4] [renderer] Add normalize_path() On the web, the normalized path separator is forward-slash (`/`), so we use the built-in `is_separator()` method to replace any path separator with the forward-slash, to ensure consistent output on unix and windows machines. --- src/renderer/html_handlebars/hbs_renderer.rs | 33 ++++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index 2f79e71e..c267ba66 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -65,7 +65,8 @@ impl HtmlHandlebars { let filepath = Path::new(&ch.path).with_extension("html"); let rendered = self.post_process(rendered, - filepath.to_str().unwrap_or(""), + &normalize_path(filepath.to_str() + .expect(&format!("Bad file name: {}", filepath.display()))), ctx.book.get_html_config().get_playpen_config()); // Write to file @@ -474,15 +475,7 @@ fn id_from_content(content: &str) -> String { content = content.replace(sub, ""); } - let mut id = String::new(); - for c in content.chars() { - if c.is_alphanumeric() || c == '_' { - id.push(c.to_ascii_lowercase()); - } else if c.is_whitespace() { - id.push('-'); - } - } - id + normalize_id(&content) } // anchors to the same page (href="#anchor") do not work because of @@ -590,6 +583,26 @@ struct RenderItemContext<'a> { is_index: bool, } +pub fn normalize_path(path: &str) -> String { + use std::path::is_separator; + path.chars() + .map(|ch| if is_separator(ch) { '/' } else { ch }) + .collect::() +} + +pub fn normalize_id(content: &str) -> String { + content.chars() + .filter_map(|ch| + if ch.is_alphanumeric() || ch == '_' { + Some(ch.to_ascii_lowercase()) + } else if ch.is_whitespace() { + Some('-') + } else { + None + } + ) + .collect::() +} #[cfg(test)] From ddee839d9cc044ee0cfadfa0507f077fcd0df7da Mon Sep 17 00:00:00 2001 From: Behnam Esfahbod Date: Wed, 6 Sep 2017 01:05:27 -0700 Subject: [PATCH 4/4] [renderer] Err on bad file names, instead of panic Addressing the review comments. --- build.rs | 2 -- src/lib.rs | 2 -- src/renderer/html_handlebars/hbs_renderer.rs | 7 ++++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/build.rs b/build.rs index 845f7b07..261a7f2e 100644 --- a/build.rs +++ b/build.rs @@ -25,8 +25,6 @@ mod execs { } -// TODO: Drop after error_chain is fixed -#[allow(unused_doc_comment)] error_chain!{ foreign_links { Io(std::io::Error); diff --git a/src/lib.rs b/src/lib.rs index f1a0d235..fff77bbd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,8 +100,6 @@ pub use book::BookItem; pub use renderer::Renderer; /// The error types used through out this crate. -// TODO: Drop after error_chain is fixed -#[allow(unused_doc_comment)] pub mod errors { error_chain!{ foreign_links { diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index c267ba66..3946439a 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -66,8 +66,9 @@ impl HtmlHandlebars { let filepath = Path::new(&ch.path).with_extension("html"); let rendered = self.post_process(rendered, &normalize_path(filepath.to_str() - .expect(&format!("Bad file name: {}", filepath.display()))), - ctx.book.get_html_config().get_playpen_config()); + .ok_or(Error::from(format!("Bad file name: {}", filepath.display())))?), + ctx.book.get_html_config().get_playpen_config() + ); // Write to file info!("[*] Creating {:?} ✓", filepath.display()); @@ -458,7 +459,7 @@ fn id_from_content(content: &str) -> String { let mut content = content.to_string(); // Skip any tags or html-encoded stuff - static REPL_SUB: &[&str] = &[ + const REPL_SUB: &[&str] = &[ "", "", "",