// // hakihaki.c by Graham Toal; 30 minute hack on 14 May 2007. // // I lost my twiki wiki in a disk crash, and anyway I was fed up // with the wiki-spam it was getting, so when I rebuilt my machine // I didn't recreate the wiki. However there were some wiki // pages that were linked to from other sites, so in order to // recreate them, I built this trivial hack to create html files // from the twiki input files which had (mostly) survived the crash. // // This will *NOT* develop into a full wiki. It started off and // will always remain a quick hack. // #include <stdio.h> #include <stdlib.h> #include <string.h> void cleanup(int n, int lineno) { if (n != 0) { fprintf(stdout, "\n</UL></UL></UL></UL></UL></UL></UL><ADDRESS>GRAHAM! You messed up the wiki markup again!!! Detected at line %d</ADDRESS></BODY>\n</HTML>\n",lineno); } else { fprintf(stdout, "\n<ADDRESS><HR>This page generated by <A HREF=\"http://www.gtoal.com/src/hakihaki/hakihaki.c.html\">HakiHaki</A></ADDRESS>\n</BODY>\n</HTML>\n"); } exit(n); } #define exit(n) cleanup(n, __LINE__) int main(int argc, char **argv) { // This is pretty much the project specification: // Keeping track of indents // === xx ===for headings // ''''s for formatting // [] links of various sorts // -- sig? // WikiWords??? // maybe embedded HTML? int indent = 0; int nest[128]; int level = 0; // 0 means not in a list, > 0 means in a list int em = 0, bf = 0; char *s, title[128]; int c; nest[0] = 0; c = fgetc(stdin); if (c == '#') { s = title; for (;;) { c = fgetc(stdin); if (c == EOF) exit(1); if (c == '\n') break; *s++ = c; // 128 limit } *s = '\0'; } else { ungetc(c, stdin); strcpy(title, "HakiHaki page"); } fprintf(stdout, "<HTML>\n<HEAD>\n<TITLE>%s</TITLE>\n</HEAD>\n<BODY>\n", title); for (;;) { for (;;) { c = fgetc(stdin); if (c == EOF) { if (em != 0) fprintf(stdout, "</EM>"); if (bf != 0) fprintf(stdout, "</B>"); while (level > 0) { fprintf(stdout, "</UL>\n"); level -= 1; } fprintf(stdout, "<BR>"); exit(0); } if (c == ' ') { indent += 1; } else if (c == '\t') { // align to 8 char indent = (indent + 8) & (~7); } else { ungetc(c, stdin); break; } } // now, do we trigger anything based on previous indents? if (c == '*') { if ((level > 0) && (indent == nest[level])) { fprintf(stdout, "<LI>"); (void)fgetc(stdin); } else if ((level > 0) && (indent < nest[level])) { fprintf(stdout, "</UL><BR>\n<LI>"); (void)fgetc(stdin); level -= 1; } else { // deeper nest[++level] = indent; // 128 limit fprintf(stdout, "<UL>\n<LI>"); (void)fgetc(stdin); } } else if (c == '=') { int depth = 0; if (em != 0) fprintf(stdout, "</EM>"); if (bf != 0) fprintf(stdout, "</B>"); while (level > 0) { fprintf(stdout, "</UL>\n"); level -= 1; } fprintf(stdout, "<BR>"); for (;;) { c = fgetc(stdin); if (c == EOF) exit(1); if (c != '=') break; depth += 1; } if (depth == 1) fprintf(stdout, "<CENTER>"); fprintf(stdout, "\n<HR><H%0d>", depth+1); for (;;) { fputc(c, stdout); if (c == EOF) exit(1); c = fgetc(stdin); if (c == '=') break; } fprintf(stdout, "</H%0d>", depth+1); if (depth == 1) fprintf(stdout, "</CENTER>"); for (;;) { depth -= 1; if (depth == 0) break; c = fgetc(stdin); if (c == EOF) exit(1); if (c != '=') exit(1); } } else if (c == '\n') { if (level == 0) fprintf(stdout, "<P>"); else fprintf(stdout, "<BR>"); (void)fgetc(stdin);indent = 0; } else { if (indent < level) { fprintf(stdout, "</UL><BR>\n"); level -= 1; } if (indent != 0) fprintf(stdout, "<P>"); if (c == '#') (void)fgetc(stdin);// GT hack to escape leading characters (*, = etc) for (;;) { c = fgetc(stdin); if (c == EOF) { if (em != 0) fprintf(stdout, "</EM>"); if (bf != 0) fprintf(stdout, "</B>"); while (level > 0) { fprintf(stdout, "</UL>\n"); level -= 1; } fprintf(stdout, "<BR>"); exit(0); //NORMAL EXIT } if (c == '[') { c = fgetc(stdin); if (c == EOF) exit(1); if (c == '[') { fprintf(stdout, "<"); for (;;) { c = fgetc(stdin); if ((c == '\n') || (c == EOF)) exit(1); if (c == ']') break; fputc(c, stdout); } c = fgetc(stdin); if (c == EOF) exit(1); if (c != ']') exit(1); fprintf(stdout, ">"); } else { s = title; for (;;) { if ((c == ' ') || (c == ']')) break; if ((c == '\n') || (c == EOF)) exit(1); *s++ = c; c = fgetc(stdin); } *s = '\0'; if (strncmp(title, "wiki:Self:", strlen("wiki:Self:")) == 0) { fprintf(stdout, "<A HREF=\"../%s\">", title+strlen("wiki:Self:")); for (;;) { c = fgetc(stdin); if (c == EOF) exit(1); if (c == ']') break; if (c == '\n') exit(1); fputc(c, stdout); } fprintf(stdout, "</A>"); } else if (strncmp(title, "http", strlen("http")) == 0) { fprintf(stdout, "<A HREF=\"%s\">", title); for (;;) { c = fgetc(stdin); if (c == EOF) exit(1); if (c == ']') break; if (c == '\n') exit(1); fputc(c, stdout); } fprintf(stdout, "</A>"); } else { fprintf(stdout, "[%s%c", title, c); if (c == ' ') { for (;;) { c = fgetc(stdin); if (c == EOF) exit(1); fputc(c, stdout); if (c == ']') break; } } } } } else if (c == '\'') { int count = 1; c = fgetc(stdin); if (c == '\'') { // 2 c = fgetc(stdin); if ((c == '\'') && (em == 0)) { c = fgetc(stdin); //only for ungetc // we have 3 quotes if (bf == 0) { fprintf(stdout, "<B>"); } else { fprintf(stdout, "</B>"); } bf = 1-bf; } else { // we have 2 quotes if (em == 0) { fprintf(stdout, "<EM>"); } else { fprintf(stdout, "</EM>"); } em = 1-em; } } else { // we have 1 quote fputc('\'', stdout); } ungetc(c, stdin); } else fputc(c, stdout); if (c == '\n') break; } indent = 0; } } return 0; }