hemplateSimple XML template engine |
git clone git://git.dimitrijedobrota.com/hemplate.git |
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | |
commit | f63c8fed3fdfe6d1db925c9a4682fc6dc5c7d49b |
parent | 597755cfc6f067e3eee598175b6d88763c9993c1 |
author | Dimitrije Dobrota <mail@dimitrijedobrota.com> |
date | Sat, 22 Jun 2024 15:01:50 +0200 |
Proof of concept HTML tags
Diffstat:M | .clang-format | | | ++-- |
M | .clang-tidy | | | +++++----- |
M | CMakeLists.txt | | | ++-- |
A | include/hemplate/classes.hpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | include/hemplate/element.hpp | | | +++++++++++++++++++++++++++++++++++++++++++++ |
A | include/hemplate/elementAtomic.hpp | | | +++++++++++++++++++++++++++++ |
A | include/hemplate/elementBoolean.hpp | | | +++++++++++++++++++++++++++++ |
D | include/hemplate/hemplate.hpp | | | ----------------- |
A | include/hemplate/streamable.hpp | | | +++++++++++++++++++++++++++++ |
A | source/element.cpp | | | +++++++++++++++++ |
D | source/hemplate.cpp | | | ------------- |
M | test/source/hemplate_test.cpp | | | +++++-- |
12 files changed, 304 insertions(+), 41 deletions(-)
diff --git a/.clang-format b/.clang-format
@@ -4,10 +4,10 @@ Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveAssignments: true
AlignConsecutiveBitFields: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: DontAlign
AlignEscapedNewlines: Right
AlignOperands: DontAlign
AlignTrailingComments: false
AllowAllArgumentsOnNextLine: true
diff --git a/.clang-tidy b/.clang-tidy
@@ -57,7 +57,7 @@ CheckOptions:
- key: 'readability-identifier-naming.AbstractClassCase'
value: 'lower_case'
- key: 'readability-identifier-naming.ClassCase'
value: 'lower_case'
value: 'camelBack'
- key: 'readability-identifier-naming.ClassConstantCase'
value: 'lower_case'
- key: 'readability-identifier-naming.ClassMemberCase'
@@ -79,9 +79,9 @@ CheckOptions:
- key: 'readability-identifier-naming.ConstexprVariableCase'
value: 'lower_case'
- key: 'readability-identifier-naming.EnumCase'
value: 'lower_case'
value: 'CamelCase'
- key: 'readability-identifier-naming.EnumConstantCase'
value: 'lower_case'
value: 'CamelCase'
- key: 'readability-identifier-naming.FunctionCase'
value: 'lower_case'
- key: 'readability-identifier-naming.GlobalConstantCase'
@@ -135,7 +135,7 @@ CheckOptions:
- key: 'readability-identifier-naming.PublicMethodCase'
value: 'lower_case'
- key: 'readability-identifier-naming.ScopedEnumConstantCase'
value: 'lower_case'
value: 'CamelCase'
- key: 'readability-identifier-naming.StaticConstantCase'
value: 'lower_case'
- key: 'readability-identifier-naming.StaticVariableCase'
@@ -152,7 +152,7 @@ CheckOptions:
value: 'lower_case'
- key: 'readability-identifier-naming.TypeTemplateParameterCase'
value: 'CamelCase'
- key: 'readability-identifier-naming.TypeTemplateParameterIgnoredRegexp',
- key: 'readability-identifier-naming.TypeTemplateParameterIgnoredRegexp'
value: 'expr-type'
- key: 'readability-identifier-naming.UnionCase'
value: 'lower_case'
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -4,7 +4,7 @@ include(cmake/prelude.cmake)
project(
hemplate
VERSION 0.1.0
VERSION 0.1.1
DESCRIPTION "Simple HTML template engine"
HOMEPAGE_URL "https://git.dimitrijedobrota.com/hemplate.git"
LANGUAGES CXX
@@ -17,7 +17,7 @@ include(cmake/variables.cmake)
add_library(
hemplate_hemplate
source/hemplate.cpp
source/element.cpp
)
add_library(hemplate::hemplate ALIAS hemplate_hemplate)
diff --git a/include/hemplate/classes.hpp b/include/hemplate/classes.hpp
@@ -0,0 +1,141 @@
#pragma once
#include <array>
#include "hemplate/elementAtomic.hpp"
#include "hemplate/elementBoolean.hpp"
#include "hemplate/hemplate_export.hpp"
template<std::size_t N>
struct string_literal
{
// NOLINTNEXTLINE
constexpr string_literal(const char (&str)[N])
: m_value(std::to_array(str))
{
}
constexpr std::size_t size() const { return N; }
constexpr const char* data() const { return m_value.data(); }
std::array<char, N> m_value;
};
template<string_literal Name>
struct tag
{
static char const* get_name() { return Name.data(); }
};
namespace hemplate
{
using a = elementBoolean<tag<"a">>;
using abbr = elementBoolean<tag<"abbr">>;
using address = elementBoolean<tag<"address">>;
using area = elementAtomic<tag<"area">>;
using article = elementBoolean<tag<"article">>;
using aside = elementBoolean<tag<"aside">>;
using audio = elementBoolean<tag<"audio">>;
using b = elementBoolean<tag<"b">>;
using base = elementAtomic<tag<"base">>;
using bdi = elementBoolean<tag<"bdi">>;
using bdo = elementBoolean<tag<"bdo">>;
using blockquote = elementBoolean<tag<"blockquote">>;
using body = elementBoolean<tag<"body">>;
using br = elementAtomic<tag<"br">>;
using button = elementBoolean<tag<"button">>;
using canvas = elementBoolean<tag<"canvas">>;
using caption = elementBoolean<tag<"caption">>;
using cite = elementBoolean<tag<"cite">>;
using code = elementBoolean<tag<"code">>;
using col = elementAtomic<tag<"col">>;
using colgroup = elementBoolean<tag<"colgroup">>;
using data = elementBoolean<tag<"data">>;
using datalist = elementBoolean<tag<"datalist">>;
using dd = elementBoolean<tag<"dd">>;
using del = elementBoolean<tag<"del">>;
using details = elementBoolean<tag<"details">>;
using dfn = elementBoolean<tag<"dfn">>;
using dialog = elementBoolean<tag<"dialog">>;
using div = elementBoolean<tag<"div">>;
using dl = elementBoolean<tag<"dl">>;
using dt = elementBoolean<tag<"dt">>;
using em = elementBoolean<tag<"em">>;
using embed = elementAtomic<tag<"embed">>;
using fieldset = elementBoolean<tag<"fieldset">>;
using figcaption = elementBoolean<tag<"figcaption">>;
using figure = elementBoolean<tag<"figure">>;
using footer = elementBoolean<tag<"footer">>;
using form = elementBoolean<tag<"form">>;
using h1 = elementBoolean<tag<"h1">>;
using head = elementBoolean<tag<"head">>;
using header = elementBoolean<tag<"header">>;
using hgroup = elementBoolean<tag<"hgroup">>;
using hr = elementAtomic<tag<"hr">>;
using html = elementBoolean<tag<"html">>;
using i = elementBoolean<tag<"i">>;
using iframe = elementBoolean<tag<"iframe">>;
using img = elementAtomic<tag<"img">>;
using input = elementAtomic<tag<"input">>;
using ins = elementBoolean<tag<"ins">>;
using kbd = elementBoolean<tag<"kbd">>;
using label = elementBoolean<tag<"label">>;
using legend = elementBoolean<tag<"legend">>;
using li = elementBoolean<tag<"li">>;
using link = elementAtomic<tag<"link">>;
using main = elementBoolean<tag<"main">>;
using map = elementBoolean<tag<"map">>;
using mark = elementBoolean<tag<"mark">>;
using menu = elementBoolean<tag<"menu">>;
using meta = elementAtomic<tag<"meta">>;
using meter = elementBoolean<tag<"meter">>;
using nav = elementBoolean<tag<"nav">>;
using noscript = elementBoolean<tag<"noscript">>;
using object = elementBoolean<tag<"object">>;
using ol = elementBoolean<tag<"ol">>;
using optgroup = elementBoolean<tag<"optgroup">>;
using option = elementBoolean<tag<"option">>;
using output = elementBoolean<tag<"output">>;
using p = elementBoolean<tag<"p">>;
using param = elementAtomic<tag<"param">>;
using picture = elementBoolean<tag<"picture">>;
using pre = elementBoolean<tag<"pre">>;
using progress = elementBoolean<tag<"progress">>;
using q = elementBoolean<tag<"q">>;
using rp = elementBoolean<tag<"rp">>;
using rt = elementBoolean<tag<"rt">>;
using ruby = elementBoolean<tag<"ruby">>;
using s = elementBoolean<tag<"s">>;
using samp = elementBoolean<tag<"samp">>;
using script = elementBoolean<tag<"script">>;
using search = elementBoolean<tag<"search">>;
using section = elementBoolean<tag<"section">>;
using select = elementBoolean<tag<"select">>;
using small = elementBoolean<tag<"small">>;
using source = elementAtomic<tag<"source">>;
using span = elementBoolean<tag<"span">>;
using strong = elementBoolean<tag<"strong">>;
using style = elementBoolean<tag<"style">>;
using sub = elementBoolean<tag<"sub">>;
using summary = elementBoolean<tag<"summary">>;
using sup = elementBoolean<tag<"sup">>;
using svg = elementBoolean<tag<"svg">>;
using table = elementBoolean<tag<"table">>;
using tbody = elementBoolean<tag<"tbody">>;
using td = elementBoolean<tag<"td">>;
using textarea = elementBoolean<tag<"textarea">>;
using tfoot = elementBoolean<tag<"tfoot">>;
using th = elementBoolean<tag<"th">>;
using thead = elementBoolean<tag<"thead">>;
using time = elementBoolean<tag<"time">>;
using title = elementBoolean<tag<"title">>;
using tr = elementBoolean<tag<"tr">>;
using track = elementAtomic<tag<"track">>;
using u = elementBoolean<tag<"u">>;
using ul = elementBoolean<tag<"ul">>;
using var = elementBoolean<tag<"var">>;
using video = elementBoolean<tag<"video">>;
using wbr = elementAtomic<tag<"wbr">>;
} // namespace hemplate
diff --git a/include/hemplate/element.hpp b/include/hemplate/element.hpp
@@ -0,0 +1,45 @@
#pragma once
#include <string>
#include "hemplate/hemplate_export.hpp"
#include "hemplate/streamable.hpp"
namespace hemplate
{
class HEMPLATE_EXPORT element : public streamable
{
public:
enum class Type
{
Atomic,
Boolean,
};
explicit element(Type type)
: m_type(type)
{
}
element(const element&) = default;
element(element&&) noexcept = default;
element& operator=(const element&) = default;
element& operator=(element&&) noexcept = default;
~element() override = default;
Type get_type() const { return m_type; }
std::string get_data() const { return m_data; }
void set_data(const std::string& data) { m_data = data; }
virtual const char* get_name() const = 0;
void render(std::ostream& out) const override;
private:
Type m_type;
std::string m_data;
};
} // namespace hemplate
diff --git a/include/hemplate/elementAtomic.hpp b/include/hemplate/elementAtomic.hpp
@@ -0,0 +1,29 @@
#pragma once
#include "hemplate/element.hpp"
#include "hemplate/hemplate_export.hpp"
namespace hemplate
{
template<typename Tag>
class HEMPLATE_EXPORT elementAtomic : public element
{
public:
elementAtomic()
: element(Type::Atomic)
{
}
elementAtomic(const elementAtomic&) = default;
elementAtomic(elementAtomic&&) noexcept = default;
elementAtomic& operator=(const elementAtomic&) = default;
elementAtomic& operator=(elementAtomic&&) noexcept = default;
~elementAtomic() override = default;
const char* get_name() const override { return Tag::get_name(); }
private:
};
} // namespace hemplate
diff --git a/include/hemplate/elementBoolean.hpp b/include/hemplate/elementBoolean.hpp
@@ -0,0 +1,29 @@
#pragma once
#include "hemplate/element.hpp"
#include "hemplate/hemplate_export.hpp"
namespace hemplate
{
template<typename Tag>
class HEMPLATE_EXPORT elementBoolean : public element
{
public:
elementBoolean()
: element(Type::Boolean)
{
}
elementBoolean(const elementBoolean&) = default;
elementBoolean(elementBoolean&&) noexcept = default;
elementBoolean& operator=(const elementBoolean&) = default;
elementBoolean& operator=(elementBoolean&&) noexcept = default;
~elementBoolean() override = default;
const char* get_name() const override { return Tag::get_name(); }
private:
};
} // namespace hemplate
diff --git a/include/hemplate/hemplate.hpp b/include/hemplate/hemplate.hpp
@@ -1,17 +0,0 @@
#pragma once
#include <string>
#include "hemplate/hemplate_export.hpp"
class HEMPLATE_EXPORT exported_class
{
public:
exported_class();
char const* name() const;
private:
HEMPLATE_SUPPRESS_C4251
std::string m_name;
};
diff --git a/include/hemplate/streamable.hpp b/include/hemplate/streamable.hpp
@@ -0,0 +1,29 @@
#pragma once
#include <ostream>
#include "hemplate/hemplate_export.hpp"
namespace hemplate
{
class HEMPLATE_EXPORT streamable
{
public:
streamable() = default;
streamable(const streamable&) = default;
streamable(streamable&&) noexcept = default;
streamable& operator=(const streamable&) = default;
streamable& operator=(streamable&&) noexcept = default;
virtual ~streamable() = default;
virtual void render(std::ostream& out) const = 0;
friend std::ostream& operator<<(std::ostream& out, const streamable& obj)
{
obj.render(out);
return out;
}
};
} // namespace hemplate
diff --git a/source/element.cpp b/source/element.cpp
@@ -0,0 +1,17 @@
#include "hemplate/element.hpp"
namespace hemplate
{
void element::render(std::ostream& out) const
{
if (get_type() == Type::Boolean) {
out << "<" << get_name() << ">";
out << get_data();
out << "</" << get_name() << ">";
} else {
out << "<" << get_name() << " />";
}
}
} // namespace hemplate
diff --git a/source/hemplate.cpp b/source/hemplate.cpp
@@ -1,13 +0,0 @@
#include <string>
#include "hemplate/hemplate.hpp"
exported_class::exported_class()
: m_name {"hemplate"}
{
}
char const* exported_class::name() const
{
return m_name.c_str();
}
diff --git a/test/source/hemplate_test.cpp b/test/source/hemplate_test.cpp
@@ -1,8 +1,11 @@
#include <string>
#include <iostream>
#include "hemplate/hemplate.hpp"
#include "hemplate/classes.hpp"
int main()
{
std::cout << hemplate::a() << std::endl;
std::cout << hemplate::meta() << std::endl;
return 0;
}