#include #include #include "escape.h" #include "serializer.h" static inline bool is_autoclosing_tag(const char* tag); namespace blankie { namespace html { std::string Element::serialize() const { std::string out; out += '<'; out += this->tag; for (const auto &[key, value] : this->attributes) { out += ' '; out += key; if (!value.empty()) { out += "=\""; out += escape(value); out += '"'; } } out += '>'; if (is_autoclosing_tag(this->tag)) { return out; } for (const Node& node : this->nodes) { if (const Element* element = std::get_if(&node)) { out += element->serialize(); } else if (const char* const* text = std::get_if(&node)) { out += escape(*text); } else if (const std::string* str = std::get_if(&node)) { out += escape(*str); } else if (const HTMLString* html_str = std::get_if(&node)) { out += html_str->str; } else { throw std::runtime_error("Encountered unknown node"); } } out += "tag; out += '>'; return out; } } // namespace html } // namespace blankie static inline bool is_autoclosing_tag(const char* tag) { return !strncmp(tag, "link", 5) || !strncmp(tag, "meta", 5) || !strncmp(tag, "img", 4) || !strncmp(tag, "br", 3) || !strncmp(tag, "input", 6); }