2 /* Copyright (C) 1989, 1990, 1991, 1992, 2004, 2007
3 Free Software Foundation, Inc.
4 Written by James Clark (jjc@jclark.com)
6 This file is part of groff.
8 groff is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 groff is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License along
19 with groff; see the file COPYING. If not, write to the Free Software
20 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
26 // SUP_RAISE_FORMAT gives the first baseline
27 // BASELINE_SEP_FORMAT gives the separation between baselines
29 int pile_box::compute_metrics(int style
)
32 for (i
= 0; i
< col
.len
; i
++)
33 col
.p
[i
]->compute_metrics(style
);
34 printf(".nr " WIDTH_FORMAT
" 0", uid
);
35 for (i
= 0; i
< col
.len
; i
++)
36 printf(">?\\n[" WIDTH_FORMAT
"]", col
.p
[i
]->uid
);
38 printf(".nr " BASELINE_SEP_FORMAT
" %dM",
39 uid
, baseline_sep
+col
.space
);
40 for (i
= 1; i
< col
.len
; i
++)
41 printf(">?(\\n[" DEPTH_FORMAT
"]+\\n[" HEIGHT_FORMAT
"]+%dM)",
42 col
.p
[i
-1]->uid
, col
.p
[i
]->uid
, default_rule_thickness
*5);
43 // round it so that it's a multiple of the vertical resolution
44 printf("/\\n(.V+(\\n(.V/2)*\\n(.V\n");
46 printf(".nr " SUP_RAISE_FORMAT
" \\n[" BASELINE_SEP_FORMAT
"]*%d/2"
48 uid
, uid
, col
.len
-1, axis_height
- shift_down
);
49 printf(".nr " HEIGHT_FORMAT
" \\n[" SUP_RAISE_FORMAT
"]+\\n["
51 uid
, uid
, col
.p
[0]->uid
);
52 printf(".nr " DEPTH_FORMAT
" \\n[" BASELINE_SEP_FORMAT
"]*%d+\\n["
53 DEPTH_FORMAT
"]-\\n[" SUP_RAISE_FORMAT
"]\n",
54 uid
, uid
, col
.len
-1, col
.p
[col
.len
-1]->uid
, uid
);
58 void pile_box::output()
60 if (output_format
== troff
) {
62 printf("\\v'-\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
63 for (i
= 0; i
< col
.len
; i
++) {
68 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u/2u'",
72 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u'",
79 printf("\\h'-\\n[" WIDTH_FORMAT
"]u'", col
.p
[i
]->uid
);
84 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u/2u'",
88 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u'",
95 printf("\\v'\\n[" BASELINE_SEP_FORMAT
"]u'", uid
);
97 printf("\\v'\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
98 printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT
"]u)'", col
.len
- 1, uid
);
99 printf("\\h'\\n[" WIDTH_FORMAT
"]u'", uid
);
101 else if (output_format
== mathml
) {
116 printf("<mtable columnalign='%s'>", av
);
117 for (int i
= 0; i
< col
.len
; i
++) {
118 printf("<mtr><mtd>");
120 printf("</mtd></mtr>");
126 pile_box::pile_box(box
*pp
) : col(pp
)
130 void pile_box::check_tabs(int level
)
132 col
.list_check_tabs(level
);
135 void pile_box::debug_print()
137 col
.debug_print("pile");
140 int matrix_box::compute_metrics(int style
)
145 for (i
= 0; i
< len
; i
++) {
146 for (j
= 0; j
< p
[i
]->len
; j
++)
147 p
[i
]->p
[j
]->compute_metrics(style
);
148 if (p
[i
]->len
> max_len
)
150 if (p
[i
]->space
> space
)
153 for (i
= 0; i
< len
; i
++) {
154 printf(".nr " COLUMN_WIDTH_FORMAT
" 0", uid
, i
);
155 for (j
= 0; j
< p
[i
]->len
; j
++)
156 printf(">?\\n[" WIDTH_FORMAT
"]", p
[i
]->p
[j
]->uid
);
159 printf(".nr " WIDTH_FORMAT
" %dM",
160 uid
, column_sep
*(len
-1)+2*matrix_side_sep
);
161 for (i
= 0; i
< len
; i
++)
162 printf("+\\n[" COLUMN_WIDTH_FORMAT
"]", uid
, i
);
164 printf(".nr " BASELINE_SEP_FORMAT
" %dM",
165 uid
, baseline_sep
+space
);
166 for (i
= 0; i
< len
; i
++)
167 for (j
= 1; j
< p
[i
]->len
; j
++)
168 printf(">?(\\n[" DEPTH_FORMAT
"]+\\n[" HEIGHT_FORMAT
"]+%dM)",
169 p
[i
]->p
[j
-1]->uid
, p
[i
]->p
[j
]->uid
, default_rule_thickness
*5);
170 // round it so that it's a multiple of the vertical resolution
171 printf("/\\n(.V+(\\n(.V/2)*\\n(.V\n");
172 printf(".nr " SUP_RAISE_FORMAT
" \\n[" BASELINE_SEP_FORMAT
"]*%d/2"
174 uid
, uid
, max_len
-1, axis_height
- shift_down
);
175 printf(".nr " HEIGHT_FORMAT
" 0\\n[" SUP_RAISE_FORMAT
"]+(0",
177 for (i
= 0; i
< len
; i
++)
178 printf(">?\\n[" HEIGHT_FORMAT
"]", p
[i
]->p
[0]->uid
);
180 printf(".nr " DEPTH_FORMAT
" \\n[" BASELINE_SEP_FORMAT
"]*%d-\\n["
181 SUP_RAISE_FORMAT
"]+(0",
182 uid
, uid
, max_len
-1, uid
);
183 for (i
= 0; i
< len
; i
++)
184 if (p
[i
]->len
== max_len
)
185 printf(">?\\n[" DEPTH_FORMAT
"]", p
[i
]->p
[max_len
-1]->uid
);
187 return FOUND_NOTHING
;
190 void matrix_box::output()
192 if (output_format
== troff
) {
193 printf("\\h'%dM'", matrix_side_sep
);
194 for (int i
= 0; i
< len
; i
++) {
196 printf("\\v'-\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
197 for (j
= 0; j
< p
[i
]->len
; j
++) {
198 switch (p
[i
]->align
) {
202 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u/2u'",
203 uid
, i
, p
[i
]->p
[j
]->uid
);
206 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u'",
207 uid
, i
, p
[i
]->p
[j
]->uid
);
212 p
[i
]->p
[j
]->output();
213 printf("\\h'-\\n[" WIDTH_FORMAT
"]u'", p
[i
]->p
[j
]->uid
);
214 switch (p
[i
]->align
) {
218 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" COLUMN_WIDTH_FORMAT
"]u/2u'",
219 p
[i
]->p
[j
]->uid
, uid
, i
);
222 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" COLUMN_WIDTH_FORMAT
"]u'",
223 p
[i
]->p
[j
]->uid
, uid
, i
);
228 if (j
!= p
[i
]->len
- 1)
229 printf("\\v'\\n[" BASELINE_SEP_FORMAT
"]u'", uid
);
231 printf("\\v'\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
232 printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT
"]u)'", p
[i
]->len
- 1, uid
);
233 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT
"]u'", uid
, i
);
235 printf("\\h'%dM'", column_sep
);
237 printf("\\h'%dM'", matrix_side_sep
);
239 else if (output_format
== mathml
) {
240 int n
= p
[0]->len
; // Each column must have the same number of rows in it
242 for (int i
= 0; i
< n
; i
++) {
244 for (int j
= 0; j
< len
; j
++) {
246 switch (p
[j
]->align
) {
259 printf("<mtd columnalign='%s'>", av
);
260 p
[j
]->p
[i
]->output();
269 matrix_box::matrix_box(column
*pp
)
272 for (int i
= 0; i
< 10; i
++)
279 matrix_box::~matrix_box()
281 for (int i
= 0; i
< len
; i
++)
286 void matrix_box::append(column
*pp
)
288 if (len
+ 1 > maxlen
) {
291 p
= new column
*[maxlen
];
292 memcpy(p
, oldp
, sizeof(column
*)*len
);
298 void matrix_box::check_tabs(int level
)
300 for (int i
= 0; i
< len
; i
++)
301 p
[i
]->list_check_tabs(level
);
304 void matrix_box::debug_print()
306 fprintf(stderr
, "matrix { ");
307 p
[0]->debug_print("col");
308 for (int i
= 1; i
< len
; i
++) {
309 fprintf(stderr
, " ");
310 p
[i
]->debug_print("col");
312 fprintf(stderr
, " }");
315 column::column(box
*pp
) : box_list(pp
), align(CENTER_ALIGN
), space(0)
319 void column::set_alignment(alignment a
)
324 void column::set_space(int n
)
329 void column::debug_print(const char *s
)
331 char c
= '\0'; // shut up -Wall
345 fprintf(stderr
, "%c%s %d { ", c
, s
, space
);
346 list_debug_print(" above ");
347 fprintf(stderr
, " }");