diff options
author | metamuffin <metamuffin@disroot.org> | 2022-09-28 21:19:47 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2022-09-28 21:19:47 +0200 |
commit | ef68fa084111813684243f1ef8ffc00131ddee49 (patch) | |
tree | df0669eab85403bca8d81b5fc333287a1cd84801 | |
parent | 1dd88ab0f7ce06fdd0dfe810c8985d17ac7126db (diff) | |
download | staticwiki-ef68fa084111813684243f1ef8ffc00131ddee49.tar staticwiki-ef68fa084111813684243f1ef8ffc00131ddee49.tar.bz2 staticwiki-ef68fa084111813684243f1ef8ffc00131ddee49.tar.zst |
basic refs
-rw-r--r-- | src/main.rs | 147 |
1 files changed, 121 insertions, 26 deletions
diff --git a/src/main.rs b/src/main.rs index e973048..2b6c3f6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use clap::Parser; -use parse_wiki_text::Node; +use parse_wiki_text::{Node, Parameter}; use std::fs::File; use std::io::{stdin, stdout, Read, Write}; use tar::Header; @@ -51,7 +51,7 @@ fn main() { Some(model) => model == "wikitext", } { - let filename = page.title.replace("/", "_"); + let filename = title_to_filename(&page.title); let ast = parse_wiki_text::Configuration::default().parse(&page.text); if args.verbose { @@ -60,10 +60,12 @@ fn main() { } } + 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, - render_nodes_to_string(ast.nodes) + page.title, inner, ); if args.tar { @@ -89,6 +91,10 @@ fn main() { archive.finish().unwrap(); } +fn title_to_filename(t: &str) -> String { + t.replace("/", "_") +} + pub fn escape(text: &str) -> String { text.replace("&", "&") .replace("<", "<") @@ -97,17 +103,19 @@ pub fn escape(text: &str) -> String { .replace("\"", """) } -fn render_nodes(html: &mut String, nodes: Vec<Node>) { +fn render_nodes(html: &mut String, refs: &mut Vec<String>, nodes: &Vec<Node>) { for n in nodes { - render_node(html, n) + render_node(html, refs, n) } } -fn render_nodes_to_string(nodes: Vec<Node>) -> String { + +fn render_nodes_to_string(nodes: &Vec<Node>, refs: &mut Vec<String>) -> String { let mut html = String::new(); - render_nodes(&mut html, nodes); + render_nodes(&mut html, refs, nodes); return html; } -fn render_node(html: &mut String, n: Node) { + +fn render_node(html: &mut String, refs: &mut Vec<String>, n: &Node) { use std::fmt::Write; match n { parse_wiki_text::Node::Bold { .. } => (), @@ -115,41 +123,128 @@ fn render_node(html: &mut String, n: Node) { parse_wiki_text::Node::Category { ordinal, target, .. } => write!(html, "[todo]").unwrap(), - parse_wiki_text::Node::CharacterEntity { character, .. } => write!(html, "[todo]").unwrap(), + parse_wiki_text::Node::CharacterEntity { character, .. } => { + write!(html, "[todo: character]").unwrap() + } parse_wiki_text::Node::Comment { .. } => (), - parse_wiki_text::Node::DefinitionList { items, .. } => write!(html, "[todo]").unwrap(), - parse_wiki_text::Node::EndTag { name, .. } => write!(html, "[todo]").unwrap(), - parse_wiki_text::Node::ExternalLink { nodes, .. } => write!(html, "[todo]").unwrap(), + 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, .. } => { + write!(html, "[todo: external link]").unwrap() + } parse_wiki_text::Node::Heading { level, nodes, .. } => write!( html, "<h{level}>{}</h{level}>", - render_nodes_to_string(nodes) + render_nodes_to_string(nodes, refs) ) .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::Italic { .. } => (), - parse_wiki_text::Node::Link { target, text, .. } => write!(html, "[todo]").unwrap(), - parse_wiki_text::Node::MagicWord { .. } => write!(html, "[todo]").unwrap(), - parse_wiki_text::Node::OrderedList { items, .. } => write!(html, "[todo]").unwrap(), - parse_wiki_text::Node::ParagraphBreak { .. } => write!(html, "[todo]").unwrap(), - parse_wiki_text::Node::Parameter { default, name, .. } => write!(html, "[todo]").unwrap(), + parse_wiki_text::Node::Link { target, text, .. } => write!( + html, + "<a href=\"{}\">{}</a>", + title_to_filename(target), // TODO does this always link to wikipedia? + render_nodes_to_string(text, refs) + ) + .unwrap(), + parse_wiki_text::Node::MagicWord { .. } => write!(html, "[todo: magic]").unwrap(), + parse_wiki_text::Node::OrderedList { items, .. } => write!( + html, + "<ol>{}</ol>", + items + .iter() + .map(|e| format!("<li>{}</li>", render_nodes_to_string(&e.nodes, refs))) + .collect::<Vec<_>>() + .join("") + ) + .unwrap(), + parse_wiki_text::Node::UnorderedList { items, .. } => write!( + html, + "<ul>{}</ul>", + items + .iter() + .map(|e| format!("<li>{}</li>", render_nodes_to_string(&e.nodes, refs))) + .collect::<Vec<_>>() + .join("") + ) + .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::Preformatted { nodes, .. } => { - write!(html, "<pre>{}</pre>", render_nodes_to_string(nodes)).unwrap() + write!(html, "<pre>{}</pre>", render_nodes_to_string(nodes, refs)).unwrap() } - parse_wiki_text::Node::Redirect { target, .. } => write!(html, "[todo]").unwrap(), - parse_wiki_text::Node::StartTag { name, .. } => write!(html, "[todo]").unwrap(), + parse_wiki_text::Node::Redirect { target, .. } => write!( + html, + "Redirect: <a href=\"{}\">{}</a>", + title_to_filename(target), + title_to_filename(target) + ) + .unwrap(), + parse_wiki_text::Node::StartTag { name, .. } => write!(html, "[todo: start tag]").unwrap(), parse_wiki_text::Node::Table { attributes, captions, rows, .. - } => write!(html, "[todo]").unwrap(), - parse_wiki_text::Node::Tag { name, nodes, .. } => write!(html, "[todo]").unwrap(), + } => write!(html, "[todo: table]").unwrap(), + parse_wiki_text::Node::Tag { name, nodes, .. } => match name.as_ref() { + "ref" => { + if !nodes.is_empty() { + let r = render_nodes_to_string(nodes, refs); + refs.push(r); + let refid = refs.len(); + write!(html, "<sup><a href=\"#{}\">[{}]</a></sup>", refid, refid).unwrap(); + } + } + _ => write!(html, "[todo: tag {name:?} template]").unwrap(), + }, parse_wiki_text::Node::Template { name, parameters, .. - } => write!(html, "[todo]").unwrap(), + } => { + let name = match name.first() { + Some(Node::Text { value, .. }) => value, + _ => panic!("no"), + }; + render_template(html, refs, name, parameters) + } parse_wiki_text::Node::Text { value, .. } => write!(html, "{}", escape(value)).unwrap(), - parse_wiki_text::Node::UnorderedList { items, .. } => write!(html, "[todo]").unwrap(), } } + +pub fn render_template( + html: &mut String, + refs: &mut Vec<String>, + name: &str, + params: &Vec<Parameter>, +) { + use std::fmt::Write; + match name { + "lang" => write!(html, "{}", render_nodes_to_string(¶ms[1].value, refs)).unwrap(), + "IPA" => write!( + html, + "<code>{}</code>", + render_nodes_to_string(¶ms[0].value, refs) + ) + .unwrap(), + + _ => { + write!(html, "[todo: {name:?} template]").unwrap(); + // eprintln!("unsupported template {name:?}"); + // eprintln!("{params:?}"); + } + } +} + +fn render_refs(html: &mut String, refs: &Vec<String>) { + use std::fmt::Write; + write!(html, "<ol>").unwrap(); + for (i, r) in refs.iter().enumerate() { + write!(html, "<li id=\"{}\">{r}</li>", i + 1).unwrap() + } + write!(html, "</ol>").unwrap(); +} |