diff --git a/ts/output/chtml/Wrappers/mrow.ts b/ts/output/chtml/Wrappers/mrow.ts
index 8ef1f5e83..e1a8f5036 100644
--- a/ts/output/chtml/Wrappers/mrow.ts
+++ b/ts/output/chtml/Wrappers/mrow.ts
@@ -250,8 +250,7 @@ export const ChtmlMrow = (function (): ChtmlMrowClass {
);
adaptor.setAttribute(parents[i], 'align', align);
if (shift) {
- adaptor.setStyle(parents[i], 'position', 'relative');
- adaptor.setStyle(parents[i], 'left', this.em(shift));
+ adaptor.setStyle(parents[i], 'margin-left', this.em(shift));
}
if (i < n && this.jax.math.display) {
adaptor.setStyle(
diff --git a/ts/output/chtml/Wrappers/mtr.ts b/ts/output/chtml/Wrappers/mtr.ts
index 920807865..4a0b906c6 100644
--- a/ts/output/chtml/Wrappers/mtr.ts
+++ b/ts/output/chtml/Wrappers/mtr.ts
@@ -164,6 +164,8 @@ export const ChtmlMtr = (function (): ChtmlMtrClass {
if (align !== 'baseline') {
this.adaptor.setAttribute(this.dom[0], 'rowalign', align);
}
+ const { h, d } = this.getBBox();
+ this.adaptor.setStyle(this.dom[0], 'height', this.em(h + d));
}
};
})();
diff --git a/ts/output/common/Wrapper.ts b/ts/output/common/Wrapper.ts
index 77a23b491..3dfdeca84 100644
--- a/ts/output/common/Wrapper.ts
+++ b/ts/output/common/Wrapper.ts
@@ -457,7 +457,7 @@ export class CommonWrapper<
* @returns {number} The container width
*/
get containerWidth(): number {
- return this.jax.containerWidth;
+ return this.parent ? this.parent.containerWidth : this.jax.containerWidth;
}
/**
diff --git a/ts/output/common/Wrappers/mpadded.ts b/ts/output/common/Wrappers/mpadded.ts
index 7affee373..35eff53ca 100644
--- a/ts/output/common/Wrappers/mpadded.ts
+++ b/ts/output/common/Wrappers/mpadded.ts
@@ -171,6 +171,18 @@ export function CommonMpaddedMixin<
extends Base
implements CommonMpadded
{
+ get containerWidth(): number {
+ const attributes = this.node.attributes;
+ const w = attributes.get('width') as string;
+ if (
+ !w.match(/^[-+]|%$/) &&
+ attributes.get('data-overflow') === 'linebreak'
+ ) {
+ return this.length2em(w);
+ }
+ return this.parent.containerWidth;
+ }
+
/**
* @override
*/
diff --git a/ts/output/common/Wrappers/mrow.ts b/ts/output/common/Wrappers/mrow.ts
index e33b34f2f..01dd522d8 100644
--- a/ts/output/common/Wrappers/mrow.ts
+++ b/ts/output/common/Wrappers/mrow.ts
@@ -327,7 +327,7 @@ export function CommonMrowMixin<
lines[n].R = this.bbox.R;
} else {
bbox.w = Math.max(...this.lineBBox.map((bbox) => bbox.w)); // natural width
- this.shiftLines(bbox.w);
+ this.shiftLines(bbox);
if (!this.jax.math.display && !this.linebreakOptions.inline) {
bbox.pwidth = BBox.fullWidth;
if (this.node.isInferred) {
@@ -391,11 +391,12 @@ export function CommonMrowMixin<
}
/**
- * Handle alignment and shifting if lines
+ * Handle alignment and shifting of lines
*
- * @param {number} W The width of the container
+ * @param {BBox} BBOX The bounding box of the container
*/
- protected shiftLines(W: number) {
+ protected shiftLines(BBOX: BBox) {
+ const W = BBOX.w;
const lines = this.lineBBox;
const n = lines.length - 1;
const [alignfirst, shiftfirst] = lines[1].indentData?.[0] || [
@@ -417,6 +418,10 @@ export function CommonMrowMixin<
);
bbox.L = 0;
bbox.L = this.getAlignX(W, bbox, align) + shift;
+ const w = bbox.L + bbox.w;
+ if (w > BBOX.w) {
+ BBOX.w = w;
+ }
}
}
@@ -432,7 +437,7 @@ export function CommonMrowMixin<
if (recompute) return false;
if (w !== null && this.bbox.w !== w) {
this.bbox.w = w;
- this.shiftLines(w);
+ this.shiftLines(this.bbox);
}
return true;
}
diff --git a/ts/output/common/Wrappers/mtable.ts b/ts/output/common/Wrappers/mtable.ts
index ee78f71a0..6b588ba9d 100644
--- a/ts/output/common/Wrappers/mtable.ts
+++ b/ts/output/common/Wrappers/mtable.ts
@@ -243,7 +243,6 @@ export interface CommonMtable<
* @param {number[]} D The maximum depth for each of the rows
* @param {number[]} W The maximum width for each column
* @param {number} M The current height for items aligned top and bottom
- * @returns {number} The updated value for M
*/
updateHDW(
cell: WW,
@@ -254,17 +253,7 @@ export interface CommonMtable<
D: number[],
W: number[],
M: number
- ): number;
-
- /**
- * Extend the H and D of a row to cover the maximum height needed by top/bottom aligned items
- *
- * @param {number} i The row whose hight and depth should be adjusted
- * @param {number[]} H The row heights
- * @param {number[]} D The row depths
- * @param {number} M The maximum height of top/bottom aligned items
- */
- extendHD(i: number, H: number[], D: number[], M: number): void;
+ ): void;
/**
* @param {WW} cell The cell to check for percentage widths
@@ -744,21 +733,29 @@ export function CommonMtableMixin<
if (
this.jax.math.root.attributes.get('overflow') !== 'linebreak' ||
!this.jax.math.display
- )
+ ) {
return;
- const { D } = this.getTableData();
+ }
+ const { H, D } = this.getTableData();
let j = 0;
let w = 0;
for (const row of this.tableRows) {
const cell = row.getChild(i);
- if (cell && cell.getBBox().w > W) {
- cell.childNodes[0].breakToWidth(W);
+ if (cell) {
+ const r = row.getBBox().rscale;
const bbox = cell.getBBox();
- D[j] = Math.max(D[j], bbox.d);
- if (bbox.w > w) {
- w = bbox.w;
+ if (cell && bbox.w * r > W) {
+ cell.childNodes[0].breakToWidth(W);
+ const align = row.node.attributes.get('rowalign') as string;
+ this.updateHDW(cell, i, j, align, H, D);
+ }
+ if (bbox.w * r > w) {
+ w = bbox.w * r;
}
}
+ const bbox = row.getBBox();
+ bbox.h = H[j];
+ bbox.d = D[j];
j++;
}
//
@@ -791,27 +788,72 @@ export function CommonMtableMixin<
const LW = [0];
const rows = this.tableRows;
for (let j = 0; j < rows.length; j++) {
- let M = 0;
const row = rows[j];
const align = row.node.attributes.get('rowalign') as string;
for (let i = 0; i < row.numCells; i++) {
const cell = row.getChild(i);
- M = this.updateHDW(cell, i, j, align, H, D, W, M);
+ this.updateHDW(cell, i, j, align, H, D, W);
this.recordPWidthCell(cell, i);
}
NH[j] = H[j];
ND[j] = D[j];
if (row.labeled) {
- M = this.updateHDW(row.childNodes[0], 0, j, align, H, D, LW, M);
+ this.updateHDW(row.childNodes[0], 0, j, align, H, D, LW);
}
- this.extendHD(j, H, D, M);
- this.extendHD(j, NH, ND, M);
+ row.bbox.h = H[j];
+ row.bbox.d = D[j];
}
const L = LW[0];
this.data = { H, D, W, NH, ND, L };
return this.data;
}
+ /**
+ * Functions for adjusting the H and D values for cells
+ * that are aligned by top, bottom, center, axis, and baseline.
+ */
+ protected adjustHD: {
+ [name: string]: (
+ h: number,
+ d: number,
+ H: number[],
+ D: number[],
+ j: number
+ ) => void;
+ } = {
+ top: (h, d, H, D, j) => {
+ if (h > H[j]) {
+ D[j] -= h - H[j];
+ H[j] = h;
+ }
+ if (h + d > H[j] + D[j]) {
+ D[j] = h + d - H[j];
+ }
+ },
+ bottom: (h, d, H, D, j) => {
+ if (d > D[j]) {
+ H[j] -= d - D[j];
+ D[j] = d;
+ }
+ if (h + d > H[j] + D[j]) {
+ H[j] = h + d - D[j];
+ }
+ },
+ center: (h, d, H, D, j) => {
+ if (h + d > H[j] + D[j]) {
+ H[j] = D[j] = (h + d) / 2;
+ }
+ },
+ other: (h, d, H, D, j) => {
+ if (h > H[j]) {
+ H[j] = h;
+ }
+ if (d > D[j]) {
+ D[j] = d;
+ }
+ },
+ };
+
/**
* @override
*/
@@ -822,9 +864,8 @@ export function CommonMtableMixin<
align: string,
H: number[],
D: number[],
- W: number[],
- M: number
- ): number {
+ W: number[] = null
+ ) {
let { h, d, w } = cell.getBBox();
const scale = cell.parent.bbox.rscale;
if (cell.parent.bbox.rscale !== 1) {
@@ -836,27 +877,12 @@ export function CommonMtableMixin<
if (h < 0.75) h = 0.75;
if (d < 0.25) d = 0.25;
}
- let m = 0;
align = (cell.node.attributes.get('rowalign') as string) || align;
- if (align !== 'baseline' && align !== 'axis') {
- m = h + d;
- h = d = 0;
+ if (!Object.hasOwn(this.adjustHD, align)) {
+ align = 'other';
}
- if (h > H[j]) H[j] = h;
- if (d > D[j]) D[j] = d;
- if (m > M) M = m;
+ this.adjustHD[align](h, d, H, D, j);
if (W && w > W[i]) W[i] = w;
- return M;
- }
-
- /**
- * @override
- */
- public extendHD(i: number, H: number[], D: number[], M: number) {
- const d = (M - (H[i] + D[i])) / 2;
- if (d < 0.00001) return;
- H[i] += d;
- D[i] += d;
}
/**