make clippy a bit happier (#1588)
This commit is contained in:
parent
8b43667a94
commit
56dcfecce2
|
@ -38,7 +38,7 @@ fn main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
// and then the ones we add
|
// and then the ones we add
|
||||||
let mut extra = base_path.clone();
|
let mut extra = base_path;
|
||||||
extra.push("extra");
|
extra.push("extra");
|
||||||
match builder.add_from_folder(&extra, true) {
|
match builder.add_from_folder(&extra, true) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
|
@ -60,7 +60,7 @@ fn main() {
|
||||||
.or_insert_with(|| HashSet::from_iter(s.file_extensions.iter().cloned()));
|
.or_insert_with(|| HashSet::from_iter(s.file_extensions.iter().cloned()));
|
||||||
}
|
}
|
||||||
let mut keys = syntaxes.keys().collect::<Vec<_>>();
|
let mut keys = syntaxes.keys().collect::<Vec<_>>();
|
||||||
keys.sort_by(|a, b| a.to_lowercase().cmp(&b.to_lowercase()));
|
keys.sort_by_key(|&a| a.to_lowercase());
|
||||||
for k in keys {
|
for k in keys {
|
||||||
if !syntaxes[k].is_empty() {
|
if !syntaxes[k].is_empty() {
|
||||||
let mut extensions_sorted = syntaxes[k].iter().cloned().collect::<Vec<_>>();
|
let mut extensions_sorted = syntaxes[k].iter().cloned().collect::<Vec<_>>();
|
||||||
|
|
|
@ -117,18 +117,18 @@ impl Config {
|
||||||
bail!("A base URL is required in config.toml with key `base_url`");
|
bail!("A base URL is required in config.toml with key `base_url`");
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.markdown.highlight_theme != "css" {
|
if config.markdown.highlight_theme != "css"
|
||||||
if !THEME_SET.themes.contains_key(&config.markdown.highlight_theme) {
|
&& !THEME_SET.themes.contains_key(&config.markdown.highlight_theme)
|
||||||
|
{
|
||||||
bail!(
|
bail!(
|
||||||
"Highlight theme {} defined in config does not exist.",
|
"Highlight theme {} defined in config does not exist.",
|
||||||
config.markdown.highlight_theme
|
config.markdown.highlight_theme
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
languages::validate_code(&config.default_language)?;
|
languages::validate_code(&config.default_language)?;
|
||||||
for code in config.languages.keys() {
|
for code in config.languages.keys() {
|
||||||
languages::validate_code(&code)?;
|
languages::validate_code(code)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.add_default_language();
|
config.add_default_language();
|
||||||
|
@ -229,8 +229,8 @@ impl Config {
|
||||||
|
|
||||||
/// Parse the theme.toml file and merges the extra data from the theme
|
/// Parse the theme.toml file and merges the extra data from the theme
|
||||||
/// with the config extra data
|
/// with the config extra data
|
||||||
pub fn merge_with_theme(&mut self, path: &PathBuf, theme_name: &str) -> Result<()> {
|
pub fn merge_with_theme(&mut self, path: PathBuf, theme_name: &str) -> Result<()> {
|
||||||
let theme = Theme::from_file(path, theme_name)?;
|
let theme = Theme::from_file(&path, theme_name)?;
|
||||||
self.add_theme_extra(&theme)
|
self.add_theme_extra(&theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,44 +414,38 @@ hello = "world"
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_make_url_index_page_with_non_trailing_slash_url() {
|
fn can_make_url_index_page_with_non_trailing_slash_url() {
|
||||||
let mut config = Config::default();
|
let config = Config { base_url: "http://vincent.is".to_string(), ..Default::default() };
|
||||||
config.base_url = "http://vincent.is".to_string();
|
|
||||||
assert_eq!(config.make_permalink(""), "http://vincent.is/");
|
assert_eq!(config.make_permalink(""), "http://vincent.is/");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_make_url_index_page_with_railing_slash_url() {
|
fn can_make_url_index_page_with_railing_slash_url() {
|
||||||
let mut config = Config::default();
|
let config = Config { base_url: "http://vincent.is".to_string(), ..Default::default() };
|
||||||
config.base_url = "http://vincent.is/".to_string();
|
|
||||||
assert_eq!(config.make_permalink(""), "http://vincent.is/");
|
assert_eq!(config.make_permalink(""), "http://vincent.is/");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_make_url_with_non_trailing_slash_base_url() {
|
fn can_make_url_with_non_trailing_slash_base_url() {
|
||||||
let mut config = Config::default();
|
let config = Config { base_url: "http://vincent.is".to_string(), ..Default::default() };
|
||||||
config.base_url = "http://vincent.is".to_string();
|
|
||||||
assert_eq!(config.make_permalink("hello"), "http://vincent.is/hello/");
|
assert_eq!(config.make_permalink("hello"), "http://vincent.is/hello/");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_make_url_with_trailing_slash_path() {
|
fn can_make_url_with_trailing_slash_path() {
|
||||||
let mut config = Config::default();
|
let config = Config { base_url: "http://vincent.is".to_string(), ..Default::default() };
|
||||||
config.base_url = "http://vincent.is/".to_string();
|
|
||||||
assert_eq!(config.make_permalink("/hello"), "http://vincent.is/hello/");
|
assert_eq!(config.make_permalink("/hello"), "http://vincent.is/hello/");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_make_url_with_localhost() {
|
fn can_make_url_with_localhost() {
|
||||||
let mut config = Config::default();
|
let config = Config { base_url: "http://127.0.0.1:1111".to_string(), ..Default::default() };
|
||||||
config.base_url = "http://127.0.0.1:1111".to_string();
|
|
||||||
assert_eq!(config.make_permalink("/tags/rust"), "http://127.0.0.1:1111/tags/rust/");
|
assert_eq!(config.make_permalink("/tags/rust"), "http://127.0.0.1:1111/tags/rust/");
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/Keats/gutenberg/issues/486
|
// https://github.com/Keats/gutenberg/issues/486
|
||||||
#[test]
|
#[test]
|
||||||
fn doesnt_add_trailing_slash_to_feed() {
|
fn doesnt_add_trailing_slash_to_feed() {
|
||||||
let mut config = Config::default();
|
let config = Config { base_url: "http://vincent.is".to_string(), ..Default::default() };
|
||||||
config.base_url = "http://vincent.is/".to_string();
|
|
||||||
assert_eq!(config.make_permalink("atom.xml"), "http://vincent.is/atom.xml");
|
assert_eq!(config.make_permalink("atom.xml"), "http://vincent.is/atom.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -656,7 +650,7 @@ bar = "baz"
|
||||||
"#;
|
"#;
|
||||||
let theme = Theme::parse(theme_str).unwrap();
|
let theme = Theme::parse(theme_str).unwrap();
|
||||||
// We expect an error here
|
// We expect an error here
|
||||||
assert_eq!(false, config.add_theme_extra(&theme).is_ok());
|
assert!(!config.add_theme_extra(&theme).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::Path;
|
||||||
|
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use toml::Value as Toml;
|
use toml::Value as Toml;
|
||||||
|
@ -39,7 +39,7 @@ impl Theme {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a theme file from the given path
|
/// Parses a theme file from the given path
|
||||||
pub fn from_file(path: &PathBuf, theme_name: &str) -> Result<Theme> {
|
pub fn from_file(path: &Path, theme_name: &str) -> Result<Theme> {
|
||||||
let content = read_file(path)
|
let content = read_file(path)
|
||||||
.map_err(|e| errors::Error::chain(format!("Failed to load theme {}", theme_name), e))?;
|
.map_err(|e| errors::Error::chain(format!("Failed to load theme {}", theme_name), e))?;
|
||||||
Theme::parse(&content)
|
Theme::parse(&content)
|
||||||
|
|
|
@ -81,7 +81,7 @@ impl PageFrontMatter {
|
||||||
let mut f: PageFrontMatter = raw.deserialize()?;
|
let mut f: PageFrontMatter = raw.deserialize()?;
|
||||||
|
|
||||||
if let Some(ref slug) = f.slug {
|
if let Some(ref slug) = f.slug {
|
||||||
if slug == "" {
|
if slug.is_empty() {
|
||||||
bail!("`slug` can't be empty if present")
|
bail!("`slug` can't be empty if present")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -338,7 +338,7 @@ impl ImageOp {
|
||||||
Some(q) => encoder.encode(q as f32),
|
Some(q) => encoder.encode(q as f32),
|
||||||
None => encoder.encode_lossless(),
|
None => encoder.encode_lossless(),
|
||||||
};
|
};
|
||||||
f.write_all(&memory.as_bytes())?;
|
f.write_all(memory.as_bytes())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,6 +408,7 @@ impl Processor {
|
||||||
self.img_ops.len() + self.img_ops_collisions.len()
|
self.img_ops.len() + self.img_ops_collisions.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enqueue(
|
pub fn enqueue(
|
||||||
&mut self,
|
&mut self,
|
||||||
input_src: String,
|
input_src: String,
|
||||||
|
|
|
@ -30,6 +30,7 @@ lazy_static! {
|
||||||
static ref PROCESSED_PREFIX: String = format!("static{0}processed_images{0}", SLASH);
|
static ref PROCESSED_PREFIX: String = format!("static{0}processed_images{0}", SLASH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn image_op_test(
|
fn image_op_test(
|
||||||
source_img: &str,
|
source_img: &str,
|
||||||
op: &str,
|
op: &str,
|
||||||
|
@ -44,7 +45,7 @@ fn image_op_test(
|
||||||
) {
|
) {
|
||||||
let source_path = TEST_IMGS.join(source_img);
|
let source_path = TEST_IMGS.join(source_img);
|
||||||
|
|
||||||
let config = Config::parse(&CONFIG).unwrap();
|
let config = Config::parse(CONFIG).unwrap();
|
||||||
let mut proc = Processor::new(TMPDIR.clone(), &config);
|
let mut proc = Processor::new(TMPDIR.clone(), &config);
|
||||||
|
|
||||||
let resp =
|
let resp =
|
||||||
|
|
|
@ -52,7 +52,7 @@ pub struct FileInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileInfo {
|
impl FileInfo {
|
||||||
pub fn new_page(path: &Path, base_path: &PathBuf) -> FileInfo {
|
pub fn new_page(path: &Path, base_path: &Path) -> FileInfo {
|
||||||
let file_path = path.to_path_buf();
|
let file_path = path.to_path_buf();
|
||||||
let mut parent = file_path.parent().expect("Get parent of page").to_path_buf();
|
let mut parent = file_path.parent().expect("Get parent of page").to_path_buf();
|
||||||
let name = path.file_stem().unwrap().to_string_lossy().to_string();
|
let name = path.file_stem().unwrap().to_string_lossy().to_string();
|
||||||
|
@ -87,7 +87,7 @@ impl FileInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_section(path: &Path, base_path: &PathBuf) -> FileInfo {
|
pub fn new_section(path: &Path, base_path: &Path) -> FileInfo {
|
||||||
let file_path = path.to_path_buf();
|
let file_path = path.to_path_buf();
|
||||||
let parent = path.parent().expect("Get parent of section").to_path_buf();
|
let parent = path.parent().expect("Get parent of section").to_path_buf();
|
||||||
let name = path.file_stem().unwrap().to_string_lossy().to_string();
|
let name = path.file_stem().unwrap().to_string_lossy().to_string();
|
||||||
|
@ -166,7 +166,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn can_find_components_in_page_with_assets() {
|
fn can_find_components_in_page_with_assets() {
|
||||||
let file = FileInfo::new_page(
|
let file = FileInfo::new_page(
|
||||||
&Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.md"),
|
Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.md"),
|
||||||
&PathBuf::new(),
|
&PathBuf::new(),
|
||||||
);
|
);
|
||||||
assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]);
|
assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]);
|
||||||
|
@ -175,7 +175,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn doesnt_fail_with_multiple_content_directories_in_path() {
|
fn doesnt_fail_with_multiple_content_directories_in_path() {
|
||||||
let file = FileInfo::new_page(
|
let file = FileInfo::new_page(
|
||||||
&Path::new("/home/vincent/code/content/site/content/posts/tutorials/python/index.md"),
|
Path::new("/home/vincent/code/content/site/content/posts/tutorials/python/index.md"),
|
||||||
&PathBuf::from("/home/vincent/code/content/site"),
|
&PathBuf::from("/home/vincent/code/content/site"),
|
||||||
);
|
);
|
||||||
assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]);
|
assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]);
|
||||||
|
@ -186,7 +186,7 @@ mod tests {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.insert("fr".to_owned(), LanguageOptions::default());
|
config.languages.insert("fr".to_owned(), LanguageOptions::default());
|
||||||
let mut file = FileInfo::new_page(
|
let mut file = FileInfo::new_page(
|
||||||
&Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"),
|
Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"),
|
||||||
&PathBuf::new(),
|
&PathBuf::new(),
|
||||||
);
|
);
|
||||||
let res = file.find_language(&config);
|
let res = file.find_language(&config);
|
||||||
|
@ -199,7 +199,7 @@ mod tests {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.insert("fr".to_owned(), LanguageOptions::default());
|
config.languages.insert("fr".to_owned(), LanguageOptions::default());
|
||||||
let mut file = FileInfo::new_page(
|
let mut file = FileInfo::new_page(
|
||||||
&Path::new("/home/vincent/code/site/content/posts/tutorials/python.en.md"),
|
Path::new("/home/vincent/code/site/content/posts/tutorials/python.en.md"),
|
||||||
&PathBuf::new(),
|
&PathBuf::new(),
|
||||||
);
|
);
|
||||||
let res = file.find_language(&config);
|
let res = file.find_language(&config);
|
||||||
|
@ -212,7 +212,7 @@ mod tests {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.insert("fr".to_owned(), LanguageOptions::default());
|
config.languages.insert("fr".to_owned(), LanguageOptions::default());
|
||||||
let mut file = FileInfo::new_page(
|
let mut file = FileInfo::new_page(
|
||||||
&Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.fr.md"),
|
Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.fr.md"),
|
||||||
&PathBuf::new(),
|
&PathBuf::new(),
|
||||||
);
|
);
|
||||||
assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]);
|
assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]);
|
||||||
|
@ -225,7 +225,7 @@ mod tests {
|
||||||
fn do_nothing_on_unknown_language_in_page_with_i18n_off() {
|
fn do_nothing_on_unknown_language_in_page_with_i18n_off() {
|
||||||
let config = Config::default();
|
let config = Config::default();
|
||||||
let mut file = FileInfo::new_page(
|
let mut file = FileInfo::new_page(
|
||||||
&Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"),
|
Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"),
|
||||||
&PathBuf::new(),
|
&PathBuf::new(),
|
||||||
);
|
);
|
||||||
let res = file.find_language(&config);
|
let res = file.find_language(&config);
|
||||||
|
@ -238,7 +238,7 @@ mod tests {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.insert("it".to_owned(), LanguageOptions::default());
|
config.languages.insert("it".to_owned(), LanguageOptions::default());
|
||||||
let mut file = FileInfo::new_page(
|
let mut file = FileInfo::new_page(
|
||||||
&Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"),
|
Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"),
|
||||||
&PathBuf::new(),
|
&PathBuf::new(),
|
||||||
);
|
);
|
||||||
let res = file.find_language(&config);
|
let res = file.find_language(&config);
|
||||||
|
@ -250,7 +250,7 @@ mod tests {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.insert("fr".to_owned(), LanguageOptions::default());
|
config.languages.insert("fr".to_owned(), LanguageOptions::default());
|
||||||
let mut file = FileInfo::new_section(
|
let mut file = FileInfo::new_section(
|
||||||
&Path::new("/home/vincent/code/site/content/posts/tutorials/_index.fr.md"),
|
Path::new("/home/vincent/code/site/content/posts/tutorials/_index.fr.md"),
|
||||||
&PathBuf::new(),
|
&PathBuf::new(),
|
||||||
);
|
);
|
||||||
let res = file.find_language(&config);
|
let res = file.find_language(&config);
|
||||||
|
@ -262,7 +262,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn correct_canonical_for_index() {
|
fn correct_canonical_for_index() {
|
||||||
let file = FileInfo::new_page(
|
let file = FileInfo::new_page(
|
||||||
&Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.md"),
|
Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.md"),
|
||||||
&PathBuf::new(),
|
&PathBuf::new(),
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -277,7 +277,7 @@ mod tests {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.insert("fr".to_owned(), LanguageOptions::default());
|
config.languages.insert("fr".to_owned(), LanguageOptions::default());
|
||||||
let mut file = FileInfo::new_page(
|
let mut file = FileInfo::new_page(
|
||||||
&Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.fr.md"),
|
Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.fr.md"),
|
||||||
&PathBuf::new(),
|
&PathBuf::new(),
|
||||||
);
|
);
|
||||||
let res = file.find_language(&config);
|
let res = file.find_language(&config);
|
||||||
|
|
|
@ -97,7 +97,7 @@ pub struct Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Page {
|
impl Page {
|
||||||
pub fn new<P: AsRef<Path>>(file_path: P, meta: PageFrontMatter, base_path: &PathBuf) -> Page {
|
pub fn new<P: AsRef<Path>>(file_path: P, meta: PageFrontMatter, base_path: &Path) -> Page {
|
||||||
let file_path = file_path.as_ref();
|
let file_path = file_path.as_ref();
|
||||||
|
|
||||||
Page { file: FileInfo::new_page(file_path, base_path), meta, ..Self::default() }
|
Page { file: FileInfo::new_page(file_path, base_path), meta, ..Self::default() }
|
||||||
|
@ -114,7 +114,7 @@ impl Page {
|
||||||
file_path: &Path,
|
file_path: &Path,
|
||||||
content: &str,
|
content: &str,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
base_path: &PathBuf,
|
base_path: &Path,
|
||||||
) -> Result<Page> {
|
) -> Result<Page> {
|
||||||
let (meta, content) = split_page_content(file_path, content)?;
|
let (meta, content) = split_page_content(file_path, content)?;
|
||||||
let mut page = Page::new(file_path, meta, base_path);
|
let mut page = Page::new(file_path, meta, base_path);
|
||||||
|
@ -205,11 +205,7 @@ impl Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read and parse a .md file into a Page struct
|
/// Read and parse a .md file into a Page struct
|
||||||
pub fn from_file<P: AsRef<Path>>(
|
pub fn from_file<P: AsRef<Path>>(path: P, config: &Config, base_path: &Path) -> Result<Page> {
|
||||||
path: P,
|
|
||||||
config: &Config,
|
|
||||||
base_path: &PathBuf,
|
|
||||||
) -> Result<Page> {
|
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
let content = read_file(path)?;
|
let content = read_file(path)?;
|
||||||
let mut page = Page::parse(path, &content, config, base_path)?;
|
let mut page = Page::parse(path, &content, config, base_path)?;
|
||||||
|
@ -217,7 +213,7 @@ impl Page {
|
||||||
if page.file.name == "index" {
|
if page.file.name == "index" {
|
||||||
let parent_dir = path.parent().unwrap();
|
let parent_dir = path.parent().unwrap();
|
||||||
page.assets = find_related_assets(parent_dir, config);
|
page.assets = find_related_assets(parent_dir, config);
|
||||||
page.serialized_assets = page.serialize_assets(&base_path);
|
page.serialized_assets = page.serialize_assets(base_path);
|
||||||
} else {
|
} else {
|
||||||
page.assets = vec![];
|
page.assets = vec![];
|
||||||
}
|
}
|
||||||
|
@ -249,11 +245,10 @@ impl Page {
|
||||||
Error::chain(format!("Failed to render content of {}", self.file.path.display()), e)
|
Error::chain(format!("Failed to render content of {}", self.file.path.display()), e)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
self.summary = if let Some(s) = res.summary_len.map(|l| &res.body[0..l]) {
|
self.summary = res
|
||||||
Some(FOOTNOTES_RE.replace(s, "").into_owned())
|
.summary_len
|
||||||
} else {
|
.map(|l| &res.body[0..l])
|
||||||
None
|
.map(|s| FOOTNOTES_RE.replace(s, "").into_owned());
|
||||||
};
|
|
||||||
self.content = res.body;
|
self.content = res.body;
|
||||||
self.toc = res.toc;
|
self.toc = res.toc;
|
||||||
self.external_links = res.external_links;
|
self.external_links = res.external_links;
|
||||||
|
@ -276,13 +271,13 @@ impl Page {
|
||||||
context.insert("page", &self.to_serialized(library));
|
context.insert("page", &self.to_serialized(library));
|
||||||
context.insert("lang", &self.lang);
|
context.insert("lang", &self.lang);
|
||||||
|
|
||||||
render_template(&tpl_name, tera, context, &config.theme).map_err(|e| {
|
render_template(tpl_name, tera, context, &config.theme).map_err(|e| {
|
||||||
Error::chain(format!("Failed to render page '{}'", self.file.path.display()), e)
|
Error::chain(format!("Failed to render page '{}'", self.file.path.display()), e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a vectors of asset URLs.
|
/// Creates a vectors of asset URLs.
|
||||||
fn serialize_assets(&self, base_path: &PathBuf) -> Vec<String> {
|
fn serialize_assets(&self, base_path: &Path) -> Vec<String> {
|
||||||
self.assets
|
self.assets
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|asset| asset.file_name())
|
.filter_map(|asset| asset.file_name())
|
||||||
|
|
|
@ -68,7 +68,7 @@ impl Section {
|
||||||
pub fn new<P: AsRef<Path>>(
|
pub fn new<P: AsRef<Path>>(
|
||||||
file_path: P,
|
file_path: P,
|
||||||
meta: SectionFrontMatter,
|
meta: SectionFrontMatter,
|
||||||
base_path: &PathBuf,
|
base_path: &Path,
|
||||||
) -> Section {
|
) -> Section {
|
||||||
let file_path = file_path.as_ref();
|
let file_path = file_path.as_ref();
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ impl Section {
|
||||||
file_path: &Path,
|
file_path: &Path,
|
||||||
content: &str,
|
content: &str,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
base_path: &PathBuf,
|
base_path: &Path,
|
||||||
) -> Result<Section> {
|
) -> Result<Section> {
|
||||||
let (meta, content) = split_section_content(file_path, content)?;
|
let (meta, content) = split_section_content(file_path, content)?;
|
||||||
let mut section = Section::new(file_path, meta, base_path);
|
let mut section = Section::new(file_path, meta, base_path);
|
||||||
|
@ -115,7 +115,7 @@ impl Section {
|
||||||
pub fn from_file<P: AsRef<Path>>(
|
pub fn from_file<P: AsRef<Path>>(
|
||||||
path: P,
|
path: P,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
base_path: &PathBuf,
|
base_path: &Path,
|
||||||
) -> Result<Section> {
|
) -> Result<Section> {
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
let content = read_file(path)?;
|
let content = read_file(path)?;
|
||||||
|
|
|
@ -25,6 +25,7 @@ impl<'a> TranslatedContent<'a> {
|
||||||
pub fn find_all_sections(section: &'a Section, library: &'a Library) -> Vec<Self> {
|
pub fn find_all_sections(section: &'a Section, library: &'a Library) -> Vec<Self> {
|
||||||
let mut translations = vec![];
|
let mut translations = vec![];
|
||||||
|
|
||||||
|
#[allow(clippy::or_fun_call)]
|
||||||
for key in library
|
for key in library
|
||||||
.translations
|
.translations
|
||||||
.get(§ion.file.canonical)
|
.get(§ion.file.canonical)
|
||||||
|
@ -47,6 +48,7 @@ impl<'a> TranslatedContent<'a> {
|
||||||
pub fn find_all_pages(page: &'a Page, library: &'a Library) -> Vec<Self> {
|
pub fn find_all_pages(page: &'a Page, library: &'a Library) -> Vec<Self> {
|
||||||
let mut translations = vec![];
|
let mut translations = vec![];
|
||||||
|
|
||||||
|
#[allow(clippy::or_fun_call)]
|
||||||
for key in
|
for key in
|
||||||
library.translations.get(&page.file.canonical).or(Some(&HashSet::new())).unwrap().iter()
|
library.translations.get(&page.file.canonical).or(Some(&HashSet::new())).unwrap().iter()
|
||||||
{
|
{
|
||||||
|
@ -181,7 +183,7 @@ impl<'a> SerializingPage<'a> {
|
||||||
|
|
||||||
/// currently only used in testing
|
/// currently only used in testing
|
||||||
pub fn get_title(&'a self) -> &'a Option<String> {
|
pub fn get_title(&'a self) -> &'a Option<String> {
|
||||||
&self.title
|
self.title
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as from_page but does not fill sibling pages
|
/// Same as from_page but does not fill sibling pages
|
||||||
|
@ -194,7 +196,7 @@ impl<'a> SerializingPage<'a> {
|
||||||
month = Some(d.1);
|
month = Some(d.1);
|
||||||
day = Some(d.2);
|
day = Some(d.2);
|
||||||
}
|
}
|
||||||
let ancestors = if let Some(ref lib) = library {
|
let ancestors = if let Some(lib) = library {
|
||||||
page.ancestors
|
page.ancestors
|
||||||
.iter()
|
.iter()
|
||||||
.map(|k| lib.get_section_by_key(*k).file.relative.as_str())
|
.map(|k| lib.get_section_by_key(*k).file.relative.as_str())
|
||||||
|
@ -203,7 +205,7 @@ impl<'a> SerializingPage<'a> {
|
||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
let translations = if let Some(ref lib) = library {
|
let translations = if let Some(lib) = library {
|
||||||
TranslatedContent::find_all_pages(page, lib)
|
TranslatedContent::find_all_pages(page, lib)
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
|
@ -313,7 +315,7 @@ impl<'a> SerializingSection<'a> {
|
||||||
let mut ancestors = vec![];
|
let mut ancestors = vec![];
|
||||||
let mut translations = vec![];
|
let mut translations = vec![];
|
||||||
let mut subsections = vec![];
|
let mut subsections = vec![];
|
||||||
if let Some(ref lib) = library {
|
if let Some(lib) = library {
|
||||||
ancestors = section
|
ancestors = section
|
||||||
.ancestors
|
.ancestors
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -84,7 +84,7 @@ impl Library {
|
||||||
let rel_path = section.path.clone();
|
let rel_path = section.path.clone();
|
||||||
|
|
||||||
let mut entries = vec![rel_path];
|
let mut entries = vec![rel_path];
|
||||||
entries.extend(section.meta.aliases.iter().map(|a| a.clone()).collect::<Vec<String>>());
|
entries.extend(section.meta.aliases.to_vec());
|
||||||
self.insert_reverse_aliases(entries, §ion.file.relative);
|
self.insert_reverse_aliases(entries, §ion.file.relative);
|
||||||
|
|
||||||
let key = self.sections.insert(section);
|
let key = self.sections.insert(section);
|
||||||
|
@ -98,7 +98,7 @@ impl Library {
|
||||||
let rel_path = page.path.clone();
|
let rel_path = page.path.clone();
|
||||||
|
|
||||||
let mut entries = vec![rel_path];
|
let mut entries = vec![rel_path];
|
||||||
entries.extend(page.meta.aliases.iter().map(|a| a.clone()).collect::<Vec<String>>());
|
entries.extend(page.meta.aliases.to_vec());
|
||||||
self.insert_reverse_aliases(entries, &page.file.relative);
|
self.insert_reverse_aliases(entries, &page.file.relative);
|
||||||
|
|
||||||
let key = self.pages.insert(page);
|
let key = self.pages.insert(page);
|
||||||
|
@ -252,7 +252,7 @@ impl Library {
|
||||||
}
|
}
|
||||||
|
|
||||||
for section in self.sections.values_mut() {
|
for section in self.sections.values_mut() {
|
||||||
if let Some(ref children) = subsections.get(§ion.file.path) {
|
if let Some(children) = subsections.get(§ion.file.path) {
|
||||||
let mut children: Vec<_> = children.iter().map(|p| sections[p]).collect();
|
let mut children: Vec<_> = children.iter().map(|p| sections[p]).collect();
|
||||||
children.sort_by(|a, b| sections_weight[a].cmp(§ions_weight[b]));
|
children.sort_by(|a, b| sections_weight[a].cmp(§ions_weight[b]));
|
||||||
section.subsections = children;
|
section.subsections = children;
|
||||||
|
@ -446,12 +446,9 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn can_find_no_collisions() {
|
fn can_find_no_collisions() {
|
||||||
let mut library = Library::new(10, 10, false);
|
let mut library = Library::new(10, 10, false);
|
||||||
let mut page = Page::default();
|
let page = Page { path: "hello".to_string(), ..Default::default() };
|
||||||
page.path = "hello".to_string();
|
let page2 = Page { path: "hello-world".to_string(), ..Default::default() };
|
||||||
let mut page2 = Page::default();
|
let section = Section { path: "blog".to_string(), ..Default::default() };
|
||||||
page2.path = "hello-world".to_string();
|
|
||||||
let mut section = Section::default();
|
|
||||||
section.path = "blog".to_string();
|
|
||||||
library.insert_page(page);
|
library.insert_page(page);
|
||||||
library.insert_page(page2);
|
library.insert_page(page2);
|
||||||
library.insert_section(section);
|
library.insert_section(section);
|
||||||
|
@ -463,14 +460,11 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn can_find_collisions_between_pages() {
|
fn can_find_collisions_between_pages() {
|
||||||
let mut library = Library::new(10, 10, false);
|
let mut library = Library::new(10, 10, false);
|
||||||
let mut page = Page::default();
|
let mut page = Page { path: "hello".to_string(), ..Default::default() };
|
||||||
page.path = "hello".to_string();
|
|
||||||
page.file.relative = "hello".to_string();
|
page.file.relative = "hello".to_string();
|
||||||
let mut page2 = Page::default();
|
let mut page2 = Page { path: "hello".to_string(), ..Default::default() };
|
||||||
page2.path = "hello".to_string();
|
|
||||||
page2.file.relative = "hello-world".to_string();
|
page2.file.relative = "hello-world".to_string();
|
||||||
let mut section = Section::default();
|
let mut section = Section { path: "blog".to_string(), ..Default::default() };
|
||||||
section.path = "blog".to_string();
|
|
||||||
section.file.relative = "hello-world".to_string();
|
section.file.relative = "hello-world".to_string();
|
||||||
library.insert_page(page.clone());
|
library.insert_page(page.clone());
|
||||||
library.insert_page(page2.clone());
|
library.insert_page(page2.clone());
|
||||||
|
@ -486,15 +480,12 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn can_find_collisions_with_an_alias() {
|
fn can_find_collisions_with_an_alias() {
|
||||||
let mut library = Library::new(10, 10, false);
|
let mut library = Library::new(10, 10, false);
|
||||||
let mut page = Page::default();
|
let mut page = Page { path: "hello".to_string(), ..Default::default() };
|
||||||
page.path = "hello".to_string();
|
|
||||||
page.file.relative = "hello".to_string();
|
page.file.relative = "hello".to_string();
|
||||||
let mut page2 = Page::default();
|
let mut page2 = Page { path: "hello".to_string(), ..Default::default() };
|
||||||
page2.path = "hello-world".to_string();
|
|
||||||
page2.file.relative = "hello-world".to_string();
|
page2.file.relative = "hello-world".to_string();
|
||||||
page2.meta.aliases = vec!["hello".to_string()];
|
page2.meta.aliases = vec!["hello".to_string()];
|
||||||
let mut section = Section::default();
|
let mut section = Section { path: "blog".to_string(), ..Default::default() };
|
||||||
section.path = "blog".to_string();
|
|
||||||
section.file.relative = "hello-world".to_string();
|
section.file.relative = "hello-world".to_string();
|
||||||
library.insert_page(page.clone());
|
library.insert_page(page.clone());
|
||||||
library.insert_page(page2.clone());
|
library.insert_page(page2.clone());
|
||||||
|
|
|
@ -255,15 +255,17 @@ mod tests {
|
||||||
use crate::library::Library;
|
use crate::library::Library;
|
||||||
use crate::taxonomies::{Taxonomy, TaxonomyItem};
|
use crate::taxonomies::{Taxonomy, TaxonomyItem};
|
||||||
use config::Taxonomy as TaxonomyConfig;
|
use config::Taxonomy as TaxonomyConfig;
|
||||||
use front_matter::SectionFrontMatter;
|
|
||||||
|
|
||||||
use super::Paginator;
|
use super::Paginator;
|
||||||
|
|
||||||
fn create_section(is_index: bool, paginate_reversed: bool) -> Section {
|
fn create_section(is_index: bool, paginate_reversed: bool) -> Section {
|
||||||
let mut f = SectionFrontMatter::default();
|
let f = front_matter::SectionFrontMatter {
|
||||||
f.paginate_by = Some(2);
|
paginate_by: Some(2),
|
||||||
f.paginate_path = "page".to_string();
|
paginate_path: "page".to_string(),
|
||||||
f.paginate_reversed = paginate_reversed;
|
paginate_reversed,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
let mut s = Section::new("content/_index.md", f, &PathBuf::new());
|
let mut s = Section::new("content/_index.md", f, &PathBuf::new());
|
||||||
if !is_index {
|
if !is_index {
|
||||||
s.path = "/posts/".to_string();
|
s.path = "/posts/".to_string();
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub fn sort_pages_by_date(
|
||||||
can_be_sorted.par_sort_unstable_by(|a, b| {
|
can_be_sorted.par_sort_unstable_by(|a, b| {
|
||||||
let ord = b.1.unwrap().cmp(&a.1.unwrap());
|
let ord = b.1.unwrap().cmp(&a.1.unwrap());
|
||||||
if ord == Ordering::Equal {
|
if ord == Ordering::Equal {
|
||||||
a.2.cmp(&b.2)
|
a.2.cmp(b.2)
|
||||||
} else {
|
} else {
|
||||||
ord
|
ord
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ pub fn sort_pages_by_title(
|
||||||
can_be_sorted.par_sort_unstable_by(|a, b| {
|
can_be_sorted.par_sort_unstable_by(|a, b| {
|
||||||
let ord = natural_lexical_cmp(a.1.unwrap(), b.1.unwrap());
|
let ord = natural_lexical_cmp(a.1.unwrap(), b.1.unwrap());
|
||||||
if ord == Ordering::Equal {
|
if ord == Ordering::Equal {
|
||||||
a.2.cmp(&b.2)
|
a.2.cmp(b.2)
|
||||||
} else {
|
} else {
|
||||||
ord
|
ord
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ pub fn sort_pages_by_weight(
|
||||||
can_be_sorted.par_sort_unstable_by(|a, b| {
|
can_be_sorted.par_sort_unstable_by(|a, b| {
|
||||||
let ord = a.1.unwrap().cmp(&b.1.unwrap());
|
let ord = a.1.unwrap().cmp(&b.1.unwrap());
|
||||||
if ord == Ordering::Equal {
|
if ord == Ordering::Equal {
|
||||||
a.2.cmp(&b.2)
|
a.2.cmp(b.2)
|
||||||
} else {
|
} else {
|
||||||
ord
|
ord
|
||||||
}
|
}
|
||||||
|
@ -119,21 +119,19 @@ mod tests {
|
||||||
use front_matter::PageFrontMatter;
|
use front_matter::PageFrontMatter;
|
||||||
|
|
||||||
fn create_page_with_date(date: &str) -> Page {
|
fn create_page_with_date(date: &str) -> Page {
|
||||||
let mut front_matter = PageFrontMatter::default();
|
let mut front_matter =
|
||||||
front_matter.date = Some(date.to_string());
|
PageFrontMatter { date: Some(date.to_string()), ..Default::default() };
|
||||||
front_matter.date_to_datetime();
|
front_matter.date_to_datetime();
|
||||||
Page::new("content/hello.md", front_matter, &PathBuf::new())
|
Page::new("content/hello.md", front_matter, &PathBuf::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_page_with_title(title: &str) -> Page {
|
fn create_page_with_title(title: &str) -> Page {
|
||||||
let mut front_matter = PageFrontMatter::default();
|
let front_matter = PageFrontMatter { title: Some(title.to_string()), ..Default::default() };
|
||||||
front_matter.title = Some(title.to_string());
|
|
||||||
Page::new("content/hello.md", front_matter, &PathBuf::new())
|
Page::new("content/hello.md", front_matter, &PathBuf::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_page_with_weight(weight: usize) -> Page {
|
fn create_page_with_weight(weight: usize) -> Page {
|
||||||
let mut front_matter = PageFrontMatter::default();
|
let front_matter = PageFrontMatter { weight: Some(weight), ..Default::default() };
|
||||||
front_matter.weight = Some(weight);
|
|
||||||
Page::new("content/hello.md", front_matter, &PathBuf::new())
|
Page::new("content/hello.md", front_matter, &PathBuf::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,11 +249,11 @@ mod tests {
|
||||||
fn can_find_siblings() {
|
fn can_find_siblings() {
|
||||||
let mut dense = DenseSlotMap::new();
|
let mut dense = DenseSlotMap::new();
|
||||||
let page1 = create_page_with_weight(1);
|
let page1 = create_page_with_weight(1);
|
||||||
let key1 = dense.insert(page1.clone());
|
let key1 = dense.insert(page1);
|
||||||
let page2 = create_page_with_weight(2);
|
let page2 = create_page_with_weight(2);
|
||||||
let key2 = dense.insert(page2.clone());
|
let key2 = dense.insert(page2);
|
||||||
let page3 = create_page_with_weight(3);
|
let page3 = create_page_with_weight(3);
|
||||||
let key3 = dense.insert(page3.clone());
|
let key3 = dense.insert(page3);
|
||||||
|
|
||||||
let input = vec![key1, key2, key3];
|
let input = vec![key1, key2, key3];
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ pub fn find_taxonomies(config: &Config, library: &Library) -> Result<Vec<Taxonom
|
||||||
let mut all_taxonomies = HashMap::new();
|
let mut all_taxonomies = HashMap::new();
|
||||||
for (key, page) in library.pages() {
|
for (key, page) in library.pages() {
|
||||||
for (name, taxo_term) in &page.meta.taxonomies {
|
for (name, taxo_term) in &page.meta.taxonomies {
|
||||||
let taxo_slug = slugify_paths(&name, config.slugify.taxonomies);
|
let taxo_slug = slugify_paths(name, config.slugify.taxonomies);
|
||||||
let taxo_key = format!("{}-{}", &taxo_slug, page.lang);
|
let taxo_key = format!("{}-{}", &taxo_slug, page.lang);
|
||||||
if taxonomies_def.contains_key(&taxo_key) {
|
if taxonomies_def.contains_key(&taxo_key) {
|
||||||
all_taxonomies.entry(taxo_key.clone()).or_insert_with(HashMap::new);
|
all_taxonomies.entry(taxo_key.clone()).or_insert_with(HashMap::new);
|
||||||
|
@ -539,8 +539,7 @@ mod tests {
|
||||||
page2.lang = config.default_language.clone();
|
page2.lang = config.default_language.clone();
|
||||||
library.insert_page(page2);
|
library.insert_page(page2);
|
||||||
|
|
||||||
let mut page3 = Page::default();
|
let mut page3 = Page { lang: "fr".to_string(), ..Default::default() };
|
||||||
page3.lang = "fr".to_string();
|
|
||||||
let mut taxo_page3 = HashMap::new();
|
let mut taxo_page3 = HashMap::new();
|
||||||
taxo_page3.insert("tags".to_string(), vec!["rust".to_string()]);
|
taxo_page3.insert("tags".to_string(), vec!["rust".to_string()]);
|
||||||
taxo_page3.insert("auteurs".to_string(), vec!["Vincent Prouillet".to_string()]);
|
taxo_page3.insert("auteurs".to_string(), vec!["Vincent Prouillet".to_string()]);
|
||||||
|
@ -617,8 +616,7 @@ mod tests {
|
||||||
};
|
};
|
||||||
config.languages.insert("fr".to_owned(), lang_options);
|
config.languages.insert("fr".to_owned(), lang_options);
|
||||||
|
|
||||||
let mut page = Page::default();
|
let mut page = Page { lang: "fr".to_string(), ..Default::default() };
|
||||||
page.lang = "fr".to_string();
|
|
||||||
let mut taxo_page = HashMap::new();
|
let mut taxo_page = HashMap::new();
|
||||||
taxo_page.insert("catégories".to_string(), vec!["Écologie".to_string()]);
|
taxo_page.insert("catégories".to_string(), vec!["Écologie".to_string()]);
|
||||||
page.meta.taxonomies = taxo_page;
|
page.meta.taxonomies = taxo_page;
|
||||||
|
@ -668,8 +666,7 @@ mod tests {
|
||||||
page2.lang = config.default_language.clone();
|
page2.lang = config.default_language.clone();
|
||||||
library.insert_page(page2);
|
library.insert_page(page2);
|
||||||
|
|
||||||
let mut page3 = Page::default();
|
let mut page3 = Page { lang: "fr".to_string(), ..Default::default() };
|
||||||
page3.lang = "fr".to_string();
|
|
||||||
let mut taxo_page3 = HashMap::new();
|
let mut taxo_page3 = HashMap::new();
|
||||||
taxo_page3.insert("tags".to_string(), vec!["rust".to_string()]);
|
taxo_page3.insert("tags".to_string(), vec!["rust".to_string()]);
|
||||||
taxo_page3.insert("auteurs".to_string(), vec!["Vincent Prouillet".to_string()]);
|
taxo_page3.insert("auteurs".to_string(), vec!["Vincent Prouillet".to_string()]);
|
||||||
|
|
|
@ -8,7 +8,7 @@ use front_matter::InsertAnchor;
|
||||||
use rendering::{render_content, render_shortcodes, RenderContext};
|
use rendering::{render_content, render_shortcodes, RenderContext};
|
||||||
use tera::Tera;
|
use tera::Tera;
|
||||||
|
|
||||||
static CONTENT: &'static str = r#"
|
static CONTENT: &str = r#"
|
||||||
# Modus cognitius profanam ne duae virtutis mundi
|
# Modus cognitius profanam ne duae virtutis mundi
|
||||||
|
|
||||||
## Ut vita
|
## Ut vita
|
||||||
|
@ -86,7 +86,15 @@ fn bench_render_content_with_highlighting(b: &mut test::Bencher) {
|
||||||
tera.add_raw_template("shortcodes/youtube.html", "{{id}}").unwrap();
|
tera.add_raw_template("shortcodes/youtube.html", "{{id}}").unwrap();
|
||||||
let permalinks_ctx = HashMap::new();
|
let permalinks_ctx = HashMap::new();
|
||||||
let config = Config::default();
|
let config = Config::default();
|
||||||
let context = RenderContext::new(&tera, &config, "", &permalinks_ctx, InsertAnchor::None);
|
let current_page_permalink = "";
|
||||||
|
let context = RenderContext::new(
|
||||||
|
&tera,
|
||||||
|
&config,
|
||||||
|
"",
|
||||||
|
current_page_permalink,
|
||||||
|
&permalinks_ctx,
|
||||||
|
InsertAnchor::None,
|
||||||
|
);
|
||||||
b.iter(|| render_content(CONTENT, &context).unwrap());
|
b.iter(|| render_content(CONTENT, &context).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +105,15 @@ fn bench_render_content_without_highlighting(b: &mut test::Bencher) {
|
||||||
let permalinks_ctx = HashMap::new();
|
let permalinks_ctx = HashMap::new();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.markdown.highlight_code = false;
|
config.markdown.highlight_code = false;
|
||||||
let context = RenderContext::new(&tera, &config, "", &permalinks_ctx, InsertAnchor::None);
|
let current_page_permalink = "";
|
||||||
|
let context = RenderContext::new(
|
||||||
|
&tera,
|
||||||
|
&config,
|
||||||
|
"",
|
||||||
|
current_page_permalink,
|
||||||
|
&permalinks_ctx,
|
||||||
|
InsertAnchor::None,
|
||||||
|
);
|
||||||
b.iter(|| render_content(CONTENT, &context).unwrap());
|
b.iter(|| render_content(CONTENT, &context).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +124,15 @@ fn bench_render_content_no_shortcode(b: &mut test::Bencher) {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.markdown.highlight_code = false;
|
config.markdown.highlight_code = false;
|
||||||
let permalinks_ctx = HashMap::new();
|
let permalinks_ctx = HashMap::new();
|
||||||
let context = RenderContext::new(&tera, &config, "", &permalinks_ctx, InsertAnchor::None);
|
let current_page_permalink = "";
|
||||||
|
let context = RenderContext::new(
|
||||||
|
&tera,
|
||||||
|
&config,
|
||||||
|
"",
|
||||||
|
current_page_permalink,
|
||||||
|
&permalinks_ctx,
|
||||||
|
InsertAnchor::None,
|
||||||
|
);
|
||||||
|
|
||||||
b.iter(|| render_content(&content2, &context).unwrap());
|
b.iter(|| render_content(&content2, &context).unwrap());
|
||||||
}
|
}
|
||||||
|
@ -119,7 +143,15 @@ fn bench_render_shortcodes_one_present(b: &mut test::Bencher) {
|
||||||
tera.add_raw_template("shortcodes/youtube.html", "{{id}}").unwrap();
|
tera.add_raw_template("shortcodes/youtube.html", "{{id}}").unwrap();
|
||||||
let config = Config::default();
|
let config = Config::default();
|
||||||
let permalinks_ctx = HashMap::new();
|
let permalinks_ctx = HashMap::new();
|
||||||
let context = RenderContext::new(&tera, &config, "", &permalinks_ctx, InsertAnchor::None);
|
let current_page_permalink = "";
|
||||||
|
let context = RenderContext::new(
|
||||||
|
&tera,
|
||||||
|
&config,
|
||||||
|
"",
|
||||||
|
current_page_permalink,
|
||||||
|
&permalinks_ctx,
|
||||||
|
InsertAnchor::None,
|
||||||
|
);
|
||||||
|
|
||||||
b.iter(|| render_shortcodes(CONTENT, &context));
|
b.iter(|| render_shortcodes(CONTENT, &context));
|
||||||
}
|
}
|
||||||
|
@ -132,7 +164,15 @@ fn bench_render_content_no_shortcode_with_emoji(b: &mut test::Bencher) {
|
||||||
config.markdown.highlight_code = false;
|
config.markdown.highlight_code = false;
|
||||||
config.markdown.render_emoji = true;
|
config.markdown.render_emoji = true;
|
||||||
let permalinks_ctx = HashMap::new();
|
let permalinks_ctx = HashMap::new();
|
||||||
let context = RenderContext::new(&tera, &config, "", &permalinks_ctx, InsertAnchor::None);
|
let current_page_permalink = "";
|
||||||
|
let context = RenderContext::new(
|
||||||
|
&tera,
|
||||||
|
&config,
|
||||||
|
"",
|
||||||
|
current_page_permalink,
|
||||||
|
&permalinks_ctx,
|
||||||
|
InsertAnchor::None,
|
||||||
|
);
|
||||||
|
|
||||||
b.iter(|| render_content(&content2, &context).unwrap());
|
b.iter(|| render_content(&content2, &context).unwrap());
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,8 @@ impl<'config> ClassHighlighter<'config> {
|
||||||
/// *Note:* This function requires `line` to include a newline at the end and
|
/// *Note:* This function requires `line` to include a newline at the end and
|
||||||
/// also use of the `load_defaults_newlines` version of the syntaxes.
|
/// also use of the `load_defaults_newlines` version of the syntaxes.
|
||||||
pub fn highlight_line(&mut self, line: &str) -> String {
|
pub fn highlight_line(&mut self, line: &str) -> String {
|
||||||
debug_assert!(line.ends_with("\n"));
|
debug_assert!(line.ends_with('\n'));
|
||||||
let parsed_line = self.parse_state.parse_line(line, &self.syntax_set);
|
let parsed_line = self.parse_state.parse_line(line, self.syntax_set);
|
||||||
let (formatted_line, delta) = line_tokens_to_classed_spans(
|
let (formatted_line, delta) = line_tokens_to_classed_spans(
|
||||||
line,
|
line,
|
||||||
parsed_line.as_slice(),
|
parsed_line.as_slice(),
|
||||||
|
@ -81,9 +81,12 @@ impl<'config> InlineHighlighter<'config> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn highlight_line(&mut self, line: &str) -> String {
|
pub fn highlight_line(&mut self, line: &str) -> String {
|
||||||
let regions = self.h.highlight(line, &self.syntax_set);
|
let regions = self.h.highlight(line, self.syntax_set);
|
||||||
// TODO: add a param like `IncludeBackground` for `IncludeForeground` in syntect
|
// TODO: add a param like `IncludeBackground` for `IncludeForeground` in syntect
|
||||||
let highlighted = styled_line_to_highlighted_html(®ions, IncludeBackground::IfDifferent(self.bg_color));
|
let highlighted = styled_line_to_highlighted_html(
|
||||||
|
®ions,
|
||||||
|
IncludeBackground::IfDifferent(self.bg_color),
|
||||||
|
);
|
||||||
highlighted.replace(&self.fg_color, "")
|
highlighted.replace(&self.fg_color, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,7 +175,7 @@ impl<'config> SyntaxHighlighter<'config> {
|
||||||
&mut styles,
|
&mut styles,
|
||||||
h.theme.settings.line_highlight.unwrap_or(Color { r: 255, g: 255, b: 0, a: 0 }),
|
h.theme.settings.line_highlight.unwrap_or(Color { r: 255, g: 255, b: 0, a: 0 }),
|
||||||
);
|
);
|
||||||
styles.push_str(";");
|
styles.push(';');
|
||||||
Some(styles)
|
Some(styles)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +198,7 @@ mod tests {
|
||||||
let mut highlighter =
|
let mut highlighter =
|
||||||
ClassHighlighter::new(syntax_and_theme.syntax, syntax_and_theme.syntax_set);
|
ClassHighlighter::new(syntax_and_theme.syntax, syntax_and_theme.syntax_set);
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
for line in LinesWithEndings::from(&code) {
|
for line in LinesWithEndings::from(code) {
|
||||||
out.push_str(&highlighter.highlight_line(line));
|
out.push_str(&highlighter.highlight_line(line));
|
||||||
}
|
}
|
||||||
out.push_str(&highlighter.finalize());
|
out.push_str(&highlighter.finalize());
|
||||||
|
@ -217,7 +220,7 @@ mod tests {
|
||||||
syntax_and_theme.theme.unwrap(),
|
syntax_and_theme.theme.unwrap(),
|
||||||
);
|
);
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
for line in LinesWithEndings::from(&code) {
|
for line in LinesWithEndings::from(code) {
|
||||||
out.push_str(&highlighter.highlight_line(line));
|
out.push_str(&highlighter.highlight_line(line));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ fn opening_html(
|
||||||
|
|
||||||
if let Some(lang) = language {
|
if let Some(lang) = language {
|
||||||
classes.push_str("language-");
|
classes.push_str("language-");
|
||||||
classes.push_str(&lang);
|
classes.push_str(lang);
|
||||||
classes.push_str(" ");
|
classes.push(' ');
|
||||||
|
|
||||||
html.push_str(" data-lang=\"");
|
html.push_str(" data-lang=\"");
|
||||||
html.push_str(lang);
|
html.push_str(lang);
|
||||||
|
@ -114,7 +114,7 @@ impl<'config> CodeBlock<'config> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// syntect leaking here in this file
|
// syntect leaking here in this file
|
||||||
for (i, line) in LinesWithEndings::from(&content).enumerate() {
|
for (i, line) in LinesWithEndings::from(content).enumerate() {
|
||||||
let one_indexed = i + 1;
|
let one_indexed = i + 1;
|
||||||
// first do we need to skip that line?
|
// first do we need to skip that line?
|
||||||
let mut skip = false;
|
let mut skip = false;
|
||||||
|
@ -143,10 +143,10 @@ impl<'config> CodeBlock<'config> {
|
||||||
buffer.push_str("<mark");
|
buffer.push_str("<mark");
|
||||||
if let Some(ref s) = mark_style {
|
if let Some(ref s) = mark_style {
|
||||||
buffer.push_str(" style=\"");
|
buffer.push_str(" style=\"");
|
||||||
buffer.push_str(&s);
|
buffer.push_str(s);
|
||||||
buffer.push_str("\">");
|
buffer.push_str("\">");
|
||||||
} else {
|
} else {
|
||||||
buffer.push_str(">")
|
buffer.push('>')
|
||||||
}
|
}
|
||||||
buffer.push_str(&num);
|
buffer.push_str(&num);
|
||||||
buffer.push_str("</mark>");
|
buffer.push_str("</mark>");
|
||||||
|
@ -161,10 +161,10 @@ impl<'config> CodeBlock<'config> {
|
||||||
buffer.push_str("<mark");
|
buffer.push_str("<mark");
|
||||||
if let Some(ref s) = mark_style {
|
if let Some(ref s) = mark_style {
|
||||||
buffer.push_str(" style=\"");
|
buffer.push_str(" style=\"");
|
||||||
buffer.push_str(&s);
|
buffer.push_str(s);
|
||||||
buffer.push_str("\">");
|
buffer.push_str("\">");
|
||||||
} else {
|
} else {
|
||||||
buffer.push_str(">")
|
buffer.push('>')
|
||||||
}
|
}
|
||||||
buffer.push_str(&highlighted_line);
|
buffer.push_str(&highlighted_line);
|
||||||
buffer.push_str("</mark>");
|
buffer.push_str("</mark>");
|
||||||
|
|
|
@ -19,5 +19,5 @@ pub fn render_content(content: &str, context: &RenderContext) -> Result<markdown
|
||||||
return Ok(html);
|
return Ok(html);
|
||||||
}
|
}
|
||||||
|
|
||||||
markdown_to_html(&content, context)
|
markdown_to_html(content, context)
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ fn fix_link(
|
||||||
// - it could be a link to a co-located asset
|
// - it could be a link to a co-located asset
|
||||||
// - it could be a normal link
|
// - it could be a normal link
|
||||||
let result = if link.starts_with("@/") {
|
let result = if link.starts_with("@/") {
|
||||||
match resolve_internal_link(&link, &context.permalinks) {
|
match resolve_internal_link(link, &context.permalinks) {
|
||||||
Ok(resolved) => {
|
Ok(resolved) => {
|
||||||
internal_links.push((resolved.md_path, resolved.anchor));
|
internal_links.push((resolved.md_path, resolved.anchor));
|
||||||
resolved.permalink
|
resolved.permalink
|
||||||
|
@ -111,7 +111,7 @@ fn fix_link(
|
||||||
return Err(format!("Relative link {} not found.", link).into());
|
return Err(format!("Relative link {} not found.", link).into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if is_colocated_asset_link(&link) {
|
} else if is_colocated_asset_link(link) {
|
||||||
format!("{}{}", context.current_page_permalink, link)
|
format!("{}{}", context.current_page_permalink, link)
|
||||||
} else {
|
} else {
|
||||||
if is_external_link(link) {
|
if is_external_link(link) {
|
||||||
|
@ -163,7 +163,7 @@ pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<Render
|
||||||
let path = context
|
let path = context
|
||||||
.tera_context
|
.tera_context
|
||||||
.get("page")
|
.get("page")
|
||||||
.or(context.tera_context.get("section"))
|
.or_else(|| context.tera_context.get("section"))
|
||||||
.map(|x| x.as_object().unwrap().get("relative_path").unwrap().as_str().unwrap());
|
.map(|x| x.as_object().unwrap().get("relative_path").unwrap().as_str().unwrap());
|
||||||
// the rendered html
|
// the rendered html
|
||||||
let mut html = String::with_capacity(content.len());
|
let mut html = String::with_capacity(content.len());
|
||||||
|
@ -213,7 +213,7 @@ pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<Render
|
||||||
}
|
}
|
||||||
_ => FenceSettings::new(""),
|
_ => FenceSettings::new(""),
|
||||||
};
|
};
|
||||||
let (block, begin) = CodeBlock::new(fence, &context.config, path);
|
let (block, begin) = CodeBlock::new(fence, context.config, path);
|
||||||
code_block = Some(block);
|
code_block = Some(block);
|
||||||
Event::Html(begin.into())
|
Event::Html(begin.into())
|
||||||
}
|
}
|
||||||
|
@ -344,7 +344,7 @@ pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<Render
|
||||||
c.insert("level", &heading_ref.level);
|
c.insert("level", &heading_ref.level);
|
||||||
|
|
||||||
let anchor_link = utils::templates::render_template(
|
let anchor_link = utils::templates::render_template(
|
||||||
&ANCHOR_LINK_TEMPLATE,
|
ANCHOR_LINK_TEMPLATE,
|
||||||
&context.tera,
|
&context.tera,
|
||||||
c,
|
c,
|
||||||
&None,
|
&None,
|
||||||
|
|
|
@ -110,7 +110,7 @@ fn render_shortcode(
|
||||||
for (key, value) in args.iter() {
|
for (key, value) in args.iter() {
|
||||||
tera_context.insert(key, value);
|
tera_context.insert(key, value);
|
||||||
}
|
}
|
||||||
if let Some(ref b) = body {
|
if let Some(b) = body {
|
||||||
// Trimming right to avoid most shortcodes with bodies ending up with a HTML new line
|
// Trimming right to avoid most shortcodes with bodies ending up with a HTML new line
|
||||||
tera_context.insert("body", b.trim_end());
|
tera_context.insert("body", b.trim_end());
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ mod tests {
|
||||||
let config = Config::default_for_test();
|
let config = Config::default_for_test();
|
||||||
let permalinks = HashMap::new();
|
let permalinks = HashMap::new();
|
||||||
let context = RenderContext::new(
|
let context = RenderContext::new(
|
||||||
&tera,
|
tera,
|
||||||
&config,
|
&config,
|
||||||
&config.default_language,
|
&config.default_language,
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -106,7 +106,7 @@ fn fill_index(
|
||||||
}
|
}
|
||||||
|
|
||||||
if search_config.include_content {
|
if search_config.include_content {
|
||||||
let body = AMMONIA.clean(&content).to_string();
|
let body = AMMONIA.clean(content).to_string();
|
||||||
if let Some(truncate_len) = search_config.truncate_content_length {
|
if let Some(truncate_len) = search_config.truncate_content_length {
|
||||||
// Not great for unicode
|
// Not great for unicode
|
||||||
// TODO: fix it like the truncate in Tera
|
// TODO: fix it like the truncate in Tera
|
||||||
|
|
|
@ -8,7 +8,7 @@ use site::Site;
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_loading_small_blog(b: &mut test::Bencher) {
|
fn bench_loading_small_blog(b: &mut test::Bencher) {
|
||||||
let mut path = env::current_dir().unwrap().to_path_buf();
|
let mut path = env::current_dir().unwrap();
|
||||||
path.push("benches");
|
path.push("benches");
|
||||||
path.push("small-blog");
|
path.push("small-blog");
|
||||||
let config_file = path.join("config.toml");
|
let config_file = path.join("config.toml");
|
||||||
|
@ -19,12 +19,12 @@ fn bench_loading_small_blog(b: &mut test::Bencher) {
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_loading_small_blog_with_syntax_highlighting(b: &mut test::Bencher) {
|
fn bench_loading_small_blog_with_syntax_highlighting(b: &mut test::Bencher) {
|
||||||
let mut path = env::current_dir().unwrap().to_path_buf();
|
let mut path = env::current_dir().unwrap();
|
||||||
path.push("benches");
|
path.push("benches");
|
||||||
path.push("small-blog");
|
path.push("small-blog");
|
||||||
let config_file = path.join("config.toml");
|
let config_file = path.join("config.toml");
|
||||||
let mut site = Site::new(&path, &config_file).unwrap();
|
let mut site = Site::new(&path, &config_file).unwrap();
|
||||||
site.config.highlight_code = true;
|
site.config.markdown.highlight_code = true;
|
||||||
|
|
||||||
b.iter(|| site.load().unwrap());
|
b.iter(|| site.load().unwrap());
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ fn bench_loading_small_blog_with_syntax_highlighting(b: &mut test::Bencher) {
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_loading_small_kb(b: &mut test::Bencher) {
|
fn bench_loading_small_kb(b: &mut test::Bencher) {
|
||||||
let mut path = env::current_dir().unwrap().to_path_buf();
|
let mut path = env::current_dir().unwrap();
|
||||||
path.push("benches");
|
path.push("benches");
|
||||||
path.push("small-kb");
|
path.push("small-kb");
|
||||||
let config_file = path.join("config.toml");
|
let config_file = path.join("config.toml");
|
||||||
|
@ -111,12 +111,12 @@ fn bench_loading_small_kb(b: &mut test::Bencher) {
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_loading_small_kb_with_syntax_highlighting(b: &mut test::Bencher) {
|
fn bench_loading_small_kb_with_syntax_highlighting(b: &mut test::Bencher) {
|
||||||
let mut path = env::current_dir().unwrap().to_path_buf();
|
let mut path = env::current_dir().unwrap();
|
||||||
path.push("benches");
|
path.push("benches");
|
||||||
path.push("small-kb");
|
path.push("small-kb");
|
||||||
let config_file = path.join("config.toml");
|
let config_file = path.join("config.toml");
|
||||||
let mut site = Site::new(&path, &config_file).unwrap();
|
let mut site = Site::new(&path, &config_file).unwrap();
|
||||||
site.config.highlight_code = true;
|
site.config.markdown.highlight_code = true;
|
||||||
|
|
||||||
b.iter(|| site.load().unwrap());
|
b.iter(|| site.load().unwrap());
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use site::Site;
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
|
|
||||||
fn setup_site(name: &str) -> Site {
|
fn setup_site(name: &str) -> Site {
|
||||||
let mut path = env::current_dir().unwrap().to_path_buf();
|
let mut path = env::current_dir().unwrap();
|
||||||
path.push("benches");
|
path.push("benches");
|
||||||
path.push(name);
|
path.push(name);
|
||||||
let config_file = path.join("config.toml");
|
let config_file = path.join("config.toml");
|
||||||
|
@ -69,7 +69,7 @@ fn bench_render_paginated(b: &mut test::Bencher) {
|
||||||
site.set_output_path(&public);
|
site.set_output_path(&public);
|
||||||
let library = site.library.read().unwrap();
|
let library = site.library.read().unwrap();
|
||||||
let section = library.sections_values()[0];
|
let section = library.sections_values()[0];
|
||||||
let paginator = Paginator::from_section(§ion, &library);
|
let paginator = Paginator::from_section(section, &library);
|
||||||
|
|
||||||
b.iter(|| site.render_paginated(Vec::new(), &paginator));
|
b.iter(|| site.render_paginated(Vec::new(), &paginator));
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ pub fn render_feed(
|
||||||
context.insert("lang", lang);
|
context.insert("lang", lang);
|
||||||
|
|
||||||
let feed_filename = &site.config.feed_filename;
|
let feed_filename = &site.config.feed_filename;
|
||||||
let feed_url = if let Some(ref base) = base_path {
|
let feed_url = if let Some(base) = base_path {
|
||||||
site.config.make_permalink(&base.join(feed_filename).to_string_lossy().replace('\\', "/"))
|
site.config.make_permalink(&base.join(feed_filename).to_string_lossy().replace('\\', "/"))
|
||||||
} else {
|
} else {
|
||||||
site.config.make_permalink(feed_filename)
|
site.config.make_permalink(feed_filename)
|
||||||
|
|
|
@ -78,8 +78,7 @@ impl Site {
|
||||||
|
|
||||||
if let Some(theme) = config.theme.clone() {
|
if let Some(theme) = config.theme.clone() {
|
||||||
// Grab data from the extra section of the theme
|
// Grab data from the extra section of the theme
|
||||||
config
|
config.merge_with_theme(path.join("themes").join(&theme).join("theme.toml"), &theme)?;
|
||||||
.merge_with_theme(&path.join("themes").join(&theme).join("theme.toml"), &theme)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let tera = load_tera(path, &config)?;
|
let tera = load_tera(path, &config)?;
|
||||||
|
@ -288,10 +287,10 @@ impl Site {
|
||||||
tpls::register_tera_global_fns(self);
|
tpls::register_tera_global_fns(self);
|
||||||
|
|
||||||
// Needs to be done after rendering markdown as we only get the anchors at that point
|
// Needs to be done after rendering markdown as we only get the anchors at that point
|
||||||
link_checking::check_internal_links_with_anchors(&self)?;
|
link_checking::check_internal_links_with_anchors(self)?;
|
||||||
|
|
||||||
if self.config.is_in_check_mode() {
|
if self.config.is_in_check_mode() {
|
||||||
link_checking::check_external_links(&self)?;
|
link_checking::check_external_links(self)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -301,7 +300,7 @@ impl Site {
|
||||||
/// a _index.md to render the index page at the root of the site
|
/// a _index.md to render the index page at the root of the site
|
||||||
pub fn create_default_index_sections(&mut self) -> Result<()> {
|
pub fn create_default_index_sections(&mut self) -> Result<()> {
|
||||||
for (index_path, lang) in self.index_section_paths() {
|
for (index_path, lang) in self.index_section_paths() {
|
||||||
if let Some(ref index_section) = self.library.read().unwrap().get_section(&index_path) {
|
if let Some(index_section) = self.library.read().unwrap().get_section(&index_path) {
|
||||||
if self.config.build_search_index && !index_section.meta.in_search_index {
|
if self.config.build_search_index && !index_section.meta.in_search_index {
|
||||||
bail!(
|
bail!(
|
||||||
"You have enabled search in the config but disabled it in the index section: \
|
"You have enabled search in the config but disabled it in the index section: \
|
||||||
|
@ -406,7 +405,7 @@ impl Site {
|
||||||
self.populate_taxonomies()?;
|
self.populate_taxonomies()?;
|
||||||
let library = self.library.read().unwrap();
|
let library = self.library.read().unwrap();
|
||||||
let page = library.get_page(&path).unwrap();
|
let page = library.get_page(&path).unwrap();
|
||||||
self.render_page(&page)
|
self.render_page(page)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a section to the site
|
/// Add a section to the site
|
||||||
|
@ -431,14 +430,14 @@ impl Site {
|
||||||
self.populate_sections();
|
self.populate_sections();
|
||||||
let library = self.library.read().unwrap();
|
let library = self.library.read().unwrap();
|
||||||
let section = library.get_section(&path).unwrap();
|
let section = library.get_section(&path).unwrap();
|
||||||
self.render_section(§ion, true)
|
self.render_section(section, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds the insert_anchor for the parent section of the directory at `path`.
|
/// Finds the insert_anchor for the parent section of the directory at `path`.
|
||||||
/// Defaults to `AnchorInsert::None` if no parent section found
|
/// Defaults to `AnchorInsert::None` if no parent section found
|
||||||
pub fn find_parent_section_insert_anchor(
|
pub fn find_parent_section_insert_anchor(
|
||||||
&self,
|
&self,
|
||||||
parent_path: &PathBuf,
|
parent_path: &Path,
|
||||||
lang: &str,
|
lang: &str,
|
||||||
) -> InsertAnchor {
|
) -> InsertAnchor {
|
||||||
let parent = if lang != self.config.default_language {
|
let parent = if lang != self.config.default_language {
|
||||||
|
@ -578,7 +577,7 @@ impl Site {
|
||||||
Ok(current_path)
|
Ok(current_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_asset(&self, src: &Path, dest: &PathBuf) -> Result<()> {
|
fn copy_asset(&self, src: &Path, dest: &Path) -> Result<()> {
|
||||||
copy_file_if_needed(src, dest, self.config.hard_link_static)
|
copy_file_if_needed(src, dest, self.config.hard_link_static)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,7 +593,7 @@ impl Site {
|
||||||
for asset in &page.assets {
|
for asset in &page.assets {
|
||||||
let asset_path = asset.as_path();
|
let asset_path = asset.as_path();
|
||||||
self.copy_asset(
|
self.copy_asset(
|
||||||
&asset_path,
|
asset_path,
|
||||||
¤t_path
|
¤t_path
|
||||||
.join(asset_path.file_name().expect("Couldn't get filename from page asset")),
|
.join(asset_path.file_name().expect("Couldn't get filename from page asset")),
|
||||||
)?;
|
)?;
|
||||||
|
@ -664,7 +663,7 @@ impl Site {
|
||||||
}
|
}
|
||||||
let pages =
|
let pages =
|
||||||
library.pages_values().iter().filter(|p| &p.lang == code).cloned().collect();
|
library.pages_values().iter().filter(|p| &p.lang == code).cloned().collect();
|
||||||
self.render_feed(pages, Some(&PathBuf::from(code)), &code, |c| c)?;
|
self.render_feed(pages, Some(&PathBuf::from(code)), code, |c| c)?;
|
||||||
start = log_time(start, "Generated feed in other language");
|
start = log_time(start, "Generated feed in other language");
|
||||||
}
|
}
|
||||||
self.render_themes_css()?;
|
self.render_themes_css()?;
|
||||||
|
@ -723,7 +722,7 @@ impl Site {
|
||||||
&self.output_path.join(&format!("search_index.{}.js", &code)),
|
&self.output_path.join(&format!("search_index.{}.js", &code)),
|
||||||
&format!(
|
&format!(
|
||||||
"window.searchIndex = {};",
|
"window.searchIndex = {};",
|
||||||
search::build_index(&code, &self.library.read().unwrap(), &self.config)?
|
search::build_index(code, &self.library.read().unwrap(), &self.config)?
|
||||||
),
|
),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
@ -748,7 +747,7 @@ impl Site {
|
||||||
}
|
}
|
||||||
None => "index.html",
|
None => "index.html",
|
||||||
};
|
};
|
||||||
let content = render_redirect_template(&permalink, &self.tera)?;
|
let content = render_redirect_template(permalink, &self.tera)?;
|
||||||
self.write_content(&split, page_name, content, false)?;
|
self.write_content(&split, page_name, content, false)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -760,12 +759,12 @@ impl Site {
|
||||||
let library = self.library.read().unwrap();
|
let library = self.library.read().unwrap();
|
||||||
for (_, page) in library.pages() {
|
for (_, page) in library.pages() {
|
||||||
for alias in &page.meta.aliases {
|
for alias in &page.meta.aliases {
|
||||||
self.render_alias(&alias, &page.permalink)?;
|
self.render_alias(alias, &page.permalink)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (_, section) in library.sections() {
|
for (_, section) in library.sections() {
|
||||||
for alias in §ion.meta.aliases {
|
for alias in §ion.meta.aliases {
|
||||||
self.render_alias(&alias, §ion.permalink)?;
|
self.render_alias(alias, §ion.permalink)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -832,7 +831,7 @@ impl Site {
|
||||||
if taxonomy.kind.is_paginated() {
|
if taxonomy.kind.is_paginated() {
|
||||||
self.render_paginated(
|
self.render_paginated(
|
||||||
comp.clone(),
|
comp.clone(),
|
||||||
&Paginator::from_taxonomy(&taxonomy, item, &library),
|
&Paginator::from_taxonomy(taxonomy, item, &library),
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
let single_output =
|
let single_output =
|
||||||
|
@ -926,7 +925,7 @@ impl Site {
|
||||||
};
|
};
|
||||||
let feed_filename = &self.config.feed_filename;
|
let feed_filename = &self.config.feed_filename;
|
||||||
|
|
||||||
if let Some(ref base) = base_path {
|
if let Some(base) = base_path {
|
||||||
let mut components = Vec::new();
|
let mut components = Vec::new();
|
||||||
for component in base.components() {
|
for component in base.components() {
|
||||||
// TODO: avoid cloning the paths
|
// TODO: avoid cloning the paths
|
||||||
|
@ -934,12 +933,12 @@ impl Site {
|
||||||
}
|
}
|
||||||
self.write_content(
|
self.write_content(
|
||||||
&components.iter().map(|x| x.as_ref()).collect::<Vec<_>>(),
|
&components.iter().map(|x| x.as_ref()).collect::<Vec<_>>(),
|
||||||
&feed_filename,
|
feed_filename,
|
||||||
feed,
|
feed,
|
||||||
false,
|
false,
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
self.write_content(&[], &feed_filename, feed, false)?;
|
self.write_content(&[], feed_filename, feed, false)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -987,7 +986,7 @@ impl Site {
|
||||||
for asset in §ion.assets {
|
for asset in §ion.assets {
|
||||||
let asset_path = asset.as_path();
|
let asset_path = asset.as_path();
|
||||||
self.copy_asset(
|
self.copy_asset(
|
||||||
&asset_path,
|
asset_path,
|
||||||
&output_path.join(
|
&output_path.join(
|
||||||
asset_path.file_name().expect("Failed to get asset filename for section"),
|
asset_path.file_name().expect("Failed to get asset filename for section"),
|
||||||
),
|
),
|
||||||
|
@ -1021,7 +1020,7 @@ impl Site {
|
||||||
if section.meta.is_paginated() {
|
if section.meta.is_paginated() {
|
||||||
self.render_paginated(
|
self.render_paginated(
|
||||||
components,
|
components,
|
||||||
&Paginator::from_section(§ion, &self.library.read().unwrap()),
|
&Paginator::from_section(section, &self.library.read().unwrap()),
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
let output =
|
let output =
|
||||||
|
|
|
@ -58,12 +58,12 @@ pub fn check_internal_links_with_anchors(site: &Site) -> Result<()> {
|
||||||
let section = library
|
let section = library
|
||||||
.get_section(&full_path)
|
.get_section(&full_path)
|
||||||
.expect("Couldn't find section in check_internal_links_with_anchors");
|
.expect("Couldn't find section in check_internal_links_with_anchors");
|
||||||
!section.has_anchor(&anchor)
|
!section.has_anchor(anchor)
|
||||||
} else {
|
} else {
|
||||||
let page = library
|
let page = library
|
||||||
.get_page(&full_path)
|
.get_page(&full_path)
|
||||||
.expect("Couldn't find section in check_internal_links_with_anchors");
|
.expect("Couldn't find section in check_internal_links_with_anchors");
|
||||||
!page.has_anchor(&anchor)
|
!page.has_anchor(anchor)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ pub fn check_internal_links_with_anchors(site: &Site) -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_link_domain(link: &str) -> Result<String> {
|
fn get_link_domain(link: &str) -> Result<String> {
|
||||||
return match Url::parse(&link) {
|
return match Url::parse(link) {
|
||||||
Ok(url) => match url.host_str().map(String::from) {
|
Ok(url) => match url.host_str().map(String::from) {
|
||||||
Some(domain_str) => Ok(domain_str),
|
Some(domain_str) => Ok(domain_str),
|
||||||
None => bail!("could not parse domain `{}` from link", link),
|
None => bail!("could not parse domain `{}` from link", link),
|
||||||
|
@ -129,7 +129,7 @@ pub fn check_external_links(site: &Site) -> Result<()> {
|
||||||
let mut links_by_domain: HashMap<String, Vec<(PathBuf, String)>> = HashMap::new();
|
let mut links_by_domain: HashMap<String, Vec<(PathBuf, String)>> = HashMap::new();
|
||||||
|
|
||||||
for link in all_links.iter() {
|
for link in all_links.iter() {
|
||||||
links_by_domain.entry(link.2.to_string()).or_insert(Vec::new());
|
links_by_domain.entry(link.2.to_string()).or_default();
|
||||||
// Insert content path and link under the domain key
|
// Insert content path and link under the domain key
|
||||||
links_by_domain
|
links_by_domain
|
||||||
.get_mut(&link.2.to_string())
|
.get_mut(&link.2.to_string())
|
||||||
|
@ -156,7 +156,7 @@ pub fn check_external_links(site: &Site) -> Result<()> {
|
||||||
.map(|(_domain, links)| {
|
.map(|(_domain, links)| {
|
||||||
let mut links_to_process = links.len();
|
let mut links_to_process = links.len();
|
||||||
links
|
links
|
||||||
.into_iter()
|
.iter()
|
||||||
.filter_map(move |(page_path, link)| {
|
.filter_map(move |(page_path, link)| {
|
||||||
links_to_process -= 1;
|
links_to_process -= 1;
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ pub fn check_external_links(site: &Site) -> Result<()> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = link_checker::check_url(&link, &site.config.link_checker);
|
let res = link_checker::check_url(link, &site.config.link_checker);
|
||||||
|
|
||||||
if links_to_process > 0 {
|
if links_to_process > 0 {
|
||||||
// Prevent rate-limiting, wait before next crawl unless we're done with this domain
|
// Prevent rate-limiting, wait before next crawl unless we're done with this domain
|
||||||
|
|
|
@ -8,7 +8,7 @@ use errors::{bail, Result};
|
||||||
use utils::fs::{create_file, ensure_directory_exists};
|
use utils::fs::{create_file, ensure_directory_exists};
|
||||||
|
|
||||||
pub fn compile_sass(base_path: &Path, output_path: &Path) -> Result<()> {
|
pub fn compile_sass(base_path: &Path, output_path: &Path) -> Result<()> {
|
||||||
ensure_directory_exists(&output_path)?;
|
ensure_directory_exists(output_path)?;
|
||||||
|
|
||||||
let sass_path = {
|
let sass_path = {
|
||||||
let mut sass_path = PathBuf::from(base_path);
|
let mut sass_path = PathBuf::from(base_path);
|
||||||
|
@ -16,8 +16,7 @@ pub fn compile_sass(base_path: &Path, output_path: &Path) -> Result<()> {
|
||||||
sass_path
|
sass_path
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut options = Options::default();
|
let mut options = Options { output_style: OutputStyle::Compressed, ..Default::default() };
|
||||||
options.output_style = OutputStyle::Compressed;
|
|
||||||
let mut compiled_paths = compile_sass_glob(&sass_path, output_path, "scss", &options)?;
|
let mut compiled_paths = compile_sass_glob(&sass_path, output_path, "scss", &options)?;
|
||||||
|
|
||||||
options.indented_syntax = true;
|
options.indented_syntax = true;
|
||||||
|
@ -91,7 +90,7 @@ fn test_get_non_partial_scss() {
|
||||||
|
|
||||||
let result = get_non_partial_scss(&path, "scss");
|
let result = get_non_partial_scss(&path, "scss");
|
||||||
|
|
||||||
assert!(result.len() != 0);
|
assert!(!result.is_empty());
|
||||||
assert!(result.iter().filter_map(|path| path.file_name()).any(|file| file == "scss.scss"))
|
assert!(result.iter().filter_map(|path| path.file_name()).any(|file| file == "scss.scss"))
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -106,6 +105,6 @@ fn test_get_non_partial_scss_underscores() {
|
||||||
|
|
||||||
let result = get_non_partial_scss(&path, "scss");
|
let result = get_non_partial_scss(&path, "scss");
|
||||||
|
|
||||||
assert!(result.len() != 0);
|
assert!(!result.is_empty());
|
||||||
assert!(result.iter().filter_map(|path| path.file_name()).any(|file| file == "scss.scss"))
|
assert!(result.iter().filter_map(|path| path.file_name()).any(|file| file == "scss.scss"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,8 +99,7 @@ pub fn find_entries<'a>(
|
||||||
let mut taxonomies_entries = vec![];
|
let mut taxonomies_entries = vec![];
|
||||||
for taxonomy in taxonomies {
|
for taxonomy in taxonomies {
|
||||||
let name = &taxonomy.kind.name;
|
let name = &taxonomy.kind.name;
|
||||||
let mut terms = vec![];
|
let mut terms = vec![SitemapEntry::new(Cow::Owned(config.make_permalink(name)), None)];
|
||||||
terms.push(SitemapEntry::new(Cow::Owned(config.make_permalink(name)), None));
|
|
||||||
for item in &taxonomy.items {
|
for item in &taxonomy.items {
|
||||||
terms.push(SitemapEntry::new(
|
terms.push(SitemapEntry::new(
|
||||||
Cow::Owned(config.make_permalink(&format!("{}/{}", name, item.slug))),
|
Cow::Owned(config.make_permalink(&format!("{}/{}", name, item.slug))),
|
||||||
|
|
|
@ -5,6 +5,7 @@ use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use path_slash::PathExt;
|
use path_slash::PathExt;
|
||||||
use site::Site;
|
use site::Site;
|
||||||
|
use std::ffi::OsStr;
|
||||||
use tempfile::{tempdir, TempDir};
|
use tempfile::{tempdir, TempDir};
|
||||||
|
|
||||||
// 2 helper macros to make all the build testing more bearable
|
// 2 helper macros to make all the build testing more bearable
|
||||||
|
@ -12,7 +13,7 @@ use tempfile::{tempdir, TempDir};
|
||||||
macro_rules! file_exists {
|
macro_rules! file_exists {
|
||||||
($root: expr, $path: expr) => {{
|
($root: expr, $path: expr) => {{
|
||||||
let mut path = $root.clone();
|
let mut path = $root.clone();
|
||||||
for component in $path.split("/") {
|
for component in $path.split('/') {
|
||||||
path = path.join(component);
|
path = path.join(component);
|
||||||
}
|
}
|
||||||
std::path::Path::new(&path).exists()
|
std::path::Path::new(&path).exists()
|
||||||
|
@ -24,7 +25,7 @@ macro_rules! file_contains {
|
||||||
($root: expr, $path: expr, $text: expr) => {{
|
($root: expr, $path: expr, $text: expr) => {{
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
let mut path = $root.clone();
|
let mut path = $root.clone();
|
||||||
for component in $path.split("/") {
|
for component in $path.split('/') {
|
||||||
path = path.join(component);
|
path = path.join(component);
|
||||||
}
|
}
|
||||||
let mut file = std::fs::File::open(&path).expect(&format!("Failed to open {:?}", $path));
|
let mut file = std::fs::File::open(&path).expect(&format!("Failed to open {:?}", $path));
|
||||||
|
@ -75,16 +76,13 @@ where
|
||||||
/// When the path is not a markdown file (.md), None is returned
|
/// When the path is not a markdown file (.md), None is returned
|
||||||
/// Strips base_dir from the start of path
|
/// Strips base_dir from the start of path
|
||||||
fn find_lang_for(entry: &Path, base_dir: &Path) -> Option<(String, Option<String>)> {
|
fn find_lang_for(entry: &Path, base_dir: &Path) -> Option<(String, Option<String>)> {
|
||||||
let ext = entry.extension();
|
// continue if we have md file,
|
||||||
if ext.is_none() {
|
// skip otherwise
|
||||||
// Not a markdown file (no extension), skip
|
match entry.extension().and_then(OsStr::to_str) {
|
||||||
return None;
|
Some("md") => (),
|
||||||
}
|
_ => return None,
|
||||||
let ext = ext.unwrap();
|
};
|
||||||
if ext != "md" {
|
|
||||||
// Not a markdown file, skip
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let mut no_ext = entry.to_path_buf();
|
let mut no_ext = entry.to_path_buf();
|
||||||
let stem = entry.file_stem().unwrap();
|
let stem = entry.file_stem().unwrap();
|
||||||
// Remove .md
|
// Remove .md
|
||||||
|
@ -101,7 +99,7 @@ fn find_lang_for(entry: &Path, base_dir: &Path) -> Option<(String, Option<String
|
||||||
Ok(path_without_prefix) => path_without_prefix.to_slash_lossy(),
|
Ok(path_without_prefix) => path_without_prefix.to_slash_lossy(),
|
||||||
_ => unified_path.to_slash_lossy(),
|
_ => unified_path.to_slash_lossy(),
|
||||||
};
|
};
|
||||||
return Some((unified_path_str, Some(lang.to_str().unwrap().into())));
|
Some((unified_path_str, Some(lang.to_str().unwrap().into())))
|
||||||
} else {
|
} else {
|
||||||
// No lang, return no_ext directly
|
// No lang, return no_ext directly
|
||||||
let mut no_ext_string = match no_ext.strip_prefix(base_dir) {
|
let mut no_ext_string = match no_ext.strip_prefix(base_dir) {
|
||||||
|
@ -109,7 +107,7 @@ fn find_lang_for(entry: &Path, base_dir: &Path) -> Option<(String, Option<String
|
||||||
_ => no_ext.to_slash_lossy(),
|
_ => no_ext.to_slash_lossy(),
|
||||||
};
|
};
|
||||||
no_ext_string.push_str(".md");
|
no_ext_string.push_str(".md");
|
||||||
return Some((no_ext_string, None));
|
Some((no_ext_string, None))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,17 +131,17 @@ pub fn add_translations_from(
|
||||||
if let Some((unified_path, lang)) = find_lang_for(&entry, strip) {
|
if let Some((unified_path, lang)) = find_lang_for(&entry, strip) {
|
||||||
if let Some(index) = expected.get_mut(&unified_path) {
|
if let Some(index) = expected.get_mut(&unified_path) {
|
||||||
// Insert found lang for rel_path, or DEFAULT otherwise
|
// Insert found lang for rel_path, or DEFAULT otherwise
|
||||||
index.push(lang.unwrap_or(default.to_string()));
|
index.push(lang.unwrap_or_else(|| default.to_string()));
|
||||||
} else {
|
} else {
|
||||||
// rel_path is not registered yet, insert it in expected
|
// rel_path is not registered yet, insert it in expected
|
||||||
expected.insert(unified_path, vec![lang.unwrap_or(default.to_string())]);
|
expected.insert(unified_path, vec![lang.unwrap_or_else(|| default.to_string())]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Not a markdown file, skip
|
// Not a markdown file, skip
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return expected;
|
expected
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate output path for Markdown files
|
/// Calculate output path for Markdown files
|
||||||
|
@ -302,7 +300,7 @@ pub fn ensure_translations_match(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Everything went well
|
// Everything went well
|
||||||
return true;
|
true
|
||||||
} else {
|
} else {
|
||||||
// Should never happen because even the default language counts as a translation
|
// Should never happen because even the default language counts as a translation
|
||||||
// Reaching here means either there is a logic error in the tests themselves,
|
// Reaching here means either there is a logic error in the tests themselves,
|
||||||
|
@ -329,7 +327,7 @@ pub fn ensure_translations_in_output(site: &Site, path: &str, permalink: &str) -
|
||||||
let output_path = site.output_path.join(output_path);
|
let output_path = site.output_path.join(output_path);
|
||||||
|
|
||||||
let output = std::fs::read_to_string(&output_path)
|
let output = std::fs::read_to_string(&output_path)
|
||||||
.expect(&format!("Output not found in {}", output_path.display()));
|
.unwrap_or_else(|_| panic!("Output not found in {}", output_path.display()));
|
||||||
|
|
||||||
for permalink in &translations_permalinks {
|
for permalink in &translations_permalinks {
|
||||||
if !output.contains(permalink) {
|
if !output.contains(permalink) {
|
||||||
|
@ -338,5 +336,5 @@ pub fn ensure_translations_in_output(site: &Site, path: &str, permalink: &str) -
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
true
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,15 +151,15 @@ fn can_build_site_without_live_reload() {
|
||||||
assert!(file_contains!(public, "posts/tutorials/devops/index.html", "docker"));
|
assert!(file_contains!(public, "posts/tutorials/devops/index.html", "docker"));
|
||||||
|
|
||||||
// We do have categories
|
// We do have categories
|
||||||
assert_eq!(file_exists!(public, "categories/index.html"), true);
|
assert!(file_exists!(public, "categories/index.html"));
|
||||||
assert_eq!(file_exists!(public, "categories/a-category/index.html"), true);
|
assert!(file_exists!(public, "categories/a-category/index.html"));
|
||||||
assert_eq!(file_exists!(public, "categories/a-category/atom.xml"), true);
|
assert!(file_exists!(public, "categories/a-category/atom.xml"));
|
||||||
// and podcast_authors (https://github.com/getzola/zola/issues/1177)
|
// and podcast_authors (https://github.com/getzola/zola/issues/1177)
|
||||||
assert_eq!(file_exists!(public, "podcast-authors/index.html"), true);
|
assert!(file_exists!(public, "podcast-authors/index.html"));
|
||||||
assert_eq!(file_exists!(public, "podcast-authors/some-person/index.html"), true);
|
assert!(file_exists!(public, "podcast-authors/some-person/index.html"));
|
||||||
assert_eq!(file_exists!(public, "podcast-authors/some-person/atom.xml"), true);
|
assert!(file_exists!(public, "podcast-authors/some-person/atom.xml"));
|
||||||
// But no tags
|
// But no tags
|
||||||
assert_eq!(file_exists!(public, "tags/index.html"), false);
|
assert!(!file_exists!(public, "tags/index.html"));
|
||||||
|
|
||||||
// Theme files are there
|
// Theme files are there
|
||||||
assert!(file_exists!(public, "sample.css"));
|
assert!(file_exists!(public, "sample.css"));
|
||||||
|
@ -181,10 +181,7 @@ fn can_build_site_without_live_reload() {
|
||||||
assert!(!file_exists!(public, "secret_section/page.html"));
|
assert!(!file_exists!(public, "secret_section/page.html"));
|
||||||
assert!(!file_exists!(public, "secret_section/secret_sub_section/hello.html"));
|
assert!(!file_exists!(public, "secret_section/secret_sub_section/hello.html"));
|
||||||
// no live reload code
|
// no live reload code
|
||||||
assert_eq!(
|
assert!(!file_contains!(public, "index.html", "/livereload.js?port=1112&mindelay=10"),);
|
||||||
file_contains!(public, "index.html", "/livereload.js?port=1112&mindelay=10"),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
// Both pages and sections are in the sitemap
|
// Both pages and sections are in the sitemap
|
||||||
assert!(file_contains!(
|
assert!(file_contains!(
|
||||||
|
@ -238,11 +235,11 @@ fn can_build_site_with_live_reload_and_drafts() {
|
||||||
// TODO: add assertion for syntax highlighting
|
// TODO: add assertion for syntax highlighting
|
||||||
|
|
||||||
// We do have categories
|
// We do have categories
|
||||||
assert_eq!(file_exists!(public, "categories/index.html"), true);
|
assert!(file_exists!(public, "categories/index.html"));
|
||||||
assert_eq!(file_exists!(public, "categories/a-category/index.html"), true);
|
assert!(file_exists!(public, "categories/a-category/index.html"));
|
||||||
assert_eq!(file_exists!(public, "categories/a-category/atom.xml"), true);
|
assert!(file_exists!(public, "categories/a-category/atom.xml"));
|
||||||
// But no tags
|
// But no tags
|
||||||
assert_eq!(file_exists!(public, "tags/index.html"), false);
|
assert!(!file_exists!(public, "tags/index.html"));
|
||||||
|
|
||||||
// no live reload code
|
// no live reload code
|
||||||
assert!(file_contains!(public, "index.html", "/livereload.js"));
|
assert!(file_contains!(public, "index.html", "/livereload.js"));
|
||||||
|
@ -320,7 +317,7 @@ fn can_build_site_with_taxonomies() {
|
||||||
// Extending from a theme works
|
// Extending from a theme works
|
||||||
assert!(file_contains!(public, "categories/a/index.html", "EXTENDED"));
|
assert!(file_contains!(public, "categories/a/index.html", "EXTENDED"));
|
||||||
// Tags aren't
|
// Tags aren't
|
||||||
assert_eq!(file_exists!(public, "tags/index.html"), false);
|
assert!(!file_exists!(public, "tags/index.html"));
|
||||||
|
|
||||||
// Categories are in the sitemap
|
// Categories are in the sitemap
|
||||||
assert!(file_contains!(
|
assert!(file_contains!(
|
||||||
|
@ -403,7 +400,7 @@ fn can_build_site_with_pagination_for_section() {
|
||||||
"posts/index.html",
|
"posts/index.html",
|
||||||
"Last: https://replace-this-with-your-url.com/posts/page/5/"
|
"Last: https://replace-this-with-your-url.com/posts/page/5/"
|
||||||
));
|
));
|
||||||
assert_eq!(file_contains!(public, "posts/index.html", "has_prev"), false);
|
assert!(!file_contains!(public, "posts/index.html", "has_prev"));
|
||||||
|
|
||||||
assert!(file_exists!(public, "posts/page/2/index.html"));
|
assert!(file_exists!(public, "posts/page/2/index.html"));
|
||||||
assert!(file_contains!(public, "posts/page/2/index.html", "Num pagers: 5"));
|
assert!(file_contains!(public, "posts/page/2/index.html", "Num pagers: 5"));
|
||||||
|
@ -526,8 +523,8 @@ fn can_build_site_with_pagination_for_index() {
|
||||||
"index.html",
|
"index.html",
|
||||||
"Last: https://replace-this-with-your-url.com/page/2/"
|
"Last: https://replace-this-with-your-url.com/page/2/"
|
||||||
));
|
));
|
||||||
assert_eq!(file_contains!(public, "index.html", "has_prev"), false);
|
assert!(!file_contains!(public, "index.html", "has_prev"));
|
||||||
assert_eq!(file_contains!(public, "index.html", "has_next"), true);
|
assert!(file_contains!(public, "index.html", "has_next"));
|
||||||
|
|
||||||
// sitemap contains the pager pages
|
// sitemap contains the pager pages
|
||||||
assert!(file_contains!(
|
assert!(file_contains!(
|
||||||
|
@ -612,7 +609,7 @@ fn can_build_site_with_pagination_for_taxonomy() {
|
||||||
"tags/a/index.html",
|
"tags/a/index.html",
|
||||||
"Last: https://replace-this-with-your-url.com/tags/a/page/8/"
|
"Last: https://replace-this-with-your-url.com/tags/a/page/8/"
|
||||||
));
|
));
|
||||||
assert_eq!(file_contains!(public, "tags/a/index.html", "has_prev"), false);
|
assert!(!file_contains!(public, "tags/a/index.html", "has_prev"));
|
||||||
|
|
||||||
// sitemap contains the pager pages
|
// sitemap contains the pager pages
|
||||||
assert!(file_contains!(
|
assert!(file_contains!(
|
||||||
|
|
|
@ -192,9 +192,9 @@ fn correct_translations_on_all_pages() {
|
||||||
|
|
||||||
// Ensure translations expected here match with those in the library
|
// Ensure translations expected here match with those in the library
|
||||||
// TODO: add constructive error message inside the function
|
// TODO: add constructive error message inside the function
|
||||||
assert!(ensure_translations_match(&translations, &site, &path));
|
assert!(ensure_translations_match(&translations, &site, path));
|
||||||
|
|
||||||
// Ensure output file contains all translations URLs
|
// Ensure output file contains all translations URLs
|
||||||
assert!(ensure_translations_in_output(&site, &path, &link));
|
assert!(ensure_translations_in_output(&site, path, &link));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,8 +214,7 @@ mod tests {
|
||||||
};
|
};
|
||||||
|
|
||||||
let taxonomies = vec![tags.clone(), tags_fr.clone()];
|
let taxonomies = vec![tags.clone(), tags_fr.clone()];
|
||||||
let static_fn =
|
let static_fn = GetTaxonomy::new(&config.default_language, taxonomies, library);
|
||||||
GetTaxonomy::new(&config.default_language, taxonomies.clone(), library.clone());
|
|
||||||
// can find it correctly
|
// can find it correctly
|
||||||
let mut args = HashMap::new();
|
let mut args = HashMap::new();
|
||||||
args.insert("kind".to_string(), to_value("tags").unwrap());
|
args.insert("kind".to_string(), to_value("tags").unwrap());
|
||||||
|
@ -291,7 +290,7 @@ mod tests {
|
||||||
items: vec![tag_fr],
|
items: vec![tag_fr],
|
||||||
};
|
};
|
||||||
|
|
||||||
let taxonomies = vec![tags.clone(), tags_fr.clone()];
|
let taxonomies = vec![tags, tags_fr];
|
||||||
let static_fn =
|
let static_fn =
|
||||||
GetTaxonomyUrl::new(&config.default_language, &taxonomies, config.slugify.taxonomies);
|
GetTaxonomyUrl::new(&config.default_language, &taxonomies, config.slugify.taxonomies);
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ impl DataSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(path) = path_arg {
|
if let Some(path) = path_arg {
|
||||||
return match search_for_file(&base_path, &path, &theme)
|
return match search_for_file(base_path, &path, theme)
|
||||||
.map_err(|e| format!("`load_data`: {}", e))?
|
.map_err(|e| format!("`load_data`: {}", e))?
|
||||||
{
|
{
|
||||||
Some((f, _)) => Ok(Some(DataSource::Path(f))),
|
Some((f, _)) => Ok(Some(DataSource::Path(f))),
|
||||||
|
@ -136,7 +136,7 @@ impl Hash for DataSource {
|
||||||
DataSource::Url(url) => url.hash(state),
|
DataSource::Url(url) => url.hash(state),
|
||||||
DataSource::Path(path) => {
|
DataSource::Path(path) => {
|
||||||
path.hash(state);
|
path.hash(state);
|
||||||
get_file_time(&path).expect("get file time").hash(state);
|
get_file_time(path).expect("get file time").hash(state);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ impl TeraFn for LoadData {
|
||||||
);
|
);
|
||||||
|
|
||||||
let method = match method_arg {
|
let method = match method_arg {
|
||||||
Some(ref method_str) => match Method::from_str(&method_str) {
|
Some(ref method_str) => match Method::from_str(method_str) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
},
|
},
|
||||||
|
@ -473,12 +473,12 @@ mod tests {
|
||||||
|
|
||||||
fn get_test_file(filename: &str) -> PathBuf {
|
fn get_test_file(filename: &str) -> PathBuf {
|
||||||
let test_files = PathBuf::from("../utils/test-files").canonicalize().unwrap();
|
let test_files = PathBuf::from("../utils/test-files").canonicalize().unwrap();
|
||||||
return test_files.join(filename);
|
test_files.join(filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fails_illegal_method_parameter() {
|
fn fails_illegal_method_parameter() {
|
||||||
let static_fn = LoadData::new(PathBuf::from(PathBuf::from("../utils")), None);
|
let static_fn = LoadData::new(PathBuf::from("../utils"), None);
|
||||||
let mut args = HashMap::new();
|
let mut args = HashMap::new();
|
||||||
args.insert("url".to_string(), to_value("https://example.com").unwrap());
|
args.insert("url".to_string(), to_value("https://example.com").unwrap());
|
||||||
args.insert("format".to_string(), to_value("plain").unwrap());
|
args.insert("format".to_string(), to_value("plain").unwrap());
|
||||||
|
@ -505,7 +505,7 @@ mod tests {
|
||||||
|
|
||||||
let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y");
|
let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y");
|
||||||
|
|
||||||
let static_fn = LoadData::new(PathBuf::from(PathBuf::from("../utils")), None);
|
let static_fn = LoadData::new(PathBuf::from("../utils"), None);
|
||||||
let mut args = HashMap::new();
|
let mut args = HashMap::new();
|
||||||
args.insert("url".to_string(), to_value(url).unwrap());
|
args.insert("url".to_string(), to_value(url).unwrap());
|
||||||
args.insert("format".to_string(), to_value("plain").unwrap());
|
args.insert("format".to_string(), to_value("plain").unwrap());
|
||||||
|
@ -533,7 +533,7 @@ mod tests {
|
||||||
|
|
||||||
let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4yw");
|
let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4yw");
|
||||||
|
|
||||||
let static_fn = LoadData::new(PathBuf::from(PathBuf::from("../utils")), None);
|
let static_fn = LoadData::new(PathBuf::from("../utils"), None);
|
||||||
let mut args = HashMap::new();
|
let mut args = HashMap::new();
|
||||||
args.insert("url".to_string(), to_value(url).unwrap());
|
args.insert("url".to_string(), to_value(url).unwrap());
|
||||||
args.insert("format".to_string(), to_value("plain").unwrap());
|
args.insert("format".to_string(), to_value("plain").unwrap());
|
||||||
|
@ -562,7 +562,7 @@ mod tests {
|
||||||
|
|
||||||
let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y");
|
let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y");
|
||||||
|
|
||||||
let static_fn = LoadData::new(PathBuf::from(PathBuf::from("../utils")), None);
|
let static_fn = LoadData::new(PathBuf::from("../utils"), None);
|
||||||
let mut args = HashMap::new();
|
let mut args = HashMap::new();
|
||||||
args.insert("url".to_string(), to_value(url).unwrap());
|
args.insert("url".to_string(), to_value(url).unwrap());
|
||||||
args.insert("format".to_string(), to_value("plain").unwrap());
|
args.insert("format".to_string(), to_value("plain").unwrap());
|
||||||
|
@ -634,7 +634,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cannot_load_outside_base_dir() {
|
fn cannot_load_outside_base_dir() {
|
||||||
let static_fn = LoadData::new(PathBuf::from(PathBuf::from("../utils")), None);
|
let static_fn = LoadData::new(PathBuf::from("../utils"), None);
|
||||||
let mut args = HashMap::new();
|
let mut args = HashMap::new();
|
||||||
args.insert("path".to_string(), to_value("../../README.md").unwrap());
|
args.insert("path".to_string(), to_value("../../README.md").unwrap());
|
||||||
args.insert("format".to_string(), to_value("plain").unwrap());
|
args.insert("format".to_string(), to_value("plain").unwrap());
|
||||||
|
@ -884,7 +884,7 @@ mod tests {
|
||||||
let error_kind = result.err().unwrap().kind;
|
let error_kind = result.err().unwrap().kind;
|
||||||
match error_kind {
|
match error_kind {
|
||||||
tera::ErrorKind::Msg(msg) => {
|
tera::ErrorKind::Msg(msg) => {
|
||||||
if msg != String::from("Error encountered when parsing csv records") {
|
if msg != *"Error encountered when parsing csv records" {
|
||||||
panic!("Error message is wrong. Perhaps wrong error is being returned?");
|
panic!("Error message is wrong. Perhaps wrong error is being returned?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -905,7 +905,7 @@ mod tests {
|
||||||
let error_kind = result.err().unwrap().kind;
|
let error_kind = result.err().unwrap().kind;
|
||||||
match error_kind {
|
match error_kind {
|
||||||
tera::ErrorKind::Msg(msg) => {
|
tera::ErrorKind::Msg(msg) => {
|
||||||
if msg != String::from("Error encountered when parsing csv records") {
|
if msg != *"Error encountered when parsing csv records" {
|
||||||
panic!("Error message is wrong. Perhaps wrong error is being returned?");
|
panic!("Error message is wrong. Perhaps wrong error is being returned?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -941,7 +941,7 @@ mod tests {
|
||||||
.create();
|
.create();
|
||||||
let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y3");
|
let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y3");
|
||||||
|
|
||||||
let static_fn = LoadData::new(PathBuf::from(PathBuf::from("../utils")), None);
|
let static_fn = LoadData::new(PathBuf::from("../utils"), None);
|
||||||
let mut args = HashMap::new();
|
let mut args = HashMap::new();
|
||||||
args.insert("url".to_string(), to_value(&url).unwrap());
|
args.insert("url".to_string(), to_value(&url).unwrap());
|
||||||
args.insert("format".to_string(), to_value("plain").unwrap());
|
args.insert("format".to_string(), to_value("plain").unwrap());
|
||||||
|
@ -973,7 +973,7 @@ mod tests {
|
||||||
.create();
|
.create();
|
||||||
let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y2");
|
let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y2");
|
||||||
|
|
||||||
let static_fn = LoadData::new(PathBuf::from(PathBuf::from("../utils")), None);
|
let static_fn = LoadData::new(PathBuf::from("../utils"), None);
|
||||||
let mut args = HashMap::new();
|
let mut args = HashMap::new();
|
||||||
args.insert("url".to_string(), to_value(&url).unwrap());
|
args.insert("url".to_string(), to_value(&url).unwrap());
|
||||||
args.insert("format".to_string(), to_value("plain").unwrap());
|
args.insert("format".to_string(), to_value("plain").unwrap());
|
||||||
|
|
|
@ -79,7 +79,7 @@ pub fn load_tera(path: &Path, config: &Config) -> Result<Tera> {
|
||||||
);
|
);
|
||||||
let mut tera_theme = Tera::parse(&theme_tpl_glob)
|
let mut tera_theme = Tera::parse(&theme_tpl_glob)
|
||||||
.map_err(|e| Error::chain("Error parsing templates from themes", e))?;
|
.map_err(|e| Error::chain("Error parsing templates from themes", e))?;
|
||||||
rewrite_theme_paths(&mut tera_theme, &theme);
|
rewrite_theme_paths(&mut tera_theme, theme);
|
||||||
|
|
||||||
if theme_path.join("templates").join("robots.txt").exists() {
|
if theme_path.join("templates").join("robots.txt").exists() {
|
||||||
tera_theme.add_template_file(theme_path.join("templates").join("robots.txt"), None)?;
|
tera_theme.add_template_file(theme_path.join("templates").join("robots.txt"), None)?;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use filetime::{set_file_mtime, FileTime};
|
use filetime::{set_file_mtime, FileTime};
|
||||||
use std::fs::{copy, create_dir_all, metadata, File};
|
use std::fs::{copy, create_dir_all, metadata, File};
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ pub fn read_file(path: &Path) -> Result<String> {
|
||||||
.read_to_string(&mut content)?;
|
.read_to_string(&mut content)?;
|
||||||
|
|
||||||
// Remove utf-8 BOM if any.
|
// Remove utf-8 BOM if any.
|
||||||
if content.starts_with("\u{feff}") {
|
if content.starts_with('\u{feff}') {
|
||||||
content.drain(..3);
|
content.drain(..3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ pub fn read_file(path: &Path) -> Result<String> {
|
||||||
|
|
||||||
/// Copy a file but takes into account where to start the copy as
|
/// Copy a file but takes into account where to start the copy as
|
||||||
/// there might be folders we need to create on the way.
|
/// there might be folders we need to create on the way.
|
||||||
pub fn copy_file(src: &Path, dest: &PathBuf, base_path: &PathBuf, hard_link: bool) -> Result<()> {
|
pub fn copy_file(src: &Path, dest: &Path, base_path: &Path, hard_link: bool) -> Result<()> {
|
||||||
let relative_path = src.strip_prefix(base_path).unwrap();
|
let relative_path = src.strip_prefix(base_path).unwrap();
|
||||||
let target_path = dest.join(relative_path);
|
let target_path = dest.join(relative_path);
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ pub fn copy_file(src: &Path, dest: &PathBuf, base_path: &PathBuf, hard_link: boo
|
||||||
/// 1. A file with the same name already exists in the dest path.
|
/// 1. A file with the same name already exists in the dest path.
|
||||||
/// 2. Its modification timestamp is identical to that of the src file.
|
/// 2. Its modification timestamp is identical to that of the src file.
|
||||||
/// 3. Its filesize is identical to that of the src file.
|
/// 3. Its filesize is identical to that of the src file.
|
||||||
pub fn copy_file_if_needed(src: &Path, dest: &PathBuf, hard_link: bool) -> Result<()> {
|
pub fn copy_file_if_needed(src: &Path, dest: &Path, hard_link: bool) -> Result<()> {
|
||||||
if let Some(parent_directory) = dest.parent() {
|
if let Some(parent_directory) = dest.parent() {
|
||||||
create_dir_all(parent_directory).map_err(|e| {
|
create_dir_all(parent_directory).map_err(|e| {
|
||||||
Error::chain(format!("Was not able to create folder {}", parent_directory.display()), e)
|
Error::chain(format!("Was not able to create folder {}", parent_directory.display()), e)
|
||||||
|
@ -120,7 +120,7 @@ pub fn copy_file_if_needed(src: &Path, dest: &PathBuf, hard_link: bool) -> Resul
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_directory(src: &PathBuf, dest: &PathBuf, hard_link: bool) -> Result<()> {
|
pub fn copy_directory(src: &Path, dest: &Path, hard_link: bool) -> Result<()> {
|
||||||
for entry in WalkDir::new(src).into_iter().filter_map(std::result::Result::ok) {
|
for entry in WalkDir::new(src).into_iter().filter_map(std::result::Result::ok) {
|
||||||
let relative_path = entry.path().strip_prefix(src).unwrap();
|
let relative_path = entry.path().strip_prefix(src).unwrap();
|
||||||
let target_path = dest.join(relative_path);
|
let target_path = dest.join(relative_path);
|
||||||
|
|
|
@ -27,7 +27,7 @@ fn strip_invalid_paths_chars(s: &str) -> String {
|
||||||
// NTFS forbidden characters : https://gist.github.com/doctaphred/d01d05291546186941e1b7ddc02034d3
|
// NTFS forbidden characters : https://gist.github.com/doctaphred/d01d05291546186941e1b7ddc02034d3
|
||||||
// Also we need to trim whitespaces and `.` from the end of filename
|
// Also we need to trim whitespaces and `.` from the end of filename
|
||||||
let trimmed = s.trim_end_matches(|c| c == ' ' || c == '.');
|
let trimmed = s.trim_end_matches(|c| c == ' ' || c == '.');
|
||||||
strip_chars(&trimmed, r#"<>:"/\|?*"#)
|
strip_chars(trimmed, r#"<>:"/\|?*"#)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slugify_paths(s: &str, strategy: SlugifyStrategy) -> String {
|
pub fn slugify_paths(s: &str, strategy: SlugifyStrategy) -> String {
|
||||||
|
|
|
@ -76,7 +76,7 @@ pub fn create_new_project(name: &str, force: bool) -> Result<()> {
|
||||||
let path = Path::new(name);
|
let path = Path::new(name);
|
||||||
|
|
||||||
// Better error message than the rust default
|
// Better error message than the rust default
|
||||||
if path.exists() && !is_directory_quasi_empty(&path)? && !force {
|
if path.exists() && !is_directory_quasi_empty(path)? && !force {
|
||||||
if name == "." {
|
if name == "." {
|
||||||
bail!("The current directory is not an empty folder (hidden files are ignored).");
|
bail!("The current directory is not an empty folder (hidden files are ignored).");
|
||||||
} else {
|
} else {
|
||||||
|
@ -103,7 +103,7 @@ pub fn create_new_project(name: &str, force: bool) -> Result<()> {
|
||||||
.replace("%SEARCH%", &format!("{}", search))
|
.replace("%SEARCH%", &format!("{}", search))
|
||||||
.replace("%HIGHLIGHT%", &format!("{}", highlight));
|
.replace("%HIGHLIGHT%", &format!("{}", highlight));
|
||||||
|
|
||||||
populate(&path, compile_sass, &config)?;
|
populate(path, compile_sass, &config)?;
|
||||||
|
|
||||||
println!();
|
println!();
|
||||||
console::success(&format!(
|
console::success(&format!(
|
||||||
|
@ -122,7 +122,7 @@ fn populate(path: &Path, compile_sass: bool, config: &str) -> Result<()> {
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
create_dir(path)?;
|
create_dir(path)?;
|
||||||
}
|
}
|
||||||
create_file(&path.join("config.toml"), &config)?;
|
create_file(&path.join("config.toml"), config)?;
|
||||||
create_dir(path.join("content"))?;
|
create_dir(path.join("content"))?;
|
||||||
create_dir(path.join("templates"))?;
|
create_dir(path.join("templates"))?;
|
||||||
create_dir(path.join("static"))?;
|
create_dir(path.join("static"))?;
|
||||||
|
@ -152,7 +152,7 @@ mod tests {
|
||||||
let allowed = is_directory_quasi_empty(&dir)
|
let allowed = is_directory_quasi_empty(&dir)
|
||||||
.expect("An error happened reading the directory's contents");
|
.expect("An error happened reading the directory's contents");
|
||||||
remove_dir(&dir).unwrap();
|
remove_dir(&dir).unwrap();
|
||||||
assert_eq!(true, allowed);
|
assert!(allowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -170,7 +170,7 @@ mod tests {
|
||||||
.expect("An error happened reading the directory's contents");
|
.expect("An error happened reading the directory's contents");
|
||||||
remove_dir(&content).unwrap();
|
remove_dir(&content).unwrap();
|
||||||
remove_dir(&dir).unwrap();
|
remove_dir(&dir).unwrap();
|
||||||
assert_eq!(false, allowed);
|
assert!(!allowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -188,7 +188,7 @@ mod tests {
|
||||||
.expect("An error happened reading the directory's contents");
|
.expect("An error happened reading the directory's contents");
|
||||||
remove_dir(&git).unwrap();
|
remove_dir(&git).unwrap();
|
||||||
remove_dir(&dir).unwrap();
|
remove_dir(&dir).unwrap();
|
||||||
assert_eq!(true, allowed);
|
assert!(allowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -201,12 +201,12 @@ mod tests {
|
||||||
create_dir(&dir).expect("Could not create test directory");
|
create_dir(&dir).expect("Could not create test directory");
|
||||||
populate(&dir, true, "").expect("Could not populate zola directories");
|
populate(&dir, true, "").expect("Could not populate zola directories");
|
||||||
|
|
||||||
assert_eq!(true, dir.join("config.toml").exists());
|
assert!(dir.join("config.toml").exists());
|
||||||
assert_eq!(true, dir.join("content").exists());
|
assert!(dir.join("content").exists());
|
||||||
assert_eq!(true, dir.join("templates").exists());
|
assert!(dir.join("templates").exists());
|
||||||
assert_eq!(true, dir.join("static").exists());
|
assert!(dir.join("static").exists());
|
||||||
assert_eq!(true, dir.join("themes").exists());
|
assert!(dir.join("themes").exists());
|
||||||
assert_eq!(true, dir.join("sass").exists());
|
assert!(dir.join("sass").exists());
|
||||||
|
|
||||||
remove_dir_all(&dir).unwrap();
|
remove_dir_all(&dir).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -220,13 +220,13 @@ mod tests {
|
||||||
}
|
}
|
||||||
populate(&dir, true, "").expect("Could not populate zola directories");
|
populate(&dir, true, "").expect("Could not populate zola directories");
|
||||||
|
|
||||||
assert_eq!(true, dir.exists());
|
assert!(dir.exists());
|
||||||
assert_eq!(true, dir.join("config.toml").exists());
|
assert!(dir.join("config.toml").exists());
|
||||||
assert_eq!(true, dir.join("content").exists());
|
assert!(dir.join("content").exists());
|
||||||
assert_eq!(true, dir.join("templates").exists());
|
assert!(dir.join("templates").exists());
|
||||||
assert_eq!(true, dir.join("static").exists());
|
assert!(dir.join("static").exists());
|
||||||
assert_eq!(true, dir.join("themes").exists());
|
assert!(dir.join("themes").exists());
|
||||||
assert_eq!(true, dir.join("sass").exists());
|
assert!(dir.join("sass").exists());
|
||||||
|
|
||||||
remove_dir_all(&dir).unwrap();
|
remove_dir_all(&dir).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ mod tests {
|
||||||
create_dir(&dir).expect("Could not create test directory");
|
create_dir(&dir).expect("Could not create test directory");
|
||||||
populate(&dir, false, "").expect("Could not populate zola directories");
|
populate(&dir, false, "").expect("Could not populate zola directories");
|
||||||
|
|
||||||
assert_eq!(false, dir.join("sass").exists());
|
assert!(!dir.join("sass").exists());
|
||||||
|
|
||||||
remove_dir_all(&dir).unwrap();
|
remove_dir_all(&dir).unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,6 +222,7 @@ fn rebuild_done_handling(broadcaster: &Sender, res: Result<()>, reload_path: &st
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn create_new_site(
|
fn create_new_site(
|
||||||
root_dir: &Path,
|
root_dir: &Path,
|
||||||
interface: &str,
|
interface: &str,
|
||||||
|
@ -265,6 +266,7 @@ fn create_new_site(
|
||||||
Ok((site, address))
|
Ok((site, address))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn serve(
|
pub fn serve(
|
||||||
root_dir: &Path,
|
root_dir: &Path,
|
||||||
interface: &str,
|
interface: &str,
|
||||||
|
@ -463,12 +465,7 @@ pub fn serve(
|
||||||
} else {
|
} else {
|
||||||
rebuild_done_handling(
|
rebuild_done_handling(
|
||||||
&broadcaster,
|
&broadcaster,
|
||||||
copy_file(
|
copy_file(path, &site.output_path, &site.static_path, site.config.hard_link_static),
|
||||||
&path,
|
|
||||||
&site.output_path,
|
|
||||||
&site.static_path,
|
|
||||||
site.config.hard_link_static,
|
|
||||||
),
|
|
||||||
&partial_path.to_string_lossy(),
|
&partial_path.to_string_lossy(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -521,7 +518,7 @@ pub fn serve(
|
||||||
);
|
);
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
match detect_change_kind(&root_dir, &path, &config_path) {
|
match detect_change_kind(root_dir, &path, config_path) {
|
||||||
(ChangeKind::Content, _) => {
|
(ChangeKind::Content, _) => {
|
||||||
console::info(&format!("-> Content changed {}", path.display()));
|
console::info(&format!("-> Content changed {}", path.display()));
|
||||||
|
|
||||||
|
@ -676,9 +673,8 @@ fn detect_change_kind(pwd: &Path, path: &Path, config_filename: &str) -> (Change
|
||||||
/// Check if the directory at path contains any file
|
/// Check if the directory at path contains any file
|
||||||
fn is_folder_empty(dir: &Path) -> bool {
|
fn is_folder_empty(dir: &Path) -> bool {
|
||||||
// Can panic if we don't have the rights I guess?
|
// Can panic if we don't have the rights I guess?
|
||||||
let files: Vec<_> =
|
|
||||||
read_dir(dir).expect("Failed to read a directory to see if it was empty").collect();
|
read_dir(dir).expect("Failed to read a directory to see if it was empty").next().is_none()
|
||||||
files.is_empty()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -702,7 +698,7 @@ mod tests {
|
||||||
];
|
];
|
||||||
|
|
||||||
for t in test_cases {
|
for t in test_cases {
|
||||||
assert!(is_temp_file(&t));
|
assert!(is_temp_file(t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -754,7 +750,7 @@ mod tests {
|
||||||
];
|
];
|
||||||
|
|
||||||
for (expected, pwd, path, config_filename) in test_cases {
|
for (expected, pwd, path, config_filename) in test_cases {
|
||||||
assert_eq!(expected, detect_change_kind(&pwd, &path, &config_filename));
|
assert_eq!(expected, detect_change_kind(pwd, path, config_filename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue