mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-12 14:38:39 +00:00
Wrap document fragment where classes, attributes, or styles are applied (#1707)
* Wrap document fragment group where classes or styles are applied * Wrap non-math node where attributes are applied in \href
This commit is contained in:
committed by
Kevin Barabash
parent
3514d48856
commit
a51dc4b072
@@ -459,6 +459,20 @@ const makeFragment = function(
|
||||
return fragment;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps group in a span if it's a document fragment, allowing to apply classes
|
||||
* and styles
|
||||
*/
|
||||
const wrapFragment = function(
|
||||
group: HtmlDomNode,
|
||||
options: Options,
|
||||
): HtmlDomNode {
|
||||
if (group instanceof DocumentFragment) {
|
||||
return makeSpan([], [group], options);
|
||||
}
|
||||
return group;
|
||||
};
|
||||
|
||||
|
||||
// These are exact object types to catch typos in the names of the optional fields.
|
||||
export type VListElem = {|
|
||||
@@ -812,6 +826,7 @@ export default {
|
||||
makeLineSpan,
|
||||
makeAnchor,
|
||||
makeFragment,
|
||||
wrapFragment,
|
||||
makeVList,
|
||||
makeOrd,
|
||||
makeGlue,
|
||||
|
@@ -44,15 +44,19 @@ defineFunction({
|
||||
// Build the argument groups in the appropriate style.
|
||||
// Ref: amsmath.dtx: \hbox{$\scriptstyle\mkern#3mu{#6}\mkern#4mu$}%
|
||||
|
||||
// Some groups can return document fragments. Handle those by wrapping
|
||||
// them in a span.
|
||||
let newOptions = options.havingStyle(style.sup());
|
||||
const upperGroup = html.buildGroup(group.body, newOptions, options);
|
||||
const upperGroup = buildCommon.wrapFragment(
|
||||
html.buildGroup(group.body, newOptions, options), options);
|
||||
upperGroup.classes.push("x-arrow-pad");
|
||||
|
||||
let lowerGroup;
|
||||
if (group.below) {
|
||||
// Build the lower group
|
||||
newOptions = options.havingStyle(style.sub());
|
||||
lowerGroup = html.buildGroup(group.below, newOptions, options);
|
||||
lowerGroup = buildCommon.wrapFragment(
|
||||
html.buildGroup(group.below, newOptions, options), options);
|
||||
lowerGroup.classes.push("x-arrow-pad");
|
||||
}
|
||||
|
||||
|
@@ -12,7 +12,10 @@ import * as mml from "../buildMathML";
|
||||
|
||||
const htmlBuilder = (group, options) => {
|
||||
// \cancel, \bcancel, \xcancel, \sout, \fbox, \colorbox, \fcolorbox
|
||||
const inner = html.buildGroup(group.body, options);
|
||||
// Some groups can return document fragments. Handle those by wrapping
|
||||
// them in a span.
|
||||
const inner = buildCommon.wrapFragment(
|
||||
html.buildGroup(group.body, options), options);
|
||||
|
||||
const label = group.label.substr(1);
|
||||
const scale = options.sizeMultiplier;
|
||||
|
@@ -2,7 +2,6 @@
|
||||
import defineFunction, {ordargument} from "../defineFunction";
|
||||
import buildCommon from "../buildCommon";
|
||||
import {assertNodeType} from "../parseNode";
|
||||
import {assertType} from "../utils";
|
||||
import {MathNode} from "../mathMLTree";
|
||||
|
||||
import * as html from "../buildHTML";
|
||||
@@ -31,8 +30,11 @@ defineFunction({
|
||||
return buildCommon.makeAnchor(group.href, [], elements, options);
|
||||
},
|
||||
mathmlBuilder: (group, options) => {
|
||||
const math = mml.buildExpressionRow(group.body, options);
|
||||
assertType(math, MathNode).setAttribute("href", group.href);
|
||||
let math = mml.buildExpressionRow(group.body, options);
|
||||
if (!(math instanceof MathNode)) {
|
||||
math = new MathNode("mrow", [math]);
|
||||
}
|
||||
math.setAttribute("href", group.href);
|
||||
return math;
|
||||
},
|
||||
});
|
||||
|
@@ -5,7 +5,6 @@ import mathMLTree from "../mathMLTree";
|
||||
import delimiter from "../delimiter";
|
||||
import Style from "../Style";
|
||||
|
||||
import {DocumentFragment} from "../tree";
|
||||
import * as html from "../buildHTML";
|
||||
import * as mml from "../buildMathML";
|
||||
|
||||
@@ -39,9 +38,7 @@ defineFunction({
|
||||
|
||||
// Some groups can return document fragments. Handle those by wrapping
|
||||
// them in a span.
|
||||
if (inner instanceof DocumentFragment) {
|
||||
inner = buildCommon.makeSpan([], [inner], options);
|
||||
}
|
||||
inner = buildCommon.wrapFragment(inner, options);
|
||||
|
||||
// Calculate the minimum size for the \surd delimiter
|
||||
const metrics = options.fontMetrics();
|
||||
|
12
src/utils.js
12
src/utils.js
@@ -91,18 +91,6 @@ export const assert = function<T>(value: ?T): T {
|
||||
return value;
|
||||
};
|
||||
|
||||
export const assertType = function<T>(val: mixed, Cls: Class<T>): T {
|
||||
if (val instanceof Cls) {
|
||||
return val;
|
||||
}
|
||||
|
||||
// $FlowFixMe: Get constructor name if possible.
|
||||
const expected = String(Cls.name || Cls);
|
||||
// $FlowFixMe: Get constructor name if possible; else stringify value.
|
||||
const actual = String(val.constructor.name || val);
|
||||
throw new Error(`Expected ${expected} but got ${actual}.`);
|
||||
};
|
||||
|
||||
export default {
|
||||
contains,
|
||||
deflt,
|
||||
|
@@ -2415,6 +2415,23 @@ describe("A smash builder", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("A document fragment", function() {
|
||||
it("should have paddings applied inside an extensible arrow", function() {
|
||||
const markup = katex.renderToString("\\tiny\\xrightarrow\\textcolor{red}{x}");
|
||||
expect(markup).toContain("x-arrow-pad");
|
||||
});
|
||||
|
||||
it("should have paddings applied inside an enclose", function() {
|
||||
const markup = katex.renderToString(r`\fbox\textcolor{red}{x}`);
|
||||
expect(markup).toContain("boxpad");
|
||||
});
|
||||
|
||||
it("should have paddings applied inside a square root", function() {
|
||||
const markup = katex.renderToString(r`\sqrt\textcolor{red}{x}`);
|
||||
expect(markup).toContain("padding-left");
|
||||
});
|
||||
});
|
||||
|
||||
describe("A parser error", function() {
|
||||
it("should report the position of an error", function() {
|
||||
try {
|
||||
@@ -2519,7 +2536,7 @@ describe("href and url commands", function() {
|
||||
// We can't use raw strings for \url because \u is for Unicode escapes.
|
||||
|
||||
it("should parse its input", function() {
|
||||
expect`\href{http://example.com/}{example here}`.toBuild();
|
||||
expect`\href{http://example.com/}{\sin}`.toBuild();
|
||||
expect("\\url{http://example.com/}").toBuild();
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user