4 #include "include/parser.h"
6 document_t *markdown_load(FILE *input) {
8 int c = 0, i = 0, bits = 0;
18 text = cstring_init();
20 while ((c = fgetc(input)) != EOF) {
24 bits = markdown_analyse(text);
26 // if text is markdown hr
27 if(CHECK_BIT(bits, IS_HR) &&
28 CHECK_BIT(line->bits, IS_EMPTY)) {
33 page = next_page(page);
47 line = next_line(line);
58 line->offset = next_nonblank(text, 0);
61 text = cstring_init();
64 } else if(c == '\t') {
66 // expand tab to spaces
67 for (i = 0; i <= 4; i++)
68 (text->expand)(text, ' ');
70 } else if(isprint(c) || isspace(c) || is_utf8(c)) {
73 (text->expand)(text, c);
78 line = doc->page->line;
79 if(line && line->text->size > 0 && line->text->text[0] == '%') {
81 // assign header to document
84 // find first non-header line
85 while(line->text->size > 0 && line->text->text[0] == '%') {
90 line->prev->next = (void*)0;
91 line->prev = (void*)0;
93 // remove header lines from page
94 doc->page->line = line;
97 // combine underlined H1/H2 in single line
102 if((CHECK_BIT(line->bits, IS_H1) ||
103 CHECK_BIT(line->bits, IS_H2)) &&
104 CHECK_BIT(line->bits, IS_EMPTY) &&
106 !CHECK_BIT(line->prev->bits, IS_EMPTY)) {
108 // remove line from linked list
109 line->prev->next = line->next;
110 line->next->prev = line->prev;
112 // set bits on revious line
113 if(CHECK_BIT(line->bits, IS_H1)) {
114 SET_BIT(line->prev->bits, IS_H1);
116 SET_BIT(line->prev->bits, IS_H2);
120 (line->text->delete)(line->text);
131 int markdown_analyse(cstring_t *text) {
134 equals = 0, hashes = 0,
135 stars = 0, minus = 0,
136 spaces = 0, other = 0;
138 // count leading spaces
139 offset = next_nonblank(text, 0);
141 // strip trailing spaces
142 for(eol = text->size; eol > offset && isspace(text->text[eol - 1]); eol--);
144 for(i = offset; i < eol; i++) {
146 switch(text->text[i]) {
147 case '=': equals++; break;
148 case '#': hashes++; break;
149 case '*': stars++; break;
150 case '-': minus++; break;
151 case ' ': spaces++; break;
152 default: other++; break;
158 hashes + stars + minus + spaces + other == 0) ||
161 text->text[offset] == '#' &&
162 text->text[offset+1] != '#')) {
164 SET_BIT(bits, IS_H1);
169 equals + hashes + stars + spaces + other == 0) ||
172 text->text[offset] == '#' &&
173 text->text[offset+1] == '#')) {
175 SET_BIT(bits, IS_H2);
181 text->text[offset] == '>') {
183 SET_BIT(bits, IS_QUOTE);
188 SET_BIT(bits, IS_CODE);
192 if((minus >= 3 && equals + hashes + stars + other == 0) ||
193 (stars >= 3 && equals + hashes + minus + other == 0)) {
195 SET_BIT(bits, IS_HR);
200 SET_BIT(bits, IS_EMPTY);
206 int is_utf8(char ch) {
210 int next_nonblank(cstring_t *text, int i) {
211 while ((i < text->size) && isspace((text->text)[i]))
216 int next_blank(cstring_t *text, int i) {
217 while ((i < text->size) && !isspace((text->text)[i]))