commit f63c8fed3fdfe6d1db925c9a4682fc6dc5c7d49b
parent 597755cfc6f067e3eee598175b6d88763c9993c1
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Sat, 22 Jun 2024 17:01:50 +0200
Proof of concept HTML tags
Diffstat:
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;
}