mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-08 04:28:41 +00:00
Implemented `\href' command (#923)
* Implements `\href' command. * Added `functions/href.js`. * Added `domTree.anchor` and `buildCommon.makeAnchor` functions. * Make `buildHTML.getTypeOfDomTree` exported. * Reflects the code reviews * Create new argType "url" to treat link string in math appropriately * Stop using too shorten variable names * Start using template strings * Adopts template literal * Elaborates on glueing * If-clause restructuring * Solved confusing explanation * Allow balanced braces in url * Adds unit-test for \href * Adds snapshot tests
This commit is contained in:
committed by
Kevin Barabash
parent
75af19c5bb
commit
fd82c4fad0
73
src/functions/href.js
Normal file
73
src/functions/href.js
Normal file
@@ -0,0 +1,73 @@
|
||||
// @flow
|
||||
import defineFunction, {ordargument} from "../defineFunction";
|
||||
import buildCommon from "../buildCommon";
|
||||
import mathMLTree from "../mathMLTree";
|
||||
|
||||
import * as html from "../buildHTML";
|
||||
import * as mml from "../buildMathML";
|
||||
|
||||
defineFunction({
|
||||
type: "href",
|
||||
names: ["\\href"],
|
||||
props: {
|
||||
numArgs: 2,
|
||||
argTypes: ["url", "original"],
|
||||
},
|
||||
handler: (context, args) => {
|
||||
const body = args[1];
|
||||
const href = args[0].value;
|
||||
return {
|
||||
type: "href",
|
||||
href: href,
|
||||
body: ordargument(body),
|
||||
};
|
||||
},
|
||||
htmlBuilder: (group, options) => {
|
||||
const elements = html.buildExpression(
|
||||
group.value.body,
|
||||
options,
|
||||
false
|
||||
);
|
||||
|
||||
const href = group.value.href;
|
||||
|
||||
/**
|
||||
* Determining class for anchors.
|
||||
* 1. if it has the only element, use its class;
|
||||
* 2. if it has more than two elements, and the classes
|
||||
* of its first and last elements coincide, then use it;
|
||||
* 3. otherwise, we will inject an empty <span>s at both ends,
|
||||
* with the same classes of both ends of elements, with the
|
||||
* first span having the same class as the first element of body,
|
||||
* and the second one the same as the last.
|
||||
*/
|
||||
|
||||
let classes = []; // Default behaviour for Case 3.
|
||||
let first; // mathtype of the first child
|
||||
let last; // mathtype of the last child
|
||||
// Invariants: both first and last must be non-null if classes is null.
|
||||
if (elements.length === 1) { // Case 1
|
||||
classes = elements[0].classes;
|
||||
} else if (elements.length >= 2) {
|
||||
first = html.getTypeOfDomTree(elements[0]) || 'mord';
|
||||
last = html.getTypeOfDomTree(elements[elements.length - 1]) || 'mord';
|
||||
if (first === last) { // Case 2 : type of both ends coincides
|
||||
classes = [first];
|
||||
} else { // Case 3: both ends have different types.
|
||||
const anc = buildCommon.makeAnchor(href, [], elements, options);
|
||||
return new buildCommon.makeFragment([
|
||||
new buildCommon.makeSpan([first], [], options),
|
||||
anc,
|
||||
new buildCommon.makeSpan([last], [], options),
|
||||
]);
|
||||
}
|
||||
}
|
||||
return new buildCommon.makeAnchor(href, classes, elements, options);
|
||||
},
|
||||
mathmlBuilder: (group, options) => {
|
||||
const inner = mml.buildExpression(group.value.body, options);
|
||||
const math = new mathMLTree.MathNode("mrow", inner);
|
||||
math.setAttribute("href", group.value.href);
|
||||
return math;
|
||||
},
|
||||
});
|
Reference in New Issue
Block a user