reading tasklists
[taskasaur.git] / parser.c
1
2 #include "headers/parser.h"
3
4 typedef struct State {
5     Board* board;
6     TodoList* cur_todolist;
7     TodoItem* cur_todoitem;
8     /* for use during processing */
9     char* last_block_text;
10 } State;
11
12 char* read_file(char* file_name, long* size);
13
14 /* processing */
15 void enter_todolist(State* state, char* list_name);
16 void exit_todolist(State* state);
17
18 void enter_todoitem(State* state, char* item_name);
19 void exit_todoitem(State* state);
20
21 void set_description(State* state, char* description);
22 void set_due(State* state, char* due); // make an acc date struct later
23 void add_subtask(State* state, char* subtask_name, SubTaskState subtask_state);
24
25 /* callbacks to parser */
26 int enter_block(MD_BLOCKTYPE type, void* detail, void* userdata);
27 int leave_block(MD_BLOCKTYPE type, void* detail, void* userdata);
28 int enter_span(MD_SPANTYPE type, void* detail, void* userdata);
29 int leave_span(MD_SPANTYPE type, void* detail, void* userdata);
30 int text(MD_TEXTTYPE type, const MD_CHAR* text, MD_SIZE size, void* userdata);
31 void debug_log(const char* msg, void* userdata);
32 void syntax(void);
33
34 const MD_PARSER parser = {
35     0,
36     MD_FLAG_TASKLISTS,
37     &enter_block,
38     &leave_block,
39     &enter_span,
40     &leave_span,
41     &text,
42     &debug_log,
43     &syntax
44 };
45
46 char*
47 read_file(char* file_name, long* size) 
48 { // apparently using seek isnt the greatest, may change to chunk reading later
49     FILE* file;
50     char* output;
51     long fsize;
52
53     file = fopen(file_name, "r");
54     if (file == NULL) {
55         printf("Something went wrong opening file\n");
56         return NULL;
57     }
58
59     fseek(file, 0, SEEK_END);
60     fsize = ftell(file);
61     fseek(file, 0, SEEK_SET);
62
63     output = malloc(fsize+1); // maybe error check malloc
64     fread(output, 1, fsize, file);
65     if (ferror(file)) {
66         printf("Something went wrong reading file\n");
67         fclose(file);
68         free(output);
69         return NULL;
70     }
71     output[fsize] = 0; // add null terminator
72     
73     /* clean up */
74     fclose(file);
75
76     /* return */
77     *size = fsize;
78     return output;
79 }
80
81 Board*
82 begin_parse(char* board_path)
83 {
84     const char* input_buffer;
85     long input_size;
86     State* state;
87     Board* new_board;
88
89     /* read entire file */
90     input_buffer = read_file(board_path, &input_size);
91
92     /* setup state */
93     state = malloc(sizeof(State));
94     state->cur_todolist = NULL;
95     state->cur_todoitem = NULL;
96
97     new_board = malloc(sizeof(Board));
98     new_board->todolist_list = malloc(0);
99     new_board->todolist_count = 0;
100     state->board = new_board;
101
102     md_parse(input_buffer, input_size, &parser, state);
103
104     /* finish calls */
105     exit_todolist(state);
106
107     free((char*)input_buffer);
108
109     return state->board;
110 }
111
112 void
113 enter_todolist(State* state, char* list_name)
114 {
115     TodoList* new_todolist;
116     
117     new_todolist = malloc(sizeof(TodoList));
118     new_todolist->list_name = list_name;
119     new_todolist->item_list = malloc(0);
120     new_todolist->item_count = 0;
121
122     state->cur_todolist = new_todolist;
123 }
124
125 void
126 exit_todolist(State* state)
127 {
128     Board* board;
129     TodoList** todolist_list;
130
131     if (state->cur_todolist == NULL) { 
132         return;
133     }
134
135     /* append new todolist to board */
136     board = state->board;
137     todolist_list = board->todolist_list;
138
139     board->todolist_count += 1;
140     todolist_list = realloc(todolist_list, board->todolist_count*sizeof(TodoList*));
141     todolist_list[board->todolist_count-1] = state->cur_todolist;
142     state->cur_todolist = NULL;
143
144     /* save */
145     board->todolist_list = todolist_list;
146
147 }
148
149 void
150 enter_todoitem(State* state, char* item_name)
151 {
152
153 }
154
155 void
156 exit_todoitem(State* state)
157 {
158
159 }
160
161 void
162 set_description(State* state, char* description)
163 {
164
165 }
166
167 void
168 set_due(State* state, char* due)
169 {
170
171 }
172
173 void
174 add_subtask(State* state, char* subtask_name, SubTaskState subtask_state)
175 {
176
177 }
178
179 int
180 enter_block(MD_BLOCKTYPE type, void* detail, void* userdata)
181 {
182     return 0;
183 }
184
185 int
186 leave_block(MD_BLOCKTYPE type, void* detail, void* userdata)
187 {
188     State* state;
189     state = (State*)userdata;
190
191     switch (type) {
192
193         case MD_BLOCK_H:
194
195             switch(((MD_BLOCK_H_DETAIL*)detail)->level) {
196
197                 case 1:
198                     printf("leave h1, %s\n", state->last_block_text);
199                 
200                 case 2:
201                     exit_todolist(state);
202                     enter_todolist(state, state->last_block_text);
203                     printf("leave h2, %s\n", state->last_block_text);
204                     break;
205                 case 3:
206                     printf("leave h3, %s\n", state->last_block_text);
207                     break;
208
209             }
210
211             break;
212
213         case MD_BLOCK_QUOTE:
214             printf("blockquote, %s\n", state->last_block_text);
215             break;
216
217         case MD_BLOCK_LI:
218             printf("todo, %s\n", state->last_block_text);
219             break;
220
221         // no need for default case for now :>
222     }
223     return 0;
224 }
225
226 int
227 enter_span(MD_SPANTYPE type, void* detail, void* userdata)
228 {
229
230
231     return 0;
232 }
233
234 int
235 leave_span(MD_SPANTYPE type, void* detail, void* userdata)
236 {
237     State* state;
238     state = (State*)userdata;
239     
240     switch (type) {
241         case MD_SPAN_STRONG:
242             printf("date, %s\n", state->last_block_text);
243             break;
244     }
245     return 0;
246 }
247
248 int
249 text(MD_TEXTTYPE type, const MD_CHAR* text, MD_SIZE size, void* userdata){
250
251     State* state;
252     char* content;
253
254     state = (State*)userdata;
255
256     content = malloc(size*sizeof(char)+1);
257     memcpy(content, text, size);
258     content[size] = 0;
259
260     /* printf("%s\n", content); */
261     state->last_block_text = content;
262     
263     return 0;
264 }
265
266 void
267 debug_log(const char* msg, void* userdata)
268 {
269     printf(msg);
270     return;
271 }
272
273 void 
274 syntax(void)
275 {
276     return;
277 }