/* * Dominic Jonak (dom@cmu.edu) * Autogen v1.8 (06/16/2010) * * Description: Website creation program, merges a content (source.txt) * and layout (layout.html) file. Assumes very strict * structure for both. * * Feel free to use the code, just don't remove this comment. * * Disclaimer: It's not finished so don't complain if it's not * perfect. Don't expect any support either. */ #define _GNU_SOURCE #include #include #include #include const int stripComments=1;/* whether comments should be stripped out or kept */ int numSections=0; char **sectionNames=NULL; char **sectionTexts=NULL; void addSectionName(const char *s){ numSections++; sectionNames = (char **)realloc(sectionNames, numSections * sizeof(char *)); sectionNames[numSections-1] = strdup(s); } int numCategories=0; char **categoryNames=NULL; char **capCategoryNames=NULL; void addCategoryName(const char *s){ numCategories++; categoryNames = (char **)realloc(categoryNames, numCategories * sizeof(char *)); categoryNames[numCategories-1] = strdup(s); } void makeCapCategoryNames(){ int i; capCategoryNames = (char **)malloc(numCategories * sizeof(char *)); for(i=0;i", buf))break; addSectionName(buf); } /* if the first section is the count, remove it */ if(numSections>1 && numSections-1 == atoi(sectionNames[0])){ sectionNames = sectionNames+1; numSections--; } printf("Read %d sections:\n", numSections); for(i=0;i0 && isspace(addedText[addedlen-1]))addedlen--; ret = (char *)realloc(oldText, oldlen + addedlen + 2); /* add a newline between concats */ /*if(oldlen)ret[oldlen++]='\n';*/ memcpy(ret+oldlen, addedText, addedlen); ret[oldlen+addedlen]='\0'; return ret; } char *readLayoutSection(FILE *f){ char buf[1024]; char commentBuf[sizeof(buf)]; char *ret=NULL; while(1){ if(!fgets(buf, sizeof(buf), f)){ if(feof(f))break; fprintf(stderr, "Error reading layout section\n"); exit(-1); } /* check if this line is a comment */ if(1 == sscanf(buf, "", commentBuf)){ /* check if this comment signals the end of the current section */ if(-1 != getSectionIndex(commentBuf))break; /* this is an internal comment, optionally strip it out */ if(stripComments)continue; } ret = myconcat(ret, buf); } return ret; } void readLayoutSections(FILE *f){ int i; sectionTexts = (char **)malloc((numSections+1) * sizeof(char *)); for(i=0;i1 && numCategories-1 == atoi(categoryNames[0])){ categoryNames = categoryNames+1; numCategories--; } makeCapCategoryNames(); printf("Read %d categories:\n", numCategories); for(i=0;i=numColorSteps) i = numColorSteps; fprintf(f, "%c", c); } void writeTitle(FILE *f, const char *title){ /* put this in to get a gradient effect */ #if 0 int len = strlen(title); int k; for(k=0;k0;k--) buildFont(f, k, title[len-k]); fprintf(f, "\n"); #else fprintf(f, "%s\n", title); #endif printf("%s\n", title); } void writeCategories(FILE *f){ int i; char linkHTML[256]; for(i=0;i%s

\n", capCategoryNames[i]); } } void writeLink(FILE *f, char *link){ char linkname[256], linkURL[256]; if(2 != sscanf(link, "%s %s", linkURL, linkname)){ fprintf(stderr, "Error creating link from \"%s\"\n", link); exit(-1); } /* support for multi-word link texts */ strcpy(linkname, strstr(link+strlen(linkURL), linkname)); fprintf(f, "
  • %s\n", linkURL, linkname); } char *extractSectionName(char *data, char **rest){ int i=0; *rest = NULL; if(!data || '&' != data[0])return NULL; data++;/* skip the '&' */ while(1){ /* advance to the end of the first token */ if( (data[i]) && !isspace(data[i]) ){ i++; continue; } /* make sure it ends with a ';' */ if(';' != data[i-1])return NULL; /* pull out and data after the token and save it in rest */ *rest = &data[i]; while( **rest && isspace(**rest) )(*rest)++; while(**rest && isspace((*rest)[strlen(*rest)-1]))(*rest)[strlen(*rest)-1]='\0'; data[i-1] = '\0'; /* make sure it's a valid section */ if(strcasecmp("end", data) && -1 == getSectionIndex(data)){ data[i-1] = ';'; return NULL; } break; } return data; } void readPageSource(FILE *f){ char linebuf[1024]; char *sectionbuf; char *restOfLine=NULL; FILE *output=NULL; char lastSection[sizeof(linebuf)]; int firstLineInSection=1; lastSection[0]='\0'; if(!currentHTML){ fprintf(stderr, "Have no html file to write too...\n"); exit(-1); } output = fopen(currentHTML, "w"); if(!output){ fprintf(stderr, "Unable to write to \"%s\"\n", currentHTML); exit(-1); } printf("%20s: ", currentHTML); while(1){ /* read each line */ if(!fgets(linebuf, sizeof(linebuf), f)){ fprintf(stderr, "Error bad source for %s\n", currentHTML); exit(-1); } /* if(strlen(linebuf)== sizeof(linebuf)-1){ fprintf(stderr, "Buffer too small for %s\n", currentHTML); exit(-1); } */ if(linebuf[strlen(linebuf)-1] == '\n') linebuf[strlen(linebuf)-1] = '\0'; if((sectionbuf = extractSectionName(linebuf, &restOfLine))){ /*fprintf(output, "\n", sectionbuf);*/ firstLineInSection=1; if(!strcasecmp("end", sectionbuf)){ /* reached end */ /*printf("%s: Reached end\n", currentHTML);*/ fprintf(output, "%s\n", sectionTexts[numSections]); break; }else{ if(!strcasecmp(sectionbuf, "right")) writeCategories(output); else if(!strcasecmp(sectionbuf, "bottom") && strcasecmp(lastSection, "right")){ /*fprintf(output, "\n", "right");*/ fprintf(output, "%s\n", sectionTexts[getSectionIndex("right")]); writeCategories(output); } /* insert the specified section */ /*printf("%s: Inserting section %s\n", currentHTML, sectionbuf);*/ /*fprintf(output, "\n", sectionbuf);*/ fprintf(output, "%s", sectionTexts[getSectionIndex(sectionbuf)]); if(restOfLine) fprintf(output, "%s", restOfLine); strcpy(lastSection, sectionbuf); } }else{ /* not a comment, write this */ /*printf("%s/%s: Writing source \"%s\"\n", currentHTML, lastSection, linebuf);*/ if(!strcasecmp(lastSection, "bottom")) writeLink(output, linebuf); else if(!strcasecmp(lastSection, "top")) writeTitle(output, linebuf); else{ /* remove leading whitespace */ char *s = linebuf; while(*s && isspace(*s))s++; /* add a newline if appropriate */ if(firstLineInSection) firstLineInSection=0; else fprintf(output, "\n"); fprintf(output, "%s", s); } } } /* done reading each line of the source of this page */ fclose(output); free(currentHTML); currentHTML=NULL; /* determine next file */ if(1 == fscanf(f, "%s", linebuf)){ if(!strstr(linebuf, ".htm")){ fprintf(stderr, "Error, writing to strange file \"%s\"\n", linebuf); exit(-1); } currentHTML = strdup(linebuf); } } void processSource(const char *file){ FILE *f = fopen(file, "r"); if(!f){ fprintf(stderr, "Error, unable to open source file \"%s\"\n", file); exit(-1); } readSourceHeader(f); while(!feof(f)) readPageSource(f); fclose(f); } int main(){ readLayout("layout.html"); processSource("source.txt"); return 0; }