duplikat dari
				https://github.com/quitesimpleorg/qsmaddy.git
				synced 2025-10-31 09:19:29 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			256 baris
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			256 baris
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * This project is licensed under the MIT license. For more information see the
 | |
|  * LICENSE file.
 | |
|  */
 | |
| #pragma once
 | |
| 
 | |
| // -----------------------------------------------------------------------------
 | |
| 
 | |
| #include <memory>
 | |
| #include <functional>
 | |
| #include <string>
 | |
| 
 | |
| // BlockParser
 | |
| #include "maddy/checklistparser.h"
 | |
| #include "maddy/codeblockparser.h"
 | |
| #include "maddy/headlineparser.h"
 | |
| #include "maddy/horizontallineparser.h"
 | |
| #include "maddy/orderedlistparser.h"
 | |
| #include "maddy/paragraphparser.h"
 | |
| #include "maddy/quoteparser.h"
 | |
| #include "maddy/tableparser.h"
 | |
| #include "maddy/unorderedlistparser.h"
 | |
| 
 | |
| // LineParser
 | |
| #include "maddy/emphasizedparser.h"
 | |
| #include "maddy/imageparser.h"
 | |
| #include "maddy/inlinecodeparser.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()
 | |
|     : emphasizedParser(std::make_shared<EmphasizedParser>())
 | |
|     , imageParser(std::make_shared<ImageParser>())
 | |
|     , inlineCodeParser(std::make_shared<InlineCodeParser>())
 | |
|     , linkParser(std::make_shared<LinkParser>())
 | |
|     , strikeThroughParser(std::make_shared<StrikeThroughParser>())
 | |
|     , strongParser(std::make_shared<StrongParser>())
 | |
|   {}
 | |
| 
 | |
|   /**
 | |
|    * Parse
 | |
|    *
 | |
|    * @method
 | |
|    * @param {const std::stringstream&} markdown
 | |
|    * @return {std::string} HTML
 | |
|    */
 | |
|   std::string
 | |
|   Parse(std::stringstream& 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;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   std::shared_ptr<EmphasizedParser> emphasizedParser;
 | |
|   std::shared_ptr<ImageParser> imageParser;
 | |
|   std::shared_ptr<InlineCodeParser> inlineCodeParser;
 | |
|   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);
 | |
|     this->emphasizedParser->Parse(line);
 | |
| 
 | |
|     this->strikeThroughParser->Parse(line);
 | |
| 
 | |
|     this->inlineCodeParser->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 (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
 | 
