/* Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
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
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
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
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
class char_box
: public simple_box
{
void handle_char_type(int, int);
class special_char_box
: public simple_box
{
special_char_box(const char *);
void handle_char_type(int, int);
const char *spacing_type_table
[] = {
const int DIGIT_TYPE
= 0;
const int LETTER_TYPE
= 1;
const char *font_type_table
[] = {
: spacing_type(ORDINARY_TYPE
), font_type(DIGIT_TYPE
)
static char_info char_table
[256];
declare_ptable(char_info
)
implement_ptable(char_info
)
PTABLE(char_info
) special_char_table
;
static int get_special_char_spacing_type(const char *ch
)
char_info
*p
= special_char_table
.lookup(ch
);
return p
? p
->spacing_type
: ORDINARY_TYPE
;
static int get_special_char_font_type(const char *ch
)
char_info
*p
= special_char_table
.lookup(ch
);
return p
? p
->font_type
: DIGIT_TYPE
;
static void set_special_char_type(const char *ch
, int st
, int ft
)
char_info
*p
= special_char_table
.lookup(ch
);
special_char_table
.define(ch
, p
);
set_special_char_type("pl", 2, -1); // binary
set_special_char_type("mi", 2, -1);
set_special_char_type("eq", 3, -1); // relation
set_special_char_type("<=", 3, -1);
set_special_char_type(">=", 3, -1);
char_table
['}'].spacing_type
= 5; // closing
char_table
[')'].spacing_type
= 5;
char_table
[']'].spacing_type
= 5;
char_table
['{'].spacing_type
= 4; // opening
char_table
['('].spacing_type
= 4;
char_table
['['].spacing_type
= 4;
char_table
[','].spacing_type
= 6; // punctuation
char_table
[';'].spacing_type
= 6;
char_table
[':'].spacing_type
= 6;
char_table
['.'].spacing_type
= 6;
char_table
['>'].spacing_type
= 3;
char_table
['<'].spacing_type
= 3;
char_table
['*'].spacing_type
= 2; // binary
for (int i
= 0; i
< 256; i
++)
char_table
[i
].font_type
= LETTER_TYPE
;
static int lookup_spacing_type(const char *type
)
for (int i
= 0; spacing_type_table
[i
] != 0; i
++)
if (strcmp(spacing_type_table
[i
], type
) == 0)
static int lookup_font_type(const char *type
)
for (int i
= 0; font_type_table
[i
] != 0; i
++)
if (strcmp(font_type_table
[i
], type
) == 0)
void box::set_spacing_type(char *type
)
int t
= lookup_spacing_type(type
);
error("unrecognised type `%1'", type
);
char_box::char_box(unsigned char cc
)
: c(cc
), prev_is_italic(0), next_is_italic(0)
spacing_type
= char_table
[c
].spacing_type
;
void char_box::hint(unsigned flags
)
if (flags
& HINT_PREV_IS_ITALIC
)
if (flags
& HINT_NEXT_IS_ITALIC
)
int font_type
= char_table
[c
].font_type
;
if (font_type
!= LETTER_TYPE
)
printf("\\f[%s]", current_roman_font
);
fputs("\\&", stdout
); // suppress ligaturing and kerning
if (font_type
!= LETTER_TYPE
)
int char_box::left_is_italic()
int font_type
= char_table
[c
].font_type
;
return font_type
== LETTER_TYPE
;
int char_box::right_is_italic()
int font_type
= char_table
[c
].font_type
;
return font_type
== LETTER_TYPE
;
void char_box::debug_print()
special_char_box::special_char_box(const char *t
)
spacing_type
= get_special_char_spacing_type(s
);
special_char_box::~special_char_box()
void special_char_box::output()
int font_type
= get_special_char_font_type(s
);
if (font_type
!= LETTER_TYPE
)
printf("\\f[%s]", current_roman_font
);
printf("\\,\\[%s]\\/", s
);
if (font_type
!= LETTER_TYPE
)
int special_char_box::is_char()
void special_char_box::debug_print()
fprintf(stderr
, "\\[%s]", s
);
void char_box::handle_char_type(int st
, int ft
)
char_table
[c
].spacing_type
= st
;
char_table
[c
].font_type
= ft
;
void special_char_box::handle_char_type(int st
, int ft
)
set_special_char_type(s
, st
, ft
);
void set_char_type(const char *type
, char *ch
)
int st
= lookup_spacing_type(type
);
int ft
= lookup_font_type(type
);
error("bad character type `%1'", type
);
b
->handle_char_type(st
, ft
);
/* We give primes special treatment so that in ``x' sub 2'', the ``2''
will be tucked under the prime */
class prime_box
: public pointer_box
{
int compute_metrics(int style
);
void compute_subscript_kern();
void handle_char_type(int, int);
box
*make_prime_box(box
*pp
)
return new prime_box(pp
);
prime_box::prime_box(box
*pp
) : pointer_box(pp
)
pb
= new special_char_box("fm");
int prime_box::compute_metrics(int style
)
int res
= p
->compute_metrics(style
);
pb
->compute_metrics(style
);
printf(".nr " WIDTH_FORMAT
" \\n[" WIDTH_FORMAT
"]"
"+\\n[" WIDTH_FORMAT
"]\n",
printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]"
">?\\n[" HEIGHT_FORMAT
"]\n",
printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]"
">?\\n[" DEPTH_FORMAT
"]\n",
void prime_box::compute_subscript_kern()
p
->compute_subscript_kern();
printf(".nr " SUB_KERN_FORMAT
" \\n[" WIDTH_FORMAT
"]"
"+\\n[" SUB_KERN_FORMAT
"]\n",
void prime_box::handle_char_type(int st
, int ft
)
p
->handle_char_type(st
, ft
);
pb
->handle_char_type(st
, ft
);
void prime_box::debug_print()
box
*split_text(char *text
)
b
= new special_char_box("pl");
b
= new special_char_box("mi");
b
= new special_char_box("eq");
b
= new special_char_box("fm");
b
= new special_char_box("<=");
b
= new special_char_box(">=");
b
= new special_char_box(buf
);
while (*s
!= ']' && *s
!= '\0')
b
= new special_char_box(ch
);
char *escape_start
= s
- 2;
for (++s
; *s
!= '\0' && *s
!= ']'; s
++)
char *buf
= new char[s
- escape_start
+ 1];
memcpy(buf
, escape_start
, s
- escape_start
);
buf
[s
- escape_start
] = '\0';
b
= new quoted_text_box(buf
);
b
= new special_char_box(buf
);
b
= new special_char_box("ga");
b
= new special_char_box("aa");
b
= new quoted_text_box(strsave(buf
));
lex_error("unquoted escape");
b
= new quoted_text_box(strsave(s
- 2));
b
= new quoted_text_box(0);
return new quoted_text_box(0);