removed duplicated expression
[smdp.git] / src / viewer.c
index 4aec11e..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"
 
@@ -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;
@@ -418,35 +419,60 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo
         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)? " |  " : "    ");
-        strcpy(&prompt[8], line->next && CHECK_BIT(line->next->bits, IS_UNORDERED_LIST_3)? " +- " : " `- ");
+
+        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[9];
         strcpy(&prompt[0], CHECK_BIT(line->bits, IS_UNORDERED_LIST_1)? " |  " : "    ");
-        strcpy(&prompt[4], line->next && CHECK_BIT(line->next->bits, IS_UNORDERED_LIST_2)? " +- " : " `- ");
+
+        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[5];
-        strcpy(&prompt[0], line->next && CHECK_BIT(line->next->bits, IS_UNORDERED_LIST_1)? " +- " : " `- ");
+
+        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,62 +484,68 @@ 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_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", ">");
-            }
-
-            // find next quote or break
-            offset++;
-            if(line->text->text[offset] == ' ')
-                offset = next_word(line->text, offset);
-        }
+    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)) {
+            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", ">");
+                }
 
-        inline_display(window, &line->text->text[offset], colors);
+                // find next quote or break
+                offset++;
+                if(line->text->text[offset] == ' ')
+                    offset = next_word(line->text, offset);
+            }
 
-    } else {
+            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_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)) {
+            // 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));
+                // 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);
+                // 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);
+                // skip hashes
+                while(line->text->text[offset] == '#')
+                    offset = next_word(line->text, offset);
 
-            // print whole lines
-            wprintw(window,
-                    "%s", &line->text->text[offset]);
+                // print whole lines
+                wprintw(window,
+                        "%s", &line->text->text[offset]);
 
-            wattroff(window, A_UNDERLINE);
+                wattroff(window, A_UNDERLINE);
 
-        // no line-wide markdown
-        } else {
+            // no line-wide markdown
+            } else {
 
-            inline_display(window, &line->text->text[offset], colors);
+                inline_display(window, &line->text->text[offset], colors);
+            }
         }
     }
 
@@ -529,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 '*':
@@ -566,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 {
@@ -601,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);
         }
     }