//
// 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;
}