diff options
Diffstat (limited to 'src/devices/grohtml/output.cpp')
-rw-r--r-- | src/devices/grohtml/output.cpp | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/src/devices/grohtml/output.cpp b/src/devices/grohtml/output.cpp new file mode 100644 index 0000000..0ffeb58 --- /dev/null +++ b/src/devices/grohtml/output.cpp @@ -0,0 +1,363 @@ +// -*- C++ -*- +/* Copyright (C) 2000-2020 Free Software Foundation, Inc. + * + * Gaius Mulley (gaius@glam.ac.uk) wrote output.cpp + * but it owes a huge amount of ideas and raw code from + * James Clark (jjc@jclark.com) grops/ps.cpp. + * + * output.cpp + * + * provide the simple low level output routines needed by html.cpp + */ + +/* +This file is part of groff. + +groff is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation, either version 3 of the License, or +(at your option) any later version. + +groff is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "driver.h" +#include "stringclass.h" +#include "cset.h" + +#include <time.h> +#include "html.h" + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#if !defined(TRUE) +# define TRUE (1==1) +#endif +#if !defined(FALSE) +# define FALSE (1==0) +#endif + + +#if defined(DEBUGGING) +# define FPUTC(X,Y) do { fputc((X),(Y)); fputc((X), stderr); fflush(stderr); } while (0) +# define FPUTS(X,Y) do { fputs((X),(Y)); fputs((X), stderr); fflush(stderr); } while (0) +# define PUTC(X,Y) do { putc((X),(Y)); putc((X), stderr); fflush(stderr); } while (0) +#else +# define FPUTC(X,Y) do { fputc((X),(Y)); } while (0) +# define FPUTS(X,Y) do { fputs((X),(Y)); } while (0) +# define PUTC(X,Y) do { putc((X),(Y)); } while (0) +#endif + + +/* + * word - initialise a word and set next to NULL + */ + +word::word (const char *w, int n) + : next(0) +{ + s = new char[n+1]; + strncpy(s, w, n); + s[n] = (char)0; +} + +/* + * destroy word and the string copy. + */ + +word::~word () +{ + delete[] s; +} + +/* + * word_list - create an empty word list. + */ + +word_list::word_list () + : length(0), head(0), tail(0) +{ +} + +/* + * flush - flush a word list to a FILE, f, and return the + * length of the buffered string. + */ + +int word_list::flush (FILE *f) +{ + word *t; + int len=length; + + while (head != 0) { + t = head; + head = head->next; + FPUTS(t->s, f); + delete t; + } + head = 0; + tail = 0; + length = 0; +#if defined(DEBUGGING) + fflush(f); // just for testing +#endif + return( len ); +} + +/* + * add_word - adds a word to the outstanding word list. + */ + +void word_list::add_word (const char *s, int n) +{ + if (head == 0) { + head = new word(s, n); + tail = head; + } else { + tail->next = new word(s, n); + tail = tail->next; + } + length += n; +} + +/* + * get_length - returns the number of characters buffered + */ + +int word_list::get_length (void) +{ + return( length ); +} + +/* + * the classes and methods for simple_output manipulation + */ + +simple_output::simple_output(FILE *f, int n) +: fp(f), max_line_length(n), col(0), fixed_point(0), newlines(0) +{ +} + +simple_output &simple_output::set_file(FILE *f) +{ + if (fp) + fflush(fp); + fp = f; + return *this; +} + +simple_output &simple_output::copy_file(FILE *infp) +{ + int c; + while ((c = getc(infp)) != EOF) + PUTC(c, fp); + return *this; +} + +simple_output &simple_output::end_line() +{ + flush_last_word(); + if (col != 0) { + PUTC('\n', fp); + col = 0; + } + return *this; +} + +simple_output &simple_output::special(const char *) +{ + return *this; +} + +simple_output &simple_output::simple_comment(const char *s) +{ + flush_last_word(); + if (col != 0) + PUTC('\n', fp); + FPUTS("<!-- ", fp); + FPUTS(s, fp); + FPUTS(" -->\n", fp); + col = 0; + return *this; +} + +simple_output &simple_output::begin_comment(const char *s) +{ + flush_last_word(); + if (col != 0) + PUTC('\n', fp); + col = 0; + put_string("<!--"); + space_or_newline(); + last_word.add_word(s, strlen(s)); + return *this; +} + +simple_output &simple_output::end_comment() +{ + flush_last_word(); + space_or_newline(); + put_string("-->").nl(); + return *this; +} + +/* + * check_newline - checks to see whether we are able to issue + * a newline and that one is needed. + */ + +simple_output &simple_output::check_newline(int n) +{ + if ((col + n + last_word.get_length() + 1 > max_line_length) && (newlines)) { + FPUTC('\n', fp); + col = last_word.flush(fp); + } + return *this; +} + +/* + * space_or_newline - will emit a newline or a space later on + * depending upon the current column. + */ + +simple_output &simple_output::space_or_newline (void) +{ + if ((col + last_word.get_length() + 1 > max_line_length) && (newlines)) { + FPUTC('\n', fp); + if (last_word.get_length() > 0) { + col = last_word.flush(fp); + } else { + col = 0; + } + } else { + if (last_word.get_length() != 0) { + if (col > 0) { + FPUTC(' ', fp); + col++; + } + col += last_word.flush(fp); + } + } + return *this; +} + +/* + * force_nl - forces a newline. + */ + +simple_output &simple_output::force_nl (void) +{ + space_or_newline(); + col += last_word.flush(fp); + FPUTC('\n', fp); + col = 0; + return *this ; +} + +/* + * nl - writes a newline providing that we + * are not in the first column. + */ + +simple_output &simple_output::nl (void) +{ + space_or_newline(); + col += last_word.flush(fp); + FPUTC('\n', fp); + col = 0; + return *this ; +} + +simple_output &simple_output::set_fixed_point(int n) +{ + assert(n >= 0 && n <= 10); + fixed_point = n; + return *this; +} + +simple_output &simple_output::put_raw_char(char c) +{ + col += last_word.flush(fp); + PUTC(c, fp); + col++; + return *this; +} + +simple_output &simple_output::put_string(const char *s, int n) +{ + last_word.add_word(s, n); + return *this; +} + +simple_output &simple_output::put_string(const char *s) +{ + last_word.add_word(s, strlen(s)); + return *this; +} + +simple_output &simple_output::put_string(const string &s) +{ + last_word.add_word(s.contents(), s.length()); + return *this; +} + +simple_output &simple_output::put_number(int n) +{ + char buf[1 + INT_DIGITS + 1]; + sprintf(buf, "%d", n); + put_string(buf); + return *this; +} + +simple_output &simple_output::put_float(double d) +{ + char buf[128]; + + sprintf(buf, "%.4f", d); + put_string(buf); + return *this; +} + +simple_output &simple_output::enable_newlines (int auto_newlines) +{ + check_newline(0); + newlines = auto_newlines; + check_newline(0); + return *this; +} + +/* + * flush_last_word - flushes the last word and adjusts the + * col position. It will insert a newline + * before the last word if allowed and if + * necessary. + */ + +void simple_output::flush_last_word (void) +{ + int len=last_word.get_length(); + + if (len > 0) { + if (newlines) { + if (col + len + 1 > max_line_length) { + FPUTS("\n", fp); + col = 0; + } else { + FPUTS(" ", fp); + col++; + } + len += last_word.flush(fp); + } else { + FPUTS(" ", fp); + col++; + col += last_word.flush(fp); + } + } +} |