Mercurial > thymian
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 |
