blob: 4a62cbcfa11c48e9e51c32e7a7cb2a6d1cff2221 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
#ifndef MARKDOWN_TRANSLATOR_H
#define MARKDOWN_TRANSLATOR_H
#include <string>
#include <vector>
#include <sstream>
#include <ctime>
class MarkdownTranslator {
public:
MarkdownTranslator();
~MarkdownTranslator();
// Main translation function - takes markdown content and returns HTML
std::string translate(const std::string& markdownContent);
std::string processLine(const std::string& line);
void addExternalMenuItem(const std::string& name, const std::string& link){
ExternalMenuItem menuItem{name, link};
externalMenuLinks.push_back(menuItem);
}
enum Theme {
CARBON
};
struct ExternalMenuItem{
std::string name;
std::string link;
};
std::vector<ExternalMenuItem> externalMenuLinks;
private:
// Regex for various tags
const std::string headerRegexStr{"^(#{1,6})\\s+(.*)$"};
const std::string boldRegexStr{"\\*\\*([^\\*]+)\\*\\*|__([^_]+)__"};
const std::string italicRegexStr{"\\*([^\\*]+)\\*|_([^_]+)_"};
const std::string linkRegexStr{"\\[([^\\]]+)\\]\\(([^\\)]+)\\)"};
const std::string imageRegexStr{"!\\[(.*?)\\]\\(([^\\s\"]+)(\\s+\"(.*?)\")?\\)"};
// Helper functions for different markdown elements
void processMetadata(const std::vector<std::string>& lines);
std::string processHeaders(const std::string& line);
std::string processBold(const std::string& text);
std::string processItalic(const std::string& text);
std::string processLinks(const std::string& text);
std::string processParagraph(const std::string& text);
std::string processSingleFigure(const std::string& text);
std::string processFigureBlock(const std::vector<std::string>& lines);
std::string processCodeBlock(const std::string& language, const std::vector<std::string>& lines);
// Navigation and table of contents
void prescanHeaders(std::stringstream& markdownStream);
void generateSideBar(std::stringstream& output);
std::string createAnchorId(const std::string& text);
// Utility functions
std::string getCurrentDateTime() {
std::time_t now = std::time(nullptr);
std::tm* localTime = std::localtime(&now);
char buffer[80];
std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", localTime);
return std::string(buffer);
}
// HTML builders
std::string buildHTMLHeader(const std::string& title){
return R"(<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>)" + title + R"(</title>
<link rel="stylesheet" href=")" + cssPath + R"(">
<link href="https://unpkg.com/prism-themes@1.6.0/themes/prism-atom-dark.css" rel="stylesheet">
</head>
<body>
)";
}
std::string buildHTMLFooter(){
return R"( <div class="article-meta">
<p>Last updated: )" + getCurrentDateTime() + R"(</p>
</div>
</div>
</div>
<script src="https://unpkg.com/prismjs@1.30.0/prism.js"></script>
<script src="https://unpkg.com/prismjs@1.30.0/plugins/autoloader/prism-autoloader.min.js"></script>
</body>
</html>
)";
}
void setTheme(const Theme& theme){
switch(theme){
case Theme::CARBON:
cssPath = "styles/carbon.css";
break;
default:
cssPath = "styles/carbon.css";
}
}
// Member variables
std::string title;
std::string cssPath{"styles/carbon.css"};
std::vector<std::string> headers; // h1-6
enum ParseState {
REGULAR,
IN_FIGURE,
IN_CODEBLOCK,
};
};
#endif // MARKDOWN_TRANSLATOR_H
|