aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremias Stotter <jeremias@stotter.eu>2022-02-27 21:44:03 +0100
committerJeremias Stotter <jeremias@stotter.eu>2022-02-27 21:44:03 +0100
commitd7202016af72f39aed66cd7591a8227e24c21f51 (patch)
treec66599ed670a171936aa0b3ffe3ce41af2d5f6ee
parent3cbe1cd90ba3419c2d6e11b79754fa1d775d8f77 (diff)
downloadJBlog-d7202016af72f39aed66cd7591a8227e24c21f51.tar.gz
JBlog-d7202016af72f39aed66cd7591a8227e24c21f51.tar.bz2
JBlog-d7202016af72f39aed66cd7591a8227e24c21f51.zip
Added inline code
-rw-r--r--md.c137
1 files changed, 89 insertions, 48 deletions
diff --git a/md.c b/md.c
index 8555a34..5302718 100644
--- a/md.c
+++ b/md.c
@@ -50,7 +50,8 @@ enum html_type {
t_ul, // Value contains the ammount of spaces used to indent at that level
t_li,
t_hr,
- t_code
+ t_code,
+ t_inline_code
};
// The file will be structured as a tree that, in the end will be converted to valid html
@@ -157,7 +158,8 @@ char* realloc_append(char* dest, char* src) {
#define ul_html "<ul>%s</ul>\n"
#define li_html "<li>%s</li>\n"
#define hr_html "<hr/>\n"
-#define code_html "<pre><code><p>%s</p></code></pre>\n"
+#define code_html "<pre><code>%s</code></pre>\n"
+#define inline_code_html "<code>%s</code>\n"
// Resolve a tree to html
int depth = 0;
char* tree_to_html(struct tree_element* root) {
@@ -243,6 +245,16 @@ char* tree_to_html(struct tree_element* root) {
html = realloc_for_html(code_html);
sprintf(html, code_html, inner_html ? inner_html : "");
break;
+ case(t_inline_code):
+ if(*(bool*)(root->value)) {
+ html = realloc_for_html(inline_code_html);
+ sprintf(html, inline_code_html, inner_html ? inner_html : "");
+ } else {
+ html = realloc(html, strlen(inner_html) + 1);
+ memcpy(html, "`", 2);
+ strcat(html, inner_html);
+ }
+ break;
default:
html=inner_html;
break;
@@ -260,9 +272,11 @@ char* tree_to_html(struct tree_element* root) {
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;
- NEXT_ALLOW_INNER((*active_element), root)
- if(*active_element == root) {
- NEW_ACTIVE_CHILD(new_active_element, root, -1, t_p, true);
+ if(active_element) {
+ NEXT_ALLOW_INNER((*active_element), root)
+ if(*active_element == root) {
+ NEW_ACTIVE_CHILD(new_active_element, root, -1, t_p, true);
+ }
}
if(new_active_element->type != t_inner) {
NEW_ACTIVE_CHILD(new_active_element, new_active_element, -1, t_inner, false);
@@ -412,11 +426,13 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
int root_on_newline = false;
int soft_newline_count = 0;
+ bool inline_code_wait = false;
+
// @todo: These two variables should be globals! Why did I even define them here at all?
struct tree_element* root = new_element();
root->allow_inner = false;
struct tree_element* active_element = root;
- for(char* cur_char = input; *cur_char != '\0'; cur_char++) {
+ for(register char* cur_char = input; *cur_char != '\0'; cur_char++) {
printf("%c", *cur_char);
if(escaped || (code_element && *cur_char != '\n' && *cur_char != '\r' && !newline)) {
escaped = false;
@@ -449,6 +465,51 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
}\
}
+ // Checks that should be done if a non special character is hit, might also be necessary to check sometimes not in default
+ #define DEFAULT_CHECKS {\
+ for(int i = 0; i < soft_newline_count; i++) \
+ append_char_to_active(root, &active_element, ' '); \
+ soft_newline_count = 0; \
+ if(spaces_trimmed >= 4 && (newline || active_element == root)) { \
+ /* if code_element is set the new active element is just returned to the code element*/ \
+ if(code_element) { \
+ active_element = code_element;\
+ /* append_char_to_active(root, &active_element, '\n'); */\
+ } else {\
+ NEW_ACTIVE_CHILD(active_element, root, -1, t_code, true);\
+ code_element = active_element;\
+ }\
+ for(int i = 0; i < spaces_trimmed - 4; i++)\
+ append_char_to_active(root, &active_element, ' ');\
+ } else if(code_element) {\
+ active_element = root;\
+ code_element = false;\
+ }\
+ if(hash_chain > 0) {\
+ for(int i = 0; i < hash_chain; i++)\
+ append_char_to_active(root, &active_element, '#');\
+ hash_chain = 0;\
+ }\
+ if(dash_chain > 0) {\
+ for(int i = 0; i < dash_chain; i++)\
+ append_char_to_active(root, &active_element, '-');\
+ dash_chain = 0;\
+ }\
+ if(eq_chain > 0) {\
+ for(int i = 0; i < eq_chain; i++)\
+ append_char_to_active(root, &active_element, '=');\
+ eq_chain = 0;\
+ }\
+ \
+ if(newline) {\
+ if(root_on_newline) {\
+ active_element = root;\
+ root_on_newline = false;\
+ } else if(!code_element)\
+ /* Check if we have a soft linebreak (two spaces before newline) */\
+ append_char_to_active(root, &active_element, ' ');\
+ }\
+ }
switch(*cur_char) {
// Character escaping
case('\\'):
@@ -523,6 +584,7 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
if(code_element)
append_char_to_active(root, &active_element, '\n');
+ inline_code_wait = false;
hash_chain = 0;
spaces_trimmed = 0;
soft_newline_count = 0;
@@ -537,7 +599,27 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
case('_'):
str_chr_hit(root, &active_element, &str_cl_wait_und, &str_fin_wait_und, &temp_str_und, &str_chr_wait_und, t_str_und);
break;
+ // No 3 backticks are supported, use 4 spaces at the begining of a line to get a <pre><code> block
case('`'):
+ DEFAULT_CHECKS;
+ if(inline_code_wait) {
+ struct tree_element* parent_code = find_parent_type(root, active_element, t_inline_code);
+ if(!parent_code)
+ goto default2;
+ *(bool*)(parent_code->value) = true;
+ active_element = parent_code->parent;
+ inline_code_wait= false;
+ }
+ else {
+ NEXT_ALLOW_INNER(active_element, root);
+ if(active_element == root) {
+ NEW_ACTIVE_CHILD(active_element, root, -1, t_p, true);
+ }
+ NEW_ACTIVE_CHILD(active_element, active_element, -1, t_inline_code, true);
+ active_element->value = malloc(sizeof(bool));
+ *(bool*)(active_element->value) = false;
+ inline_code_wait = true;
+ }
break;
case('~'):
break;
@@ -670,48 +752,7 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
// Default character handling
default2:
default:
- for(int i = 0; i < soft_newline_count; i++)
- append_char_to_active(root, &active_element, ' ');
- soft_newline_count = 0;
- if(spaces_trimmed >= 4 && (newline || active_element == root)) {
- // if code_element is set the new active element is just returned to the code element
- if(code_element) {
- active_element = code_element;
- //append_char_to_active(root, &active_element, '\n');
- } else {
- NEW_ACTIVE_CHILD(active_element, root, -1, t_code, true);
- code_element = active_element;
- }
- for(int i = 0; i < spaces_trimmed - 4; i++)
- append_char_to_active(root, &active_element, ' ');
- } else if(code_element) {
- active_element = root;
- code_element = false;
- }
- if(hash_chain > 0) {
- for(int i = 0; i < hash_chain; i++)
- append_char_to_active(root, &active_element, '#');
- hash_chain = 0;
- }
- if(dash_chain > 0) {
- for(int i = 0; i < dash_chain; i++)
- append_char_to_active(root, &active_element, '-');
- dash_chain = 0;
- }
- if(eq_chain > 0) {
- for(int i = 0; i < eq_chain; i++)
- append_char_to_active(root, &active_element, '=');
- eq_chain = 0;
- }
-
- if(newline) {
- if(root_on_newline) {
- active_element = root;
- root_on_newline = false;
- } else if(!code_element)
- // Check if we have a soft linebreak (two spaces before newline)
- append_char_to_active(root, &active_element, ' ');
- }
+ DEFAULT_CHECKS;
newline = false;
list_waiting = false;
append_char_to_active(root, &active_element, *cur_char);
Jeremias Stotters git repositories generated by CGIT