diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bfd114ca..d5f1add2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,7 +32,7 @@ jobs: - build: msrv os: ubuntu-latest # sync MSRV with docs: guide/src/guide/installation.md - rust: 1.54.0 + rust: 1.56.0 steps: - uses: actions/checkout@master - name: Install Rust diff --git a/CHANGELOG.md b/CHANGELOG.md index 34bc27cd..686004c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## mdBook 0.4.21 +[92afe9b...8f01d02](https://github.com/rust-lang/mdBook/compare/92afe9b...8f01d02) + +### Fixed +- Fixed an issue where mdBook would fail to compile with Rust nightly-2022-07-22. + [#1861](https://github.com/rust-lang/mdBook/pull/1861) + ## mdBook 0.4.20 [53055e0...da166e0](https://github.com/rust-lang/mdBook/compare/53055e0...da166e0) diff --git a/Cargo.lock b/Cargo.lock index dd7feff1..90b8073f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -796,7 +796,7 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "mdbook" -version = "0.4.20" +version = "0.4.21" dependencies = [ "ammonia", "anyhow", @@ -809,10 +809,10 @@ dependencies = [ "futures-util", "gitignore", "handlebars", - "lazy_static", "log", "memchr", "notify", + "once_cell", "opener", "predicates", "pretty_assertions", @@ -997,6 +997,12 @@ dependencies = [ "libc", ] +[[package]] +name = "once_cell" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" + [[package]] name = "opaque-debug" version = "0.2.3" diff --git a/Cargo.toml b/Cargo.toml index de7ff8c9..5b564ec9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,13 @@ [package] name = "mdbook" -version = "0.4.20" +version = "0.4.21" authors = [ "Mathieu David ", "Michael-F-Bryan ", "Matt Ickstadt " ] documentation = "http://rust-lang.github.io/mdBook/index.html" -edition = "2018" +edition = "2021" exclude = ["/guide/*"] keywords = ["book", "gitbook", "rustbook", "markdown"] license = "MPL-2.0" @@ -20,9 +20,9 @@ anyhow = "1.0.28" chrono = "0.4" clap = { version = "3.0", features = ["cargo"] } clap_complete = "3.0" +once_cell = "1" env_logger = "0.9.0" handlebars = "4.0" -lazy_static = "1.0" log = "0.4" memchr = "2.0" opener = "0.5" @@ -65,3 +65,7 @@ search = ["elasticlunr-rs", "ammonia"] [[bin]] doc = false name = "mdbook" + +[[example]] +name = "nop-preprocessor" +test = true diff --git a/examples/nop-preprocessor.rs b/examples/nop-preprocessor.rs index ace40093..a5e47daa 100644 --- a/examples/nop-preprocessor.rs +++ b/examples/nop-preprocessor.rs @@ -101,4 +101,58 @@ mod nop_lib { renderer != "not-supported" } } + + #[cfg(test)] + mod test { + use super::*; + + #[test] + fn nop_preprocessor_run() { + let input_json = r##"[ + { + "root": "/path/to/book", + "config": { + "book": { + "authors": ["AUTHOR"], + "language": "en", + "multilingual": false, + "src": "src", + "title": "TITLE" + }, + "preprocessor": { + "nop": {} + } + }, + "renderer": "html", + "mdbook_version": "0.4.21" + }, + { + "sections": [ + { + "Chapter": { + "name": "Chapter 1", + "content": "# Chapter 1\n", + "number": [1], + "sub_items": [], + "path": "chapter_1.md", + "source_path": "chapter_1.md", + "parent_names": [] + } + } + ], + "__non_exhaustive": null + } + ]"##; + let input_json = input_json.as_bytes(); + + let (ctx, book) = mdbook::preprocess::CmdPreprocessor::parse_input(input_json).unwrap(); + let expected_book = book.clone(); + let result = Nop::new().run(&ctx, book); + assert!(result.is_ok()); + + // The nop-preprocessor should not have made any changes to the book content. + let actual_book = result.unwrap(); + assert_eq!(actual_book, expected_book); + } + } } diff --git a/guide/src/cli/test.md b/guide/src/cli/test.md index e134dc9b..a542f3ce 100644 --- a/guide/src/cli/test.md +++ b/guide/src/cli/test.md @@ -43,7 +43,7 @@ mdbook test path/to/book The `--library-path` (`-L`) option allows you to add directories to the library search path used by `rustdoc` when it builds and tests the examples. Multiple directories can be specified with multiple options (`-L foo -L bar`) or with a -comma-delimited list (`-L foo,bar`). The path should point to the Cargo +comma-delimited list (`-L foo,bar`). The path should point to the Cargo [build cache](https://doc.rust-lang.org/cargo/guide/build-cache.html) `deps` directory that contains the build output of your project. For example, if your Rust project's book is in a directory named `my-book`, the following command would include the crate's dependencies when running `test`: @@ -61,3 +61,8 @@ The `--dest-dir` (`-d`) option allows you to change the output directory for the book. Relative paths are interpreted relative to the book's root directory. If not specified it will default to the value of the `build.build-dir` key in `book.toml`, or to `./book`. + +#### --chapter + +The `--chapter` (`-c`) option allows you to test a specific chapter of the +book using the chapter name or the relative path to the chapter. \ No newline at end of file diff --git a/guide/src/continuous-integration.md b/guide/src/continuous-integration.md index 64764d9a..c39cb010 100644 --- a/guide/src/continuous-integration.md +++ b/guide/src/continuous-integration.md @@ -21,7 +21,7 @@ A simple approach would be to use the popular `curl` CLI tool to download the ex ```sh mkdir bin -curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.20/mdbook-v0.4.20-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin +curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.21/mdbook-v0.4.21-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin bin/mdbook build ``` diff --git a/guide/src/format/configuration/renderers.md b/guide/src/format/configuration/renderers.md index f1d5ee15..b9c30861 100644 --- a/guide/src/format/configuration/renderers.md +++ b/guide/src/format/configuration/renderers.md @@ -157,7 +157,8 @@ The following configuration options are available: Defaults to `404.md`. - **site-url:** The url where the book will be hosted. This is required to ensure navigation links and script/css imports in the 404 file work correctly, even when accessing - urls in subdirectories. Defaults to `/`. + urls in subdirectories. Defaults to `/`. If `site-url` is set, + make sure to use document relative links for your assets, meaning they should not start with `/`. - **cname:** The DNS subdomain or apex domain at which your book will be hosted. This string will be written to a file named CNAME in the root of your site, as required by GitHub Pages (see [*Managing a custom domain for your GitHub Pages diff --git a/src/book/book.rs b/src/book/book.rs index d28c22da..b46843df 100644 --- a/src/book/book.rs +++ b/src/book/book.rs @@ -8,7 +8,7 @@ use super::summary::{parse_summary, Link, SectionNumber, Summary, SummaryItem}; use crate::config::BuildConfig; use crate::errors::*; use crate::utils::bracket_escape; - +use log::debug; use serde::{Deserialize, Serialize}; /// Load a book into memory from its `src/` directory. diff --git a/src/book/init.rs b/src/book/init.rs index 264c113d..dd3fa8b0 100644 --- a/src/book/init.rs +++ b/src/book/init.rs @@ -6,6 +6,7 @@ use super::MDBook; use crate::config::Config; use crate::errors::*; use crate::theme; +use log::{debug, error, info, trace}; /// A helper for setting up a new book and its directory structure. #[derive(Debug, Clone, PartialEq)] diff --git a/src/book/mod.rs b/src/book/mod.rs index 9745d2b7..5ec64d7c 100644 --- a/src/book/mod.rs +++ b/src/book/mod.rs @@ -14,6 +14,7 @@ pub use self::book::{load_book, Book, BookItem, BookItems, Chapter}; pub use self::init::BookBuilder; pub use self::summary::{parse_summary, Link, SectionNumber, Summary, SummaryItem}; +use log::{debug, error, info, log_enabled, trace, warn}; use std::io::Write; use std::path::PathBuf; use std::process::Command; @@ -246,6 +247,13 @@ impl MDBook { /// Run `rustdoc` tests on the book, linking against the provided libraries. pub fn test(&mut self, library_paths: Vec<&str>) -> Result<()> { + // test_chapter with chapter:None will run all tests. + self.test_chapter(library_paths, None) + } + + /// Run `rustdoc` tests on a specific chapter of the book, linking against the provided libraries. + /// If `chapter` is `None`, all tests will be run. + pub fn test_chapter(&mut self, library_paths: Vec<&str>, chapter: Option<&str>) -> Result<()> { let library_args: Vec<&str> = (0..library_paths.len()) .map(|_| "-L") .zip(library_paths.into_iter()) @@ -254,6 +262,8 @@ impl MDBook { let temp_dir = TempFileBuilder::new().prefix("mdbook-").tempdir()?; + let mut chapter_found = false; + // FIXME: Is "test" the proper renderer name to use here? let preprocess_context = PreprocessorContext::new(self.root.clone(), self.config.clone(), "test".to_string()); @@ -270,8 +280,16 @@ impl MDBook { _ => continue, }; - let path = self.source_dir().join(&chapter_path); - info!("Testing file: {:?}", path); + if let Some(chapter) = chapter { + if ch.name != chapter && chapter_path.to_str() != Some(chapter) { + if chapter == "?" { + info!("Skipping chapter '{}'...", ch.name); + } + continue; + } + } + chapter_found = true; + info!("Testing chapter '{}': {:?}", ch.name, chapter_path); // write preprocessed file to tempdir let path = temp_dir.path().join(&chapter_path); @@ -311,6 +329,11 @@ impl MDBook { if failed { bail!("One or more tests failed"); } + if let Some(chapter) = chapter { + if !chapter_found { + bail!("Chapter not found: {}", chapter); + } + } Ok(()) } diff --git a/src/book/summary.rs b/src/book/summary.rs index 2bd81580..02f67c6f 100644 --- a/src/book/summary.rs +++ b/src/book/summary.rs @@ -1,4 +1,5 @@ use crate::errors::*; +use log::{debug, trace, warn}; use memchr::{self, Memchr}; use pulldown_cmark::{self, Event, HeadingLevel, Tag}; use serde::{Deserialize, Serialize}; diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index bafbfd52..00eaa46b 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -89,8 +89,7 @@ pub fn execute(args: &ArgMatches) -> Result<()> { let input_404 = book .config .get("output.html.input-404") - .map(toml::Value::as_str) - .and_then(std::convert::identity) // flatten + .and_then(toml::Value::as_str) .map(ToString::to_string); let file_404 = get_404_output_file(&input_404); diff --git a/src/cmd/test.rs b/src/cmd/test.rs index 02f982a4..f5ca3ee4 100644 --- a/src/cmd/test.rs +++ b/src/cmd/test.rs @@ -17,6 +17,16 @@ pub fn make_subcommand<'help>() -> App<'help> { Relative paths are interpreted relative to the book's root directory.{n}\ If omitted, mdBook uses build.build-dir from book.toml or defaults to `./book`.", ), + ).arg( + Arg::new("chapter") + .short('c') + .long("chapter") + .value_name("chapter") + .help( + "Only test the specified chapter{n}\ + Where the name of the chapter is defined in the SUMMARY.md file.{n}\ + Use the special name \"?\" to the list of chapter names." + ) ) .arg(arg!([dir] "Root directory for the book{n}\ @@ -41,14 +51,18 @@ pub fn execute(args: &ArgMatches) -> Result<()> { .values_of("library-path") .map(std::iter::Iterator::collect) .unwrap_or_default(); + let chapter: Option<&str> = args.value_of("chapter"); + let book_dir = get_book_dir(args); let mut book = MDBook::load(&book_dir)?; if let Some(dest_dir) = args.value_of("dest-dir") { book.config.build.build_dir = dest_dir.into(); } - - book.test(library_paths)?; + match chapter { + Some(_) => book.test_chapter(library_paths, chapter), + None => book.test(library_paths), + }?; Ok(()) } diff --git a/src/config.rs b/src/config.rs index b7d03d1a..6b8f1414 100644 --- a/src/config.rs +++ b/src/config.rs @@ -49,6 +49,7 @@ #![deny(missing_docs)] +use log::{debug, trace, warn}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::collections::HashMap; use std::env; @@ -295,7 +296,7 @@ impl Default for Config { } } -impl<'de> Deserialize<'de> for Config { +impl<'de> serde::Deserialize<'de> for Config { fn deserialize>(de: D) -> std::result::Result { let raw = Value::deserialize(de)?; @@ -717,6 +718,7 @@ impl<'de, T> Updateable<'de> for T where T: Serialize + Deserialize<'de> {} mod tests { use super::*; use crate::utils::fs::get_404_output_file; + use serde_json::json; const COMPLEX_CONFIG: &str = r#" [book] diff --git a/src/lib.rs b/src/lib.rs index cc62b0ab..14cd94d9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -83,17 +83,6 @@ #![deny(missing_docs)] #![deny(rust_2018_idioms)] -#[macro_use] -extern crate lazy_static; -#[macro_use] -extern crate log; -#[macro_use] -extern crate serde_json; - -#[cfg(test)] -#[macro_use] -extern crate pretty_assertions; - pub mod book; pub mod config; pub mod preprocess; diff --git a/src/preprocess/cmd.rs b/src/preprocess/cmd.rs index c47fd5d2..149dabda 100644 --- a/src/preprocess/cmd.rs +++ b/src/preprocess/cmd.rs @@ -1,6 +1,7 @@ use super::{Preprocessor, PreprocessorContext}; use crate::book::Book; use crate::errors::*; +use log::{debug, trace, warn}; use shlex::Shlex; use std::io::{self, Read, Write}; use std::process::{Child, Command, Stdio}; diff --git a/src/preprocess/index.rs b/src/preprocess/index.rs index fd60ad4d..004b7eda 100644 --- a/src/preprocess/index.rs +++ b/src/preprocess/index.rs @@ -1,10 +1,11 @@ use regex::Regex; use std::path::Path; -use crate::errors::*; - use super::{Preprocessor, PreprocessorContext}; use crate::book::{Book, BookItem}; +use crate::errors::*; +use log::warn; +use once_cell::sync::Lazy; /// A preprocessor for converting file name `README.md` to `index.md` since /// `README.md` is the de facto index file in markdown-based documentation. @@ -67,9 +68,8 @@ fn warn_readme_name_conflict>(readme_path: P, index_path: P) { } fn is_readme_file>(path: P) -> bool { - lazy_static! { - static ref RE: Regex = Regex::new(r"(?i)^readme$").unwrap(); - } + static RE: Lazy = Lazy::new(|| Regex::new(r"(?i)^readme$").unwrap()); + RE.is_match( path.as_ref() .file_stem() diff --git a/src/preprocess/links.rs b/src/preprocess/links.rs index da9141ea..0521e2e9 100644 --- a/src/preprocess/links.rs +++ b/src/preprocess/links.rs @@ -10,6 +10,8 @@ use std::path::{Path, PathBuf}; use super::{Preprocessor, PreprocessorContext}; use crate::book::{Book, BookItem}; +use log::{error, warn}; +use once_cell::sync::Lazy; const ESCAPE_CHAR: char = '\\'; const MAX_LINK_NESTED_DEPTH: usize = 10; @@ -434,19 +436,20 @@ impl<'a> Iterator for LinkIter<'a> { fn find_links(contents: &str) -> LinkIter<'_> { // lazily compute following regex // r"\\\{\{#.*\}\}|\{\{#([a-zA-Z0-9]+)\s*([^}]+)\}\}")?; - lazy_static! { - static ref RE: Regex = Regex::new( + static RE: Lazy = Lazy::new(|| { + Regex::new( r"(?x) # insignificant whitespace mode - \\\{\{\#.*\}\} # match escaped link - | # or - \{\{\s* # link opening parens and whitespace - \#([a-zA-Z0-9_]+) # link type - \s+ # separating whitespace - ([^}]+) # link target path and space separated properties - \}\} # link closing parens" + \\\{\{\#.*\}\} # match escaped link + | # or + \{\{\s* # link opening parens and whitespace + \#([a-zA-Z0-9_]+) # link type + \s+ # separating whitespace + ([^}]+) # link target path and space separated properties + \}\} # link closing parens", ) - .unwrap(); - } + .unwrap() + }); + LinkIter(RE.captures_iter(contents)) } diff --git a/src/preprocess/mod.rs b/src/preprocess/mod.rs index 894e2003..df01a3db 100644 --- a/src/preprocess/mod.rs +++ b/src/preprocess/mod.rs @@ -12,12 +12,11 @@ use crate::book::Book; use crate::config::Config; use crate::errors::*; +use serde::{Deserialize, Serialize}; use std::cell::RefCell; use std::collections::HashMap; use std::path::PathBuf; -use serde::{Deserialize, Serialize}; - /// Extra information for a `Preprocessor` to give them more context when /// processing a book. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index b933a359..710449af 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -14,7 +14,10 @@ use std::path::{Path, PathBuf}; use crate::utils::fs::get_404_output_file; use handlebars::Handlebars; +use log::{debug, trace, warn}; +use once_cell::sync::Lazy; use regex::{Captures, Regex}; +use serde_json::json; #[derive(Default)] pub struct HtmlHandlebars; @@ -764,9 +767,8 @@ fn make_data( /// Goes through the rendered HTML, making sure all header tags have /// an anchor respectively so people can link to sections directly. fn build_header_links(html: &str) -> String { - lazy_static! { - static ref BUILD_HEADER_LINKS: Regex = Regex::new(r"(.*?)").unwrap(); - } + static BUILD_HEADER_LINKS: Lazy = + Lazy::new(|| Regex::new(r"(.*?)").unwrap()); let mut id_counter = HashMap::new(); @@ -807,10 +809,8 @@ fn insert_link_into_header( // ``` // This function replaces all commas by spaces in the code block classes fn fix_code_blocks(html: &str) -> String { - lazy_static! { - static ref FIX_CODE_BLOCKS: Regex = - Regex::new(r##"]+)class="([^"]+)"([^>]*)>"##).unwrap(); - } + static FIX_CODE_BLOCKS: Lazy = + Lazy::new(|| Regex::new(r##"]+)class="([^"]+)"([^>]*)>"##).unwrap()); FIX_CODE_BLOCKS .replace_all(html, |caps: &Captures<'_>| { @@ -833,10 +833,9 @@ fn add_playground_pre( playground_config: &Playground, edition: Option, ) -> String { - lazy_static! { - static ref ADD_PLAYGROUND_PRE: Regex = - Regex::new(r##"((?s)]?class="([^"]+)".*?>(.*?))"##).unwrap(); - } + static ADD_PLAYGROUND_PRE: Lazy = + Lazy::new(|| Regex::new(r##"((?s)]?class="([^"]+)".*?>(.*?))"##).unwrap()); + ADD_PLAYGROUND_PRE .replace_all(html, |caps: &Captures<'_>| { let text = &caps[1]; @@ -899,18 +898,19 @@ fn add_playground_pre( } fn hide_lines(content: &str) -> String { - lazy_static! { - static ref BORING_LINES_REGEX: Regex = Regex::new(r"^(\s*)#(.?)(.*)$").unwrap(); - } + static BORING_LINES_REGEX: Lazy = Lazy::new(|| Regex::new(r"^(\s*)#(.?)(.*)$").unwrap()); let mut result = String::with_capacity(content.len()); - for line in content.lines() { + let mut lines = content.lines().peekable(); + while let Some(line) = lines.next() { + // Don't include newline on the last line. + let newline = if lines.peek().is_none() { "" } else { "\n" }; if let Some(caps) = BORING_LINES_REGEX.captures(line) { if &caps[2] == "#" { result += &caps[1]; result += &caps[2]; result += &caps[3]; - result += "\n"; + result += newline; continue; } else if &caps[2] != "!" && &caps[2] != "[" { result += ""; @@ -919,13 +919,13 @@ fn hide_lines(content: &str) -> String { result += &caps[2]; } result += &caps[3]; - result += "\n"; + result += newline; result += ""; continue; } } result += line; - result += "\n"; + result += newline; } result } @@ -1005,19 +1005,19 @@ mod tests { fn add_playground() { let inputs = [ ("x()", - "
#![allow(unused)]\nfn main() {\nx()\n}\n
"), + "
#![allow(unused)]\nfn main() {\nx()\n}
"), ("fn main() {}", - "
fn main() {}\n
"), + "
fn main() {}
"), ("let s = \"foo\n # bar\n\";", - "
let s = \"foo\n bar\n\";\n
"), + "
let s = \"foo\n bar\n\";
"), ("let s = \"foo\n ## bar\n\";", - "
let s = \"foo\n # bar\n\";\n
"), + "
let s = \"foo\n # bar\n\";
"), ("let s = \"foo\n # bar\n#\n\";", - "
let s = \"foo\n bar\n\n\";\n
"), + "
let s = \"foo\n bar\n\n\";
"), ("let s = \"foo\n # bar\n\";", - "let s = \"foo\n bar\n\";\n"), + "let s = \"foo\n bar\n\";"), ("#![no_std]\nlet s = \"foo\";\n #[some_attr]", - "
#![no_std]\nlet s = \"foo\";\n #[some_attr]\n
"), + "
#![no_std]\nlet s = \"foo\";\n #[some_attr]
"), ]; for (src, should_be) in &inputs { let got = add_playground_pre( @@ -1035,13 +1035,13 @@ mod tests { fn add_playground_edition2015() { let inputs = [ ("x()", - "
#![allow(unused)]\nfn main() {\nx()\n}\n
"), + "
#![allow(unused)]\nfn main() {\nx()\n}
"), ("fn main() {}", - "
fn main() {}\n
"), + "
fn main() {}
"), ("fn main() {}", - "
fn main() {}\n
"), + "
fn main() {}
"), ("fn main() {}", - "
fn main() {}\n
"), + "
fn main() {}
"), ]; for (src, should_be) in &inputs { let got = add_playground_pre( @@ -1059,13 +1059,13 @@ mod tests { fn add_playground_edition2018() { let inputs = [ ("x()", - "
#![allow(unused)]\nfn main() {\nx()\n}\n
"), + "
#![allow(unused)]\nfn main() {\nx()\n}
"), ("fn main() {}", - "
fn main() {}\n
"), + "
fn main() {}
"), ("fn main() {}", - "
fn main() {}\n
"), + "
fn main() {}
"), ("fn main() {}", - "
fn main() {}\n
"), + "
fn main() {}
"), ]; for (src, should_be) in &inputs { let got = add_playground_pre( @@ -1083,13 +1083,13 @@ mod tests { fn add_playground_edition2021() { let inputs = [ ("x()", - "
#![allow(unused)]\nfn main() {\nx()\n}\n
"), + "
#![allow(unused)]\nfn main() {\nx()\n}
"), ("fn main() {}", - "
fn main() {}\n
"), + "
fn main() {}
"), ("fn main() {}", - "
fn main() {}\n
"), + "
fn main() {}
"), ("fn main() {}", - "
fn main() {}\n
"), + "
fn main() {}
"), ]; for (src, should_be) in &inputs { let got = add_playground_pre( diff --git a/src/renderer/html_handlebars/helpers/navigation.rs b/src/renderer/html_handlebars/helpers/navigation.rs index d3f6ca90..b184c441 100644 --- a/src/renderer/html_handlebars/helpers/navigation.rs +++ b/src/renderer/html_handlebars/helpers/navigation.rs @@ -4,6 +4,8 @@ use std::path::Path; use handlebars::{Context, Handlebars, Helper, Output, RenderContext, RenderError, Renderable}; use crate::utils; +use log::{debug, trace}; +use serde_json::json; type StringMap = BTreeMap; @@ -146,15 +148,12 @@ fn render( trace!("Render template"); - _h.template() - .ok_or_else(|| RenderError::new("Error with the handlebars template")) - .and_then(|t| { - let mut local_rc = rc.clone(); - let local_ctx = Context::wraps(&context)?; - t.render(r, &local_ctx, &mut local_rc, out) - })?; - - Ok(()) + let t = _h + .template() + .ok_or_else(|| RenderError::new("Error with the handlebars template"))?; + let local_ctx = Context::wraps(&context)?; + let mut local_rc = rc.clone(); + t.render(r, &local_ctx, &mut local_rc, out) } pub fn previous( diff --git a/src/renderer/html_handlebars/helpers/theme.rs b/src/renderer/html_handlebars/helpers/theme.rs index 809ee117..83aba677 100644 --- a/src/renderer/html_handlebars/helpers/theme.rs +++ b/src/renderer/html_handlebars/helpers/theme.rs @@ -1,4 +1,5 @@ use handlebars::{Context, Handlebars, Helper, Output, RenderContext, RenderError}; +use log::trace; pub fn theme_option( h: &Helper<'_, '_>, diff --git a/src/renderer/html_handlebars/helpers/toc.rs b/src/renderer/html_handlebars/helpers/toc.rs index 0884d30a..e96e6ef6 100644 --- a/src/renderer/html_handlebars/helpers/toc.rs +++ b/src/renderer/html_handlebars/helpers/toc.rs @@ -117,35 +117,35 @@ impl HelperDef for RenderToc { } // Link - let path_exists = if let Some(path) = - item.get("path") - .and_then(|p| if p.is_empty() { None } else { Some(p) }) - { - out.write(" { + out.write("")?; + path_exists = true; } - - out.write(">")?; - true - } else { - out.write("
")?; - false - }; + _ => { + out.write("
")?; + path_exists = false; + } + } if !self.no_section_label { // Section does not necessarily exist diff --git a/src/renderer/html_handlebars/search.rs b/src/renderer/html_handlebars/search.rs index c3b944c9..a9e2f5ca 100644 --- a/src/renderer/html_handlebars/search.rs +++ b/src/renderer/html_handlebars/search.rs @@ -3,6 +3,7 @@ use std::collections::{HashMap, HashSet}; use std::path::Path; use elasticlunr::{Index, IndexBuilder}; +use once_cell::sync::Lazy; use pulldown_cmark::*; use crate::book::{Book, BookItem}; @@ -10,7 +11,7 @@ use crate::config::Search; use crate::errors::*; use crate::theme::searcher; use crate::utils; - +use log::{debug, warn}; use serde::Serialize; const MAX_WORD_LENGTH_TO_INDEX: usize = 80; @@ -266,21 +267,19 @@ fn write_to_json(index: Index, search_config: &Search, doc_urls: Vec) -> } fn clean_html(html: &str) -> String { - lazy_static! { - static ref AMMONIA: ammonia::Builder<'static> = { - let mut clean_content = HashSet::new(); - clean_content.insert("script"); - clean_content.insert("style"); - let mut builder = ammonia::Builder::new(); - builder - .tags(HashSet::new()) - .tag_attributes(HashMap::new()) - .generic_attributes(HashSet::new()) - .link_rel(None) - .allowed_classes(HashMap::new()) - .clean_content_tags(clean_content); - builder - }; - } + static AMMONIA: Lazy> = Lazy::new(|| { + let mut clean_content = HashSet::new(); + clean_content.insert("script"); + clean_content.insert("style"); + let mut builder = ammonia::Builder::new(); + builder + .tags(HashSet::new()) + .tag_attributes(HashMap::new()) + .generic_attributes(HashSet::new()) + .link_rel(None) + .allowed_classes(HashMap::new()) + .clean_content_tags(clean_content); + builder + }); AMMONIA.clean(html).to_string() } diff --git a/src/renderer/markdown_renderer.rs b/src/renderer/markdown_renderer.rs index bd5def1f..13bd05cc 100644 --- a/src/renderer/markdown_renderer.rs +++ b/src/renderer/markdown_renderer.rs @@ -2,7 +2,7 @@ use crate::book::BookItem; use crate::errors::*; use crate::renderer::{RenderContext, Renderer}; use crate::utils; - +use log::trace; use std::fs; #[derive(Default)] diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 15465fbc..1c97f8f2 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -27,6 +27,7 @@ use std::process::{Command, Stdio}; use crate::book::Book; use crate::config::Config; use crate::errors::*; +use log::{error, info, trace, warn}; use toml::Value; use serde::{Deserialize, Serialize}; diff --git a/src/theme/index.hbs b/src/theme/index.hbs index 18d984a2..0321e141 100644 --- a/src/theme/index.hbs +++ b/src/theme/index.hbs @@ -51,18 +51,18 @@ {{#if mathjax_support}} - + {{/if}} - - - - {{/if}} {{#if playground_copyable}} - {{/if}} {{#if playground_js}} - - - - - + + + + + {{/if}} {{#if search_js}} - - - + + + {{/if}} - - - + + + {{#each additional_js}} - + {{/each}} {{#if is_print}} {{#if mathjax_support}} - {{else}} -