Add hyperlink support to MarkdownParser

MarkdownParser now supports hyperlinks.
This commit is contained in:
luca0N! 2022-03-08 18:00:41 -03:00
parent 99e2f412cd
commit c4d83a9eef
Signed by: luca0N
GPG Key ID: 2E7B4655CF16D7D6
1 changed files with 86 additions and 11 deletions

View File

@ -22,18 +22,53 @@
#include "MarkdownParser.hxx" #include "MarkdownParser.hxx"
#include <assert.h> #include <assert.h>
#include <iostream>
#define ASCII_DIGIT_START 48 #define ASCII_DIGIT_START 48
enum HyperlinkStage {
NONE, // not reading a hyperlink
READING_CONTENTS, // reading the contents (like text) of a hyperlink
EXPECTING_URL, // done reading contents of hyperlink; expecting its URL to be specified
READING_URL // reading the hyperlink url
};
std::string html,
tag_a_text_buf, // used for storing the text contents of a hyperlink
tag_a_buf; // used for storing the hyperlink address
enum HyperlinkStage tag_a = NONE;
void append(std::string const &s) {
// TODO: add proper error handling.
assert(tag_a != EXPECTING_URL);
switch(tag_a) {
case NONE:
html += s;
break;
case READING_CONTENTS:
tag_a_text_buf += s;
break;
case READING_URL:
tag_a_buf += s;
break;
}
}
void append(const char *c) {
append(std::string(c));
}
void cleanup() {
html = "";
}
namespace MarkdownParser { namespace MarkdownParser {
std::string make_html(std::filesystem::path const &path) { std::string make_html(std::filesystem::path const &path) {
cleanup();
FILE *mdFile = fopen(path.string().c_str(), "r"); FILE *mdFile = fopen(path.string().c_str(), "r");
// TODO: Add proper error handling. // TODO: Add proper error handling.
assert(mdFile != NULL); assert(mdFile != NULL);
std::string html;
int buflen = 64; int buflen = 64;
char buf[buflen]; char buf[buflen];
@ -105,25 +140,24 @@ std::string make_html(std::filesystem::path const &path) {
// Bold check // Bold check
// Check whether this character has been escaped. // Check whether this character has been escaped.
if (buf[x-1] == '\\') { if (buf[x-1] == '\\') {
html += "*"; append(&c);
break; break;
} }
html += tag_b ? "</b>" : "<b>"; append(tag_b ? "</b>" : "<b>");
tag_b = !tag_b; tag_b = !tag_b;
break; break;
case '_': case '_':
// Italics check // Italics check
// Check whether this character has // Check whether this character has
// been escaped. // been escaped.
if (buf[x-1] == '\\') { if (buf[x-1] == '\\') {
html += "_"; append(&c);
break; break;
} }
html += tag_i ? "</i>" : "<i>"; append(tag_i ? "</i>" : "<i>");
tag_i = !tag_i; tag_i = !tag_i;
break; break;
case '#': case '#':
@ -133,7 +167,7 @@ std::string make_html(std::filesystem::path const &path) {
// beginning of a new line. Ignore it // beginning of a new line. Ignore it
// if this is not a new line. // if this is not a new line.
if (!newline) { if (!newline) {
html += "#"; append(&c);
break; break;
} }
@ -143,7 +177,7 @@ std::string make_html(std::filesystem::path const &path) {
// Check if this header was specified // Check if this header was specified
// right at the beginning of the line. // right at the beginning of the line.
(tag_h == 0 && x != 0)) { (tag_h == 0 && x != 0)) {
html += "#"; append(&c);
break; break;
} }
@ -192,14 +226,55 @@ std::string make_html(std::filesystem::path const &path) {
ignoreSpace = true; ignoreSpace = true;
tag_li = true; tag_li = true;
break; break;
case '[':
// Hyperlink text declaration has begun
if (tag_a != NONE) {
// Cannot add hyperlinks inside of hyperlinks;
append(&c);
break;
}
tag_a_buf = "";
tag_a_text_buf = "";
tag_a = READING_CONTENTS;
break;
case ']':
// Hyperlink text declaration ended
if (tag_a != READING_CONTENTS) {
// Ignore if not reading hyperlink.
append(&c);
break;
}
tag_a = EXPECTING_URL;
break;
case '(':
// Hyperlink address declaration has begun
if (tag_a != EXPECTING_URL) {
append(&c);
break;
}
tag_a = READING_URL;
break;
case ')':
// Hyperlink address declaration ended
if (tag_a != READING_URL) {
append(&c);
break;
}
tag_a = NONE;
append("<a href=\"");
append(tag_a_buf);
append("\">");
append(tag_a_text_buf);
append("</a>");
break;
case ' ': case ' ':
if (ignoreSpace) { if (ignoreSpace) {
ignoreSpace = false; ignoreSpace = false;
break; break;
} else html += ' '; } else append(" ");
break; break;
default: default:
html += c; append(&c);
break; break;
} }
} }