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 <= 4; i++) {
84 (text->expand)(text, ' ');
88 } else if(isprint(c) || isspace(c)) {
91 (text->expand)(text, c);
94 } else if(is_utf8(c)) {
97 (text->expand)(text, c);
99 // if utf-8 char > 1 byte add remaing to line
100 for(i = 0; i < length_utf8(c) - 1; i++) {
102 (text->expand)(text, c);
112 line = deck->slide->line;
113 if(line && line->text->size > 0 && line->text->text[0] == '%') {
115 // assign header to deck
118 // find first non-header line
119 while(line->text->size > 0 && line->text->text[0] == '%') {
125 line->prev->next = (void*)0;
126 line->prev = (void*)0;
128 // remove header lines from slide
129 deck->slide->line = line;
133 deck->slide->lines -= hc;
136 // combine underlined H1/H2 in single line
141 if((CHECK_BIT(line->bits, IS_H1) ||
142 CHECK_BIT(line->bits, IS_H2)) &&
143 CHECK_BIT(line->bits, IS_EMPTY) &&
145 !CHECK_BIT(line->prev->bits, IS_EMPTY)) {
147 // remove line from linked list
148 line->prev->next = line->next;
149 line->next->prev = line->prev;
151 // set bits on revious line
152 if(CHECK_BIT(line->bits, IS_H1)) {
153 SET_BIT(line->prev->bits, IS_H1);
155 SET_BIT(line->prev->bits, IS_H2);
162 (line->text->delete)(line->text);
173 int markdown_analyse(cstring_t *text) {
175 int i = 0; // increment
176 int bits = 0; // markdown bits
177 int offset = 0; // text offset
178 int eol = 0; // end of line
180 int equals = 0, hashes = 0,
181 stars = 0, minus = 0,
182 spaces = 0, other = 0; // special character counts
184 // count leading spaces
185 offset = next_nonblank(text, 0);
187 // strip trailing spaces
188 for(eol = text->size; eol > offset && isspace(text->text[eol - 1]); eol--);
190 for(i = offset; i < eol; i++) {
192 switch(text->text[i]) {
193 case '=': equals++; break;
194 case '#': hashes++; break;
195 case '*': stars++; break;
196 case '-': minus++; break;
197 case ' ': spaces++; break;
198 default: other++; break;
204 hashes + stars + minus + spaces + other == 0) ||
207 text->text[offset] == '#' &&
208 text->text[offset+1] != '#')) {
210 SET_BIT(bits, IS_H1);
215 equals + hashes + stars + spaces + other == 0) ||
218 text->text[offset] == '#' &&
219 text->text[offset+1] == '#')) {
221 SET_BIT(bits, IS_H2);
227 text->text[offset] == '>') {
229 SET_BIT(bits, IS_QUOTE);
234 SET_BIT(bits, IS_CODE);
238 if((minus >= 3 && equals + hashes + stars + other == 0) ||
239 (stars >= 3 && equals + hashes + minus + other == 0)) {
241 SET_BIT(bits, IS_HR);
246 SET_BIT(bits, IS_EMPTY);
252 void markdown_debug(deck_t *deck, int debug) {
254 int sc = 0; // slide count
255 int lc = 0; // line count
261 fprintf(stderr, "headers: %i\nslides: %i\n", deck->headers, deck->slides);
263 } else if(debug > 1) {
265 // print header to STDERR
267 header = deck->header;
269 header->length > 0 &&
270 header->text->text[0] == '%') {
272 // skip descriptor word (e.g. %title:)
273 offset = next_blank(header->text, 0) + 1;
275 fprintf(stderr, "header: %s\n", &header->text->text[offset]);
276 header = header->next;
281 slide_t *slide = deck->slide;
284 // print slide/line count to STDERR
289 fprintf(stderr, " slide %i: %i lines\n", sc, slide->lines);
291 } else if(debug > 1) {
293 // also print bits and line length
294 fprintf(stderr, " slide %i:\n", sc);
299 fprintf(stderr, " line %i: bits = %i, length = %i\n", lc, line->bits, line->length);
308 int is_utf8(char ch) {
312 int length_utf8(char ch) {
314 int i = 0; // increment
324 int next_nonblank(cstring_t *text, int i) {
325 while ((i < text->size) && isspace((text->text)[i]))
331 int next_blank(cstring_t *text, int i) {
332 while ((i < text->size) && !isspace((text->text)[i]))