From 7b358424ebad9349421acd533c2fa1cbf6cf3e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 28 Dec 2016 16:52:56 +0100 Subject: Initial import of xtrkcad version 1:4.0.2-2 --- app/help/prochelp.c | 2178 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2178 insertions(+) create mode 100644 app/help/prochelp.c (limited to 'app/help/prochelp.c') diff --git a/app/help/prochelp.c b/app/help/prochelp.c new file mode 100644 index 0000000..d1dd256 --- /dev/null +++ b/app/help/prochelp.c @@ -0,0 +1,2178 @@ + +/* 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); +} -- cgit v1.2.3