0

I'm trying to write a dynamic web page to drill the user on arithmetic. My intent is for a piece of JavaScript to generate an arithmetic problem, build and present a MathML DOM node to represent it to the user, and then deal with their answer.

I expect a handwritten MathML element to render exactly the same as "the same" JavaScript-generated element. But that's not what I'm getting with my script.

Here is the handwritten version:

body {
	font: medium/1.5 sans-serif;
	margin: 0;
	position: absolute;
	height: 100%;
	width: 100%;
	display: table;
}

math { font-family: sans-serif; }

#history {
	width: 16em;
	background: silver;
	display: table-cell;
}

#present {
	font-size: 3em;
	text-align: center;
	vertical-align: middle;
	display: table-cell;
}

input {
	font-size: inherit;
	width: 4em;
	text-align: center;
	display: block;
	margin: auto;
}
<html>
<head>
<meta charset="UTF-8"/>
<title>Automatic Arithmetic Drill</title>
</head>
<body>
<div id="present"><math id="problem"><mrow><mn>5</mn><mo>+</mo><mn>5</mn></mrow></math><input id="answer"></input></div>
<div id="history">
</div>
</body>
</html>

This renders, for me, with Firefox 68.4.1esr (32-bit) on Debian, like this: Usual spacing between elements.

Here is the dynamic version:

function update_problem(left, infix, right) {
	var problem = document.createElement("math");
	var problem_row = document.createElement("mrow");
	var problem_left = document.createElement("mn");
	var problem_infix = document.createElement("mo");
	var problem_right = document.createElement("mn");
	var problem_left_text = document.createTextNode(left);
	var problem_infix_text  = document.createTextNode(infix);
	var problem_right_text = document.createTextNode(right);
	problem_left.appendChild(problem_left_text);
	problem_infix.appendChild(problem_infix_text);
	problem_right.appendChild(problem_right_text);
	problem_row.appendChild(problem_left);
	problem_row.appendChild(problem_infix);
	problem_row.appendChild(problem_right);
	problem.appendChild(problem_row);
	var old_problem = document.getElementById("problem");
	old_problem.replaceWith(problem);
	problem.id = "problem";
}

update_problem(5, "+", 5);
body {
	font: medium/1.5 sans-serif;
	margin: 0;
	position: absolute;
	height: 100%;
	width: 100%;
	display: table;
}

math { font-family: sans-serif; }

#history {
	width: 16em;
	background: silver;
	display: table-cell;
}

#present {
	font-size: 3em;
	text-align: center;
	vertical-align: middle;
	display: table-cell;
}

input {
	font-size: inherit;
	width: 4em;
	text-align: center;
	display: block;
	margin: auto;
}
<!DOCTYPE html>

<html>
<head>
<meta charset="UTF-8"/>
<title>Automatic Arithmetic Drill</title>
</head>
<body>
<div id="present"><math id="problem"></math><input id="answer"></input></div>
<div id="history">
</div>
</body>
</html>

This renders for me like this:

No spacing between elements.

As you can see, in the static case, there is the default MathML spacing between the mn, mo, and mn elements, but there's no spacing in the dynamic case. I want the generated version to look just the same as the static verison.

Thinking that the dynamically generated nodes lacked their default attributes, I tried adding

problem_infix.setAttribute("lspace", (5.0 / 18.0).toString() + "em");
problem_infix.setAttribute("rspace", (5.0 / 18.0).toString() + "em");

but this made no difference.

I can't find any resources about this; MathML seems not in widespread use.

How can I fix the spacing for the JavaScript-generated node?

0 Answers