annotate 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
rev   line source
ferencd@0 1 /*
ferencd@0 2 * This project is licensed under the MIT license. For more information see the
ferencd@0 3 * LICENSE file.
ferencd@0 4 */
ferencd@0 5 #pragma once
ferencd@0 6
ferencd@0 7 // -----------------------------------------------------------------------------
ferencd@0 8
ferencd@0 9 #include <functional>
ferencd@0 10 #include <sstream>
ferencd@0 11 #include <string>
ferencd@0 12 // windows compatibility includes
ferencd@0 13 #include <cctype>
ferencd@0 14 #include <algorithm>
ferencd@0 15
ferencd@0 16 // -----------------------------------------------------------------------------
ferencd@0 17
ferencd@0 18 namespace maddy {
ferencd@0 19
ferencd@0 20 // -----------------------------------------------------------------------------
ferencd@0 21
ferencd@0 22 /**
ferencd@0 23 * BlockParser
ferencd@0 24 *
ferencd@0 25 * The code expects every child to have the following static function to be
ferencd@0 26 * implemented:
ferencd@0 27 * `static bool IsStartingLine(const std::string& line)`
ferencd@0 28 *
ferencd@0 29 * @class
ferencd@0 30 */
ferencd@0 31 class BlockParser
ferencd@0 32 {
ferencd@0 33 public:
ferencd@0 34 /**
ferencd@0 35 * ctor
ferencd@0 36 *
ferencd@0 37 * @method
ferencd@0 38 * @param {std::function<void(std::string&)>} parseLineCallback
ferencd@0 39 * @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
ferencd@0 40 */
ferencd@0 41 BlockParser(
ferencd@0 42 std::function<void(std::string&)> parseLineCallback,
ferencd@0 43 std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
ferencd@0 44 )
ferencd@0 45 : result("", std::ios_base::ate | std::ios_base::in | std::ios_base::out)
ferencd@0 46 , childParser(nullptr)
ferencd@0 47 , parseLineCallback(parseLineCallback)
ferencd@0 48 , getBlockParserForLineCallback(getBlockParserForLineCallback)
ferencd@0 49 {}
ferencd@0 50
ferencd@0 51 /**
ferencd@0 52 * dtor
ferencd@0 53 *
ferencd@0 54 * @method
ferencd@0 55 */
ferencd@0 56 virtual ~BlockParser() {}
ferencd@0 57
ferencd@0 58 /**
ferencd@0 59 * AddLine
ferencd@0 60 *
ferencd@0 61 * Adding a line which has to be parsed.
ferencd@0 62 *
ferencd@0 63 * @method
ferencd@0 64 * @param {std::string&} line
ferencd@0 65 * @return {void}
ferencd@0 66 */
ferencd@0 67 virtual void
ferencd@0 68 AddLine(std::string& line)
ferencd@0 69 {
ferencd@0 70 this->parseBlock(line);
ferencd@0 71
ferencd@0 72 if (this->isInlineBlockAllowed() && !this->childParser)
ferencd@0 73 {
ferencd@0 74 this->childParser = this->getBlockParserForLine(line);
ferencd@0 75 }
ferencd@0 76
ferencd@0 77 if (this->childParser)
ferencd@0 78 {
ferencd@0 79 this->childParser->AddLine(line);
ferencd@0 80
ferencd@0 81 if (this->childParser->IsFinished())
ferencd@0 82 {
ferencd@0 83 this->result << this->childParser->GetResult().str();
ferencd@0 84 this->childParser = nullptr;
ferencd@0 85 }
ferencd@0 86
ferencd@0 87 return;
ferencd@0 88 }
ferencd@0 89
ferencd@0 90 if (this->isLineParserAllowed())
ferencd@0 91 {
ferencd@0 92 this->parseLine(line);
ferencd@0 93 }
ferencd@0 94
ferencd@0 95 this->result << line;
ferencd@0 96 }
ferencd@0 97
ferencd@0 98 /**
ferencd@0 99 * IsFinished
ferencd@0 100 *
ferencd@0 101 * Check if the BlockParser is done
ferencd@0 102 *
ferencd@0 103 * @method
ferencd@0 104 * @return {bool}
ferencd@0 105 */
ferencd@0 106 virtual bool IsFinished() const = 0;
ferencd@0 107
ferencd@0 108 /**
ferencd@0 109 * GetResult
ferencd@0 110 *
ferencd@0 111 * Get the parsed HTML output.
ferencd@0 112 *
ferencd@0 113 * @method
ferencd@0 114 * @return {std::stringstream}
ferencd@0 115 */
ferencd@0 116 std::stringstream&
ferencd@0 117 GetResult()
ferencd@0 118 {
ferencd@0 119 return this->result;
ferencd@0 120 }
ferencd@0 121
ferencd@0 122 /**
ferencd@0 123 * Clear
ferencd@0 124 *
ferencd@0 125 * Clear the result to reuse the parser object.
ferencd@0 126 *
ferencd@0 127 * It is only used by one test for now.
ferencd@0 128 *
ferencd@0 129 * @method
ferencd@0 130 * @return {void}
ferencd@0 131 */
ferencd@0 132 void
ferencd@0 133 Clear()
ferencd@0 134 {
ferencd@0 135 this->result.str("");
ferencd@0 136 }
ferencd@0 137
ferencd@0 138 protected:
ferencd@0 139 std::stringstream result;
ferencd@0 140 std::shared_ptr<BlockParser> childParser;
ferencd@0 141
ferencd@0 142 virtual bool isInlineBlockAllowed() const = 0;
ferencd@0 143 virtual bool isLineParserAllowed() const = 0;
ferencd@0 144 virtual void parseBlock(std::string& line) = 0;
ferencd@0 145
ferencd@0 146 void
ferencd@0 147 parseLine(std::string& line)
ferencd@0 148 {
ferencd@0 149 if (parseLineCallback)
ferencd@0 150 {
ferencd@0 151 parseLineCallback(line);
ferencd@0 152 }
ferencd@0 153 }
ferencd@0 154
ferencd@0 155 uint32_t
ferencd@0 156 getIndentationWidth(const std::string& line) const
ferencd@0 157 {
ferencd@0 158 bool hasMetNonSpace = false;
ferencd@0 159
ferencd@0 160 uint32_t indentation = static_cast<uint32_t>(
ferencd@0 161 std::count_if(
ferencd@0 162 line.begin(),
ferencd@0 163 line.end(),
ferencd@0 164 [&hasMetNonSpace](unsigned char c)
ferencd@0 165 {
ferencd@0 166 if (hasMetNonSpace)
ferencd@0 167 {
ferencd@0 168 return false;
ferencd@0 169 }
ferencd@0 170
ferencd@0 171 if (std::isspace(c))
ferencd@0 172 {
ferencd@0 173 return true;
ferencd@0 174 }
ferencd@0 175
ferencd@0 176 hasMetNonSpace = true;
ferencd@0 177 return false;
ferencd@0 178 }
ferencd@0 179 )
ferencd@0 180 );
ferencd@0 181
ferencd@0 182 return indentation;
ferencd@0 183 }
ferencd@0 184
ferencd@0 185 std::shared_ptr<BlockParser>
ferencd@0 186 getBlockParserForLine(const std::string& line)
ferencd@0 187 {
ferencd@0 188 if (getBlockParserForLineCallback)
ferencd@0 189 {
ferencd@0 190 return getBlockParserForLineCallback(line);
ferencd@0 191 }
ferencd@0 192
ferencd@0 193 return nullptr;
ferencd@0 194 }
ferencd@0 195
ferencd@0 196 private:
ferencd@0 197 std::function<void(std::string&)> parseLineCallback;
ferencd@0 198 std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback;
ferencd@0 199 }; // class BlockParser
ferencd@0 200
ferencd@0 201 // -----------------------------------------------------------------------------
ferencd@0 202
ferencd@0 203 } // namespace maddy