Add hyperlink support to MarkdownParser
MarkdownParser now supports hyperlinks.
This commit is contained in:
parent
99e2f412cd
commit
c4d83a9eef
|
@ -22,18 +22,53 @@
|
|||
#include "MarkdownParser.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
#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 {
|
||||
|
||||
std::string make_html(std::filesystem::path const &path) {
|
||||
cleanup();
|
||||
FILE *mdFile = fopen(path.string().c_str(), "r");
|
||||
// TODO: Add proper error handling.
|
||||
assert(mdFile != NULL);
|
||||
|
||||
std::string html;
|
||||
|
||||
int buflen = 64;
|
||||
char buf[buflen];
|
||||
|
||||
|
@ -105,25 +140,24 @@ std::string make_html(std::filesystem::path const &path) {
|
|||
// Bold check
|
||||
// Check whether this character has been escaped.
|
||||
if (buf[x-1] == '\\') {
|
||||
html += "*";
|
||||
append(&c);
|
||||
break;
|
||||
}
|
||||
|
||||
html += tag_b ? "</b>" : "<b>";
|
||||
append(tag_b ? "</b>" : "<b>");
|
||||
tag_b = !tag_b;
|
||||
break;
|
||||
case '_':
|
||||
// Italics check
|
||||
|
||||
// Check whether this character has
|
||||
// been escaped.
|
||||
|
||||
if (buf[x-1] == '\\') {
|
||||
html += "_";
|
||||
append(&c);
|
||||
break;
|
||||
}
|
||||
|
||||
html += tag_i ? "</i>" : "<i>";
|
||||
append(tag_i ? "</i>" : "<i>");
|
||||
tag_i = !tag_i;
|
||||
break;
|
||||
case '#':
|
||||
|
@ -133,7 +167,7 @@ std::string make_html(std::filesystem::path const &path) {
|
|||
// beginning of a new line. Ignore it
|
||||
// if this is not a new line.
|
||||
if (!newline) {
|
||||
html += "#";
|
||||
append(&c);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -143,7 +177,7 @@ std::string make_html(std::filesystem::path const &path) {
|
|||
// Check if this header was specified
|
||||
// right at the beginning of the line.
|
||||
(tag_h == 0 && x != 0)) {
|
||||
html += "#";
|
||||
append(&c);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -192,14 +226,55 @@ std::string make_html(std::filesystem::path const &path) {
|
|||
ignoreSpace = true;
|
||||
tag_li = true;
|
||||
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 ' ':
|
||||
if (ignoreSpace) {
|
||||
ignoreSpace = false;
|
||||
break;
|
||||
} else html += ' ';
|
||||
} else append(" ");
|
||||
break;
|
||||
default:
|
||||
html += c;
|
||||
append(&c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue