diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/maddy/parser.h	Tue Aug 17 11:19:54 2021 +0200
@@ -0,0 +1,294 @@
+/*
+ * This project is licensed under the MIT license. For more information see the
+ * LICENSE file.
+ */
+#pragma once
+
+// -----------------------------------------------------------------------------
+
+#include <memory>
+#include <functional>
+#include <string>
+
+#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<ParserConfig> config = nullptr)
+    : config(config)
+    , breakLineParser(std::make_shared<BreakLineParser>())
+    , emphasizedParser(std::make_shared<EmphasizedParser>())
+    , imageParser(std::make_shared<ImageParser>())
+    , inlineCodeParser(std::make_shared<InlineCodeParser>())
+    , italicParser(std::make_shared<ItalicParser>())
+    , linkParser(std::make_shared<LinkParser>())
+    , strikeThroughParser(std::make_shared<StrikeThroughParser>())
+    , strongParser(std::make_shared<StrongParser>())
+  {}
+
+  /**
+   * Parse
+   *
+   * @method
+   * @param {const std::istream&} markdown
+   * @return {std::string} HTML
+   */
+  std::string
+  Parse(std::istream& markdown) const
+  {
+    std::string result = "";
+    std::shared_ptr<BlockParser> 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<ParserConfig> config;
+  std::shared_ptr<BreakLineParser> breakLineParser;
+  std::shared_ptr<EmphasizedParser> emphasizedParser;
+  std::shared_ptr<ImageParser> imageParser;
+  std::shared_ptr<InlineCodeParser> inlineCodeParser;
+  std::shared_ptr<ItalicParser> italicParser;
+  std::shared_ptr<LinkParser> linkParser;
+  std::shared_ptr<StrikeThroughParser> strikeThroughParser;
+  std::shared_ptr<StrongParser> 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<BlockParser>
+  getBlockParserForLine(const std::string& line) const
+  {
+    std::shared_ptr<BlockParser> parser;
+
+    if (maddy::CodeBlockParser::IsStartingLine(line))
+    {
+      parser = std::make_shared<maddy::CodeBlockParser>(
+        nullptr,
+        nullptr
+      );
+    }
+    else if (maddy::HeadlineParser::IsStartingLine(line))
+    {
+      parser = std::make_shared<maddy::HeadlineParser>(
+        nullptr,
+        nullptr
+      );
+    }
+    else if (maddy::HorizontalLineParser::IsStartingLine(line))
+    {
+      parser = std::make_shared<maddy::HorizontalLineParser>(
+        nullptr,
+        nullptr
+      );
+    }
+    else if (maddy::QuoteParser::IsStartingLine(line))
+    {
+      parser = std::make_shared<maddy::QuoteParser>(
+        [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<maddy::TableParser>(
+        [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<maddy::HtmlParser>(nullptr, nullptr);
+    }
+    else if (maddy::ParagraphParser::IsStartingLine(line))
+    {
+      parser = std::make_shared<maddy::ParagraphParser>(
+        [this](std::string& line){ this->runLineParser(line); },
+        nullptr
+      );
+    }
+
+    return parser;
+  }
+
+  std::shared_ptr<BlockParser>
+  createChecklistParser() const
+  {
+    return std::make_shared<maddy::ChecklistParser>(
+      [this](std::string& line){ this->runLineParser(line); },
+      [this](const std::string& line)
+      {
+        std::shared_ptr<BlockParser> parser;
+
+        if (maddy::ChecklistParser::IsStartingLine(line))
+        {
+          parser = this->createChecklistParser();
+        }
+
+        return parser;
+      }
+    );
+  }
+
+  std::shared_ptr<BlockParser>
+  createOrderedListParser() const
+  {
+    return std::make_shared<maddy::OrderedListParser>(
+      [this](std::string& line){ this->runLineParser(line); },
+      [this](const std::string& line)
+      {
+        std::shared_ptr<BlockParser> parser;
+
+        if (maddy::OrderedListParser::IsStartingLine(line))
+        {
+          parser = this->createOrderedListParser();
+        }
+        else if (maddy::UnorderedListParser::IsStartingLine(line))
+        {
+          parser = this->createUnorderedListParser();
+        }
+
+        return parser;
+      }
+    );
+  }
+
+  std::shared_ptr<BlockParser>
+  createUnorderedListParser() const
+  {
+    return std::make_shared<maddy::UnorderedListParser>(
+      [this](std::string& line){ this->runLineParser(line); },
+      [this](const std::string& line)
+      {
+        std::shared_ptr<BlockParser> parser;
+
+        if (maddy::OrderedListParser::IsStartingLine(line))
+        {
+          parser = this->createOrderedListParser();
+        }
+        else if (maddy::UnorderedListParser::IsStartingLine(line))
+        {
+          parser = this->createUnorderedListParser();
+        }
+
+        return parser;
+      }
+    );
+  }
+}; // class Parser
+
+// -----------------------------------------------------------------------------
+
+} // namespace maddy