From 85e13483ebc0514d7f577546de96a16ae15fb222 Mon Sep 17 00:00:00 2001
From: Vincent Prouillet
Date: Sun, 6 May 2018 22:58:39 +0200
Subject: [PATCH] Use the new shortcode parser
---
Cargo.lock | 5 +-
README.md | 4 +-
components/content/src/page.rs | 14 +-
components/content/src/section.rs | 9 +-
components/front_matter/src/page.rs | 2 +-
.../examples/generate_sublime.rs | 0
components/highlighting/src/lib.rs | 15 +-
components/rendering/Cargo.toml | 2 -
components/rendering/benches/all.rs | 43 ++-
components/rendering/src/context.rs | 28 +-
components/rendering/src/lib.rs | 22 +-
components/rendering/src/markdown.rs | 361 ++++++------------
components/rendering/src/short_code.rs | 190 ---------
components/rendering/src/shortcode.rs | 30 +-
components/rendering/src/table_of_contents.rs | 12 +-
components/rendering/tests/markdown.rs | 164 ++++----
sublime_syntaxes/newlines.packdump | Bin 413042 -> 416076 bytes
sublime_syntaxes/nonewlines.packdump | Bin 413083 -> 416145 bytes
18 files changed, 322 insertions(+), 579 deletions(-)
rename components/{rendering => highlighting}/examples/generate_sublime.rs (100%)
delete mode 100644 components/rendering/src/short_code.rs
diff --git a/Cargo.lock b/Cargo.lock
index 9023ba27..513d8662 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1113,12 +1113,13 @@ dependencies = [
name = "rendering"
version = "0.1.0"
dependencies = [
+ "config 0.1.0",
"errors 0.1.0",
"front_matter 0.1.0",
"highlighting 0.1.0",
- "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
"slug 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/README.md b/README.md
index 95bb0f52..23454eb7 100644
--- a/README.md
+++ b/README.md
@@ -52,7 +52,7 @@ If you want a feature added or modified, please open an issue to discuss it befo
Syntax highlighting depends on submodules so ensure you load them first:
```bash
-$ git submodule update --init
+$ git submodule update --init
```
Gutenberg only works with syntaxes in the `.sublime-syntax` format. If your syntax
@@ -75,7 +75,7 @@ You can check for any updates to the current packages by running:
$ git submodule update --remote --merge
```
-And finally from the root of the components/rendering crate run the following command:
+And finally from the root of the components/highlighting crate run the following command:
```bash
$ cargo run --example generate_sublime synpack ../../sublime_syntaxes ../../sublime_syntaxes/newlines.packdump ../../sublime_syntaxes/nonewlines.packdump
diff --git a/components/content/src/page.rs b/components/content/src/page.rs
index b3cd820b..f977c464 100644
--- a/components/content/src/page.rs
+++ b/components/content/src/page.rs
@@ -14,7 +14,7 @@ use utils::fs::{read_file, find_related_assets};
use utils::site::get_reading_analytics;
use utils::templates::render_template;
use front_matter::{PageFrontMatter, InsertAnchor, split_page_content};
-use rendering::{Context, Header, markdown_to_html};
+use rendering::{RenderContext, Header, render_content};
use file_info::FileInfo;
@@ -162,21 +162,23 @@ impl Page {
/// We need access to all pages url to render links relative to content
/// so that can't happen at the same time as parsing
pub fn render_markdown(&mut self, permalinks: &HashMap, tera: &Tera, config: &Config, anchor_insert: InsertAnchor) -> Result<()> {
- let context = Context::new(
+ let context = RenderContext::new(
tera,
- config.highlight_code,
- config.highlight_theme.clone(),
+ config,
&self.permalink,
permalinks,
anchor_insert
);
- let res = markdown_to_html(&self.raw_content.replacen("", "", 1), &context)?;
+ let res = render_content(
+ &self.raw_content.replacen("", "", 1),
+ &context
+ )?;
self.content = res.0;
self.toc = res.1;
if self.raw_content.contains("") {
self.summary = Some({
let summary = self.raw_content.splitn(2, "").collect::>()[0];
- markdown_to_html(summary, &context)?.0
+ render_content(summary, &context)?.0
})
}
diff --git a/components/content/src/section.rs b/components/content/src/section.rs
index b75581c6..c864318e 100644
--- a/components/content/src/section.rs
+++ b/components/content/src/section.rs
@@ -11,7 +11,7 @@ use errors::{Result, ResultExt};
use utils::fs::read_file;
use utils::templates::render_template;
use utils::site::get_reading_analytics;
-use rendering::{Context, Header, markdown_to_html};
+use rendering::{RenderContext, Header, render_content};
use page::Page;
use file_info::FileInfo;
@@ -98,15 +98,14 @@ impl Section {
/// We need access to all pages url to render links relative to content
/// so that can't happen at the same time as parsing
pub fn render_markdown(&mut self, permalinks: &HashMap, tera: &Tera, config: &Config) -> Result<()> {
- let context = Context::new(
+ let context = RenderContext::new(
tera,
- config.highlight_code,
- config.highlight_theme.clone(),
+ config,
&self.permalink,
permalinks,
self.meta.insert_anchor_links,
);
- let res = markdown_to_html(&self.raw_content, &context)?;
+ let res = render_content(&self.raw_content, &context)?;
self.content = res.0;
self.toc = res.1;
Ok(())
diff --git a/components/front_matter/src/page.rs b/components/front_matter/src/page.rs
index 86cde2a9..0b33a3a2 100644
--- a/components/front_matter/src/page.rs
+++ b/components/front_matter/src/page.rs
@@ -21,7 +21,7 @@ fn from_toml_datetime<'de, D>(deserializer: D) -> StdResult
{}", s))),
- Err(e) => {
- error = Some(e);
- return Event::Html(Owned(String::new()));
- }
+ // Business as usual
+ Event::Text(text)
+ },
+ Event::Start(Tag::CodeBlock(ref info)) => {
+ if !context.config.highlight_code {
+ return Event::Html(Owned("
".to_owned()));
}
- }
-
- // Shortcode with a body
- if shortcode_block.is_none() && text.starts_with("{%") && text.ends_with("%}") {
- if SHORTCODE_RE.is_match(&text) {
- let (name, args) = parse_shortcode(&text);
- shortcode_block = Some(ShortCode::new(&name, args));
+ let theme = &THEME_SET.themes[&context.config.highlight_theme];
+ highlighter = Some(get_highlighter(&theme, info));
+ let snippet = start_coloured_html_snippet(theme);
+ Event::Html(Owned(snippet))
+ },
+ Event::End(Tag::CodeBlock(_)) => {
+ if !context.config.highlight_code {
+ return Event::Html(Owned("
\n".to_owned()))
}
- // Don't return anything
- return Event::Text(Owned(String::new()));
- }
-
- // If we have some text while in a shortcode, it's either the body
- // or the end tag
- if shortcode_block.is_some() {
- if let Some(ref mut shortcode) = shortcode_block {
- if text.trim() == "{% end %}" {
- added_shortcode = true;
- clear_shortcode_block = true;
- match shortcode.render(context.tera) {
- Ok(s) => return Event::Html(Owned(format!("{}", s))),
- Err(e) => {
- error = Some(e);
- return Event::Html(Owned(String::new()));
- }
+ // reset highlight and close the code block
+ highlighter = None;
+ Event::Html(Owned("".to_owned()))
+ },
+ // Need to handle relative links
+ Event::Start(Tag::Link(ref link, ref title)) => {
+ if in_header {
+ return Event::Html(Owned("".to_owned()));
+ }
+ if link.starts_with("./") {
+ match resolve_internal_link(link, context.permalinks) {
+ Ok(url) => {
+ return Event::Start(Tag::Link(Owned(url), title.clone()));
+ },
+ Err(_) => {
+ error = Some(format!("Relative link {} not found.", link).into());
+ return Event::Html(Owned("".to_string()));
}
- } else {
- shortcode.append(&text);
- return Event::Html(Owned(String::new()));
- }
+ };
}
- }
- // Business as usual
- Event::Text(text)
- },
- Event::Start(Tag::CodeBlock(ref info)) => {
- in_code_block = true;
- if !should_highlight {
- return Event::Html(Owned("".to_owned()));
+ Event::Start(Tag::Link(link.clone(), title.clone()))
+ },
+ Event::End(Tag::Link(_, _)) => {
+ if in_header {
+ return Event::Html(Owned("".to_owned()));
+ }
+ event
}
- let theme = &THEME_SET.themes[&context.highlight_theme];
- highlighter = SYNTAX_SET.with(|ss| {
- let syntax = info
- .split(' ')
- .next()
- .and_then(|lang| ss.find_syntax_by_token(lang))
- .unwrap_or_else(|| ss.find_syntax_plain_text());
- Some(HighlightLines::new(syntax, theme))
- });
- let snippet = start_coloured_html_snippet(theme);
- Event::Html(Owned(snippet))
- },
- Event::End(Tag::CodeBlock(_)) => {
- in_code_block = false;
- if !should_highlight{
- return Event::Html(Owned("
\n".to_owned()))
- }
- // reset highlight and close the code block
- highlighter = None;
- Event::Html(Owned("".to_owned()))
- },
- // Need to handle relative links
- Event::Start(Tag::Link(ref link, ref title)) => {
- if in_header {
- return Event::Html(Owned("".to_owned()));
- }
- if link.starts_with("./") {
- match resolve_internal_link(link, context.permalinks) {
- Ok(url) => {
- return Event::Start(Tag::Link(Owned(url), title.clone()));
- },
- Err(_) => {
- error = Some(format!("Relative link {} not found.", link).into());
- return Event::Html(Owned("".to_string()));
- }
- };
- }
-
- Event::Start(Tag::Link(link.clone(), title.clone()))
- },
- Event::End(Tag::Link(_, _)) => {
- if in_header {
- return Event::Html(Owned("".to_owned()));
- }
- event
+ Event::Start(Tag::Code) => {
+ if in_header {
+ temp_header.push("");
+ return Event::Html(Owned(String::new()));
+ }
+ event
+ },
+ Event::End(Tag::Code) => {
+ if in_header {
+ temp_header.push("
");
+ return Event::Html(Owned(String::new()));
+ }
+ event
+ },
+ Event::Start(Tag::Header(num)) => {
+ in_header = true;
+ temp_header = TempHeader::new(num);
+ Event::Html(Owned(String::new()))
+ },
+ Event::End(Tag::Header(_)) => {
+ // End of a header, reset all the things and return the stringified version of the header
+ in_header = false;
+ header_created = false;
+ let val = temp_header.to_string(context.tera, context.insert_anchor);
+ headers.push(temp_header.clone());
+ temp_header = TempHeader::default();
+ Event::Html(Owned(val))
+ },
+ _ => event,
}
- // need to know when we are in a code block to disable shortcodes in them
- Event::Start(Tag::Code) => {
- in_code_block = true;
- if in_header {
- temp_header.push("");
- return Event::Html(Owned(String::new()));
- }
- event
- },
- Event::End(Tag::Code) => {
- in_code_block = false;
- if in_header {
- temp_header.push("
");
- return Event::Html(Owned(String::new()));
- }
- event
- },
- Event::Start(Tag::Header(num)) => {
- in_header = true;
- temp_header = TempHeader::new(num);
- Event::Html(Owned(String::new()))
- },
- Event::End(Tag::Header(_)) => {
- // End of a header, reset all the things and return the stringified version of the header
- in_header = false;
- header_created = false;
- let val = temp_header.to_string(context);
- headers.push(temp_header.clone());
- temp_header = TempHeader::default();
- Event::Html(Owned(val))
- },
- // If we added shortcodes, don't close a paragraph since there's none
- Event::End(Tag::Paragraph) => {
- if added_shortcode {
- added_shortcode = false;
- return Event::Html(Owned("".to_owned()));
- }
- event
- },
- // Ignore softbreaks inside shortcodes
- Event::SoftBreak => {
- if shortcode_block.is_some() {
- return Event::Html(Owned("".to_owned()));
- }
- event
- },
- _ => {
- // println!("event = {:?}", event);
- event
- },
- }});
+ });
cmark::html::push_html(&mut html, parser);
}
- if !current_shortcode.is_empty() {
- return Err(format!("A shortcode was not closed properly:\n{:?}", current_shortcode).into());
- }
-
match error {
Some(e) => Err(e),
- None => Ok((html.replace("", "").replace("", ""), make_table_of_contents(&headers))),
+ None => Ok((
+ html.replace("", "").replace("", ""),
+ make_table_of_contents(&headers)
+ )),
}
}
diff --git a/components/rendering/src/short_code.rs b/components/rendering/src/short_code.rs
deleted file mode 100644
index f1cd3fbb..00000000
--- a/components/rendering/src/short_code.rs
+++ /dev/null
@@ -1,190 +0,0 @@
-use std::collections::HashMap;
-
-use regex::Regex;
-use tera::{Tera, Context, Value, to_value};
-
-use errors::{Result, ResultExt};
-
-lazy_static!{
- // Does this look like a shortcode?
- pub static ref SHORTCODE_RE: Regex = Regex::new(
- r#"\{(?:%|\{)\s+(\w+?)\((\w+?="?(?:.|\n)+?"?)?\)\s+(?:%|\})\}"#
- ).unwrap();
-
- // Parse the shortcode args with capture groups named after their type
- pub static ref SHORTCODE_ARGS_RE: Regex = Regex::new(
- r#"(?P\w+)=\s*((?P".*?")|(?P[-+]?[0-9]+\.[0-9]+)|(?P[-+]?[0-9]+)|(?Ptrue|false))"#
- ).unwrap();
-}
-
-/// A shortcode that has a body
-/// Called by having some content like {% ... %} body {% end %}
-/// We need the struct to hold the data while we're processing the markdown
-#[derive(Debug)]
-pub struct ShortCode {
- name: String,
- args: HashMap,
- body: String,
-}
-
-impl ShortCode {
- pub fn new(name: &str, args: HashMap) -> ShortCode {
- ShortCode {
- name: name.to_string(),
- args,
- body: String::new(),
- }
- }
-
- pub fn append(&mut self, text: &str) {
- self.body.push_str(text)
- }
-
- pub fn render(&self, tera: &Tera) -> Result {
- let mut context = Context::new();
- for (key, value) in &self.args {
- context.add(key, value);
- }
- context.add("body", &self.body);
- let tpl_name = format!("shortcodes/{}.html", self.name);
- tera.render(&tpl_name, &context)
- .chain_err(|| format!("Failed to render {} shortcode", self.name))
- }
-}
-
-/// Parse a shortcode without a body
-pub fn parse_shortcode(input: &str) -> (String, HashMap) {
- let mut args = HashMap::new();
- let caps = SHORTCODE_RE.captures(input).unwrap();
- // caps[0] is the full match
- let name = &caps[1];
-
- if let Some(arg_list) = caps.get(2) {
- for arg_cap in SHORTCODE_ARGS_RE.captures_iter(arg_list.as_str()) {
- let arg_name = arg_cap["name"].trim().to_string();
-
- if let Some(arg_val) = arg_cap.name("str") {
- args.insert(arg_name, to_value(arg_val.as_str().replace("\"", "")).unwrap());
- continue;
- }
-
- if let Some(arg_val) = arg_cap.name("int") {
- args.insert(arg_name, to_value(arg_val.as_str().parse::().unwrap()).unwrap());
- continue;
- }
-
- if let Some(arg_val) = arg_cap.name("float") {
- args.insert(arg_name, to_value(arg_val.as_str().parse::().unwrap()).unwrap());
- continue;
- }
-
- if let Some(arg_val) = arg_cap.name("bool") {
- args.insert(arg_name, to_value(arg_val.as_str() == "true").unwrap());
- continue;
- }
- }
- }
-
- (name.to_string(), args)
-}
-
-/// Renders a shortcode or return an error
-pub fn render_simple_shortcode(tera: &Tera, name: &str, args: &HashMap) -> Result {
- let mut context = Context::new();
- for (key, value) in args.iter() {
- context.add(key, value);
- }
- let tpl_name = format!("shortcodes/{}.html", name);
-
- tera.render(&tpl_name, &context).chain_err(|| format!("Failed to render {} shortcode", name))
-}
-
-
-#[cfg(test)]
-mod tests {
- use super::{parse_shortcode, SHORTCODE_RE};
-
- #[test]
- fn can_match_all_kinds_of_shortcode() {
- let inputs = vec![
- "{{ basic() }}",
- "{{ basic(ho=1) }}",
- "{{ basic(ho=\"hey\") }}",
- "{{ basic(ho=\"hey_underscore\") }}",
- "{{ basic(ho=\"hey-dash\") }}",
- "{% basic(ho=\"hey-dash\") %}",
- "{% basic(ho=\"hey_underscore\") %}",
- "{% basic() %}",
- "{% quo_te(author=\"Bob\") %}",
- "{{ quo_te(author=\"Bob\") }}",
- // https://github.com/Keats/gutenberg/issues/229
- r#"{{ youtube(id="dQw4w9WgXcQ",
-
- autoplay=true) }}"#,
- ];
-
- for i in inputs {
- println!("{}", i);
- assert!(SHORTCODE_RE.is_match(i));
- }
- }
-
- // https://github.com/Keats/gutenberg/issues/228
- #[test]
- fn doesnt_panic_on_invalid_shortcode() {
- let (name, args) = parse_shortcode(r#"{{ youtube(id="dQw4w9WgXcQ", autoplay) }}"#);
- assert_eq!(name, "youtube");
- assert_eq!(args["id"], "dQw4w9WgXcQ");
- assert!(args.get("autoplay").is_none());
- }
-
- #[test]
- fn can_parse_simple_shortcode_no_arg() {
- let (name, args) = parse_shortcode(r#"{{ basic() }}"#);
- assert_eq!(name, "basic");
- assert!(args.is_empty());
- }
-
- #[test]
- fn can_parse_simple_shortcode_one_arg() {
- let (name, args) = parse_shortcode(r#"{{ youtube(id="w7Ft2ymGmfc") }}"#);
- assert_eq!(name, "youtube");
- assert_eq!(args["id"], "w7Ft2ymGmfc");
- }
-
- #[test]
- fn can_parse_simple_shortcode_several_arg() {
- let (name, args) = parse_shortcode(r#"{{ youtube(id="w7Ft2ymGmfc", autoplay=true) }}"#);
- assert_eq!(name, "youtube");
- assert_eq!(args["id"], "w7Ft2ymGmfc");
- assert_eq!(args["autoplay"], true);
- }
-
- #[test]
- fn can_parse_block_shortcode_several_arg() {
- let (name, args) = parse_shortcode(r#"{% youtube(id="w7Ft2ymGmfc", autoplay=true) %}"#);
- assert_eq!(name, "youtube");
- assert_eq!(args["id"], "w7Ft2ymGmfc");
- assert_eq!(args["autoplay"], true);
- }
-
- #[test]
- fn can_parse_shortcode_number() {
- let (name, args) = parse_shortcode(r#"{% test(int=42, float=42.0, autoplay=false) %}"#);
- assert_eq!(name, "test");
- assert_eq!(args["int"], 42);
- assert_eq!(args["float"], 42.0);
- assert_eq!(args["autoplay"], false);
- }
-
- // https://github.com/Keats/gutenberg/issues/249
- #[test]
- fn can_parse_shortcode_with_comma_in_it() {
- let (name, args) = parse_shortcode(
- r#"{% quote(author="C++ Standard Core Language Defect Reports and Accepted Issues, Revision 82, delete and user-written deallocation function", href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#348") %}"#
- );
- assert_eq!(name, "quote");
- assert_eq!(args["author"], "C++ Standard Core Language Defect Reports and Accepted Issues, Revision 82, delete and user-written deallocation function");
- assert_eq!(args["href"], "http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#348");
- }
-}
diff --git a/components/rendering/src/shortcode.rs b/components/rendering/src/shortcode.rs
index 009a0cfe..4f0d0f1a 100644
--- a/components/rendering/src/shortcode.rs
+++ b/components/rendering/src/shortcode.rs
@@ -90,7 +90,8 @@ fn render_shortcode(name: String, args: Map, tera: &Tera, config:
context.insert(key, value);
}
if let Some(ref b) = body {
- context.insert("body", b);
+ // Trimming right to avoid most shortcodes with bodies ending up with a HTML new line
+ context.insert("body", b.trim_right());
}
context.insert("config", config);
let tpl_name = format!("shortcodes/{}.html", name);
@@ -99,16 +100,25 @@ fn render_shortcode(name: String, args: Map, tera: &Tera, config:
}
pub fn render_shortcodes(content: &str, tera: &Tera, config: &Config) -> Result {
- // Don't do anything if there is nothing like a shortcode in the content
- if !content.contains("{{") && !content.contains("{%") {
- return Ok(content.to_string());
- }
-
let mut res = String::with_capacity(content.len());
let mut pairs = match ContentParser::parse(Rule::page, content) {
Ok(p) => p,
- Err(_) => panic!("TODO"), // TODO: error handling
+ Err(e) => {
+ let fancy_e = e.renamed_rules(|rule| {
+ match *rule {
+ Rule::int => "an integer".to_string(),
+ Rule::float => "a float".to_string(),
+ Rule::string => "a string".to_string(),
+ Rule::literal => "a literal (int, float, string, bool)".to_string(),
+ Rule::array => "an array".to_string(),
+ Rule::kwarg => "a keyword argument".to_string(),
+ Rule::ident => "an identifier".to_string(),
+ _ => format!("TODO error: {:?}", rule).to_string(),
+ }
+ });
+ bail!("{}", fancy_e);
+ },
};
// We have at least a `page` pair
@@ -333,4 +343,10 @@ Hello World
let res = render_shortcodes("Body\n {% youtube() %}Hey!{% end %}", &tera, &Config::default()).unwrap();
assert_eq!(res, "Body\n Hey!");
}
+
+ #[test]
+ fn errors_on_unterminated_shortcode() {
+ let res = render_shortcodes("{{ youtube(", &Tera::default(), &Config::default());
+ assert!(res.is_err());
+ }
}
diff --git a/components/rendering/src/table_of_contents.rs b/components/rendering/src/table_of_contents.rs
index 70f75954..688c64d9 100644
--- a/components/rendering/src/table_of_contents.rs
+++ b/components/rendering/src/table_of_contents.rs
@@ -1,8 +1,6 @@
-use tera::{Context as TeraContext};
+use tera::{Tera, Context as TeraContext};
use front_matter::InsertAnchor;
-use context::Context;
-
#[derive(Debug, PartialEq, Clone, Serialize)]
pub struct Header {
@@ -50,16 +48,16 @@ impl TempHeader {
}
/// Transform all the information we have about this header into the HTML string for it
- pub fn to_string(&self, context: &Context) -> String {
- let anchor_link = if context.should_insert_anchor() {
+ pub fn to_string(&self, tera: &Tera, insert_anchor: InsertAnchor) -> String {
+ let anchor_link = if insert_anchor != InsertAnchor::None {
let mut c = TeraContext::new();
c.add("id", &self.id);
- context.tera.render("anchor-link.html", &c).unwrap()
+ tera.render("anchor-link.html", &c).unwrap()
} else {
String::new()
};
- match context.insert_anchor {
+ match insert_anchor {
InsertAnchor::None => format!("{t}\n", lvl=self.level, t=self.title, id=self.id),
InsertAnchor::Left => format!("{a}{t}\n", lvl=self.level, a=anchor_link, t=self.title, id=self.id),
InsertAnchor::Right => format!("{t}{a}\n", lvl=self.level, a=anchor_link, t=self.title, id=self.id),
diff --git a/components/rendering/tests/markdown.rs b/components/rendering/tests/markdown.rs
index 8dbdcc73..2e547f33 100644
--- a/components/rendering/tests/markdown.rs
+++ b/components/rendering/tests/markdown.rs
@@ -2,22 +2,25 @@ extern crate tera;
extern crate front_matter;
extern crate templates;
extern crate rendering;
+extern crate config;
use std::collections::HashMap;
use tera::Tera;
+use config::Config;
use front_matter::InsertAnchor;
use templates::GUTENBERG_TERA;
-use rendering::{Context, markdown_to_html};
+use rendering::{RenderContext, render_content};
#[test]
-fn can_do_markdown_to_html_simple() {
+fn can_do_render_content_simple() {
let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new();
- let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
- let res = markdown_to_html("hello", &context).unwrap();
+ let config = Config::default();
+ let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
+ let res = render_content("hello", &context).unwrap();
assert_eq!(res.0, "hello
\n");
}
@@ -25,9 +28,10 @@ fn can_do_markdown_to_html_simple() {
fn doesnt_highlight_code_block_with_highlighting_off() {
let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new();
- let mut context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
- context.highlight_code = false;
- let res = markdown_to_html("```\n$ gutenberg server\n```", &context).unwrap();
+ let mut config = Config::default();
+ config.highlight_code = false;
+ let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
+ let res = render_content("```\n$ gutenberg server\n```", &context).unwrap();
assert_eq!(
res.0,
"$ gutenberg server\n
\n"
@@ -38,8 +42,9 @@ fn doesnt_highlight_code_block_with_highlighting_off() {
fn can_highlight_code_block_no_lang() {
let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new();
- let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
- let res = markdown_to_html("```\n$ gutenberg server\n$ ping\n```", &context).unwrap();
+ let config = Config::default();
+ let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
+ let res = render_content("```\n$ gutenberg server\n$ ping\n```", &context).unwrap();
assert_eq!(
res.0,
"\n$ gutenberg server\n$ ping\n
"
@@ -50,8 +55,9 @@ fn can_highlight_code_block_no_lang() {
fn can_highlight_code_block_with_lang() {
let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new();
- let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
- let res = markdown_to_html("```python\nlist.append(1)\n```", &context).unwrap();
+ let config = Config::default();
+ let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
+ let res = render_content("```python\nlist.append(1)\n```", &context).unwrap();
assert_eq!(
res.0,
"\nlist.append(1)\n
"
@@ -62,8 +68,9 @@ fn can_highlight_code_block_with_lang() {
fn can_higlight_code_block_with_unknown_lang() {
let tera_ctx = Tera::default();
let permalinks_ctx = HashMap::new();
- let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
- let res = markdown_to_html("```yolo\nlist.append(1)\n```", &context).unwrap();
+ let config = Config::default();
+ let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
+ let res = render_content("```yolo\nlist.append(1)\n```", &context).unwrap();
// defaults to plain text
assert_eq!(
res.0,
@@ -74,8 +81,9 @@ fn can_higlight_code_block_with_unknown_lang() {
#[test]
fn can_render_shortcode() {
let permalinks_ctx = HashMap::new();
- let context = Context::new(&GUTENBERG_TERA, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
- let res = markdown_to_html(r#"
+ let config = Config::default();
+ let context = RenderContext::new(&GUTENBERG_TERA, &config, "", &permalinks_ctx, InsertAnchor::None);
+ let res = render_content(r#"
Hello
{{ youtube(id="ub36ffWAqgQ") }}
@@ -87,7 +95,8 @@ Hello
#[test]
fn can_render_shortcode_with_markdown_char_in_args_name() {
let permalinks_ctx = HashMap::new();
- let context = Context::new(&GUTENBERG_TERA, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
+ let config = Config::default();
+ let context = RenderContext::new(&GUTENBERG_TERA, &config, "", &permalinks_ctx, InsertAnchor::None);
let input = vec![
"name",
"na_me",
@@ -95,7 +104,7 @@ fn can_render_shortcode_with_markdown_char_in_args_name() {
"n1",
];
for i in input {
- let res = markdown_to_html(&format!("{{{{ youtube(id=\"hey\", {}=1) }}}}", i), &context).unwrap();
+ let res = render_content(&format!("{{{{ youtube(id=\"hey\", {}=1) }}}}", i), &context).unwrap();
assert!(res.0.contains(r#"