hemplateSimple XML template engine | 
          
| git clone git://git.dimitrijedobrota.com/hemplate.git | 
| Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | 
| commit | c5294d1c704cdb3f305970a2e3ef46fa98e6fda1 | 
| parent | 7b79f6bda1d93c11b4e581d375b585cb9bbe9c63 | 
| author | Dimitrije Dobrota < mail@dimitrijedobrota.com > | 
| date | Sat, 3 May 2025 11:26:24 +0200 | 
Rename classes to common
| M | CMakeLists.txt | | | ++ --- | 
| M | include/hemplate/atom.hpp | | | + - | 
| D | include/hemplate/classes.hpp | | | -------------------------------------------------------------- | 
| A | include/hemplate/common.hpp | | | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| M | include/hemplate/html.hpp | | | + - | 
| M | include/hemplate/rss.hpp | | | + - | 
| M | include/hemplate/sitemap.hpp | | | + - | 
| D | source/classes.cpp | | | ------------------------------------------------------------ | 
| A | source/common.cpp | | | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| M | test/CMakeLists.txt | | | + - | 
| D | test/source/classes_test.cpp | | | --------------------------------------------------------------------------- | 
| A | test/source/common_test.cpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
12 files changed, 204 insertions(+), 205 deletions(-)
diff --git a/ CMakeLists.txt b/ CMakeLists.txt
          @@ -13,13 +13,13 @@ 
          project(
        
        
          include(cmake/project-is-top-level.cmake)
          include(cmake/variables.cmake)
          find_package(based 0.1 CONFIG REQUIRED)
          find_package(based 0.1.1 CONFIG REQUIRED)
          # ---- Declare library ----
          add_library(
              hemplate_hemplate
              source/classes.cpp
              source/common.cpp
              source/attribute.cpp
          )
          target_link_libraries(hemplate_hemplate PUBLIC based::based)
        
        
          @@ -76,7 +76,6 @@ 
          if(PROJECT_IS_TOP_LEVEL)
        
        
            endif()
          endif()
          # ---- Developer mode ----
          if(NOT hemplate_DEVELOPER_MODE)
        
        diff --git a/ include/hemplate/atom.hpp b/ include/hemplate/atom.hpp
@@ -1,6 +1,6 @@
#pragma once
          #include "hemplate/classes.hpp"
          #include "hemplate/common.hpp"
          #include "hemplate/hemplate_export.hpp"
          namespace hemplate::atom
        
        diff --git a/ include/hemplate/classes.hpp b/ include/hemplate/classes.hpp
@@ -1,62 +0,0 @@
#pragma once
          #include <array>
          #include <based/string.hpp>
          #include <based/type_traits.hpp>
          #include "hemplate/element.hpp"
          #include "hemplate/hemplate_export.hpp"
          namespace hemplate
          {
          class HEMPLATE_EXPORT comment : public element
          {
          public:
            explicit comment(std::string_view data)
                : element(std::format("<-- {} -->", data))
            {
            }
          };
          class HEMPLATE_EXPORT xml : public element
          {
            static auto attrs(std::string_view version, std::string_view encoding)
            {
              return attribute_list {
                  {"version", version},
                  {"encoding", encoding},
              };
            }
          public:
            static constexpr const auto def_version = "1.0";
            static constexpr const auto def_encoding = "UTF-8";
            explicit xml(
                std::string_view version = def_version,
                std::string_view encoding = def_encoding
            )
                : element(std::format("<? xml {}?>", attrs(version, encoding)))
            {
            }
          };
          template<std::ranges::forward_range R>
          element transform(
              const R& range,
              based::Procedure<element, std::ranges::range_value_t<R>> auto proc
          )
          {
            std::vector<element> res;
            res.reserve(std::size(range));
            for (const auto& elem : range) {
              res.emplace_back(proc(elem));
            }
            return element {res};
          }
          }  // namespace hemplate
        
        diff --git a/ include/hemplate/common.hpp b/ include/hemplate/common.hpp
@@ -0,0 +1,62 @@
#pragma once
          #include <array>
          #include <based/string.hpp>
          #include <based/type_traits.hpp>
          #include "hemplate/element.hpp"
          #include "hemplate/hemplate_export.hpp"
          namespace hemplate
          {
          class HEMPLATE_EXPORT comment : public element
          {
          public:
            explicit comment(std::string_view data)
                : element(std::format("<-- {} -->", data))
            {
            }
          };
          class HEMPLATE_EXPORT xml : public element
          {
            static auto attrs(std::string_view version, std::string_view encoding)
            {
              return attribute_list {
                  {"version", version},
                  {"encoding", encoding},
              };
            }
          public:
            static constexpr const auto def_version = "1.0";
            static constexpr const auto def_encoding = "UTF-8";
            explicit xml(
                std::string_view version = def_version,
                std::string_view encoding = def_encoding
            )
                : element(std::format("<? xml {}?>", attrs(version, encoding)))
            {
            }
          };
          template<std::ranges::forward_range R>
          element transform(
              const R& range,
              based::Procedure<element, std::ranges::range_value_t<R>> auto proc
          )
          {
            std::vector<element> res;
            res.reserve(std::size(range));
            for (const auto& elem : range) {
              res.emplace_back(proc(elem));
            }
            return element {res};
          }
          }  // namespace hemplate
        
        diff --git a/ include/hemplate/html.hpp b/ include/hemplate/html.hpp
@@ -1,6 +1,6 @@
#pragma once
          #include "hemplate/classes.hpp"
          #include "hemplate/common.hpp"
          namespace hemplate::html
          {
        
        diff --git a/ include/hemplate/rss.hpp b/ include/hemplate/rss.hpp
@@ -1,6 +1,6 @@
#pragma once
          #include "hemplate/classes.hpp"
          #include "hemplate/common.hpp"
          #include "hemplate/hemplate_export.hpp"
          namespace hemplate::rss
        
        diff --git a/ include/hemplate/sitemap.hpp b/ include/hemplate/sitemap.hpp
@@ -1,6 +1,6 @@
#pragma once
          #include "hemplate/classes.hpp"
          #include "hemplate/common.hpp"
          #include "hemplate/hemplate_export.hpp"
          namespace hemplate::sitemap
        
        diff --git a/ source/classes.cpp b/ source/classes.cpp
@@ -1,60 +0,0 @@
#include <chrono>
          #include <ctime>
          #include <format>
          #include <string>
          #include "hemplate/atom.hpp"
          #include "hemplate/rss.hpp"
          namespace
          {
          auto sec_since_epoch(int64_t sec)
          {
            return std::chrono::time_point_cast<std::chrono::seconds>(
                std::chrono::system_clock::from_time_t(time_t {0})
                + std::chrono::seconds(sec)
            );
          }
          auto get_time_now()
          {
            return std::chrono::current_zone()
                       ->to_local(std::chrono::system_clock::now())
                       .time_since_epoch()
                / std::chrono::seconds(1);
          }
          }  // namespace
          namespace hemplate::atom
          {
          std::string format_time(int64_t sec)
          {
            static constexpr const char* rfc3339_f = "{:%FT%H:%M:%SZ}";
            return std::format(rfc3339_f, sec_since_epoch(sec));
          }
          std::string format_time_now()
          {
            return format_time(get_time_now());
          }
          }  // namespace hemplate::atom
          namespace hemplate::rss
          {
          std::string format_time(int64_t sec)
          {
            static constexpr const char* rfc882_f = "{:%a, %d %b %Y %H:%M:%S %z}";
            return std::format(rfc882_f, sec_since_epoch(sec));
          }
          std::string format_time_now()
          {
            return format_time(get_time_now());
          }
          }  // namespace hemplate::rss
        
        diff --git a/ source/common.cpp b/ source/common.cpp
@@ -0,0 +1,60 @@
#include <chrono>
          #include <ctime>
          #include <format>
          #include <string>
          #include "hemplate/atom.hpp"
          #include "hemplate/rss.hpp"
          namespace
          {
          auto sec_since_epoch(int64_t sec)
          {
            return std::chrono::time_point_cast<std::chrono::seconds>(
                std::chrono::system_clock::from_time_t(time_t {0})
                + std::chrono::seconds(sec)
            );
          }
          auto get_time_now()
          {
            return std::chrono::current_zone()
                       ->to_local(std::chrono::system_clock::now())
                       .time_since_epoch()
                / std::chrono::seconds(1);
          }
          }  // namespace
          namespace hemplate::atom
          {
          std::string format_time(int64_t sec)
          {
            static constexpr const char* rfc3339_f = "{:%FT%H:%M:%SZ}";
            return std::format(rfc3339_f, sec_since_epoch(sec));
          }
          std::string format_time_now()
          {
            return format_time(get_time_now());
          }
          }  // namespace hemplate::atom
          namespace hemplate::rss
          {
          std::string format_time(int64_t sec)
          {
            static constexpr const char* rfc882_f = "{:%a, %d %b %Y %H:%M:%S %z}";
            return std::format(rfc882_f, sec_since_epoch(sec));
          }
          std::string format_time_now()
          {
            return format_time(get_time_now());
          }
          }  // namespace hemplate::rss
        
        diff --git a/ test/CMakeLists.txt b/ test/CMakeLists.txt
          @@ -24,7 +24,7 @@ 
          endfunction()
        
        
          add_test(attribute_test)
          add_test(attribute_list_test)
          add_test(element_test)
          add_test(classes_test)
          add_test(common_test)
          add_test(html_test)
          add_test(atom_test)
          add_test(rss_test)
        
        diff --git a/ test/source/classes_test.cpp b/ test/source/classes_test.cpp
@@ -1,75 +0,0 @@
#include "hemplate/classes.hpp"
          #include <catch2/catch_test_macros.hpp>
          TEST_CASE("comment", "[classes/comment]")
          {
            const hemplate::comment comment {"hello world"};
            REQUIRE(std::string(comment) == "<-- hello world -->\n");
          }
          TEST_CASE("xml", "[classes/xml]")
          {
            SECTION("default")
            {
              const hemplate::xml xml;
              REQUIRE(
                  std::string(xml) == "<? xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
              );
            }
            SECTION("version")
            {
              const hemplate::xml xml {"ver"};
              REQUIRE(
                  std::string(xml) == "<? xml version=\"ver\" encoding=\"UTF-8\"?>\n"
              );
            }
            SECTION("version encoding")
            {
              const hemplate::xml xml {"ver", "utf"};
              REQUIRE(std::string(xml) == "<? xml version=\"ver\" encoding=\"utf\"?>\n");
            }
          }
          TEST_CASE("transform", "[classes/transform]")
          {
            using tag = hemplate::element_boolean<"t">;
            using child = hemplate::element_boolean<"c">;
            SECTION("direct")
            {
              const std::vector<std::string> vec = {"1", "2"};
              const auto t = tag {hemplate::transform(
                  vec,
                  [](const auto& e)
                  {
                    return child {e};
                  }
              )};
              REQUIRE(
                  std::string(t)
                  == "<t>\n  <c>1</c>\n  <c>2</c>\n</t>\n"
              );
            }
            SECTION("indirect")
            {
              const std::vector<std::string> vec = {"1", "2"};
              const auto t = tag {hemplate::transform(
                  vec,
                  [](const auto& e)
                  {
                    return hemplate::element {e};
                  }
              )};
              REQUIRE(std::string(t) == "<t>\n  1\n  2\n</t>\n");
            }
          }
        
        diff --git a/ test/source/common_test.cpp b/ test/source/common_test.cpp
@@ -0,0 +1,75 @@
#include "hemplate/common.hpp"
          #include <catch2/catch_test_macros.hpp>
          TEST_CASE("comment", "[common/comment]")
          {
            const hemplate::comment comment {"hello world"};
            REQUIRE(std::string(comment) == "<-- hello world -->\n");
          }
          TEST_CASE("xml", "[common/xml]")
          {
            SECTION("default")
            {
              const hemplate::xml xml;
              REQUIRE(
                  std::string(xml) == "<? xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
              );
            }
            SECTION("version")
            {
              const hemplate::xml xml {"ver"};
              REQUIRE(
                  std::string(xml) == "<? xml version=\"ver\" encoding=\"UTF-8\"?>\n"
              );
            }
            SECTION("version encoding")
            {
              const hemplate::xml xml {"ver", "utf"};
              REQUIRE(std::string(xml) == "<? xml version=\"ver\" encoding=\"utf\"?>\n");
            }
          }
          TEST_CASE("transform", "[common/transform]")
          {
            using tag = hemplate::element_boolean<"t">;
            using child = hemplate::element_boolean<"c">;
            SECTION("direct")
            {
              const std::vector<std::string> vec = {"1", "2"};
              const auto t = tag {hemplate::transform(
                  vec,
                  [](const auto& e)
                  {
                    return child {e};
                  }
              )};
              REQUIRE(
                  std::string(t)
                  == "<t>\n  <c>1</c>\n  <c>2</c>\n</t>\n"
              );
            }
            SECTION("indirect")
            {
              const std::vector<std::string> vec = {"1", "2"};
              const auto t = tag {hemplate::transform(
                  vec,
                  [](const auto& e)
                  {
                    return hemplate::element {e};
                  }
              )};
              REQUIRE(std::string(t) == "<t>\n  1\n  2\n</t>\n");
            }
          }