From cdd0cc6b784ed7a3e8cec55387b8acacbac208ca Mon Sep 17 00:00:00 2001 From: jmsgrogan Date: Wed, 12 Oct 2022 09:01:19 +0100 Subject: [PATCH] Start templating engine. --- src/compiler/CMakeLists.txt | 2 + src/compiler/TemplatingEngine.cpp | 0 src/compiler/TemplatingEngine.h | 147 +++++++++++++++++++++++++ src/core/StringUtils.cpp | 31 ++++++ src/core/StringUtils.h | 2 + test/CMakeLists.txt | 3 +- test/compiler/TestTemplatingEngine.cpp | 15 +++ test/data/base.html | 17 +++ test/data/index.html | 14 +++ 9 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 src/compiler/TemplatingEngine.cpp create mode 100644 src/compiler/TemplatingEngine.h create mode 100644 test/compiler/TestTemplatingEngine.cpp create mode 100644 test/data/base.html create mode 100644 test/data/index.html diff --git a/src/compiler/CMakeLists.txt b/src/compiler/CMakeLists.txt index c8f4bed..04c667c 100644 --- a/src/compiler/CMakeLists.txt +++ b/src/compiler/CMakeLists.txt @@ -1,9 +1,11 @@ list(APPEND compiler_HEADERS Lexer.h + TemplatingEngine.h ) list(APPEND compiler_LIB_INCLUDES Lexer.cpp + TemplatingEngine.cpp ) add_library(compiler SHARED ${compiler_LIB_INCLUDES} ${compiler_HEADERS}) diff --git a/src/compiler/TemplatingEngine.cpp b/src/compiler/TemplatingEngine.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/compiler/TemplatingEngine.h b/src/compiler/TemplatingEngine.h new file mode 100644 index 0000000..60bae69 --- /dev/null +++ b/src/compiler/TemplatingEngine.h @@ -0,0 +1,147 @@ +#pragma once + +#include "File.h" +#include "Directory.h" +#include "StringUtils.h" + +#include +#include +#include + +class TemplateBlock +{ + +}; + +class TemplateFile +{ +public: + TemplateFile(const Path& path) + : mPath(path) + { + + } + + std::vector getProcessedContent() const + { + return mProcessedContent; + } + + std::string getName() const + { + return mPath.stem().string(); + } + + void loadContent() + { + std::cout << "Trying to load file at: " << mPath << std::endl; + mRawContent = File(mPath).readLines(); + mWorkingLine = 0; + for (const auto& line : mRawContent) + { + processLine(line); + mWorkingLine++; + } + } + + void processLine(const std::string& line) + { + bool last_was_ldelimiter{ false }; + bool last_was_rdelimiter{ false }; + bool in_tag{ false }; + std::string working_string; + for (auto c : line) + { + if (c == '{') + { + last_was_ldelimiter = true; + } + else if (c == '%' && last_was_ldelimiter) + { + last_was_ldelimiter = false; + in_tag = true; + working_string = ""; + } + else if (c == '%' && in_tag) + { + last_was_rdelimiter = true; + } + else if (c == '}' && last_was_rdelimiter) + { + break; + } + else + { + working_string += c; + } + } + + if (in_tag) + { + onFoundTag(working_string); + } + } + + void onFoundTag(const std::string& tag_string) + { + const auto tag_elements = StringUtils::split(tag_string); + + for (const auto& element : tag_elements) + { + std::cout << "Got tag element: " << element << std::endl; + } + } + +private: + Path mPath; + unsigned mWorkingLine{ 0 }; + std::string mParentName; + std::vector mRawContent; + std::vector mProcessedContent; + std::vector mBlocks; +}; + +class TemplatingEngine +{ +public: + TemplatingEngine(const Path& workingDirectory) + : mWorkingDirectory(workingDirectory) + { + + } + + void loadTemplateFiles() + { + const auto files = Directory::getFilesWithExtension(mWorkingDirectory, mTemplateExtension); + for (const auto& file : files) + { + mTemplateFiles.push_back(TemplateFile(file)); + } + } + + void processTemplate(const std::string& name) + { + for (auto& file : mTemplateFiles) + { + const auto filename = file.getName(); + if (filename == name) + { + processTemplate(file); + break; + } + } + } + + void processTemplate(TemplateFile& file) + { + file.loadContent(); + } + + + + +private: + std::vector mTemplateFiles; + Path mWorkingDirectory; + std::string mTemplateExtension{ ".html" }; +}; \ No newline at end of file diff --git a/src/core/StringUtils.cpp b/src/core/StringUtils.cpp index da21622..145b0ea 100644 --- a/src/core/StringUtils.cpp +++ b/src/core/StringUtils.cpp @@ -20,6 +20,37 @@ bool StringUtils::IsSpace(char c) return std::isspace(c, loc); } +std::vector StringUtils::split(const std::string& input) +{ + std::vector substrings; + std::string working_string; + std::locale loc; + bool last_was_nonspace{ false }; + for (auto c : input) + { + if (std::isspace(c, loc)) + { + if (last_was_nonspace) + { + substrings.push_back(working_string); + working_string = ""; + last_was_nonspace = false; + } + } + else + { + last_was_nonspace = true; + working_string += c; + } + } + if (!working_string.empty()) + { + substrings.push_back(working_string); + } + return substrings; +} + + std::string StringUtils::ToLower(const std::string& s) { std::string ret; diff --git a/src/core/StringUtils.h b/src/core/StringUtils.h index 757895c..7336b52 100644 --- a/src/core/StringUtils.h +++ b/src/core/StringUtils.h @@ -1,6 +1,7 @@ #pragma once #include +#include class StringUtils { @@ -20,4 +21,5 @@ public: static std::string ToLower(const std::string& s); static std::string convert(const std::wstring& input); static std::string ToPaddedString(unsigned numBytes, unsigned entry); + static std::vector split(const std::string& input); }; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 92d2f56..9159a01 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,6 +13,7 @@ list(APPEND TestFiles core/TestBinaryStream.cpp core/TestTomlReader.cpp compiler/TestLexer.cpp + compiler/TestTemplatingEngine.cpp compression/TestStreamCompressor.cpp database/TestDatabase.cpp fonts/TestFontReader.cpp @@ -50,7 +51,7 @@ foreach(TestFile ${TestFiles}) add_executable(${TestName} ${TestFile}) - target_link_libraries(${TestName} PUBLIC core compression fonts network image publishing video database geometry audio graphics web client test_utils ${DBUS_LIBRARIES}) + target_link_libraries(${TestName} PUBLIC core compiler compression fonts network image publishing video database geometry audio graphics web client test_utils ${DBUS_LIBRARIES}) set_property(TARGET ${TestName} PROPERTY FOLDER test) endforeach() diff --git a/test/compiler/TestTemplatingEngine.cpp b/test/compiler/TestTemplatingEngine.cpp new file mode 100644 index 0000000..cd85e4a --- /dev/null +++ b/test/compiler/TestTemplatingEngine.cpp @@ -0,0 +1,15 @@ +#include "TemplatingEngine.h" + +#include +#include + +int main() +{ + const auto data_loc = std::filesystem::path(__FILE__) / "../../data"; + + auto engine = TemplatingEngine(data_loc); + engine.loadTemplateFiles(); + engine.processTemplate("index"); + + +} \ No newline at end of file diff --git a/test/data/base.html b/test/data/base.html new file mode 100644 index 0000000..a302942 --- /dev/null +++ b/test/data/base.html @@ -0,0 +1,17 @@ + + + + {% block head %} + + {% block title %}{% endblock %} - My Webpage + {% endblock %} + + +
{% block content %}{% endblock %}
+ + + \ No newline at end of file diff --git a/test/data/index.html b/test/data/index.html new file mode 100644 index 0000000..7d3ffd6 --- /dev/null +++ b/test/data/index.html @@ -0,0 +1,14 @@ +{% extends "base.html" %} +{% block title %}Index{% endblock %} +{% block head %} + {{ super() }} + +{% endblock %} +{% block content %} +

Index

+

+ Welcome to my awesome homepage. +

+{% endblock %} \ No newline at end of file