diff options
-rw-r--r-- | src/main.rs | 96 |
1 files changed, 64 insertions, 32 deletions
diff --git a/src/main.rs b/src/main.rs index 2b6c3f6..eb2f70f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,7 +51,7 @@ fn main() { Some(model) => model == "wikitext", } { - let filename = title_to_filename(&page.title); + let filename = urlencode(&page.title); let ast = parse_wiki_text::Configuration::default().parse(&page.text); if args.verbose { @@ -59,14 +59,15 @@ fn main() { eprintln!("wikitext warning: {}", w.message.message()) } } - + use std::fmt::Write; let mut refs = vec![]; - let mut inner = render_nodes_to_string(&ast.nodes, &mut refs); - render_refs(&mut inner, &refs); - let html = format!( - "<!DOCTYPE html><html><head><title>{}</title></head><body>{}</body></html>", - page.title, inner, - ); + let mut html = String::from("<!DOCTYPE html><html><head>"); + write!(&mut html, "<title>{}</title></head>", escape(&page.title)).unwrap(); + write!(&mut html, "<body><h1>{}</h1>", escape(&page.title)).unwrap(); + render_toc(&mut html, &ast.nodes); + render_nodes(&mut html, &mut refs, &ast.nodes); + render_refs(&mut html, &refs); + write!(&mut html, "</body></html>").unwrap(); if args.tar { let mut header = Header::new_gnu(); @@ -91,10 +92,9 @@ fn main() { archive.finish().unwrap(); } -fn title_to_filename(t: &str) -> String { +fn urlencode(t: &str) -> String { t.replace("/", "_") } - pub fn escape(text: &str) -> String { text.replace("&", "&") .replace("<", "<") @@ -121,32 +121,34 @@ fn render_node(html: &mut String, refs: &mut Vec<String>, n: &Node) { parse_wiki_text::Node::Bold { .. } => (), parse_wiki_text::Node::BoldItalic { .. } => (), parse_wiki_text::Node::Category { - ordinal, target, .. + ordinal: _, + target: _, + .. } => write!(html, "[todo]").unwrap(), - parse_wiki_text::Node::CharacterEntity { character, .. } => { + parse_wiki_text::Node::CharacterEntity { character: _, .. } => { write!(html, "[todo: character]").unwrap() } parse_wiki_text::Node::Comment { .. } => (), - parse_wiki_text::Node::DefinitionList { items, .. } => { + parse_wiki_text::Node::DefinitionList { items: _, .. } => { write!(html, "[todo: def list]").unwrap() } - parse_wiki_text::Node::EndTag { name, .. } => write!(html, "[todo: tag end]").unwrap(), - parse_wiki_text::Node::ExternalLink { nodes, .. } => { + parse_wiki_text::Node::EndTag { name: _, .. } => write!(html, "[todo: tag end]").unwrap(), + parse_wiki_text::Node::ExternalLink { nodes: _, .. } => { write!(html, "[todo: external link]").unwrap() } - parse_wiki_text::Node::Heading { level, nodes, .. } => write!( - html, - "<h{level}>{}</h{level}>", - render_nodes_to_string(nodes, refs) - ) - .unwrap(), + parse_wiki_text::Node::Heading { level, nodes, .. } => { + let h = render_nodes_to_string(nodes, refs); + write!(html, "<h{level} id=\"{}\">{}</h{level}>", urlencode(&h), h).unwrap(); + } parse_wiki_text::Node::HorizontalDivider { .. } => write!(html, "<hr>").unwrap(), - parse_wiki_text::Node::Image { target, text, .. } => write!(html, "[todo: image]").unwrap(), + parse_wiki_text::Node::Image { + target: _, text: _, .. + } => write!(html, "[todo: image]").unwrap(), parse_wiki_text::Node::Italic { .. } => (), parse_wiki_text::Node::Link { target, text, .. } => write!( html, "<a href=\"{}\">{}</a>", - title_to_filename(target), // TODO does this always link to wikipedia? + urlencode(target), // TODO does this always link to wikipedia? render_nodes_to_string(text, refs) ) .unwrap(), @@ -172,24 +174,28 @@ fn render_node(html: &mut String, refs: &mut Vec<String>, n: &Node) { ) .unwrap(), parse_wiki_text::Node::ParagraphBreak { .. } => write!(html, "</p><p>").unwrap(), - parse_wiki_text::Node::Parameter { default, name, .. } => { - write!(html, "[todo: parameter]").unwrap() - } + parse_wiki_text::Node::Parameter { + default: _, + name: _, + .. + } => write!(html, "[todo: parameter]").unwrap(), parse_wiki_text::Node::Preformatted { nodes, .. } => { write!(html, "<pre>{}</pre>", render_nodes_to_string(nodes, refs)).unwrap() } parse_wiki_text::Node::Redirect { target, .. } => write!( html, "Redirect: <a href=\"{}\">{}</a>", - title_to_filename(target), - title_to_filename(target) + urlencode(target), + urlencode(target) ) .unwrap(), - parse_wiki_text::Node::StartTag { name, .. } => write!(html, "[todo: start tag]").unwrap(), + parse_wiki_text::Node::StartTag { name: _, .. } => { + write!(html, "[todo: start tag]").unwrap() + } parse_wiki_text::Node::Table { - attributes, - captions, - rows, + attributes: _, + captions: _, + rows: _, .. } => write!(html, "[todo: table]").unwrap(), parse_wiki_text::Node::Tag { name, nodes, .. } => match name.as_ref() { @@ -216,6 +222,32 @@ fn render_node(html: &mut String, refs: &mut Vec<String>, n: &Node) { } } +fn render_toc(html: &mut String, nodes: &Vec<Node>) { + use std::fmt::Write; + write!(html, "<div><h4><i>Table of contents</i></h4>").unwrap(); + let mut k = 0; + for n in nodes { + match n { + Node::Heading { level, nodes, .. } => { + let level = *level as usize; + while k < level { + k += 1; + write!(html, "<ol>").unwrap(); + } + while k > level { + k -= 1; + write!(html, "</ol>").unwrap(); + } + let h = render_nodes_to_string(nodes, &mut vec![]); + + write!(html, "<li><a href=\"#{}\">{}</a></li>", urlencode(&h), h).unwrap(); + } + _ => (), + } + } + write!(html, "</div>").unwrap(); +} + pub fn render_template( html: &mut String, refs: &mut Vec<String>, |