4 #include "include/parser.h"
6 deck_t *markdown_load(FILE *input) {
9 int i = 0; // increment
10 int l = 0; // line length
11 int hc = 0; // header count
12 int lc = 0; // line count
13 int sc = 0; // slide count
14 int bits = 0; // markdown bits
16 deck_t *deck = new_deck();
17 slide_t *slide = new_slide();
19 cstring_t *text = cstring_init();
21 // assign first slide to deck
25 while ((c = fgetc(input)) != EOF) {
29 bits = markdown_analyse(text);
31 // if text is markdown hr
32 if(CHECK_BIT(bits, IS_HR) &&
33 CHECK_BIT(line->bits, IS_EMPTY)) {
42 slide = next_slide(slide);
47 // if slide ! has line
58 line = next_line(line);
73 line->offset = next_nonblank(text, 0);
76 text = cstring_init();
80 } else if(c == '\t') {
82 // expand tab to spaces
83 for (i = 0; i <= EXPAND_TABS; i++) {
84 (text->expand)(text, ' ');
88 } else if(c == '\\') {
91 (text->expand)(text, c);
94 // if !IS_CODE add next char to line
95 // and do not increase line count
96 if(next_nonblank(text, 0) < CODE_INDENT) {
99 (text->expand)(text, c);
103 // if utf-8 char > 1 byte add remaing to line
104 for(i = 0; i < length_utf8(c) - 1; i++) {
106 (text->expand)(text, c);
112 } else if(isprint(c) || isspace(c)) {
115 (text->expand)(text, c);
118 } else if(is_utf8(c)) {
121 (text->expand)(text, c);
123 // if utf-8 char > 1 byte add remaing to line
124 for(i = 0; i < length_utf8(c) - 1; i++) {
126 (text->expand)(text, c);
137 line = deck->slide->line;
138 if(line && line->text->size > 0 && line->text->text[0] == '%') {
140 // assign header to deck
143 // find first non-header line
144 while(line->text->size > 0 && line->text->text[0] == '%') {
150 line->prev->next = (void*)0;
151 line->prev = (void*)0;
153 // remove header lines from slide
154 deck->slide->line = line;
158 deck->slide->lines -= hc;
161 // combine underlined H1/H2 in single line
166 if((CHECK_BIT(line->bits, IS_H1) ||
167 CHECK_BIT(line->bits, IS_H2)) &&
168 CHECK_BIT(line->bits, IS_EMPTY) &&
170 !CHECK_BIT(line->prev->bits, IS_EMPTY)) {
172 // remove line from linked list
173 line->prev->next = line->next;
174 line->next->prev = line->prev;
176 // set bits on revious line
177 if(CHECK_BIT(line->bits, IS_H1)) {
178 SET_BIT(line->prev->bits, IS_H1);
180 SET_BIT(line->prev->bits, IS_H2);
187 (line->text->delete)(line->text);
198 int markdown_analyse(cstring_t *text) {
200 int i = 0; // increment
201 int bits = 0; // markdown bits
202 int offset = 0; // text offset
203 int eol = 0; // end of line
205 int equals = 0, hashes = 0,
206 stars = 0, minus = 0,
207 spaces = 0, other = 0; // special character counts
209 // count leading spaces
210 offset = next_nonblank(text, 0);
212 // strip trailing spaces
213 for(eol = text->size; eol > offset && isspace(text->text[eol - 1]); eol--);
216 if(offset >= CODE_INDENT) {
217 SET_BIT(bits, IS_CODE);
220 for(i = offset; i < eol; i++) {
222 if(text->text[i] == ' ') {
225 } else if(CHECK_BIT(bits, IS_CODE)) {
229 switch(text->text[i]) {
230 case '=': equals++; break;
231 case '#': hashes++; break;
232 case '*': stars++; break;
233 case '-': minus++; break;
234 case '\\': other++; i++; break;
235 default: other++; break;
242 hashes + stars + minus + spaces + other == 0) ||
245 text->text[offset] == '#' &&
246 text->text[offset+1] != '#')) {
248 SET_BIT(bits, IS_H1);
253 equals + hashes + stars + spaces + other == 0) ||
256 text->text[offset] == '#' &&
257 text->text[offset+1] == '#')) {
259 SET_BIT(bits, IS_H2);
265 text->text[offset] == '>') {
267 SET_BIT(bits, IS_QUOTE);
271 if((minus >= 3 && equals + hashes + stars + other == 0) ||
272 (stars >= 3 && equals + hashes + minus + other == 0)) {
274 SET_BIT(bits, IS_HR);
279 SET_BIT(bits, IS_EMPTY);
285 void markdown_debug(deck_t *deck, int debug) {
287 int sc = 0; // slide count
288 int lc = 0; // line count
294 fprintf(stderr, "headers: %i\nslides: %i\n", deck->headers, deck->slides);
296 } else if(debug > 1) {
298 // print header to STDERR
300 header = deck->header;
302 header->length > 0 &&
303 header->text->text[0] == '%') {
305 // skip descriptor word (e.g. %title:)
306 offset = next_blank(header->text, 0) + 1;
308 fprintf(stderr, "header: %s\n", &header->text->text[offset]);
309 header = header->next;
314 slide_t *slide = deck->slide;
317 // print slide/line count to STDERR
322 fprintf(stderr, " slide %i: %i lines\n", sc, slide->lines);
324 } else if(debug > 1) {
326 // also print bits and line length
327 fprintf(stderr, " slide %i:\n", sc);
332 fprintf(stderr, " line %i: bits = %i, length = %i\n", lc, line->bits, line->length);
341 int is_utf8(char ch) {
345 int length_utf8(char ch) {
347 int i = 0; // increment
357 int next_nonblank(cstring_t *text, int i) {
358 while ((i < text->size) && isspace((text->text)[i]))
364 int next_blank(cstring_t *text, int i) {
365 while ((i < text->size) && !isspace((text->text)[i]))