added special char for horizontal centering (#3)
authorMichael Göhler <somebody.here@gmx.de>
Mon, 6 Oct 2014 23:03:06 +0000 (01:03 +0200)
committerMichael Göhler <somebody.here@gmx.de>
Sun, 12 Oct 2014 15:36:44 +0000 (17:36 +0200)
include/cstring.h
include/markdown.h
src/cstring.c
src/parser.c
src/viewer.c

index 631c7e3..d0a7c1c 100644 (file)
@@ -26,6 +26,7 @@
  * function: cstring_init to intialize struct of type cstring_t
  * function: cstring_t->expand to add one character to the struct
  * function: cstring_t->expand_arr to add a string to the struct
+ * function: cstring_t->strip to remove a substring
  * function: cstring_t->reset to clear and reuse the struct
  * function: cstring_t->delete to free the allocated memory
  *
@@ -46,6 +47,7 @@ typedef struct _cstring_t {
     size_t alloc;
     void (*expand)(struct _cstring_t *self, char x);
     void (*expand_arr)(struct _cstring_t *self, char *x);
+    void (*strip)(struct _cstring_t *self, int pos, int len);
     void (*reset)(struct _cstring_t *self);
     void (*delete)(struct _cstring_t *self);
 } cstring_t;
@@ -53,6 +55,7 @@ typedef struct _cstring_t {
 cstring_t *cstring_init();
 void cstring_expand(cstring_t *self, char x);
 void cstring_expand_arr(cstring_t *self, char *x);
+void cstring_strip(cstring_t *self, int pos, int len);
 void cstring_reset(cstring_t *self);
 void cstring_delete(cstring_t *self);
 
index a1dd759..46a1f38 100644 (file)
@@ -47,6 +47,7 @@ enum line_bitmask {
     IS_UNORDERED_LIST_1,
     IS_UNORDERED_LIST_2,
     IS_UNORDERED_LIST_3,
+    IS_CENTER,
     IS_EMPTY
 };
 
index d004217..d321260 100644 (file)
@@ -19,7 +19,7 @@
  *
  */
 
-#include <string.h> // strlen
+#include <string.h> // strlen, memmove
 #include <stdio.h> // fprintf
 #include <stdlib.h> // malloc, realloc
 
@@ -32,6 +32,7 @@ cstring_t *cstring_init() {
         x->size = x->alloc = 0;
         x->expand = cstring_expand;
         x->expand_arr = cstring_expand_arr;
+        x->strip = cstring_strip;
         x->reset = cstring_reset;
         x->delete = cstring_delete;
     } else {
@@ -67,6 +68,18 @@ void cstring_expand_arr(cstring_t *self, char *x) {
     self->text[self->size+1] = '\0';
 }
 
+void cstring_strip(cstring_t *self, int pos, int len) {
+    if(pos + len >= self->size) {
+        if(pos <= self->size) {
+            self->text[pos] = '\0';
+            self->size = pos;
+        }
+        return;
+    }
+    memmove(&self->text[pos], &self->text[pos+len], self->size - pos);
+    self->size -= len;
+}
+
 void cstring_reset(cstring_t *self) {
     free(self->text);
     self->text = NULL;
index ce3f702..815b9a2 100644 (file)
@@ -225,6 +225,7 @@ deck_t *markdown_load(FILE *input) {
                 // delete line
                 (tmp->text->delete)(tmp->text);
                 free(tmp);
+
             } else if(CHECK_BIT(line->bits, IS_UNORDERED_LIST_3)) {
                 tmp = line->next;
                 line_t *list_last_level_3 = line;
@@ -240,6 +241,7 @@ deck_t *markdown_load(FILE *input) {
                 for(tmp = line; tmp != list_last_level_3; tmp = tmp->next) {
                     SET_BIT(tmp->bits, IS_UNORDERED_LIST_3);
                 }
+
             } else if(CHECK_BIT(line->bits, IS_UNORDERED_LIST_2)) {
                 tmp = line->next;
                 line_t *list_last_level_2 = line;
@@ -256,6 +258,7 @@ deck_t *markdown_load(FILE *input) {
                 for(tmp = line; tmp != list_last_level_2; tmp = tmp->next) {
                     SET_BIT(tmp->bits, IS_UNORDERED_LIST_2);
                 }
+
             } else if(CHECK_BIT(line->bits, IS_UNORDERED_LIST_1)) {
                 tmp = line->next;
                 line_t *list_last_level_1 = line;
@@ -299,6 +302,12 @@ int markdown_analyse(cstring_t *text) {
 
     const int unordered_list_offset = unordered_list_level_offset[unordered_list_level];
 
+    // return IS_EMPTY on null pointers
+    if(!text || !text->text) {
+        SET_BIT(bits, IS_EMPTY);
+        return bits;
+    }
+
     // count leading spaces
     offset = next_nonblank(text, 0);
 
@@ -358,6 +367,36 @@ int markdown_analyse(cstring_t *text) {
 
         } else {
 
+            // IS_QUOTE
+            if(text->text[offset] == '>') {
+                SET_BIT(bits, IS_QUOTE);
+            }
+
+            // IS_CENTER
+            if(text->size >= offset + 3 &&
+               text->text[offset] == '-' &&
+               text->text[offset + 1] == '>' &&
+               text->text[offset + 2] == ' ') {
+                SET_BIT(bits, IS_CENTER);
+
+                // remove start tag
+                (text->strip)(text, offset, 3);
+                eol -= 3;
+
+                if(text->size >= offset + 3 &&
+                   text->text[eol - 1] == '-' &&
+                   text->text[eol - 2] == '<' &&
+                   text->text[eol - 3] == ' ') {
+
+                    // remove end tags
+                    (text->strip)(text, eol - 3, 3);
+
+                    // adjust end of line
+                    for(eol = text->size; eol > offset && isspace((unsigned char) text->text[eol - 1]); eol--);
+
+                }
+            }
+
             for(i = offset; i < eol; i++) {
 
                 if(text->text[i] == ' ') {
@@ -378,9 +417,7 @@ int markdown_analyse(cstring_t *text) {
             // IS_H1
             if((equals > 0 &&
                 hashes + stars + minus + spaces + other == 0) ||
-               (text &&
-                text->text &&
-                text->text[offset] == '#' &&
+               (text->text[offset] == '#' &&
                 text->text[offset+1] != '#')) {
 
                 SET_BIT(bits, IS_H1);
@@ -389,22 +426,12 @@ int markdown_analyse(cstring_t *text) {
             // IS_H2
             if((minus > 0 &&
                 equals + hashes + stars + spaces + other == 0) ||
-               (text &&
-                text->text &&
-                text->text[offset] == '#' &&
+               (text->text[offset] == '#' &&
                 text->text[offset+1] == '#')) {
 
                 SET_BIT(bits, IS_H2);
             }
 
-            // IS_QUOTE
-            if(text &&
-               text->text &&
-               text->text[offset] == '>') {
-
-                SET_BIT(bits, IS_QUOTE);
-            }
-
             // IS_HR
             if((minus >= 3 && equals + hashes + stars + other == 0) ||
                (stars >= 3 && equals + hashes + minus + other == 0)) {
index 2de71e4..4aec11e 100644 (file)
@@ -459,50 +459,62 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo
         wprintw(window,
                 "%s", &line->text->text[offset]);
 
-    // IS_H1 || IS_H2
-    } else if(CHECK_BIT(line->bits, IS_H1) || CHECK_BIT(line->bits, IS_H2)) {
+    // IS_QUOTE
+    } else if(CHECK_BIT(line->bits, IS_QUOTE)) {
+        while(line->text->text[offset] == '>') {
+            // print a reverse color block
+            if(colors) {
+                wattron(window, COLOR_PAIR(CP_BLACK));
+                wprintw(window, "%s", " ");
+                wattron(window, COLOR_PAIR(CP_WHITE));
+                wprintw(window, "%s", " ");
+            } else {
+                wprintw(window, "%s", ">");
+            }
 
-        // set headline color
-        if(colors)
-            wattron(window, COLOR_PAIR(CP_BLUE));
+            // find next quote or break
+            offset++;
+            if(line->text->text[offset] == ' ')
+                offset = next_word(line->text, offset);
+        }
 
-        // enable underline for H1
-        if(CHECK_BIT(line->bits, IS_H1))
-            wattron(window, A_UNDERLINE);
+        inline_display(window, &line->text->text[offset], colors);
 
-        // skip hashes
-        while(line->text->text[offset] == '#')
-            offset = next_word(line->text, offset);
+    } else {
 
-        // print whole lines
-        wprintw(window,
-                "%s", &line->text->text[offset]);
+        // IS_CENTER
+        if(CHECK_BIT(line->bits, IS_CENTER)) {
+            if(line->length < max_cols) {
+                wmove(window, y, x + ((max_cols - line->length) / 2));
+            }
+        }
 
-        wattroff(window, A_UNDERLINE);
+        // IS_H1 || IS_H2
+        if(CHECK_BIT(line->bits, IS_H1) || CHECK_BIT(line->bits, IS_H2)) {
 
-    } else {
+            // set headline color
+            if(colors)
+                wattron(window, COLOR_PAIR(CP_BLUE));
 
-        // IS_QUOTE
-        if(CHECK_BIT(line->bits, IS_QUOTE)) {
-            while(line->text->text[offset] == '>') {
-                // print a reverse color block
-                if(colors) {
-                    wattron(window, COLOR_PAIR(CP_BLACK));
-                    wprintw(window, "%s", " ");
-                    wattron(window, COLOR_PAIR(CP_WHITE));
-                    wprintw(window, "%s", " ");
-                } else {
-                    wprintw(window, "%s", ">");
-                }
+            // enable underline for H1
+            if(CHECK_BIT(line->bits, IS_H1))
+                wattron(window, A_UNDERLINE);
 
-                // find next quote or break
-                offset++;
-                if(line->text->text[offset] == ' ')
-                    offset = next_word(line->text, offset);
-            }
-        }
+            // skip hashes
+            while(line->text->text[offset] == '#')
+                offset = next_word(line->text, offset);
 
-        inline_display(window, &line->text->text[offset], colors);
+            // print whole lines
+            wprintw(window,
+                    "%s", &line->text->text[offset]);
+
+            wattroff(window, A_UNDERLINE);
+
+        // no line-wide markdown
+        } else {
+
+            inline_display(window, &line->text->text[offset], colors);
+        }
     }
 
     // fill rest off line with spaces