aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremias Stotter <jeremias@stotter.eu>2021-12-28 20:35:24 +0100
committerJeremias Stotter <jeremias@stotter.eu>2021-12-28 20:35:24 +0100
commit4c3bb4528c1583ae397c56397c4d46660d67a935 (patch)
treeab4a75c21f7aa9afb8f3768ca5ee289bdc215aeb
parent8c20d5f8262468097798007798c93af235867efd (diff)
downloadJBlog-4c3bb4528c1583ae397c56397c4d46660d67a935.tar.gz
JBlog-4c3bb4528c1583ae397c56397c4d46660d67a935.tar.bz2
JBlog-4c3bb4528c1583ae397c56397c4d46660d67a935.zip
Added setext like headers and hr
And of course a few other things
-rw-r--r--md.c145
1 files changed, 95 insertions, 50 deletions
diff --git a/md.c b/md.c
index 3683bd1..6b26b8d 100644
--- a/md.c
+++ b/md.c
@@ -47,7 +47,8 @@ enum html_type {
t_a,
t_ol,
t_ul, // Value contains the ammount of spaces used to indent at that level
- t_li
+ t_li,
+ t_hr
};
// The file will be structured as a tree that, in the end will be converted to valid html
@@ -125,6 +126,7 @@ char* realloc_append(char* dest, char* src) {
#define ol_html "<ol>%s</ol>\n"
#define ul_html "<ul>%s</ul>\n"
#define li_html "<li>%s</li>\n"
+#define hr_html "<hr/>\n"
// Resolve a tree to html
char* tree_to_html(struct tree_element* root) {
char* html=NULL;
@@ -159,7 +161,7 @@ char* tree_to_html(struct tree_element* root) {
sprintf(html, em_html, inner_html ? inner_html : "");
break;
case(t_br):
- html = realloc_for_html(b_html);
+ html = realloc_for_html(br_html);
strcpy(html, br_html);
break;
case(t_ul):
@@ -170,6 +172,10 @@ char* tree_to_html(struct tree_element* root) {
html = realloc_for_html(li_html);
sprintf(html, li_html, inner_html ? inner_html : "");
break;
+ case(t_hr):
+ html = realloc_for_html(hr_html);
+ strcpy(html, hr_html);
+ break;
default:
html=inner_html;
break;
@@ -212,8 +218,11 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
memset(buffer, 0, buffer_size);
bool escaped = false;
bool newline = true;
-
+ bool list_waiting = true;
+
int hash_chain = 0;
+ int dash_chain = 0;
+ int eq_chain = 0;
int spaces_trimmed = 0;
int root_on_newline = false;
@@ -234,6 +243,15 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
continue;
}
+ #define LAST_TO_TITLE(n) {\
+ struct tree_element* last_element = root->children[root->children_n-1];\
+ last_element->type = t_h;\
+ if(last_element->value)\
+ free(last_element->value);\
+ last_element->value = malloc(sizeof(int));\
+ *(int*)last_element->value = n;\
+ }
+
switch(*cur_char) {
// Character escaping
case('\\'):
@@ -248,61 +266,41 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
// Ignoring \r goes against the commonmark spec, but who cares
break;
case('\n'):
+ if(dash_chain >= 1) {
+ active_element = root;
+ // Make the last element a title unless
+ if(dash_chain >= 3 && active_element == root && !newline) {
+ struct tree_element* hr = new_child(root, -1);
+ hr->type = t_hr;
+ hr->allow_inner = false;
+ } else {
+ LAST_TO_TITLE(2);
+ }
+ }
+ if(eq_chain >= 1 && newline) {
+ LAST_TO_TITLE(1);
+ }
+
+ eq_chain = 0;
+ dash_chain = 0;
+
if(hash_chain > 0)
active_element = root;
if(newline) {
// A double new line means we return the active element to root
active_element = root;
newline = false;
- } else {
+ } else if(active_element != root) {
newline = true;
}
hash_chain = 0;
spaces_trimmed = 0;
break;
- // Text strength
case('*'):
- void new_ul(struct tree_element* parent) {
- active_element = new_child(parent, -1);
- active_element->type = t_ul;
- active_element->allow_inner = false;
- active_element->value = malloc(sizeof(int));
- printf("SPACES TRIMMED: %d\n", spaces_trimmed);
- *(int*)active_element->value = spaces_trimmed;
- }
if(active_element == root || newline) {
- newline = false;
- // Look if we have an ancestor somewhere that has spaces fewer or equal to the spaces we skipped.
- // 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;
- bool found_ul = false;
- while(look_element && look_element != root){
- if(look_element->type == t_ul) {
- if(*(int*)look_element->value < spaces_trimmed) {
- new_ul(look_element);
- found_ul = true;
- break;
- }
- if(*(int*)look_element->value == spaces_trimmed) {
- active_element = look_element;
- found_ul = true;
- break;
- }
- }
- look_element = look_element->parent;
- }
- // Enter a new list
- if(!found_ul) {
- new_ul(root);
- }
-
- active_element = new_child(active_element, -1);
- active_element->type = t_li;
- active_element->allow_inner = true;
- root_on_newline = true;
+ list_waiting = true;
} else {
+ // Text strength
}
break;
case('_'):
@@ -314,15 +312,15 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
break;
// Titles
case('='):
- if(newline) {
+ if(active_element == root || newline) {
// Make the last line a title, otherwise we fall through
+ eq_chain++;
break;
}
- break;
case('-'):
- if(newline) {
- // Make the last line a title, otherwise we fall through
- break;
+ if(active_element == root || newline) {
+ list_waiting = true;
+ dash_chain++;
}
break;
case('#'):
@@ -354,6 +352,50 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
root_on_newline = true;
break;
}
+ // Here lists are created
+ if(list_waiting) {
+ // This adds a new unordered list
+ void new_ul(struct tree_element* parent) {
+ active_element = new_child(parent, -1);
+ active_element->type = t_ul;
+ active_element->allow_inner = false;
+ active_element->value = malloc(sizeof(int));
+ *(int*)active_element->value = spaces_trimmed;
+ }
+
+ newline = false;
+ /* Look if we have an ancestor somewhere that has spaces fewer or equal to the spaces we skipped.
+ * 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;
+ bool found_ul = false;
+ while(look_element && look_element != root){
+ if(look_element->type == t_ul) {
+ if(*(int*)look_element->value < spaces_trimmed) {
+ new_ul(look_element);
+ found_ul = true;
+ break;
+ }
+ if(*(int*)look_element->value == spaces_trimmed) {
+ active_element = look_element;
+ found_ul = true;
+ break;
+ }
+ }
+ look_element = look_element->parent;
+ }
+ // Enter a new list
+ if(!found_ul) {
+ new_ul(root);
+ }
+
+ active_element = new_child(active_element, -1);
+ active_element->type = t_li;
+ active_element->allow_inner = true;
+ root_on_newline = true;
+ list_waiting = false;
+ }
// Trim spaces from newline
if(active_element == root || newline) {
//@todo with this we should relatively easily be able to check for code blocks!
@@ -371,9 +413,12 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
active_element = root;
root_on_newline = false;
}
+ dash_chain = 0;
+ eq_chain = 0;
newline = false;
+ list_waiting = false;
append_char_to_active(root, &active_element, *cur_char);
- break;
+ break;
}
}
// Convert the tree to valid html
Jeremias Stotters git repositories generated by CGIT