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, "- {r}
", i + 1).unwrap()
+ }
+ write!(html, "
").unwrap();
+}
--
cgit v1.2.3-70-g09d2