56 lines
1.9 KiB
JavaScript
56 lines
1.9 KiB
JavaScript
export default {
|
|
extensions: [
|
|
{
|
|
name: 'mfm',
|
|
level: 'inline',
|
|
start (src) { return src.match(/\$\[/)?.index },
|
|
tokenizer (src, tokens) {
|
|
const rule = /^\$\[(?<markup>[\w\d]+)(?:\.(?<options>\S+))? (?<text>.+)\]$/
|
|
const match = rule.exec(src)
|
|
if (match) {
|
|
const 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 (token) {
|
|
let options = {}
|
|
if (token.options) {
|
|
options = token.options.split(',').reduce((i, opt) => {
|
|
i[opt.split('=')[0]] = opt.split('=')[1] || true
|
|
return i
|
|
}, {})
|
|
}
|
|
const el = (mfmClass, mfmStyle = '') => `<span style="display: inline-block;${mfmStyle}" class="${mfmClass}">${this.parser.parseInline(token.tokens)}</span>`
|
|
switch (token.markup) {
|
|
case 'x2': {
|
|
return el('x2')
|
|
}
|
|
case 'twitch': {
|
|
const speed = options.speed || '0.5s'
|
|
return el('twitch', ` animation: mfm-twitch ${speed} ease infinite;`)
|
|
}
|
|
case 'sparkle': {
|
|
return el('sparkle')
|
|
}
|
|
case 'spin': {
|
|
const direction = options.left ? 'reverse' : options.alternate ? 'alternate' : 'normal'
|
|
const anime = options.x ? 'mfm-spinX' : options.y ? 'mfm-spinY' : 'mfm-spin'
|
|
const speed = options.speed || '1.5s'
|
|
return el('spin', ` animation: ${anime} ${speed} linear infinite; animation-direction: ${direction};`)
|
|
}
|
|
default: {
|
|
return `$[${token.markup} ${this.parser.parseInline(token.tokens)}]`
|
|
}
|
|
}
|
|
},
|
|
},
|
|
],
|
|
}
|