From 7d3c9ec7368a5d25235e818c2c147ba7e89f6567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gassmann?= Date: Sun, 27 Feb 2022 14:06:15 +0100 Subject: [+] Added base project --- inc/maddy/parser.h | 294 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 inc/maddy/parser.h (limited to 'inc/maddy/parser.h') diff --git a/inc/maddy/parser.h b/inc/maddy/parser.h new file mode 100644 index 0000000..add4c45 --- /dev/null +++ b/inc/maddy/parser.h @@ -0,0 +1,294 @@ +/* + * This project is licensed under the MIT license. For more information see the + * LICENSE file. + */ +#pragma once + +// ----------------------------------------------------------------------------- + +#include +#include +#include + +#include "maddy/parserconfig.h" + +// BlockParser +#include "maddy/checklistparser.h" +#include "maddy/codeblockparser.h" +#include "maddy/headlineparser.h" +#include "maddy/horizontallineparser.h" +#include "maddy/htmlparser.h" +#include "maddy/orderedlistparser.h" +#include "maddy/paragraphparser.h" +#include "maddy/quoteparser.h" +#include "maddy/tableparser.h" +#include "maddy/unorderedlistparser.h" + +// LineParser +#include "maddy/breaklineparser.h" +#include "maddy/emphasizedparser.h" +#include "maddy/imageparser.h" +#include "maddy/inlinecodeparser.h" +#include "maddy/italicparser.h" +#include "maddy/linkparser.h" +#include "maddy/strikethroughparser.h" +#include "maddy/strongparser.h" + +// ----------------------------------------------------------------------------- + +namespace maddy { + +// ----------------------------------------------------------------------------- + +/** + * Parser + * + * Transforms Markdown to HTML + * + * @class + */ +class Parser +{ +public: + /** + * ctor + * + * Initializes all `LineParser` + * + * @method + */ + Parser(std::shared_ptr config = nullptr) + : config(config) + , breakLineParser(std::make_shared()) + , emphasizedParser(std::make_shared()) + , imageParser(std::make_shared()) + , inlineCodeParser(std::make_shared()) + , italicParser(std::make_shared()) + , linkParser(std::make_shared()) + , strikeThroughParser(std::make_shared()) + , strongParser(std::make_shared()) + {} + + /** + * Parse + * + * @method + * @param {const std::istream&} markdown + * @return {std::string} HTML + */ + std::string + Parse(std::istream& markdown) const + { + std::string result = ""; + std::shared_ptr currentBlockParser = nullptr; + + for (std::string line; std::getline(markdown, line);) + { + if (!currentBlockParser) + { + currentBlockParser = getBlockParserForLine(line); + } + + if (currentBlockParser) + { + currentBlockParser->AddLine(line); + + if (currentBlockParser->IsFinished()) + { + result += currentBlockParser->GetResult().str(); + currentBlockParser = nullptr; + } + } + } + + // make sure, that all parsers are finished + if (currentBlockParser) + { + std::string emptyLine = ""; + currentBlockParser->AddLine(emptyLine); + if (currentBlockParser->IsFinished()) + { + result += currentBlockParser->GetResult().str(); + currentBlockParser = nullptr; + } + } + + return result; + } + +private: + std::shared_ptr config; + std::shared_ptr breakLineParser; + std::shared_ptr emphasizedParser; + std::shared_ptr imageParser; + std::shared_ptr inlineCodeParser; + std::shared_ptr italicParser; + std::shared_ptr linkParser; + std::shared_ptr strikeThroughParser; + std::shared_ptr strongParser; + + // block parser have to run before + void + runLineParser(std::string& line) const + { + // Attention! ImageParser has to be before LinkParser + this->imageParser->Parse(line); + this->linkParser->Parse(line); + + // Attention! StrongParser has to be before EmphasizedParser + this->strongParser->Parse(line); + + if (!this->config || this->config->isEmphasizedParserEnabled) + { + this->emphasizedParser->Parse(line); + } + + this->strikeThroughParser->Parse(line); + + this->inlineCodeParser->Parse(line); + + this->italicParser->Parse(line); + + this->breakLineParser->Parse(line); + } + + std::shared_ptr + getBlockParserForLine(const std::string& line) const + { + std::shared_ptr parser; + + if (maddy::CodeBlockParser::IsStartingLine(line)) + { + parser = std::make_shared( + nullptr, + nullptr + ); + } + else if (maddy::HeadlineParser::IsStartingLine(line)) + { + parser = std::make_shared( + nullptr, + nullptr + ); + } + else if (maddy::HorizontalLineParser::IsStartingLine(line)) + { + parser = std::make_shared( + nullptr, + nullptr + ); + } + else if (maddy::QuoteParser::IsStartingLine(line)) + { + parser = std::make_shared( + [this](std::string& line){ this->runLineParser(line); }, + [this](const std::string& line){ return this->getBlockParserForLine(line); } + ); + } + else if (maddy::TableParser::IsStartingLine(line)) + { + parser = std::make_shared( + [this](std::string& line){ this->runLineParser(line); }, + nullptr + ); + } + else if (maddy::ChecklistParser::IsStartingLine(line)) + { + parser = this->createChecklistParser(); + } + else if (maddy::OrderedListParser::IsStartingLine(line)) + { + parser = this->createOrderedListParser(); + } + else if (maddy::UnorderedListParser::IsStartingLine(line)) + { + parser = this->createUnorderedListParser(); + } + else if ( + this->config && + !this->config->isHTMLWrappedInParagraph && + maddy::HtmlParser::IsStartingLine(line) + ) + { + parser = std::make_shared(nullptr, nullptr); + } + else if (maddy::ParagraphParser::IsStartingLine(line)) + { + parser = std::make_shared( + [this](std::string& line){ this->runLineParser(line); }, + nullptr + ); + } + + return parser; + } + + std::shared_ptr + createChecklistParser() const + { + return std::make_shared( + [this](std::string& line){ this->runLineParser(line); }, + [this](const std::string& line) + { + std::shared_ptr parser; + + if (maddy::ChecklistParser::IsStartingLine(line)) + { + parser = this->createChecklistParser(); + } + + return parser; + } + ); + } + + std::shared_ptr + createOrderedListParser() const + { + return std::make_shared( + [this](std::string& line){ this->runLineParser(line); }, + [this](const std::string& line) + { + std::shared_ptr parser; + + if (maddy::OrderedListParser::IsStartingLine(line)) + { + parser = this->createOrderedListParser(); + } + else if (maddy::UnorderedListParser::IsStartingLine(line)) + { + parser = this->createUnorderedListParser(); + } + + return parser; + } + ); + } + + std::shared_ptr + createUnorderedListParser() const + { + return std::make_shared( + [this](std::string& line){ this->runLineParser(line); }, + [this](const std::string& line) + { + std::shared_ptr parser; + + if (maddy::OrderedListParser::IsStartingLine(line)) + { + parser = this->createOrderedListParser(); + } + else if (maddy::UnorderedListParser::IsStartingLine(line)) + { + parser = this->createUnorderedListParser(); + } + + return parser; + } + ); + } +}; // class Parser + +// ----------------------------------------------------------------------------- + +} // namespace maddy -- cgit v1.2.3