aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremias Stotter <jeremias@stotter.eu>2022-01-03 01:07:46 +0100
committerJeremias Stotter <jeremias@stotter.eu>2022-01-03 01:07:46 +0100
commit1864e46afaf76aad3aa377b857289bcaca37e0c6 (patch)
tree485bfa73e099528a44a121fbb09096ad03db2211
parenta4a5a6050a18a034633306a4e031f2f6d3cd02cc (diff)
downloadJBlog-1864e46afaf76aad3aa377b857289bcaca37e0c6.tar.gz
JBlog-1864e46afaf76aad3aa377b857289bcaca37e0c6.tar.bz2
JBlog-1864e46afaf76aad3aa377b857289bcaca37e0c6.zip
Somewhat working implementation bold and italics
Only with asterisk for now
-rw-r--r--md.c177
1 files changed, 154 insertions, 23 deletions
diff --git a/md.c b/md.c
index c5ac072..272fb4c 100644
--- a/md.c
+++ b/md.c
@@ -42,7 +42,8 @@ enum html_type {
t_h, // Contains a pointer to an int as its value, this pointer indicates title strength (1-6)
t_p,
t_br,
- t_str, // t_str contains an int pointer as its level
+ t_str_ast, // t_str contains an int pointer to its level
+ t_str_und,
t_img,
t_a,
t_ol,
@@ -119,8 +120,9 @@ char* realloc_append(char* dest, char* src) {
#define p_html "<p>%s</p>\n"
#define br_html "<br/>"
#define h_html "<h%d>%s</h%d>\n"
-#define em_html "<em>%s</p>\n"
+#define em_html "<em>%s</em>\n"
#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 ol_html "<ol>%s</ol>\n"
@@ -156,9 +158,26 @@ char* tree_to_html(struct tree_element* root) {
html = realloc_for_html(h_html);
sprintf(html, h_html, *(int*)(root->value), inner_html ? inner_html : "", *(int*)(root->value));
break;
- case(t_str):
- html = realloc_for_html(em_html);
- sprintf(html, em_html, inner_html ? inner_html : "");
+ case(t_str_ast):
+ case(t_str_und):
+ switch(*(unsigned int*)root->value) {
+ case(1):
+ html = realloc_for_html(em_html);
+ sprintf(html, em_html, inner_html ? inner_html : "");
+ break;
+ case(2):
+ html = realloc_for_html(b_html);
+ sprintf(html, b_html, inner_html ? inner_html : "");
+ break;
+ case(3):
+ html = realloc_for_html(emb_html);
+ sprintf(html, emb_html, inner_html ? inner_html : "");
+ break;
+ default:
+ html = realloc_for_html("");
+ strcpy(html, inner_html);
+ break;
+ }
break;
case(t_br):
html = realloc_for_html(br_html);
@@ -225,6 +244,43 @@ struct tree_element* new_ul(struct tree_element* parent, int indent) {
return new_ul;
}
+// Walk up the tree until root, stop if we encounter the requested type and return that node, otherwise return NULL
+struct tree_element* find_parent_type(struct tree_element* root, struct tree_element* start, int type) {
+ struct tree_element* check_element = start;
+ while(check_element != root) {
+ if(check_element->type == type)
+ return check_element;
+ check_element = check_element->parent;
+ }
+ return NULL;
+}
+
+
+
+void end_strength(struct tree_element* root, struct tree_element** active_element, char marker, int tmp_str) {
+ struct tree_element* parent_strength = find_parent_type(root, *active_element, t_str_ast);
+ printf("\n##%d##\n", *(unsigned int*)parent_strength->value);
+ *active_element = parent_strength->parent;
+ if(tmp_str < *(unsigned int*)parent_strength->value) {
+ struct tree_element* tmp_active = parent_strength->parent;
+ for(int i = tmp_str; i < *(unsigned int*)parent_strength->value; i++)
+ append_char_to_active(root, &tmp_active, '*');
+ *(unsigned int*)parent_strength->value = tmp_str;
+ } else if(tmp_str > *(unsigned int*)parent_strength->value) {
+ struct tree_element* tmp_active;
+ 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;
+ }
+ for(int i = *(unsigned int*)parent_strength->value; i < tmp_str; i++)
+ append_char_to_active(root, &tmp_active, '*');
+ }
+
+}
+
// The program needs to loop through the loop again to cose all the open things at the end, THIS NEEDS TO BE IMPLEMENTED for xhtml
int parse_markdown(char* input, char* buffer, size_t buffer_size) {
clock_t before = clock();
@@ -239,6 +295,24 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
int spaces_trimmed = 0;
int root_on_newline = false;
+ // These store temporary strength values
+ unsigned int temp_str_ast = 0;
+ unsigned int temp_str_und = 0;
+
+ // These are true if a strength element is waiting for closing
+ bool str_cl_wait_ast = false;
+ bool str_cl_wait_und = false;
+
+ // These are true if a strength element waits for a different character
+ bool str_chr_wait_ast = false;
+ bool str_chr_wait_und = false;
+
+ bool str_fin_wait_ast = false;
+ bool str_fin_wait_und = false;
+
+#define ZERO_STR_AST temp_str_ast = 0; str_cl_wait_ast = false; str_chr_wait_ast = false; str_fin_wait_ast = false;
+#define ZERO_STR_UND temp_str_und = 0; str_cl_wait_und = false; str_chr_wait_und = false; str_fin_wait_und = false;
+
struct tree_element* root = new_element();
struct tree_element* active_element = root;
for(char* cur_char = input; *cur_char != '\0'; cur_char++) {
@@ -256,6 +330,21 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
continue;
}
+ if(str_chr_wait_ast && *cur_char != '*') {
+ printf("\n|%d|\n", temp_str_ast);
+ if(str_cl_wait_ast) {
+ if(str_fin_wait_ast) {
+ end_strength(root, &active_element, '*', temp_str_ast);
+ str_fin_wait_ast = false;
+ temp_str_ast = 0;
+ }
+ str_cl_wait_ast = false;
+ } else
+ str_cl_wait_ast = true;
+
+ str_chr_wait_ast = false;
+ }
+
#define LAST_TO_TITLE(n) {\
if(root->children_n >= 1) {\
struct tree_element* last_element = root->children[root->children_n-1];\
@@ -320,14 +409,55 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
} else if(active_element != root) {
newline = true;
}
+
+ if(temp_str_ast > 0)
+ end_strength(root, &active_element, '*', temp_str_ast);
+
+ if(temp_str_und > 0)
+ end_strength(root, &active_element, '_', temp_str_und);
+
hash_chain = 0;
spaces_trimmed = 0;
+ ZERO_STR_AST
+ ZERO_STR_UND
break;
case('*'):
- if(active_element == root || newline) {
+ printf("\n#%d %d %d %d#\n", temp_str_ast, str_cl_wait_ast, str_fin_wait_ast, str_chr_wait_ast);
+ if((active_element == root || newline) && *(cur_char+1) == ' ' ) {
list_waiting = true;
} else {
- // Text strength
+ struct tree_element* parent_strength = find_parent_type(root, active_element, t_str_ast);
+ if(parent_strength) {
+ // We are already in a strength element
+ // Check if we are waiting to close
+ if(str_cl_wait_ast) {
+ (*(unsigned int*)(parent_strength->value))++;
+ if((*(unsigned int*)(parent_strength->value)) >= temp_str_ast) {
+ active_element = parent_strength->parent;
+ ZERO_STR_AST
+ break;
+ } else {
+ str_fin_wait_ast = true;
+ }
+ } else {
+ temp_str_ast++;
+ }
+ } else {
+ // Enter a new strength element as we are currently not in one
+ 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;
+ }
+ active_element = new_child(active_element, -1);
+ active_element->type = t_str_ast;
+ active_element->allow_inner = true;
+ active_element->value = calloc(sizeof(unsigned int), 1);
+ temp_str_ast = 1;
+ }
+ str_chr_wait_ast = true;
}
break;
case('_'):
@@ -386,24 +516,25 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
* On fewer spaces we enter a new list below the one we found
* Is it equal we just add a new list item
* If we do not find a list we create a new one at the root node */
- struct tree_element* look_element = active_element;
+ struct tree_element* look_element = find_parent_type(root, active_element, t_ul);;
bool found_ul = false;
- while(look_element && look_element != root){
- if(look_element->type == t_ul) {
- // Enter new child ul
- if(*(int*)look_element->value < spaces_trimmed) {
- active_element = new_ul(look_element, spaces_trimmed);
- found_ul = true;
- break;
- }
- // We found a list of the exact indentation level
- if(*(int*)look_element->value == spaces_trimmed) {
- active_element = look_element;
- found_ul = true;
- break;
- }
+ while(look_element != NULL){
+ // Enter new child ul
+ if(*(int*)look_element->value < spaces_trimmed) {
+ active_element = new_ul(look_element, spaces_trimmed);
+ found_ul = true;
+ break;
+ }
+ // We found a list of the exact indentation level
+ if(*(int*)look_element->value == spaces_trimmed) {
+ active_element = look_element;
+ found_ul = true;
+ break;
}
- look_element = look_element->parent;
+ if(*(int*)look_element->value > spaces_trimmed)
+ look_element = find_parent_type(root, look_element->parent, t_ul);
+ else
+ look_element = find_parent_type(root, look_element, t_ul);
}
// Enter a new list
if(!found_ul) {
Jeremias Stotters git repositories generated by CGIT