Fix regex matching of MFM tag

This commit is contained in:
Sol Fisher Romanoff 2022-07-08 20:54:26 +03:00
parent f19d22dc89
commit 0f60653105
No known key found for this signature in database
GPG key ID: 9D3F2B64F2341B62
3 changed files with 28 additions and 3 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "marked-mfm", "name": "marked-mfm",
"version": "0.1.0", "version": "0.1.1",
"description": "Marked.js extension for Misskey-flavored Markdown", "description": "Marked.js extension for Misskey-flavored Markdown",
"main": "./src/index.js", "main": "./src/index.js",
"type": "module", "type": "module",

View file

@ -5,8 +5,23 @@ export default {
level: 'inline', level: 'inline',
start (src) { return src.match(/\$\[/)?.index }, start (src) { return src.match(/\$\[/)?.index },
tokenizer (src, tokens) { tokenizer (src, tokens) {
const rule = /^\$\[(?<markup>[\w\d]+)(?:\.(?<options>\S+))? (?<text>[\S\s]+)\]$/ // regex doesn't do well finding MFM tags: it's always either too lazy
const match = rule.exec(src) // or too greedy.
let level = 0
let 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
const rule = /^\$\[(?<markup>[\w\d]+)(?:\.(?<options>\S+))? (?<text>[\S\s]+)\]/
const match = rule.exec(src.slice(0, walk))
if (match) { if (match) {
const token = { const token = {
type: 'mfm', type: 'mfm',

View file

@ -17,6 +17,16 @@ describe('marked-mfm', () => {
expect(marked('$[x2 x2 $[sparkle sparkle]]')).toBe('<p><span style="display: inline-block;" class="_mfm_x2_">x2 <span style="display: inline-block;" class="_mfm_sparkle_">sparkle</span></span></p>\n') expect(marked('$[x2 x2 $[sparkle sparkle]]')).toBe('<p><span style="display: inline-block;" class="_mfm_x2_">x2 <span style="display: inline-block;" class="_mfm_sparkle_">sparkle</span></span></p>\n')
}) })
test('lazy matching', () => {
marked.use(markedMfm)
expect(marked('$[x2 one] $[x2 two]')).toBe('<p><span style="display: inline-block;" class="_mfm_x2_">one</span> <span style="display: inline-block;" class="_mfm_x2_">two</span></p>\n')
})
test('nested & lazy matching', () => {
marked.use(markedMfm)
expect(marked('$[x2 one $[x2 two]] $[x2 three]')).toBe('<p><span style="display: inline-block;" class="_mfm_x2_">one <span style="display: inline-block;" class="_mfm_x2_">two</span></span> <span style="display: inline-block;" class="_mfm_x2_">three</span></p>\n')
})
test('invalid', () => { test('invalid', () => {
marked.use(markedMfm) marked.use(markedMfm)
expect(marked('$[invalid $[x2 test]]')).toBe('<p>$[invalid <span style="display: inline-block;" class="_mfm_x2_">test</span>]</p>\n') expect(marked('$[invalid $[x2 test]]')).toBe('<p>$[invalid <span style="display: inline-block;" class="_mfm_x2_">test</span>]</p>\n')