From ef68fa084111813684243f1ef8ffc00131ddee49 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Wed, 28 Sep 2022 21:19:47 +0200 Subject: basic refs --- src/main.rs | 147 +++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file 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!( "{}{}", - 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) { +fn render_nodes(html: &mut String, refs: &mut Vec, nodes: &Vec) { for n in nodes { - render_node(html, n) + render_node(html, refs, n) } } -fn render_nodes_to_string(nodes: Vec) -> String { + +fn render_nodes_to_string(nodes: &Vec, refs: &mut Vec) -> 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, 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, "{}", - render_nodes_to_string(nodes) + render_nodes_to_string(nodes, refs) ) .unwrap(), parse_wiki_text::Node::HorizontalDivider { .. } => write!(html, "
").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, + "{}", + 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, + "
    {}
", + items + .iter() + .map(|e| format!("
  • {}
  • ", render_nodes_to_string(&e.nodes, refs))) + .collect::>() + .join("") + ) + .unwrap(), + parse_wiki_text::Node::UnorderedList { items, .. } => write!( + html, + "
      {}
    ", + items + .iter() + .map(|e| format!("
  • {}
  • ", render_nodes_to_string(&e.nodes, refs))) + .collect::>() + .join("") + ) + .unwrap(), + parse_wiki_text::Node::ParagraphBreak { .. } => write!(html, "

    ").unwrap(), + parse_wiki_text::Node::Parameter { default, name, .. } => { + write!(html, "[todo: parameter]").unwrap() + } parse_wiki_text::Node::Preformatted { nodes, .. } => { - write!(html, "

    {}
    ", render_nodes_to_string(nodes)).unwrap() + write!(html, "
    {}
    ", 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: {}", + 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, "[{}]", 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, + name: &str, + params: &Vec, +) { + use std::fmt::Write; + match name { + "lang" => write!(html, "{}", render_nodes_to_string(¶ms[1].value, refs)).unwrap(), + "IPA" => write!( + html, + "{}", + 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) { + use std::fmt::Write; + write!(html, "
      ").unwrap(); + for (i, r) in refs.iter().enumerate() { + write!(html, "
    1. {r}
    2. ", i + 1).unwrap() + } + write!(html, "
    ").unwrap(); +} -- cgit v1.2.3-70-g09d2