2 /* Copyright (C) 1989-2018 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 3 of the License, or
10 (at your option) any later version.
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
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 // SUP_RAISE_FORMAT gives the first baseline
25 // BASELINE_SEP_FORMAT gives the separation between baselines
27 int pile_box::compute_metrics(int style)
30 for (i = 0; i < col.len; i++)
31 col.p[i]->compute_metrics(style);
32 printf(".nr " WIDTH_FORMAT " 0", uid);
33 for (i = 0; i < col.len; i++)
34 printf(">?\\n[" WIDTH_FORMAT "]", col.p[i]->uid);
36 printf(".nr " BASELINE_SEP_FORMAT " %dM",
37 uid, baseline_sep+col.space);
38 for (i = 1; i < col.len; i++)
39 printf(">?(\\n[" DEPTH_FORMAT "]+\\n[" HEIGHT_FORMAT "]+%dM)",
40 col.p[i-1]->uid, col.p[i]->uid, default_rule_thickness*5);
41 // round it so that it's a multiple of the vertical resolution
42 printf("+(\\n(.V/2)/\\n(.V*\\n(.V\n");
44 printf(".nr " SUP_RAISE_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d/2"
46 uid, uid, col.len-1, axis_height - shift_down);
47 printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
49 uid, uid, col.p[0]->uid);
50 printf(".nr " DEPTH_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d+\\n["
51 DEPTH_FORMAT "]-\\n[" SUP_RAISE_FORMAT "]\n",
52 uid, uid, col.len-1, col.p[col.len-1]->uid, uid);
56 void pile_box::output()
58 if (output_format == troff) {
60 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
61 for (i = 0; i < col.len; i++) {
66 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
70 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
77 printf("\\h'-\\n[" WIDTH_FORMAT "]u'", col.p[i]->uid);
82 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
86 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
93 printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid);
95 printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
96 printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT "]u)'", col.len - 1, uid);
97 printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
99 else if (output_format == mathml) {
114 printf("<mtable columnalign='%s'>", av);
115 for (int i = 0; i < col.len; i++) {
116 printf("<mtr><mtd>");
118 printf("</mtd></mtr>");
124 pile_box::pile_box(box *pp) : col(pp)
128 void pile_box::check_tabs(int level)
130 col.list_check_tabs(level);
133 void pile_box::debug_print()
135 col.debug_print("pile");
138 int matrix_box::compute_metrics(int style)
143 for (i = 0; i < len; i++) {
144 for (j = 0; j < p[i]->len; j++)
145 p[i]->p[j]->compute_metrics(style);
146 if (p[i]->len > max_len)
148 if (p[i]->space > space)
151 for (i = 0; i < len; i++) {
152 printf(".nr " COLUMN_WIDTH_FORMAT " 0", uid, i);
153 for (j = 0; j < p[i]->len; j++)
154 printf(">?\\n[" WIDTH_FORMAT "]", p[i]->p[j]->uid);
157 printf(".nr " WIDTH_FORMAT " %dM",
158 uid, column_sep*(len-1)+2*matrix_side_sep);
159 for (i = 0; i < len; i++)
160 printf("+\\n[" COLUMN_WIDTH_FORMAT "]", uid, i);
162 printf(".nr " BASELINE_SEP_FORMAT " %dM",
163 uid, baseline_sep+space);
164 for (i = 0; i < len; i++)
165 for (j = 1; j < p[i]->len; j++)
166 printf(">?(\\n[" DEPTH_FORMAT "]+\\n[" HEIGHT_FORMAT "]+%dM)",
167 p[i]->p[j-1]->uid, p[i]->p[j]->uid, default_rule_thickness*5);
168 // round it so that it's a multiple of the vertical resolution
169 printf("+(\\n(.V/2)/\\n(.V*\\n(.V\n");
170 printf(".nr " SUP_RAISE_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d/2"
172 uid, uid, max_len-1, axis_height - shift_down);
173 printf(".nr " HEIGHT_FORMAT " 0\\n[" SUP_RAISE_FORMAT "]+(0",
175 for (i = 0; i < len; i++)
176 printf(">?\\n[" HEIGHT_FORMAT "]", p[i]->p[0]->uid);
178 printf(".nr " DEPTH_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d-\\n["
179 SUP_RAISE_FORMAT "]+(0",
180 uid, uid, max_len-1, uid);
181 for (i = 0; i < len; i++)
182 if (p[i]->len == max_len)
183 printf(">?\\n[" DEPTH_FORMAT "]", p[i]->p[max_len-1]->uid);
185 return FOUND_NOTHING;
188 void matrix_box::output()
190 if (output_format == troff) {
191 printf("\\h'%dM'", matrix_side_sep);
192 for (int i = 0; i < len; i++) {
194 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
195 for (j = 0; j < p[i]->len; j++) {
196 switch (p[i]->align) {
200 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
201 uid, i, p[i]->p[j]->uid);
204 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
205 uid, i, p[i]->p[j]->uid);
210 p[i]->p[j]->output();
211 printf("\\h'-\\n[" WIDTH_FORMAT "]u'", p[i]->p[j]->uid);
212 switch (p[i]->align) {
216 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" COLUMN_WIDTH_FORMAT "]u/2u'",
217 p[i]->p[j]->uid, uid, i);
220 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" COLUMN_WIDTH_FORMAT "]u'",
221 p[i]->p[j]->uid, uid, i);
226 if (j != p[i]->len - 1)
227 printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid);
229 printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
230 printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT "]u)'", p[i]->len - 1, uid);
231 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u'", uid, i);
233 printf("\\h'%dM'", column_sep);
235 printf("\\h'%dM'", matrix_side_sep);
237 else if (output_format == mathml) {
238 int n = p[0]->len; // Each column must have the same number of rows in it
240 for (int i = 0; i < n; i++) {
242 for (int j = 0; j < len; j++) {
244 switch (p[j]->align) {
257 printf("<mtd columnalign='%s'>", av);
258 p[j]->p[i]->output();
267 matrix_box::matrix_box(column *pp)
270 for (int i = 0; i < 10; i++)
277 matrix_box::~matrix_box()
279 for (int i = 0; i < len; i++)
284 void matrix_box::append(column *pp)
286 if (len + 1 > maxlen) {
289 p = new column*[maxlen];
290 memcpy(p, oldp, sizeof(column*)*len);
296 void matrix_box::check_tabs(int level)
298 for (int i = 0; i < len; i++)
299 p[i]->list_check_tabs(level);
302 void matrix_box::debug_print()
304 fprintf(stderr, "matrix { ");
305 p[0]->debug_print("col");
306 for (int i = 1; i < len; i++) {
307 fprintf(stderr, " ");
308 p[i]->debug_print("col");
310 fprintf(stderr, " }");
313 column::column(box *pp) : box_list(pp), align(CENTER_ALIGN), space(0)
317 void column::set_alignment(alignment a)
322 void column::set_space(int n)
327 void column::debug_print(const char *s)
329 char c = '\0'; // shut up -Wall
343 fprintf(stderr, "%c%s %d { ", c, s, space);
344 list_debug_print(" above ");
345 fprintf(stderr, " }");