@vivliostyle/vfm
Version:
Custom Markdown syntax specialized in book authoring.
189 lines (188 loc) • 6.62 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.hast = exports.handlerDisplayMath = exports.handlerInlineMath = exports.mdast = void 0;
var hast_util_select_1 = require("hast-util-select");
var mdast_util_find_and_replace_1 = __importDefault(require("mdast-util-find-and-replace"));
var unist_builder_1 = __importDefault(require("unist-builder"));
var unist_util_visit_1 = __importDefault(require("unist-util-visit"));
/**
* Inline math format, e.g. `$...$`.
* - OK: `$x = y$`, `$x = \$y$`
* - NG: `$$x = y$`, `$x = y$$`, `$ x = y$`, `$x = y $`, `$x = y$7`
*/
var REGEXP_INLINE = /\$([^$\s].*?(?<=[^\\$\s]|[^\\](?:\\\\)+))\$(?!\$|\d)/gs;
/** Display math format, e.g. `$$...$$`. */
var REGEXP_DISPLAY = /\$\$([^$].*?(?<=[^$]))\$\$(?!\$)/gs;
/** Type of inline math in Markdown AST. */
var TYPE_INLINE = 'inlineMath';
/** Type of display math in Markdown AST. */
var TYPE_DISPLAY = 'displayMath';
/** URL of MathJax v2 supported by Vivliostyle. */
var MATH_URL = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.9/MathJax.js?config=TeX-MML-AM_CHTML';
/**
* Create tokenizers for remark-parse.
* @returns Tokenizers.
*/
var createTokenizers = function () {
var tokenizerInlineMath = function (eat, value, silent) {
if (!value.startsWith('$') ||
value.startsWith('$ ') ||
value.startsWith('$$')) {
return;
}
var match = new RegExp(REGEXP_INLINE).exec(value);
if (!match) {
return;
}
if (silent) {
return true;
}
var eaten = match[0], valueText = match[1];
var now = eat.now();
now.column += 1;
now.offset += 1;
return eat(eaten)({
type: TYPE_INLINE,
children: [],
data: { hName: TYPE_INLINE, value: valueText },
});
};
tokenizerInlineMath.notInLink = true;
tokenizerInlineMath.locator = function (value, fromIndex) {
return value.indexOf('$', fromIndex);
};
var tokenizerDisplayMath = function (eat, value, silent) {
if (!value.startsWith('$$') || value.startsWith('$$$')) {
return;
}
var match = new RegExp(REGEXP_DISPLAY).exec(value);
if (!match) {
return;
}
if (silent) {
return true;
}
var eaten = match[0], valueText = match[1];
var now = eat.now();
now.column += 1;
now.offset += 1;
return eat(eaten)({
type: TYPE_DISPLAY,
children: [],
data: { hName: TYPE_DISPLAY, value: valueText },
});
};
tokenizerDisplayMath.notInLink = true;
tokenizerDisplayMath.locator = function (value, fromIndex) {
return value.indexOf('$$', fromIndex);
};
return { tokenizerInlineMath: tokenizerInlineMath, tokenizerDisplayMath: tokenizerDisplayMath };
};
/**
* Process Markdown AST.
* @returns Transformer or undefined (less than remark 13).
*/
var mdast = function () {
// For less than remark 13 with exclusive other markdown syntax
if (this.Parser &&
this.Parser.prototype.inlineTokenizers &&
this.Parser.prototype.inlineMethods) {
var _a = this.Parser.prototype, inlineTokenizers = _a.inlineTokenizers, inlineMethods = _a.inlineMethods;
var tokenizers = createTokenizers();
inlineTokenizers[TYPE_INLINE] = tokenizers.tokenizerInlineMath;
inlineTokenizers[TYPE_DISPLAY] = tokenizers.tokenizerDisplayMath;
inlineMethods.splice(inlineMethods.indexOf('text'), 0, TYPE_INLINE);
inlineMethods.splice(inlineMethods.indexOf('text'), 0, TYPE_DISPLAY);
return;
}
return function (tree) {
(0, mdast_util_find_and_replace_1.default)(tree, REGEXP_INLINE, function (_, valueText) {
return {
type: TYPE_INLINE,
data: {
hName: TYPE_INLINE,
value: valueText,
},
children: [],
};
});
(0, mdast_util_find_and_replace_1.default)(tree, REGEXP_DISPLAY, function (_, valueText) {
return {
type: TYPE_DISPLAY,
data: {
hName: TYPE_DISPLAY,
value: valueText,
},
children: [],
};
});
};
};
exports.mdast = mdast;
/**
* Handle inline math to Hypertext AST.
* @param h Hypertext AST formatter.
* @param node Node.
* @returns Hypertext AST.
*/
var handlerInlineMath = function (h, node) {
if (!node.data) {
node.data = {};
}
return h({
type: 'element',
}, 'span', {
class: 'math inline',
'data-math-typeset': 'true',
}, [(0, unist_builder_1.default)('text', "\\(".concat(node.data.value, "\\)"))]);
};
exports.handlerInlineMath = handlerInlineMath;
/**
* Handle display math to Hypertext AST.
* @param h Hypertext AST formatter.
* @param node Node.
* @returns Hypertext AST.
*/
var handlerDisplayMath = function (h, node) {
if (!node.data) {
node.data = {};
}
return h({
type: 'element',
}, 'span', {
class: 'math display',
'data-math-typeset': 'true',
}, [(0, unist_builder_1.default)('text', "$$".concat(node.data.value, "$$"))]);
};
exports.handlerDisplayMath = handlerDisplayMath;
/**
* Process math related Hypertext AST.
* Set the `<script>` to load MathJax and `<body>` attribute that enable math typesetting.
*
* This function does the work even if it finds a `<math>` that it does not treat as a VFM. Therefore, call it only if the VFM option is `math: true`.
*/
var hast = function () { return function (tree) {
if (!((0, hast_util_select_1.select)('[data-math-typeset="true"]', tree) || (0, hast_util_select_1.select)('math', tree))) {
return;
}
(0, unist_util_visit_1.default)(tree, 'element', function (node) {
switch (node.tagName) {
case 'head':
node.children.push({
type: 'element',
tagName: 'script',
properties: {
async: true,
src: MATH_URL,
},
children: [],
});
node.children.push({ type: 'text', value: '\n' });
break;
}
});
}; };
exports.hast = hast;