4 /* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
5 Written by James Clark (jjc@jclark.com)
7 This file is part of groff.
9 groff is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
14 groff is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License along
20 with groff; see the file COPYING. If not, write to the Free Software
21 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
26 list_box
*box::to_list_box()
31 list_box
*list_box::to_list_box()
36 void list_box::append(box
*pp
)
38 list_box
*q
= pp
->to_list_box();
42 for (int i
= 0; i
< q
->list
.len
; i
++) {
43 list
.append(q
->list
.p
[i
]);
51 list_box::list_box(box
*pp
) : list(pp
), sty(-1)
53 list_box
*q
= pp
->to_list_box();
56 list
.p
[0] = q
->list
.p
[0];
57 for (int i
= 1; i
< q
->list
.len
; i
++) {
58 list
.append(q
->list
.p
[i
]);
66 static int compute_spacing(int is_script
, int left
, int right
)
68 if (left
== SUPPRESS_TYPE
|| right
== SUPPRESS_TYPE
)
70 if (left
== PUNCTUATION_TYPE
)
71 return is_script
? 0 : thin_space
;
72 if (left
== OPENING_TYPE
|| right
== CLOSING_TYPE
)
74 if (right
== BINARY_TYPE
|| left
== BINARY_TYPE
)
75 return is_script
? 0 : medium_space
;
76 if (right
== RELATION_TYPE
) {
77 if (left
== RELATION_TYPE
)
80 return is_script
? 0 : thick_space
;
82 if (left
== RELATION_TYPE
)
83 return is_script
? 0 : thick_space
;
84 if (right
== OPERATOR_TYPE
)
86 if (left
== INNER_TYPE
|| right
== INNER_TYPE
)
87 return is_script
? 0 : thin_space
;
88 if (left
== OPERATOR_TYPE
&& right
== ORDINARY_TYPE
)
93 int list_box::compute_metrics(int style
)
97 for (i
= 0; i
< list
.len
; i
++) {
98 int t
= list
.p
[i
]->spacing_type
;
100 if (t
== BINARY_TYPE
) {
103 || (prevt
= list
.p
[i
-1]->spacing_type
) == BINARY_TYPE
104 || prevt
== OPERATOR_TYPE
105 || prevt
== RELATION_TYPE
106 || prevt
== OPENING_TYPE
107 || prevt
== PUNCTUATION_TYPE
)
108 list
.p
[i
]->spacing_type
= ORDINARY_TYPE
;
111 else if ((t
== RELATION_TYPE
|| t
== CLOSING_TYPE
112 || t
== PUNCTUATION_TYPE
)
113 && i
> 0 && list
.p
[i
-1]->spacing_type
== BINARY_TYPE
)
114 list
.p
[i
-1]->spacing_type
= ORDINARY_TYPE
;
116 for (i
= 0; i
< list
.len
; i
++) {
118 if (i
- 1 >= 0 && list
.p
[i
- 1]->right_is_italic())
119 flags
|= HINT_PREV_IS_ITALIC
;
120 if (i
+ 1 < list
.len
&& list
.p
[i
+ 1]->left_is_italic())
121 flags
|= HINT_NEXT_IS_ITALIC
;
123 list
.p
[i
]->hint(flags
);
125 is_script
= (style
<= SCRIPT_STYLE
);
126 int total_spacing
= 0;
127 for (i
= 1; i
< list
.len
; i
++)
128 total_spacing
+= compute_spacing(is_script
, list
.p
[i
-1]->spacing_type
,
129 list
.p
[i
]->spacing_type
);
131 for (i
= 0; i
< list
.len
; i
++)
132 if (!list
.p
[i
]->is_simple()) {
133 int r
= list
.p
[i
]->compute_metrics(style
);
136 error("multiple marks and lineups");
138 compute_sublist_width(i
);
139 printf(".nr " MARK_REG
" +\\n[" TEMP_REG
"]\n");
144 printf(".nr " WIDTH_FORMAT
" %dM", uid
, total_spacing
);
145 for (i
= 0; i
< list
.len
; i
++)
146 if (!list
.p
[i
]->is_simple())
147 printf("+\\n[" WIDTH_FORMAT
"]", list
.p
[i
]->uid
);
149 printf(".nr " HEIGHT_FORMAT
" 0", uid
);
150 for (i
= 0; i
< list
.len
; i
++)
151 if (!list
.p
[i
]->is_simple())
152 printf(">?\\n[" HEIGHT_FORMAT
"]", list
.p
[i
]->uid
);
154 printf(".nr " DEPTH_FORMAT
" 0", uid
);
155 for (i
= 0; i
< list
.len
; i
++)
156 if (!list
.p
[i
]->is_simple())
157 printf(">?\\n[" DEPTH_FORMAT
"]", list
.p
[i
]->uid
);
160 for (i
= 0; i
< list
.len
&& !have_simple
; i
++)
161 have_simple
= list
.p
[i
]->is_simple();
163 printf(".nr " WIDTH_FORMAT
" +\\w" DELIMITER_CHAR
, uid
);
164 for (i
= 0; i
< list
.len
; i
++)
165 if (list
.p
[i
]->is_simple())
167 printf(DELIMITER_CHAR
"\n");
168 printf(".nr " HEIGHT_FORMAT
" \\n[rst]>?\\n[" HEIGHT_FORMAT
"]\n",
170 printf(".nr " DEPTH_FORMAT
" 0-\\n[rsb]>?\\n[" DEPTH_FORMAT
"]\n",
176 void list_box::compute_sublist_width(int n
)
178 int total_spacing
= 0;
180 for (i
= 1; i
< n
+ 1 && i
< list
.len
; i
++)
181 total_spacing
+= compute_spacing(is_script
, list
.p
[i
-1]->spacing_type
,
182 list
.p
[i
]->spacing_type
);
183 printf(".nr " TEMP_REG
" %dM", total_spacing
);
184 for (i
= 0; i
< n
; i
++)
185 if (!list
.p
[i
]->is_simple())
186 printf("+\\n[" WIDTH_FORMAT
"]", list
.p
[i
]->uid
);
188 for (i
= 0; i
< n
&& !have_simple
; i
++)
189 have_simple
= list
.p
[i
]->is_simple();
191 printf("+\\w" DELIMITER_CHAR
);
192 for (i
= 0; i
< n
; i
++)
193 if (list
.p
[i
]->is_simple())
195 printf(DELIMITER_CHAR
);
200 void list_box::compute_subscript_kern()
202 // We can only call compute_subscript_kern if we have called
203 // compute_metrics first.
204 if (list
.p
[list
.len
-1]->is_simple())
205 list
.p
[list
.len
-1]->compute_metrics(sty
);
206 list
.p
[list
.len
-1]->compute_subscript_kern();
207 printf(".nr " SUB_KERN_FORMAT
" \\n[" SUB_KERN_FORMAT
"]\n",
208 uid
, list
.p
[list
.len
-1]->uid
);
211 void list_box::output()
213 for (int i
= 0; i
< list
.len
; i
++) {
215 int n
= compute_spacing(is_script
,
216 list
.p
[i
-1]->spacing_type
,
217 list
.p
[i
]->spacing_type
);
219 printf("\\h'%dM'", n
);
225 void list_box::handle_char_type(int st
, int ft
)
227 for (int i
= 0; i
< list
.len
; i
++)
228 list
.p
[i
]->handle_char_type(st
, ft
);
231 void list_box::debug_print()
233 list
.list_debug_print(" ");
236 void list_box::check_tabs(int level
)
238 list
.list_check_tabs(level
);