From 4dcec75db81400e3aa932378b9a53ea299f199b5 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Nov 2025 08:26:10 +0000 Subject: [PATCH 1/2] Update wikitext_simplified to latest version and fix Spanned wrapper Updated the wikitext_simplified dependency to the latest version which introduced the Spanned wrapper type for nodes to include source location information. Made the following changes: - Updated Cargo.lock with new wikitext_simplified commit (e637ff1b) - Added Spanned and Span imports to both main.rs and template.rs - Created helper function spanned() to wrap nodes with default spans - Updated pattern matching to access .value field on Spanned nodes - Modified children vectors to use Vec> - Updated function signatures to handle Spanned types correctly - Fixed all compilation errors related to the API changes All tests pass successfully. --- Cargo.lock | 4 ++-- src/main.rs | 52 ++++++++++++++++++++++++++++++++----------------- src/template.rs | 25 ++++++++++++++++-------- 3 files changed, 53 insertions(+), 28 deletions(-) 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..8cd440b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,15 @@ use std::{ }; use template::{TemplateToInstantiate, Templates}; -use wikitext_simplified::{WikitextSimplifiedNode, wikitext_util::parse_wiki_text_2}; +use wikitext_simplified::{WikitextSimplifiedNode, Spanned, Span, wikitext_util::parse_wiki_text_2}; + +/// Helper to create a Spanned node with a default (empty) span +fn spanned(value: T) -> Spanned { + Spanned { + value, + span: Span { start: 0, end: 0 }, + } +} mod page_context; use page_context::PageContext; @@ -296,7 +304,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 +332,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 +446,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| spanned(n.clone())).collect(), }), &[], page_context, @@ -455,7 +464,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 +487,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 +601,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 +654,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| 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 +676,19 @@ fn convert_wikitext_to_html( if !has_class_attr { // Add Tailwind table classes - modified_attributes.push(WSN::Text { + modified_attributes.push(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 +718,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..03e2f51 100644 --- a/src/template.rs +++ b/src/template.rs @@ -3,10 +3,18 @@ use std::{ path::{Path, PathBuf}, }; -use wikitext_simplified::{TemplateParameter, WikitextSimplifiedNode, parse_wiki_text_2}; +use wikitext_simplified::{TemplateParameter, WikitextSimplifiedNode, Spanned, Span, parse_wiki_text_2}; use crate::page_context::PageContext; +/// Helper to create a Spanned node with a default (empty) span +fn spanned(value: T) -> Spanned { + Spanned { + value, + span: Span { start: 0, end: 0 }, + } +} + /// Trait for loading wikitext template files pub trait TemplateLoader { fn load(&self, name: &str) -> anyhow::Result; @@ -137,7 +145,7 @@ impl<'a> Templates<'a> { cell.content = children; } other => { - cell.content = vec![other]; + cell.content = vec![spanned(other)]; } } } @@ -146,7 +154,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 +236,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 +408,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 +505,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" ); } From 99b4c6bd7fe44499e001774491f2c83e5959c3f5 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Nov 2025 08:36:14 +0000 Subject: [PATCH 2/2] Refactor: Extract empty_spanned helper to common util module Created a new util module to hold common helper functions and moved the spanned helper there, renaming it to empty_spanned for clarity. Changes: - Created src/util.rs with empty_spanned() function - Updated main.rs to import and use empty_spanned from util - Updated template.rs to import and use empty_spanned from util - Removed duplicate spanned() definitions from both files - Removed unused Spanned import from template.rs This reduces code duplication and provides a central location for common utility functions. --- src/main.rs | 19 +++++++------------ src/template.rs | 13 +++---------- src/util.rs | 9 +++++++++ 3 files changed, 19 insertions(+), 22 deletions(-) create mode 100644 src/util.rs diff --git a/src/main.rs b/src/main.rs index 8cd440b..c1e56c2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,21 +6,16 @@ use std::{ }; use template::{TemplateToInstantiate, Templates}; -use wikitext_simplified::{WikitextSimplifiedNode, Spanned, Span, wikitext_util::parse_wiki_text_2}; - -/// Helper to create a Spanned node with a default (empty) span -fn spanned(value: T) -> Spanned { - Spanned { - value, - span: Span { start: 0, end: 0 }, - } -} +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"; @@ -446,7 +441,7 @@ fn convert_wikitext_to_html( let attributes = templates.instantiate( pwt_configuration, TemplateToInstantiate::Node(WikitextSimplifiedNode::Fragment { - children: attributes.iter().map(|n| spanned(n.clone())).collect(), + children: attributes.iter().map(|n| empty_spanned(n.clone())).collect(), }), &[], page_context, @@ -654,7 +649,7 @@ fn convert_wikitext_to_html( let instantiated = templates.instantiate( pwt_configuration, TemplateToInstantiate::Node(WikitextSimplifiedNode::Fragment { - children: attributes.iter().map(|n| spanned(n.value.clone())).collect(), + children: attributes.iter().map(|n| empty_spanned(n.value.clone())).collect(), }), &[], page_context, @@ -676,7 +671,7 @@ fn convert_wikitext_to_html( if !has_class_attr { // Add Tailwind table classes - modified_attributes.push(spanned(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(), })); diff --git a/src/template.rs b/src/template.rs index 03e2f51..58100aa 100644 --- a/src/template.rs +++ b/src/template.rs @@ -3,17 +3,10 @@ use std::{ path::{Path, PathBuf}, }; -use wikitext_simplified::{TemplateParameter, WikitextSimplifiedNode, Spanned, Span, parse_wiki_text_2}; +use wikitext_simplified::{TemplateParameter, WikitextSimplifiedNode, parse_wiki_text_2}; use crate::page_context::PageContext; - -/// Helper to create a Spanned node with a default (empty) span -fn spanned(value: T) -> Spanned { - Spanned { - value, - span: Span { start: 0, end: 0 }, - } -} +use crate::util::empty_spanned; /// Trait for loading wikitext template files pub trait TemplateLoader { @@ -145,7 +138,7 @@ impl<'a> Templates<'a> { cell.content = children; } other => { - cell.content = vec![spanned(other)]; + cell.content = vec![empty_spanned(other)]; } } } 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 }, + } +}