#include #include #include #include #define ROWSIZE 256 FILE *infile; int width, height, j, k, ccount, mcount, anum, dnum; int apos, dpos; int acount, dcount; char inbuf[ROWSIZE]; /* Here is a lazy programmer's waste of space. */ char aspace[ROWSIZE][ROWSIZE]; char dspace[ROWSIZE][ROWSIZE]; char rowtext[10*ROWSIZE]; char tmp[ROWSIZE]; char title[80]; char author[80]; char copyright[80]; char matrix[ROWSIZE*ROWSIZE*10]; char actext[ROWSIZE][80]; char dctext[ROWSIZE][80]; char aclues[ROWSIZE*15*16]; char dclues[ROWSIZE*15*16]; void fgetsa(char *, int, FILE *); void main(int argc, char *argv[]) { /* Open the puzzle file. */ if (argc < 2) { printf("Usage: usaconv \n"); exit(1); } infile = fopen(argv[1], "r"); if (infile == NULL) { printf("Error opening %s.\n"); exit(1); } /* From here on we're assuming a non-corrupt puzzle file. An enhancement later could be to check for this. */ /* start reading stuff in */ fgetsa(inbuf, 80, infile); /**/ fgetsa(inbuf, 80, infile); /**/ fgetsa(title, 80, infile); fgetsa(inbuf, 80, infile); /*<AUTHOR>*/ fgetsa(author, 80, infile); fgetsa(inbuf, 80, infile); /*<COPYRIGHT>*/ fgetsa(copyright,80, infile); fgetsa(inbuf, 80, infile); /*<SIZE>*/ fgetsa(inbuf, 80, infile); height = width = 0 ; /* we calculate instead */ fgetsa(inbuf, 80, infile); /*<GRID>*/ /* Read in the first line of the solution/diagram and determine width */ fgetsa(&aspace[height][0], 80, infile); width = strlen(&aspace[height][0]); height++; while (1) { fgetsa(&aspace[height][0], 80, infile); if(strcmp(&aspace[height][0],"<ACROSS>")==0) goto didit; height++; } didit: /* Read and save across and down clues */ apos=dpos=0; while(1) { fgetsa(&actext[apos][0], 80, infile); if(strcmp(&actext[apos][0],"<DOWN>")==0)goto dida; apos++; } dida: while(1) { fgetsa(&dctext[dpos][0], 80, infile); if(feof(infile)) goto didd; dpos++; } didd: apos=dpos=0; /* Now we are ready to produce the LaTeX stuff for the puzzle diagram. Again we are assuming we have an unscrambled solution. How can we know this? Put on TODO list. */ /* We write to standard out. Lazy but effective. */ printf("\\documentclass{article}\n"); printf("\\usepackage{cwpuzzle}\n"); printf("\\title{%s}\n", title); printf("\\author{%s}\n", author); printf("\\date{%s}\n", copyright); printf("\\voffset -1in\n"); printf("\\hoffset -1in\n"); printf("\\begin{document}\n"); ccount = 0; mcount = 0; acount = dcount = 0; for (j=0; j<height; j++) { strcpy(rowtext,"\0"); for (k=0; k<width; k++) { /* Analyze position for across-number */ /* Left edge non-black followed by non-black */ anum = 0; if ( (k==0 && aspace[j][k]!='.' && aspace[j][k+1]!='.') || /* Previous black - nonblack - nonblack */ ( (k+1)<width && (k-1)>=0 && aspace[j][k]!='.' && aspace[j][k-1]=='.' && aspace[j][k+1]!='.' ) ){ ccount++; anum = ccount; } /* Analyze position for down-number */ dnum = 0; /* Top row non-black followed by non-black */ if ( (j==0 && aspace[j][k]!='.' && aspace[j+1][k]!='.') || /* Black above - nonblack - nonblack below */ ( (j-1)>=0 && (j+1)<height && aspace[j][k]!='.' && aspace[j-1][k]=='.' && aspace[j+1][k]!='.' ) ){ /* Don't double number the same space */ if (anum == 0) ccount++; dnum = ccount; } /* Now, if necessary, assign some clues and save them. */ if (anum != 0) { sprintf(&aclues[apos], "\\Clue{%d}{}{%s}\\\\\n", anum, actext[acount]); acount++; apos = strlen(aclues); } if (dnum != 0) { sprintf(&dclues[dpos], "\\Clue{%d}{}{%s}\\\\\n", dnum, dctext[dcount]); dcount++; dpos = strlen(dclues); } /* Concat the current info to the current row. */ strcat(rowtext, "|"); if (aspace[j][k] == '.') strcat(rowtext, "*"); else { /* see if we need a grid number */ if (dnum != 0) { sprintf(tmp, "[%d]", dnum); strcat(rowtext, tmp); } else if (anum != 0) { sprintf(tmp, "[%d]", anum); strcat(rowtext, tmp); } /* Put in solution letter */ /* this is for real */ if (aspace[j][k]== '&') strncat(rowtext, "\\", 1); strncat(rowtext, &aspace[j][k], 1); } } /* End of the row. Put in marker and output it. */ strcat(rowtext, "|."); sprintf(&matrix[mcount], "%s\n", rowtext); mcount = strlen(matrix); } /* That's it for the puzzle. */ /* Now output the clue section */ printf("\\begin{PuzzleClues}{\\textbf{Across}}\\\\\n"); for (j=0; j<strlen(aclues); j++){ printf("%c",aclues[j]); } printf("\\end{PuzzleClues}\n"); printf("\\begin{PuzzleClues}{\\textbf{Down}}\\\\\n"); for (j=0; j<strlen(dclues); j++){ printf("%c",dclues[j]); } printf("\\end{PuzzleClues}\n"); /* Now output the diagram */ printf("\\newpage\n"); printf("\\maketitle\n"); printf("\\begin{Puzzle}{%d}{%d}\n", width, height); printf("%s", matrix); printf("\\end{Puzzle}\n"); printf("\\end{document}\n"); exit(0); } void fgetsa(char *foo, int size, FILE *infile) { int i, oe; fgets(tmp, size, infile); tmp[strlen(tmp)-1] = '\0'; strcpy(foo, "\0"); oe = 0; for (i=0; i<strlen(tmp); i++) { if (tmp[i]=='$' || tmp[i] == '_' || tmp[i] =='&' || tmp[i] == '#') strcat(foo, "\\"); if (tmp[i] == '"') { if (oe == 0) { oe = 1; strcat(foo, "``"); } else { oe = 0; strcat(foo, "''"); } } else strncat(foo, &tmp[i], 1); } }