From 7d3c9ec7368a5d25235e818c2c147ba7e89f6567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gassmann?= Date: Sun, 27 Feb 2022 14:06:15 +0100 Subject: [+] Added base project --- inc/maddy/blockparser.h | 203 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 inc/maddy/blockparser.h (limited to 'inc/maddy/blockparser.h') diff --git a/inc/maddy/blockparser.h b/inc/maddy/blockparser.h new file mode 100644 index 0000000..9df4fa6 --- /dev/null +++ b/inc/maddy/blockparser.h @@ -0,0 +1,203 @@ +/* + * This project is licensed under the MIT license. For more information see the + * LICENSE file. + */ +#pragma once + +// ----------------------------------------------------------------------------- + +#include +#include +#include +// windows compatibility includes +#include +#include + +// ----------------------------------------------------------------------------- + +namespace maddy { + +// ----------------------------------------------------------------------------- + +/** + * BlockParser + * + * The code expects every child to have the following static function to be + * implemented: + * `static bool IsStartingLine(const std::string& line)` + * + * @class + */ +class BlockParser +{ +public: + /** + * ctor + * + * @method + * @param {std::function} parseLineCallback + * @param {std::function(const std::string& line)>} getBlockParserForLineCallback + */ + BlockParser( + std::function parseLineCallback, + std::function(const std::string& line)> getBlockParserForLineCallback + ) + : result("", std::ios_base::ate | std::ios_base::in | std::ios_base::out) + , childParser(nullptr) + , parseLineCallback(parseLineCallback) + , getBlockParserForLineCallback(getBlockParserForLineCallback) + {} + + /** + * dtor + * + * @method + */ + virtual ~BlockParser() {} + + /** + * AddLine + * + * Adding a line which has to be parsed. + * + * @method + * @param {std::string&} line + * @return {void} + */ + virtual void + AddLine(std::string& line) + { + this->parseBlock(line); + + if (this->isInlineBlockAllowed() && !this->childParser) + { + this->childParser = this->getBlockParserForLine(line); + } + + if (this->childParser) + { + this->childParser->AddLine(line); + + if (this->childParser->IsFinished()) + { + this->result << this->childParser->GetResult().str(); + this->childParser = nullptr; + } + + return; + } + + if (this->isLineParserAllowed()) + { + this->parseLine(line); + } + + this->result << line; + } + + /** + * IsFinished + * + * Check if the BlockParser is done + * + * @method + * @return {bool} + */ + virtual bool IsFinished() const = 0; + + /** + * GetResult + * + * Get the parsed HTML output. + * + * @method + * @return {std::stringstream} + */ + std::stringstream& + GetResult() + { + return this->result; + } + + /** + * Clear + * + * Clear the result to reuse the parser object. + * + * It is only used by one test for now. + * + * @method + * @return {void} + */ + void + Clear() + { + this->result.str(""); + } + +protected: + std::stringstream result; + std::shared_ptr childParser; + + virtual bool isInlineBlockAllowed() const = 0; + virtual bool isLineParserAllowed() const = 0; + virtual void parseBlock(std::string& line) = 0; + + void + parseLine(std::string& line) + { + if (parseLineCallback) + { + parseLineCallback(line); + } + } + + uint32_t + getIndentationWidth(const std::string& line) const + { + bool hasMetNonSpace = false; + + uint32_t indentation = static_cast( + std::count_if( + line.begin(), + line.end(), + [&hasMetNonSpace](unsigned char c) + { + if (hasMetNonSpace) + { + return false; + } + + if (std::isspace(c)) + { + return true; + } + + hasMetNonSpace = true; + return false; + } + ) + ); + + return indentation; + } + + std::shared_ptr + getBlockParserForLine(const std::string& line) + { + if (getBlockParserForLineCallback) + { + return getBlockParserForLineCallback(line); + } + + return nullptr; + } + +private: + std::function parseLineCallback; + std::function(const std::string& line)> getBlockParserForLineCallback; +}; // class BlockParser + +// ----------------------------------------------------------------------------- + +} // namespace maddy -- cgit v1.2.3