Message-ID: <34435C6E.356D@acm.org> Date: Tue, 14 Oct 1997 06:50:06 -0500 From: Randall Maas Reply-To: rcmaas AT piper DOT hamline DOT edu MIME-Version: 1.0 Newsgroups: comp.os.msdos.djgpp Subject: Re: texinfo / makeinfo References: <01bcd2f5$27209b00$1e621ecb AT cybercafe DOT effect DOT net DOT au> Content-Type: multipart/mixed; boundary="------------4A24292D746A" NNTP-Posting-Host: 208.153.214.48 Lines: 335 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk This is a multi-part message in MIME format. --------------4A24292D746A Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit I've written one awhile ago, it it is of any use. it uses "@txh" and "@end txh" to indicate the start and end of formatting. You'll have to tinker with it for your own purposes. Let me know how it goes. Randy Maas randym AT acm DOT org --------------4A24292D746A Content-Type: text/plain; charset=us-ascii; name="c2txh.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="c2txh.c" /* C to TXH translator Copyright 1997, Randall Maas. (randym AT acm DOT org) @txh @node c2txh, utils @subheading Usage @example c2txh -[flags] < file.c >file.txh @end example @subheading Description This will strip out of the comments all of the texinfo documentation within a program. All of the leading white space is also removed, except within an example block. Comments must start and end in the ANSI C standard fashion: /* *@/. To enable texinfo documentation within source code, simply use the marking "@@txh" on line by itself. To disable texinfo, use "@@end txh" on line by itself. Neither of these are marks are outputted. @subheading Flags @table @code @item -s, --strip This prints the file as it would be without the txh markup. @item -h, --help Has info display this help screen. @end table @subheading @@ Commands @table @code @item @@@@ This will produce an @@ in the txh file. @item @@txh This marks the begining of a TXH block. @item @@end txh This marks the end of a TXH block. @item @@/ This will put a / in the TXH file. @item @@example This works just like @@example should, but it also outputs the non-commented C Code as well. @item @@end example This stops doing the above. @end table @subheading Note Future version will require that the headings be contained within braces @{ @}, to improve processing and reduce potential misunderstandings with TeXInfo. (Note: TeXInfo does not support these and so they will be removed.) @end txh */ # include "mylibs.h" // --- Tests for string equality. ------------------------------------------- # define strneq(A,B,N) (strncmp(A,B,N)==0) # define strieq(A,B) (stricmp(A,B)==0) # define Help(x) // --- Working flags -------------------------------------------------------- # define F_Strip (0x1) # define F_Comment (0x2) # define F_TXH (0x4) static unsigned Flags = 0; /* Example is a count of the nestings */ static unsigned Example = 0; typedef struct { char* Begin, Begin_Len; char* End, End_Len; } Block_Mark; # define B_Comment (0) # define B_Example (1) # define B_TXH (2) # define B_At (3) # define B_Slash (4) Block_Mark Block_Marks[]= { {"/*", 2, "*/", 2}, /* Comment */ {"@example", 8, "@end example", 12}, /* Example */ {"@txh", 4, "@end txh", 8}, /* TXH */ {"@@", 2, NULL, 0}, /* At */ {"@/", 2, NULL, 0} /* Slash */ }; static char* Block_Begin(Line, B) char* Line; int B; { /* Determines if we are at the start of a block Return Value Pointer where to process next, if the block began NULL otherwise */ if (!Line) return NULL; if (strneq(Line, Block_Marks[B].Begin, Block_Marks[B].Begin_Len)) return Line + Block_Marks[B].Begin_Len; return NULL; } static char* Block_End(Line, B) char* Line; int B; { if (!Line) return NULL; if (strneq(Line, Block_Marks[B].End, Block_Marks[B].End_Len)) return Line + Block_Marks[B].End_Len; return NULL; } static char* Active_Process(Line) char* Line; { /* Check for each and ever possible active command and do the proper startup processing */ char* X; /* Check for TXH */ X = Block_Begin(Line, B_TXH); if (X) {Line = X; Flags |= F_TXH;} if (!Example && !(Flags & F_TXH)) return Line; X = Block_End(Line, B_TXH); if (X) {Line = X; Flags &= ~F_TXH;} if (!Example && !(Flags & F_TXH)) return Line; /* Check for Example */ X = Block_Begin(Line, B_Example); if (X) { Line = X; Example++; if (!(Flags & F_Strip)) fputs(Block_Marks[B_Example].Begin, stdout); } X = Block_End (Line, B_Example); if (X) { Line = X; Example=Example?Example-1:0; if (!(Flags & F_Strip)) fputs(Block_Marks[B_Example].End, stdout); } /* Check for a literal */ X = Block_Begin(Line, B_At); if (X) { Line = X; if (!(Flags & F_Strip)) fputc('@', stdout); } X = Block_Begin(Line, B_Slash); if (X) { Line = X; if (!(Flags & F_Strip)) fputc('/', stdout); } return Line; } static char* Actives_Process(Line) char* Line; { for (; Line;) { char* X; if (!Example) { int S =0; while (isspace(Line[0])) { S++; if (!Line[0]) { if (!(Flags & F_Strip)) fputc('\n', stdout); return Line; } else if ((Flags & (F_TXH|F_Strip)) == F_Strip) fputc(Line[0], stdout); Line++; } if (S && (Flags & (F_TXH|F_Strip)) == F_TXH) fputc(' ', stdout); } X = Active_Process(Line); if (X == Line) break; Line = X; } return Line; } static char* Line_Active(Line) char* Line; { /* Mode == Comment && !Example */ for(;Line;) { Line = Actives_Process(Line); if (!Line || !Line[0]) { if (!Example && !(Flags & F_Strip)) fputc('\n', stdout); return NULL; } if (Flags & F_Comment) { char* X = Block_End(Line, B_Comment); if (X) { /* End of comment */ Flags &= ~F_Comment; Line = X; if (Flags & F_Strip) fputs(Block_Marks[B_Comment].End, stdout); } } if (!Example && !(Flags & F_Comment)) return Line; if ((Example && !(Flags & F_Strip)) || (Flags & (F_TXH|F_Strip)) == F_TXH || (!Example && (Flags & (F_TXH|F_Strip)) == F_Strip)) fputc(Line[0], stdout); Line++; } return NULL; } static char* Line_Proc(Line) char* Line; { char* X; if (Flags & F_Comment) Line = Actives_Process(Line); /* Determine if we can process this line or not */ if ((Flags & (F_Comment|F_TXH)) == (F_Comment|F_TXH)) Line = Line_Active(Line); if (Example) Line = Line_Active(Line); /* Mode == Code */ while(Line && Line[0]) { if (!(Flags & F_Comment)) { /* We are in C Code area, scan for the start of comments */ char* Y = Block_Begin(Line, B_Comment); if (Y) { Flags |= F_Comment; Line = Y; if (Flags & F_Strip) fputs(Block_Marks[B_Comment].Begin, stdout); Line = Line_Proc(Line); } } else { if (Line[0]) { /* Determine if we should print the character */ if (Flags & F_Strip) fputc(Line[0], stdout); Line++; /* Go to the next character in the line */ } } } return Line; } int main(int argc, char** argv) { unsigned I; char Buffer[255]; /* Parse the command line arguments */ for (I = 1; I < argc; I++) { /* The help flag */ if (strieq("-h", argv[I]) || strieq("--help", argv[I])) { Help(argv[0]); exit(0); /* We don't process on a help request */ } /* The strip flag */ if (strieq("-s", argv[I]) || strieq("--strip", argv[I])) Flags |= F_Strip; } while (!feof(stdin) && fgets(Buffer, 254, stdin)) Line_Proc(Buffer); return 1; } --------------4A24292D746A--