2 /* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.com)
5 This file is part of groff.
7 groff is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 groff is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License along
18 with groff; see the file COPYING. If not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "stringclass.h"
24 #include "searchpath.h"
25 #include "macropath.h"
27 #define STARTUP_FILE "eqnrc"
31 static char *delim_search(char *, int);
32 static int inline_equation(FILE *, string &, string &);
34 char start_delim = '\0';
35 char end_delim = '\0';
39 int one_size_reduction_flag = 0;
40 int compatible_flag = 0;
41 int no_newline_in_delim_flag = 0;
43 int read_line(FILE *fp, string *p)
47 while ((c = getc(fp)) != EOF) {
48 if (!illegal_input_char(c))
51 error("illegal input character code `%1'", c);
56 return p->length() > 0;
59 void do_file(FILE *fp, const char *filename)
63 printf(".lf 1 %s\n", filename);
64 current_filename = filename;
66 while (read_line(fp, &linebuf)) {
67 if (linebuf.length() >= 4
68 && linebuf[0] == '.' && linebuf[1] == 'l' && linebuf[2] == 'f'
69 && (linebuf[3] == ' ' || linebuf[3] == '\n' || compatible_flag)) {
70 put_string(linebuf, stdout);
72 if (interpret_lf_args(linebuf.contents() + 3))
75 else if (linebuf.length() >= 4
79 && (linebuf[3] == ' ' || linebuf[3] == '\n' || compatible_flag)) {
80 put_string(linebuf, stdout);
81 put_string(".if '\\*(.T'html' \\X(graphic-start(\\c\n", stdout);
82 int start_lineno = current_lineno + 1;
85 if (!read_line(fp, &linebuf))
86 fatal("end of file before .EN");
87 if (linebuf.length() >= 3 && linebuf[0] == '.' && linebuf[1] == 'E') {
89 && (linebuf.length() == 3 || linebuf[3] == ' '
90 || linebuf[3] == '\n' || compatible_flag))
92 else if (linebuf[2] == 'Q' && linebuf.length() > 3
93 && (linebuf[3] == ' ' || linebuf[3] == '\n'
101 init_lex(str.contents(), current_filename, start_lineno);
105 if (non_empty_flag) {
106 printf(".lf %d\n", current_lineno - 1);
109 restore_compatibility();
110 printf(".lf %d\n", current_lineno);
111 put_string(".if '\\*(.T'html' \\X(graphic-end(\\c\n", stdout);
112 put_string(linebuf, stdout);
114 else if (start_delim != '\0' && linebuf.search(start_delim) >= 0
115 && inline_equation(fp, linebuf, str))
118 put_string(linebuf, stdout);
120 current_filename = 0;
124 /* Handle an inline equation. Return 1 if it was an inline equation,
127 static int inline_equation(FILE *fp, string &linebuf, string &str)
130 char *ptr = &linebuf[0];
131 char *start = delim_search(ptr, start_delim);
133 // It wasn't a delimiter after all.
134 linebuf.set_length(linebuf.length() - 1); // strip the '\0'
140 if (no_newline_in_delim_flag && strchr(start + 1, end_delim) == 0) {
141 error("missing `%1'", end_delim);
142 char *nl = strchr(start + 1, '\n');
148 int start_lineno = current_lineno;
154 char *end = strchr(ptr, end_delim);
162 if (!read_line(fp, &linebuf))
163 fatal("end of file before `%1'", end_delim);
168 put_string(".if '\\*(.T'html' \\X(graphic-start(\\c\n", stdout);
169 init_lex(str.contents(), current_filename, start_lineno);
171 start = delim_search(ptr, start_delim);
173 char *nl = strchr(ptr, '\n');
180 printf(".lf %d\n", current_lineno);
182 restore_compatibility();
183 put_string(".if '\\*(.T'html' \\X(graphic-end(\\c\n", stdout);
184 printf(".lf %d\n", current_lineno + 1);
188 /* Search for delim. Skip over number register and string names etc. */
190 static char *delim_search(char *ptr, int delim)
195 if (*ptr++ == '\\') {
207 if (*++ptr != '\\' && *ptr != '\0' && *++ptr != '\\' && *ptr != '\0')
211 while (*++ptr != '\0')
237 "usage: %s [ -rvDCNR ] -dxx -fn -sn -pn -mn -Mdir -Ts [ files ... ]\n",
242 int main(int argc, char **argv)
244 program_name = argv[0];
245 static char stderr_buf[BUFSIZ];
246 setbuf(stderr, stderr_buf);
248 int load_startup_file = 1;
249 while ((opt = getopt(argc, argv, "DCRvd:f:p:s:m:T:M:rN")) != EOF)
254 case 'R': // don't load eqnchar
255 load_startup_file = 0;
258 macro_path.command_line_dir(optarg);
262 extern const char *version_string;
263 fprintf(stderr, "GNU eqn version %s\n", version_string);
268 if (optarg[0] == '\0' || optarg[1] == '\0')
269 error("-d requires two character argument");
270 else if (illegal_input_char(optarg[0]))
271 error("bad delimiter `%1'", optarg[0]);
272 else if (illegal_input_char(optarg[1]))
273 error("bad delimiter `%1'", optarg[1]);
275 start_delim = optarg[0];
276 end_delim = optarg[1];
286 if (!set_gsize(optarg))
287 error("invalid size `%1'", optarg);
292 if (sscanf(optarg, "%d", &n) == 1)
293 set_script_reduction(n);
295 error("bad size `%1'", optarg);
301 if (sscanf(optarg, "%d", &n) == 1)
304 error("bad size `%1'", optarg);
308 one_size_reduction_flag = 1;
311 warning("-D option is obsolete: use `set draw_lines 1' instead");
315 no_newline_in_delim_flag = 1;
325 printf(".if !'\\*(.T'%s' "
326 ".tm warning: %s should have been given a `-T\\*(.T' option\n",
327 device, program_name);
328 if (load_startup_file) {
330 FILE *fp = macro_path.open_file(STARTUP_FILE, &path);
340 for (int i = optind; i < argc; i++)
341 if (strcmp(argv[i], "-") == 0)
345 FILE *fp = fopen(argv[i], "r");
347 fatal("can't open `%1': %2", argv[i], strerror(errno));
349 do_file(fp, argv[i]);
353 if (ferror(stdout) || fflush(stdout) < 0)
354 fatal("output error");