diff --git a/Cargo.lock b/Cargo.lock index df1a7b6..30208e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -472,7 +472,7 @@ dependencies = [ [[package]] name = "wikitext_simplified" version = "0.1.0" -source = "git+https://github.com/philpax/wikitext_simplified.git#1272ffc45b073467afbed9fb4ec0e9c8cf1ad2e7" +source = "git+https://github.com/philpax/wikitext_simplified.git#e637ff1bf6559c8ed01ea980c15041b42cea5ce5" dependencies = [ "parse-wiki-text-2", "serde", @@ -482,7 +482,7 @@ dependencies = [ [[package]] name = "wikitext_util" version = "0.1.0" -source = "git+https://github.com/philpax/wikitext_simplified.git#1272ffc45b073467afbed9fb4ec0e9c8cf1ad2e7" +source = "git+https://github.com/philpax/wikitext_simplified.git#e637ff1bf6559c8ed01ea980c15041b42cea5ce5" dependencies = [ "parse-wiki-text-2", ] diff --git a/src/main.rs b/src/main.rs index a178308..c1e56c2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,13 +6,16 @@ use std::{ }; use template::{TemplateToInstantiate, Templates}; -use wikitext_simplified::{WikitextSimplifiedNode, wikitext_util::parse_wiki_text_2}; +use wikitext_simplified::{WikitextSimplifiedNode, Spanned, wikitext_util::parse_wiki_text_2}; mod page_context; use page_context::PageContext; mod syntax; mod template; +mod util; + +use util::empty_spanned; const WIKI_DIRECTORY: &str = "wiki"; @@ -296,7 +299,8 @@ fn generate_wiki_folder( .map(|s| s.to_string()), ); - let document = if let [WikitextSimplifiedNode::Redirect { target }] = simplified.as_slice() + let document = if let [node] = simplified.as_slice() + && let WikitextSimplifiedNode::Redirect { target } = &node.value { redirect(&page_title_to_route_path(target).url_path()) } else { @@ -323,7 +327,7 @@ fn generate_wiki_folder( layout( &page_context.title, paxhtml::Element::from_iter(simplified.iter().map(|node| { - convert_wikitext_to_html(templates, pwt_configuration, node, &page_context) + convert_wikitext_to_html(templates, pwt_configuration, &node.value, &page_context) })), ) }; @@ -437,7 +441,7 @@ fn convert_wikitext_to_html( let attributes = templates.instantiate( pwt_configuration, TemplateToInstantiate::Node(WikitextSimplifiedNode::Fragment { - children: attributes.to_vec(), + children: attributes.iter().map(|n| empty_spanned(n.clone())).collect(), }), &[], page_context, @@ -455,7 +459,7 @@ fn convert_wikitext_to_html( let merged_text = attributes .iter() .filter_map(|node| { - if let WSN::Text { text } = node { + if let WSN::Text { text } = &node.value { Some(text.as_str()) } else { None @@ -478,29 +482,30 @@ fn convert_wikitext_to_html( pwt_configuration: &parse_wiki_text_2::Configuration, page_context: &PageContext, attributes_context: &str, - attributes: &Option>, + attributes: &Option>>, ) -> Vec { attributes - .as_deref() + .as_ref() .map(|attributes| { + let unwrapped: Vec = attributes.iter().map(|s| s.value.clone()).collect(); parse_attributes_from_wsn( templates, pwt_configuration, page_context, attributes_context, - attributes, + &unwrapped, ) }) .unwrap_or_default() } - let convert_children = |templates: &mut Templates, children: &[WikitextSimplifiedNode]| { + let convert_children = |templates: &mut Templates, children: &[Spanned]| { paxhtml::Element::from_iter( children .iter() - .skip_while(|node| matches!(node, WSN::ParagraphBreak | WSN::Newline)) + .skip_while(|node| matches!(node.value, WSN::ParagraphBreak | WSN::Newline)) .map(|node| { - convert_wikitext_to_html(templates, pwt_configuration, node, page_context) + convert_wikitext_to_html(templates, pwt_configuration, &node.value, page_context) }), ) }; @@ -591,7 +596,9 @@ fn convert_wikitext_to_html( }; // Get the code text - let code = if let [WSN::Text { text }] = children.as_slice() { + let code = if let [node] = children.as_slice() + && let WSN::Text { text } = &node.value + { text.trim() } else { // If not simple text, fall back to plain rendering @@ -642,13 +649,15 @@ fn convert_wikitext_to_html( let instantiated = templates.instantiate( pwt_configuration, TemplateToInstantiate::Node(WikitextSimplifiedNode::Fragment { - children: attributes.to_vec(), + children: attributes.iter().map(|n| empty_spanned(n.value.clone())).collect(), }), &[], page_context, ); if let WSN::Fragment { children } = instantiated { - if let Some(WSN::Text { text }) = children.first() { + if let Some(node) = children.first() + && let WSN::Text { text } = &node.value + { text.contains("class=") } else { false @@ -662,18 +671,19 @@ fn convert_wikitext_to_html( if !has_class_attr { // Add Tailwind table classes - modified_attributes.push(WSN::Text { + modified_attributes.push(empty_spanned(WSN::Text { text: " class=\"min-w-full divide-y divide-gray-200 border border-gray-300\"" .to_string(), - }); + })); } + let unwrapped_attributes: Vec = modified_attributes.iter().map(|s| s.value.clone()).collect(); let attributes = parse_attributes_from_wsn( templates, pwt_configuration, page_context, "main", - &modified_attributes, + &unwrapped_attributes, ); html! { @@ -703,12 +713,13 @@ fn convert_wikitext_to_html( .iter() .enumerate() .map(|(idx, row)| { + let unwrapped_row_attrs: Vec = row.attributes.iter().map(|s| s.value.clone()).collect(); let attributes = parse_attributes_from_wsn( templates, pwt_configuration, page_context, "row", - &row.attributes, + &unwrapped_row_attrs, ); let row_class = if idx % 2 == 0 { "bg-white" } else { "bg-gray-50" }; html! { diff --git a/src/template.rs b/src/template.rs index 9ebb73d..58100aa 100644 --- a/src/template.rs +++ b/src/template.rs @@ -6,6 +6,7 @@ use std::{ use wikitext_simplified::{TemplateParameter, WikitextSimplifiedNode, parse_wiki_text_2}; use crate::page_context::PageContext; +use crate::util::empty_spanned; /// Trait for loading wikitext template files pub trait TemplateLoader { @@ -137,7 +138,7 @@ impl<'a> Templates<'a> { cell.content = children; } other => { - cell.content = vec![other]; + cell.content = vec![empty_spanned(other)]; } } } @@ -146,7 +147,7 @@ impl<'a> Templates<'a> { } WSN::Fragment { children } => { for child in children { - self.reparse_table_cells(child, pwt_configuration, page_context); + self.reparse_table_cells(&mut child.value, pwt_configuration, page_context); } } _ => {} @@ -228,7 +229,7 @@ impl<'a> Templates<'a> { // Flatten single-child fragments to avoid nested structures match result { WSN::Fragment { children } if children.len() == 1 => { - children.into_iter().next().unwrap() + children.into_iter().next().unwrap().value } _ => result, } @@ -400,10 +401,11 @@ mod tests { // Verify the result is a table (possibly wrapped in a Fragment) let table_node = match &result { WikitextSimplifiedNode::Table { .. } => &result, - WikitextSimplifiedNode::Fragment { children } => children + WikitextSimplifiedNode::Fragment { children } => &children .iter() - .find(|node| matches!(node, WikitextSimplifiedNode::Table { .. })) - .expect("Fragment should contain a Table node"), + .find(|node| matches!(node.value, WikitextSimplifiedNode::Table { .. })) + .expect("Fragment should contain a Table node") + .value, _ => panic!( "Expected Table or Fragment with Table node, got {:?}", result @@ -496,7 +498,7 @@ mod tests { assert!( children .iter() - .any(|node| matches!(node, WikitextSimplifiedNode::Bold { .. })), + .any(|node| matches!(node.value, WikitextSimplifiedNode::Bold { .. })), "Template should be reparsed into Bold node through wikitext roundtrip" ); } diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..ef5acc6 --- /dev/null +++ b/src/util.rs @@ -0,0 +1,9 @@ +use wikitext_simplified::{Span, Spanned}; + +/// Helper to create a Spanned node with a default (empty) span +pub fn empty_spanned(value: T) -> Spanned { + Spanned { + value, + span: Span { start: 0, end: 0 }, + } +}