From f9b2e74b4525eabb5ea7d1df84b4e570194429b8 Mon Sep 17 00:00:00 2001 From: gyoder <70408179+gyoder@users.noreply.github.com> Date: Mon, 7 Jul 2025 11:33:26 -0600 Subject: Fixed document vs fragment parsing --- htmlua-parser/src/helpers.rs | 32 ++++++++++++++++++++++++++++++++ htmlua-parser/src/lib.rs | 1 + htmlua-parser/src/render.rs | 14 +++++++------- htmlua-parser/src/serve.rs | 8 +++----- 4 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 htmlua-parser/src/helpers.rs (limited to 'htmlua-parser/src') diff --git a/htmlua-parser/src/helpers.rs b/htmlua-parser/src/helpers.rs new file mode 100644 index 0000000..90439f7 --- /dev/null +++ b/htmlua-parser/src/helpers.rs @@ -0,0 +1,32 @@ +use std::{fs::File, io::{BufRead, BufReader, Read, Seek, SeekFrom}, path::PathBuf}; + +use anyhow::Result; +use kuchikiki::NodeRef; +use markup5ever::{LocalName, Namespace, QualName}; +use tendril::TendrilSink; + + + + +pub fn read_doc_from_file(path: PathBuf) -> Result { + + let mut file = File::open(path)?; + let mut reader = BufReader::new(&mut file); + + let mut first_line = String::new(); + reader.read_line(&mut first_line)?; + let first_line_trimmed = first_line.trim(); + + let is_whole_doc = first_line_trimmed.eq_ignore_ascii_case(""); + + file.seek(SeekFrom::Start(0))?; + let mut page_string = String::new(); + file.read_to_string(&mut page_string)?; + + if is_whole_doc { + Ok(kuchikiki::parse_html().one(page_string)) + } else { + let ctx_name = QualName::new(None, Namespace::from("http://www.w3.org/1999/xhtml"), LocalName::from("div")); + Ok(kuchikiki::parse_fragment(ctx_name, Vec::new()).one(page_string)) + } +} diff --git a/htmlua-parser/src/lib.rs b/htmlua-parser/src/lib.rs index 03e66bd..cd87be2 100644 --- a/htmlua-parser/src/lib.rs +++ b/htmlua-parser/src/lib.rs @@ -1,2 +1,3 @@ pub mod render; pub mod serve; +pub mod helpers; diff --git a/htmlua-parser/src/render.rs b/htmlua-parser/src/render.rs index fe0b64f..1ea99a0 100644 --- a/htmlua-parser/src/render.rs +++ b/htmlua-parser/src/render.rs @@ -1,14 +1,15 @@ use std::cell::RefCell; use std::fmt::Write; -use std::fs::read_to_string; use std::path::PathBuf; use std::rc::Rc; use anyhow::Result; use anyhow::anyhow; -use kuchikiki::{NodeRef, traits::TendrilSink}; +use kuchikiki::NodeRef; use mlua::{Lua, Table}; +use crate::helpers::read_doc_from_file; + fn create_htmlua_stdlib(l: &Lua, stdout: &Rc>) -> mlua::Result { let t = l.create_table()?; @@ -79,13 +80,14 @@ pub fn expand_template(document: NodeRef, component_path: &PathBuf, include_from let exported = from_node .select_first(format!("exportelement.{name}").as_str()) .map_err(|()| anyhow!("Error finding exportelement"))?; - exported.as_node().children().for_each(|c| i.as_node().insert_after(c)); + exported.as_node().children().rev().for_each(|c| i.as_node().insert_after(c)); } } while let Ok(i) = document.select_first("includeelement") { i.as_node().detach(); } } + for i in document .select("include") .map_err(|()| anyhow!("Error finding include"))? @@ -97,10 +99,8 @@ pub fn expand_template(document: NodeRef, component_path: &PathBuf, include_from if let Some(include_path) = attrs.get("path") { let mut item_path = component_path.clone(); item_path.push(include_path); - let component_text = read_to_string(item_path)?; - let new_doc = kuchikiki::parse_html().one(component_text); - let new_node = new_doc.select_first("body").map_err(|()| anyhow!("Failed to get body"))?; - let replaced_node = expand_template(new_node.as_node().clone(), component_path, Some(i.as_node()))?; + let new_node = read_doc_from_file(item_path)?; + let replaced_node = expand_template(new_node, component_path, Some(i.as_node()))?; i.as_node().insert_before(replaced_node); i.as_node().detach(); } diff --git a/htmlua-parser/src/serve.rs b/htmlua-parser/src/serve.rs index 134cc13..370d2e9 100644 --- a/htmlua-parser/src/serve.rs +++ b/htmlua-parser/src/serve.rs @@ -1,8 +1,8 @@ +use crate::helpers::read_doc_from_file; + use super::render::execute_lua; use super::render::expand_template; use anyhow::Result; -use kuchikiki::traits::TendrilSink; -use std::fs::read_to_string; use std::path::{Path, PathBuf}; pub fn serve_content(request_uri: &str) -> Result { @@ -13,9 +13,7 @@ pub fn serve_content(request_uri: &str) -> Result { let safe_path = Path::new(request_uri).strip_prefix("/")?; let page_path = pages.join(safe_path); - let page_string = read_to_string(&page_path)?; - - let doc = kuchikiki::parse_html().one(page_string); + let doc = read_doc_from_file(page_path)?; let full_doc = expand_template(doc, &components, None)?; let executed_doc = execute_lua(full_doc)?; -- cgit v1.3.1