Mercurial > ~dholland > hg > ag > index.cgi
diff help2html/mhh6.syn @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/help2html/mhh6.syn Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,1060 @@ +/* + * October 30, 2007. mhh6: use C, not C++. + * + * Sept 5, 2006. mhh5.syn modified for XML_OUTPUT option. + * + * June 20, 2001. mhh5.syn + * Modifying mhh4 to create HTML output + * (mhh4 sorts a help.src file case-insensitively by title line while + * cleaning it up a bit.) + * + * June 16 2001 + * Unlike mhh3b, mhh4 stores and sorts title *lines*, not titles, + * from help.src. Another AgStringDirectory has been added to hold + * topic bodies. + * + * Change mhh3b.syn to store title lines in string dicts. + * Change mhh3a.syn to use AgStringDictionary for titles. + * Jun 8/01 Change mhh3.syn to add main and some reduc. procedures + * + * June 8, 2001 - mhh3.syn now parses Jerry's current help.src (b8) + * with no conflicts or keyword anomalies but spaces (and tabs) are + * not allowed in blank lines. Why the eof line tolerates spaces is + * something of a mystery. + */ + +// -- CONFIGURATION SECTION ---------------------------- +[ + pointer input + no cr // no carr. ret. in output parser + parser file name = "#.c" + line numbers +] +//------------------------------------------------------ + + +eof = 0 +char = ~eof +lead title char = char - blank - tab - ',' - bullet - '\n' - '\r' +title char = char - ',' - bullet - '\n' - '\r' +lead topic char = char - blank - tab - bullet - '\n' - '\r' +text char = char - bullet - '\n' - '\r' +table char = char - tab - '\n' - '\r' + +blank = 0x20 +tab = 9 +bullet = 7 + +//blank line +// -> blank?..., '\n' +blank line + -> '\n' /* Don't allow spaces in line */ + -> '\r','\n' + +eof line + -> blank?..., eof + +eol + -> '\n' + -> '\r','\n' + +(void) help sourcefile $ // ** Grammar token ** + -> topic..., blank line?, eof line + + +topic + -> blank line?..., title line, eol, blank line?..., topic lines, + end topic + +title line + -> title line too = { + title_line_count++; + // buffer_append(&titleLine, "</h3>\n<p>"); + saveTitleLine(); + } + +title line too + -> title = title_count++, putTitle(); + -> title line too, ',', blank?..., title = title_count++, appendTitle(); + +title + -> lead title char:c = + buffer_start(&title, c), buffer_start(&title1, toupper(c)); + -> title, title char:c = + buffer_add(&title, c), buffer_add(&title1, toupper(c)); + +end topic + -> "##", blank?..., eol + -> "\n##", blank?..., eol + -> "\r\n##", blank?..., eol + +topic lines + -> topic lines too = { saveTopicBody(); } + +topic lines too + -> text parag =buffer_append(&topicBody,"\n"); + -> topic lines too, blank line..., parag=buffer_append(&topicBody,"\n"); + +parag + -> text parag + -> table parag + -> list1 parag = finishList(Tlist1); + -> list2 parag = finishList(Tlist2); + -> listtab parag = finishList(Tlisttab); + -> code parag + + +text parag + -> partial text parag + -> partial text parag, table parag + -> text block, list1 parag = finishList(Tlist1); + -> text block, listtab parag = finishList(Tlisttab); + -> text block, code parag + -> text block, code parag, text block + + +partial text parag + -> text block + -> partial text parag, table parag, text block + + + +text block + -> !buffer_append(&topicBody, "<p>");, + first text line, other text line?... = + buffer_append(&topicBody, "</p>"); + + +table parag + -> table parag too = buffer_append(&topicBody, "\n</table>\n\n"); + +table parag too + -> first table line + -> table parag too, other table line + + +list1 parag + -> list1 block, list1 block?... + +list1 block + -> first list1 line, other list1 line?... = + buffer_append(&topicBody, "</li>\n"); + -> first list1 line, other list1 line?..., table parag = + buffer_append(&topicBody, "</li>\n"); + -> first list1 line, other list1 line?..., code parag = + buffer_append(&topicBody, "</li>\n"); + + +list2 parag + -> first list2 line, other list2 line?... = + buffer_append(&topicBody, "</li>\n"); + +listtab parag + -> listtab block, listtab block?... + +listtab block + -> first listtab line, other listtab line?... = + buffer_append(&topicBody, "</li>\n"); + -> first listtab line, other listtab line?..., table parag = + buffer_append(&topicBody, "</li>\n"); + +code parag + -> code parag too = + buffer_append(&topicBody, "\n</pre>"); + +code parag too + -> first code line + -> code parag too, other code line + + +first text line + -> lead topic char:c, text frag?, eol = { + total1sttextline++; + appendEnd(c); + } + -> blank, lead topic char:c, text frag?,eol = { + total1sttextlineb++; + buffer_add(&topicBody, 0x20); + appendEnd(c); + } +other text line + -> lead topic char:c, text frag?, eol = appendEnd(c); + + +//################# OLD #################################################### +//first table line +// -> tab seq, blank seq?, lead topic char:c, text frag?, '\n' = { +// total1sttableline++; +// buffer_append(&topicBody, "\n<pre> "); +// appendEnd(c); +// buffer_clear(&tabFrag); +// buffer_clear(&blankFrag); +// } +// +//other table line +// -> tab seq, blank seq?, lead topic char:c, text frag?, '\n' = { +// buffer_append(&topicBody, " "); +// appendEnd(c); +// buffer_clear(&tabFrag); +// buffer_clear(&blankFrag); +// } +//############################################################################ + + + + +first table line + -> first table line body, eol = + buffer_append(&topicBody, "</td></tr>"); + +first table line body + -> tab seq, blank seq?, lead topic char:c, table frag? = { + total1sttableline++; + buffer_append(&topicBody, + "\n\n<table cellpadding=\"7\" cellspacing=\"2\" >\n<tr><td> "); + appendTableCell(c); + buffer_clear(&tabFrag); + buffer_clear(&blankFrag); + } + + -> first table line body, tab seq, blank seq?, lead topic char:c, + table frag? = { + buffer_append(&topicBody, "</td>\n<td> "); + appendTableCell(c); + buffer_clear(&tabFrag); + buffer_clear(&blankFrag); + } + +other table line + -> other table line body, eol = + buffer_append(&topicBody, "</td></tr>"); + +other table line body + -> tab seq, blank seq?, lead topic char:c, table frag? = { + buffer_append(&topicBody, "\n\n<tr><td> "); + appendTableCell(c); + buffer_clear(&tabFrag); + buffer_clear(&blankFrag); + } + + -> other table line body, tab seq, blank seq?, lead topic char:c, + table frag? = { + buffer_append(&topicBody, "</td>\n<td> "); + appendTableCell(c); + buffer_clear(&tabFrag); + buffer_clear(&blankFrag); + } + + + +first list1 line + -> bullet, blank, lead topic char:c, text frag?, eol = { + total1stlist1line++; + if (intstack_top(¶gType) != Tlist1) { + intstack_push(¶gType, Tlist1); + buffer_append(&topicBody, "\n<ul>"); + } + buffer_append(&topicBody, "\n<li>"); + buffer_add(&topicBody, 0x20); + appendEnd(c); + } + +other list1 line + -> lead topic char:c, text frag?, eol = appendEnd(c); + + +first list2 line + -> bullet, blank, blank, lead topic char:c, text frag?, eol = { + total1stlist2line++; + if (intstack_top(¶gType) != Tlist2) { + intstack_push(¶gType, Tlist2); + buffer_append(&topicBody, "\n<ul>"); + } + buffer_append(&topicBody, "\n<li>"); + buffer_append(&topicBody, " "); + appendEnd(c); + } + +other list2 line + -> lead topic char:c, text frag?, eol = appendEnd(c); + + +first listtab line + -> bullet, tab:t, lead topic char:c, text frag?, eol = { + total1stlisttabline++; + if (intstack_top(¶gType) != Tlisttab) { + intstack_push(¶gType, Tlisttab); + buffer_append(&topicBody, "\n<ul>"); + } + buffer_append(&topicBody, "\n<li>"); + buffer_add(&topicBody, t); + appendEnd(c); + } + +other listtab line + -> lead topic char:c, text frag?, eol = appendEnd(c); + + + +first code line + -> " ", lead topic char:c, text frag?, eol = { + total1stcodeline++; + buffer_append(&topicBody, "\n<pre> "); + appendEnd(c); + } + -> " ", lead topic char:c, text frag?, eol = { + total1stcodeline++; + buffer_append(&topicBody, "\n<pre> "); + appendEnd(c); + } + -> " ", lead topic char:c, text frag?, eol = { + total1stcodeline++; + buffer_append(&topicBody, "\n<pre> "); + appendEnd(c); + } + -> " ", lead topic char:c, text frag?, eol = { + total1stcodeline++; + buffer_append(&topicBody, "\n<pre> "); + appendEnd(c); + } + -> " ", lead topic char:c, text frag?, eol = { + total1stcodeline++; + buffer_append(&topicBody, "\n<pre> "); + appendEnd(c); + } + -> " ", lead topic char:c, text frag?, eol = { + total1stcodeline++; + buffer_append(&topicBody, "\n<pre> "); + appendEnd(c); + } + -> " ", lead topic char:c, text frag?, eol = { + total1stcodeline++; + buffer_append(&topicBody, "\n<pre> "); + appendEnd(c); + } + + +other code line + -> " ", lead topic char:c, text frag?, eol = { + buffer_append(&topicBody, " "); + appendEnd(c); + } + -> " ", lead topic char:c, text frag?, eol = { + buffer_append(&topicBody, " "); + appendEnd(c); + } + -> " ", lead topic char:c, text frag?, eol = { + buffer_append(&topicBody, " "); + appendEnd(c); + } + -> " ", lead topic char:c, text frag?, eol = { + buffer_append(&topicBody, " "); + appendEnd(c); + } + -> " ", lead topic char:c, text frag?, eol = { + buffer_append(&topicBody, " "); + appendEnd(c); + } + -> " ", lead topic char:c, text frag?, eol = { + buffer_append(&topicBody, " "); + appendEnd(c); + } + -> " ", lead topic char:c, text frag?, eol = { + buffer_append(&topicBody, " "); + appendEnd(c); + } + +text frag + -> text char:c = buffer_start(&topicFrag, c); + -> text frag, text char:c = buffer_add(&topicFrag, c); + +table frag + -> table char:c = buffer_start(&topicFrag, c); + -> table frag, table char:c = buffer_add(&topicFrag, c); + + +tab seq + -> tab:t = buffer_start(&tabFrag, t); + -> tab seq, tab:t = buffer_add(&tabFrag, t); + +blank seq + -> blank = buffer_start(&blankFrag, 0x20); + -> blank seq, blank = buffer_add(&blankFrag, 0x20); + + + + +{ /* ----- Embedded C --------------------------------------------*/ + + +#include <stdio.h> +#include <string.h> +#include <malloc.h> +#include <assert.h> +#include <ctype.h> +#include <assert.h> +#include <err.h> +#include "uintarray.h" +#include "support.h" +#include "buffer.h" +#include "stringdict.h" +#include "must.h" + + int verbose = 0; + + int total1sttextline = 0; + int total1sttextlineb = 0; + int total1sttableline = 0; + int total1stlist1line = 0; + int total1stlist2line = 0; + int total1stlisttabline = 0; + int total1stcodeline = 0; + + int title_count =0; + int title_line_count = 0; + + char *helpentStr; + struct buffer title; + struct buffer title1; + struct buffer titleLine; + struct buffer titleLine1; + struct stringdict *titleDict; + struct stringdict *titleDict1; // upper case + struct stringdict *titleLineDict; + struct stringdict *titleLineDict1; // upper case + struct buffer topicFrag; + struct buffer tabFrag; + struct buffer blankFrag; + struct buffer topicBody; + struct stringdict *topicBodyDict; + struct uintarray titleToTitleLine; + struct intstack paragType; + + enum paragTypes {Tnone=0, Ttext=1, Ttable=2, Tlist1=3, Tlist2=4, + Tlisttab=5, Tcode=6}; + + char *charToEntity(const char *instring); + void putTitle(void); + void appendTitle(void); + void saveTitleLine(void); + void appendEnd(int c); + void removeFinalNewline(void); + void saveTopicBody(void); + void printDict(const struct stringdict *dictionary); + void writeSortedHtml(FILE *output); + void writeFullTopics(FILE *output, const struct stringdict *dictionary, + const struct stringdict *dictionary1, + const struct stringdict *dictionaryb); + void writeTitles(FILE *output, const struct stringdict *dictionary, + const struct stringdict *dictionary1); + int processLinkString(FILE *filein, FILE *fileout); + + + // replace &, <, > in S with entities + char *charToEntity(const char *s) { + char *ret; + int i, j, len=0; + + for (i=0; s[i]; i++) { + if (s[i] == '&') len += 5; /* & */ + else if (s[i] == '<') len += 4; /* < */ + else if (s[i] == '>') len += 4; /* > */ + else len++; + } + + ret = malloc(len+1); + if (!ret) { + errx(1, "Out of memory"); + } + + for (i=j=0; s[i]; i++) { + if (s[i] == '&') { strcpy(ret+j, "&"); j += 5; } + else if (s[i] == '<' ) { strcpy(ret+j, "<"); j += 4; } + else if (s[i] == '>' ) { strcpy(ret+j, ">"); j += 4; } + else ret[j++] = s[i]; + } + ret[j] = 0; + + return ret; + } + + // Save title both ways, make map entry for title<--->title line + void saveTitle(void) { + if (stringdict_exists(titleDict, title.text)) { + fprintf( stderr, "Warning: Repeated title %s\n", title.text ); + } +#if 0 + else if (!strcmp(title.text, "Secret of Life")) { + // Do not save "Secret of Life" title + return; + } +#endif + else { + // Save title in dictionary + unsigned titleIndex = stringdict_intern(titleDict, title.text); + + // Save title in upper case dictionary + stringdict_intern(titleDict1, title1.text); + + // count() should give next index + unsigned titleLineIndex = stringdict_count(titleLineDict); + + // use an array for this (the keys are array indexes anyway) + if (titleIndex >= uintarray_num(&titleToTitleLine)) { + unsigned x, old = uintarray_num(&titleToTitleLine); + uintarray_setsize(&titleToTitleLine, titleIndex+1); + for (x=old; x<titleIndex; x++) { + uintarray_set(&titleToTitleLine, x, (unsigned) -1); + } + } + // Store indices in map + uintarray_set(&titleToTitleLine, titleIndex, titleLineIndex); + } + } + + + void putTitle(void) { + // Save title itself in both reg. and upper case title dicts + saveTitle(); + buffer_append(&titleLine, title.text); + buffer_append(&titleLine1, title1.text); + } + + + void appendTitle() { + // Save title itself in both reg. and upper case title dicts + saveTitle(); + buffer_append(&titleLine, ", "); + buffer_append(&titleLine1, ", "); + buffer_append(&titleLine, title.text); + buffer_append(&titleLine1, title1.text); + } + + + void saveTitleLine() { +#if 0 + static int foundSoL=0; + if (stringdict_count(titleLineDict)==0 && + strcmp(titleLine.text, "Secret of Life")!=0 && foundSoL==0) { + fprintf(stderr, "Warning: Secret of Life does not lead file!\n"); + } +#endif + +#if 0 + if (!strcmp(titleLine.text, "Secret of Life")) { + // Don't save title line in dicts. + // Should be at beginning of help file + assert(stringdict_count(titleLineDict)==0); + foundSoL = 1; + if (verbose) { + printf( "\n Found Secret of Life!\n\n" ); + } + } + else +#endif + if ( stringdict_exists(titleLineDict, titleLine.text) ) { + fprintf( stderr, "Warning: Repeated title line %s\n", + titleLine.text ); + } + else { + // Save title line in dictionary + stringdict_intern(titleLineDict, titleLine.text); + // Save title line in upper case dictionary + stringdict_intern(titleLineDict1, titleLine1.text); + } + buffer_clear(&titleLine); + buffer_clear(&titleLine1); + } + + + // Append the latter part of the line + void appendEnd(int c) { + buffer_add(&topicBody, c); + buffer_append(&topicBody, topicFrag.text); + buffer_append(&topicBody, "\n" ); + buffer_clear(&topicFrag); + } + + // Append a cell to the table row + void appendTableCell(int c) { + // Could insert <pre> </pre> or <code> </code> tags here for cell + buffer_append(&topicBody, "<code> " ); + buffer_add(&topicBody, c); + buffer_append(&topicBody, topicFrag.text); + buffer_append(&topicBody, "</code>" ); + //buffer_append(&topicBody, "\n" ); + buffer_clear(&topicFrag); + } + + void removeFinalNewline(void) { + int x = topicBody.len; + assert(topicBody.text[x-2]=='\n' && topicBody.text[x-1]=='\n'); + topicBody.text[x-1] = 0; + } + + void saveTopicBody(void) { +#if 0 + // do not save Secret of Life topic body + if (stringdict_count(titleLineDict) != 0) { +#endif + // save topic body + stringdict_intern(topicBodyDict, topicBody.text); +#if 0 + } +#endif + buffer_clear(&topicBody); + } + +/* + void startTable(void) { + // If we don't currently have table, start a new one + if (paragType.top() != Ttable) { + // Start table + paragType.push( Ttable ); + } + } +*/ + + void finishList(int listtype){ + //printf( "\nfinishList() - top type = %d, listtype = %d, " + // "stack size = %d\n" + // " titleLineDict size = %d\n", + // paragType.top(), listtype, paragType.size(), + // titleLineDict.size() ); + assert(intstack_top(¶gType) == listtype); + intstack_pop(¶gType); + buffer_append(&topicBody, "\n</ul>"); + } + + void printDict(const struct stringdict *dictionary) { + unsigned i; + for (i=0; i<stringdict_count(dictionary); i++) { + printf("%4d: %s\n", i, stringdict_getbynum(dictionary, i)); + } + } + + char *SqueezeWS(const char *Input) { + /* return a (strdup()-like) copy of Input, with whitespace squeezed out */ + char *copy; + int cnt, outcnt; + + copy = must_malloc(strlen(Input)+1); + + for (cnt=0, outcnt=0; Input[cnt]; cnt++) { + unsigned char ch = Input[cnt]; + if (!isspace(ch)) { + copy[outcnt]=ch; + outcnt++; + } + } + copy[outcnt]=0; + + return copy; + } + + void writeFullTopics(FILE *output, + const struct stringdict *dictionary, /* title lines */ + const struct stringdict *dictionary1, /* UC titlelines*/ + const struct stringdict *dictionaryb) /* topic bodies */ + { + unsigned i; + +#if 0 + /* Write "Secret of Life" topic at beginning of topics */ + //fprintf(output, "Secret of Life>\n\n"); + //fprintf(output, "No help message for this topic.\n##\n"); +#endif + + assert( stringdict_count(dictionary) == stringdict_count(dictionary1) ); + struct permutation *perm = mySort(dictionary1); // Sort dictionary1 + + + /* Write out topics in a definition list <dl> */ + fprintf( output, "\n\n<dl>\n\n" ); + + // write dictionary, sorted according to dict1 + for (i = 0; i < stringdict_count(dictionary); i++) { + //fprintf(output, "<dt><b><a name=\"%04d\">%s</a></b></dt>\n" + // "<dd>%s\n</dd><br/>\n\n", + // perm->v[i], + // stringdict_getbynum(dictionary, perm->v[i]), + // stringdict_getbynum(dictionaryb, perm->v[i]) ); + + char *anchorname=SqueezeWS(stringdict_getbynum(dictionary, perm->v[i])); + fprintf(output, "<dt><b><a name=\"%s\">%s</a></b></dt>\n" + "<dd>%s\n</dd>\n\n", + anchorname, + stringdict_getbynum(dictionary, perm->v[i]), + stringdict_getbynum(dictionaryb, perm->v[i]) ); + free(anchorname); + } + fprintf( output, "\n\n</dl>\n\n" ); + permutation_destroy(perm); + } + + void writeTitles(FILE *output, + const struct stringdict *dictionary, /* titles */ + const struct stringdict *dictionary1) /* uppercase titles */ + { + assert( stringdict_count(dictionary) == stringdict_count(dictionary1) ); + struct permutation *perm = mySort(dictionary1); // Sort dictionary1 + + /* Write 2-column table of titles */ + /* + // n_t is true title count w/o Secret of Life + int n_t = stringdict_count(dictionary); + // we better have some titles + assert( n_t >= 2 ); + // n_t1 is #titles in 1st column + int n_t1 = n_t%2 ? n_t/2 +1 : n_t/2; + // n_t2 is #titles in 2nd column + int n_t2 = n_t%2; + int i; + fprintf( output, "\n\n<table width=\"100%%\" " + "style=\"margin-left: auto ; margin-right: auto\" \n" + " cellpadding=\"15\" cellspacing=\"5\" >\n" + "<tr align=\"left\">\n" + "<td valign=\"top\" style=\"white-space: nowrap\">" + "\n\n\n"); + + // Write out dictionary sorted acc. to dictionary1 + // write out the first half, sorted + for (i = 0; i < n_t1; i++) { + fprintf(output, " \xA9%s\xAA\n<br/>", + stringdict_getbynum(dictionary, perm->v[i])); + } + + fprintf(output, "</td>\n\n"); + fprintf(output, "<td valign=\"top\" style=\"white-space: nowrap\">\n\n"); + + // write out the last half, sorted + for ( i = n_t1; i < n_t; i++) { + fprintf(output, " \xA9%s\xAA\n<br/>", + stringdict_getbynum(dictionary, perm->v[i])); + } + + fprintf(output, "</td>\n</tr>\n</table>\n\n<hr><br/><br/>\n\n" ); + */ + + /* Write 1-column list of titles */ + + // n_t is true title count w/o Secret of Life + unsigned n_t = stringdict_count(dictionary); + // we better have some titles + assert( n_t >= 2 ); + unsigned i; + + fprintf(output, "<h2>Help Topic Index</h2>\n\n" ); + // Write out the index, sorted acc. to dictionary1 + for (i = 0; i < n_t; i++) { + fprintf(output, "\xA9%s\xAA\n<br/>", + stringdict_getbynum(dictionary, perm->v[i])); + } + } + + void writeSortedHtml( FILE *output ) { + /* Leading HTML */ + +#ifdef XML_OUTPUT + fprintf(output, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<?xml-stylesheet type=\"text/xsl\" href=\"../ag_web.xml\"?>\n" + "\n" + "<body rootdir=\"..\" navname=\"Documentation: AnaGram Help\">\n"); + +#else + fprintf(output, "<html>\n<head>\n"); + fprintf(output, "<title>AnaGram Help Topics - HTML version</title>\n"); + fprintf(output, "</head>\n\n\n"); + fprintf(output, "<body bgcolor=\"#ffffff\" text=\"#000000\""); + fprintf(output, " link=\"#0033CC\" vlink=\"#CC0033\" alink=\"#CC0099\">"); + fprintf(output, "\n\n\n"); +#endif + + /* Write page title */ +#ifdef XML_OUTPUT + fprintf(output, "<h1>AnaGram Help</h1>\n\n"); +#else + fprintf(output, "<hr><h2>AnaGram Help Topics - HTML Version</h2><hr>\n\n"); +#endif + /* Write 2-column table of titles */ + writeTitles( output, titleDict, titleDict1 ); + + /* Write full topics in single- column table */ + //fprintf( output, "\n\n<table width=\"100%%\">\n<tr><td>\n<p>\n\n"); + //writeFullTopics( output, titleLineDict, titleLineDict1, topicBodyDict ); + //fprintf( output, "</td></tr>\n</table>\n" ); + + /* Write full topics directly to the output page */ + writeFullTopics( output, titleLineDict, titleLineDict1, topicBodyDict ); + +#ifdef XML_OUTPUT + fprintf(output,"\n</body>\n"); +#else + /* Ending HTML */ + fprintf( output, "\n<p><br/><address><a " + "NAME=\"copyright\">AnaGram Help Topics, HTML version.</a>\n" + "<br> Copyright © Parsifal Software, 2001.<br>\n" + "All Rights Reserved.</address>" + "\n\n</body>\n</html>\n\n" ); +#endif + } + + int processLinkString( FILE *filein, FILE *fileout ) { + struct buffer linkString; // lower case + struct buffer linkString1; // upper case version + unsigned index; + int c; + int wspaceFlag =0; + + buffer_init(&linkString); + buffer_init(&linkString1); + + while ( (c=fgetc(filein)) != EOF ) { + + if ( c != 0xAA) { // test for end of link char + if ( c == 0x20 || c == 0x0D || c == 0x0A ) { + // don't append these chars + wspaceFlag = 1; + } + else { + if (wspaceFlag) { + // Replace space, cr, lf with single space + buffer_add(&linkString, 0x20); + buffer_add(&linkString1, toupper(0x20)); + } + buffer_add(&linkString, c); + buffer_add(&linkString1, toupper(c)); + wspaceFlag = 0; + } + } + else { + // end of link - look up using upper case string + if (!stringdict_exists(titleDict1, linkString1.text)) { + // try match w/o final S + if ( linkString1.text[linkString1.len - 1] == 'S' ) { + linkString1.text[linkString1.len - 1] = 0; + if (stringdict_exists(titleDict1, linkString1.text)) { + goto matched; // Eccch - a goto! + } + } + + fprintf(stderr, "Can't find this link in titleDict1: %s\n", + linkString1.text); + return 21; + } + + /* find corresp. index in title line direc. */ + matched: + + index = stringdict_findbyname(titleDict1, linkString1.text); + + unsigned ilink = uintarray_get(&titleToTitleLine, index); + assert(ilink != (unsigned) -1); + + // Write out string, linked to title line + char *linkname=SqueezeWS(stringdict_getbynum(titleLineDict, ilink)); + //fprintf(fileout, "<a href=\"#%04d\">%s</a>", ilink, linkString.text); + fprintf( fileout, "<a href=\"#%s\">%s</a>", linkname, linkString.text); + free(linkname); + + buffer_cleanup(&linkString); + buffer_cleanup(&linkString1); + + return 0; // normal return - have found and written link + } + } + // Error - unexpected end of file + fprintf(stderr, "Error: EOF detected while searching for end of link.\n"); + fprintf(stderr, " Current link string is: %s\n", linkString.text ); + return 23; + } + + static void init(void) { + buffer_init(&title); + buffer_init(&title1); + buffer_init(&titleLine); + buffer_init(&titleLine1); + titleDict = stringdict_create(); + titleDict1 = stringdict_create(); + titleLineDict = stringdict_create(); + titleLineDict1 = stringdict_create(); + topicBodyDict = stringdict_create(); + buffer_init(&topicFrag); + buffer_init(&tabFrag); + buffer_init(&blankFrag); + buffer_init(&topicBody); + intstack_init(¶gType); + uintarray_init(&titleToTitleLine); + } + +/* -- Main Program -- */ + +int main(int argc, char *argv[]) { + + FILE *input; + + long fileLength; + size_t stringLength; + char *helpsrcString; + + init(); + + if (verbose) { + printf( "\n This program reads a help.src-type file, " + "replaces &, <, > with entities,\n" + "sorts in a case-insensitive manner and writes " + "to output file as HTML\n" + "with a preceding list of the help topics. \n\n" ); + } + + /* Check for enough arguments */ + if (argc != 3) { + fprintf(stderr, "Usage: mhh6 helpdata.src help.html\n"); + return 1; + } + + /* Open input file */ + input = fopen(argv[1],"r"); + if (input == NULL) { + fprintf(stderr, "Cannot open %s\n", argv[1]); + return 2; + } + + /* find out how big the input file is */ + if (fseek(input, SEEK_SET, SEEK_END)) { + fprintf(stderr, "Strange problems with %s\n", argv[1]); + return 3; + } + fileLength = ftell(input); + if (fileLength < 0 ) { // -1L is error return + fprintf(stderr, "Error getting file length (%ld) of %s\n", + fileLength, argv[1]); + return 4; + } + + /* fseek to beginning of file */ + if (fseek(input, 0, SEEK_SET)) { + fprintf(stderr, "Strange problems with %s\n", argv[1]); + return 5; + } + + /* Allocate storage for input string */ + helpsrcString = must_malloc(fileLength + 1); + + /* read file */ + stringLength = fread(helpsrcString, 1, (unsigned)fileLength, input); + if (stringLength == 0) { + fprintf(stderr, "Unable to read %s\n", argv[1]); + free(helpsrcString); + fclose(input); + return 7; + } + // Terminate string with null + helpsrcString[stringLength] = 0; + + /* first, replace < > & with entities */ + helpentStr = charToEntity( helpsrcString ); + + /* no more need for input string or file */ + free(helpsrcString); + fclose(input); + + /* initialize stack of parag types */ + intstack_push(¶gType, Tnone); + + /* call parser */ + PCB.pointer = (unsigned char *)(const char *)helpentStr; + mhh6(); + + /* Print file statistics */ + if (verbose) { + printf("No. of title lines in line dict.= %d\n", + stringdict_count(titleLineDict) ); + printDict(titleLineDict); // print title lines + printf( "\n\n" ); + + printf( "title count = %d, includes Secret of Life \n\n", title_count ); + printf( "title line count = %d, includes Secret of Life \n\n", + title_line_count ); + printf( "total1sttextline = %d, \n", total1sttextline ); + printf( "total1sttextlineb = %d \n", total1sttextlineb ); + printf( "total1sttableline = %d \n", total1sttableline ); + printf( "total1stlist1line = %d \n", total1stlist1line ); + printf( "total1stlist2line = %d \n", total1stlist2line ); + printf( "total1stlisttabline = %d \n", total1stlisttabline ); + printf( "total1stcodeline = %d \n", total1stcodeline ); + } + + /* check for error */ + if (verbose) { + printf( "PCB.exit_flag = %d (%d for success)\n", PCB.exit_flag, + AG_SUCCESS_CODE); + } + if (PCB.exit_flag != AG_SUCCESS_CODE) { + fprintf(stderr, "File %s: error at line %d, column %d\n", + argv[1], + PCB.line, + PCB.column); + return 8; + } + + // Write sorted title lines & topics as HTML to intermediate file + FILE *intermed; + const char *filename = "intermed.html"; + /* Open intermediate file */ + intermed = fopen(filename ,"w+"); // create intermediate text file + if (intermed == NULL) { + fprintf(stderr, "Cannot open %s\n", filename); + return 9; + } + if (verbose) { + printf( "Writing sorted title lines & topic bodies to " + "intermediate file in HTML format...\n"); + } + writeSortedHtml(intermed); + rewind(intermed); + + /* Create output HTML file, inserting links */ + FILE *output; + /* Open output file */ + output = fopen(argv[2] ,"w"); + if (output == NULL) { + fprintf(stderr, "Cannot open %s\n", argv[2]); + return 10; + } + + if (verbose) { + printf( "Writing output file with HTML links...\n"); + } + + int c = 0; + int ctest = 0; + + while ( (c=fgetc(intermed)) != EOF ){ + + if ( c == 0xA9 ) { // begins link string + // printf( "\n Found beginning of link" ); + int itest = processLinkString(intermed, output); + if (itest !=0) return itest; // error return + } + else { + ctest = fputc( c, output ); // write out current character + if (ctest == EOF) return 11; + } + } + + fclose(intermed); + fclose(output); + + + /* done */ + if (verbose) { + printf( "All done.\n" ); + } + return 0; // normal return + +} /* -- End of main() function -- */ + +} /* ---- End of embedded C ----------------------------------------- */ + +