64 lines
1.5 KiB
C++
64 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, "hr", 3)
|
|
|| !strncmp(tag, "input", 6);
|
|
}
|