Check in remainder of groff 1.08

This commit is contained in:
jtc 1993-07-15 16:40:48 +00:00
parent f81ad74956
commit 100ce3fca6
50 changed files with 10945 additions and 1414 deletions

View File

@ -0,0 +1,11 @@
# Makefile for tfmtodit
PROG= tfmtodit
SRCS= tfmtodit.cc
CFLAGS+= -I$(.CURDIR)/../include
LDADD+= $(LIBGROFF) -lm
DPADD+= $(LIBGROFF) $(LIBMATH)
.include <bsd.prog.mk>
.include "../../Makefile.inc"
.include "../Makefile.cfg"

View File

@ -0,0 +1,2 @@
tfmtodit.o : tfmtodit.cc ../include/lib.h ../include/errarg.h \
../include/error.h ../include/assert.h ../include/cset.h

View File

@ -0,0 +1,150 @@
.\" -*- nroff -*-
.ie t .ds tx T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X
.el .ds tx TeX
.\" Like TP, but if specified indent is more than half
.\" the current line-length - indent, use the default indent.
.de Tp
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
.el .TP "\\$1"
..
.TH TFMTODIT 1 "6 August 1992" "Groff Version 1.08"
.SH NAME
tfmtodit \- create font files for use with groff \-Tdvi
.SH SYNOPSIS
.B tfmtodit
[
.B \-sv
]
[
.BI \-g gf_file
]
[
.BI \-k skewchar
]
.I tfm_file
.I map_file
.I font
.SH DESCRIPTION
.B tfmtodit
creates a font file for use with
.B
groff \-Tdvi\fR.
.I tfm_file
is the name of the \*(tx font metric file for the font.
.I map_file
is a file giving the groff names for characters in the font;
this file should consist of a sequence of lines of the form:
.IP
.I
n c1 c2 \fR.\|.\|.
.LP
where
.I n
is a decimal integer giving the position of the character in the font,
and
.IR c1 ,
.IR c2 ,.\|.\|.
are the groff names of the character.
If a character has no groff names but exists in the tfm file,
then it will be put in the groff font file as an unnamed character.
.I font
is the name of the groff font file.
The groff font file is written to
.IR font .
.LP
The
.B \-s
option should be given if the font is special
(a font is
.I special
if
.B troff
should search it whenever
a character is not found in the current font.)
If the font is special,
it should be listed in the
.B fonts
command in the DESC file;
if it is not special, there is no need to list it, since
.B troff
can automatically mount it when it's first used.
.LP
To do a good job of math typesetting, groff requires
font metric information not present in the tfm file.
The reason for this is that \*(tx has separate math italic fonts
whereas groff uses normal italic fonts for math.
The additional information required by groff is given by the
two arguments to the
.B math_fit
macro in the Metafont programs for the Computer Modern fonts.
In a text font (a font for which
.B math_fitting
is false), Metafont normally ignores these two arguments.
Metafont can be made to put this information in the gf file
by loading the following definition after
.B cmbase
when creating
.BR cm.base :
.IP
.nf
.ft B
def ignore_math_fit(expr left_adjustment,right_adjustment) =
special "adjustment";
numspecial left_adjustment*16/designsize;
numspecial right_adjustment*16/designsize;
enddef;
.fi
.ft R
.LP
The gf file created using this modified
.B cm.base
should be specified with the
.B \-g
option.
The
.B \-g
option should not be given for a font for which
.B math_fitting
is true.
.SH OPTIONS
.TP
.B \-v
Print the version number.
.TP
.B \-s
The font is special.
The effect of this option is to add the
.B special
command to the font file.
.TP
.BI \-k n
The skewchar of this font is at position
.IR n .
.I n
should be an integer;
it may be given in decimal,
or with a leading
.B 0
in octal,
or with a leading
.B 0x
in hexadecimal.
The effect of this option is to ignore any kerns whose second component
is the specified character.
.TP
.BI \-g gf_file
.I gf_file
is a gf file produced by Metafont containing special and numspecial
commands giving additional font metric information.
.SH FILES
.Tp \w'\fB/usr/share/groff_font/devdvi/DESC'u+2n
.B /usr/share/groff_font/devdvi/DESC
Device desciption file.
.TP
.BI /usr/share/groff_font/devdvi/ F
Font description file for font
.IR F .
.SH "SEE ALSO"
.BR groff (1),
.BR grodvi (1),
.BR groff_font (5)

View File

@ -0,0 +1,850 @@
// -*- 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* I have tried to incorporate the changes needed for TeX 3.0 tfm files,
but I haven't tested them. */
/* Groff requires more font metric information than TeX. The reason
for this is that TeX has separate Math Italic fonts, whereas groff
uses normal italic fonts for math. The two additional pieces of
information required by groff correspond to the two arguments to the
math_fit() macro in the Metafont programs for the CM fonts. In the
case of a font for which math_fitting is false, these two arguments
are normally ignored by Metafont. We need to get hold of these two
parameters and put them in the groff font file.
We do this by loading this definition after cmbase when creating cm.base.
def ignore_math_fit(expr left_adjustment,right_adjustment) =
special "adjustment";
numspecial left_adjustment*16/designsize;
numspecial right_adjustment*16/designsize;
enddef;
This puts the two arguments to the math_fit macro into the gf file.
(They will appear in the gf file immediately before the character to
which they apply.) We then create a gf file using this cm.base. Then
we run tfmtodit and specify this gf file with the -g option.
This need only be done for a font for which math_fitting is false;
When it's true, the left_correction and subscript_correction should
both be zero. */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <errno.h>
#include "lib.h"
#include "errarg.h"
#include "error.h"
#include "assert.h"
#include "cset.h"
/* Values in the tfm file should be multiplied by this. */
#define MULTIPLIER 1
struct char_info_word {
unsigned char width_index;
char height_index;
char depth_index;
char italic_index;
char tag;
unsigned char remainder;
};
struct lig_kern_command {
unsigned char skip_byte;
unsigned char next_char;
unsigned char op_byte;
unsigned char remainder;
};
class tfm {
int bc;
int ec;
int nw;
int nh;
int nd;
int ni;
int nl;
int nk;
int np;
int cs;
int ds;
char_info_word *char_info;
int *width;
int *height;
int *depth;
int *italic;
lig_kern_command *lig_kern;
int *kern;
int *param;
public:
tfm();
~tfm();
int load(const char *);
int contains(int);
int get_width(int);
int get_height(int);
int get_depth(int);
int get_italic(int);
int get_param(int, int *);
int get_checksum();
int get_design_size();
int get_lig(unsigned char, unsigned char, unsigned char *);
friend class kern_iterator;
};
class kern_iterator {
tfm *t;
int c;
int i;
public:
kern_iterator(tfm *);
int next(unsigned char *c1, unsigned char *c2, int *k);
};
kern_iterator::kern_iterator(tfm *p)
: t(p), i(-1), c(t->bc)
{
}
int kern_iterator::next(unsigned char *c1, unsigned char *c2, int *k)
{
for (; c <= t->ec; c++)
if (t->char_info[c - t->bc].tag == 1) {
if (i < 0) {
i = t->char_info[c - t->bc].remainder;
if (t->lig_kern[i].skip_byte > 128)
i = (256*t->lig_kern[i].op_byte
+ t->lig_kern[i].remainder);
}
for (;;) {
int skip = t->lig_kern[i].skip_byte;
if (skip <= 128 && t->lig_kern[i].op_byte >= 128) {
*c1 = c;
*c2 = t->lig_kern[i].next_char;
*k = t->kern[256*(t->lig_kern[i].op_byte - 128)
+ t->lig_kern[i].remainder];
if (skip == 128) {
c++;
i = -1;
}
else
i += skip + 1;
return 1;
}
if (skip >= 128)
break;
i += skip + 1;
}
i = -1;
}
return 0;
}
tfm::tfm()
: char_info(0), width(0), height(0), depth(0), italic(0), lig_kern(0),
kern(0), param(0)
{
}
int tfm::get_lig(unsigned char c1, unsigned char c2, unsigned char *cp)
{
if (contains(c1) && char_info[c1 - bc].tag == 1) {
int i = char_info[c1 - bc].remainder;
if (lig_kern[i].skip_byte > 128)
i = 256*lig_kern[i].op_byte + lig_kern[i].remainder;
for (;;) {
int skip = lig_kern[i].skip_byte;
if (skip > 128)
break;
// We are only interested in normal ligatures, for which
// op_byte == 0.
if (lig_kern[i].op_byte == 0
&& lig_kern[i].next_char == c2) {
*cp = lig_kern[i].remainder;
return 1;
}
if (skip == 128)
break;
i += skip + 1;
}
}
return 0;
}
int tfm::contains(int i)
{
return i >= bc && i <= ec && char_info[i - bc].width_index != 0;
}
int tfm::get_width(int i)
{
return width[char_info[i - bc].width_index];
}
int tfm::get_height(int i)
{
return height[char_info[i - bc].height_index];
}
int tfm::get_depth(int i)
{
return depth[char_info[i - bc].depth_index];
}
int tfm::get_italic(int i)
{
return italic[char_info[i - bc].italic_index];
}
int tfm::get_param(int i, int *p)
{
if (i <= 0 || i > np)
return 0;
else {
*p = param[i - 1];
return 1;
}
}
int tfm::get_checksum()
{
return cs;
}
int tfm::get_design_size()
{
return ds;
}
tfm::~tfm()
{
a_delete char_info;
a_delete width;
a_delete height;
a_delete depth;
a_delete italic;
a_delete lig_kern;
a_delete kern;
a_delete param;
}
int read2(unsigned char *&s)
{
int n;
n = *s++ << 8;
n |= *s++;
return n;
}
int read4(unsigned char *&s)
{
int n;
n = *s++ << 24;
n |= *s++ << 16;
n |= *s++ << 8;
n |= *s++;
return n;
}
int tfm::load(const char *file)
{
errno = 0;
FILE *fp = fopen(file, "r");
if (!fp) {
error("can't open `%1': %2", file, strerror(errno));
return 0;
}
int c1 = getc(fp);
int c2 = getc(fp);
if (c1 == EOF || c2 == EOF) {
fclose(fp);
error("unexpected end of file on `%1'", file);
return 0;
}
int lf = (c1 << 8) + c2;
int toread = lf*4 - 2;
unsigned char *buf = new unsigned char[toread];
if (fread(buf, 1, toread, fp) != toread) {
if (feof(fp))
error("unexpected end of file on `%1'", file);
else
error("error on file `%1'", file);
a_delete buf;
fclose(fp);
return 0;
}
fclose(fp);
if (lf < 6) {
error("bad tfm file `%1': impossibly short", file);
a_delete buf;
return 0;
}
unsigned char *ptr = buf;
int lh = read2(ptr);
bc = read2(ptr);
ec = read2(ptr);
nw = read2(ptr);
nh = read2(ptr);
nd = read2(ptr);
ni = read2(ptr);
nl = read2(ptr);
nk = read2(ptr);
int ne = read2(ptr);
np = read2(ptr);
if (6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np != lf) {
error("bad tfm file `%1': lengths do not sum", file);
a_delete buf;
return 0;
}
if (lh < 2) {
error("bad tfm file `%1': header too short", file);
a_delete buf;
return 0;
}
char_info = new char_info_word[ec - bc + 1];
width = new int[nw];
height = new int[nh];
depth = new int[nd];
italic = new int[ni];
lig_kern = new lig_kern_command[nl];
kern = new int[nk];
param = new int[np];
int i;
cs = read4(ptr);
ds = read4(ptr);
ptr += (lh-2)*4;
for (i = 0; i < ec - bc + 1; i++) {
char_info[i].width_index = *ptr++;
unsigned char tem = *ptr++;
char_info[i].depth_index = tem & 0xf;
char_info[i].height_index = tem >> 4;
tem = *ptr++;
char_info[i].italic_index = tem >> 2;
char_info[i].tag = tem & 3;
char_info[i].remainder = *ptr++;
}
for (i = 0; i < nw; i++)
width[i] = read4(ptr);
for (i = 0; i < nh; i++)
height[i] = read4(ptr);
for (i = 0; i < nd; i++)
depth[i] = read4(ptr);
for (i = 0; i < ni; i++)
italic[i] = read4(ptr);
for (i = 0; i < nl; i++) {
lig_kern[i].skip_byte = *ptr++;
lig_kern[i].next_char = *ptr++;
lig_kern[i].op_byte = *ptr++;
lig_kern[i].remainder = *ptr++;
}
for (i = 0; i < nk; i++)
kern[i] = read4(ptr);
ptr += ne*4;
for (i = 0; i < np; i++)
param[i] = read4(ptr);
assert(ptr == buf + lf*4 - 2);
a_delete buf;
return 1;
}
class gf {
int left[256];
int right[256];
static int sread4(int *p, FILE *fp);
static int uread3(int *p, FILE *fp);
static int uread2(int *p, FILE *fp);
static int skip(int n, FILE *fp);
public:
gf();
int load(const char *file);
int get_left_adjustment(int i) { return left[i]; }
int get_right_adjustment(int i) { return right[i]; }
};
gf::gf()
{
for (int i = 0; i < 256; i++)
left[i] = right[i] = 0;
}
int gf::load(const char *file)
{
enum {
paint_0 = 0,
paint1 = 64,
boc = 67,
boc1 = 68,
eoc = 69,
skip0 = 70,
skip1 = 71,
new_row_0 = 74,
xxx1 = 239,
yyy = 243,
no_op = 244,
pre = 247,
post = 248
};
int got_an_adjustment = 0;
int pending_adjustment = 0;
int left_adj, right_adj;
const int gf_id_byte = 131;
errno = 0;
FILE *fp = fopen(file, "r");
if (!fp) {
error("can't open `%1': %2", file, strerror(errno));
return 0;
}
if (getc(fp) != pre || getc(fp) != gf_id_byte) {
error("bad gf file");
return 0;
}
int n = getc(fp);
if (n == EOF)
goto eof;
if (!skip(n, fp))
goto eof;
for (;;) {
int op = getc(fp);
if (op == EOF)
goto eof;
if (op == post)
break;
if ((op >= paint_0 && op <= paint_0 + 63)
|| (op >= new_row_0 && op <= new_row_0 + 164))
continue;
switch (op) {
case no_op:
case eoc:
case skip0:
break;
case paint1:
case skip1:
if (!skip(1, fp))
goto eof;
break;
case paint1 + 1:
case skip1 + 1:
if (!skip(2, fp))
goto eof;
break;
case paint1 + 2:
case skip1 + 2:
if (!skip(3, fp))
goto eof;
break;
case boc:
{
int code;
if (!sread4(&code, fp))
goto eof;
if (pending_adjustment) {
pending_adjustment = 0;
left[code & 0377] = left_adj;
right[code & 0377] = right_adj;
}
if (!skip(20, fp))
goto eof;
break;
}
case boc1:
{
int code = getc(fp);
if (code == EOF)
goto eof;
if (pending_adjustment) {
pending_adjustment = 0;
left[code] = left_adj;
right[code] = right_adj;
}
if (!skip(4, fp))
goto eof;
break;
}
case xxx1:
{
int len = getc(fp);
if (len == EOF)
goto eof;
char buf[256];
if (fread(buf, 1, len, fp) != len)
goto eof;
if (len == 10 /* strlen("adjustment") */
&& memcmp(buf, "adjustment", len) == 0) {
int c = getc(fp);
if (c != yyy) {
if (c != EOF)
ungetc(c, fp);
break;
}
if (!sread4(&left_adj, fp))
goto eof;
c = getc(fp);
if (c != yyy) {
if (c != EOF)
ungetc(c, fp);
break;
}
if (!sread4(&right_adj, fp))
goto eof;
got_an_adjustment = 1;
pending_adjustment = 1;
}
break;
}
case xxx1 + 1:
if (!uread2(&n, fp) || !skip(n, fp))
goto eof;
break;
case xxx1 + 2:
if (!uread3(&n, fp) || !skip(n, fp))
goto eof;
break;
case xxx1 + 3:
if (!sread4(&n, fp) || !skip(n, fp))
goto eof;
break;
case yyy:
if (!skip(4, fp))
goto eof;
break;
default:
fatal("unrecognized opcode `%1'", op);
break;
}
}
if (!got_an_adjustment)
warning("no adjustment specials found in gf file");
return 1;
eof:
error("unexpected end of file");
return 0;
}
int gf::sread4(int *p, FILE *fp)
{
*p = getc(fp);
if (*p >= 128)
*p -= 256;
*p <<= 8;
*p |= getc(fp);
*p <<= 8;
*p |= getc(fp);
*p <<= 8;
*p |= getc(fp);
return !ferror(fp) && !feof(fp);
}
int gf::uread3(int *p, FILE *fp)
{
*p = getc(fp);
*p <<= 8;
*p |= getc(fp);
*p <<= 8;
*p |= getc(fp);
return !ferror(fp) && !feof(fp);
}
int gf::uread2(int *p, FILE *fp)
{
*p = getc(fp);
*p <<= 8;
*p |= getc(fp);
return !ferror(fp) && !feof(fp);
}
int gf::skip(int n, FILE *fp)
{
while (--n >= 0)
if (getc(fp) == EOF)
return 0;
return 1;
}
struct char_list {
char *ch;
char_list *next;
char_list(const char *, char_list * = 0);
};
char_list::char_list(const char *s, char_list *p) : ch(strsave(s)), next(p)
{
}
int read_map(const char *file, char_list **table)
{
errno = 0;
FILE *fp = fopen(file, "r");
if (!fp) {
error("can't open `%1': %2", file, strerror(errno));
return 0;
}
for (int i = 0; i < 256; i++)
table[i] = 0;
char buf[512];
int lineno = 0;
while (fgets(buf, int(sizeof(buf)), fp)) {
lineno++;
char *ptr = buf;
while (csspace(*ptr))
ptr++;
if (*ptr == '\0' || *ptr == '#')
continue;
ptr = strtok(ptr, " \n\t");
if (!ptr)
continue;
int n;
if (sscanf(ptr, "%d", &n) != 1) {
error("%1:%2: bad map file", file, lineno);
fclose(fp);
return 0;
}
if (n < 0 || n > 255) {
error("%1:%2: code out of range", file, lineno);
fclose(fp);
return 0;
}
ptr = strtok(0, " \n\t");
if (!ptr) {
error("%1:%2: missing names", file, lineno);
fclose(fp);
return 0;
}
for (; ptr; ptr = strtok(0, " \n\t"))
table[n] = new char_list(ptr, table[n]);
}
fclose(fp);
return 1;
}
/* Every character that can participate in a ligature appears in the
lig_chars table. `ch' gives the full-name of the character, `name'
gives the groff name of the character, `i' gives its index in
the encoding, which is filled in later (-1 if it does not appear). */
struct {
const char *ch;
int i;
} lig_chars[] = {
"f", -1,
"i", -1,
"l", -1,
"ff", -1,
"fi", -1,
"fl", -1,
"Fi", -1,
"Fl", -1,
};
// Indices into lig_chars[].
enum { CH_f, CH_i, CH_l, CH_ff, CH_fi, CH_fl, CH_ffi, CH_ffl };
// Each possible ligature appears in this table.
struct {
unsigned char c1, c2, res;
const char *ch;
} lig_table[] = {
CH_f, CH_f, CH_ff, "ff",
CH_f, CH_i, CH_fi, "fi",
CH_f, CH_l, CH_fl, "fl",
CH_ff, CH_i, CH_ffi, "ffi",
CH_ff, CH_l, CH_ffl, "ffl",
};
static void usage();
int main(int argc, char **argv)
{
program_name = argv[0];
int special_flag = 0;
int skewchar = -1;
int opt;
const char *gf_file = 0;
while ((opt = getopt(argc, argv, "svg:k:")) != EOF)
switch (opt) {
case 'g':
gf_file = optarg;
break;
case 's':
special_flag = 1;
break;
case 'k':
{
char *ptr;
long n = strtol(optarg, &ptr, 0);
if ((n == 0 && ptr == optarg)
|| *ptr != '\0'
|| n < 0
|| n > UCHAR_MAX)
error("invalid skewchar");
else
skewchar = (int)n;
break;
}
case 'v':
{
extern const char *version_string;
fprintf(stderr, "tfmtodit version %s\n", version_string);
fflush(stderr);
break;
}
case '?':
usage();
break;
case EOF:
assert(0);
}
if (argc - optind != 3)
usage();
gf g;
if (gf_file) {
if (!g.load(gf_file))
return 1;
}
const char *tfm_file = argv[optind];
const char *map_file = argv[optind + 1];
const char *font_file = argv[optind + 2];
tfm t;
if (!t.load(tfm_file))
return 1;
char_list *table[256];
if (!read_map(map_file, table))
return 1;
errno = 0;
if (!freopen(font_file, "w", stdout)) {
error("can't open `%1' for writing: %2", font_file, strerror(errno));
return 1;
}
printf("name %s\n", font_file);
if (special_flag)
fputs("special\n", stdout);
char *internal_name = strsave(argv[optind]);
int len = strlen(internal_name);
if (len > 4 && strcmp(internal_name + len - 4, ".tfm") == 0)
internal_name[len - 4] = '\0';
char *s = strrchr(internal_name, '/');
printf("internalname %s\n", s ? s + 1 : internal_name);
int n;
if (t.get_param(2, &n)) {
if (n > 0)
printf("spacewidth %d\n", n*MULTIPLIER);
}
if (t.get_param(1, &n) && n != 0)
printf("slant %f\n", atan2(n/double(1<<20), 1.0)*180.0/M_PI);
int xheight;
if (!t.get_param(5, &xheight))
xheight = 0;
int i;
// Print the list of ligatures.
// First find the indices of each character that can participate in
// a ligature.
for (i = 0; i < 256; i++)
for (int j = 0; j < sizeof(lig_chars)/sizeof(lig_chars[0]); j++)
for (char_list *p = table[i]; p; p = p->next)
if (strcmp(lig_chars[j].ch, p->ch) == 0)
lig_chars[j].i = i;
// For each possible ligature, if its participants all exist,
// and it appears as a ligature in the tfm file, include in
// the list of ligatures.
int started = 0;
for (i = 0; i < sizeof(lig_table)/sizeof(lig_table[0]); i++) {
int i1 = lig_chars[lig_table[i].c1].i;
int i2 = lig_chars[lig_table[i].c2].i;
int r = lig_chars[lig_table[i].res].i;
if (i1 >= 0 && i2 >= 0 && r >= 0) {
unsigned char c;
if (t.get_lig(i1, i2, &c) && c == r) {
if (!started) {
started = 1;
fputs("ligatures", stdout);
}
printf(" %s", lig_table[i].ch);
}
}
}
if (started)
fputs(" 0\n", stdout);
printf("checksum %d\n", t.get_checksum());
printf("designsize %d\n", t.get_design_size());
// Now print out the kerning information.
int had_kern = 0;
kern_iterator iter(&t);
unsigned char c1, c2;
int k;
while (iter.next(&c1, &c2, &k))
if (c2 != skewchar) {
k *= MULTIPLIER;
char_list *q = table[c2];
for (char_list *p1 = table[c1]; p1; p1 = p1->next)
for (char_list *p2 = q; p2; p2 = p2->next) {
if (!had_kern) {
printf("kernpairs\n");
had_kern = 1;
}
printf("%s %s %d\n", p1->ch, p2->ch, k);
}
}
printf("charset\n");
char_list unnamed("---");
for (i = 0; i < 256; i++)
if (t.contains(i)) {
char_list *p = table[i] ? table[i] : &unnamed;
int m[6];
m[0] = t.get_width(i);
m[1] = t.get_height(i);
m[2] = t.get_depth(i);
m[3] = t.get_italic(i);
m[4] = g.get_left_adjustment(i);
m[5] = g.get_right_adjustment(i);
printf("%s\t%d", p->ch, m[0]*MULTIPLIER);
for (int j = int(sizeof(m)/sizeof(m[0])) - 1; j > 0; j--)
if (m[j] != 0)
break;
for (int k = 1; k <= j; k++)
printf(",%d", m[k]*MULTIPLIER);
int type = 0;
if (m[2] > 0)
type = 1;
if (m[1] > xheight)
type += 2;
printf("\t%d\t%04o\n", type, i);
for (p = p->next; p; p = p->next)
printf("%s\t\"\n", p->ch);
}
return 0;
}
static void usage()
{
fprintf(stderr, "usage: %s [-sv] [-g gf_file] [-k skewchar] tfm_file map_file font\n",
program_name);
exit(1);
}

View File

@ -0,0 +1,26 @@
# Makefile for groff macros
TMACOWN?= bin
TMACGRP?= bin
TMACMODE?= 444
TMACDIR?= /usr/share/tmac
MAN7= groff_ms.0
MLINKS= groff_ms.7 ms.7
FILES= tmac.pic tmac.ps tmac.psnew tmac.psold tmac.pspic tmac.psatk\
tmac.dvi tmac.tty tmac.tty-char tmac.X tmac.Xps tmac.latin1\
man.local eqnrc troffrc
afterinstall:
for f in ${FILES}; do \
install -c -o ${TMACOWN} -g ${TMACGRP} -m ${TMACMODE} \
${.CURDIR}/$$f ${DESTDIR}${TMACDIR}; \
done
install -c -o ${TMACOWN} -g ${TMACGRP} -m ${TMACMODE} \
${.CURDIR}/tmac.s ${DESTDIR}${TMACDIR}/tmac.${tmac_s}
install -c -o ${TMACOWN} -g ${TMACGRP} -m ${TMACMODE} \
${.CURDIR}/tmac.an ${DESTDIR}${TMACDIR}/tmac.an.old
.include <bsd.prog.mk>
.include "../Makefile.cfg"

View File

@ -0,0 +1,38 @@
Support multiple line-spacing.
Improve the device independence of the character definitions.
If we have footnotes in the abstract in RP format, then the footnote
will appear on the cover sheet, which it should, but also on the first
page, which it should not.
Should we allow multi-page cover-sheets?
Warn about automatically numbered footnotes in floating keeps.
When we bring back the footnote overflow at the top of page, it would
be more efficient to avoid diverting it again. (Need to keep track of
footnote height.)
Possibly have a place above which the footnote trap must not be
placed.
Improved indexing, not using tm, controlled by string variable (eg
-dIDX=file.idx).
When changing from multi-column to narrower columns, we could avoid
doing a @super-eject. (This might not be a good idea.)
Think about cutmarks. Possibly implement CM.
Implement thesis Mode (TM, CT).
Implement more V10 features.
Should this
.LP
.rs
.sp \n(.tu
print two pages?

View File

@ -0,0 +1,60 @@
.\" Startup file for eqn.
.EQ
sdefine << %{ < back 20 < }%
sdefine >> %{ > back 20 > }%
sdefine dot %accent "\fR\(a.\fP"%
sdefine dotdot %accent "\fR\(ad\fP"%
sdefine vec %accent {up 52 "\s[\En[.s]/2u]\(->\s0"}%
sdefine dyad %accent {up 52 "\s[\En[.s]/2u]\(<>\s0"}%
sdefine cdot %type "binary" \(md%
ifdef X75 ! define X %1% !
ifdef X100 ! define X %1% !
ifdef X75-12 ! define X %1% !
ifdef X100-12 ! define X %1% !
ifdef ps ! define ps|X %1% !
ifdef X ! define ps|X %1% !
ifdef ps|X ! sdefine inf %"\s[\En[.s]*13u/10u]\v'12M'\(if\v'-12M'\s0"% !
ifdef dvi !
sdefine int %{type "operator" vcenter \(is}%
sdefine sum %{type "operator" vcenter \[sum]}%
sdefine prod %{type "operator" vcenter \[product]}%
sdefine coprod %{type "operator" vcenter \[coproduct]}%
set num1 68
set num2 39
set denom1 69
set denom2 34
set sup1 41
set sup2 36
set sup3 29
set sup_drop 39
set sub_drop 5
set axis_height 25
set x_height 43
set default_rule_thickness 4
set big_op_spacing1 11
set big_op_spacing2 16
set big_op_spacing3 20
set big_op_spacing4 60
set big_op_spacing5 10
!
ifdef X ! set axis_height 32 !
ifdef ps|X ! set draw_lines 1 !
ifdef ascii ! define n %1% !
ifdef latin1 ! define n %1% !
ifdef n !
set nroff 1
!
undef X
undef ps|X
undef n
.EN

View File

@ -0,0 +1,210 @@
.\" -*- nroff -*-
.TH GROFF_MS 7 "6 August 1992" "Groff Version 1.08"
.SH NAME
groff_ms \- groff ms macros
.SH SYNOPSIS
.B groff
.B \-ms
[
.IR options .\|.\|.
]
[
.IR files .\|.\|.
]
.SH DESCRIPTION
This manual page describes the GNU version of the ms macros,
which is part of the groff document formatting system.
The groff ms macros are intended to be compatible with the 4.3
.SM BSD
Unix ms macros subject to the following limitations:
.IP \(bu
the internals of groff ms are not similar to the internals of Unix ms
and so documents that depend upon implementation details of Unix ms
may well not work with groff ms;
.IP \(bu
there is no support for typewriter-like devices;
.IP \(bu
Berkeley localisms, in particular the
.B TM
and
.B CT
macros, are not implemented;
.IP \(bu
groff ms
does not provide cut marks;
.IP \(bu
multiple line spacing is not allowed
(use a larger vertical spacing instead);
.IP \(bu
groff ms does not work in compatibility mode (eg with the
.B \-C
option);
.IP \(bu
the error-handling policy of groff ms
is to detect and report errors,
rather than silently to ignore them.
.LP
The groff ms macros make use of many features of GNU troff
and therefore cannot be used with any other troff.
.LP
Bell Labs localisms are not implemented in either the
.SM BSD
ms macros or in the groff ms macros.
.LP
Some Unix ms documentation says that the
.B CW
and
.B GW
number registers can be used to control the column width and
gutter width respectively.
This is not the case.
These number registers are not used in groff ms.
.LP
Macros that cause a reset set the indent.
Macros that change the indent do not increment or decrement
the indent, but rather set it absolutely.
This can cause problems for documents that define
additional macros of their own.
The solution is to use not the
.B in
request but instead the
.B RS
and
.B RE
macros.
.LP
The number register
.B GS
is set to 1 by the groff ms macros,
but is not used by the Unix ms macros.
It is intended that documents that need to determine whether
they are being formatted with Unix ms or groff ms make use of this
number register.
.LP
Footnotes are implemented so that they can safely be used within
keeps and displays.
Automatically numbered footnotes within floating keeps are
not recommended.
It is safe to have another
.B \e**
between a
.B \e**
and the corresponding
.BR .FS ;
it is required only that each
.B .FS
occur after the corresponding
.B \e**
and that the occurrences of
.B .FS
are in the same order as the corresponding occurrences of
.BR \e** .
.LP
The strings
.B \e*{
and
.B \e*}
can be used to begin and end a superscript.
.LP
Some Unix V10 ms features are implemented.
The
.BR B ,
.BR I
and
.B BI
macros can have an optional third argument which will be printed
in the current font before the first argument.
There is a macro
.B CW
like
.B B
that changes to a constant-width font.
.LP
The following strings can be redefined to adapt the groff ms macros
to languages other than English:
.LP
.nf
.ta \w'REFERENCES'u+2n
String Default Value
.sp .3v
REFERENCES References
ABSTRACT ABSTRACT
TOC Table of Contents
MONTH1 January
MONTH2 February
MONTH3 March
MONTH4 April
MONTH5 May
MONTH6 June
MONTH7 July
MONTH8 August
MONTH9 September
MONTH10 October
MONTH11 November
MONTH12 December
.fi
.LP
The font family is reset from the string
.BR FAM ;
at initialization if this string is undefined it is set to the current
font family.
The point size, vertical spacing, and inter-paragraph spacing for footnotes
are taken from the number registers
.BR FPS ,
.BR FVS ,
and
.BR FPD ;
at initialization these are set to
.BR \en(PS-2 ,
.BR \en[FPS]+2 ,
and
.B \en(PD/2
respectively; however, if any of these registers has been defined
before initialization, it will not be set.
.LP
Right-aligned displays are available with
.B ".DS R"
and
.BR .RD .
.LP
The following conventions are used for names of macros, strings and
number registers.
External names available to documents that use the groff ms
macros contain only uppercase letters and digits.
Internally the macros are divided into modules.
Names used only within one module are of the form
.IB module * name\fR.
Names used outside the module in which they are defined are of the form
.IB module @ name\fR.
Names associated with a particular environment are of the form
.IB environment : name;
these are used only within the
.B par
module,
and
.I name
does not have a module prefix.
Constructed names used to implement arrays are of the form
.IB array ! index\fR.
Thus the groff ms macros reserve the following names:
.IP \(bu
names containing
.BR * ;
.IP \(bu
names containing
.BR @ ;
.IP \(bu
names containing
.BR : ;
.IP \(bu
names containing only uppercase letters and digits.
.SH FILES
.B /usr/share/tmac/tmac.s
.SH "SEE ALSO"
.BR groff (1),
.BR troff (1),
.BR tbl (1),
.BR pic (1),
.BR eqn (1)
.br
.BR ms (7)

View File

View File

@ -0,0 +1,45 @@
.nr _C \n(.C
.cp 0
.ftr CW CR
.ftr C CR
.ftr CO CI
.ftr CX CBI
.ftr H HR
.ftr HO HI
.ftr HX HBI
.ftr NX NBI
.char \(ru \D'l .5m 0'
.char \(ul \v'.25m'\D'l .5m 0'\v'-.25m'
.char \(br \v'.25m'\D'l 0 -1m'\v'.75m'
.char ~ \v'-.55m'\\s[\\n(.s/2u]\v'.2m'\(ti\v'-.2m'\s0\v'.55m'
.char ^ \v'-.55m'\\s[\\n(.s/2u]\v'.3m'\(ha\v'-.3m'\s0\v'.55m'
.if !c\(va .char \(va \o'\(ua\(da'
.if !c\(em .char \(em --
.if !c\(en .char \(en \-
.if !c\(fi .char \(fi fi
.if !c\(fl .char \(fl fl
.if !c\(ff .char \(ff ff
.if !c\(Fi .char \(Fi ffi
.if !c\(Fl .char \(Fl ffl
.if !c\(ci .char \(ci \v'-.25m'\h'.05m'\D'c .5m'\h'.05m'\v'.25m'
.if !c\(sq .char \(sq \h'.05m'\D'l .5m 0'\D'l 0 -.5m'\D'l -.5m 0'\D'l 0 .5m'\h'.55m'
.if !c\(ga .char \(ga \Z'\v'-.7m'\D'l .22m .18m''\h'.33m'
.if !c\(dg .char \(dg \Z'\h'.25m'\v'.15m'\D'l 0 -.8m'\v'.2m'\h'-.195m'\
\D'l .39m 0''\h'.5m'
.if !c\(dd .char \(dd \Z'\h'.25m'\v'.15m'\D'l 0 -.8m'\v'.2m'\h'-.195m'\
\D'l .39m 0'\v'.4m'\D'l -.39m 0''\h'.5m'
.if !c\(lq .char \(lq ``
.if !c\(rq .char \(rq ''
.if !c\(Bq .char \(bq ,,
.if !c\(OE .char \(OE O\h'-.25m'E
.if !c\(oe .char \(oe o\h'-.14m'e
.if !c\(ah .char \(ah \v'-.55m'\s[\En[.s]/2u]v\s0\v'.55m'
.if !c\(ao .char \(ao \v'-.55m'\s[\En[.s]*6u/10u]\D'c .25m'\s0\v'.55m'
.if !c\(ho .char \(ho \s[\En[.s]/2u]\v'.4m'c\v'-.4m'\s0
.if !c\(lh .tr \(lh\(lA
.if !c\(rh .tr \(rh\(rA
.if !c\(bq .tr \(bq,
.if !c\(aq .tr \(aq'
.if '\*(.T'X100' .char \(rn \h'-\w'\(sr'u'\(rn\h'\w'\(sr'u'
.if !\n(_C .mso tmac.pspic
.cp \n(_C

View File

@ -0,0 +1,44 @@
.do mso tmac.ps
.nr _C \n(.C
.cp 0
.de Xps-char
.char \\$1 \Z"\X'ps: invis'\\$2\X'ps: endinvis'"\\$1
..
.Xps-char \(bu \fS\(bu\fP
.Xps-char \(em "\v'-.25m'\h'.05m'\D'l .9m 0'\h'.05m'"
.Xps-char \(aq '
.Xps-char \(bq ,
.Xps-char \(Bq ,,
.Xps-char \(lq ``
.Xps-char \(rq ''
.Xps-char \(OE OE
.Xps-char \(oe oe
.Xps-char \(Fn \fS\(Fn\fP
.Xps-char \(vS \o'\(ahS'
.Xps-char \(vs \o'\(ahs'
.Xps-char \(vZ \o'\(ahZ'
.Xps-char \(vz \o'\(ahz'
.Xps-char \(/L \o'/L'
.Xps-char \(/l \o'/l'
.Xps-char \(:Y \o'\(adY'
.Xps-char \(a" \(sd
.Xps-char \(a. \v'-.6m'.
.Xps-char \(ga "\Z'\v'-.7m'\D'l .22m .18m''\h'.33m'"
.Xps-char \(ab \v'-.55m'\s'\\\\n(.s*6u/10u'u\s0
.Xps-char \(ah \v'-.55m'\s[\En[.s]/2u]v\s0\v'.55m'
.Xps-char \(ao "\v'-.55m'\s[\En[.s]*6u/10u]\D'c .25m'\s0\v'.55m'"
.Xps-char \(ho \s[\En[.s]/2u]\v'.4m'c\v'-.4m'\s0
.Xps-char \(.i i
.Xps-char \(fo <
.Xps-char \(fc >
.Xps-char \(OK \s'\\\\n(.s*6u/10u'\e\s0/
.Xps-char \(tm \v'-.3m'\s'\\\\n(.s*6u/10u'TM\s0\v'.3m'
.Xps-char \(dd "\Z'\h'.25m'\v'.15m'\D'l 0 -.8m'\v'.2m'\h'-.195m'\
\D'l .39m 0'\v'.4m'\D'l -.39m 0''\h'.5m'"
.Xps-char \(dg "\Z'\h'.25m'\v'.15m'\D'l 0 -.8m'\v'.2m'\h'-.195m'\
\D'l .39m 0''\h'.5m'"
.Xps-char \(en \-
.Xps-char \(%0 %\s'\\\\n(.s*6u/10u'\fI0\fP\s0
.Xps-char \(lh \(->
.Xps-char \(rh \(<-
.cp \n(_C

View File

@ -0,0 +1,326 @@
.\"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, 675 Mass Ave, Cambridge, MA 02139, USA.
.\"
.\" -rC1 => number pages continuously, rather than start each at 1
.\" -rD1 => double-sided printing, ie different odd and even page footers
.\" -rPnnn => number first page nnn
.\" -rXnnn => number pages after nnn as nnna, nnnb, nnnc, ...
.\"
.\" The file man.local is loaded at the end. Put local additions there.
.\" If you need to add things to TH, use `.am TH'.
.\"
.if !\n(.g .ab These man macros work only with groff.
.nr _C \n(.C
.cp 0
.if !rD .nr D 0
.if !rC .nr C 0
.if rP .pn 0\nP
.\" .TH title section extra1 extra2 extra3
.de TH
.cp 0
.de an-init \" We have to do it like this to get multiple man pages right.
.ds an-title "\\$1
.ds an-section "\\$2
.ds an-extra1 "\\$3
.ie \\n[.$]>3 .ds an-extra2 "\\$4
.el .ds an-extra2 \"Sun Release 4.0
.ie \\n[.$]>4 .ds an-extra3 "\\$5
.el .ds an-extra3 \"UNIX Programmer's Manual
.ds an-init
\\..
.DT
.nr IN 7.2n
.nr LL 6.5i
.PD
.nr PS 10 \" normal point-size
.nr SN 3n \" the indentation of sub-sub-headings relative to sub-headings
.nr an-level 1
.nr an-margin \\n[IN]
.nr an-prevailing-indent \\n[IN]
.nr an-tag-sep 1n
.nr an-no-space-flag 0
.nr an-break-flag 0
.nr an-div? 0
.wh 0 an-header
.wh -1i an-footer
.wh -.5i an-p-footer
.if \\n[nl]>0 \{\
. ie \\nC .bp \\n%+1
. el .bp 1
.\}
..
.de DT
.ta T .5i \" This sets tabs every .5 inches
..
.de PD
.ie \\n[.$] .nr PD (v;\\$1)
.el .nr PD .4v>?\n[.V]
..
.de an-header
.an-init
.ev 1
.sp .5i
.tl '\\*[an-title](\\*[an-section])'\\*[an-extra3]'\\*[an-title](\\*[an-section])'
.sp |1i
.ev
.ns
..
.de an-footer
'bp
..
.af an-page-letter a
.de an-p-footer
.ev 1
.ds an-page-string \\n%
.if rX \{\
. if \\n%>\\nX \{\
. nr an-page-letter \\n%-\\nX
. ds an-page-string \\nX\\n[an-page-letter]
.\}\}
.ie \\nD \{\
. if o .tl '\\*[an-extra2]'\\*[an-extra1]'\\*[an-page-string]'
. if e .tl '\\*[an-page-string]'\\*[an-extra1]'\\*[an-extra2]'
.\}
.el .tl '\\*[an-extra2]'\\*[an-extra1]'\\*[an-page-string]'
.ev
..
.de SH
.sp \\n[PD]u
.nr an-level 1
.nr an-margin \\n[IN]
.nr an-prevailing-indent \\n[IN]
.fi
.in \\n[IN]u
.ti 0
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.ps \\n[PS]-1
.ft B
.ne 2v+1u
.if \\n[.$] \&\\$*
..
.de SS
.sp \\n[PD]u
.nr an-level 1
.nr an-margin \\n[IN]
.nr an-prevailing-indent \\n[IN]
.fi
.in \\n[IN]u
.ti \\n[SN]u
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.ps \\n[PS]
.ft B
.ne 2v+1u
.if \\n[.$] \&\\$*
..
.de B
.it 1 an-trap
.ft B
.if \\n[.$] \&\\$*
..
.de I
.it 1 an-trap
.ft I
.if \\n[.$] \&\\$*
..
.de SM
.it 1 an-trap
.ps -1
.if \\n[.$] \&\\$*
..
.de SB
.it 1 an-trap
.ps -1
.ft B
.if \\n[.$] \&\\$*
..
.de TP
.sp \\n[PD]u
.if \\n[.$] .nr an-prevailing-indent (n;\\$1)
.it 1 an-trap
.if !\\n[an-div?] .di an-div
.in 0
.nr an-div? 1
..
.de an-trap
.ft R
.ps \\n[PS]
.if \\n[an-break-flag] \{\
. br
. nr an-break-flag 0
.\}
.if \\n[an-no-space-flag] \{\
. ns
. nr an-no-space-flag 0
.\}
.if \\n[an-div?] .an-do-tag
..
.de an-do-tag
.nr an-div? 0
.br
.di
.in \\n[an-margin]u+\\n[an-prevailing-indent]u
.ti -\\n[an-prevailing-indent]u
.ie \\n[dl]+\\n[an-tag-sep]>\\n[an-prevailing-indent] \{\
. ne 2v+1u
. an-div
. br
.\}
.el \{\
. chop an-div
. ne 1v+1u
\\*[an-div]\\h'|\\n[an-prevailing-indent]u'\c
.\}
..
.de LP
.br
.sp \\n[PD]u
.ps \\n[PS]
.ft R
.in \\n[an-margin]u
.nr an-prevailing-indent \\n[IN]
..
.als PP LP
.als P LP
.de IP
.ie !\\n[.$] \{\
. ps \\n[PS]
. ft R
. sp \\n[PD]u
. ne 1v+1u
. in \\n[an-margin]u+\\n[an-prevailing-indent]u
.\}
.el \{\
. ie \\n[.$]-1 .TP "\\$2"
. el .TP
\&\\$1
.\}
..
.de HP
.ps \\n[PS]
.ft R
.sp \\n[PD]u
.ne 1v+1u
.if \\n[.$] .nr an-prevailing-indent (n;\\$1)
.in \\n[an-margin]u+\\n[an-prevailing-indent]u
.ti \\n[an-margin]u
..
.de RI
.if \\n[.$] \{\
. ds an-result \&\\$1
. shift
. while \\n[.$]>=2 \{\
. as an-result \,\fI\\$1\fR\/\\$2
. shift 2
. \}
. if \\n[.$] .as an-result \,\fI\\$1\fR
\\*[an-result]
.\}
..
.de IR
.if \\n[.$] \{\
. ds an-result \&\fI\\$1\fR
. shift
. while \\n[.$]>=2 \{\
. as an-result \/\\$1\fI\,\\$2\fR
. shift 2
. \}
. if \\n[.$] .as an-result \/\\$1
\\*[an-result]
.\}
..
.de IB
.if \\n[.$] \{\
. ds an-result \&\fI\\$1
. shift
. while \\n[.$]>=2 \{\
. as an-result \/\\fB\\$1\fI\,\\$2
. shift 2
. \}
. if \\n[.$] .as an-result \/\\fB\\$1
\\*[an-result]
. ft R
.\}
..
.de BI
.if \\n[.$] \{\
. ds an-result \&\fB\\$1
. shift
. while \\n[.$]>=2 \{\
. as an-result \,\fI\\$1\fB\/\\$2
. shift 2
. \}
. if \\n[.$] .as an-result \,\fI\\$1
\\*[an-result]
. ft R
.\}
..
.de RB
.ds an-result \&
.while \\n[.$]>=2 \{\
. as an-result \fR\\$1\fB\\$2
. shift 2
.\}
.if \\n[.$] .as an-result \fR\\$1
\\*[an-result]
.ft R
..
.de BR
.ds an-result \&
.while \\n[.$]>=2 \{\
. as an-result \fB\\$1\fR\\$2
. shift 2
.\}
.if \\n[.$] .as an-result \fB\\$1
\\*[an-result]
.ft R
..
.de RS
.br
.nr an-saved-margin\\n[an-level] \\n[an-margin]
.nr an-saved-prevailing-indent\\n[an-level] \\n[an-prevailing-indent]
.ie \\n[.$] .nr an-margin +(n;\\$1)
.el .nr an-margin +\\n[an-prevailing-indent]
.in \\n[an-margin]u
.nr an-prevailing-indent \\n[IN]
.nr an-level +1
..
.de RE
.br
.ie \\n[.$] .nr an-level (;\\$1)<?\\n[an-level]
.el .nr an-level -1
.nr an-level 1>?\\n[an-level]
.nr an-margin \\n[an-saved-margin\\n[an-level]]
.nr an-prevailing-indent \\n[an-saved-prevailing-indent\\n[an-level]]
.in \\n[an-margin]u
..
.ds S \s[\\n[PS]]
.ie c\[rg] .ds R \[rg]
.el .ds R (Reg.)
.ie c\[tm] .ds Tm \[tm]
.el .ds Tm (TM)
.ds lq \(lq
.ds rq \(rq
.hy 14
.\" Load local modifications.
.mso man.local
.cp \n(_C

View File

@ -0,0 +1,132 @@
.nr _C \n(.C
.cp 0
.ftr CR CW
.ftr C CW
.ftr TT CW
.ftr HR H
.\" This uses the dvi-char_1 string in font CW, dvi-char_0 otherwise.
.char _ \R'dvi-char_ \\n(.f=\f(CW\\n(.f\fP'\\*[dvi-char_\\n[dvi-char_]]
.char \[ul] \R'dvi-char_ \w'M'=\w'i''\\*[dvi-char_\\n[dvi-char_]]
.\" Normally use a rule.
.ds dvi-char_0 \v'.23m'\D'R .5m .04m'\v'-.04m'\v'-.23m'
.\" In font CW use a real _ character.
.ds dvi-char_1 _
.if !c\[rn] .char \[rn] \D'R .5m -.04m'\v'.04m'
.if !c\[br] .char \[br] \Z'\v'.25m'\D'R .04m -1m''
.if !c\[ru] .char \[ru] \v'-.02m'\D'R .5m .04m'\v'-.04m'\v'.02m'
.if !c\[co] .char \[co] \z\(ci\h'\w'\(ci'u-\w'c'u/2u'c\h'\w'\(ci'u-\w'c'u/2u'
.if !c\[rg] .char \[rg] \z\(ci\h'\w'\(ci'u-\w'r'u/2u'r\h'\w'\(ci'u-\w'r'u/2u'
.if !c\[fm] .char \[fm] \v'-.35m'\s[\\n(.s*7u/10u]\[prime]\s0\v'.35m'
.if !c\[de] .char \[de] \h'.05m'\v'-.54m'\D'c .3m'\v'.54m'\h'.05m'
.if !c\[ct] .char \[ct] \o'c/'
.if !c\[sq] .char \[sq] \Z'\h'.05m'\D'R .4m -.04m'\v'.04m'\h'-.04m'\
\D'R .04m -.4m'\v'.04m'\D'R -.4m -.04m'\D'R .04m .4m''\h'.5m'
.\"char \[sq] \h'.05m'\D'l .4m 0'\D'l 0 -.4m'\D'l -.4m 0'\D'l 0 .4m'\h'.45m'
.if !c\[!=] .char \[!=] \[slashnot]\(eq
.if !c\[tm] .char \[tm] \v'-.3m'\s[\\n(.s/2u]TM\s0\v'.3m'
.if !c\[aq] .char \[aq] '
.if !c\[bq] .char \[bq] ,
.if !c\[Bq] .char \[Bq] ,\h'\w'\(rq'u-(2u*\w"'"u)',
.if !c\[ho] .char \[ho] \s[\En[.s]/2u]\v'.4m'c\v'-.4m'\s0
.if !c\[-D] .char \[-D] \Z'\v'-.1m'\h'.05m'-'D
.if !c\[Sd] .char \[Sd] \Z'\v'-.3m'\h'.35m'-'\(pd
.if !c\[TP] .char \[TP] I\h'-.25m'\v'-.33m'\s[\En[.s]*6u/10u]\v'.33m'D\
\v'-.33m'\s0\v'.33m'
.if !c\[Tp] .char \[Tp] \zlp
.cflags 8 \(an
.if !c\[an] .char \[an] \h'-.167m'\(mi\h'-.167m'
.\" Define some fractions.
.de dvi-frac
.if !c\[\\$1\\$2] .char \[\\$1\\$2] \
\v'-.25m'\s[\\\\n(.s*7u/10u]\\$1\s0\v'.25m'\h'-.2m'\
/\h'-.2m'\v'.25m'\s[\\\\n(.s*7u/10u]\\$2\s0\v'-.25m'
..
.dvi-frac 1 2
.dvi-frac 3 4
.dvi-frac 1 4
.dvi-frac 1 8
.dvi-frac 3 8
.dvi-frac 5 8
.dvi-frac 7 8
.\" support for ISO Latin-1
.if !c\[S1] .char \[S1] \v'-.2m'\s-31\s+3\v'+.2m'
.if !c\[S2] .char \[S2] \v'-.2m'\s-32\s+3\v'+.2m'
.if !c\[S3] .char \[S3] \v'-.2m'\s-33\s+3\v'+.2m'
.if !c\[Of] .char \[Of] \v'-.2m'\s'\En(.s*6u/10u'\o'_a'\s0\v'.2m'
.if !c\[Om] .char \[Om] \v'-.2m'\s'\En(.s*6u/10u'\o'_o'\s0\v'.2m'
.if !c\[Fo] .char \[Fo] <<
.if !c\[Fc] .char \[Fc] >>
.if !c\[bb] .char \[bb] |
.if !c\[Ye] .char \[Ye] \o'-Y'
.if !c\[Cs] .char \[Cs] \o'\[mu]o'
.de dvi-achar
.\" Note that character definitions are always interpreted with
.\" compatibility mode off.
.if !c\\$1 \{\
.char \\$1 \\$3\
\k[acc]\
\h'(u;-\w'\\$2'-\w'\\$3'/2+\\\\n[skw]+(\w'x'*0)-\\\\n[skw])'\
\v'(u;\w'x'*0+\\\\n[rst]+(\w'\\$3'*0)-\\\\n[rst])'\
\\$2\
\v'(u;\w'x'*0-\\\\n[rst]+(\w'\\$3'*0)+\\\\n[rst])'\
\h'|\\\\n[acc]u'
.\}
.hcode \\$1\\$4
..
.dvi-achar \(`A \` A a
.dvi-achar \('A \' A a
.dvi-achar \(^A ^ A a
.dvi-achar \(~A ~ A a
.dvi-achar \(:A \(ad A a
.dvi-achar \(oA \(ao A a
.dvi-achar \(`E \` E e
.dvi-achar \('E \' E e
.dvi-achar \(^E ^ E e
.dvi-achar \(:E \(ad E e
.dvi-achar \(`I \` I i
.dvi-achar \('I \' I i
.dvi-achar \(^I ^ I i
.dvi-achar \(:I \(ad I i
.dvi-achar \(~N ~ N n
.dvi-achar \(`O \` O o
.dvi-achar \('O \' O o
.dvi-achar \(^O ^ O o
.dvi-achar \(~O ~ O o
.dvi-achar \(:O \(ad O o
.dvi-achar \(`U \` U u
.dvi-achar \('U \' U u
.dvi-achar \(^U ^ U u
.dvi-achar \(:U \(ad U u
.dvi-achar \('Y \' Y y
.dvi-achar \(`a \` a a
.dvi-achar \('a \' a a
.dvi-achar \(^a ^ a a
.dvi-achar \(~a ~ a a
.dvi-achar \(:a \(ad a a
.dvi-achar \(oa \(ao a a
.dvi-achar \(`e \` e e
.dvi-achar \('e \' e e
.dvi-achar \(^e ^ e e
.dvi-achar \(:e \(ad e e
.dvi-achar \(`i \` \(.i i
.dvi-achar \('i \' \(.i i
.dvi-achar \(^i ^ \(.i i
.dvi-achar \(:i \(ad \(.i i
.dvi-achar \(~n ~ n n
.dvi-achar \(`o \` o o
.dvi-achar \('o \' o o
.dvi-achar \(^o ^ o o
.dvi-achar \(~o ~ o o
.dvi-achar \(:o \(ad o o
.dvi-achar \(`u \` u u
.dvi-achar \('u \' u u
.dvi-achar \(^u ^ u u
.dvi-achar \(:u \(ad u u
.dvi-achar \('y \' y y
.dvi-achar \(:y \(ad y y
.char \(,C \o'\(acc'
.hcode \(,Cc
.char \(,c \o'\(acc'
.hcode \(,cc
.cp \n(_C
.do mso tmac.latin1

View File

@ -0,0 +1,101 @@
.nr _C \n(.C
.cp 0
.de latin1-tr
.if c\\$2 .if !c\\$1 .tr \\$1\\$2
..
.latin1-tr \[char161] \(r!
.latin1-tr \[char162] \(ct
.latin1-tr \[char163] \(Po
.latin1-tr \[char164] \(Cs
.latin1-tr \[char165] \(Ye
.latin1-tr \[char166] \(bb
.latin1-tr \[char167] \(sc
.latin1-tr \[char168] \(ad
.latin1-tr \[char169] \(co
.latin1-tr \[char170] \(Of
.latin1-tr \[char171] \(Fo
.latin1-tr \[char172] \(no
.latin1-tr \[char173] \(hy
.latin1-tr \[char174] \(rg
.latin1-tr \[char175] \(a-
.latin1-tr \[char176] \(de
.latin1-tr \[char177] \(+-
.latin1-tr \[char178] \(S2
.latin1-tr \[char179] \(S3
.latin1-tr \[char180] \(aa
.latin1-tr \[char181] \(*m
.latin1-tr \[char182] \(ps
.latin1-tr \[char183] \(md
.latin1-tr \[char184] \(ac
.latin1-tr \[char185] \(S1
.latin1-tr \[char186] \(Om
.latin1-tr \[char187] \(Fc
.latin1-tr \[char188] \(14
.latin1-tr \[char189] \(12
.latin1-tr \[char190] \(34
.latin1-tr \[char191] \(r?
.latin1-tr \[char192] \(`A
.latin1-tr \[char193] \('A
.latin1-tr \[char194] \(^A
.latin1-tr \[char195] \(~A
.latin1-tr \[char196] \(:A
.latin1-tr \[char197] \(oA
.latin1-tr \[char198] \(AE
.latin1-tr \[char199] \(,C
.latin1-tr \[char200] \(`E
.latin1-tr \[char201] \('E
.latin1-tr \[char202] \(^E
.latin1-tr \[char203] \(:E
.latin1-tr \[char204] \(`I
.latin1-tr \[char205] \('I
.latin1-tr \[char206] \(^I
.latin1-tr \[char207] \(:I
.latin1-tr \[char208] \(-D
.latin1-tr \[char209] \(~N
.latin1-tr \[char210] \(`O
.latin1-tr \[char211] \('O
.latin1-tr \[char212] \(^O
.latin1-tr \[char213] \(~O
.latin1-tr \[char214] \(:O
.latin1-tr \[char215] \(mu
.latin1-tr \[char216] \(/O
.latin1-tr \[char217] \(`U
.latin1-tr \[char218] \('U
.latin1-tr \[char219] \(^U
.latin1-tr \[char220] \(:U
.latin1-tr \[char221] \('Y
.latin1-tr \[char222] \(TP
.latin1-tr \[char223] \(ss
.latin1-tr \[char224] \(`a
.latin1-tr \[char225] \('a
.latin1-tr \[char226] \(^a
.latin1-tr \[char227] \(~a
.latin1-tr \[char228] \(:a
.latin1-tr \[char229] \(oa
.latin1-tr \[char230] \(ae
.latin1-tr \[char231] \(,c
.latin1-tr \[char232] \(`e
.latin1-tr \[char233] \('e
.latin1-tr \[char234] \(^e
.latin1-tr \[char235] \(:e
.latin1-tr \[char236] \(`i
.latin1-tr \[char237] \('i
.latin1-tr \[char238] \(^i
.latin1-tr \[char239] \(:i
.latin1-tr \[char240] \(Sd
.latin1-tr \[char241] \(~n
.latin1-tr \[char242] \(`o
.latin1-tr \[char243] \('o
.latin1-tr \[char244] \(^o
.latin1-tr \[char245] \(~o
.latin1-tr \[char246] \(:o
.latin1-tr \[char247] \(di
.latin1-tr \[char248] \(/o
.latin1-tr \[char249] \(`u
.latin1-tr \[char250] \('u
.latin1-tr \[char251] \(^u
.latin1-tr \[char252] \(:u
.latin1-tr \[char253] \('y
.latin1-tr \[char254] \(Tp
.latin1-tr \[char255] \(:y
.cp \n(_C

View File

@ -0,0 +1,10 @@
.de PS
.br
.sp .3v
.ne 0\\$1+1v+\n(.Vu
.in \\n(.lu-\\n(.iu-0\\$2/2u>?0
..
.de PE
.in
.sp .3v+.5m
..

View File

@ -0,0 +1,52 @@
.nr _C \n(.C
.cp 0
.ftr AX ABI
.ftr KR BMR
.ftr KI BMI
.ftr KB BMB
.ftr KX BMBI
.ftr CW CR
.ftr CO CI
.ftr CX CBI
.ftr H HR
.ftr HO HI
.ftr HX HBI
.ftr Hr HNR
.ftr Hi HNI
.ftr Hb HNB
.ftr Hx HNBI
.ftr NX NBI
.ftr PA PR
.ftr PX PBI
.ftr ZI ZCMI
.ftr C CR
.cflags 8 \(an
.char \(rn \h'-\w'\(sr'u'\(rn\h'\w'\(sr'u'
.char \(mo \h'.08m'\(mo\h'-.08m'
.char \(nm \h'.08m'\(nm\h'-.08m'
.char \[parenlefttp] \[parenlefttp]\h'.016m'
.char \[parenleftbt] \[parenleftbt]\h'.016m'
.char \[parenleftex] \[parenleftex]\h'.016m'
.char \[parenrighttp] \[parenrighttp]\h'.016m'
.char \[parenrightbt] \[parenrightbt]\h'.016m'
.char \[parenrightex] \[parenrightex]\h'.016m'
.if !c\[va] .char \[va] \o'\[ua]\[da]'
.if !c\[ci] \
.char \[ci] \v'-.25m'\h'.05m'\D'c .5m'\h'.05m'\v'.25m'
.if !c\[sq] \
.char \[sq] \h'.05m'\D'l .5m 0'\D'l 0 -.5m'\D'l -.5m 0'\D'l 0 .5m'\h'.55m'
.if !c\[ru] .char \[ru] \D'l .5m 0'
.if !c\[ul] .char \[ul] \v'.25m'\D'l .5m 0'\v'-.25m'
.if !c\[br] .char \[br] \Z'\v'.25m'\D'l 0 -1m''
.if !c\[or] .char \[or] \h'.1m'\Z'\D'l 0 -.675m''\h'.1m'
.if !c\[Fi] .char \[Fi] ffi
.if !c\[Fl] .char \[Fl] ffl
.if !c\[ff] .char \[ff] ff
.if !c\[ij] .char \[ij] ij
.if !c\[IJ] .char \[IJ] IJ
.if !c\[tm] .char \[tm] \s-3\v'-.3m'TM\v'+.3m'\s+3
.\" pic tests this register to see whether it should use \X'ps:...'
.nr 0p 1
.cp \n(_C
.if !\n(.C .mso tmac.pspic
.do mso tmac.psold

View File

@ -0,0 +1,61 @@
.\" Implementation of the ATK PB and PE macros for use with groff and grops.
.\" Load this after tmac.atk.
.nr zT 0
.if '\*(.T'ps' .nr zT 1
.nr psatk-unit 1p
.de psatk-defs
ps: mdef 5
/PB {
/saved save def
currentpoint translate
\n[psatk-unit] u -\n[psatk-unit] u scale
userdict begin
/showpage {} def
} bind def
/PE {
end
saved restore
} bind def
/troffadjust {
pop 0
} bind def
..
.de PB
.ne \\$1p
.nr zT \\n(zT>0
\\*[PB\\n(zT]\\
..
.de PE
\\*[PE\\n(zT]\\
..
.ds PB0
.\" The last line before the "'PE" is "\}" rather than ".\}". This
.\" would cause a spurious space to be introduced before any picture
.\" that was the first thing on a line. So we have to catch that and
.\" remove it.
.de PB1
.ev psatk
.fi
.di psatk-mac
\!ps: exec PB
..
.de PE0
\v'-.75m'\
\D'l \\$1p 0'\D'l 0 \\$2p'\D'l -\\$1p 0'\D'l 0 -\\$2p'\
\h'\\$1p'\v'.75m'\x'\\$2p-1m>?0'\c
..
.ds psatk-init \Y[psatk-defs]
.de PE1
\!PE
.di
.di null
.br
.di
.rm null
.ev
\v'-.75m'\
\\*[psatk-init]\Y[psatk-mac]\
\h'\\$1p'\v'.75m'\x'\\$2p-1m>?0'\c
.rm psatk-mac
.if \\n(.P .ds psatk-init
..

View File

@ -0,0 +1,87 @@
.\" These are macros to make psfig work with groff.
.\" They require that psfig be patched as described in ../grops/psfig.diff.
.de psfig-defs
ps: mdef 100
% wid ht llx lly urx ury psfigstart -
/psfigstart {
/level1 save def
/ury exch def
/urx exch def
/lly exch def
/llx exch def
/ht exch u def
/wid exch u def
currentpoint ht add translate
wid urx llx sub div ht ury lly sub div neg scale
llx neg lly neg translate
% set the graphics state to default values
0 setgray
0 setlinecap
1 setlinewidth
0 setlinejoin
10 setmiterlimit
[] 0 setdash
newpath
/showpage {} def
} bind def
% psfigclip -
/psfigclip {
currentpoint newpath
llx lly moveto
urx lly lineto
urx ury lineto
llx ury lineto
closepath clip
newpath moveto
} bind def
% psfigend -
/psfigend {
level1 restore
} bind def
% globalstart -
/globalstart {
% save the current space code on the stack
SC
level0 restore
} bind def
% globalend -
/globalend {
end
BP
/SC exch def
DEFS begin
} bind def
..
.de psfig-init
.if \\n[.P] \{\
\Y[psfig-defs]
. br
. sp -1
. ds psfig-init\" empty
. rm psfig-defs
.\}
..
.de F+
.br
.psfig-init
.nr psfig-fill \\n[.u]
.nf
.sp -.5
.if !\\n[.$] .ce 9999
..
.de F-
.br
.ce 0
.if \\n[psfig-fill] .fi
..

View File

@ -0,0 +1,26 @@
.\" Undo the effect of tmac.psold. This gives access to the additional
.\" characters that are present in the text fonts of newer PostScript
.\" printers. It is a bad idea to use this if you are going to
.\" distribute the resulting PostScript output to others.
.nr _C \n(.C
.cp 0
.rchar \('y\('Y\(12\(14\(34\(S1\(S2\(S3\(bb\(de\(Tp\(TP\(-D\(Sd
.tr \[char166]\[char166]
.tr \[char176]\[char176]
.tr \[char177]\[char177]
.tr \[char178]\[char178]
.tr \[char179]\[char179]
.tr \[char181]\[char181]
.tr \[char185]\[char185]
.tr \[char188]\[char188]
.tr \[char189]\[char189]
.tr \[char190]\[char190]
.tr \[char208]\[char208]
.tr \[char215]\[char215]
.tr \[char221]\[char221]
.tr \[char222]\[char222]
.tr \[char240]\[char240]
.tr \[char247]\[char247]
.tr \[char253]\[char253]
.tr \[char254]\[char254]
.cp \n(_C

View File

@ -0,0 +1,60 @@
.\" In the newer PostScript printers, the text fonts contain all ISO Latin-1
.\" characters. The font description files that comes with groff match
.\" these fonts. The text fonts in older PostScript printers are missing
.\" some of these characters. This file prevents those characters from
.\" being used. This will allow the PostScript output to be printed on both
.\" old and new printers. The effect of this file can be undone by
.\" tmac.psnew.
.nr _C \n(.C
.cp 0
.\" Define an accented character.
.de ps-achar
.\" Note that character definitions are always interpreted with
.\" compatibility mode off.
.char \\$1 \\$3\
\k[acc]\
\h'(u;-\w'\\$2'-\w'\\$3'/2+\\\\n[skw]+(\w'x'*0)-\\\\n[skw])'\
\v'(u;\w'x'*0+\\\\n[rst]+(\w'\\$3'*0)-\\\\n[rst])'\
\\$2\
\v'(u;\w'x'*0-\\\\n[rst]+(\w'\\$3'*0)+\\\\n[rst])'\
\h'|\\\\n[acc]u'
.ie '\\$3'\(.i' .hcode \\$1i
.el .hcode \\$1\\$3
..
.ps-achar \['y] \(aa y
.ps-achar \['Y] \(aa Y
.char \[12] \v'-.7m\s[\\n(.s*6u/10u]+.7m'1\v'-.7m\s0+.7m'\
\(f/\s[\\n(.s*6u/10u]2\s0
.char \[14] \v'-.7m\s[\\n(.s*6u/10u]+.7m'1\v'-.7m\s0+.7m'\
\(f/\s[\\n(.s*6u/10u]4\s0
.char \[34] \v'-.7m\s[\\n(.s*6u/10u]+.7m'3\v'-.7m\s0+.7m'\
\(f/\s[\\n(.s*6u/10u]4\s0
.char \[S1] \v'-.2m'\s-31\s+3\v'+.2m'
.char \[S2] \v'-.2m'\s-32\s+3\v'+.2m'
.char \[S3] \v'-.2m'\s-33\s+3\v'+.2m'
.char \[bb] |
.char \[de] \fS\(de
.char \[-D] \Z'\v'-.1m'-'D
.char \[TP] \
I\h'-.25m'\v'-.33m'\s'\En(.s*6u/10u'\v'.33m'D\v'-.33m'\s0\v'.33m'
.char \[Sd] \Z'\v'-.3m'\h'.2m'-'\(pd
.char \[Tp] \zlp
.tr \[char166]\[bb]
.tr \[char176]\[de]
.tr \[char177]\[+-]
.tr \[char178]\[S2]
.tr \[char179]\[S3]
.tr \[char181]\[*m]
.tr \[char185]\[S1]
.tr \[char188]\[14]
.tr \[char189]\[12]
.tr \[char190]\[34]
.tr \[char208]\[-D]
.tr \[char215]\[mu]
.tr \[char221]\['Y]
.tr \[char222]\[TP]
.tr \[char240]\[Sd]
.tr \[char247]\[di]
.tr \[char253]\['y]
.tr \[char254]\[Tp]
.cp \n(_C

View File

@ -0,0 +1,41 @@
.\" Define the PSPIC macro.
.\" When used other than with -Tps, it will draw a box around where
.\" the picture would go.
.de ps-bb
.nr ps-nargs \\n[.$]
.if \\n[ps-nargs]=4 \{\
. nr ps-llx 0\\$1
. nr ps-lly 0\\$2
. nr ps-urx 0\\$3
. nr ps-ury 0\\$4
.\}
..
.de PSPIC
.br
.sy echo .ps-bb `psbb \\$1` >/tmp/psbb\\n[$$]
.so /tmp/psbb\\n[$$]
.if \\n[ps-nargs]=4 \{\
. nr ps-wid (\\n[ps-urx]-\\n[ps-llx])
. nr ps-ht (\\n[ps-ury]-\\n[ps-lly])
. if \\n[ps-wid]<0 .nr ps-wid 0-\\n[ps-wid]
. if \\n[ps-ht]<0 .nr ps-ht 0-\\n[ps-ht]
. ie \\n[.$]>=2 .nr ps-deswid (i;\\$2)
. el .nr ps-deswid \\n[.l]-\\n[.i]<?\\n[ps-wid]p
. ie \\n[.$]>=3 .nr ps-desht (i;\\$3)
. el .nr ps-desht \\n[ps-deswid]*1000+(\\n[ps-wid]/2)/\\n[ps-wid]\
*\\n[ps-ht]+500/1000
. ne \\n[ps-desht]u+1v
. nr ps-offset \\n[.l]-\\n[.i]-\\n[ps-deswid]/2
. ie \\n[.$]>=3 .ds ps-desht \\n[ps-desht]
. el .ds ps-desht \" empty
\h'\\n[ps-offset]u'\
\X'ps: invis'\
\Z'\D'p 0 \\n[ps-desht]u \\n[ps-deswid]u 0 0 -\\n[ps-desht]u''\
\X'ps: endinvis'\
\v'\\n[ps-desht]u'\X'ps: import \\$1 \
\\n[ps-llx] \\n[ps-lly] \\n[ps-urx] \\n[ps-ury] \\n[ps-deswid] \\*[ps-desht]'
. br
. sp \\n[ps-desht]u
.\}
.sy rm /tmp/psbb\\n[$$]
..

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
.nr _C \n(.C
.cp 0
.nroff
.ftr CW B
.ftr C B
.ftr CR B
.po 0
.if c\[char173] .shc \[char173]
.de tty-char
.if !c\\$1 .char \\$1 "\\$2
..
.if c\(md .tr \(bu\(md
.tty-char \(bu \z+o
.tty-char \(14 1/4
.tty-char \(12 1/2
.tty-char \(34 3/4
.tty-char \(ff ff
.tty-char \(fi fi
.tty-char \(fl fl
.tty-char \(Fi ffi
.tty-char \(Fl ffl
.tty-char \(<- <-
.tty-char \(-> ->
.tty-char \(<> <->
.tty-char \(em --
.tty-char \(+- +-
.tty-char \(co (C)
.tty-char \(<= <=
.tty-char \(>= >=
.tty-char \(!= !=
.tty-char \(== ==
.tty-char \(~= ~=
.tty-char \(sq []
.tty-char \(lh <=
.tty-char \(rh =>
.tty-char \(lA <=
.tty-char \(rA =>
.tty-char \(hA <=>
.tty-char \(rg (R)
.tty-char \(OE OE
.tty-char \(oe oe
.tty-char \(AE AE
.tty-char \(ae ae
.tty-char \(an -
.cp \n(_C
.\" If you want the character definitions in tmac.tty-char to be loaded
.\" automatically, remove the `\"' from the next line.
.\"do mso tmac.tty-char

View File

@ -0,0 +1,196 @@
.\" This file defines standard troff characters and some groff characters for
.\" use with -Tascii and -Tlatin1.
.\"
.\" These definitions are chosen so that, as far as possible, they:
.\" - work with both -Tascii and -Tlatin1.
.\" - work on devices that display only the last overstruck character
.\" as well as on devices that support overstriking
.\" - represent the character's graphical shape (not its meaning)
.\"
.nr _C \n(.C
.cp 0
.de tty-char
.if !c\\$1 .char \\$1 "\\$2
..
.ie c\(a- .ds tty-rn \(a-
.el .ds tty-rn \v'-1m'_\v'+1m'
.tty-char \(tm tm
.tty-char \(rn \*[tty-rn]
.tty-char \(ua \z|^
.tty-char \(da \z|v
.tty-char \(sc S
.tty-char \(ct \z/c
.tty-char \(dg \z|-
.tty-char \(dd \z|=
.tty-char \(ib (\z=_
.tty-char \(ip \z=_)
.tty-char \(sb (=
.tty-char \(sp =)
.tty-char \(if oo
.tty-char \(pt oc
.tty-char \(es {}
.tty-char \(ca (^)
.tty-char \(cu U
.tty-char \(de o
.tty-char \(di -:-
.tty-char \(no ~
.tty-char \(gr \Z'\*[tty-rn]'V
.tty-char \(is \z'\z,I
.tty-char \(mo E
.tty-char \(pd a
.tty-char \(sr \e/
.tty-char \(*C \z_H
.tty-char \(*D \z_/\z_\e
.tty-char \(*F \zIO
.tty-char \(*G |\*[tty-rn]
.tty-char \(*H \z-O
.tty-char \(*L /\e
.tty-char \(*P TT
.tty-char \(*Q \zIY
.tty-char \(*S \z_\Z'\*[tty-rn]'>
.tty-char \(*W \z_O
.if c\(ss .tty-char \(*b \(ss
.tty-char \(*b B
.tty-char \(*a a
.tty-char \(*c \z,E
.tty-char \(*d d
.tty-char \(*e e
.tty-char \(*f \z|o
.tty-char \(+f \z|o
.tty-char \(*g y
.tty-char \(*h \z-0
.tty-char \(+h \z-0
.tty-char \(*i i
.tty-char \(*k k
.tty-char \(*l \z>\e
.tty-char \(*m \z,u
.tty-char \(*n v
.tty-char \(*p \z-n
.tty-char \(+p \z-w
.tty-char \(*q \z|u
.tty-char \(*r p
.tty-char \(*s \z-o
.tty-char \(*t \z~t
.tty-char \(*u u
.tty-char \(*w w
.tty-char \(*x x
.tty-char \(*y n
.tty-char \(*z \z,C
.tty-char \(ts s
.\" Definition of \(ss should follow that of \(*b.
.tty-char \(ss B
.tty-char \(c* \zO\(mu
.tty-char \(c+ \zO+
.tty-char \(AN ^
.tty-char \(OR v
.tty-char \(uA \z=^
.tty-char \(dA \z=v
.if c\(md .tty-char \(a. \(md
.tty-char \(Im I
.tty-char \(Re R
.tty-char \(/L \z/L
.tty-char \(/l \z/l
.tty-char \(%0 %o
.tty-char \(ao o
.tty-char \(a" """"
.tty-char \(ah v
.tty-char \(ho \(ac
.tty-char \(/_ \z_/
.tty-char \(=~ =~
.tty-char \(Ah N
.tty-char \(CR _|
.tty-char \(fa \z-V
.tty-char \(nm \z/E
.tty-char \(pp \z_|
.tty-char \(sd ''
.tty-char \(st -)
.tty-char \(te 3
.if c\(md .tty-char \(tf .\(md.
.tty-char \(tf .:.
.tty-char \(wp p
.tty-char \(~~ ~~
.tty-char \(Fn \z,f
.tty-char \(Bq ,,
.tty-char \(bq ,
.tty-char \(lz <>
.\" Latin-1 characters
.tty-char \(r! \z,i
.tty-char \(Po \z-L
.tty-char \(Cs \zox
.tty-char \(Ye \z=Y
.tty-char \(bb |
.tty-char \(ad """"
.tty-char \(Of \z_a
.tty-char \(Fo <<
.tty-char \(a- \*[tty-rn]
.tty-char \(S2 2
.tty-char \(S3 3
.tty-char \(ps 9|
.tty-char \(md .
.tty-char \(ac ,
.tty-char \(S1 1
.tty-char \(Om \z_o
.tty-char \(Fc >>
.tty-char \(r? \z'c
.tty-char \(`A \z`A
.tty-char \('A \z'A
.tty-char \(^A \z^A
.tty-char \(~A \z~A
.tty-char \(:A \z"A
.tty-char \(oA \zoA
.tty-char \(,C \z,C
.tty-char \(`E \z`E
.tty-char \('E \z'E
.tty-char \(^E \z^E
.tty-char \(:E \z"E
.tty-char \(`I \z`I
.tty-char \('I \z'I
.tty-char \(^I \z^I
.tty-char \(:I \z"I
.tty-char \(-D \z-D
.tty-char \(~N \z~N
.tty-char \(`O \z`O
.tty-char \('O \z'O
.tty-char \(^O \z^O
.tty-char \(~O \z~O
.tty-char \(:O \z"O
.tty-char \(/O \z/O
.tty-char \(`U \z`U
.tty-char \('U \z'U
.tty-char \(^U \z^U
.tty-char \(:U \z"U
.tty-char \('Y \z'Y
.tty-char \(TP \zIb
.tty-char \(`a \z`a
.tty-char \('a \z'a
.tty-char \(^a \z^a
.tty-char \(~a \z~a
.tty-char \(:a \z"a
.tty-char \(oa \zoa
.tty-char \(,c \z,c
.tty-char \(`e \z`e
.tty-char \('e \z'e
.tty-char \(^e \z^e
.tty-char \(:e \z"e
.tty-char \(`i \z`i
.tty-char \('i \z'i
.tty-char \(^i \z^i
.tty-char \(:i \z"i
.tty-char \(Sd \z`\z'o
.tty-char \(~n \z~n
.tty-char \(`o \z`o
.tty-char \('o \z'o
.tty-char \(^o \z^o
.tty-char \(~o \z~o
.tty-char \(:o \z"o
.tty-char \(/o \z/o
.tty-char \(`u \z`u
.tty-char \('u \z'u
.tty-char \(^u \z^u
.tty-char \(:u \z"u
.tty-char \('y \z'y
.tty-char \(Tp \zpb
.tty-char \(:y \z"y
.\"tty-char \(:y \ij
.cp \n(_C
.do mso tmac.latin1

View File

@ -0,0 +1,24 @@
.\" Startup file for troff.
.\" This is tested by pic.
.nr 0p 0
.\" Use .do here, so that it works with -C.
.\" The groff command defines the .X string if the -X option was given.
.ie r.X .do ds troffrc!ps tmac.Xps
.el .do ds troffrc!ps tmac.ps
.do ds troffrc!dvi tmac.dvi
.do ds troffrc!X75 tmac.X
.do ds troffrc!X75-12 tmac.X
.do ds troffrc!X100 tmac.X
.do ds troffrc!X100-12 tmac.X
.do ds troffrc!ascii tmac.tty
.do ds troffrc!latin1 tmac.tty
.do if d troffrc!\*[.T] \
. do mso \*[troffrc!\*[.T]]
.do rm troffrc!ps troffrc!Xps troffrc!dvi troffrc!X75 troffrc!X75-12 \
troffrc!X100 troffrc!X100-12
.do tr \[char160]
.\" Set the hyphenation language to `us'.
.do hla us
.\" Load hyphenation patterns from `hyphen.us' (in the tmac directory).
.do hpf hyphen.us
.\" Don't let blank lines creep in here.

View File

@ -1,21 +1,35 @@
# @(#)Makefile 6.2 (Berkeley) 3/3/91
.include "../Makefile.g++"
.include "../../Makefile.inc"
# Makefile for troff
PROG= troff
HYPHENDIR= /usr/share/misc
SRCS= column.cc dictionary.cc div.cc env.cc input.cc \
node.cc number.cc reg.cc symbol.cc
LDADD+= $(.CURDIR)/../libgroff/obj/libgroff.a -lm
# Delete the -Ig++-include after we fix libg++ and install it
CXXFLAGS+= -I$(.CURDIR) -I$(.CURDIR)/../libgroff \
-I$(.CURDIR)/../../../lib/libg++/g++-include \
-DMACROPATH=\"/usr/share/tmac\" -DSTORE_WIDTH \
-DHYPHENFILE=\"$(HYPHENDIR)/hyphen\"
SRCS= env.cc node.cc input.cc div.cc symbol.cc dictionary.cc reg.cc \
number.cc majorminor.cc
CFLAGS+= -I$(.CURDIR)/../include
LDADD+= $(LIBGROFF) -lm
DPADD+= $(LIBGROFF) $(LIBMATH)
CLEANFILES+= majorminor.cc
majorminor.cc: $(.CURDIR)/../VERSION
@echo Making $@
@-rm -f $@
@echo const char \*major_version = \
\"`sed -e 's/^\([^.]*\)\..*$$/\1/' $(.CURDIR)/../VERSION`\"\; >$@
@echo const char \*minor_version = \
\"`sed -e 's/^[^.]*\.\([0-9]*\).*$$/\1/' $(.CURDIR)/../VERSION`\"\; >>$@
install_data: hyphen.us
-test -d $(datadir) || mkdir $(datadir)
-test -d $(datasubdir) || mkdir $(datasubdir)
-test -d $(tmacdir) || mkdir $(tmacdir)
-rm -f $(tmacdir)/hyphen.us
$(INSTALL_DATA) $(srcdir)/hyphen.us $(tmacdir)/hyphen.us
uninstall_sub:
-rm -f $(tmacdir)/hyphen.us
afterinstall:
install -c -o bin -g bin -m 444 $(.CURDIR)/hyphen \
$(DESTDIR)$(HYPHENDIR)/hyphen
install -c -o bin -g bin -m 444 $(.CURDIR)/hyphen.us \
$(DESTDIR)$(tmacdir)/hyphen.us
.include <bsd.prog.mk>
.include "../../Makefile.inc"
.include "../Makefile.cfg"

View File

@ -0,0 +1,34 @@
env.o : env.cc troff.h ../include/lib.h ../include/assert.h \
../include/device.h ../include/cset.h ../include/cmap.h \
../include/errarg.h ../include/error.h symbol.h dictionary.h hvunits.h \
env.h request.h node.h token.h div.h reg.h charinfo.h \
../include/searchpath.h ../include/macropath.h
node.o : node.cc troff.h ../include/lib.h ../include/assert.h \
../include/device.h ../include/cset.h ../include/cmap.h \
../include/errarg.h ../include/error.h symbol.h dictionary.h hvunits.h \
env.h request.h node.h token.h charinfo.h ../include/font.h reg.h
input.o : input.cc troff.h ../include/lib.h ../include/assert.h \
../include/device.h ../include/cset.h ../include/cmap.h \
../include/errarg.h ../include/error.h symbol.h dictionary.h hvunits.h \
env.h request.h node.h reg.h token.h div.h charinfo.h ../include/font.h \
../include/searchpath.h ../include/macropath.h ../include/defs.h \
../include/posix.h
div.o : div.cc troff.h ../include/lib.h ../include/assert.h \
../include/device.h ../include/cset.h ../include/cmap.h \
../include/errarg.h ../include/error.h symbol.h dictionary.h hvunits.h \
env.h request.h node.h token.h div.h reg.h
symbol.o : symbol.cc troff.h ../include/lib.h ../include/assert.h \
../include/device.h ../include/cset.h ../include/cmap.h \
../include/errarg.h ../include/error.h symbol.h
dictionary.o : dictionary.cc troff.h ../include/lib.h ../include/assert.h \
../include/device.h ../include/cset.h ../include/cmap.h \
../include/errarg.h ../include/error.h symbol.h dictionary.h
reg.o : reg.cc troff.h ../include/lib.h ../include/assert.h \
../include/device.h ../include/cset.h ../include/cmap.h \
../include/errarg.h ../include/error.h symbol.h dictionary.h token.h \
request.h reg.h
number.o : number.cc troff.h ../include/lib.h ../include/assert.h \
../include/device.h ../include/cset.h ../include/cmap.h \
../include/errarg.h ../include/error.h symbol.h hvunits.h env.h token.h \
div.h
majorminor.o : majorminor.cc

View File

@ -1,15 +1,12 @@
Give a more helpful error message when the indent is set to a value
greater than the line-length.
Tracing. This is a pain to implement because requests are responsible
for reading their own arguments.
Possibly implement -s option (stop every N pages). This functionality
would be more appropriate in a postprocessor.
Make it possible to have multilingual documents, by having a ``current
language'' with which hyphenation information (the pattern trie and
exception dictionary) is associated; the current language should be
associated with the environment. Get some pattern tries for other
languages (assuming ISO Latin-1).
Line breaking should be smarter. In particular, it should be possible
to shrink spaces. Also avoid having a line that's been shrunk a lot
next to a line that's been stretched a lot. The difficulty is to
@ -90,8 +87,6 @@ Make it possible to suppress hyphenation on a word-by-word basis.
Possibly allow multiple simultaneous input line traps.
Paddable, unbreakable space escape sequence.
Unpaddable, breakable space escape sequence.
Support hanging punctuation.
@ -117,5 +112,21 @@ Generalized ligatures.
Provide some way for a macro to tell whether it was called with `'' or
`.'. This would be useful for implementing a tracing macro packge.
Request to remove an environment. (Need to check it's not on the
environment stack).
Request to remove an environment. (Maintain a count of the references
to the environment from the environment table, environment dictionary
or environment stack.)
Perhaps in the nr request a leading `-' should only be recognized as a
decrement when it's at the same input level as the request.
Don't ever change a charinfo. Create new variants instead and chain
them together.
Make it possible to tr characters onto \~.
Unix troff appears to read the first character of a request name in
copy mode. Should we do the same?
Number register giving name of end macro.
More thorough range checking.

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,7 +15,7 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
class macro;
@ -24,13 +24,15 @@ class charinfo {
static int next_index;
charinfo *translation;
int index;
int number;
macro *mac;
unsigned char special_translation;
unsigned char hyphenation_code;
unsigned char flags;
unsigned char ascii_code;
unsigned char number;
char not_found;
char transparent_translate; // non-zero means translation applies to
// to transparent throughput
public:
enum {
ENDS_SENTENCE = 1,
@ -39,12 +41,14 @@ public:
OVERLAPS_HORIZONTALLY = 8,
OVERLAPS_VERTICALLY = 16,
TRANSPARENT = 32,
NUMBERED = 64,
NUMBERED = 64
};
enum {
TRANSLATE_NONE,
TRANSLATE_SPACE,
TRANSLATE_DUMMY,
TRANSLATE_STRETCHABLE_SPACE,
TRANSLATE_HYPHEN_INDICATOR
};
symbol nm;
charinfo(symbol s);
@ -59,22 +63,22 @@ public:
unsigned char get_ascii_code();
void set_hyphenation_code(unsigned char);
void set_ascii_code(unsigned char);
charinfo *get_translation();
void set_translation(charinfo *);
charinfo *get_translation(int = 0);
void set_translation(charinfo *, int);
void set_flags(unsigned char);
void set_special_translation(int);
int get_special_translation();
void set_special_translation(int, int);
int get_special_translation(int = 0);
macro *set_macro(macro *);
macro *get_macro();
int first_time_not_found();
void set_number(unsigned char);
void set_number(int);
int get_number();
int numbered();
};
charinfo *get_charinfo(symbol);
extern charinfo *charset_table[];
charinfo *get_charinfo_by_number(unsigned char);
charinfo *get_charinfo_by_number(int);
inline int charinfo::overlaps_horizontally()
{
@ -111,9 +115,11 @@ inline int charinfo::numbered()
return flags & NUMBERED;
}
inline charinfo *charinfo::get_translation()
inline charinfo *charinfo::get_translation(int transparent_throughput)
{
return translation;
return (transparent_throughput && !transparent_translate
? 0
: translation);
}
inline unsigned char charinfo::get_hyphenation_code()
@ -136,9 +142,11 @@ inline int charinfo::get_index()
return index;
}
inline int charinfo::get_special_translation()
inline int charinfo::get_special_translation(int transparent_throughput)
{
return special_translation;
return (transparent_throughput && !transparent_translate
? TRANSLATE_NONE
: special_translation);
}
inline macro *charinfo::get_macro()

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,12 +15,12 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef COLUMN
#include "groff.h"
#include "troff.h"
#include "symbol.h"
#include "dictionary.h"
#include "hvunits.h"
@ -464,8 +464,8 @@ justification_spec::justification_spec(vunits h)
justification_spec::~justification_spec()
{
delete type;
delete amount;
a_delete type;
a_delete amount;
}
void justification_spec::append(symbol t, vunits v)
@ -486,12 +486,12 @@ void justification_spec::append(symbol t, vunits v)
int i;
for (i = 0; i < n; i++)
type[i] = old_type[i];
delete old_type;
a_delete old_type;
vunits *old_amount = amount;
amount = new vunits[maxn];
for (i = 0; i < n; i++)
amount[i] = old_amount[i];
delete old_amount;
a_delete old_amount;
}
assert(n < maxn);
type[n] = t;

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,11 +15,11 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "groff.h"
#include "troff.h"
#include "symbol.h"
#include "dictionary.h"
@ -49,7 +49,7 @@ dictionary::dictionary(int n) : threshold(0.5), factor(1.5), used(0), size(n)
void *dictionary::lookup(symbol s, void *v)
{
for (int i = s.hash() % size;
for (int i = int(s.hash() % size);
table[i].v != 0;
i == 0 ? i = size - 1: --i)
if (s == table[i].s) {
@ -77,6 +77,7 @@ void *dictionary::lookup(symbol s, void *v)
for (i = 0; i < old_size; i++)
if (old_table[i].v != 0)
(void)lookup(old_table[i].s, old_table[i].v);
a_delete old_table;
}
return 0;
}
@ -95,7 +96,7 @@ void *dictionary::lookup(const char *p)
void *dictionary::remove(symbol s)
{
// this relies on the fact that we are using linear probing
for (int i = s.hash() % size;
for (int i = int(s.hash() % size);
table[i].v != 0 && s != table[i].s;
i == 0 ? i = size - 1: --i)
;
@ -110,7 +111,7 @@ void *dictionary::remove(symbol s)
i = size - 1;
if (table[i].v == 0)
break;
r = table[i].s.hash() % size;
r = int(table[i].s.hash() % size);
} while ((i <= r && r < j) || (j < i && i <= r));
table[j] = table[i];
}

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,7 +15,7 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,13 +15,13 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
// diversions
#include "groff.h"
#include "troff.h"
#include "symbol.h"
#include "dictionary.h"
#include "hvunits.h"
@ -32,6 +32,11 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "div.h"
#include "reg.h"
int exit_started = 0; // the exit process has started
int done_end_macro = 0; // the end macro (if any) has finished
int seen_last_page_ejector = 0; // seen the LAST_PAGE_EJECTOR cookie
static int began_page_in_end_macro = 0; // a new page was begun during the end macro
static int last_post_line_extra_space = 0; // needed for \n(.a
static int nl_reg_contents = -1;
static int dl_reg_contents = 0;
@ -59,7 +64,7 @@ vertical_size::vertical_size(vunits vs, int ls)
post = V0;
}
void node::set_vertical_size(vertical_size *v)
void node::set_vertical_size(vertical_size *)
{
}
@ -256,8 +261,8 @@ void macro_diversion::output(node *nd, int retain_size,
mac->append(new vertical_size_node(v.post));
mac->append('\n');
vertical_position += x;
if (vertical_position > high_water_mark)
high_water_mark = vertical_position;
if (vertical_position - v.post > high_water_mark)
high_water_mark = vertical_position - v.post;
}
void macro_diversion::space(vunits n, int)
@ -273,8 +278,6 @@ void macro_diversion::space(vunits n, int)
n = -vertical_position;
mac->append(new diverted_space_node(n));
vertical_position += n;
if (vertical_position > high_water_mark)
high_water_mark = vertical_position;
}
void macro_diversion::copy_file(const char *filename)
@ -285,8 +288,8 @@ void macro_diversion::copy_file(const char *filename)
top_level_diversion::top_level_diversion()
: page_count(0), have_next_page_number(0), page_length(units_per_inch*11),
page_offset(units_per_inch), prev_page_offset(units_per_inch),
ejecting_page(0), page_trap_list(0), first_page_begun(0), no_space_mode(0),
page_number(0)
ejecting_page(0), page_trap_list(0), before_first_page(1), no_space_mode(0),
page_number(0), last_page_count(-1)
{
}
@ -332,7 +335,7 @@ void top_level_diversion::output(node *nd, int retain_size,
no_space_mode = 0;
vunits next_trap_pos;
trap *next_trap = find_next_trap(&next_trap_pos);
if (!first_page_begun && begin_page())
if (before_first_page && begin_page())
fatal("sorry, I didn't manage to begin the first page in time: use an explicit .br request");
vertical_size v(vs, ls);
for (node *tem = nd; tem != 0; tem = tem->next)
@ -348,14 +351,14 @@ void top_level_diversion::output(node *nd, int retain_size,
the_output->print_line(page_offset, vertical_position, nd,
v.pre + v.pre_extra, v.post_extra);
vertical_position += v.post_extra;
if (vertical_position > high_water_mark)
high_water_mark = vertical_position;
if (vertical_position_traps_flag && vertical_position >= page_length)
begin_page();
else if (vertical_position_traps_flag
&& next_trap != 0 && vertical_position >= next_trap_pos) {
nl_reg_contents = vertical_position.to_units();
truncated_space = v.post;
if (vertical_position > high_water_mark)
high_water_mark = vertical_position;
spring_trap(next_trap->nm);
}
else if (v.post > V0) {
@ -365,28 +368,20 @@ void top_level_diversion::output(node *nd, int retain_size,
truncated_space = vertical_position - next_trap_pos;
vertical_position = next_trap_pos;
nl_reg_contents = vertical_position.to_units();
if (vertical_position > high_water_mark)
high_water_mark = vertical_position;
spring_trap(next_trap->nm);
}
else if (vertical_position_traps_flag && vertical_position >= page_length)
begin_page();
else {
else
nl_reg_contents = vertical_position.to_units();
if (vertical_position > high_water_mark)
high_water_mark = vertical_position;
}
}
else {
else
nl_reg_contents = vertical_position.to_units();
if (vertical_position > high_water_mark)
high_water_mark = vertical_position;
}
}
void top_level_diversion::transparent_output(unsigned char c)
{
if (!first_page_begun && begin_page())
if (before_first_page && begin_page())
// This can only happen with the transparent() request.
fatal("sorry, I didn't manage to begin the first page in time: use an explicit .br request");
const char *s = asciify(c);
@ -401,7 +396,7 @@ void top_level_diversion::transparent_output(node * /*n*/)
void top_level_diversion::copy_file(const char *filename)
{
if (!first_page_begun && begin_page())
if (before_first_page && begin_page())
fatal("sorry, I didn't manage to begin the first page in time: use an explicit .br request");
the_output->copy_file(page_offset, vertical_position, filename);
}
@ -414,7 +409,7 @@ void top_level_diversion::space(vunits n, int forced)
else
no_space_mode = 0;
}
if (!first_page_begun) {
if (before_first_page) {
if (begin_page()) {
// This happens if there's a top of page trap, and the first-page
// transition is caused by `'sp'.
@ -429,8 +424,6 @@ void top_level_diversion::space(vunits n, int forced)
vertical_position = next_trap_pos;
nl_reg_contents = vertical_position.to_units();
truncated_space = y - vertical_position;
if (vertical_position > high_water_mark)
high_water_mark = vertical_position;
spring_trap(next_trap->nm);
}
else if (y < V0) {
@ -442,8 +435,6 @@ void top_level_diversion::space(vunits n, int forced)
else {
vertical_position = y;
nl_reg_contents = vertical_position.to_units();
if (vertical_position > high_water_mark)
high_water_mark = vertical_position;
}
}
@ -456,12 +447,14 @@ void top_level_diversion::add_trap(symbol nm, vunits pos)
{
trap *first_free_slot = 0;
for (trap **p = &page_trap_list; *p; p = &(*p)->next) {
if ((*p)->position == pos) {
if ((*p)->nm.is_null()) {
if (first_free_slot == 0)
first_free_slot = *p;
}
else if ((*p)->position == pos) {
(*p)->nm = nm;
return;
}
else if ((*p)->nm.is_null() && first_free_slot == 0)
first_free_slot = *p;
}
if (first_free_slot) {
first_free_slot->nm = nm;
@ -521,19 +514,25 @@ void end_diversions()
NO_RETURN void cleanup_and_exit(int exit_code)
{
if (the_output)
if (the_output) {
the_output->trailer(topdiv->get_page_length());
delete the_output;
}
exit(exit_code);
}
int exit_flag = 0;
// returns non-zero if it sprung a top of page trap
int top_level_diversion::begin_page()
{
if (exit_flag == 2 || (exit_flag == 1 && curenv->is_empty()))
cleanup_and_exit(0);
if (exit_started) {
if (page_count == last_page_count
? curenv->is_empty()
: (done_end_macro && (seen_last_page_ejector || began_page_in_end_macro)))
cleanup_and_exit(0);
if (!done_end_macro)
began_page_in_end_macro = 1;
}
if (!the_output)
init_output();
++page_count;
@ -541,6 +540,8 @@ int top_level_diversion::begin_page()
page_number = next_page_number;
have_next_page_number = 0;
}
else if (before_first_page == 1)
page_number = 1;
else
page_number++;
// spring the top of page trap if there is one
@ -548,9 +549,13 @@ int top_level_diversion::begin_page()
vertical_position = -vresolution;
trap *next_trap = find_next_trap(&next_trap_pos);
vertical_position = V0;
first_page_begun = 1;
high_water_mark = V0;
ejecting_page = 0;
the_output->begin_page(page_number, page_length);
// If before_first_page was 2, then the top of page transition was undone
// using eg .nr nl 0-1. See nl_reg::set_value.
if (before_first_page != 2)
the_output->begin_page(page_number, page_length);
before_first_page = 0;
nl_reg_contents = vertical_position.to_units();
if (vertical_position_traps_flag && next_trap != 0 && next_trap_pos == V0) {
truncated_space = V0;
@ -598,25 +603,20 @@ diversion::~diversion()
void page_offset()
{
hunits n;
if (!has_arg()) {
hunits temp = topdiv->page_offset;
topdiv->page_offset = topdiv->prev_page_offset;
topdiv->prev_page_offset = temp;
}
else if (get_hunits(&n, 'v', topdiv->page_offset)) {
topdiv->prev_page_offset = topdiv->page_offset;
topdiv->page_offset = n;
}
if (!has_arg() || !get_hunits(&n, 'v', topdiv->page_offset))
n = topdiv->prev_page_offset;
topdiv->prev_page_offset = topdiv->page_offset;
topdiv->page_offset = n;
skip_line();
}
void page_length()
{
vunits n;
if (!has_arg())
topdiv->set_page_length(11*units_per_inch);
else if (get_vunits(&n, 'v', topdiv->get_page_length()))
if (has_arg() && get_vunits(&n, 'v', topdiv->get_page_length()))
topdiv->set_page_length(n);
else
topdiv->set_page_length(11*units_per_inch);
skip_line();
}
@ -642,10 +642,15 @@ void begin_page()
while (!tok.newline() && !tok.eof())
tok.next();
if (curdiv == topdiv) {
if (!topdiv->first_page_begun) {
if (topdiv->no_space_mode && !got_arg) {
topdiv->begin_page();
if (topdiv->before_first_page) {
if (!break_flag) {
if (got_arg)
topdiv->set_next_page_number(n);
if (got_arg || !topdiv->no_space_mode)
topdiv->begin_page();
}
else if (topdiv->no_space_mode && !got_arg)
topdiv->begin_page();
else {
/* Given this
@ -712,23 +717,16 @@ void space_request()
postpone_traps();
if (break_flag)
curenv->do_break();
int err = 0;
vunits n;
if (!has_arg())
if (!has_arg() || !get_vunits(&n, 'v'))
n = curenv->get_vertical_spacing();
else if (!get_vunits(&n, 'v'))
err = 1;
while (!tok.newline() && !tok.eof())
tok.next();
if (!unpostpone_traps()) {
if (!err)
curdiv->space(n);
}
else {
if (!unpostpone_traps())
curdiv->space(n);
else
// The line might have had line spacing that was truncated.
if (!err)
truncated_space += n;
}
truncated_space += n;
tok.next();
}
@ -746,16 +744,12 @@ BEGIN_TRAP token is not skipped over. */
void need_space()
{
int err = 0;
vunits n;
if (!has_arg())
if (!has_arg() || !get_vunits(&n, 'v'))
n = curenv->get_vertical_spacing();
else if (!get_vunits(&n, 'v'))
err = 1;
while (!tok.newline() && !tok.eof())
tok.next();
if (!err)
curdiv->need(n);
curdiv->need(n);
tok.next();
}
@ -862,15 +856,18 @@ void mark()
symbol s = get_name();
if (s.is_null())
curdiv->marked_place = curdiv->get_vertical_position();
else if (curdiv == topdiv)
set_number_reg(s, nl_reg_contents);
else
set_number_reg(s, curdiv->get_vertical_position().to_units());
skip_line();
}
// This is truly bizarre. It is documented in the SQ manual.
void return_request()
{
vunits dist = V0;
// This is truly bizarre. It is documented in the SQ manual.
vunits dist = curdiv->marked_place - curdiv->get_vertical_position();
if (has_arg()) {
if (tok.ch() == '-') {
tok.next();
@ -880,12 +877,10 @@ void return_request()
}
else {
vunits x;
if (get_vunits(&x, 'v') && x >= V0)
dist = x - curdiv->get_vertical_position();
if (get_vunits(&x, 'v'))
dist = x >= V0 ? x - curdiv->get_vertical_position() : V0;
}
}
else
dist = curdiv->marked_place - curdiv->get_vertical_position();
if (dist < V0)
curdiv->space(dist);
skip_line();
@ -894,10 +889,10 @@ void return_request()
void vertical_position_traps()
{
int n;
if (!has_arg())
vertical_position_traps_flag = 1;
else if (get_integer(&n))
if (has_arg() && get_integer(&n))
vertical_position_traps_flag = (n != 0);
else
vertical_position_traps_flag = 1;
skip_line();
}
@ -943,7 +938,7 @@ public:
int vertical_position_reg::get_value(units *res)
{
if (curdiv == topdiv && !topdiv->first_page_begun)
if (curdiv == topdiv && topdiv->before_first_page)
*res = -1;
else
*res = curdiv->get_vertical_position().to_units();
@ -952,7 +947,7 @@ int vertical_position_reg::get_value(units *res)
const char *vertical_position_reg::get_string()
{
if (curdiv == topdiv && !topdiv->first_page_begun)
if (curdiv == topdiv && topdiv->before_first_page)
return "-1";
else
return itoa(curdiv->get_vertical_position().to_units());
@ -1060,6 +1055,30 @@ const char *constant_vunits_reg::get_string()
return itoa(p->to_units());
}
class nl_reg : public variable_reg {
public:
nl_reg();
void set_value(units);
};
nl_reg::nl_reg() : variable_reg(&nl_reg_contents)
{
}
void nl_reg::set_value(units n)
{
variable_reg::set_value(n);
// Setting nl to a negative value when the vertical position in
// the top-level diversion is 0 undoes the top of page transition,
// so that the header macro will be called as if the top of page
// transition hasn't happened. This is used by Larry Wall's
// wrapman program. Setting before_first_page to 2 rather than 1,
// tells top_level_diversion::begin_page not to call
// output_file::begin_page again.
if (n < 0 && topdiv->get_vertical_position() == V0)
topdiv->before_first_page = 2;
}
void init_div_requests()
{
init_request("wh", when_request);
@ -1092,7 +1111,7 @@ void init_div_requests()
number_reg_dictionary.define(".t", new distance_to_next_trap_reg);
number_reg_dictionary.define("dl", new variable_reg(&dl_reg_contents));
number_reg_dictionary.define("dn", new variable_reg(&dn_reg_contents));
number_reg_dictionary.define("nl", new variable_reg(&nl_reg_contents));
number_reg_dictionary.define("nl", new nl_reg);
number_reg_dictionary.define(".vpt",
new constant_int_reg(&vertical_position_traps_flag));
number_reg_dictionary.define("%", new page_number_reg);

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,7 +15,7 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
class diversion {
@ -82,6 +82,7 @@ struct output_file;
class top_level_diversion : public diversion {
int page_number;
int page_count;
int last_page_count;
vunits page_length;
hunits prev_page_offset;
hunits page_offset;
@ -91,7 +92,7 @@ class top_level_diversion : public diversion {
int next_page_number;
int ejecting_page; // Is the current page being ejected?
public:
int first_page_begun;
int before_first_page;
int no_space_mode;
top_level_diversion();
void output(node *nd, int retain_size, vunits vs, int ls, hunits width);
@ -122,11 +123,16 @@ public:
friend void page_offset();
void set_diversion_trap(symbol, vunits);
void clear_diversion_trap();
void set_last_page() { last_page_count = page_count; }
};
extern top_level_diversion *topdiv;
extern diversion *curdiv;
extern int exit_started;
extern int done_end_macro;
extern int seen_last_page_ejector;
void spring_trap(symbol); // implemented by input.c
extern int trap_sprung_flag;
void postpone_traps();

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,7 +15,7 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
struct size_range {
@ -62,6 +62,13 @@ inline int font_size::to_points()
return p/sizescale;
}
struct environment;
hunits env_digit_width(environment *);
hunits env_space_width(environment *);
hunits env_sentence_space_width(environment *);
hunits env_narrow_space_width(environment *);
hunits env_half_narrow_space_width(environment *);
struct tab;
@ -82,6 +89,9 @@ public:
const char *to_string();
};
const unsigned MARGIN_CHARACTER_ON = 1;
const unsigned MARGIN_CHARACTER_NEXT = 2;
struct charinfo;
struct node;
struct breakpoint;
@ -147,6 +157,7 @@ class environment {
int tab_precedes_field;
int discarding;
int spread_flag; // set by \p
unsigned margin_character_flags;
node *margin_character_node;
hunits margin_character_distance;
node *numbering_nodes;
@ -160,6 +171,7 @@ class environment {
int hyphen_line_max;
hunits hyphenation_space;
hunits hyphenation_margin;
int composite; // used for construction of composite char?
pending_output_line *pending_lines;
#ifdef WIDOW_CONTROL
int widow_control;
@ -179,6 +191,7 @@ class environment {
void hyphenate_line();
void start_field();
void wrap_up_field();
void add_padding();
node *make_tab_node(hunits d, node *next = 0);
node *get_prev_char();
public:
@ -192,6 +205,8 @@ public:
~environment();
int is_dummy() { return dummy; }
int is_empty();
int is_composite() { return composite; }
void set_composite() { composite = 1; }
vunits get_vertical_spacing(); // .v
int get_line_spacing(); // .L
int get_point_size() { return size.to_scaled_points(); }
@ -218,11 +233,12 @@ public:
vunits get_prev_char_depth();
hunits get_text_length(); // .k
hunits get_prev_text_length(); // .n
hunits get_space_width();
int get_space_size(); // in ems/36
int get_sentence_space_size();
hunits get_narrow_space_width();
hunits get_half_narrow_space_width();
hunits get_space_width() { return env_space_width(this); }
int get_space_size() { return space_size; } // in ems/36
int get_sentence_space_size() { return sentence_space_size; }
hunits get_narrow_space_width() { return env_narrow_space_width(this); }
hunits get_half_narrow_space_width()
{ return env_half_narrow_space_width(this); }
hunits get_input_line_position();
const char *get_tabs();
int get_hyphenation_flags();
@ -247,6 +263,7 @@ public:
void interrupt();
void spread() { spread_flag = 1; }
void do_break(); // .br
void final_break();
void newline();
void handle_tab(int is_leader = 0); // do a tab or leader
void add_node(node *);
@ -307,3 +324,4 @@ void read_hyphen_file(const char *name);
extern int break_flag;
extern symbol default_family;
extern int translate_space_to_dummy;

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,7 +15,7 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
@ -28,21 +28,21 @@ public:
int is_zero();
vunits& operator+=(const vunits&);
vunits& operator-=(const vunits&);
friend vunits scale(vunits n, units x, units y); // scale n by x/y
friend vunits scale(vunits n, vunits x, vunits y);
friend vunits operator +(const vunits&, const vunits&);
friend vunits operator -(const vunits&, const vunits&);
friend vunits operator -(const vunits&);
friend int operator /(const vunits&, const vunits&);
friend vunits operator /(const vunits&, int);
friend vunits operator *(const vunits&, int);
friend vunits operator *(int, const vunits&);
friend int operator <(const vunits&, const vunits&);
friend int operator >(const vunits&, const vunits&);
friend int operator <=(const vunits&, const vunits&);
friend int operator >=(const vunits&, const vunits&);
friend int operator ==(const vunits&, const vunits&);
friend int operator !=(const vunits&, const vunits&);
friend inline vunits scale(vunits n, units x, units y); // scale n by x/y
friend inline vunits scale(vunits n, vunits x, vunits y);
friend inline vunits operator +(const vunits&, const vunits&);
friend inline vunits operator -(const vunits&, const vunits&);
friend inline vunits operator -(const vunits&);
friend inline int operator /(const vunits&, const vunits&);
friend inline vunits operator /(const vunits&, int);
friend inline vunits operator *(const vunits&, int);
friend inline vunits operator *(int, const vunits&);
friend inline int operator <(const vunits&, const vunits&);
friend inline int operator >(const vunits&, const vunits&);
friend inline int operator <=(const vunits&, const vunits&);
friend inline int operator >=(const vunits&, const vunits&);
friend inline int operator ==(const vunits&, const vunits&);
friend inline int operator !=(const vunits&, const vunits&);
};
extern vunits V0;
@ -57,21 +57,21 @@ public:
int is_zero();
hunits& operator+=(const hunits&);
hunits& operator-=(const hunits&);
friend hunits scale(hunits n, units x, units y); // scale n by x/y
friend hunits scale(hunits n, double x);
friend hunits operator +(const hunits&, const hunits&);
friend hunits operator -(const hunits&, const hunits&);
friend hunits operator -(const hunits&);
friend int operator /(const hunits&, const hunits&);
friend hunits operator /(const hunits&, int);
friend hunits operator *(const hunits&, int);
friend hunits operator *(int, const hunits&);
friend int operator <(const hunits&, const hunits&);
friend int operator >(const hunits&, const hunits&);
friend int operator <=(const hunits&, const hunits&);
friend int operator >=(const hunits&, const hunits&);
friend int operator ==(const hunits&, const hunits&);
friend int operator !=(const hunits&, const hunits&);
friend inline hunits scale(hunits n, units x, units y); // scale n by x/y
friend inline hunits scale(hunits n, double x);
friend inline hunits operator +(const hunits&, const hunits&);
friend inline hunits operator -(const hunits&, const hunits&);
friend inline hunits operator -(const hunits&);
friend inline int operator /(const hunits&, const hunits&);
friend inline hunits operator /(const hunits&, int);
friend inline hunits operator *(const hunits&, int);
friend inline hunits operator *(int, const hunits&);
friend inline int operator <(const hunits&, const hunits&);
friend inline int operator >(const hunits&, const hunits&);
friend inline int operator <=(const hunits&, const hunits&);
friend inline int operator >=(const hunits&, const hunits&);
friend inline int operator ==(const hunits&, const hunits&);
friend inline int operator !=(const hunits&, const hunits&);
};
extern hunits H0;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,10 +15,10 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "groff.h"
#include "troff.h"
#include "symbol.h"
#include "dictionary.h"
#include "hvunits.h"
@ -30,8 +30,13 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "font.h"
#include "reg.h"
#define STORE_WIDTH 1
symbol HYPHEN_SYMBOL("hy");
// Character used when a hyphen is inserted at a line break.
static charinfo *soft_hyphen_char;
enum constant_space_type {
CONSTANT_SPACE_NONE,
CONSTANT_SPACE_RELATIVE,
@ -104,7 +109,7 @@ public:
int is_named(symbol);
symbol get_name();
tfont *get_tfont(font_size, int, int, int);
hunits get_space_width(font_size);
hunits get_space_width(font_size, int);
hunits get_narrow_space_width(font_size);
hunits get_half_narrow_space_width(font_size);
int get_bold(hunits *);
@ -343,9 +348,16 @@ symbol font_info::get_name()
return internal_name;
}
hunits font_info::get_space_width(font_size fs)
hunits font_info::get_space_width(font_size fs, int space_size)
{
return hunits(fm->get_space_width(fs.to_scaled_points()));
if (is_constant_spaced == CONSTANT_SPACE_NONE)
return scale(hunits(fm->get_space_width(fs.to_scaled_points())),
space_size, 12);
else if (is_constant_spaced == CONSTANT_SPACE_ABSOLUTE)
return constant_space;
else
return scale(constant_space*fs.to_scaled_points(),
units_per_inch, 36*72*sizescale);
}
hunits font_info::get_narrow_space_width(font_size fs)
@ -680,8 +692,8 @@ class troff_output_file : public real_output_file {
char tbuf[TBUF_SIZE];
int tbuf_len;
int tbuf_kern;
int begun_page;
void do_motion();
vunits page_length;
void put(char c);
void put(unsigned char c);
void put(int i);
@ -691,6 +703,7 @@ class troff_output_file : public real_output_file {
public:
troff_output_file();
~troff_output_file();
void trailer(vunits page_length);
void put_char(charinfo *ci, tfont *tf);
void put_char_width(charinfo *ci, tfont *tf, hunits w, hunits k);
void right(hunits);
@ -867,10 +880,9 @@ void troff_output_file::put_char_width(charinfo *ci, tfont *tf, hunits w,
if (c == '\0') {
flush_tbuf();
do_motion();
int n = ci->get_number();
if (n >= 0) {
if (ci->numbered()) {
put('N');
put(n);
put(ci->get_number());
}
else {
put('C');
@ -927,10 +939,9 @@ void troff_output_file::put_char(charinfo *ci, tfont *tf)
char c = ci->get_ascii_code();
if (c == '\0') {
do_motion();
int n = ci->get_number();
if (n >= 0) {
if (ci->numbered()) {
put('N');
put(n);
put(ci->get_number());
}
else {
put('C');
@ -982,7 +993,7 @@ void troff_output_file::set_font(tfont *tf)
font_position = new symbol[nfont_positions];
memcpy(font_position, old_font_position,
old_nfont_positions*sizeof(symbol));
delete old_font_position;
a_delete old_font_position;
}
font_position[n] = nm;
}
@ -1054,15 +1065,18 @@ void troff_output_file::draw(char code, hvpair *point, int npoints,
put('\n');
}
void troff_output_file::really_begin_page(int pageno, vunits pl)
void troff_output_file::really_begin_page(int pageno, vunits page_length)
{
flush_tbuf();
if (page_length > V0) {
put('V');
put(page_length.to_units());
put('\n');
if (begun_page) {
if (page_length > V0) {
put('V');
put(page_length.to_units());
put('\n');
}
}
page_length = pl;
else
begun_page = 1;
current_tfont = 0;
current_font_number = -1;
current_size = 0;
@ -1085,6 +1099,7 @@ void troff_output_file::really_copy_file(hunits x, vunits y, const char *filenam
moveto(x, y);
flush_tbuf();
do_motion();
errno = 0;
FILE *ifp = fopen(filename, "r");
if (ifp == 0)
error("can't open `%1': %2", filename, strerror(errno));
@ -1108,6 +1123,11 @@ void troff_output_file::really_transparent_char(unsigned char c)
}
troff_output_file::~troff_output_file()
{
a_delete font_position;
}
void troff_output_file::trailer(vunits page_length)
{
flush_tbuf();
if (page_length > V0) {
@ -1117,11 +1137,11 @@ troff_output_file::~troff_output_file()
put('\n');
}
put("x stop\n");
delete font_position;
}
troff_output_file::troff_output_file()
: current_height(0), current_slant(0), tbuf_len(0), nfont_positions(10)
: current_height(0), current_slant(0), tbuf_len(0), nfont_positions(10),
begun_page(0)
{
font_position = new symbol[nfont_positions];
put("x T ");
@ -1149,6 +1169,10 @@ output_file::~output_file()
{
}
void output_file::trailer(vunits)
{
}
real_output_file::real_output_file()
: printing(0)
{
@ -1272,11 +1296,11 @@ void suppress_output_file::really_print_line(hunits, vunits, node *, vunits, vun
{
}
void suppress_output_file::really_begin_page(int pageno, vunits page_length)
void suppress_output_file::really_begin_page(int, vunits)
{
}
void suppress_output_file::really_transparent_char(unsigned char c)
void suppress_output_file::really_transparent_char(unsigned char)
{
}
@ -1717,14 +1741,13 @@ hunits kern_pair_node::subscript_correction()
node *kern_pair_node::add_discretionary_hyphen()
{
charinfo *hci = get_charinfo(HYPHEN_SYMBOL);
tfont *tf = n2->get_tfont();
if (tf) {
if (tf->contains(hci)) {
if (tf->contains(soft_hyphen_char)) {
node *next1 = next;
next = 0;
node *n = copy();
glyph_node *gn = new glyph_node(hci, tf);
glyph_node *gn = new glyph_node(soft_hyphen_char, tf);
node *nn = n->merge_glyph_node(gn);
if (nn == 0) {
gn->next = n;
@ -1852,12 +1875,11 @@ node *node::add_discretionary_hyphen()
tfont *tf = get_tfont();
if (!tf)
return new hyphen_inhibitor_node(this);
charinfo *hci = get_charinfo(HYPHEN_SYMBOL);
if (tf->contains(hci)) {
if (tf->contains(soft_hyphen_char)) {
node *next1 = next;
next = 0;
node *n = copy();
glyph_node *gn = new glyph_node(hci, tf);
glyph_node *gn = new glyph_node(soft_hyphen_char, tf);
node *n1 = n->merge_glyph_node(gn);
if (n1 == 0) {
gn->next = n;
@ -2702,7 +2724,7 @@ void kern_pair_node::ascii_print(ascii_output_file *ascii)
}
void node::ascii_print(ascii_output_file *ascii)
void node::ascii_print(ascii_output_file *)
{
}
@ -2773,17 +2795,6 @@ void ligature_node::asciify(macro *m)
delete this;
}
void composite_node::asciify(macro *m)
{
unsigned char c = ci->get_ascii_code();
if (c != 0) {
m->append(c);
delete this;
}
else
m->append(this);
}
void break_char_node::asciify(macro *m)
{
ch->asciify(m);
@ -3043,8 +3054,34 @@ void special_node::tprint_end(troff_output_file *out)
/* composite_node */
composite_node::composite_node(node *p, charinfo *c, font_size s, node *x)
: node(x), n(p), ci(c), sz(s)
class composite_node : public node {
charinfo *ci;
node *n;
tfont *tf;
public:
composite_node(node *, charinfo *, tfont *, node * = 0);
~composite_node();
node *copy();
hunits width();
node *last_char_node();
units size();
void tprint(troff_output_file *);
hyphenation_type get_hyphenation_type();
int overlaps_horizontally();
int overlaps_vertically();
void ascii_print(ascii_output_file *);
void asciify(macro *);
hyphen_list *get_hyphen_list(hyphen_list *tail);
node *add_self(node *, hyphen_list **);
tfont *get_tfont();
int same(node *);
const char *type();
void vertical_extent(vunits *, vunits *);
vunits vertical_width();
};
composite_node::composite_node(node *p, charinfo *c, tfont *t, node *x)
: node(x), n(p), ci(c), tf(t)
{
}
@ -3055,14 +3092,21 @@ composite_node::~composite_node()
node *composite_node::copy()
{
return new composite_node(copy_node_list(n), ci, sz);
return new composite_node(copy_node_list(n), ci, tf);
}
hunits composite_node::width()
{
hunits x = H0;
hunits x;
if (tf->get_constant_space(&x))
return x;
x = H0;
for (node *tem = n; tem; tem = tem->next)
x += tem->width();
hunits offset;
if (tf->get_bold(&offset))
x += offset;
x += tf->get_track_kern();
return x;
}
@ -3081,7 +3125,7 @@ vunits composite_node::vertical_width()
units composite_node::size()
{
return sz.to_units();
return tf->get_size().to_units();
}
hyphenation_type composite_node::get_hyphenation_type()
@ -3099,6 +3143,17 @@ int composite_node::overlaps_vertically()
return ci->overlaps_vertically();
}
void composite_node::asciify(macro *m)
{
unsigned char c = ci->get_ascii_code();
if (c != 0) {
m->append(c);
delete this;
}
else
m->append(this);
}
void composite_node::ascii_print(ascii_output_file *ascii)
{
unsigned char c = ci->get_ascii_code();
@ -3130,10 +3185,7 @@ node *composite_node::add_self(node *nn, hyphen_list **p)
tfont *composite_node::get_tfont()
{
if (n)
return n->get_tfont();
else
return 0;
return tf;
}
node *reverse_node_list(node *n)
@ -3175,6 +3227,41 @@ void word_space_node::tprint(troff_output_file *out)
space_node::tprint(out);
}
unbreakable_space_node::unbreakable_space_node(hunits d, node *x)
: word_space_node(d, x)
{
}
unbreakable_space_node::unbreakable_space_node(hunits d, int s, node *x)
: word_space_node(d, s, x)
{
}
node *unbreakable_space_node::copy()
{
return new unbreakable_space_node(n, set);
}
breakpoint *unbreakable_space_node::get_breakpoints(hunits, int,
breakpoint *rest, int)
{
return rest;
}
int unbreakable_space_node::nbreaks()
{
return 0;
}
void unbreakable_space_node::split(int, node **, node **)
{
assert(0);
}
int unbreakable_space_node::merge_space(hunits)
{
return 0;
}
hvpair::hvpair()
{
@ -3207,7 +3294,7 @@ const char *draw_node::type()
draw_node::~draw_node()
{
if (point)
delete point;
a_delete point;
}
hunits draw_node::width()
@ -3436,7 +3523,7 @@ void bracket_node::tprint(troff_output_file *out)
++npieces;
vunits h = list->size();
vunits totalh = h*npieces;
vunits y = (totalh + h)/2;
vunits y = (totalh - h)/2;
out->down(y);
for (tem = list; tem; tem = tem->next) {
tem->zero_width_tprint(out);
@ -3446,7 +3533,7 @@ void bracket_node::tprint(troff_output_file *out)
out->down(totalh - y);
}
void node::tprint(troff_output_file *out)
void node::tprint(troff_output_file *)
{
}
@ -3495,7 +3582,53 @@ void dbreak_node::tprint(troff_output_file *out)
void composite_node::tprint(troff_output_file *out)
{
hunits bold_offset;
int is_bold = tf->get_bold(&bold_offset);
hunits track_kern = tf->get_track_kern();
hunits constant_space;
int is_constant_spaced = tf->get_constant_space(&constant_space);
hunits x = H0;
if (is_constant_spaced) {
x = constant_space;
for (node *tem = n; tem; tem = tem->next)
x -= tem->width();
if (is_bold)
x -= bold_offset;
hunits x2 = x/2;
out->right(x2);
x -= x2;
}
if (is_bold) {
int hpos = out->get_hpos();
int vpos = out->get_vpos();
tprint_reverse_node_list(out, n);
out->moveto(hpos, vpos);
out->right(bold_offset);
}
tprint_reverse_node_list(out, n);
if (is_constant_spaced)
out->right(x);
else
out->right(track_kern);
}
node *make_composite_node(charinfo *s, environment *env)
{
int fontno = env_definite_font(env);
if (fontno < 0) {
error("no current font");
return 0;
}
assert(fontno < font_table_size && font_table[fontno] != 0);
node *n = charinfo_to_node_list(s, env);
font_size fs = env->get_font_size();
int char_height = env->get_char_height();
int char_slant = env->get_char_slant();
tfont *tf = font_table[fontno]->get_tfont(fs, char_height, char_slant,
fontno);
if (env->is_composite())
tf = tf->get_plain();
return new composite_node(n, s, tf);
}
node *make_glyph_node(charinfo *s, environment *env, int no_error_message = 0)
@ -3565,6 +3698,8 @@ node *make_glyph_node(charinfo *s, environment *env, int no_error_message = 0)
int char_height = env->get_char_height();
int char_slant = env->get_char_slant();
tfont *tf = font_table[fontno]->get_tfont(fs, char_height, char_slant, fn);
if (env->is_composite())
tf = tf->get_plain();
return new glyph_node(s, tf);
}
@ -3575,13 +3710,16 @@ node *make_node(charinfo *ci, environment *env)
return new space_char_hmotion_node(env->get_space_width());
case charinfo::TRANSLATE_DUMMY:
return new dummy_node;
case charinfo::TRANSLATE_HYPHEN_INDICATOR:
error("translation to \\% ignored in this context");
break;
}
charinfo *tem = ci->get_translation();
if (tem)
ci = tem;
macro *mac = ci->get_macro();
if (mac)
return charinfo_to_node(ci, env);
return make_composite_node(ci, env);
else
return make_glyph_node(ci, env);
}
@ -3613,13 +3751,15 @@ node *node::add_char(charinfo *ci, environment *env, hunits *widthp)
return res;
case charinfo::TRANSLATE_DUMMY:
return new dummy_node(this);
case charinfo::TRANSLATE_HYPHEN_INDICATOR:
return add_discretionary_hyphen();
}
charinfo *tem = ci->get_translation();
if (tem)
ci = tem;
macro *mac = ci->get_macro();
if (mac) {
res = charinfo_to_node(ci, env);
res = make_composite_node(ci, env);
if (res) {
res->next = this;
*widthp += res->width();
@ -4069,6 +4209,17 @@ const char *word_space_node::type()
return "word_space_node";
}
int unbreakable_space_node::same(node *nd)
{
return (n == ((unbreakable_space_node *)nd)->n
&& set == ((unbreakable_space_node *)nd)->set);
}
const char *unbreakable_space_node::type()
{
return "unbreakable_space_node";
}
int diverted_space_node::same(node *nd)
{
return n == ((diverted_space_node *)nd)->n;
@ -4103,6 +4254,7 @@ static void grow_font_table(int n)
if (old_font_table_size)
memcpy(font_table, old_font_table,
old_font_table_size*sizeof(font_info *));
a_delete old_font_table;
for (int i = old_font_table_size; i < font_table_size; i++)
font_table[i] = 0;
}
@ -4126,15 +4278,20 @@ static int mount_font_no_translate(int n, symbol name, symbol external_name)
font *fm = 0;
void *p = font_dictionary.lookup(external_name);
if (p == 0) {
fm = font::load_font(external_name.contents());
int not_found;
fm = font::load_font(external_name.contents(), &not_found);
if (!fm) {
if (not_found)
warning(WARN_FONT, "can't find font `%1'", external_name.contents());
font_dictionary.lookup(external_name, &a_char);
return 0;
}
font_dictionary.lookup(name, fm);
}
else if (p == &a_char) {
#if 0
error("invalid font `%1'", external_name.contents());
#endif
return 0;
}
else
@ -4222,7 +4379,7 @@ font_family::font_family(symbol s)
font_family::~font_family()
{
delete map;
a_delete map;
}
int font_family::make_definite(int i)
@ -4241,7 +4398,7 @@ int font_family::make_definite(int i)
map_size = i + 10;
map = new int[map_size];
memcpy(map, old_map, old_map_size*sizeof(int));
delete old_map;
a_delete old_map;
for (int j = old_map_size; j < map_size; j++)
map[j] = -1;
}
@ -4444,11 +4601,20 @@ hunits env_space_width(environment *env)
int fn = env_definite_font(env);
font_size fs = env->get_font_size();
if (fn < 0 || fn >= font_table_size || font_table[fn] == 0)
return fs.to_units()/3;
return scale(fs.to_units()/3, env->get_space_size(), 12);
else
return font_table[fn]->get_space_width(fs);
return font_table[fn]->get_space_width(fs, env->get_space_size());
}
hunits env_sentence_space_width(environment *env)
{
int fn = env_definite_font(env);
font_size fs = env->get_font_size();
if (fn < 0 || fn >= font_table_size || font_table[fn] == 0)
return scale(fs.to_units()/3, env->get_sentence_space_size(), 12);
else
return font_table[fn]->get_space_width(fs, env->get_sentence_space_size());
}
hunits env_half_narrow_space_width(environment *env)
{
@ -4478,27 +4644,19 @@ void bold_font()
if (tok.delimiter()) {
int f = get_fontno();
if (f >= 0) {
if (has_arg()) {
units offset;
if (get_number(&offset, 'u')) {
if (offset >= 1)
font_table[f]->set_conditional_bold(n, hunits(offset - 1));
else
font_table[f]->conditional_unbold(n);
}
}
units offset;
if (has_arg() && get_number(&offset, 'u') && offset >= 1)
font_table[f]->set_conditional_bold(n, hunits(offset - 1));
else
font_table[f]->conditional_unbold(n);
}
}
else {
units offset;
if (get_number(&offset, 'u')) {
if (offset >= 1)
font_table[n]->set_bold(hunits(offset - 1));
else
font_table[n]->unbold();
}
if (get_number(&offset, 'u') && offset >= 1)
font_table[n]->set_bold(hunits(offset - 1));
else
font_table[n]->unbold();
}
}
else
@ -4564,18 +4722,15 @@ void track_kern()
{
int n = get_fontno();
if (n >= 0) {
if (has_arg()) {
int min_s, max_s;
hunits min_a, max_a;
if (!get_number(&min_s, 'z')
|| !get_hunits(&min_a, 'p')
|| !get_number(&max_s, 'z')
|| !get_hunits(&max_a, 'p'))
error("bad arguments for track kerning");
else {
track_kerning_function tk(min_s, min_a, max_s, max_a);
font_table[n]->set_track_kern(tk);
}
int min_s, max_s;
hunits min_a, max_a;
if (has_arg()
&& get_number(&min_s, 'z')
&& get_hunits(&min_a, 'p')
&& get_number(&max_s, 'z')
&& get_hunits(&max_a, 'p')) {
track_kerning_function tk(min_s, min_a, max_s, max_a);
font_table[n]->set_track_kern(tk);
}
else {
track_kerning_function tk;
@ -4587,15 +4742,15 @@ void track_kern()
void constant_space()
{
int x, y;
int n = get_fontno();
if (n >= 0) {
if (!has_arg())
int x, y;
if (!has_arg() || !get_integer(&x))
font_table[n]->set_constant_space(CONSTANT_SPACE_NONE);
else if (get_integer(&x)) {
if (!has_arg())
else {
if (!has_arg() || !get_number(&y, 'z'))
font_table[n]->set_constant_space(CONSTANT_SPACE_RELATIVE, x);
else if (get_number(&y, 'z'))
else
font_table[n]->set_constant_space(CONSTANT_SPACE_ABSOLUTE,
scale(y*x,
units_per_inch,
@ -4607,14 +4762,9 @@ void constant_space()
void ligature()
{
if (has_arg()) {
int lig;
if (get_integer(&lig)) {
if (lig > 2 || lig < 0)
lig = 1;
global_ligature_mode = lig;
}
}
int lig;
if (has_arg() && get_integer(&lig) && lig >= 0 && lig <= 2)
global_ligature_mode = lig;
else
global_ligature_mode = 1;
skip_line();
@ -4622,16 +4772,22 @@ void ligature()
void kern_request()
{
if (has_arg()) {
int k;
if (get_integer(&k))
global_kern_mode = k != 0;
}
int k;
if (has_arg() && get_integer(&k))
global_kern_mode = k != 0;
else
global_kern_mode = 1;
skip_line();
}
void set_soft_hyphen_char()
{
soft_hyphen_char = get_optional_char();
if (!soft_hyphen_char)
soft_hyphen_char = get_charinfo(HYPHEN_SYMBOL);
skip_line();
}
void init_output()
{
if (suppress_output_flag)
@ -4678,11 +4834,12 @@ void init_node_requests()
init_request("special", special_request);
init_request("fspecial", font_special_request);
init_request("ftr", font_translate);
init_request("shc", set_soft_hyphen_char);
number_reg_dictionary.define(".fp", new next_available_font_position_reg);
number_reg_dictionary.define(".kern",
new constant_int_reg(&global_kern_mode));
number_reg_dictionary.define(".lg",
new constant_int_reg(&global_ligature_mode));
number_reg_dictionary.define(".P", new printing_reg);
soft_hyphen_char = get_charinfo(HYPHEN_SYMBOL);
}

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,7 +15,7 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
@ -170,6 +170,7 @@ public:
};
class word_space_node : public space_node {
protected:
word_space_node(hunits, int, node * = 0);
public:
word_space_node(hunits, node * = 0);
@ -179,7 +180,20 @@ public:
const char *type();
};
class unbreakable_space_node : public word_space_node {
unbreakable_space_node(hunits, int, node * = 0);
public:
unbreakable_space_node(hunits, node * = 0);
node *copy();
int same(node *);
const char *type();
breakpoint *get_breakpoints(hunits width, int nspaces, breakpoint *rest = 0,
int is_inner = 0);
int nbreaks();
void split(int, node **, node **);
int merge_space(hunits);
};
class diverted_space_node : public node {
public:
vunits n;
@ -389,33 +403,6 @@ public:
const char *type();
};
class charinfo;
class composite_node : public node {
charinfo *ci;
node *n;
font_size sz;
public:
composite_node(node *, charinfo *, font_size, node * = 0);
~composite_node();
node *copy();
hunits width();
node *last_char_node();
units size();
void tprint(troff_output_file *);
hyphenation_type get_hyphenation_type();
int overlaps_horizontally();
int overlaps_vertically();
void ascii_print(ascii_output_file *);
void asciify(macro *);
hyphen_list *get_hyphen_list(hyphen_list *tail);
node *add_self(node *, hyphen_list **);
tfont *get_tfont();
int same(node *);
const char *type();
void vertical_extent(vunits *, vunits *);
vunits vertical_width();
};
struct hvpair {
hunits h;
@ -440,6 +427,7 @@ public:
const char *type();
};
class charinfo;
node *make_node(charinfo *ci, environment *);
int character_exists(charinfo *, environment *);
@ -448,10 +436,6 @@ node *reverse_node_list(node *n);
void delete_node_list(node *);
node *copy_node_list(node *);
hunits env_digit_width(environment *);
hunits env_space_width(environment *);
hunits env_narrow_space_width(environment *);
hunits env_half_narrow_space_width(environment *);
int get_bold_fontno(int f);
inline hyphen_list::hyphen_list(unsigned char code, hyphen_list *p)
@ -473,6 +457,7 @@ class output_file {
public:
output_file();
virtual ~output_file();
virtual void trailer(vunits page_length);
virtual void flush() = 0;
virtual void transparent_char(unsigned char) = 0;
virtual void print_line(hunits x, vunits y, node *n,

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,11 +15,11 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "groff.h"
#include "troff.h"
#include "symbol.h"
#include "hvunits.h"
#include "env.h"
@ -388,10 +388,6 @@ static int parse_term(units *v, int scale_indicator, int parenthesised)
tok.next();
negative = !negative;
}
else if (tok.is_size()) {
tok.process();
tok.next();
}
else
break;
unsigned char c = tok.ch();
@ -402,12 +398,21 @@ static int parse_term(units *v, int scale_indicator, int parenthesised)
tok.next();
if (!parse_term(v, scale_indicator, parenthesised))
return 0;
int tem = (scale_indicator == 'v'
? curdiv->get_vertical_position().to_units()
: curenv->get_input_line_position().to_units());
if (*v < INT_MIN + tem) {
error("numeric overflow");
return 0;
int tem;
tem = (scale_indicator == 'v'
? curdiv->get_vertical_position().to_units()
: curenv->get_input_line_position().to_units());
if (tem >= 0) {
if (*v < INT_MIN + tem) {
error("numeric overflow");
return 0;
}
}
else {
if (*v > INT_MAX + tem) {
error("numeric overflow");
return 0;
}
}
*v -= tem;
if (negative) {
@ -434,7 +439,8 @@ static int parse_term(units *v, int scale_indicator, int parenthesised)
scale_indicator = c;
}
else {
error("expected `;' after scale-indicator");
error("expected `;' after scale-indicator (got %1)",
tok.description());
return 0;
}
}
@ -446,7 +452,7 @@ static int parse_term(units *v, int scale_indicator, int parenthesised)
return 0;
tok.skip();
if (tok.ch() != ')') {
warning(WARN_SYNTAX, "missing ')'");
warning(WARN_SYNTAX, "missing `)' (got %1)", tok.description());
}
else
tok.next();
@ -478,7 +484,7 @@ static int parse_term(units *v, int scale_indicator, int parenthesised)
return 0;
}
*v *= 10;
if (*v > INT_MAX - (c - '0')) {
if (*v > INT_MAX - (int(c) - '0')) {
error("numeric overflow");
return 0;
}
@ -520,6 +526,7 @@ static int parse_term(units *v, int scale_indicator, int parenthesised)
}
}
int si = scale_indicator;
int do_next = 0;
if ((c = tok.ch()) != 0 && strchr(SCALE_INDICATOR_CHARS, c) != 0) {
switch (scale_indicator) {
case 'z':
@ -544,7 +551,9 @@ static int parse_term(units *v, int scale_indicator, int parenthesised)
si = c;
break;
}
tok.next();
// Don't do tok.next() here because the next token might be \s, which
// would affect the interpretation of m.
do_next = 1;
}
switch (si) {
case 'i':
@ -600,10 +609,8 @@ static int parse_term(units *v, int scale_indicator, int parenthesised)
default:
assert(0);
}
if (tok.is_size()) {
tok.process();
if (do_next)
tok.next();
}
if (negative) {
if (*v == INT_MIN) {
error("numeric overflow");

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,10 +15,10 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "groff.h"
#include "troff.h"
#include "symbol.h"
#include "dictionary.h"
#include "token.h"
@ -294,15 +294,15 @@ void define_number_reg()
return;
}
reg *r = (reg *)number_reg_dictionary.lookup(nm);
if (r == 0) {
r = new number_reg;
number_reg_dictionary.define(nm, r);
}
units v;
units prev_value;
if (!r->get_value(&prev_value))
if (!r || !r->get_value(&prev_value))
prev_value = 0;
if (get_number(&v, 'u', prev_value)) {
if (r == 0) {
r = new number_reg;
number_reg_dictionary.define(nm, r);
}
r->set_value(v);
if (tok.space() && has_arg() && get_number(&v, 'u'))
r->set_increment(v);

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,7 +15,7 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,7 +15,7 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
typedef void (*REQUEST_FUNCP)();
@ -58,6 +58,7 @@ public:
void invoke(symbol);
macro *to_macro();
void print_size();
int empty();
friend class string_iterator;
friend void chop_macro();
friend int operator==(const macro &, const macro &);
@ -76,4 +77,4 @@ extern int no_break_flag; // indicates whether request was invoked with . or '
class charinfo;
class environment;
node *charinfo_to_node(charinfo *, const environment *);
node *charinfo_to_node_list(charinfo *, const environment *);

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,11 +15,11 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "groff.h"
#include "troff.h"
#include "symbol.h"
const char **symbol::table = 0;
@ -30,6 +30,10 @@ int symbol::block_size = 0;
const symbol NULL_SYMBOL;
#ifdef BLOCK_SIZE
#undef BLOCK_SIZE
#endif
const int BLOCK_SIZE = 1024;
// the table will increase in size as necessary
// the size will be chosen from the following array
@ -72,7 +76,7 @@ symbol::symbol(const char *p, int how)
}
if (table == 0) {
table_size = table_sizes[0];
table = new char*[table_size];
table = (const char **)new char*[table_size];
for (int i = 0; i < table_size; i++)
table[i] = 0;
table_used = 0;
@ -97,7 +101,7 @@ symbol::symbol(const char *p, int how)
fatal("too many symbols");
table_size = table_sizes[i];
table_used = 0;
table = new char*[table_size];
table = (const char **)new char*[table_size];
for (i = 0; i < table_size; i++)
table[i] = 0;
for (pp = old_table + old_table_size - 1;
@ -105,7 +109,7 @@ symbol::symbol(const char *p, int how)
--pp) {
symbol temp(*pp, 1); /* insert it into the new table */
}
delete old_table;
a_delete old_table;
for (pp = table + hc % table_size;
*pp != 0;
(pp == table ? pp = table + table_size - 1 : --pp))
@ -134,7 +138,7 @@ symbol concat(symbol s1, symbol s2)
strcpy(buf, s1.contents());
strcat(buf, s2.contents());
symbol res(buf);
delete buf;
a_delete buf;
return res;
}

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,7 +15,7 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define DONT_STORE 1
@ -31,7 +31,7 @@ class symbol {
public:
symbol(const char *p, int how = 0);
symbol();
int hash() const;
unsigned long hash() const;
operator ==(symbol) const;
operator !=(symbol) const;
const char *contents() const;
@ -55,12 +55,9 @@ inline int symbol::operator!=(symbol p) const
return s != p.s;
}
// guaranteed to return a positive integer
inline int symbol::hash() const
inline unsigned long symbol::hash() const
{
int i = int(s);
return i < 0 ? -i : i;
return (unsigned long)s;
}
inline const char *symbol::contents() const

View File

@ -1,12 +1,12 @@
// -*- C++ -*-
/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
/* 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 1, or (at your option) any later
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
@ -15,7 +15,7 @@ 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 LICENSE. If not, write to the Free Software
with groff; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
@ -36,14 +36,10 @@ class token {
TOKEN_BACKSPACE,
TOKEN_BEGIN_TRAP,
TOKEN_CHAR, // a normal printing character
TOKEN_CHAR_HEIGHT, // \H
TOKEN_CHAR_SLANT, // \S
TOKEN_DUMMY,
TOKEN_EMPTY, // this is the initial value
TOKEN_END_TRAP,
TOKEN_ESCAPE, // \e
TOKEN_FONT_NAME, // \f followed by a name
TOKEN_FONT_POSITION, // \f followed by a digit
TOKEN_HYPHEN_INDICATOR,
TOKEN_INTERRUPT, // \c
TOKEN_ITALIC_CORRECTION, // \/
@ -56,7 +52,6 @@ class token {
TOKEN_PAGE_EJECTOR,
TOKEN_REQUEST,
TOKEN_RIGHT_BRACE,
TOKEN_SIZE, // \s
TOKEN_SPACE, // ` ' -- ordinary space
TOKEN_SPECIAL, // a special character -- \' \` \- \(xx
TOKEN_SPREAD, // \p -- break and spread output line
@ -81,19 +76,17 @@ public:
int leader();
int backspace();
int delimiter(int warn = 0); // is it suitable for use as a delimiter?
symbol special();
int dummy();
int transparent();
int left_brace();
int right_brace();
int page_ejector();
int hyphen_indicator();
int operator==(const token &); // need this for delimiters, and for conditions
int operator!=(const token &); // ditto
unsigned char ch();
charinfo *get_char(int required = 0);
int add_to_node_list(node **);
int changes_env();
int is_size();
int title();
void make_space();
void make_newline();
@ -166,21 +159,11 @@ inline int token::eof()
return type == TOKEN_EOF;
}
inline symbol token::special()
{
return type == TOKEN_SPECIAL ? nm : symbol();
}
inline int token::dummy()
{
return type == TOKEN_DUMMY;
}
inline int token::is_size()
{
return type == TOKEN_SIZE;
}
inline int token::left_brace()
{
return type == TOKEN_LEFT_BRACE;
@ -191,15 +174,6 @@ inline int token::right_brace()
return type == TOKEN_RIGHT_BRACE;
}
inline int token::changes_env()
{
return (type == TOKEN_CHAR_HEIGHT
|| type == TOKEN_CHAR_SLANT
|| type == TOKEN_FONT_NAME
|| type == TOKEN_FONT_POSITION
|| type == TOKEN_SIZE);
}
inline int token::tab()
{
return type == TOKEN_TAB;
@ -215,4 +189,9 @@ inline int token::backspace()
return type == TOKEN_BACKSPACE;
}
inline int token::hyphen_indicator()
{
return type == TOKEN_HYPHEN_INDICATOR;
}
int has_arg();

View File

@ -7,20 +7,30 @@
.ns
.TP \\$1
..
.TH GTROFF 1 "19 October 1990" "Groff Version @VERSION@"
.\" Like TP, but if specified indent is more than half
.\" the current line-length - indent, use the default indent.
.de Tp
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
.el .TP "\\$1"
..
.\" The BSD man macros can't handle " in arguments to font change macros,
.\" so use \(ts instead of ".
.tr \(ts"
.TH TROFF 1 "1 April 1993" "Groff Version 1.08"
.SH NAME
gtroff \- format documents
.SH SYNOPIS
troff \- format documents
.SH SYNOPSIS
.nr a \n(.j
.ad l
.nr i \n(.i
.in +\w'\fBgtroff 'u
.in +\w'\fBtroff 'u
.ti \niu
.B gtroff
.B troff
.de OP
.ie \\n(.$-1 .RI "[\ \fB\\$1\fP" "\\$2" "\ ]"
.el .RB "[\ " "\\$1" "\ ]"
..
.OP \-abivzCE
.OP \-abivzCER
.OP \-w name
.OP \-W name
.OP \-d cs
@ -32,13 +42,14 @@ gtroff \- format documents
.OP \-T name
.OP \-F dir
.OP \-M dir
.OP \-H file
.RI "[\ " files\|.\|.\|. "\ ]"
.br
.ad b
.ad \na
.SH DESCRIPTION
gtroff is the central part of the groff document formatting system.
It is highly compatible with device-independent troff.
This manual page describes the GNU version of
.BR troff ,
which is part of the groff document formatting system.
It is highly compatible with Unix troff.
Usually it should be invoked using the groff command, which will
also run preprocessors and postprocessors in the appropriate
order and with the appropriate options.
@ -52,7 +63,7 @@ approximation of the typeset output.
.B \-b
Print a backtrace with each warning or error message. This backtrace
should help track down the cause of the error. The line numbers given
in the backtrace may not always correct: gtroff's idea of line numbers
in the backtrace may not always correct: troff's idea of line numbers
gets confused by
.B as
or
@ -111,7 +122,11 @@ as the default font family.
.BI \-m name
Read in the file
.BI tmac. name\fR.
Normally this will be searched for in @MACRODIR@.
Normally this will be searched for in /usr/share/tmac.
.TP
.B \-R
Don't load
.BR troffrc .
.TP
.BI \-n num
Number the first page
@ -130,7 +145,7 @@ means print every page between
and
.IR n ,
.BI \- n
mans print every page up to
means print every page up to
.IR n ,
.IB n \-
means print every page from
@ -148,13 +163,13 @@ to
.I c
must be a one character name;
.I n
can be any gtroff numeric expression.
can be any troff numeric expression.
.TP
.BI \-T name
Prepare output for device
.IR name ,
rather than the default
.BR @DEVICE@ .
.BR ps .
.TP
.BI \-F dir
Search
@ -166,21 +181,15 @@ is the name of the device)
for the
.B DESC
file and font files before the normal
.BR @FONTDIR@ .
.TP
.BI \-H file
Read hyphenation patterns from
.IR file ,
rather than the default
.BR @HYPHENFILE@ .
.BR /usr/share/groff_font .
.TP
.BI \-M dir
Search directory
.I dir
for macro files before the normal
.BR @MACRODIR@ .
.BR /usr/share/tmac .
.SH USAGE
Only the features not in device-independent troff are described here.
Only the features not in Unix troff are described here.
.SS Long names
The names of number registers, fonts, strings/macros/diversions,
special characters can be of any length. In escape sequences, where
@ -217,7 +226,7 @@ file (1 by default.)
There is a new scale indicator
.B z
which has the effect of multiplying by sizescale.
Requests and escape sequences in gtroff
Requests and escape sequences in troff
interpret arguments that represent a pointsize as being in units
of scaled points, but they evaluate each such argument
using a default scale indicator of
@ -263,7 +272,7 @@ whose default scale indicator was neither
nor
.BR z ,
and so
.B gtroff
.B troff
disallows this.
Similarily it would make no sense to use a scaling indicator
other than
@ -273,7 +282,7 @@ or
in a numeric expression whose default scale indicator was
.BR z ,
and so
.B gtroff
.B troff
disallows this as well.
.LP
There is also new scale indicator
@ -319,6 +328,23 @@ is missing, ignore scaling indicators in the evaluation of
.IR e .
.SS New escape sequences
.TP
.BI \eA' anything '
This expands to
.B 1
or
.B 0
according as
.I anything
is or is not acceptable as the name of a string, macro, diversion,
number register, environment or font.
It will return
.B 0
if
.I anything
is empty.
This is useful if you want to lookup user input in some sort of
associative table.
.TP
.BI \eC' xxx '
Typeset character named
.IR xxx .
@ -354,8 +380,9 @@ Typeset the character with code
.I n
in the current font.
.I n
must be a decimal integer between 0 and 255.
If the current font does not contain the character,
can be any integer.
Most devices only have characters with codes between 0 and 255.
If the current font does not contain a character with that code,
special fonts will
.I not
be searched.
@ -381,6 +408,13 @@ the
.B \eN
escape sequence is the only way to use these.
.TP
.BI \eR' name\ \(+-n '
This has the same effect as
.RS
.IP
.BI .nr\ name\ \(+-n
.RE
.TP
.BI \es( nn
.TQ
.BI \es\(+-( nn
@ -404,6 +438,18 @@ scaled points;
is a numeric expression with a default scale indicator of
.BR z .
.TP
.BI \eV x
.TQ
.BI \eV( xx
.TQ
.BI \eV[ xxx ]
Interpolate the contents of the environment variable
.I xxx ,
as returned by
.BR getenv (3).
.B \eV
is interpreted in copy-mode.
.TP
.BI \eY x
.TQ
.BI \eY( xx
@ -420,7 +466,7 @@ to have been defined as a macro and thus contain newlines
(it is not permitted for the argument to
.B \eX
to contain newlines).
The inclusion of newlines requires an extension to the troff output
The inclusion of newlines requires an extension to the Unix troff output
format, and will confuse drivers that do not know about this
extension.
.TP
@ -434,7 +480,7 @@ may not contain tabs or leaders.
The name by which the current macro was invoked.
The
.B als
request can make a macro can have more than one name.
request can make a macro have more than one name.
.TP
.B \e$*
In a macro, the concatenation of all the arguments separated by spaces.
@ -467,7 +513,7 @@ may not contain newlines; use
.B \e!
if you want to embed newlines in a diversion.
The escape sequence
.B \e!
.B \e?
is also recognised in copy mode and turned into a single internal
code; it is this code that terminates
.IR anything .
@ -538,6 +584,19 @@ Like
except that it behaves like a character declared with the
.B cflags
request to be transparent for the purposes of end of sentence recognition.
.TP
.B \e~
This produces an unbreakable space that stretches like a normal inter-word
space when a line is adjusted.
.TP
.B \e#
Everything up to and including the next newline is ignored.
This is interpreted in copy mode.
This is like
.B \e%
except that
.B \e%
does not ignore the terminating newline.
.SS New requests
.TP
.BI .aln\ xx\ yy
@ -578,7 +637,7 @@ request; normally they modify the value of an existing object.
.TP
.BI .asciify\ xx
This request only exists in order to make it possible
to make certain gross troff hacks work with gtroff.
to make certain gross hacks work with GNU troff.
It `unformats' the diversion
.I xx
in such a way that
@ -671,7 +730,7 @@ the character is transparent for the purposes of end of sentence
recognition;
this is the same as having a zero space factor in \*(tx
(initially characters
.B """')]*\e(dg"
.B \(ts')]*\e(dg\e(rq
have this property).
.RE
.TP
@ -686,6 +745,15 @@ needs to be printed,
.I string
will be processed in a temporary environment and the result
will be wrapped up into a single object.
Compatibility mode will be turned off
and the escape character will be set to
.B \e
while
.I string
is being processed.
Any emboldening, constant spacing or track kerning will be applied
to this object rather than to individual characters in
.IR string .
A character defined by this request can be used just like
a normal character provided by the output device.
In particular other characters can be translated to it
@ -708,6 +776,9 @@ There is a special anti-recursion feature:
use of character within the character's definition
will be handled like normal characters not defined with
.BR char .
A character definition can be removed with the
.B rchar
request.
.TP
.BI .chop\ xx
Chop the last character off macro, string, or diversion
@ -742,6 +813,28 @@ disable it.
In compatibility mode, long names are not recognised, and the
incompatibilities caused by long names do not arise.
.TP
.BI .do\ xxx
Interpret
.I .xxx
with compatibility mode disabled.
For example,
.RS
.IP
.B
\&.do fam T
.LP
would have the same effect as
.IP
.B
\&.fam T
.LP
except that it would work even if compatibility mode had been enabled.
Note that the previous compatibility mode is restored before any files
sourced by
.I xxx
are interpreted.
.RE
.TP
.BI .fam\ xx
Set the current font family to
.IR xx .
@ -812,12 +905,23 @@ character (not a special character) other than a digit or a space.
Initially each lower-case letter has a hyphenation code, which
is itself, and each upper-case letter has a hyphenation code
which is the lower case version of itself.
Hyphenation is controlled by a file of hyphenation patterns
(normally @HYPHENFILE@);
this file should have the same format as the argument to
the \epatterns primitive in \*(tx;
the letters appearing in this file are interpreted as hyphenation
codes.
See also the
.B hpf
request.
.TP
.BI .hla\ lang
Set the current hyphenation language to
.IR lang .
Hyphenation exceptions specified with the
.B hw
request and hyphenation patterns specified with the
.B hpf
request are both associated with the current hyphenation language.
The
.B hla
request is usually invoked by the
.B troffrc
file.
.TP
.BI .hlm\ n
Set the maximum number of consecutive hyphenated lines to
@ -833,6 +937,33 @@ Hyphens resulting from
.B \e%
are counted; explicit hyphens are not.
.TP
.BI .hpf\ file
Read hyphenation patterns from
.IR file ;
this will be searched for in the same way that
.BI tmac. name
is searched for when the
.BI \-m name
option is specified.
It should have the same format as the argument to
the \epatterns primitive in \*(tx;
the letters appearing in this file are interpreted as hyphenation
codes.
A
.B %
character in the patterns file introduces a comment that continues
to the end of the line.
The set of hyphenation patterns is associated with the current language
set by the
.B hla
request.
The
.B hpf
request
is usually invoked by the
.B troffrc
file.
.TP
.BI .hym\ n
Set the
.I hyphenation margin
@ -874,6 +1005,17 @@ If
.I n
is non-zero or missing, enable pairwise kerning, otherwise disable it.
.TP
.BI .mso\ file
The same as the
.B so
request except that
.I file
is searched for in the same way that
.BI tmac. name
is searched for when the
.BI \-m name
option is specified.
.TP
.B .nroff
Make the
.B n
@ -914,6 +1056,14 @@ traps and diversion traps) on stderr. Empty slots in the page trap
list are printed as well, because they can affect the priority of
subsequently planted traps.
.TP
.BI .rchar\ c1\ c2\|.\|.\|.
Remove the definitions of characters
.IR c1 ,
.IR c2 ,\|.\|.\|.
This undoes the effect of a
.B char
request.
.TP
.B .rj
.TQ
.BI .rj\ n
@ -937,6 +1087,27 @@ Rename number register
to
.IR yy .
.TP
.BI .shc\ c
Set the soft hyphen character to
.IR c .
If
.I c
is omitted,
the soft hyphen character will be set to the default
.BR \e(hy .
The soft hyphen character is the character which will be inserted
when a word is hyphenated at a line break.
If the soft hyphen character does not exist in the font of the character
immediately preceding a potential break point,
then the line will not be broken at that point.
Neither definitions (specified with the
.B char
request)
nor translations (specified with the
.B tr
request)
are considered when finding the soft hyphen character.
.TP
.BI .shift\ n
In a macro, shift the arguments by
.I n
@ -1010,7 +1181,7 @@ the width of every character will be increased by an amount
between
.I n1
and
.IR n2 :
.IR n2 ;
when the current point size is less than or equal to
.I s1
the width will be increased by
@ -1051,7 +1222,36 @@ Unlike with the
request,
the file cannot contain characters such as
.SM NUL
that are not legal gtroff input characters.
that are not legal troff input characters.
.RE
.TP
.B .trnt abcd
This is the same as the
.B tr
request except that the translations do not apply to text that is
transparently throughput into a diversion with
.BR \e! .
For example,
.RS
.LP
.nf
.ft B
\&.tr ab
\&.di x
\e!.tm a
\&.di
\&.x
.fi
.ft
.LP
will print
.BR b ;
if
.B trnt
is used instead of
.B tr
it will print
.BR a .
.RE
.TP
.B .troff
@ -1130,7 +1330,7 @@ request.
.I anything
is read in copy mode;
a leading
.B """"
.B \(ts
will be stripped.
.SS Extended requests
.TP
@ -1138,7 +1338,8 @@ will be stripped.
When used in a diversion, this will embed in the diversion an object which,
when reread, will cause the contents of
.I filename
to be transparently copied through to the output. In troff, the
to be transparently copied through to the output.
In Unix troff, the
contents of
.I filename
is immediately copied through to the output regardless of whether
@ -1163,7 +1364,7 @@ request has an optional third argument.
This argument gives the external name of the font,
which is used for finding the font description file.
The second argument gives the internal name of the font
which is used to refer to the font in gtroff after it has been mounted.
which is used to refer to the font in troff after it has been mounted.
If there is no third argument then the internal name will be used
as the external name.
This feature allows you to use fonts with long names in compatibility mode.
@ -1184,11 +1385,11 @@ if the end of a sentence occurs at the end of a line in fill mode, then
both an inter-word space and a sentence space will be added;
if two spaces follow the end of a sentence in the middle of a line,
then the second space will be a sentence space.
Note that the behaviour of troff will be exactly
that exhibited by gtroff if a second argument is never given to the
Note that the behaviour of Unix troff will be exactly
that exhibited by GNU troff if a second argument is never given to the
.B ss
request.
In gtroff, as in troff, you should always
In GNU troff, as in Unix troff, you should always
follow a sentence with either a newline or two spaces.
.TP
.BI .ta\ n1\ n2\|.\|.\|.nn \ T\ r1\ r2\|.\|.\|.\|rn
@ -1253,7 +1454,12 @@ The number of the next free font position.
.B \en[.g]
Always 1.
Macros should use this to determine whether they are running
under gtroff.
under GNU troff.
.TP
.B \en[.hla]
The current hyphenation language as set by the
.B hla
request.
.TP
.B \en[.hlc]
The number of immediately preceding consecutive hyphenated lines.
@ -1281,6 +1487,17 @@ request.)
.B \en[.in]
The indent that applies to the current output line.
.TP
.B \en[.kern]
.B 1
if pairwise kerning is enabled,
.B 0
otherwise.
.TP
.B \en[.lg]
The current ligature mode (as set by the
.B lg
request.)
.TP
.B \en[.ll]
The line length that applies to the current output line.
.TP
@ -1425,7 +1642,7 @@ which can be found in the
.B \en[.fp]
register;
although
.B gtroff
.B troff
does not enforce this strictly,
it will not allow a font to be mounted at a position whose number is much
greater than that of any currently used position.
@ -1467,6 +1684,11 @@ The implementation of
ensures that the double quotes surrounding an argument
will appear the same input level, which will be different
to the input level of the argument itself.
In a long escape name
.B ]
will not be recognized as a closing delimiter except
when it occurs at the same input level as the opening
.BR ] .
In compatibility mode, no attention is paid to the input-level.
.LP
There are some new types of condition:
@ -1498,7 +1720,7 @@ has been defined by the
request.
.SS Warnings
The warnings that can be given by
.B gtroff
.B troff
are divided into the following categories.
The name associated with each warning is used by the
.B \-w
@ -1594,9 +1816,11 @@ and the first two characters of the name make a defined name.
The request or macro will not be invoked.
When this warning is given, no macro is automatically defined.
This is enabled by default.
.B mac
is given.
This warning will never occur in compatibility mode.
.TP
.BR font \t131072
Non-existent fonts.
This is enabled by default.
.LP
There are also names that can be used to refer to groups of warnings:
.TP
@ -1614,7 +1838,7 @@ All warnings.
.SS Incompatibilities
.LP
Long names cause some incompatibilities.
Troff will interpret
Unix troff will interpret
.IP
.B
\&.dsabcd
@ -1623,19 +1847,19 @@ as defining a string
.B ab
with contents
.BR cd .
Normally, gtroff will interpret this as a call of a macro named
Normally, GNU troff will interpret this as a call of a macro named
.BR dsabcd .
Also troff will interpret
Also Unix troff will interpret
.B \e*[
or
.B \en[
as references to a string or number register called
.BR [ .
In gtroff, however, this will normally be interpreted as the start
In GNU troff, however, this will normally be interpreted as the start
of a long name.
In
.I compatibility mode
gtroff will interpret these things in the traditional way.
GNU troff will interpret these things in the traditional way.
In compatibility mode, however, long names are not recognised.
Compatibility mode can be turned on with the
.B \-C
@ -1646,20 +1870,27 @@ The number register
.B \en(.C
is 1 if compatibility mode is on, 0 otherwise.
.LP
GNU troff
does not allow the use of the escape sequences
.BR \\e\e|\e^\e&\e}\e{\e (space) \e'\e`\e-\e_\e!\e%\ec
in names of strings, macros, diversions, number registers,
fonts or environments; Unix troff does.
The
.B \eA
escape sequence may be helpful in avoiding use of these
escape sequences in names.
.LP
Fractional pointsizes cause one noteworthy incompatibility.
In
.B troff
the
In Unix troff the
.B ps
request ignores scale indicators and so
.IP
.B .ps\ 10u
.LP
will set the pointsize to 10 points, whereas in
.B gtroff
it will set the pointsize to 10 scaled points.
GNU troff it will set the pointsize to 10 scaled points.
.LP
In gtroff there is a fundamental difference between unformatted,
In GNU troff there is a fundamental difference between unformatted,
input characters, and formatted, output characters.
Everything that affects how an output character
will be output is stored with the character; once an output
@ -1696,7 +1927,7 @@ For example,
.LP
will print
.B \e\e
in gtroff;
in GNU troff;
each pair of input
.BR \e s
is turned into one output
@ -1704,7 +1935,7 @@ is turned into one output
and the resulting output
.BR \e s
are not interpreted as escape characters when they are reread.
Troff would interpret them as escape characters
Unix troff would interpret them as escape characters
when they were reread and would end up printing one
.BR \e .
The correct way to obtain a printable
@ -1713,7 +1944,7 @@ is to use the
.B \ee
escape sequence: this will always print a single instance of the
current escape character, regardless of whether or not it is used in a
diversion; it will also work in both gtroff and troff.
diversion; it will also work in both GNU troff and Unix troff.
If you wish for some reason to store in a diversion an escape
sequence that will be interpreted when the diversion is reread,
you can either use the traditional
@ -1737,41 +1968,37 @@ Default device.
A colon separated list of directories in which to search for the
.BI dev name
directory.
Gtroff will search in directories given in the
.B troff
will search in directories given in the
.B \-F
option before these, and in standard directories
.RB ( @FONTPATH@ )
.RB ( /usr/share/groff_font )
after these.
.TP
.SM
.B GROFF_HYPHEN
File containing hyphenation patterns.
.SH FILES
.TP \w'@FONTDIR@/devname/DESC'u+3n
.B @HYPHENFILE@
Hyphenation patterns
.Tp \w'/usr/share/groff_font/devname/DESC'u+3n
.B /usr/share/tmac/troffrc
Initialization file
.TP
.BI @MACRODIR@/tmac. name
.BI /usr/share/tmac/tmac. name
Macro files
.TP
.BI @FONTDIR@/dev name /DESC
.BI /usr/share/groff_font/dev name /DESC
Device description file for device
.IR name .
.TP
.BI @FONTDIR@/dev name / F
.BI /usr/share/groff_font/dev name / F
Font file for font
.I F
of device
.IR name .
.SH "SEE ALSO"
.BR groff (@MAN1EXT@)
.BR gtbl (@MAN1EXT@),
.BR gpic (@MAN1EXT@),
.BR geqn (@MAN1EXT@),
.BR grops (@MAN1EXT@),
.BR grodvi (@MAN1EXT@),
.BR grotty (@MAN1EXT@),
.BR groff_font (@MAN5EXT@),
.BR groff_out (@MAN5EXT@)
.br
.I "Groff Character Names"
.BR groff (1)
.BR tbl (1),
.BR pic (1),
.BR eqn (1),
.BR grops (1),
.BR grodvi (1),
.BR grotty (1),
.BR groff_font (5),
.BR groff_out (5),
.BR groff_char (7)

View File

@ -0,0 +1,88 @@
// -*- 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <stddef.h>
#include <stdlib.h>
#include <errno.h>
#include "lib.h"
#include "assert.h"
#include "device.h"
#ifdef __GNUG__
#define NO_RETURN volatile
#else
#define NO_RETURN
#endif
NO_RETURN void cleanup_and_exit(int n);
typedef int units;
extern units scale(units n, units x, units y); // scale n by x/y
extern units units_per_inch;
extern int ascii_output_flag;
extern int suppress_output_flag;
extern int tcommand_flag;
extern int vresolution;
extern int hresolution;
extern int sizescale;
#include "cset.h"
#include "cmap.h"
#include "errarg.h"
#include "error.h"
enum warning_type {
WARN_CHAR = 01,
WARN_NUMBER = 02,
WARN_BREAK = 04,
WARN_DELIM = 010,
WARN_EL = 020,
WARN_SCALE = 040,
WARN_RANGE = 0100,
WARN_SYNTAX = 0200,
WARN_DI = 0400,
WARN_MAC = 01000,
WARN_REG = 02000,
WARN_TAB = 04000,
WARN_RIGHT_BRACE = 010000,
WARN_MISSING = 020000,
WARN_INPUT = 040000,
WARN_ESCAPE = 0100000,
WARN_SPACE = 0200000,
WARN_FONT = 0400000
// change WARN_TOTAL if you add more warning types
};
const int WARN_TOTAL = 0777777;
int warning(warning_type, const char *,
const errarg & = empty_errarg,
const errarg & = empty_errarg,
const errarg & = empty_errarg);