5 #include "include/parser.h"
7 deck_t *markdown_load(FILE *input) {
10 int i = 0; // increment
11 int l = 0; // line length
12 int hc = 0; // header count
13 int lc = 0; // line count
14 int sc = 0; // slide count
15 int bits = 0; // markdown bits
17 deck_t *deck = new_deck();
18 slide_t *slide = new_slide();
20 cstring_t *text = cstring_init();
22 // assign first slide to deck
26 while ((c = fgetc(input)) != EOF) {
30 bits = markdown_analyse(text);
32 // if text is markdown hr
33 if(CHECK_BIT(bits, IS_HR) &&
34 CHECK_BIT(line->bits, IS_EMPTY)) {
43 slide = next_slide(slide);
48 // if slide ! has line
59 line = next_line(line);
74 line->offset = next_nonblank(text, 0);
77 text = cstring_init();
81 } else if(c == '\t') {
83 // expand tab to spaces
84 for (i = 0; i <= EXPAND_TABS; i++) {
85 (text->expand)(text, ' ');
89 } else if(c == '\\') {
92 (text->expand)(text, c);
95 // if !IS_CODE add next char to line
96 // and do not increase line count
97 if(next_nonblank(text, 0) < CODE_INDENT) {
100 (text->expand)(text, c);
104 // if utf-8 char > 1 byte add remaing to line
105 for(i = 0; i < length_utf8(c) - 1; i++) {
107 (text->expand)(text, c);
113 } else if(isprint(c) || isspace(c)) {
116 (text->expand)(text, c);
119 } else if(is_utf8(c)) {
122 (text->expand)(text, c);
124 // if utf-8 char > 1 byte add remaing to line
125 for(i = 0; i < length_utf8(c) - 1; i++) {
127 (text->expand)(text, c);
138 line = deck->slide->line;
139 if(line && line->text->size > 0 && line->text->text[0] == '%') {
141 // assign header to deck
144 // find first non-header line
145 while(line->text->size > 0 && line->text->text[0] == '%') {
151 line->prev->next = (void*)0;
152 line->prev = (void*)0;
154 // remove header lines from slide
155 deck->slide->line = line;
159 deck->slide->lines -= hc;
162 // combine underlined H1/H2 in single line
167 if((CHECK_BIT(line->bits, IS_H1) ||
168 CHECK_BIT(line->bits, IS_H2)) &&
169 CHECK_BIT(line->bits, IS_EMPTY) &&
171 !CHECK_BIT(line->prev->bits, IS_EMPTY)) {
173 // remove line from linked list
174 line->prev->next = line->next;
175 line->next->prev = line->prev;
177 // set bits on revious line
178 if(CHECK_BIT(line->bits, IS_H1)) {
179 SET_BIT(line->prev->bits, IS_H1);
181 SET_BIT(line->prev->bits, IS_H2);
188 (line->text->delete)(line->text);
199 int markdown_analyse(cstring_t *text) {
201 int i = 0; // increment
202 int bits = 0; // markdown bits
203 int offset = 0; // text offset
204 int eol = 0; // end of line
206 int equals = 0, hashes = 0,
207 stars = 0, minus = 0,
208 spaces = 0, other = 0; // special character counts
210 // count leading spaces
211 offset = next_nonblank(text, 0);
213 // strip trailing spaces
214 for(eol = text->size; eol > offset && isspace(text->text[eol - 1]); eol--);
217 if(offset >= CODE_INDENT) {
218 SET_BIT(bits, IS_CODE);
221 for(i = offset; i < eol; i++) {
223 if(text->text[i] == ' ') {
226 } else if(CHECK_BIT(bits, IS_CODE)) {
230 switch(text->text[i]) {
231 case '=': equals++; break;
232 case '#': hashes++; break;
233 case '*': stars++; break;
234 case '-': minus++; break;
235 case '\\': other++; i++; break;
236 default: other++; break;
243 hashes + stars + minus + spaces + other == 0) ||
246 text->text[offset] == '#' &&
247 text->text[offset+1] != '#')) {
249 SET_BIT(bits, IS_H1);
254 equals + hashes + stars + spaces + other == 0) ||
257 text->text[offset] == '#' &&
258 text->text[offset+1] == '#')) {
260 SET_BIT(bits, IS_H2);
266 text->text[offset] == '>') {
268 SET_BIT(bits, IS_QUOTE);
272 if((minus >= 3 && equals + hashes + stars + other == 0) ||
273 (stars >= 3 && equals + hashes + minus + other == 0)) {
275 SET_BIT(bits, IS_HR);
280 SET_BIT(bits, IS_EMPTY);
286 void markdown_debug(deck_t *deck, int debug) {
288 int sc = 0; // slide count
289 int lc = 0; // line count
295 fprintf(stderr, "headers: %i\nslides: %i\n", deck->headers, deck->slides);
297 } else if(debug > 1) {
299 // print header to STDERR
301 header = deck->header;
303 header->length > 0 &&
304 header->text->text[0] == '%') {
306 // skip descriptor word (e.g. %title:)
307 offset = next_blank(header->text, 0) + 1;
309 fprintf(stderr, "header: %s\n", &header->text->text[offset]);
310 header = header->next;
315 slide_t *slide = deck->slide;
318 // print slide/line count to STDERR
323 fprintf(stderr, " slide %i: %i lines\n", sc, slide->lines);
325 } else if(debug > 1) {
327 // also print bits and line length
328 fprintf(stderr, " slide %i:\n", sc);
333 fprintf(stderr, " line %i: bits = %i, length = %i\n", lc, line->bits, line->length);
342 int is_utf8(char ch) {
346 int length_utf8(char ch) {
348 int i = 0; // increment
358 int next_nonblank(cstring_t *text, int i) {
359 while ((i < text->size) && isspace((text->text)[i]))
365 int next_blank(cstring_t *text, int i) {
366 while ((i < text->size) && !isspace((text->text)[i]))