Implemented emoji aliases support in markdown files (#1194)

* Implemented emoji aliases support in markdown files

* Added emoji aliases rendering unit tests

* Added bench for emoji
This commit is contained in:
Vladislav Nikonov 2020-10-30 18:02:07 +02:00 committed by Vincent Prouillet
parent a26422d401
commit b1091bbb45
7 changed files with 77 additions and 10 deletions

11
Cargo.lock generated
View file

@ -761,6 +761,16 @@ dependencies = [
"wasi 0.9.0+wasi-snapshot-preview1", "wasi 0.9.0+wasi-snapshot-preview1",
] ]
[[package]]
name = "gh-emoji"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a17a050b7eb420553344e1cf1db648e8b584c79e98b74e6e6d119eeedd9ddcbc"
dependencies = [
"phf",
"regex",
]
[[package]] [[package]]
name = "gif" name = "gif"
version = "0.11.1" version = "0.11.1"
@ -1975,6 +1985,7 @@ dependencies = [
"config", "config",
"errors", "errors",
"front_matter", "front_matter",
"gh-emoji",
"lazy_static", "lazy_static",
"link_checker", "link_checker",
"pest", "pest",

View file

@ -106,6 +106,9 @@ pub struct Config {
/// The search config, telling what to include in the search index /// The search config, telling what to include in the search index
pub search: search::Search, pub search: search::Search,
/// Whether to render emoji aliases (e.g.: :smile: => 😄) in the markdown files
pub emoji_rendering: bool,
/// All user params set in [extra] in the config /// All user params set in [extra] in the config
pub extra: HashMap<String, Toml>, pub extra: HashMap<String, Toml>,
} }
@ -337,6 +340,7 @@ impl Default for Config {
slugify: slugify::Slugify::default(), slugify: slugify::Slugify::default(),
search: search::Search::default(), search: search::Search::default(),
extra: HashMap::new(), extra: HashMap::new(),
emoji_rendering: false,
} }
} }
} }

View file

@ -15,6 +15,7 @@ pest = "2"
pest_derive = "2" pest_derive = "2"
regex = "1" regex = "1"
lazy_static = "1" lazy_static = "1"
gh-emoji = "1.0"
errors = { path = "../errors" } errors = { path = "../errors" }
front_matter = { path = "../front_matter" } front_matter = { path = "../front_matter" }

View file

@ -17,12 +17,12 @@ Lorem markdownum litora, care ponto nomina, et ut aspicit gelidas sui et
purpureo genuit. Tamen colla venientis [delphina](http://nil-sol.com/ecquis) purpureo genuit. Tamen colla venientis [delphina](http://nil-sol.com/ecquis)
Tusci et temptata citaeque curam isto ubi vult vulnere reppulit. Tusci et temptata citaeque curam isto ubi vult vulnere reppulit.
- Seque vidit flendoque de quodam - :one: Seque vidit flendoque de quodam
- Dabit minimos deiecto caputque noctis pluma - :two: Dabit minimos deiecto caputque noctis pluma
- Leti coniunx est Helicen - :three: Leti coniunx est Helicen
- Illius pulvereumque Icare inpositos - :four: Illius pulvereumque Icare inpositos
- Vivunt pereo pluvio tot ramos Olenios gelidis - :five: Vivunt pereo pluvio tot ramos Olenios gelidis
- Quater teretes natura inde - :six: Quater teretes natura inde
### A subsection ### A subsection
@ -35,7 +35,7 @@ granum captantur potuisse Minervae, frugum.
> Clivo sub inprovisoque nostrum minus fama est, discordia patrem petebat precatur > Clivo sub inprovisoque nostrum minus fama est, discordia patrem petebat precatur
absumitur, poena per sit. Foramina *tamen cupidine* memor supplex tollentes absumitur, poena per sit. Foramina *tamen cupidine* memor supplex tollentes
dictum unam orbem, Anubis caecae. Viderat formosior tegebat satis, Aethiopasque dictum unam orbem, Anubis caecae. Viderat formosior tegebat satis, Aethiopasque
sit submisso coniuge tristis ubi! sit submisso coniuge tristis ubi! :exclamation:
## Praeceps Corinthus totidem quem crus vultum cape ## Praeceps Corinthus totidem quem crus vultum cape
@ -68,7 +68,7 @@ And a shortcode:
### Another subsection ### Another subsection
Gotta make the toc do a little bit of work Gotta make the toc do a little bit of work
# A big title # A big title :fire:
- hello - hello
- world - world
@ -123,3 +123,16 @@ fn bench_render_shortcodes_one_present(b: &mut test::Bencher) {
b.iter(|| render_shortcodes(CONTENT, &context)); b.iter(|| render_shortcodes(CONTENT, &context));
} }
#[bench]
fn bench_render_content_no_shortcode_with_emoji(b: &mut test::Bencher) {
let tera = Tera::default();
let content2 = CONTENT.replace(r#"{{ youtube(id="my_youtube_id") }}"#, "");
let mut config = Config::default();
config.highlight_code = false;
config.emoji_rendering = true;
let permalinks_ctx = HashMap::new();
let context = RenderContext::new(&tera, &config, "", &permalinks_ctx, InsertAnchor::None);
b.iter(|| render_content(&content2, &context).unwrap());
}

View file

@ -168,6 +168,10 @@ fn get_heading_refs(events: &[Event]) -> Vec<HeadingRef> {
} }
pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<Rendered> { pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<Rendered> {
lazy_static! {
static ref EMOJI_REPLACER: gh_emoji::Replacer = gh_emoji::Replacer::new();
}
// the rendered html // the rendered html
let mut html = String::with_capacity(content.len()); let mut html = String::with_capacity(content.len());
// Set while parsing // Set while parsing
@ -198,8 +202,13 @@ pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<Render
let html = code_block.highlight(&text); let html = code_block.highlight(&text);
Event::Html(html.into()) Event::Html(html.into())
} else { } else {
// Business as usual if context.config.emoji_rendering {
Event::Text(text) let processed_text = EMOJI_REPLACER.replace_all(&text);
Event::Text(processed_text.to_string().into())
} else {
// Business as usual
Event::Text(text)
}
} }
} }
Event::Start(Tag::CodeBlock(ref kind)) => { Event::Start(Tag::CodeBlock(ref kind)) => {

View file

@ -1036,3 +1036,28 @@ Again more text"#;
let res = render_content(markdown_string, &context).unwrap(); let res = render_content(markdown_string, &context).unwrap();
assert_eq!(res.body, expected); assert_eq!(res.body, expected);
} }
#[test]
fn can_render_emoji_alias() {
let permalinks_ctx = HashMap::new();
let mut config = Config::default();
config.emoji_rendering = true;
let context = RenderContext::new(&ZOLA_TERA, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content("Hello, World! :smile:", &context).unwrap();
assert_eq!(
res.body,
"<p>Hello, World! 😄</p>\n"
);
}
#[test]
fn emoji_aliases_are_ignored_when_disabled_in_config() {
let permalinks_ctx = HashMap::new();
let config = Config::default();
let context = RenderContext::new(&ZOLA_TERA, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content("Hello, World! :smile:", &context).unwrap();
assert_eq!(
res.body,
"<p>Hello, World! :smile:</p>\n"
);
}

View file

@ -61,6 +61,10 @@ generate_feed = false
# files are always copied, regardless of this setting. # files are always copied, regardless of this setting.
# hard_link_static = false # hard_link_static = false
# When set to "true", emoji aliases translated to their corresponding
# Unicode emoji equivalent in the rendered Markdown files. (e.g.: :smile: => 😄)
# emoji_rendering = false
# The taxonomies to be rendered for the site and their configuration. # The taxonomies to be rendered for the site and their configuration.
# Example: # Example:
# taxonomies = [ # taxonomies = [