/* Copyright (C) 1989, 1990 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. */
list_box
*box::to_list_box()
list_box
*list_box::to_list_box()
void list_box::append(box
*pp
)
list_box
*q
= pp
->to_list_box();
for (int i
= 0; i
< q
->list
.len
; i
++) {
list
.append(q
->list
.p
[i
]);
list_box::list_box(box
*pp
) : list(pp
), sty(-1)
list_box
*q
= pp
->to_list_box();
list
.p
[0] = q
->list
.p
[0];
for (int i
= 1; i
< q
->list
.len
; i
++) {
list
.append(q
->list
.p
[i
]);
static int compute_spacing(int is_script
, int left
, int right
)
if (left
== SUPPRESS_TYPE
|| right
== SUPPRESS_TYPE
)
if (left
== PUNCTUATION_TYPE
)
return is_script
? 0 : thin_space
;
if (left
== OPENING_TYPE
|| right
== CLOSING_TYPE
)
if (right
== BINARY_TYPE
|| left
== BINARY_TYPE
)
return is_script
? 0 : medium_space
;
if (right
== RELATION_TYPE
) {
if (left
== RELATION_TYPE
)
return is_script
? 0 : thick_space
;
if (left
== RELATION_TYPE
)
return is_script
? 0 : thick_space
;
if (right
== OPERATOR_TYPE
)
if (left
== INNER_TYPE
|| right
== INNER_TYPE
)
return is_script
? 0 : thin_space
;
if (left
== OPERATOR_TYPE
&& right
== ORDINARY_TYPE
)
int list_box::compute_metrics(int style
)
for (i
= 0; i
< list
.len
; i
++) {
int t
= list
.p
[i
]->spacing_type
;
|| (prevt
= list
.p
[i
-1]->spacing_type
) == BINARY_TYPE
|| prevt
== OPERATOR_TYPE
|| prevt
== RELATION_TYPE
|| prevt
== PUNCTUATION_TYPE
)
list
.p
[i
]->spacing_type
= ORDINARY_TYPE
;
else if ((t
== RELATION_TYPE
|| t
== CLOSING_TYPE
|| t
== PUNCTUATION_TYPE
)
&& i
> 0 && list
.p
[i
-1]->spacing_type
== BINARY_TYPE
)
list
.p
[i
-1]->spacing_type
= ORDINARY_TYPE
;
for (i
= 0; i
< list
.len
; i
++) {
if (i
- 1 >= 0 && list
.p
[i
- 1]->right_is_italic())
flags
|= HINT_PREV_IS_ITALIC
;
if (i
+ 1 < list
.len
&& list
.p
[i
+ 1]->left_is_italic())
flags
|= HINT_NEXT_IS_ITALIC
;
is_script
= (style
<= SCRIPT_STYLE
);
for (i
= 1; i
< list
.len
; i
++)
total_spacing
+= compute_spacing(is_script
, list
.p
[i
-1]->spacing_type
,
list
.p
[i
]->spacing_type
);
for (i
= 0; i
< list
.len
; i
++)
if (!list
.p
[i
]->is_simple()) {
int r
= list
.p
[i
]->compute_metrics(style
);
error("multiple marks and lineups");
compute_sublist_width(i
);
printf(".nr " MARK_REG
" +\\n[" TEMP_REG
"]\n");
printf(".nr " WIDTH_FORMAT
" %dM", uid
, total_spacing
);
for (i
= 0; i
< list
.len
; i
++)
if (!list
.p
[i
]->is_simple())
printf("+\\n[" WIDTH_FORMAT
"]", list
.p
[i
]->uid
);
printf(".nr " HEIGHT_FORMAT
" 0", uid
);
for (i
= 0; i
< list
.len
; i
++)
if (!list
.p
[i
]->is_simple())
printf(">?\\n[" HEIGHT_FORMAT
"]", list
.p
[i
]->uid
);
printf(".nr " DEPTH_FORMAT
" 0", uid
);
for (i
= 0; i
< list
.len
; i
++)
if (!list
.p
[i
]->is_simple())
printf(">?\\n[" DEPTH_FORMAT
"]", list
.p
[i
]->uid
);
for (i
= 0; i
< list
.len
&& !have_simple
; i
++)
have_simple
= list
.p
[i
]->is_simple();
printf(".nr " WIDTH_FORMAT
" +\\w" DELIMITER_CHAR
, uid
);
for (int i
= 0; i
< list
.len
; i
++)
if (list
.p
[i
]->is_simple())
printf(DELIMITER_CHAR
"\n");
printf(".nr " HEIGHT_FORMAT
" \\n[rst]>?\\n[" HEIGHT_FORMAT
"]\n",
printf(".nr " DEPTH_FORMAT
" 0-\\n[rsb]>?\\n[" DEPTH_FORMAT
"]\n",
void list_box::compute_sublist_width(int n
)
for (int i
= 1; i
< n
+ 1 && i
< list
.len
; i
++)
total_spacing
+= compute_spacing(is_script
, list
.p
[i
-1]->spacing_type
,
list
.p
[i
]->spacing_type
);
printf(".nr " TEMP_REG
" %dM", total_spacing
);
if (!list
.p
[i
]->is_simple())
printf("+\\n[" WIDTH_FORMAT
"]", list
.p
[i
]->uid
);
for (i
= 0; i
< n
&& !have_simple
; i
++)
have_simple
= list
.p
[i
]->is_simple();
printf("+\\w" DELIMITER_CHAR
);
for (int i
= 0; i
< n
; i
++)
if (list
.p
[i
]->is_simple())
void list_box::compute_subscript_kern()
// We can only call compute_subscript_kern if we have called
// compute_metrics first.
if (list
.p
[list
.len
-1]->is_simple())
list
.p
[list
.len
-1]->compute_metrics(sty
);
list
.p
[list
.len
-1]->compute_subscript_kern();
printf(".nr " SUB_KERN_FORMAT
" \\n[" SUB_KERN_FORMAT
"]\n",
uid
, list
.p
[list
.len
-1]->uid
);
for (int i
= 0; i
< list
.len
; i
++) {
int n
= compute_spacing(is_script
,
list
.p
[i
-1]->spacing_type
,
list
.p
[i
]->spacing_type
);
void list_box::handle_char_type(int st
, int ft
)
for (int i
= 0; i
< list
.len
; i
++)
list
.p
[i
]->handle_char_type(st
, ft
);
void list_box::debug_print()
list
.list_debug_print(" ");
void list_box::check_tabs(int level
)
list
.list_check_tabs(level
);