From e6dc3183064df117cab299e66495e543dac67a48 Mon Sep 17 00:00:00 2001 From: Hayden Hargreaves Date: Wed, 22 Oct 2025 12:03:02 -0700 Subject: [PATCH] (FEAT): Heading parser uses a new inline method. The only difference between this and the original one is the exit condition. --- input.md | 6 ++++- lib/parser.cpp | 68 +++++++++++++++++++++++++++++++++++++++----------- lib/parser.h | 5 ++++ 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/input.md b/input.md index 72e47cf..f66ff5f 100644 --- a/input.md +++ b/input.md @@ -15,4 +15,8 @@ this is too far` ## **Hello world** -### hello world +### hello *world* + +# ***This is both!*** + +###### This is neither diff --git a/lib/parser.cpp b/lib/parser.cpp index 54372e5..1d5a7e5 100644 --- a/lib/parser.cpp +++ b/lib/parser.cpp @@ -108,25 +108,15 @@ std::unique_ptr Parser::ParseHeading() { ConsumeWhiteSpace(); - std::string str; - while (!IsEOF()) { - c = Peek(); - // We can stop as soon as we see a new line. Headings are single line blocks - if (c == '\n') - break; - - // If a newline, use a space instead - str += c; - Consume(); + // This should call parse inline + auto text_nodes = ParseInline(); + for (auto &text_node : text_nodes) { + node->AddChild(std::move(text_node)); } - // BUG: Why do we need to check this? - if (str == "") + if (node->IsEmpty()) return nullptr; - auto text_node = std::make_unique(str); - node->AddChild(std::move(text_node)); - return node; } @@ -179,6 +169,54 @@ vector> Parser::ParseInline() { return nodes; } +vector> Parser::ParseInlineHeading() { + vector> nodes; + string str; + + while (!IsEOF()) { + char c = Peek(); + // We can stop as soon as we see a new line. Headings are single line blocks + if (c == '\n') + break; + + 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); + Consume(); + } + + // Push the last node, if the string is not empty + PushTextNode(nodes, str); + return nodes; +} + std::unique_ptr Parser::ParseItalic() { string str; Consume(1); diff --git a/lib/parser.h b/lib/parser.h index 63766af..02ccb35 100644 --- a/lib/parser.h +++ b/lib/parser.h @@ -117,10 +117,15 @@ private: // Working input content string content; + // TODO: Document these methods, no more magic methods :) + std::unique_ptr ParseParagraph(); std::unique_ptr ParseHeading(); vector> ParseInline(); + // The only difference is the exit condition + vector> ParseInlineHeading(); + void PushTextNode(vector> &nodes, string &str); std::unique_ptr ParseItalic();