1
0
Fork 0
mirror of https://github.com/lise-henry/crowbook synced 2024-06-01 22:16:30 +02:00

added a toc module

This commit is contained in:
Elisabeth Henry 2016-02-24 19:13:59 +01:00
parent 55e9458256
commit 0a19bb7929
4 changed files with 123 additions and 1 deletions

View File

@ -141,7 +141,7 @@ impl<'a> HtmlRenderer<'a> {
}
}
///
/// Renders the HML of a chapter
pub fn render_html(&mut self, tokens: &[Token])-> String {
let mut res = String::new();
for token in tokens {

View File

@ -30,6 +30,7 @@ pub mod book;
pub mod epub;
pub mod latex;
pub mod odt;
pub mod toc;
pub use book::Book;
pub use error::{Result, Error};
@ -39,6 +40,7 @@ pub use html::HtmlRenderer;
pub use epub::EpubRenderer;
pub use latex::LatexRenderer;
pub use odt::OdtRenderer;
pub use toc::Toc;
mod zipper;
mod templates;

90
src/lib/toc.rs Normal file
View File

@ -0,0 +1,90 @@
use std::iter;
/// A structure for manipulating Table Of Content
pub struct Toc {
elements: Vec<TocElement>
}
impl Toc {
/// Create a new, empty, Toc
pub fn new() -> Toc {
Toc {
elements: vec!(),
}
}
/// Adds an element
pub fn add(&mut self, level: i32, url: String, title: String) {
let element = TocElement::new(level, url, title);
self.elements.push(element);
}
/// Render the Toc
pub fn render(&self) -> String {
let mut output = String::new();
let mut x = 0;
let mut level = 0;
output.push_str(&self.render_vec(&mut x, &mut level));
for i in (0..level).rev() {
output.push_str(&format!("{}</ul>",
iter::repeat(' ').take(i as usize).collect::<String>()));
}
output
}
fn render_vec(&self, x: &mut usize, level: &mut i32) -> String {
let orig_level = *level;
let mut content = String::new();
while *x < self.elements.len() {
let elem = &self.elements[*x];
if elem.level <= orig_level {
return content
}
*x += 1;
if elem.level > *level {
for i in *level..elem.level {
content.push_str(&format!("{}<ul>\n",
iter::repeat(' ').take(i as usize).collect::<String>()));
*level = elem.level;
}
} else if elem.level < *level {
*level = elem.level;
}
let spaces:String = iter::repeat(' ').take(elem.level as usize).collect();
content.push_str(&format!("{}<li>{}\n", spaces, elem.title));
content.push_str(&self.render_vec(x, level));
for i in (elem.level..*level).rev() {
content.push_str(&format!("{}</ul>\n",
iter::repeat(' ').take(i as usize).collect::<String>()));
}
content.push_str(&format!("{}</li>\n", spaces));
}
content
}
}
struct TocElement {
level: i32,
url: String,
title: String,
}
impl TocElement {
pub fn new(level: i32, url: String, title: String) -> TocElement {
TocElement {
level: level,
url: url,
title: title,
}
}
}

30
tests/toc.rs Normal file
View File

@ -0,0 +1,30 @@
extern crate crowbook;
use crowbook::Toc;
mod test_helper;
use test_helper::test_eq;
#[test]
fn toc_simple() {
let mut toc = Toc::new();
toc.add(1, String::new(), "0".to_owned());
toc.add(1, String::new(), "1".to_owned());
toc.add(3, String::new(), "1.0.1".to_owned());
toc.add(1, String::new(), "2".to_owned());
let actual = toc.render();
let expected = "<ul>
<li>0
</li>
<li>1
<ul>
<ul>
<li>1.0.1
</li>
</ul>
</ul>
</li>
<li>2
</li>
</ul>";
test_eq(&actual, expected);
}