2 /* Copyright (C) 1989, 1990, 1991, 1992, 2007 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.com)
5 This file is part of groff.
7 groff is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 groff is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License along
18 with groff; see the file COPYING. If not, write to the Free Software
19 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
24 list_box
*box::to_list_box()
29 list_box
*list_box::to_list_box()
34 void list_box::append(box
*pp
)
36 list_box
*q
= pp
->to_list_box();
40 for (int i
= 0; i
< q
->list
.len
; i
++) {
41 list
.append(q
->list
.p
[i
]);
49 list_box::list_box(box
*pp
) : list(pp
), sty(-1)
51 list_box
*q
= pp
->to_list_box();
54 list
.p
[0] = q
->list
.p
[0];
55 for (int i
= 1; i
< q
->list
.len
; i
++) {
56 list
.append(q
->list
.p
[i
]);
64 static int compute_spacing(int is_script
, int left
, int right
)
66 if (left
== SUPPRESS_TYPE
|| right
== SUPPRESS_TYPE
)
68 if (left
== PUNCTUATION_TYPE
)
69 return is_script
? 0 : thin_space
;
70 if (left
== OPENING_TYPE
|| right
== CLOSING_TYPE
)
72 if (right
== BINARY_TYPE
|| left
== BINARY_TYPE
)
73 return is_script
? 0 : medium_space
;
74 if (right
== RELATION_TYPE
) {
75 if (left
== RELATION_TYPE
)
78 return is_script
? 0 : thick_space
;
80 if (left
== RELATION_TYPE
)
81 return is_script
? 0 : thick_space
;
82 if (right
== OPERATOR_TYPE
)
84 if (left
== INNER_TYPE
|| right
== INNER_TYPE
)
85 return is_script
? 0 : thin_space
;
86 if (left
== OPERATOR_TYPE
&& right
== ORDINARY_TYPE
)
91 int list_box::compute_metrics(int style
)
95 for (i
= 0; i
< list
.len
; i
++) {
96 int t
= list
.p
[i
]->spacing_type
;
98 if (t
== BINARY_TYPE
) {
101 || (prevt
= list
.p
[i
-1]->spacing_type
) == BINARY_TYPE
102 || prevt
== OPERATOR_TYPE
103 || prevt
== RELATION_TYPE
104 || prevt
== OPENING_TYPE
105 || prevt
== PUNCTUATION_TYPE
)
106 list
.p
[i
]->spacing_type
= ORDINARY_TYPE
;
109 else if ((t
== RELATION_TYPE
|| t
== CLOSING_TYPE
110 || t
== PUNCTUATION_TYPE
)
111 && i
> 0 && list
.p
[i
-1]->spacing_type
== BINARY_TYPE
)
112 list
.p
[i
-1]->spacing_type
= ORDINARY_TYPE
;
114 for (i
= 0; i
< list
.len
; i
++) {
116 if (i
- 1 >= 0 && list
.p
[i
- 1]->right_is_italic())
117 flags
|= HINT_PREV_IS_ITALIC
;
118 if (i
+ 1 < list
.len
&& list
.p
[i
+ 1]->left_is_italic())
119 flags
|= HINT_NEXT_IS_ITALIC
;
121 list
.p
[i
]->hint(flags
);
123 is_script
= (style
<= SCRIPT_STYLE
);
124 int total_spacing
= 0;
125 for (i
= 1; i
< list
.len
; i
++)
126 total_spacing
+= compute_spacing(is_script
, list
.p
[i
-1]->spacing_type
,
127 list
.p
[i
]->spacing_type
);
129 for (i
= 0; i
< list
.len
; i
++)
130 if (!list
.p
[i
]->is_simple()) {
131 int r
= list
.p
[i
]->compute_metrics(style
);
134 error("multiple marks and lineups");
136 compute_sublist_width(i
);
137 printf(".nr " MARK_REG
" +\\n[" TEMP_REG
"]\n");
142 printf(".nr " WIDTH_FORMAT
" %dM", uid
, total_spacing
);
143 for (i
= 0; i
< list
.len
; i
++)
144 if (!list
.p
[i
]->is_simple())
145 printf("+\\n[" WIDTH_FORMAT
"]", list
.p
[i
]->uid
);
147 printf(".nr " HEIGHT_FORMAT
" 0", uid
);
148 for (i
= 0; i
< list
.len
; i
++)
149 if (!list
.p
[i
]->is_simple())
150 printf(">?\\n[" HEIGHT_FORMAT
"]", list
.p
[i
]->uid
);
152 printf(".nr " DEPTH_FORMAT
" 0", uid
);
153 for (i
= 0; i
< list
.len
; i
++)
154 if (!list
.p
[i
]->is_simple())
155 printf(">?\\n[" DEPTH_FORMAT
"]", list
.p
[i
]->uid
);
158 for (i
= 0; i
< list
.len
&& !have_simple
; i
++)
159 have_simple
= list
.p
[i
]->is_simple();
161 printf(".nr " WIDTH_FORMAT
" +\\w" DELIMITER_CHAR
, uid
);
162 for (i
= 0; i
< list
.len
; i
++)
163 if (list
.p
[i
]->is_simple())
165 printf(DELIMITER_CHAR
"\n");
166 printf(".nr " HEIGHT_FORMAT
" \\n[rst]>?\\n[" HEIGHT_FORMAT
"]\n",
168 printf(".nr " DEPTH_FORMAT
" 0-\\n[rsb]>?\\n[" DEPTH_FORMAT
"]\n",
174 void list_box::compute_sublist_width(int n
)
176 int total_spacing
= 0;
178 for (i
= 1; i
< n
+ 1 && i
< list
.len
; i
++)
179 total_spacing
+= compute_spacing(is_script
, list
.p
[i
-1]->spacing_type
,
180 list
.p
[i
]->spacing_type
);
181 printf(".nr " TEMP_REG
" %dM", total_spacing
);
182 for (i
= 0; i
< n
; i
++)
183 if (!list
.p
[i
]->is_simple())
184 printf("+\\n[" WIDTH_FORMAT
"]", list
.p
[i
]->uid
);
186 for (i
= 0; i
< n
&& !have_simple
; i
++)
187 have_simple
= list
.p
[i
]->is_simple();
189 printf("+\\w" DELIMITER_CHAR
);
190 for (i
= 0; i
< n
; i
++)
191 if (list
.p
[i
]->is_simple())
193 printf(DELIMITER_CHAR
);
198 void list_box::compute_subscript_kern()
200 // We can only call compute_subscript_kern if we have called
201 // compute_metrics first.
202 if (list
.p
[list
.len
-1]->is_simple())
203 list
.p
[list
.len
-1]->compute_metrics(sty
);
204 list
.p
[list
.len
-1]->compute_subscript_kern();
205 printf(".nr " SUB_KERN_FORMAT
" \\n[" SUB_KERN_FORMAT
"]\n",
206 uid
, list
.p
[list
.len
-1]->uid
);
209 void list_box::output()
211 if (output_format
== mathml
)
213 for (int i
= 0; i
< list
.len
; i
++) {
214 if (output_format
== troff
&& i
> 0) {
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
);
223 if (output_format
== mathml
)
227 void list_box::handle_char_type(int st
, int ft
)
229 for (int i
= 0; i
< list
.len
; i
++)
230 list
.p
[i
]->handle_char_type(st
, ft
);
233 void list_box::debug_print()
235 list
.list_debug_print(" ");
238 void list_box::check_tabs(int level
)
240 list
.list_check_tabs(level
);