DuyTa's picture
Upload folder using huggingface_hub
bc20498 verified
// @flow
import defineFunction from "../defineFunction";
import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import delimiter from "../delimiter";
import Style from "../Style";
import {makeEm} from "../units";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
defineFunction({
type: "sqrt",
names: ["\\sqrt"],
props: {
numArgs: 1,
numOptionalArgs: 1,
},
handler({parser}, args, optArgs) {
const index = optArgs[0];
const body = args[0];
return {
type: "sqrt",
mode: parser.mode,
body,
index,
};
},
htmlBuilder(group, options) {
// Square roots are handled in the TeXbook pg. 443, Rule 11.
// First, we do the same steps as in overline to build the inner group
// and line
let inner = html.buildGroup(group.body, options.havingCrampedStyle());
if (inner.height === 0) {
// Render a small surd.
inner.height = options.fontMetrics().xHeight;
}
// Some groups can return document fragments. Handle those by wrapping
// them in a span.
inner = buildCommon.wrapFragment(inner, options);
// Calculate the minimum size for the \surd delimiter
const metrics = options.fontMetrics();
const theta = metrics.defaultRuleThickness;
let phi = theta;
if (options.style.id < Style.TEXT.id) {
phi = options.fontMetrics().xHeight;
}
// Calculate the clearance between the body and line
let lineClearance = theta + phi / 4;
const minDelimiterHeight = (inner.height + inner.depth +
lineClearance + theta);
// Create a sqrt SVG of the required minimum size
const {span: img, ruleWidth, advanceWidth} =
delimiter.sqrtImage(minDelimiterHeight, options);
const delimDepth = img.height - ruleWidth;
// Adjust the clearance based on the delimiter size
if (delimDepth > inner.height + inner.depth + lineClearance) {
lineClearance =
(lineClearance + delimDepth - inner.height - inner.depth) / 2;
}
// Shift the sqrt image
const imgShift = img.height - inner.height - lineClearance - ruleWidth;
inner.style.paddingLeft = makeEm(advanceWidth);
// Overlay the image and the argument.
const body = buildCommon.makeVList({
positionType: "firstBaseline",
children: [
{type: "elem", elem: inner, wrapperClasses: ["svg-align"]},
{type: "kern", size: -(inner.height + imgShift)},
{type: "elem", elem: img},
{type: "kern", size: ruleWidth},
],
}, options);
if (!group.index) {
return buildCommon.makeSpan(["mord", "sqrt"], [body], options);
} else {
// Handle the optional root index
// The index is always in scriptscript style
const newOptions = options.havingStyle(Style.SCRIPTSCRIPT);
const rootm = html.buildGroup(group.index, newOptions, options);
// The amount the index is shifted by. This is taken from the TeX
// source, in the definition of `\r@@t`.
const toShift = 0.6 * (body.height - body.depth);
// Build a VList with the superscript shifted up correctly
const rootVList = buildCommon.makeVList({
positionType: "shift",
positionData: -toShift,
children: [{type: "elem", elem: rootm}],
}, options);
// Add a class surrounding it so we can add on the appropriate
// kerning
const rootVListWrap = buildCommon.makeSpan(["root"], [rootVList]);
return buildCommon.makeSpan(["mord", "sqrt"],
[rootVListWrap, body], options);
}
},
mathmlBuilder(group, options) {
const {body, index} = group;
return index ?
new mathMLTree.MathNode(
"mroot", [
mml.buildGroup(body, options),
mml.buildGroup(index, options),
]) :
new mathMLTree.MathNode(
"msqrt", [mml.buildGroup(body, options)]);
},
});