Skip to content

Commit 59dc6b1

Browse files
committed
Merge branch 'fix-label-positions' into master
2 parents 3d01c8d + d178eb5 commit 59dc6b1

File tree

8 files changed

+186
-32
lines changed

8 files changed

+186
-32
lines changed

mathjax3-ts/core/MmlTree/MmlNode.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {Property, PropertyList, Node, AbstractNode, AbstractEmptyNode, NodeClass
2626
import {MmlFactory} from './MmlFactory.js';
2727

2828
/*
29-
* Used in setInheritedAttrbutes() to pass originating node kind as well as property value
29+
* Used in setInheritedAttributes() to pass originating node kind as well as property value
3030
*/
3131
export type AttributeList = {[attribute: string]: [string, Property]};
3232

@@ -67,6 +67,14 @@ const TEXSPACE = [
6767
[ 1, -1, 2, 3, 1, 0, 1, 1] // INNER
6868
];
6969

70+
/*
71+
* Attributes used to determine indentation and shifting
72+
*/
73+
export const indentAttributes = [
74+
'indentalign', 'indentalignfirst',
75+
'indentshift', 'indentshiftfirst'
76+
];
77+
7078

7179
/*****************************************************************/
7280
/*

mathjax3-ts/core/MmlTree/MmlNodes/mtable.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
*/
2323

2424
import {PropertyList, Node} from '../../Tree/Node.js';
25-
import {MmlNode, AbstractMmlNode, AttributeList, TEXCLASS} from '../MmlNode.js';
25+
import {MmlNode, AbstractMmlNode, AttributeList, TEXCLASS, indentAttributes} from '../MmlNode.js';
2626
import {split} from '../../../util/string.js';
2727

2828
/*****************************************************************/
@@ -71,6 +71,25 @@ export class MmlMtable extends AbstractMmlNode {
7171
return true;
7272
}
7373

74+
/*
75+
* @override
76+
*/
77+
setInheritedAttributes(attributes: AttributeList, display: boolean, level: number, prime: boolean) {
78+
//
79+
// Force inheritance of shift and align values (since they are needed to output tables with labels)
80+
// but make sure they are not given explicitly on the <mtable> tag.
81+
//
82+
for (const name of indentAttributes) {
83+
if (attributes[name]) {
84+
this.attributes.setInherited(name, attributes[name][1]);
85+
}
86+
if (this.attributes.getExplicit(name) !== undefined) {
87+
delete (this.attributes.getAllAttributes())[name];
88+
}
89+
}
90+
super.setInheritedAttributes(attributes, display, level, prime);
91+
};
92+
7493
/*
7594
* Make sure all children are mtr or mlabeledtr nodes
7695
* Inherit the table attributes, and set the display attribute based on the table's displaystyle attribute

mathjax3-ts/output/chtml/BBox.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ export type BBoxData = {
5252
*/
5353

5454
export class BBox {
55+
/*
56+
* Constant for pwidth of full width box
57+
*/
58+
public static fullWidth = '100%';
59+
5560
/*
5661
* These are the data stored for a bounding box
5762
*/

mathjax3-ts/output/chtml/Wrapper.ts

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
import {AbstractWrapper} from '../../core/Tree/Wrapper.js';
2525
import {Node, PropertyList} from '../../core/Tree/Node.js';
26-
import {MmlNode, TextNode, AbstractMmlNode, AttributeList} from '../../core/MmlTree/MmlNode.js';
26+
import {MmlNode, TextNode, AbstractMmlNode, AttributeList, indentAttributes} from '../../core/MmlTree/MmlNode.js';
2727
import {MmlMo} from '../../core/MmlTree/MmlNodes/mo.js';
2828
import {Property} from '../../core/Tree/Node.js';
2929
import {OptionList} from '../../util/Options.js';
@@ -291,7 +291,11 @@ export class CHTMLWrapper<N, T, D> extends AbstractWrapper<MmlNode, CHTMLWrapper
291291
this.getScale();
292292
this.getSpace();
293293
this.childNodes = node.childNodes.map((child: Node) => {
294-
return this.wrap(child as MmlNode);
294+
const wrapped = this.wrap(child as MmlNode);
295+
if (wrapped.bbox.pwidth) {
296+
this.bbox.pwidth = BBox.fullWidth;
297+
}
298+
return wrapped;
295299
});
296300
}
297301

@@ -574,6 +578,7 @@ export class CHTMLWrapper<N, T, D> extends AbstractWrapper<MmlNode, CHTMLWrapper
574578
this.handleColor();
575579
this.handleSpace();
576580
this.handleAttributes();
581+
this.handlePWidth();
577582
return chtml;
578583
}
579584

@@ -685,7 +690,8 @@ export class CHTMLWrapper<N, T, D> extends AbstractWrapper<MmlNode, CHTMLWrapper
685690
const defaults = attributes.getAllDefaults();
686691
const skip = CHTMLWrapper.skipAttributes;
687692
for (const name of attributes.getExplicitNames()) {
688-
if (skip[name] === false || (!(name in defaults) && !skip[name] && !this.adaptor.hasAttribute(this.chtml, name))) {
693+
if (skip[name] === false || (!(name in defaults) && !skip[name] &&
694+
!this.adaptor.hasAttribute(this.chtml, name))) {
689695
this.adaptor.setAttribute(this.chtml, name, attributes.getExplicit(name) as string);
690696
}
691697
}
@@ -694,6 +700,19 @@ export class CHTMLWrapper<N, T, D> extends AbstractWrapper<MmlNode, CHTMLWrapper
694700
}
695701
}
696702

703+
/*
704+
* Handle the attributes needed for percentage widths
705+
*/
706+
protected handlePWidth() {
707+
if (this.bbox.pwidth) {
708+
if (this.bbox.pwidth === BBox.fullWidth) {
709+
this.adaptor.setAttribute(this.chtml, 'width', 'full');
710+
} else {
711+
this.adaptor.setStyle(this.chtml, 'width', this.bbox.pwidth);
712+
}
713+
}
714+
}
715+
697716
/*******************************************************************/
698717

699718
/*
@@ -742,6 +761,42 @@ export class CHTMLWrapper<N, T, D> extends AbstractWrapper<MmlNode, CHTMLWrapper
742761
return this.stretch.dir !== DIRECTION.None;
743762
}
744763

764+
/*
765+
* @return{[string, number]} The alignment and indentation shift for the expression
766+
*/
767+
protected getAlignShift() {
768+
let {indentalign, indentshift, indentalignfirst, indentshiftfirst} =
769+
this.node.attributes.getList(...indentAttributes) as StringMap;
770+
if (indentalignfirst !== 'indentalign') {
771+
indentalign = indentalignfirst;
772+
}
773+
if (indentalign === 'auto') {
774+
indentalign = 'center';
775+
}
776+
if (indentshiftfirst !== 'indentshift') {
777+
indentshift = indentshiftfirst;
778+
}
779+
if (indentshift === 'auto') {
780+
indentshift = '0';
781+
}
782+
const shift = this.length2em(indentshift, this.metrics.containerWidth);
783+
return [indentalign, shift] as [string, number];
784+
}
785+
786+
/*
787+
* @param{N} chtml The HTML node whose indentation is to be adjusted
788+
* @param{string} align The alignment for the node
789+
* @param{number} shift The indent (positive or negative) for the node
790+
*/
791+
protected setIndent(chtml: N, align: string, shift: number) {
792+
if (align === 'center' || align === 'left') {
793+
this.adaptor.setStyle(chtml, 'margin-left', this.em(shift));
794+
}
795+
if (align === 'center' || align === 'right') {
796+
this.adaptor.setStyle(chtml, 'margin-right', this.em(-shift));
797+
}
798+
}
799+
745800
/*******************************************************************/
746801
/*
747802
* For debugging

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

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ export class CHTMLmath<N, T, D> extends CHTMLWrapper<N, T, D> {
6161
},
6262
'mjx-chtml.MJX-DISPLAY mjx-math': {
6363
padding: 0
64+
},
65+
'mjx-chtml[justify="left"]': {
66+
'text-align': 'left'
67+
},
68+
'mjx-chtml[justify="right"]': {
69+
'text-align': 'right'
6470
}
6571
};
6672

@@ -69,9 +75,20 @@ export class CHTMLmath<N, T, D> extends CHTMLWrapper<N, T, D> {
6975
*/
7076
public toCHTML(parent: N) {
7177
super.toCHTML(parent);
72-
if (this.node.attributes.get('display') === 'block') {
73-
this.adaptor.setAttribute(this.chtml, 'display', 'true');
74-
this.adaptor.addClass(parent, 'MJX-DISPLAY');
78+
const chtml = this.chtml;
79+
const adaptor = this.adaptor;
80+
const attributes = this.node.attributes;
81+
const display = (attributes.get('display') === 'block');
82+
if (display) {
83+
adaptor.setAttribute(chtml, 'display', 'true');
84+
adaptor.addClass(parent, 'MJX-DISPLAY');
85+
}
86+
const [align, shift] = this.getAlignShift();
87+
if (align !== 'center') {
88+
adaptor.setAttribute(parent, 'justify', align);
89+
}
90+
if (display && shift && !adaptor.hasAttribute(chtml, 'width')) {
91+
this.setIndent(chtml, align, shift);
7592
}
7693
}
7794

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

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ export class CHTMLmrow<N, T, D> extends CHTMLWrapper<N, T, D> {
4646
constructor(factory: CHTMLWrapperFactory<N, T, D>, node: MmlNode, parent: CHTMLWrapper<N, T, D> = null) {
4747
super(factory, node, parent);
4848
this.stretchChildren();
49+
for (const child of this.childNodes) {
50+
if (child.bbox.pwidth) {
51+
this.bbox.pwidth = BBox.fullWidth;
52+
break;
53+
}
54+
}
4955
}
5056

5157
/*
@@ -59,9 +65,6 @@ export class CHTMLmrow<N, T, D> extends CHTMLWrapper<N, T, D> {
5965
if (child.bbox.w < 0) {
6066
hasNegative = true;
6167
}
62-
if (child.bbox.pwidth) {
63-
this.makeFullWidth();
64-
}
6568
}
6669
// FIXME: handle line breaks
6770
if (hasNegative) {
@@ -75,15 +78,6 @@ export class CHTMLmrow<N, T, D> extends CHTMLWrapper<N, T, D> {
7578
}
7679
}
7780

78-
/*
79-
* Handle the case where a child has a percentage width by
80-
* marking the parent as 100% width.
81-
*/
82-
protected makeFullWidth() {
83-
this.bbox.pwidth = '100%';
84-
this.adaptor.setAttribute(this.chtml, 'width', 'full');
85-
}
86-
8781
/*
8882
* Handle vertical stretching of children to match height of
8983
* other nodes in the row.

0 commit comments

Comments
 (0)