/** ** genHTML - generate HTML pages ** ** CREATED: 99.07.24 ABS copied from t_filter ** MODIFIED: 99.07.25 ABS hacked ** MODIFIED: 99.08.01 ABS got parser HTML output working ** MODIFIED: 99.08.29 ABS lat/lon input ** MODIFIED: 99.09.01 ABS lat/lon output ** MODIFIED: 99.09.03 ABS added walks ** **/ #include "genHTML.h" main(argc, argv) int argc; char** argv; { /* declare functions */ double atof(); double sqrt(); NODE *doubleInsert(); NODE *doubleDelete(); /* declare local variables */ NODE *currentYear; PLACE *oldPlace; PLACE *newPlace; PLACE *currentPlace; PLACE *otherPlace; THING *oldThing; THING *newThing; THING *currentThing; TRIP *oldTrip; TRIP *newTrip; TRIP *currentTrip; JUMP *oldJump; JUMP *newJump; JUMP *currentJump; int n, m, o; /* iteration variables */ int numPlaces; int numLines; int length; int c, v, t, l, r, j; char d; int lat1, lat2, lat3; int lon1, lon2, lon3; double tempLat, tempLon; char latChar, lonChar; char lat1S[MAX_LINE]; char lat2S[MAX_LINE]; char lat3S[MAX_LINE]; char lon1S[MAX_LINE]; char lon2S[MAX_LINE]; char lon3S[MAX_LINE]; double distance, deltaLat, deltaLon; double divisor, sign; char input_line[MAX_LINE]; char keyword[MAX_LINE]; char value[MAX_LINE]; char tempFileName[MAX_LINE]; FILE *tempFile; /* initialize global variables (including parameters) */ defaultParms(); parseArgs(argc, argv); /* initialize local variables */ YearListHeader = (NODE *)NULL; PlaceListHeader = (PLACE *)NULL; oldPlace = (PLACE *)NULL; newPlace = (PLACE *)NULL; oldThing = (THING *)NULL; newThing = (THING *)NULL; length = 1; numLines = 0; numPlaces = 0; /* read */ while (length) { length = getl(stdin, input_line, MAX_LINE); if (length) { numLines++; for (c = 0; input_line[c] != ':'; c++) { keyword[c] = input_line[c]; } keyword[c] = (char)0; v = 0; if (input_line[c++] != ':') { /* skip colon */ fprintf(stderr, "%s: ERROR: no colon after keyword %s\n", argv[0], keyword); exit(1); } while ((input_line[c] != (char)0) && (input_line[c] != (char)10)) { value[v++] = input_line[c++]; } value[v] = (char)0; #ifdef DEBUG if (Debug != FALSE) { fprintf(stderr, "%s: DEBUG: keyword = %s\n", argv[0], keyword); fprintf(stderr, "%s: DEBUG: value = %s\n", argv[0], value); } #endif if (strcmp(keyword,"Handle") == 0) { numPlaces++; if (newPlace != (PLACE *)NULL) oldPlace = newPlace; /* allocate new place */ newPlace = (PLACE *) malloc(sizeof(PLACE)); if (newPlace == NULL) { fprintf(stderr, "%s: ERROR: out of memory (#1)\n", argv[0]); exit(1); } if (numPlaces == 1) { PlaceListHeader = newPlace; } newPlace->thingListHeader = (THING *)NULL; newPlace->tripListHeader = (TRIP *)NULL; newPlace->jumpListHeader = (JUMP *)NULL; newPlace->Prev = oldPlace; newPlace->Next = (PLACE *)NULL; if (oldPlace != (PLACE *)NULL) { oldPlace->Next = newPlace; } strcpy(newPlace->handle, value); /* Handle */ } else if (strcmp(keyword,"Name") == 0) { strcpy(newPlace->name, value); /* Name */ } else if (strcmp(keyword,"Lat/Lon") == 0) { lat1 = lat2 = lat3 = lon1 = lon2 = lon3 = 0; /* parse Lat */ m = 0; d = value[m]; while (isdigit(d)) { lat1S[m] = d; m++; d = value[m]; } lat1S[m] = (char)0; lat1 = atoi(lat1S); /* degrees */ if (d != ':') { fprintf(stderr, "%s: ERROR: Lat delimiter (%c) (ASCII %d) should be colon (:)\n", d, d, argv[0]); exit(1); } m++; o = 0; d = value[m]; while (isdigit(d)) { lat2S[o] = d; m++; o++; d = value[m]; } lat2S[o] = (char)0; lat2 = atoi(lat2S); /* minutes (without fractional part) */ if (d != ':' && d != '.') { fprintf(stderr, "%s: ERROR: Lat delimiter (%c) (ASCII %d) should be colon (:) or decimal point (.)\n", d, d, argv[0]); exit(1); } if (d == ':') divisor = 60.0; if (d == '.') divisor = 100.0; m++; o = 0; d = value[m]; while (isdigit(d)) { lat3S[o] = d; m++; o++; d = value[m]; } lat3S[o] = (char)0; lat3 = atoi(lat3S); /* seconds (without fractional part) or decimal degrees */ if (Debug != FALSE) { fprintf(stderr, "%s: DEBUG: lat1 = %d\n", argv[0], lat1); fprintf(stderr, "%s: DEBUG: lat2 = %d\n", argv[0], lat2); fprintf(stderr, "%s: DEBUG: lat3 = %d\n", argv[0], lat3); } if (d != 'N' && d != 'S') { fprintf(stderr, "%s: ERROR: Lat direction (%c) (ASCII %d) should be N or S\n", argv[0], d, d); exit(1); } if (d == 'N') sign = 1.0; /* +1 */ if (d == 'S') sign = -1.0; /* -+1 */ newPlace->lat = sign*((double)lat1 + ((double)lat2)/60.0 + ((double)lat3)/(60.0*divisor)); /* Lat */ m++; d = value[m]; if (d != '/') { fprintf(stderr, "%s: ERROR: Lat/Lon delimiter (%c) (ASCII %d) should be /\n", argv[0], d, d); exit(1); } /* parse Lon */ m++; o = 0; d = value[m]; while (isdigit(d)) { lon1S[o] = d; m++; o++; d = value[m]; } lon1S[o] = (char)0; lon1 = atoi(lon1S); /* degrees */ if (d != ':') { fprintf(stderr, "%s: ERROR: Lon delimiter (%c) (ASCII %d) should be colon (:)\n", d, d, argv[0]); exit(1); } m++; o = 0; d = value[m]; while (isdigit(d)) { lon2S[o] = d; m++; o++; d = value[m]; } lon2S[o] = (char)0; lon2 = atoi(lon2S); /* minutes (without fractional part) */ if (d != ':' && d != '.') { fprintf(stderr, "%s: ERROR: Lon delimiter (%c) (ASCII %d) should be colon (:) or decimal point (.)\n", d, d, argv[0]); exit(1); } if (d == ':') divisor = 60.0; if (d == '.') divisor = 100.0; m++; o = 0; d = value[m]; while (isdigit(d)) { lon3S[o] = d; m++; o++; d = value[m]; } lon3S[o] = (char)0; lon3 = atoi(lon3S); /* seconds (without fractional part) or decimal degrees */ if (Debug != FALSE) { fprintf(stderr, "%s: DEBUG: lon1 = %d\n", argv[0], lon1); fprintf(stderr, "%s: DEBUG: lon2 = %d\n", argv[0], lon2); fprintf(stderr, "%s: DEBUG: lon3 = %d\n", argv[0], lon3); } if (d != 'E' && d != 'W') { fprintf(stderr, "%s: ERROR: Lon direction (%c) (ASCII %d) should be E or S\n", argv[0], d, d); exit(1); } if (d == 'E') sign = 1.0; /* +1 */ if (d == 'W') sign = -1.0; /* -+1 */ newPlace->lon = sign*((double)lon1 + ((double)lon2)/60.0 + ((double)lon3)/(60.0*divisor)); /* Lon */ } else if (strcmp(keyword,"StartDate") == 0) { newPlace->startDate = atoi(value); /* StartDate */ YearListHeader = doubleInsert(YearListHeader, newPlace->startDate); } else if (strcmp(keyword,"EndDate") == 0) { newPlace->endDate = atoi(value); /* EndDate */ YearListHeader = doubleInsert(YearListHeader, newPlace->endDate); } else if (strcmp(keyword,"NumThings") == 0) { newPlace->numThings = atoi(value); /* NumThings */ oldThing = (THING *)NULL; for (t = 0; t < newPlace->numThings; t++) { /* allocate new thing */ newThing = (THING *) malloc(sizeof(THING)); if (newThing == NULL) { fprintf(stderr, "%s: ERROR: out of memory (#2)\n", argv[0]); exit(1); } if (t == 0) { newPlace->thingListHeader = newThing; } newThing->Prev = oldThing; newThing->Next = (THING *)NULL; if (oldThing != (THING *)NULL) { oldThing->Next = newThing; } for (l = 0; l < 5; l++) { /* 5 input lines for things */ length = getl(stdin, input_line, MAX_LINE); if (length) { numLines++; for (c = 0; isdigit(input_line[c]) == FALSE; c++) { keyword[c] = input_line[c]; } keyword[c] = (char)0; v = 0; { int d; char digit[2]; digit[0] = input_line[c++]; digit[1] = (char)0; d = atoi(digit); if (d != t + 1) { fprintf(stderr, "%s: ERROR: wrong thing number %d (should be %d) for keyword %s\n", argv[0], d, t + 1, keyword); exit(1); } } if (input_line[c++] != ':') { /* skip colon */ fprintf(stderr, "%s: ERROR: no colon after keyword %s\n", argv[0], keyword); exit(1); } while ((input_line[c] != (char)0) && (input_line[c] != (char)10)) { value[v++] = input_line[c++]; } value[v] = (char)0; #ifdef DEBUG if (Debug != FALSE) { fprintf(stderr, "%s: DEBUG: thing keyword = %s\n", argv[0], keyword); fprintf(stderr, "%s: DEBUG: thing value = %s\n", argv[0], value); } #endif if (strcmp(keyword,"ThingPic") == 0) { strcpy(newThing->pic, value); /* ThingPic */ } else if (strcmp(keyword,"ThingTxt") == 0) { strcpy(newThing->txt, value); /* ThingTxt */ } else if (strcmp(keyword,"ThingCat") == 0) { strcpy(newThing->cat, value); /* ThingCat */ } else if (strcmp(keyword,"ThingStartDate") == 0) { newThing->startDate = atoi(value); YearListHeader = doubleInsert(YearListHeader, newThing->startDate); } else if (strcmp(keyword,"ThingEndDate") == 0) { newThing->endDate = atoi(value); YearListHeader = doubleInsert(YearListHeader, newThing->endDate); } else { /* error: unknown thing keyword */ fprintf(stderr, "%s: ERROR: illegal thing keyword: %s\n", argv[0], keyword); exit(1); } } else { fprintf(stderr, "%s: ERROR: not enough things\n", argv[0]); exit(1); } } oldThing = newThing; } } else if (strcmp(keyword,"NumTrips") == 0) { newPlace->numTrips = atoi(value); /* NumTrips */ oldTrip = (TRIP *)NULL; for (r = 0; r < newPlace->numTrips; r++) { /* allocate new trip */ newTrip = (TRIP *) malloc(sizeof(TRIP)); if (newTrip == NULL) { fprintf(stderr, "%s: ERROR: out of memory (#2)\n", argv[0]); exit(1); } if (r == 0) { newPlace->tripListHeader = newTrip; } newTrip->Prev = oldTrip; newTrip->Next = (TRIP *)NULL; if (oldTrip != (TRIP *)NULL) { oldTrip->Next = newTrip; } for (l = 0; l < 7; l++) { /* 7 input lines for trips */ length = getl(stdin, input_line, MAX_LINE); if (length) { numLines++; for (c = 0; isdigit(input_line[c]) == FALSE; c++) { keyword[c] = input_line[c]; } keyword[c] = (char)0; v = 0; { int d; char digit[2]; digit[0] = input_line[c++]; digit[1] = (char)0; d = atoi(digit); if (d != r + 1) { fprintf(stderr, "%s: ERROR: wrong trip number %d (should be %d) for keyword %s\n", argv[0], d, r + 1, keyword); exit(1); } } if (input_line[c++] != ':') { /* skip colon */ fprintf(stderr, "%s: ERROR: no colon after keyword %s\n", argv[0], keyword); exit(1); } while ((input_line[c] != (char)0) && (input_line[c] != (char)10)) { value[v++] = input_line[c++]; } value[v] = (char)0; #ifdef DEBUG if (Debug != FALSE) { fprintf(stderr, "%s: DEBUG: trip keyword = %s\n", argv[0], keyword); fprintf(stderr, "%s: DEBUG: trip value = %s\n", argv[0], value); } #endif if (strcmp(keyword,"TripName") == 0) { strcpy(newTrip->name, value); /* TripName */ } else if (strcmp(keyword,"TripPic") == 0) { strcpy(newTrip->pic, value); /* TripPic */ } else if (strcmp(keyword,"TripTxt") == 0) { strcpy(newTrip->txt, value); /* TripTxt */ } else if (strcmp(keyword,"TripToHandle") == 0) { strcpy(newTrip->toHandle, value); } else if (strcmp(keyword,"TripStartDate") == 0) { newTrip->startDate = atoi(value); YearListHeader = doubleInsert(YearListHeader, newTrip->startDate); } else if (strcmp(keyword,"TripEndDate") == 0) { newTrip->endDate = atoi(value); YearListHeader = doubleInsert(YearListHeader, newTrip->endDate); } else if (strcmp(keyword,"TripHours") == 0) { newTrip->hours = atoi(value); } else { /* error: unknown trip keyword */ fprintf(stderr, "%s: ERROR: illegal trip keyword: %s\n", argv[0], keyword); exit(1); } } else { fprintf(stderr, "%s: ERROR: not enough trips\n", argv[0]); exit(1); } } oldTrip = newTrip; } } else if (strcmp(keyword,"NumJumps") == 0) { newPlace->numJumps = atoi(value); /* NumJumps */ oldJump = (JUMP *)NULL; for (j = 0; j < newPlace->numJumps; j++) { /* allocate new jump */ newJump = (JUMP *) malloc(sizeof(JUMP)); if (newJump == NULL) { fprintf(stderr, "%s: ERROR: out of memory (#2)\n", argv[0]); exit(1); } if (j == 0) { newPlace->jumpListHeader = newJump; } newJump->Prev = oldJump; newJump->Next = (JUMP *)NULL; if (oldJump != (JUMP *)NULL) { oldJump->Next = newJump; } for (l = 0; l < 6; l++) { /* 6 input lines for jumps */ length = getl(stdin, input_line, MAX_LINE); if (length) { numLines++; for (c = 0; isdigit(input_line[c]) == FALSE; c++) { keyword[c] = input_line[c]; } keyword[c] = (char)0; v = 0; { int d; char digit[2]; digit[0] = input_line[c++]; digit[1] = (char)0; d = atoi(digit); if (d != j + 1) { fprintf(stderr, "%s: ERROR: wrong jump number %d (should be %d) for keyword %s\n", argv[0], d, j + 1, keyword); exit(1); } } if (input_line[c++] != ':') { /* skip colon */ fprintf(stderr, "%s: ERROR: no colon after keyword %s\n", argv[0], keyword); exit(1); } while ((input_line[c] != (char)0) && (input_line[c] != (char)10)) { value[v++] = input_line[c++]; } value[v] = (char)0; #ifdef DEBUG if (Debug != FALSE) { fprintf(stderr, "%s: DEBUG: jump keyword = %s\n", argv[0], keyword); fprintf(stderr, "%s: DEBUG: jump value = %s\n", argv[0], value); } #endif if (strcmp(keyword,"JumpName") == 0) { strcpy(newJump->name, value); } else if (strcmp(keyword,"JumpPic") == 0) { strcpy(newJump->pic, value); } else if (strcmp(keyword,"JumpTxt") == 0) { strcpy(newJump->txt, value); } else if (strcmp(keyword,"JumpTargetDate") == 0) { newJump->targetDate = atoi(value); YearListHeader = doubleInsert(YearListHeader, newJump->targetDate); } else if (strcmp(keyword,"JumpStartDate") == 0) { newJump->startDate = atoi(value); YearListHeader = doubleInsert(YearListHeader, newJump->startDate); } else if (strcmp(keyword,"JumpEndDate") == 0) { newJump->endDate = atoi(value); YearListHeader = doubleInsert(YearListHeader, newJump->endDate); } else { /* error: unknown jump keyword */ fprintf(stderr, "%s: ERROR: illegal jump keyword: %s\n", argv[0], keyword); exit(1); } } else { fprintf(stderr, "%s: ERROR: not enough jumps\n", argv[0]); exit(1); } } oldJump = newJump; } } else { /* error: unknown keyword */ fprintf(stderr, "%s: ERROR: illegal keyword: %s\n", argv[0], keyword); exit(1); } } } if (Debug != FALSE) { fprintf(stderr, "%s: DEBUG: numLines = %d\n", argv[0], numLines); fprintf(stderr, "%s: DEBUG: numPlaces = %d\n", argv[0], numPlaces); fprintf(stderr, "%s: DEBUG: PlaceListHeader->handle = %s\n", argv[0], PlaceListHeader->handle); fprintf(stderr, "%s: DEBUG: PlaceListHeader->name = %s\n", argv[0], PlaceListHeader->name); fprintf(stderr, "%s: DEBUG: PlaceListHeader->lat = %g\n", argv[0], PlaceListHeader->lat); fprintf(stderr, "%s: DEBUG: PlaceListHeader->lon = %g\n", argv[0], PlaceListHeader->lon); fprintf(stderr, "%s: DEBUG: PlaceListHeader->startDate = %d\n", argv[0], PlaceListHeader->startDate); fprintf(stderr, "%s: DEBUG: PlaceListHeader->endDate = %d\n", argv[0], PlaceListHeader->endDate); fprintf(stderr, "%s: DEBUG: PlaceListHeader->numThings = %d\n", argv[0], PlaceListHeader->numThings); fprintf(stderr, "%s: DEBUG: PlaceListHeader->numTrips = %d\n", argv[0], PlaceListHeader->numTrips); fprintf(stderr, "%s: DEBUG: PlaceListHeader->numJumps = %d\n", argv[0], PlaceListHeader->numJumps); fprintf(stderr, "%s: INFO: distance from 0,0 is %f\n", argv[0], sqrt(newPlace->lat*newPlace->lat + newPlace->lon*newPlace->lon)); } /* write */ if (Check == FALSE) { fprintf(stdout, "\n"); fprintf(stdout, "\n"); fprintf(stdout, "TBH HTML Map index\n"); fprintf(stdout, "\n"); fprintf(stdout, "\n"); fprintf(stdout, "

TBH HTML Map index

\n"); n = 0; for (currentYear = YearListHeader; currentYear != NULL; currentYear=currentYear->Next) { for (currentPlace = PlaceListHeader; currentPlace != NULL; currentPlace = currentPlace->Next) { /* place */ sprintf(tempFileName, "%s%d.html", currentPlace->handle, currentYear->Year); fprintf(stdout, "%s
\n", tempFileName, tempFileName); tempFile = fopen(tempFileName, "a"); fprintf(tempFile, "\n"); fprintf(tempFile, "\n"); fprintf(tempFile, "%s, %d\n", currentPlace->name, currentYear->Year); fprintf(tempFile, "\n"); fprintf(tempFile, "\n"); fprintf(tempFile, "

%s, %d

\n", currentPlace->name, currentYear->Year); /* lat/lon */ tempLat = currentPlace->lat; latChar = 'N'; if (tempLat < 0.0) { tempLat = tempLat*-1.0; latChar = 'S'; } tempLon = currentPlace->lon; lonChar = 'E'; if (tempLon < 0.0) { tempLon = tempLon*-1.0; lonChar = 'W'; } lat1 = (int)tempLat; lon1 = (int)tempLon; fprintf(tempFile, "latitude= %d:%5.2f%c / \n", lat1, (tempLat - (double)lat1)*60.0, latChar); fprintf(tempFile, "longitude= %d:%5.2f%c
\n", lon1, (tempLon - (double)lon1)*60.0, lonChar); /* things */ if (currentPlace->numThings) { fprintf(tempFile, "

Things

\n"); currentThing = currentPlace->thingListHeader; for (t = 0; t < currentPlace->numThings; t++) { if ((currentThing->startDate <= currentYear->Year) && (currentThing->endDate >= currentYear->Year)) { fprintf(tempFile, "
\n", currentThing->pic); fprintf(tempFile, "%s
\n", currentThing->txt); } if (currentThing->Next != (THING *)NULL) { currentThing = currentThing->Next; } } } /* trips */ if (currentPlace->numTrips) { fprintf(tempFile, "

Trips

\n"); currentTrip = currentPlace->tripListHeader; for (r = 0; r < currentPlace->numTrips; r++) { if ((currentTrip->startDate <= currentYear->Year) && (currentTrip->endDate >= currentYear->Year)) { fprintf(tempFile, "%s to %s (%d hours)
\n", currentTrip->toHandle, currentYear->Year, currentTrip->name, currentTrip->toHandle, currentTrip->hours); fprintf(tempFile, "
\n", currentTrip->pic); fprintf(tempFile, "%s\n", currentTrip->txt); } if (currentTrip->Next != (TRIP *)NULL) { currentTrip = currentTrip->Next; } } } /* jumps */ if (currentPlace->numJumps) { fprintf(tempFile, "

Jumps

\n"); currentJump = currentPlace->jumpListHeader; for (r = 0; r < currentPlace->numJumps; r++) { if ((currentJump->startDate <= currentYear->Year) && (currentJump->endDate >= currentYear->Year)) { fprintf(tempFile, "Jump \"%s\" to year %d
\n", currentPlace->handle, currentJump->targetDate, currentJump->name, currentJump->targetDate); fprintf(tempFile, "
\n", currentJump->pic); fprintf(tempFile, "%s
\n", currentJump->txt); } if (currentJump->Next != (JUMP *)NULL) { currentJump = currentJump->Next; } } } /* walks */ fprintf(tempFile, "

Walks

\n"); for (otherPlace = PlaceListHeader; otherPlace != NULL; otherPlace = otherPlace->Next) { if (otherPlace != currentPlace) { deltaLat = currentPlace->lat - otherPlace->lat; deltaLon = currentPlace->lon - otherPlace->lon; distance = 60.0*sqrt(deltaLat*deltaLat + deltaLon*deltaLon); fprintf(tempFile, "Walk to %s (%5.2f miles, %5.2f hours)
\n", otherPlace->handle, currentYear->Year, otherPlace->name, distance, distance/3.0); } } fprintf(tempFile, "\n"); fclose(tempFile); } } fprintf(stdout, "\n"); fprintf(stdout, "\n"); } } /* end main */ /* * defaultParms - initialize global variables */ defaultParms() { Debug = FALSE; Check = FALSE; FloatParam = 442.0; IntParam = 28743; } /* end defaultParms() */ /* * parseArgs - parse arguments into global variables */ parseArgs(argc, argv) int argc; char** argv; { int i; for (i = 0; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'C' : Check = TRUE; break; case 'D' : Debug = TRUE; break; case 'f' : FloatParam = atof(&argv[++i][0]); break; case 'h' : help(argv); exit(0); break; case 'i' : IntParam = atoi(&argv[++i][0]); break; case 'u' : usage(argv); exit(0); break; default: fprintf(stderr, "%s: ERROR: illegal flag: %s\n", argv[0], argv[i]); usage(argv); exit(1); break; } /* end switch */ } /* end if */ } /* end for(i) */ } /* end parseArgs() */ /* * getl - modified from Kernighan & Ritchie to take stream */ int getl(stream, s, lim) /* get line into s, return length */ FILE *stream; char s[]; int lim; { int c, i; i = 0; while (--lim > 0 && (c = getc(stream)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return(i); } /* end getl() */