/* XTrkCad - Model Railroad CAD * Copyright (C) 2005 Dave Bullis * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #if defined (__sun) && defined (__SVR4) #include #endif #include "readpng.h" #define PROGNAME "prochelp" char line[1024]; int lineNum; FILE * ifile; FILE * ofile; int wordwrap = 1; int listLevel = -1; int listType[10]; int listCount[10]; int lineWidth = 80; int listWidth = 80; int verbose = 0; int toc = 0; char * dirs[10] = { "." }; char ** dirList = &dirs[1]; int FontSize = 22; double MarginTop = -1; double MarginBottom = -1; double MarginLeft = -1; double MarginRight = -1; double MarginGutter = -1; #define LISTNONE (0) #define LISTBULLET (1) #define LISTDASH (2) #define LISTNUMBER (3) int USE_BMP = 0; typedef struct { void (*start)( char *, char * ); void (*finish)( void ); void (*newParagraph)( void ); void (*startLine)( int ); void (*doBold)( char * ); void (*doItalic)( char * ); void (*doXref)( char *, char *, char * ); void (*doPicture)( char *, int ); void (*endLine)( void ); void (*putChar)( char ); void (*doSection)( char, char *, char *, char *, char *, int ); void (*doHeader)( char * ); void (*doStartDisplay)( void ); void (*doEndDisplay)( void ); void (*doThread)( char * ); void (*doListStart)( void ); void (*doListItem)( void ); void (*doListEnd)( void ); void (*page)( void ); } dispatchTable; dispatchTable *curMode; struct tocList_t; typedef struct tocList_t * tocList_p; typedef struct tocList_t { tocList_p next; char section; long num; char * title; } tocList_t; tocList_p tocHead = NULL; tocList_p tocTail = NULL; long tocNum = 37061946; void no_op( void ) { } FILE * openFile( char * filename ) { FILE * f; char tmp[1024]; char ** d; for ( d=dirs; *d; d++ ) { sprintf( tmp, "%s/%s", *d, filename ); f = fopen( tmp, "r" ); if (f) return f; } fprintf( stderr, "Can't open %s\n", filename ); exit(1); } void normalStart( char * inName, char * outName ) { ifile = openFile( inName ); if ( strcmp( outName, "-" ) == 0 ) { ofile = stdout; } else { ofile = fopen( outName, "w" ); if (ofile == NULL) { perror( outName ); exit( 1 ); } } } void normalFinish( void ) { if (ofile) fclose( ofile ); } void process( FILE * ); /****************************************************************************** * * COMMON RTF * *****************************************************************************/ int rtfNeedPar = FALSE; int rtfNeedGap = FALSE; int rtfNeedFI0 = FALSE; int rtfGapHeight = -1; int rtfBigGap = 60; void rtfFlushParagraph( void ) { if ( rtfNeedPar ) { if ( rtfNeedGap==TRUE && rtfGapHeight!=rtfBigGap ) { fprintf( ofile, "\\sb%d", rtfBigGap ); rtfGapHeight = rtfBigGap; } if ( rtfNeedGap==FALSE && rtfGapHeight!=0 ) { fprintf( ofile, "\\sb0" ); rtfGapHeight = 0; } fprintf( ofile, "\\par\n" ); if ( rtfNeedFI0 ) fprintf( ofile, "\\fi0\n" ); rtfNeedPar = FALSE; rtfNeedGap = FALSE; rtfNeedFI0 = FALSE; } } void rtfPutChar( char ch ) { if ( ((ch) & 0x80) ){ fprintf( ofile, "\\'%2.2X", (unsigned char)ch ); } else if ( (ch) == '\\' ){ fprintf( ofile, "\\\\" ); } else { fputc( ch, ofile ); } rtfNeedPar = TRUE; } void rtfPutString( char * cp ) { while (*cp) { rtfPutChar( *cp++ ); } } void rtfNewParagraph( void ) { if ( wordwrap ) { rtfFlushParagraph(); #ifdef LATER if ( listLevel < 0 ) { rtfFlushParagraph(); rtfNeedGap = 1; } else { if ( rtfNeedPar ) { fprintf( ofile, "\\line\r\n" ); rtfNeedPar = FALSE; } } #endif } } void rtfStartLine( int lastBlank ) { if ( !wordwrap ) { fprintf( ofile, "\\tab\r\n" ); } else if ( lastBlank ) { rtfFlushParagraph(); } } void rtfBold( char * name ) { fprintf( ofile, "{\\b " ); rtfPutString( name ); fprintf( ofile, "}" ); } void rtfItalic( char * name ) { fprintf( ofile, "{\\i " ); rtfPutString( name ); fprintf( ofile, "}" ); } void rtfEndLine( void ) { if ( !wordwrap ) { rtfNeedPar = TRUE; rtfFlushParagraph(); } } void rtfStartDisplay( void ) { rtfFlushParagraph(); } void rtfListStart( void ) { rtfFlushParagraph(); if (listLevel>0) { fprintf( ofile, "\\pard" ); /* if ( rtfNeedGap ) { fprintf( ofile, "\\sb%d", rtfBigGap ); rtfGapHeight = rtfBigGap; rtfNeedGap = FALSE; } */ rtfGapHeight = -1; } fprintf( ofile, "\\tx360\\li%d\r\n", 360*(listLevel+1) ); } void rtfListItem( void ) { /*if (listLevel == 0 || listCount[listLevel] > 1)*/ rtfFlushParagraph(); fprintf( ofile, "\\fi-360 " ); rtfNeedFI0 = TRUE; switch (listType[listLevel]) { case LISTNONE: #ifdef LATER if ( listCount[listLevel] > 0 ) fprintf( ofile, "\\fi-360 " ); rtfNeedFI0 = TRUE; #endif break; case LISTBULLET: fprintf( ofile, "{\\f1\\'B7}\\tab" ); break; case LISTDASH: fprintf( ofile, "{\\b -}\\tab" ); break; case LISTNUMBER: fprintf( ofile, "{\\b %d}\\tab", listCount[listLevel] ); break; } fprintf( ofile, "\r\n" ); } void rtfListEnd( void ) { if (listLevel == -1) fprintf( ofile, "\\par\\pard\r\n" ); else fprintf( ofile, "\\par\\pard\\tx360\\li%d\\fi-360\r\n", 360*(listLevel+1) ); rtfNeedPar = FALSE; rtfGapHeight = -1; rtfNeedGap = FALSE; } void rtfPage( void ) { rtfFlushParagraph(); fprintf( ofile, "\\page\r\n" ); } /****************************************************************************** * * MSW-HELP * *****************************************************************************/ int pageCnt = 0; struct { char * name; int count; } threads[100]; int threadCnt = 0; char * remap_minus( char * cp ) { char * cp0 = cp; for ( ; *cp; cp++ ) if ( *cp == '-' ) *cp = '_'; return cp0; } int lookupThread( char * name ) { int inx; if (!name) { fprintf( stderr, "%d: NULL thread string\n", lineNum ); return 0; } for (inx=0;inx= 40) { fprintf( outF, "\n" ); off = 0; } } if (off != 1) fprintf( outF, "\n" ); } void conv24to8( long * colorTab, unsigned char * buff, int channels, int width24, int width8, int height ) { long * lastColor, *cp; long color; unsigned char * ip; unsigned char *op; int h, w; lastColor = colorTab; memset( colorTab, 0, 1024 ); op = buff; for (h=0; h=0; h--) { for (i=3; i>=0; i--) buff[h*4+i] = buff[h*3+i]; buff[h*4+3] = 0; } } dumpBytes( buff, 1024, outF ); rc = fseek( bmpF, bmfhOff, 0 ); buff = (char*)realloc( buff, (int)scanWidth ); for ( h=0; h=0; h--) { for (i=3; i>=0; i--) buff[h*4+i] = buff[h*3+i]; buff[h*4+3] = 0; } dumpBytes( buff, 1024, outF ); rc = fseek( bmpF, bmfhOff, 0 ); buff = (char*)realloc( buff, (int)scanWidth*2+10 ); width8 = (bmih.width+3)/4*4; for ( h=0; h=0; i--) { buff[i*2+1] = buff[i]&0xF; buff[i*2] = (buff[i]>>4)&0xF; } dumpBytes( buff, width8, outF ); } break; case 1: buff = (char*)malloc(1024); fseek( bmpF, colormapOff, 0 ); memset( buff, 0, 1024 ); rc = fread( buff, 3*2, 1, bmpF ); for (h=1; h>=0; h--) { for (i=3; i>=0; i--) buff[h*4+i] = buff[h*3+i]; buff[h*4+3] = 0; } dumpBytes( buff, 1024, outF ); rc = fseek( bmpF, bmfhOff, 0 ); buff = (char*)realloc( buff, (int)scanWidth*8+10 ); width8 = (bmih.width+3)/4*4; for ( h=0; h=0; i--) { for (j=7; j>=0; j--) { buff[i*8+j] = (buff[i]&(128>>j))?1:0; } } dumpBytes( buff, width8, outF ); } break; case 24: buff = (char*)malloc( (int)(fullSize) ); rc = fread( buff, (int)(fullSize), 1, bmpF ); colorTab = (long*)malloc( 1024 ); width8 = ((bmih.width+3)/4)*4; conv24to8( colorTab, buff, (int)scanWidth, 3, (int)width8, (int)bmih.height ); dumpBytes( (char*)colorTab, 1024, outF ); for ( h=0; hsection = section; tl->title = (char*)malloc( strlen(sectionNumS) + strlen(title) + 1 ); sprintf( tl->title, "%s%s", sectionNumS, title ); tl->num = tocNum++; tl->next = NULL; if (tocHead == NULL) tocHead = tl; else tocTail->next = tl; tocTail = tl; } rtfNeedPar = FALSE; rtfNeedGap = TRUE; rtfGapHeight = -1; } void mswwordStart( char * inName, char * outName ) { normalStart( inName, outName ); if ( MarginGutter >= 0.0 ) fprintf( ofile, "\\margmirror\\gutter%d\n", (int)(MarginGutter*1440.0) ); if (MarginTop >= 0.0) fprintf( ofile, "\\margt%d\n", (int)(MarginTop*1440.0) ); if (MarginBottom >= 0.0) fprintf( ofile, "\\margb%d\n", (int)(MarginBottom*1440.0) ); if (MarginRight >= 0.0) fprintf( ofile, "\\margr%d\n", (int)(MarginRight*1440.0) ); if (MarginLeft >= 0.0) fprintf( ofile, "\\margl%d\n", (int)(MarginLeft*1440.0) ); } void mswwordFinish( void ) { char lastSection = 'A'; tocList_p tl; rtfFlushParagraph(); if (toc) { fprintf( ofile, "\ \\sect \\sectd \\pgnrestart\\pgnlcrm\\linex0\\endnhere\ \\pard\\plain \\qc\\widctlpar \\f4\\fs22 \ {\\b\\fs36\\lang1024\\kerning28 Contents \\par \\par }\ \\pard\\plain \\s17\\widctlpar\\tqr\\tldot\\tx8640 \\f4\\fs%d\n", FontSize ); for ( tl=tocHead; tl; tl=tl->next ) { if ( tl->section != lastSection ) { fprintf( ofile, "\ \\pard\\plain \\s%d\\li%d\\widctlpar\\tqr\\tldot\\tx8640 \\f4\\fs%d\n", tl->section-'A'+17, (tl->section-'A')*200, FontSize ); lastSection = tl->section; } fprintf( ofile, "\ {\\lang1024\\kerning28 %s}{\\lang1024 \\tab }\ {\\field{\\*\\fldinst {\\lang1024 GOTOBUTTON _Toc%ld }\n\ {\\field{\\*\\fldinst {\\lang1024 PAGEREF _Toc%ld }}\ {\\fldrslt {\\lang1024 3}}}}}{\\lang1024 \\par }\n", tl->title, tl->num, tl->num); } fprintf( ofile, "\\pard\\plain \\widctlpar \\f4\\fs%d\n}\n}\n" /*\\pard\\plain \*/ "\\widctlpar \\f4\\fs%d\n" , FontSize, FontSize); } normalFinish(); } dispatchTable mswwordTable = { mswwordStart, mswwordFinish, rtfNewParagraph, rtfStartLine, rtfBold, rtfItalic, mswwordXref, mswwordPicture, rtfEndLine, rtfPutChar, mswwordSection, (void*)no_op, rtfStartDisplay, (void*)no_op, (void*)no_op, rtfListStart, rtfListItem, rtfListEnd, rtfPage }; /****************************************************************************** * * TEXT * *****************************************************************************/ char textBuff[1024]; char *textBuffP = textBuff; int textNewLine = 1; int textIndent = 0; int textAllowLeadingBlanks = 0; int textNoIndent = 0; int textLineLength; void textPutChar( char ch ) { char *cp, *cq; int indent; int width; if (textNewLine) { textLineLength = 0; if (ch == ' ' && !textAllowLeadingBlanks) { return; } if (!textNoIndent) { for (indent=0; indent0?listWidth:lineWidth); if ( wordwrap && width > 0 && textLineLength > width ) { for (cp = textBuffP-1; *cp != ' ' && cp>textBuff+lineWidth/2; cp-- ); while ( *cp == ' ' && cp>textBuff+lineWidth/2 ) cp--; cp++; fwrite( textBuff, cp-textBuff, 1, ofile ); fwrite( "\n", 1, 1, ofile ); textNewLine = 1; while (*cp == ' ' && cp= sizeof textBuff ) { fwrite( textBuff, textBuffP-textBuff, 1, ofile ); textBuffP = textBuff; textLineLength = 0; } } void textBreakLine( void ) { if ( !textNewLine ) { fwrite( textBuff, textBuffP-textBuff, 1, ofile ); fwrite( "\n", 1, 1, ofile ); textNewLine = 1; textBuffP = textBuff; textLineLength = 0; } } void textSaveLine( char * tmp ) { if (!textNewLine) { int len = textBuffP-textBuff; memcpy( tmp, textBuff, len ); tmp[len] = '\0'; textNewLine = 1; textBuffP = textBuff; textLineLength = 0; } else { tmp[0] = '\0'; } } void textRestoreLine( char * tmp ) { int len = strlen( tmp ); if (len > 0) { memcpy( textBuffP, tmp, len ); textBuffP += len; textLineLength += len; textNewLine = 0; } } void textFinish( void ) { textBreakLine(); normalFinish(); } void textPutString( char * cp ) { while (*cp) textPutChar( *cp++ ); } void textNewParagraph( void ) { textBreakLine(); if (wordwrap) { fwrite( "\n", 1, 1, ofile ); } } void textStartLine( int lastlineblank ) { } void textBold( char * name ) { char * cp; /*textPutChar( '<' );*/ for ( cp = name; *cp; cp++ ) { textPutChar( *cp ); if (*cp != ' ') { textPutChar( '\010' ); textPutChar( *cp ); } } /*textPutString( name );*/ /*textPutChar( '>' );*/ } void textItalic( char * name ) { char * cp; /*textPutChar( '<' );*/ for ( cp = name; *cp; cp++ ) { textPutChar( *cp ); if (*cp != ' ') { textPutChar( '\010' ); textPutChar( *cp ); } } /*textPutString( name );*/ /*textPutChar( '>' );*/ } void textXref( char * name, char * ref1, char * ref2 ) { textBold( name ); /*textPutChar( '<' ); textPutString( name ); textPutChar( '>' );*/ if (ref2) { textPutString( " (See " ); textPutString( ref2 ); textPutString( " for Details)" ); } } void textPicture( char * picture, int inLine ) { textPutString( "<<" ); textPutString( picture ); textPutString( ">>" ); if (inLine) { textPutString( " " ); } else { textBreakLine(); fwrite( "\n", 1, 1, ofile ); } } void textEndLine( void ) { if ( !wordwrap ) textBreakLine(); } void textSection( char section, char * title, char * context, char * picture, char * keywords, int newpage ) { int len; textBreakLine(); if (pageCnt > 0 && newpage) { fwrite( "\014\n", 1, 2, ofile ); } pageCnt++; textBold( title ); /*textPutString( title );*/ textBreakLine(); for ( len = strlen(title); len>0; len-- ) { textBold( "=" ); /*fwrite( "=", 1, 1, ofile );*/ } textBreakLine(); fwrite( "\n", 1, 1, ofile ); } void textHeader( char * line ) { } void textStartIndent( void ) { textBreakLine(); textIndent++; } void textEndIndent( void ) { textBreakLine(); if (textIndent < 0) { fprintf( stderr, "%d: textIndent < 0\n", lineNum ); textIndent = 0; } else { textIndent--; } } void textListItem( void ) { char num[4]; textBreakLine(); textIndent--; textAllowLeadingBlanks = 1; switch( listType[listLevel] ) { case LISTNONE: default: textPutString( " " ); break; case LISTBULLET: textPutString( " o " ); break; case LISTDASH: textPutString( " - " ); break; case LISTNUMBER: sprintf( num, "%3.3d", listCount[listLevel] ); textPutString( num ); textPutChar( ' ' ); break; } textAllowLeadingBlanks = 0; textIndent++; } void textPage( void ) { fwrite( "\014\n", 1, 2, ofile ); } dispatchTable textTable = { normalStart, textFinish, textNewParagraph, textStartLine, textBold, textItalic, textXref, textPicture, textEndLine, textPutChar, textSection, textHeader, textStartIndent, textEndIndent, (void*)no_op, textStartIndent, textListItem, textEndIndent, textPage }; /****************************************************************************** * * XVIEW * *****************************************************************************/ void xviewStart( char * inName, char * outName ) { normalStart( inName, outName ); lineWidth = 0; } void xviewBold( char * name ) { char * cp; textPutChar( '<' ); textPutString( name ); textPutChar( '>' ); } void xviewItalic( char * name ) { char * cp; textPutChar( '<' ); textPutString( name ); textPutChar( '>' ); } void xviewXref( char * name, char * ref1, char * ref2 ) { xviewBold( name ); if (ref2) { textPutString( " (See " ); textPutString( ref2 ); textPutString( " for Details)" ); } } void xviewSection( char section, char * title, char * context, char * picture, char * keywords, int newpage ) { int indent; int len; static char * stars = "************"; indent = line[1]-'A'+1; textBreakLine(); if (pageCnt > 0 && newpage) { fwrite( "\n", 1, 1, ofile ); } if ( newpage ) { pageCnt++; textNoIndent = 1; textPutChar( ':' ); textPutString( stars+strlen(stars)-indent ); textPutChar( '-' ); textPutString( title ); textBreakLine(); if (context) { textPutChar( ':' ); textPutString( context ); textPutChar( ' ' ); textBreakLine(); } } textNoIndent = 0; xviewBold( title ); textBreakLine(); for ( len = strlen(title); len>0; len-- ) fwrite( "=", 1, 1, ofile ); fwrite( "\n\n", 1, 2, ofile ); } void xviewHeader( char * line ) { char tmp[1024]; textSaveLine( tmp ); textNoIndent = 1; textPutChar( ':' ); textPutString( line ); textPutChar( ' ' ); textBreakLine(); textNoIndent = 0; textRestoreLine( tmp ); } dispatchTable xviewTable = { xviewStart, normalFinish, textNewParagraph, textStartLine, xviewBold, xviewItalic, xviewXref, (void*)no_op, /* picture */ textEndLine, textPutChar, xviewSection, xviewHeader, textStartIndent, /* startDisplay */ textEndIndent, /* endDisplay */ (void*)no_op, textStartIndent, /* listStart */ textListItem, textEndIndent, /* listEnd */ (void*)no_op }; /****************************************************************************** * * HTML * *****************************************************************************/ char * htmlName; char htmlFileName[1024]; struct { char * name; int index; int section; } links[500]; int linkCnt = 0; void setLink( char * name, int sectionNumber ) { links[linkCnt].name = strdup( name ); links[linkCnt].section = sectionNumber; linkCnt++; } void getLinks( int sectionNumber, int * prev, int * next ) { int cur, inx; *prev = -1; *next = -1; for ( cur = 0; cur < linkCnt; cur++ ) { if ( links[cur].section == sectionNumber ) { for (inx = cur-1; inx >= 0; inx-- ) { if ( strcmp( links[cur].name, links[inx].name ) == 0 ) { *prev = links[inx].section; break; } } for (inx = cur+1; inx < linkCnt; inx++ ) { if ( strcmp( links[cur].name, links[inx].name ) == 0 ) { *next = links[inx].section; break; } } } } } struct { char * name; int sectionNumber; int subSection; } sections[500]; int sectionCnt = 0; int lastSection = 0; int curSection = 0; int subSection = 0; void defineSection( char * name, int sectionNumber ) { if (!name) { fprintf( stderr, "%d: NULL context string\n", lineNum ); return; } sections[sectionCnt].name = strdup( name ); sections[sectionCnt].sectionNumber = sectionNumber; if (lastSection != sectionNumber) { subSection = 0; } sections[sectionCnt].subSection = subSection++; sectionCnt++; } int lookupSection( char * name, int *subSection ) { int inx; if (!name) { return -1; } for (inx=0; inx


" ); fprintf( ofile, "Return to Contents", htmlName ); comma = 1; } getLinks( sectionNumber, &prev, &next ); if (prev > 0) { if (comma) fprintf( ofile, ", " ); else if (!begin) fprintf( ofile, "\n


" ); fprintf( ofile, "Previous Page", htmlName, prev ); comma = 1; } if (next > 0) { if (comma) fprintf( ofile, ", " ); else if (!begin) fprintf( ofile, "\n


" ); fprintf( ofile, "Next Page", htmlName, next ); comma = 1; } if (comma) if (begin) fprintf( ofile, "


\n" ); else fprintf( ofile, "

\n" ); } } int preHtmlSectionNumber = -1; void preHtmlSection( char section, char * title, char * context, char * picture, char * keywords, int newpage ) { if ( !newpage ) return; preHtmlSectionNumber++; defineSection( context, preHtmlSectionNumber ); } void preHtmlHeader( char * line ) { if ( line[0] == '*' ) return; defineSection( line, preHtmlSectionNumber ); } void preHtmlThread( char * thread ) { setLink( thread, preHtmlSectionNumber ); } dispatchTable preHtmlTable = { (void*)no_op, (void*)no_op, (void*)no_op, (void*)no_op, (void*)no_op, (void*)no_op, (void*)no_op, (void*)no_op, (void*)no_op, (void*)no_op, preHtmlSection, preHtmlHeader, (void*)no_op, (void*)no_op, preHtmlThread, (void*)no_op, (void*)no_op, (void*)no_op, (void*)no_op }; dispatchTable htmlTable; void htmlStart( char * inName, char * outName ) { curMode = &preHtmlTable; ifile = openFile( inName ); process( ifile ); fclose( ifile ); curMode = &htmlTable; ifile = openFile( inName ); htmlName = outName; sprintf( htmlFileName, "%s.html", htmlName ); ofile = fopen( htmlFileName, "w" ); if (ofile == NULL) { perror( outName ); exit( 1 ); } } void htmlFinish( void ) { genHtmlLinks( curSection, 0 ); } void htmlNewParagraph( void ) { if (wordwrap) { if ( listLevel < 0 ) fprintf( ofile, "

" ); else fprintf( ofile, "
" ); } else { fprintf( ofile, "\n" ); } } void htmlStartLine( int lastBlank ) { if (wordwrap) fprintf( ofile, "\n" ); else fprintf( ofile, "\t" ); } void htmlBold( char * name ) { fprintf( ofile, "%s", name ); } void htmlItalic( char * name ) { fprintf( ofile, "%s", name ); } void htmlXref( char * name, char * ref1, char * ref2 ) { int sectionNumber, subSection; sectionNumber = lookupSection( ref1, &subSection ); if (sectionNumber < 0) return; fprintf( ofile, "%s", name ); } void htmlPicture( char * name, int inLine ) { fprintf( ofile, "", name ); if (inLine) fprintf( ofile, "\t" ); else fprintf( ofile, "

\n" ); } void htmlEndLine( void ) { if ( !wordwrap ) fprintf( ofile, "\n" ); } void htmlPutChar( char ch ) { if ( ch == '<' ) fprintf( ofile, "<" ); else if ( ch == '>' ) fprintf( ofile, ">" ); else fputc( ch, ofile ); } void htmlSection( char section, char * title, char * context, char * picture, char * keywords, int newpage ) { int sectionNumber, subSection; if ( newpage ) { /*if (line[1] == 'A')*/ sectionNumber = curSection; curSection = lookupSection( context, &subSection ); if (curSection > 0) { genHtmlLinks( sectionNumber, 0 ); if (ofile) fclose( ofile ); sprintf( htmlFileName, "%s-%d.html", htmlName, curSection ); ofile = fopen( htmlFileName, "w" ); if (ofile == NULL) { perror( htmlFileName ); exit(1); } } fprintf( ofile, "%s\n", title ); genHtmlLinks( curSection, 1 ); } if (picture && picture[0] != '\0') fprintf( ofile, " ", picture ); fprintf( ofile, "%s\n", line[1]-'A'+1, title, line[1]-'A'+1 ); } void htmlHeader( char * line ) { int sectionNumber, subSection; if ( line[0] == '*' ) return; sectionNumber = lookupSection( line, &subSection ); if (sectionNumber < 0) return; fprintf( ofile, "\n", sectionNumber ); } void htmlStartDisplay( void ) { fprintf( ofile, "

\n

" );
}
void htmlEndDisplay( void )
{
	fprintf( ofile, "
\n" ); } void htmlListStart( void ) { fprintf( ofile, "
    " ); } void htmlListItem( void ) { fprintf( ofile, "
  • " ); } void htmlListEnd( void ) { fprintf( ofile, "
\n" ); } dispatchTable htmlTable = { htmlStart, htmlFinish, htmlNewParagraph, htmlStartLine, htmlBold, htmlItalic, htmlXref, htmlPicture, htmlEndLine, htmlPutChar, htmlSection, htmlHeader, htmlStartDisplay, htmlEndDisplay, (void*)no_op, htmlListStart, htmlListItem, htmlListEnd, (void*)no_op }; /****************************************************************************** * * DEFINES * *****************************************************************************/ struct { char * name; int refCount; int lineNum; } defs[500]; int defCnt = 0; void lookupDef( char * name, int def ) { int inx; if (!name) { fprintf( stderr, "%d: NULL context string\n", lineNum ); return; } for (inx=0;inx= 499) { if (defCnt == 499) { fprintf( stderr, "%d: too many defines\n", lineNum ); defCnt++; } return; } else { defs[defCnt].name = strdup( name ); defs[defCnt].lineNum = (def?lineNum:-1); defs[defCnt].refCount = 0; defCnt++; } } void defsFinish( void ) { int inx; for ( inx=0; inx 0 && line[len-1] == '\n') line[--len] = '\0'; if (len > 0 && line[len-1] == '\r') line[--len] = '\0'; if (len <= 0) { if (lastlineblank) return; curMode->newParagraph(); lastlineblank = 1; return; } else { curMode->startLine( lastlineblank ); lastlineblank = 0; } #ifndef LATER if (wordwrap) { if (line[len-1] != ' ') { line[len++] = ' '; if (line[len-2] == '.') line[len++] = ' '; } line[len] = '\0'; } #endif for ( cp=line; *cp; cp++ ) { if (*cp == '$') { cp++; switch (*cp) { case '?': case '$': curMode->putChar( *cp ); break; case '{': curMode->putChar( '$' ); curMode->putChar( '{' ); break; case 'B': name = ++cp; cp = skipChars( cp ); if (*cp=='\0') break; *cp = '\0'; curMode->doBold( name ); break; case 'I': name = ++cp; cp = skipChars( cp ); if (*cp=='\0') break; *cp = '\0'; curMode->doItalic( name ); break; case 'X': name = ++cp; while (*cp && *cp != '|') cp++; if (*cp=='\0') break; *cp++ = '\0'; mswhelpref = cp; while (*cp && *cp != '|' && *cp != '$') cp++; if (*cp=='\0') break; if (*cp == '|') { *cp++ = '\0'; xvref = cp; while (*cp && *cp != '$') cp++; if (*cp=='\0') break; for (cq=xvref; cqdoXref( name, mswhelpref, xvref ); break; case 'G': name = ++cp; while (*cp && *cp != '$') cp++; if (*cp=='\0') break; *cp = '\0'; curMode->doPicture( name, 1 ); break; default: fprintf( stderr, "%d Invalid $ command - %c\n", lineNum, *cp ); break; } } else { if (*cp != '\014') curMode->putChar( *cp ); } } curMode->endLine(); } char * conds[100]; char **condPtr = conds; void addCond( char * name ) { *condPtr++ = name; } int lookupCond( char * name ) { char ** p; int ret = 1; if (strlen(name) == 0) return 1; if (*name == '!') { ret = 0; name++; } for (p=conds; pdoSection( line[1], title, context, fileName, keywords, sectionNewPage ); lastlineblank = 0; break; case 'H': curMode->doHeader( line+2 ); break; case 'W': if (line[2] == '+') { curMode->doEndDisplay(); wordwrap = 1; } else if (line[2] == '-') { curMode->doStartDisplay(); wordwrap = 0; } else { fprintf( stderr, "%d: Bad ?W command\n", lineNum); exit(1); } lastlineblank = 0; break; case 'G': curMode->doPicture( line+2, 0 ); lastlineblank = 0; break; case 'T': curMode->doThread( line+2 ); break; case 'L': switch (line[2]) { case 'S': listLevel++; listCount[listLevel] = 0; switch (line[3]) { case 'o': listType[listLevel] = LISTBULLET; break; case '-': listType[listLevel] = LISTDASH; break; case '1': listType[listLevel] = LISTNUMBER; break; default: listType[listLevel] = LISTNONE; } curMode->doListStart(); break; case 'I': if (listLevel<0) { fprintf( stderr, "%d: ?LI not in list\n", lineNum ); break; } listCount[listLevel]++; curMode->doListItem(); break; case 'E': listLevel--; curMode->doListEnd(); break; } lastlineblank = 0; break; case 'P': curMode->page(); lastlineblank = 0; break; case 'Q': noSectionNewPage = 1; break; default: fprintf( stderr, "%d: Invalid ? command: %c\n", lineNum, line[1] ); } } lineNum = lineNum0; } /****************************************************************************** * * MAIN * *****************************************************************************/ int main ( int argc, char * argv[] ) { int inx; curMode = NULL; argv++; argc--; while ( argc > 1 && argv[0][0] == '-' ) { if ( strcmp( argv[0], "-xv" ) == 0 ) { curMode = &xviewTable; addCond( "xv" ); } else if ( strcmp( argv[0], "-mswhelp" ) == 0 ) { curMode = &mswhelpTable; addCond( "mswhelp" ); } else if ( strcmp( argv[0], "-mswword" ) == 0 ) { curMode = &mswwordTable; addCond( "mswword" ); } else if ( strcmp( argv[0], "-html" ) == 0 ) { curMode = &htmlTable; addCond( "html" ); } else if ( strcmp( argv[0], "-def" ) == 0 ) { curMode = &defsTable; addCond( "def" ); } else if ( strcmp( argv[0], "-text" ) == 0 ) { curMode = &textTable; addCond( "text" ); } else if ( strncmp( argv[0], "-C", 2 ) == 0 ) { argv++; argc--; addCond( argv[0] ); } else if ( strncmp( argv[0], "-v", 2 ) == 0 ) { verbose = 1; } else if ( strncmp( argv[0], "-d", 2 ) == 0 ) { argv++; argc--; *dirList++ = argv[0]; } else if ( strncmp( argv[0], "-width", 2 ) == 0 ) { argv++; argc--; listWidth = lineWidth = atoi(argv[0]); if (lineWidth < 10) { fprintf( stderr, "Invalid linewidth %s\n", argv[0] ); exit(1); } } else if ( strncmp( argv[0], "-mt", 3 ) == 0 ) { argv++; argc--; MarginTop = atof( *argv ); } else if ( strncmp( argv[0], "-mb", 3 ) == 0 ) { argv++; argc--; MarginBottom = atof( *argv ); } else if ( strncmp( argv[0], "-mr", 3 ) == 0 ) { argv++; argc--; MarginRight = atof( *argv ); } else if ( strncmp( argv[0], "-ml", 3 ) == 0 ) { argv++; argc--; MarginLeft = atof( *argv ); } else if ( strncmp( argv[0], "-mg", 3 ) == 0 ) { argv++; argc--; MarginGutter = atof( *argv ); } else if ( strncmp( argv[0], "-toc", 4 ) == 0 ) { toc++; } else { fprintf( stderr, "unrecognized option: %s\n", argv[0] ); exit( 1 ); } argv++;argc--; } if (curMode == NULL) { fprintf( stderr, "Must spec either -mswhelp or -xv\n" ); exit(1); } if ( argc != 2 ) { fprintf( stderr, "Usage: prochelp [-mswhelp|-xv] \n" ); exit( 1 ); } curMode->start( argv[0], argv[1] ); process( ifile ); fclose( ifile ); curMode->finish(); exit(0); }