~ubuntu-branches/ubuntu/dapper/groff/dapper

« back to all changes in this revision

Viewing changes to src/devices/grohtml/output.cc

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2002-03-17 04:11:50 UTC
  • Revision ID: james.westby@ubuntu.com-20020317041150-wkgfawjc3gxlk0o5
Tags: upstream-1.17.2
ImportĀ upstreamĀ versionĀ 1.17.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- C++ -*-
 
2
/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
 
3
 *
 
4
 *  Gaius Mulley (gaius@glam.ac.uk) wrote output.cc
 
5
 *  but it owes a huge amount of ideas and raw code from
 
6
 *  James Clark (jjc@jclark.com) grops/ps.cc.
 
7
 *
 
8
 *  output.cc
 
9
 *
 
10
 *  provide the simple low level output routines needed by html.cc
 
11
 */
 
12
 
 
13
/*
 
14
This file is part of groff.
 
15
 
 
16
groff is free software; you can redistribute it and/or modify it under
 
17
the terms of the GNU General Public License as published by the Free
 
18
Software Foundation; either version 2, or (at your option) any later
 
19
version.
 
20
 
 
21
groff is distributed in the hope that it will be useful, but WITHOUT ANY
 
22
WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
23
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
24
for more details.
 
25
 
 
26
You should have received a copy of the GNU General Public License along
 
27
with groff; see the file COPYING.  If not, write to the Free Software
 
28
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 
29
 
 
30
#include "driver.h"
 
31
#include "stringclass.h"
 
32
#include "cset.h"
 
33
 
 
34
#include <time.h>
 
35
#include "html.h"
 
36
 
 
37
#ifdef HAVE_UNISTD_H
 
38
#include <unistd.h>
 
39
#endif
 
40
 
 
41
#if !defined(TRUE)
 
42
#   define TRUE  (1==1)
 
43
#endif
 
44
#if !defined(FALSE)
 
45
#   define FALSE (1==0)
 
46
#endif
 
47
 
 
48
/*
 
49
 *  word - initialise a word and set next to NULL
 
50
 */
 
51
 
 
52
word::word (const char *w, int n)
 
53
  : next(0)
 
54
{
 
55
  s = (char *)malloc(n+1);
 
56
  strncpy(s, w, n);
 
57
  s[n] = (char)0;
 
58
}
 
59
 
 
60
/*
 
61
 *  destroy word and the string copy.
 
62
 */
 
63
 
 
64
word::~word ()
 
65
{
 
66
  free(s);
 
67
}
 
68
 
 
69
/*
 
70
 *  word_list - create an empty word list.
 
71
 */
 
72
 
 
73
word_list::word_list ()
 
74
  : length(0), head(0), tail(0)
 
75
{
 
76
}
 
77
 
 
78
/*
 
79
 *  flush - flush a word list to a FILE, f, and return the
 
80
 *          length of the buffered string.
 
81
 */
 
82
 
 
83
int word_list::flush (FILE *f)
 
84
{
 
85
  word *t;
 
86
  int   len=length;
 
87
 
 
88
  while (head != 0) {
 
89
    t = head;
 
90
    head = head->next;
 
91
    fputs(t->s, f);
 
92
    delete t;
 
93
  }
 
94
  head   = 0;
 
95
  tail   = 0;
 
96
  length = 0;
 
97
#if defined(DEBUGGING)
 
98
  fflush(f);   // just for testing
 
99
#endif
 
100
  return( len );
 
101
}
 
102
 
 
103
/*
 
104
 *  add_word - adds a word to the outstanding word list.
 
105
 */
 
106
 
 
107
void word_list::add_word (const char *s, int n)
 
108
{
 
109
  if (head == 0) {
 
110
    head = new word(s, n);
 
111
    tail = head;
 
112
  } else {
 
113
    tail->next = new word(s, n);
 
114
    tail       = tail->next;
 
115
  }
 
116
  length += n;
 
117
}
 
118
 
 
119
/*
 
120
 *  get_length - returns the number of characters buffered
 
121
 */
 
122
 
 
123
int word_list::get_length (void)
 
124
{
 
125
  return( length );
 
126
}
 
127
 
 
128
/*
 
129
 *  the classes and methods for simple_output manipulation
 
130
 */
 
131
 
 
132
simple_output::simple_output(FILE *f, int n)
 
133
: fp(f), max_line_length(n), col(0), fixed_point(0), newlines(0)
 
134
{
 
135
}
 
136
 
 
137
simple_output &simple_output::set_file(FILE *f)
 
138
{
 
139
  if (fp)
 
140
    fflush(fp);
 
141
  fp = f;
 
142
  return *this;
 
143
}
 
144
 
 
145
simple_output &simple_output::copy_file(FILE *infp)
 
146
{
 
147
  int c;
 
148
  while ((c = getc(infp)) != EOF)
 
149
    putc(c, fp);
 
150
  return *this;
 
151
}
 
152
 
 
153
simple_output &simple_output::end_line()
 
154
{
 
155
  flush_last_word();
 
156
  if (col != 0) {
 
157
    putc('\n', fp);
 
158
    col = 0;
 
159
  }
 
160
  return *this;
 
161
}
 
162
 
 
163
simple_output &simple_output::special(const char *s)
 
164
{
 
165
  return *this;
 
166
}
 
167
 
 
168
simple_output &simple_output::simple_comment(const char *s)
 
169
{
 
170
  flush_last_word();
 
171
  if (col != 0)
 
172
    putc('\n', fp);
 
173
  fputs("<!-- ", fp);
 
174
  fputs(s, fp);
 
175
  fputs(" -->\n", fp);
 
176
  col = 0;
 
177
  return *this;
 
178
}
 
179
 
 
180
simple_output &simple_output::begin_comment(const char *s)
 
181
{
 
182
  flush_last_word();
 
183
  if (col != 0)
 
184
    putc('\n', fp);
 
185
  col = 0;
 
186
  put_string("<!--");
 
187
  space_or_newline();
 
188
  last_word.add_word(s, strlen(s));
 
189
  return *this;
 
190
}
 
191
 
 
192
simple_output &simple_output::end_comment()
 
193
{
 
194
  flush_last_word();
 
195
  space_or_newline();
 
196
  put_string("-->").nl();
 
197
  return *this;
 
198
}
 
199
 
 
200
/*
 
201
 *  check_newline - checks to see whether we are able to issue
 
202
 *                  a newline and that one is needed.
 
203
 */
 
204
 
 
205
simple_output &simple_output::check_newline(int n)
 
206
{
 
207
  if ((col + n + last_word.get_length() + 1 > max_line_length) && (newlines)) {
 
208
    fputc('\n', fp);
 
209
    col = last_word.flush(fp);
 
210
  }
 
211
  return *this;
 
212
}
 
213
 
 
214
/*
 
215
 *  space_or_newline - will emit a newline or a space later on
 
216
 *                     depending upon the current column.
 
217
 */
 
218
 
 
219
simple_output &simple_output::space_or_newline (void)
 
220
{
 
221
#if defined(DEBUGGING)
 
222
  fflush(fp);   // just for testing
 
223
#endif
 
224
  if ((col + last_word.get_length() + 1 > max_line_length) && (newlines)) {
 
225
    fputc('\n', fp);
 
226
    if (last_word.get_length() > 0) {
 
227
      col = last_word.flush(fp);
 
228
    } else {
 
229
      col = 0;
 
230
    }
 
231
  } else {
 
232
    if (last_word.get_length() != 0) {
 
233
      if (col > 0) {
 
234
        fputc(' ', fp);
 
235
        col++;
 
236
      }
 
237
      col += last_word.flush(fp);
 
238
    }
 
239
  }
 
240
  return *this;
 
241
}
 
242
 
 
243
/*
 
244
 *  nl - writes a newline providing that we
 
245
 *       are not in the first column.
 
246
 */
 
247
 
 
248
simple_output &simple_output::nl (void)
 
249
{
 
250
  space_or_newline();
 
251
  col += last_word.flush(fp);
 
252
  if (col != 0) {
 
253
    fputc('\n', fp);
 
254
    col = 0;
 
255
  }
 
256
  return *this ;
 
257
}
 
258
 
 
259
simple_output &simple_output::set_fixed_point(int n)
 
260
{
 
261
  assert(n >= 0 && n <= 10);
 
262
  fixed_point = n;
 
263
  return *this;
 
264
}
 
265
 
 
266
simple_output &simple_output::put_raw_char(char c)
 
267
{
 
268
  col += last_word.flush(fp);
 
269
  putc(c, fp);
 
270
  col++;
 
271
  return *this;
 
272
}
 
273
 
 
274
simple_output &simple_output::put_string(const char *s, int n)
 
275
{
 
276
  last_word.add_word(s, n);
 
277
  return *this;
 
278
}
 
279
 
 
280
simple_output &simple_output::put_string(const char *s)
 
281
{
 
282
  last_word.add_word(s, strlen(s));
 
283
  return *this;
 
284
}
 
285
 
 
286
simple_output &simple_output::put_number(int n)
 
287
{
 
288
  char buf[1 + INT_DIGITS + 1];
 
289
  sprintf(buf, "%d", n);
 
290
  put_string(buf);
 
291
  return *this;
 
292
}
 
293
 
 
294
simple_output &simple_output::put_float(double d)
 
295
{
 
296
  char buf[128];
 
297
 
 
298
  sprintf(buf, "%.4f", d);
 
299
  put_string(buf);
 
300
  return *this;
 
301
}
 
302
 
 
303
simple_output &simple_output::enable_newlines (int auto_newlines)
 
304
{
 
305
  check_newline(0);
 
306
  newlines = auto_newlines;
 
307
  check_newline(0);
 
308
  return *this;
 
309
}
 
310
 
 
311
/*
 
312
 *  flush_last_word - flushes the last word and adjusts the
 
313
 *                    col position. It will insert a newline
 
314
 *                    before the last word if allowed and if
 
315
 *                    necessary.
 
316
 */
 
317
 
 
318
void simple_output::flush_last_word (void)
 
319
{
 
320
  int len=last_word.get_length();
 
321
 
 
322
  if (len > 0) {
 
323
    if (newlines) {
 
324
      if (col + len + 1 > max_line_length) {
 
325
        fputs("\n", fp);
 
326
        col = 0;
 
327
      } else {
 
328
        fputs(" ", fp);
 
329
        col++;
 
330
      }
 
331
      len += last_word.flush(fp);
 
332
    } else {
 
333
      fputs(" ", fp);
 
334
      col++;
 
335
      col += last_word.flush(fp);
 
336
    }
 
337
  }
 
338
}