Skip to content

Commit

Permalink
wip: layout improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
arnog committed Aug 24, 2023
1 parent aa2c0a3 commit ce844a4
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 46 deletions.
1 change: 1 addition & 0 deletions src/core-atoms/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ export class ArrayAtom extends Atom {
//

const separator = new Box(null, { classes: 'vertical-separator' });
separator.height = totalHeight;
separator.setStyle('height', totalHeight, 'em');
separator.setStyle(
'border-right',
Expand Down
7 changes: 2 additions & 5 deletions src/core-atoms/box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ export class BoxAtom extends Atom {

const offset = parentContext.toEm(this.offset ?? { dimension: 0 });
base.depth += offset;
// base.setStyle('display', 'inline-block');
// base.setStyle('position', 'relative');
// base.setStyle('background-color', 'rgba(255, 0, 0, .2)');
// base.setStyle('vertical-align', raise, 'em');

const context = new Context({ parent: parentContext }, this.style);

Expand All @@ -88,10 +84,11 @@ export class BoxAtom extends Atom {
box.depth = base.depth + padding;
box.setStyle('box-sizing', 'border-box');
box.setStyle('position', 'absolute');

box.setStyle('top', -padding + 0.3, 'em'); // empirical
box.setStyle('left', 0);

box.setStyle('height', box.height + box.depth, 'em');
box.setStyle('left', 0);
box.setStyle('width', '100%');

if (this.backgroundcolor) {
Expand Down
1 change: 1 addition & 0 deletions src/core-atoms/enclose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ export class EncloseAtom extends Atom {
result.setStyle('display', 'inline-block');

// The padding adds to the width and height of the pod
result.width = w - 2 * padding;
result.height = notation.height;
result.depth = notation.depth;
result.left = padding;
Expand Down
34 changes: 18 additions & 16 deletions src/core-atoms/genfrac.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export class GenfracAtom extends Atom {
: Atom.createBox(denomContext, this.below, { type: 'ignore' }) ??
new Box(null, { type: 'ignore' });

const ruleWidth = this.hasBarLine ? metrics.defaultRuleThickness : 0;
const ruleThickness = this.hasBarLine ? metrics.defaultRuleThickness : 0;

// Rule 15b from TeXBook Appendix G, p.444
//
Expand All @@ -163,12 +163,12 @@ export class GenfracAtom extends Atom {
let denomShift: number;
if (fracContext.isDisplayStyle) {
numerShift = numContext.metrics.num1; // Set u ← σ8
clearance = ruleWidth > 0 ? 3 * ruleWidth : 7 * ruleWidth;
clearance = ruleThickness > 0 ? 3 * ruleThickness : 7 * ruleThickness;
denomShift = denomContext.metrics.denom1; // V ← σ11
} else {
if (ruleWidth > 0) {
if (ruleThickness > 0) {
numerShift = numContext.metrics.num2; // U ← σ9
clearance = ruleWidth; // Φ ← θ
clearance = ruleThickness; // Φ ← θ
} else {
numerShift = numContext.metrics.num3; // U ← σ10
clearance = 3 * metrics.defaultRuleThickness; // Φ ← 3 ξ8
Expand All @@ -182,7 +182,7 @@ export class GenfracAtom extends Atom {
const numerDepth = numerBox.depth;
const denomHeight = denomBox.height;
let frac: Box;
if (ruleWidth <= 0) {
if (ruleThickness <= 0) {
// Rule 15c from Appendix G
// No bar line between numerator and denominator
const candidateClearance =
Expand All @@ -209,23 +209,25 @@ export class GenfracAtom extends Atom {
} else {
// Rule 15d from Appendix G of the TeXBook.
// There is a bar line between the numerator and the denominator
const numerLine = AXIS_HEIGHT + ruleWidth / 2;
const denomLine = AXIS_HEIGHT - ruleWidth / 2;
if (numerShift < clearance + numerDepth + numerLine)
numerShift = clearance + numerDepth + numerLine;

if (denomShift < clearance + denomHeight - denomLine)
denomShift = clearance + denomHeight - denomLine;

const fracLine = new Box(null, {
classes: 'ML__frac-line',
mode: this.mode,
style: this.style,
});
// Manually set the height of the frac line because its height is
// created in CSS
fracLine.height = ruleWidth / 2;
fracLine.depth = ruleWidth / 2;

// const numerLine = AXIS_HEIGHT + ruleThickness / 2;
const denomLine = AXIS_HEIGHT - ruleThickness / 2;
// if (numerShift < clearance + numerDepth + numerLine)
// numerShift = clearance + numerDepth + numerLine;

fracLine.width = Math.max(numerBox.width, denomBox.width);
fracLine.height = ruleThickness / 2;
fracLine.depth = ruleThickness / 2;

if (denomShift < clearance + denomHeight - denomLine)
denomShift = clearance + denomHeight - denomLine;

frac = new VBox({
individualShift: [
{
Expand Down
15 changes: 9 additions & 6 deletions src/core-atoms/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,10 @@ export class PromptAtom extends Atom {
const content = Atom.createBox(parentContext, this.body);

if (!content) return null;
// An empty prompt should not be too small, pretend content has height 0.5em
// An empty prompt should not be too small, pretend content
// has height sigma 5 (x-height)

if (!content.height) content.height = 0.5;
if (!content.height) content.height = context.metrics.xHeight;

content.setStyle('vertical-align', -content.height, 'em');
if (this.correctness === 'correct') {
Expand Down Expand Up @@ -108,19 +109,21 @@ export class PromptAtom extends Atom {
});
box.height = base.height + vPadding;
box.depth = base.depth + vPadding;
box.width = base.width + 2 * hPadding;
box.setStyle('box-sizing', 'border-box');
box.setStyle('position', 'absolute');

box.setStyle('height', base.height + base.depth + 2 * vPadding, 'em');
if (hPadding === 0) box.setStyle('width', '100%');
else {
box.setStyle('width', `calc(100% + ${2 * hPadding}em)`);
box.setStyle('height', base.height + base.depth + 2 * vPadding, 'em'); // @todo: remove
if (hPadding === 0) box.setStyle('width', '100%'); // @todo: remove
if (hPadding !== 0) {
box.setStyle('width', `calc(100% + ${2 * hPadding}em)`); // @todo: remove
box.setStyle('top', fboxsep, 'em'); // empirical
box.setStyle('left', -hPadding, 'em');
}

// empty prompt should be a little wider
if (!this.body || this.body.length === 1) {
box.width = 3 * hPadding;
box.setStyle('width', `calc(100% + ${3 * hPadding}em)`);
box.setStyle('left', -1.5 * hPadding, 'em');
}
Expand Down
20 changes: 15 additions & 5 deletions src/core-definitions/styling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -999,21 +999,31 @@ defineFunction(['overline', 'underline'], '{:auto}', {
);
const inner = Atom.createBox(context, atom.body);
if (!inner) return null;
const ruleWidth =
const ruleThickness =
context.metrics.defaultRuleThickness / context.scalingFactor;
const line = new Box(null, { classes: position + '-line' });
line.height = ruleWidth;
line.maxFontSize = ruleWidth * 1.125 * context.scalingFactor;
line.height = ruleThickness;
line.maxFontSize = ruleThickness * 1.125 * context.scalingFactor;
let stack: Box;
if (position === 'overline') {
stack = new VBox({
shift: 0,
children: [{ box: inner }, 3 * ruleWidth, { box: line }, ruleWidth],
children: [
{ box: inner },
3 * ruleThickness,
{ box: line },
ruleThickness,
],
});
} else {
stack = new VBox({
top: inner.height,
children: [ruleWidth, { box: line }, 3 * ruleWidth, { box: inner }],
children: [
ruleThickness,
{ box: line },
3 * ruleThickness,
{ box: inner },
],
});
}

Expand Down
3 changes: 2 additions & 1 deletion src/core/box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,8 @@ export class Box implements BoxInterface {
svgMarkup += '">';
svgMarkup += body;
svgMarkup += '</span>';
svgMarkup += '<svg style="position:absolute;overflow:overlay;';
svgMarkup += '<svg style="position:absolute;overflow:visible;';

svgMarkup += `height:${
Math.floor(100 * (this.height + this.depth)) / 100
}em;`;
Expand Down
7 changes: 2 additions & 5 deletions src/core/skip-box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ export function addSkipBefore(box: Box, width: number): void {
}

// If there's a skip box to our left, merge
if (i > 0 && siblings[i - 1].type === 'skip') {
siblings[i - 1].width += width;
return;
}
siblings.splice(i, 0, new SkipBox(width));
if (i > 0 && siblings[i - 1].type === 'skip') siblings[i - 1].width += width;
else siblings.splice(i, 0, new SkipBox(width));
}
13 changes: 10 additions & 3 deletions src/core/v-box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ function makeRows(
let minPos = depth;
let maxPos = depth;
let currPos = depth;
let width = 0;
for (const child of children) {
if (typeof child === 'number') currPos += child;
else {
Expand All @@ -166,6 +167,7 @@ function makeRows(

realChildren.push(childWrap);
currPos += box.height + box.depth;
width = Math.max(width, childWrap.width);
}
minPos = Math.min(minPos, currPos);
maxPos = Math.max(maxPos, currPos);
Expand All @@ -175,6 +177,8 @@ function makeRows(
// This cell's bottom edge will determine the containing table's baseline
// without overly expanding the containing line-box.
const vlist = new Box(realChildren, { classes: 'vlist' });
vlist.width = width;
vlist.height = maxPos;
vlist.setStyle('height', maxPos, 'em');

// A second row is used if necessary to represent the vlist's depth.
Expand All @@ -187,6 +191,7 @@ function makeRows(
// text content. And that min-height over-rides our desired height.
// So we put another empty box inside the depth strut box.
const depthStrut = new Box(new Box(null), { classes: 'vlist' });
depthStrut.height = -minPos;
depthStrut.setStyle('height', -minPos, 'em');

// Safari wants the first row to have inline content; otherwise it
Expand Down Expand Up @@ -214,15 +219,17 @@ export class VBox extends Box {
options?: { classes?: string; type?: BoxType }
) {
const [rows, height, depth] = makeRows(content);

super(rows.length === 1 ? rows[0] : rows, {
type: options?.type,
classes:
(options?.classes ?? '') +
' vlist-t' +
(rows.length === 2 ? ' vlist-t2' : ''),
height,
depth,
type: options?.type,
});
this.height = height;
this.depth = depth;
this.width = rows.reduce((acc, row) => Math.max(acc, row.width), 0);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/public/core-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ export type BoxCSSProperties =
| 'display'
| 'font-family'
| 'left'
| 'height'
| 'height' // @todo: remove
| 'line-height'
| 'margin-top'
| 'margin-left'
Expand All @@ -369,7 +369,7 @@ export type BoxCSSProperties =
| 'top'
| 'bottom'
| 'vertical-align'
| 'width'
| 'width' // @todo: remove
| 'z-index';

export type MatrixEnvironment =
Expand Down
15 changes: 12 additions & 3 deletions test/smoke/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
max-width: 640px;
width: 100%;
}
#mathml-render {
margin-top: 1rem;
margin-bottom: 1rem;
}
</style>
</head>
<body>
Expand All @@ -39,9 +43,10 @@ <h1>Smoke Test</h1>
</ul>
</header>
<main>
<math-field id="mf"
>-=a\phase{abc}\enclose{longdiv}{\frac{1}{12345}}\enclose{box}{\sqrt{\frac{1}{x+1}}}</math-field
>
<math-field id="mf"> \sqrt[3]{x} \sqrt{1+2\ne\frac{1}{2345}}</math-field>
<!-- <math-field id="mf"
>-=a\phase{abc}\enclose{longdiv}{\frac{1}{12+3+4+5}}\enclose{box}{\sqrt[1234567]{\frac{1}{x+1}}}</math-field
> -->
<!-- <math-field id="mf"
>\phase{abc}\enclose{box}{\sqrt{\frac{1}{x+1}}}\enclose{roundedbox}{\sqrt{\frac{1}{x+1}}}\enclose{circle}{\sqrt{\frac{1}{x+1}}}\enclose{top}{\sqrt{\frac{1}{x+1}}}\enclose{left}{\sqrt{\frac{1}{x+1}}}\enclose{right}{\sqrt{\frac{1}{x+1}}}\enclose{bottom}{\sqrt{\frac{1}{x+1}}}\enclose{horizontalstrike}{\sqrt{\frac{1}{x+1}}}\enclose{verticalstrike}{\sqrt{\frac{1}{x+1}}}\enclose{updiagonalstrike}{\sqrt{\frac{1}{x+1}}}\enclose{downdiagonalstrike}{\sqrt{\frac{1}{x+1}}}\enclose{updiagonalarrow}{\sqrt{\frac{1}{x+1}}}\enclose{downdiagonalarrow}{\sqrt{\frac{1}{x+1}}}\enclose{phasorangle}{\sqrt{\frac{1}{x+1}}}\enclose{radical}{\sqrt{\frac{1}{x+1}}}\enclose{longdiv}{\sqrt{\frac{1}{x+1}}}\enclose{actuarial}{\sqrt{\frac{1}{x+1}}}\enclose{madruwb}{\sqrt{\frac{1}{x+1}}}</math-field
> -->
Expand Down Expand Up @@ -70,6 +75,7 @@ <h2>ASCII Math</h2>

<h2>MathML</h2>
<div class="output" id="mathml"></div>
<div id="mathml-render"></div>

<h2>Latex to Speakable Text</h2>
<div class="output" id="latex2speech"></div>
Expand Down Expand Up @@ -291,6 +297,9 @@ <h2>Latex to Speakable Text</h2>
setHtml('latex', mf.getValue('latex-expanded'));
setHtml('ascii-math', mf.getValue('ascii-math'));
setHtml('mathml', mf.getValue('math-ml'));
document.getElementById(
'mathml-render'
).innerHTML = `<math>${mf.getValue('math-ml')}</math>`;
// setHtml('math-json', ce.parse(mf.value));
setHtml('latex2speech', convertLatexToSpeakableText(mf.getValue()));

Expand Down

0 comments on commit ce844a4

Please sign in to comment.