#include #include #include #include #include #include "tokens.h" #include "output.h" #include "util.h" typedef enum mode { NONE, LIST, CHECK, OUTPUT, } mode; typedef enum outputformats { GOATNOTE, HTML, GROFF, } outputformats; outputformats outputformat; mode m = NONE; token tokens[1024]; int tokcount = 0; char *stripwhitespace(char *expr) { while (isblank(expr[0])) expr++; while (isblank(expr[strlen(expr) - 1])) expr[strlen(expr) - 1] = 0; return expr; } void formatcheck() { types prev = NIL; for (int i = 0; i < tokcount; i++) { switch (prev) { case NIL: if (tokens[i].type != HEADING) eprint("Expected heading!"); break; case HEADING: if (tokens[i].type != DATE) eprint("Expected date"); break; case DATE: if (tokens[i].type != TODO) eprint("Expected todo|done marker"); break; } prev = tokens[i].type; } } int readuntil(char *file, int off, char end, types t) { int j = 0; char tok[256]; off++; while (file[off] != end) { if (file[off] == 0) eprint("Never closed expression!") ; tok[j] = file[off]; off++; j++; } tok[j] = 0; memcpy(tokens[tokcount].data, stripwhitespace(tok), 256); tokens[tokcount].type = t; tokcount++; return off; } int main(int argc, char **argv) { for (int i = 0; i < argc && argc != 1; i++) { if (strcmp(argv[i], "-l") == 0) m = LIST; else if (strcmp(argv[i], "-c") == 0) m = CHECK; else if (strcmp(argv[i], "-o") == 0) { i++; if (strcmp(argv[i], "goatnote") == 0) outputformat = GOATNOTE; else if (strcmp(argv[i], "html") == 0) outputformat = HTML; else if (strcmp(argv[i], "groff") == 0) outputformat = GROFF; m = OUTPUT; } } char file[INT16_MAX]; int i; char c; while ((c = getchar()) != EOF) { file[i] = c; i++; } file[i] = 0; for (i = 0; i < strlen(file); i++) { switch (file[i]) { case '*': i = readuntil(file, i, '*', HEADING); break; case '[': i = readuntil(file, i, ']', DATE); break; case '{': i = readuntil(file, i, '}', TODO); break; case '-': i = readuntil(file, i, '\n', BULLET); break; } } switch (m) { case LIST: for (int i = 0; i < tokcount; i++) if (tokens[i].type == HEADING) printf("%s\n", tokens[i].data); break; case CHECK: formatcheck(); break; case OUTPUT: formatcheck(); for (int i = 0; i < tokcount; i++){ switch (outputformat) { case HTML: printashtml(tokens[i]); break; case GOATNOTE: printasgn(tokens[i]); break; case GROFF: printasgroff(tokens[i]); break; } } case NONE: return 0; } return 0; }