(FEAT): Added support for inline code blocks. #23
@ -21,3 +21,5 @@ string BoldNode::ToHtml() const {
|
||||
string BoldItalicNode::ToHtml() const {
|
||||
return "<strong><em>" + this->content + "</em></strong>";
|
||||
}
|
||||
|
||||
string CodeNode::ToHtml() const { return "<code>" + this->content + "</code>"; }
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define INLINENODE_H
|
||||
|
||||
#include "node.h"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
@ -37,6 +38,15 @@ public:
|
||||
*/
|
||||
void AddChild(std::unique_ptr<Node> child);
|
||||
|
||||
/**
|
||||
* @brief Is the node empty.
|
||||
*
|
||||
* This is the same as checking if the nodes content is empty.
|
||||
*
|
||||
* @author Hayden Hargreaves (hhargreaves2006@gmail.com)
|
||||
*/
|
||||
bool IsEmpty() const { return this->content.empty(); };
|
||||
|
||||
protected:
|
||||
std::string content;
|
||||
};
|
||||
@ -94,4 +104,17 @@ public:
|
||||
std::string ToHtml() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc An inline code block node.
|
||||
*
|
||||
* This node returns it's content wrapped with <code></code> tags.
|
||||
*
|
||||
* @author Hayden Hargreaves (hhargreaves2006@gmail.com)
|
||||
*/
|
||||
class CodeNode : public InlineNode {
|
||||
public:
|
||||
CodeNode(std::string content) : InlineNode(content) {};
|
||||
std::string ToHtml() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -67,6 +67,15 @@ public:
|
||||
virtual const std::vector<std::unique_ptr<Node>> &GetChilren() const {
|
||||
return this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Is the node empty.
|
||||
*
|
||||
* This is done differently for inline nodes and structure nodes.
|
||||
*
|
||||
* @author Hayden Hargreaves (hhargreaves2006@gmail.com)
|
||||
*/
|
||||
virtual bool IsEmpty() const = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -89,7 +89,7 @@ std::unique_ptr<Node> Parser::ParseParagraph() {
|
||||
node->AddChild(std::move(text_node));
|
||||
}
|
||||
|
||||
if (node->GetChilren().size() < 1)
|
||||
if (node->IsEmpty())
|
||||
return nullptr;
|
||||
|
||||
return node;
|
||||
@ -143,15 +143,29 @@ vector<std::unique_ptr<Node>> Parser::ParseInline() {
|
||||
|
||||
if (c == '*' && Peek(1) == '*' && Peek(2) == '*') {
|
||||
PushTextNode(nodes, str);
|
||||
nodes.push_back(std::move(ParseBoldItalic()));
|
||||
auto node = ParseBoldItalic();
|
||||
if (!node->IsEmpty())
|
||||
nodes.push_back(std::move(node));
|
||||
continue;
|
||||
} else if (c == '*' && Peek(1) == '*') {
|
||||
PushTextNode(nodes, str);
|
||||
nodes.push_back(std::move(ParseBold()));
|
||||
auto node = ParseBold();
|
||||
if (!node->IsEmpty())
|
||||
nodes.push_back(std::move(node));
|
||||
continue;
|
||||
} else if (c == '*') {
|
||||
PushTextNode(nodes, str);
|
||||
nodes.push_back(std::move(ParseItalic()));
|
||||
auto node = ParseItalic();
|
||||
if (!node->IsEmpty())
|
||||
nodes.push_back(std::move(node));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '`') {
|
||||
PushTextNode(nodes, str);
|
||||
auto node = ParseCode();
|
||||
if (!node->IsEmpty())
|
||||
nodes.push_back(std::move(node));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -231,6 +245,28 @@ std::unique_ptr<Node> Parser::ParseBoldItalic() {
|
||||
return std::make_unique<BoldItalicNode>(str);
|
||||
}
|
||||
|
||||
std::unique_ptr<Node> Parser::ParseCode() {
|
||||
string str;
|
||||
Consume(1);
|
||||
|
||||
while (!IsEOF()) {
|
||||
char c = Peek();
|
||||
|
||||
if (c == '\n' && Peek(1) == '\n')
|
||||
break;
|
||||
|
||||
if (c == '`') {
|
||||
Consume(1);
|
||||
break;
|
||||
}
|
||||
|
||||
str += c;
|
||||
Consume();
|
||||
}
|
||||
|
||||
return std::make_unique<CodeNode>(str);
|
||||
}
|
||||
|
||||
void Parser::PushTextNode(vector<std::unique_ptr<Node>> &nodes, string &str) {
|
||||
if (!str.empty())
|
||||
nodes.push_back(std::move(std::make_unique<TextNode>(str)));
|
||||
|
||||
@ -126,6 +126,7 @@ private:
|
||||
std::unique_ptr<Node> ParseItalic();
|
||||
std::unique_ptr<Node> ParseBold();
|
||||
std::unique_ptr<Node> ParseBoldItalic();
|
||||
std::unique_ptr<Node> ParseCode();
|
||||
|
||||
char Peek(size_t offset = 0);
|
||||
void Consume(size_t count = 1);
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define STRUCTURENODE_H
|
||||
|
||||
#include "node.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
@ -23,6 +24,15 @@ public:
|
||||
* @author Hayden Hargreaves (hhargreaves2006@gmail.com)
|
||||
*/
|
||||
virtual std::string ToHtml() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Is the node empty.
|
||||
*
|
||||
* This is the same as checking if the node has no children.
|
||||
*
|
||||
* @author Hayden Hargreaves (hhargreaves2006@gmail.com)
|
||||
*/
|
||||
bool IsEmpty() const { return this->children.size() == 0; };
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -79,7 +79,7 @@ void test_input(int argc, char **argv) {
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Parser p("syntax.md");
|
||||
Parser p("input.md");
|
||||
p.ParseDocument();
|
||||
p.WriteOutput();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user