Remove/replace some "C with classes" junk. The C++ core guidelines state

that you must not use ALL_CAPS for enum members. enum class is now used
as well, to further reinforce the idea that this is a C++ library. While
neither of these changes are necessary, it leads to a better and more
intuitive API design.

More operator overloading has also been added for many of the classes,
particularly the [] index operator, which can now be used in place of
the at() method. More methods have also been added, particularly for
Section and Document.

Some methods have also been fixed, or have had their behavior altered
slightly, but this should now be covered under the new tests, which have
also been (for the most part) rewritten, both because they were
previously both primitive and rather ugly and because new functionality
was added.

Examples have also been updated to reflect the changes made in this
commit, so that they build successfully.

Of course, these changes mean that the new API is incompatible with any
applications written with the 0.0.1 version. Hopefully most of these
changes are dealt with before the 1.0 release, because I would prefer
not making API-breaking changes by that point.
This commit is contained in:
Jacob 2024-05-20 01:32:49 +02:00
parent 223f81dc90
commit 14cd8c4122
6 changed files with 2227 additions and 898 deletions

View file

@ -11,7 +11,7 @@
#include <docpp/docpp.hpp> #include <docpp/docpp.hpp>
int main() { int main() {
docpp::HTML::Section html(docpp::HTML::ELEMENT_HTML, {}); docpp::HTML::Section html(docpp::HTML::Tag::Html, {});
html.push_back({"title", {}, "Google"}); html.push_back({"title", {}, "Google"});
@ -30,9 +30,9 @@ int main() {
}}, }},
}}; }};
html.push_back({"style", {}, sheet.get(docpp::CSS::FORMATTING_PRETTY)}); html.push_back({"style", {}, sheet.get(docpp::CSS::Formatting::Pretty)});
docpp::HTML::Section div{docpp::HTML::ELEMENT_DIV, {docpp::HTML::Property("class", "center")}}; docpp::HTML::Section div{docpp::HTML::Tag::Div, {docpp::HTML::Property("class", "center")}};
div.push_back({"font", {docpp::HTML::Property("color", "blue")}, "G"}); div.push_back({"font", {docpp::HTML::Property("color", "blue")}, "G"});
div.push_back({"font", {docpp::HTML::Property("color", "red")}, "o"}); div.push_back({"font", {docpp::HTML::Property("color", "red")}, "o"});
@ -43,11 +43,11 @@ int main() {
html.push_back(div); html.push_back(div);
docpp::HTML::Section div2{docpp::HTML::ELEMENT_DIV, {docpp::HTML::Property("align", "center")}}; docpp::HTML::Section div2{docpp::HTML::Tag::Div, {docpp::HTML::Property("align", "center")}};
docpp::HTML::Section form{"form", {{docpp::HTML::Property("action", "https://google.com/search"), docpp::HTML::Property("method", "get")}}}; docpp::HTML::Section form{"form", {{docpp::HTML::Property("action", "https://google.com/search"), docpp::HTML::Property("method", "get")}}};
form.push_back({"input", docpp::HTML::Properties({docpp::HTML::Property("type", "text"), docpp::HTML::Property("name", "q")}), "", docpp::HTML::TYPE_SELF_CLOSING}); form.push_back({"input", docpp::HTML::Properties({docpp::HTML::Property("type", "text"), docpp::HTML::Property("name", "q")}), "", docpp::HTML::Type::Self_Closing});
form.push_back({"input", docpp::HTML::Properties({docpp::HTML::Property("type", "submit"), docpp::HTML::Property("value", "Search!")}), "", docpp::HTML::TYPE_SELF_CLOSING}); form.push_back({"input", docpp::HTML::Properties({docpp::HTML::Property("type", "submit"), docpp::HTML::Property("value", "Search!")}), "", docpp::HTML::Type::Self_Closing});
div2.push_back(form); div2.push_back(form);
html.push_back(div2); html.push_back(div2);
@ -56,7 +56,7 @@ int main() {
std::ofstream file("biteme.lol.html"); std::ofstream file("biteme.lol.html");
file << doc.get(docpp::HTML::FORMATTING_PRETTY); file << doc.get(docpp::HTML::Formatting::Pretty);
file.close(); file.close();

View file

@ -19,7 +19,7 @@ int main() {
docpp::HTML::Document doc{}; docpp::HTML::Document doc{};
/* This is an HTML section. It can hold any number of elements and/or sections. /* This is an HTML section. It can hold any number of elements and/or sections.
* The first argument is the type of section, and this can either be a predefined value (e.g., docpp::HTML::ELEMENT_HTML) or a * The first argument is the type of section, and this can either be a predefined value (e.g., docpp::HTML::Tag::Html) or a
* custom value in the form of an std::string object. * custom value in the form of an std::string object.
* *
* The second argument is an HTMLProperties object, which is a collection of Property objects. Each property is a std::pair of an * The second argument is an HTMLProperties object, which is a collection of Property objects. Each property is a std::pair of an
@ -32,10 +32,10 @@ int main() {
* *
* To get the section as an std::string object, call section.get(). * To get the section as an std::string object, call section.get().
*/ */
docpp::HTML::Section htmlSection(docpp::HTML::ELEMENT_HTML, {}); // <html></html> docpp::HTML::Section htmlSection(docpp::HTML::Tag::Html, {}); // <html></html>
docpp::HTML::Section headSection(docpp::HTML::ELEMENT_HEAD, {}); // <head></head> docpp::HTML::Section headSection(docpp::HTML::Tag::Head, {}); // <head></head>
docpp::HTML::Section bodySection(docpp::HTML::ELEMENT_BODY, {}); // <body></body> docpp::HTML::Section bodySection(docpp::HTML::Tag::Body, {}); // <body></body>
docpp::HTML::Section footerSection(docpp::HTML::ELEMENT_FOOTER, {}); // <footer></footer> docpp::HTML::Section footerSection(docpp::HTML::Tag::Footer, {}); // <footer></footer>
/* This is an HTML element. Unlike a section, an element cannot hold any other elements or sections, rather it holds text and/or attributes. /* This is an HTML element. Unlike a section, an element cannot hold any other elements or sections, rather it holds text and/or attributes.
* The first argument is the type of element, and this should simply be the tag name (e.g., "p", "h1", "a", etc.). * The first argument is the type of element, and this should simply be the tag name (e.g., "p", "h1", "a", etc.).
@ -48,7 +48,7 @@ int main() {
* *
* The fourth argument is an integer representing the closing tag type. This can be one of the following: * The fourth argument is an integer representing the closing tag type. This can be one of the following:
* *
* - docpp::HTML::TYPE_NON_CLOSED: No closing tag will be appended. * - docpp::HTML::Type::Non_Closed: No closing tag will be appended.
* Example: <img src="example.jpg"> * Example: <img src="example.jpg">
* - docpp::HTML::TYPE_NON_SELF_CLOSING: A closing tag will be appended. * - docpp::HTML::TYPE_NON_SELF_CLOSING: A closing tag will be appended.
* Example: <p>Hello world</p> * Example: <p>Hello world</p>
@ -61,7 +61,7 @@ int main() {
/* Add the title and meta elements to the head section. */ /* Add the title and meta elements to the head section. */
headSection.push_back(titleElement); headSection.push_back(titleElement);
headSection.push_back(docpp::HTML::Element("meta", {{docpp::HTML::Property("name", "description"), docpp::HTML::Property("content", "Hello world document description!")}}, "", docpp::HTML::TYPE_NON_CLOSED)); headSection.push_back(docpp::HTML::Element("meta", {{docpp::HTML::Property("name", "description"), docpp::HTML::Property("content", "Hello world document description!")}}, "", docpp::HTML::Type::Non_Closed));
/* This is a CSS document. It is essentially the CSS equivalent of an HTML section. /* This is a CSS document. It is essentially the CSS equivalent of an HTML section.
* It is essentially a collection of Element objects, which is a collection of Property objects. * It is essentially a collection of Element objects, which is a collection of Property objects.
@ -84,14 +84,14 @@ int main() {
stylesheet.push_back(bodyStyling); stylesheet.push_back(bodyStyling);
/* To get the stylesheet as an std::string object, call stylesheet.get(). It can then be used in an Element object. */ /* To get the stylesheet as an std::string object, call stylesheet.get(). It can then be used in an Element object. */
const std::string& css = stylesheet.get(docpp::CSS::FORMATTING_PRETTY); // body { background-color: black; color: white; } const std::string& css = stylesheet.get(docpp::CSS::Formatting::Pretty); // body { background-color: black; color: white; }
headSection.push_back(docpp::HTML::Element("style", {}, css)); // <style>body { background-color: black; color: white; }</style> headSection.push_back(docpp::HTML::Element("style", {}, css)); // <style>body { background-color: black; color: white; }</style>
/* Add a paragraph element to the footer section. */ /* Add a paragraph element to the footer section. */
footerSection.push_back(docpp::HTML::Element("p", {}, "This is the footer.")); // <p>This is the footer.</p> footerSection.push_back(docpp::HTML::Element("p", {}, "This is the footer.")); // <p>This is the footer.</p>
docpp::HTML::Section divSection(docpp::HTML::ELEMENT_DIV, {{docpp::HTML::Property("id", "main")}}); // <div id="main"></div> docpp::HTML::Section divSection(docpp::HTML::Tag::Div, {{docpp::HTML::Property("id", "main")}}); // <div id="main"></div>
/* Add a header element and a paragraph element to the div section. */ /* Add a header element and a paragraph element to the div section. */
divSection.push_back(docpp::HTML::Element("h1", {}, "Hello world!")); // <h1>Hello world!</h1> divSection.push_back(docpp::HTML::Element("h1", {}, "Hello world!")); // <h1>Hello world!</h1>
@ -113,10 +113,10 @@ int main() {
/* Finally, let's output the document to a file and print it to standard output. */ /* Finally, let's output the document to a file and print it to standard output. */
std::ofstream file("hello-world.html"); std::ofstream file("hello-world.html");
/* Optionally, you can use the get() method with the docpp::HTML::FORMATTING_PRETTY argument to get a *slightly* more readable document. /* Optionally, you can use the get() method with the docpp::HTML::Formatting::Pretty argument to get a *slightly* more readable document.
* The same goes for the CSS document. Or, you can use docpp::HTML::FORMATTING_NEWLINE to get a document with elements separated by newlines. * The same goes for the CSS document. Or, you can use docpp::HTML::FORMATTING_NEWLINE to get a document with elements separated by newlines.
*/ */
file << doc.get(docpp::HTML::FORMATTING_PRETTY); file << doc.get(docpp::HTML::Formatting::Pretty);
file.close(); file.close();

View file

@ -3,7 +3,7 @@
#include <docpp/docpp.hpp> #include <docpp/docpp.hpp>
docpp::HTML::Section getCSS() { docpp::HTML::Section getCSS() {
docpp::HTML::Section css{docpp::HTML::ELEMENT_STYLE}; docpp::HTML::Section css{docpp::HTML::Tag::Style};
docpp::CSS::Stylesheet stylesheet{}; docpp::CSS::Stylesheet stylesheet{};
@ -180,20 +180,20 @@ docpp::HTML::Section getCSS() {
} }
}); });
css.push_back({docpp::HTML::ELEMENT_EMPTY_NO_FORMAT, {}, stylesheet.get<std::string>(docpp::CSS::FORMATTING_PRETTY, 4)}); css.push_back({docpp::HTML::Tag::Empty_No_Formatting, {}, stylesheet.get<std::string>(docpp::CSS::Formatting::Pretty, 4)});
return css; return css;
} }
docpp::HTML::Section getNavbar(docpp::HTML::Section& e) { docpp::HTML::Section getNavbar(docpp::HTML::Section& e) {
docpp::HTML::Section navbar(docpp::HTML::ELEMENT_DIV, {{docpp::HTML::Property{{"class", "navbar"}}}}); docpp::HTML::Section navbar(docpp::HTML::Tag::Div, {{docpp::HTML::Property{{"class", "navbar"}}}});
docpp::HTML::Section span(docpp::HTML::ELEMENT_SPAN, {}); docpp::HTML::Section span(docpp::HTML::Tag::Span, {});
span.push_back({docpp::HTML::ELEMENT_EMPTY, {}, "speedie.site\n"}); span.push_back({docpp::HTML::Tag::Empty, {}, "speedie.site\n"});
const auto append_to_span = [&](const std::string& img, const std::string& url, const std::string& text) { const auto append_to_span = [&](const std::string& img, const std::string& url, const std::string& text) {
span.push_back({docpp::HTML::ELEMENT_IMG, {{docpp::HTML::Property{{"src", img}}, docpp::HTML::Property{{"width", "16"}}, docpp::HTML::Property{{"height", "16"}}}}, ""}); span.push_back({docpp::HTML::Tag::Img, {{docpp::HTML::Property{{"src", img}}, docpp::HTML::Property{{"width", "16"}}, docpp::HTML::Property{{"height", "16"}}}}, ""});
span.push_back({docpp::HTML::ELEMENT_A, {{docpp::HTML::Property{{"href", url}}}}, text}); span.push_back({docpp::HTML::Tag::A, {{docpp::HTML::Property{{"href", url}}}}, text});
}; };
append_to_span("img/home.png", "/", "Home"); append_to_span("img/home.png", "/", "Home");
@ -208,15 +208,15 @@ docpp::HTML::Section getNavbar(docpp::HTML::Section& e) {
} }
docpp::HTML::Section getHead() { docpp::HTML::Section getHead() {
docpp::HTML::Section e{docpp::HTML::ELEMENT_HEAD}; docpp::HTML::Section e{docpp::HTML::Tag::Head};
docpp::HTML::Element content_type{docpp::HTML::ELEMENT_META, {{docpp::HTML::Property{{"http-equiv", "content-type"}}, docpp::HTML::Property{{"content", "text/html; charset=utf-8"}}}}}; docpp::HTML::Element content_type{docpp::HTML::Tag::Meta, {{docpp::HTML::Property{{"http-equiv", "content-type"}}, docpp::HTML::Property{{"content", "text/html; charset=utf-8"}}}}};
docpp::HTML::Element charset{docpp::HTML::ELEMENT_META, {{docpp::HTML::Property{{"charset", "UTF-8"}}}}}; docpp::HTML::Element charset{docpp::HTML::Tag::Meta, {{docpp::HTML::Property{{"charset", "UTF-8"}}}}};
docpp::HTML::Element favicon(docpp::HTML::ELEMENT_LINK, {{docpp::HTML::Property{{"rel", "icon"}}, docpp::HTML::Property{{"type", "image/x-icon"}}, docpp::HTML::Property{{"href", "/img/favicon.svg"}}}}); docpp::HTML::Element favicon(docpp::HTML::Tag::Link, {{docpp::HTML::Property{{"rel", "icon"}}, docpp::HTML::Property{{"type", "image/x-icon"}}, docpp::HTML::Property{{"href", "/img/favicon.svg"}}}});
docpp::HTML::Element description(docpp::HTML::ELEMENT_META, {{docpp::HTML::Property{{"name", "description"}}, docpp::HTML::Property{{"content", "Welcome to my personal website."}}}}); docpp::HTML::Element description(docpp::HTML::Tag::Meta, {{docpp::HTML::Property{{"name", "description"}}, docpp::HTML::Property{{"content", "Welcome to my personal website."}}}});
docpp::HTML::Element author(docpp::HTML::ELEMENT_META, {{docpp::HTML::Property{{"name", "author"}}, docpp::HTML::Property{{"content", "speedie"}}}}); docpp::HTML::Element author(docpp::HTML::Tag::Meta, {{docpp::HTML::Property{{"name", "author"}}, docpp::HTML::Property{{"content", "speedie"}}}});
docpp::HTML::Element title(docpp::HTML::ELEMENT_TITLE, {}, "speedie's site"); docpp::HTML::Element title(docpp::HTML::Tag::Title, {}, "speedie's site");
docpp::HTML::Section css{docpp::HTML::ELEMENT_STYLE}; docpp::HTML::Section css{docpp::HTML::Tag::Style};
e.push_back(content_type); e.push_back(content_type);
e.push_back(favicon); e.push_back(favicon);
@ -229,23 +229,23 @@ docpp::HTML::Section getHead() {
} }
docpp::HTML::Section getMain() { docpp::HTML::Section getMain() {
docpp::HTML::Section content(docpp::HTML::ELEMENT_DIV, {{docpp::HTML::Property{{"class", "content"}}}}); docpp::HTML::Section content(docpp::HTML::Tag::Div, {{docpp::HTML::Property{{"class", "content"}}}});
content.push_back({docpp::HTML::ELEMENT_H2, {}, "Hello world!"}); content.push_back({docpp::HTML::Tag::H2, {}, "Hello world!"});
content.push_back({docpp::HTML::ELEMENT_P, {}, "Hello there! This is a replica of my old website, using docpp to generate the HTML. With that said. This only provides the index page, so many links are not functional. This is more to show off that docpp can be used to generate a proper website."}); content.push_back({docpp::HTML::Tag::P, {}, "Hello there! This is a replica of my old website, using docpp to generate the HTML. With that said. This only provides the index page, so many links are not functional. This is more to show off that docpp can be used to generate a proper website."});
content.push_back({docpp::HTML::ELEMENT_H3, {}, "Links"}); content.push_back({docpp::HTML::Tag::H3, {}, "Links"});
docpp::HTML::Section links(docpp::HTML::ELEMENT_DIV, {{docpp::HTML::Property{{"class", "links"}}}}); docpp::HTML::Section links(docpp::HTML::Tag::Div, {{docpp::HTML::Property{{"class", "links"}}}});
docpp::HTML::Section table(docpp::HTML::ELEMENT_TABLE); docpp::HTML::Section table(docpp::HTML::Tag::Table);
static const auto append_to_table = [&](const std::string& img, const std::string& url, const std::string& short_text, const std::string& long_text) { static const auto append_to_table = [&](const std::string& img, const std::string& url, const std::string& short_text, const std::string& long_text) {
docpp::HTML::Section tr{docpp::HTML::ELEMENT_TR}; docpp::HTML::Section tr{docpp::HTML::Tag::Tr};
docpp::HTML::Section td{docpp::HTML::ELEMENT_TD}; docpp::HTML::Section td{docpp::HTML::Tag::Td};
docpp::HTML::Section td2{docpp::HTML::ELEMENT_TD}; docpp::HTML::Section td2{docpp::HTML::Tag::Td};
td.push_back({docpp::HTML::ELEMENT_IMG, {{docpp::HTML::Property{{"src", img}}, docpp::HTML::Property{{"width", "16"}}, docpp::HTML::Property{{"height", "16"}}}}, ""}); td.push_back({docpp::HTML::Tag::Img, {{docpp::HTML::Property{{"src", img}}, docpp::HTML::Property{{"width", "16"}}, docpp::HTML::Property{{"height", "16"}}}}, ""});
td.push_back({docpp::HTML::ELEMENT_A, {{docpp::HTML::Property{{"href", url}}}}, short_text}); td.push_back({docpp::HTML::Tag::A, {{docpp::HTML::Property{{"href", url}}}}, short_text});
td2.push_back({docpp::HTML::ELEMENT_EMPTY, {}, long_text + "\n"}); td2.push_back({docpp::HTML::Tag::Empty, {}, long_text + "\n"});
tr.push_back(td); tr.push_back(td);
tr.push_back(td2); tr.push_back(td2);
@ -265,25 +265,25 @@ docpp::HTML::Section getMain() {
} }
docpp::HTML::Section getFooter() { docpp::HTML::Section getFooter() {
docpp::HTML::Section footer(docpp::HTML::ELEMENT_FOOTER); docpp::HTML::Section footer(docpp::HTML::Tag::Footer);
docpp::HTML::Section div(docpp::HTML::ELEMENT_DIV, {{docpp::HTML::Property("class", "column")}}); docpp::HTML::Section div(docpp::HTML::Tag::Div, {{docpp::HTML::Property("class", "column")}});
docpp::HTML::Section span(docpp::HTML::ELEMENT_SPAN, {{docpp::HTML::Property("class", "links")}}); docpp::HTML::Section span(docpp::HTML::Tag::Span, {{docpp::HTML::Property("class", "links")}});
span.push_back({docpp::HTML::ELEMENT_A, {{docpp::HTML::Property("class", "links"), docpp::HTML::Property("href", "https://git.speedie.site")}}, "Git"}); span.push_back({docpp::HTML::Tag::A, {{docpp::HTML::Property("class", "links"), docpp::HTML::Property("href", "https://git.speedie.site")}}, "Git"});
span.push_back({docpp::HTML::ELEMENT_A, {{docpp::HTML::Property("class", "links"), docpp::HTML::Property("href", "https://ls.speedie.site")}}, "Downloads"}); span.push_back({docpp::HTML::Tag::A, {{docpp::HTML::Property("class", "links"), docpp::HTML::Property("href", "https://ls.speedie.site")}}, "Downloads"});
span.push_back({docpp::HTML::ELEMENT_A, {{docpp::HTML::Property("class", "links"), docpp::HTML::Property("href", "privacy.html")}}, "Licensing"}); span.push_back({docpp::HTML::Tag::A, {{docpp::HTML::Property("class", "links"), docpp::HTML::Property("href", "privacy.html")}}, "Licensing"});
div.push_back(span); div.push_back(span);
div.push_back({docpp::HTML::ELEMENT_P, {{docpp::HTML::Property("style", "padding-top: 0px;")}}, "Made in Sweden"}); div.push_back({docpp::HTML::Tag::P, {{docpp::HTML::Property("style", "padding-top: 0px;")}}, "Made in Sweden"});
footer.push_back(div); footer.push_back(div);
return footer; return footer;
} }
int main() { int main() {
docpp::HTML::Section html_section = docpp::HTML::Section(docpp::HTML::ELEMENT_HTML); docpp::HTML::Section html_section = docpp::HTML::Section(docpp::HTML::Tag::Html);
docpp::HTML::Section head{getHead()}; docpp::HTML::Section head{getHead()};
docpp::HTML::Section body(docpp::HTML::ELEMENT_BODY); docpp::HTML::Section body(docpp::HTML::Tag::Body);
body.push_back(getMain()); body.push_back(getMain());
@ -295,8 +295,8 @@ int main() {
docpp::HTML::Document html_doc(html_section); docpp::HTML::Document html_doc(html_section);
std::cout << html_doc.get<std::string>(docpp::HTML::FORMATTING_PRETTY) << "\n"; std::cout << html_doc.get<std::string>(docpp::HTML::Formatting::Pretty) << "\n";
std::ofstream fs{"speedie-page.html"}; std::ofstream fs{"speedie-page.html"};
fs << html_doc.get<std::string>(docpp::HTML::FORMATTING_PRETTY); fs << html_doc.get<std::string>(docpp::HTML::Formatting::Pretty);
fs.close(); fs.close();
} }

View file

@ -15,9 +15,9 @@
#include <type_traits> #include <type_traits>
/** /**
* @brief A namespace to represent HTML elements and documents * @brief A inline namespace to represent HTML elements and documents
*/ */
namespace docpp { inline namespace docpp {
/** /**
* @brief A class to represent an exception when an index is out of range * @brief A class to represent an exception when an index is out of range
*/ */
@ -47,178 +47,178 @@ namespace docpp {
}; };
/** /**
* @brief A namespace to represent HTML elements and documents * @brief A inline namespace to represent HTML elements and documents
*/ */
namespace HTML { inline namespace HTML {
/** /**
* @brief Enum for element tags. * @brief Enum for element tags.
*/ */
enum Tag { enum class Tag {
ELEMENT_EMPTY, /* Empty element */ Empty, /* Empty element */
ELEMENT_EMPTY_NO_FORMAT, /* Empty element, that ignores any formatting by get() calls. */ Empty_No_Formatting, /* Empty element, that ignores any formatting by get() calls. */
ELEMENT_ABBREVIATION, /* <abbr></abbr> */ Abbreviation, /* <abbr></abbr> */
ELEMENT_ABBR, /* <abbr></abbr> */ Abbr, /* <abbr></abbr> */
ELEMENT_ACRONYM, /* <acronym></acronym> */ Acronym, /* <acronym></acronym> */
ELEMENT_ADDRESS, /* <address></address> */ Address, /* <address></address> */
ELEMENT_ANCHOR, /* <a></a> */ Anchor, /* <a></a> */
ELEMENT_A, /* <a></a> */ A, /* <a></a> */
ELEMENT_APPLET, /* <applet></applet> */ Applet, /* <applet></applet> */
ELEMENT_ARTICLE, /* <article></article> */ Article, /* <article></article> */
ELEMENT_AREA, /* <area></area> */ Area, /* <area></area> */
ELEMENT_ASIDE, /* <aside></aside> */ Aside, /* <aside></aside> */
ELEMENT_AUDIO, /* <audio></audio> */ Audio, /* <audio></audio> */
ELEMENT_BASE, /* <base></base> */ Base, /* <base></base> */
ELEMENT_BASEFONT, /* <basefont></basefont> */ Basefont, /* <basefont></basefont> */
ELEMENT_BDI, /* <bdi></bdi> */ Bdi, /* <bdi></bdi> */
ELEMENT_BDO, /* <bdo></bdo> */ Bdo, /* <bdo></bdo> */
ELEMENT_BGSOUND, /* <bgsound></bgsound> */ Bgsound, /* <bgsound></bgsound> */
ELEMENT_BIG, /* <big></big> */ Big, /* <big></big> */
ELEMENT_BLOCKQUOTE, /* <blockquote></blockquote> */ Blockquote, /* <blockquote></blockquote> */
ELEMENT_BODY, /* <body></body> */ Body, /* <body></body> */
ELEMENT_BOLD, /* <b></b> */ Bold, /* <b></b> */
ELEMENT_B, /* <b></b> */ B, /* <b></b> */
ELEMENT_BR, /* <br> */ Br, /* <br> */
ELEMENT_BREAK, /* <br> */ Break, /* <br> */
ELEMENT_BUTTON, /* <button></button> */ Button, /* <button></button> */
ELEMENT_CAPTION, /* <caption></caption> */ Caption, /* <caption></caption> */
ELEMENT_CANVAS, /* <canvas></canvas> */ Canvas, /* <canvas></canvas> */
ELEMENT_CENTER, /* <center></center> */ Center, /* <center></center> */
ELEMENT_CITE, /* <cite></cite> */ Cite, /* <cite></cite> */
ELEMENT_CODE, /* <code></code> */ Code, /* <code></code> */
ELEMENT_COLGROUP, /* <colgroup></colgroup> */ Colgroup, /* <colgroup></colgroup> */
ELEMENT_COL, /* <col></col> */ Col, /* <col></col> */
ELEMENT_COLUMN, /* <col></col> */ Column, /* <col></col> */
ELEMENT_DATA, /* <data></data> */ Data, /* <data></data> */
ELEMENT_DATALIST, /* <datalist></datalist> */ Datalist, /* <datalist></datalist> */
ELEMENT_DD, /* <dd></dd> */ Dd, /* <dd></dd> */
ELEMENT_DFN, /* <dfn></dfn> */ Dfn, /* <dfn></dfn> */
ELEMENT_DEFINE, /* <dfn></dfn> */ Define, /* <dfn></dfn> */
ELEMENT_DELETE, /* <del></del> */ Delete, /* <del></del> */
ELEMENT_DEL, /* <del></del> */ Del, /* <del></del> */
ELEMENT_DETAILS, /* <details></details> */ Details, /* <details></details> */
ELEMENT_DIALOG, /* <dialog></dialog> */ Dialog, /* <dialog></dialog> */
ELEMENT_DIR, /* <dir></dir> */ Dir, /* <dir></dir> */
ELEMENT_DIV, /* <div></div> */ Div, /* <div></div> */
ELEMENT_DL, /* <dl></dl> */ Dl, /* <dl></dl> */
ELEMENT_DT, /* <dt></dt> */ Dt, /* <dt></dt> */
ELEMENT_EMBED, /* <embed></embed> */ Embed, /* <embed></embed> */
ELEMENT_FIELDSET, /* <fieldset></fieldset> */ Fieldset, /* <fieldset></fieldset> */
ELEMENT_FIGCAPTION, /* <figcaption></figcaption> */ Figcaption, /* <figcaption></figcaption> */
ELEMENT_FIGURE, /* <figure></figure> */ Figure, /* <figure></figure> */
ELEMENT_FONT, /* <font></font> */ Font, /* <font></font> */
ELEMENT_FOOTER, /* <footer></footer> */ Footer, /* <footer></footer> */
ELEMENT_FORM, /* <form></form> */ Form, /* <form></form> */
ELEMENT_FRAME, /* <frame></frame> */ Frame, /* <frame></frame> */
ELEMENT_FRAMESET, /* <frameset></frameset> */ Frameset, /* <frameset></frameset> */
ELEMENT_HEAD, /* <head></head> */ Head, /* <head></head> */
ELEMENT_HEADER, /* <header></header> */ Header, /* <header></header> */
ELEMENT_H1, /* <h1></h1> */ H1, /* <h1></h1> */
ELEMENT_H2, /* <h2></h2> */ H2, /* <h2></h2> */
ELEMENT_H3, /* <h3></h3> */ H3, /* <h3></h3> */
ELEMENT_H4, /* <h4></h4> */ H4, /* <h4></h4> */
ELEMENT_H5, /* <h5></h5> */ H5, /* <h5></h5> */
ELEMENT_H6, /* <h6></h6> */ H6, /* <h6></h6> */
ELEMENT_HGROUP, /* <hgroup></hgroup> */ Hgroup, /* <hgroup></hgroup> */
ELEMENT_HR, /* <hr> */ Hr, /* <hr> */
ELEMENT_HTML, /* <html></html> */ Html, /* <html></html> */
ELEMENT_IFRAME, /* <iframe></iframe> */ Iframe, /* <iframe></iframe> */
ELEMENT_IMAGE, /* <img> */ Image, /* <img> */
ELEMENT_IMG, /* <img> */ Img, /* <img> */
ELEMENT_INPUT, /* <input> */ Input, /* <input> */
ELEMENT_INS, /* <ins></ins> */ Ins, /* <ins></ins> */
ELEMENT_ISINDEX, /* <isindex></isindex> */ Isindex, /* <isindex></isindex> */
ELEMENT_ITALIC, /* <i></i> */ Italic, /* <i></i> */
ELEMENT_I, /* <i></i> */ I, /* <i></i> */
ELEMENT_KBD, /* <kbd></kbd> */ Kbd, /* <kbd></kbd> */
ELEMENT_KEYGEN, /* <keygen></keygen> */ Keygen, /* <keygen></keygen> */
ELEMENT_LABEL, /* <label></label> */ Label, /* <label></label> */
ELEMENT_LEGEND, /* <legend></legend> */ Legend, /* <legend></legend> */
ELEMENT_LIST, /* <li></li> */ List, /* <li></li> */
ELEMENT_LI, /* <li></li> */ Li, /* <li></li> */
ELEMENT_LINK, /* <link></link> */ Link, /* <link></link> */
ELEMENT_MAIN, /* <main></main> */ Main, /* <main></main> */
ELEMENT_MARK, /* <mark></mark> */ Mark, /* <mark></mark> */
ELEMENT_MARQUEE, /* <marquee></marquee> */ Marquee, /* <marquee></marquee> */
ELEMENT_MENUITEM, /* <menuitem></menuitem> */ Menuitem, /* <menuitem></menuitem> */
ELEMENT_META, /* <meta></meta> */ Meta, /* <meta></meta> */
ELEMENT_METER, /* <meter></meter> */ Meter, /* <meter></meter> */
ELEMENT_NAV, /* <nav></nav> */ Nav, /* <nav></nav> */
ELEMENT_NOBREAK, /* <nobr></nobr> */ Nobreak, /* <nobr></nobr> */
ELEMENT_NOBR, /* <nobr></nobr> */ Nobr, /* <nobr></nobr> */
ELEMENT_NOEMBED, /* <noembed></noembed> */ Noembed, /* <noembed></noembed> */
ELEMENT_NOSCRIPT, /* <noscript></noscript> */ Noscript, /* <noscript></noscript> */
ELEMENT_OBJECT, /* <object></object> */ Object, /* <object></object> */
ELEMENT_OPTGROUP, /* <optgroup></optgroup> */ Optgroup, /* <optgroup></optgroup> */
ELEMENT_OPTION, /* <option></option> */ Option, /* <option></option> */
ELEMENT_OUTPUT, /* <output></output> */ Output, /* <output></output> */
ELEMENT_PARAGRAPH, /* <p></p> */ Paragraph, /* <p></p> */
ELEMENT_P, /* <p></p> */ P, /* <p></p> */
ELEMENT_PARAM, /* <param></param> */ Param, /* <param></param> */
ELEMENT_PHRASE, /* <pharse></pharse> */ Phrase, /* <pharse></pharse> */
ELEMENT_PRE, /* <pre></pre> */ Pre, /* <pre></pre> */
ELEMENT_PROGRESS, /* <progress></progress> */ Progress, /* <progress></progress> */
ELEMENT_QUOTE, /* <q></q> */ Quote, /* <q></q> */
ELEMENT_Q, /* <q></q> */ Q, /* <q></q> */
ELEMENT_RP, /* <rp></rp> */ Rp, /* <rp></rp> */
ELEMENT_RT, /* <rt></rt> */ Rt, /* <rt></rt> */
ELEMENT_RUBY, /* <ruby></ruby> */ Ruby, /* <ruby></ruby> */
ELEMENT_OUTDATED, /* <s></s> */ Outdated, /* <s></s> */
ELEMENT_S, /* <s></s> */ S, /* <s></s> */
ELEMENT_SAMPLE, /* <samp></samp> */ Sample, /* <samp></samp> */
ELEMENT_SAMP, /* <samp></samp> */ Samp, /* <samp></samp> */
ELEMENT_SCRIPT, /* <script></script> */ Script, /* <script></script> */
ELEMENT_SECTION, /* <section></section> */ Section, /* <section></section> */
ELEMENT_SMALL, /* <small></small> */ Small, /* <small></small> */
ELEMENT_SOURCE, /* <source></source> */ Source, /* <source></source> */
ELEMENT_SPACER, /* <spacer></spacer> */ Spacer, /* <spacer></spacer> */
ELEMENT_SPAN, /* <span></span> */ Span, /* <span></span> */
ELEMENT_STRIKE, /* <strike></strike> */ Strike, /* <strike></strike> */
ELEMENT_STRONG, /* <strong></strong> */ Strong, /* <strong></strong> */
ELEMENT_STYLE, /* <style></style> */ Style, /* <style></style> */
ELEMENT_SUB, /* <sub></sub> */ Sub, /* <sub></sub> */
ELEMENT_SUBSCRIPT, /* <sub></sub> */ Subscript, /* <sub></sub> */
ELEMENT_SUP, /* <sup></sup> */ Sup, /* <sup></sup> */
ELEMENT_SUPERSCRIPT, /* <sup></sup> */ Superscript, /* <sup></sup> */
ELEMENT_SUMMARY, /* <summary></summary> */ Summary, /* <summary></summary> */
ELEMENT_SVG, /* <svg></svg> */ Svg, /* <svg></svg> */
ELEMENT_TABLE, /* <table></table> */ Table, /* <table></table> */
ELEMENT_TBODY, /* <tbody></tbody> */ Tbody, /* <tbody></tbody> */
ELEMENT_TD, /* <td></td> */ Td, /* <td></td> */
ELEMENT_TEMPLATE, /* <template></template> */ Template, /* <template></template> */
ELEMENT_TFOOT, /* <tfoot></tfoot> */ Tfoot, /* <tfoot></tfoot> */
ELEMENT_TH, /* <th></th> */ Th, /* <th></th> */
ELEMENT_THEAD, /* <thead></thead> */ Thead, /* <thead></thead> */
ELEMENT_TIME, /* <time></time> */ Time, /* <time></time> */
ELEMENT_TITLE, /* <title></title> */ Title, /* <title></title> */
ELEMENT_TR, /* <tr></tr> */ Tr, /* <tr></tr> */
ELEMENT_TRACK, /* <track></track> */ Track, /* <track></track> */
ELEMENT_TT, /* <tt></tt> */ Tt, /* <tt></tt> */
ELEMENT_UNDERLINE, /* <u></u> */ Underline, /* <u></u> */
ELEMENT_U, /* <u></u> */ U, /* <u></u> */
ELEMENT_VAR, /* <var></var> */ Var, /* <var></var> */
ELEMENT_VIDEO, /* <video></video> */ Video, /* <video></video> */
ELEMENT_WBR, /* <wbr></wbr> */ Wbr, /* <wbr></wbr> */
ELEMENT_XMP, /* <xmp></xmp> */ Xmp, /* <xmp></xmp> */
}; };
/** /**
* @brief Enum for element types. * @brief Enum for element types.
*/ */
enum Type { enum class Type {
TYPE_SELF_CLOSING, /* Self-closing element (<tag></tag>)*/ Self_Closing, /* Self-closing element (<tag></tag>)*/
TYPE_NON_SELF_CLOSING, /* Non-self-closing element (<tag>) */ Non_Self_Closing, /* Non-self-closing element (<tag>) */
TYPE_NON_CLOSED, /* Non-closed element (<tag>) */ Non_Closed, /* Non-closed element (<tag>) */
TYPE_TEXT, /* Text element (my text here). Note that this does *not* append a newline character. */ Text_No_Formatting, /* Text element with no formatting (my text here). */
TYPE_TEXT_TAB, /* Text element with tab characters appropriately prepended (my text here). Note that this does *not* append a newline character. */ Text, /* Text element with tab characters appropriately prepended (my text here). Note that this does *not* append a newline character. */
}; };
/** /**
* @brief Enum for formatting options. * @brief Enum for formatting options.
*/ */
enum Formatting { enum class Formatting {
FORMATTING_NONE, /* No formatting. Output is in the form of one long string of text, and a single newline character. */ None, /* No formatting. Output is in the form of one long string of text, and a single newline character. */
FORMATTING_PRETTY, /* Pretty formatting. Output is formatted with newlines and tabs as deemed appropriate. */ Pretty, /* Pretty formatting. Output is formatted with newlines and tabs as deemed appropriate. */
FORMATTING_NEWLINE, /* Newline formatting. Each element has a newline appended. */ Newline, /* Newline formatting. Each element has a newline appended. */
}; };
/** /**
@ -318,6 +318,21 @@ namespace docpp {
* @param property The property. * @param property The property.
*/ */
void set(const std::pair<std::string, std::string>& property); void set(const std::pair<std::string, std::string>& property);
/**
* @brief Clear the property
*/
void clear();
/**
* @brief Check if the property is empty
* @return bool True if the property is empty, false otherwise
*/
bool empty() const;
Property& operator=(const Property& property);
Property& operator=(const std::pair<std::string, std::string>& property);
bool operator==(const Property& property) const;
bool operator!=(const Property& property) const;
}; };
/** /**
@ -446,6 +461,15 @@ namespace docpp {
* @return size_type The size of the element * @return size_type The size of the element
*/ */
size_type size() const; size_type size() const;
/**
* @brief Clear the properties
*/
void clear();
/**
* @brief Check if the properties are empty
* @return bool True if the properties are empty, false otherwise
*/
bool empty() const;
/** /**
* @brief Prepend a property to the element * @brief Prepend a property to the element
* @param property The property to add * @param property The property to add
@ -470,10 +494,16 @@ namespace docpp {
* @brief Construct a new Properties object * @brief Construct a new Properties object
*/ */
Properties() = default; Properties() = default;
Properties operator=(const Properties& properties); Properties& operator=(const Properties& properties);
Properties operator=(const std::vector<Property>& properties); Properties& operator=(const std::vector<Property>& properties);
Properties operator=(const Property& property); Properties& operator=(const Property& property);
void operator+=(const Property& property); bool operator==(const Properties& properties) const;
bool operator==(const Property& property) const;
bool operator!=(const Properties& properties) const;
bool operator!=(const Property& property) const;
Property operator[](const size_type& index) const;
Properties& operator+=(const Property& property);
Properties& operator+=(const Properties& properties);
}; };
/** /**
@ -483,7 +513,7 @@ namespace docpp {
private: private:
std::string tag{}; std::string tag{};
std::string data{}; std::string data{};
Type type{TYPE_NON_SELF_CLOSING}; Type type{Type::Non_Self_Closing};
Properties properties{}; Properties properties{};
protected: protected:
public: public:
@ -500,7 +530,7 @@ namespace docpp {
* @param data The data of the element * @param data The data of the element
* @param type The close tag type. * @param type The close tag type.
*/ */
Element(const std::string& tag, const Properties& properties = {}, const std::string& data = {}, const Type type = TYPE_NON_SELF_CLOSING) : tag(tag), properties(properties), data(data), type(type) {}; Element(const std::string& tag, const Properties& properties = {}, const std::string& data = {}, const Type type = Type::Non_Self_Closing) : tag(tag), properties(properties), data(data), type(type) {};
/** /**
* @brief Construct a new Element object * @brief Construct a new Element object
* @param tag The tag of the element * @param tag The tag of the element
@ -519,18 +549,50 @@ namespace docpp {
* @param data The data of the element * @param data The data of the element
* @param type The close tag type. * @param type The close tag type.
*/ */
void set(const std::string& tag, const Properties& properties = {}, const std::string& data = {}, const Type type = TYPE_NON_SELF_CLOSING); void set(const std::string& tag, const Properties& properties = {}, const std::string& data = {}, const Type type = Type::Non_Self_Closing);
/**
* @brief Set the tag, properties, and data of the element
* @param tag The tag of the element
* @param properties The properties of the element
* @param data The data of the element
*/
void set(const Tag tag, const Properties& properties = {}, const std::string& data = {});
/**
* @brief Set the tag of the element
* @param tag The tag of the element
*/
void set_tag(const std::string& tag);
/**
* @brief Set the tag of the element
* @param tag The tag of the element
*/
void set_tag(const Tag tag);
/**
* @brief Set the data of the element
* @param data The data of the element
*/
void set_data(const std::string& data);
/**
* @brief Set the properties of the element
* @param properties The properties of the element
*/
void set_properties(const Properties& properties);
/**
* @brief Set the type of the element
* @param type The type of the element
*/
void set_type(const Type type);
/** /**
* @brief Get the element in the form of an HTML tag. * @brief Get the element in the form of an HTML tag.
* @return std::string The tag of the element * @return std::string The tag of the element
*/ */
std::string get(const Formatting formatting = FORMATTING_NONE, const int tabc = 0) const; std::string get(const Formatting formatting = Formatting::None, const int tabc = 0) const;
/** /**
* @brief Get the element in the form of a specific type. * @brief Get the element in the form of a specific type.
* @return T The element in the form of a specific type * @return T The element in the form of a specific type
*/ */
template <typename T> T get(const Formatting formatting = FORMATTING_NONE, const int tabc = 0) const { template <typename T> T get(const Formatting formatting = Formatting::None, const int tabc = 0) const {
if (std::is_same<T, std::string>::value) { if (std::is_same<T, std::string>::value) {
return this->get(formatting, tabc); return this->get(formatting, tabc);
} }
@ -568,9 +630,30 @@ namespace docpp {
} }
return T(this->data); return T(this->data);
} }
/**
* @brief Get the properties of the element
* @return Properties The properties of the element
*/
Properties get_properties() const;
/**
* @brief Get the type of the element
* @return Type The type of the element
*/
Type get_type() const;
/**
* @brief Clear the element
*/
void clear();
/**
* @brief Check if the element is empty.
* @return bool True if the element is empty, false otherwise.
*/
bool empty() const;
Element operator=(const Element& element); Element& operator=(const Element& element);
void operator+=(const std::string& data); Element& operator+=(const std::string& data);
bool operator==(const Element& element) const;
bool operator!=(const Element& element) const;
}; };
/** /**
@ -717,19 +800,52 @@ namespace docpp {
* @return size_type The size of the section * @return size_type The size of the section
*/ */
size_type size() const; size_type size() const;
/**
* @brief Clear the section
*/
void clear();
/**
* @brief Check if the section is empty
* @return bool True if the section is empty, false otherwise
*/
bool empty() const;
/** /**
* @brief Construct a new Section object * @brief Construct a new Section object
* @param tag The tag of the section * @param tag The tag of the section
* @param properties The properties of the section * @param properties The properties of the section
* @param elements The elements of the section
*/ */
Section(const std::string& tag, const Properties& properties = {}) : tag(tag), properties(properties) {}; Section(const std::string& tag, const Properties& properties = {}, const std::vector<Element>& elements = {}) : tag(tag), properties(properties) {
for (const auto& element : elements) this->push_back(element);
};
/** /**
* @brief Construct a new Section object * @brief Construct a new Section object
* @param tag The tag of the section * @param tag The tag of the section
* @param properties The properties of the section * @param properties The properties of the section
* @param elements The elements of the section
*/ */
Section(const Tag tag, const Properties& properties = {}) : tag(resolve_tag(tag).first), properties(properties) {}; Section(const Tag tag, const Properties& properties = {}, const std::vector<Element>& elements = {}) : tag(resolve_tag(tag).first), properties(properties) {
for (const auto& element : elements) this->push_back(element);
};
/**
* @brief Construct a new Section object
* @param tag The tag of the section
* @param properties The properties of the section
* @param sections The sections of the section
*/
Section(const std::string& tag, const Properties& properties, const std::vector<Section>& sections) : tag(tag), properties(properties) {
for (const auto& section : sections) this->push_back(section);
};
/**
* @brief Construct a new Section object
* @param tag The tag of the section
* @param properties The properties of the section
* @param sections The sections of the section
*/
Section(const Tag tag, const Properties& properties, const std::vector<Section>& sections) : tag(resolve_tag(tag).first), properties(properties) {
for (const auto& section : sections) this->push_back(section);
};
/** /**
* @brief Construct a new Section object * @brief Construct a new Section object
*/ */
@ -748,6 +864,21 @@ namespace docpp {
* @param classes The classes of the section * @param classes The classes of the section
*/ */
void set(const Tag tag, const Properties& properties = {}); void set(const Tag tag, const Properties& properties = {});
/**
* @brief Set the tag of the section
* @param tag The tag of the section
*/
void set_tag(const std::string& tag);
/**
* @brief Set the tag of the section
* @param tag The tag of the section
*/
void set_tag(const Tag tag);
/**
* @brief Set the properties of the section
* @param properties The properties of the section
*/
void set_properties(const Properties& properties);
/** /**
* @brief Swap two elements in the section * @brief Swap two elements in the section
* @param index1 The index of the first element * @param index1 The index of the first element
@ -781,21 +912,46 @@ namespace docpp {
* @brief Dump the entire section. * @brief Dump the entire section.
* @return std::string The section * @return std::string The section
*/ */
std::string get(const Formatting formatting = FORMATTING_NONE, const int tabc = 0) const; std::string get(const Formatting formatting = Formatting::None, const int tabc = 0) const;
/** /**
* @brief Get the element in the form of a specific type. * @brief Get the element in the form of a specific type.
* @return T The element in the form of a specific type * @return T The element in the form of a specific type
*/ */
template <typename T> T get(const Formatting formatting = FORMATTING_NONE, const int tabc = 0) const { template <typename T> T get(const Formatting formatting = Formatting::None, const int tabc = 0) const {
if (std::is_same<T, std::string>::value) { if (std::is_same<T, std::string>::value) {
return this->get(formatting, tabc); return this->get(formatting, tabc);
} }
return T(this->get(formatting, tabc)); return T(this->get(formatting, tabc));
} }
Section operator=(const Section& section); /**
void operator+=(const Element& element); * @brief Get the tag of the section
void operator+=(const Section& section); * @return std::string The tag of the section
*/
std::string get_tag() const;
/**
* @brief Get the tag of the section in a specific type
* @return T The tag of the section
*/
template <typename T> T get_tag() const {
if (std::is_same<T, std::string>::value) {
return this->tag;
}
return T(this->tag);
}
/**
* @brief Get the properties of the section
* @return Properties The properties of the section
*/
Properties get_properties() const;
Section& operator=(const Section& section);
Section& operator+=(const Element& element);
Section& operator+=(const Section& section);
bool operator==(const Element& element) const;
bool operator==(const Section& section) const;
bool operator!=(const Element& element) const;
bool operator!=(const Section& section) const;
Element operator[](const int& index) const; Element operator[](const int& index) const;
private: private:
size_type index{}; size_type index{};
@ -827,12 +983,12 @@ namespace docpp {
* @param std::string The type to return * @param std::string The type to return
* @return std::string The document * @return std::string The document
*/ */
std::string get(const Formatting formatting = FORMATTING_NONE, const int tabc = 0) const; std::string get(const Formatting formatting = Formatting::None, const int tabc = 0) const;
/** /**
* @brief Get the document in the form of a specific type. * @brief Get the document in the form of a specific type.
* @return T The document in the form of a specific type * @return T The document in the form of a specific type
*/ */
template <typename T> T get(const Formatting formatting = FORMATTING_NONE, const int tabc = 0) const { template <typename T> T get(const Formatting formatting = Formatting::None, const int tabc = 0) const {
if (std::is_same<T, std::string>::value) { if (std::is_same<T, std::string>::value) {
return this->get(formatting, tabc); return this->get(formatting, tabc);
} }
@ -871,6 +1027,14 @@ namespace docpp {
* @param doctype The doctype to set * @param doctype The doctype to set
*/ */
void set_doctype(const std::string& doctype); void set_doctype(const std::string& doctype);
/**
* @brief Check if the document is empty
*/
bool empty() const;
/**
* @brief Clear the document
*/
void clear();
/** /**
* @brief Construct a new Document object * @brief Construct a new Document object
*/ */
@ -881,22 +1045,26 @@ namespace docpp {
*/ */
Document(const Section& document, const std::string& doctype = "<!DOCTYPE html>") : document(document), doctype(doctype) {}; Document(const Section& document, const std::string& doctype = "<!DOCTYPE html>") : document(document), doctype(doctype) {};
Document operator=(const Document& document); Document& operator=(const Document& document);
Document operator=(const Section& section); Document& operator=(const Section& section);
bool operator==(const Document& document) const;
bool operator==(const Section& section) const;
bool operator!=(const Document& document) const;
bool operator!=(const Section& section) const;
}; };
} // namespace HTML } // inline namespace HTML
/** /**
* @brief A namespace to represent CSS elements and documents * @brief A inline namespace to represent CSS elements and documents
*/ */
namespace CSS { inline namespace CSS {
/** /**
* @brief Enum for formatting options. * @brief Enum for formatting options.
*/ */
enum Formatting { enum class Formatting {
FORMATTING_NONE, None,
FORMATTING_PRETTY, Pretty,
FORMATTING_NEWLINE, Newline,
}; };
/** /**
@ -993,8 +1161,8 @@ namespace docpp {
*/ */
void set(const std::string& key, const std::string& value); void set(const std::string& key, const std::string& value);
Property operator=(const Property& property); Property& operator=(const Property& property);
Property operator=(const std::pair<std::string, std::string>& property); Property& operator=(const std::pair<std::string, std::string>& property);
}; };
/** /**
@ -1150,12 +1318,12 @@ namespace docpp {
* @brief Get the element * @brief Get the element
* @return std::pair<std::string, std::vector<Property>> The element * @return std::pair<std::string, std::vector<Property>> The element
*/ */
std::string get(const Formatting formatting = FORMATTING_NONE, const int tabc = 0) const; std::string get(const Formatting formatting = Formatting::None, const int tabc = 0) const;
/** /**
* @brief Get the element in the form of a specific type. * @brief Get the element in the form of a specific type.
* @return T The element in the form of a specific type * @return T The element in the form of a specific type
*/ */
template <typename T> T get(const Formatting formatting = FORMATTING_NONE, const int tabc = 0) const { template <typename T> T get(const Formatting formatting = Formatting::None, const int tabc = 0) const {
if (std::is_same<T, std::string>::value) { if (std::is_same<T, std::string>::value) {
return this->get(formatting, tabc); return this->get(formatting, tabc);
} }
@ -1182,10 +1350,10 @@ namespace docpp {
*/ */
std::vector<Property> get_properties() const; std::vector<Property> get_properties() const;
Element operator=(const Element& element); Element& operator=(const Element& element);
Element operator=(const std::pair<std::string, std::vector<Property>>& element); Element& operator=(const std::pair<std::string, std::vector<Property>>& element);
void operator+=(const Property& property); Element& operator+=(const Property& property);
Property operator[](const int& index) const; Property operator[](const size_type& index) const;
}; };
/** /**
@ -1335,21 +1503,21 @@ namespace docpp {
* @brief Get the stylesheet * @brief Get the stylesheet
* @return std::string The stylesheet * @return std::string The stylesheet
*/ */
std::string get(const Formatting formatting = FORMATTING_NONE, const int tabc = 0) const; std::string get(const Formatting formatting = Formatting::None, const int tabc = 0) const;
/** /**
* @brief Get the stylesheet in the form of a specific type. * @brief Get the stylesheet in the form of a specific type.
* @return T The stylesheet in the form of a specific type * @return T The stylesheet in the form of a specific type
*/ */
template <typename T> T get(const Formatting formatting = FORMATTING_NONE, const int tabc = 0) const { template <typename T> T get(const Formatting formatting = Formatting::None, const int tabc = 0) const {
if (std::is_same<T, std::string>::value) { if (std::is_same<T, std::string>::value) {
return this->get(formatting, tabc); return this->get(formatting, tabc);
} }
return T(this->get(formatting, tabc)); return T(this->get(formatting, tabc));
} }
Stylesheet operator=(const Stylesheet& stylesheet); Stylesheet& operator=(const Stylesheet& stylesheet);
void operator+=(const Element& element); Stylesheet& operator+=(const Element& element);
Element operator[](const int& index) const; Element operator[](const int& index) const;
}; };
} // namespace CSS } // inline namespace CSS
} // namespace docpp } // inline namespace docpp

View file

@ -34,23 +34,90 @@ void docpp::HTML::Property::set(const std::pair<std::string, std::string>& prope
this->property = property; this->property = property;
} }
docpp::HTML::Properties docpp::HTML::Properties::operator=(const docpp::HTML::Property& property) { docpp::HTML::Property& docpp::HTML::Property::operator=(const docpp::HTML::Property& property) {
this->set(property.get());
return *this;
}
docpp::HTML::Property& docpp::HTML::Property::operator=(const std::pair<std::string, std::string>& property) {
this->set(property);
return *this;
}
bool docpp::HTML::Property::operator==(const docpp::HTML::Property& property) const {
return this->property == property.get();
}
bool docpp::HTML::Property::operator!=(const docpp::HTML::Property& property) const {
return this->property != property.get();
}
void docpp::HTML::Property::clear() {
this->property = {};
}
bool docpp::HTML::Property::empty() const {
return this->property.first.empty() && this->property.second.empty();
}
docpp::HTML::Properties& docpp::HTML::Properties::operator=(const docpp::HTML::Property& property) {
this->properties = {property}; this->properties = {property};
return *this; return *this;
} }
docpp::HTML::Properties docpp::HTML::Properties::operator=(const docpp::HTML::Properties& properties) { docpp::HTML::Properties& docpp::HTML::Properties::operator=(const docpp::HTML::Properties& properties) {
this->set(properties.get_properties()); this->set(properties.get_properties());
return *this; return *this;
} }
docpp::HTML::Properties docpp::HTML::Properties::operator=(const std::vector<docpp::HTML::Property>& properties) { docpp::HTML::Properties& docpp::HTML::Properties::operator=(const std::vector<docpp::HTML::Property>& properties) {
this->set(properties); this->set(properties);
return *this; return *this;
} }
void docpp::HTML::Properties::operator+=(const docpp::HTML::Property& property) { docpp::HTML::Property docpp::HTML::Properties::operator[](const size_type& index) const {
return this->at(index);
}
bool docpp::HTML::Properties::operator==(const docpp::HTML::Properties& properties) const {
return this->properties == properties.get_properties();
}
bool docpp::HTML::Properties::operator==(const docpp::HTML::Property& property) const {
for (const docpp::HTML::Property& it : this->properties) {
if (it.get() == property.get()) {
return true;
}
}
return false;
}
bool docpp::HTML::Properties::operator!=(const docpp::HTML::Properties& properties) const {
return this->properties != properties.get_properties();
}
bool docpp::HTML::Properties::operator!=(const docpp::HTML::Property& property) const {
for (const docpp::HTML::Property& it : this->properties) {
if (it.get() == property.get()) {
return false;
}
}
return true;
}
docpp::HTML::Properties& docpp::HTML::Properties::operator+=(const docpp::HTML::Property& property) {
this->push_back(property); this->push_back(property);
return *this;
}
docpp::HTML::Properties& docpp::HTML::Properties::operator+=(const docpp::HTML::Properties& properties) {
for (docpp::HTML::Properties::const_iterator it{properties.cbegin()}; it != properties.cend(); it++) {
this->push_back(*it);
}
return *this;
} }
std::vector<docpp::HTML::Property> docpp::HTML::Properties::get_properties() const { std::vector<docpp::HTML::Property> docpp::HTML::Properties::get_properties() const {
@ -135,6 +202,14 @@ docpp::HTML::Properties::size_type docpp::HTML::Properties::size() const {
return this->properties.size(); return this->properties.size();
} }
void docpp::HTML::Properties::clear() {
this->properties.clear();
}
bool docpp::HTML::Properties::empty() const {
return this->properties.empty();
}
void docpp::HTML::Properties::swap(const size_type index1, const size_type index2) { void docpp::HTML::Properties::swap(const size_type index1, const size_type index2) {
if (index1 < 0 || index1 >= this->properties.size() || index2 < 0 || index2 >= this->properties.size()) { if (index1 < 0 || index1 >= this->properties.size() || index2 < 0 || index2 >= this->properties.size()) {
throw docpp::out_of_range("Index out of range"); throw docpp::out_of_range("Index out of range");
@ -148,28 +223,65 @@ void docpp::HTML::Properties::swap(const docpp::HTML::Property& property1, const
} }
docpp::HTML::Element docpp::HTML::Element::operator=(const docpp::HTML::Element& element) { docpp::HTML::Element& docpp::HTML::Element::operator=(const docpp::HTML::Element& element) {
this->set(element.get_tag(), element.properties, element.get_data(), element.type); this->set(element.get_tag(), element.properties, element.get_data(), element.type);
return *this; return *this;
} }
void docpp::HTML::Element::operator+=(const std::string& data) { docpp::HTML::Element& docpp::HTML::Element::operator+=(const std::string& data) {
this->data += data; this->data += data;
return *this;
}
bool docpp::HTML::Element::operator==(const docpp::HTML::Element& element) const {
return this->tag == element.get_tag() && this->properties == element.properties && this->data == element.get_data() && this->type == element.type;
}
bool docpp::HTML::Element::operator!=(const docpp::HTML::Element& element) const {
return this->tag != element.get_tag() || this->properties != element.properties || this->data != element.get_data() || this->type != element.type;
} }
void docpp::HTML::Element::set(const std::string& tag, const Properties& properties, const std::string& data, const Type type) { void docpp::HTML::Element::set(const std::string& tag, const Properties& properties, const std::string& data, const Type type) {
this->set_tag(tag);
this->set_properties(properties);
this->set_data(data);
this->set_type(type);
}
void docpp::HTML::Element::set(const Tag tag, const Properties& properties, const std::string& data) {
this->set_tag(tag);
this->set_properties(properties);
this->set_data(data);
}
void docpp::HTML::Element::set_tag(const std::string& tag) {
this->tag = tag; this->tag = tag;
}
void docpp::HTML::Element::set_tag(const Tag tag) {
std::pair<std::string, docpp::HTML::Type> resolved{resolve_tag(tag)};
this->tag = resolved.first;
this->type = resolved.second;
}
void docpp::HTML::Element::set_data(const std::string& data) {
this->data = data; this->data = data;
this->properties = properties; }
void docpp::HTML::Element::set_type(const Type type) {
this->type = type; this->type = type;
} }
void docpp::HTML::Element::set_properties(const Properties& properties) {
this->properties = properties;
}
std::string docpp::HTML::Element::get(const Formatting formatting, const int tabc) const { std::string docpp::HTML::Element::get(const Formatting formatting, const int tabc) const {
std::string ret{}; std::string ret{};
if (this->type == docpp::HTML::TYPE_TEXT) { if (this->type == docpp::HTML::Type::Text_No_Formatting) {
return this->data; return this->data;
} else if (this->type == docpp::HTML::TYPE_TEXT_TAB) { } else if (this->type == docpp::HTML::Type::Text) {
for (size_type i{0}; i < tabc; i++) { for (size_type i{0}; i < tabc; i++) {
ret += "\t"; ret += "\t";
} }
@ -177,7 +289,7 @@ std::string docpp::HTML::Element::get(const Formatting formatting, const int tab
return ret + this->data; return ret + this->data;
} }
if (formatting == docpp::HTML::FORMATTING_PRETTY) { if (formatting == docpp::HTML::Formatting::Pretty) {
for (size_type i{0}; i < tabc; i++) { for (size_type i{0}; i < tabc; i++) {
ret += "\t"; ret += "\t";
} }
@ -192,17 +304,17 @@ std::string docpp::HTML::Element::get(const Formatting formatting, const int tab
ret += " " + it.get_key() + "=\"" + it.get_value() + "\""; ret += " " + it.get_key() + "=\"" + it.get_value() + "\"";
} }
if (this->type != docpp::HTML::TYPE_SELF_CLOSING) { if (this->type != docpp::HTML::Type::Self_Closing) {
ret += ">"; ret += ">";
} }
if (this->type == docpp::HTML::TYPE_NON_SELF_CLOSING) { if (this->type == docpp::HTML::Type::Non_Self_Closing) {
ret += this->data + "</" + this->tag + ">"; ret += this->data + "</" + this->tag + ">";
} else if (this->type == docpp::HTML::TYPE_SELF_CLOSING) { } else if (this->type == docpp::HTML::Type::Self_Closing) {
ret += this->data + "/>"; ret += this->data + "/>";
} }
if (formatting == docpp::HTML::FORMATTING_PRETTY || formatting == docpp::HTML::FORMATTING_NEWLINE) { if (formatting == docpp::HTML::Formatting::Pretty || formatting == docpp::HTML::Formatting::Newline) {
ret += "\n"; ret += "\n";
} }
@ -217,7 +329,25 @@ std::string docpp::HTML::Element::get_data() const {
return this->data; return this->data;
} }
docpp::HTML::Section docpp::HTML::Section::operator=(const docpp::HTML::Section& section) { docpp::HTML::Type docpp::HTML::Element::get_type() const {
return this->type;
}
docpp::HTML::Properties docpp::HTML::Element::get_properties() const {
return this->properties;
}
bool docpp::HTML::Element::empty() const {
return this->tag.empty() && this->data.empty() && this->properties.empty();
}
void docpp::HTML::Element::clear() {
this->tag.clear();
this->data.clear();
this->properties.clear();
}
docpp::HTML::Section& docpp::HTML::Section::operator=(const docpp::HTML::Section& section) {
this->tag = section.tag; this->tag = section.tag;
this->properties = section.properties; this->properties = section.properties;
this->elements = section.elements; this->elements = section.elements;
@ -227,170 +357,213 @@ docpp::HTML::Section docpp::HTML::Section::operator=(const docpp::HTML::Section&
return *this; return *this;
} }
void docpp::HTML::Section::operator+=(const docpp::HTML::Element& element) { docpp::HTML::Section& docpp::HTML::Section::operator+=(const docpp::HTML::Element& element) {
this->push_back(element); this->push_back(element);
return *this;
} }
void docpp::HTML::Section::operator+=(const docpp::HTML::Section& section) { docpp::HTML::Section& docpp::HTML::Section::operator+=(const docpp::HTML::Section& section) {
this->push_back(section); this->push_back(section);
return *this;
} }
docpp::HTML::Element docpp::HTML::Section::operator[](const int& index) const { docpp::HTML::Element docpp::HTML::Section::operator[](const int& index) const {
return this->at(index); return this->at(index);
} }
bool docpp::HTML::Section::operator==(const docpp::HTML::Section& section) const {
return this->tag == section.tag && this->properties == section.properties && this->elements == section.elements && this->sections == section.sections && this->index == section.index;
}
bool docpp::HTML::Section::operator==(const docpp::HTML::Element& element) const {
for (const Element& it : this->get_elements()) {
if (it.get() == element.get()) {
return true;
}
}
return false;
}
bool docpp::HTML::Section::operator!=(const docpp::HTML::Section& section) const {
return this->tag != section.tag || this->properties != section.properties || this->elements != section.elements || this->sections != section.sections || this->index != section.index;
}
bool docpp::HTML::Section::operator!=(const docpp::HTML::Element& element) const {
for (const Element& it : this->get_elements()) {
if (it.get() == element.get()) {
return false;
}
}
return true;
}
void docpp::HTML::Section::set(const std::string& tag, const Properties& properties) { void docpp::HTML::Section::set(const std::string& tag, const Properties& properties) {
this->tag = tag; this->tag = tag;
this->properties = properties; this->properties = properties;
} }
void docpp::HTML::Section::set_tag(const std::string& tag) {
this->tag = tag;
}
void docpp::HTML::Section::set_tag(const Tag tag) {
std::pair<std::string, docpp::HTML::Type> resolved{resolve_tag(tag)};
this->tag = resolved.first;
}
void docpp::HTML::Section::set_properties(const Properties& properties) {
this->properties = properties;
}
std::pair<std::string, docpp::HTML::Type> docpp::HTML::resolve_tag(const Tag tag) { std::pair<std::string, docpp::HTML::Type> docpp::HTML::resolve_tag(const Tag tag) {
const std::unordered_map<docpp::HTML::Tag, std::pair<std::string, docpp::HTML::Type>> tag_map{ static const std::unordered_map<docpp::HTML::Tag, std::pair<std::string, docpp::HTML::Type>> tag_map{
{ELEMENT_EMPTY, {"", docpp::HTML::TYPE_TEXT_TAB}}, {Tag::Empty, {"", docpp::HTML::Type::Text}},
{ELEMENT_EMPTY_NO_FORMAT, {"", docpp::HTML::TYPE_TEXT}}, {Tag::Empty_No_Formatting, {"", docpp::HTML::Type::Text_No_Formatting}},
{ELEMENT_ABBREVIATION, {"abbr", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Abbreviation, {"abbr", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_ABBR, {"abbr", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Abbr, {"abbr", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_ACRONYM, {"acronym", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Acronym, {"acronym", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_ADDRESS, {"address", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Address, {"address", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_APPLET, {"applet", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Applet, {"applet", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_ANCHOR, {"a", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Anchor, {"a", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_A, {"a", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::A, {"a", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_ARTICLE, {"article", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Article, {"article", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_AREA, {"area", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Area, {"area", docpp::HTML::Type::Non_Closed}},
{ELEMENT_ASIDE, {"aside", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Aside, {"aside", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_AUDIO, {"audio", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Audio, {"audio", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_BASE, {"base", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Base, {"base", docpp::HTML::Type::Non_Closed}},
{ELEMENT_BASEFONT, {"basefont", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Basefont, {"basefont", docpp::HTML::Type::Non_Closed}},
{ELEMENT_BDI, {"bdi", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Bdi, {"bdi", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_BDO, {"bdo", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Bdo, {"bdo", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_BGSOUND, {"bgsound", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Bgsound, {"bgsound", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_BIG, {"big", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Big, {"big", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_BLOCKQUOTE, {"blockquote", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Blockquote, {"blockquote", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_BODY, {"body", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Body, {"body", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_B, {"b", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::B, {"b", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_BOLD, {"b", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Bold, {"b", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_BR, {"br", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Br, {"br", docpp::HTML::Type::Non_Closed}},
{ELEMENT_BREAK, {"br", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Break, {"br", docpp::HTML::Type::Non_Closed}},
{ELEMENT_BUTTON, {"button", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Button, {"button", docpp::HTML::Type::Non_Closed}},
{ELEMENT_CAPTION, {"caption", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Caption, {"caption", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_CANVAS, {"canvas", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Canvas, {"canvas", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_CENTER, {"center", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Center, {"center", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_CITE, {"cite", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Cite, {"cite", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_CODE, {"code", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Code, {"code", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_COLGROUP, {"colgroup", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Colgroup, {"colgroup", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_COLUMN, {"col", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Column, {"col", docpp::HTML::Type::Non_Closed}},
{ELEMENT_COL, {"col", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Col, {"col", docpp::HTML::Type::Non_Closed}},
{ELEMENT_DATA, {"data", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Data, {"data", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_DATALIST, {"datalist", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Datalist, {"datalist", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_DD, {"dd", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Dd, {"dd", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_DFN, {"dfn", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Dfn, {"dfn", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_DEFINE, {"dfn", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Define, {"dfn", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_DELETE, {"del", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Delete, {"del", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_DEL, {"del", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Del, {"del", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_DETAILS, {"details", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Details, {"details", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_DIALOG, {"dialog", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Dialog, {"dialog", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_DIR, {"dir", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Dir, {"dir", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_DIV, {"div", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Div, {"div", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_DL, {"dl", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Dl, {"dl", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_DT, {"dt", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Dt, {"dt", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_EMBED, {"embed", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Embed, {"embed", docpp::HTML::Type::Non_Closed}},
{ELEMENT_FIELDSET, {"fieldset", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Fieldset, {"fieldset", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_FIGCAPTION, {"figcaption", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Figcaption, {"figcaption", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_FIGURE, {"figure", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Figure, {"figure", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_FONT, {"font", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Font, {"font", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_FOOTER, {"footer", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Footer, {"footer", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_FORM, {"form", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Form, {"form", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_FRAME, {"frame", docpp::HTML::TYPE_SELF_CLOSING}}, {Tag::Frame, {"frame", docpp::HTML::Type::Self_Closing}},
{ELEMENT_FRAMESET, {"frameset", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Frameset, {"frameset", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_HEAD, {"head", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Head, {"head", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_HEADER, {"header", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Header, {"header", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_H1, {"h1", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::H1, {"h1", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_H2, {"h2", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::H2, {"h2", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_H3, {"h3", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::H3, {"h3", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_H4, {"h4", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::H4, {"h4", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_H5, {"h5", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::H5, {"h5", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_H6, {"h6", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::H6, {"h6", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_HR, {"hr", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Hr, {"hr", docpp::HTML::Type::Non_Closed}},
{ELEMENT_HGROUP, {"hgroup", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Hgroup, {"hgroup", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_HTML, {"html", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Html, {"html", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_IFRAME, {"iframe", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Iframe, {"iframe", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_IMAGE, {"img", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Image, {"img", docpp::HTML::Type::Non_Closed}},
{ELEMENT_IMG, {"img", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Img, {"img", docpp::HTML::Type::Non_Closed}},
{ELEMENT_INPUT, {"input", docpp::HTML::TYPE_SELF_CLOSING}}, {Tag::Input, {"input", docpp::HTML::Type::Self_Closing}},
{ELEMENT_INS, {"ins", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Ins, {"ins", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_ISINDEX, {"isindex", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Isindex, {"isindex", docpp::HTML::Type::Non_Closed}},
{ELEMENT_ITALIC, {"i", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Italic, {"i", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_I, {"i", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::I, {"i", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_KBD, {"kbd", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Kbd, {"kbd", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_KEYGEN, {"keygen", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Keygen, {"keygen", docpp::HTML::Type::Non_Closed}},
{ELEMENT_LABEL, {"label", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Label, {"label", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_LEGEND, {"legend", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Legend, {"legend", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_LIST, {"li", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::List, {"li", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_LI, {"li", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Li, {"li", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_LINK, {"link", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Link, {"link", docpp::HTML::Type::Non_Closed}},
{ELEMENT_MAIN, {"main", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Main, {"main", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_MARK, {"mark", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Mark, {"mark", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_MARQUEE, {"marquee", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Marquee, {"marquee", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_MENUITEM, {"menuitem", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Menuitem, {"menuitem", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_META, {"meta", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Meta, {"meta", docpp::HTML::Type::Non_Closed}},
{ELEMENT_METER, {"meter", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Meter, {"meter", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_NAV, {"nav", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Nav, {"nav", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_NOBREAK, {"nobr", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Nobreak, {"nobr", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_NOBR, {"nobr", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Nobr, {"nobr", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_NOEMBED, {"noembed", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Noembed, {"noembed", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_NOSCRIPT, {"noscript", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Noscript, {"noscript", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_OBJECT, {"object", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Object, {"object", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_OPTGROUP, {"optgroup", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Optgroup, {"optgroup", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_OPTION, {"option", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Option, {"option", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_OUTPUT, {"output", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Output, {"output", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_PARAGRAPH, {"p", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Paragraph, {"p", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_P, {"p", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::P, {"p", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_PARAM, {"param", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Param, {"param", docpp::HTML::Type::Non_Closed}},
{ELEMENT_PHRASE, {"phrase", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Phrase, {"phrase", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_PRE, {"pre", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Pre, {"pre", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_PROGRESS, {"progress", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Progress, {"progress", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_QUOTE, {"q", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Quote, {"q", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_Q, {"q", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Q, {"q", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_RP, {"rp", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Rp, {"rp", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_RT, {"rt", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Rt, {"rt", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_RUBY, {"ruby", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Ruby, {"ruby", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_OUTDATED, {"s", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Outdated, {"s", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_S, {"s", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::S, {"s", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_SAMPLE, {"samp", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Sample, {"samp", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_SAMP, {"samp", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Samp, {"samp", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_SCRIPT, {"script", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Script, {"script", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_SECTION, {"section", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Section, {"section", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_SMALL, {"small", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Small, {"small", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_SOURCE, {"source", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Source, {"source", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_SPACER, {"spacer", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Spacer, {"spacer", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_SPAN, {"span", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Span, {"span", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_STRIKE, {"strike", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Strike, {"strike", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_STRONG, {"strong", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Strong, {"strong", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_STYLE, {"style", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Style, {"style", docpp::HTML::Type::Non_Closed}},
{ELEMENT_SUB, {"sub", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Sub, {"sub", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_SUBSCRIPT, {"sub", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Subscript, {"sub", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_SUP, {"sup", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Sup, {"sup", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_SUPERSCRIPT, {"sup", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Superscript, {"sup", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_SUMMARY, {"summary", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Summary, {"summary", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_SVG, {"svg", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Svg, {"svg", docpp::HTML::Type::Non_Closed}},
{ELEMENT_TABLE, {"table", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Table, {"table", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_TBODY, {"tbody", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Tbody, {"tbody", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_TD, {"td", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Td, {"td", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_TEMPLATE, {"template", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Template, {"template", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_TFOOT, {"tfoot", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Tfoot, {"tfoot", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_TH, {"th", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Th, {"th", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_TR, {"tr", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Tr, {"tr", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_THEAD, {"thead", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Thead, {"thead", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_TIME, {"time", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Time, {"time", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_TITLE, {"title", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Title, {"title", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_TRACK, {"track", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Track, {"track", docpp::HTML::Type::Non_Closed}},
{ELEMENT_TT, {"tt", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Tt, {"tt", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_UNDERLINE, {"u", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Underline, {"u", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_U, {"u", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::U, {"u", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_VAR, {"var", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Var, {"var", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_VIDEO, {"video", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Video, {"video", docpp::HTML::Type::Non_Self_Closing}},
{ELEMENT_WBR, {"wbr", docpp::HTML::TYPE_NON_CLOSED}}, {Tag::Wbr, {"wbr", docpp::HTML::Type::Non_Closed}},
{ELEMENT_XMP, {"xmp", docpp::HTML::TYPE_NON_SELF_CLOSING}}, {Tag::Xmp, {"xmp", docpp::HTML::Type::Non_Self_Closing}},
}; };
if (tag_map.find(tag) != tag_map.end()) { if (tag_map.find(tag) != tag_map.end()) {
@ -530,18 +703,26 @@ docpp::HTML::Section::size_type docpp::HTML::Section::find(const Section& sectio
} }
docpp::HTML::Section::size_type docpp::HTML::Section::find(const std::string& str) { docpp::HTML::Section::size_type docpp::HTML::Section::find(const std::string& str) {
const std::vector<Element> elements = this->get_elements(); const std::vector<docpp::HTML::Element> elements{this->get_elements()};
for (size_type i{0}; i < elements.size(); i++) { for (size_type i{0}; i < this->size(); i++) {
if (!elements.at(i).get().compare(str)) { if (elements.size() <= i) {
break;
}
if (elements.at(i).get().find(str) != docpp::HTML::Section::npos) {
return i; return i;
} }
} }
const std::vector<Section> sections = this->get_sections(); const std::vector<docpp::HTML::Section> sections{this->get_sections()};
for (size_type i{0}; i < sections.size(); i++) { for (size_type i{0}; i < this->size(); i++) {
if (!sections.at(i).get().compare(str)) { if (elements.size() <= i) {
break;
}
if (elements.at(i).get().find(str) != docpp::HTML::Section::npos) {
return i; return i;
} }
} }
@ -585,6 +766,18 @@ docpp::HTML::Section::size_type docpp::HTML::Section::size() const {
return this->index; return this->index;
} }
void docpp::HTML::Section::clear() {
this->tag.clear();
this->properties.clear();
this->elements.clear();
this->sections.clear();
this->index = 0;
}
bool docpp::HTML::Section::empty() const {
return this->index == 0;
}
std::vector<docpp::HTML::Element> docpp::HTML::Section::get_elements() const { std::vector<docpp::HTML::Element> docpp::HTML::Section::get_elements() const {
std::vector<docpp::HTML::Element> ret{}; std::vector<docpp::HTML::Element> ret{};
ret.reserve(this->index); ret.reserve(this->index);
@ -621,7 +814,7 @@ std::string docpp::HTML::Section::get(const Formatting formatting, const int tab
} }
} }
if (formatting == docpp::HTML::FORMATTING_PRETTY) { if (formatting == docpp::HTML::Formatting::Pretty) {
for (size_type i{0}; i < tabcount; i++) { for (size_type i{0}; i < tabcount; i++) {
ret += "\t"; ret += "\t";
} }
@ -639,7 +832,7 @@ std::string docpp::HTML::Section::get(const Formatting formatting, const int tab
ret += ">"; ret += ">";
if (formatting == docpp::HTML::FORMATTING_PRETTY || formatting == docpp::HTML::FORMATTING_NEWLINE) { if (formatting == docpp::HTML::Formatting::Pretty || formatting == docpp::HTML::Formatting::Newline) {
ret += "\n"; ret += "\n";
} }
} }
@ -650,13 +843,13 @@ std::string docpp::HTML::Section::get(const Formatting formatting, const int tab
} else if (this->sections.find(i) != this->sections.end()) { } else if (this->sections.find(i) != this->sections.end()) {
ret += this->sections.at(i).get(formatting, tabcount + 1); ret += this->sections.at(i).get(formatting, tabcount + 1);
if (formatting == docpp::HTML::FORMATTING_PRETTY || formatting == docpp::HTML::FORMATTING_NEWLINE) { if (formatting == docpp::HTML::Formatting::Pretty || formatting == docpp::HTML::Formatting::Newline) {
ret += "\n"; ret += "\n";
} }
} }
} }
if (formatting == docpp::HTML::FORMATTING_PRETTY) { if (formatting == docpp::HTML::Formatting::Pretty) {
for (size_type i{0}; i < tabcount; i++) { for (size_type i{0}; i < tabcount; i++) {
ret += "\t"; ret += "\t";
} }
@ -667,6 +860,14 @@ std::string docpp::HTML::Section::get(const Formatting formatting, const int tab
return std::move(ret); return std::move(ret);
} }
std::string docpp::HTML::Section::get_tag() const {
return this->tag;
}
docpp::HTML::Properties docpp::HTML::Section::get_properties() const {
return this->properties;
}
void docpp::HTML::Section::swap(const size_type index1, const size_type index2) { void docpp::HTML::Section::swap(const size_type index1, const size_type index2) {
if (this->elements.find(index1) != this->elements.end() && this->elements.find(index2) != this->elements.end()) { if (this->elements.find(index1) != this->elements.end() && this->elements.find(index2) != this->elements.end()) {
std::swap(this->elements[index1], this->elements[index2]); std::swap(this->elements[index1], this->elements[index2]);
@ -686,7 +887,7 @@ void docpp::HTML::Section::swap(const Section& section1, const Section& section2
} }
std::string docpp::HTML::Document::get(const Formatting formatting, const int tabc) const { std::string docpp::HTML::Document::get(const Formatting formatting, const int tabc) const {
return this->doctype + (formatting == FORMATTING_PRETTY ? "\n" : formatting == FORMATTING_NEWLINE ? "\n" : "") + this->document.get(formatting, tabc); return this->doctype + (formatting == Formatting::Pretty ? "\n" : formatting == Formatting::Newline ? "\n" : "") + this->document.get(formatting, tabc);
} }
docpp::HTML::Section& docpp::HTML::Document::get_section() { docpp::HTML::Section& docpp::HTML::Document::get_section() {
@ -701,17 +902,42 @@ void docpp::HTML::Document::set_doctype(const std::string& doctype) {
this->doctype = doctype; this->doctype = doctype;
} }
docpp::HTML::Document docpp::HTML::Document::operator=(const docpp::HTML::Document& document) { void docpp::HTML::Document::clear() {
this->doctype.clear();
this->document.clear();
}
bool docpp::HTML::Document::empty() const {
return this->doctype.empty() && this->document.empty();
}
docpp::HTML::Document& docpp::HTML::Document::operator=(const docpp::HTML::Document& document) {
this->set(document.get()); this->set(document.get());
this->set_doctype(document.get_doctype()); this->set_doctype(document.get_doctype());
return *this; return *this;
} }
docpp::HTML::Document docpp::HTML::Document::operator=(const docpp::HTML::Section& section) { docpp::HTML::Document& docpp::HTML::Document::operator=(const docpp::HTML::Section& section) {
this->set(section); this->set(section);
return *this; return *this;
} }
bool docpp::HTML::Document::operator==(const docpp::HTML::Document& document) const {
return this->get() == document.get();
}
bool docpp::HTML::Document::operator==(const docpp::HTML::Section& section) const {
return this->document == section;
}
bool docpp::HTML::Document::operator!=(const docpp::HTML::Document& document) const {
return this->doctype != document.get_doctype() || this->document != document.document;
}
bool docpp::HTML::Document::operator!=(const docpp::HTML::Section& section) const {
return this->document != section;
}
std::string docpp::HTML::Document::get_doctype() const { std::string docpp::HTML::Document::get_doctype() const {
return this->doctype; return this->doctype;
} }
@ -744,26 +970,27 @@ void docpp::CSS::Property::set(const std::string& key, const std::string& value)
this->property = std::make_pair(key, value); this->property = std::make_pair(key, value);
} }
docpp::CSS::Property docpp::CSS::Property::operator=(const docpp::CSS::Property& property) { docpp::CSS::Property& docpp::CSS::Property::operator=(const docpp::CSS::Property& property) {
this->set(property.get()); this->set(property.get());
return *this; return *this;
} }
docpp::CSS::Property docpp::CSS::Property::operator=(const std::pair<std::string, std::string>& property) { docpp::CSS::Property& docpp::CSS::Property::operator=(const std::pair<std::string, std::string>& property) {
this->set(property); this->set(property);
return *this; return *this;
} }
docpp::CSS::Element docpp::CSS::Element::operator=(const docpp::CSS::Element& element) { docpp::CSS::Element& docpp::CSS::Element::operator=(const docpp::CSS::Element& element) {
this->set({element.get_tag(), element.get_properties()}); this->set({element.get_tag(), element.get_properties()});
return *this; return *this;
} }
void docpp::CSS::Element::operator+=(const Property& property) { docpp::CSS::Element& docpp::CSS::Element::operator+=(const Property& property) {
this->push_back(property); this->push_back(property);
return *this;
} }
docpp::CSS::Property docpp::CSS::Element::operator[](const int& index) const { docpp::CSS::Property docpp::CSS::Element::operator[](const size_type& index) const {
return this->at(index); return this->at(index);
} }
@ -856,7 +1083,7 @@ std::string docpp::CSS::Element::get(const Formatting formatting, const int tabc
std::string ret{}; std::string ret{};
if (this->element.first.compare("")) { if (this->element.first.compare("")) {
if (formatting == docpp::CSS::FORMATTING_PRETTY) { if (formatting == docpp::CSS::Formatting::Pretty) {
for (size_type i{0}; i < tabc; i++) { for (size_type i{0}; i < tabc; i++) {
ret += "\t"; ret += "\t";
} }
@ -864,7 +1091,7 @@ std::string docpp::CSS::Element::get(const Formatting formatting, const int tabc
ret += this->element.first + " {"; ret += this->element.first + " {";
if (formatting == docpp::CSS::FORMATTING_PRETTY || formatting == docpp::CSS::FORMATTING_NEWLINE) { if (formatting == docpp::CSS::Formatting::Pretty || formatting == docpp::CSS::Formatting::Newline) {
ret += "\n"; ret += "\n";
} }
@ -872,7 +1099,7 @@ std::string docpp::CSS::Element::get(const Formatting formatting, const int tabc
if (!it.get_key().compare("")) continue; if (!it.get_key().compare("")) continue;
if (!it.get_value().compare("")) continue; if (!it.get_value().compare("")) continue;
if (formatting == docpp::CSS::FORMATTING_PRETTY) { if (formatting == docpp::CSS::Formatting::Pretty) {
for (size_type i{0}; i < tabc + 1; i++) { for (size_type i{0}; i < tabc + 1; i++) {
ret += "\t"; ret += "\t";
} }
@ -880,12 +1107,12 @@ std::string docpp::CSS::Element::get(const Formatting formatting, const int tabc
ret += it.get_key() + ": " + it.get_value() + ";"; ret += it.get_key() + ": " + it.get_value() + ";";
if (formatting == docpp::CSS::FORMATTING_PRETTY || formatting == docpp::CSS::FORMATTING_NEWLINE) { if (formatting == docpp::CSS::Formatting::Pretty || formatting == docpp::CSS::Formatting::Newline) {
ret += "\n"; ret += "\n";
} }
} }
if (formatting == docpp::CSS::FORMATTING_PRETTY) { if (formatting == docpp::CSS::Formatting::Pretty) {
for (size_type i{0}; i < tabc; i++) { for (size_type i{0}; i < tabc; i++) {
ret += "\t"; ret += "\t";
} }
@ -893,7 +1120,7 @@ std::string docpp::CSS::Element::get(const Formatting formatting, const int tabc
ret += "}"; ret += "}";
if (formatting == docpp::CSS::FORMATTING_PRETTY || formatting == docpp::CSS::FORMATTING_NEWLINE) { if (formatting == docpp::CSS::Formatting::Pretty || formatting == docpp::CSS::Formatting::Newline) {
ret += "\n"; ret += "\n";
} }
} }
@ -937,13 +1164,14 @@ void docpp::CSS::Stylesheet::erase(const size_type index) {
this->elements.erase(this->elements.begin() + index); this->elements.erase(this->elements.begin() + index);
} }
docpp::CSS::Stylesheet docpp::CSS::Stylesheet::operator=(const docpp::CSS::Stylesheet& stylesheet) { docpp::CSS::Stylesheet& docpp::CSS::Stylesheet::operator=(const docpp::CSS::Stylesheet& stylesheet) {
this->set(stylesheet.get_elements()); this->set(stylesheet.get_elements());
return *this; return *this;
} }
void docpp::CSS::Stylesheet::operator+=(const Element& element) { docpp::CSS::Stylesheet& docpp::CSS::Stylesheet::operator+=(const Element& element) {
this->push_back(element); this->push_back(element);
return *this;
} }
docpp::CSS::Element docpp::CSS::Stylesheet::operator[](const int& index) const { docpp::CSS::Element docpp::CSS::Stylesheet::operator[](const int& index) const {

File diff suppressed because it is too large Load diff