From: Michael Göhler Date: Sat, 31 Jan 2015 23:28:38 +0000 (+0100) Subject: replace pseudo UTF-8 with real wide character support X-Git-Url: https://git.danieliu.xyz/?a=commitdiff_plain;h=4b8ad1b3b464836eca2e876dd418a8e8d87bd721;p=smdp.git replace pseudo UTF-8 with real wide character support --- diff --git a/include/cstack.h b/include/cstack.h index fd6c60d..230fcdd 100644 --- a/include/cstack.h +++ b/include/cstack.h @@ -41,21 +41,21 @@ #include "common.h" typedef struct _cstack_t { - char *content; + wchar_t *content; size_t alloc; size_t size; int head; - void (*push)(struct _cstack_t *self, char c); - char (*pop)(struct _cstack_t *self); - bool (*top)(struct _cstack_t *self, char c); + void (*push)(struct _cstack_t *self, wchar_t c); + wchar_t (*pop)(struct _cstack_t *self); + bool (*top)(struct _cstack_t *self, wchar_t c); bool (*empty)(struct _cstack_t *self); void (*delete)(struct _cstack_t *self); } cstack_t; cstack_t *cstack_init(); -void cstack_push(cstack_t *self, char c); -char cstack_pop(cstack_t *self); -bool cstack_top(cstack_t *self, char c); +void cstack_push(cstack_t *self, wchar_t c); +wchar_t cstack_pop(cstack_t *self); +bool cstack_top(cstack_t *self, wchar_t c); bool cstack_empty(cstack_t *self); void cstack_delete(cstack_t *self); diff --git a/include/cstring.h b/include/cstring.h index d0a7c1c..d74cd80 100644 --- a/include/cstring.h +++ b/include/cstring.h @@ -42,19 +42,19 @@ #define REALLOC_ADD 10 typedef struct _cstring_t { - char *text; + wchar_t *text; size_t size; size_t alloc; - void (*expand)(struct _cstring_t *self, char x); - void (*expand_arr)(struct _cstring_t *self, char *x); + void (*expand)(struct _cstring_t *self, wchar_t x); + void (*expand_arr)(struct _cstring_t *self, wchar_t *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; cstring_t *cstring_init(); -void cstring_expand(cstring_t *self, char x); -void cstring_expand_arr(cstring_t *self, char *x); +void cstring_expand(cstring_t *self, wchar_t x); +void cstring_expand_arr(cstring_t *self, wchar_t *x); void cstring_strip(cstring_t *self, int pos, int len); void cstring_reset(cstring_t *self); void cstring_delete(cstring_t *self); diff --git a/include/parser.h b/include/parser.h index 477342d..23cd12f 100644 --- a/include/parser.h +++ b/include/parser.h @@ -48,8 +48,6 @@ deck_t *markdown_load(FILE *input); int markdown_analyse(cstring_t *text, int prev); void markdown_debug(deck_t *deck, int debug); void adjust_line_length(line_t *line); -bool is_utf8(char ch); -int length_utf8(char ch); int next_nonblank(cstring_t *text, int i); int prev_blank(cstring_t *text, int i); int next_blank(cstring_t *text, int i); diff --git a/include/url.h b/include/url.h index 1bd3950..e48e194 100644 --- a/include/url.h +++ b/include/url.h @@ -24,21 +24,21 @@ */ typedef struct _url_t { - char *link_name; - char *target; + wchar_t *link_name; + wchar_t *target; int x; int y; struct _url_t *next; } url_t; void url_init(void); -int url_add(const char *link_name, int link_name_length, const char *target, int target_length, int x, int y); -char * url_get_target(int index); -char * url_get_name(int index); +int url_add(const wchar_t *link_name, int link_name_length, const wchar_t *target, int target_length, int x, int y); +wchar_t* url_get_target(int index); +wchar_t* url_get_name(int index); int url_get_amount(void); void url_purge(void); void url_dump(void); -int url_count_inline(const char *line); -int url_len_inline(const char *text); +int url_count_inline(const wchar_t *line); +int url_len_inline(const wchar_t *text); #endif // !defined( URL_H ) diff --git a/include/viewer.h b/include/viewer.h index d921247..81f23ec 100644 --- a/include/viewer.h +++ b/include/viewer.h @@ -32,6 +32,9 @@ * */ +#define _GNU_SOURCE // enable ncurses wchar support +#define _XOPEN_SOURCE_EXTENDED 1 // enable ncurses wchar support + #if defined( WIN32 ) #include #else @@ -54,7 +57,7 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reload, int noreload); void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colors); -void inline_display(WINDOW *window, const char *c, const int colors); +void inline_display(WINDOW *window, const wchar_t *c, const int colors); void fade_out(WINDOW *window, int trans, int colors, int invert); void fade_in(WINDOW *window, int trans, int colors, int invert); int int_length (int val); diff --git a/src/cstack.c b/src/cstack.c index 4763b5b..df27ff4 100644 --- a/src/cstack.c +++ b/src/cstack.c @@ -19,6 +19,7 @@ * */ +#include #include // fprintf #include // malloc, realloc @@ -42,24 +43,24 @@ cstack_t *cstack_init() { return stack; } -void cstack_push(cstack_t *self, char c) { +void cstack_push(cstack_t *self, wchar_t c) { if(self->size + sizeof(c) > self->alloc) { - self->alloc += (sizeof(char)); + self->alloc += (sizeof(wchar_t)); if((self->content = realloc(self->content, self->alloc)) == NULL) { fprintf(stderr, "%s\n", "cstack_push() failed to reallocate memory."); exit(EXIT_FAILURE); } } self->content[++self->head] = c; - self->size += (sizeof(char)); + self->size += (sizeof(wchar_t)); } -char cstack_pop(cstack_t *self) { - self->size -= (sizeof(char)); +wchar_t cstack_pop(cstack_t *self) { + self->size -= (sizeof(wchar_t)); return self->content[self->head--]; } -bool cstack_top(cstack_t *self, char c) { +bool cstack_top(cstack_t *self, wchar_t c) { return self->head >= 0 && self->content[self->head] == c; } diff --git a/src/cstring.c b/src/cstring.c index 558a786..1570786 100644 --- a/src/cstring.c +++ b/src/cstring.c @@ -19,7 +19,7 @@ * */ -#include // strlen, memmove +#include // wcslen, wcscat, wmemmove #include // fprintf #include // malloc, realloc @@ -42,41 +42,41 @@ cstring_t *cstring_init() { return x; } -void cstring_expand(cstring_t *self, char x) { - if(self->size + sizeof(x) + sizeof(char) > self->alloc) { - self->alloc += (REALLOC_ADD * sizeof(char)); +void cstring_expand(cstring_t *self, wchar_t x) { + if((self->size + 2) * sizeof(wchar_t) > self->alloc) { + self->alloc += (REALLOC_ADD * sizeof(wchar_t)); if((self->text = realloc(self->text, self->alloc)) == NULL) { fprintf(stderr, "%s\n", "cstring_expand() failed to reallocate memory."); exit(EXIT_FAILURE); } } self->text[self->size] = x; - self->text[self->size+1] = '\0'; - self->size = strlen(self->text); + self->text[self->size+1] = L'\0'; + self->size = wcslen(self->text); } -void cstring_expand_arr(cstring_t *self, char *x) { - if(self->size + strlen(x) + sizeof(char) > self->alloc) { - self->alloc = ((strlen(x) + self->size + 1) * sizeof(char)); +void cstring_expand_arr(cstring_t *self, wchar_t *x) { + if((self->size + wcslen(x) + 1) * sizeof(wchar_t) > self->alloc) { + self->alloc = ((self->size + wcslen(x) + 1) * sizeof(wchar_t)); if((self->text = realloc(self->text, self->alloc)) == NULL) { - fprintf(stderr, "%s\n", "cstring_expand() failed to reallocate memory."); + fprintf(stderr, "%s\n", "cstring_expand_arr() failed to reallocate memory."); exit(EXIT_FAILURE); } } - self->text = strcat(self->text, x); - self->size = strlen(self->text); - self->text[self->size+1] = '\0'; + self->text = wcscat(self->text, x); + self->size = wcslen(self->text); + self->text[self->size+1] = L'\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->text[pos] = L'\0'; self->size = pos; } return; } - memmove(&self->text[pos], &self->text[pos+len], self->size - pos - len+1); + wmemmove(&self->text[pos], &self->text[pos+len], self->size - pos - len+1); self->size -= len; } diff --git a/src/main.c b/src/main.c index 37af9bc..e762fbb 100644 --- a/src/main.c +++ b/src/main.c @@ -19,6 +19,7 @@ #include #include +#include // setlocale #include #include #include @@ -82,6 +83,9 @@ int main(int argc, char *argv[]) { } } + // set locale to read and display UTF-8 correctly in ncurses + setlocale(LC_CTYPE, "en_US.UTF8"); + // open file or set input to STDIN char *file = NULL; FILE *input; diff --git a/src/parser.c b/src/parser.c index f835a5c..4d48e33 100644 --- a/src/parser.c +++ b/src/parser.c @@ -25,13 +25,15 @@ #include #include #include +#include +#include #include #include "parser.h" deck_t *markdown_load(FILE *input) { - int c = 0; // char + wchar_t c = L'\0'; // char int i = 0; // increment int hc = 0; // header count int lc = 0; // line count @@ -48,13 +50,13 @@ deck_t *markdown_load(FILE *input) { // initialize bits as empty line SET_BIT(bits, IS_EMPTY); - while ((c = fgetc(input)) != EOF) { + while ((c = fgetwc(input)) != WEOF) { if (ferror(input)) { fprintf(stderr, "markdown_load() failed to read input: %s\n", strerror(errno)); exit(EXIT_FAILURE); } - if(c == '\n') { + if(c == L'\n') { // markdown analyse prev = bits; @@ -114,14 +116,14 @@ deck_t *markdown_load(FILE *input) { text = cstring_init(); } - } else if(c == '\t') { + } else if(c == L'\t') { // expand tab to spaces for (i = 0; i < EXPAND_TABS; i++) { - (text->expand)(text, ' '); + (text->expand)(text, L' '); } - } else if(c == '\\') { + } else if(c == L'\\') { // add char to line (text->expand)(text, c); @@ -130,35 +132,14 @@ deck_t *markdown_load(FILE *input) { // and do not increase line count if(next_nonblank(text, 0) < CODE_INDENT) { - c = fgetc(input); + c = fgetwc(input); (text->expand)(text, c); - - if(is_utf8(c)) { - - // if utf-8 char > 1 byte add remaing to line - for(i = 0; i < length_utf8(c) - 1; i++) { - c = fgetc(input); - (text->expand)(text, c); - } - } - } - } else if(isprint(c) || isspace((unsigned char) c)) { + } else if(iswprint(c) || iswspace(c)) { // add char to line (text->expand)(text, c); - - } else if(is_utf8(c)) { - - // add char to line - (text->expand)(text, c); - - // if utf-8 char > 1 byte add remaing to line - for(i = 0; i < length_utf8(c) - 1; i++) { - c = fgetc(input); - (text->expand)(text, c); - } } } (text->delete)(text); @@ -168,13 +149,13 @@ deck_t *markdown_load(FILE *input) { // detect header line = deck->slide->line; - if(line && line->text->size > 0 && line->text->text[0] == '%') { + if(line && line->text->size > 0 && line->text->text[0] == L'%') { // assign header to deck deck->header = line; // find first non-header line - while(line && line->text->size > 0 && line->text->text[0] == '%') { + while(line && line->text->size > 0 && line->text->text[0] == L'%') { hc++; line = line->next; } @@ -328,12 +309,12 @@ int markdown_analyse(cstring_t *text, int prev) { offset = next_nonblank(text, 0); // strip trailing spaces - for(eol = text->size; eol > offset && isspace((unsigned char) text->text[eol - 1]); eol--); + for(eol = text->size; eol > offset && iswspace(text->text[eol - 1]); eol--); // IS_UNORDERED_LIST_# if(text->size >= offset + 2 && - (text->text[offset] == '*' || text->text[offset] == '-') && - text->text[offset + 1] == ' ') { + (text->text[offset] == L'*' || text->text[offset] == L'-') && + iswspace(text->text[offset + 1])) { // if different from last lines offset if(offset != unordered_list_offset) { @@ -406,15 +387,15 @@ int markdown_analyse(cstring_t *text, int prev) { } else { // IS_QUOTE - if(text->text[offset] == '>') { + if(text->text[offset] == L'>') { SET_BIT(bits, IS_QUOTE); } // IS_CENTER if(text->size >= offset + 3 && - text->text[offset] == '-' && - text->text[offset + 1] == '>' && - text->text[offset + 2] == ' ') { + text->text[offset] == L'-' && + text->text[offset + 1] == L'>' && + iswspace(text->text[offset + 2])) { SET_BIT(bits, IS_CENTER); // remove start tag @@ -422,31 +403,31 @@ int markdown_analyse(cstring_t *text, int prev) { eol -= 3; if(text->size >= offset + 3 && - text->text[eol - 1] == '-' && - text->text[eol - 2] == '<' && - text->text[eol - 3] == ' ') { + text->text[eol - 1] == L'-' && + text->text[eol - 2] == L'<' && + iswspace(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(eol = text->size; eol > offset && iswspace(text->text[eol - 1]); eol--); } } for(i = offset; i < eol; i++) { - if(text->text[i] == ' ') { + if(iswspace(text->text[i])) { spaces++; } else { switch(text->text[i]) { - case '=': equals++; break; - case '#': hashes++; break; - case '*': stars++; break; - case '-': minus++; break; - case '\\': other++; i++; break; + case L'=': equals++; break; + case L'#': hashes++; break; + case L'*': stars++; break; + case L'-': minus++; break; + case L'\\': other++; i++; break; default: other++; break; } } @@ -454,23 +435,23 @@ int markdown_analyse(cstring_t *text, int prev) { // IS_H1 if(equals > 0 && - hashes + stars + minus + spaces + other == 0) { + hashes + stars + minus + spaces + other == 0) { SET_BIT(bits, IS_H1); } - if(text->text[offset] == '#' && - text->text[offset+1] == ' ') { + if(text->text[offset] == L'#' && + iswspace(text->text[offset+1])) { SET_BIT(bits, IS_H1); SET_BIT(bits, IS_H1_ATX); } // IS_H2 if(minus > 0 && - equals + hashes + stars + spaces + other == 0) { + equals + hashes + stars + spaces + other == 0) { SET_BIT(bits, IS_H2); } - if(text->text[offset] == '#' && - text->text[offset+1] == '#' && - text->text[offset+2] == ' ') { + if(text->text[offset] == L'#' && + text->text[offset+1] == L'#' && + iswspace(text->text[offset+2])) { SET_BIT(bits, IS_H2); SET_BIT(bits, IS_H2_ATX); } @@ -501,7 +482,7 @@ void markdown_debug(deck_t *deck, int debug) { line_t *header; if(debug == 1) { - fprintf(stderr, "headers: %i\nslides: %i\n", deck->headers, deck->slides); + fwprintf(stderr, L"headers: %i\nslides: %i\n", deck->headers, deck->slides); } else if(debug > 1) { @@ -510,12 +491,12 @@ void markdown_debug(deck_t *deck, int debug) { header = deck->header; while(header && header->length > 0 && - header->text->text[0] == '%') { + header->text->text[0] == L'%') { // skip descriptor word (e.g. %title:) offset = next_blank(header->text, 0) + 1; - fprintf(stderr, "header: %s\n", &header->text->text[offset]); + fwprintf(stderr, L"header: %S\n", &header->text->text[offset]); header = header->next; } } @@ -529,17 +510,17 @@ void markdown_debug(deck_t *deck, int debug) { sc++; if(debug == 1) { - fprintf(stderr, " slide %i: %i lines\n", sc, slide->lines); + fwprintf(stderr, L" slide %i: %i lines\n", sc, slide->lines); } else if(debug > 1) { // also print bits and line length - fprintf(stderr, " slide %i:\n", sc); + fwprintf(stderr, L" slide %i:\n", sc); line = slide->line; lc = 0; while(line) { lc++; - fprintf(stderr, " line %i: bits = %i, length = %i\n", lc, line->bits, line->length); + fwprintf(stderr, L" line %i: bits = %i, length = %i\n", lc, line->bits, line->length); line = line->next; } } @@ -550,22 +531,22 @@ void markdown_debug(deck_t *deck, int debug) { void adjust_line_length(line_t *line) { int l = 0; - const static char *special = "\\*_`"; // list of interpreted chars - const char *c = &line->text->text[line->offset]; + const static wchar_t *special = L"\\*_`"; // list of interpreted chars + const wchar_t *c = &line->text->text[line->offset]; cstack_t *stack = cstack_init(); // for each char in line for(; *c; c++) { // if char is in special char list - if(strchr(special, *c)) { + if(wcschr(special, *c)) { // closing special char (or second backslash) if((stack->top)(stack, *c)) { - if(*c == '\\') l++; + if(*c == L'\\') l++; (stack->pop)(stack); // treat special as regular char - } else if((stack->top)(stack, '\\')) { + } else if((stack->top)(stack, L'\\')) { l++; (stack->pop)(stack); @@ -576,7 +557,7 @@ void adjust_line_length(line_t *line) { } else { // remove backslash from stack - if((stack->top)(stack, '\\')) + if((stack->top)(stack, L'\\')) (stack->pop)(stack); l++; } @@ -592,38 +573,22 @@ void adjust_line_length(line_t *line) { (stack->delete)(stack); } -bool is_utf8(char ch) { - return (ch & 0x80) != 0x00; -} - -int length_utf8(char ch) { - - int i = 0; // increment - - while(is_utf8(ch)) { - i++; - ch <<= 1; - } - - return i; -} - int next_nonblank(cstring_t *text, int i) { - while ((i < text->size) && isspace((unsigned char) (text->text)[i])) + while ((i < text->size) && iswspace((text->text)[i])) i++; return i; } int prev_blank(cstring_t *text, int i) { - while ((i > 0) && !isspace((unsigned char) (text->text)[i])) + while ((i > 0) && !iswspace((text->text)[i])) i--; return i; } int next_blank(cstring_t *text, int i) { - while ((i < text->size) && !isspace((unsigned char) (text->text)[i])) + while ((i < text->size) && !iswspace((text->text)[i])) i++; return i; diff --git a/src/url.c b/src/url.c index 1aa2de6..a7a5c0c 100644 --- a/src/url.c +++ b/src/url.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include "url.h" @@ -39,7 +39,7 @@ void url_init(void) { init_ok = 1; } -int url_add(const char *link_name, int link_name_length, const char *target, int target_length, int x, int y) { +int url_add(const wchar_t *link_name, int link_name_length, const wchar_t *target, int target_length, int x, int y) { if (!init_ok) return -1; url_t *tmp = NULL; @@ -60,14 +60,14 @@ int url_add(const char *link_name, int link_name_length, const char *target, int assert(tmp); } - tmp -> link_name = calloc(link_name_length+1, sizeof(char)); + tmp -> link_name = calloc(link_name_length+1, sizeof(wchar_t)); assert(tmp->link_name); - strncpy(tmp->link_name, link_name, link_name_length); + wcsncpy(tmp->link_name, link_name, link_name_length); tmp->link_name[link_name_length] = '\0'; - tmp->target = calloc(target_length+1, sizeof(char)); + tmp->target = calloc(target_length+1, sizeof(wchar_t)); assert(tmp->target); - strncpy(tmp->target, target, target_length); + wcsncpy(tmp->target, target, target_length); tmp->target[target_length] = '\0'; tmp->x = x; @@ -79,7 +79,7 @@ int url_add(const char *link_name, int link_name_length, const char *target, int return index_max-1; } -char * url_get_target(int index) { +wchar_t * url_get_target(int index) { if (!init_ok) return NULL; url_t *tmp = list; @@ -96,7 +96,7 @@ char * url_get_target(int index) { } else return NULL; } -char * url_get_name(int index) { +wchar_t * url_get_name(int index) { url_t *tmp = list; while (index > 0 && tmp && tmp->next) { @@ -158,9 +158,9 @@ int url_get_amount(void) { return index_max; } -int url_count_inline(const char *line) { +int url_count_inline(const wchar_t *line) { int count = 0; - const char *i = line; + const wchar_t *i = line; for (; *i; i++) { if (*i == '\\') { @@ -168,9 +168,9 @@ int url_count_inline(const char *line) { } else if ( *i == '[' && *(i+1) != ']') { while (*i && *i != ']') i++; i++; - if (*i == '(' && strchr(i, ')')) { + if (*i == '(' && wcschr(i, ')')) { count ++; - i = strchr(i, ')'); + i = wcschr(i, ')'); } } } @@ -178,9 +178,9 @@ int url_count_inline(const char *line) { return count; } -int url_len_inline(const char *text) { +int url_len_inline(const wchar_t *text) { int count = 0; - const char *i = text; + const wchar_t *i = text; for (; *i; i++) { if (*i == '\\') { @@ -188,7 +188,7 @@ int url_len_inline(const char *text) { } else if ( *i == '[' && *(i+1) != ']') { while (*i && *i != ']') i++; i++; - if (*i == '(' && strchr(i, ')')) { + if (*i == '(' && wcschr(i, ')')) { while (*i && *i != ')') { count++; i++; diff --git a/src/viewer.c b/src/viewer.c index 3e391b1..8d97139 100644 --- a/src/viewer.c +++ b/src/viewer.c @@ -22,10 +22,10 @@ */ #include // isalnum -#include // setlocale -#include // strchr +#include // wcschr +#include // iswalnum +#include // strcpy #include // usleep - #include "viewer.h" // color ramp for fading from black to color @@ -83,9 +83,6 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa slide_t *slide = deck->slide; line_t *line; - // set locale to display UTF-8 correctly in ncurses - setlocale(LC_CTYPE, ""); - // init ncurses initscr(); @@ -117,8 +114,8 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa endwin(); // print error - fprintf(stderr, "Error: Terminal width (%i columns) too small. Need at least %i columns.\n", COLS, i); - fprintf(stderr, "You may need to shorten some lines by inserting line breaks.\n"); + fwprintf(stderr, L"Error: Terminal width (%i columns) too small. Need at least %i columns.\n", COLS, i); + fwprintf(stderr, L"You may need to shorten some lines by inserting line breaks.\n"); // no reload return 0; @@ -154,8 +151,8 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa endwin(); // print error - 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"); + fwprintf(stderr, L"Error: Terminal height (%i lines) too small. Need at least %i lines.\n", LINES, max_lines + bar_top + bar_bottom); + fwprintf(stderr, L"You may need to add additional horizontal rules (---) to split your file in shorter slides.\n"); // no reload return 0; @@ -269,9 +266,9 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa line = deck->header; offset = next_blank(line->text, 0) + 1; // add text to header - mvwprintw(stdscr, - 0, (COLS - line->length + offset) / 2, - "%s", &line->text->text[offset]); + mvwaddwstr(stdscr, + 0, (COLS - line->length + offset) / 2, + &line->text->text[offset]); } // setup footer @@ -279,10 +276,11 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa line = deck->header->next; offset = next_blank(line->text, 0) + 1; // add text to left footer - mvwprintw(stdscr, - LINES - 1, 3, - "%s", &line->text->text[offset]); + mvwaddwstr(stdscr, + LINES - 1, 3, + &line->text->text[offset]); } + // add slide number to right footer mvwprintw(stdscr, LINES - 1, COLS - int_length(deck->slides) - int_length(sc) - 6, @@ -306,7 +304,8 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa getmaxyx( content, ymax, i ); for (i = 0; i < url_get_amount(); i++) { mvwprintw(content, ymax - url_get_amount() - 1 + i, 3, - "[%d] %s", i, url_get_target(i)); + "[%d] ", i); + waddwstr(content, url_get_target(i)); } // make content visible @@ -538,8 +537,7 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo wattron(window, COLOR_PAIR(CP_BLACK)); // print whole lines - wprintw(window, - "%s", &line->text->text[offset]); + waddwstr(window, &line->text->text[offset]); } if(!CHECK_BIT(line->bits, IS_UNORDERED_LIST_1) && @@ -592,8 +590,7 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo offset = next_word(line->text, offset); // print whole lines - wprintw(window, - "%s", &line->text->text[offset]); + waddwstr(window, &line->text->text[offset]); wattroff(window, A_UNDERLINE); @@ -615,10 +612,10 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo wattroff(window, A_UNDERLINE); } -void inline_display(WINDOW *window, const char *c, const int colors) { - const static char *special = "\\*_`!["; // list of interpreted chars - const char *i = c; // iterator - const char *start_link_name, *start_url; +void inline_display(WINDOW *window, const wchar_t *c, const int colors) { + const static wchar_t *special = L"\\*_`!["; // list of interpreted chars + const wchar_t *i = c; // iterator + const wchar_t *start_link_name, *start_url; int length_link_name, url_num; cstack_t *stack = cstack_init(); @@ -627,29 +624,29 @@ void inline_display(WINDOW *window, const char *c, const int colors) { for(; *i; i++) { // if char is in special char list - if(strchr(special, *i)) { + if(wcschr(special, *i)) { // closing special char (or second backslash) // only if not followed by :alnum: if((stack->top)(stack, *i) && - (!isalnum((int)i[1]) || *(i + 1) == '\0' || *i == '\\')) { + (!iswalnum(i[1]) || *(i + 1) == L'\0' || *i == L'\\')) { switch(*i) { // print escaped backslash - case '\\': - wprintw(window, "%c", *i); + case L'\\': + waddnwstr(window, i, 1); break; // disable highlight - case '*': + case L'*': if(colors) wattron(window, COLOR_PAIR(CP_WHITE)); break; // disable underline - case '_': + case L'_': wattroff(window, A_UNDERLINE); break; // disable inline code - case '`': + case L'`': if(colors) wattron(window, COLOR_PAIR(CP_WHITE)); break; @@ -659,8 +656,8 @@ void inline_display(WINDOW *window, const char *c, const int colors) { (stack->pop)(stack); // treat special as regular char - } else if((stack->top)(stack, '\\')) { - wprintw(window, "%c", *i); + } else if((stack->top)(stack, L'\\')) { + waddnwstr(window, i, 1); // remove backslash from stack (stack->pop)(stack); @@ -672,17 +669,18 @@ void inline_display(WINDOW *window, const char *c, const int colors) { // 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 == '\\') { + iswspace(*(i - 1)) || + ((iswspace(*(i - 1)) || *(i - 1) == L'*' || *(i - 1) == L'_') && + ((i - 1) == c || iswspace(*(i - 2)))) || + *i == L'\\') { // url in pandoc style - if ((*i == '[' && strchr(i, ']')) || - (*i == '!' && *(i + 1) == '[' && strchr(i, ']'))) { + if ((*i == L'[' && wcschr(i, L']')) || + (*i == L'!' && *(i + 1) == L'[' && wcschr(i, L']'))) { - if (*i == '!') i++; + if (*i == L'!') i++; - if (strchr(i, ']')[1] == '(') { + if (wcschr(i, L']')[1] == L'(') { i++; // turn higlighting and underlining on @@ -695,9 +693,9 @@ void inline_display(WINDOW *window, const char *c, const int colors) { // print the content of the label // the label is printed as is do { - wprintw(window, "%c", *i); + waddnwstr(window, i, 1); i++; - } while (*i != ']'); + } while (*i != L']'); length_link_name = i - 1 - start_link_name; @@ -706,9 +704,9 @@ void inline_display(WINDOW *window, const char *c, const int colors) { start_url = i; - while (*i != ')') i++; + while (*i != L')') i++; - url_num = url_add(start_link_name, length_link_name, start_url, i - start_url, 0,0); + url_num = url_add(start_link_name, length_link_name, start_url, i - start_url, 0, 0); wprintw(window, " [%d]", url_num); @@ -722,16 +720,16 @@ void inline_display(WINDOW *window, const char *c, const int colors) { } else switch(*i) { // enable highlight - case '*': + case L'*': if(colors) wattron(window, COLOR_PAIR(CP_RED)); break; // enable underline - case '_': + case L'_': wattron(window, A_UNDERLINE); break; // enable inline code - case '`': + case L'`': if(colors) wattron(window, COLOR_PAIR(CP_BLACK)); break; @@ -742,17 +740,17 @@ void inline_display(WINDOW *window, const char *c, const int colors) { (stack->push)(stack, *i); } else { - wprintw(window, "%c", *i); + waddnwstr(window, i, 1); } } } else { // remove backslash from stack - if((stack->top)(stack, '\\')) + if((stack->top)(stack, L'\\')) (stack->pop)(stack); // print regular char - wprintw(window, "%c", *i); + waddnwstr(window, i, 1); } } @@ -760,16 +758,16 @@ void inline_display(WINDOW *window, const char *c, const int colors) { while(!(stack->empty)(stack)) { switch((stack->pop)(stack)) { // disable highlight - case '*': + case L'*': if(colors) wattron(window, COLOR_PAIR(CP_WHITE)); break; // disable underline - case '_': + case L'_': wattroff(window, A_UNDERLINE); break; // disable inline code - case '`': + case L'`': if(colors) wattron(window, COLOR_PAIR(CP_WHITE)); break;