From 5fea6ece5c4c90753e19c27150522678b1872a12 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Tue, 28 Oct 2025 02:44:33 -0700 Subject: pre-parse headers and add external links metadata tag for sidemenu --- src/markdown_translator.cpp | 71 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 11 deletions(-) (limited to 'src') 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 #include -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& 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& 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 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 << "
\n"; htmlOutput << "
\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& headers) { +void MarkdownTranslator::generateSideBar(std::stringstream& output) { output << "
\n"; output << "
\n"; output << "

" + title + "

\n"; output << "
\n"; output << "
    \n"; - + if(externalMenuLinks.size() > 0){ + for(const ExternalMenuItem& menuItem : externalMenuLinks){ + output << "
  • "+menuItem.name+"
  • \n"; + } + } output << "

    Table of Contents

    \n"; - output << "
  • Home
  • \n"; - output << "
  • Recent Changes
  • \n"; - output << "
  • Random Page
  • \n"; output << "
      \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 << "
    • " << content << "
    • \n"; + output << indentation << "
    • " << content << "
    • \n"; } } -- cgit v1.2.3