removed duplicated expression
[smdp.git] / src / viewer.c
index 3e4284b..b9dcbf7 100644 (file)
  *
  */
 
+#include <ctype.h>  // isalnum
 #include <locale.h> // setlocale
-#include <stdlib.h>
 #include <string.h> // strchr
-#include <unistd.h>
+#include <unistd.h> // usleep
 
 #include "viewer.h"
 
@@ -146,7 +146,7 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert) {
         endwin();
 
         // print error
-        fprintf(stderr, "Error: Terminal heigth (%i lines) too small. Need at least %i lines.\n", LINES, max_lines + bar_top + bar_bottom);
+        fprintf(stderr, "Error: Terminal height (%i lines) too small. Need at least %i lines.\n", LINES, max_lines + bar_top + bar_bottom);
         fprintf(stderr, "You may need to add additional horizontal rules ('***') to split your file in shorter slides.\n");
 
         return 1;
@@ -266,6 +266,7 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert) {
                   "%d / %d", sc, deck->slides);
 
         // make header + fooder visible
+        wrefresh(content);
         wrefresh(stdscr);
 
         line = slide->line;
@@ -415,38 +416,63 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo
     // IS_UNORDERED_LIST_3
     if(CHECK_BIT(line->bits, IS_UNORDERED_LIST_3)) {
         offset = next_nonblank(line->text, 0);
-        char prompt[10];
-        strcpy(&prompt[0], CHECK_BIT(line->bits, IS_UNORDERED_LIST_1)? "|  " : "   ");
-        strcpy(&prompt[3], CHECK_BIT(line->bits, IS_UNORDERED_LIST_2)? "|  " : "   ");
-        strcpy(&prompt[6], line->next && CHECK_BIT(line->next->bits, IS_UNORDERED_LIST_3)? "+- " : "`- ");
+        char prompt[13];
+        strcpy(&prompt[0], CHECK_BIT(line->bits, IS_UNORDERED_LIST_1)? " |  " : "    ");
+        strcpy(&prompt[4], CHECK_BIT(line->bits, IS_UNORDERED_LIST_2)? " |  " : "    ");
+
+        if(CHECK_BIT(line->bits, IS_UNORDERED_LIST_EXT)) {
+            strcpy(&prompt[8], line->next && CHECK_BIT(line->next->bits, IS_UNORDERED_LIST_3)? " |  " : "    ");
+        } else {
+            strcpy(&prompt[8], " +- ");
+            offset += 2;
+        }
+
         wprintw(window,
                 "%s", prompt);
 
-        inline_display(window, &line->text->text[offset + 2], colors);
+        if(!CHECK_BIT(line->bits, IS_CODE))
+            inline_display(window, &line->text->text[offset], colors);
 
     // IS_UNORDERED_LIST_2
     } else if(CHECK_BIT(line->bits, IS_UNORDERED_LIST_2)) {
         offset = next_nonblank(line->text, 0);
-        char prompt[7];
-        strcpy(&prompt[0], CHECK_BIT(line->bits, IS_UNORDERED_LIST_1)? "|  " : "   ");
-        strcpy(&prompt[3], line->next && CHECK_BIT(line->next->bits, IS_UNORDERED_LIST_2)? "+- " : "`- ");
+        char prompt[9];
+        strcpy(&prompt[0], CHECK_BIT(line->bits, IS_UNORDERED_LIST_1)? " |  " : "    ");
+
+        if(CHECK_BIT(line->bits, IS_UNORDERED_LIST_EXT)) {
+            strcpy(&prompt[4], line->next && CHECK_BIT(line->next->bits, IS_UNORDERED_LIST_2)? " |  " : "    ");
+        } else {
+            strcpy(&prompt[4], " +- ");
+            offset += 2;
+        }
+
         wprintw(window,
                 "%s", prompt);
 
-        inline_display(window, &line->text->text[offset + 2], colors);
+        if(!CHECK_BIT(line->bits, IS_CODE))
+            inline_display(window, &line->text->text[offset], colors);
 
     // IS_UNORDERED_LIST_1
     } else if(CHECK_BIT(line->bits, IS_UNORDERED_LIST_1)) {
         offset = next_nonblank(line->text, 0);
-        char prompt[4];
-        strcpy(&prompt[0], line->next && CHECK_BIT(line->next->bits, IS_UNORDERED_LIST_1)? "+- " : "`- ");
+        char prompt[5];
+
+        if(CHECK_BIT(line->bits, IS_UNORDERED_LIST_EXT)) {
+            strcpy(&prompt[0], line->next && CHECK_BIT(line->next->bits, IS_UNORDERED_LIST_1)? " |  " : "    ");
+        } else {
+            strcpy(&prompt[0], " +- ");
+            offset += 2;
+        }
+
         wprintw(window,
                 "%s", prompt);
 
-        inline_display(window, &line->text->text[offset + 2], colors);
+        if(!CHECK_BIT(line->bits, IS_CODE))
+            inline_display(window, &line->text->text[offset], colors);
+    }
 
     // IS_CODE
-    } else if(CHECK_BIT(line->bits, IS_CODE)) {
+    if(CHECK_BIT(line->bits, IS_CODE)) {
 
         // set static offset for code
         offset = CODE_INDENT;
@@ -458,29 +484,12 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo
         // print whole lines
         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)) {
-
-        // set headline color
-        if(colors)
-            wattron(window, COLOR_PAIR(CP_BLUE));
-
-        // enable underline for H1
-        if(CHECK_BIT(line->bits, IS_H1))
-            wattron(window, A_UNDERLINE);
-
-        // skip hashes
-        while(line->text->text[offset] == '#')
-            offset = next_word(line->text, offset);
-
-        // print whole lines
-        wprintw(window,
-                "%s", &line->text->text[offset]);
-
-        wattroff(window, A_UNDERLINE);
-
-    } else {
+    if(!CHECK_BIT(line->bits, IS_UNORDERED_LIST_1) &&
+       !CHECK_BIT(line->bits, IS_UNORDERED_LIST_2) &&
+       !CHECK_BIT(line->bits, IS_UNORDERED_LIST_3) &&
+       !CHECK_BIT(line->bits, IS_CODE)) {
 
         // IS_QUOTE
         if(CHECK_BIT(line->bits, IS_QUOTE)) {
@@ -500,9 +509,44 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo
                 if(line->text->text[offset] == ' ')
                     offset = next_word(line->text, offset);
             }
-        }
 
-        inline_display(window, &line->text->text[offset], colors);
+            inline_display(window, &line->text->text[offset], colors);
+        } else {
+
+            // IS_CENTER
+            if(CHECK_BIT(line->bits, IS_CENTER)) {
+                if(line->length < max_cols) {
+                    wmove(window, y, x + ((max_cols - line->length) / 2));
+                }
+            }
+
+            // IS_H1 || IS_H2
+            if(CHECK_BIT(line->bits, IS_H1) || CHECK_BIT(line->bits, IS_H2)) {
+
+                // set headline color
+                if(colors)
+                    wattron(window, COLOR_PAIR(CP_BLUE));
+
+                // enable underline for H1
+                if(CHECK_BIT(line->bits, IS_H1))
+                    wattron(window, A_UNDERLINE);
+
+                // skip hashes
+                while(line->text->text[offset] == '#')
+                    offset = next_word(line->text, offset);
+
+                // 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
@@ -517,21 +561,25 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo
 
 void inline_display(WINDOW *window, const char *c, const int colors) {
     const static char *special = "\\*_`"; // list of interpreted chars
+    const char *i = c; // iterator
     cstack_t *stack = cstack_init();
 
+
     // for each char in line
-    for(; *c; c++) {
+    for(; *i; i++) {
 
         // if char is in special char list
-        if(strchr(special, *c)) {
+        if(strchr(special, *i)) {
 
             // closing special char (or second backslash)
-            if((stack->top)(stack, *c)) {
+            // only if not followed by :alnum:
+            if((stack->top)(stack, *i) &&
+               (!isalnum((int)i[1]) || *(i + 1) == '\0' || *i == '\\')) {
 
-                switch(*c) {
+                switch(*i) {
                     // print escaped backslash
                     case '\\':
-                        wprintw(window, "%c", *c);
+                        wprintw(window, "%c", *i);
                         break;
                     // disable highlight
                     case '*':
@@ -554,33 +602,46 @@ void inline_display(WINDOW *window, const char *c, const int colors) {
 
             // treat special as regular char
             } else if((stack->top)(stack, '\\')) {
-                wprintw(window, "%c", *c);
+                wprintw(window, "%c", *i);
 
                 // remove backslash from stack
                 (stack->pop)(stack);
 
             // opening special char
             } else {
-                switch(*c) {
-                    // enable highlight
-                    case '*':
-                        if(colors)
-                            wattron(window, COLOR_PAIR(CP_RED));
-                        break;
-                    // enable underline
-                    case '_':
-                        wattron(window, A_UNDERLINE);
-                        break;
-                    // enable inline code
-                    case '`':
-                        if(colors)
-                            wattron(window, COLOR_PAIR(CP_BLACK));
-                        break;
-                    // do nothing for backslashes
-                }
 
-                // push special char to stack
-                (stack->push)(stack, *c);
+                // emphasis or code span can start after new-line or space only
+                // and of cause after another emphasis markup
+                //TODO this condition looks ugly
+                if(i == c ||
+                   *(i - 1) == ' ' ||
+                   ((*(i - 1) == '_' || *(i - 1) == '*') && ((i - 1) == c || *(i - 2) == ' ')) ||
+                   *i == '\\') {
+
+                    switch(*i) {
+                        // enable highlight
+                        case '*':
+                            if(colors)
+                                wattron(window, COLOR_PAIR(CP_RED));
+                            break;
+                        // enable underline
+                        case '_':
+                            wattron(window, A_UNDERLINE);
+                            break;
+                        // enable inline code
+                        case '`':
+                            if(colors)
+                                wattron(window, COLOR_PAIR(CP_BLACK));
+                            break;
+                        // do nothing for backslashes
+                    }
+
+                    // push special char to stack
+                    (stack->push)(stack, *i);
+
+                } else {
+                    wprintw(window, "%c", *i);
+                }
             }
 
         } else {
@@ -589,7 +650,7 @@ void inline_display(WINDOW *window, const char *c, const int colors) {
                 (stack->pop)(stack);
 
             // print regular char
-            wprintw(window, "%c", *c);
+            wprintw(window, "%c", *i);
         }
     }