4 /* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002
5 Free Software Foundation, Inc.
6 Written by James Clark (jjc@jclark.com)
8 This file is part of groff.
10 groff is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 2, or (at your option) any later
15 groff is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License along
21 with groff; see the file COPYING. If not, write to the Free Software
22 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
25 #include "stringclass.h"
27 #include "searchpath.h"
28 #include "macropath.h"
33 #define STARTUP_FILE "eqnrc"
36 extern "C" const char *Version_string
;
38 static char *delim_search (char *, int);
39 static int inline_equation (FILE *, string
&, string
&);
41 char start_delim
= '\0';
42 char end_delim
= '\0';
46 int one_size_reduction_flag
= 0;
47 int compatible_flag
= 0;
48 int no_newline_in_delim_flag
= 0;
52 int read_line(FILE *fp
, string
*p
)
56 while ((c
= getc(fp
)) != EOF
) {
57 if (!invalid_input_char(c
))
60 error("invalid input character code `%1'", c
);
65 return p
->length() > 0;
68 void do_file(FILE *fp
, const char *filename
)
72 printf(".lf 1 %s\n", filename
);
73 current_filename
= filename
;
75 while (read_line(fp
, &linebuf
)) {
76 if (linebuf
.length() >= 4
77 && linebuf
[0] == '.' && linebuf
[1] == 'l' && linebuf
[2] == 'f'
78 && (linebuf
[3] == ' ' || linebuf
[3] == '\n' || compatible_flag
)) {
79 put_string(linebuf
, stdout
);
81 if (interpret_lf_args(linebuf
.contents() + 3))
84 else if (linebuf
.length() >= 4
88 && (linebuf
[3] == ' ' || linebuf
[3] == '\n'
89 || compatible_flag
)) {
90 put_string(linebuf
, stdout
);
91 int start_lineno
= current_lineno
+ 1;
94 if (!read_line(fp
, &linebuf
))
95 fatal("end of file before .EN");
96 if (linebuf
.length() >= 3 && linebuf
[0] == '.' && linebuf
[1] == 'E') {
98 && (linebuf
.length() == 3 || linebuf
[3] == ' '
99 || linebuf
[3] == '\n' || compatible_flag
))
101 else if (linebuf
[2] == 'Q' && linebuf
.length() > 3
102 && (linebuf
[3] == ' ' || linebuf
[3] == '\n'
110 init_lex(str
.contents(), current_filename
, start_lineno
);
114 restore_compatibility();
115 if (non_empty_flag
) {
116 printf(".lf %d\n", current_lineno
- 1);
119 printf(".lf %d\n", current_lineno
);
120 put_string(linebuf
, stdout
);
122 else if (start_delim
!= '\0' && linebuf
.search(start_delim
) >= 0
123 && inline_equation(fp
, linebuf
, str
))
126 put_string(linebuf
, stdout
);
128 current_filename
= 0;
132 // Handle an inline equation. Return 1 if it was an inline equation,
134 static int inline_equation(FILE *fp
, string
&linebuf
, string
&str
)
137 char *ptr
= &linebuf
[0];
138 char *start
= delim_search(ptr
, start_delim
);
140 // It wasn't a delimiter after all.
141 linebuf
.set_length(linebuf
.length() - 1); // strip the '\0'
147 if (no_newline_in_delim_flag
&& strchr(start
+ 1, end_delim
) == 0) {
148 error("missing `%1'", end_delim
);
149 char *nl
= strchr(start
+ 1, '\n');
155 int start_lineno
= current_lineno
;
161 char *end
= strchr(ptr
, end_delim
);
169 if (!read_line(fp
, &linebuf
))
170 fatal("unterminated `%1' at line %2, looking for `%3'",
171 start_delim
, start_lineno
, end_delim
);
177 printf(".as1 %s ", LINE_STRING
);
178 html_begin_suppress();
181 init_lex(str
.contents(), current_filename
, start_lineno
);
184 printf(".as1 %s ", LINE_STRING
);
188 start
= delim_search(ptr
, start_delim
);
190 char *nl
= strchr(ptr
, '\n');
197 restore_compatibility();
198 printf(".lf %d\n", current_lineno
);
200 printf(".lf %d\n", current_lineno
+ 1);
204 /* Search for delim. Skip over number register and string names etc. */
206 static char *delim_search(char *ptr
, int delim
)
211 if (*ptr
++ == '\\') {
223 if (*++ptr
!= '\\' && *ptr
!= '\0'
224 && *++ptr
!= '\\' && *ptr
!= '\0')
228 while (*++ptr
!= '\0')
251 void usage(FILE *stream
)
254 "usage: %s [ -rvDCNR ] -dxx -fn -sn -pn -mn -Mdir -Ts [ files ... ]\n",
258 int main(int argc
, char **argv
)
260 program_name
= argv
[0];
261 static char stderr_buf
[BUFSIZ
];
262 setbuf(stderr
, stderr_buf
);
264 int load_startup_file
= 1;
265 static const struct option long_options
[] = {
266 { "help", no_argument
, 0, CHAR_MAX
+ 1 },
267 { "version", no_argument
, 0, 'v' },
270 while ((opt
= getopt_long(argc
, argv
, "DCRvd:f:p:s:m:T:M:rN", long_options
,
277 case 'R': // don't load eqnrc
278 load_startup_file
= 0;
281 config_macro_path
.command_line_dir(optarg
);
285 printf("GNU eqn (groff) version %s\n", Version_string
);
290 if (optarg
[0] == '\0' || optarg
[1] == '\0')
291 error("-d requires two character argument");
292 else if (invalid_input_char(optarg
[0]))
293 error("bad delimiter `%1'", optarg
[0]);
294 else if (invalid_input_char(optarg
[1]))
295 error("bad delimiter `%1'", optarg
[1]);
297 start_delim
= optarg
[0];
298 end_delim
= optarg
[1];
306 if (strcmp(device
, "ps:html") == 0) {
312 if (!set_gsize(optarg
))
313 error("invalid size `%1'", optarg
);
318 if (sscanf(optarg
, "%d", &n
) == 1)
319 set_script_reduction(n
);
321 error("bad size `%1'", optarg
);
327 if (sscanf(optarg
, "%d", &n
) == 1)
330 error("bad size `%1'", optarg
);
334 one_size_reduction_flag
= 1;
337 warning("-D option is obsolete: use `set draw_lines 1' instead");
341 no_newline_in_delim_flag
= 1;
343 case CHAR_MAX
+ 1: // --help
356 printf(".if !'\\*(.T'%s' "
357 ".if !'\\*(.T'html' " // the html device uses `-Tps' to render
358 // equations as images
359 ".tm warning: %s should have been given a `-T\\*(.T' option\n",
360 device
, program_name
);
361 printf(".if '\\*(.T'html' "
363 ".tm warning: %s should have been given a `-Tps' option\n",
364 device
, program_name
);
365 printf(".if '\\*(.T'html' "
367 ".tm warning: (it is advisable to invoke groff via: groff -Thtml -e)\n",
369 if (load_startup_file
) {
371 FILE *fp
= config_macro_path
.open_file(STARTUP_FILE
, &path
);
381 for (int i
= optind
; i
< argc
; i
++)
382 if (strcmp(argv
[i
], "-") == 0)
386 FILE *fp
= fopen(argv
[i
], "r");
388 fatal("can't open `%1': %2", argv
[i
], strerror(errno
));
390 do_file(fp
, argv
[i
]);
394 if (ferror(stdout
) || fflush(stdout
) < 0)
395 fatal("output error");