hemplate

Simple XML template engine
git clone git://git.dimitrijedobrota.com/hemplate.git
Log | Files | Refs | README | LICENSE

commit ba1eaaa156534fa7cbc18261d1627db25cb585d5
parent 41d951b84e20292564864a236ce056874123adf7
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Sun, 23 Jun 2024 00:16:37 +0200

Subsequent .set style or .set class are additive

* Improve formatting

Diffstat:
M.clang-format | 10+++++-----
MCMakeLists.txt | 2+-
Minclude/hemplate/attribute.hpp | 16+++++-----------
Minclude/hemplate/classes.hpp | 3+--
Minclude/hemplate/element.hpp | 3+--
Minclude/hemplate/elementAtomic.hpp | 3+--
Minclude/hemplate/elementBoolean.hpp | 3+--
Minclude/hemplate/streamable.hpp | 3+--
Msource/attribute.cpp | 35+++++++++++++++++++++++++++++------
Msource/element.cpp | 36+++++++++++++++---------------------
Mtest/source/hemplate_test.cpp | 11+++++++----
11 files changed, 67 insertions(+), 58 deletions(-)

diff --git a/.clang-format b/.clang-format @@ -18,8 +18,8 @@ AllowShortBlocksOnASingleLine: Empty AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: Inline AllowShortLambdasOnASingleLine: All -AllowShortIfStatementsOnASingleLine: true -AllowShortLoopsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: AllIfsAndElse +AllowShortLoopsOnASingleLine: true AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: true @@ -29,16 +29,16 @@ BinPackParameters: false BraceWrapping: AfterCaseLabel: false AfterClass: true - AfterControlStatement: MultiLine + AfterControlStatement: Always AfterEnum: true AfterFunction: true - AfterNamespace: true + AfterNamespace: false AfterObjCDeclaration: false AfterStruct: true AfterUnion: true AfterExternBlock: true BeforeCatch: false - BeforeElse: false + BeforeElse: true BeforeLambdaBody: true BeforeWhile: false IndentBraces: false diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -4,7 +4,7 @@ include(cmake/prelude.cmake) project( hemplate - VERSION 0.1.4 + VERSION 0.1.5 DESCRIPTION "Simple HTML template engine" HOMEPAGE_URL "https://git.dimitrijedobrota.com/hemplate.git" LANGUAGES CXX diff --git a/include/hemplate/attribute.hpp b/include/hemplate/attribute.hpp @@ -7,8 +7,7 @@ #include "hemplate/hemplate_export.hpp" #include "hemplate/streamable.hpp" -namespace hemplate -{ +namespace hemplate { class HEMPLATE_EXPORT attribute : public streamable { @@ -57,15 +56,8 @@ public: attributeList& operator=(attributeList&&) = default; ~attributeList() override = default; - attributeList(std::initializer_list<attribute> list) - : m_attributes(list) - { - } - - attributeList(attribute attr) // NOLINT - : m_attributes({std::move(attr)}) - { - } + attributeList(std::initializer_list<attribute> list); + attributeList(attribute attr); // NOLINT attributeList& set(const std::string& name); attributeList& set(const std::string& name, const std::string& value); @@ -76,6 +68,8 @@ public: private: std::vector<attribute> m_attributes; + attribute m_class = attribute("class"); + attribute m_style = attribute("style"); }; } // namespace hemplate diff --git a/include/hemplate/classes.hpp b/include/hemplate/classes.hpp @@ -27,8 +27,7 @@ struct tag static char const* get_name() { return Name.data(); } }; -namespace hemplate -{ +namespace hemplate { using a = elementBoolean<tag<"a">>; using abbr = elementBoolean<tag<"abbr">>; diff --git a/include/hemplate/element.hpp b/include/hemplate/element.hpp @@ -8,8 +8,7 @@ #include "hemplate/hemplate_export.hpp" #include "hemplate/streamable.hpp" -namespace hemplate -{ +namespace hemplate { class element; diff --git a/include/hemplate/elementAtomic.hpp b/include/hemplate/elementAtomic.hpp @@ -3,8 +3,7 @@ #include "hemplate/element.hpp" #include "hemplate/hemplate_export.hpp" -namespace hemplate -{ +namespace hemplate { template<typename Tag> class HEMPLATE_EXPORT elementAtomic : public element diff --git a/include/hemplate/elementBoolean.hpp b/include/hemplate/elementBoolean.hpp @@ -3,8 +3,7 @@ #include "hemplate/element.hpp" #include "hemplate/hemplate_export.hpp" -namespace hemplate -{ +namespace hemplate { template<typename Tag> class HEMPLATE_EXPORT elementBoolean : public element diff --git a/include/hemplate/streamable.hpp b/include/hemplate/streamable.hpp @@ -4,8 +4,7 @@ #include "hemplate/hemplate_export.hpp" -namespace hemplate -{ +namespace hemplate { class HEMPLATE_EXPORT streamable { diff --git a/source/attribute.cpp b/source/attribute.cpp @@ -1,7 +1,18 @@ +#include <algorithm> + #include "hemplate/attribute.hpp" -namespace hemplate +namespace hemplate { + +attributeList::attributeList(std::initializer_list<attribute> list) +{ + for (const auto& attr : list) set(attr.get_name(), attr.get_value()); +} + +attributeList::attributeList(attribute attr) // NOLINT { + set(attr.get_name(), attr.get_value()); +} bool attribute::operator!=(const attribute& rhs) const { @@ -20,22 +31,34 @@ void attribute::render(std::ostream& out) const attributeList& attributeList::set(const std::string& name) { - m_attributes.emplace_back(name); + if (name != "class" && name != "style") m_attributes.emplace_back(name); return *this; } attributeList& attributeList::set(const std::string& name, const std::string& value) { - m_attributes.emplace_back(name, value); + if (name == "class") + { + if (m_class.get_value().empty()) m_class.set_value(value); + else m_class.set_value(m_class.get_value() + " " + value); + } + else if (name == "style") + { + if (m_style.get_value().empty()) m_style.set_value(value); + else m_style.set_value(m_style.get_value() + "; " + value); + } + else m_attributes.emplace_back(name, value); + return *this; } void attributeList::render(std::ostream& out) const { - for (const auto& attr : m_attributes) { - out << attr << ' '; - } + if (!m_class.get_value().empty()) out << m_class << ' '; + if (!m_style.get_value().empty()) out << m_style << ' '; + + for (const auto& attr : m_attributes) out << attr << ' '; } } // namespace hemplate diff --git a/source/element.cpp b/source/element.cpp @@ -1,7 +1,6 @@ #include "hemplate/element.hpp" -namespace hemplate -{ +namespace hemplate { element& element::add(const element& elem) { @@ -32,35 +31,34 @@ void element::render(std::ostream& out) const const auto open_tag = [this, &out](bool atomic) { out << '<' << get_name(); - if (!m_attributes.empty()) { - out << ' '; - m_attributes.render(out); - } + if (!m_attributes.empty()) out << ' ', m_attributes.render(out); out << (atomic ? " />" : ">"); }; const auto close_tag = [this, &out]() { out << "</" << get_name() << '>'; }; - if (m_type == Type::Atomic) { + if (m_type == Type::Atomic) + { open_tag(true); return; } - if (!m_data.empty()) { + if (!m_data.empty()) + { open_tag(false); - if (!m_embeded.empty()) { - m_embeded.render(out); - } else { - out << m_data; - } + if (!m_embeded.empty()) m_embeded.render(out); + else out << m_data; close_tag(); return; } - if (m_embeded.empty()) { + if (m_embeded.empty()) + { tgl_state(); get_state() ? open_tag(false) : close_tag(); - } else { + } + else + { open_tag(false); m_embeded.render(out); close_tag(); @@ -77,9 +75,7 @@ elementList& elementList::operator=(const elementList& rhs) if (this == &rhs) return *this; m_elems.clear(); - for (const auto& elem : rhs.m_elems) { - add(*elem); - } + for (const auto& elem : rhs.m_elems) add(*elem); return *this; } @@ -98,9 +94,7 @@ elementList& elementList::add(std::unique_ptr<element> elem) void elementList::render(std::ostream& out) const { - for (const auto& elem : m_elems) { - elem->render(out); - } + for (const auto& elem : m_elems) elem->render(out); } } // namespace hemplate diff --git a/test/source/hemplate_test.cpp b/test/source/hemplate_test.cpp @@ -6,14 +6,17 @@ int main() { using namespace hemplate; // NOLINT - const attributeList ul_attrs({{"id", "main_ul"}, {"class", "home_ul"}}); const attributeList li_attrs({"class", "home_li"}); + const attributeList ul_attrs({{"id", "main_ul"}, + {"class", "home_ul"}, + {"style", "margin-bottom: 1em"}}); std::cout << html() << std::endl; std::cout << ul("Won't see", ul_attrs) - .set("style", "margin-top: 1em;") - .add(li("Item 1", li_attrs)) - .add(li("Item 2", li_attrs)) + .set("style", "margin-top: 1em") + .set("class", "center") + .add(li("Item 1", li_attrs).set("class", "item1")) + .add(li("Item 2", li_attrs).set("class", "item2")) << std::endl; std::cout << meta() << std::endl; std::cout << html() << std::endl;