Mercurial > thymian
comparison 3rdparty/maddy/tableparser.h @ 0:a4671277546c tip
created the repository for the thymian project
| author | ferencd |
|---|---|
| date | Tue, 17 Aug 2021 11:19:54 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:a4671277546c |
|---|---|
| 1 /* | |
| 2 * This project is licensed under the MIT license. For more information see the | |
| 3 * LICENSE file. | |
| 4 */ | |
| 5 #pragma once | |
| 6 | |
| 7 // ----------------------------------------------------------------------------- | |
| 8 | |
| 9 #include <functional> | |
| 10 #include <string> | |
| 11 #include <regex> | |
| 12 | |
| 13 #include "maddy/blockparser.h" | |
| 14 | |
| 15 // ----------------------------------------------------------------------------- | |
| 16 | |
| 17 namespace maddy { | |
| 18 | |
| 19 // ----------------------------------------------------------------------------- | |
| 20 | |
| 21 /** | |
| 22 * TableParser | |
| 23 * | |
| 24 * For more information, see the docs folder. | |
| 25 * | |
| 26 * @class | |
| 27 */ | |
| 28 class TableParser : public BlockParser | |
| 29 { | |
| 30 public: | |
| 31 /** | |
| 32 * ctor | |
| 33 * | |
| 34 * @method | |
| 35 * @param {std::function<void(std::string&)>} parseLineCallback | |
| 36 * @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback | |
| 37 */ | |
| 38 TableParser( | |
| 39 std::function<void(std::string&)> parseLineCallback, | |
| 40 std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback | |
| 41 ) | |
| 42 : BlockParser(parseLineCallback, getBlockParserForLineCallback) | |
| 43 , isStarted(false) | |
| 44 , isFinished(false) | |
| 45 , currentBlock(0) | |
| 46 , currentRow(0) | |
| 47 {} | |
| 48 | |
| 49 /** | |
| 50 * IsStartingLine | |
| 51 * | |
| 52 * If the line has exact `|table>`, then it is starting the table. | |
| 53 * | |
| 54 * @method | |
| 55 * @param {const std::string&} line | |
| 56 * @return {bool} | |
| 57 */ | |
| 58 static bool | |
| 59 IsStartingLine(const std::string& line) | |
| 60 { | |
| 61 static std::string matchString("|table>"); | |
| 62 return line == matchString; | |
| 63 } | |
| 64 | |
| 65 /** | |
| 66 * AddLine | |
| 67 * | |
| 68 * Adding a line which has to be parsed. | |
| 69 * | |
| 70 * @method | |
| 71 * @param {std::string&} line | |
| 72 * @return {void} | |
| 73 */ | |
| 74 void | |
| 75 AddLine(std::string& line) override | |
| 76 { | |
| 77 if (!this->isStarted && line == "|table>") | |
| 78 { | |
| 79 this->isStarted = true; | |
| 80 return; | |
| 81 } | |
| 82 | |
| 83 if (this->isStarted) | |
| 84 { | |
| 85 if (line == "- | - | -") | |
| 86 { | |
| 87 ++this->currentBlock; | |
| 88 this->currentRow = 0; | |
| 89 return; | |
| 90 } | |
| 91 | |
| 92 if (line == "|<table") | |
| 93 { | |
| 94 static std::string emptyLine = ""; | |
| 95 this->parseBlock(emptyLine); | |
| 96 this->isFinished = true; | |
| 97 return; | |
| 98 } | |
| 99 | |
| 100 if (this->table.size() < this->currentBlock + 1) | |
| 101 { | |
| 102 this->table.push_back(std::vector<std::vector<std::string>>()); | |
| 103 } | |
| 104 this->table[this->currentBlock].push_back(std::vector<std::string>()); | |
| 105 | |
| 106 std::string segment; | |
| 107 std::stringstream streamToSplit(line); | |
| 108 | |
| 109 while (std::getline(streamToSplit, segment, '|')) | |
| 110 { | |
| 111 this->parseLine(segment); | |
| 112 this->table[this->currentBlock][this->currentRow].push_back(segment); | |
| 113 } | |
| 114 | |
| 115 ++this->currentRow; | |
| 116 } | |
| 117 } | |
| 118 | |
| 119 /** | |
| 120 * IsFinished | |
| 121 * | |
| 122 * A table ends with `|<table`. | |
| 123 * | |
| 124 * @method | |
| 125 * @return {bool} | |
| 126 */ | |
| 127 bool | |
| 128 IsFinished() const override | |
| 129 { | |
| 130 return this->isFinished; | |
| 131 } | |
| 132 | |
| 133 protected: | |
| 134 bool | |
| 135 isInlineBlockAllowed() const override | |
| 136 { | |
| 137 return false; | |
| 138 } | |
| 139 | |
| 140 bool | |
| 141 isLineParserAllowed() const override | |
| 142 { | |
| 143 return true; | |
| 144 } | |
| 145 | |
| 146 void | |
| 147 parseBlock(std::string&) override | |
| 148 { | |
| 149 result << "<table>"; | |
| 150 | |
| 151 bool hasHeader = false; | |
| 152 bool hasFooter = false; | |
| 153 bool isFirstBlock = true; | |
| 154 uint32_t currentBlockNumber = 0; | |
| 155 | |
| 156 if (this->table.size() > 1) | |
| 157 { | |
| 158 hasHeader = true; | |
| 159 } | |
| 160 | |
| 161 if (this->table.size() >= 3) | |
| 162 { | |
| 163 hasFooter = true; | |
| 164 } | |
| 165 | |
| 166 for (const std::vector<std::vector<std::string>>& block : this->table) | |
| 167 { | |
| 168 bool isInHeader = false; | |
| 169 bool isInFooter = false; | |
| 170 ++currentBlockNumber; | |
| 171 | |
| 172 if (hasHeader && isFirstBlock) | |
| 173 { | |
| 174 result << "<thead>"; | |
| 175 isInHeader = true; | |
| 176 } | |
| 177 else if (hasFooter && currentBlockNumber == this->table.size()) | |
| 178 { | |
| 179 result << "<tfoot>"; | |
| 180 isInFooter = true; | |
| 181 } | |
| 182 else | |
| 183 { | |
| 184 result << "<tbody>"; | |
| 185 } | |
| 186 | |
| 187 for (const std::vector<std::string>& row : block) | |
| 188 { | |
| 189 result << "<tr>"; | |
| 190 | |
| 191 for (const std::string& column : row) | |
| 192 { | |
| 193 if (isInHeader) | |
| 194 { | |
| 195 result << "<th>"; | |
| 196 } | |
| 197 else | |
| 198 { | |
| 199 result << "<td>"; | |
| 200 } | |
| 201 | |
| 202 result << column; | |
| 203 | |
| 204 if (isInHeader) | |
| 205 { | |
| 206 result << "</th>"; | |
| 207 } | |
| 208 else | |
| 209 { | |
| 210 result << "</td>"; | |
| 211 } | |
| 212 } | |
| 213 | |
| 214 result << "</tr>"; | |
| 215 } | |
| 216 | |
| 217 if (isInHeader) | |
| 218 { | |
| 219 result << "</thead>"; | |
| 220 } | |
| 221 else if (isInFooter) | |
| 222 { | |
| 223 result << "</tfoot>"; | |
| 224 } | |
| 225 else | |
| 226 { | |
| 227 result << "</tbody>"; | |
| 228 } | |
| 229 | |
| 230 isFirstBlock = false; | |
| 231 } | |
| 232 | |
| 233 result << "</table>"; | |
| 234 } | |
| 235 | |
| 236 private: | |
| 237 bool isStarted; | |
| 238 bool isFinished; | |
| 239 uint32_t currentBlock; | |
| 240 uint32_t currentRow; | |
| 241 std::vector<std::vector<std::vector<std::string>>> table; | |
| 242 }; // class TableParser | |
| 243 | |
| 244 // ----------------------------------------------------------------------------- | |
| 245 | |
| 246 } // namespace maddy |
