Updated the call site for handlebars rendering
This commit is contained in:
parent
951c873df6
commit
867fbfec05
|
@ -4,7 +4,6 @@ use std::collections::BTreeMap;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use handlebars::{Context, Handlebars, Helper, RenderContext, RenderError, Renderable};
|
use handlebars::{Context, Handlebars, Helper, RenderContext, RenderError, Renderable};
|
||||||
|
|
||||||
|
|
||||||
type StringMap = BTreeMap<String, String>;
|
type StringMap = BTreeMap<String, String>;
|
||||||
|
|
||||||
/// Target for `find_chapter`.
|
/// Target for `find_chapter`.
|
||||||
|
@ -15,22 +14,23 @@ enum Target {
|
||||||
|
|
||||||
impl Target {
|
impl Target {
|
||||||
/// Returns target if found.
|
/// Returns target if found.
|
||||||
fn find(&self,
|
fn find(
|
||||||
base_path: &String,
|
&self,
|
||||||
current_path: &String,
|
base_path: &String,
|
||||||
current_item: &StringMap,
|
current_path: &String,
|
||||||
previous_item: &StringMap,
|
current_item: &StringMap,
|
||||||
) -> Result<Option<StringMap>, RenderError> {
|
previous_item: &StringMap,
|
||||||
|
) -> Result<Option<StringMap>, RenderError> {
|
||||||
match self {
|
match self {
|
||||||
&Target::Next => {
|
&Target::Next => {
|
||||||
let previous_path = previous_item.get("path").ok_or_else(|| {
|
let previous_path = previous_item
|
||||||
RenderError::new("No path found for chapter in JSON data")
|
.get("path")
|
||||||
})?;
|
.ok_or_else(|| RenderError::new("No path found for chapter in JSON data"))?;
|
||||||
|
|
||||||
if previous_path == base_path {
|
if previous_path == base_path {
|
||||||
return Ok(Some(current_item.clone()));
|
return Ok(Some(current_item.clone()));
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
&Target::Previous => {
|
&Target::Previous => {
|
||||||
if current_path == base_path {
|
if current_path == base_path {
|
||||||
|
@ -43,21 +43,18 @@ impl Target {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_chapter(
|
fn find_chapter(rc: &mut RenderContext, target: Target) -> Result<Option<StringMap>, RenderError> {
|
||||||
rc: &mut RenderContext,
|
|
||||||
target: Target
|
|
||||||
) -> Result<Option<StringMap>, RenderError> {
|
|
||||||
debug!("Get data from context");
|
debug!("Get data from context");
|
||||||
|
|
||||||
let chapters = rc.evaluate_absolute("chapters").and_then(|c| {
|
let chapters = rc.evaluate_absolute("chapters", true).and_then(|c| {
|
||||||
serde_json::value::from_value::<Vec<StringMap>>(c.clone())
|
serde_json::value::from_value::<Vec<StringMap>>(c.clone())
|
||||||
.map_err(|_| RenderError::new("Could not decode the JSON data"))
|
.map_err(|_| RenderError::new("Could not decode the JSON data"))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let base_path = rc.evaluate_absolute("path")?
|
let base_path = rc.evaluate_absolute("path", true)?
|
||||||
.as_str()
|
.as_str()
|
||||||
.ok_or_else(|| RenderError::new("Type error for `path`, string expected"))?
|
.ok_or_else(|| RenderError::new("Type error for `path`, string expected"))?
|
||||||
.replace("\"", "");
|
.replace("\"", "");
|
||||||
|
|
||||||
let mut previous: Option<StringMap> = None;
|
let mut previous: Option<StringMap> = None;
|
||||||
|
|
||||||
|
@ -78,7 +75,7 @@ fn find_chapter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(
|
fn render(
|
||||||
|
@ -91,18 +88,21 @@ fn render(
|
||||||
|
|
||||||
let mut context = BTreeMap::new();
|
let mut context = BTreeMap::new();
|
||||||
|
|
||||||
chapter.get("name")
|
chapter
|
||||||
.ok_or_else(|| RenderError::new("No title found for chapter in JSON data"))
|
.get("name")
|
||||||
.map(|name| context.insert("title".to_owned(), json!(name)))?;
|
.ok_or_else(|| RenderError::new("No title found for chapter in JSON data"))
|
||||||
|
.map(|name| context.insert("title".to_owned(), json!(name)))?;
|
||||||
|
|
||||||
chapter.get("path")
|
chapter
|
||||||
.ok_or_else(|| RenderError::new("No path found for chapter in JSON data"))
|
.get("path")
|
||||||
.and_then(|p| {
|
.ok_or_else(|| RenderError::new("No path found for chapter in JSON data"))
|
||||||
Path::new(p).with_extension("html")
|
.and_then(|p| {
|
||||||
.to_str()
|
Path::new(p)
|
||||||
.ok_or_else(|| RenderError::new("Link could not be converted to str"))
|
.with_extension("html")
|
||||||
.map(|p| context.insert("link".to_owned(), json!(p.replace("\\", "/"))))
|
.to_str()
|
||||||
})?;
|
.ok_or_else(|| RenderError::new("Link could not be converted to str"))
|
||||||
|
.map(|p| context.insert("link".to_owned(), json!(p.replace("\\", "/"))))
|
||||||
|
})?;
|
||||||
|
|
||||||
trace!("Render template");
|
trace!("Render template");
|
||||||
|
|
||||||
|
@ -138,14 +138,14 @@ pub fn next(_h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), R
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
static TEMPLATE: &'static str =
|
static TEMPLATE: &'static str =
|
||||||
"{{#previous}}{{title}}: {{link}}{{/previous}}|{{#next}}{{title}}: {{link}}{{/next}}";
|
"{{#previous}}{{title}}: {{link}}{{/previous}}|{{#next}}{{title}}: {{link}}{{/next}}";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_next_previous() {
|
fn test_next_previous() {
|
||||||
let data = json!({
|
let data = json!({
|
||||||
"name": "two",
|
"name": "two",
|
||||||
"path": "two.path",
|
"path": "two.path",
|
||||||
"chapters": [
|
"chapters": [
|
||||||
|
@ -164,18 +164,19 @@ mod tests {
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut h = Handlebars::new();
|
let mut h = Handlebars::new();
|
||||||
h.register_helper("previous", Box::new(previous));
|
h.register_helper("previous", Box::new(previous));
|
||||||
h.register_helper("next", Box::new(next));
|
h.register_helper("next", Box::new(next));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
h.template_render(TEMPLATE, &data).unwrap(),
|
h.render_template(TEMPLATE, &data).unwrap(),
|
||||||
"one: one.html|three: three.html");
|
"one: one.html|three: three.html"
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_first() {
|
fn test_first() {
|
||||||
let data = json!({
|
let data = json!({
|
||||||
"name": "one",
|
"name": "one",
|
||||||
"path": "one.path",
|
"path": "one.path",
|
||||||
"chapters": [
|
"chapters": [
|
||||||
|
@ -194,17 +195,18 @@ mod tests {
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut h = Handlebars::new();
|
let mut h = Handlebars::new();
|
||||||
h.register_helper("previous", Box::new(previous));
|
h.register_helper("previous", Box::new(previous));
|
||||||
h.register_helper("next", Box::new(next));
|
h.register_helper("next", Box::new(next));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
h.template_render(TEMPLATE, &data).unwrap(),
|
h.render_template(TEMPLATE, &data).unwrap(),
|
||||||
"|two: two.html");
|
"|two: two.html"
|
||||||
}
|
);
|
||||||
#[test]
|
}
|
||||||
fn test_last() {
|
#[test]
|
||||||
let data = json!({
|
fn test_last() {
|
||||||
|
let data = json!({
|
||||||
"name": "three",
|
"name": "three",
|
||||||
"path": "three.path",
|
"path": "three.path",
|
||||||
"chapters": [
|
"chapters": [
|
||||||
|
@ -223,12 +225,13 @@ mod tests {
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut h = Handlebars::new();
|
let mut h = Handlebars::new();
|
||||||
h.register_helper("previous", Box::new(previous));
|
h.register_helper("previous", Box::new(previous));
|
||||||
h.register_helper("next", Box::new(next));
|
h.register_helper("next", Box::new(next));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
h.template_render(TEMPLATE, &data).unwrap(),
|
h.render_template(TEMPLATE, &data).unwrap(),
|
||||||
"two: two.html|");
|
"two: two.html|"
|
||||||
}
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use pulldown_cmark::{html, Event, Parser, Tag};
|
||||||
// Handlebars helper to construct TOC
|
// Handlebars helper to construct TOC
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct RenderToc {
|
pub struct RenderToc {
|
||||||
pub no_section_label: bool
|
pub no_section_label: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HelperDef for RenderToc {
|
impl HelperDef for RenderToc {
|
||||||
|
@ -16,14 +16,14 @@ impl HelperDef for RenderToc {
|
||||||
// get value from context data
|
// get value from context data
|
||||||
// rc.get_path() is current json parent path, you should always use it like this
|
// rc.get_path() is current json parent path, you should always use it like this
|
||||||
// param is the key of value you want to display
|
// param is the key of value you want to display
|
||||||
let chapters = rc.evaluate_absolute("chapters").and_then(|c| {
|
let chapters = rc.evaluate_absolute("chapters", true).and_then(|c| {
|
||||||
serde_json::value::from_value::<Vec<BTreeMap<String, String>>>(c.clone())
|
serde_json::value::from_value::<Vec<BTreeMap<String, String>>>(c.clone())
|
||||||
.map_err(|_| RenderError::new("Could not decode the JSON data"))
|
.map_err(|_| RenderError::new("Could not decode the JSON data"))
|
||||||
})?;
|
})?;
|
||||||
let current = rc.evaluate_absolute("path")?
|
let current = rc.evaluate_absolute("path", true)?
|
||||||
.as_str()
|
.as_str()
|
||||||
.ok_or_else(|| RenderError::new("Type error for `path`, string expected"))?
|
.ok_or_else(|| RenderError::new("Type error for `path`, string expected"))?
|
||||||
.replace("\"", "");
|
.replace("\"", "");
|
||||||
|
|
||||||
rc.writer.write_all(b"<ol class=\"chapter\">")?;
|
rc.writer.write_all(b"<ol class=\"chapter\">")?;
|
||||||
|
|
||||||
|
@ -107,12 +107,12 @@ impl HelperDef for RenderToc {
|
||||||
|
|
||||||
// filter all events that are not inline code blocks
|
// filter all events that are not inline code blocks
|
||||||
let parser = Parser::new(name).filter(|event| match *event {
|
let parser = Parser::new(name).filter(|event| match *event {
|
||||||
Event::Start(Tag::Code) |
|
Event::Start(Tag::Code)
|
||||||
Event::End(Tag::Code) |
|
| Event::End(Tag::Code)
|
||||||
Event::InlineHtml(_) |
|
| Event::InlineHtml(_)
|
||||||
Event::Text(_) => true,
|
| Event::Text(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// render markdown to html
|
// render markdown to html
|
||||||
let mut markdown_parsed_name = String::with_capacity(name.len() * 3 / 2);
|
let mut markdown_parsed_name = String::with_capacity(name.len() * 3 / 2);
|
||||||
|
|
Loading…
Reference in New Issue