chapter.content, .src_path, .dest_path

This commit is contained in:
Gambhiro 2017-01-13 17:01:59 +00:00
parent da9c57e6f5
commit 0713d49e7b
9 changed files with 383 additions and 208 deletions

View File

@ -16,6 +16,8 @@ pub struct BookConfig {
// Paths
// TODO test if dest and src behaves correctly when mdbook.dest_base and mdbook.src_base is not 'book' and 'src'
pub dest: PathBuf,
pub src: PathBuf,
@ -84,9 +86,9 @@ impl BookConfig {
conf
}
/// Parses recognized keys from a BTreeMap one by one. Not trying to
/// directly de-serialize to `BookConfig` so that we can provide some
/// convenient shorthands for the user.
/// Parses keys from a BTreeMap one by one. Not trying to directly
/// de-serialize to `BookConfig` so that we can provide some convenient
/// shorthands for the user.
///
/// `book.toml` is a user interface, not an app data store, we never have to
/// write data back to it.

View File

@ -3,6 +3,7 @@ extern crate toml;
use regex::Regex;
use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use std::fs::File;
use std::error::Error;
@ -40,18 +41,30 @@ pub struct Chapter {
/// The title of the chapter.
pub title: String,
/// The Markdown content of the chapter without the optional TOML header.
pub content: Option<String>,
/// Path to the chapter's markdown file, relative to the book's source
/// directory.
///
/// `book.src.join(chapter.path)` points to the Markdown file, and
/// `book.dest.join(chapter.path).with_extension("html")` points to the
/// output html file. This way if the user had a custom folder structure in
/// their source folder, this is re-created in the destination folder.
pub path: PathBuf,
/// Use `.content` to access the Markdown text when possible, instead of
/// reading the Markdown file with `.src_path`.
///
/// `book.get_src_base().join(chapter.get_src_path())` should point to the
/// Markdown file.
///
/// This way if the user had a custom folder structure in their source
/// folder, this is re-created in the destination folder.
///
/// When this is `None`, the chapter is treated as as draft. An output file
/// is not rendered, but it appears in the TOC grayed out.
src_path: Option<PathBuf>,
/// Optional destination path to write to. Used when changing the first
/// chapter's path to index.html.
pub dest_path: Option<PathBuf>,
/// Destination path to write to, relative to the book's source directory.
///
/// `book.get_dest_base().join(chapter.get_dest_path())` should point to the
/// output HTML file.
dest_path: Option<PathBuf>,
/// Links to the corresponding translations.
pub translation_links: Option<Vec<TranslationLink>>,
@ -65,6 +78,8 @@ pub struct Chapter {
/// The description of the chapter.
pub description: Option<String>,
/// TODO use this in the template
/// CSS class that will be added to the page-level wrap div to allow
/// customized chapter styles.
pub css_class: Option<String>,
@ -74,7 +89,8 @@ impl Default for Chapter {
fn default() -> Chapter {
Chapter {
title: "Untitled".to_string(),
path: PathBuf::from("src".to_string()).join("untitled.md"),
content: None,
src_path: None,
dest_path: None,
translation_links: None,
authors: None,
@ -87,10 +103,18 @@ impl Default for Chapter {
impl Chapter {
pub fn new(title: String, path: PathBuf) -> Chapter {
pub fn new(title: String, src_path: PathBuf) -> Chapter {
let mut chapter = Chapter::default();
chapter.title = title;
chapter.path = path;
if src_path.as_os_str().len() > 0 {
chapter.src_path = Some(src_path.clone());
chapter.dest_path = Some(src_path.clone().with_extension("html"));
} else {
chapter.src_path = None;
chapter.dest_path = None;
}
chapter
}
@ -98,39 +122,43 @@ impl Chapter {
debug!("[fn] Chapter::parse_or_create() : {:?}", &self);
let src_path = &book_src_dir.join(&self.path).to_owned();
if !src_path.exists() {
debug!("[*] Creating: {:?}", src_path);
match create_with_str(src_path, &format!("# {}", self.title)) {
Ok(_) => { return Ok(self); },
Err(e) => {
return Err(format!("Could not create: {:?}", src_path));
},
}
}
let mut text = String::new();
match File::open(src_path) {
Err(e) => { return Err(format!("Read error: {:?}", e)); },
Ok(mut f) => {
f.read_to_string(&mut text);
}
}
let re: Regex = Regex::new(r"(?ms)^\+\+\+\n(?P<toml>.*)\n\+\+\+\n").unwrap();
match re.captures(&text) {
Some(caps) => {
let toml = caps.name("toml").unwrap();
match utils::toml_str_to_btreemap(&toml) {
Ok(x) => {self.parse_from_btreemap(&x);},
if let Some(p) = self.get_src_path() {
let src_path = &book_src_dir.join(&p).to_owned();
if !src_path.exists() {
debug!("[*] Creating: {:?}", src_path);
match create_with_str(src_path, &format!("# {}", self.title)) {
Ok(_) => { return Ok(self); },
Err(e) => {
error!("[*] Errors while parsing TOML: {:?}", e);
return Err(e);
}
return Err(format!("Could not create: {:?}", src_path));
},
}
}
None => {},
let mut text = String::new();
match File::open(src_path) {
Err(e) => { return Err(format!("Read error: {:?}", e)); },
Ok(mut f) => {
// TODO try! here and return error
f.read_to_string(&mut text);
self.content = Some(utils::strip_toml_header(&text));
}
}
let re: Regex = Regex::new(r"(?ms)^\+\+\+\n(?P<toml>.*)\n\+\+\+\n").unwrap();
match re.captures(&text) {
Some(caps) => {
let toml = caps.name("toml").unwrap();
match utils::toml_str_to_btreemap(&toml) {
Ok(x) => {self.parse_from_btreemap(&x);},
Err(e) => {
error!("[*] Errors while parsing TOML: {:?}", e);
return Err(e);
}
}
}
None => {},
}
}
Ok(self)
@ -199,33 +227,67 @@ impl Chapter {
self
}
/// FIXME chapter content should be read when parsing SUMMARY.md so that you
/// don't have to pass around the Book struct for getting the src dir
// TODO not being used?
/// Reads in the chapter's content from the markdown file. Chapter doesn't
/// know the book's src folder, hence the `book_src_dir` argument.
pub fn read_content_using(&self, book_src_dir: &PathBuf) -> Result<String, Box<Error>> {
// /// Reads in the chapter's content from the markdown file. Chapter doesn't
// /// know the book's src folder, hence the `book_src_dir` argument.
// pub fn read_content_using(&self, book_src_dir: &PathBuf) -> Result<String, Box<Error>> {
// let p = match self.get_src_path() {
// Some(x) => x,
// None => {
// return Err(Box::new(io::Error::new(
// io::ErrorKind::Other,
// format!("src_path is None"))
// ));
// }
// };
let src_path = book_src_dir.join(&self.path);
// let src_path = book_src_dir.join(&p);
if !src_path.exists() {
return Err(Box::new(io::Error::new(
io::ErrorKind::Other,
format!("Doesn't exist: {:?}", src_path))
));
// if !src_path.exists() {
// return Err(Box::new(io::Error::new(
// io::ErrorKind::Other,
// format!("Doesn't exist: {:?}", src_path))
// ));
// }
// debug!("[*]: Opening file: {:?}", src_path);
// let mut f = try!(File::open(&src_path));
// let mut content: String = String::new();
// debug!("[*]: Reading file");
// try!(f.read_to_string(&mut content));
// content = utils::strip_toml_header(&content);
// Ok(content)
// }
pub fn get_src_path(&self) -> Option<PathBuf> {
self.src_path.clone()
}
pub fn set_src_path(&mut self, path: PathBuf) -> &mut Chapter {
if path.as_os_str() == OsStr::new(".") {
self.src_path = Some(PathBuf::from("".to_string()));
} else {
self.src_path = Some(path.to_owned());
}
self
}
debug!("[*]: Opening file: {:?}", src_path);
pub fn get_dest_path(&self) -> Option<PathBuf> {
self.dest_path.clone()
}
let mut f = try!(File::open(&src_path));
let mut content: String = String::new();
debug!("[*]: Reading file");
try!(f.read_to_string(&mut content));
content = utils::strip_toml_header(&content);
Ok(content)
pub fn set_dest_path(&mut self, path: PathBuf) -> &mut Chapter {
if path.as_os_str() == OsStr::new(".") {
self.dest_path = Some(PathBuf::from("".to_string()));
} else {
self.dest_path = Some(path.to_owned());
}
self
}
}

View File

@ -39,7 +39,7 @@ pub struct MDBook {
template_dir: PathBuf,
/// Input base for all books, relative to `project_root`. Defaults to `src`.
src_base: PathBuf,// FIXME use this
src_base: PathBuf,
/// Output base for all books, relative to `project_root`. Defaults to
/// `book`.
@ -262,6 +262,11 @@ impl MDBook {
config.remove("project_root");
}
if let Some(a) = config.get("src_base") {
self.set_src_base(&PathBuf::from(&a.to_string()));
}
config.remove("src_base");
if let Some(a) = config.get("dest_base") {
self.set_dest_base(&PathBuf::from(&a.to_string()));
}
@ -300,6 +305,9 @@ impl MDBook {
// keys to the default source and destination folder such as `/src/en`
// and `./book/en`. This may be overridden if set specifically.
// TODO if no is_main_book = true was set in the config, find the first
// translation (as in the config) and mark it as the main.
if let Some(a) = config.get("translations") {
if let Some(b) = a.as_table() {

View File

@ -134,12 +134,12 @@ backmatter."#;
let i = match item {
TocItem::Numbered(mut content) => {
found_first = true;
content.chapter.dest_path = Some(PathBuf::from("index.html".to_string()));
content.chapter.set_dest_path(PathBuf::from("index.html".to_string()));
TocItem::Numbered(content)
},
TocItem::Unnumbered(mut content) => {
found_first = true;
content.chapter.dest_path = Some(PathBuf::from("index.html".to_string()));
content.chapter.set_dest_path(PathBuf::from("index.html".to_string()));
TocItem::Unnumbered(content)
},
TocItem::Unlisted(content) => {

View File

@ -45,6 +45,7 @@ impl Renderer for HtmlHandlebars {
//try!(utils::fs::remove_dir_content(&book_project.get_dest_base()));
// TODO talk to the user
try!(self.render(&book_project));
Ok(())
@ -190,18 +191,11 @@ impl Renderer for HtmlHandlebars {
TocItem::Unnumbered(ref i) |
TocItem::Unlisted(ref i) => {
let mut chapter: Chapter = i.chapter.clone();
chapter.dest_path = Some(PathBuf::from("index.html".to_string()));
chapter.set_dest_path(PathBuf::from("index.html".to_string()));
// almost the same as process_chapter(), but we have to
// manipulate path_to_root in data and rendered_path
let mut content = try!(chapter.read_content_using(&book.config.src));
// Parse for playpen links
if let Some(p) = book.config.get_src().join(&chapter.path).parent() {
content = helpers::playpen::render_playpen(&content, p);
}
let mut data = try!(make_data(&book, &chapter, &book_project.livereload_script));
data.remove("path_to_root");
@ -211,7 +205,7 @@ impl Renderer for HtmlHandlebars {
debug!("[*]: Render template");
let rendered_content = try!(handlebars.render("page", &data));
let p = chapter.dest_path.unwrap();
let p = chapter.get_dest_path().unwrap();
let rendered_path = &book_project.get_dest_base().join(&p);
debug!("[*]: Create file {:?}", rendered_path);
@ -230,38 +224,14 @@ impl Renderer for HtmlHandlebars {
try!(self.process_items(&book.toc, &book, &book_project.livereload_script, &handlebars));
// Write print.html
// FIXME chapter should have its content so that we don't have to duplicate process_chapter() here
if let Some(mut content) = self.collect_print_content_markdown(&book.toc, &book) {
if let Some(content) = self.collect_print_content_markdown(&book.toc, &book) {
let mut chapter: Chapter = Chapter::new(book.config.title.to_owned(), PathBuf::from(""));
chapter.dest_path = Some(PathBuf::from("print.html"));
chapter.set_dest_path(PathBuf::from("print.html"));
chapter.content = Some(content);
// FIXME this is process_chapter() except we replace content in data
let mut data = try!(make_data(&book, &chapter, &None));
content = utils::render_markdown(&content);
if let Some(p) = book.config.get_src().join(&chapter.path).parent() {
content = helpers::playpen::render_playpen(&content, p);
}
data.remove("content");
data.insert("content".to_owned(), content.to_json());
let rendered_content = try!(handlebars.render("page", &data));
let p = match chapter.dest_path.clone() {
Some(x) => x,
None => chapter.path.with_extension("html")
};
let rendered_path = &book.config.get_dest().join(&p);
let mut file = try!(utils::fs::create_file(rendered_path));
try!(file.write_all(&rendered_content.into_bytes()));
try!(self.process_chapter(&chapter, &book, &None, &handlebars));
}
}
@ -283,13 +253,7 @@ impl HtmlHandlebars {
TocItem::Numbered(ref i) |
TocItem::Unnumbered(ref i) |
TocItem::Unlisted(ref i) => {
// FIXME chapters with path "" are interpreted as draft now,
// not rendered here, and displayed gray in the TOC. Either
// path should be instead an Option or all chapter output
// should be used from setting dest_path, which is already
// Option but currently only used for rendering a chapter as
// index.html.
if i.chapter.path.as_os_str().len() > 0 {
if let Some(_) = i.chapter.get_dest_path() {
try!(self.process_chapter(&i.chapter, book, livereload_script, handlebars));
}
@ -313,10 +277,8 @@ impl HtmlHandlebars {
TocItem::Numbered(ref i) |
TocItem::Unnumbered(ref i) |
TocItem::Unlisted(ref i) => {
if i.chapter.path.as_os_str().len() > 0 {
if let Ok(x) = i.chapter.read_content_using(&book.config.src) {
text.push_str(&x);
}
if let Some(content) = i.chapter.content.clone() {
text.push_str(&content);
}
if let Some(ref subs) = i.sub_items {
@ -351,9 +313,14 @@ impl HtmlHandlebars {
debug!("[*]: Render template");
let rendered_content = try!(handlebars.render("page", &data));
let p = match chapter.dest_path.clone() {
let p = match chapter.get_dest_path() {
Some(x) => x,
None => chapter.path.with_extension("html")
None => {
return Err(Box::new(io::Error::new(
io::ErrorKind::Other,
format!("process_chapter(), dest_path is None: {:#?}", chapter))
));
}
};
let rendered_path = &book.config.get_dest().join(&p);
@ -391,47 +358,50 @@ fn make_data(book: &Book,
// Chapter data
let mut path = if let Some(ref dest_path) = chapter.dest_path {
PathBuf::from(dest_path)
} else {
chapter.path.clone()
};
if book.config.is_multilang && path.as_os_str().len() > 0 {
let p = PathBuf::from(&book.config.language.code);
path = p.join(path);
}
match path.to_str() {
Some(p) => {
data.insert("path".to_owned(), p.to_json());
match chapter.get_dest_path() {
Some(mut path) => {
if book.config.is_multilang {
path = PathBuf::from(&book.config.language.code).join(&path);
}
match path.to_str() {
Some(p) => {
data.insert("path".to_owned(), p.to_json());
data.insert("path_to_root".to_owned(), utils::fs::path_to_root(&path).to_json());
},
None => {
return Err(Box::new(io::Error::new(
io::ErrorKind::Other,
"Could not convert path to str")
))
},
}
},
None => {
return Err(Box::new(io::Error::new(
io::ErrorKind::Other,
"Could not convert path to str")
))
},
format!("make_data(), dest_path is None: {:#?}", chapter))
));
}
}
match chapter.read_content_using(&book.config.src) {
Ok(mut content) => {
match chapter.content.clone() {
Some(mut content) => {
content = utils::render_markdown(&content);
// Parse for playpen links
if let Some(p) = book.config.get_src().join(&chapter.path).parent() {
content = helpers::playpen::render_playpen(&content, p);
if let Some(a) = chapter.get_src_path() {
if let Some(p) = book.config.get_src().join(&a).parent() {
content = helpers::playpen::render_playpen(&content, p);
}
}
data.insert("content".to_owned(), content.to_json());
},
Err(e) => {
debug!("Couldn't read chapter content: {:#?}", e);
None => {
debug!("Chapter has dest_path but doesn't have content: {:#?}", chapter);
},
}
data.insert("path_to_root".to_owned(), utils::fs::path_to_root(&path).to_json());
if let Some(ref links) = chapter.translation_links {
data.insert("translation_links".to_owned(), links.to_json());
}
@ -473,48 +443,47 @@ fn items_to_chapters(items: &Vec<TocItem>, book: &Book)
fn process_chapter_and_subs(i: &TocContent, book: &Book)
-> Result<Vec<serde_json::Map<String, serde_json::Value>>, Box<Error>> {
let mut chapters = vec![];
let mut chapters_data = vec![];
// Create the data to inject in the template
let mut chapter = serde_json::Map::new();
let ch = &i.chapter;
let mut data = serde_json::Map::new();
let chapter = &i.chapter;
if let Some(_) = i.section {
let s = i.section_as_string();
chapter.insert("section".to_owned(), s.to_json());
data.insert("section".to_owned(), s.to_json());
}
chapter.insert("title".to_owned(), ch.title.to_json());
data.insert("title".to_owned(), chapter.title.to_json());
let mut path = if let Some(ref dest_path) = ch.dest_path {
PathBuf::from(dest_path)
} else {
ch.path.clone()
};
if book.config.is_multilang && path.as_os_str().len() > 0 {
let p = PathBuf::from(&book.config.language.code);
path = p.join(path);
}
match path.to_str() {
Some(p) => {
chapter.insert("path".to_owned(), p.to_json());
},
None => {
return Err(Box::new(io::Error::new(
io::ErrorKind::Other,
"Could not convert path to str")
))
match chapter.get_dest_path() {
Some(mut path) => {
if book.config.is_multilang {
path = PathBuf::from(&book.config.language.code).join(&path);
}
match path.to_str() {
Some(p) => {
data.insert("path".to_owned(), p.to_json());
data.insert("path_to_root".to_owned(), utils::fs::path_to_root(&path).to_json());
},
None => {
return Err(Box::new(io::Error::new(
io::ErrorKind::Other,
"Could not convert path to str")
))
},
}
},
// is draft chapter
None => {}
}
chapters.push(chapter);
chapters_data.push(data);
if let Some(ref subs) = i.sub_items {
let mut sub_chs = try!(items_to_chapters(&subs, book));
chapters.append(&mut sub_chs);
chapters_data.append(&mut sub_chs);
}
Ok(chapters)
Ok(chapters_data)
}

View File

@ -18,5 +18,6 @@ fn it_parses_when_exists() {
// test that the author is parsed from the TOML header
expected.authors = Some(vec![Author::new("H.P. Lovecraft")]);
assert_eq!(format!("{:?}", result), format!("{:?}", expected));
assert!(result.content.unwrap().contains("Nemesis, 1917"));
assert_eq!(format!("{:?}", result.authors), format!("{:?}", expected.authors));
}

View File

@ -12,7 +12,7 @@ fn it_renders_multilanguage_book() {
let renderer = HtmlHandlebars::new();
if let Err(e) = renderer.build(&path) {
println!("{:#?}", e);
panic!("{:#?}", e);
}
let mut proj = MDBook::new(&path);
@ -29,22 +29,27 @@ fn it_renders_multilanguage_book() {
s = utils::fs::file_to_string(&chapter_path).unwrap();
assert!(s.contains("<title>Alice's Adventures in Wonderland</title>"));
assert!(s.contains("<h1>Alice's Adventures in Wonderland</h1>"));
assert!(s.contains("<base href=\"\">"));
// Test if each translation was rendered
chapter_path = book_path.join("tears.html");
s = utils::fs::file_to_string(&chapter_path).unwrap();
assert!(s.contains("<h1>The Pool of Tears</h1>"));
assert!(s.contains("<base href=\"../\">"));
assert!(s.contains("li><a href=\"en/tears.html\" class=\"active\"><strong>2.</strong> The Pool of Tears</a></li>"));
book_path = proj.translations.get("fr").unwrap().config.get_dest();
chapter_path = book_path.join("larmes.html");
s = utils::fs::file_to_string(&chapter_path).unwrap();
assert!(s.contains("<h1>La mare aux larmes</h1>"));
assert!(s.contains("<base href=\"../\">"));
book_path = proj.translations.get("hu").unwrap().config.get_dest();
chapter_path = book_path.join("konnyto.html");
s = utils::fs::file_to_string(&chapter_path).unwrap();
assert!(s.contains("<h1>Könnytó</h1>"));
assert!(s.contains("<base href=\"../\">"));
// Test if book's asset files were copied
@ -66,4 +71,21 @@ fn it_renders_multilanguage_book() {
assert!(s.contains("<a href=\"en/index.html\">en</a>"));
assert!(s.contains("<a href=\"hu/index.html\">hu</a>"));
assert!(s.contains("<a href=\"fr/index.html\">fr</a>"));
// Test if print.html is produced for each translations
book_path = proj.translations.get("en").unwrap().config.get_dest();
chapter_path = book_path.join("print.html");
s = utils::fs::file_to_string(&chapter_path).unwrap();
assert!(s.contains("<h1>The Pool of Tears</h1>"));
book_path = proj.translations.get("fr").unwrap().config.get_dest();
chapter_path = book_path.join("print.html");
s = utils::fs::file_to_string(&chapter_path).unwrap();
assert!(s.contains("<h1>La mare aux larmes</h1>"));
book_path = proj.translations.get("hu").unwrap().config.get_dest();
chapter_path = book_path.join("print.html");
s = utils::fs::file_to_string(&chapter_path).unwrap();
assert!(s.contains("<h1>Könnytó</h1>"));
}

View File

@ -107,6 +107,7 @@ indent_spaces = 2
[[translations.en]]
title = "Alice's Adventures in Wonderland"
author = "Lewis Carroll"
is_main_book = true
[[translations.hu]]
title = "Alice Csodaországban"
@ -141,6 +142,8 @@ name = "Kosztolányi Dezső"
conf.authors = vec![Author::new("Lewis Carroll")];
conf.src = expected.get_project_root().join("src").join("en");
conf.dest = expected.get_project_root().join("book").join("en");
conf.is_multilang = true;
conf.is_main_book = true;
let mut book = Book::default();
book.config = conf;
@ -155,6 +158,8 @@ name = "Kosztolányi Dezső"
conf.translators = Some(vec![Author::new("Kosztolányi Dezső")]);
conf.src = expected.get_project_root().join("src").join("hu");
conf.dest = expected.get_project_root().join("book").join("hu");
conf.is_multilang = true;
conf.is_main_book = false;
let mut book = Book::default();
book.config = conf;

View File

@ -38,10 +38,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "Introduction",
path: "misc/introduction.md",
content: None,
src_path: Some(
"misc/introduction.md"
),
dest_path: Some(
"index.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -55,8 +59,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "mdBook",
path: "README.md",
dest_path: None,
content: None,
src_path: Some(
"README.md"
),
dest_path: Some(
"README.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -74,8 +84,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "Command Line Tool",
path: "cli/cli-tool.md",
dest_path: None,
content: None,
src_path: Some(
"cli/cli-tool.md"
),
dest_path: Some(
"cli/cli-tool.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -87,8 +103,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "init",
path: "cli/init.md",
dest_path: None,
content: None,
src_path: Some(
"cli/init.md"
),
dest_path: Some(
"cli/init.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -107,8 +129,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "build",
path: "cli/build.md",
dest_path: None,
content: None,
src_path: Some(
"cli/build.md"
),
dest_path: Some(
"cli/build.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -127,8 +155,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "watch",
path: "cli/watch.md",
dest_path: None,
content: None,
src_path: Some(
"cli/watch.md"
),
dest_path: Some(
"cli/watch.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -147,8 +181,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "serve",
path: "cli/serve.md",
dest_path: None,
content: None,
src_path: Some(
"cli/serve.md"
),
dest_path: Some(
"cli/serve.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -167,8 +207,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "test",
path: "cli/test.md",
dest_path: None,
content: None,
src_path: Some(
"cli/test.md"
),
dest_path: Some(
"cli/test.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -196,8 +242,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "Format",
path: "format/format.md",
dest_path: None,
content: None,
src_path: Some(
"format/format.md"
),
dest_path: Some(
"format/format.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -209,8 +261,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "SUMMARY.md",
path: "format/summary.md",
dest_path: None,
content: None,
src_path: Some(
"format/summary.md"
),
dest_path: Some(
"format/summary.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -229,8 +287,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "Configuration",
path: "format/config.md",
dest_path: None,
content: None,
src_path: Some(
"format/config.md"
),
dest_path: Some(
"format/config.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -249,8 +313,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "Theme",
path: "format/theme/theme.md",
dest_path: None,
content: None,
src_path: Some(
"format/theme/theme.md"
),
dest_path: Some(
"format/theme/theme.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -262,8 +332,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "index.hbs",
path: "format/theme/index-hbs.md",
dest_path: None,
content: None,
src_path: Some(
"format/theme/index-hbs.md"
),
dest_path: Some(
"format/theme/index-hbs.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -283,8 +359,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "Syntax highlighting",
path: "format/theme/syntax-highlighting.md",
dest_path: None,
content: None,
src_path: Some(
"format/theme/syntax-highlighting.md"
),
dest_path: Some(
"format/theme/syntax-highlighting.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -314,8 +396,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "MathJax Support",
path: "format/mathjax.md",
dest_path: None,
content: None,
src_path: Some(
"format/mathjax.md"
),
dest_path: Some(
"format/mathjax.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -334,8 +422,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "Rust code specific features",
path: "format/rust.md",
dest_path: None,
content: None,
src_path: Some(
"format/rust.md"
),
dest_path: Some(
"format/rust.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -363,8 +457,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "Rust Library",
path: "lib/lib.md",
dest_path: None,
content: None,
src_path: Some(
"lib/lib.md"
),
dest_path: Some(
"lib/lib.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,
@ -383,8 +483,14 @@ fn it_parses_summary_to_tocitems() {
TocContent {
chapter: Chapter {
title: "Contributors",
path: "misc/contributors.md",
dest_path: None,
content: None,
src_path: Some(
"misc/contributors.md"
),
dest_path: Some(
"misc/contributors.html"
),
translation_links: None,
authors: None,
translators: None,
description: None,