Mercurial > thymian
diff 3rdparty/maddy/blockparser.h @ 0:a4671277546c tip
created the repository for the thymian project
| author | ferencd |
|---|---|
| date | Tue, 17 Aug 2021 11:19:54 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/maddy/blockparser.h Tue Aug 17 11:19:54 2021 +0200 @@ -0,0 +1,203 @@ +/* + * This project is licensed under the MIT license. For more information see the + * LICENSE file. + */ +#pragma once + +// ----------------------------------------------------------------------------- + +#include <functional> +#include <sstream> +#include <string> +// windows compatibility includes +#include <cctype> +#include <algorithm> + +// ----------------------------------------------------------------------------- + +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<void(std::string&)>} parseLineCallback + * @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback + */ + BlockParser( + std::function<void(std::string&)> parseLineCallback, + std::function<std::shared_ptr<BlockParser>(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<BlockParser> 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<uint32_t>( + 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<BlockParser> + getBlockParserForLine(const std::string& line) + { + if (getBlockParserForLineCallback) + { + return getBlockParserForLineCallback(line); + } + + return nullptr; + } + +private: + std::function<void(std::string&)> parseLineCallback; + std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback; +}; // class BlockParser + +// ----------------------------------------------------------------------------- + +} // namespace maddy
