1 /*@ Provide the simple low level output routines needed by html.cpp.
3 * Copyright (c) 2014 - 2017 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
5 * Copyright (C) 2000 - 2001, 2003 - 2005 Free Software Foundation, Inc.
7 * Gaius Mulley (gaius@glam.ac.uk) wrote output.cpp
8 * but it owes a huge amount of ideas and raw code from
9 * James Clark (jjc@jclark.com) grops/ps.cpp.
12 * This is free software; you can redistribute it and/or modify it under
13 * the terms of the GNU General Public License as published by the Free
14 * Software Foundation; either version 2, or (at your option) any later
17 * This is distributed in the hope that it will be useful, but WITHOUT ANY
18 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * You should have received a copy of the GNU General Public License along
23 * with groff; see the file COPYING. If not, write to the Free Software
24 * Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
28 #include "html-config.h"
38 #include "stringclass.h"
43 # define FPUTC(X,Y) do { fputc((X),(Y)); fputc((X), stderr); fflush(stderr); } while (0)
44 # define FPUTS(X,Y) do { fputs((X),(Y)); fputs((X), stderr); fflush(stderr); } while (0)
45 # define PUTC(X,Y) do { putc((X),(Y)); putc((X), stderr); fflush(stderr); } while (0)
47 # define FPUTC(X,Y) do { fputc((X),(Y)); } while (0)
48 # define FPUTS(X,Y) do { fputs((X),(Y)); } while (0)
49 # define PUTC(X,Y) do { putc((X),(Y)); } while (0)
53 * word - initialise a word and set next to NULL
56 word::word (const char *w
, int n
)
65 * destroy word and the string copy.
74 * word_list - create an empty word list.
77 word_list::word_list ()
78 : length(0), head(0), tail(0)
83 * flush - flush a word list to a FILE, f, and return the
84 * length of the buffered string.
87 int word_list::flush (FILE *f
)
101 #if defined(DEBUGGING)
102 fflush(f
); // just for testing
108 * add_word - adds a word to the outstanding word list.
111 void word_list::add_word (const char *s
, int n
)
114 head
= new word(s
, n
);
117 tail
->next
= new word(s
, n
);
124 * get_length - returns the number of characters buffered
127 int word_list::get_length (void)
133 * the classes and methods for simple_output manipulation
136 simple_output::simple_output(FILE *f
, int n
)
137 : fp(f
), max_line_length(n
), col(0), fixed_point(0), newlines(0)
141 simple_output
&simple_output::set_file(FILE *f
)
149 simple_output
&simple_output::copy_file(FILE *infp
)
152 while ((c
= getc(infp
)) != EOF
)
157 simple_output
&simple_output::end_line()
167 simple_output
&simple_output::special(const char *)
172 simple_output
&simple_output::simple_comment(const char *s
)
184 simple_output
&simple_output::begin_comment(const char *s
)
192 last_word
.add_word(s
, strlen(s
));
196 simple_output
&simple_output::end_comment()
200 put_string("-->").nl();
205 * check_newline - checks to see whether we are able to issue
206 * a newline and that one is needed.
209 simple_output
&simple_output::check_newline(int n
)
211 if ((col
+ n
+ last_word
.get_length() + 1 > max_line_length
) && (newlines
)) {
213 col
= last_word
.flush(fp
);
219 * space_or_newline - will emit a newline or a space later on
220 * depending upon the current column.
223 simple_output
&simple_output::space_or_newline (void)
225 if ((col
+ last_word
.get_length() + 1 > max_line_length
) && (newlines
)) {
227 if (last_word
.get_length() > 0) {
228 col
= last_word
.flush(fp
);
233 if (last_word
.get_length() != 0) {
238 col
+= last_word
.flush(fp
);
245 * force_nl - forces a newline.
248 simple_output
&simple_output::force_nl (void)
251 col
+= last_word
.flush(fp
);
258 * nl - writes a newline providing that we
259 * are not in the first column.
262 simple_output
&simple_output::nl (void)
265 col
+= last_word
.flush(fp
);
271 simple_output
&simple_output::set_fixed_point(int n
)
273 assert(n
>= 0 && n
<= 10);
278 simple_output
&simple_output::put_raw_char(char c
)
280 col
+= last_word
.flush(fp
);
286 simple_output
&simple_output::put_string(const char *s
, int n
)
288 last_word
.add_word(s
, n
);
292 simple_output
&simple_output::put_string(const char *s
)
294 last_word
.add_word(s
, strlen(s
));
298 simple_output
&simple_output::put_string(const string
&s
)
300 last_word
.add_word(s
.contents(), s
.length());
304 simple_output
&simple_output::put_number(int n
)
306 char buf
[1 + INT_DIGITS
+ 1];
307 sprintf(buf
, "%d", n
);
312 simple_output
&simple_output::put_float(double d
)
316 sprintf(buf
, "%.4f", d
);
321 simple_output
&simple_output::enable_newlines (int auto_newlines
)
324 newlines
= auto_newlines
;
330 * flush_last_word - flushes the last word and adjusts the
331 * col position. It will insert a newline
332 * before the last word if allowed and if
336 void simple_output::flush_last_word (void)
338 int len
=last_word
.get_length();
342 if (col
+ len
+ 1 > max_line_length
) {
349 len
+= last_word
.flush(fp
);
353 col
+= last_word
.flush(fp
);