From 991a725c2675a7385ce0246e4b6dc56783231cda Mon Sep 17 00:00:00 2001 From: Bas Bossink Date: Tue, 4 Dec 2018 00:10:09 +0100 Subject: [PATCH 01/13] Solve the simplest clippy warnings and run rustfmt --- src/book/book.rs | 6 +- src/book/init.rs | 2 +- src/book/mod.rs | 59 ++++----- src/book/summary.rs | 6 +- src/cmd/serve.rs | 2 +- src/config.rs | 6 +- src/main.rs | 4 +- src/preprocess/index.rs | 2 +- src/preprocess/links.rs | 78 ++++-------- src/renderer/html_handlebars/hbs_renderer.rs | 114 ++++++++---------- .../html_handlebars/helpers/navigation.rs | 10 +- src/renderer/html_handlebars/search.rs | 10 +- src/renderer/mod.rs | 4 +- src/utils/mod.rs | 17 +-- 14 files changed, 131 insertions(+), 189 deletions(-) diff --git a/src/book/book.rs b/src/book/book.rs index e4c631ef..b69e98ab 100644 --- a/src/book/book.rs +++ b/src/book/book.rs @@ -167,9 +167,9 @@ impl Chapter { ) -> Chapter { Chapter { name: name.to_string(), - content: content, + content, path: path.into(), - parent_names: parent_names, + parent_names, ..Default::default() } } @@ -210,7 +210,7 @@ fn load_summary_item>( match *item { SummaryItem::Separator => Ok(BookItem::Separator), SummaryItem::Link(ref link) => { - load_chapter(link, src_dir, parent_names).map(|c| BookItem::Chapter(c)) + load_chapter(link, src_dir, parent_names).map(BookItem::Chapter) } } } diff --git a/src/book/init.rs b/src/book/init.rs index 202b3ec5..4acf4b52 100644 --- a/src/book/init.rs +++ b/src/book/init.rs @@ -175,7 +175,7 @@ impl BookBuilder { let summary = src_dir.join("SUMMARY.md"); let mut f = File::create(&summary).chain_err(|| "Unable to create SUMMARY.md")?; writeln!(f, "# Summary")?; - writeln!(f, "")?; + writeln!(f)?; writeln!(f, "- [Chapter 1](./chapter_1.md)")?; let chapter_1 = src_dir.join("chapter_1.md"); diff --git a/src/book/mod.rs b/src/book/mod.rs index 3ffbde6f..48537a37 100644 --- a/src/book/mod.rs +++ b/src/book/mod.rs @@ -20,8 +20,9 @@ use tempfile::Builder as TempFileBuilder; use toml::Value; use errors::*; -use preprocess::{IndexPreprocessor, LinkPreprocessor, Preprocessor, - PreprocessorContext, CmdPreprocessor}; +use preprocess::{ + CmdPreprocessor, IndexPreprocessor, LinkPreprocessor, Preprocessor, PreprocessorContext, +}; use renderer::{CmdRenderer, HtmlHandlebars, RenderContext, Renderer}; use utils; @@ -160,15 +161,16 @@ impl MDBook { /// Run the entire build process for a particular `Renderer`. fn execute_build_process(&self, renderer: &Renderer) -> Result<()> { let mut preprocessed_book = self.book.clone(); - let preprocess_ctx = PreprocessorContext::new(self.root.clone(), - self.config.clone(), - renderer.name().to_string()); + let preprocess_ctx = PreprocessorContext::new( + self.root.clone(), + self.config.clone(), + renderer.name().to_string(), + ); for preprocessor in &self.preprocessors { if preprocessor_should_run(&**preprocessor, renderer, &self.config) { debug!("Running the {} preprocessor.", preprocessor.name()); - preprocessed_book = - preprocessor.run(&preprocess_ctx, preprocessed_book)?; + preprocessed_book = preprocessor.run(&preprocess_ctx, preprocessed_book)?; } } @@ -178,11 +180,7 @@ impl MDBook { Ok(()) } - fn render( - &self, - preprocessed_book: &Book, - renderer: &Renderer, - ) -> Result<()> { + fn render(&self, preprocessed_book: &Book, renderer: &Renderer) -> Result<()> { let name = renderer.name(); let build_dir = self.build_dir_for(name); if build_dir.exists() { @@ -233,9 +231,8 @@ impl MDBook { let temp_dir = TempFileBuilder::new().prefix("mdbook-").tempdir()?; // FIXME: Is "test" the proper renderer name to use here? - let preprocess_context = PreprocessorContext::new(self.root.clone(), - self.config.clone(), - "test".to_string()); + let preprocess_context = + PreprocessorContext::new(self.root.clone(), self.config.clone(), "test".to_string()); let book = LinkPreprocessor::new().run(&preprocess_context, self.book.clone())?; // Index Preprocessor is disabled so that chapter paths continue to point to the @@ -363,17 +360,11 @@ fn determine_preprocessors(config: &Config) -> Result>> { preprocessors.extend(default_preprocessors()); } - if let Some(preprocessor_table) = - config.get("preprocessor").and_then(|v| v.as_table()) - { + if let Some(preprocessor_table) = config.get("preprocessor").and_then(|v| v.as_table()) { for key in preprocessor_table.keys() { match key.as_ref() { - "links" => { - preprocessors.push(Box::new(LinkPreprocessor::new())) - } - "index" => { - preprocessors.push(Box::new(IndexPreprocessor::new())) - } + "links" => preprocessors.push(Box::new(LinkPreprocessor::new())), + "index" => preprocessors.push(Box::new(IndexPreprocessor::new())), name => preprocessors.push(interpret_custom_preprocessor( name, &preprocessor_table[name], @@ -385,10 +376,7 @@ fn determine_preprocessors(config: &Config) -> Result>> { Ok(preprocessors) } -fn interpret_custom_preprocessor( - key: &str, - table: &Value, -) -> Box { +fn interpret_custom_preprocessor(key: &str, table: &Value) -> Box { let command = table .get("command") .and_then(|c| c.as_str()) @@ -406,8 +394,7 @@ fn interpret_custom_renderer(key: &str, table: &Value) -> Box { .and_then(|c| c.as_str()) .map(|s| s.to_string()); - let command = - table_dot_command.unwrap_or_else(|| format!("mdbook-{}", key)); + let command = table_dot_command.unwrap_or_else(|| format!("mdbook-{}", key)); Box::new(CmdRenderer::new(key.to_string(), command.to_string())) } @@ -428,7 +415,8 @@ fn preprocessor_should_run(preprocessor: &Preprocessor, renderer: &Renderer, cfg let renderer_name = renderer.name(); if let Some(Value::Array(ref explicit_renderers)) = cfg.get(&key) { - return explicit_renderers.into_iter() + return explicit_renderers + .iter() .filter_map(|val| val.as_str()) .any(|name| name == renderer_name); } @@ -436,7 +424,6 @@ fn preprocessor_should_run(preprocessor: &Preprocessor, renderer: &Renderer, cfg preprocessor.supports_renderer(renderer_name) } - #[cfg(test)] mod tests { use super::*; @@ -539,10 +526,7 @@ mod tests { // make sure the `preprocessor.random` table exists let random = cfg.get_preprocessor("random").unwrap(); - let random = interpret_custom_preprocessor( - "random", - &Value::Table(random.clone()), - ); + let random = interpret_custom_preprocessor("random", &Value::Table(random.clone())); assert_eq!(random.cmd(), "python random.py"); } @@ -557,7 +541,8 @@ mod tests { let cfg = Config::from_str(cfg_str).unwrap(); // double-check that we can access preprocessor.links.renderers[0] - let html = cfg.get_preprocessor("links") + let html = cfg + .get_preprocessor("links") .and_then(|links| links.get("renderers")) .and_then(|renderers| renderers.as_array()) .and_then(|renderers| renderers.get(0)) diff --git a/src/book/summary.rs b/src/book/summary.rs index a7f73358..31bf0b9b 100644 --- a/src/book/summary.rs +++ b/src/book/summary.rs @@ -280,7 +280,7 @@ impl<'a> SummaryParser<'a> { Err(self.parse_error("You can't have an empty link.")) } else { Ok(Link { - name: name, + name, location: PathBuf::from(href.to_string()), number: None, nested_items: Vec::new(), @@ -313,7 +313,6 @@ impl<'a> SummaryParser<'a> { root_items += bunch_of_items.len() as u32; items.extend(bunch_of_items); - match self.next_event() { Some(Event::Start(Tag::Paragraph)) => { // we're starting the suffix chapters @@ -732,7 +731,8 @@ mod tests { /// Ensure section numbers are correctly incremented after a horizontal separator. #[test] fn keep_numbering_after_separator() { - let src = "- [First](./first.md)\n---\n- [Second](./second.md)\n---\n- [Third](./third.md)\n"; + let src = + "- [First](./first.md)\n---\n- [Second](./second.md)\n---\n- [Third](./third.md)\n"; let should_be = vec![ SummaryItem::Link(Link { name: String::from("First"), diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index ba89c587..0fd88c3a 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -115,7 +115,7 @@ pub fn execute(args: &ArgMatches) -> Result<()> { } #[cfg(feature = "watch")] - watch::trigger_on_change(&mut book, move |path, book_dir| { + watch::trigger_on_change(&book, move |path, book_dir| { info!("File changed: {:?}", path); info!("Building book..."); diff --git a/src/config.rs b/src/config.rs index 71591ace..c6b37094 100644 --- a/src/config.rs +++ b/src/config.rs @@ -301,8 +301,8 @@ impl<'de> Deserialize<'de> for Config { .unwrap_or_default(); Ok(Config { - book: book, - build: build, + book, + build, rest: Value::Table(table), }) } @@ -444,7 +444,7 @@ pub struct HtmlConfig { pub search: Option, /// Git repository url. If `None`, the git button will not be shown. pub git_repository_url: Option, - /// FontAwesome icon class to use for the Git repository link. + /// FontAwesome icon class to use for the Git repository link. /// Defaults to `fa-github` if `None`. pub git_repository_icon: Option, } diff --git a/src/main.rs b/src/main.rs index 86147532..dec89cf3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,8 +20,8 @@ use std::path::{Path, PathBuf}; mod cmd; -const NAME: &'static str = "mdBook"; -const VERSION: &'static str = concat!("v", crate_version!()); +const NAME: &str = "mdBook"; +const VERSION: &str = concat!("v", crate_version!()); fn main() { init_logger(); diff --git a/src/preprocess/index.rs b/src/preprocess/index.rs index 5560db54..a8818518 100644 --- a/src/preprocess/index.rs +++ b/src/preprocess/index.rs @@ -7,7 +7,7 @@ use super::{Preprocessor, PreprocessorContext}; use book::{Book, BookItem}; /// A preprocessor for converting file name `README.md` to `index.md` since -/// `README.md` is the de facto index file in a markdown-based documentation. +/// `README.md` is the de facto index file in markdown-based documentation. pub struct IndexPreprocessor; impl IndexPreprocessor { diff --git a/src/preprocess/links.rs b/src/preprocess/links.rs index 3403891a..90a057b0 100644 --- a/src/preprocess/links.rs +++ b/src/preprocess/links.rs @@ -69,12 +69,7 @@ where Ok(new_content) => { if depth < MAX_LINK_NESTED_DEPTH { if let Some(rel_path) = playpen.link.relative_path(path) { - replaced.push_str(&replace_all( - &new_content, - rel_path, - source, - depth + 1, - )); + replaced.push_str(&replace_all(&new_content, rel_path, source, depth + 1)); } else { replaced.push_str(&new_content); } @@ -118,18 +113,10 @@ impl<'a> LinkType<'a> { let base = base.as_ref(); match self { LinkType::Escaped => None, - LinkType::IncludeRange(p, _) => { - Some(return_relative_path(base, &p)) - } - LinkType::IncludeRangeFrom(p, _) => { - Some(return_relative_path(base, &p)) - } - LinkType::IncludeRangeTo(p, _) => { - Some(return_relative_path(base, &p)) - } - LinkType::IncludeRangeFull(p, _) => { - Some(return_relative_path(base, &p)) - } + LinkType::IncludeRange(p, _) => Some(return_relative_path(base, &p)), + LinkType::IncludeRangeFrom(p, _) => Some(return_relative_path(base, &p)), + LinkType::IncludeRangeTo(p, _) => Some(return_relative_path(base, &p)), + LinkType::IncludeRangeFull(p, _) => Some(return_relative_path(base, &p)), LinkType::Playpen(p, _) => Some(return_relative_path(base, &p)), } } @@ -155,27 +142,21 @@ fn parse_include_path(path: &str) -> LinkType<'static> { let end = end.and_then(|s| s.parse::().ok()); match start { Some(start) => match end { - Some(end) => LinkType::IncludeRange( - path, - Range { - start: start, - end: end, - }, - ), + Some(end) => LinkType::IncludeRange(path, Range { start, end }), None => if has_end { - LinkType::IncludeRangeFrom(path, RangeFrom { start: start }) + LinkType::IncludeRangeFrom(path, RangeFrom { start }) } else { LinkType::IncludeRange( path, Range { - start: start, + start, end: start + 1, }, ) }, }, None => match end { - Some(end) => LinkType::IncludeRangeTo(path, RangeTo { end: end }), + Some(end) => LinkType::IncludeRangeTo(path, RangeTo { end }), None => LinkType::IncludeRangeFull(path, RangeFull), }, } @@ -199,15 +180,11 @@ impl<'a> Link<'a> { match (typ.as_str(), file_arg) { ("include", Some(pth)) => Some(parse_include_path(pth)), - ("playpen", Some(pth)) => { - Some(LinkType::Playpen(pth.into(), props)) - } + ("playpen", Some(pth)) => Some(LinkType::Playpen(pth.into(), props)), _ => None, } } - (Some(mat), None, None) - if mat.as_str().starts_with(ESCAPE_CHAR) => - { + (Some(mat), None, None) if mat.as_str().starts_with(ESCAPE_CHAR) => { Some(LinkType::Escaped) } _ => None, @@ -258,7 +235,7 @@ impl<'a> Link<'a> { let target = base.join(pat); file_to_string(&target) - .map(|s| take_lines(&s, range.clone())) + .map(|s| take_lines(&s, *range)) .chain_err(|| { format!( "Could not read file for link {} ({})", @@ -271,22 +248,23 @@ impl<'a> Link<'a> { let target = base.join(pat); file_to_string(&target).chain_err(|| { - format!("Could not read file for link {} ({})", - self.link_text, - target.display()) + format!( + "Could not read file for link {} ({})", + self.link_text, + target.display() + ) }) } LinkType::Playpen(ref pat, ref attrs) => { let target = base.join(pat); - let contents = - file_to_string(&target).chain_err(|| { - format!( - "Could not read file for link {} ({})", - self.link_text, - target.display() - ) - })?; + let contents = file_to_string(&target).chain_err(|| { + format!( + "Could not read file for link {} ({})", + self.link_text, + target.display() + ) + })?; let ftype = if !attrs.is_empty() { "rust," } else { "rust" }; Ok(format!( "```{}{}\n{}\n```\n", @@ -531,10 +509,7 @@ mod tests { Link { start_index: 38, end_index: 68, - link: LinkType::Playpen( - PathBuf::from("file.rs"), - vec!["editable"] - ), + link: LinkType::Playpen(PathBuf::from("file.rs"), vec!["editable"]), link_text: "{{#playpen file.rs editable }}", }, Link { @@ -544,8 +519,7 @@ mod tests { PathBuf::from("my.rs"), vec!["editable", "no_run", "should_panic"], ), - link_text: - "{{#playpen my.rs editable no_run should_panic}}", + link_text: "{{#playpen my.rs editable no_run should_panic}}", }, ] ); diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index 6ef12f3c..f12fd168 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -30,75 +30,67 @@ impl HtmlHandlebars { print_content: &mut String, ) -> Result<()> { // FIXME: This should be made DRY-er and rely less on mutable state - match *item { - BookItem::Chapter(ref ch) => { - let content = ch.content.clone(); - let content = utils::render_markdown(&content, ctx.html_config.curly_quotes); - print_content.push_str(&content); + if let BookItem::Chapter(ref ch) = *item { + let content = ch.content.clone(); + let content = utils::render_markdown(&content, ctx.html_config.curly_quotes); + print_content.push_str(&content); - // Update the context with data for this file - let path = ch - .path - .to_str() - .chain_err(|| "Could not convert path to str")?; - let filepath = Path::new(&ch.path).with_extension("html"); + // Update the context with data for this file + let path = ch + .path + .to_str() + .chain_err(|| "Could not convert path to str")?; + let filepath = Path::new(&ch.path).with_extension("html"); - // "print.html" is used for the print page. - if ch.path == Path::new("print.md") { - bail!(ErrorKind::ReservedFilenameError(ch.path.clone())); - }; + // "print.html" is used for the print page. + if ch.path == Path::new("print.md") { + bail!(ErrorKind::ReservedFilenameError(ch.path.clone())); + }; - // Non-lexical lifetimes needed :'( - let title: String; - { - let book_title = ctx - .data - .get("book_title") - .and_then(serde_json::Value::as_str) - .unwrap_or(""); - title = ch.name.clone() + " - " + book_title; - } - - ctx.data.insert("path".to_owned(), json!(path)); - ctx.data.insert("content".to_owned(), json!(content)); - ctx.data.insert("chapter_title".to_owned(), json!(ch.name)); - ctx.data.insert("title".to_owned(), json!(title)); - ctx.data.insert( - "path_to_root".to_owned(), - json!(utils::fs::path_to_root(&ch.path)), - ); - - // Render the handlebars template with the data - debug!("Render template"); - let rendered = ctx.handlebars.render("index", &ctx.data)?; - - let rendered = self.post_process(rendered, &ctx.html_config.playpen); - - // Write to file - debug!("Creating {}", filepath.display()); - utils::fs::write_file(&ctx.destination, &filepath, rendered.as_bytes())?; - - if ctx.is_index { - ctx.data.insert("path".to_owned(), json!("index.html")); - ctx.data.insert("path_to_root".to_owned(), json!("")); - let rendered_index = ctx.handlebars.render("index", &ctx.data)?; - let rendered_index = - self.post_process(rendered_index, &ctx.html_config.playpen); - debug!("Creating index.html from {}", path); - utils::fs::write_file( - &ctx.destination, - "index.html", - rendered_index.as_bytes(), - )?; - } + // Non-lexical lifetimes needed :'( + let title: String; + { + let book_title = ctx + .data + .get("book_title") + .and_then(serde_json::Value::as_str) + .unwrap_or(""); + title = ch.name.clone() + " - " + book_title; + } + + ctx.data.insert("path".to_owned(), json!(path)); + ctx.data.insert("content".to_owned(), json!(content)); + ctx.data.insert("chapter_title".to_owned(), json!(ch.name)); + ctx.data.insert("title".to_owned(), json!(title)); + ctx.data.insert( + "path_to_root".to_owned(), + json!(utils::fs::path_to_root(&ch.path)), + ); + + // Render the handlebars template with the data + debug!("Render template"); + let rendered = ctx.handlebars.render("index", &ctx.data)?; + + let rendered = self.post_process(rendered, &ctx.html_config.playpen); + + // Write to file + debug!("Creating {}", filepath.display()); + utils::fs::write_file(&ctx.destination, &filepath, rendered.as_bytes())?; + + if ctx.is_index { + ctx.data.insert("path".to_owned(), json!("index.html")); + ctx.data.insert("path_to_root".to_owned(), json!("")); + let rendered_index = ctx.handlebars.render("index", &ctx.data)?; + let rendered_index = self.post_process(rendered_index, &ctx.html_config.playpen); + debug!("Creating index.html from {}", path); + utils::fs::write_file(&ctx.destination, "index.html", rendered_index.as_bytes())?; } - _ => {} } Ok(()) } - #[cfg_attr(feature = "cargo-clippy", allow(let_and_return))] + #[cfg_attr(feature = "cargo-clippy", allow(clippy::let_and_return))] fn post_process(&self, rendered: String, playpen_config: &Playpen) -> String { let rendered = build_header_links(&rendered); let rendered = fix_code_blocks(&rendered); @@ -328,7 +320,7 @@ impl Renderer for HtmlHandlebars { handlebars: &handlebars, destination: destination.to_path_buf(), data: data.clone(), - is_index: is_index, + is_index, html_config: html_config.clone(), }; self.render_item(item, ctx, &mut print_content)?; diff --git a/src/renderer/html_handlebars/helpers/navigation.rs b/src/renderer/html_handlebars/helpers/navigation.rs index dc84d0da..0e551004 100644 --- a/src/renderer/html_handlebars/helpers/navigation.rs +++ b/src/renderer/html_handlebars/helpers/navigation.rs @@ -18,13 +18,13 @@ impl Target { /// Returns target if found. fn find( &self, - base_path: &String, - current_path: &String, + base_path: &str, + current_path: &str, current_item: &StringMap, previous_item: &StringMap, ) -> Result, RenderError> { - match self { - &Target::Next => { + match *self { + Target::Next => { let previous_path = previous_item .get("path") .ok_or_else(|| RenderError::new("No path found for chapter in JSON data"))?; @@ -34,7 +34,7 @@ impl Target { } } - &Target::Previous => { + Target::Previous => { if current_path == base_path { return Ok(Some(previous_item.clone())); } diff --git a/src/renderer/html_handlebars/search.rs b/src/renderer/html_handlebars/search.rs index fd055f38..c27977e1 100644 --- a/src/renderer/html_handlebars/search.rs +++ b/src/renderer/html_handlebars/search.rs @@ -54,7 +54,7 @@ fn add_doc( section_id: &Option, items: &[&str], ) { - let url = if let &Some(ref id) = section_id { + let url = if let Some(ref id) = *section_id { Cow::Owned(format!("{}#{}", anchor_base, id)) } else { Cow::Borrowed(anchor_base) @@ -74,8 +74,8 @@ fn render_item( doc_urls: &mut Vec, item: &BookItem, ) -> Result<()> { - let chapter = match item { - &BookItem::Chapter(ref ch) => ch, + let chapter = match *item { + BookItem::Chapter(ref ch) => ch, _ => return Ok(()), }; @@ -101,7 +101,7 @@ fn render_item( for event in p { match event { Event::Start(Tag::Header(i)) if i <= max_section_depth => { - if heading.len() > 0 { + if !heading.is_empty() { // Section finished, the next header is following now // Write the data to the index, and clear it for the next section add_doc( @@ -155,7 +155,7 @@ fn render_item( } } - if heading.len() > 0 { + if !heading.is_empty() { // Make sure the last section is added to the index add_doc( index, diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index bf5f59c5..ae26c6ac 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -76,8 +76,8 @@ impl RenderContext { Q: Into, { RenderContext { - book: book, - config: config, + book, + config, version: ::MDBOOK_VERSION.to_string(), root: root.into(), destination: destination.into(), diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 73015f5a..31abe98c 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -119,7 +119,7 @@ struct EventQuoteConverter { impl EventQuoteConverter { fn new(enabled: bool) -> Self { EventQuoteConverter { - enabled: enabled, + enabled, convert_text: true, } } @@ -324,14 +324,8 @@ more text with spaces id_from_content("## Method-call expressions"), "method-call-expressions" ); - assert_eq!( - id_from_content("## **Bold** title"), - "bold-title" - ); - assert_eq!( - id_from_content("## `Code` title"), - "code-title" - ); + assert_eq!(id_from_content("## **Bold** title"), "bold-title"); + assert_eq!(id_from_content("## `Code` title"), "code-title"); } #[test] @@ -344,10 +338,7 @@ more text with spaces id_from_content("## 中文標題 CJK title"), "中文標題-cjk-title" ); - assert_eq!( - id_from_content("## Über"), - "Über" - ); + assert_eq!(id_from_content("## Über"), "Über"); } #[test] From 742dbbc91700dce1b7d910bca6b3e10a5ae46b86 Mon Sep 17 00:00:00 2001 From: Bas Bossink Date: Tue, 4 Dec 2018 00:11:41 +0100 Subject: [PATCH 02/13] Run rustfmt. --- examples/de-emphasize.rs | 11 +++----- examples/nop-preprocessor.rs | 12 +++------ src/cmd/init.rs | 7 ++--- src/preprocess/cmd.rs | 29 ++++++++------------- src/preprocess/mod.rs | 4 +-- src/renderer/html_handlebars/helpers/mod.rs | 2 +- tests/custom_preprocessors.rs | 9 +++++-- 7 files changed, 33 insertions(+), 41 deletions(-) diff --git a/examples/de-emphasize.rs b/examples/de-emphasize.rs index 933e5c45..fffcc44e 100644 --- a/examples/de-emphasize.rs +++ b/examples/de-emphasize.rs @@ -56,10 +56,7 @@ where Ok(()) } -fn remove_emphasis( - num_removed_items: &mut usize, - chapter: &mut Chapter, -) -> Result { +fn remove_emphasis(num_removed_items: &mut usize, chapter: &mut Chapter) -> Result { let mut buf = String::with_capacity(chapter.content.len()); let events = Parser::new(&chapter.content).filter(|e| { @@ -76,7 +73,7 @@ fn remove_emphasis( should_keep }); - cmark(events, &mut buf, None).map(|_| buf).map_err(|err| { - Error::from(format!("Markdown serialization failed: {}", err)) - }) + cmark(events, &mut buf, None) + .map(|_| buf) + .map_err(|err| Error::from(format!("Markdown serialization failed: {}", err))) } diff --git a/examples/nop-preprocessor.rs b/examples/nop-preprocessor.rs index d4615ef6..374ee60f 100644 --- a/examples/nop-preprocessor.rs +++ b/examples/nop-preprocessor.rs @@ -6,9 +6,9 @@ use clap::{App, Arg, ArgMatches, SubCommand}; use mdbook::book::Book; use mdbook::errors::Error; use mdbook::preprocess::{CmdPreprocessor, Preprocessor, PreprocessorContext}; +use nop_lib::Nop; use std::io; use std::process; -use nop_lib::Nop; pub fn make_app() -> App<'static, 'static> { App::new("nop-preprocessor") @@ -16,7 +16,8 @@ pub fn make_app() -> App<'static, 'static> { .subcommand( SubCommand::with_name("supports") .arg(Arg::with_name("renderer").required(true)) - .about("Check whether a renderer is supported by this preprocessor")) + .about("Check whether a renderer is supported by this preprocessor"), + ) } fn main() { @@ -87,11 +88,7 @@ mod nop_lib { "nop-preprocessor" } - fn run( - &self, - ctx: &PreprocessorContext, - book: Book, - ) -> Result { + fn run(&self, ctx: &PreprocessorContext, book: Book) -> Result { // In testing we want to tell the preprocessor to blow up by setting a // particular config value if let Some(nop_cfg) = ctx.config.get_preprocessor(self.name()) { @@ -109,4 +106,3 @@ mod nop_lib { } } } - diff --git a/src/cmd/init.rs b/src/cmd/init.rs index 629563b2..c6bba9d5 100644 --- a/src/cmd/init.rs +++ b/src/cmd/init.rs @@ -12,9 +12,10 @@ pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> { SubCommand::with_name("init") .about("Creates the boilerplate structure and files for a new book") // the {n} denotes a newline which will properly aligned in all help messages - .arg_from_usage("[dir] 'Directory to create the book in{n}\ - (Defaults to the Current Directory when omitted)'") - .arg_from_usage("--theme 'Copies the default theme into your source folder'") + .arg_from_usage( + "[dir] 'Directory to create the book in{n}\ + (Defaults to the Current Directory when omitted)'", + ).arg_from_usage("--theme 'Copies the default theme into your source folder'") .arg_from_usage("--force 'Skips confirmation prompts'") } diff --git a/src/preprocess/cmd.rs b/src/preprocess/cmd.rs index 59b0cdd3..d548d90e 100644 --- a/src/preprocess/cmd.rs +++ b/src/preprocess/cmd.rs @@ -43,19 +43,11 @@ impl CmdPreprocessor { /// A convenience function custom preprocessors can use to parse the input /// written to `stdin` by a `CmdRenderer`. - pub fn parse_input( - reader: R, - ) -> Result<(PreprocessorContext, Book)> { - serde_json::from_reader(reader) - .chain_err(|| "Unable to parse the input") + pub fn parse_input(reader: R) -> Result<(PreprocessorContext, Book)> { + serde_json::from_reader(reader).chain_err(|| "Unable to parse the input") } - fn write_input_to_child( - &self, - child: &mut Child, - book: &Book, - ctx: &PreprocessorContext, - ) { + fn write_input_to_child(&self, child: &mut Child, book: &Book, ctx: &PreprocessorContext) { let stdin = child.stdin.take().expect("Child has stdin"); if let Err(e) = self.write_input(stdin, &book, &ctx) { @@ -128,8 +120,7 @@ impl Preprocessor for CmdPreprocessor { "The preprocessor exited unsuccessfully" ); - serde_json::from_slice(&output.stdout) - .chain_err(|| "Unable to parse the preprocessed book") + serde_json::from_slice(&output.stdout).chain_err(|| "Unable to parse the preprocessed book") } fn supports_renderer(&self, renderer: &str) -> bool { @@ -142,7 +133,11 @@ impl Preprocessor for CmdPreprocessor { let mut cmd = match self.command() { Ok(c) => c, Err(e) => { - warn!("Unable to create the command for the \"{}\" preprocessor, {}", self.name(), e); + warn!( + "Unable to create the command for the \"{}\" preprocessor, {}", + self.name(), + e + ); return false; } }; @@ -177,8 +172,7 @@ mod tests { use MDBook; fn book_example() -> MDBook { - let example = - Path::new(env!("CARGO_MANIFEST_DIR")).join("book-example"); + let example = Path::new(env!("CARGO_MANIFEST_DIR")).join("book-example"); MDBook::load(example).unwrap() } @@ -195,8 +189,7 @@ mod tests { let mut buffer = Vec::new(); cmd.write_input(&mut buffer, &md.book, &ctx).unwrap(); - let (got_ctx, got_book) = - CmdPreprocessor::parse_input(buffer.as_slice()).unwrap(); + let (got_ctx, got_book) = CmdPreprocessor::parse_input(buffer.as_slice()).unwrap(); assert_eq!(got_book, md.book); assert_eq!(got_ctx, ctx); diff --git a/src/preprocess/mod.rs b/src/preprocess/mod.rs index 917ab5ca..1a305408 100644 --- a/src/preprocess/mod.rs +++ b/src/preprocess/mod.rs @@ -1,12 +1,12 @@ //! Book preprocessing. +pub use self::cmd::CmdPreprocessor; pub use self::index::IndexPreprocessor; pub use self::links::LinkPreprocessor; -pub use self::cmd::CmdPreprocessor; +mod cmd; mod index; mod links; -mod cmd; use book::Book; use config::Config; diff --git a/src/renderer/html_handlebars/helpers/mod.rs b/src/renderer/html_handlebars/helpers/mod.rs index e9a8f932..52be6d20 100644 --- a/src/renderer/html_handlebars/helpers/mod.rs +++ b/src/renderer/html_handlebars/helpers/mod.rs @@ -1,3 +1,3 @@ pub mod navigation; +pub mod theme; pub mod toc; -pub mod theme; \ No newline at end of file diff --git a/tests/custom_preprocessors.rs b/tests/custom_preprocessors.rs index 54bfd51d..dd120eab 100644 --- a/tests/custom_preprocessors.rs +++ b/tests/custom_preprocessors.rs @@ -7,7 +7,10 @@ use mdbook::preprocess::{CmdPreprocessor, Preprocessor}; use mdbook::MDBook; fn example() -> CmdPreprocessor { - CmdPreprocessor::new("nop-preprocessor".to_string(), "cargo run --example nop-preprocessor --".to_string()) + CmdPreprocessor::new( + "nop-preprocessor".to_string(), + "cargo run --example nop-preprocessor --".to_string(), + ) } #[test] @@ -35,7 +38,9 @@ fn ask_the_preprocessor_to_blow_up() { let mut md = MDBook::load(temp.path()).unwrap(); md.with_preprecessor(example()); - md.config.set("preprocessor.nop-preprocessor.blow-up", true).unwrap(); + md.config + .set("preprocessor.nop-preprocessor.blow-up", true) + .unwrap(); let got = md.build(); From 3f002979c4d2f91cdb04a21399f76c9ab8972a34 Mon Sep 17 00:00:00 2001 From: Bas Bossink Date: Tue, 4 Dec 2018 00:57:15 +0100 Subject: [PATCH 03/13] Suppress dead_code warning in test --- examples/de-emphasize.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/de-emphasize.rs b/examples/de-emphasize.rs index fffcc44e..1cdf0823 100644 --- a/examples/de-emphasize.rs +++ b/examples/de-emphasize.rs @@ -17,6 +17,7 @@ fn main() { panic!("This example is intended to be part of a library"); } +#[allow(dead_code)] struct Deemphasize; impl Preprocessor for Deemphasize { From 3598e905aab13d94835aec502699767fa596e8ed Mon Sep 17 00:00:00 2001 From: Bas Bossink Date: Wed, 5 Dec 2018 22:26:53 +0100 Subject: [PATCH 04/13] Make failing_alternate_backend test more platform specific Use the suggestion from @Michael-F-Bryan to make the passing_ and failing_alternate_backend test more reliable across platforms. --- tests/alternate_backends.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/alternate_backends.rs b/tests/alternate_backends.rs index c7ebb6b8..41cf2f84 100644 --- a/tests/alternate_backends.rs +++ b/tests/alternate_backends.rs @@ -11,14 +11,14 @@ use tempfile::{Builder as TempFileBuilder, TempDir}; #[test] fn passing_alternate_backend() { - let (md, _temp) = dummy_book_with_backend("passing", "true"); + let (md, _temp) = dummy_book_with_backend("passing", success_cmd()); md.build().unwrap(); } #[test] fn failing_alternate_backend() { - let (md, _temp) = dummy_book_with_backend("failing", "false"); + let (md, _temp) = dummy_book_with_backend("failing", fail_cmd()); md.build().unwrap_err(); } @@ -84,3 +84,19 @@ fn dummy_book_with_backend(name: &str, command: &str) -> (MDBook, TempDir) { (md, temp) } + +fn fail_cmd() -> &'static str { + if cfg!(windows) { + r#"cmd.exe /c "exit 1""# + } else { + "false" + } +} + +fn success_cmd() -> &'static str { + if cfg!(windows) { + r#"cmd.exe /c "exit 0""# + } else { + "true" + } +} From eb19d2d65457ca448ca6ec206637a34d7986da10 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Sat, 8 Dec 2018 13:48:59 +0100 Subject: [PATCH 05/13] Update CONTRIBUTING.md (Clippy is on stable now) --- CONTRIBUTING.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 46888587..8349f86a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -62,7 +62,7 @@ The quick guide is 1. Install it ``` - rustup component add rustfmt-preview + rustup component add rustfmt ``` 1. You can now run `rustfmt` on a single file simply by... ``` @@ -87,14 +87,11 @@ The best documentation can be found over at [rust-clippy](https://github.com/rus 1. To install ``` - rustup update - rustup install nightly - rustup component add clippy-preview --toolchain=nightly + rustup component add clippy ``` 2. Running clippy - As you may notice from the previous step, Clippy is on the nightly branch, so running it is like ``` - cargo +nightly clippy + cargo clippy ``` Clippy has an ever growing list of checks, that are managed in [lint files](https://rust-lang-nursery.github.io/rust-clippy/master/index.html). From b675b9198009878bfea8877334cebb83c9c66f9c Mon Sep 17 00:00:00 2001 From: Shawn Date: Sat, 15 Dec 2018 10:09:23 +0900 Subject: [PATCH 06/13] Update broken link https://www.rust-lang.org/downloads.html is the outdated link. --- book-example/src/cli/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book-example/src/cli/README.md b/book-example/src/cli/README.md index ca8e6de6..18fe9f3b 100644 --- a/book-example/src/cli/README.md +++ b/book-example/src/cli/README.md @@ -18,7 +18,7 @@ mdBook can also be installed from source mdBook is written in **[Rust](https://www.rust-lang.org/)** and therefore needs to be compiled with **Cargo**. If you haven't already installed Rust, please go -ahead and [install it](https://www.rust-lang.org/downloads.html) now. +ahead and [install it](https://www.rust-lang.org/tools/install) now. ### Install Crates.io version From 954cfa86e591bdb316ad8c7d4f1cb1a157bd542e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Derosiaux?= Date: Wed, 9 Jan 2019 17:59:45 +0100 Subject: [PATCH 07/13] Fix websocket hostname usage The livereload url was using an unknown property "websocket-address" instead of "websocket-hostname", hence it was always fallback onto the hostname (which can be different). --- src/cmd/serve.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index 0fd88c3a..9659d820 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -76,7 +76,7 @@ pub fn execute(args: &ArgMatches) -> Result<()> { let port = args.value_of("port").unwrap(); let ws_port = args.value_of("websocket-port").unwrap(); let hostname = args.value_of("hostname").unwrap(); - let public_address = args.value_of("websocket-address").unwrap_or(hostname); + let public_address = args.value_of("websocket-hostname").unwrap_or(hostname); let open_browser = args.is_present("open"); let address = format!("{}:{}", hostname, port); From a481735fa25a84493bc1e4b5093c904fde2fda4c Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 14 Jan 2019 15:49:23 -0500 Subject: [PATCH 08/13] failing test --- tests/dummy_book/src/SUMMARY.md | 1 + tests/dummy_book/src/second/nested.md | 4 + tests/rendered_output.rs | 18 +- tests/searchindex_fixture.json | 380 ++++++++++++++++++++++---- 4 files changed, 346 insertions(+), 57 deletions(-) create mode 100644 tests/dummy_book/src/second/nested.md diff --git a/tests/dummy_book/src/SUMMARY.md b/tests/dummy_book/src/SUMMARY.md index 0536e5c2..ee2426e4 100644 --- a/tests/dummy_book/src/SUMMARY.md +++ b/tests/dummy_book/src/SUMMARY.md @@ -8,6 +8,7 @@ - [Includes](first/includes.md) - [Recursive](first/recursive.md) - [Second Chapter](second.md) + - [Nested Chapter](second/nested.md) --- diff --git a/tests/dummy_book/src/second/nested.md b/tests/dummy_book/src/second/nested.md new file mode 100644 index 00000000..c3eb3c8f --- /dev/null +++ b/tests/dummy_book/src/second/nested.md @@ -0,0 +1,4 @@ +# Testing relative links for the print page + +When we link to [the first section](../first/nested.md), it should work on +both the print page and the non-print page. \ No newline at end of file diff --git a/tests/rendered_output.rs b/tests/rendered_output.rs index 44aed62b..b7777ee7 100644 --- a/tests/rendered_output.rs +++ b/tests/rendered_output.rs @@ -31,7 +31,7 @@ const TOC_TOP_LEVEL: &[&'static str] = &[ "Introduction", ]; const TOC_SECOND_LEVEL: &[&'static str] = - &["1.1. Nested Chapter", "1.2. Includes", "1.3. Recursive"]; + &["1.1. Nested Chapter", "1.2. Includes", "2.1. Nested Chapter", "1.3. Recursive"]; /// Make sure you can load the dummy book and build it without panicking. #[test] @@ -109,6 +109,20 @@ fn check_correct_cross_links_in_nested_dir() { ); } +#[test] +fn check_correct_relative_links_in_print_page() { + let temp = DummyBook::new().build().unwrap(); + let md = MDBook::load(temp.path()).unwrap(); + md.build().unwrap(); + + let first = temp.path().join("book"); + + assert_contains_strings( + first.join("print.html"), + &[r##"the first section,"##], + ); +} + #[test] fn rendered_code_has_playpen_stuff() { let temp = DummyBook::new().build().unwrap(); @@ -443,7 +457,7 @@ mod search { assert_eq!(docs[&some_section]["body"], ""); assert_eq!( docs[&summary]["body"], - "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Second Chapter Conclusion" + "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Second Chapter Nested Chapter Conclusion" ); assert_eq!(docs[&summary]["breadcrumbs"], "First Chapter » Summary"); assert_eq!(docs[&conclusion]["body"], "I put <HTML> in here!"); diff --git a/tests/searchindex_fixture.json b/tests/searchindex_fixture.json index 330bc648..78a39153 100644 --- a/tests/searchindex_fixture.json +++ b/tests/searchindex_fixture.json @@ -9,6 +9,7 @@ "first/includes.html#includes", "first/includes.html#summary", "second.html#second-chapter", + "second/nested.html#testing-relative-links-for-the-print-page", "conclusion.html#conclusion" ], "index": { @@ -24,6 +25,11 @@ "breadcrumbs": 1, "title": 1 }, + "10": { + "body": 3, + "breadcrumbs": 1, + "title": 1 + }, "2": { "body": 2, "breadcrumbs": 2, @@ -50,7 +56,7 @@ "title": 1 }, "7": { - "body": 12, + "body": 14, "breadcrumbs": 3, "title": 1 }, @@ -60,9 +66,9 @@ "title": 2 }, "9": { - "body": 3, - "breadcrumbs": 1, - "title": 1 + "body": 10, + "breadcrumbs": 7, + "title": 5 } }, "docs": { @@ -78,6 +84,12 @@ "id": "1", "title": "Introduction" }, + "10": { + "body": "I put <HTML> in here!", + "breadcrumbs": "Conclusion", + "id": "10", + "title": "Conclusion" + }, "2": { "body": "more text.", "breadcrumbs": "First Chapter", @@ -109,7 +121,7 @@ "title": "Includes" }, "7": { - "body": "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Second Chapter Conclusion", + "body": "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Second Chapter Nested Chapter Conclusion", "breadcrumbs": "First Chapter » Summary", "id": "7", "title": "Summary" @@ -121,13 +133,13 @@ "title": "Second Chapter" }, "9": { - "body": "I put <HTML> in here!", - "breadcrumbs": "Conclusion", + "body": "When we link to the first section , it should work on both the print page and the non-print page.", + "breadcrumbs": "Second Chapter » Testing relative links for the print page", "id": "9", - "title": "Conclusion" + "title": "Testing relative links for the print page" } }, - "length": 10, + "length": 11, "save": true }, "fields": [ @@ -206,6 +218,18 @@ } } } + }, + "t": { + "df": 0, + "docs": {}, + "h": { + "df": 1, + "docs": { + "9": { + "tf": 1.0 + } + } + } } } }, @@ -251,7 +275,7 @@ "tf": 1.0 }, "7": { - "tf": 1.7320508075688773 + "tf": 2.0 }, "8": { "tf": 1.0 @@ -296,10 +320,10 @@ "s": { "df": 2, "docs": { - "7": { + "10": { "tf": 1.0 }, - "9": { + "7": { "tf": 1.0 } } @@ -420,13 +444,16 @@ "df": 0, "docs": {}, "t": { - "df": 2, + "df": 3, "docs": { "2": { "tf": 1.0 }, "7": { "tf": 1.0 + }, + "9": { + "tf": 1.0 } } } @@ -485,7 +512,7 @@ "0": { "tf": 1.0 }, - "9": { + "10": { "tf": 1.0 } } @@ -683,6 +710,14 @@ "tf": 1.0 } } + }, + "k": { + "df": 1, + "docs": { + "9": { + "tf": 1.4142135623730951 + } + } } } }, @@ -709,7 +744,7 @@ "t": { "df": 1, "docs": { - "9": { + "10": { "tf": 1.0 } } @@ -791,14 +826,42 @@ "tf": 1.0 }, "7": { - "tf": 1.0 + "tf": 1.4142135623730951 } } } } + }, + "o": { + "df": 0, + "docs": {}, + "n": { + "df": 1, + "docs": { + "9": { + "tf": 1.0 + } + } + } } }, "p": { + "a": { + "df": 0, + "docs": {}, + "g": { + "df": 0, + "docs": {}, + "e": { + "df": 1, + "docs": { + "9": { + "tf": 1.7320508075688772 + } + } + } + } + }, "df": 0, "docs": {}, "r": { @@ -871,8 +934,12 @@ "df": 0, "docs": {}, "t": { - "df": 0, - "docs": {}, + "df": 1, + "docs": { + "9": { + "tf": 1.7320508075688772 + } + }, "l": { "df": 0, "docs": {}, @@ -935,7 +1002,7 @@ "t": { "df": 1, "docs": { - "9": { + "10": { "tf": 1.0 } } @@ -967,7 +1034,15 @@ } }, "df": 0, - "docs": {} + "docs": {}, + "l": { + "df": 1, + "docs": { + "9": { + "tf": 1.0 + } + } + } }, "u": { "df": 0, @@ -1050,13 +1125,16 @@ "df": 0, "docs": {}, "n": { - "df": 2, + "df": 3, "docs": { "3": { "tf": 1.0 }, "5": { "tf": 1.0 + }, + "9": { + "tf": 1.0 } } } @@ -1170,8 +1248,12 @@ "df": 0, "docs": {} }, - "df": 0, - "docs": {} + "df": 1, + "docs": { + "9": { + "tf": 1.0 + } + } } }, "x": { @@ -1200,6 +1282,14 @@ "r": { "df": 0, "docs": {}, + "k": { + "df": 1, + "docs": { + "9": { + "tf": 1.0 + } + } + }, "l": { "d": { "df": 1, @@ -1280,13 +1370,25 @@ "df": 2, "docs": { "0": { - "tf": 1.4142135623730952 + "tf": 1.4142135623730951 }, "7": { "tf": 1.0 } } } + }, + "t": { + "df": 0, + "docs": {}, + "h": { + "df": 1, + "docs": { + "9": { + "tf": 1.0 + } + } + } } } }, @@ -1323,13 +1425,13 @@ "df": 0, "docs": {}, "r": { - "df": 6, + "df": 7, "docs": { "2": { - "tf": 1.4142135623730952 + "tf": 1.4142135623730951 }, "4": { - "tf": 1.7320508075688773 + "tf": 1.7320508075688772 }, "5": { "tf": 1.0 @@ -1338,10 +1440,13 @@ "tf": 1.0 }, "7": { - "tf": 2.0 + "tf": 2.23606797749979 }, "8": { - "tf": 1.4142135623730952 + "tf": 1.4142135623730951 + }, + "9": { + "tf": 1.0 } } } @@ -1383,11 +1488,11 @@ "s": { "df": 2, "docs": { + "10": { + "tf": 1.4142135623730951 + }, "7": { "tf": 1.0 - }, - "9": { - "tf": 1.4142135623730952 } } } @@ -1419,7 +1524,7 @@ "df": 2, "docs": { "0": { - "tf": 1.4142135623730952 + "tf": 1.4142135623730951 }, "7": { "tf": 1.0 @@ -1507,10 +1612,10 @@ "df": 0, "docs": {}, "t": { - "df": 5, + "df": 6, "docs": { "2": { - "tf": 1.4142135623730952 + "tf": 1.4142135623730951 }, "4": { "tf": 1.0 @@ -1522,7 +1627,10 @@ "tf": 1.0 }, "7": { - "tf": 1.4142135623730952 + "tf": 1.4142135623730951 + }, + "9": { + "tf": 1.0 } } } @@ -1581,7 +1689,7 @@ "0": { "tf": 1.0 }, - "9": { + "10": { "tf": 1.0 } } @@ -1636,7 +1744,7 @@ "df": 2, "docs": { "6": { - "tf": 1.4142135623730952 + "tf": 1.4142135623730951 }, "7": { "tf": 1.0 @@ -1728,7 +1836,7 @@ "df": 2, "docs": { "1": { - "tf": 1.4142135623730952 + "tf": 1.4142135623730951 }, "7": { "tf": 1.0 @@ -1779,6 +1887,14 @@ "tf": 1.0 } } + }, + "k": { + "df": 1, + "docs": { + "9": { + "tf": 1.7320508075688772 + } + } } } }, @@ -1805,7 +1921,7 @@ "t": { "df": 1, "docs": { - "9": { + "10": { "tf": 1.0 } } @@ -1884,17 +2000,45 @@ "df": 2, "docs": { "4": { - "tf": 1.4142135623730952 + "tf": 1.4142135623730951 }, "7": { - "tf": 1.0 + "tf": 1.4142135623730951 } } } } + }, + "o": { + "df": 0, + "docs": {}, + "n": { + "df": 1, + "docs": { + "9": { + "tf": 1.0 + } + } + } } }, "p": { + "a": { + "df": 0, + "docs": {}, + "g": { + "df": 0, + "docs": {}, + "e": { + "df": 1, + "docs": { + "9": { + "tf": 2.0 + } + } + } + } + }, "df": 0, "docs": {}, "r": { @@ -1967,8 +2111,12 @@ "df": 0, "docs": {}, "t": { - "df": 0, - "docs": {}, + "df": 1, + "docs": { + "9": { + "tf": 2.0 + } + }, "l": { "df": 0, "docs": {}, @@ -2031,7 +2179,7 @@ "t": { "df": 1, "docs": { - "9": { + "10": { "tf": 1.0 } } @@ -2063,7 +2211,15 @@ } }, "df": 0, - "docs": {} + "docs": {}, + "l": { + "df": 1, + "docs": { + "9": { + "tf": 1.4142135623730951 + } + } + } }, "u": { "df": 0, @@ -2122,13 +2278,16 @@ "docs": {}, "n": { "d": { - "df": 2, + "df": 3, "docs": { "7": { "tf": 1.0 }, "8": { - "tf": 1.4142135623730952 + "tf": 1.4142135623730951 + }, + "9": { + "tf": 1.0 } } }, @@ -2146,13 +2305,16 @@ "df": 0, "docs": {}, "n": { - "df": 2, + "df": 3, "docs": { "3": { - "tf": 1.4142135623730952 + "tf": 1.4142135623730951 }, "5": { - "tf": 1.4142135623730952 + "tf": 1.4142135623730951 + }, + "9": { + "tf": 1.0 } } } @@ -2216,7 +2378,7 @@ "df": 1, "docs": { "7": { - "tf": 1.4142135623730952 + "tf": 1.4142135623730951 } } } @@ -2266,8 +2428,12 @@ "df": 0, "docs": {} }, - "df": 0, - "docs": {} + "df": 1, + "docs": { + "9": { + "tf": 1.4142135623730951 + } + } } }, "x": { @@ -2296,6 +2462,14 @@ "r": { "df": 0, "docs": {}, + "k": { + "df": 1, + "docs": { + "9": { + "tf": 1.0 + } + } + }, "l": { "d": { "df": 1, @@ -2388,7 +2562,7 @@ "s": { "df": 1, "docs": { - "9": { + "10": { "tf": 1.0 } } @@ -2511,6 +2685,26 @@ } } }, + "l": { + "df": 0, + "docs": {}, + "i": { + "df": 0, + "docs": {}, + "n": { + "df": 0, + "docs": {}, + "k": { + "df": 1, + "docs": { + "9": { + "tf": 1.0 + } + } + } + } + } + }, "n": { "df": 0, "docs": {}, @@ -2531,6 +2725,62 @@ } } }, + "p": { + "a": { + "df": 0, + "docs": {}, + "g": { + "df": 0, + "docs": {}, + "e": { + "df": 1, + "docs": { + "9": { + "tf": 1.0 + } + } + } + } + }, + "df": 0, + "docs": {}, + "r": { + "df": 0, + "docs": {}, + "i": { + "df": 0, + "docs": {}, + "n": { + "df": 0, + "docs": {}, + "t": { + "df": 1, + "docs": { + "9": { + "tf": 1.0 + } + } + } + } + } + } + }, + "r": { + "df": 0, + "docs": {}, + "e": { + "df": 0, + "docs": {}, + "l": { + "df": 1, + "docs": { + "9": { + "tf": 1.0 + } + } + } + } + }, "s": { "df": 0, "docs": {}, @@ -2609,6 +2859,26 @@ } } } + }, + "t": { + "df": 0, + "docs": {}, + "e": { + "df": 0, + "docs": {}, + "s": { + "df": 0, + "docs": {}, + "t": { + "df": 1, + "docs": { + "9": { + "tf": 1.0 + } + } + } + } + } } } } From 2ddbb37f49076dfe319f7d4b11de0f0d0fc5c880 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 15 Jan 2019 13:19:10 -0500 Subject: [PATCH 09/13] Fix the bug --- src/renderer/html_handlebars/hbs_renderer.rs | 6 +++++- src/utils/mod.rs | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index f12fd168..b5ef228d 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -33,7 +33,11 @@ impl HtmlHandlebars { if let BookItem::Chapter(ref ch) = *item { let content = ch.content.clone(); let content = utils::render_markdown(&content, ctx.html_config.curly_quotes); - print_content.push_str(&content); + + let string_path = ch.path.parent().unwrap().display().to_string(); + + let fixed_content = utils::render_markdown_with_base(&ch.content, ctx.html_config.curly_quotes, &string_path); + print_content.push_str(&fixed_content); // Update the context with data for this file let path = ch diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 31abe98c..aacdb1c7 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -66,7 +66,7 @@ pub fn id_from_content(content: &str) -> String { normalize_id(trimmed) } -fn adjust_links(event: Event) -> Event { +fn adjust_links<'a>(event: Event<'a>, with_base: &str) -> Event<'a> { lazy_static! { static ref HTTP_LINK: Regex = Regex::new("^https?://").unwrap(); static ref MD_LINK: Regex = Regex::new("(?P.*).md(?P#.*)?").unwrap(); @@ -75,6 +75,12 @@ fn adjust_links(event: Event) -> Event { match event { Event::Start(Tag::Link(dest, title)) => { if !HTTP_LINK.is_match(&dest) { + let dest = if !with_base.is_empty() { + format!("{}/{}", with_base, dest) + } else { + dest.clone().into_owned() + }; + if let Some(caps) = MD_LINK.captures(&dest) { let mut html_link = [&caps["link"], ".html"].concat(); @@ -94,6 +100,10 @@ fn adjust_links(event: Event) -> Event { /// Wrapper around the pulldown-cmark parser for rendering markdown to HTML. pub fn render_markdown(text: &str, curly_quotes: bool) -> String { + render_markdown_with_base(text, curly_quotes, "") +} + +pub fn render_markdown_with_base(text: &str, curly_quotes: bool, base: &str) -> String { let mut s = String::with_capacity(text.len() * 3 / 2); let mut opts = Options::empty(); @@ -104,7 +114,7 @@ pub fn render_markdown(text: &str, curly_quotes: bool) -> String { let mut converter = EventQuoteConverter::new(curly_quotes); let events = p .map(clean_codeblock_headers) - .map(adjust_links) + .map(|event| adjust_links(event, base)) .map(|event| converter.convert(event)); html::push_html(&mut s, events); From 23ac06e2ebdc7ce566442edc8ca45cc194008905 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 16 Jan 2019 15:44:51 -0500 Subject: [PATCH 10/13] Fix a bug in link re-writing In a regex, `.` means `[0-9a-zA-Z]`, not a period character. This means that this regex worked, unless a link anchor contained `md` inside of it. This fixes the regex to match a literal period. Reported by @ehuss in https://github.com/rust-lang-nursery/mdBook/pull/866#issuecomment-454595806 --- src/utils/mod.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/utils/mod.rs b/src/utils/mod.rs index aacdb1c7..df997d5e 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -69,7 +69,7 @@ pub fn id_from_content(content: &str) -> String { fn adjust_links<'a>(event: Event<'a>, with_base: &str) -> Event<'a> { lazy_static! { static ref HTTP_LINK: Regex = Regex::new("^https?://").unwrap(); - static ref MD_LINK: Regex = Regex::new("(?P.*).md(?P#.*)?").unwrap(); + static ref MD_LINK: Regex = Regex::new(r"(?P.*)\.md(?P#.*)?").unwrap(); } match event { @@ -230,6 +230,12 @@ mod tests { render_markdown("[example_anchor](example.md#anchor)", false), "

example_anchor

\n" ); + + // this anchor contains 'md' inside of it + assert_eq!( + render_markdown("[phantom data](foo.html#phantomdata)", false), + "

phantom data

\n" + ); } #[test] From 6cbc41d413c820bb012f7463a130145def8c593a Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 18 Jan 2019 10:39:51 -0500 Subject: [PATCH 11/13] version 0.2.3 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 17ad40dc..e83459ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -525,7 +525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "mdbook" -version = "0.2.3-alpha.0" +version = "0.2.3" dependencies = [ "ammonia 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 295014f1..ec6619b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mdbook" -version = "0.2.3-alpha.0" +version = "0.2.3" authors = [ "Mathieu David ", "Michael-F-Bryan ", From c068703028d19fb6c5a4690e904ae6f2bd74292f Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 18 Jan 2019 10:43:59 -0500 Subject: [PATCH 12/13] start next development iteration 0.2.4-alpha.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e83459ad..7d981de6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -525,7 +525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "mdbook" -version = "0.2.3" +version = "0.2.4-alpha.0" dependencies = [ "ammonia 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index ec6619b2..aa5129e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mdbook" -version = "0.2.3" +version = "0.2.4-alpha.0" authors = [ "Mathieu David ", "Michael-F-Bryan ", From 11f86f45118aaf4880ad420363debf5dd218f701 Mon Sep 17 00:00:00 2001 From: "ji.zhou" Date: Fri, 12 Apr 2019 22:53:21 +0800 Subject: [PATCH 13/13] Correct grammar: remove the redundancy --- book-example/src/cli/serve.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book-example/src/cli/serve.md b/book-example/src/cli/serve.md index 40fae4dd..0629d9ca 100644 --- a/book-example/src/cli/serve.md +++ b/book-example/src/cli/serve.md @@ -37,7 +37,7 @@ configured. #### --open -When you use the `--open` (`-o`) flag, mdbook will open the book in your your +When you use the `--open` (`-o`) flag, mdbook will open the book in your default web browser after starting the server. #### --dest-dir