diff --git a/input.md b/input.md index a4cf29c..cd608b8 100644 --- a/input.md +++ b/input.md @@ -38,3 +38,10 @@ world - hello world number two + +``` +int x = 5; +int y = 10; + +console.log(x + y); // '15' +``` diff --git a/lib/inlineNode.cpp b/lib/inlineNode.cpp index 625de65..e0cced9 100644 --- a/lib/inlineNode.cpp +++ b/lib/inlineNode.cpp @@ -23,3 +23,5 @@ string BoldItalicNode::ToHtml() const { } string CodeNode::ToHtml() const { return "" + this->content + ""; } + +string RawTextNode::ToHtml() const { return this->content; }; diff --git a/lib/inlineNode.h b/lib/inlineNode.h index af825a7..9866b6e 100644 --- a/lib/inlineNode.h +++ b/lib/inlineNode.h @@ -117,4 +117,17 @@ public: std::string ToHtml() const; }; +/** + * @desc A raw text node. + * + * This node returns only it content, with no formatting at all. + * + * @author Hayden Hargreaves (hhargreaves2006@gmail.com) + */ +class RawTextNode : public InlineNode { +public: + RawTextNode(std::string content) : InlineNode(content) {}; + std::string ToHtml() const; +}; + #endif diff --git a/lib/parser.cpp b/lib/parser.cpp index 4e8b052..f01c505 100644 --- a/lib/parser.cpp +++ b/lib/parser.cpp @@ -4,6 +4,7 @@ #include "structureNode.h" #include #include +#include #include #include @@ -95,7 +96,12 @@ std::unique_ptr Parser::ParseBlock() { return ParseList(true); } - // 4. Parser paragraph + // 4. Parse code block + if (c == '`' && c_next == '`' && Peek(2) == '`') { + return ParseCodeBlock(); + } + + // 5. Parser paragraph return ParseParagraph(); } @@ -177,6 +183,37 @@ std::unique_ptr Parser::ParseList(bool ordered) { return node; }; +std::unique_ptr Parser::ParseCodeBlock() { + auto node = std::make_unique(); + string str; + + // Remove the first three characters, the '```' + Consume(3); + + // Parse text into a single text node until '```' is found, include everything + // else + while (!IsEOF()) { + char c = Peek(); + if (c == '`' && Peek(1) == '`' && Peek(2) == '`') { + Consume(3); + break; + } + + // Swap any '\n' with BR tags, so it will visually break + if (c == '\n') + str += "\n
\n"; + else + str += c; + + Consume(); + } + + auto text_node = std::make_unique(str); + node->AddChild(std::move(text_node)); + + return node; +} + vector> Parser::ParseInline() { vector> nodes; string str; diff --git a/lib/parser.h b/lib/parser.h index 1305c02..ae01214 100644 --- a/lib/parser.h +++ b/lib/parser.h @@ -123,6 +123,7 @@ private: std::unique_ptr ParseHeading(); std::unique_ptr ParseList(bool ordered); vector> ParseInline(); + std::unique_ptr ParseCodeBlock(); // The only differences are the exit condition vector> ParseInlineHeading(); diff --git a/lib/structureNode.cpp b/lib/structureNode.cpp index ca4b00f..9516c3b 100644 --- a/lib/structureNode.cpp +++ b/lib/structureNode.cpp @@ -67,3 +67,16 @@ string ListNode::ToHtml() const { ss << (this->ordered ? "" : "") << "\n"; return ss.str(); } + +string CodeBlockNode::ToHtml() const { + std::stringstream ss; + + ss << "\n"; + + for (const auto &child : this->GetChilren()) { + ss << child->ToHtml() << "\n"; + } + + ss << "\n"; + return ss.str(); +} diff --git a/lib/structureNode.h b/lib/structureNode.h index 7e07bf8..d8632d3 100644 --- a/lib/structureNode.h +++ b/lib/structureNode.h @@ -111,4 +111,19 @@ public: std::string ToHtml() const; }; +/** + * @desc A code block container node. + * + * This node is used to wrap a code block node. When three '`' are used a + * code block should be created. This node's children are expected to be simple + * text nodes - containing no formatting at all. Since code blocks are not parsed + * any deeper then their parents. + * + * @author Hayden Hargreaves (hhargreaves2006@gmail.com) + */ +class CodeBlockNode : public StructureNode { +public: + std::string ToHtml() const; +}; + #endif