pixwhile/blankie/serializer.cpp

63 lines
1.5 KiB
C++

#include <cstring>
#include <stdexcept>
#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<Element>(&node)) {
out += element->serialize();
} else if (const char* const* text = std::get_if<const char*>(&node)) {
out += escape(*text);
} else if (const std::string* str = std::get_if<std::string>(&node)) {
out += escape(*str);
} else if (const HTMLString* html_str = std::get_if<HTMLString>(&node)) {
out += html_str->str;
} else {
throw std::runtime_error("Encountered unknown node");
}
}
out += "</";
out += this->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);
}