X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=parser.c;h=1ff125c69775ca61ce981e10f5216a26ed7fbff3;hb=6edf0543111ac7f119c0255ae254159d9508f770;hp=41219641e1c5a5257b5aa8f71b06cd5a552c0e09;hpb=f7c44aadc65ba6401992ec02f7ccb1ea4c2301ff;p=smdp.git diff --git a/parser.c b/parser.c index 4121964..1ff125c 100644 --- a/parser.c +++ b/parser.c @@ -1,3 +1,27 @@ +/* + * Functions necessary to parse a file and transform its content into + * a deck of slides containing lines. All based on markdown formating + * rules. + * Copyright (C) 2014 Michael Goehler + * + * This file is part of mdp. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include #include #include @@ -15,7 +39,8 @@ deck_t *markdown_load(FILE *input) { deck_t *deck = new_deck(); slide_t *slide = new_slide(); - line_t *line; + line_t *line = NULL; + line_t *tmp = NULL; cstring_t *text = cstring_init(); // assign first slide to deck @@ -28,9 +53,15 @@ deck_t *markdown_load(FILE *input) { // markdown analyse bits = markdown_analyse(text); + // if first line in file is markdown hr + if(!line && CHECK_BIT(bits, IS_HR)) { + + // clear text + (text->reset)(text); + // if text is markdown hr - if(CHECK_BIT(bits, IS_HR) && - CHECK_BIT(line->bits, IS_EMPTY)) { + } else if(CHECK_BIT(bits, IS_HR) && + CHECK_BIT(line->bits, IS_EMPTY)) { slide->lines = lc; @@ -80,12 +111,36 @@ deck_t *markdown_load(FILE *input) { } else if(c == '\t') { // expand tab to spaces - for (i = 0; i <= 4; i++) { + for (i = 0; i < EXPAND_TABS; i++) { (text->expand)(text, ' '); l++; } - } else if(isprint(c) || isspace(c)) { + } else if(c == '\\') { + + // add char to line + (text->expand)(text, c); + l++; + + // if !IS_CODE add next char to line + // and do not increase line count + if(next_nonblank(text, 0) < CODE_INDENT) { + + c = fgetc(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)) { // add char to line (text->expand)(text, c); @@ -101,6 +156,7 @@ deck_t *markdown_load(FILE *input) { c = fgetc(input); (text->expand)(text, c); } + l++; } } @@ -146,9 +202,10 @@ deck_t *markdown_load(FILE *input) { // remove line from linked list line->prev->next = line->next; - line->next->prev = line->prev; + if(line->next) + line->next->prev = line->prev; - // set bits on revious line + // set bits on previous line if(CHECK_BIT(line->bits, IS_H1)) { SET_BIT(line->prev->bits, IS_H1); } else { @@ -158,9 +215,13 @@ deck_t *markdown_load(FILE *input) { // adjust line count slide->lines -= 1; + // maintain loop condition + tmp = line; + line = line->prev; + // delete line - (line->text->delete)(line->text); - free(line); + (tmp->text->delete)(tmp->text); + free(tmp); } line = line->next; } @@ -185,17 +246,30 @@ int markdown_analyse(cstring_t *text) { offset = next_nonblank(text, 0); // strip trailing spaces - for(eol = text->size; eol > offset && isspace(text->text[eol - 1]); eol--); + for(eol = text->size; eol > offset && isspace((unsigned char) text->text[eol - 1]); eol--); + + // IS_CODE + if(offset >= CODE_INDENT) { + SET_BIT(bits, IS_CODE); + } for(i = offset; i < eol; i++) { - switch(text->text[i]) { - case '=': equals++; break; - case '#': hashes++; break; - case '*': stars++; break; - case '-': minus++; break; - case ' ': spaces++; break; - default: other++; break; + if(text->text[i] == ' ') { + spaces++; + + } else if(CHECK_BIT(bits, IS_CODE)) { + other++; + + } else { + switch(text->text[i]) { + case '=': equals++; break; + case '#': hashes++; break; + case '*': stars++; break; + case '-': minus++; break; + case '\\': other++; i++; break; + default: other++; break; + } } } @@ -229,11 +303,6 @@ int markdown_analyse(cstring_t *text) { SET_BIT(bits, IS_QUOTE); } - // IS_CODE - if(offset >= 4) { - SET_BIT(bits, IS_CODE); - } - // IS_HR if((minus >= 3 && equals + hashes + stars + other == 0) || (stars >= 3 && equals + hashes + minus + other == 0)) { @@ -322,16 +391,20 @@ int length_utf8(char ch) { } int next_nonblank(cstring_t *text, int i) { - while ((i < text->size) && isspace((text->text)[i])) + while ((i < text->size) && isspace((unsigned char) (text->text)[i])) ++i; return i; -}; +} int next_blank(cstring_t *text, int i) { - while ((i < text->size) && !isspace((text->text)[i])) + while ((i < text->size) && !isspace((unsigned char) (text->text)[i])) ++i; return i; -}; +} + +int next_word(cstring_t *text, int i) { + return next_nonblank(text, next_blank(text, i)); +}