Initial release of Maemo 5 port of gnuplot
[gnuplot] / docs / doc2ms.c
1 #ifndef lint
2 static char *RCSid() { return RCSid("$Id: doc2ms.c,v 1.18 2005/06/03 05:11:55 sfeam Exp $"); }
3 #endif
4
5 /* GNUPLOT - doc2ms.c */
6
7 /*[
8  * Copyright 1986 - 1993, 1998, 2004   Thomas Williams, Colin Kelley
9  *
10  * Permission to use, copy, and distribute this software and its
11  * documentation for any purpose with or without fee is hereby granted,
12  * provided that the above copyright notice appear in all copies and
13  * that both that copyright notice and this permission notice appear
14  * in supporting documentation.
15  *
16  * Permission to modify the software is granted, but not the right to
17  * distribute the complete modified source code.  Modifications are to
18  * be distributed as patches to the released version.  Permission to
19  * distribute binaries produced by compiling modified sources is granted,
20  * provided you
21  *   1. distribute the corresponding source modifications from the
22  *    released version in the form of a patch file along with the binaries,
23  *   2. add special version identification to distinguish your version
24  *    in addition to the base release version number,
25  *   3. provide your name and address as the primary contact for the
26  *    support of your modified version, and
27  *   4. retain our contact information in regard to use of the base
28  *    software.
29  * Permission to distribute the released version of the source code along
30  * with corresponding source modifications in the form of a patch file is
31  * granted with same provisions 2 through 4 for binary distributions.
32  *
33  * This software is provided "as is" without express or implied warranty
34  * to the extent permitted by applicable law.
35 ]*/
36
37 /*
38  * doc2ms.c  -- program to convert Gnuplot .DOC format to *roff -ms document
39  * From hlp2ms by Thomas Williams
40  *
41  * Modified by Russell Lang, 2nd October 1989
42  * to make vms help level 1 and 2 create the same ms section level.
43  *
44  * Modified to become doc2ms by David Kotz (David.Kotz@Dartmouth.edu) 12/89
45  * Added table and backquote support.
46  *
47  * usage:  doc2ms [file.doc [file.ms]]
48  *
49  *   where file.doc is a VMS .DOC file, and file.ms will be a [nt]roff
50  *     document suitable for printing with nroff -ms or troff -ms
51  *
52  * typical usage for GNUPLOT:
53  *
54  *   doc2ms gnuplot.doc | tbl | eqn | troff -ms
55  *
56  * or
57  *
58  *   doc2ms gnuplot.doc | groff -ms -et >gnuplot.ps
59  */
60
61 #ifdef HAVE_CONFIG_H
62 # include "config.h"
63 #endif
64
65 #include "syscfg.h"
66 #include "stdfn.h"
67 #include "doc2x.h"
68
69 #define LINE_SKIP               3
70
71 void init __PROTO((FILE *));
72 void convert __PROTO((FILE *, FILE *));
73 void process_line __PROTO((char *, FILE *));
74 void section __PROTO((char *, FILE *));
75 void putms __PROTO((char *, FILE *));
76 void putms_verb __PROTO((char *, FILE *));
77 void finish __PROTO((FILE *));
78
79 static TBOOLEAN intable = FALSE;
80
81 int
82 main (int argc, char **argv)
83 {
84     FILE *infile;
85     FILE *outfile;
86     infile = stdin;
87     outfile = stdout;
88     if (argc > 3) {
89         fprintf(stderr, "Usage: %s [infile [outfile]]\n", argv[0]);
90         exit(EXIT_FAILURE);
91     }
92     if (argc >= 2) {
93         if ((infile = fopen(argv[1], "r")) == (FILE *) NULL) {
94             fprintf(stderr, "%s: Can't open %s for reading\n",
95                     argv[0], argv[1]);
96             exit(EXIT_FAILURE);
97         }
98     }
99     if (argc == 3) {
100         if ((outfile = fopen(argv[2], "w")) == (FILE *) NULL) {
101             fprintf(stderr, "%s: Can't open %s for writing\n",
102                     argv[0], argv[2]);
103             exit(EXIT_FAILURE);
104         }
105     }
106     init(outfile);
107     convert(infile, outfile);
108     finish(outfile);
109     return EXIT_SUCCESS;
110 }
111
112
113 void
114 init(FILE *b)
115 {
116     /* in nroff, increase line length by 8 and don't adjust lines */
117     (void) fputs(".if n \\{.nr LL +8m\n.na \\}\n\
118 .nr PO +0.3i\n\
119 .so titlepag.ms\n\
120 .pn 1\n\
121 .bp\n\
122 .ta 1.5i 3.0i 4.5i 6.0i 7.5i\n\
123 \\&\n.sp 3\n.PP\n", b);
124
125     /* following line commented out by rjl
126        (void) fputs(".so intro\n",b);
127      */
128 }
129
130
131 void
132 convert( FILE *a, FILE *b)
133 {
134     static char line[MAX_LINE_LEN+1];
135
136     while (get_line(line, sizeof(line), a)) {
137         process_line(line, b);
138     }
139 }
140
141 void
142 process_line( char *line, FILE *b)
143 {
144     switch (line[0]) {          /* control character */
145     case '?':{                  /* interactive help entry */
146             break;              /* ignore */
147         }
148     case '@':{                  /* start/end table */
149             if (intable) {
150                 (void) fputs(".TE\n.KE\n", b);
151                 (void) fputs(".EQ\ndelim off\n.EN\n\n", b);
152                 intable = FALSE;
153             } else {
154                 (void) fputs("\n.EQ\ndelim $$\n.EN\n", b);
155                 (void) fputs(".KS\n.TS\ncenter box tab (@) ;\n", b);
156                 /* moved to gnuplot.doc by RCC
157                    (void) fputs("c c l .\n", b);
158                  */
159                 intable = TRUE;
160             }
161             /* ignore rest of line */
162             break;
163         }
164     case '^':{                  /* html table entry */
165             break;              /* ignore */
166         }
167     case '=':                   /* latex index entry */
168     case '#':{                  /* latex table entry */
169             break;              /* ignore */
170         }
171     case '%':{                  /* troff table entry */
172             if (intable)
173                 (void) fputs(line + 1, b);      /* copy directly */
174             else
175                 fprintf(stderr, "error: %% line found outside of table\n");
176             break;
177         }
178     case '\n':                  /* empty text line */
179     case ' ':{                  /* normal text line */
180             if (intable)
181                 break;          /* ignore while in table */
182             switch (line[1]) {
183             case ' ':{
184                     /* verbatim mode */
185                     fputs(".br\n", b);
186                     putms_verb(line + 1, b);
187                     fputs(".br\n", b);
188                     break;
189                 }
190             case '\'':{
191                     fputs("\\&", b);
192                     putms(line + 1, b);
193                     break;
194                 }
195             case '.':{          /* hide leading . from ms */
196                     fputs("\\&", b);
197                     putms(line + 1, b);
198                     break;
199                 }
200             default:{
201                     if (line[0] == '\n')
202                         putms(line, b);         /* handle totally blank line */
203                     else
204                         putms(line + 1, b);
205                     break;
206                 }
207                 break;
208             }
209             break;
210         }
211     default:{
212             if (isdigit((int)line[0])) {        /* start of section */
213                 if (!intable)   /* ignore while in table */
214                     section(line, b);
215             } else
216                 fprintf(stderr, "unknown control code '%c' in column 1\n",
217                         line[0]);
218             break;
219         }
220     }
221 }
222
223
224 /* process a line with a digit control char */
225 /* starts a new [sub]section */
226
227 void
228 section( char *line, FILE *b)
229 {
230     static char string[MAX_LINE_LEN+1];
231     int sh_i;
232     static int old = 1;
233
234
235     (void) sscanf(line, "%d %[^\n]s", &sh_i, string);
236
237     (void) fprintf(b, ".sp %d\n", (sh_i == 1) ? LINE_SKIP : LINE_SKIP - 1);
238
239     if (sh_i > old) {
240         do
241             if (old != 1)       /* this line added by rjl */
242                 (void) fputs(".RS\n.IP\n", b);
243         while (++old < sh_i);
244     } else if (sh_i < old) {
245         do
246             if (sh_i != 1)      /* this line added by rjl */
247                 (void) fputs(".RE\n.br\n", b);
248         while (--old > sh_i);
249     }
250     /* added by dfk to capitalize section headers */
251     if (islower((int)string[0]))
252         string[0] = toupper(string[0]);
253
254     /* next 3 lines added by rjl */
255     if (sh_i != 1)
256         (void) fprintf(b, ".NH %d\n%s\n.sp 1\n.LP\n", sh_i - 1, string);
257     else
258         (void) fprintf(b, ".NH %d\n%s\n.sp 1\n.LP\n", sh_i, string);
259     old = sh_i;
260
261     (void) fputs(".XS\n", b);
262     (void) fputs(string, b);
263     (void) fputs("\n.XE\n", b);
264 }
265
266 void
267 putms( char *s, FILE *file)
268 {
269     static TBOOLEAN inquote = FALSE;
270
271     while (*s != NUL) {
272         switch (*s) {
273         case '`':{              /* backquote -> boldface */
274                 if (inquote) {
275                     fputs("\\fR", file);
276                     inquote = FALSE;
277                 } else {
278                     fputs("\\fB", file);
279                     inquote = TRUE;
280                 }
281                 break;
282             }
283         case '\\':{             /* backslash */
284                 fputs("\\\\", file);
285                 break;
286             }
287         case '\'':{             /* single quote */
288                 fputs("\\&'", file);
289                 break;
290             }
291         default:{
292                 fputc(*s, file);
293                 break;
294             }
295         }
296         s++;
297     }
298 }
299
300 /*
301  * convert a verbatim line to troff input style, i.e. convert "\" to "\\"
302  * (added by Alexander Lehmann 01/30/93)
303  */
304
305 void
306 putms_verb( char *s, FILE *file)
307 {
308     while (*s != '\0') {
309         if (*s == '\\') {
310             fputc('\\', file);
311         }
312         fputc(*s, file);
313         s++;
314     }
315 }
316
317 /* spit out table of contents */
318 void
319 finish(FILE *b)
320 {
321     fputs("\
322 .pn 1\n\
323 .ds RH %\n\
324 .af % i\n\
325 .bp\n.PX\n", b);
326 }