// @flow import buildCommon from "../buildCommon"; import defineFunction from "../defineFunction"; import mathMLTree from "../mathMLTree"; import {assertNodeType} from "../parseNode"; import {calculateSize, makeEm} from "../units"; defineFunction({ type: "rule", names: ["\\rule"], props: { numArgs: 2, numOptionalArgs: 1, argTypes: ["size", "size", "size"], }, handler({parser}, args, optArgs) { const shift = optArgs[0]; const width = assertNodeType(args[0], "size"); const height = assertNodeType(args[1], "size"); return { type: "rule", mode: parser.mode, shift: shift && assertNodeType(shift, "size").value, width: width.value, height: height.value, }; }, htmlBuilder(group, options) { // Make an empty span for the rule const rule = buildCommon.makeSpan(["mord", "rule"], [], options); // Calculate the shift, width, and height of the rule, and account for units const width = calculateSize(group.width, options); const height = calculateSize(group.height, options); const shift = (group.shift) ? calculateSize(group.shift, options) : 0; // Style the rule to the right size rule.style.borderRightWidth = makeEm(width); rule.style.borderTopWidth = makeEm(height); rule.style.bottom = makeEm(shift); // Record the height and width rule.width = width; rule.height = height + shift; rule.depth = -shift; // Font size is the number large enough that the browser will // reserve at least `absHeight` space above the baseline. // The 1.125 factor was empirically determined rule.maxFontSize = height * 1.125 * options.sizeMultiplier; return rule; }, mathmlBuilder(group, options) { const width = calculateSize(group.width, options); const height = calculateSize(group.height, options); const shift = (group.shift) ? calculateSize(group.shift, options) : 0; const color = options.color && options.getColor() || "black"; const rule = new mathMLTree.MathNode("mspace"); rule.setAttribute("mathbackground", color); rule.setAttribute("width", makeEm(width)); rule.setAttribute("height", makeEm(height)); const wrapper = new mathMLTree.MathNode("mpadded", [rule]); if (shift >= 0) { wrapper.setAttribute("height", makeEm(shift)); } else { wrapper.setAttribute("height", makeEm(shift)); wrapper.setAttribute("depth", makeEm(-shift)); } wrapper.setAttribute("voffset", makeEm(shift)); return wrapper; }, });