/* -*- c -*- */ /* Butchered version of html2html.l to post-process RTF files * * Steve Tynor (tynor@atlanta.twr.com). I'm not proud of this code. It's a hack * foisted upon a hack, nested within another hack or two. It sort of works * well enough for my purposes (generating WinHelp .RTF files for my documents), * but it could definitely use a redesign/rewrite. I shamelessly blame the RTF * format for most of the hackery here -- RTF is not a _language_ like LaTeX or * ROFF -- it's just a file format. So, we can't rely on RTF to do even simple * things like "insert a paragraph break here only if the previous token was not * also a paragraph break. Since the SGML front end has no conditional processing * capabilities, multiple blank likes in the SGML get translated to multiple para * breaks in the RTF (actually, that's why I use the <@@par> crap....). * * XREF: BROKEN_DELIMITERS: We say "{}K{\footnote .." instead of just * "\nK{\footnote .." since the MicroS$ft RTF parser does not (always?) treat * white space as a delimeter before a hyperlink markup. * * ESR reordered the @@indent rules to eliminate a generation-time warning. */ %{ #include #include #include /* #define DEBUG */ /* NOTE: must be kept in sync with the

defs in mapping */ #define LEFTMARGIN 500 #define NEWPAR "\\par\\pard\\plain\\li500\\sb200\\fi0" #define INDENT_AMT 500 /* twips for each level of indentation */ const static char* header = "{\\rtf1\\ansi\n" "{\\fonttbl\n" "{\\f0\\fswiss Helvetica;}\n" "{\\f1\\fmodern Courier;}\n" "{\\f2\\froman Times;}\n" "{\\f3\\froman Symbol;}\n" "}\n" "{\\info{\\comment Translated from SGML to RTF w/ Linuxdoc-SGML}}\n" ; int big_page_mode = 1; /* default is backwards compatible */ /* style uses as the top-level section;
uses . We need to know whether a should be numbered as "n" or "n.m". We assume
more unless we see a */ int chapter_mode = 0; int section_id = 0; /* used for TOC hyperlinks */ int in_appendix = 0; FILE *out; FILE *idx_fp; char buf[2048], sectname[256], labeltxt[256]; char firstname[256], outname[256]; char ssectname[256], Tmp1[4096], Tmp2[256], headname[256]; char urlname[256], Headbuf[4096], refname[256]; int indent = 0; int nofill = 0; int filenum = 1; int filecount = 1; int tmpfn; int secnr = 0; int ssecnr; int current; int skipnewline = 0; extern char *yytext; #if (YY_FLEX_MAJOR_VERSION == 2 && YY_FLEX_MINOR_VERSION == 5 && YY_FLEX_SUBMINOR_VERSION > 35) \ || (YY_FLEX_MAJOR_VERSION == 2 && YY_FLEX_MINOR_VERSION == 6 && YY_FLEX_SUBMINOR_VERSION == 0) extern yy_size_t yyleng; #else extern int yyleng; #endif #define CHAPTER 1 #define SECTION 2 #define SUBSECT 3 void fatal_perror ( char *fmt, char *arg ) { fprintf( stderr, "rtf2rtf: Fatal: " ); fprintf( stderr, fmt, arg); perror( "\nReason"); exit(1); } int getstr( char *str, int n ) { #ifdef DEBUG fprintf( stderr, "DEBUG: yytext: <<%s>>\n", yytext ); #endif if( strlen( yytext ) == n ) return 0; strncpy( str, yytext+n, yyleng-n); str[ yyleng-n ] = 0; return 1; } void put_reference (FILE *fp, char *str) { char *p; char buf[2] = {0, 0}; /* trim trailing spaces: */ while (str[strlen(str)-1] == ' ') { str[strlen(str)-1] = '\0'; } /* replace non-legal topic-id characters with underscores */ p = str; while (*p) { buf[0] = *p; if (! strpbrk(buf, "abcdegfhijklmnopqrstuvwxyz" "ABCDEGFHIJKLMNOPQRSTUVWXYZ" "0123456789")) { fprintf (fp, "_"); } else { fprintf (fp, "%c", *p); } p++; } } void put_secnum (FILE *fp, int s1, int s2) { if (in_appendix) { if (s2 == 0) { fprintf (fp, "%c", 'A'-1+s1); } else { fprintf (fp, "%c.%d", 'A'-1+s1, s2); } } else { if (s2 == 0) { fprintf (fp, "%d", s1); } else { fprintf (fp, "%d.%d", s1, s2); } } } void heading (char *str, int s1, int s2, int newpage) { if (newpage && (out == stdout)) { sprintf (outname, "%s-0.rtf", firstname); out = fopen (outname, "w"); if (! out ) { fatal_perror ("Could not open file \"%s\"", outname); } fputs (header, out); } /* fprintf (out, "\n\\page{\\pard\\plain\\s2\\f0\\fs%d\\b\\fi0\\li576\\sb160\\sa160\\tx576 { }", (s2==0 ? 36 : 24) ); */ if (newpage) { fprintf (out, "\n\\page{\\pard\\plain\\keepn\\f0\\fs%d\\b\\tx576{", (s2==0 ? 36 : 24) ); } else { fprintf (out, "\n{\\pard\\sb200\\plain\\f0\\fs%d\\b\\tx576{", (s2==0 ? 36 : 24) ); } put_secnum (out, s1, s2); fprintf (out, " %s}}", str); /* Used as a target for the link on the TOC page. Use a SECT_ prefix just in case the document has any explicit