mirror of
https://github.com/rust-lang/mdBook
synced 2024-12-14 14:52:37 +00:00
Merge pull request #206 from frewsxcv/serde
Bump serde, serde_json, and handlebars crates.
This commit is contained in:
commit
f3fb1f1e16
7 changed files with 53 additions and 51 deletions
|
@ -16,9 +16,9 @@ exclude = [
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.19.2"
|
clap = "2.19.2"
|
||||||
handlebars = { version = "0.23.0", features = ["serde_type"] }
|
handlebars = { version = "0.25.0", features = ["serde_type"] }
|
||||||
serde = "0.8"
|
serde = "0.9"
|
||||||
serde_json = "0.8"
|
serde_json = "0.9"
|
||||||
pulldown-cmark = "0.0.8"
|
pulldown-cmark = "0.0.8"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
env_logger = "0.3"
|
env_logger = "0.3"
|
||||||
|
|
|
@ -214,9 +214,9 @@ pub fn json_value_to_toml_value(json: serde_json::Value) -> toml::Value {
|
||||||
match json {
|
match json {
|
||||||
serde_json::Value::Null => toml::Value::String("".to_string()),
|
serde_json::Value::Null => toml::Value::String("".to_string()),
|
||||||
serde_json::Value::Bool(x) => toml::Value::Boolean(x),
|
serde_json::Value::Bool(x) => toml::Value::Boolean(x),
|
||||||
serde_json::Value::I64(x) => toml::Value::Integer(x),
|
serde_json::Value::Number(ref x) if x.is_i64() => toml::Value::Integer(x.as_i64().unwrap()),
|
||||||
serde_json::Value::U64(x) => toml::Value::Integer(x as i64),
|
serde_json::Value::Number(ref x) if x.is_u64() => toml::Value::Integer(x.as_i64().unwrap()),
|
||||||
serde_json::Value::F64(x) => toml::Value::Float(x),
|
serde_json::Value::Number(x) => toml::Value::Float(x.as_f64().unwrap()),
|
||||||
serde_json::Value::String(x) => toml::Value::String(x),
|
serde_json::Value::String(x) => toml::Value::String(x),
|
||||||
serde_json::Value::Array(x) => {
|
serde_json::Value::Array(x) => {
|
||||||
toml::Value::Array(x.iter().map(|v| json_value_to_toml_value(v.to_owned())).collect())
|
toml::Value::Array(x.iter().map(|v| json_value_to_toml_value(v.to_owned())).collect())
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use serde::{Serialize, Serializer};
|
use serde::{Serialize, Serializer};
|
||||||
|
use serde::ser::SerializeStruct;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -36,11 +37,11 @@ impl Chapter {
|
||||||
|
|
||||||
|
|
||||||
impl Serialize for Chapter {
|
impl Serialize for Chapter {
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
||||||
let mut state = try!(serializer.serialize_struct("Chapter", 2));
|
let mut struct_ = try!(serializer.serialize_struct("Chapter", 2));
|
||||||
try!(serializer.serialize_struct_elt(&mut state, "name", self.name.clone()));
|
try!(struct_.serialize_field("name", &self.name));
|
||||||
try!(serializer.serialize_struct_elt(&mut state, "path", self.path.clone()));
|
try!(struct_.serialize_field("path", &self.path));
|
||||||
serializer.serialize_struct_end(state)
|
struct_.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
//! Make sure to take a look at it.
|
//! Make sure to take a look at it.
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
#[macro_use]
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate handlebars;
|
extern crate handlebars;
|
||||||
extern crate pulldown_cmark;
|
extern crate pulldown_cmark;
|
||||||
|
|
|
@ -13,7 +13,6 @@ use std::collections::BTreeMap;
|
||||||
use handlebars::Handlebars;
|
use handlebars::Handlebars;
|
||||||
|
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use serde_json::value::ToJson;
|
|
||||||
|
|
||||||
|
|
||||||
pub struct HtmlHandlebars;
|
pub struct HtmlHandlebars;
|
||||||
|
@ -84,10 +83,10 @@ impl Renderer for HtmlHandlebars {
|
||||||
// Update the context with data for this file
|
// Update the context with data for this file
|
||||||
let path = ch.path.to_str().ok_or(io::Error::new(io::ErrorKind::Other,
|
let path = ch.path.to_str().ok_or(io::Error::new(io::ErrorKind::Other,
|
||||||
"Could not convert path to str"))?;
|
"Could not convert path to str"))?;
|
||||||
data.insert("path".to_owned(), path.to_json());
|
data.insert("path".to_owned(), json!(path));
|
||||||
data.insert("content".to_owned(), content.to_json());
|
data.insert("content".to_owned(), json!(content));
|
||||||
data.insert("chapter_title".to_owned(), ch.name.to_json());
|
data.insert("chapter_title".to_owned(), json!(ch.name));
|
||||||
data.insert("path_to_root".to_owned(), utils::fs::path_to_root(&ch.path).to_json());
|
data.insert("path_to_root".to_owned(), json!(utils::fs::path_to_root(&ch.path)));
|
||||||
|
|
||||||
// Render the handlebars template with the data
|
// Render the handlebars template with the data
|
||||||
debug!("[*]: Render template");
|
debug!("[*]: Render template");
|
||||||
|
@ -128,9 +127,9 @@ impl Renderer for HtmlHandlebars {
|
||||||
// Print version
|
// Print version
|
||||||
|
|
||||||
// Update the context with data for this file
|
// Update the context with data for this file
|
||||||
data.insert("path".to_owned(), "print.md".to_json());
|
data.insert("path".to_owned(), json!("print.md"));
|
||||||
data.insert("content".to_owned(), print_content.to_json());
|
data.insert("content".to_owned(), json!(print_content));
|
||||||
data.insert("path_to_root".to_owned(), utils::fs::path_to_root(Path::new("print.md")).to_json());
|
data.insert("path_to_root".to_owned(), json!(utils::fs::path_to_root(Path::new("print.md"))));
|
||||||
|
|
||||||
// Render the handlebars template with the data
|
// Render the handlebars template with the data
|
||||||
debug!("[*]: Render template");
|
debug!("[*]: Render template");
|
||||||
|
@ -167,12 +166,12 @@ fn make_data(book: &MDBook) -> Result<serde_json::Map<String, serde_json::Value>
|
||||||
debug!("[fn]: make_data");
|
debug!("[fn]: make_data");
|
||||||
|
|
||||||
let mut data = serde_json::Map::new();
|
let mut data = serde_json::Map::new();
|
||||||
data.insert("language".to_owned(), "en".to_json());
|
data.insert("language".to_owned(), json!("en"));
|
||||||
data.insert("title".to_owned(), book.get_title().to_json());
|
data.insert("title".to_owned(), json!(book.get_title()));
|
||||||
data.insert("description".to_owned(), book.get_description().to_json());
|
data.insert("description".to_owned(), json!(book.get_description()));
|
||||||
data.insert("favicon".to_owned(), "favicon.png".to_json());
|
data.insert("favicon".to_owned(), json!("favicon.png"));
|
||||||
if let Some(livereload) = book.get_livereload() {
|
if let Some(livereload) = book.get_livereload() {
|
||||||
data.insert("livereload".to_owned(), livereload.to_json());
|
data.insert("livereload".to_owned(), json!(livereload));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut chapters = vec![];
|
let mut chapters = vec![];
|
||||||
|
@ -183,20 +182,20 @@ fn make_data(book: &MDBook) -> Result<serde_json::Map<String, serde_json::Value>
|
||||||
|
|
||||||
match *item {
|
match *item {
|
||||||
BookItem::Affix(ref ch) => {
|
BookItem::Affix(ref ch) => {
|
||||||
chapter.insert("name".to_owned(), ch.name.to_json());
|
chapter.insert("name".to_owned(), json!(ch.name));
|
||||||
let path = ch.path.to_str().ok_or(io::Error::new(io::ErrorKind::Other,
|
let path = ch.path.to_str().ok_or(io::Error::new(io::ErrorKind::Other,
|
||||||
"Could not convert path to str"))?;
|
"Could not convert path to str"))?;
|
||||||
chapter.insert("path".to_owned(), path.to_json());
|
chapter.insert("path".to_owned(), json!(path));
|
||||||
},
|
},
|
||||||
BookItem::Chapter(ref s, ref ch) => {
|
BookItem::Chapter(ref s, ref ch) => {
|
||||||
chapter.insert("section".to_owned(), s.to_json());
|
chapter.insert("section".to_owned(), json!(s));
|
||||||
chapter.insert("name".to_owned(), ch.name.to_json());
|
chapter.insert("name".to_owned(), json!(ch.name));
|
||||||
let path = ch.path.to_str().ok_or(io::Error::new(io::ErrorKind::Other,
|
let path = ch.path.to_str().ok_or(io::Error::new(io::ErrorKind::Other,
|
||||||
"Could not convert path to str"))?;
|
"Could not convert path to str"))?;
|
||||||
chapter.insert("path".to_owned(), path.to_json());
|
chapter.insert("path".to_owned(), json!(path));
|
||||||
},
|
},
|
||||||
BookItem::Spacer => {
|
BookItem::Spacer => {
|
||||||
chapter.insert("spacer".to_owned(), "_spacer_".to_json());
|
chapter.insert("spacer".to_owned(), json!("_spacer_"));
|
||||||
},
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -204,7 +203,7 @@ fn make_data(book: &MDBook) -> Result<serde_json::Map<String, serde_json::Value>
|
||||||
chapters.push(chapter);
|
chapters.push(chapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.insert("chapters".to_owned(), chapters.to_json());
|
data.insert("chapters".to_owned(), json!(chapters));
|
||||||
|
|
||||||
debug!("[*]: JSON constructed");
|
debug!("[*]: JSON constructed");
|
||||||
Ok(data)
|
Ok(data)
|
||||||
|
|
|
@ -2,22 +2,21 @@ use std::path::Path;
|
||||||
use std::collections::{VecDeque, BTreeMap};
|
use std::collections::{VecDeque, BTreeMap};
|
||||||
|
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use serde_json::value::ToJson;
|
use handlebars::{Handlebars, RenderError, RenderContext, Helper, Renderable};
|
||||||
use handlebars::{Handlebars, RenderError, RenderContext, Helper, Context, Renderable};
|
|
||||||
|
|
||||||
|
|
||||||
// Handlebars helper for navigation
|
// Handlebars helper for navigation
|
||||||
|
|
||||||
pub fn previous(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
pub fn previous(_h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
||||||
debug!("[fn]: previous (handlebars helper)");
|
debug!("[fn]: previous (handlebars helper)");
|
||||||
|
|
||||||
debug!("[*]: Get data from context");
|
debug!("[*]: Get data from context");
|
||||||
// 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 = c.navigate(rc.get_path(), &VecDeque::new(), "chapters");
|
let chapters = rc.context().navigate(rc.get_path(), &VecDeque::new(), "chapters").to_owned();
|
||||||
|
|
||||||
let current = c.navigate(rc.get_path(), &VecDeque::new(), "path")
|
let current = rc.context().navigate(rc.get_path(), &VecDeque::new(), "path")
|
||||||
.to_string()
|
.to_string()
|
||||||
.replace("\"", "");
|
.replace("\"", "");
|
||||||
|
|
||||||
|
@ -50,7 +49,7 @@ pub fn previous(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext
|
||||||
match previous.get("name") {
|
match previous.get("name") {
|
||||||
Some(n) => {
|
Some(n) => {
|
||||||
debug!("[*]: Inserting title: {}", n);
|
debug!("[*]: Inserting title: {}", n);
|
||||||
previous_chapter.insert("title".to_owned(), n.to_json())
|
previous_chapter.insert("title".to_owned(), json!(n))
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
debug!("[*]: No title found for chapter");
|
debug!("[*]: No title found for chapter");
|
||||||
|
@ -68,7 +67,7 @@ pub fn previous(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext
|
||||||
|
|
||||||
match path.to_str() {
|
match path.to_str() {
|
||||||
Some(p) => {
|
Some(p) => {
|
||||||
previous_chapter.insert("link".to_owned(), p.replace("\\", "/").to_json());
|
previous_chapter.insert("link".to_owned(), json!(p.replace("\\", "/")));
|
||||||
},
|
},
|
||||||
None => return Err(RenderError::new("Link could not be converted to str")),
|
None => return Err(RenderError::new("Link could not be converted to str")),
|
||||||
}
|
}
|
||||||
|
@ -78,13 +77,14 @@ pub fn previous(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext
|
||||||
|
|
||||||
debug!("[*]: Inject in context");
|
debug!("[*]: Inject in context");
|
||||||
// Inject in current context
|
// Inject in current context
|
||||||
let updated_context = c.extend(&previous_chapter);
|
let updated_context = rc.context().extend(&previous_chapter);
|
||||||
|
|
||||||
debug!("[*]: Render template");
|
debug!("[*]: Render template");
|
||||||
// Render template
|
// Render template
|
||||||
match _h.template() {
|
match _h.template() {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
try!(t.render(&updated_context, r, rc));
|
*rc.context_mut() = updated_context;
|
||||||
|
try!(t.render(r, rc));
|
||||||
},
|
},
|
||||||
None => return Err(RenderError::new("Error with the handlebars template")),
|
None => return Err(RenderError::new("Error with the handlebars template")),
|
||||||
}
|
}
|
||||||
|
@ -108,16 +108,16 @@ pub fn previous(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn next(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
pub fn next(_h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
||||||
debug!("[fn]: next (handlebars helper)");
|
debug!("[fn]: next (handlebars helper)");
|
||||||
|
|
||||||
debug!("[*]: Get data from context");
|
debug!("[*]: Get data from context");
|
||||||
// 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 = c.navigate(rc.get_path(), &VecDeque::new(), "chapters");
|
let chapters = rc.context().navigate(rc.get_path(), &VecDeque::new(), "chapters").to_owned();
|
||||||
|
|
||||||
let current = c.navigate(rc.get_path(), &VecDeque::new(), "path")
|
let current = rc.context().navigate(rc.get_path(), &VecDeque::new(), "path")
|
||||||
.to_string()
|
.to_string()
|
||||||
.replace("\"", "");
|
.replace("\"", "");
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ pub fn next(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext) ->
|
||||||
match item.get("name") {
|
match item.get("name") {
|
||||||
Some(n) => {
|
Some(n) => {
|
||||||
debug!("[*]: Inserting title: {}", n);
|
debug!("[*]: Inserting title: {}", n);
|
||||||
next_chapter.insert("title".to_owned(), n.to_json());
|
next_chapter.insert("title".to_owned(), json!(n));
|
||||||
},
|
},
|
||||||
None => return Err(RenderError::new("No title found for chapter in JSON data")),
|
None => return Err(RenderError::new("No title found for chapter in JSON data")),
|
||||||
}
|
}
|
||||||
|
@ -166,21 +166,22 @@ pub fn next(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext) ->
|
||||||
match link.to_str() {
|
match link.to_str() {
|
||||||
Some(l) => {
|
Some(l) => {
|
||||||
// Hack for windows who tends to use `\` as separator instead of `/`
|
// Hack for windows who tends to use `\` as separator instead of `/`
|
||||||
next_chapter.insert("link".to_owned(), l.replace("\\", "/").to_json());
|
next_chapter.insert("link".to_owned(), json!(l.replace("\\", "/")));
|
||||||
},
|
},
|
||||||
None => return Err(RenderError::new("Link could not converted to str")),
|
None => return Err(RenderError::new("Link could not converted to str")),
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("[*]: Inject in context");
|
debug!("[*]: Inject in context");
|
||||||
// Inject in current context
|
// Inject in current context
|
||||||
let updated_context = c.extend(&next_chapter);
|
let updated_context = rc.context().extend(&next_chapter);
|
||||||
|
|
||||||
debug!("[*]: Render template");
|
debug!("[*]: Render template");
|
||||||
|
|
||||||
// Render template
|
// Render template
|
||||||
match _h.template() {
|
match _h.template() {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
try!(t.render(&updated_context, r, rc));
|
*rc.context_mut() = updated_context;
|
||||||
|
try!(t.render(r, rc));
|
||||||
},
|
},
|
||||||
None => return Err(RenderError::new("Error with the handlebars template")),
|
None => return Err(RenderError::new("Error with the handlebars template")),
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::path::Path;
|
||||||
use std::collections::{VecDeque, BTreeMap};
|
use std::collections::{VecDeque, BTreeMap};
|
||||||
|
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use handlebars::{Handlebars, HelperDef, RenderError, RenderContext, Helper, Context};
|
use handlebars::{Handlebars, HelperDef, RenderError, RenderContext, Helper};
|
||||||
use pulldown_cmark::{Parser, html, Event, Tag};
|
use pulldown_cmark::{Parser, html, Event, Tag};
|
||||||
|
|
||||||
// Handlebars helper to construct TOC
|
// Handlebars helper to construct TOC
|
||||||
|
@ -10,13 +10,13 @@ use pulldown_cmark::{Parser, html, Event, Tag};
|
||||||
pub struct RenderToc;
|
pub struct RenderToc;
|
||||||
|
|
||||||
impl HelperDef for RenderToc {
|
impl HelperDef for RenderToc {
|
||||||
fn call(&self, c: &Context, _h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
fn call(&self, _h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
||||||
|
|
||||||
// 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 = c.navigate(rc.get_path(), &VecDeque::new(), "chapters");
|
let chapters = rc.context().navigate(rc.get_path(), &VecDeque::new(), "chapters").to_owned();
|
||||||
let current = c.navigate(rc.get_path(), &VecDeque::new(), "path").to_string().replace("\"", "");
|
let current = rc.context().navigate(rc.get_path(), &VecDeque::new(), "path").to_string().replace("\"", "");
|
||||||
try!(rc.writer.write("<ul class=\"chapter\">".as_bytes()));
|
try!(rc.writer.write("<ul class=\"chapter\">".as_bytes()));
|
||||||
|
|
||||||
// Decode json format
|
// Decode json format
|
||||||
|
|
Loading…
Reference in a new issue