forked from nbsp/marked-mfm
274 lines
7.4 KiB
JavaScript
274 lines
7.4 KiB
JavaScript
'use strict';
|
|
|
|
function _wrapRegExp() {
|
|
_wrapRegExp = function (re, groups) {
|
|
return new BabelRegExp(re, void 0, groups);
|
|
};
|
|
|
|
var _super = RegExp.prototype,
|
|
_groups = new WeakMap();
|
|
|
|
function BabelRegExp(re, flags, groups) {
|
|
var _this = new RegExp(re, flags);
|
|
|
|
return _groups.set(_this, groups || _groups.get(re)), _setPrototypeOf(_this, BabelRegExp.prototype);
|
|
}
|
|
|
|
function buildGroups(result, re) {
|
|
var g = _groups.get(re);
|
|
|
|
return Object.keys(g).reduce(function (groups, name) {
|
|
return groups[name] = result[g[name]], groups;
|
|
}, Object.create(null));
|
|
}
|
|
|
|
return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (str) {
|
|
var result = _super.exec.call(this, str);
|
|
|
|
return result && (result.groups = buildGroups(result, this)), result;
|
|
}, BabelRegExp.prototype[Symbol.replace] = function (str, substitution) {
|
|
if ("string" == typeof substitution) {
|
|
var groups = _groups.get(this);
|
|
|
|
return _super[Symbol.replace].call(this, str, substitution.replace(/\$<([^>]+)>/g, function (_, name) {
|
|
return "$" + groups[name];
|
|
}));
|
|
}
|
|
|
|
if ("function" == typeof substitution) {
|
|
var _this = this;
|
|
|
|
return _super[Symbol.replace].call(this, str, function () {
|
|
var args = arguments;
|
|
return "object" != typeof args[args.length - 1] && (args = [].slice.call(args)).push(buildGroups(args, _this)), substitution.apply(this, args);
|
|
});
|
|
}
|
|
|
|
return _super[Symbol.replace].call(this, str, substitution);
|
|
}, _wrapRegExp.apply(this, arguments);
|
|
}
|
|
|
|
function _inherits(subClass, superClass) {
|
|
if (typeof superClass !== "function" && superClass !== null) {
|
|
throw new TypeError("Super expression must either be null or a function");
|
|
}
|
|
|
|
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
|
constructor: {
|
|
value: subClass,
|
|
writable: true,
|
|
configurable: true
|
|
}
|
|
});
|
|
Object.defineProperty(subClass, "prototype", {
|
|
writable: false
|
|
});
|
|
if (superClass) _setPrototypeOf(subClass, superClass);
|
|
}
|
|
|
|
function _setPrototypeOf(o, p) {
|
|
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
|
|
o.__proto__ = p;
|
|
return o;
|
|
};
|
|
return _setPrototypeOf(o, p);
|
|
}
|
|
|
|
var index = {
|
|
extensions: [{
|
|
name: 'mfm',
|
|
level: 'inline',
|
|
start: function start(src) {
|
|
var _src$match;
|
|
|
|
return (_src$match = src.match(/\$\[/)) == null ? void 0 : _src$match.index;
|
|
},
|
|
tokenizer: function tokenizer(src, tokens) {
|
|
// regex doesn't do well finding MFM tags: it's always either too lazy
|
|
// or too greedy.
|
|
var level = 0;
|
|
var walk = 0;
|
|
|
|
while (level > 0 || walk === 0) {
|
|
if (src[walk] + src[walk + 1] === '$[') {
|
|
level++;
|
|
walk++;
|
|
} else if (src[walk] === ']') {
|
|
level--;
|
|
}
|
|
|
|
walk++;
|
|
} // original regex, now definitely on the correct tag
|
|
|
|
|
|
var rule = /*#__PURE__*/_wrapRegExp(/^\$\[([\w\d]+)(?:\.(\S+))? ([\S\s]+)\]/, {
|
|
markup: 1,
|
|
options: 2,
|
|
text: 3
|
|
});
|
|
|
|
var match = rule.exec(src.slice(0, walk));
|
|
|
|
if (match) {
|
|
var token = {
|
|
type: 'mfm',
|
|
raw: match[0],
|
|
markup: match.groups.markup,
|
|
options: match.groups.options,
|
|
text: match.groups.text,
|
|
tokens: []
|
|
};
|
|
this.lexer.inline(token.text, token.tokens);
|
|
return token;
|
|
}
|
|
},
|
|
renderer: function renderer(token) {
|
|
var _this = this;
|
|
|
|
var options = {};
|
|
|
|
if (token.options) {
|
|
options = token.options.split(',').reduce(function (i, opt) {
|
|
i[opt.split('=')[0]] = opt.split('=')[1] || true;
|
|
return i;
|
|
}, {});
|
|
}
|
|
|
|
var el = function el(mfmClass, mfmStyle) {
|
|
if (mfmStyle === void 0) {
|
|
mfmStyle = '';
|
|
}
|
|
|
|
return "<span style=\"display: inline-block;" + mfmStyle + "\" class=\"" + mfmClass + "\">" + _this.parser.parseInline(token.tokens) + "</span>";
|
|
};
|
|
|
|
switch (token.markup) {
|
|
case 'blur':
|
|
{
|
|
return el('_mfm_blur_');
|
|
}
|
|
|
|
case 'bounce':
|
|
{
|
|
return el('_mfm_bounce_');
|
|
}
|
|
|
|
case 'flip':
|
|
{
|
|
var transform = options.x && options.v ? 'scale(-1, -1)' : options.v ? 'scaleY(-1)' : 'scaleX(-1)';
|
|
return el('_mfm_flip_', " transform: " + transform + ";");
|
|
}
|
|
|
|
case 'font':
|
|
{
|
|
var family = options.serif ? 'serif' : options.monospace ? 'monospace' : options.cursive ? 'cursive' : options.fantasy ? 'fantasy' : options.emoji ? 'emoji' : options.math ? 'math' : 'inherit';
|
|
return el('_mfm_font_', " font-family: " + family + ";");
|
|
}
|
|
|
|
case 'jelly':
|
|
{
|
|
var speed = options.speed || '1s';
|
|
return el('_mfm_jelly_', " animation: mfm-rubberBand " + speed + " linear infinite both;");
|
|
}
|
|
|
|
case 'jump':
|
|
{
|
|
return el('_mfm_jump_');
|
|
}
|
|
|
|
case 'rainbow':
|
|
{
|
|
return el('_mfm_rainbow_');
|
|
}
|
|
|
|
case 'rotate':
|
|
{
|
|
var degrees = options.deg || '90';
|
|
return el('_mfm_rotate_', " transform: rotate(" + degrees + "deg); transform-origin: center center;");
|
|
}
|
|
|
|
case 'shake':
|
|
{
|
|
var _speed = options.speed || '0.5s';
|
|
|
|
return el('_mfm_shake_', " animation: mfm-shake " + _speed + " ease infinite;");
|
|
}
|
|
|
|
case 'spin':
|
|
{
|
|
var direction = options.left ? 'reverse' : options.alternate ? 'alternate' : 'normal';
|
|
var anime = options.x ? 'mfm-spinX' : options.y ? 'mfm-spinY' : 'mfm-spin';
|
|
|
|
var _speed2 = options.speed || '1.5s';
|
|
|
|
return el('_mfm_spin_', " animation: " + anime + " " + _speed2 + " linear infinite; animation-direction: " + direction + ";");
|
|
}
|
|
|
|
case 'tada':
|
|
{
|
|
return el('_mfm_tada_');
|
|
}
|
|
|
|
case 'twitch':
|
|
{
|
|
var _speed3 = options.speed || '0.5s';
|
|
|
|
return el('_mfm_twitch_', " animation: mfm-twitch " + _speed3 + " ease infinite;");
|
|
}
|
|
|
|
case 'sparkle':
|
|
{
|
|
return el('_mfm_sparkle_');
|
|
}
|
|
|
|
case 'x2':
|
|
{
|
|
return el('_mfm_x2_');
|
|
}
|
|
|
|
case 'x3':
|
|
{
|
|
return el('_mfm_x3_');
|
|
}
|
|
|
|
case 'x4':
|
|
{
|
|
return el('_mfm_x4_');
|
|
}
|
|
|
|
default:
|
|
{
|
|
return "$[" + token.markup + " " + this.parser.parseInline(token.tokens) + "]";
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
name: 'mfmSearch',
|
|
level: 'block',
|
|
start: function start(src) {
|
|
var _src$match2;
|
|
|
|
return (_src$match2 = src.match(/[^\n]+ search/)) == null ? void 0 : _src$match2.index;
|
|
},
|
|
tokenizer: function tokenizer(src, tokens) {
|
|
var rule = /^([^\n]+) search$/;
|
|
var match = rule.exec(src);
|
|
|
|
if (match) {
|
|
var token = {
|
|
type: 'mfmSearch',
|
|
raw: match[0],
|
|
query: match[1].trim(),
|
|
tokens: []
|
|
};
|
|
this.lexer.inline(token.text, token.tokens);
|
|
return token;
|
|
}
|
|
},
|
|
renderer: function renderer(token) {
|
|
return "<a href=\"https://google.com/search?q=" + token.query + "\" class=\"_mfm_search_\">" + token.raw + "</a>";
|
|
}
|
|
}]
|
|
};
|
|
|
|
module.exports = index;
|