diff options
| author | Pinapelz <yukais@pinapelz.com> | 2025-10-28 02:44:33 -0700 |
|---|---|---|
| committer | Pinapelz <yukais@pinapelz.com> | 2025-10-28 02:44:44 -0700 |
| commit | 5fea6ece5c4c90753e19c27150522678b1872a12 (patch) | |
| tree | 51f08a6e294e5a60fa0e6af38c71a0e5981853a0 /src/markdown_translator.cpp | |
| parent | 29a0ab1f2b04a9b9a45282b6c9026136b1ed1f6d (diff) | |
pre-parse headers and add external links metadata tag for sidemenu
Diffstat (limited to 'src/markdown_translator.cpp')
| -rw-r--r-- | src/markdown_translator.cpp | 71 |
1 files changed, 60 insertions, 11 deletions
diff --git a/src/markdown_translator.cpp b/src/markdown_translator.cpp index 5bd1cc4..e9ddcae 100644 --- a/src/markdown_translator.cpp +++ b/src/markdown_translator.cpp @@ -3,15 +3,36 @@ #include <iostream> #include <algorithm> -MarkdownTranslator::MarkdownTranslator() : title("WikiMD2HTML") { +MarkdownTranslator::MarkdownTranslator() : title("WikiMD2HTML"), cssPath("styles/carbon.css") { } MarkdownTranslator::~MarkdownTranslator() { } +void MarkdownTranslator::prescanHeaders(std::stringstream& markdownStream) { + auto savedPos = markdownStream.tellg(); + markdownStream.seekg(0); + std::regex headerRegex(headerRegexStr); + std::smatch matches; + std::string line; + while (std::getline(markdownStream, line)) { + if (std::regex_match(line, matches, headerRegex)) { + int level = matches[1].length(); + std::string content = matches[2]; + headers.push_back(std::to_string(level) + ":" + content); + } + } + markdownStream.clear(); + markdownStream.seekg(savedPos); +} + + void MarkdownTranslator::processMetadata(const std::vector<std::string>& lines){ // format of keys -> key: value + int externalLinkBuilderState{0}; + std::string currExternalLinkName; + std::string currExternalLinkUrl; for(std::string currentLine : lines){ size_t colonPos = currentLine.find(':'); if (colonPos != std::string::npos) { @@ -21,6 +42,30 @@ void MarkdownTranslator::processMetadata(const std::vector<std::string>& lines){ if (key == "title") { title = value; } + else if (key == "external-name") { + currExternalLinkName = value; + externalLinkBuilderState = 1; + } + else if (key == "external-url") { + if (externalLinkBuilderState != 0) { + currExternalLinkUrl = value; + if (!currExternalLinkName.empty() && !currExternalLinkUrl.empty()) { + addExternalMenuItem(currExternalLinkName, currExternalLinkUrl); + currExternalLinkName = ""; + currExternalLinkUrl = ""; + externalLinkBuilderState = 0; + } + } + else{ + std::cout << "[WARNING] Unexpected external-url \"" << value << "\" found with no matching external-name. Ignoring..."; + } + } + else { + std::cerr << "ERROR OCCURED IN METADATA. UNKNOWN KEY" << std::endl; + } + if (key == "title") { + title = value; + } } } } @@ -29,7 +74,6 @@ std::string MarkdownTranslator::translate(const std::string& markdownContent) { std::stringstream htmlOutput; std::stringstream markdownStream(markdownContent); std::string line; - std::vector<std::string> headers; std::string currentLine; // Parse metadata section if it exists @@ -48,8 +92,12 @@ std::string MarkdownTranslator::translate(const std::string& markdownContent) { // Process and apply metadata to curr object if(metadataExists) processMetadata(metadataLines); + + // Pre-scan for headers before generating sidebar + prescanHeaders(markdownStream); + htmlOutput << buildHTMLHeader(title); - generateSideBar(htmlOutput, headers); + generateSideBar(htmlOutput); // Main content container htmlOutput << " <div class=\"main-content\">\n"; htmlOutput << " <div class=\"container\">\n"; @@ -81,23 +129,24 @@ std::string MarkdownTranslator::translate(const std::string& markdownContent) { } + return htmlOutput.str(); } -void MarkdownTranslator::generateSideBar(std::stringstream& output, const std::vector<std::string>& headers) { +void MarkdownTranslator::generateSideBar(std::stringstream& output) { output << " <div class=\"nav-sidebar\">\n"; output << " <div class=\"nav-logo\">\n"; output << " <h3>" + title + "</h3>\n"; output << " </div>\n"; output << " <ul class=\"nav-menu\">\n"; - + if(externalMenuLinks.size() > 0){ + for(const ExternalMenuItem& menuItem : externalMenuLinks){ + output << " <li><a href=\""+menuItem.link+"\">"+menuItem.name+"</a></li>\n"; + } + } output << " <h4>Table of Contents</h4>\n"; - output << " <li><a href=\"index.html\">Home</a></li>\n"; - output << " <li><a href=\"#\">Recent Changes</a></li>\n"; - output << " <li><a href=\"#\">Random Page</a></li>\n"; output << " <ul class=\"nav-submenu\">\n"; - // Generate navigation from headers for (const auto& header : headers) { size_t separatorPos = header.find(':'); if (separatorPos != std::string::npos) { @@ -108,12 +157,12 @@ void MarkdownTranslator::generateSideBar(std::stringstream& output, const std::v std::string anchorId = createAnchorId(content); // Add indentation based on header level - std::string indentation = ""; + std::string indentation = " "; for (int i = 1; i < level; ++i) { indentation += " "; } - output << " " << indentation << "<li><a href=\"#" << anchorId << "\">" << content << "</a></li>\n"; + output << indentation << "<li class=\"level-" << level << "\"><a href=\"#" << anchorId << "\">" << content << "</a></li>\n"; } } |
