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:
parent
55e9458256
commit
0a19bb7929
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue