/* * j2t.lex : An example of the use (possibly abuse!) * of start states. */ %{ #define MAX_STATES 1024 #define TRUE 1 #define FALSE 0 #define CHAPTER "@chapter" #define SECTION "@section" #define SSECTION "@subsection" #define SSSECTION "@subsubsection" int states[MAX_STATES]; int statep = 0; int need_closing = FALSE; char buffer[YY_BUF_SIZE]; extern char *yytext; /* * set up the head of the *.texinfo file the program * will produce. This is a standard texinfo header. */ void print_header(void) { printf("\\input texinfo @c -*-texinfo-*-\n"); printf("@c %c**start of header\n",'%'); printf("@setfilename jargon.info\n"); printf("@settitle The New Hackers Dictionary\n"); printf("@synindex fn cp\n"); printf("@synindex vr cp\n"); printf("@c %c**end of header\n",'%'); printf("@setchapternewpage odd\n"); printf("@finalout\n"); printf("@c @smallbook\n"); printf("\n"); printf("@c ==========================================================\n\n"); printf("@c This file was produced by j2t. Any mistakes are *not* the\n"); printf("@c fault of the jargon file editors. \n"); printf("@c ==========================================================\n\n"); printf("@titlepage\n"); printf("@title The New Hackers Dictionary\n"); printf("@subtitle Version 2.9.10\n"); printf("@subtitle Generated by j2t\n"); printf("@author Eric S. Raymond, Guy L. Steel, Mark Crispin et al.\n"); printf("@end titlepage\n"); printf("@page\n"); printf("\n@c ==========================================================\n"); printf("\n\n"); printf("@unnumbered Preface\n"); printf("@c *******\n"); } /* * create the tail of the texinfo file produced. */ void print_trailer(void) { printf("\n@c ==========================================================\n"); printf("@contents\n"); /* print the table of contents */ printf("@bye\n\n"); } /* * write an underline under a section * or chapter so we can find it later. */ void write_underline(int len, int space, char ch) { int loop; printf("@c "); for(loop=3; loop<space; loop++){ printf(" "); } while(len--){ printf("%c",ch); } printf("\n\n"); } /* * check for texinfo special characters * and escape them */ char *check_and_convert(char *string) { int buffpos = 0; int len,loop; len = strlen(string); for(loop=0; loop<len; loop++){ if(string[loop] == '@' || string[loop] == '{' || string[loop] == '}'){ buffer[buffpos++] = '@'; buffer[buffpos++] = string[loop]; } else { buffer[buffpos++] = string[loop]; } } buffer[buffpos] = '\0'; return(buffer); } /* * write out a chapter,section, or subsection * header */ void write_block_header(char *type) { int loop; int len; (void)check_and_convert(yytext); len = strlen(buffer); for(loop=0; buffer[loop] != '\n';loop++) ; buffer[loop] = '\0'; printf("%s %s\n",type,buffer); write_underline(strlen(buffer),strlen(type)+1,'*'); } %} /* * the flex description starts here */ %x HEADING EXAMPLE ENUM EXAMPLE2 %x BITEM BITEM_ITEM %s LITEM LITEM2 %% ^#[^#]*"#" /* skip the header & trailer */ /* chapters have asterisks under them * and are terminated by a colon */ ^[^\n:]+\n[*]+\n write_block_header(CHAPTER); ^"= "[A-Z]" ="\n"="* { /* we create a seciton for each category */ if(need_closing == TRUE){ printf("@end table\n\n\n"); } need_closing = TRUE; write_block_header(SECTION); printf("\n\n@table @b\n"); } "Examples:"[^\.]+ ECHO; "*"[^*\n]+"*" { /* @emph{}(emphasized) text */ yytext[yyleng-1] = '\0'; (void)check_and_convert(&yytext[1]); printf("@i{%s}",buffer); } "{{"[^}]+"}}" { /* special emphasis */ yytext[yyleng-2] = '\0'; (void)check_and_convert(&yytext[2]); printf("@b{%s}",buffer); } "{"[^}]+"}" { /* special emphasis */ yytext[yyleng-1] = '\0'; (void)check_and_convert(&yytext[1]); printf("@b{%s}",buffer); } /* escape some special texinfo characters */ <INITIAL,LITEM,LITEM2,BITEM,ENUM,EXAMPLE,EXAMPLE2>"@" printf("@@"); <INITIAL,LITEM,LITEM2,BITEM,ENUM,EXAMPLE,EXAMPLE2>"{" printf("@{"); <INITIAL,LITEM,LITEM2,BITEM,ENUM,EXAMPLE,EXAMPLE2>"}" printf("@}"); /* * reproduce @example code */ ":"\n+[^\n0-9*]+\n" "[^ ] { int loop; int len; int cnt; printf(":\n\n@example \n"); strcpy(buffer,yytext); len = strlen(buffer); cnt = 0; for(loop=len; loop > 0;loop--){ if(buffer[loop] == '\n') cnt++; if(cnt == 2) break; } yyless(loop+1); statep++; states[statep] = EXAMPLE2; BEGIN(EXAMPLE2); } <EXAMPLE,EXAMPLE2>^\n { printf("@end example\n\n"); statep--; BEGIN(states[statep]); } /* * repoduce @enumerate lists */ ":"\n+[ \t]*[0-9]+"." { int loop; int len; printf(":\n\n@enumerate \n"); strcpy(buffer,yytext); len = strlen(buffer); for(loop=len; loop > 0;loop--){ if(buffer[loop] == '\n') break; } yyless(loop); statep++; states[statep] = ENUM; BEGIN(ENUM); } <ENUM>"@" printf("@@"); <ENUM>":"\n+" "[^0-9] { printf(":\n\n@example\n"); statep++; states[statep] = EXAMPLE; BEGIN(EXAMPLE); } <ENUM>\n[ \t]+[0-9]+"." { printf("\n\n@item "); } <ENUM>^[^ ] | <ENUM>\n\n\n[ \t]+[^0-9] { printf("\n\n@end enumerate\n\n"); statep--; BEGIN(states[statep]); } /* * reproduce one kind of @itemize list */ ":"\n+":" { int loop; int len; printf(":\n\n@itemize @bullet \n"); yyless(2); statep++; states[statep] = LITEM2; BEGIN(LITEM2); } <LITEM2>^":".+":" { (void)check_and_convert(&yytext[1]); buffer[strlen(buffer)-1]='\0'; printf("@item @b{%s:}\n",buffer); } <LITEM2>\n\n\n+[^:\n] { printf("\n\n@end itemize\n\n"); ECHO; statep--; BEGIN(states[statep]); } /* * create a list out of the revision history part. * We need the "Version" for this because it * clashes with other rules otherwise. */ :[\n]+"Version"[^:\n*]+":" { int loop; int len; printf(":\n\n@itemize @bullet \n"); strcpy(buffer,yytext); len = strlen(buffer); for(loop=len; loop > 0;loop--){ if(buffer[loop] == '\n') break; } yyless(loop); statep++; states[statep] = LITEM; BEGIN(LITEM); } <LITEM>^.+":" { (void)check_and_convert(yytext); buffer[strlen(buffer)-1]='\0'; printf("@item @b{%s}\n\n",buffer); } <LITEM>^[^:\n]+\n\n[^:\n]+\n { int loop; strcpy(buffer,yytext); for(loop=0; buffer[loop] != '\n'; loop++); buffer[loop] = '\0'; printf("%s\n",buffer); printf("@end itemize\n\n"); printf("%s",&buffer[loop+1]); statep--; BEGIN(states[statep]); } /* * reproduce @itemize @bullet lists */ ":"\n[ ]*"*" { int loop; int len; printf(":\n\n@itemize @bullet \n"); len = strlen(buffer); for(loop=0; loop < len;loop++){ if(buffer[loop] == '\n') break; } yyless((len-loop)+2); statep++; states[statep] = BITEM; BEGIN(BITEM); } <BITEM>^" "*"*" { printf("@item"); statep++; states[statep] = BITEM_ITEM; BEGIN(BITEM_ITEM); } <BITEM>"@" printf("@@"); <BITEM>^\n { printf("@end itemize\n\n"); statep--; BEGIN(states[statep]); } <BITEM_ITEM>[^\:]* { printf(" @b{%s}\n\n",check_and_convert(yytext)); } <BITEM_ITEM>":" { statep--; BEGIN(states[statep]); } /* * recreate @chapter, @section etc. */ ^:[^:]* { (void)check_and_convert(&yytext[1]); statep++; states[statep] = HEADING; BEGIN(HEADING); } <HEADING>:[^\n] { printf("@item @b{%s}\n",buffer); write_underline(strlen(buffer),6,'~'); statep--; BEGIN(states[statep]); } <HEADING>:\n"*"* { if(need_closing == TRUE){ printf("@end table\n\n\n"); need_closing = FALSE; } printf("@chapter %s\n",buffer); write_underline(strlen(buffer),9,'*'); statep--; BEGIN(states[statep]); } <HEADING>:\n"="* { if(need_closing == TRUE){ printf("@end table\n\n\n"); need_closing = FALSE; } printf("@section %s\n",buffer); write_underline(strlen(buffer),9,'='); statep--; BEGIN(states[statep]); } <HEADING>"@" printf("@@"); <HEADING>:\n"-"* { if(need_closing == TRUE){ printf("@end table\n\n\n"); need_closing = FALSE; } printf("@subsection %s\n",buffer); write_underline(strlen(buffer),12,'-'); statep--; BEGIN(states[statep]); } /* * recreate @example text */ ^" " { printf("@example\n"); statep++; states[statep] = EXAMPLE; BEGIN(EXAMPLE); } <EXAMPLE>^" " . ECHO; %% /* * initialise and go. */ int main(int argc, char *argv[]) { states[0] = INITIAL; statep = 0; print_header(); yylex(); print_trailer(); return(0); }