Compare commits
No commits in common. "436e08dbefffa0a4fa8c21bd5e6bad03898f4b71" and "40d3963babb06ec861973aadbc3fa43744024549" have entirely different histories.
436e08dbef
...
40d3963bab
2
Makefile
2
Makefile
@ -40,7 +40,7 @@ $(BUILD_DIR)/%.o: $(LIB_DIR)/%.cpp
|
|||||||
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ -pie
|
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ -pie
|
||||||
|
|
||||||
test: all
|
test: all
|
||||||
./$(TARGET) test/input.md -o output.html
|
./$(TARGET) test/journal.md -o output.html
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILD_DIR) $(TARGET)
|
rm -rf $(BUILD_DIR) $(TARGET)
|
||||||
|
|||||||
107
lib/parser.cpp
107
lib/parser.cpp
@ -8,13 +8,6 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
//
|
|
||||||
// Please please PLEASSSEEEE ignore the "wetness" of this...
|
|
||||||
// The architecture is under construction...
|
|
||||||
//
|
|
||||||
// wetness means not DRY, I just made it up :)
|
|
||||||
//
|
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
@ -110,12 +103,7 @@ std::unique_ptr<Node> Parser::ParseBlock() {
|
|||||||
return ParseImage();
|
return ParseImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Parse block quote
|
// 6. Parser paragraph
|
||||||
if (c == '>') {
|
|
||||||
return ParseBlockQuote();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. Parser paragraph
|
|
||||||
return ParseParagraph();
|
return ParseParagraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,24 +201,6 @@ std::unique_ptr<Node> Parser::ParseList(bool ordered) {
|
|||||||
return node;
|
return node;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Node> Parser::ParseBlockQuote() {
|
|
||||||
auto node = std::make_unique<BlockQuoteNode>();
|
|
||||||
|
|
||||||
char c = Peek();
|
|
||||||
while (c == '>') {
|
|
||||||
Consume(); // Consume the '>' character
|
|
||||||
ConsumeWhiteSpace(); // Consume whitespace
|
|
||||||
c = Peek();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto children = ParseInlineBlockQuote();
|
|
||||||
for (auto &child : children) {
|
|
||||||
node->AddChild(std::move(child));
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Node> Parser::ParseCodeBlock() {
|
std::unique_ptr<Node> Parser::ParseCodeBlock() {
|
||||||
auto node = std::make_unique<CodeBlockNode>();
|
auto node = std::make_unique<CodeBlockNode>();
|
||||||
string str;
|
string str;
|
||||||
@ -485,81 +455,6 @@ std::unique_ptr<Node> Parser::ParseInlineListContent() {
|
|||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<std::unique_ptr<Node>> Parser::ParseInlineBlockQuote() {
|
|
||||||
vector<std::unique_ptr<Node>> nodes;
|
|
||||||
string str;
|
|
||||||
|
|
||||||
while (!IsEOF()) {
|
|
||||||
char c = Peek();
|
|
||||||
char c_next = Peek(1);
|
|
||||||
|
|
||||||
if (c == '\n') {
|
|
||||||
if (c_next == '\n')
|
|
||||||
break;
|
|
||||||
|
|
||||||
Consume(); // consume the '\n'
|
|
||||||
|
|
||||||
if (Peek() == '>') {
|
|
||||||
Consume(); // consume the '>'
|
|
||||||
str += " ";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == '!' && c_next == '[') {
|
|
||||||
PushTextNode(nodes, str);
|
|
||||||
auto node = ParseImage();
|
|
||||||
if (!node->IsEmpty())
|
|
||||||
nodes.push_back(std::move(node));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == '[') {
|
|
||||||
PushTextNode(nodes, str);
|
|
||||||
auto node = ParseLink();
|
|
||||||
if (!node->IsEmpty())
|
|
||||||
nodes.push_back(std::move(node));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == '*' && Peek(1) == '*' && Peek(2) == '*') {
|
|
||||||
PushTextNode(nodes, str);
|
|
||||||
auto node = ParseBoldItalic();
|
|
||||||
if (!node->IsEmpty())
|
|
||||||
nodes.push_back(std::move(node));
|
|
||||||
continue;
|
|
||||||
} else if (c == '*' && Peek(1) == '*') {
|
|
||||||
PushTextNode(nodes, str);
|
|
||||||
auto node = ParseBold();
|
|
||||||
if (!node->IsEmpty())
|
|
||||||
nodes.push_back(std::move(node));
|
|
||||||
continue;
|
|
||||||
} else if (c == '*') {
|
|
||||||
PushTextNode(nodes, str);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a newline, use a space instead
|
|
||||||
str += (c == '\n' ? ' ' : c); // TODO: Maybe we don't need this...?
|
|
||||||
Consume();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push the last node, if the string is not empty
|
|
||||||
PushTextNode(nodes, str);
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Node> Parser::ParseItalic() {
|
std::unique_ptr<Node> Parser::ParseItalic() {
|
||||||
string str;
|
string str;
|
||||||
Consume(1);
|
Consume(1);
|
||||||
|
|||||||
@ -123,13 +123,11 @@ private:
|
|||||||
std::unique_ptr<Node> ParseHeading();
|
std::unique_ptr<Node> ParseHeading();
|
||||||
std::unique_ptr<Node> ParseList(bool ordered);
|
std::unique_ptr<Node> ParseList(bool ordered);
|
||||||
std::unique_ptr<Node> ParseCodeBlock();
|
std::unique_ptr<Node> ParseCodeBlock();
|
||||||
std::unique_ptr<Node> ParseBlockQuote();
|
|
||||||
vector<std::unique_ptr<Node>> ParseInline();
|
vector<std::unique_ptr<Node>> ParseInline();
|
||||||
|
|
||||||
// The only differences are the exit condition
|
// The only differences are the exit condition
|
||||||
vector<std::unique_ptr<Node>> ParseInlineHeading();
|
vector<std::unique_ptr<Node>> ParseInlineHeading();
|
||||||
std::unique_ptr<Node> ParseInlineListContent();
|
std::unique_ptr<Node> ParseInlineListContent();
|
||||||
vector<std::unique_ptr<Node>> ParseInlineBlockQuote();
|
|
||||||
|
|
||||||
void PushTextNode(vector<std::unique_ptr<Node>> &nodes, string &str);
|
void PushTextNode(vector<std::unique_ptr<Node>> &nodes, string &str);
|
||||||
|
|
||||||
|
|||||||
@ -99,15 +99,3 @@ string ImageNode::ToHtml() const {
|
|||||||
ss << "<img src=\"" << this->src << "\" alt=\"" << this->alt << "\" />\n";
|
ss << "<img src=\"" << this->src << "\" alt=\"" << this->alt << "\" />\n";
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
string BlockQuoteNode::ToHtml() const {
|
|
||||||
std::stringstream ss;
|
|
||||||
|
|
||||||
ss << "<blockquote>";
|
|
||||||
for (const auto &child : this->GetChilren()) {
|
|
||||||
ss << *child;
|
|
||||||
}
|
|
||||||
|
|
||||||
ss << "</blockquote>\n";
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|||||||
@ -143,9 +143,4 @@ public:
|
|||||||
std::string ToHtml() const;
|
std::string ToHtml() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlockQuoteNode : public StructureNode {
|
|
||||||
public:
|
|
||||||
std::string ToHtml() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,29 +1 @@
|
|||||||
hello world
|

|
||||||
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
> hello world
|
|
||||||
> hello world
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
> **a final line**
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
|
|
||||||
|
|
||||||
> hello
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
hi mom
|
|
||||||
|
|
||||||
> hello world\n>\n>\n>\n> a new line
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user