aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremias Stotter <jeremias@stotter.eu>2022-02-06 22:27:48 +0100
committerJeremias Stotter <jeremias@stotter.eu>2022-02-06 22:27:48 +0100
commitd2a4ce480a38738f15dd00e2de164b5a6398a140 (patch)
treeb8d58c28a25e24b68b39d8dde268b2e9d8beb938
parent204b3f626d4d3f6dde6dd64f9be6446fb9306ed1 (diff)
downloadJBlog-d2a4ce480a38738f15dd00e2de164b5a6398a140.tar.gz
JBlog-d2a4ce480a38738f15dd00e2de164b5a6398a140.tar.bz2
JBlog-d2a4ce480a38738f15dd00e2de164b5a6398a140.zip
Added link support
-rw-r--r--md.c111
1 files changed, 54 insertions, 57 deletions
diff --git a/md.c b/md.c
index 94a3400..b8201da 100644
--- a/md.c
+++ b/md.c
@@ -154,7 +154,7 @@ char* realloc_append(char* dest, char* src) {
#define b_html "<b>%s</b>\n"
#define emb_html "<em><b>%s</b></em>\n"
#define img_html "<img src=\"%s\" alt=\"%s\" title=\"\"/>\n"
-#define a_html "<a href=%s>%s</a>\n"
+#define a_html "<a href=\"%s\">%s</a>\n"
#define ol_html "<ol>%s</ol>\n"
#define ul_html "<ul>%s</ul>\n"
#define li_html "<li>%s</li>\n"
@@ -179,7 +179,8 @@ char* tree_to_html(struct tree_element* root) {
}
}
// printf("%s\n", inner_html ? inner_html : "(EMPTY)");
- #define realloc_for_html(html_pattern) realloc(html, (inner_html ? strlen(inner_html) : 0) + strlen(html_pattern) + 1);
+ #define realloc_len(html_pattern) (inner_html ? strlen(inner_html) : 0) + strlen(html_pattern) + 1
+ #define realloc_for_html(html_pattern) realloc(html, realloc_len(html_pattern));
switch(root->type) {
case(t_p):
html = realloc_for_html(p_html);
@@ -210,6 +211,12 @@ char* tree_to_html(struct tree_element* root) {
break;
}
break;
+ case(t_a):
+ html = realloc(html, realloc_len(a_html) + strlen(root->value));
+ if(!html)
+ exit(-1);
+ sprintf(html, a_html, root->value ? (char*)(root->value) : "", inner_html ? inner_html : "");
+ break;
case(t_br):
html = realloc_for_html(br_html);
strcpy(html, br_html);
@@ -237,18 +244,18 @@ char* tree_to_html(struct tree_element* root) {
return html;
}
+// Use this to create a new child of another element and quickly set its atributes
+#define new_active_child(ae_var, parent, index, type_v, allow_inner_v) ae_var = new_child(parent, index); ae_var->type = type_v; ae_var->allow_inner = allow_inner_v;
+
// This appends the cur_char to active element / it creates a new active element if the active element can not have text
void append_char_to_active(struct tree_element* root, struct tree_element** active_element, char cur_char) {
// We are not allowed to add inner to this element so we'll start a new paragraph
struct tree_element* new_active_element = active_element ? *active_element : root;
if(!(new_active_element->allow_inner) && new_active_element->type != t_inner) {
- new_active_element = new_child(root, -1);
- new_active_element->type = t_p;
- new_active_element->allow_inner = true;
+ new_active_child(new_active_element, root, -1, t_p, true);
}
if(new_active_element->type != t_inner) {
- new_active_element = new_child(new_active_element, -1);
- new_active_element->type = t_inner;
+ new_active_child(new_active_element, new_active_element, -1, t_inner, false);
}
if((cur_char <= 47 ||
(cur_char >=58 && cur_char <=64) ||
@@ -271,9 +278,7 @@ void append_char_to_active(struct tree_element* root, struct tree_element** acti
// indent is the spaces that the list indicator ( * or - ) was intendend
struct tree_element* new_ul(struct tree_element* parent, int indent) {
struct tree_element *new_ul;
- new_ul = new_child(parent, -1);
- new_ul->type = t_ul;
- new_ul->allow_inner = false;
+ new_active_child(new_ul, parent, -1, t_ul, false);
new_ul->value = malloc(sizeof(int));
*(int*)new_ul->value = indent;
return new_ul;
@@ -323,9 +328,7 @@ void end_strength(struct tree_element* root, struct tree_element** active_elemen
if((parent_strength->parent)->children_n >= 2)
tmp_active = &(*(parent_strength->parent)->children[(parent_strength->parent)->children_n-2]);
else {
- tmp_active = new_child(parent_strength->parent, 0);
- tmp_active->type = t_inner;
- tmp_active->allow_inner = false;
+ new_active_child(tmp_active, parent_strength->parent, 0, t_inner, false);
}
for(int i = *(unsigned int*)parent_strength->value; i < tmp_str; i++)
append_char_to_active(root, &tmp_active, '*');
@@ -370,13 +373,9 @@ void str_chr_hit(struct tree_element* root, struct tree_element** active_element
if((*active_element)->type == t_inner)
*active_element = (*active_element)->parent;
if(*active_element == root) {
- *active_element = new_child(root, -1);
- (*active_element)->type = t_p;
- (*active_element)->allow_inner = true;
+ new_active_child((*active_element), root, -1, t_p, true);
}
- *active_element = new_child(*active_element, -1);
- (*active_element)->type = desired_type;
- (*active_element)->allow_inner = true;
+ new_active_child((*active_element), (*active_element), -1, desired_type, true);
(*active_element)->value = calloc(sizeof(unsigned int), 1);
*temp_str = 1;
}
@@ -411,8 +410,7 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
if((*cur_char == '\n' || *cur_char == '\r')) {
if(active_element->parent)
active_element = active_element->parent;
- struct tree_element* br_child = new_child(active_element, -1);
- br_child->type = t_br;
+ struct tree_element* br_child = new_active_child(br_child, active_element, -1, t_br, false);
} else {
append_char_to_active(root, &active_element, *cur_char);
}
@@ -458,9 +456,7 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
// Make the last element a title unless
if(!newline) {
if(dash_chain >= 3 && active_element == root) {
- struct tree_element* hr = new_child(root, -1);
- hr->type = t_hr;
- hr->allow_inner = false;
+ struct tree_element* hr = new_active_child(hr, root, -1, t_hr, false);
} else {
for(int i = 0; i < dash_chain; i++)
append_char_to_active(root, NULL, '-');
@@ -522,6 +518,33 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
break;
case('~'):
break;
+ case('['):
+ char* link_text = NULL;
+ char* link_loc = NULL;
+ size_t link_len = 0;
+ char* new_position = get_link_components(cur_char, &link_text, &link_loc, &link_len);
+ if(new_position) {
+ if(active_element == root) {
+ new_active_child(active_element, active_element, -1, t_p, true);
+ }
+ while(!active_element->allow_inner && active_element)
+ active_element = active_element->parent;
+ // We have a link
+ // Create a new a element which contains the link adress
+ new_active_child(active_element, active_element, -1, t_a, true);
+ active_element->value = link_loc;
+ // Create an inner element in it which contains the text
+ new_active_child(active_element, active_element, -1, t_inner, false);
+ active_element->value = link_text;
+ // Return to the old parent
+ active_element = active_element->parent->parent;
+ cur_char = new_position;
+ break;
+ }
+ else
+ goto default2;
+ case('!'):
+ break;
// Titles
case('='):
if(active_element == root || newline) {
@@ -553,9 +576,7 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
if(active_element->parent ? active_element->parent->type == t_h : false) {
active_element = active_element->parent;
} else {
- active_element = new_child(root, -1);
- active_element->allow_inner = true;
- active_element->type = t_h;
+ new_active_child(active_element, root, -1, t_h, true);
active_element->value = malloc(sizeof(int));
}
}
@@ -595,10 +616,7 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
if(!found_ul) {
active_element = new_ul(root, spaces_trimmed);
}
-
- active_element = new_child(active_element, -1);
- active_element->type = t_li;
- active_element->allow_inner = true;
+ new_active_child(active_element, active_element, -1, t_li, true);
root_on_newline = true;
list_waiting = false;
}
@@ -609,6 +627,7 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
break;
}
// Default character handling
+ default2:
default:
if(spaces_trimmed >= 4 && (newline || active_element == root)) {
// if code_element is set the new active element is just returned to the code element
@@ -616,9 +635,7 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
active_element = code_element;
//append_char_to_active(root, &active_element, '\n');
} else {
- active_element = new_child(root, -1);
- active_element->type = t_code;
- active_element->allow_inner = true;
+ new_active_child(active_element, root, -1, t_code, true);
code_element = active_element;
}
for(int i = 0; i < spaces_trimmed - 4; i++)
@@ -686,29 +703,9 @@ int trim_space(char* input, char** output) {
return count;
}
-/*
-// Append in_src to in_dst, then return length of new string
-size_t append(char* in_dest, char* in_src) {
- strcat(in_dest, in_src);
- // for pure safety reasons I'll put a terminating \0 at the end of the destination string
- in_dest[LINE_MAX-1] = '\0';
- return strlen(in_dest);
-}
-
-// Prepend in_src to in_dst, then return length of new string
-size_t prepend(char* in_dest, char* in_src) {
- char prepended_string[LINE_MAX] = {'\0'};
- strncpy(prepended_string, in_src, LINE_MAX - 1);
- strncat(prepended_string, in_dest, LINE_MAX - 1);
- memcpy(in_dest, prepended_string, LINE_MAX);
- // for pure safety reasons I'll put a terminating \0 at the end of the destination string
- in_dest[LINE_MAX-1] = '\0';
- return strlen(in_dest);
-}
-*/
-// start is the first curly bracket we have
-// Returns pointer to last round bracket
-// free the returned pointers yourself
+// Returns location of the closing round bracket if found, otherwise it returns a NULL
+// out_text and out_loc are allocated by this function
+// Don't forget to free
char* get_link_components(char* start, char** out_text, char** out_loc, size_t* out_len) {
// Search for the next closing bracket
char* closing_sqr_bracket = strchr(start, ']');
Jeremias Stotters git repositories generated by CGIT