Wordcount + reading time
This commit is contained in:
parent
4acce865b4
commit
e5367453d7
52
src/page.rs
52
src/page.rs
|
@ -73,6 +73,7 @@ impl Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the URL (without the base URL) to that page
|
||||||
pub fn get_url(&self) -> String {
|
pub fn get_url(&self) -> String {
|
||||||
if let Some(ref u) = self.meta.url {
|
if let Some(ref u) = self.meta.url {
|
||||||
return u.to_string();
|
return u.to_string();
|
||||||
|
@ -85,6 +86,16 @@ impl Page {
|
||||||
format!("/{}", self.get_slug())
|
format!("/{}", self.get_slug())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get word count and estimated reading time
|
||||||
|
pub fn get_reading_analytics(&self) -> (usize, usize) {
|
||||||
|
// Only works for latin language but good enough for a start
|
||||||
|
let word_count: usize = self.raw_content.split_whitespace().count();
|
||||||
|
|
||||||
|
// https://help.medium.com/hc/en-us/articles/214991667-Read-time
|
||||||
|
// 275 seems a bit too high though
|
||||||
|
(word_count, (word_count / 200))
|
||||||
|
}
|
||||||
|
|
||||||
// Parse a page given the content of the .md file
|
// Parse a page given the content of the .md file
|
||||||
// Files without front matter or with invalid front matter are considered
|
// Files without front matter or with invalid front matter are considered
|
||||||
// erroneous
|
// erroneous
|
||||||
|
@ -149,6 +160,7 @@ impl Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Renders the page using the default layout, unless specified in front-matter
|
||||||
pub fn render_html(&self, tera: &Tera, config: &Config) -> Result<String> {
|
pub fn render_html(&self, tera: &Tera, config: &Config) -> Result<String> {
|
||||||
let tpl = self.get_layout_name();
|
let tpl = self.get_layout_name();
|
||||||
let mut context = Context::new();
|
let mut context = Context::new();
|
||||||
|
@ -162,7 +174,7 @@ impl Page {
|
||||||
|
|
||||||
impl ser::Serialize for Page {
|
impl ser::Serialize for Page {
|
||||||
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error> where S: ser::Serializer {
|
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error> where S: ser::Serializer {
|
||||||
let mut state = serializer.serialize_struct("page", 10)?;
|
let mut state = serializer.serialize_struct("page", 12)?;
|
||||||
state.serialize_field("content", &self.content)?;
|
state.serialize_field("content", &self.content)?;
|
||||||
state.serialize_field("title", &self.meta.title)?;
|
state.serialize_field("title", &self.meta.title)?;
|
||||||
state.serialize_field("description", &self.meta.description)?;
|
state.serialize_field("description", &self.meta.description)?;
|
||||||
|
@ -173,6 +185,9 @@ impl ser::Serialize for Page {
|
||||||
state.serialize_field("draft", &self.meta.draft)?;
|
state.serialize_field("draft", &self.meta.draft)?;
|
||||||
state.serialize_field("category", &self.meta.category)?;
|
state.serialize_field("category", &self.meta.category)?;
|
||||||
state.serialize_field("extra", &self.meta.extra)?;
|
state.serialize_field("extra", &self.meta.extra)?;
|
||||||
|
let (word_count, reading_time) = self.get_reading_analytics();
|
||||||
|
state.serialize_field("word_count", &word_count)?;
|
||||||
|
state.serialize_field("reading_time", &reading_time)?;
|
||||||
state.end()
|
state.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,4 +328,39 @@ Hello world"#;
|
||||||
let page = res.unwrap();
|
let page = res.unwrap();
|
||||||
assert_eq!(page.get_slug(), "file-with-space");
|
assert_eq!(page.get_slug(), "file-with-space");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_reading_analytics_short() {
|
||||||
|
let content = r#"
|
||||||
|
+++
|
||||||
|
title = "Hello"
|
||||||
|
description = "hey there"
|
||||||
|
+++
|
||||||
|
Hello world"#;
|
||||||
|
let res = Page::parse("file with space.md", content);
|
||||||
|
assert!(res.is_ok());
|
||||||
|
let page = res.unwrap();
|
||||||
|
let (word_count, reading_time) = page.get_reading_analytics();
|
||||||
|
assert_eq!(word_count, 2);
|
||||||
|
assert_eq!(reading_time, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_reading_analytics_long() {
|
||||||
|
let mut content = r#"
|
||||||
|
+++
|
||||||
|
title = "Hello"
|
||||||
|
description = "hey there"
|
||||||
|
+++
|
||||||
|
Hello world"#.to_string();
|
||||||
|
for _ in 0..1000 {
|
||||||
|
content.push_str(" Hello world");
|
||||||
|
}
|
||||||
|
let res = Page::parse("hello.md", &content);
|
||||||
|
assert!(res.is_ok());
|
||||||
|
let page = res.unwrap();
|
||||||
|
let (word_count, reading_time) = page.get_reading_analytics();
|
||||||
|
assert_eq!(word_count, 2002);
|
||||||
|
assert_eq!(reading_time, 10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue