diff --git a/CHANGELOG.md b/CHANGELOG.md
index 99bdad82..a113313f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
- Change the single item template context for categories/tags
- Add a `get_url` global Tera function
- Add a config option to control how many articles to show in RSS feed
+- Move `insert_anchor_links` from config to being a section option
## 0.0.5 (2017-05-15)
diff --git a/Cargo.lock b/Cargo.lock
index eab7fd13..2250fef8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -56,7 +56,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cpp_demangle 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cpp_demangle 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -187,10 +187,12 @@ dependencies = [
[[package]]
name = "cpp_demangle"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
+ "clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fixedbitset 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1100,7 +1102,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b8f69e518f967224e628896b54e41ff6acfb4dcfefc5076325c36525dac900f"
"checksum cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "92278eb79412c8f75cfc89e707a1bb3a6490b68f7f2e78d15c774f30fe701122"
"checksum conduit-mime-types 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "95ca30253581af809925ef68c2641cc140d6183f43e12e0af4992d53768bd7b8"
-"checksum cpp_demangle 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1040e8145a72a251c1ccdd1d3d4b4ad175acc363da8a9c21a21cbb5b1f9056"
+"checksum cpp_demangle 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2692e985e8b489736612f206c8b2d071767c05ac9343a654dd5ebd791a9035d5"
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
"checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90"
"checksum error 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "a6e606f14042bb87cc02ef6a14db6c90ab92ed6f62d87e69377bc759fd7987cc"
diff --git a/src/bin/rebuild.rs b/src/bin/rebuild.rs
index 4f75bb97..6ea7944d 100644
--- a/src/bin/rebuild.rs
+++ b/src/bin/rebuild.rs
@@ -7,7 +7,7 @@ use gutenberg::errors::Result;
/// Finds the section that contains the page given if there is one
pub fn find_parent_section<'a>(site: &'a Site, page: &Page) -> Option<&'a Section> {
for section in site.sections.values() {
- if section.is_child_page(page) {
+ if section.is_child_page(&page.file.path) {
return Some(section)
}
}
diff --git a/src/content/page.rs b/src/content/page.rs
index caa9fdb5..667b88cf 100644
--- a/src/content/page.rs
+++ b/src/content/page.rs
@@ -4,14 +4,15 @@ use std::path::{Path, PathBuf};
use std::result::Result as StdResult;
-use tera::{Tera, Context};
+use tera::{Tera, Context as TeraContext};
use serde::ser::{SerializeStruct, self};
use slug::slugify;
use errors::{Result, ResultExt};
use config::Config;
-use front_matter::{PageFrontMatter, split_page_content};
+use front_matter::{PageFrontMatter, InsertAnchor, split_page_content};
use rendering::markdown::markdown_to_html;
+use rendering::context::Context;
use fs::{read_file};
use content::utils::{find_related_assets, get_reading_analytics};
use content::file_info::FileInfo;
@@ -112,13 +113,13 @@ 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) -> Result<()> {
- self.content = markdown_to_html(&self.raw_content, permalinks, tera, config)?;
-
+ pub fn render_markdown(&mut self, permalinks: &HashMap, tera: &Tera, config: &Config, anchor_insert: InsertAnchor) -> Result<()> {
+ let context = Context::new(tera, config, permalinks, anchor_insert);
+ self.content = markdown_to_html(&self.raw_content, &context)?;
if self.raw_content.contains("") {
self.summary = Some({
let summary = self.raw_content.splitn(2, "").collect::>()[0];
- markdown_to_html(summary, permalinks, tera, config)?
+ markdown_to_html(summary, &context)?
})
}
@@ -132,7 +133,7 @@ impl Page {
None => "page.html".to_string()
};
- let mut context = Context::new();
+ let mut context = TeraContext::new();
context.add("config", config);
context.add("page", self);
context.add("current_url", &self.permalink);
@@ -195,6 +196,7 @@ mod tests {
use config::Config;
use super::Page;
+ use front_matter::InsertAnchor;
#[test]
@@ -209,7 +211,7 @@ Hello world"#;
let res = Page::parse(Path::new("post.md"), content, &Config::default());
assert!(res.is_ok());
let mut page = res.unwrap();
- page.render_markdown(&HashMap::default(), &Tera::default(), &Config::default()).unwrap();
+ page.render_markdown(&HashMap::default(), &Tera::default(), &Config::default(), InsertAnchor::None).unwrap();
assert_eq!(page.meta.title.unwrap(), "Hello".to_string());
assert_eq!(page.meta.slug.unwrap(), "hello-world".to_string());
@@ -228,8 +230,7 @@ Hello world"#;
conf.base_url = "http://hello.com/".to_string();
let res = Page::parse(Path::new("content/posts/intro/start.md"), content, &conf);
assert!(res.is_ok());
- let mut page = res.unwrap();
- page.render_markdown(&HashMap::default(), &Tera::default(), &Config::default()).unwrap();
+ let page = res.unwrap();
assert_eq!(page.path, "posts/intro/hello-world");
assert_eq!(page.permalink, "http://hello.com/posts/intro/hello-world");
}
@@ -244,8 +245,7 @@ Hello world"#;
let config = Config::default();
let res = Page::parse(Path::new("start.md"), content, &config);
assert!(res.is_ok());
- let mut page = res.unwrap();
- page.render_markdown(&HashMap::default(), &Tera::default(), &config).unwrap();
+ let page = res.unwrap();
assert_eq!(page.path, "hello-world");
assert_eq!(page.permalink, config.make_permalink("hello-world"));
}
@@ -268,8 +268,7 @@ Hello world"#;
let config = Config::default();
let res = Page::parse(Path::new(" file with space.md"), "+++\n+++", &config);
assert!(res.is_ok());
- let mut page = res.unwrap();
- page.render_markdown(&HashMap::default(), &Tera::default(), &config).unwrap();
+ let page = res.unwrap();
assert_eq!(page.slug, "file-with-space");
assert_eq!(page.permalink, config.make_permalink(&page.slug));
}
@@ -285,7 +284,7 @@ Hello world
let res = Page::parse(Path::new("hello.md"), &content, &config);
assert!(res.is_ok());
let mut page = res.unwrap();
- page.render_markdown(&HashMap::default(), &Tera::default(), &config).unwrap();
+ page.render_markdown(&HashMap::default(), &Tera::default(), &config, InsertAnchor::None).unwrap();
assert_eq!(page.summary, Some("
Hello world
\n".to_string()));
}
diff --git a/src/content/section.rs b/src/content/section.rs
index a8e41ef7..4468bceb 100644
--- a/src/content/section.rs
+++ b/src/content/section.rs
@@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::result::Result as StdResult;
-use tera::{Tera, Context};
+use tera::{Tera, Context as TeraContext};
use serde::ser::{SerializeStruct, self};
use config::Config;
@@ -10,6 +10,7 @@ use front_matter::{SectionFrontMatter, split_section_content};
use errors::{Result, ResultExt};
use fs::{read_file};
use rendering::markdown::markdown_to_html;
+use rendering::context::Context;
use content::Page;
use content::file_info::FileInfo;
@@ -85,7 +86,8 @@ 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<()> {
- self.content = markdown_to_html(&self.raw_content, permalinks, tera, config)?;
+ let context = Context::new(tera, config, permalinks, self.meta.insert_anchor.unwrap());
+ self.content = markdown_to_html(&self.raw_content, &context)?;
Ok(())
}
@@ -93,7 +95,7 @@ impl Section {
pub fn render_html(&self, sections: HashMap, tera: &Tera, config: &Config) -> Result {
let tpl_name = self.get_template_name();
- let mut context = Context::new();
+ let mut context = TeraContext::new();
context.add("config", config);
context.add("section", self);
context.add("current_url", &self.permalink);
@@ -120,8 +122,8 @@ impl Section {
}
/// Whether the page given belongs to that section
- pub fn is_child_page(&self, page: &Page) -> bool {
- self.all_pages_path().contains(&page.file.path)
+ pub fn is_child_page(&self, path: &PathBuf) -> bool {
+ self.all_pages_path().contains(path)
}
}
diff --git a/src/front_matter/mod.rs b/src/front_matter/mod.rs
index 6bc075b8..b46fadf1 100644
--- a/src/front_matter/mod.rs
+++ b/src/front_matter/mod.rs
@@ -8,7 +8,7 @@ mod page;
mod section;
pub use self::page::PageFrontMatter;
-pub use self::section::{SectionFrontMatter};
+pub use self::section::{SectionFrontMatter, InsertAnchor};
lazy_static! {
static ref PAGE_RE: Regex = Regex::new(r"^[[:space:]]*\+\+\+\r?\n((?s).*?(?-s))\+\+\+\r?\n?((?s).*(?-s))$").unwrap();
diff --git a/src/front_matter/section.rs b/src/front_matter/section.rs
index 8d7c7d27..2f216659 100644
--- a/src/front_matter/section.rs
+++ b/src/front_matter/section.rs
@@ -9,6 +9,14 @@ use content::SortBy;
static DEFAULT_PAGINATE_PATH: &'static str = "page";
+#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum InsertAnchor {
+ Left,
+ Right,
+ None,
+}
+
/// The front matter of every section
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SectionFrontMatter {
@@ -28,6 +36,10 @@ pub struct SectionFrontMatter {
/// Path to be used by pagination: the page number will be appended after it. Defaults to `page`.
#[serde(skip_serializing)]
pub paginate_path: Option,
+ /// Whether to insert a link for each header like in Github READMEs. Defaults to false
+ /// The default template can be overridden by creating a `anchor-link.html` template and CSS will need to be
+ /// written if you turn that on.
+ pub insert_anchor: Option,
/// Whether to render that section or not. Defaults to `true`.
/// Useful when the section is only there to organize things but is not meant
/// to be used directly, like a posts section in a personal site
@@ -56,6 +68,10 @@ impl SectionFrontMatter {
f.sort_by = Some(SortBy::None);
}
+ if f.insert_anchor.is_none() {
+ f.insert_anchor = Some(InsertAnchor::None);
+ }
+
Ok(f)
}
@@ -87,6 +103,7 @@ impl Default for SectionFrontMatter {
paginate_by: None,
paginate_path: Some(DEFAULT_PAGINATE_PATH.to_string()),
render: Some(true),
+ insert_anchor: Some(InsertAnchor::None),
extra: None,
}
}
diff --git a/src/lib.rs b/src/lib.rs
index b72af67a..01f809d3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -31,6 +31,6 @@ mod templates;
pub use site::{Site};
pub use config::{Config, get_config};
-pub use front_matter::{PageFrontMatter, SectionFrontMatter, split_page_content, split_section_content};
+pub use front_matter::{PageFrontMatter, SectionFrontMatter, InsertAnchor, split_page_content, split_section_content};
pub use content::{Page, Section, SortBy, sort_pages, populate_previous_and_next_pages};
pub use fs::{create_file};
diff --git a/src/rendering/context.rs b/src/rendering/context.rs
new file mode 100644
index 00000000..d7f77c43
--- /dev/null
+++ b/src/rendering/context.rs
@@ -0,0 +1,33 @@
+use std::collections::HashMap;
+
+use tera::Tera;
+
+use config::Config;
+use front_matter::InsertAnchor;
+
+
+/// All the information from the gutenberg site that is needed to render HTML from markdown
+#[derive(Debug)]
+pub struct Context<'a> {
+ pub tera: &'a Tera,
+ pub highlight_code: bool,
+ pub highlight_theme: String,
+ pub permalinks: &'a HashMap,
+ pub insert_anchor: InsertAnchor,
+}
+
+impl<'a> Context<'a> {
+ pub fn new(tera: &'a Tera, config: &'a Config, permalinks: &'a HashMap, insert_anchor: InsertAnchor) -> Context<'a> {
+ Context {
+ tera,
+ permalinks,
+ insert_anchor,
+ highlight_code: config.highlight_code.unwrap(),
+ highlight_theme: config.highlight_theme.clone().unwrap(),
+ }
+ }
+
+ pub fn should_insert_anchor(&self) -> bool {
+ self.insert_anchor != InsertAnchor::None
+ }
+}
diff --git a/src/rendering/markdown.rs b/src/rendering/markdown.rs
index bc93cdf3..5e18a4b7 100644
--- a/src/rendering/markdown.rs
+++ b/src/rendering/markdown.rs
@@ -1,5 +1,4 @@
use std::borrow::Cow::Owned;
-use std::collections::HashMap;
use pulldown_cmark as cmark;
use self::cmark::{Parser, Event, Tag, Options, OPTION_ENABLE_TABLES, OPTION_ENABLE_FOOTNOTES};
@@ -9,11 +8,12 @@ use syntect::dumps::from_binary;
use syntect::easy::HighlightLines;
use syntect::parsing::SyntaxSet;
use syntect::html::{start_coloured_html_snippet, styles_to_coloured_html, IncludeBackground};
-use tera::{Tera, Context};
+use tera::{Context as TeraContext};
-use config::Config;
use errors::{Result};
use site::resolve_internal_link;
+use front_matter::InsertAnchor;
+use rendering::context::Context;
use rendering::highlighting::THEME_SET;
use rendering::short_code::{ShortCode, parse_shortcode, render_simple_shortcode};
@@ -36,18 +36,18 @@ lazy_static!{
};
}
-pub fn markdown_to_html(content: &str, permalinks: &HashMap, tera: &Tera, config: &Config) -> Result {
+
+pub fn markdown_to_html(content: &str, context: &Context) -> Result {
// We try to be smart about highlighting code as it can be time-consuming
// If the global config disables it, then we do nothing. However,
// if we see a code block in the content, we assume that this page needs
// to be highlighted. It could potentially have false positive if the content
// has ``` in it but that seems kind of unlikely
- let should_highlight = if config.highlight_code.unwrap() {
+ let should_highlight = if context.highlight_code {
content.contains("```")
} else {
false
};
- let highlight_theme = config.highlight_theme.clone().unwrap();
// Set while parsing
let mut error = None;
let mut highlighter: Option = None;
@@ -105,7 +105,7 @@ pub fn markdown_to_html(content: &str, permalinks: &HashMap, ter
if shortcode_block.is_none() && text.starts_with("{{") && text.ends_with("}}") && SHORTCODE_RE.is_match(&text) {
let (name, args) = parse_shortcode(&text);
added_shortcode = true;
- match render_simple_shortcode(tera, &name, &args) {
+ match render_simple_shortcode(context.tera, &name, &args) {
Ok(s) => return Event::Html(Owned(format!("
{}", s))),
Err(e) => {
error = Some(e);
@@ -131,7 +131,7 @@ pub fn markdown_to_html(content: &str, permalinks: &HashMap, ter
if let Some(ref mut shortcode) = shortcode_block {
if text.trim() == "{% end %}" {
added_shortcode = true;
- match shortcode.render(tera) {
+ match shortcode.render(context.tera) {
Ok(s) => return Event::Html(Owned(format!("{}", s))),
Err(e) => {
error = Some(e);
@@ -151,15 +151,20 @@ pub fn markdown_to_html(content: &str, permalinks: &HashMap, ter
}
let id = find_anchor(&anchors, slugify(&text), 0);
anchors.push(id.clone());
- let anchor_link = if config.insert_anchor_links.unwrap() {
- let mut context = Context::new();
- context.add("id", &id);
- tera.render("anchor-link.html", &context).unwrap()
+ let anchor_link = if context.should_insert_anchor() {
+ let mut c = TeraContext::new();
+ c.add("id", &id);
+ context.tera.render("anchor-link.html", &c).unwrap()
} else {
String::new()
};
header_already_inserted = true;
- return Event::Html(Owned(format!(r#"id="{}">{}{}"#, id, anchor_link, text)));
+ let event = match context.insert_anchor {
+ InsertAnchor::Left => Event::Html(Owned(format!(r#"id="{}">{}{}"#, id, anchor_link, text))),
+ InsertAnchor::Right => Event::Html(Owned(format!(r#"id="{}">{}{}"#, id, text, anchor_link))),
+ InsertAnchor::None => Event::Html(Owned(format!(r#"id="{}">{}"#, id, text)))
+ };
+ return event;
}
// Business as usual
@@ -170,7 +175,7 @@ pub fn markdown_to_html(content: &str, permalinks: &HashMap, ter
if !should_highlight {
return Event::Html(Owned("
".to_owned()));
}
- let theme = &THEME_SET.themes[&highlight_theme];
+ let theme = &THEME_SET.themes[&context.highlight_theme];
let syntax = info
.split(' ')
.next()
@@ -195,7 +200,7 @@ pub fn markdown_to_html(content: &str, permalinks: &HashMap, ter
return Event::Html(Owned("".to_owned()));
}
if link.starts_with("./") {
- match resolve_internal_link(link, permalinks) {
+ match resolve_internal_link(link, context.permalinks) {
Ok(url) => {
return Event::Start(Tag::Link(Owned(url), title.clone()));
},
@@ -268,46 +273,33 @@ pub fn markdown_to_html(content: &str, permalinks: &HashMap, ter
mod tests {
use std::collections::HashMap;
- use templates::GUTENBERG_TERA;
use tera::Tera;
use config::Config;
- use super::{markdown_to_html, parse_shortcode};
+ use front_matter::InsertAnchor;
+ use templates::GUTENBERG_TERA;
+ use rendering::context::Context;
- #[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");
- }
+ use super::markdown_to_html;
#[test]
fn can_do_markdown_to_html_simple() {
- let res = markdown_to_html("hello", &HashMap::new(), &Tera::default(), &Config::default()).unwrap();
+ let tera_ctx = Tera::default();
+ let permalinks_ctx = HashMap::new();
+ let config_ctx = Config::default();
+ let context = Context::new(&tera_ctx, &config_ctx, &permalinks_ctx, InsertAnchor::None);
+ let res = markdown_to_html("hello", &context).unwrap();
assert_eq!(res, "
hello
\n");
}
#[test]
fn doesnt_highlight_code_block_with_highlighting_off() {
- let mut config = Config::default();
- config.highlight_code = Some(false);
- let res = markdown_to_html("```\n$ gutenberg server\n```", &HashMap::new(), &Tera::default(), &config).unwrap();
+ let tera_ctx = Tera::default();
+ let permalinks_ctx = HashMap::new();
+ let config_ctx = Config::default();
+ let mut context = Context::new(&tera_ctx, &config_ctx, &permalinks_ctx, InsertAnchor::None);
+ context.highlight_code = false;
+ let res = markdown_to_html("```\n$ gutenberg server\n```", &context).unwrap();
assert_eq!(
res,
"
$ gutenberg server\n
\n"
@@ -316,7 +308,11 @@ mod tests {
#[test]
fn can_highlight_code_block_no_lang() {
- let res = markdown_to_html("```\n$ gutenberg server\n$ ping\n```", &HashMap::new(), &Tera::default(), &Config::default()).unwrap();
+ let tera_ctx = Tera::default();
+ let permalinks_ctx = HashMap::new();
+ let config_ctx = Config::default();
+ let context = Context::new(&tera_ctx, &config_ctx, &permalinks_ctx, InsertAnchor::None);
+ let res = markdown_to_html("```\n$ gutenberg server\n$ ping\n```", &context).unwrap();
assert_eq!(
res,
"
\n$ gutenberg server\n$ ping\n
"
@@ -325,7 +321,11 @@ mod tests {
#[test]
fn can_highlight_code_block_with_lang() {
- let res = markdown_to_html("```python\nlist.append(1)\n```", &HashMap::new(), &Tera::default(), &Config::default()).unwrap();
+ let tera_ctx = Tera::default();
+ let permalinks_ctx = HashMap::new();
+ let config_ctx = Config::default();
+ let context = Context::new(&tera_ctx, &config_ctx, &permalinks_ctx, InsertAnchor::None);
+ let res = markdown_to_html("```python\nlist.append(1)\n```", &context).unwrap();
assert_eq!(
res,
"
\nlist.append(1)\n
"
@@ -334,7 +334,11 @@ mod tests {
#[test]
fn can_higlight_code_block_with_unknown_lang() {
- let res = markdown_to_html("```yolo\nlist.append(1)\n```", &HashMap::new(), &Tera::default(), &Config::default()).unwrap();
+ let tera_ctx = Tera::default();
+ let permalinks_ctx = HashMap::new();
+ let config_ctx = Config::default();
+ let context = Context::new(&tera_ctx, &config_ctx, &permalinks_ctx, InsertAnchor::None);
+ let res = markdown_to_html("```yolo\nlist.append(1)\n```", &context).unwrap();
// defaults to plain text
assert_eq!(
res,
@@ -344,17 +348,23 @@ mod tests {
#[test]
fn can_render_shortcode() {
+ let permalinks_ctx = HashMap::new();
+ let config_ctx = Config::default();
+ let context = Context::new(&GUTENBERG_TERA, &config_ctx, &permalinks_ctx, InsertAnchor::None);
let res = markdown_to_html(r#"
Hello
{{ youtube(id="ub36ffWAqgQ") }}
- "#, &HashMap::new(), &GUTENBERG_TERA, &Config::default()).unwrap();
+ "#, &context).unwrap();
assert!(res.contains("