use crate::markdown::line::{Line, LineType};
use crate::utils::*;
use crate::consts::*;
pub fn render_toc(lines: &Vec<Line>, headers: &Vec<Line>) -> Vec<Line> {
let mut result = Vec::with_capacity(lines.len());
let toc = gen_toc(headers);
for ln in lines.iter() {
if ln.line_type == LineType::Tag && is_toc(&ln.content) {
result.push(toc.clone());
}
else {
result.push(ln.clone());
}
}
result
}
fn is_toc(content: &Vec<u16>) -> bool {
lowercase_and_remove_spaces(content) == into_v16("[[toc]]")
}
fn gen_toc(headers: &Vec<Line>) -> Line {
let mut result = Vec::with_capacity(headers.len());
result.push(into_v16("[[box]]\n[[center]][[big]]Table of Contents[[/big]][[/center]]\n[[left]]\n"));
for header in headers.iter() {
let (sharps, sharps_removed) = take_and_drop_while(&header.content, U16_SHARP);
let indents_removed = drop_while(&sharps_removed, U16_SPACE);
let line = vec![
vec![U16_SPACE; (sharps.len() - 1) * 2],
into_v16("- ["),
indents_removed.clone(),
into_v16("](#"),
remove_special_characters(&indents_removed),
into_v16(")\n")
].concat();
result.push(line);
}
result.push(into_v16("[[/left]]\n[[/box]]\n"));
Line {
line_type: LineType::Toc,
content: result.concat(),
indent: 0
}
}
pub fn collect_headers(lines: &Vec<Line>) -> Vec<Line> {
lines.iter().filter(|ln| ln.line_type == LineType::Header).map(|ln| ln.clone()).collect()
}