home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
misc
/
wingnuplot
/
doc2ag
/
doc2ag.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-27
|
12KB
|
476 lines
#ifndef lint
static char *RCSid = "$Id: doc2ag.c%v 3.38.2.70 1993/09/19 23:02:23 woo Exp woo $";
#endif
/*
* doc2ag.c -- program to convert Gnuplot .DOC format to AmigaGuide® document
*
* This is version 1.0 written by Thomas Huchtemeier
*
* usage: doc2ag [file.doc [file.guide]]
*
* where file.doc is a Gnuplot .DOC file, and file.guide will be an
* AmigaGuide® hyper-text file
*
* typical usage for GNUPLOT:
*
* doc2ag gnuplot.doc gnuplot.guide
*/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/*!!!!!!!!!!!!! DO NOT EDIT THE FOLLOWING LINES !!!!!!!*/
/*!!!!!!!!!!!!! FOR MODIFICATIOS SEE doc2ag.user !!!!!!!*/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
char Version[] = "$VER: Doc2AG V1.1 ";
#define TEMP_FILE "temp_gnu.guide"
#define TRUE 1
#define FALSE 0
#include "doc2ag.user"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef int boolean;
struct topicList {
int depth;
char *string;
char *orgString;
};
struct linkList {
char *search;
char *linkTo;
};
FILE *temp_guide,
*infile,
*outfile;
struct topicList *topic[MAX_TOPIC_NUM];
struct linkList *linkEntry[MAX_LINK_NUM];
int topicNum = 0,
linkNum = 0,
oldDepth = 2;
result = 0;
void file_header(void);
void make_topics(void);
void make_nodes(void);
void insert_text(void);
void filter_line(char *line);
void make_links(char *line);
void make_entry(int topicDepth, char *topicString, char *orgString);
void parse_line(char *line);
char *upcase(char *string);
void section(char *line);
main(int argc, char *argv[])
{
infile = stdin;
outfile = stdout;
if (argc > 3) {
fprintf(stderr, "Usage: %s [infile [outfile]]\n", argv[0]);
exit(1);
}
if (argc >= 2)
if ( (infile = fopen(argv[1], "r")) == (FILE *)NULL) {
fprintf(stderr, "doc2ag error: Can't open %s for reading\n", argv[1]);
exit(1);
}
if (argc == 3)
if ( (outfile = fopen(argv[2], "w+")) == (FILE *)NULL) {
fprintf(stderr, "doc2ag error: Can't open %s for writing\n", argv[2]);
}
if ( (temp_guide = fopen(TEMP_FILE,"w+")) == (FILE *)NULL) {
fprintf(stderr, "doc2ag error: Can't open %s for writing\n", TEMP_FILE);
}
file_header();
make_nodes();
topicNum -= 1;
make_topics();
fclose(temp_guide);
remove(TEMP_FILE);
fprintf(stderr, "doc2ag success: Conversion completed. Found %d topics and %d links.\n", topicNum,
linkNum);
exit(0);
}
/* The file header gives the required information for an AmigaGuide® database */
void file_header(void)
{
fputs("@database \"gnuplot.guide\"\n@master \"gnuplot.doc\"\n@wordwrap\n\n",
temp_guide);
}
/* Find out the beginning and the end of each node */
void make_nodes(void)
{
static char line[MAX_LINE_LEN];
while (fgets(line,MAX_LINE_LEN, infile)) {
filter_line(line);
}
fputs("@endnode\n", temp_guide);
rewind(temp_guide);
}
/* Insert (sub)topics to special nodes */
void make_topics(void)
{
static char line[MAX_LINE_LEN];
int actStart,
actEnd,
actDepth,
maxDepth,
counter = 1,
oldDepth,
oldCounter,
depthBuffer,
sectionPos[MAX_TOPIC_NUM],
sectionCounter,
tempCounter;
boolean cont, firstTopic = TRUE;
while (fgets(line, MAX_LINE_LEN, temp_guide)) {
if (line[0] == ' ') {
parse_line(line);
}
else {
fputs(line, outfile);
}
maxDepth = 3;
sectionCounter = 0;
cont = TRUE;
if ((strcmp(line, SUBTOPIC_STRING) == 0) && (firstTopic)) {
firstTopic = FALSE;
fputc('\n', outfile);
while (counter <= topicNum) {
if (topic[counter]->depth == 2) {
fputs(topic[counter]->string, outfile);
fputc('\n', outfile);
}
counter++;
}
counter = 1;
}
else if ((strcmp(line, SUBTOPIC_STRING) == 0) && (!firstTopic)) {
while ((topic[counter]->depth == 2) && (counter <= topicNum)) {
counter++;
}
actStart = counter;
while ((topic[counter]->depth > 2) && (counter <= topicNum)) {
if (topic[counter]->depth > maxDepth) {
maxDepth = topic[counter]->depth;
}
counter++;
}
actEnd = counter - 1;
actDepth = topic[actStart]->depth;
counter = actStart;
fputc('\n', outfile);
while (counter <= actEnd) {
if (topic[counter]->depth == actDepth) {
fputs(topic[counter]->string, outfile);
fputc('\n', outfile);
}
counter++;
}
insert_text();
actDepth++;
counter = actStart;
while ((topic[counter]->depth < actDepth) && (counter <= actEnd)) {
counter++;
}
oldDepth = topic[counter]->depth;
fputc('\n', outfile);
while (counter <= actEnd) {
if (topic[counter]->depth == actDepth) {
fputs(topic[counter]->string, outfile);
fputc('\n', outfile);
cont = TRUE;
}
else {
if ((topic[counter]->depth < oldDepth)) {
depthBuffer = topic[counter]->depth;
oldCounter = counter;
while ((topic[counter]->depth == depthBuffer) && (counter <= actEnd)) {
counter++;
}
counter--;
if (counter != actEnd) {
insert_text();
}
counter = oldCounter;
}
if ((topic[counter]->depth > actDepth) && (cont)) {
if (cont) {
sectionCounter++;
sectionPos[sectionCounter] = counter;
cont = FALSE;
}
}
}
oldDepth = topic[counter]->depth;
counter++;
}
counter = actEnd + 1;
}
if ((sectionCounter > 0) && (topic[counter]->depth < oldDepth)) {
insert_text();
tempCounter = 1;
while (tempCounter <= sectionCounter) {
fputc('\n', outfile);
while (topic[sectionPos[tempCounter]]->depth == 5) {
fputs(topic[sectionPos[tempCounter]]->string, outfile);
fputc('\n', outfile);
sectionPos[tempCounter]++;
}
if (tempCounter != sectionCounter) {
insert_text();
}
tempCounter++;
}
}
}
}
/* Read the temp_guide.gnu file until another (sub)topic occurs */
void insert_text(void)
{
static char line[MAX_LINE_LEN];
while ((fgets(line, MAX_LINE_LEN, temp_guide)) && (strcmp(line, SUBTOPIC_STRING) != 0)) {
if (line[0] == ' ') {
parse_line(line);
}
else {
fputs(line, outfile);
}
}
if (strcmp(line, SUBTOPIC_STRING) == 0) {
fputs(line, outfile);
}
}
/* Seperate relevant from non-relevant lines */
void filter_line(char *line)
{
switch(line[0]) { /* control character */
case '?' : { /* interactive help entry */
make_links(line);
break;
}
case '@' : break; /* start/end table */
case '#' : break; /* latex table entry */
case '%' : break; /* troff table entry */
case '\n': /* empty text line */
case ' ' : { /* normal text line */
fputs(line, temp_guide);
break;
}
default : {
if (isdigit(line[0])) { /* start of a (sub)topic */
section(line);
make_links(line+1);
}
else {
fprintf(stderr, "doc2ag error: Unknown control code '%c' in column 1\n", line[0]);
}
break;
}
}
}
/* Upcase strings */
char *upcase(char *string)
{
static char upString[MAX_LINE_LEN];
int counter = 0;
while(string[counter]) {
upString[counter] = toupper(string[counter]);
counter++;
}
upString[counter] = '\0';
return upString;
}
/* Mark keywords found in each line */
void parse_line(char *line)
{
register char actChar;
static boolean inquote = FALSE;
char upStringBuffer[MAX_LINE_LEN],
upLinkSearch[MAX_LINE_LEN],
stringBuffer[MAX_LINE_LEN];
int counter = 0, linkCounter = 1;
static boolean foundLink = FALSE;
while( (actChar = *line++) != '\0') {
switch(actChar) {
case '`':
if (inquote) {
inquote = FALSE;
stringBuffer[counter] = '\0';
while ((!foundLink) && (linkCounter <= linkNum)) {
strcpy(upStringBuffer ,upcase(stringBuffer));
strcpy(upLinkSearch ,upcase(linkEntry[linkCounter]->search));
if (strcmp(upStringBuffer, upLinkSearch) == 0) {
foundLink = TRUE;
fprintf(outfile, "@{\" %s \" link \"%s\"}", stringBuffer,
linkEntry[linkCounter]->linkTo);
}
else {
linkCounter++;
}
}
if ((!foundLink) && (linkCounter >= linkNum)) {
fprintf(outfile, "%s%s%s", MARK_TEXT, stringBuffer, UNMARK_TEXT);
}
}
else {
inquote = TRUE;
foundLink = FALSE;
linkCounter = 1;
counter = 0;
}
break;
default:
if (inquote) {
stringBuffer[counter++] = actChar;
}
else {
fputc(actChar, outfile);
}
break;
}
}
}
/* Make an entry to the (sub)topic-list */
void make_entry(int topicDepth, char *topicString, char *orgString)
{
if (topic[topicNum] = calloc(1, sizeof(struct topicList))) {
if (topic[topicNum]->string=calloc(strlen(topicString)+1,1)) {
if (topic[topicNum]->orgString=calloc(strlen(orgString)+1,1)) {
topic[topicNum]->depth = topicDepth;
strcpy(topic[topicNum]->string, topicString);
strcpy(topic[topicNum]->orgString, orgString);
}
}
}
else {
fprintf(stderr, "doc2ag error: Conversion terminated. Sorry, not enough memory to do my work.\n");
exit(0);
}
}
/* Link interactive help-entries to the recommended (sub)topic */
void make_links(char *line)
{
static char string[MAX_LINE_LEN];
boolean noMemory = FALSE;
sscanf(line+1,"%[^\n]s", string);
if (string[0] != '\0') {
linkNum++;
if (linkNum <= MAX_LINK_NUM) {
if (linkEntry[linkNum] = calloc(1, sizeof(struct linkList))) {
if (linkEntry[linkNum]->search=calloc(strlen(string)+1,1)) {
strcpy(linkEntry[linkNum]->search, string);
if (isspace(line[0])) {
if (linkEntry[linkNum]->linkTo=calloc(strlen(string)+1,1)) {
strcpy(linkEntry[linkNum]->linkTo, string);
}
else {
noMemory = TRUE;
}
}
else {
if (linkEntry[linkNum]->linkTo=calloc(strlen(topic[topicNum-1]->orgString)+1,1)) {
strcpy(linkEntry[linkNum]->linkTo, topic[topicNum-1]->orgString);
}
else {
noMemory = TRUE;
}
}
}
}
else {
noMemory = TRUE;
}
if (noMemory) {
fprintf(stderr, "doc2ag error: Conversion terminated. Sorry, not enough memory to do my work\n");
exit(0);
}
}
else {
fprintf(stderr, "doc2ag error: Conversion terminated. Sorry, too many links. Please revise your #DEFINEs.\n");
exit(0);
}
}
}
/* Insert (sub)topic entries (nodes) to the temp_guide.gnu file and compound
link-entry for the (sub)topic-list */
void section(char *line)
{
static char buttonString[MAX_LINE_LEN],
stringBuffer[MAX_LINE_LEN],
string[MAX_LINE_LEN],
titleString[MAX_LINE_LEN];
int actDepth;
sscanf(line,"%d %[^\n]s", &actDepth, string);
sprintf(buttonString, "%-20s", string);
switch(actDepth) {
case 1:
fputs("@node main \"", temp_guide);
break;
default:
if (oldDepth < actDepth){
fputs(SUBTOPIC_STRING, temp_guide);
fputs("\n@endnode\n", temp_guide);
}
else {
fputs("@endnode\n", temp_guide);
}
sprintf(stringBuffer, " @{\" %s \" link \"%s\"}", buttonString, string);
make_entry(actDepth, stringBuffer, string);
fputs("\n@node \"", temp_guide);
break;
}
if (islower(string[0])) {
string[0] = toupper(string[0]);
}
strcpy(titleString, TITLE);
strcat(titleString, string);
fprintf(temp_guide, "%s\"\n@title \"%s\"\n", string, titleString);
oldDepth = actDepth;
topicNum++;
if (topicNum > MAX_TOPIC_NUM) {
fprintf(stderr, "doc2ag error: Conversion terminated. Sorry, too many topics. Please revise your #DEFINEs.\n");
exit(0);
}
}