Blame docs/doc2rtf.c

Packit 0986c0
#ifndef lint
Packit 0986c0
static char *RCSid() { return RCSid("$Id: doc2rtf.c,v 1.16 2007/10/24 00:47:51 sfeam Exp $"); }
Packit 0986c0
#endif
Packit 0986c0
Packit 0986c0
/* GNUPLOT - doc2rtf.c */
Packit 0986c0
Packit 0986c0
/*[
Packit 0986c0
 * Copyright 1986 - 1993, 1998, 2004   Thomas Williams, Colin Kelley
Packit 0986c0
 *
Packit 0986c0
 * Permission to use, copy, and distribute this software and its
Packit 0986c0
 * documentation for any purpose with or without fee is hereby granted,
Packit 0986c0
 * provided that the above copyright notice appear in all copies and
Packit 0986c0
 * that both that copyright notice and this permission notice appear
Packit 0986c0
 * in supporting documentation.
Packit 0986c0
 *
Packit 0986c0
 * Permission to modify the software is granted, but not the right to
Packit 0986c0
 * distribute the complete modified source code.  Modifications are to
Packit 0986c0
 * be distributed as patches to the released version.  Permission to
Packit 0986c0
 * distribute binaries produced by compiling modified sources is granted,
Packit 0986c0
 * provided you
Packit 0986c0
 *   1. distribute the corresponding source modifications from the
Packit 0986c0
 *    released version in the form of a patch file along with the binaries,
Packit 0986c0
 *   2. add special version identification to distinguish your version
Packit 0986c0
 *    in addition to the base release version number,
Packit 0986c0
 *   3. provide your name and address as the primary contact for the
Packit 0986c0
 *    support of your modified version, and
Packit 0986c0
 *   4. retain our contact information in regard to use of the base
Packit 0986c0
 *    software.
Packit 0986c0
 * Permission to distribute the released version of the source code along
Packit 0986c0
 * with corresponding source modifications in the form of a patch file is
Packit 0986c0
 * granted with same provisions 2 through 4 for binary distributions.
Packit 0986c0
 *
Packit 0986c0
 * This software is provided "as is" without express or implied warranty
Packit 0986c0
 * to the extent permitted by applicable law.
Packit 0986c0
]*/
Packit 0986c0
Packit 0986c0
/*
Packit 0986c0
 * doc2rtf.c  -- program to convert Gnuplot .DOC format to MS windows
Packit 0986c0
 * help (.rtf) format.
Packit 0986c0
 *
Packit 0986c0
 * This involves stripping all lines with a leading digit or
Packit 0986c0
 * a leading @, #, or %.
Packit 0986c0
 * Modified by Maurice Castro from doc2gih.c by Thomas Williams
Packit 0986c0
 *
Packit 0986c0
 * usage:  doc2rtf file.doc file.rtf [-d]
Packit 0986c0
 *
Packit 0986c0
 */
Packit 0986c0
Packit 0986c0
/* note that tables must begin in at least the second column to */
Packit 0986c0
/* be formatted correctly and tabs are forbidden */
Packit 0986c0
Packit 0986c0
#ifdef HAVE_CONFIG_H
Packit 0986c0
# include "config.h"
Packit 0986c0
#endif
Packit 0986c0
Packit 0986c0
#include "syscfg.h"
Packit 0986c0
#include "stdfn.h"
Packit 0986c0
#define MAX_LINE_LEN 1023
Packit 0986c0
#include "doc2x.h"
Packit 0986c0
#include "xref.h"
Packit 0986c0
Packit 0986c0
static TBOOLEAN debug = FALSE;
Packit 0986c0
Packit 0986c0
void footnote __PROTO((int, char *, FILE *));
Packit 0986c0
void convert __PROTO((FILE *, FILE *));
Packit 0986c0
void process_line __PROTO((char *, FILE *));
Packit 0986c0
Packit 0986c0
int
Packit 0986c0
main (int argc, char **argv)
Packit 0986c0
{
Packit 0986c0
    FILE *infile;
Packit 0986c0
    FILE *outfile;
Packit 0986c0
    if (argc == 4 && argv[3][0] == '-' && argv[3][1] == 'd')
Packit 0986c0
	debug = TRUE;
Packit 0986c0
Packit 0986c0
    if (argc != 3 && !debug) {
Packit 0986c0
	fprintf(stderr, "Usage: %s infile outfile\n", argv[0]);
Packit 0986c0
	exit(EXIT_FAILURE);
Packit 0986c0
    }
Packit 0986c0
    if ((infile = fopen(argv[1], "r")) == (FILE *) NULL) {
Packit 0986c0
	fprintf(stderr, "%s: Can't open %s for reading\n",
Packit 0986c0
		argv[0], argv[1]);
Packit 0986c0
	exit(EXIT_FAILURE);
Packit 0986c0
    }
Packit 0986c0
    if ((outfile = fopen(argv[2], "w")) == (FILE *) NULL) {
Packit 0986c0
	fprintf(stderr, "%s: Can't open %s for writing\n",
Packit 0986c0
		argv[0], argv[2]);
Packit 0986c0
	exit(EXIT_FAILURE);
Packit 0986c0
    }
Packit 0986c0
    parse(infile);
Packit 0986c0
    convert(infile, outfile);
Packit 0986c0
    return (EXIT_SUCCESS);
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
/* generate an RTF footnote with reference char c and text s */
Packit 0986c0
void
Packit 0986c0
footnote(int c, char *s, FILE *b)
Packit 0986c0
{
Packit 0986c0
    fprintf(b, "%c{\\footnote %c %s}\n", c, c, s);
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
void
Packit 0986c0
convert(FILE *a, FILE *b)
Packit 0986c0
{
Packit 0986c0
    static char line[MAX_LINE_LEN+1];
Packit 0986c0
Packit 0986c0
    /* generate rtf header */
Packit 0986c0
    fprintf(b, "{\\rtf1\\ansi ");	/* vers 1 rtf, ansi char set */
Packit 0986c0
    fprintf(b, "\\deff0");	/* default font font 0 */
Packit 0986c0
    /* font table: font 0 proportional, font 1 fixed */
Packit 0986c0
    fprintf(b, "{\\fonttbl{\\f0\\fswiss Arial;}{\\f1\\fmodern Courier New;}}\n");
Packit 0986c0
Packit 0986c0
    /* process each line of the file */
Packit 0986c0
    while (get_line(line, sizeof(line), a)) {
Packit 0986c0
	process_line(line, b);
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    /* close final page and generate trailer */
Packit 0986c0
    fprintf(b, "}{\\plain \\page}\n");
Packit 0986c0
    /* fprintf(b,"}\n"); */ /* HBB: HACK ALERT: only without this, hc31 works */
Packit 0986c0
    list_free();
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
void
Packit 0986c0
process_line(char *line, FILE *b)
Packit 0986c0
{
Packit 0986c0
    static int line_count = 0;
Packit 0986c0
    static char line2[MAX_LINE_LEN+1];
Packit 0986c0
    static int last_line;
Packit 0986c0
    int i;
Packit 0986c0
    int j;
Packit 0986c0
    static int startpage = 1;
Packit 0986c0
    char str[MAX_LINE_LEN+1];
Packit 0986c0
    char topic[MAX_LINE_LEN+1];
Packit 0986c0
    int k, l;
Packit 0986c0
    static int tabl = 0;
Packit 0986c0
    static int para = 0;
Packit 0986c0
    static int llpara = 0;
Packit 0986c0
    static int inquote = FALSE;
Packit 0986c0
    static int inref = FALSE;
Packit 0986c0
    struct LIST *klist;
Packit 0986c0
    static int initem = FALSE;
Packit 0986c0
Packit 0986c0
    line_count++;
Packit 0986c0
Packit 0986c0
    i = 0;
Packit 0986c0
    j = 0;
Packit 0986c0
    while (line[i] != NUL) {
Packit 0986c0
	switch (line[i]) {
Packit 0986c0
	case '\\':
Packit 0986c0
	case '{':
Packit 0986c0
	case '}':
Packit 0986c0
	    line2[j] = '\\';
Packit 0986c0
	    j++;
Packit 0986c0
	    line2[j] = line[i];
Packit 0986c0
	    break;
Packit 0986c0
	case '\r':
Packit 0986c0
	case '\n':
Packit 0986c0
	    break;
Packit 0986c0
	case '`':		/* backquotes mean boldface or link */
Packit 0986c0
	    if (line[1] == ' ')	/* tabular line */
Packit 0986c0
		line2[j] = line[i];
Packit 0986c0
	    else if ((!inref) && (!inquote)) {
Packit 0986c0
		k = i + 1;	/* index into current string */
Packit 0986c0
		l = 0;		/* index into topic string */
Packit 0986c0
		while ((line[k] != '`') && (line[k] != NUL))
Packit 0986c0
		    topic[l++] = line[k++];
Packit 0986c0
		topic[l] = NUL;
Packit 0986c0
		klist = lookup(topic);
Packit 0986c0
		if (klist && (k = klist->line) > 0 && (k != last_line)) {
Packit 0986c0
		    line2[j++] = '{';
Packit 0986c0
		    line2[j++] = '\\';
Packit 0986c0
		    line2[j++] = 'u';
Packit 0986c0
		    line2[j++] = 'l';
Packit 0986c0
		    line2[j++] = 'd';
Packit 0986c0
		    line2[j++] = 'b';
Packit 0986c0
		    line2[j] = ' ';
Packit 0986c0
		    inref = k;
Packit 0986c0
		} else {
Packit 0986c0
		    if (debug)
Packit 0986c0
			fprintf(stderr, "Can't make link for \042%s\042 on line %d\n", topic, line_count);
Packit 0986c0
		    line2[j++] = '{';
Packit 0986c0
		    line2[j++] = '\\';
Packit 0986c0
		    line2[j++] = 'b';
Packit 0986c0
		    line2[j] = ' ';
Packit 0986c0
		    inquote = TRUE;
Packit 0986c0
		}
Packit 0986c0
	    } else {
Packit 0986c0
		if (inquote && inref)
Packit 0986c0
		    fprintf(stderr, "Warning: Reference Quote conflict line %d\n", line_count);
Packit 0986c0
		if (inquote) {
Packit 0986c0
		    line2[j] = '}';
Packit 0986c0
		    inquote = FALSE;
Packit 0986c0
		}
Packit 0986c0
		if (inref) {
Packit 0986c0
		    /* must be inref */
Packit 0986c0
		    sprintf(topic, "%d", inref);
Packit 0986c0
		    line2[j++] = '}';
Packit 0986c0
		    line2[j++] = '{';
Packit 0986c0
		    line2[j++] = '\\';
Packit 0986c0
		    line2[j++] = 'v';
Packit 0986c0
		    line2[j++] = ' ';
Packit 0986c0
		    line2[j++] = 'l';
Packit 0986c0
		    line2[j++] = 'o';
Packit 0986c0
		    line2[j++] = 'c';
Packit 0986c0
		    k = 0;
Packit 0986c0
		    while (topic[k] != NUL)
Packit 0986c0
			line2[j++] = topic[k++];
Packit 0986c0
		    line2[j] = '}';
Packit 0986c0
		    inref = 0;
Packit 0986c0
		}
Packit 0986c0
	    }
Packit 0986c0
	    break;
Packit 0986c0
	default:
Packit 0986c0
	    line2[j] = line[i];
Packit 0986c0
	}
Packit 0986c0
	i++;
Packit 0986c0
	j++;
Packit 0986c0
	line2[j] = NUL;
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    i = 1;
Packit 0986c0
Packit 0986c0
    switch (line[0]) {		/* control character */
Packit 0986c0
    case '?':{			/* interactive help entry */
Packit 0986c0
	    if ((line2[1] != NUL) && (line2[1] != ' '))
Packit 0986c0
		footnote('K', &(line2[1]), b);
Packit 0986c0
	    break;
Packit 0986c0
	}
Packit 0986c0
    case '@':{			/* start/end table */
Packit 0986c0
	    break;		/* ignore */
Packit 0986c0
	}
Packit 0986c0
    case '^':{			/* html link escape */
Packit 0986c0
	    break;		/* ignore */
Packit 0986c0
	}
Packit 0986c0
    case '=':			/* latex index entry */
Packit 0986c0
    case 'F':			/* latex embedded figure */
Packit 0986c0
    case '#':			/* latex table entry */
Packit 0986c0
	/* or new item entry */
Packit 0986c0
	if (strncmp(line2 + 1, "start", 5) == 0) {
Packit 0986c0
	    fprintf(b, "\\par\n");
Packit 0986c0
	    initem = TRUE;
Packit 0986c0
	} else if (strncmp(line2 + 1, "end", 3) == 0) {
Packit 0986c0
	    fprintf(b, "\\par\n");
Packit 0986c0
	    initem = FALSE;
Packit 0986c0
	} else if ((line2[1] != NUL) && (line2[1] == 'b')) {
Packit 0986c0
	    fprintf(b, "\\par\n");
Packit 0986c0
	    fprintf(b, "\\pard \\plain \\qj \\fs20 \\f0 * ");
Packit 0986c0
	    fprintf(b, "%s", &line2[2]);
Packit 0986c0
        } else if ((line2[1] != NUL) && (line2[1] == '#'))
Packit 0986c0
	  fprintf(b, "%s", &line2[2]);
Packit 0986c0
	break;
Packit 0986c0
    case '%':{			/* troff table entry */
Packit 0986c0
	    break;		/* ignore */
Packit 0986c0
	}
Packit 0986c0
    case '\n':			/* empty text line */
Packit 0986c0
	fprintf(b, "\\par\n");
Packit 0986c0
	llpara = para;
Packit 0986c0
	para = 0;
Packit 0986c0
	tabl = 0;
Packit 0986c0
	break;
Packit 0986c0
    case ' ':{			/* normal text line */
Packit 0986c0
	    if (initem) {
Packit 0986c0
		fprintf(b, "%s", &line2[1]);
Packit 0986c0
		break;
Packit 0986c0
	    }
Packit 0986c0
	    if ((line2[1] == NUL) || (line2[1] == '\n')) {
Packit 0986c0
		fprintf(b, "\\par\n");
Packit 0986c0
		llpara = para;
Packit 0986c0
		para = 0;
Packit 0986c0
		tabl = 0;
Packit 0986c0
	    }
Packit 0986c0
	    if (line2[1] == ' ') {
Packit 0986c0
		if (!tabl) {
Packit 0986c0
		    fprintf(b, "\\par\n");
Packit 0986c0
		}
Packit 0986c0
		fprintf(b, "{\\pard \\plain \\f1\\fs20 ");
Packit 0986c0
		fprintf(b, "%s", &line2[1]);
Packit 0986c0
		fprintf(b, "}\\par\n");
Packit 0986c0
		llpara = 0;
Packit 0986c0
		para = 0;
Packit 0986c0
		tabl = 1;
Packit 0986c0
	    } else {
Packit 0986c0
		if (!para) {
Packit 0986c0
		    if (llpara)
Packit 0986c0
			fprintf(b, "\\par\n");	/* blank line between paragraphs */
Packit 0986c0
		    llpara = 0;
Packit 0986c0
		    para = 1;	/* not in para so start one */
Packit 0986c0
		    tabl = 0;
Packit 0986c0
		    fprintf(b, "\\pard \\plain \\qj \\fs20 \\f0 ");
Packit 0986c0
		}
Packit 0986c0
		fprintf(b, "%s \n", &line2[1]);
Packit 0986c0
	    }
Packit 0986c0
	    break;
Packit 0986c0
	}
Packit 0986c0
    default:{
Packit 0986c0
	    if (isdigit((int)line[0])) {	/* start of section */
Packit 0986c0
		if (startpage) {	/* use new level 0 item */
Packit 0986c0
		    refs(0, b, "\\par", NULL, "\\par{\\uldb %s}{\\v loc%d}\n");
Packit 0986c0
		    fprintf(b, "}{\\plain \\page}\n");
Packit 0986c0
		} else {
Packit 0986c0
		    refs(last_line, b, "\\par", NULL, "\\par{\\uldb %s}{\\v loc%d}\n");
Packit 0986c0
		    fprintf(b, "}{\\plain \\page}\n");
Packit 0986c0
		}
Packit 0986c0
		para = 0;	/* not in a paragraph */
Packit 0986c0
		tabl = 0;
Packit 0986c0
		last_line = line_count;
Packit 0986c0
		startpage = 0;
Packit 0986c0
		fprintf(b, "{\n");
Packit 0986c0
		sprintf(str, "browse:%05d", line_count);
Packit 0986c0
		footnote('+', str, b);
Packit 0986c0
		footnote('$', &(line2[1]), b);	/* title */
Packit 0986c0
		fprintf(b, "{\\b \\fs24 %s}\\plain\\par\\par\n", &(line2[1]));
Packit 0986c0
		/* output unique ID */
Packit 0986c0
		sprintf(str, "loc%d", line_count);
Packit 0986c0
		footnote('#', str, b);
Packit 0986c0
	    } else
Packit 0986c0
		fprintf(stderr, "unknown control code '%c' in column 1, line %d\n",
Packit 0986c0
			line[0], line_count);
Packit 0986c0
	    break;
Packit 0986c0
	}
Packit 0986c0
    }
Packit 0986c0
}