From 7fdf49473c970aa96ee1bae16928d1db23643228 Mon Sep 17 00:00:00 2001 From: pst Date: Sat, 7 Sep 1996 16:18:32 +0000 Subject: Virgin import of FSF groff v1.10 --- contrib/groff/grotty/Makefile.dep | 3 + contrib/groff/grotty/Makefile.sub | 6 + contrib/groff/grotty/TODO | 3 + contrib/groff/grotty/grotty.man | 221 +++++++++++++++++++ contrib/groff/grotty/tty.cc | 443 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 676 insertions(+) create mode 100644 contrib/groff/grotty/Makefile.dep create mode 100644 contrib/groff/grotty/Makefile.sub create mode 100644 contrib/groff/grotty/TODO create mode 100644 contrib/groff/grotty/grotty.man create mode 100644 contrib/groff/grotty/tty.cc (limited to 'contrib/groff/grotty') diff --git a/contrib/groff/grotty/Makefile.dep b/contrib/groff/grotty/Makefile.dep new file mode 100644 index 0000000..5939058 --- /dev/null +++ b/contrib/groff/grotty/Makefile.dep @@ -0,0 +1,3 @@ +tty.o: tty.cc ../include/driver.h ../include/errarg.h \ + ../include/error.h ../include/font.h ../include/printer.h \ + ../include/lib.h diff --git a/contrib/groff/grotty/Makefile.sub b/contrib/groff/grotty/Makefile.sub new file mode 100644 index 0000000..b0002cb --- /dev/null +++ b/contrib/groff/grotty/Makefile.sub @@ -0,0 +1,6 @@ +PROG=grotty +MAN1=grotty.n +XLIBS=$(LIBDRIVER) $(LIBGROFF) +MLIB=$(LIBM) +OBJS=tty.o +CCSRCS=tty.cc diff --git a/contrib/groff/grotty/TODO b/contrib/groff/grotty/TODO new file mode 100644 index 0000000..3f23dc3 --- /dev/null +++ b/contrib/groff/grotty/TODO @@ -0,0 +1,3 @@ +Document font and device description file usage of grotty. + +With -h avoid using a tab when a single space will do. diff --git a/contrib/groff/grotty/grotty.man b/contrib/groff/grotty/grotty.man new file mode 100644 index 0000000..d8d6ebd --- /dev/null +++ b/contrib/groff/grotty/grotty.man @@ -0,0 +1,221 @@ +.ig \"-*- nroff -*- +Copyright (C) 1989-1995 Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the Free Software Foundation instead of in +the original English. +.. +.TH GROTTY @MAN1EXT@ "@MDATE@" "Groff Version @VERSION@" +.SH NAME +grotty \- groff driver for typewriter-like devices +.SH SYNOPSIS +.B grotty +[ +.B \-hfbuodBUv +] [ +.BI \-F dir +] [ +.IR files \|.\|.\|. +] +.SH DESCRIPTION +.B grotty +translates the output of GNU +.B troff +into a form suitable for typewriter-like devices. +Normally +.B grotty +should invoked by using the +.B groff +command +with a +.B \-Tascii +or +.B \-Tlatin1 +option. +If no files are given, +.B grotty +will read the standard input. +A filename of +.B \- +will also cause +.B grotty +to read the standard input. +Output is written to the standard output. +.LP +Normally +.B grotty +prints a bold character +.I c +using the sequence +.RI ` c +.SM BACKSPACE +.IR c ' +and a italic character +.I c +by the sequence +.RB ` _ +.SM BACKSPACE +.IR c '. +These sequences can be displayed on a terminal +by piping through +.BR ul (1). +Pagers such as +.BR more (1) +or +.BR less (1) +are also able to display these sequences. +Use either +.B \-B +or +.B \-U +when piping into +.BR less (1); +use +.B \-b +when piping into +.BR more (1). +There is no need to filter the output through +.BR col (1) +since +.B grotty +never outputs reverse line feeds. +.LP +The font description file may contain a command +.IP +.BI internalname\ n +.LP +where +.I n +is a decimal integer. +If the 01 bit in +.I n +is set, +then the font will be treated as an italic font; +if the 02 bit is set, +then it will be treated as a bold font. +The code field in the font description field gives the +code which will be used to output the character. +This code can also be used in the +.B \eN +escape sequence in +.BR troff . +.SH OPTIONS +.TP +.BI \-F dir +Search the directory +.IB dir /dev name +for font and device description files; +.I name +is the name of the device, usually +.B ascii +or +.BR latin1 . +.TP +.B \-h +Use horizontal tabs in the output. +Tabs are assumed to be set every 8 columns. +.TP +.B \-f +Use form feeds in the output. +A form feed will be output at the end of each page that has no output +on its last line. +.TP +.B \-b +Suppress the use of overstriking for bold characters. +.TP +.B \-u +Suppress the use of underlining for italic characters. +.TP +.B \-B +Use only overstriking for bold-italic characters. +.TP +.B \-U +Use only underlining for bold-italic characters. +.TP +.B \-o +Suppress overstriking (other than for bold or underlined characters). +.TP +.B \-d +Ignore all +.B \eD +commands. +Without this +.B grotty +will render +.B \eD'l\|.\|.\|.' +commands that have at least at least one zero argument +(and so are either horizontal or vertical) +using +.BR \- , +.B | +and +.B + +characters. +.TP +.B \-v +Print the version number. +.SH FILES +.TP +.B @FONTDIR@/devascii/DESC +Device description file for +.B ascii +device. +.TP +.B @FONTDIR@/devascii/ F +Font description file for font +.I F +of +.B ascii device. +.TP +.B @FONTDIR@/devlatin1/DESC +Device description file for +.B latin1 +device. +.TP +.B @FONTDIR@/devlatin1/ F +Font description file for font +.I F +of +.B latin1 device. +.TP +.B @MACRODIR@/tmac.tty +Macros for use with +.BR grotty . +.TP +.B @MACRODIR@/tmac.tty-char +Additional klugey character definitions for use with +.BR grotty . +.SH BUGS +.LP +.B grotty +is intended only for simple documents. +.LP +There is no support for fractional horizontal or vertical motions. +.LP +There is no support for +.B \eD +commands +other than horizontal and vertical lines. +.LP +Characters above the first line (ie with a vertical position of 0) +cannot be printed. +.SH "SEE ALSO" +.BR groff (@MAN1EXT@), +.BR @g@troff (@MAN1EXT@), +.BR groff_out (@MAN5EXT@), +.BR groff_font (@MAN5EXT@), +.BR groff_char (@MAN7EXT@), +.BR ul (1), +.BR more (1), +.BR less (1) diff --git a/contrib/groff/grotty/tty.cc b/contrib/groff/grotty/tty.cc new file mode 100644 index 0000000..3ac46aa --- /dev/null +++ b/contrib/groff/grotty/tty.cc @@ -0,0 +1,443 @@ +// -*- C++ -*- +/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +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 2, 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 groff; see the file COPYING. If not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "driver.h" + +#ifndef SHRT_MIN +#define SHRT_MIN (-32768) +#endif + +#ifndef SHRT_MAX +#define SHRT_MAX 32767 +#endif + +#define TAB_WIDTH 8 + +static int horizontal_tab_flag = 0; +static int form_feed_flag = 0; +static int bold_flag = 1; +static int underline_flag = 1; +static int overstrike_flag = 1; +static int draw_flag = 1; + +enum { + UNDERLINE_MODE = 01, + BOLD_MODE = 02, + VDRAW_MODE = 04, + HDRAW_MODE = 010 +}; + +// Mode to use for bold-underlining. +static unsigned char bold_underline_mode = BOLD_MODE|UNDERLINE_MODE; + +class tty_font : public font { + tty_font(const char *); + unsigned char mode; +public: + ~tty_font(); + unsigned char get_mode() { return mode; } +#if 0 + void handle_x_command(int argc, const char **argv); +#endif + static tty_font *load_tty_font(const char *); +}; + +tty_font *tty_font::load_tty_font(const char *s) +{ + tty_font *f = new tty_font(s); + if (!f->load()) { + delete f; + return 0; + } + const char *num = f->get_internal_name(); + long n; + if (num != 0 && (n = strtol(num, 0, 0)) != 0) + f->mode = int(n & (BOLD_MODE|UNDERLINE_MODE)); + if (!underline_flag) + f->mode &= ~UNDERLINE_MODE; + if (!bold_flag) + f->mode &= ~BOLD_MODE; + if ((f->mode & (BOLD_MODE|UNDERLINE_MODE)) == (BOLD_MODE|UNDERLINE_MODE)) + f->mode = (f->mode & ~(BOLD_MODE|UNDERLINE_MODE)) | bold_underline_mode; + return f; +} + +tty_font::tty_font(const char *nm) +: font(nm), mode(0) +{ +} + +tty_font::~tty_font() +{ +} + +#if 0 +void tty_font::handle_x_command(int argc, const char **argv) +{ + if (argc >= 1 && strcmp(argv[0], "bold") == 0) + mode |= BOLD_MODE; + else if (argc >= 1 && strcmp(argv[0], "underline") == 0) + mode |= UNDERLINE_MODE; +} +#endif + +class glyph { + static glyph *free_list; +public: + glyph *next; + short hpos; + unsigned char code; + unsigned char mode; + void *operator new(size_t); + void operator delete(void *); + inline int draw_mode() { return mode & (VDRAW_MODE|HDRAW_MODE); } +}; + +glyph *glyph::free_list = 0; + +void *glyph::operator new(size_t) +{ + if (!free_list) { + const int BLOCK = 1024; + free_list = (glyph *)new char[sizeof(glyph)*BLOCK]; + for (int i = 0; i < BLOCK - 1; i++) + free_list[i].next = free_list + i + 1; + free_list[BLOCK - 1].next = 0; + } + glyph *p = free_list; + free_list = free_list->next; + p->next = 0; + return p; +} + +void glyph::operator delete(void *p) +{ + if (p) { + ((glyph *)p)->next = free_list; + free_list = (glyph *)p; + } +} + +class tty_printer : public printer { + glyph **lines; + int nlines; + int cached_v; + int cached_vpos; + void add_char(unsigned char, int, int, unsigned char); +public: + tty_printer(); + ~tty_printer(); + void set_char(int, font *, const environment *, int); + void draw(int code, int *p, int np, const environment *env); + void begin_page(int) { } + void end_page(int page_length); + font *make_font(const char *); +}; + +tty_printer::tty_printer() : cached_v(0) +{ + nlines = 66; + lines = new glyph *[nlines]; + for (int i = 0; i < nlines; i++) + lines[i] = 0; +} + +tty_printer::~tty_printer() +{ + a_delete lines; +} + +void tty_printer::set_char(int i, font *f, const environment *env, int w) +{ + if (w != font::hor) + fatal("width of character not equal to horizontal resolution"); + add_char(f->get_code(i), env->hpos, env->vpos, ((tty_font *)f)->get_mode()); +} + +void tty_printer::add_char(unsigned char c, int h, int v, unsigned char mode) +{ +#if 0 + // This is too expensive. + if (h % font::hor != 0) + fatal("horizontal position not a multiple of horizontal resolution"); +#endif + int hpos = h / font::hor; + if (hpos < SHRT_MIN || hpos > SHRT_MAX) { + error("character with ridiculous horizontal position discarded"); + return; + } + int vpos; + if (v == cached_v && cached_v != 0) + vpos = cached_vpos; + else { + if (v % font::vert != 0) + fatal("vertical position not a multiple of vertical resolution"); + vpos = v / font::vert; + if (vpos > nlines) { + glyph **old_lines = lines; + lines = new glyph *[vpos + 1]; + memcpy(lines, old_lines, nlines*sizeof(glyph *)); + for (int i = nlines; i <= vpos; i++) + lines[i] = 0; + a_delete old_lines; + nlines = vpos + 1; + } + // Note that the first output line corresponds to groff + // position font::vert. + if (vpos <= 0) { + error("character above first line discarded"); + return; + } + cached_v = v; + cached_vpos = vpos; + } + glyph *g = new glyph; + g->hpos = hpos; + g->code = c; + g->mode = mode; + + // The list will be reversed later. After reversal, it must be in + // increasing order of hpos, with HDRAW characters before VDRAW + // characters before normal characters at each hpos, and otherwise + // in order of occurrence. + + glyph **pp; + for (pp = lines + (vpos - 1); *pp; pp = &(*pp)->next) + if ((*pp)->hpos < hpos + || ((*pp)->hpos == hpos && (*pp)->draw_mode() >= g->draw_mode())) + break; + + g->next = *pp; + *pp = g; +} + +void tty_printer::draw(int code, int *p, int np, const environment *env) +{ + if (code != 'l' || !draw_flag) + return; + if (np != 2) { + error("2 arguments required for line"); + return; + } + if (p[0] == 0) { + // vertical line + int v = env->vpos; + int len = p[1]; + if (len < 0) { + v += len; + len = -len; + } + while (len >= 0) { + add_char('|', env->hpos, v, VDRAW_MODE); + len -= font::vert; + v += font::vert; + } + } + if (p[1] == 0) { + // horizontal line + int h = env->hpos; + int len = p[0]; + if (len < 0) { + h += len; + len = -len; + } + while (len >= 0) { + add_char('-', h, env->vpos, HDRAW_MODE); + len -= font::hor; + h += font::hor; + } + } +} + +void tty_printer::end_page(int page_length) +{ + if (page_length % font::vert != 0) + error("vertical position at end of page not multiple of vertical resolution"); + int lines_per_page = page_length / font::vert; + int last_line; + for (last_line = nlines; last_line > 0; last_line--) + if (lines[last_line - 1]) + break; +#if 0 + if (last_line > lines_per_page) { + error("characters past last line discarded"); + do { + --last_line; + while (lines[last_line]) { + glyph *tem = lines[last_line]; + lines[last_line] = tem->next; + delete tem; + } + } while (last_line > lines_per_page); + } +#endif + for (int i = 0; i < last_line; i++) { + glyph *p = lines[i]; + lines[i] = 0; + glyph *g = 0; + while (p) { + glyph *tem = p->next; + p->next = g; + g = p; + p = tem; + } + int hpos = 0; + + glyph *nextp; + for (p = g; p; delete p, p = nextp) { + nextp = p->next; + if (nextp && p->hpos == nextp->hpos) { + if (p->draw_mode() == HDRAW_MODE && nextp->draw_mode() == VDRAW_MODE) { + nextp->code = '+'; + continue; + } + if (p->draw_mode() != 0 && p->draw_mode() == nextp->draw_mode()) { + nextp->code = p->code; + continue; + } + if (!overstrike_flag) + continue; + } + if (hpos > p->hpos) { + do { + putchar('\b'); + hpos--; + } while (hpos > p->hpos); + } + else { + if (horizontal_tab_flag) { + for (;;) { + int next_tab_pos = ((hpos + TAB_WIDTH) / TAB_WIDTH) * TAB_WIDTH; + if (next_tab_pos > p->hpos) + break; + putchar('\t'); + hpos = next_tab_pos; + } + } + for (; hpos < p->hpos; hpos++) + putchar(' '); + } + assert(hpos == p->hpos); + if (p->mode & UNDERLINE_MODE) { + putchar('_'); + putchar('\b'); + } + if (p->mode & BOLD_MODE) { + putchar(p->code); + putchar('\b'); + } + putchar(p->code); + hpos++; + } + putchar('\n'); + } + if (form_feed_flag) { + if (last_line < lines_per_page) + putchar('\f'); + } + else { + for (; last_line < lines_per_page; last_line++) + putchar('\n'); + } +} + +font *tty_printer::make_font(const char *nm) +{ + return tty_font::load_tty_font(nm); +} + +printer *make_printer() +{ + return new tty_printer; +} + +static void usage(); + +int main(int argc, char **argv) +{ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); + int c; + while ((c = getopt(argc, argv, "F:vhfbuoBUd")) != EOF) + switch(c) { + case 'v': + { + extern const char *version_string; + fprintf(stderr, "grotty version %s\n", version_string); + fflush(stderr); + break; + } + case 'b': + // Do not embolden by overstriking. + bold_flag = 0; + break; + case 'u': + // Do not underline. + underline_flag = 0; + break; + case 'o': + // Do not overstrike (other than emboldening and underlining). + overstrike_flag = 0; + break; + case 'B': + // Do bold-underlining as bold. + bold_underline_mode = BOLD_MODE; + break; + case 'U': + // Do bold-underlining as underlining. + bold_underline_mode = UNDERLINE_MODE; + break; + case 'h': + // Use horizontal tabs. + horizontal_tab_flag = 1; + break; + case 'f': + form_feed_flag = 1; + break; + case 'F': + font::command_line_font_dir(optarg); + break; + case 'd': + // Ignore \D commands. + draw_flag = 0; + break; + case '?': + usage(); + break; + default: + assert(0); + } + if (optind >= argc) + do_file("-"); + else { + for (int i = optind; i < argc; i++) + do_file(argv[i]); + } + delete pr; + return 0; +} + +static void usage() +{ + fprintf(stderr, "usage: %s [-hfvbuodBU] [-F dir] [files ...]\n", + program_name); + exit(1); +} -- cgit v1.1