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