summaryrefslogtreecommitdiffstats
path: root/vendor/mdbook/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:58 +0000
commita4b7ed7a42c716ab9f05e351f003d589124fd55d (patch)
treeb620cd3f223850b28716e474e80c58059dca5dd4 /vendor/mdbook/src
parentAdding upstream version 1.67.1+dfsg1. (diff)
downloadrustc-a4b7ed7a42c716ab9f05e351f003d589124fd55d.tar.xz
rustc-a4b7ed7a42c716ab9f05e351f003d589124fd55d.zip
Adding upstream version 1.68.2+dfsg1.upstream/1.68.2+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/mdbook/src')
-rw-r--r--vendor/mdbook/src/book/book.rs2
-rw-r--r--vendor/mdbook/src/book/init.rs1
-rw-r--r--vendor/mdbook/src/book/mod.rs28
-rw-r--r--vendor/mdbook/src/book/summary.rs3
-rw-r--r--vendor/mdbook/src/cmd/build.rs30
-rw-r--r--vendor/mdbook/src/cmd/clean.rs26
-rw-r--r--vendor/mdbook/src/cmd/command_prelude.rs45
-rw-r--r--vendor/mdbook/src/cmd/init.rs44
-rw-r--r--vendor/mdbook/src/cmd/mod.rs1
-rw-r--r--vendor/mdbook/src/cmd/serve.rs47
-rw-r--r--vendor/mdbook/src/cmd/test.rs66
-rw-r--r--vendor/mdbook/src/cmd/watch.rs81
-rw-r--r--vendor/mdbook/src/config.rs16
-rw-r--r--vendor/mdbook/src/lib.rs11
-rw-r--r--vendor/mdbook/src/main.rs42
-rw-r--r--vendor/mdbook/src/preprocess/cmd.rs1
-rw-r--r--vendor/mdbook/src/preprocess/index.rs10
-rw-r--r--vendor/mdbook/src/preprocess/links.rs25
-rw-r--r--vendor/mdbook/src/preprocess/mod.rs3
-rw-r--r--vendor/mdbook/src/renderer/html_handlebars/hbs_renderer.rs76
-rw-r--r--vendor/mdbook/src/renderer/html_handlebars/helpers/navigation.rs17
-rw-r--r--vendor/mdbook/src/renderer/html_handlebars/helpers/theme.rs1
-rw-r--r--vendor/mdbook/src/renderer/html_handlebars/helpers/toc.rs56
-rw-r--r--vendor/mdbook/src/renderer/html_handlebars/search.rs33
-rw-r--r--vendor/mdbook/src/renderer/markdown_renderer.rs2
-rw-r--r--vendor/mdbook/src/renderer/mod.rs1
-rw-r--r--vendor/mdbook/src/theme/book.js17
-rw-r--r--vendor/mdbook/src/theme/css/chrome.css14
-rw-r--r--vendor/mdbook/src/theme/css/general.css16
-rw-r--r--vendor/mdbook/src/theme/css/variables.css2
-rw-r--r--vendor/mdbook/src/theme/index.hbs59
-rw-r--r--vendor/mdbook/src/theme/mod.rs2
-rw-r--r--vendor/mdbook/src/theme/redirect.hbs4
-rw-r--r--vendor/mdbook/src/utils/fs.rs1
-rw-r--r--vendor/mdbook/src/utils/mod.rs26
-rw-r--r--vendor/mdbook/src/utils/string.rs9
36 files changed, 436 insertions, 382 deletions
diff --git a/vendor/mdbook/src/book/book.rs b/vendor/mdbook/src/book/book.rs
index d28c22dad..b46843df5 100644
--- a/vendor/mdbook/src/book/book.rs
+++ b/vendor/mdbook/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/vendor/mdbook/src/book/init.rs b/vendor/mdbook/src/book/init.rs
index 264c113d3..dd3fa8b0d 100644
--- a/vendor/mdbook/src/book/init.rs
+++ b/vendor/mdbook/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/vendor/mdbook/src/book/mod.rs b/vendor/mdbook/src/book/mod.rs
index 9745d2b7e..75bbcc714 100644
--- a/vendor/mdbook/src/book/mod.rs
+++ b/vendor/mdbook/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);
@@ -295,6 +313,7 @@ impl MDBook {
}
}
+ debug!("running {:?}", cmd);
let output = cmd.output()?;
if !output.status.success() {
@@ -311,6 +330,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/vendor/mdbook/src/book/summary.rs b/vendor/mdbook/src/book/summary.rs
index 2bd81580f..b2784ce5f 100644
--- a/vendor/mdbook/src/book/summary.rs
+++ b/vendor/mdbook/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};
@@ -453,7 +454,7 @@ impl<'a> SummaryParser<'a> {
items.push(item);
}
Some(Event::Start(Tag::List(..))) => {
- // Skip this tag after comment bacause it is not nested.
+ // Skip this tag after comment because it is not nested.
if items.is_empty() {
continue;
}
diff --git a/vendor/mdbook/src/cmd/build.rs b/vendor/mdbook/src/cmd/build.rs
index 5fe73236c..14a9fec6e 100644
--- a/vendor/mdbook/src/cmd/build.rs
+++ b/vendor/mdbook/src/cmd/build.rs
@@ -1,28 +1,16 @@
+use super::command_prelude::*;
use crate::{get_book_dir, open};
-use clap::{arg, App, Arg, ArgMatches};
use mdbook::errors::Result;
use mdbook::MDBook;
+use std::path::PathBuf;
// Create clap subcommand arguments
-pub fn make_subcommand<'help>() -> App<'help> {
- App::new("build")
+pub fn make_subcommand() -> Command {
+ Command::new("build")
.about("Builds a book from its markdown files")
- .arg(
- Arg::new("dest-dir")
- .short('d')
- .long("dest-dir")
- .value_name("dest-dir")
- .help(
- "Output directory for the book{n}\
- 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!([dir]
- "Root directory for the book{n}\
- (Defaults to the Current Directory when omitted)"
- ))
- .arg(arg!(-o --open "Opens the compiled book in a web browser"))
+ .arg_dest_dir()
+ .arg_root_dir()
+ .arg_open()
}
// Build command implementation
@@ -30,13 +18,13 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
let book_dir = get_book_dir(args);
let mut book = MDBook::load(&book_dir)?;
- if let Some(dest_dir) = args.value_of("dest-dir") {
+ if let Some(dest_dir) = args.get_one::<PathBuf>("dest-dir") {
book.config.build.build_dir = dest_dir.into();
}
book.build()?;
- if args.is_present("open") {
+ if args.get_flag("open") {
// FIXME: What's the right behaviour if we don't use the HTML renderer?
let path = book.build_dir_for("html").join("index.html");
if !path.exists() {
diff --git a/vendor/mdbook/src/cmd/clean.rs b/vendor/mdbook/src/cmd/clean.rs
index 0569726e1..3ec605fea 100644
--- a/vendor/mdbook/src/cmd/clean.rs
+++ b/vendor/mdbook/src/cmd/clean.rs
@@ -1,28 +1,16 @@
+use super::command_prelude::*;
use crate::get_book_dir;
use anyhow::Context;
-use clap::{arg, App, Arg, ArgMatches};
use mdbook::MDBook;
use std::fs;
+use std::path::PathBuf;
// Create clap subcommand arguments
-pub fn make_subcommand<'help>() -> App<'help> {
- App::new("clean")
+pub fn make_subcommand() -> Command {
+ Command::new("clean")
.about("Deletes a built book")
- .arg(
- Arg::new("dest-dir")
- .short('d')
- .long("dest-dir")
- .value_name("dest-dir")
- .help(
- "Output directory for the book{n}\
- 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!([dir]
- "Root directory for the book{n}\
- (Defaults to the Current Directory when omitted)"
- ))
+ .arg_dest_dir()
+ .arg_root_dir()
}
// Clean command implementation
@@ -30,7 +18,7 @@ pub fn execute(args: &ArgMatches) -> mdbook::errors::Result<()> {
let book_dir = get_book_dir(args);
let book = MDBook::load(&book_dir)?;
- let dir_to_remove = match args.value_of("dest-dir") {
+ let dir_to_remove = match args.get_one::<PathBuf>("dest-dir") {
Some(dest_dir) => dest_dir.into(),
None => book.root.join(&book.config.build.build_dir),
};
diff --git a/vendor/mdbook/src/cmd/command_prelude.rs b/vendor/mdbook/src/cmd/command_prelude.rs
new file mode 100644
index 000000000..b6362e603
--- /dev/null
+++ b/vendor/mdbook/src/cmd/command_prelude.rs
@@ -0,0 +1,45 @@
+//! Helpers for building the command-line arguments for commands.
+
+pub use clap::{arg, Arg, ArgMatches, Command};
+use std::path::PathBuf;
+
+pub trait CommandExt: Sized {
+ fn _arg(self, arg: Arg) -> Self;
+
+ fn arg_dest_dir(self) -> Self {
+ self._arg(
+ Arg::new("dest-dir")
+ .short('d')
+ .long("dest-dir")
+ .value_name("dest-dir")
+ .value_parser(clap::value_parser!(PathBuf))
+ .help(
+ "Output directory for the book\n\
+ 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`.",
+ ),
+ )
+ }
+
+ fn arg_root_dir(self) -> Self {
+ self._arg(
+ Arg::new("dir")
+ .help(
+ "Root directory for the book\n\
+ (Defaults to the current directory when omitted)",
+ )
+ .value_parser(clap::value_parser!(PathBuf)),
+ )
+ }
+
+ fn arg_open(self) -> Self {
+ self._arg(arg!(-o --open "Opens the compiled book in a web browser"))
+ }
+}
+
+impl CommandExt for Command {
+ fn _arg(self, arg: Arg) -> Self {
+ self.arg(arg)
+ }
+}
diff --git a/vendor/mdbook/src/cmd/init.rs b/vendor/mdbook/src/cmd/init.rs
index c964dcc13..d8ce93d16 100644
--- a/vendor/mdbook/src/cmd/init.rs
+++ b/vendor/mdbook/src/cmd/init.rs
@@ -1,5 +1,5 @@
use crate::get_book_dir;
-use clap::{arg, App, Arg, ArgMatches};
+use clap::{arg, ArgMatches, Command as ClapCommand};
use mdbook::config;
use mdbook::errors::Result;
use mdbook::MDBook;
@@ -8,30 +8,22 @@ use std::io::Write;
use std::process::Command;
// Create clap subcommand arguments
-pub fn make_subcommand<'help>() -> App<'help> {
- App::new("init")
+pub fn make_subcommand() -> ClapCommand {
+ ClapCommand::new("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(arg!([dir]
- "Directory to create the book in{n}\
- (Defaults to the Current Directory when omitted)"
- ))
- .arg(arg!(--theme "Copies the default theme into your source folder"))
- .arg(arg!(--force "Skips confirmation prompts"))
.arg(
- Arg::new("title")
- .long("title")
- .takes_value(true)
- .help("Sets the book title")
- .required(false),
+ arg!([dir]
+ "Directory to create the book in\n\
+ (Defaults to the current directory when omitted)"
+ )
+ .value_parser(clap::value_parser!(std::path::PathBuf)),
)
+ .arg(arg!(--theme "Copies the default theme into your source folder"))
+ .arg(arg!(--force "Skips confirmation prompts"))
+ .arg(arg!(--title <title> "Sets the book title"))
.arg(
- Arg::new("ignore")
- .long("ignore")
- .takes_value(true)
- .possible_values(&["none", "git"])
- .help("Creates a VCS ignore file (i.e. .gitignore)")
- .required(false),
+ arg!(--ignore <ignore> "Creates a VCS ignore file (i.e. .gitignore)")
+ .value_parser(["none", "git"]),
)
}
@@ -41,12 +33,12 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
let mut builder = MDBook::init(&book_dir);
let mut config = config::Config::default();
// If flag `--theme` is present, copy theme to src
- if args.is_present("theme") {
+ if args.get_flag("theme") {
let theme_dir = book_dir.join("theme");
println!();
println!("Copying the default theme to {}", theme_dir.display());
// Skip this if `--force` is present
- if !args.is_present("force") && theme_dir.exists() {
+ if !args.get_flag("force") && theme_dir.exists() {
println!("This could potentially overwrite files already present in that directory.");
print!("\nAre you sure you want to continue? (y/n) ");
@@ -59,7 +51,7 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
}
}
- if let Some(ignore) = args.value_of("ignore") {
+ if let Some(ignore) = args.get_one::<String>("ignore").map(|s| s.as_str()) {
match ignore {
"git" => builder.create_gitignore(true),
_ => builder.create_gitignore(false),
@@ -71,8 +63,8 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
}
}
- config.book.title = if args.is_present("title") {
- args.value_of("title").map(String::from)
+ config.book.title = if args.contains_id("title") {
+ args.get_one::<String>("title").map(String::from)
} else {
request_book_title()
};
diff --git a/vendor/mdbook/src/cmd/mod.rs b/vendor/mdbook/src/cmd/mod.rs
index c5b6730f1..b21979b27 100644
--- a/vendor/mdbook/src/cmd/mod.rs
+++ b/vendor/mdbook/src/cmd/mod.rs
@@ -2,6 +2,7 @@
pub mod build;
pub mod clean;
+pub mod command_prelude;
pub mod init;
#[cfg(feature = "serve")]
pub mod serve;
diff --git a/vendor/mdbook/src/cmd/serve.rs b/vendor/mdbook/src/cmd/serve.rs
index bafbfd52e..88898567e 100644
--- a/vendor/mdbook/src/cmd/serve.rs
+++ b/vendor/mdbook/src/cmd/serve.rs
@@ -1,7 +1,8 @@
+use super::command_prelude::*;
#[cfg(feature = "watch")]
use super::watch;
use crate::{get_book_dir, open};
-use clap::{arg, App, Arg, ArgMatches};
+use clap::builder::NonEmptyStringValueParser;
use futures_util::sink::SinkExt;
use futures_util::StreamExt;
use mdbook::errors::*;
@@ -18,43 +19,30 @@ use warp::Filter;
const LIVE_RELOAD_ENDPOINT: &str = "__livereload";
// Create clap subcommand arguments
-pub fn make_subcommand<'help>() -> App<'help> {
- App::new("serve")
+pub fn make_subcommand() -> Command {
+ Command::new("serve")
.about("Serves a book at http://localhost:3000, and rebuilds it on changes")
- .arg(
- Arg::new("dest-dir")
- .short('d')
- .long("dest-dir")
- .value_name("dest-dir")
- .help(
- "Output directory for the book{n}\
- 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!([dir]
- "Root directory for the book{n}\
- (Defaults to the Current Directory when omitted)"
- ))
+ .arg_dest_dir()
+ .arg_root_dir()
.arg(
Arg::new("hostname")
.short('n')
.long("hostname")
- .takes_value(true)
+ .num_args(1)
.default_value("localhost")
- .forbid_empty_values(true)
+ .value_parser(NonEmptyStringValueParser::new())
.help("Hostname to listen on for HTTP connections"),
)
.arg(
Arg::new("port")
.short('p')
.long("port")
- .takes_value(true)
+ .num_args(1)
.default_value("3000")
- .forbid_empty_values(true)
+ .value_parser(NonEmptyStringValueParser::new())
.help("Port to use for HTTP connections"),
)
- .arg(arg!(-o --open "Opens the compiled book in a web browser"))
+ .arg_open()
}
// Serve command implementation
@@ -62,17 +50,17 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
let book_dir = get_book_dir(args);
let mut book = MDBook::load(&book_dir)?;
- let port = args.value_of("port").unwrap();
- let hostname = args.value_of("hostname").unwrap();
- let open_browser = args.is_present("open");
+ let port = args.get_one::<String>("port").unwrap();
+ let hostname = args.get_one::<String>("hostname").unwrap();
+ let open_browser = args.get_flag("open");
let address = format!("{}:{}", hostname, port);
let update_config = |book: &mut MDBook| {
book.config
- .set("output.html.live-reload-endpoint", &LIVE_RELOAD_ENDPOINT)
+ .set("output.html.live-reload-endpoint", LIVE_RELOAD_ENDPOINT)
.expect("live-reload-endpoint update failed");
- if let Some(dest_dir) = args.value_of("dest-dir") {
+ if let Some(dest_dir) = args.get_one::<PathBuf>("dest-dir") {
book.config.build.build_dir = dest_dir.into();
}
// Override site-url for local serving of the 404 file
@@ -89,8 +77,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/vendor/mdbook/src/cmd/test.rs b/vendor/mdbook/src/cmd/test.rs
index 02f982a49..3efe130b1 100644
--- a/vendor/mdbook/src/cmd/test.rs
+++ b/vendor/mdbook/src/cmd/test.rs
@@ -1,54 +1,58 @@
+use super::command_prelude::*;
use crate::get_book_dir;
-use clap::{arg, App, Arg, ArgMatches};
+use clap::builder::NonEmptyStringValueParser;
+use clap::{Arg, ArgAction, ArgMatches, Command};
use mdbook::errors::Result;
use mdbook::MDBook;
+use std::path::PathBuf;
// Create clap subcommand arguments
-pub fn make_subcommand<'help>() -> App<'help> {
- App::new("test")
+pub fn make_subcommand() -> Command {
+ Command::new("test")
.about("Tests that a book's Rust code samples compile")
+ // FIXME: --dest-dir is unused by the test command, it should be removed
+ .arg_dest_dir()
+ .arg_root_dir()
.arg(
- Arg::new("dest-dir")
- .short('d')
- .long("dest-dir")
- .value_name("dest-dir")
+ Arg::new("chapter")
+ .short('c')
+ .long("chapter")
+ .value_name("chapter"),
+ )
+ .arg(
+ Arg::new("library-path")
+ .short('L')
+ .long("library-path")
+ .value_name("dir")
+ .value_delimiter(',')
+ .value_parser(NonEmptyStringValueParser::new())
+ .action(ArgAction::Append)
.help(
- "Output directory for the book{n}\
- 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`.",
+ "A comma-separated list of directories to add to the crate \
+ search path when building tests",
),
)
- .arg(arg!([dir]
- "Root directory for the book{n}\
- (Defaults to the Current Directory when omitted)"
- ))
- .arg(Arg::new("library-path")
- .short('L')
- .long("library-path")
- .value_name("dir")
- .takes_value(true)
- .use_delimiter(true)
- .require_delimiter(true)
- .multiple_values(true)
- .multiple_occurrences(true)
- .forbid_empty_values(true)
- .help("A comma-separated list of directories to add to {n}the crate search path when building tests"))
}
// test command implementation
pub fn execute(args: &ArgMatches) -> Result<()> {
let library_paths: Vec<&str> = args
- .values_of("library-path")
- .map(std::iter::Iterator::collect)
+ .get_many("library-path")
+ .map(|it| it.map(String::as_str).collect())
.unwrap_or_default();
+
+ let chapter: Option<&str> = args.get_one::<String>("chapter").map(|s| s.as_str());
+
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();
+ if let Some(dest_dir) = args.get_one::<PathBuf>("dest-dir") {
+ book.config.build.build_dir = dest_dir.to_path_buf();
}
-
- book.test(library_paths)?;
+ match chapter {
+ Some(_) => book.test_chapter(library_paths, chapter),
+ None => book.test(library_paths),
+ }?;
Ok(())
}
diff --git a/vendor/mdbook/src/cmd/watch.rs b/vendor/mdbook/src/cmd/watch.rs
index 9336af779..bbc6bde71 100644
--- a/vendor/mdbook/src/cmd/watch.rs
+++ b/vendor/mdbook/src/cmd/watch.rs
@@ -1,34 +1,20 @@
+use super::command_prelude::*;
use crate::{get_book_dir, open};
-use clap::{arg, App, Arg, ArgMatches};
use mdbook::errors::Result;
use mdbook::utils;
use mdbook::MDBook;
-use notify::Watcher;
use std::path::{Path, PathBuf};
use std::sync::mpsc::channel;
use std::thread::sleep;
use std::time::Duration;
// Create clap subcommand arguments
-pub fn make_subcommand<'help>() -> App<'help> {
- App::new("watch")
+pub fn make_subcommand() -> Command {
+ Command::new("watch")
.about("Watches a book's files and rebuilds it on changes")
- .arg(
- Arg::new("dest-dir")
- .short('d')
- .long("dest-dir")
- .value_name("dest-dir")
- .help(
- "Output directory for the book{n}\
- 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!([dir]
- "Root directory for the book{n}\
- (Defaults to the Current Directory when omitted)"
- ))
- .arg(arg!(-o --open "Opens the compiled book in a web browser"))
+ .arg_dest_dir()
+ .arg_root_dir()
+ .arg_open()
}
// Watch command implementation
@@ -37,13 +23,13 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
let mut book = MDBook::load(&book_dir)?;
let update_config = |book: &mut MDBook| {
- if let Some(dest_dir) = args.value_of("dest-dir") {
+ if let Some(dest_dir) = args.get_one::<PathBuf>("dest-dir") {
book.config.build.build_dir = dest_dir.into();
}
};
update_config(&mut book);
- if args.is_present("open") {
+ if args.get_flag("open") {
book.build()?;
let path = book.build_dir_for("html").join("index.html");
if !path.exists() {
@@ -121,30 +107,42 @@ pub fn trigger_on_change<F>(book: &MDBook, closure: F)
where
F: Fn(Vec<PathBuf>, &Path),
{
- use notify::DebouncedEvent::*;
use notify::RecursiveMode::*;
// Create a channel to receive the events.
let (tx, rx) = channel();
- let mut watcher = match notify::watcher(tx, Duration::from_secs(1)) {
- Ok(w) => w,
+ let mut debouncer = match notify_debouncer_mini::new_debouncer(Duration::from_secs(1), None, tx)
+ {
+ Ok(d) => d,
Err(e) => {
error!("Error while trying to watch the files:\n\n\t{:?}", e);
std::process::exit(1)
}
};
+ let watcher = debouncer.watcher();
// Add the source directory to the watcher
- if let Err(e) = watcher.watch(book.source_dir(), Recursive) {
+ if let Err(e) = watcher.watch(&book.source_dir(), Recursive) {
error!("Error while watching {:?}:\n {:?}", book.source_dir(), e);
std::process::exit(1);
};
- let _ = watcher.watch(book.theme_dir(), Recursive);
+ let _ = watcher.watch(&book.theme_dir(), Recursive);
// Add the book.toml file to the watcher if it exists
- let _ = watcher.watch(book.root.join("book.toml"), NonRecursive);
+ let _ = watcher.watch(&book.root.join("book.toml"), NonRecursive);
+
+ for dir in &book.config.build.extra_watch_dirs {
+ let path = dir.canonicalize().unwrap();
+ if let Err(e) = watcher.watch(&path, Recursive) {
+ error!(
+ "Error while watching extra directory {:?}:\n {:?}",
+ path, e
+ );
+ std::process::exit(1);
+ }
+ }
info!("Listening for changes...");
@@ -155,18 +153,25 @@ where
let all_events = std::iter::once(first_event).chain(other_events);
- let paths = all_events
- .filter_map(|event| {
- debug!("Received filesystem event: {:?}", event);
-
- match event {
- Create(path) | Write(path) | Remove(path) | Rename(_, path) => Some(path),
- _ => None,
+ let paths: Vec<_> = all_events
+ .filter_map(|event| match event {
+ Ok(events) => Some(events),
+ Err(errors) => {
+ for error in errors {
+ log::warn!("error while watching for changes: {error}");
+ }
+ None
}
})
- .collect::<Vec<_>>();
-
- let paths = remove_ignored_files(&book.root, &paths[..]);
+ .flatten()
+ .map(|event| event.path)
+ .collect();
+
+ // If we are watching files outside the current repository (via extra-watch-dirs), then they are definitionally
+ // ignored by gitignore. So we handle this case by including such files into the watched paths list.
+ let any_external_paths = paths.iter().filter(|p| !p.starts_with(&book.root)).cloned();
+ let mut paths = remove_ignored_files(&book.root, &paths[..]);
+ paths.extend(any_external_paths);
if !paths.is_empty() {
closure(paths, &book.root);
diff --git a/vendor/mdbook/src/config.rs b/vendor/mdbook/src/config.rs
index b7d03d1a2..0c367d848 100644
--- a/vendor/mdbook/src/config.rs
+++ b/vendor/mdbook/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<D: Deserializer<'de>>(de: D) -> std::result::Result<Self, D::Error> {
let raw = Value::deserialize(de)?;
@@ -437,6 +438,8 @@ pub struct BuildConfig {
/// Should the default preprocessors always be used when they are
/// compatible with the renderer?
pub use_default_preprocessors: bool,
+ /// Extra directories to trigger rebuild when watching/serving
+ pub extra_watch_dirs: Vec<PathBuf>,
}
impl Default for BuildConfig {
@@ -445,6 +448,7 @@ impl Default for BuildConfig {
build_dir: PathBuf::from("book"),
create_missing: true,
use_default_preprocessors: true,
+ extra_watch_dirs: Vec::new(),
}
}
}
@@ -526,10 +530,9 @@ pub struct HtmlConfig {
/// directly jumping to editing the currently viewed page.
/// Contains {path} that is replaced with chapter source file path
pub edit_url_template: Option<String>,
- /// Endpoint of websocket, for livereload usage. Value loaded from .toml file
- /// is ignored, because our code overrides this field with the value [`LIVE_RELOAD_ENDPOINT`]
- ///
- /// [`LIVE_RELOAD_ENDPOINT`]: cmd::serve::LIVE_RELOAD_ENDPOINT
+ /// Endpoint of websocket, for livereload usage. Value loaded from .toml
+ /// file is ignored, because our code overrides this field with an
+ /// internal value (`LIVE_RELOAD_ENDPOINT)
///
/// This config item *should not be edited* by the end user.
#[doc(hidden)]
@@ -717,6 +720,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]
@@ -770,6 +774,7 @@ mod tests {
build_dir: PathBuf::from("outputs"),
create_missing: false,
use_default_preprocessors: true,
+ extra_watch_dirs: Vec::new(),
};
let rust_should_be = RustConfig { edition: None };
let playground_should_be = Playground {
@@ -980,6 +985,7 @@ mod tests {
build_dir: PathBuf::from("my-book"),
create_missing: true,
use_default_preprocessors: true,
+ extra_watch_dirs: Vec::new(),
};
let html_should_be = HtmlConfig {
diff --git a/vendor/mdbook/src/lib.rs b/vendor/mdbook/src/lib.rs
index cc62b0abd..14cd94d9d 100644
--- a/vendor/mdbook/src/lib.rs
+++ b/vendor/mdbook/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/vendor/mdbook/src/main.rs b/vendor/mdbook/src/main.rs
index 35562e64b..3e576c5b5 100644
--- a/vendor/mdbook/src/main.rs
+++ b/vendor/mdbook/src/main.rs
@@ -5,7 +5,7 @@ extern crate log;
use anyhow::anyhow;
use chrono::Local;
-use clap::{App, AppSettings, Arg, ArgMatches};
+use clap::{Arg, ArgMatches, Command};
use clap_complete::Shell;
use env_logger::Builder;
use log::LevelFilter;
@@ -13,7 +13,7 @@ use mdbook::utils;
use std::env;
use std::ffi::OsStr;
use std::io::Write;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
mod cmd;
@@ -22,10 +22,10 @@ const VERSION: &str = concat!("v", crate_version!());
fn main() {
init_logger();
- let app = create_clap_app();
+ let command = create_clap_command();
- // Check which subcomamnd the user ran...
- let res = match app.get_matches().subcommand() {
+ // Check which subcommand the user ran...
+ let res = match command.get_matches().subcommand() {
Some(("init", sub_matches)) => cmd::init::execute(sub_matches),
Some(("build", sub_matches)) => cmd::build::execute(sub_matches),
Some(("clean", sub_matches)) => cmd::clean::execute(sub_matches),
@@ -35,15 +35,13 @@ fn main() {
Some(("serve", sub_matches)) => cmd::serve::execute(sub_matches),
Some(("test", sub_matches)) => cmd::test::execute(sub_matches),
Some(("completions", sub_matches)) => (|| {
- let shell: Shell = sub_matches
- .value_of("shell")
- .ok_or_else(|| anyhow!("Shell name missing."))?
- .parse()
- .map_err(|s| anyhow!("Invalid shell: {}", s))?;
+ let shell = sub_matches
+ .get_one::<Shell>("shell")
+ .ok_or_else(|| anyhow!("Shell name missing."))?;
- let mut complete_app = create_clap_app();
+ let mut complete_app = create_clap_command();
clap_complete::generate(
- shell,
+ *shell,
&mut complete_app,
"mdbook",
&mut std::io::stdout().lock(),
@@ -61,13 +59,13 @@ fn main() {
}
/// Create a list of valid arguments and sub-commands
-fn create_clap_app() -> App<'static> {
- let app = App::new(crate_name!())
+fn create_clap_command() -> Command {
+ let app = Command::new(crate_name!())
.about(crate_description!())
.author("Mathieu David <mathieudavid@mathieudavid.org>")
.version(VERSION)
- .setting(AppSettings::PropagateVersion)
- .setting(AppSettings::ArgRequiredElseHelp)
+ .propagate_version(true)
+ .arg_required_else_help(true)
.after_help(
"For more information about a specific command, try `mdbook <command> --help`\n\
The source code for mdBook is available at: https://github.com/rust-lang/mdBook",
@@ -77,12 +75,11 @@ fn create_clap_app() -> App<'static> {
.subcommand(cmd::test::make_subcommand())
.subcommand(cmd::clean::make_subcommand())
.subcommand(
- App::new("completions")
+ Command::new("completions")
.about("Generate shell completions for your shell to stdout")
.arg(
Arg::new("shell")
- .takes_value(true)
- .possible_values(Shell::possible_values())
+ .value_parser(clap::value_parser!(Shell))
.help("the shell to generate completions for")
.value_name("SHELL")
.required(true),
@@ -124,11 +121,10 @@ fn init_logger() {
}
fn get_book_dir(args: &ArgMatches) -> PathBuf {
- if let Some(dir) = args.value_of("dir") {
+ if let Some(p) = args.get_one::<PathBuf>("dir") {
// Check if path is relative from current dir, or absolute...
- let p = Path::new(dir);
if p.is_relative() {
- env::current_dir().unwrap().join(dir)
+ env::current_dir().unwrap().join(p)
} else {
p.to_path_buf()
}
@@ -146,5 +142,5 @@ fn open<P: AsRef<OsStr>>(path: P) {
#[test]
fn verify_app() {
- create_clap_app().debug_assert();
+ create_clap_command().debug_assert();
}
diff --git a/vendor/mdbook/src/preprocess/cmd.rs b/vendor/mdbook/src/preprocess/cmd.rs
index c47fd5d22..149dabda5 100644
--- a/vendor/mdbook/src/preprocess/cmd.rs
+++ b/vendor/mdbook/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/vendor/mdbook/src/preprocess/index.rs b/vendor/mdbook/src/preprocess/index.rs
index fd60ad4da..004b7eda6 100644
--- a/vendor/mdbook/src/preprocess/index.rs
+++ b/vendor/mdbook/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<P: AsRef<Path>>(readme_path: P, index_path: P) {
}
fn is_readme_file<P: AsRef<Path>>(path: P) -> bool {
- lazy_static! {
- static ref RE: Regex = Regex::new(r"(?i)^readme$").unwrap();
- }
+ static RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)^readme$").unwrap());
+
RE.is_match(
path.as_ref()
.file_stem()
diff --git a/vendor/mdbook/src/preprocess/links.rs b/vendor/mdbook/src/preprocess/links.rs
index 7ca6fd345..c2c81f522 100644
--- a/vendor/mdbook/src/preprocess/links.rs
+++ b/vendor/mdbook/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;
@@ -408,19 +410,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<Regex> = 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/vendor/mdbook/src/preprocess/mod.rs b/vendor/mdbook/src/preprocess/mod.rs
index 894e20035..df01a3dbf 100644
--- a/vendor/mdbook/src/preprocess/mod.rs
+++ b/vendor/mdbook/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/vendor/mdbook/src/renderer/html_handlebars/hbs_renderer.rs b/vendor/mdbook/src/renderer/html_handlebars/hbs_renderer.rs
index b933a359a..1b648dac1 100644
--- a/vendor/mdbook/src/renderer/html_handlebars/hbs_renderer.rs
+++ b/vendor/mdbook/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;
@@ -337,6 +340,7 @@ impl HtmlHandlebars {
);
handlebars.register_helper("previous", Box::new(helpers::navigation::previous));
handlebars.register_helper("next", Box::new(helpers::navigation::next));
+ // TODO: remove theme_option in 0.5, it is not needed.
handlebars.register_helper("theme_option", Box::new(helpers::theme::theme_option));
}
@@ -627,6 +631,7 @@ fn make_data(
);
}
+ // TODO: remove default_theme in 0.5, it is not needed.
let default_theme = match html_config.default_theme {
Some(ref theme) => theme.to_lowercase(),
None => "light".to_string(),
@@ -764,9 +769,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"<h(\d)>(.*?)</h\d>").unwrap();
- }
+ static BUILD_HEADER_LINKS: Lazy<Regex> =
+ Lazy::new(|| Regex::new(r"<h(\d)>(.*?)</h\d>").unwrap());
let mut id_counter = HashMap::new();
@@ -807,10 +811,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##"<code([^>]+)class="([^"]+)"([^>]*)>"##).unwrap();
- }
+ static FIX_CODE_BLOCKS: Lazy<Regex> =
+ Lazy::new(|| Regex::new(r##"<code([^>]+)class="([^"]+)"([^>]*)>"##).unwrap());
FIX_CODE_BLOCKS
.replace_all(html, |caps: &Captures<'_>| {
@@ -833,10 +835,9 @@ fn add_playground_pre(
playground_config: &Playground,
edition: Option<RustEdition>,
) -> String {
- lazy_static! {
- static ref ADD_PLAYGROUND_PRE: Regex =
- Regex::new(r##"((?s)<code[^>]?class="([^"]+)".*?>(.*?)</code>)"##).unwrap();
- }
+ static ADD_PLAYGROUND_PRE: Lazy<Regex> =
+ Lazy::new(|| Regex::new(r##"((?s)<code[^>]?class="([^"]+)".*?>(.*?)</code>)"##).unwrap());
+
ADD_PLAYGROUND_PRE
.replace_all(html, |caps: &Captures<'_>| {
let text = &caps[1];
@@ -899,18 +900,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<Regex> = 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 += "<span class=\"boring\">";
@@ -919,13 +921,13 @@ fn hide_lines(content: &str) -> String {
result += &caps[2];
}
result += &caps[3];
- result += "\n";
+ result += newline;
result += "</span>";
continue;
}
}
result += line;
- result += "\n";
+ result += newline;
}
result
}
@@ -1005,19 +1007,19 @@ mod tests {
fn add_playground() {
let inputs = [
("<code class=\"language-rust\">x()</code>",
- "<pre class=\"playground\"><code class=\"language-rust\"><span class=\"boring\">#![allow(unused)]\n</span><span class=\"boring\">fn main() {\n</span>x()\n<span class=\"boring\">}\n</span></code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust\"><span class=\"boring\">#![allow(unused)]\n</span><span class=\"boring\">fn main() {\n</span>x()\n<span class=\"boring\">}</span></code></pre>"),
("<code class=\"language-rust\">fn main() {}</code>",
- "<pre class=\"playground\"><code class=\"language-rust\">fn main() {}\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust\">fn main() {}</code></pre>"),
("<code class=\"language-rust editable\">let s = \"foo\n # bar\n\";</code>",
- "<pre class=\"playground\"><code class=\"language-rust editable\">let s = \"foo\n<span class=\"boring\"> bar\n</span>\";\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust editable\">let s = \"foo\n<span class=\"boring\"> bar\n</span>\";</code></pre>"),
("<code class=\"language-rust editable\">let s = \"foo\n ## bar\n\";</code>",
- "<pre class=\"playground\"><code class=\"language-rust editable\">let s = \"foo\n # bar\n\";\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust editable\">let s = \"foo\n # bar\n\";</code></pre>"),
("<code class=\"language-rust editable\">let s = \"foo\n # bar\n#\n\";</code>",
- "<pre class=\"playground\"><code class=\"language-rust editable\">let s = \"foo\n<span class=\"boring\"> bar\n</span><span class=\"boring\">\n</span>\";\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust editable\">let s = \"foo\n<span class=\"boring\"> bar\n</span><span class=\"boring\">\n</span>\";</code></pre>"),
("<code class=\"language-rust ignore\">let s = \"foo\n # bar\n\";</code>",
- "<code class=\"language-rust ignore\">let s = \"foo\n<span class=\"boring\"> bar\n</span>\";\n</code>"),
+ "<code class=\"language-rust ignore\">let s = \"foo\n<span class=\"boring\"> bar\n</span>\";</code>"),
("<code class=\"language-rust editable\">#![no_std]\nlet s = \"foo\";\n #[some_attr]</code>",
- "<pre class=\"playground\"><code class=\"language-rust editable\">#![no_std]\nlet s = \"foo\";\n #[some_attr]\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust editable\">#![no_std]\nlet s = \"foo\";\n #[some_attr]</code></pre>"),
];
for (src, should_be) in &inputs {
let got = add_playground_pre(
@@ -1035,13 +1037,13 @@ mod tests {
fn add_playground_edition2015() {
let inputs = [
("<code class=\"language-rust\">x()</code>",
- "<pre class=\"playground\"><code class=\"language-rust edition2015\"><span class=\"boring\">#![allow(unused)]\n</span><span class=\"boring\">fn main() {\n</span>x()\n<span class=\"boring\">}\n</span></code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust edition2015\"><span class=\"boring\">#![allow(unused)]\n</span><span class=\"boring\">fn main() {\n</span>x()\n<span class=\"boring\">}</span></code></pre>"),
("<code class=\"language-rust\">fn main() {}</code>",
- "<pre class=\"playground\"><code class=\"language-rust edition2015\">fn main() {}\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust edition2015\">fn main() {}</code></pre>"),
("<code class=\"language-rust edition2015\">fn main() {}</code>",
- "<pre class=\"playground\"><code class=\"language-rust edition2015\">fn main() {}\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust edition2015\">fn main() {}</code></pre>"),
("<code class=\"language-rust edition2018\">fn main() {}</code>",
- "<pre class=\"playground\"><code class=\"language-rust edition2018\">fn main() {}\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust edition2018\">fn main() {}</code></pre>"),
];
for (src, should_be) in &inputs {
let got = add_playground_pre(
@@ -1059,13 +1061,13 @@ mod tests {
fn add_playground_edition2018() {
let inputs = [
("<code class=\"language-rust\">x()</code>",
- "<pre class=\"playground\"><code class=\"language-rust edition2018\"><span class=\"boring\">#![allow(unused)]\n</span><span class=\"boring\">fn main() {\n</span>x()\n<span class=\"boring\">}\n</span></code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust edition2018\"><span class=\"boring\">#![allow(unused)]\n</span><span class=\"boring\">fn main() {\n</span>x()\n<span class=\"boring\">}</span></code></pre>"),
("<code class=\"language-rust\">fn main() {}</code>",
- "<pre class=\"playground\"><code class=\"language-rust edition2018\">fn main() {}\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust edition2018\">fn main() {}</code></pre>"),
("<code class=\"language-rust edition2015\">fn main() {}</code>",
- "<pre class=\"playground\"><code class=\"language-rust edition2015\">fn main() {}\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust edition2015\">fn main() {}</code></pre>"),
("<code class=\"language-rust edition2018\">fn main() {}</code>",
- "<pre class=\"playground\"><code class=\"language-rust edition2018\">fn main() {}\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust edition2018\">fn main() {}</code></pre>"),
];
for (src, should_be) in &inputs {
let got = add_playground_pre(
@@ -1083,13 +1085,13 @@ mod tests {
fn add_playground_edition2021() {
let inputs = [
("<code class=\"language-rust\">x()</code>",
- "<pre class=\"playground\"><code class=\"language-rust edition2021\"><span class=\"boring\">#![allow(unused)]\n</span><span class=\"boring\">fn main() {\n</span>x()\n<span class=\"boring\">}\n</span></code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust edition2021\"><span class=\"boring\">#![allow(unused)]\n</span><span class=\"boring\">fn main() {\n</span>x()\n<span class=\"boring\">}</span></code></pre>"),
("<code class=\"language-rust\">fn main() {}</code>",
- "<pre class=\"playground\"><code class=\"language-rust edition2021\">fn main() {}\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust edition2021\">fn main() {}</code></pre>"),
("<code class=\"language-rust edition2015\">fn main() {}</code>",
- "<pre class=\"playground\"><code class=\"language-rust edition2015\">fn main() {}\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust edition2015\">fn main() {}</code></pre>"),
("<code class=\"language-rust edition2018\">fn main() {}</code>",
- "<pre class=\"playground\"><code class=\"language-rust edition2018\">fn main() {}\n</code></pre>"),
+ "<pre class=\"playground\"><code class=\"language-rust edition2018\">fn main() {}</code></pre>"),
];
for (src, should_be) in &inputs {
let got = add_playground_pre(
diff --git a/vendor/mdbook/src/renderer/html_handlebars/helpers/navigation.rs b/vendor/mdbook/src/renderer/html_handlebars/helpers/navigation.rs
index 65929bbfc..b184c4410 100644
--- a/vendor/mdbook/src/renderer/html_handlebars/helpers/navigation.rs
+++ b/vendor/mdbook/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<String, String>;
@@ -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 local_ctx = Context::wraps(&context)?;
- let mut local_rc = rc.clone();
- 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/vendor/mdbook/src/renderer/html_handlebars/helpers/theme.rs b/vendor/mdbook/src/renderer/html_handlebars/helpers/theme.rs
index 809ee1176..83aba6774 100644
--- a/vendor/mdbook/src/renderer/html_handlebars/helpers/theme.rs
+++ b/vendor/mdbook/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/vendor/mdbook/src/renderer/html_handlebars/helpers/toc.rs b/vendor/mdbook/src/renderer/html_handlebars/helpers/toc.rs
index 0884d30ad..e96e6ef64 100644
--- a/vendor/mdbook/src/renderer/html_handlebars/helpers/toc.rs
+++ b/vendor/mdbook/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("<a href=\"")?;
-
- let tmp = Path::new(item.get("path").expect("Error: path should be Some(_)"))
- .with_extension("html")
- .to_str()
- .unwrap()
- // Hack for windows who tends to use `\` as separator instead of `/`
- .replace('\\', "/");
-
- // Add link
- out.write(&utils::fs::path_to_root(&current_path))?;
- out.write(&tmp)?;
- out.write("\"")?;
-
- if path == &current_path || is_first_chapter {
- is_first_chapter = false;
- out.write(" class=\"active\"")?;
- }
+ let path_exists: bool;
+ match item.get("path") {
+ Some(path) if !path.is_empty() => {
+ out.write("<a href=\"")?;
+ let tmp = Path::new(path)
+ .with_extension("html")
+ .to_str()
+ .unwrap()
+ // Hack for windows who tends to use `\` as separator instead of `/`
+ .replace('\\', "/");
+
+ // Add link
+ out.write(&utils::fs::path_to_root(&current_path))?;
+ out.write(&tmp)?;
+ out.write("\"")?;
+
+ if path == &current_path || is_first_chapter {
+ is_first_chapter = false;
+ out.write(" class=\"active\"")?;
+ }
- out.write(">")?;
- true
- } else {
- out.write("<div>")?;
- false
- };
+ out.write(">")?;
+ path_exists = true;
+ }
+ _ => {
+ out.write("<div>")?;
+ path_exists = false;
+ }
+ }
if !self.no_section_label {
// Section does not necessarily exist
diff --git a/vendor/mdbook/src/renderer/html_handlebars/search.rs b/vendor/mdbook/src/renderer/html_handlebars/search.rs
index c3b944c9d..a9e2f5ca6 100644
--- a/vendor/mdbook/src/renderer/html_handlebars/search.rs
+++ b/vendor/mdbook/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<String>) ->
}
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<ammonia::Builder<'static>> = 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/vendor/mdbook/src/renderer/markdown_renderer.rs b/vendor/mdbook/src/renderer/markdown_renderer.rs
index bd5def1f4..13bd05cc3 100644
--- a/vendor/mdbook/src/renderer/markdown_renderer.rs
+++ b/vendor/mdbook/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/vendor/mdbook/src/renderer/mod.rs b/vendor/mdbook/src/renderer/mod.rs
index 15465fbce..1c97f8f22 100644
--- a/vendor/mdbook/src/renderer/mod.rs
+++ b/vendor/mdbook/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/vendor/mdbook/src/theme/book.js b/vendor/mdbook/src/theme/book.js
index d40440c72..e303ebb45 100644
--- a/vendor/mdbook/src/theme/book.js
+++ b/vendor/mdbook/src/theme/book.js
@@ -4,14 +4,16 @@
window.onunload = function () { };
// Global variable, shared between modules
-function playground_text(playground) {
+function playground_text(playground, hidden = true) {
let code_block = playground.querySelector("code");
if (window.ace && code_block.classList.contains("editable")) {
let editor = window.ace.edit(code_block);
return editor.getValue();
- } else {
+ } else if (hidden) {
return code_block.textContent;
+ } else {
+ return code_block.innerText;
}
}
@@ -166,7 +168,6 @@ function playground_text(playground) {
.filter(function (node) {return node.classList.contains("editable"); })
.forEach(function (block) { block.classList.remove('language-rust'); });
- Array
code_nodes
.filter(function (node) {return !node.classList.contains("editable"); })
.forEach(function (block) { hljs.highlightBlock(block); });
@@ -300,6 +301,13 @@ function playground_text(playground) {
themePopup.querySelector("button#" + get_theme()).focus();
}
+ function updateThemeSelected() {
+ themePopup.querySelectorAll('.theme-selected').forEach(function (el) {
+ el.classList.remove('theme-selected');
+ });
+ themePopup.querySelector("button#" + get_theme()).classList.add('theme-selected');
+ }
+
function hideThemes() {
themePopup.style.display = 'none';
themeToggleButton.setAttribute('aria-expanded', false);
@@ -355,6 +363,7 @@ function playground_text(playground) {
html.classList.remove(previousTheme);
html.classList.add(theme);
+ updateThemeSelected();
}
// Set theme
@@ -592,7 +601,7 @@ function playground_text(playground) {
text: function (trigger) {
hideTooltip(trigger);
let playground = trigger.closest("pre");
- return playground_text(playground);
+ return playground_text(playground, false);
}
});
diff --git a/vendor/mdbook/src/theme/css/chrome.css b/vendor/mdbook/src/theme/css/chrome.css
index 10fa4b365..59eae11fd 100644
--- a/vendor/mdbook/src/theme/css/chrome.css
+++ b/vendor/mdbook/src/theme/css/chrome.css
@@ -507,6 +507,8 @@ ul#searchresults span.teaser em {
padding: 0;
list-style: none;
display: none;
+ /* Don't let the children's background extend past the rounded corners. */
+ overflow: hidden;
}
.theme-popup .default {
color: var(--icons);
@@ -515,7 +517,7 @@ ul#searchresults span.teaser em {
width: 100%;
border: 0;
margin: 0;
- padding: 2px 10px;
+ padding: 2px 20px;
line-height: 25px;
white-space: nowrap;
text-align: left;
@@ -527,8 +529,10 @@ ul#searchresults span.teaser em {
.theme-popup .theme:hover {
background-color: var(--theme-hover);
}
-.theme-popup .theme:hover:first-child,
-.theme-popup .theme:hover:last-child {
- border-top-left-radius: inherit;
- border-top-right-radius: inherit;
+
+.theme-selected::before {
+ display: inline-block;
+ content: "✓";
+ margin-left: -14px;
+ width: 14px;
}
diff --git a/vendor/mdbook/src/theme/css/general.css b/vendor/mdbook/src/theme/css/general.css
index 0e4f07a50..344b53eb7 100644
--- a/vendor/mdbook/src/theme/css/general.css
+++ b/vendor/mdbook/src/theme/css/general.css
@@ -22,8 +22,8 @@ body {
}
code {
- font-family: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace !important;
- font-size: 0.875em; /* please adjust the ace font size accordingly in editor.js */
+ font-family: var(--mono-font) !important;
+ font-size: var(--code-font-size);
}
/* make long words/inline code not x overflow */
@@ -148,6 +148,18 @@ blockquote {
border-bottom: .1em solid var(--quote-border);
}
+kbd {
+ background-color: var(--table-border-color);
+ border-radius: 4px;
+ border: solid 1px var(--theme-popup-border);
+ box-shadow: inset 0 -1px 0 var(--theme-hover);
+ display: inline-block;
+ font-size: var(--code-font-size);
+ font-family: var(--mono-font);
+ line-height: 10px;
+ padding: 4px 5px;
+ vertical-align: middle;
+}
:not(.footnote-definition) + .footnote-definition,
.footnote-definition + :not(.footnote-definition) {
diff --git a/vendor/mdbook/src/theme/css/variables.css b/vendor/mdbook/src/theme/css/variables.css
index 56b634bc3..21bf8e55e 100644
--- a/vendor/mdbook/src/theme/css/variables.css
+++ b/vendor/mdbook/src/theme/css/variables.css
@@ -6,6 +6,8 @@
--page-padding: 15px;
--content-max-width: 750px;
--menu-bar-height: 50px;
+ --mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace;
+ --code-font-size: 0.875em /* please adjust the ace font size accordingly in editor.js */
}
/* Themes */
diff --git a/vendor/mdbook/src/theme/index.hbs b/vendor/mdbook/src/theme/index.hbs
index 18d984a2b..147eb9af2 100644
--- a/vendor/mdbook/src/theme/index.hbs
+++ b/vendor/mdbook/src/theme/index.hbs
@@ -15,7 +15,6 @@
<!-- Custom HTML head -->
{{> head}}
- <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="{{ description }}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
@@ -51,18 +50,18 @@
{{#if mathjax_support}}
<!-- MathJax -->
- <script async type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
{{/if}}
</head>
<body>
<!-- Provide site root to javascript -->
- <script type="text/javascript">
+ <script>
var path_to_root = "{{ path_to_root }}";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
- <script type="text/javascript">
+ <script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
@@ -78,7 +77,7 @@
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
- <script type="text/javascript">
+ <script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
@@ -90,7 +89,7 @@
</script>
<!-- Hide / unhide sidebar before it is displayed -->
- <script type="text/javascript">
+ <script>
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
@@ -122,11 +121,11 @@
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
- <li role="none"><button role="menuitem" class="theme" id="light">{{ theme_option "Light" }}</button></li>
- <li role="none"><button role="menuitem" class="theme" id="rust">{{ theme_option "Rust" }}</button></li>
- <li role="none"><button role="menuitem" class="theme" id="coal">{{ theme_option "Coal" }}</button></li>
- <li role="none"><button role="menuitem" class="theme" id="navy">{{ theme_option "Navy" }}</button></li>
- <li role="none"><button role="menuitem" class="theme" id="ayu">{{ theme_option "Ayu" }}</button></li>
+ <li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
+ <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
+ <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
+ <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
+ <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
{{#if search_enabled}}
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
@@ -171,7 +170,7 @@
{{/if}}
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
- <script type="text/javascript">
+ <script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
@@ -221,7 +220,7 @@
{{#if live_reload_endpoint}}
<!-- Livereload script (if served using the cli tool) -->
- <script type="text/javascript">
+ <script>
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsAddress = wsProtocol + "//" + location.host + "/" + "{{{live_reload_endpoint}}}";
const socket = new WebSocket(wsAddress);
@@ -240,7 +239,7 @@
{{#if google_analytics}}
<!-- Google Analytics Tag -->
- <script type="text/javascript">
+ <script>
var localAddrs = ["localhost", "127.0.0.1", ""];
// make sure we don't activate google analytics if the developer is
@@ -258,43 +257,43 @@
{{/if}}
{{#if playground_line_numbers}}
- <script type="text/javascript">
+ <script>
window.playground_line_numbers = true;
</script>
{{/if}}
{{#if playground_copyable}}
- <script type="text/javascript">
+ <script>
window.playground_copyable = true;
</script>
{{/if}}
{{#if playground_js}}
- <script src="{{ path_to_root }}ace.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{ path_to_root }}editor.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{ path_to_root }}mode-rust.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{ path_to_root }}theme-dawn.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{ path_to_root }}theme-tomorrow_night.js" type="text/javascript" charset="utf-8"></script>
+ <script src="{{ path_to_root }}ace.js"></script>
+ <script src="{{ path_to_root }}editor.js"></script>
+ <script src="{{ path_to_root }}mode-rust.js"></script>
+ <script src="{{ path_to_root }}theme-dawn.js"></script>
+ <script src="{{ path_to_root }}theme-tomorrow_night.js"></script>
{{/if}}
{{#if search_js}}
- <script src="{{ path_to_root }}elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{ path_to_root }}mark.min.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{ path_to_root }}searcher.js" type="text/javascript" charset="utf-8"></script>
+ <script src="{{ path_to_root }}elasticlunr.min.js"></script>
+ <script src="{{ path_to_root }}mark.min.js"></script>
+ <script src="{{ path_to_root }}searcher.js"></script>
{{/if}}
- <script src="{{ path_to_root }}clipboard.min.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{ path_to_root }}highlight.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{ path_to_root }}book.js" type="text/javascript" charset="utf-8"></script>
+ <script src="{{ path_to_root }}clipboard.min.js"></script>
+ <script src="{{ path_to_root }}highlight.js"></script>
+ <script src="{{ path_to_root }}book.js"></script>
<!-- Custom JS scripts -->
{{#each additional_js}}
- <script type="text/javascript" src="{{ ../path_to_root }}{{this}}"></script>
+ <script src="{{ ../path_to_root }}{{this}}"></script>
{{/each}}
{{#if is_print}}
{{#if mathjax_support}}
- <script type="text/javascript">
+ <script>
window.addEventListener('load', function() {
MathJax.Hub.Register.StartupHook('End', function() {
window.setTimeout(window.print, 100);
@@ -302,7 +301,7 @@
});
</script>
{{else}}
- <script type="text/javascript">
+ <script>
window.addEventListener('load', function() {
window.setTimeout(window.print, 100);
});
diff --git a/vendor/mdbook/src/theme/mod.rs b/vendor/mdbook/src/theme/mod.rs
index a1ee18aff..7af5e2b70 100644
--- a/vendor/mdbook/src/theme/mod.rs
+++ b/vendor/mdbook/src/theme/mod.rs
@@ -12,7 +12,7 @@ use std::io::Read;
use std::path::Path;
use crate::errors::*;
-
+use log::warn;
pub static INDEX: &[u8] = include_bytes!("index.hbs");
pub static HEAD: &[u8] = include_bytes!("head.hbs");
pub static REDIRECT: &[u8] = include_bytes!("redirect.hbs");
diff --git a/vendor/mdbook/src/theme/redirect.hbs b/vendor/mdbook/src/theme/redirect.hbs
index 9f49e6d09..d0532a504 100644
--- a/vendor/mdbook/src/theme/redirect.hbs
+++ b/vendor/mdbook/src/theme/redirect.hbs
@@ -3,8 +3,8 @@
<head>
<meta charset="utf-8">
<title>Redirecting...</title>
- <meta http-equiv="refresh" content="0;URL='{{url}}'">
- <meta rel="canonical" href="{{url}}">
+ <meta http-equiv="refresh" content="0; URL={{url}}">
+ <link rel="canonical" href="{{url}}">
</head>
<body>
<p>Redirecting to... <a href="{{url}}">{{url}}</a>.</p>
diff --git a/vendor/mdbook/src/utils/fs.rs b/vendor/mdbook/src/utils/fs.rs
index a933d548a..0d6f38374 100644
--- a/vendor/mdbook/src/utils/fs.rs
+++ b/vendor/mdbook/src/utils/fs.rs
@@ -1,4 +1,5 @@
use crate::errors::*;
+use log::{debug, trace};
use std::convert::Into;
use std::fs::{self, File};
use std::io::Write;
diff --git a/vendor/mdbook/src/utils/mod.rs b/vendor/mdbook/src/utils/mod.rs
index a205633f9..9f67deda7 100644
--- a/vendor/mdbook/src/utils/mod.rs
+++ b/vendor/mdbook/src/utils/mod.rs
@@ -4,9 +4,10 @@ pub mod fs;
mod string;
pub(crate) mod toml_ext;
use crate::errors::Error;
-use regex::Regex;
-
+use log::error;
+use once_cell::sync::Lazy;
use pulldown_cmark::{html, CodeBlockKind, CowStr, Event, Options, Parser, Tag};
+use regex::Regex;
use std::borrow::Cow;
use std::collections::HashMap;
@@ -20,9 +21,7 @@ pub use self::string::{
/// Replaces multiple consecutive whitespace characters with a single space character.
pub fn collapse_whitespace(text: &str) -> Cow<'_, str> {
- lazy_static! {
- static ref RE: Regex = Regex::new(r"\s\s+").unwrap();
- }
+ static RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"\s\s+").unwrap());
RE.replace_all(text, " ")
}
@@ -51,9 +50,7 @@ pub fn id_from_content(content: &str) -> String {
let mut content = content.to_string();
// Skip any tags or html-encoded stuff
- lazy_static! {
- static ref HTML: Regex = Regex::new(r"(<.*?>)").unwrap();
- }
+ static HTML: Lazy<Regex> = Lazy::new(|| Regex::new(r"(<.*?>)").unwrap());
content = HTML.replace_all(&content, "").into();
const REPL_SUB: &[&str] = &["&lt;", "&gt;", "&amp;", "&#39;", "&quot;"];
for sub in REPL_SUB {
@@ -96,10 +93,9 @@ pub fn unique_id_from_content(content: &str, id_counter: &mut HashMap<String, us
/// None. Ideally, print page links would link to anchors on the print page,
/// but that is very difficult.
fn adjust_links<'a>(event: Event<'a>, path: Option<&Path>) -> Event<'a> {
- lazy_static! {
- static ref SCHEME_LINK: Regex = Regex::new(r"^[a-z][a-z0-9+.-]*:").unwrap();
- static ref MD_LINK: Regex = Regex::new(r"(?P<link>.*)\.md(?P<anchor>#.*)?").unwrap();
- }
+ static SCHEME_LINK: Lazy<Regex> = Lazy::new(|| Regex::new(r"^[a-z][a-z0-9+.-]*:").unwrap());
+ static MD_LINK: Lazy<Regex> =
+ Lazy::new(|| Regex::new(r"(?P<link>.*)\.md(?P<anchor>#.*)?").unwrap());
fn fix<'a>(dest: CowStr<'a>, path: Option<&Path>) -> CowStr<'a> {
if dest.starts_with('#') {
@@ -152,10 +148,8 @@ fn adjust_links<'a>(event: Event<'a>, path: Option<&Path>) -> Event<'a> {
// There are dozens of HTML tags/attributes that contain paths, so
// feel free to add more tags if desired; these are the only ones I
// care about right now.
- lazy_static! {
- static ref HTML_LINK: Regex =
- Regex::new(r#"(<(?:a|img) [^>]*?(?:src|href)=")([^"]+?)""#).unwrap();
- }
+ static HTML_LINK: Lazy<Regex> =
+ Lazy::new(|| Regex::new(r#"(<(?:a|img) [^>]*?(?:src|href)=")([^"]+?)""#).unwrap());
HTML_LINK
.replace_all(&html, |caps: &regex::Captures<'_>| {
diff --git a/vendor/mdbook/src/utils/string.rs b/vendor/mdbook/src/utils/string.rs
index 97485d7b6..6dafe2603 100644
--- a/vendor/mdbook/src/utils/string.rs
+++ b/vendor/mdbook/src/utils/string.rs
@@ -1,3 +1,4 @@
+use once_cell::sync::Lazy;
use regex::Regex;
use std::ops::Bound::{Excluded, Included, Unbounded};
use std::ops::RangeBounds;
@@ -23,10 +24,10 @@ pub fn take_lines<R: RangeBounds<usize>>(s: &str, range: R) -> String {
}
}
-lazy_static! {
- static ref ANCHOR_START: Regex = Regex::new(r"ANCHOR:\s*(?P<anchor_name>[\w_-]+)").unwrap();
- static ref ANCHOR_END: Regex = Regex::new(r"ANCHOR_END:\s*(?P<anchor_name>[\w_-]+)").unwrap();
-}
+static ANCHOR_START: Lazy<Regex> =
+ Lazy::new(|| Regex::new(r"ANCHOR:\s*(?P<anchor_name>[\w_-]+)").unwrap());
+static ANCHOR_END: Lazy<Regex> =
+ Lazy::new(|| Regex::new(r"ANCHOR_END:\s*(?P<anchor_name>[\w_-]+)").unwrap());
/// Take anchored lines from a string.
/// Lines containing anchor are ignored.