diff --git a/src/loader/summary.rs b/src/loader/summary.rs index ef5586ae..776583ea 100644 --- a/src/loader/summary.rs +++ b/src/loader/summary.rs @@ -218,18 +218,19 @@ impl<'a> SummaryParser<'a> { } fn step(&mut self) -> Result<()> { - let next_event = self.stream.next().expect("TODO: error-chain"); + if let Some(next_event) = self.stream.next() { trace!("[*] Current state: {:?}, next event: {:?}", self.state, next_event); match self.state { State::Begin => self.step_start(next_event)?, State::PrefixChapters => self.step_prefix(next_event)?, State::NumberedChapters(n) => self.step_numbered(next_event, n)?, - other => { - trace!("[*] unimplemented state: {:?}", other); - trace!("{:#?}", self.summary); - unimplemented!() - } + State::SuffixChapters => self.step_suffix(next_event)?, + State::End => {}, + } + } else { + trace!("[*] Reached end of SUMMARY.md"); + self.state = State::End; } Ok(()) @@ -300,6 +301,35 @@ impl<'a> SummaryParser<'a> { } } + fn step_suffix(&mut self, event: Event<'a>) -> Result<()> { + // FIXME: This has been copy/pasted from step_prefix. make DRY. + match event { + Event::Start(Tag::Link(location, _)) => { + let content = collect_events!(self.stream, Tag::Link(_, _)); + let text = stringify_events(content); + let link = Link { + name: text, + location: PathBuf::from(location.as_ref()), + number: None, + nested_items: Vec::new(), + }; + + debug!("[*] Found a suffix chapter, {:?}", link.name); + self.summary.suffix_chapters.push(SummaryItem::Link(link)); + }, + Event::End(Tag::Rule) => { + debug!("[*] Found a suffix chapter separator"); + self.summary.suffix_chapters.push(SummaryItem::Separator); + }, + other => { + trace!("[*] Skipping unexpected token in summary: {:?}", other); + }, + } + + Ok(()) + } + + /// Parse a single item (`[Some Chapter Name](./path/to/chapter.md)`). fn parse_item(&mut self) -> Result { let next = self.stream.next(); @@ -377,7 +407,8 @@ impl<'a> SummaryParser<'a> { fn push_numbered_section(&mut self, item: SummaryItem) -> SectionNumber { if let State::NumberedChapters(level) = self.state { push_item_at_nesting_level(&mut self.summary.numbered_chapters, item, level as usize) - .chain_err(|| "The parser should always ensure we add the next item at the correct level") + .chain_err(|| format!("The parser should always ensure we add the next \ + item at the correct level ({}:{})", module_path!(), line!())) .unwrap() } else { // this method should only ever be called when parsing a numbered diff --git a/tests/loading.rs b/tests/loading.rs index fed0cf04..c4aef503 100644 --- a/tests/loading.rs +++ b/tests/loading.rs @@ -1,5 +1,7 @@ //! Integration tests for loading a book into memory +#[macro_use] +extern crate pretty_assertions; extern crate mdbook; extern crate env_logger; @@ -7,7 +9,7 @@ use std::path::PathBuf; use mdbook::loader::{parse_summary, Link, SummaryItem, SectionNumber, Summary}; -const SUMMARY: &str = " +const SUMMARY: &'static str = " # Summary [Introduction](/intro.md) @@ -16,7 +18,7 @@ const SUMMARY: &str = " [A Prefix Chapter](/some_prefix.md) -- [First chapter](/chapter_1/index.md) +- [First Chapter](/chapter_1/index.md) - [Some Subsection](/chapter_1/subsection.md) ---