make part titles another SummaryItem
This commit is contained in:
parent
b1ccb30220
commit
d0fe9bd41c
|
@ -31,12 +31,7 @@ fn create_missing(src_dir: &Path, summary: &Summary) -> Result<()> {
|
||||||
let mut items: Vec<_> = summary
|
let mut items: Vec<_> = summary
|
||||||
.prefix_chapters
|
.prefix_chapters
|
||||||
.iter()
|
.iter()
|
||||||
.chain(
|
.chain(summary.numbered_chapters.iter())
|
||||||
summary
|
|
||||||
.parts
|
|
||||||
.iter()
|
|
||||||
.flat_map(|part| part.numbered_chapters.iter()),
|
|
||||||
)
|
|
||||||
.chain(summary.suffix_chapters.iter())
|
.chain(summary.suffix_chapters.iter())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -212,24 +207,17 @@ pub(crate) fn load_book_from_disk<P: AsRef<Path>>(summary: &Summary, src_dir: P)
|
||||||
debug!("Loading the book from disk");
|
debug!("Loading the book from disk");
|
||||||
let src_dir = src_dir.as_ref();
|
let src_dir = src_dir.as_ref();
|
||||||
|
|
||||||
|
let prefix = summary.prefix_chapters.iter();
|
||||||
|
let numbered = summary.numbered_chapters.iter();
|
||||||
|
let suffix = summary.suffix_chapters.iter();
|
||||||
|
|
||||||
|
let summary_items = prefix.chain(numbered).chain(suffix);
|
||||||
|
|
||||||
let mut chapters = Vec::new();
|
let mut chapters = Vec::new();
|
||||||
|
|
||||||
for prefix_chapter in &summary.prefix_chapters {
|
for summary_item in summary_items {
|
||||||
chapters.push(load_summary_item(prefix_chapter, src_dir, Vec::new())?);
|
let chapter = load_summary_item(summary_item, src_dir, Vec::new())?;
|
||||||
}
|
chapters.push(chapter);
|
||||||
|
|
||||||
for part in &summary.parts {
|
|
||||||
if let Some(title) = &part.title {
|
|
||||||
chapters.push(BookItem::PartTitle(title.clone()));
|
|
||||||
}
|
|
||||||
|
|
||||||
for numbered_chapter in &part.numbered_chapters {
|
|
||||||
chapters.push(load_summary_item(numbered_chapter, src_dir, Vec::new())?);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for suffix_chapter in &summary.suffix_chapters {
|
|
||||||
chapters.push(load_summary_item(suffix_chapter, src_dir, Vec::new())?);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Book {
|
Ok(Book {
|
||||||
|
@ -243,11 +231,12 @@ fn load_summary_item<P: AsRef<Path> + Clone>(
|
||||||
src_dir: P,
|
src_dir: P,
|
||||||
parent_names: Vec<String>,
|
parent_names: Vec<String>,
|
||||||
) -> Result<BookItem> {
|
) -> Result<BookItem> {
|
||||||
match *item {
|
match item {
|
||||||
SummaryItem::Separator => Ok(BookItem::Separator),
|
SummaryItem::Separator => Ok(BookItem::Separator),
|
||||||
SummaryItem::Link(ref link) => {
|
SummaryItem::Link(ref link) => {
|
||||||
load_chapter(link, src_dir, parent_names).map(BookItem::Chapter)
|
load_chapter(link, src_dir, parent_names).map(BookItem::Chapter)
|
||||||
}
|
}
|
||||||
|
SummaryItem::PartTitle(title) => Ok(BookItem::PartTitle(title.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,7 +330,6 @@ impl Display for Chapter {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::book::summary::Part;
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use tempfile::{Builder as TempFileBuilder, TempDir};
|
use tempfile::{Builder as TempFileBuilder, TempDir};
|
||||||
|
|
||||||
|
@ -445,10 +433,7 @@ And here is some \
|
||||||
fn load_a_book_with_a_single_chapter() {
|
fn load_a_book_with_a_single_chapter() {
|
||||||
let (link, temp) = dummy_link();
|
let (link, temp) = dummy_link();
|
||||||
let summary = Summary {
|
let summary = Summary {
|
||||||
parts: vec![Part {
|
numbered_chapters: vec![SummaryItem::Link(link)],
|
||||||
title: None,
|
|
||||||
numbered_chapters: vec![SummaryItem::Link(link)],
|
|
||||||
}],
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let should_be = Book {
|
let should_be = Book {
|
||||||
|
@ -582,14 +567,12 @@ And here is some \
|
||||||
fn cant_load_chapters_with_an_empty_path() {
|
fn cant_load_chapters_with_an_empty_path() {
|
||||||
let (_, temp) = dummy_link();
|
let (_, temp) = dummy_link();
|
||||||
let summary = Summary {
|
let summary = Summary {
|
||||||
parts: vec![Part {
|
numbered_chapters: vec![SummaryItem::Link(Link {
|
||||||
title: None,
|
name: String::from("Empty"),
|
||||||
numbered_chapters: vec![SummaryItem::Link(Link {
|
location: Some(PathBuf::from("")),
|
||||||
name: String::from("Empty"),
|
..Default::default()
|
||||||
location: Some(PathBuf::from("")),
|
})],
|
||||||
..Default::default()
|
|
||||||
})],
|
|
||||||
}],
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -604,14 +587,11 @@ And here is some \
|
||||||
fs::create_dir(&dir).unwrap();
|
fs::create_dir(&dir).unwrap();
|
||||||
|
|
||||||
let summary = Summary {
|
let summary = Summary {
|
||||||
parts: vec![Part {
|
numbered_chapters: vec![SummaryItem::Link(Link {
|
||||||
title: None,
|
name: String::from("nested"),
|
||||||
numbered_chapters: vec![SummaryItem::Link(Link {
|
location: Some(dir),
|
||||||
name: String::from("nested"),
|
..Default::default()
|
||||||
location: Some(dir),
|
})],
|
||||||
..Default::default()
|
|
||||||
})],
|
|
||||||
}],
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -61,22 +61,11 @@ pub struct Summary {
|
||||||
/// Chapters before the main text (e.g. an introduction).
|
/// Chapters before the main text (e.g. an introduction).
|
||||||
pub prefix_chapters: Vec<SummaryItem>,
|
pub prefix_chapters: Vec<SummaryItem>,
|
||||||
/// The main numbered chapters of the book, broken into one or more possibly named parts.
|
/// The main numbered chapters of the book, broken into one or more possibly named parts.
|
||||||
pub parts: Vec<Part>,
|
pub numbered_chapters: Vec<SummaryItem>,
|
||||||
/// Items which come after the main document (e.g. a conclusion).
|
/// Items which come after the main document (e.g. a conclusion).
|
||||||
pub suffix_chapters: Vec<SummaryItem>,
|
pub suffix_chapters: Vec<SummaryItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A struct representing a "part" in the `SUMMARY.md`. This is a possibly-titled section with
|
|
||||||
/// numbered chapters in it.
|
|
||||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub struct Part {
|
|
||||||
/// An optional title for the `SUMMARY.md`, currently just ignored.
|
|
||||||
pub title: Option<String>,
|
|
||||||
|
|
||||||
/// The main chapters in the document.
|
|
||||||
pub numbered_chapters: Vec<SummaryItem>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A struct representing an entry in the `SUMMARY.md`, possibly with nested
|
/// A struct representing an entry in the `SUMMARY.md`, possibly with nested
|
||||||
/// entries.
|
/// entries.
|
||||||
///
|
///
|
||||||
|
@ -124,6 +113,8 @@ pub enum SummaryItem {
|
||||||
Link(Link),
|
Link(Link),
|
||||||
/// A separator (`---`).
|
/// A separator (`---`).
|
||||||
Separator,
|
Separator,
|
||||||
|
/// A part title.
|
||||||
|
PartTitle(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SummaryItem {
|
impl SummaryItem {
|
||||||
|
@ -246,7 +237,7 @@ impl<'a> SummaryParser<'a> {
|
||||||
let prefix_chapters = self
|
let prefix_chapters = self
|
||||||
.parse_affix(true)
|
.parse_affix(true)
|
||||||
.chain_err(|| "There was an error parsing the prefix chapters")?;
|
.chain_err(|| "There was an error parsing the prefix chapters")?;
|
||||||
let parts = self
|
let numbered_chapters = self
|
||||||
.parse_parts()
|
.parse_parts()
|
||||||
.chain_err(|| "There was an error parsing the numbered chapters")?;
|
.chain_err(|| "There was an error parsing the numbered chapters")?;
|
||||||
let suffix_chapters = self
|
let suffix_chapters = self
|
||||||
|
@ -256,7 +247,7 @@ impl<'a> SummaryParser<'a> {
|
||||||
Ok(Summary {
|
Ok(Summary {
|
||||||
title,
|
title,
|
||||||
prefix_chapters,
|
prefix_chapters,
|
||||||
parts,
|
numbered_chapters,
|
||||||
suffix_chapters,
|
suffix_chapters,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -295,7 +286,7 @@ impl<'a> SummaryParser<'a> {
|
||||||
Ok(items)
|
Ok(items)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_parts(&mut self) -> Result<Vec<Part>> {
|
fn parse_parts(&mut self) -> Result<Vec<SummaryItem>> {
|
||||||
let mut parts = vec![];
|
let mut parts = vec![];
|
||||||
|
|
||||||
// We want the section numbers to be continues through all parts.
|
// We want the section numbers to be continues through all parts.
|
||||||
|
@ -331,10 +322,10 @@ impl<'a> SummaryParser<'a> {
|
||||||
.parse_numbered(&mut root_items, &mut root_number)
|
.parse_numbered(&mut root_items, &mut root_number)
|
||||||
.chain_err(|| "There was an error parsing the numbered chapters")?;
|
.chain_err(|| "There was an error parsing the numbered chapters")?;
|
||||||
|
|
||||||
parts.push(Part {
|
if let Some(title) = title {
|
||||||
title,
|
parts.push(SummaryItem::PartTitle(title));
|
||||||
numbered_chapters,
|
}
|
||||||
});
|
parts.extend(numbered_chapters);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(parts)
|
Ok(parts)
|
||||||
|
@ -817,37 +808,30 @@ mod tests {
|
||||||
# Title 2\n- [Third](./third.md)\n\t- [Fourth](./fourth.md)";
|
# Title 2\n- [Third](./third.md)\n\t- [Fourth](./fourth.md)";
|
||||||
|
|
||||||
let should_be = vec![
|
let should_be = vec![
|
||||||
Part {
|
SummaryItem::Link(Link {
|
||||||
title: None,
|
name: String::from("First"),
|
||||||
numbered_chapters: vec![
|
location: Some(PathBuf::from("./first.md")),
|
||||||
SummaryItem::Link(Link {
|
number: Some(SectionNumber(vec![1])),
|
||||||
name: String::from("First"),
|
nested_items: Vec::new(),
|
||||||
location: Some(PathBuf::from("./first.md")),
|
}),
|
||||||
number: Some(SectionNumber(vec![1])),
|
SummaryItem::Link(Link {
|
||||||
nested_items: Vec::new(),
|
name: String::from("Second"),
|
||||||
}),
|
location: Some(PathBuf::from("./second.md")),
|
||||||
SummaryItem::Link(Link {
|
number: Some(SectionNumber(vec![2])),
|
||||||
name: String::from("Second"),
|
nested_items: Vec::new(),
|
||||||
location: Some(PathBuf::from("./second.md")),
|
}),
|
||||||
number: Some(SectionNumber(vec![2])),
|
SummaryItem::PartTitle(String::from("Title 2")),
|
||||||
nested_items: Vec::new(),
|
SummaryItem::Link(Link {
|
||||||
}),
|
name: String::from("Third"),
|
||||||
],
|
location: Some(PathBuf::from("./third.md")),
|
||||||
},
|
number: Some(SectionNumber(vec![3])),
|
||||||
Part {
|
nested_items: vec![SummaryItem::Link(Link {
|
||||||
title: Some(String::from("Title 2")),
|
name: String::from("Fourth"),
|
||||||
numbered_chapters: vec![SummaryItem::Link(Link {
|
location: Some(PathBuf::from("./fourth.md")),
|
||||||
name: String::from("Third"),
|
number: Some(SectionNumber(vec![3, 1])),
|
||||||
location: Some(PathBuf::from("./third.md")),
|
nested_items: Vec::new(),
|
||||||
number: Some(SectionNumber(vec![3])),
|
|
||||||
nested_items: vec![SummaryItem::Link(Link {
|
|
||||||
name: String::from("Fourth"),
|
|
||||||
location: Some(PathBuf::from("./fourth.md")),
|
|
||||||
number: Some(SectionNumber(vec![3, 1])),
|
|
||||||
nested_items: Vec::new(),
|
|
||||||
})],
|
|
||||||
})],
|
})],
|
||||||
},
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut parser = SummaryParser::new(src);
|
let mut parser = SummaryParser::new(src);
|
||||||
|
|
Loading…
Reference in New Issue