mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-05 19:28:39 +00:00
Flatten a bunch of non-pervasive ParseNode types (part 1) (#1551)
* Flatten "url" ParseNode. * Flatten "href" ParseNode. * Flatten "verb" ParseNode. * Flatten "tag" ParseNode. * Flatten "cr" ParseNode. * Flatten "delimsizing" ParseNode. * Flatten "middle" ParseNode. * Flatten "leftright" ParseNode. * Flatten "leftright-right" ParseNode. * Flatten "mathchoice" ParseNode. * Remove unused ParseNode type "mod". * Flatten "mclass" ParseNode. * Flatten "font" ParseNode. * Flatten "phantom" ParseNode. * Flatten "hphantom" ParseNode. * Flatten "vphantom" ParseNode.
This commit is contained in:
@@ -942,10 +942,7 @@ export default class Parser {
|
|||||||
const urlArg = {
|
const urlArg = {
|
||||||
type: "url",
|
type: "url",
|
||||||
mode: this.mode,
|
mode: this.mode,
|
||||||
value: {
|
url,
|
||||||
type: "url",
|
|
||||||
value: url,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
this.consume();
|
this.consume();
|
||||||
if (funcName === "\\href") { // two arguments
|
if (funcName === "\\href") { // two arguments
|
||||||
@@ -983,11 +980,8 @@ export default class Parser {
|
|||||||
return newArgument({
|
return newArgument({
|
||||||
type: "verb",
|
type: "verb",
|
||||||
mode: "text",
|
mode: "text",
|
||||||
value: {
|
body: arg,
|
||||||
type: "verb",
|
star,
|
||||||
body: arg,
|
|
||||||
star: star,
|
|
||||||
},
|
|
||||||
}, nucleus);
|
}, nucleus);
|
||||||
}
|
}
|
||||||
// At this point, we should have a symbol, possibly with accents.
|
// At this point, we should have a symbol, possibly with accents.
|
||||||
|
@@ -613,8 +613,8 @@ const makeVList = function(params: VListParam, options: Options): DomSpan {
|
|||||||
|
|
||||||
// Converts verb group into body string, dealing with \verb* form
|
// Converts verb group into body string, dealing with \verb* form
|
||||||
const makeVerb = function(group: ParseNode<"verb">, options: Options): string {
|
const makeVerb = function(group: ParseNode<"verb">, options: Options): string {
|
||||||
let text = group.value.body;
|
let text = group.body;
|
||||||
if (group.value.star) {
|
if (group.star) {
|
||||||
text = text.replace(/ /g, '\u2423'); // Open Box
|
text = text.replace(/ /g, '\u2423'); // Open Box
|
||||||
} else {
|
} else {
|
||||||
text = text.replace(/ /g, '\xA0'); // No-Break Space
|
text = text.replace(/ /g, '\xA0'); // No-Break Space
|
||||||
|
@@ -309,8 +309,8 @@ export default function buildHTML(tree: AnyParseNode[], options: Options): DomSp
|
|||||||
// Strip off outer tag wrapper for processing below.
|
// Strip off outer tag wrapper for processing below.
|
||||||
let tag = null;
|
let tag = null;
|
||||||
if (tree.length === 1 && tree[0].type === "tag") {
|
if (tree.length === 1 && tree[0].type === "tag") {
|
||||||
tag = tree[0].value.tag;
|
tag = tree[0].tag;
|
||||||
tree = tree[0].value.body;
|
tree = tree[0].body;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the expression contained in the tree
|
// Build the expression contained in the tree
|
||||||
|
@@ -139,7 +139,7 @@ function parseArray(
|
|||||||
if (!cr) {
|
if (!cr) {
|
||||||
throw new ParseError(`Failed to parse function after ${next}`);
|
throw new ParseError(`Failed to parse function after ${next}`);
|
||||||
}
|
}
|
||||||
rowGaps.push(assertNodeType(cr, "cr").value.size);
|
rowGaps.push(assertNodeType(cr, "cr").size);
|
||||||
|
|
||||||
// check for \hline(s) following the row separator
|
// check for \hline(s) following the row separator
|
||||||
hLinesBeforeRow.push(getHLines(parser));
|
hLinesBeforeRow.push(getHLines(parser));
|
||||||
@@ -563,12 +563,9 @@ defineEnvironment({
|
|||||||
return delimiters ? {
|
return delimiters ? {
|
||||||
type: "leftright",
|
type: "leftright",
|
||||||
mode: context.mode,
|
mode: context.mode,
|
||||||
value: {
|
body: [res],
|
||||||
type: "leftright",
|
left: delimiters[0],
|
||||||
body: [res],
|
right: delimiters[1],
|
||||||
left: delimiters[0],
|
|
||||||
right: delimiters[1],
|
|
||||||
},
|
|
||||||
} : res;
|
} : res;
|
||||||
},
|
},
|
||||||
htmlBuilder,
|
htmlBuilder,
|
||||||
@@ -614,12 +611,9 @@ defineEnvironment({
|
|||||||
return {
|
return {
|
||||||
type: "leftright",
|
type: "leftright",
|
||||||
mode: context.mode,
|
mode: context.mode,
|
||||||
value: {
|
body: [res],
|
||||||
type: "leftright",
|
left: "\\{",
|
||||||
body: [res],
|
right: ".",
|
||||||
left: "\\{",
|
|
||||||
right: ".",
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
htmlBuilder,
|
htmlBuilder,
|
||||||
|
@@ -40,12 +40,9 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "cr",
|
type: "cr",
|
||||||
mode: parser.mode,
|
mode: parser.mode,
|
||||||
value: {
|
newLine,
|
||||||
type: "cr",
|
newRow,
|
||||||
newLine,
|
size: size && assertNodeType(size, "size"),
|
||||||
newRow,
|
|
||||||
size: size && assertNodeType(size, "size"),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -53,16 +50,16 @@ defineFunction({
|
|||||||
// not within tabular/array environments.
|
// not within tabular/array environments.
|
||||||
|
|
||||||
htmlBuilder: (group, options) => {
|
htmlBuilder: (group, options) => {
|
||||||
if (group.value.newRow) {
|
if (group.newRow) {
|
||||||
throw new ParseError(
|
throw new ParseError(
|
||||||
"\\cr valid only within a tabular/array environment");
|
"\\cr valid only within a tabular/array environment");
|
||||||
}
|
}
|
||||||
const span = buildCommon.makeSpan(["mspace"], [], options);
|
const span = buildCommon.makeSpan(["mspace"], [], options);
|
||||||
if (group.value.newLine) {
|
if (group.newLine) {
|
||||||
span.classes.push("newline");
|
span.classes.push("newline");
|
||||||
if (group.value.size) {
|
if (group.size) {
|
||||||
span.style.marginTop =
|
span.style.marginTop =
|
||||||
calculateSize(group.value.size.value.value, options) + "em";
|
calculateSize(group.size.value.value, options) + "em";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return span;
|
return span;
|
||||||
@@ -70,11 +67,11 @@ defineFunction({
|
|||||||
|
|
||||||
mathmlBuilder: (group, options) => {
|
mathmlBuilder: (group, options) => {
|
||||||
const node = new mathMLTree.MathNode("mspace");
|
const node = new mathMLTree.MathNode("mspace");
|
||||||
if (group.value.newLine) {
|
if (group.newLine) {
|
||||||
node.setAttribute("linebreak", "newline");
|
node.setAttribute("linebreak", "newline");
|
||||||
if (group.value.size) {
|
if (group.size) {
|
||||||
node.setAttribute("height",
|
node.setAttribute("height",
|
||||||
calculateSize(group.value.size.value.value, options) + "em");
|
calculateSize(group.size.value.value, options) + "em");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
|
@@ -12,7 +12,6 @@ import * as mml from "../buildMathML";
|
|||||||
|
|
||||||
import type Options from "../Options";
|
import type Options from "../Options";
|
||||||
import type {AnyParseNode, ParseNode, SymbolParseNode} from "../parseNode";
|
import type {AnyParseNode, ParseNode, SymbolParseNode} from "../parseNode";
|
||||||
import type {LeftRightDelimType} from "../parseNode";
|
|
||||||
import type {FunctionContext} from "../defineFunction";
|
import type {FunctionContext} from "../defineFunction";
|
||||||
|
|
||||||
// Extra data needed for the delimiter handler down below
|
// Extra data needed for the delimiter handler down below
|
||||||
@@ -52,7 +51,7 @@ const delimiters = [
|
|||||||
".",
|
".",
|
||||||
];
|
];
|
||||||
|
|
||||||
type IsMiddle = {value: string, options: Options};
|
type IsMiddle = {delim: string, options: Options};
|
||||||
|
|
||||||
// Delimiter functions
|
// Delimiter functions
|
||||||
function checkDelimiter(
|
function checkDelimiter(
|
||||||
@@ -87,39 +86,33 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "delimsizing",
|
type: "delimsizing",
|
||||||
mode: context.parser.mode,
|
mode: context.parser.mode,
|
||||||
value: {
|
size: delimiterSizes[context.funcName].size,
|
||||||
type: "delimsizing",
|
mclass: delimiterSizes[context.funcName].mclass,
|
||||||
size: delimiterSizes[context.funcName].size,
|
delim: delim.value,
|
||||||
mclass: delimiterSizes[context.funcName].mclass,
|
|
||||||
value: delim.value,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
htmlBuilder: (group, options) => {
|
htmlBuilder: (group, options) => {
|
||||||
const delim = group.value.value;
|
if (group.delim === ".") {
|
||||||
|
|
||||||
if (delim === ".") {
|
|
||||||
// Empty delimiters still count as elements, even though they don't
|
// Empty delimiters still count as elements, even though they don't
|
||||||
// show anything.
|
// show anything.
|
||||||
return buildCommon.makeSpan([group.value.mclass]);
|
return buildCommon.makeSpan([group.mclass]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use delimiter.sizedDelim to generate the delimiter.
|
// Use delimiter.sizedDelim to generate the delimiter.
|
||||||
return delimiter.sizedDelim(
|
return delimiter.sizedDelim(
|
||||||
delim, group.value.size, options, group.mode,
|
group.delim, group.size, options, group.mode, [group.mclass]);
|
||||||
[group.value.mclass]);
|
|
||||||
},
|
},
|
||||||
mathmlBuilder: (group) => {
|
mathmlBuilder: (group) => {
|
||||||
const children = [];
|
const children = [];
|
||||||
|
|
||||||
if (group.value.value !== ".") {
|
if (group.delim !== ".") {
|
||||||
children.push(mml.makeText(group.value.value, group.mode));
|
children.push(mml.makeText(group.delim, group.mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
const node = new mathMLTree.MathNode("mo", children);
|
const node = new mathMLTree.MathNode("mo", children);
|
||||||
|
|
||||||
if (group.value.mclass === "mopen" ||
|
if (group.mclass === "mopen" ||
|
||||||
group.value.mclass === "mclose") {
|
group.mclass === "mclose") {
|
||||||
// Only some of the delimsizing functions act as fences, and they
|
// Only some of the delimsizing functions act as fences, and they
|
||||||
// return "mopen" or "mclose" mclass.
|
// return "mopen" or "mclose" mclass.
|
||||||
node.setAttribute("fence", "true");
|
node.setAttribute("fence", "true");
|
||||||
@@ -134,11 +127,10 @@ defineFunction({
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function leftRightGroupValue(group: ParseNode<"leftright">): LeftRightDelimType {
|
function assertParsed(group: ParseNode<"leftright">) {
|
||||||
if (!group.value.body) {
|
if (!group.body) {
|
||||||
throw new Error("Bug: The leftright ParseNode wasn't fully parsed.");
|
throw new Error("Bug: The leftright ParseNode wasn't fully parsed.");
|
||||||
}
|
}
|
||||||
return group.value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -155,10 +147,7 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "leftright-right",
|
type: "leftright-right",
|
||||||
mode: context.parser.mode,
|
mode: context.parser.mode,
|
||||||
value: {
|
delim: checkDelimiter(args[0], context).value,
|
||||||
type: "leftright-right",
|
|
||||||
value: checkDelimiter(args[0], context).value,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -188,18 +177,15 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "leftright",
|
type: "leftright",
|
||||||
mode: parser.mode,
|
mode: parser.mode,
|
||||||
value: {
|
body,
|
||||||
type: "leftright",
|
left: delim.value,
|
||||||
body: body,
|
right: assertNodeType(right, "leftright-right").delim,
|
||||||
left: delim.value,
|
|
||||||
right: assertNodeType(right, "leftright-right").value.value,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
htmlBuilder: (group, options) => {
|
htmlBuilder: (group, options) => {
|
||||||
const groupValue = leftRightGroupValue(group);
|
assertParsed(group);
|
||||||
// Build the inner expression
|
// Build the inner expression
|
||||||
const inner = html.buildExpression(groupValue.body, options, true,
|
const inner = html.buildExpression(group.body, options, true,
|
||||||
[null, "mclose"]);
|
[null, "mclose"]);
|
||||||
|
|
||||||
let innerHeight = 0;
|
let innerHeight = 0;
|
||||||
@@ -226,14 +212,14 @@ defineFunction({
|
|||||||
innerDepth *= options.sizeMultiplier;
|
innerDepth *= options.sizeMultiplier;
|
||||||
|
|
||||||
let leftDelim;
|
let leftDelim;
|
||||||
if (groupValue.left === ".") {
|
if (group.left === ".") {
|
||||||
// Empty delimiters in \left and \right make null delimiter spaces.
|
// Empty delimiters in \left and \right make null delimiter spaces.
|
||||||
leftDelim = html.makeNullDelimiter(options, ["mopen"]);
|
leftDelim = html.makeNullDelimiter(options, ["mopen"]);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, use leftRightDelim to generate the correct sized
|
// Otherwise, use leftRightDelim to generate the correct sized
|
||||||
// delimiter.
|
// delimiter.
|
||||||
leftDelim = delimiter.leftRightDelim(
|
leftDelim = delimiter.leftRightDelim(
|
||||||
groupValue.left, innerHeight, innerDepth, options,
|
group.left, innerHeight, innerDepth, options,
|
||||||
group.mode, ["mopen"]);
|
group.mode, ["mopen"]);
|
||||||
}
|
}
|
||||||
// Add it to the beginning of the expression
|
// Add it to the beginning of the expression
|
||||||
@@ -250,7 +236,7 @@ defineFunction({
|
|||||||
if (isMiddle) {
|
if (isMiddle) {
|
||||||
// Apply the options that were active when \middle was called
|
// Apply the options that were active when \middle was called
|
||||||
inner[i] = delimiter.leftRightDelim(
|
inner[i] = delimiter.leftRightDelim(
|
||||||
isMiddle.value, innerHeight, innerDepth,
|
isMiddle.delim, innerHeight, innerDepth,
|
||||||
isMiddle.options, group.mode, []);
|
isMiddle.options, group.mode, []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -258,11 +244,11 @@ defineFunction({
|
|||||||
|
|
||||||
let rightDelim;
|
let rightDelim;
|
||||||
// Same for the right delimiter
|
// Same for the right delimiter
|
||||||
if (groupValue.right === ".") {
|
if (group.right === ".") {
|
||||||
rightDelim = html.makeNullDelimiter(options, ["mclose"]);
|
rightDelim = html.makeNullDelimiter(options, ["mclose"]);
|
||||||
} else {
|
} else {
|
||||||
rightDelim = delimiter.leftRightDelim(
|
rightDelim = delimiter.leftRightDelim(
|
||||||
groupValue.right, innerHeight, innerDepth, options,
|
group.right, innerHeight, innerDepth, options,
|
||||||
group.mode, ["mclose"]);
|
group.mode, ["mclose"]);
|
||||||
}
|
}
|
||||||
// Add it to the end of the expression.
|
// Add it to the end of the expression.
|
||||||
@@ -271,21 +257,21 @@ defineFunction({
|
|||||||
return buildCommon.makeSpan(["minner"], inner, options);
|
return buildCommon.makeSpan(["minner"], inner, options);
|
||||||
},
|
},
|
||||||
mathmlBuilder: (group, options) => {
|
mathmlBuilder: (group, options) => {
|
||||||
const groupValue = leftRightGroupValue(group);
|
assertParsed(group);
|
||||||
const inner = mml.buildExpression(groupValue.body, options);
|
const inner = mml.buildExpression(group.body, options);
|
||||||
|
|
||||||
if (groupValue.left !== ".") {
|
if (group.left !== ".") {
|
||||||
const leftNode = new mathMLTree.MathNode(
|
const leftNode = new mathMLTree.MathNode(
|
||||||
"mo", [mml.makeText(groupValue.left, group.mode)]);
|
"mo", [mml.makeText(group.left, group.mode)]);
|
||||||
|
|
||||||
leftNode.setAttribute("fence", "true");
|
leftNode.setAttribute("fence", "true");
|
||||||
|
|
||||||
inner.unshift(leftNode);
|
inner.unshift(leftNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groupValue.right !== ".") {
|
if (group.right !== ".") {
|
||||||
const rightNode = new mathMLTree.MathNode(
|
const rightNode = new mathMLTree.MathNode(
|
||||||
"mo", [mml.makeText(groupValue.right, group.mode)]);
|
"mo", [mml.makeText(group.right, group.mode)]);
|
||||||
|
|
||||||
rightNode.setAttribute("fence", "true");
|
rightNode.setAttribute("fence", "true");
|
||||||
|
|
||||||
@@ -311,22 +297,19 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "middle",
|
type: "middle",
|
||||||
mode: context.parser.mode,
|
mode: context.parser.mode,
|
||||||
value: {
|
delim: delim.value,
|
||||||
type: "middle",
|
|
||||||
value: delim.value,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
htmlBuilder: (group, options) => {
|
htmlBuilder: (group, options) => {
|
||||||
let middleDelim;
|
let middleDelim;
|
||||||
if (group.value.value === ".") {
|
if (group.delim === ".") {
|
||||||
middleDelim = html.makeNullDelimiter(options, []);
|
middleDelim = html.makeNullDelimiter(options, []);
|
||||||
} else {
|
} else {
|
||||||
middleDelim = delimiter.sizedDelim(
|
middleDelim = delimiter.sizedDelim(
|
||||||
group.value.value, 1, options,
|
group.delim, 1, options,
|
||||||
group.mode, []);
|
group.mode, []);
|
||||||
|
|
||||||
const isMiddle: IsMiddle = {value: group.value.value, options};
|
const isMiddle: IsMiddle = {delim: group.delim, options};
|
||||||
// Property `isMiddle` not defined on `span`. It is only used in
|
// Property `isMiddle` not defined on `span`. It is only used in
|
||||||
// this file above.
|
// this file above.
|
||||||
// TODO: Fix this violation of the `span` type and possibly rename
|
// TODO: Fix this violation of the `span` type and possibly rename
|
||||||
@@ -338,7 +321,7 @@ defineFunction({
|
|||||||
},
|
},
|
||||||
mathmlBuilder: (group, options) => {
|
mathmlBuilder: (group, options) => {
|
||||||
const middleNode = new mathMLTree.MathNode(
|
const middleNode = new mathMLTree.MathNode(
|
||||||
"mo", [mml.makeText(group.value.value, group.mode)]);
|
"mo", [mml.makeText(group.delim, group.mode)]);
|
||||||
middleNode.setAttribute("fence", "true");
|
middleNode.setAttribute("fence", "true");
|
||||||
return middleNode;
|
return middleNode;
|
||||||
},
|
},
|
||||||
|
@@ -7,17 +7,18 @@ import defineFunction from "../defineFunction";
|
|||||||
import * as html from "../buildHTML";
|
import * as html from "../buildHTML";
|
||||||
import * as mml from "../buildMathML";
|
import * as mml from "../buildMathML";
|
||||||
|
|
||||||
|
import type {ParseNode} from "../parseNode";
|
||||||
|
|
||||||
const htmlBuilder = (group, options) => {
|
const htmlBuilder = (group: ParseNode<"font">, options) => {
|
||||||
const font = group.value.font;
|
const font = group.font;
|
||||||
const newOptions = options.withFont(font);
|
const newOptions = options.withFont(font);
|
||||||
return html.buildGroup(group.value.body, newOptions);
|
return html.buildGroup(group.body, newOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
const mathmlBuilder = (group, options) => {
|
const mathmlBuilder = (group: ParseNode<"font">, options) => {
|
||||||
const font = group.value.font;
|
const font = group.font;
|
||||||
const newOptions = options.withFont(font);
|
const newOptions = options.withFont(font);
|
||||||
return mml.buildGroup(group.value.body, newOptions);
|
return mml.buildGroup(group.body, newOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
const fontAliases = {
|
const fontAliases = {
|
||||||
@@ -53,11 +54,8 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "font",
|
type: "font",
|
||||||
mode: parser.mode,
|
mode: parser.mode,
|
||||||
value: {
|
font: func.slice(1),
|
||||||
type: "font",
|
body,
|
||||||
font: func.slice(1),
|
|
||||||
body,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
htmlBuilder,
|
htmlBuilder,
|
||||||
@@ -78,21 +76,15 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "mclass",
|
type: "mclass",
|
||||||
mode: parser.mode,
|
mode: parser.mode,
|
||||||
value: {
|
mclass: binrelClass(body),
|
||||||
type: "mclass",
|
body: [
|
||||||
mclass: binrelClass(body),
|
{
|
||||||
value: [
|
type: "font",
|
||||||
{
|
mode: parser.mode,
|
||||||
type: "font",
|
font: "boldsymbol",
|
||||||
mode: parser.mode,
|
body,
|
||||||
value: {
|
},
|
||||||
type: "font",
|
],
|
||||||
font: "boldsymbol",
|
|
||||||
body,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -114,14 +106,11 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "font",
|
type: "font",
|
||||||
mode: mode,
|
mode: mode,
|
||||||
value: {
|
font: style,
|
||||||
type: "font",
|
body: {
|
||||||
font: style,
|
type: "ordgroup",
|
||||||
body: {
|
mode: parser.mode,
|
||||||
type: "ordgroup",
|
value: body,
|
||||||
mode: parser.mode,
|
|
||||||
value: body,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@@ -18,31 +18,21 @@ defineFunction({
|
|||||||
},
|
},
|
||||||
handler: ({parser}, args) => {
|
handler: ({parser}, args) => {
|
||||||
const body = args[1];
|
const body = args[1];
|
||||||
const href = assertNodeType(args[0], "url").value.value;
|
const href = assertNodeType(args[0], "url").url;
|
||||||
return {
|
return {
|
||||||
type: "href",
|
type: "href",
|
||||||
mode: parser.mode,
|
mode: parser.mode,
|
||||||
value: {
|
href,
|
||||||
type: "href",
|
body: ordargument(body),
|
||||||
href: href,
|
|
||||||
body: ordargument(body),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
htmlBuilder: (group, options) => {
|
htmlBuilder: (group, options) => {
|
||||||
const elements = html.buildExpression(
|
const elements = html.buildExpression(group.body, options, false);
|
||||||
group.value.body,
|
return new buildCommon.makeAnchor(group.href, [], elements, options);
|
||||||
options,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
const href = group.value.href;
|
|
||||||
|
|
||||||
return new buildCommon.makeAnchor(href, [], elements, options);
|
|
||||||
},
|
},
|
||||||
mathmlBuilder: (group, options) => {
|
mathmlBuilder: (group, options) => {
|
||||||
const math = mml.buildExpressionRow(group.value.body, options);
|
const math = mml.buildExpressionRow(group.body, options);
|
||||||
assertType(math, MathNode).setAttribute("href", group.value.href);
|
assertType(math, MathNode).setAttribute("href", group.href);
|
||||||
return math;
|
return math;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -56,7 +46,7 @@ defineFunction({
|
|||||||
allowedInText: true,
|
allowedInText: true,
|
||||||
},
|
},
|
||||||
handler: ({parser}, args) => {
|
handler: ({parser}, args) => {
|
||||||
const href = assertNodeType(args[0], "url").value.value;
|
const href = assertNodeType(args[0], "url").url;
|
||||||
const chars = [];
|
const chars = [];
|
||||||
for (let i = 0; i < href.length; i++) {
|
for (let i = 0; i < href.length; i++) {
|
||||||
let c = href[i];
|
let c = href[i];
|
||||||
@@ -81,11 +71,8 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "href",
|
type: "href",
|
||||||
mode: parser.mode,
|
mode: parser.mode,
|
||||||
value: {
|
href,
|
||||||
type: "href",
|
body: ordargument(body),
|
||||||
href: href,
|
|
||||||
body: ordargument(body),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@@ -6,19 +6,16 @@ import Style from "../Style";
|
|||||||
import * as html from "../buildHTML";
|
import * as html from "../buildHTML";
|
||||||
import * as mml from "../buildMathML";
|
import * as mml from "../buildMathML";
|
||||||
|
|
||||||
const chooseMathStyle = (group, options) => {
|
import type {ParseNode} from "../parseNode";
|
||||||
const style = options.style;
|
|
||||||
if (style.size === Style.DISPLAY.size) {
|
|
||||||
return group.value.display;
|
|
||||||
} else if (style.size === Style.TEXT.size) {
|
|
||||||
return group.value.text;
|
|
||||||
} else if (style.size === Style.SCRIPT.size) {
|
|
||||||
return group.value.script;
|
|
||||||
} else if (style.size === Style.SCRIPTSCRIPT.size) {
|
|
||||||
return group.value.scriptscript;
|
|
||||||
}
|
|
||||||
return group.value.text;
|
|
||||||
|
|
||||||
|
const chooseMathStyle = (group: ParseNode<"mathchoice">, options) => {
|
||||||
|
switch (options.style.size) {
|
||||||
|
case Style.DISPLAY.size: return group.display;
|
||||||
|
case Style.TEXT.size: return group.text;
|
||||||
|
case Style.SCRIPT.size: return group.script;
|
||||||
|
case Style.SCRIPTSCRIPT.size: return group.scriptscript;
|
||||||
|
default: return group.text;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
defineFunction({
|
defineFunction({
|
||||||
@@ -31,13 +28,10 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "mathchoice",
|
type: "mathchoice",
|
||||||
mode: parser.mode,
|
mode: parser.mode,
|
||||||
value: {
|
display: ordargument(args[0]),
|
||||||
type: "mathchoice",
|
text: ordargument(args[1]),
|
||||||
display: ordargument(args[0]),
|
script: ordargument(args[2]),
|
||||||
text: ordargument(args[1]),
|
scriptscript: ordargument(args[3]),
|
||||||
script: ordargument(args[2]),
|
|
||||||
scriptscript: ordargument(args[3]),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
htmlBuilder: (group, options) => {
|
htmlBuilder: (group, options) => {
|
||||||
|
@@ -7,15 +7,17 @@ import type {AnyParseNode} from "../parseNode";
|
|||||||
import * as html from "../buildHTML";
|
import * as html from "../buildHTML";
|
||||||
import * as mml from "../buildMathML";
|
import * as mml from "../buildMathML";
|
||||||
|
|
||||||
|
import type {ParseNode} from "../parseNode";
|
||||||
|
|
||||||
const makeSpan = buildCommon.makeSpan;
|
const makeSpan = buildCommon.makeSpan;
|
||||||
|
|
||||||
function htmlBuilder(group, options) {
|
function htmlBuilder(group: ParseNode<"mclass">, options) {
|
||||||
const elements = html.buildExpression(group.value.value, options, true);
|
const elements = html.buildExpression(group.body, options, true);
|
||||||
return makeSpan([group.value.mclass], elements, options);
|
return makeSpan([group.mclass], elements, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mathmlBuilder(group, options) {
|
function mathmlBuilder(group: ParseNode<"mclass">, options) {
|
||||||
const inner = mml.buildExpression(group.value.value, options);
|
const inner = mml.buildExpression(group.body, options);
|
||||||
return mathMLTree.newDocumentFragment(inner);
|
return mathMLTree.newDocumentFragment(inner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,11 +36,8 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "mclass",
|
type: "mclass",
|
||||||
mode: parser.mode,
|
mode: parser.mode,
|
||||||
value: {
|
mclass: "m" + funcName.substr(5),
|
||||||
type: "mclass",
|
body: ordargument(body),
|
||||||
mclass: "m" + funcName.substr(5),
|
|
||||||
value: ordargument(body),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
htmlBuilder,
|
htmlBuilder,
|
||||||
@@ -70,11 +69,8 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "mclass",
|
type: "mclass",
|
||||||
mode: parser.mode,
|
mode: parser.mode,
|
||||||
value: {
|
mclass: binrelClass(args[0]),
|
||||||
type: "mclass",
|
body: [args[1]],
|
||||||
mclass: binrelClass(args[0]),
|
|
||||||
value: [args[1]],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -119,11 +115,8 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "mclass",
|
type: "mclass",
|
||||||
mode: parser.mode,
|
mode: parser.mode,
|
||||||
value: {
|
mclass,
|
||||||
type: "mclass",
|
body: [supsub],
|
||||||
mclass: mclass,
|
|
||||||
value: [supsub],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
htmlBuilder,
|
htmlBuilder,
|
||||||
|
@@ -18,15 +18,12 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "phantom",
|
type: "phantom",
|
||||||
mode: parser.mode,
|
mode: parser.mode,
|
||||||
value: {
|
body: ordargument(body),
|
||||||
type: "phantom",
|
|
||||||
value: ordargument(body),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
htmlBuilder: (group, options) => {
|
htmlBuilder: (group, options) => {
|
||||||
const elements = html.buildExpression(
|
const elements = html.buildExpression(
|
||||||
group.value.value,
|
group.body,
|
||||||
options.withPhantom(),
|
options.withPhantom(),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
@@ -36,7 +33,7 @@ defineFunction({
|
|||||||
return new buildCommon.makeFragment(elements);
|
return new buildCommon.makeFragment(elements);
|
||||||
},
|
},
|
||||||
mathmlBuilder: (group, options) => {
|
mathmlBuilder: (group, options) => {
|
||||||
const inner = mml.buildExpression(group.value.value, options);
|
const inner = mml.buildExpression(group.body, options);
|
||||||
return new mathMLTree.MathNode("mphantom", inner);
|
return new mathMLTree.MathNode("mphantom", inner);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -53,16 +50,12 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "hphantom",
|
type: "hphantom",
|
||||||
mode: parser.mode,
|
mode: parser.mode,
|
||||||
value: {
|
body,
|
||||||
type: "hphantom",
|
|
||||||
value: ordargument(body),
|
|
||||||
body: body,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
htmlBuilder: (group, options) => {
|
htmlBuilder: (group, options) => {
|
||||||
let node = buildCommon.makeSpan(
|
let node = buildCommon.makeSpan(
|
||||||
[], [html.buildGroup(group.value.body, options.withPhantom())]);
|
[], [html.buildGroup(group.body, options.withPhantom())]);
|
||||||
node.height = 0;
|
node.height = 0;
|
||||||
node.depth = 0;
|
node.depth = 0;
|
||||||
if (node.children) {
|
if (node.children) {
|
||||||
@@ -81,7 +74,7 @@ defineFunction({
|
|||||||
return node;
|
return node;
|
||||||
},
|
},
|
||||||
mathmlBuilder: (group, options) => {
|
mathmlBuilder: (group, options) => {
|
||||||
const inner = mml.buildExpression(group.value.value, options);
|
const inner = mml.buildExpression(ordargument(group.body), options);
|
||||||
const node = new mathMLTree.MathNode("mphantom", inner);
|
const node = new mathMLTree.MathNode("mphantom", inner);
|
||||||
node.setAttribute("height", "0px");
|
node.setAttribute("height", "0px");
|
||||||
return node;
|
return node;
|
||||||
@@ -100,23 +93,19 @@ defineFunction({
|
|||||||
return {
|
return {
|
||||||
type: "vphantom",
|
type: "vphantom",
|
||||||
mode: parser.mode,
|
mode: parser.mode,
|
||||||
value: {
|
body,
|
||||||
type: "vphantom",
|
|
||||||
value: ordargument(body),
|
|
||||||
body: body,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
htmlBuilder: (group, options) => {
|
htmlBuilder: (group, options) => {
|
||||||
const inner = buildCommon.makeSpan(
|
const inner = buildCommon.makeSpan(
|
||||||
["inner"],
|
["inner"],
|
||||||
[html.buildGroup(group.value.body, options.withPhantom())]);
|
[html.buildGroup(group.body, options.withPhantom())]);
|
||||||
const fix = buildCommon.makeSpan(["fix"], []);
|
const fix = buildCommon.makeSpan(["fix"], []);
|
||||||
return buildCommon.makeSpan(
|
return buildCommon.makeSpan(
|
||||||
["mord", "rlap"], [inner, fix], options);
|
["mord", "rlap"], [inner, fix], options);
|
||||||
},
|
},
|
||||||
mathmlBuilder: (group, options) => {
|
mathmlBuilder: (group, options) => {
|
||||||
const inner = mml.buildExpression(group.value.value, options);
|
const inner = mml.buildExpression(ordargument(group.body), options);
|
||||||
const node = new mathMLTree.MathNode("mphantom", inner);
|
const node = new mathMLTree.MathNode("mphantom", inner);
|
||||||
node.setAttribute("width", "0px");
|
node.setAttribute("width", "0px");
|
||||||
return node;
|
return node;
|
||||||
|
@@ -10,10 +10,10 @@ defineFunctionBuilders({
|
|||||||
const table = new mathMLTree.MathNode("mtable", [
|
const table = new mathMLTree.MathNode("mtable", [
|
||||||
new mathMLTree.MathNode("mlabeledtr", [
|
new mathMLTree.MathNode("mlabeledtr", [
|
||||||
new mathMLTree.MathNode("mtd", [
|
new mathMLTree.MathNode("mtd", [
|
||||||
mml.buildExpressionRow(group.value.tag, options),
|
mml.buildExpressionRow(group.tag, options),
|
||||||
]),
|
]),
|
||||||
new mathMLTree.MathNode("mtd", [
|
new mathMLTree.MathNode("mtd", [
|
||||||
mml.buildExpressionRow(group.value.body, options),
|
mml.buildExpressionRow(group.body, options),
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
|
117
src/parseNode.js
117
src/parseNode.js
@@ -10,13 +10,6 @@ import type {Measurement} from "./units";
|
|||||||
export type NodeType = $Keys<ParseNodeTypes>;
|
export type NodeType = $Keys<ParseNodeTypes>;
|
||||||
export type ParseNode<TYPE: NodeType> = $ElementType<ParseNodeTypes, TYPE>;
|
export type ParseNode<TYPE: NodeType> = $ElementType<ParseNodeTypes, TYPE>;
|
||||||
|
|
||||||
export type LeftRightDelimType = {|
|
|
||||||
type: "leftright",
|
|
||||||
body: AnyParseNode[],
|
|
||||||
left: string,
|
|
||||||
right: string,
|
|
||||||
|};
|
|
||||||
|
|
||||||
// ParseNode's corresponding to Symbol `Group`s in symbols.js.
|
// ParseNode's corresponding to Symbol `Group`s in symbols.js.
|
||||||
export type SymbolParseNode =
|
export type SymbolParseNode =
|
||||||
ParseNode<"atom"> |
|
ParseNode<"atom"> |
|
||||||
@@ -116,11 +109,8 @@ type ParseNodeTypes = {
|
|||||||
type: "tag",
|
type: "tag",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
body: AnyParseNode[],
|
||||||
type: "tag",
|
tag: AnyParseNode[],
|
||||||
body: AnyParseNode[],
|
|
||||||
tag: AnyParseNode[],
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
"text": {|
|
"text": {|
|
||||||
type: "text",
|
type: "text",
|
||||||
@@ -136,20 +126,14 @@ type ParseNodeTypes = {
|
|||||||
type: "url",
|
type: "url",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
url: string,
|
||||||
type: "url",
|
|
||||||
value: string,
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
"verb": {|
|
"verb": {|
|
||||||
type: "verb",
|
type: "verb",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
body: string,
|
||||||
type: "verb",
|
star: boolean,
|
||||||
body: string,
|
|
||||||
star: boolean,
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
// From symbol groups, constructed in Parser.js via `symbols` lookup.
|
// From symbol groups, constructed in Parser.js via `symbols` lookup.
|
||||||
// (Some of these have "-token" suffix to distinguish them from existing
|
// (Some of these have "-token" suffix to distinguish them from existing
|
||||||
@@ -216,23 +200,17 @@ type ParseNodeTypes = {
|
|||||||
type: "cr",
|
type: "cr",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
newRow: boolean,
|
||||||
type: "cr",
|
newLine: boolean,
|
||||||
newRow: boolean,
|
size: ?ParseNode<"size">,
|
||||||
newLine: boolean,
|
|
||||||
size: ?ParseNode<"size">,
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
"delimsizing": {|
|
"delimsizing": {|
|
||||||
type: "delimsizing",
|
type: "delimsizing",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
size: 1 | 2 | 3 | 4,
|
||||||
type: "delimsizing",
|
mclass: "mopen" | "mclose" | "mrel" | "mord",
|
||||||
size: 1 | 2 | 3 | 4,
|
delim: string,
|
||||||
mclass: "mopen" | "mclose" | "mrel" | "mord",
|
|
||||||
value: string,
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
"enclose": {|
|
"enclose": {|
|
||||||
type: "enclose",
|
type: "enclose",
|
||||||
@@ -260,11 +238,8 @@ type ParseNodeTypes = {
|
|||||||
type: "font",
|
type: "font",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
font: string,
|
||||||
type: "font",
|
body: AnyParseNode,
|
||||||
font: string,
|
|
||||||
body: AnyParseNode,
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
"genfrac": {|
|
"genfrac": {|
|
||||||
type: "genfrac",
|
type: "genfrac",
|
||||||
@@ -294,11 +269,8 @@ type ParseNodeTypes = {
|
|||||||
type: "href",
|
type: "href",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
href: string,
|
||||||
type: "href",
|
body: AnyParseNode[],
|
||||||
href: string,
|
|
||||||
body: AnyParseNode[],
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
"htmlmathml": {|
|
"htmlmathml": {|
|
||||||
type: "htmlmathml",
|
type: "htmlmathml",
|
||||||
@@ -344,57 +316,37 @@ type ParseNodeTypes = {
|
|||||||
type: "leftright",
|
type: "leftright",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: LeftRightDelimType,
|
body: AnyParseNode[],
|
||||||
|
left: string,
|
||||||
|
right: string,
|
||||||
|},
|
|},
|
||||||
"leftright-right": {|
|
"leftright-right": {|
|
||||||
type: "leftright-right",
|
type: "leftright-right",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
delim: string,
|
||||||
type: "leftright-right",
|
|
||||||
value: string,
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
"mathchoice": {|
|
"mathchoice": {|
|
||||||
type: "mathchoice",
|
type: "mathchoice",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
display: AnyParseNode[],
|
||||||
type: "mathchoice",
|
text: AnyParseNode[],
|
||||||
display: AnyParseNode[],
|
script: AnyParseNode[],
|
||||||
text: AnyParseNode[],
|
scriptscript: AnyParseNode[],
|
||||||
script: AnyParseNode[],
|
|
||||||
scriptscript: AnyParseNode[],
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
"middle": {|
|
"middle": {|
|
||||||
type: "middle",
|
type: "middle",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
delim: string,
|
||||||
type: "middle",
|
|
||||||
value: string,
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
"mclass": {|
|
"mclass": {|
|
||||||
type: "mclass",
|
type: "mclass",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
mclass: string,
|
||||||
type: "mclass",
|
body: AnyParseNode[],
|
||||||
mclass: string,
|
|
||||||
value: AnyParseNode[],
|
|
||||||
|},
|
|
||||||
|},
|
|
||||||
"mod": {|
|
|
||||||
type: "mod",
|
|
||||||
mode: Mode,
|
|
||||||
loc?: ?SourceLocation,
|
|
||||||
value: {|
|
|
||||||
type: "mod",
|
|
||||||
modType: string,
|
|
||||||
value: ?AnyParseNode[],
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
"operatorname": {|
|
"operatorname": {|
|
||||||
type: "operatorname",
|
type: "operatorname",
|
||||||
@@ -418,30 +370,19 @@ type ParseNodeTypes = {
|
|||||||
type: "phantom",
|
type: "phantom",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
body: AnyParseNode[],
|
||||||
type: "phantom",
|
|
||||||
value: AnyParseNode[],
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
"hphantom": {|
|
"hphantom": {|
|
||||||
type: "hphantom",
|
type: "hphantom",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
body: AnyParseNode,
|
||||||
type: "hphantom",
|
|
||||||
body: AnyParseNode,
|
|
||||||
value: AnyParseNode[],
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
"vphantom": {|
|
"vphantom": {|
|
||||||
type: "vphantom",
|
type: "vphantom",
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
loc?: ?SourceLocation,
|
loc?: ?SourceLocation,
|
||||||
value: {|
|
body: AnyParseNode,
|
||||||
type: "vphantom",
|
|
||||||
body: AnyParseNode,
|
|
||||||
value: AnyParseNode[],
|
|
||||||
|},
|
|
||||||
|},
|
|},
|
||||||
"raisebox": {|
|
"raisebox": {|
|
||||||
type: "raisebox",
|
type: "raisebox",
|
||||||
|
@@ -32,11 +32,8 @@ const parseTree = function(toParse: string, settings: Settings): AnyParseNode[]
|
|||||||
tree = [{
|
tree = [{
|
||||||
type: "tag",
|
type: "tag",
|
||||||
mode: "text",
|
mode: "text",
|
||||||
value: {
|
body: tree,
|
||||||
type: "tag",
|
tag: parser.parse(),
|
||||||
body: tree,
|
|
||||||
tag: parser.parse(),
|
|
||||||
},
|
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -110,7 +110,7 @@ const getBaseElem = function(group: AnyParseNode): AnyParseNode {
|
|||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
} else if (group.type === "font") {
|
} else if (group.type === "font") {
|
||||||
return getBaseElem(group.value.body);
|
return getBaseElem(group.body);
|
||||||
} else {
|
} else {
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
@@ -751,22 +751,19 @@ exports[`An implicit group parser within optional groups should work with old fo
|
|||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"type": "font",
|
"type": "font",
|
||||||
"mode": "math",
|
"body": {
|
||||||
"value": {
|
"type": "ordgroup",
|
||||||
"type": "font",
|
"mode": "math",
|
||||||
"body": {
|
"value": [
|
||||||
"type": "ordgroup",
|
{
|
||||||
"mode": "math",
|
"type": "textord",
|
||||||
"value": [
|
"mode": "math",
|
||||||
{
|
"value": "3"
|
||||||
"type": "textord",
|
}
|
||||||
"mode": "math",
|
]
|
||||||
"value": "3"
|
},
|
||||||
}
|
"font": "mathtt",
|
||||||
]
|
"mode": "math"
|
||||||
},
|
|
||||||
"font": "mathtt"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -95,7 +95,7 @@ describe("A rel parser", function() {
|
|||||||
group = group.value.html[0];
|
group = group.value.html[0];
|
||||||
}
|
}
|
||||||
if (group.type === "mclass") {
|
if (group.type === "mclass") {
|
||||||
expect(group.value.mclass).toEqual("mrel");
|
expect(group.mclass).toEqual("mrel");
|
||||||
} else {
|
} else {
|
||||||
expect(group.type).toEqual("atom");
|
expect(group.type).toEqual("atom");
|
||||||
expect(group.family).toEqual("rel");
|
expect(group.family).toEqual("rel");
|
||||||
@@ -895,16 +895,16 @@ describe("A delimiter sizing parser", function() {
|
|||||||
const leftParse = getParsed(normalDelim)[0];
|
const leftParse = getParsed(normalDelim)[0];
|
||||||
const rightParse = getParsed(bigDelim)[0];
|
const rightParse = getParsed(bigDelim)[0];
|
||||||
|
|
||||||
expect(leftParse.value.mclass).toEqual("mopen");
|
expect(leftParse.mclass).toEqual("mopen");
|
||||||
expect(rightParse.value.mclass).toEqual("mclose");
|
expect(rightParse.mclass).toEqual("mclose");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse the correct size delimiter", function() {
|
it("should parse the correct size delimiter", function() {
|
||||||
const smallParse = getParsed(normalDelim)[0];
|
const smallParse = getParsed(normalDelim)[0];
|
||||||
const bigParse = getParsed(bigDelim)[0];
|
const bigParse = getParsed(bigDelim)[0];
|
||||||
|
|
||||||
expect(smallParse.value.size).toEqual(1);
|
expect(smallParse.size).toEqual(1);
|
||||||
expect(bigParse.value.size).toEqual(4);
|
expect(bigParse.size).toEqual(4);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1122,8 +1122,8 @@ describe("A left/right parser", function() {
|
|||||||
const parse = getParsed(normalLeftRight)[0];
|
const parse = getParsed(normalLeftRight)[0];
|
||||||
|
|
||||||
expect(parse.type).toEqual("leftright");
|
expect(parse.type).toEqual("leftright");
|
||||||
expect(parse.value.left).toEqual("(");
|
expect(parse.left).toEqual("(");
|
||||||
expect(parse.value.right).toEqual(")");
|
expect(parse.right).toEqual(")");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should error when it is mismatched", function() {
|
it("should error when it is mismatched", function() {
|
||||||
@@ -1476,37 +1476,37 @@ describe("A font parser", function() {
|
|||||||
|
|
||||||
it("should produce the correct fonts", function() {
|
it("should produce the correct fonts", function() {
|
||||||
const mathbbParse = getParsed`\mathbb x`[0];
|
const mathbbParse = getParsed`\mathbb x`[0];
|
||||||
expect(mathbbParse.value.font).toEqual("mathbb");
|
expect(mathbbParse.font).toEqual("mathbb");
|
||||||
expect(mathbbParse.value.type).toEqual("font");
|
expect(mathbbParse.type).toEqual("font");
|
||||||
|
|
||||||
const mathrmParse = getParsed`\mathrm x`[0];
|
const mathrmParse = getParsed`\mathrm x`[0];
|
||||||
expect(mathrmParse.value.font).toEqual("mathrm");
|
expect(mathrmParse.font).toEqual("mathrm");
|
||||||
expect(mathrmParse.value.type).toEqual("font");
|
expect(mathrmParse.type).toEqual("font");
|
||||||
|
|
||||||
const mathitParse = getParsed`\mathit x`[0];
|
const mathitParse = getParsed`\mathit x`[0];
|
||||||
expect(mathitParse.value.font).toEqual("mathit");
|
expect(mathitParse.font).toEqual("mathit");
|
||||||
expect(mathitParse.value.type).toEqual("font");
|
expect(mathitParse.type).toEqual("font");
|
||||||
|
|
||||||
const mathcalParse = getParsed`\mathcal C`[0];
|
const mathcalParse = getParsed`\mathcal C`[0];
|
||||||
expect(mathcalParse.value.font).toEqual("mathcal");
|
expect(mathcalParse.font).toEqual("mathcal");
|
||||||
expect(mathcalParse.value.type).toEqual("font");
|
expect(mathcalParse.type).toEqual("font");
|
||||||
|
|
||||||
const mathfrakParse = getParsed`\mathfrak C`[0];
|
const mathfrakParse = getParsed`\mathfrak C`[0];
|
||||||
expect(mathfrakParse.value.font).toEqual("mathfrak");
|
expect(mathfrakParse.font).toEqual("mathfrak");
|
||||||
expect(mathfrakParse.value.type).toEqual("font");
|
expect(mathfrakParse.type).toEqual("font");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse nested font commands", function() {
|
it("should parse nested font commands", function() {
|
||||||
const nestedParse = getParsed`\mathbb{R \neq \mathrm{R}}`[0];
|
const nestedParse = getParsed`\mathbb{R \neq \mathrm{R}}`[0];
|
||||||
expect(nestedParse.value.font).toEqual("mathbb");
|
expect(nestedParse.font).toEqual("mathbb");
|
||||||
expect(nestedParse.value.type).toEqual("font");
|
expect(nestedParse.type).toEqual("font");
|
||||||
|
|
||||||
const bbBody = nestedParse.value.body.value;
|
const bbBody = nestedParse.body.value;
|
||||||
expect(bbBody).toHaveLength(3);
|
expect(bbBody).toHaveLength(3);
|
||||||
expect(bbBody[0].type).toEqual("mathord");
|
expect(bbBody[0].type).toEqual("mathord");
|
||||||
expect(bbBody[2].type).toEqual("font");
|
expect(bbBody[2].type).toEqual("font");
|
||||||
expect(bbBody[2].value.font).toEqual("mathrm");
|
expect(bbBody[2].font).toEqual("mathrm");
|
||||||
expect(bbBody[2].value.type).toEqual("font");
|
expect(bbBody[2].type).toEqual("font");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should work with \\textcolor", function() {
|
it("should work with \\textcolor", function() {
|
||||||
@@ -1515,8 +1515,8 @@ describe("A font parser", function() {
|
|||||||
expect(colorMathbbParse.value.color).toEqual("blue");
|
expect(colorMathbbParse.value.color).toEqual("blue");
|
||||||
const body = colorMathbbParse.value.value;
|
const body = colorMathbbParse.value.value;
|
||||||
expect(body).toHaveLength(1);
|
expect(body).toHaveLength(1);
|
||||||
expect(body[0].value.type).toEqual("font");
|
expect(body[0].type).toEqual("font");
|
||||||
expect(body[0].value.font).toEqual("mathbb");
|
expect(body[0].font).toEqual("mathbb");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not parse a series of font commands", function() {
|
it("should not parse a series of font commands", function() {
|
||||||
@@ -1525,13 +1525,13 @@ describe("A font parser", function() {
|
|||||||
|
|
||||||
it("should nest fonts correctly", function() {
|
it("should nest fonts correctly", function() {
|
||||||
const bf = getParsed`\mathbf{a\mathrm{b}c}`[0];
|
const bf = getParsed`\mathbf{a\mathrm{b}c}`[0];
|
||||||
expect(bf.value.type).toEqual("font");
|
expect(bf.type).toEqual("font");
|
||||||
expect(bf.value.font).toEqual("mathbf");
|
expect(bf.font).toEqual("mathbf");
|
||||||
expect(bf.value.body.value).toHaveLength(3);
|
expect(bf.body.value).toHaveLength(3);
|
||||||
expect(bf.value.body.value[0].value).toEqual("a");
|
expect(bf.body.value[0].value).toEqual("a");
|
||||||
expect(bf.value.body.value[1].value.type).toEqual("font");
|
expect(bf.body.value[1].type).toEqual("font");
|
||||||
expect(bf.value.body.value[1].value.font).toEqual("mathrm");
|
expect(bf.body.value[1].font).toEqual("mathrm");
|
||||||
expect(bf.value.body.value[2].value).toEqual("c");
|
expect(bf.body.value[2].value).toEqual("c");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should have the correct greediness", function() {
|
it("should have the correct greediness", function() {
|
||||||
@@ -2292,7 +2292,7 @@ describe("A phantom parser", function() {
|
|||||||
const parse = getParsed`\phantom{x}`[0];
|
const parse = getParsed`\phantom{x}`[0];
|
||||||
|
|
||||||
expect(parse.type).toEqual("phantom");
|
expect(parse.type).toEqual("phantom");
|
||||||
expect(parse.value.value).toBeDefined();
|
expect(parse.body).toBeDefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2499,17 +2499,17 @@ describe("href and url commands", function() {
|
|||||||
it("should allow letters [#$%&~_^] without escaping", function() {
|
it("should allow letters [#$%&~_^] without escaping", function() {
|
||||||
const url = "http://example.org/~bar/#top?foo=$foo&bar=ba^r_boo%20baz";
|
const url = "http://example.org/~bar/#top?foo=$foo&bar=ba^r_boo%20baz";
|
||||||
const parsed1 = getParsed(`\\href{${url}}{\\alpha}`)[0];
|
const parsed1 = getParsed(`\\href{${url}}{\\alpha}`)[0];
|
||||||
expect(parsed1.value.href).toBe(url);
|
expect(parsed1.href).toBe(url);
|
||||||
const parsed2 = getParsed(`\\url{${url}}`)[0];
|
const parsed2 = getParsed(`\\url{${url}}`)[0];
|
||||||
expect(parsed2.value.href).toBe(url);
|
expect(parsed2.href).toBe(url);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should allow balanced braces in url", function() {
|
it("should allow balanced braces in url", function() {
|
||||||
const url = "http://example.org/{too}";
|
const url = "http://example.org/{too}";
|
||||||
const parsed1 = getParsed(`\\href{${url}}{\\alpha}`)[0];
|
const parsed1 = getParsed(`\\href{${url}}{\\alpha}`)[0];
|
||||||
expect(parsed1.value.href).toBe(url);
|
expect(parsed1.href).toBe(url);
|
||||||
const parsed2 = getParsed(`\\url{${url}}`)[0];
|
const parsed2 = getParsed(`\\url{${url}}`)[0];
|
||||||
expect(parsed2.value.href).toBe(url);
|
expect(parsed2.href).toBe(url);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not allow unbalanced brace(s) in url", function() {
|
it("should not allow unbalanced brace(s) in url", function() {
|
||||||
@@ -2523,9 +2523,9 @@ describe("href and url commands", function() {
|
|||||||
const url = "http://example.org/~bar/#top?foo=$}foo{&bar=bar^r_boo%20baz";
|
const url = "http://example.org/~bar/#top?foo=$}foo{&bar=bar^r_boo%20baz";
|
||||||
const input = url.replace(/([#$%&~_^{}])/g, '\\$1');
|
const input = url.replace(/([#$%&~_^{}])/g, '\\$1');
|
||||||
const parsed1 = getParsed(`\\href{${input}}{\\alpha}`)[0];
|
const parsed1 = getParsed(`\\href{${input}}{\\alpha}`)[0];
|
||||||
expect(parsed1.value.href).toBe(url);
|
expect(parsed1.href).toBe(url);
|
||||||
const parsed2 = getParsed(`\\url{${input}}`)[0];
|
const parsed2 = getParsed(`\\url{${input}}`)[0];
|
||||||
expect(parsed2.value.href).toBe(url);
|
expect(parsed2.href).toBe(url);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be marked up correctly", function() {
|
it("should be marked up correctly", function() {
|
||||||
|
Reference in New Issue
Block a user