hemplate

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

commit bf0389ba151e90bf9837fb2c442a73b14e5ef91b
parent 51fafc0d0c594527807ffbeae0075095fedc502a
author Dimitrije Dobrota <mail@dimitrijedobrota.com>
date Fri, 25 Apr 2025 09:34:22 +0200

Even more simplicity and flexibility

Diffstat:
M example/html.cpp | ++
M include/hemplate/atom.hpp | -
M include/hemplate/classes.hpp | ++++ ------
M include/hemplate/element.hpp | +++++++++++++++++++++++++++ -----------------------------------------------------
M include/hemplate/html.hpp | + --
M include/hemplate/rss.hpp | -
M include/hemplate/sitemap.hpp | -
M source/element.cpp | + -----------

8 files changed, 35 insertions(+), 75 deletions(-)


diff --git a/ example/html.cpp b/ example/html.cpp

@@ -22,10 +22,12 @@ int main() html::li { {li_attrs, {{"class", "item1"}}}, "Item 1",
"some text",
}, html::li { {li_attrs, {{"class", "item2"}}}, "Item 2",
"some text",
}, }, html::hr {},

diff --git a/ include/hemplate/atom.hpp b/ include/hemplate/atom.hpp

@@ -33,7 +33,6 @@ public: } };
using hemplate::blank;
using hemplate::comment; using hemplate::element; using hemplate::transform;

diff --git a/ include/hemplate/classes.hpp b/ include/hemplate/classes.hpp

@@ -15,7 +15,7 @@ class HEMPLATE_EXPORT comment : public element { public: explicit comment(std::string_view data)
: element(std::format("<-- {} -->", data), "", "")
: element(std::format("<-- {} -->", data))
{ } };

@@ -36,15 +36,13 @@ public: std::string_view version = default_version, std::string_view encoding = default_encoding )
: element(
std::format("<? {}?>", attribute_list {version, encoding}), "", ""
)
: element(std::format("<? {}?>", attribute_list {version, encoding}))
{ } }; template<std::ranges::forward_range R>
blank transform(
element transform(
const R& range, based::Procedure<std::ranges::range_value_t<R>> auto proc ) {

@@ -55,7 +53,7 @@ blank transform( res.emplace_back(proc(elem)); }
return blank {res};
return element {res};
} } // namespace hemplate

diff --git a/ include/hemplate/element.hpp b/ include/hemplate/element.hpp

@@ -27,6 +27,9 @@ public: Boolean, };
template<based::string_literal Tag, Type MyType>
friend class element_builder;
private: std::string m_otag; std::string m_ctag;

@@ -37,23 +40,6 @@ private: void render_children(std::ostream& out, std::size_t indent_value) const; void render(std::ostream& out, std::size_t indent_value) const;
public:
explicit element(std::string_view open_tag)
: m_otag(open_tag)
{
}
explicit element(
std::string_view open_tag,
std::string_view close_tag,
std::string_view data
)
: m_otag(open_tag)
, m_ctag(close_tag)
, m_data(data)
{
}
explicit element( std::string_view open_tag, std::string_view close_tag,

@@ -76,6 +62,24 @@ public: { }
public:
// NOLINTBEGIN *-explicit-constructor
element(std::string_view data)
: m_data(data)
{
}
element(const is_element auto&... children)
: m_children(std::initializer_list<element> {children...})
{
}
element(std::span<const element> children)
: m_children(std::begin(children), std::end(children))
{
}
// NOLINTEND *-explicit-constructor
explicit operator std::string() const { std::stringstream ss;

@@ -105,13 +109,9 @@ class HEMPLATE_EXPORT element_builder<Tag, element::Type::Boolean> } public:
explicit element_builder(std::string_view data)
: element(open(), close(), data)
{
}
explicit element_builder(const is_element auto&... children)
: element(open(), close(), children...)
template<typename... Args>
explicit element_builder(Args&&... args)
: element(open(), close(), element(std::forward<Args>(args))...)
{ }

@@ -119,16 +119,9 @@ public: : element(open(), close(), children) { }
explicit element_builder(const attribute_list& attrs, std::string_view data)
: element(open(attrs), close(), data)
{
}
explicit element_builder(
const attribute_list& attrs, const is_element auto&... children
)
: element(open(attrs), close(), children...)
template<typename... Args>
explicit element_builder(const attribute_list& attrs, Args&&... args)
: element(open(attrs), close(), element(std::forward<Args>(args))...)
{ }

@@ -157,23 +150,4 @@ public: } };
class HEMPLATE_EXPORT blank : public element
{
public:
explicit blank(std::string_view data)
: element("", "", data)
{
}
explicit blank(const is_element auto&... children)
: element("", "", children...)
{
}
explicit blank(std::span<const element> children)
: element("", "", children)
{
}
};
} // namespace hemplate

diff --git a/ include/hemplate/html.hpp b/ include/hemplate/html.hpp

@@ -5,7 +5,6 @@ namespace hemplate::html {
using hemplate::blank;
using hemplate::comment; using hemplate::element; using hemplate::transform;

@@ -15,7 +14,7 @@ class doctype : public element { public: explicit doctype()
: element("<!DOCTYPE html>", "", "")
: element("<!DOCTYPE html>")
{ } };

diff --git a/ include/hemplate/rss.hpp b/ include/hemplate/rss.hpp

@@ -87,7 +87,6 @@ public: } };
using hemplate::blank;
using hemplate::comment; using hemplate::element; using hemplate::transform;

diff --git a/ include/hemplate/sitemap.hpp b/ include/hemplate/sitemap.hpp

@@ -31,7 +31,6 @@ public: } };
using hemplate::blank;
using hemplate::comment; using hemplate::element; using hemplate::transform;

diff --git a/ source/element.cpp b/ source/element.cpp

@@ -26,20 +26,10 @@ void element::render(std::ostream& out, std::size_t indent_value) const return; }
if (m_ctag.empty()) {
out << indent << m_otag << '\n';
return;
}
if (!m_data.empty()) {
out << indent << m_otag << m_data << m_ctag << '\n';
return;
}
if (!m_children.empty()) { out << indent << m_otag << '\n'; render_children(out, indent_value + 2);
out << m_ctag << '\n';
out << indent << m_ctag << '\n';
return; }