Skip to content

Commit 0ec2894

Browse files
committed
Add support for stretchy cells in tables
1 parent 3b7fd80 commit 0ec2894

File tree

4 files changed

+126
-4
lines changed

4 files changed

+126
-4
lines changed

mathjax3-ts/output/chtml/Wrappers/mo.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -347,16 +347,16 @@ export class CHTMLmo extends CHTMLWrapper {
347347
* @return{number[]} The height and depth for the vertically stretched delimiter
348348
*/
349349
protected getBaseline(WHD: number[], HD: number, C: DelimiterData) {
350-
const hasWHD = (WHD.length === 2);
351-
const symmetric = (hasWHD && this.node.attributes.get('symmetric'));
350+
const hasWHD = (WHD.length === 2 && WHD[0] + WHD[1] === HD);
351+
const symmetric = this.node.attributes.get('symmetric');
352352
const [H, D] = (hasWHD ? WHD : [HD, 0]);
353353
let [h, d] = [H + D, 0];
354354
if (symmetric) {
355355
//
356356
// Center on the math axis
357357
//
358358
const a = this.font.params.axis_height;
359-
h = 2 * Math.max(H - a, D + a);
359+
if (hasWHD) h = 2 * Math.max(H - a, D + a);
360360
d = h / 2 - a;
361361
} else if (hasWHD) {
362362
//

mathjax3-ts/output/chtml/Wrappers/mtable.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {BBox} from '../BBox.js';
2828
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
2929
import {MmlMtable} from '../../../core/MmlTree/MmlNodes/mtable.js';
3030
import {StyleList} from '../CssStyles.js';
31+
import {DIRECTION} from '../FontData.js';
3132

3233
/*****************************************************************/
3334
/*
@@ -71,6 +72,58 @@ export class CHTMLmtable extends CHTMLWrapper {
7172
//
7273
this.numCols = this.childNodes.map(row => (row as CHTMLmtr).numCells).reduce((a, b) => Math.max(a, b));
7374
this.numRows = this.childNodes.length;
75+
//
76+
// Stretch the columns (rows are already taken care of in the CHTMLmtr wrapper)
77+
//
78+
for (let i = 0; i < this.numCols; i++) {
79+
this.stretchColumn(i);
80+
}
81+
}
82+
83+
/*
84+
* Handle horizontal stretching within the ith column
85+
*/
86+
protected stretchColumn(i: number) {
87+
let stretchy: CHTMLWrapper[] = [];
88+
//
89+
// Locate and count the stretchy children
90+
//
91+
for (const row of (this.childNodes as CHTMLmtr[])) {
92+
const cell = row.childNodes[i + row.firstCell];
93+
if (cell) {
94+
const child = cell.childNodes[0];
95+
if (child.stretch.dir === DIRECTION.None && child.canStretch(DIRECTION.Horizontal)) {
96+
stretchy.push(child);
97+
}
98+
}
99+
}
100+
let count = stretchy.length;
101+
let nodeCount = this.childNodes.length;
102+
if (count && nodeCount > 1) {
103+
let W = 0;
104+
//
105+
// If all the children are stretchy, find the largest one,
106+
// otherwise, find the width of the non-stretchy children.
107+
//
108+
let all = (count > 1 && count === nodeCount);
109+
for (const row of (this.childNodes as CHTMLmtr[])) {
110+
const cell = row.childNodes[i + row.firstCell];
111+
if (cell) {
112+
const child = cell.childNodes[0];
113+
const noStretch = (child.stretch.dir === DIRECTION.None);
114+
if (all || noStretch) {
115+
const {w} = child.getBBox(noStretch);
116+
if (w > W) W = w;
117+
}
118+
}
119+
}
120+
//
121+
// Stretch the stretchable children
122+
//
123+
for (const child of stretchy) {
124+
child.coreMO().getStretchedVariant([W]);
125+
}
126+
}
74127
}
75128

76129
/******************************************************************/

mathjax3-ts/output/chtml/Wrappers/mtr.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ import {CHTMLWrapper} from '../Wrapper.js';
2626
import {CHTMLWrapperFactory} from '../WrapperFactory.js';
2727
import {BBox} from '../BBox.js';
2828
import {MmlMtr, MmlMlabeledtr} from '../../../core/MmlTree/MmlNodes/mtr.js';
29+
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
2930
import {StyleList} from '../CssStyles.js';
31+
import {DIRECTION} from '../FontData.js';
3032

3133
/*****************************************************************/
3234
/*
@@ -49,13 +51,73 @@ export class CHTMLmtr extends CHTMLWrapper {
4951
return this.childNodes.length;
5052
}
5153

54+
/*
55+
* @return{number} The index of the first table cell (overridden in mlabeledtr)
56+
*/
57+
get firstCell() {
58+
return 0;
59+
}
60+
5261
/*
5362
* @return{BBox[]} An array of the bounding boxes for the mtd's in the row
5463
*/
5564
public getChildBBoxes() {
5665
return this.childNodes.map(cell => cell.getBBox());
5766
}
5867

68+
/*
69+
* @override
70+
* @constructor
71+
*/
72+
constructor(factory: CHTMLWrapperFactory, node: MmlNode, parent: CHTMLWrapper = null) {
73+
super(factory, node, parent);
74+
this.stretchChildren();
75+
}
76+
77+
/*
78+
* Handle vertical stretching of cells to match height of
79+
* other cells in the row.
80+
*/
81+
protected stretchChildren() {
82+
let stretchy: CHTMLWrapper[] = [];
83+
let children = (this.firstCell ? this.childNodes.slice(this.firstCell) : this.childNodes);
84+
//
85+
// Locate and count the stretchy children
86+
//
87+
for (const mtd of children) {
88+
const child = mtd.childNodes[0];
89+
if (child.canStretch(DIRECTION.Vertical)) {
90+
stretchy.push(child);
91+
}
92+
}
93+
let count = stretchy.length;
94+
let nodeCount = this.childNodes.length;
95+
if (count && nodeCount > 1) {
96+
let H = 0, D = 0;
97+
//
98+
// If all the children are stretchy, find the largest one,
99+
// otherwise, find the height and depth of the non-stretchy
100+
// children.
101+
//
102+
let all = (count > 1 && count === nodeCount);
103+
for (const mtd of children) {
104+
const child = mtd.childNodes[0];
105+
const noStretch = (child.stretch.dir === DIRECTION.None);
106+
if (all || noStretch) {
107+
const {h, d} = child.getBBox(noStretch);
108+
if (h > H) H = h;
109+
if (d > D) D = d;
110+
}
111+
}
112+
//
113+
// Stretch the stretchable children
114+
//
115+
for (const child of stretchy) {
116+
child.coreMO().getStretchedVariant([H, D]);
117+
}
118+
}
119+
}
120+
59121
}
60122

61123
/*****************************************************************/
@@ -96,6 +158,13 @@ export class CHTMLmlabeledtr extends CHTMLWrapper {
96158
return Math.max(0, this.childNodes.length - 1);
97159
}
98160

161+
/*
162+
* @override
163+
*/
164+
get firstCell() {
165+
return 1;
166+
}
167+
99168
/*
100169
* @override
101170
*/

mathjax3-ts/output/chtml/Wrappers/scriptbase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ export class CHTMLscriptbase extends CHTMLWrapper {
284284
let W = 0;
285285
//
286286
// If all the children are stretchy, find the largest one,
287-
// otherwise, find the width of the non-stretchy children.
287+
// otherwise, find the width of the non-stretchy children.
288288
//
289289
let all = (count > 1 && count === nodeCount);
290290
for (const child of this.childNodes) {

0 commit comments

Comments
 (0)