1 /*@ piles and matrices.
3 * Copyright (c) 2014 - 2015 Steffen (Daode) Nurpmeso <sdaoden@users.sf.net>.
5 * Copyright (C) 1989 - 1992, 2004, 2007
6 * Free Software Foundation, Inc.
7 * Written by James Clark (jjc@jclark.com)
9 * This 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 * This 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.
25 #include "eqn-config.h"
30 // SUP_RAISE_FORMAT gives the first baseline
31 // BASELINE_SEP_FORMAT gives the separation between baselines
33 int pile_box::compute_metrics(int style
)
36 for (i
= 0; i
< col
.len
; i
++)
37 col
.p
[i
]->compute_metrics(style
);
38 printf(".nr " WIDTH_FORMAT
" 0", uid
);
39 for (i
= 0; i
< col
.len
; i
++)
40 printf(">?\\n[" WIDTH_FORMAT
"]", col
.p
[i
]->uid
);
42 printf(".nr " BASELINE_SEP_FORMAT
" %dM",
43 uid
, baseline_sep
+col
.space
);
44 for (i
= 1; i
< col
.len
; i
++)
45 printf(">?(\\n[" DEPTH_FORMAT
"]+\\n[" HEIGHT_FORMAT
"]+%dM)",
46 col
.p
[i
-1]->uid
, col
.p
[i
]->uid
, default_rule_thickness
*5);
47 // round it so that it's a multiple of the vertical resolution
48 printf("+(\\n(.V/2)/\\n(.V*\\n(.V\n");
50 printf(".nr " SUP_RAISE_FORMAT
" \\n[" BASELINE_SEP_FORMAT
"]*%d/2"
52 uid
, uid
, col
.len
-1, axis_height
- shift_down
);
53 printf(".nr " HEIGHT_FORMAT
" \\n[" SUP_RAISE_FORMAT
"]+\\n["
55 uid
, uid
, col
.p
[0]->uid
);
56 printf(".nr " DEPTH_FORMAT
" \\n[" BASELINE_SEP_FORMAT
"]*%d+\\n["
57 DEPTH_FORMAT
"]-\\n[" SUP_RAISE_FORMAT
"]\n",
58 uid
, uid
, col
.len
-1, col
.p
[col
.len
-1]->uid
, uid
);
62 void pile_box::output()
64 if (output_format
== troff
) {
66 printf("\\v'-\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
67 for (i
= 0; i
< col
.len
; i
++) {
72 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u/2u'",
76 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u'",
83 printf("\\h'-\\n[" WIDTH_FORMAT
"]u'", col
.p
[i
]->uid
);
88 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u/2u'",
92 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u'",
99 printf("\\v'\\n[" BASELINE_SEP_FORMAT
"]u'", uid
);
101 printf("\\v'\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
102 printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT
"]u)'", col
.len
- 1, uid
);
103 printf("\\h'\\n[" WIDTH_FORMAT
"]u'", uid
);
105 else if (output_format
== mathml
) {
120 printf("<mtable columnalign='%s'>", av
);
121 for (int i
= 0; i
< col
.len
; i
++) {
122 printf("<mtr><mtd>");
124 printf("</mtd></mtr>");
130 pile_box::pile_box(box
*pp
) : col(pp
)
134 void pile_box::check_tabs(int level
)
136 col
.list_check_tabs(level
);
139 void pile_box::debug_print()
141 col
.debug_print("pile");
144 int matrix_box::compute_metrics(int style
)
149 for (i
= 0; i
< len
; i
++) {
150 for (j
= 0; j
< p
[i
]->len
; j
++)
151 p
[i
]->p
[j
]->compute_metrics(style
);
152 if (p
[i
]->len
> max_len
)
154 if (p
[i
]->space
> space
)
157 for (i
= 0; i
< len
; i
++) {
158 printf(".nr " COLUMN_WIDTH_FORMAT
" 0", uid
, i
);
159 for (j
= 0; j
< p
[i
]->len
; j
++)
160 printf(">?\\n[" WIDTH_FORMAT
"]", p
[i
]->p
[j
]->uid
);
163 printf(".nr " WIDTH_FORMAT
" %dM",
164 uid
, column_sep
*(len
-1)+2*matrix_side_sep
);
165 for (i
= 0; i
< len
; i
++)
166 printf("+\\n[" COLUMN_WIDTH_FORMAT
"]", uid
, i
);
168 printf(".nr " BASELINE_SEP_FORMAT
" %dM",
169 uid
, baseline_sep
+space
);
170 for (i
= 0; i
< len
; i
++)
171 for (j
= 1; j
< p
[i
]->len
; j
++)
172 printf(">?(\\n[" DEPTH_FORMAT
"]+\\n[" HEIGHT_FORMAT
"]+%dM)",
173 p
[i
]->p
[j
-1]->uid
, p
[i
]->p
[j
]->uid
, default_rule_thickness
*5);
174 // round it so that it's a multiple of the vertical resolution
175 printf("+(\\n(.V/2)/\\n(.V*\\n(.V\n");
176 printf(".nr " SUP_RAISE_FORMAT
" \\n[" BASELINE_SEP_FORMAT
"]*%d/2"
178 uid
, uid
, max_len
-1, axis_height
- shift_down
);
179 printf(".nr " HEIGHT_FORMAT
" 0\\n[" SUP_RAISE_FORMAT
"]+(0",
181 for (i
= 0; i
< len
; i
++)
182 printf(">?\\n[" HEIGHT_FORMAT
"]", p
[i
]->p
[0]->uid
);
184 printf(".nr " DEPTH_FORMAT
" \\n[" BASELINE_SEP_FORMAT
"]*%d-\\n["
185 SUP_RAISE_FORMAT
"]+(0",
186 uid
, uid
, max_len
-1, uid
);
187 for (i
= 0; i
< len
; i
++)
188 if (p
[i
]->len
== max_len
)
189 printf(">?\\n[" DEPTH_FORMAT
"]", p
[i
]->p
[max_len
-1]->uid
);
191 return FOUND_NOTHING
;
194 void matrix_box::output()
196 if (output_format
== troff
) {
197 printf("\\h'%dM'", matrix_side_sep
);
198 for (int i
= 0; i
< len
; i
++) {
200 printf("\\v'-\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
201 for (j
= 0; j
< p
[i
]->len
; j
++) {
202 switch (p
[i
]->align
) {
206 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u/2u'",
207 uid
, i
, p
[i
]->p
[j
]->uid
);
210 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u'",
211 uid
, i
, p
[i
]->p
[j
]->uid
);
216 p
[i
]->p
[j
]->output();
217 printf("\\h'-\\n[" WIDTH_FORMAT
"]u'", p
[i
]->p
[j
]->uid
);
218 switch (p
[i
]->align
) {
222 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" COLUMN_WIDTH_FORMAT
"]u/2u'",
223 p
[i
]->p
[j
]->uid
, uid
, i
);
226 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" COLUMN_WIDTH_FORMAT
"]u'",
227 p
[i
]->p
[j
]->uid
, uid
, i
);
232 if (j
!= p
[i
]->len
- 1)
233 printf("\\v'\\n[" BASELINE_SEP_FORMAT
"]u'", uid
);
235 printf("\\v'\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
236 printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT
"]u)'", p
[i
]->len
- 1, uid
);
237 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT
"]u'", uid
, i
);
239 printf("\\h'%dM'", column_sep
);
241 printf("\\h'%dM'", matrix_side_sep
);
243 else if (output_format
== mathml
) {
244 int n
= p
[0]->len
; // Each column must have the same number of rows in it
246 for (int i
= 0; i
< n
; i
++) {
248 for (int j
= 0; j
< len
; j
++) {
250 switch (p
[j
]->align
) {
263 printf("<mtd columnalign='%s'>", av
);
264 p
[j
]->p
[i
]->output();
273 matrix_box::matrix_box(column
*pp
)
276 for (int i
= 0; i
< 10; i
++)
283 matrix_box::~matrix_box()
285 for (int i
= 0; i
< len
; i
++)
290 void matrix_box::append(column
*pp
)
292 if (len
+ 1 > maxlen
) {
295 p
= new column
*[maxlen
];
296 memcpy(p
, oldp
, sizeof(column
*)*len
);
302 void matrix_box::check_tabs(int level
)
304 for (int i
= 0; i
< len
; i
++)
305 p
[i
]->list_check_tabs(level
);
308 void matrix_box::debug_print()
310 fprintf(stderr
, "matrix { ");
311 p
[0]->debug_print("col");
312 for (int i
= 1; i
< len
; i
++) {
313 fprintf(stderr
, " ");
314 p
[i
]->debug_print("col");
316 fprintf(stderr
, " }");
319 column::column(box
*pp
) : box_list(pp
), align(CENTER_ALIGN
), space(0)
323 void column::set_alignment(alignment a
)
328 void column::set_space(int n
)
333 void column::debug_print(const char *s
)
335 char c
= '\0'; // shut up -Wall
349 fprintf(stderr
, "%c%s %d { ", c
, s
, space
);
350 list_debug_print(" above ");
351 fprintf(stderr
, " }");