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