From 15f08f474f926f2de317c6a23767575731dc6950 Mon Sep 17 00:00:00 2001 From: Mike Nolan Date: Fri, 25 Sep 2026 16:17:11 -0500 Subject: [PATCH] Make html parser use case insensitive unordered_map for attributes --- apps/thtml2json.cpp | 10 +++------- apps/topengraph.cpp | 14 ++++++------- changelog.md | 3 +++ cmake/version.cmake | 2 +- .../TessesFramework/Serialization/Html.hpp | 20 ++++++++++++++++++- src/Serialization/Html.cpp | 9 ++++----- 6 files changed, 37 insertions(+), 21 deletions(-) diff --git a/apps/thtml2json.cpp b/apps/thtml2json.cpp index a48cc24..a49dbca 100644 --- a/apps/thtml2json.cpp +++ b/apps/thtml2json.cpp @@ -9,14 +9,10 @@ Json::JToken Html2JToken(std::shared_ptr node) { } else { Json::JObject obj; obj.SetValue("Tag", node->text_or_tag); - Json::JArray attrs; + Json::JObject attrs; for (auto &item : node->attributes) { - if (item.second) - attrs.Add(Json::JObject( - {{"Key", item.first}, {"Value", item.second.value()}})); - else - attrs.Add( - Json::JObject({{"Key", item.first}, {"Value", nullptr}})); + attrs.SetValue(item.first, + item.second.value_or(nullptr)); } obj.SetValue("Attributes", attrs); diff --git a/apps/topengraph.cpp b/apps/topengraph.cpp index 4d4fcfb..7f3d531 100644 --- a/apps/topengraph.cpp +++ b/apps/topengraph.cpp @@ -58,13 +58,13 @@ int main(int argc, char **argv) { html->FindNodes("meta", metaTags); for (auto &meta : metaTags) { - std::optional prop, content; - for (auto &[k, v] : meta->attributes) { - if (k == "property" && v) - prop = *v; - if (k == "content" && v) - content = *v; - } + auto prop_off = meta->attributes.find("property"); + auto content_off = meta->attributes.find("content"); + if (!(prop_off != meta->attributes.end() && + content_off != meta->attributes.end())) + continue; + auto &prop = prop_off->second; + auto &content = content_off->second; if (prop && content && prop->find("og:") == 0) { Tesses::Framework::Console::WriteView(prop.value()); diff --git a/changelog.md b/changelog.md index 0609286..9c9f8f3 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,8 @@ # Changelog +## 0.0.9 +Make html parser use case insensitive unordered_map for attributes + ## 0.0.8 Fixed a stoll bug that was there since day one, html parser, fix pkgconfig diff --git a/cmake/version.cmake b/cmake/version.cmake index 1f385ec..f6f5b00 100644 --- a/cmake/version.cmake +++ b/cmake/version.cmake @@ -1,3 +1,3 @@ set(TESSESFRAMEWORK_MAJOR_VERSION 0) set(TESSESFRAMEWORK_MINOR_VERSION 0) -set(TESSESFRAMEWORK_PATCH_VERSION 8) +set(TESSESFRAMEWORK_PATCH_VERSION 9) diff --git a/include/TessesFramework/Serialization/Html.hpp b/include/TessesFramework/Serialization/Html.hpp index c20d857..e6c8960 100644 --- a/include/TessesFramework/Serialization/Html.hpp +++ b/include/TessesFramework/Serialization/Html.hpp @@ -21,13 +21,31 @@ #pragma once #include "../TextStreams/TextReader.hpp" + +#include namespace Tesses::Framework::Serialization::Html { +struct CaseInsensitiveHash { + size_t operator()(const std::string &s) const { + std::string lower = s; + std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); + return std::hash{}(lower); + } +}; + +struct CaseInsensitiveEqual { + bool operator()(const std::string &a, const std::string &b) const { + return strcasecmp(a.c_str(), b.c_str()) == 0; + } +}; + struct HtmlNode; struct HtmlNode : public std::enable_shared_from_this { std::string text_or_tag; - std::vector>> attributes; + std::unordered_map, + CaseInsensitiveHash, CaseInsensitiveEqual> + attributes; std::vector> children; bool isText = false; diff --git a/src/Serialization/Html.cpp b/src/Serialization/Html.cpp index 5cc7247..bc867ce 100644 --- a/src/Serialization/Html.cpp +++ b/src/Serialization/Html.cpp @@ -360,16 +360,15 @@ struct HtmlParser { if (v.type == HtmlLexTokenType::STRING) { Read(); - newNode->attributes.emplace_back( - k.text, + newNode->attributes[k.text] = Http::HttpUtils::HtmlDecode( - v.text)); + v.text); + continue; } } } - newNode->attributes.emplace_back(k.text, - std::nullopt); + newNode->attributes[k.text] = std::nullopt; continue; }