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