#include #include #include #include #include #include "tokens.h" #include "output.h" #include "util.h" typedef enum mode { NONE = 0, LIST = 1, CHECK = 2, OUTPUT = 4, PRETTY = 8, } mode; typedef enum outputformats { GOATNOTE, HTML, GROFF, } outputformats; outputformats outputformat; mode m = NONE; token tokens[1024]; int tokcount = 0; char *header = NULL, *footer = NULL; 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; if (strcmp(argv[i], "-c") == 0) m |= CHECK; if (strcmp(argv[i], "-o") == 0) { i++; if (!(i < argc)) eprint("expecet additional argument after -o!") ; 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; } if (strcmp(argv[i], "-p") == 0) m |= PRETTY; if (strcmp(argv[i], "-h") == 0) { i++; if (!(i < argc)) eprint("expecet additional argument after -h!"); header = argv[i]; } if (strcmp(argv[i], "-f") == 0) { i++; if (!(i < argc)) eprint("expecet additional argument after -f!"); footer = argv[i]; } } 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; case ' ': case '\n': case '\t': break; default: eprint("unknown char found!"); } } if (header != NULL) printf("%s\n", header); if ((m & LIST) == LIST) { formatcheck(); for (int i = 0; i < tokcount; i++) { if (tokens[i].type == HEADING) { if ((m & PRETTY) == PRETTY) printf("\e[1m%s\e[0m \e[4m%s\e[0m \e[2m%s\e[0m\n", tokens[i].data, tokens[i+1].data, tokens[i+2].data); else printf("%s %s %s\n", tokens[i].data, tokens[i+1].data, tokens[i+2].data); i += 2; } } } if ((m & CHECK) == CHECK) { formatcheck(); } if ((m & OUTPUT) == 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; } } } if (footer != NULL) printf("%s\n", footer); return 0; }