Some more refactoring
This commit is contained in:
parent
6851ade642
commit
27a200bb4e
|
@ -9,7 +9,7 @@ use crate::sorting::sort_pages;
|
||||||
use crate::taxonomies::{find_taxonomies, Taxonomy};
|
use crate::taxonomies::{find_taxonomies, Taxonomy};
|
||||||
use crate::{Page, Section, SortBy};
|
use crate::{Page, Section, SortBy};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Library {
|
pub struct Library {
|
||||||
pub pages: AHashMap<PathBuf, Page>,
|
pub pages: AHashMap<PathBuf, Page>,
|
||||||
pub sections: AHashMap<PathBuf, Section>,
|
pub sections: AHashMap<PathBuf, Section>,
|
||||||
|
@ -21,13 +21,7 @@ pub struct Library {
|
||||||
|
|
||||||
impl Library {
|
impl Library {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self::default()
|
||||||
pages: AHashMap::new(),
|
|
||||||
sections: AHashMap::new(),
|
|
||||||
taxonomies: Vec::new(),
|
|
||||||
reverse_aliases: AHashMap::new(),
|
|
||||||
translations: AHashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_reverse_aliases(&mut self, file_path: &Path, entries: Vec<String>) {
|
fn insert_reverse_aliases(&mut self, file_path: &Path, entries: Vec<String>) {
|
||||||
|
|
|
@ -182,7 +182,7 @@ impl Section {
|
||||||
context.insert("config", &config.serialize(&self.lang));
|
context.insert("config", &config.serialize(&self.lang));
|
||||||
context.insert("current_url", &self.permalink);
|
context.insert("current_url", &self.permalink);
|
||||||
context.insert("current_path", &self.path);
|
context.insert("current_path", &self.path);
|
||||||
context.insert("section", &SerializingSection::new(&self, SectionSerMode::Full(library)));
|
context.insert("section", &SerializingSection::new(self, SectionSerMode::Full(library)));
|
||||||
context.insert("lang", &self.lang);
|
context.insert("lang", &self.lang);
|
||||||
|
|
||||||
render_template(tpl_name, tera, context, &config.theme)
|
render_template(tpl_name, tera, context, &config.theme)
|
||||||
|
|
|
@ -4,9 +4,9 @@ extern crate test;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use front_matter::InsertAnchor;
|
use utils::types::InsertAnchor;
|
||||||
use libs::tera::Tera;
|
use libs::tera::Tera;
|
||||||
use rendering::{render_content, RenderContext};
|
use markdown::{render_content, RenderContext};
|
||||||
|
|
||||||
static CONTENT: &str = r#"
|
static CONTENT: &str = r#"
|
||||||
# Modus cognitius profanam ne duae virtutis mundi
|
# Modus cognitius profanam ne duae virtutis mundi
|
||||||
|
@ -85,10 +85,10 @@ fn bench_render_content_with_highlighting(b: &mut test::Bencher) {
|
||||||
let mut tera = Tera::default();
|
let mut tera = Tera::default();
|
||||||
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 mut config = Config::default();
|
let mut config = Config::default_for_test();
|
||||||
config.markdown.highlight_code = true;
|
config.markdown.highlight_code = true;
|
||||||
let current_page_permalink = "";
|
let current_page_permalink = "";
|
||||||
let context = RenderContext::new(
|
let mut context = RenderContext::new(
|
||||||
&tera,
|
&tera,
|
||||||
&config,
|
&config,
|
||||||
&config.default_language,
|
&config.default_language,
|
||||||
|
@ -96,6 +96,8 @@ fn bench_render_content_with_highlighting(b: &mut test::Bencher) {
|
||||||
&permalinks_ctx,
|
&permalinks_ctx,
|
||||||
InsertAnchor::None,
|
InsertAnchor::None,
|
||||||
);
|
);
|
||||||
|
let shortcode_def = utils::templates::get_shortcodes(&tera);
|
||||||
|
context.set_shortcode_definitions(&shortcode_def);
|
||||||
b.iter(|| render_content(CONTENT, &context).unwrap());
|
b.iter(|| render_content(CONTENT, &context).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,10 +106,10 @@ fn bench_render_content_without_highlighting(b: &mut test::Bencher) {
|
||||||
let mut tera = Tera::default();
|
let mut tera = Tera::default();
|
||||||
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 mut config = Config::default();
|
let mut config = Config::default_for_test();
|
||||||
config.markdown.highlight_code = false;
|
config.markdown.highlight_code = false;
|
||||||
let current_page_permalink = "";
|
let current_page_permalink = "";
|
||||||
let context = RenderContext::new(
|
let mut context = RenderContext::new(
|
||||||
&tera,
|
&tera,
|
||||||
&config,
|
&config,
|
||||||
&config.default_language,
|
&config.default_language,
|
||||||
|
@ -115,6 +117,8 @@ fn bench_render_content_without_highlighting(b: &mut test::Bencher) {
|
||||||
&permalinks_ctx,
|
&permalinks_ctx,
|
||||||
InsertAnchor::None,
|
InsertAnchor::None,
|
||||||
);
|
);
|
||||||
|
let shortcode_def = utils::templates::get_shortcodes(&tera);
|
||||||
|
context.set_shortcode_definitions(&shortcode_def);
|
||||||
b.iter(|| render_content(CONTENT, &context).unwrap());
|
b.iter(|| render_content(CONTENT, &context).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +126,7 @@ fn bench_render_content_without_highlighting(b: &mut test::Bencher) {
|
||||||
fn bench_render_content_no_shortcode(b: &mut test::Bencher) {
|
fn bench_render_content_no_shortcode(b: &mut test::Bencher) {
|
||||||
let tera = Tera::default();
|
let tera = Tera::default();
|
||||||
let content2 = CONTENT.replace(r#"{{ youtube(id="my_youtube_id") }}"#, "");
|
let content2 = CONTENT.replace(r#"{{ youtube(id="my_youtube_id") }}"#, "");
|
||||||
let mut config = Config::default();
|
let mut config = Config::default_for_test();
|
||||||
config.markdown.highlight_code = false;
|
config.markdown.highlight_code = false;
|
||||||
let permalinks_ctx = HashMap::new();
|
let permalinks_ctx = HashMap::new();
|
||||||
let current_page_permalink = "";
|
let current_page_permalink = "";
|
||||||
|
@ -142,7 +146,7 @@ fn bench_render_content_no_shortcode(b: &mut test::Bencher) {
|
||||||
fn bench_render_content_with_emoji(b: &mut test::Bencher) {
|
fn bench_render_content_with_emoji(b: &mut test::Bencher) {
|
||||||
let tera = Tera::default();
|
let tera = Tera::default();
|
||||||
let content2 = CONTENT.replace(r#"{{ youtube(id="my_youtube_id") }}"#, "");
|
let content2 = CONTENT.replace(r#"{{ youtube(id="my_youtube_id") }}"#, "");
|
||||||
let mut config = Config::default();
|
let mut config = Config::default_for_test();
|
||||||
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();
|
||||||
|
|
|
@ -12,7 +12,6 @@ use utils::site::resolve_internal_link;
|
||||||
use utils::slugs::slugify_anchors;
|
use utils::slugs::slugify_anchors;
|
||||||
use utils::table_of_contents::{make_table_of_contents, Heading};
|
use utils::table_of_contents::{make_table_of_contents, Heading};
|
||||||
use utils::types::InsertAnchor;
|
use utils::types::InsertAnchor;
|
||||||
use utils::vec::InsertMany;
|
|
||||||
|
|
||||||
use self::cmark::{Event, LinkType, Options, Parser, Tag};
|
use self::cmark::{Event, LinkType, Options, Parser, Tag};
|
||||||
use crate::codeblock::{CodeBlock, FenceSettings};
|
use crate::codeblock::{CodeBlock, FenceSettings};
|
||||||
|
@ -22,6 +21,27 @@ const CONTINUE_READING: &str = "<span id=\"continue-reading\"></span>";
|
||||||
const ANCHOR_LINK_TEMPLATE: &str = "anchor-link.html";
|
const ANCHOR_LINK_TEMPLATE: &str = "anchor-link.html";
|
||||||
static EMOJI_REPLACER: Lazy<EmojiReplacer> = Lazy::new(EmojiReplacer::new);
|
static EMOJI_REPLACER: Lazy<EmojiReplacer> = Lazy::new(EmojiReplacer::new);
|
||||||
|
|
||||||
|
|
||||||
|
/// Efficiently insert multiple element in their specified index.
|
||||||
|
/// The elements should sorted in ascending order by their index.
|
||||||
|
///
|
||||||
|
/// This is done in O(n) time.
|
||||||
|
fn insert_many<T>(input: &mut Vec<T>, elem_to_insert: Vec<(usize, T)>) {
|
||||||
|
let mut inserted = vec![];
|
||||||
|
let mut last_idx = 0;
|
||||||
|
|
||||||
|
for (idx, elem) in elem_to_insert.into_iter() {
|
||||||
|
let head_len = idx - last_idx;
|
||||||
|
inserted.extend(input.splice(0..head_len, std::iter::empty()));
|
||||||
|
inserted.push(elem);
|
||||||
|
last_idx = idx;
|
||||||
|
}
|
||||||
|
let len = input.len();
|
||||||
|
inserted.extend(input.drain(0..len));
|
||||||
|
|
||||||
|
*input = inserted;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Rendered {
|
pub struct Rendered {
|
||||||
pub body: String,
|
pub body: String,
|
||||||
|
@ -490,7 +510,7 @@ pub fn markdown_to_html(
|
||||||
}
|
}
|
||||||
|
|
||||||
if context.insert_anchor != InsertAnchor::None {
|
if context.insert_anchor != InsertAnchor::None {
|
||||||
events.insert_many(anchors_to_insert);
|
insert_many(&mut events, anchors_to_insert);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmark::html::push_html(&mut html, events.into_iter());
|
cmark::html::push_html(&mut html, events.into_iter());
|
||||||
|
@ -512,6 +532,17 @@ pub fn markdown_to_html(
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
|
||||||
|
fn insert_many_works() {
|
||||||
|
let mut v = vec![1, 2, 3, 4, 5];
|
||||||
|
insert_many(&mut v, vec![(0, 0), (2, -1), (5, 6)]);
|
||||||
|
assert_eq!(v, &[0, 1, 2, -1, 3, 4, 5, 6]);
|
||||||
|
|
||||||
|
let mut v2 = vec![1, 2, 3, 4, 5];
|
||||||
|
insert_many(&mut v2, vec![(0, 0), (2, -1)]);
|
||||||
|
assert_eq!(v2, &[0, 1, 2, -1, 3, 4, 5]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_external_link() {
|
fn test_is_external_link() {
|
||||||
|
|
|
@ -3,6 +3,7 @@ pub mod link_checking;
|
||||||
pub mod sass;
|
pub mod sass;
|
||||||
pub mod sitemap;
|
pub mod sitemap;
|
||||||
pub mod tpls;
|
pub mod tpls;
|
||||||
|
mod minify;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs::remove_dir_all;
|
use std::fs::remove_dir_all;
|
||||||
|
@ -23,7 +24,6 @@ use templates::{load_tera, render_redirect_template};
|
||||||
use utils::fs::{
|
use utils::fs::{
|
||||||
copy_directory, copy_file_if_needed, create_directory, create_file, ensure_directory_exists,
|
copy_directory, copy_file_if_needed, create_directory, create_file, ensure_directory_exists,
|
||||||
};
|
};
|
||||||
use utils::minify;
|
|
||||||
use utils::net::get_available_port;
|
use utils::net::get_available_port;
|
||||||
use utils::templates::{render_template, ShortcodeDefinition};
|
use utils::templates::{render_template, ShortcodeDefinition};
|
||||||
use utils::types::InsertAnchor;
|
use utils::types::InsertAnchor;
|
||||||
|
|
|
@ -96,7 +96,7 @@ pub fn check_internal_links_with_anchors(site: &Site) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_skip_by_prefix(link: &String, skip_prefixes: &Vec<String>) -> bool {
|
fn should_skip_by_prefix(link: &str, skip_prefixes: &[String]) -> bool {
|
||||||
skip_prefixes.iter().any(|prefix| link.starts_with(prefix))
|
skip_prefixes.iter().any(|prefix| link.starts_with(prefix))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ pub fn check_external_links(site: &Site) -> Result<()> {
|
||||||
for link in checked_links.iter() {
|
for link in checked_links.iter() {
|
||||||
links_by_domain.entry(link.domain.to_string()).or_default();
|
links_by_domain.entry(link.domain.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.get_mut(&link.domain).unwrap().push(&link);
|
links_by_domain.get_mut(&link.domain).unwrap().push(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
if checked_links.is_empty() {
|
if checked_links.is_empty() {
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
pub mod de;
|
pub mod de;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
pub mod links;
|
pub mod links;
|
||||||
pub mod minify;
|
|
||||||
pub mod net;
|
pub mod net;
|
||||||
pub mod site;
|
pub mod site;
|
||||||
pub mod slugs;
|
pub mod slugs;
|
||||||
pub mod table_of_contents;
|
pub mod table_of_contents;
|
||||||
pub mod templates;
|
pub mod templates;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
pub mod vec;
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use libs::percent_encoding::percent_decode;
|
use libs::percent_encoding::percent_decode;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::hash::BuildHasher;
|
|
||||||
|
|
||||||
use errors::{anyhow, Result};
|
use errors::{anyhow, Result};
|
||||||
|
|
||||||
|
@ -19,9 +18,9 @@ pub struct ResolvedInternalLink {
|
||||||
|
|
||||||
/// Resolves an internal link (of the `@/posts/something.md#hey` sort) to its absolute link and
|
/// Resolves an internal link (of the `@/posts/something.md#hey` sort) to its absolute link and
|
||||||
/// returns the path + anchor as well
|
/// returns the path + anchor as well
|
||||||
pub fn resolve_internal_link<S: BuildHasher>(
|
pub fn resolve_internal_link(
|
||||||
link: &str,
|
link: &str,
|
||||||
permalinks: &HashMap<String, String, S>,
|
permalinks: &HashMap<String, String>,
|
||||||
) -> Result<ResolvedInternalLink> {
|
) -> Result<ResolvedInternalLink> {
|
||||||
// First we remove the ./ since that's zola specific
|
// First we remove the ./ since that's zola specific
|
||||||
let clean_link = link.replacen("@/", "", 1);
|
let clean_link = link.replacen("@/", "", 1);
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
pub trait InsertMany {
|
|
||||||
type Element;
|
|
||||||
fn insert_many(&mut self, elem_to_insert: Vec<(usize, Self::Element)>);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> InsertMany for Vec<T> {
|
|
||||||
type Element = T;
|
|
||||||
|
|
||||||
/// Efficiently insert multiple element in their specified index.
|
|
||||||
/// The elements should sorted in ascending order by their index.
|
|
||||||
///
|
|
||||||
/// This is done in O(n) time.
|
|
||||||
fn insert_many(&mut self, elem_to_insert: Vec<(usize, T)>) {
|
|
||||||
let mut inserted = vec![];
|
|
||||||
let mut last_idx = 0;
|
|
||||||
|
|
||||||
for (idx, elem) in elem_to_insert.into_iter() {
|
|
||||||
let head_len = idx - last_idx;
|
|
||||||
inserted.extend(self.splice(0..head_len, std::iter::empty()));
|
|
||||||
inserted.push(elem);
|
|
||||||
last_idx = idx;
|
|
||||||
}
|
|
||||||
let len = self.len();
|
|
||||||
inserted.extend(self.drain(0..len));
|
|
||||||
|
|
||||||
*self = inserted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::InsertMany;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn insert_many_works() {
|
|
||||||
let mut v = vec![1, 2, 3, 4, 5];
|
|
||||||
v.insert_many(vec![(0, 0), (2, -1), (5, 6)]);
|
|
||||||
assert_eq!(v, &[0, 1, 2, -1, 3, 4, 5, 6]);
|
|
||||||
|
|
||||||
let mut v2 = vec![1, 2, 3, 4, 5];
|
|
||||||
v2.insert_many(vec![(0, 0), (2, -1)]);
|
|
||||||
assert_eq!(v2, &[0, 1, 2, -1, 3, 4, 5]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,7 +12,7 @@ mod cmd;
|
||||||
mod console;
|
mod console;
|
||||||
mod prompt;
|
mod prompt;
|
||||||
|
|
||||||
fn get_config_file_path(dir: &PathBuf, config_path: &Path) -> (PathBuf, PathBuf) {
|
fn get_config_file_path(dir: &Path, config_path: &Path) -> (PathBuf, PathBuf) {
|
||||||
let root_dir = dir
|
let root_dir = dir
|
||||||
.ancestors()
|
.ancestors()
|
||||||
.find_map(|a| if a.join(&config_path).exists() { Some(a) } else { None })
|
.find_map(|a| if a.join(&config_path).exists() { Some(a) } else { None })
|
||||||
|
|
Loading…
Reference in New Issue