@yozora/tokenizer-math
Version:
Tokenizer for processing fenced math block (formulas)
100 lines (92 loc) • 3.22 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var character = require('@yozora/character');
var FencedBlockTokenizer = require('@yozora/tokenizer-fenced-block');
var ast = require('@yozora/ast');
var coreTokenizer = require('@yozora/core-tokenizer');
const match = function (api) {
const { markers } = this;
const hook = FencedBlockTokenizer.fencedBlockMatch.call(this, api);
return {
...hook,
isContainingBlock: false,
eatOpener,
eatAndInterruptPreviousSibling,
};
function eatOpener(line, parentToken) {
const result = hook.eatOpener(line, parentToken);
if (result == null)
return null;
const { token } = result;
const [lft, rht] = character.calcTrimBoundaryOfCodePoints(token.infoString);
if (lft >= rht)
return result;
let i = rht - 1;
for (; i >= lft; --i) {
const c = token.infoString[i].codePoint;
if (!markers.includes(c))
break;
}
const countOfTailingMarker = rht - i - 1;
if (countOfTailingMarker !== token.markerCount)
return null;
const mathToken = {
...token,
infoString: [],
lines: [
{
nodePoints: token.infoString,
startIndex: 0,
endIndex: rht - countOfTailingMarker,
firstNonWhitespaceIndex: lft,
countOfPrecedeSpaces: 0,
},
],
};
return { token: mathToken, nextIndex: line.endIndex, saturated: true };
}
function eatAndInterruptPreviousSibling(line, prevSiblingToken, parentToken) {
const result = eatOpener(line, parentToken);
if (result == null)
return null;
return {
token: result.token,
nextIndex: result.nextIndex,
remainingSibling: prevSiblingToken,
saturated: result.saturated,
};
}
};
const parse = function (api) {
return {
parse: tokens => tokens.map(token => {
const contents = coreTokenizer.mergeContentLinesFaithfully(token.lines);
let value = character.calcStringFromNodePoints(contents);
if (!/\n$/.test(value))
value += '\n';
const node = api.shouldReservePosition
? { type: ast.MathType, position: token.position, value }
: { type: ast.MathType, value };
return node;
}),
};
};
const uniqueName = '@yozora/tokenizer-math';
class MathTokenizer extends FencedBlockTokenizer {
constructor(props = {}) {
super({
name: props.name ?? uniqueName,
priority: props.priority ?? coreTokenizer.TokenizerPriority.FENCED_BLOCK,
nodeType: ast.MathType,
markers: [character.AsciiCodePoint.DOLLAR_SIGN],
markersRequired: 2,
});
}
match = match;
parse = parse;
}
exports.MathTokenizer = MathTokenizer;
exports.MathTokenizerName = uniqueName;
exports.default = MathTokenizer;
exports.mathMatch = match;
exports.mathParse = parse;