commit
4cf005d4bd
|
@ -386,7 +386,7 @@ fn determine_renderers(config: &Config) -> Vec<Box<dyn Renderer>> {
|
||||||
renderers
|
renderers
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_PREPROCESSORS: &[&'static str] = &["links", "index"];
|
const DEFAULT_PREPROCESSORS: &[&str] = &["links", "index"];
|
||||||
|
|
||||||
fn is_default_preprocessor(pre: &dyn Preprocessor) -> bool {
|
fn is_default_preprocessor(pre: &dyn Preprocessor) -> bool {
|
||||||
let name = pre.name();
|
let name = pre.name();
|
||||||
|
@ -756,10 +756,9 @@ mod tests {
|
||||||
|
|
||||||
let preprocessors = determine_preprocessors(&cfg).unwrap();
|
let preprocessors = determine_preprocessors(&cfg).unwrap();
|
||||||
|
|
||||||
assert!(preprocessors
|
assert!(!preprocessors
|
||||||
.iter()
|
.iter()
|
||||||
.find(|preprocessor| preprocessor.name() == "random")
|
.any(|preprocessor| preprocessor.name() == "random"));
|
||||||
.is_none());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -776,10 +775,9 @@ mod tests {
|
||||||
|
|
||||||
let preprocessors = determine_preprocessors(&cfg).unwrap();
|
let preprocessors = determine_preprocessors(&cfg).unwrap();
|
||||||
|
|
||||||
assert!(preprocessors
|
assert!(!preprocessors
|
||||||
.iter()
|
.iter()
|
||||||
.find(|preprocessor| preprocessor.name() == "links")
|
.any(|preprocessor| preprocessor.name() == "links"));
|
||||||
.is_none());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -122,8 +122,5 @@ fn confirm() -> bool {
|
||||||
io::stdout().flush().unwrap();
|
io::stdout().flush().unwrap();
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
io::stdin().read_line(&mut s).ok();
|
io::stdin().read_line(&mut s).ok();
|
||||||
match &*s.trim() {
|
matches!(&*s.trim(), "Y" | "y" | "yes" | "Yes")
|
||||||
"Y" | "y" | "yes" | "Yes" => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,10 +227,10 @@ impl Config {
|
||||||
let value = Value::try_from(value)
|
let value = Value::try_from(value)
|
||||||
.with_context(|| "Unable to represent the item as a JSON Value")?;
|
.with_context(|| "Unable to represent the item as a JSON Value")?;
|
||||||
|
|
||||||
if index.starts_with("book.") {
|
if let Some(key) = index.strip_prefix("book.") {
|
||||||
self.book.update_value(&index[5..], value);
|
self.book.update_value(key, value);
|
||||||
} else if index.starts_with("build.") {
|
} else if let Some(key) = index.strip_prefix("build.") {
|
||||||
self.build.update_value(&index[6..], value);
|
self.build.update_value(key, value);
|
||||||
} else {
|
} else {
|
||||||
self.rest.insert(index, value);
|
self.rest.insert(index, value);
|
||||||
}
|
}
|
||||||
|
@ -371,15 +371,8 @@ impl Serialize for Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_env(key: &str) -> Option<String> {
|
fn parse_env(key: &str) -> Option<String> {
|
||||||
const PREFIX: &str = "MDBOOK_";
|
key.strip_prefix("MDBOOK_")
|
||||||
|
.map(|key| key.to_lowercase().replace("__", ".").replace('_', "-"))
|
||||||
if key.starts_with(PREFIX) {
|
|
||||||
let key = &key[PREFIX.len()..];
|
|
||||||
|
|
||||||
Some(key.to_lowercase().replace("__", ".").replace("_", "-"))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_legacy_format(table: &Value) -> bool {
|
fn is_legacy_format(table: &Value) -> bool {
|
||||||
|
@ -828,7 +821,7 @@ mod tests {
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
let got = Config::from_str(src).unwrap();
|
let got = Config::from_str(src).unwrap();
|
||||||
assert_eq!(got.html_config().unwrap().playground.runnable, false);
|
assert!(!got.html_config().unwrap().playground.runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1037,7 +1030,7 @@ mod tests {
|
||||||
fn encode_env_var(key: &str) -> String {
|
fn encode_env_var(key: &str) -> String {
|
||||||
format!(
|
format!(
|
||||||
"MDBOOK_{}",
|
"MDBOOK_{}",
|
||||||
key.to_uppercase().replace('.', "__").replace("-", "_")
|
key.to_uppercase().replace('.', "__").replace('-', "_")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1061,11 +1054,10 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(clippy::approx_constant)]
|
|
||||||
fn update_config_using_env_var_and_complex_value() {
|
fn update_config_using_env_var_and_complex_value() {
|
||||||
let mut cfg = Config::default();
|
let mut cfg = Config::default();
|
||||||
let key = "foo-bar.baz";
|
let key = "foo-bar.baz";
|
||||||
let value = json!({"array": [1, 2, 3], "number": 3.14});
|
let value = json!({"array": [1, 2, 3], "number": 13.37});
|
||||||
let value_str = serde_json::to_string(&value).unwrap();
|
let value_str = serde_json::to_string(&value).unwrap();
|
||||||
|
|
||||||
assert!(cfg.get(key).is_none());
|
assert!(cfg.get(key).is_none());
|
||||||
|
@ -1184,15 +1176,15 @@ mod tests {
|
||||||
"#;
|
"#;
|
||||||
let got = Config::from_str(src).unwrap();
|
let got = Config::from_str(src).unwrap();
|
||||||
let html_config = got.html_config().unwrap();
|
let html_config = got.html_config().unwrap();
|
||||||
assert_eq!(html_config.print.enable, false);
|
assert!(!html_config.print.enable);
|
||||||
assert_eq!(html_config.print.page_break, true);
|
assert!(html_config.print.page_break);
|
||||||
let src = r#"
|
let src = r#"
|
||||||
[output.html.print]
|
[output.html.print]
|
||||||
page-break = false
|
page-break = false
|
||||||
"#;
|
"#;
|
||||||
let got = Config::from_str(src).unwrap();
|
let got = Config::from_str(src).unwrap();
|
||||||
let html_config = got.html_config().unwrap();
|
let html_config = got.html_config().unwrap();
|
||||||
assert_eq!(html_config.print.enable, true);
|
assert!(html_config.print.enable);
|
||||||
assert_eq!(html_config.print.page_break, false);
|
assert!(!html_config.print.page_break);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,6 @@
|
||||||
|
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![deny(rust_2018_idioms)]
|
#![deny(rust_2018_idioms)]
|
||||||
#![allow(clippy::comparison_chain)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
|
@ -146,6 +146,7 @@ enum RangeOrAnchor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// A range of lines specified with some include directive.
|
// A range of lines specified with some include directive.
|
||||||
|
#[allow(clippy::enum_variant_names)] // The prefix can't be removed, and is meant to mirror the contained type
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
enum LineRange {
|
enum LineRange {
|
||||||
Range(Range<usize>),
|
Range(Range<usize>),
|
||||||
|
|
|
@ -814,7 +814,7 @@ fn fix_code_blocks(html: &str) -> String {
|
||||||
FIX_CODE_BLOCKS
|
FIX_CODE_BLOCKS
|
||||||
.replace_all(html, |caps: &Captures<'_>| {
|
.replace_all(html, |caps: &Captures<'_>| {
|
||||||
let before = &caps[1];
|
let before = &caps[1];
|
||||||
let classes = &caps[2].replace(",", " ");
|
let classes = &caps[2].replace(',', " ");
|
||||||
let after = &caps[3];
|
let after = &caps[3];
|
||||||
|
|
||||||
format!(
|
format!(
|
||||||
|
|
|
@ -61,7 +61,7 @@ fn find_chapter(
|
||||||
.as_json()
|
.as_json()
|
||||||
.as_str()
|
.as_str()
|
||||||
.ok_or_else(|| RenderError::new("Type error for `path`, string expected"))?
|
.ok_or_else(|| RenderError::new("Type error for `path`, string expected"))?
|
||||||
.replace("\"", "");
|
.replace('\"', "");
|
||||||
|
|
||||||
if !rc.evaluate(ctx, "@root/is_index")?.is_missing() {
|
if !rc.evaluate(ctx, "@root/is_index")?.is_missing() {
|
||||||
// Special case for index.md which may be a synthetic page.
|
// Special case for index.md which may be a synthetic page.
|
||||||
|
@ -121,7 +121,7 @@ fn render(
|
||||||
.as_json()
|
.as_json()
|
||||||
.as_str()
|
.as_str()
|
||||||
.ok_or_else(|| RenderError::new("Type error for `path`, string expected"))?
|
.ok_or_else(|| RenderError::new("Type error for `path`, string expected"))?
|
||||||
.replace("\"", "");
|
.replace('\"', "");
|
||||||
|
|
||||||
context.insert(
|
context.insert(
|
||||||
"path_to_root".to_owned(),
|
"path_to_root".to_owned(),
|
||||||
|
@ -141,7 +141,7 @@ fn render(
|
||||||
.with_extension("html")
|
.with_extension("html")
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or_else(|| RenderError::new("Link could not be converted to str"))
|
.ok_or_else(|| RenderError::new("Link could not be converted to str"))
|
||||||
.map(|p| context.insert("link".to_owned(), json!(p.replace("\\", "/"))))
|
.map(|p| context.insert("link".to_owned(), json!(p.replace('\\', "/"))))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
trace!("Render template");
|
trace!("Render template");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::{cmp::Ordering, collections::BTreeMap};
|
||||||
|
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
use crate::utils::bracket_escape;
|
use crate::utils::bracket_escape;
|
||||||
|
@ -33,7 +33,7 @@ impl HelperDef for RenderToc {
|
||||||
.as_json()
|
.as_json()
|
||||||
.as_str()
|
.as_str()
|
||||||
.ok_or_else(|| RenderError::new("Type error for `path`, string expected"))?
|
.ok_or_else(|| RenderError::new("Type error for `path`, string expected"))?
|
||||||
.replace("\"", "");
|
.replace('\"', "");
|
||||||
|
|
||||||
let current_section = rc
|
let current_section = rc
|
||||||
.evaluate(ctx, "@root/section")?
|
.evaluate(ctx, "@root/section")?
|
||||||
|
@ -81,23 +81,27 @@ impl HelperDef for RenderToc {
|
||||||
level - 1 < fold_level as usize
|
level - 1 < fold_level as usize
|
||||||
};
|
};
|
||||||
|
|
||||||
if level > current_level {
|
match level.cmp(¤t_level) {
|
||||||
|
Ordering::Greater => {
|
||||||
while level > current_level {
|
while level > current_level {
|
||||||
out.write("<li>")?;
|
out.write("<li>")?;
|
||||||
out.write("<ol class=\"section\">")?;
|
out.write("<ol class=\"section\">")?;
|
||||||
current_level += 1;
|
current_level += 1;
|
||||||
}
|
}
|
||||||
write_li_open_tag(out, is_expanded, false)?;
|
write_li_open_tag(out, is_expanded, false)?;
|
||||||
} else if level < current_level {
|
}
|
||||||
|
Ordering::Less => {
|
||||||
while level < current_level {
|
while level < current_level {
|
||||||
out.write("</ol>")?;
|
out.write("</ol>")?;
|
||||||
out.write("</li>")?;
|
out.write("</li>")?;
|
||||||
current_level -= 1;
|
current_level -= 1;
|
||||||
}
|
}
|
||||||
write_li_open_tag(out, is_expanded, false)?;
|
write_li_open_tag(out, is_expanded, false)?;
|
||||||
} else {
|
}
|
||||||
|
Ordering::Equal => {
|
||||||
write_li_open_tag(out, is_expanded, item.get("section").is_none())?;
|
write_li_open_tag(out, is_expanded, item.get("section").is_none())?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Part title
|
// Part title
|
||||||
if let Some(title) = item.get("part") {
|
if let Some(title) = item.get("part") {
|
||||||
|
@ -119,7 +123,7 @@ impl HelperDef for RenderToc {
|
||||||
.to_str()
|
.to_str()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
// Hack for windows who tends to use `\` as separator instead of `/`
|
// Hack for windows who tends to use `\` as separator instead of `/`
|
||||||
.replace("\\", "/");
|
.replace('\\', "/");
|
||||||
|
|
||||||
// Add link
|
// Add link
|
||||||
out.write(&utils::fs::path_to_root(¤t_path))?;
|
out.write(&utils::fs::path_to_root(¤t_path))?;
|
||||||
|
|
|
@ -227,12 +227,13 @@ fn write_to_json(index: Index, search_config: &Search, doc_urls: Vec<String>) ->
|
||||||
|
|
||||||
let mut fields = BTreeMap::new();
|
let mut fields = BTreeMap::new();
|
||||||
let mut opt = SearchOptionsField::default();
|
let mut opt = SearchOptionsField::default();
|
||||||
opt.boost = Some(search_config.boost_title);
|
let mut insert_boost = |key: &str, boost| {
|
||||||
fields.insert("title".into(), opt);
|
opt.boost = Some(boost);
|
||||||
opt.boost = Some(search_config.boost_paragraph);
|
fields.insert(key.into(), opt);
|
||||||
fields.insert("body".into(), opt);
|
};
|
||||||
opt.boost = Some(search_config.boost_hierarchy);
|
insert_boost("title", search_config.boost_title);
|
||||||
fields.insert("breadcrumbs".into(), opt);
|
insert_boost("body", search_config.boost_paragraph);
|
||||||
|
insert_boost("breadcrumbs", search_config.boost_hierarchy);
|
||||||
|
|
||||||
let search_options = SearchOptions {
|
let search_options = SearchOptions {
|
||||||
bool: if search_config.use_boolean_and {
|
bool: if search_config.use_boolean_and {
|
||||||
|
|
|
@ -122,6 +122,7 @@ mod tests {
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[allow(clippy::reversed_empty_ranges)] // Intentionally checking that those are correctly handled
|
||||||
fn take_lines_test() {
|
fn take_lines_test() {
|
||||||
let s = "Lorem\nipsum\ndolor\nsit\namet";
|
let s = "Lorem\nipsum\ndolor\nsit\namet";
|
||||||
assert_eq!(take_lines(s, 1..3), "ipsum\ndolor");
|
assert_eq!(take_lines(s, 1..3), "ipsum\ndolor");
|
||||||
|
@ -163,6 +164,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[allow(clippy::reversed_empty_ranges)] // Intentionally checking that those are correctly handled
|
||||||
fn take_rustdoc_include_lines_test() {
|
fn take_rustdoc_include_lines_test() {
|
||||||
let s = "Lorem\nipsum\ndolor\nsit\namet";
|
let s = "Lorem\nipsum\ndolor\nsit\namet";
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
Loading…
Reference in New Issue