1 /*@ piles and matrices.
3 * Copyright (c) 2014 - 2017 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
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
) {
116 // FALLTHRU (pacify compiler)
121 printf("<mtable columnalign='%s'>", av
);
122 for (int i
= 0; i
< col
.len
; i
++) {
123 printf("<mtr><mtd>");
125 printf("</mtd></mtr>");
131 pile_box::pile_box(box
*pp
) : col(pp
)
135 void pile_box::check_tabs(int level
)
137 col
.list_check_tabs(level
);
140 void pile_box::debug_print()
142 col
.debug_print("pile");
145 int matrix_box::compute_metrics(int style
)
150 for (i
= 0; i
< len
; i
++) {
151 for (j
= 0; j
< p
[i
]->len
; j
++)
152 p
[i
]->p
[j
]->compute_metrics(style
);
153 if (p
[i
]->len
> max_len
)
155 if (p
[i
]->space
> space
)
158 for (i
= 0; i
< len
; i
++) {
159 printf(".nr " COLUMN_WIDTH_FORMAT
" 0", uid
, i
);
160 for (j
= 0; j
< p
[i
]->len
; j
++)
161 printf(">?\\n[" WIDTH_FORMAT
"]", p
[i
]->p
[j
]->uid
);
164 printf(".nr " WIDTH_FORMAT
" %dM",
165 uid
, column_sep
*(len
-1)+2*matrix_side_sep
);
166 for (i
= 0; i
< len
; i
++)
167 printf("+\\n[" COLUMN_WIDTH_FORMAT
"]", uid
, i
);
169 printf(".nr " BASELINE_SEP_FORMAT
" %dM",
170 uid
, baseline_sep
+space
);
171 for (i
= 0; i
< len
; i
++)
172 for (j
= 1; j
< p
[i
]->len
; j
++)
173 printf(">?(\\n[" DEPTH_FORMAT
"]+\\n[" HEIGHT_FORMAT
"]+%dM)",
174 p
[i
]->p
[j
-1]->uid
, p
[i
]->p
[j
]->uid
, default_rule_thickness
*5);
175 // round it so that it's a multiple of the vertical resolution
176 printf("+(\\n(.V/2)/\\n(.V*\\n(.V\n");
177 printf(".nr " SUP_RAISE_FORMAT
" \\n[" BASELINE_SEP_FORMAT
"]*%d/2"
179 uid
, uid
, max_len
-1, axis_height
- shift_down
);
180 printf(".nr " HEIGHT_FORMAT
" 0\\n[" SUP_RAISE_FORMAT
"]+(0",
182 for (i
= 0; i
< len
; i
++)
183 printf(">?\\n[" HEIGHT_FORMAT
"]", p
[i
]->p
[0]->uid
);
185 printf(".nr " DEPTH_FORMAT
" \\n[" BASELINE_SEP_FORMAT
"]*%d-\\n["
186 SUP_RAISE_FORMAT
"]+(0",
187 uid
, uid
, max_len
-1, uid
);
188 for (i
= 0; i
< len
; i
++)
189 if (p
[i
]->len
== max_len
)
190 printf(">?\\n[" DEPTH_FORMAT
"]", p
[i
]->p
[max_len
-1]->uid
);
192 return FOUND_NOTHING
;
195 void matrix_box::output()
197 if (output_format
== troff
) {
198 printf("\\h'%dM'", matrix_side_sep
);
199 for (int i
= 0; i
< len
; i
++) {
201 printf("\\v'-\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
202 for (j
= 0; j
< p
[i
]->len
; j
++) {
203 switch (p
[i
]->align
) {
207 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u/2u'",
208 uid
, i
, p
[i
]->p
[j
]->uid
);
211 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u'",
212 uid
, i
, p
[i
]->p
[j
]->uid
);
217 p
[i
]->p
[j
]->output();
218 printf("\\h'-\\n[" WIDTH_FORMAT
"]u'", p
[i
]->p
[j
]->uid
);
219 switch (p
[i
]->align
) {
223 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" COLUMN_WIDTH_FORMAT
"]u/2u'",
224 p
[i
]->p
[j
]->uid
, uid
, i
);
227 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" COLUMN_WIDTH_FORMAT
"]u'",
228 p
[i
]->p
[j
]->uid
, uid
, i
);
233 if (j
!= p
[i
]->len
- 1)
234 printf("\\v'\\n[" BASELINE_SEP_FORMAT
"]u'", uid
);
236 printf("\\v'\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
237 printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT
"]u)'", p
[i
]->len
- 1, uid
);
238 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT
"]u'", uid
, i
);
240 printf("\\h'%dM'", column_sep
);
242 printf("\\h'%dM'", matrix_side_sep
);
244 else if (output_format
== mathml
) {
245 int n
= p
[0]->len
; // Each column must have the same number of rows in it
247 for (int i
= 0; i
< n
; i
++) {
249 for (int j
= 0; j
< len
; j
++) {
251 switch (p
[j
]->align
) {
260 // FALLTHRU (pacify compiler)
265 printf("<mtd columnalign='%s'>", av
);
266 p
[j
]->p
[i
]->output();
275 matrix_box::matrix_box(column
*pp
)
278 for (int i
= 0; i
< 10; i
++)
285 matrix_box::~matrix_box()
287 for (int i
= 0; i
< len
; i
++)
292 void matrix_box::append(column
*pp
)
294 if (len
+ 1 > maxlen
) {
297 p
= new column
*[maxlen
];
298 memcpy(p
, oldp
, sizeof(column
*)*len
);
304 void matrix_box::check_tabs(int level
)
306 for (int i
= 0; i
< len
; i
++)
307 p
[i
]->list_check_tabs(level
);
310 void matrix_box::debug_print()
312 fprintf(stderr
, "matrix { ");
313 p
[0]->debug_print("col");
314 for (int i
= 1; i
< len
; i
++) {
315 fprintf(stderr
, " ");
316 p
[i
]->debug_print("col");
318 fprintf(stderr
, " }");
321 column::column(box
*pp
) : box_list(pp
), align(CENTER_ALIGN
), space(0)
325 void column::set_alignment(alignment a
)
330 void column::set_space(int n
)
335 void column::debug_print(const char *s
)
337 char c
= '\0'; // shut up -Wall
351 fprintf(stderr
, "%c%s %d { ", c
, s
, space
);
352 list_debug_print(" above ");
353 fprintf(stderr
, " }");