aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs96
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("&", "&amp;")
.replace("<", "&lt;")
@@ -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>,