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;
176 line->next->prev = line->prev;
178 // set bits on revious line
179 if(CHECK_BIT(line->bits, IS_H1)) {
180 SET_BIT(line->prev->bits, IS_H1);
182 SET_BIT(line->prev->bits, IS_H2);
189 (line->text->delete)(line->text);
200 int markdown_analyse(cstring_t *text) {
202 int i = 0; // increment
203 int bits = 0; // markdown bits
204 int offset = 0; // text offset
205 int eol = 0; // end of line
207 int equals = 0, hashes = 0,
208 stars = 0, minus = 0,
209 spaces = 0, other = 0; // special character counts
211 // count leading spaces
212 offset = next_nonblank(text, 0);
214 // strip trailing spaces
215 for(eol = text->size; eol > offset && isspace(text->text[eol - 1]); eol--);
218 if(offset >= CODE_INDENT) {
219 SET_BIT(bits, IS_CODE);
222 for(i = offset; i < eol; i++) {
224 if(text->text[i] == ' ') {
227 } else if(CHECK_BIT(bits, IS_CODE)) {
231 switch(text->text[i]) {
232 case '=': equals++; break;
233 case '#': hashes++; break;
234 case '*': stars++; break;
235 case '-': minus++; break;
236 case '\\': other++; i++; break;
237 default: other++; break;
244 hashes + stars + minus + spaces + other == 0) ||
247 text->text[offset] == '#' &&
248 text->text[offset+1] != '#')) {
250 SET_BIT(bits, IS_H1);
255 equals + hashes + stars + spaces + other == 0) ||
258 text->text[offset] == '#' &&
259 text->text[offset+1] == '#')) {
261 SET_BIT(bits, IS_H2);
267 text->text[offset] == '>') {
269 SET_BIT(bits, IS_QUOTE);
273 if((minus >= 3 && equals + hashes + stars + other == 0) ||
274 (stars >= 3 && equals + hashes + minus + other == 0)) {
276 SET_BIT(bits, IS_HR);
281 SET_BIT(bits, IS_EMPTY);
287 void markdown_debug(deck_t *deck, int debug) {
289 int sc = 0; // slide count
290 int lc = 0; // line count
296 fprintf(stderr, "headers: %i\nslides: %i\n", deck->headers, deck->slides);
298 } else if(debug > 1) {
300 // print header to STDERR
302 header = deck->header;
304 header->length > 0 &&
305 header->text->text[0] == '%') {
307 // skip descriptor word (e.g. %title:)
308 offset = next_blank(header->text, 0) + 1;
310 fprintf(stderr, "header: %s\n", &header->text->text[offset]);
311 header = header->next;
316 slide_t *slide = deck->slide;
319 // print slide/line count to STDERR
324 fprintf(stderr, " slide %i: %i lines\n", sc, slide->lines);
326 } else if(debug > 1) {
328 // also print bits and line length
329 fprintf(stderr, " slide %i:\n", sc);
334 fprintf(stderr, " line %i: bits = %i, length = %i\n", lc, line->bits, line->length);
343 int is_utf8(char ch) {
347 int length_utf8(char ch) {
349 int i = 0; // increment
359 int next_nonblank(cstring_t *text, int i) {
360 while ((i < text->size) && isspace((text->text)[i]))
366 int next_blank(cstring_t *text, int i) {
367 while ((i < text->size) && !isspace((text->text)[i]))
373 int next_word(cstring_t *text, int i) {
374 return next_nonblank(text, next_blank(text, i));