No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / groff / src / devices / grohtml / output.cpp
blobaec497ee9f3e7362e44676bf9aa3728aa41f6575
1 /* $NetBSD$ */
3 // -*- C++ -*-
4 /* Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
6 * Gaius Mulley (gaius@glam.ac.uk) wrote output.cpp
7 * but it owes a huge amount of ideas and raw code from
8 * James Clark (jjc@jclark.com) grops/ps.cpp.
10 * output.cpp
12 * provide the simple low level output routines needed by html.cpp
16 This file is part of groff.
18 groff is free software; you can redistribute it and/or modify it under
19 the terms of the GNU General Public License as published by the Free
20 Software Foundation; either version 2, or (at your option) any later
21 version.
23 groff is distributed in the hope that it will be useful, but WITHOUT ANY
24 WARRANTY; without even the implied warranty of MERCHANTABILITY or
25 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 for more details.
28 You should have received a copy of the GNU General Public License along
29 with groff; see the file COPYING. If not, write to the Free Software
30 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
32 #include "driver.h"
33 #include "stringclass.h"
34 #include "cset.h"
36 #include <time.h>
37 #include "html.h"
39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
43 #undef DEBUGGING
44 // #define DEBUGGING
46 #if !defined(TRUE)
47 # define TRUE (1==1)
48 #endif
49 #if !defined(FALSE)
50 # define FALSE (1==0)
51 #endif
54 #if defined(DEBUGGING)
55 # define FPUTC(X,Y) do { fputc((X),(Y)); fputc((X), stderr); fflush(stderr); } while (0)
56 # define FPUTS(X,Y) do { fputs((X),(Y)); fputs((X), stderr); fflush(stderr); } while (0)
57 # define PUTC(X,Y) do { putc((X),(Y)); putc((X), stderr); fflush(stderr); } while (0)
58 #else
59 # define FPUTC(X,Y) do { fputc((X),(Y)); } while (0)
60 # define FPUTS(X,Y) do { fputs((X),(Y)); } while (0)
61 # define PUTC(X,Y) do { putc((X),(Y)); } while (0)
62 #endif
66 * word - initialise a word and set next to NULL
69 word::word (const char *w, int n)
70 : next(0)
72 s = new char[n+1];
73 strncpy(s, w, n);
74 s[n] = (char)0;
78 * destroy word and the string copy.
81 word::~word ()
83 a_delete s;
87 * word_list - create an empty word list.
90 word_list::word_list ()
91 : length(0), head(0), tail(0)
96 * flush - flush a word list to a FILE, f, and return the
97 * length of the buffered string.
100 int word_list::flush (FILE *f)
102 word *t;
103 int len=length;
105 while (head != 0) {
106 t = head;
107 head = head->next;
108 FPUTS(t->s, f);
109 delete t;
111 head = 0;
112 tail = 0;
113 length = 0;
114 #if defined(DEBUGGING)
115 fflush(f); // just for testing
116 #endif
117 return( len );
121 * add_word - adds a word to the outstanding word list.
124 void word_list::add_word (const char *s, int n)
126 if (head == 0) {
127 head = new word(s, n);
128 tail = head;
129 } else {
130 tail->next = new word(s, n);
131 tail = tail->next;
133 length += n;
137 * get_length - returns the number of characters buffered
140 int word_list::get_length (void)
142 return( length );
146 * the classes and methods for simple_output manipulation
149 simple_output::simple_output(FILE *f, int n)
150 : fp(f), max_line_length(n), col(0), fixed_point(0), newlines(0)
154 simple_output &simple_output::set_file(FILE *f)
156 if (fp)
157 fflush(fp);
158 fp = f;
159 return *this;
162 simple_output &simple_output::copy_file(FILE *infp)
164 int c;
165 while ((c = getc(infp)) != EOF)
166 PUTC(c, fp);
167 return *this;
170 simple_output &simple_output::end_line()
172 flush_last_word();
173 if (col != 0) {
174 PUTC('\n', fp);
175 col = 0;
177 return *this;
180 simple_output &simple_output::special(const char *)
182 return *this;
185 simple_output &simple_output::simple_comment(const char *s)
187 flush_last_word();
188 if (col != 0)
189 PUTC('\n', fp);
190 FPUTS("<!-- ", fp);
191 FPUTS(s, fp);
192 FPUTS(" -->\n", fp);
193 col = 0;
194 return *this;
197 simple_output &simple_output::begin_comment(const char *s)
199 flush_last_word();
200 if (col != 0)
201 PUTC('\n', fp);
202 col = 0;
203 put_string("<!--");
204 space_or_newline();
205 last_word.add_word(s, strlen(s));
206 return *this;
209 simple_output &simple_output::end_comment()
211 flush_last_word();
212 space_or_newline();
213 put_string("-->").nl();
214 return *this;
218 * check_newline - checks to see whether we are able to issue
219 * a newline and that one is needed.
222 simple_output &simple_output::check_newline(int n)
224 if ((col + n + last_word.get_length() + 1 > max_line_length) && (newlines)) {
225 FPUTC('\n', fp);
226 col = last_word.flush(fp);
228 return *this;
232 * space_or_newline - will emit a newline or a space later on
233 * depending upon the current column.
236 simple_output &simple_output::space_or_newline (void)
238 if ((col + last_word.get_length() + 1 > max_line_length) && (newlines)) {
239 FPUTC('\n', fp);
240 if (last_word.get_length() > 0) {
241 col = last_word.flush(fp);
242 } else {
243 col = 0;
245 } else {
246 if (last_word.get_length() != 0) {
247 if (col > 0) {
248 FPUTC(' ', fp);
249 col++;
251 col += last_word.flush(fp);
254 return *this;
258 * force_nl - forces a newline.
261 simple_output &simple_output::force_nl (void)
263 space_or_newline();
264 col += last_word.flush(fp);
265 FPUTC('\n', fp);
266 col = 0;
267 return *this ;
271 * nl - writes a newline providing that we
272 * are not in the first column.
275 simple_output &simple_output::nl (void)
277 space_or_newline();
278 col += last_word.flush(fp);
279 FPUTC('\n', fp);
280 col = 0;
281 return *this ;
284 simple_output &simple_output::set_fixed_point(int n)
286 assert(n >= 0 && n <= 10);
287 fixed_point = n;
288 return *this;
291 simple_output &simple_output::put_raw_char(char c)
293 col += last_word.flush(fp);
294 PUTC(c, fp);
295 col++;
296 return *this;
299 simple_output &simple_output::put_string(const char *s, int n)
301 last_word.add_word(s, n);
302 return *this;
305 simple_output &simple_output::put_string(const char *s)
307 last_word.add_word(s, strlen(s));
308 return *this;
311 simple_output &simple_output::put_string(const string &s)
313 last_word.add_word(s.contents(), s.length());
314 return *this;
317 simple_output &simple_output::put_number(int n)
319 char buf[1 + INT_DIGITS + 1];
320 sprintf(buf, "%d", n);
321 put_string(buf);
322 return *this;
325 simple_output &simple_output::put_float(double d)
327 char buf[128];
329 sprintf(buf, "%.4f", d);
330 put_string(buf);
331 return *this;
334 simple_output &simple_output::enable_newlines (int auto_newlines)
336 check_newline(0);
337 newlines = auto_newlines;
338 check_newline(0);
339 return *this;
343 * flush_last_word - flushes the last word and adjusts the
344 * col position. It will insert a newline
345 * before the last word if allowed and if
346 * necessary.
349 void simple_output::flush_last_word (void)
351 int len=last_word.get_length();
353 if (len > 0) {
354 if (newlines) {
355 if (col + len + 1 > max_line_length) {
356 FPUTS("\n", fp);
357 col = 0;
358 } else {
359 FPUTS(" ", fp);
360 col++;
362 len += last_word.flush(fp);
363 } else {
364 FPUTS(" ", fp);
365 col++;
366 col += last_word.flush(fp);