comparison 3rdparty/maddy/parser.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 <memory>
10 #include <functional>
11 #include <string>
12
13 #include "maddy/parserconfig.h"
14
15 // BlockParser
16 #include "maddy/checklistparser.h"
17 #include "maddy/codeblockparser.h"
18 #include "maddy/headlineparser.h"
19 #include "maddy/horizontallineparser.h"
20 #include "maddy/htmlparser.h"
21 #include "maddy/orderedlistparser.h"
22 #include "maddy/paragraphparser.h"
23 #include "maddy/quoteparser.h"
24 #include "maddy/tableparser.h"
25 #include "maddy/unorderedlistparser.h"
26
27 // LineParser
28 #include "maddy/breaklineparser.h"
29 #include "maddy/emphasizedparser.h"
30 #include "maddy/imageparser.h"
31 #include "maddy/inlinecodeparser.h"
32 #include "maddy/italicparser.h"
33 #include "maddy/linkparser.h"
34 #include "maddy/strikethroughparser.h"
35 #include "maddy/strongparser.h"
36
37 // -----------------------------------------------------------------------------
38
39 namespace maddy {
40
41 // -----------------------------------------------------------------------------
42
43 /**
44 * Parser
45 *
46 * Transforms Markdown to HTML
47 *
48 * @class
49 */
50 class Parser
51 {
52 public:
53 /**
54 * ctor
55 *
56 * Initializes all `LineParser`
57 *
58 * @method
59 */
60 Parser(std::shared_ptr<ParserConfig> config = nullptr)
61 : config(config)
62 , breakLineParser(std::make_shared<BreakLineParser>())
63 , emphasizedParser(std::make_shared<EmphasizedParser>())
64 , imageParser(std::make_shared<ImageParser>())
65 , inlineCodeParser(std::make_shared<InlineCodeParser>())
66 , italicParser(std::make_shared<ItalicParser>())
67 , linkParser(std::make_shared<LinkParser>())
68 , strikeThroughParser(std::make_shared<StrikeThroughParser>())
69 , strongParser(std::make_shared<StrongParser>())
70 {}
71
72 /**
73 * Parse
74 *
75 * @method
76 * @param {const std::istream&} markdown
77 * @return {std::string} HTML
78 */
79 std::string
80 Parse(std::istream& markdown) const
81 {
82 std::string result = "";
83 std::shared_ptr<BlockParser> currentBlockParser = nullptr;
84
85 for (std::string line; std::getline(markdown, line);)
86 {
87 if (!currentBlockParser)
88 {
89 currentBlockParser = getBlockParserForLine(line);
90 }
91
92 if (currentBlockParser)
93 {
94 currentBlockParser->AddLine(line);
95
96 if (currentBlockParser->IsFinished())
97 {
98 result += currentBlockParser->GetResult().str();
99 currentBlockParser = nullptr;
100 }
101 }
102 }
103
104 // make sure, that all parsers are finished
105 if (currentBlockParser)
106 {
107 std::string emptyLine = "";
108 currentBlockParser->AddLine(emptyLine);
109 if (currentBlockParser->IsFinished())
110 {
111 result += currentBlockParser->GetResult().str();
112 currentBlockParser = nullptr;
113 }
114 }
115
116 return result;
117 }
118
119 private:
120 std::shared_ptr<ParserConfig> config;
121 std::shared_ptr<BreakLineParser> breakLineParser;
122 std::shared_ptr<EmphasizedParser> emphasizedParser;
123 std::shared_ptr<ImageParser> imageParser;
124 std::shared_ptr<InlineCodeParser> inlineCodeParser;
125 std::shared_ptr<ItalicParser> italicParser;
126 std::shared_ptr<LinkParser> linkParser;
127 std::shared_ptr<StrikeThroughParser> strikeThroughParser;
128 std::shared_ptr<StrongParser> strongParser;
129
130 // block parser have to run before
131 void
132 runLineParser(std::string& line) const
133 {
134 // Attention! ImageParser has to be before LinkParser
135 this->imageParser->Parse(line);
136 this->linkParser->Parse(line);
137
138 // Attention! StrongParser has to be before EmphasizedParser
139 this->strongParser->Parse(line);
140
141 if (!this->config || this->config->isEmphasizedParserEnabled)
142 {
143 this->emphasizedParser->Parse(line);
144 }
145
146 this->strikeThroughParser->Parse(line);
147
148 this->inlineCodeParser->Parse(line);
149
150 this->italicParser->Parse(line);
151
152 this->breakLineParser->Parse(line);
153 }
154
155 std::shared_ptr<BlockParser>
156 getBlockParserForLine(const std::string& line) const
157 {
158 std::shared_ptr<BlockParser> parser;
159
160 if (maddy::CodeBlockParser::IsStartingLine(line))
161 {
162 parser = std::make_shared<maddy::CodeBlockParser>(
163 nullptr,
164 nullptr
165 );
166 }
167 else if (maddy::HeadlineParser::IsStartingLine(line))
168 {
169 parser = std::make_shared<maddy::HeadlineParser>(
170 nullptr,
171 nullptr
172 );
173 }
174 else if (maddy::HorizontalLineParser::IsStartingLine(line))
175 {
176 parser = std::make_shared<maddy::HorizontalLineParser>(
177 nullptr,
178 nullptr
179 );
180 }
181 else if (maddy::QuoteParser::IsStartingLine(line))
182 {
183 parser = std::make_shared<maddy::QuoteParser>(
184 [this](std::string& line){ this->runLineParser(line); },
185 [this](const std::string& line){ return this->getBlockParserForLine(line); }
186 );
187 }
188 else if (maddy::TableParser::IsStartingLine(line))
189 {
190 parser = std::make_shared<maddy::TableParser>(
191 [this](std::string& line){ this->runLineParser(line); },
192 nullptr
193 );
194 }
195 else if (maddy::ChecklistParser::IsStartingLine(line))
196 {
197 parser = this->createChecklistParser();
198 }
199 else if (maddy::OrderedListParser::IsStartingLine(line))
200 {
201 parser = this->createOrderedListParser();
202 }
203 else if (maddy::UnorderedListParser::IsStartingLine(line))
204 {
205 parser = this->createUnorderedListParser();
206 }
207 else if (
208 this->config &&
209 !this->config->isHTMLWrappedInParagraph &&
210 maddy::HtmlParser::IsStartingLine(line)
211 )
212 {
213 parser = std::make_shared<maddy::HtmlParser>(nullptr, nullptr);
214 }
215 else if (maddy::ParagraphParser::IsStartingLine(line))
216 {
217 parser = std::make_shared<maddy::ParagraphParser>(
218 [this](std::string& line){ this->runLineParser(line); },
219 nullptr
220 );
221 }
222
223 return parser;
224 }
225
226 std::shared_ptr<BlockParser>
227 createChecklistParser() const
228 {
229 return std::make_shared<maddy::ChecklistParser>(
230 [this](std::string& line){ this->runLineParser(line); },
231 [this](const std::string& line)
232 {
233 std::shared_ptr<BlockParser> parser;
234
235 if (maddy::ChecklistParser::IsStartingLine(line))
236 {
237 parser = this->createChecklistParser();
238 }
239
240 return parser;
241 }
242 );
243 }
244
245 std::shared_ptr<BlockParser>
246 createOrderedListParser() const
247 {
248 return std::make_shared<maddy::OrderedListParser>(
249 [this](std::string& line){ this->runLineParser(line); },
250 [this](const std::string& line)
251 {
252 std::shared_ptr<BlockParser> parser;
253
254 if (maddy::OrderedListParser::IsStartingLine(line))
255 {
256 parser = this->createOrderedListParser();
257 }
258 else if (maddy::UnorderedListParser::IsStartingLine(line))
259 {
260 parser = this->createUnorderedListParser();
261 }
262
263 return parser;
264 }
265 );
266 }
267
268 std::shared_ptr<BlockParser>
269 createUnorderedListParser() const
270 {
271 return std::make_shared<maddy::UnorderedListParser>(
272 [this](std::string& line){ this->runLineParser(line); },
273 [this](const std::string& line)
274 {
275 std::shared_ptr<BlockParser> parser;
276
277 if (maddy::OrderedListParser::IsStartingLine(line))
278 {
279 parser = this->createOrderedListParser();
280 }
281 else if (maddy::UnorderedListParser::IsStartingLine(line))
282 {
283 parser = this->createUnorderedListParser();
284 }
285
286 return parser;
287 }
288 );
289 }
290 }; // class Parser
291
292 // -----------------------------------------------------------------------------
293
294 } // namespace maddy