File: [local] / OpenXM_contrib / gnuplot / docs / Attic / doc2info.c (download)
Revision 1.1.1.2 (vendor branch), Sat Jan 22 14:16:11 2000 UTC (24 years, 8 months ago) by maekawa
Branch: GNUPLOT
CVS Tags: maekawa-ipv6, VERSION_3_7_1, RELEASE_20000124, RELEASE_1_2_2, RELEASE_1_2_1, RELEASE_1_1_3, RELEASE_1_1_2 Changes since 1.1.1.1: +8 -2
lines
Import gnuplot 3.7.1
|
/*
* $Id: doc2info.c,v 1.9.2.1 1999/08/19 14:31:53 lhecking Exp $
*
*/
/* GNUPLOT - doc2info.c */
/*[
* Copyright 1986 - 1993, 1998 Thomas Williams, Colin Kelley
*
* Permission to use, copy, and distribute this software and its
* documentation for any purpose with or without fee is hereby granted,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation.
*
* Permission to modify the software is granted, but not the right to
* distribute the complete modified source code. Modifications are to
* be distributed as patches to the released version. Permission to
* distribute binaries produced by compiling modified sources is granted,
* provided you
* 1. distribute the corresponding source modifications from the
* released version in the form of a patch file along with the binaries,
* 2. add special version identification to distinguish your version
* in addition to the base release version number,
* 3. provide your name and address as the primary contact for the
* support of your modified version, and
* 4. retain our contact information in regard to use of the base
* software.
* Permission to distribute the released version of the source code along
* with corresponding source modifications in the form of a patch file is
* granted with same provisions 2 through 4 for binary distributions.
*
* This software is provided "as is" without express or implied warranty
* to the extent permitted by applicable law.
]*/
/*
* doc2info.c -- program to convert Gnuplot .DOC format to
* (Emacs -) Info-file format
*
* Created by Stefan Bodewig from doc2gih by Thomas Williams
* and doc2html by Russel Lang
* 1/29/1996
*
* usage: doc2info gnuplot.doc gnuplot.info
*
*/
/* note that tables must begin in at least the second column to */
/* be formatted correctly and tabs are forbidden */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "ansichek.h"
#include "stdfn.h"
#define MAX_LINE_LEN 1023
#include "doc2x.h"
#include "xref.h"
struct BUFFER { /* buffer to reformat paragraphs with xrefs */
char *content;
struct BUFFER *next;
struct BUFFER *prev;
};
struct XREFLIST { /* a list of xrefs allready mentioned in this node */
struct LIST *ref;
struct XREFLIST *next;
struct XREFLIST *prev;
};
/* xref.c */
extern struct LIST *list;
extern struct LIST *head;
extern struct LIST *keylist;
extern struct LIST *keyhead;
extern int maxlevel;
extern int listitems;
char title[MAX_LINE_LEN+1];
char ifile[MAX_LINE_LEN+1];
char ofile[MAX_LINE_LEN+1];
struct XREFLIST *refhead = NULL;
void convert __PROTO((FILE *, FILE *));
void process_line __PROTO((char *, FILE *));
void node_head __PROTO((char *, char *, char *, char *, FILE *));
void name_free __PROTO((char **));
char **name_alloc __PROTO(());
void clear_buffer __PROTO((struct BUFFER *, FILE *));
int inxreflist __PROTO((struct LIST *));
void xref_free __PROTO((void));
int main(argc, argv)
int argc;
char **argv;
{
FILE *infile;
FILE *outfile;
infile = stdin;
outfile = stdout;
if (argc > 3) {
fprintf(stderr, "Usage: %s [infile [outfile]]\n", argv[0]);
exit(EXIT_FAILURE);
}
if (argc >= 2) {
strcpy(ifile, argv[1]);
if ((infile = fopen(argv[1], "r")) == (FILE *) NULL) {
fprintf(stderr, "%s: Can't open %s for reading\n",
argv[0], argv[1]);
exit(EXIT_FAILURE);
}
} else
safe_strncpy(ifile, "gnuplot.doc", sizeof(ifile)); /* default value */
if (argc == 3) {
safe_strncpy(ofile, argv[2], sizeof(ofile));
if ((outfile = fopen(argv[2], "w")) == (FILE *) NULL) {
fprintf(stderr, "%s: Can't open %s for writing\n",
argv[0], argv[2]);
exit(EXIT_FAILURE);
}
} else
safe_strncpy(ofile, "gnuplot.info", sizeof(ofile)); /* default value */
safe_strncpy(title, ofile, sizeof(title));
strtok(title, "."); /* without type */
convert(infile, outfile);
exit(EXIT_SUCCESS);
}
void convert(a, b)
FILE *a, *b;
{
static char line[MAX_LINE_LEN+1];
parse(a);
refhead = (struct XREFLIST *) xmalloc(sizeof(struct XREFLIST));
refhead->next = refhead->prev = NULL;
/* Info header */
fprintf(b, "\
This file is %s created by doc2info from %s.\n\
\n\
START-INFO-DIR-ENTRY\n\
* Gnuplot: (gnuplot). Gnuplot plotting program\n\
END-INFO-DIR-ENTRY\n\n",
ofile, ifile);
/* and Top node */
node_head(NULL, NULL, head->next->string, NULL, b);
while (get_line(line, sizeof(line), a)) {
process_line(line, b);
}
list_free();
free(refhead);
}
/*
* scans the lines for xrefs, creates new nodes and prints or ignores
* the rest.
*
* Info xrefs are visible. Therefore we have to reformat the paragraphs
* containing them. All lines of the paragraph are written into a buffer
* and printed at the end of the paragraph.
*/
void process_line(line, b)
char *line;
FILE *b;
{
static int line_count = 0;
struct LIST *node; /* current node */
static struct LIST *prev = NULL; /* previous node */
int level; /* current level */
static char **up = NULL; /* Array with node names */
static char **pre = NULL;
char topic[MAX_LINE_LEN+1]; /* for xrefs */
int i, j, k, l;
static int inref = FALSE; /* flags */
static int inbold = FALSE;
static struct BUFFER *buffer; /* buffer to hold the lines of a paragraph */
static struct BUFFER *buf_head = NULL;
int inbuf = 0; /* offset into buffer */
char line2[3*MAX_LINE_LEN+1]; /* line of text with added xrefs */
struct LIST *reflist;
static struct XREFLIST *lastref = NULL; /* xrefs that are already mentioned in this node */
line2[0] = NUL;
if (!prev) /* last node visited */
prev = head;
if (!lastref)
lastref = refhead;
if (!up) { /* Names of `Prev:' and `Up:' nodes */
up = name_alloc();
pre = name_alloc();
strcpy(up[0], "(dir)");
strcpy(up[1], "Top");
strcpy(pre[1], "(dir)");
strcpy(pre[2], "Top");
}
line_count++;
if (line[0] == ' ') /* scan line for xrefs */
for (i = 0; line[i] != NUL; ++i)
if (line[i] == '`') { /* Reference or boldface (ignore the latter) */
if (!inref && !inbold) {
k = i + 1; /* next character */
j = 0; /* index into topic */
while (line[k] != '`' && line[k] != NUL)
topic[j++] = line[k++];
topic[j] = NUL;
/* try to find the xref */
reflist = lookup(topic);
if (reflist) {
/* now we have the (key-)list-entry */
/* convert it to a list-entry that represents a node */
reflist = lkup_by_number(reflist->line);
}
/* not interested in xrefs pointing to `Top' or same node */
/* we want only one reference per topic in node */
if (reflist && reflist->level != 0 && reflist != prev && !inxreflist(reflist)) {
/* new entry to xreflist */
lastref->next = (struct XREFLIST *) xmalloc(sizeof(struct XREFLIST));
lastref->next->prev = lastref;
lastref = lastref->next;
lastref->ref = reflist;
lastref->next = NULL;
if (!buf_head) { /* No buffer yet */
buf_head = (struct BUFFER *) xmalloc(sizeof(struct BUFFER));
buffer = buf_head;
buffer->prev = NULL;
buffer->next = NULL;
}
/* eliminate leading spaces of topic */
for (j = 0; isspace((int) reflist->string[j]); ++j);
/* encountered end of line */
if (line[k] == NUL) {
if (line[k - 1] == '\n') /* throw away new-lines */
line[--k] = NUL;
/* insert xref into line */
sprintf(line2, "%s%s (*note %s:: )", line2, line + inbuf, reflist->string + j);
inref = TRUE;
/* line is done */
break;
}
/* eliminate spaces before the second ` */
if (isspace((int) line[k - 1]))
for (l = k - 1; line[l] != NUL; ++l)
line[l] = line[l + 1];
/* let `plot`s look nicer */
if (isalpha((int) line[k + 1]))
++k;
sprintf(line2, "%s%.*s (*note %s:: )", line2, k - inbuf + 1, line + inbuf, reflist->string + j);
/* line2 contains first inbuf characters of line */
i = inbuf = k;
} else { /* found no reference */
inbold = TRUE;
}
} else {
if (inref) /* inref || inbold */
inref = FALSE;
else
inbold = FALSE;
}
}
/* just copy normal characters of line with xref */
else if (inbuf) {
strncat(line2, line + i, 1);
inbuf++;
}
switch (line[0]) { /* control character */
case '?':{ /* interactive help entry */
break; /* ignore */
}
case '@':{ /* start/end table */
break; /* ignore */
}
case '#':{ /* latex table entry */
break; /* ignore */
}
case '%':{ /* troff table entry */
break; /* ignore */
}
case '^':{ /* html entry */
break; /* ignore */
}
case '\n': /* empty text line */
if (buf_head) { /* do we have a buffer? */
/* paragraph finished, print it */
clear_buffer(buf_head, b);
buffer = buf_head = NULL;
} else /* just copy the blank line */
fputs(line, b);
break;
case ' ':{ /* normal text line */
if (buf_head) { /* must be inserted in buffer ? */
buffer->next = (struct BUFFER *) xmalloc(sizeof(struct BUFFER));
buffer->next->prev = buffer;
buffer = buffer->next;
buffer->next = NULL;
if (line2[0] == NUL) { /* line doesn't contain xref */
buffer->content = (char *) xmalloc(strlen(line) + 1);
strcpy(buffer->content, line);
} else { /* line contains xref */
buffer->content = (char *) xmalloc(strlen(line2) + 1);
strcpy(buffer->content, line2);
}
} else /* no buffer, just copy */
fputs(line, b);
break;
}
default:
if (isdigit((int) line[0])) { /* start of section */
/* clear xref-list */
xref_free();
lastref = 0;
if (buf_head) { /* do we have a buffer */
/* paragraphs are not allways separated by a blank line */
clear_buffer(buf_head, b);
buffer = buf_head = NULL;
}
level = line[0] - '0';
if (level > prev->level) /* going down */
/* so write menu of previous node */
refs(prev->line, b, "\n* Menu:\n\n", NULL, "* %s::\n");
node = prev->next;
if (!node->next) { /* last node ? */
node_head(node->string, pre[level + 1], NULL, up[level], b);
name_free(up);
name_free(pre);
/* next node will go up, no 'Next:' node */
} else if (node->next->level < level)
node_head(node->string, pre[level + 1], NULL, up[level], b);
else {
node_head(node->string, pre[level + 1], node->next->string, up[level], b);
strcpy(pre[level + 1], node->string);
/* next node will go down */
if (level < node->next->level) {
strcpy(up[level + 1], node->string);
strcpy(pre[node->next->level + 1], node->string);
}
}
prev = node;
} else
fprintf(stderr, "unknown control code '%c' in column 1, line %d\n",
line[0], line_count);
break;
}
}
/*
* write the header of an Info node, treat Top node specially
*/
void node_head(node, prev, next, up, b)
char *node, *prev, *next, *up;
FILE *b;
{
/* eliminate leading spaces */
while (node && isspace((int) *node))
node++;
while (next && isspace((int) *next))
next++;
while (prev && isspace((int) *prev))
prev++;
while (up && isspace((int) *up))
up++;
if (!prev) { /* Top node */
int i;
fprintf(b, "\nFile: %s, Node: Top, Prev: (dir), Next: %s, Up: (dir)\n\n", ofile, next);
fprintf(b, "%s\n", title);
for (i = 0; i < strlen(title); ++i)
fprintf(b, "*");
fprintf(b, "\n\n");
return;
}
fprintf(b, "\n\nFile: %s, ", ofile);
fprintf(b, "Node: %s, Prev: %s, Up: %s", node, prev, up);
if (next)
fprintf(b, ", Next: %s\n\n", next);
else
fputs("\n\n", b);
}
/*
* allocate memory for the node titles (up and prev)
* need at most maxlevel+Top+(dir) entries
*/
char **name_alloc __PROTO((void))
{
char **a;
int i;
a = (char **) xmalloc((maxlevel + 2) * sizeof(char *));
for (i = 0; i <= maxlevel + 1; i++)
a[i] = (char *) xmalloc(MAX_LINE_LEN+1);
return a;
}
/*
* free node names
*/
void name_free(names)
char **names;
{
int i;
for (i = 0; i <= maxlevel + 1; i++)
free(names[i]);
free(names);
}
/*
* reformat the buffered lines
*/
void clear_buffer(buf_head, b)
struct BUFFER *buf_head;
FILE *b;
{
struct BUFFER *run;
int in_line = 0; /* offset into current line */
int in_buf = 0; /* offset into buffer */
int i, todo;
char c;
/* for all buffer entries */
for (run = buf_head; run->next; run = run->next) {
/* unprinted characters */
todo = strlen(run->next->content);
/* eliminate new-lines */
if (run->next->content[todo - 1] == '\n')
run->next->content[--todo] = NUL;
while (todo)
if (79 - in_line > todo) { /* buffer fits into line */
fprintf(b, "%s", run->next->content + in_buf);
in_line += todo;
todo = in_buf = 0;
} else { /* buffer must be split over lines */
/* search for whitespace to split at */
for (i = 79 - in_line; i > 2; --i)
if (isspace((int) (run->next->content[in_buf + i]))) {
char *beginnote, *linestart;
c = run->next->content[in_buf + i - 1];
if (c == '.') /* don't split at end of sentence */
continue;
if (c == ' ') /* ditto */
continue;
/* dont break xref */
/* search for xref in current line */
linestart = run->next->content + in_buf;
beginnote = strstr(linestart, "(*note");
while (beginnote && beginnote < linestart + i) {
/* don't split if it didn't fit into the line as a whole */
if (strchr(beginnote, ')') > linestart + i)
break;
/* xref is complete, maybe there's another one? */
beginnote = strstr(beginnote + 1, "(*note");
}
/* unbalanced xref ? */
if (beginnote && beginnote < linestart + i)
continue;
break;
}
if (i > 2) { /* found a point to split buffer */
fprintf(b, "%.*s\n", i, run->next->content + in_buf);
todo -= i;
in_buf += i;
in_line = 0;
} else { /* try with a new line */
fputs("\n", b);
in_line = 0;
}
}
}
if (in_line) /* paragraph ended incomplete line */
fputs("\n", b);
fputs("\n", b);
/* free the buffer */
for (run = run->prev; run->prev; run = run->prev) {
free(run->next->content);
free(run->next);
run->next = NULL;
}
if (buf_head->next) {
free(buf_head->next->content);
free(buf_head->next);
buf_head->next = NULL;
}
free(buf_head);
}
/*
* test whether topic is allready referenced in node
*/
int inxreflist(reflist)
struct LIST *reflist;
{
struct XREFLIST *run;
for (run = refhead; run->next; run = run->next)
if (run->next->ref == reflist)
return TRUE;
return FALSE;
}
/*
* free the list of xrefs
*/
void xref_free __PROTO((void))
{
struct XREFLIST *lastref;
for (lastref = refhead; lastref->next; lastref = lastref->next);
if (lastref != refhead)
for (lastref = lastref->prev; lastref->prev; lastref = lastref->prev)
free(lastref->next);
if (refhead->next)
free(refhead->next);
refhead->next = NULL;
}