@@ -23,7 +23,6 @@ export const mfmLanguage = P.createLanguage({
|
||||
root: r => P.alt(r.block, r.inline).atLeast(1),
|
||||
plain: r => P.alt(r.emoji, r.text).atLeast(1),
|
||||
block: r => P.alt(
|
||||
r.title,
|
||||
r.quote,
|
||||
r.search,
|
||||
r.blockCode,
|
||||
@@ -37,14 +36,6 @@ export const mfmLanguage = P.createLanguage({
|
||||
return P.makeFailure(i, 'not newline');
|
||||
}
|
||||
}),
|
||||
title: r => r.startOfLine.then(P((input, i) => {
|
||||
const text = input.substr(i);
|
||||
const match = text.match(/^([【\[]([^【\[】\]\n]+?)[】\]])(\n|$)/);
|
||||
if (!match) return P.makeFailure(i, 'not a title');
|
||||
const q = match[2].trim();
|
||||
const contents = r.inline.atLeast(1).tryParse(q);
|
||||
return P.makeSuccess(i + match[0].length, createTree('title', contents, {}));
|
||||
})),
|
||||
quote: r => r.startOfLine.then(P((input, i) => {
|
||||
const text = input.substr(i);
|
||||
if (!text.match(/^>[\s\S]+?/)) return P.makeFailure(i, 'not a quote');
|
||||
@@ -67,17 +58,10 @@ export const mfmLanguage = P.createLanguage({
|
||||
return P.makeSuccess(i + match[0].length, createLeaf('blockCode', { code: match[2], lang: match[1] ? match[1].trim() : null }));
|
||||
})),
|
||||
inline: r => P.alt(
|
||||
r.big,
|
||||
r.bold,
|
||||
r.small,
|
||||
r.italic,
|
||||
r.strike,
|
||||
r.motion,
|
||||
r.spin,
|
||||
r.jump,
|
||||
r.flip,
|
||||
r.twitch,
|
||||
r.shake,
|
||||
r.inlineCode,
|
||||
r.mathInline,
|
||||
r.mention,
|
||||
@@ -85,9 +69,9 @@ export const mfmLanguage = P.createLanguage({
|
||||
r.url,
|
||||
r.link,
|
||||
r.emoji,
|
||||
r.fn,
|
||||
r.text
|
||||
),
|
||||
big: r => P.regexp(/^\*\*\*([\s\S]+?)\*\*\*/, 1).map(x => createTree('big', r.inline.atLeast(1).tryParse(x), {})),
|
||||
bold: r => {
|
||||
const asterisk = P.regexp(/\*\*([\s\S]+?)\*\*/, 1);
|
||||
const underscore = P.regexp(/__([a-zA-Z0-9\s]+?)__/, 1);
|
||||
@@ -107,25 +91,6 @@ export const mfmLanguage = P.createLanguage({
|
||||
return P.alt(xml, underscore).map(x => createTree('italic', r.inline.atLeast(1).tryParse(x), {}));
|
||||
},
|
||||
strike: r => P.regexp(/~~([^\n~]+?)~~/, 1).map(x => createTree('strike', r.inline.atLeast(1).tryParse(x), {})),
|
||||
motion: r => {
|
||||
const paren = P.regexp(/\(\(\(([\s\S]+?)\)\)\)/, 1);
|
||||
const xml = P.regexp(/<motion>(.+?)<\/motion>/, 1);
|
||||
return P.alt(paren, xml).map(x => createTree('motion', r.inline.atLeast(1).tryParse(x), {}));
|
||||
},
|
||||
spin: r => {
|
||||
return P((input, i) => {
|
||||
const text = input.substr(i);
|
||||
const match = text.match(/^<spin(\s[a-z]+?)?>(.+?)<\/spin>/i);
|
||||
if (!match) return P.makeFailure(i, 'not a spin');
|
||||
return P.makeSuccess(i + match[0].length, {
|
||||
content: match[2], attr: match[1] ? match[1].trim() : null
|
||||
});
|
||||
}).map(x => createTree('spin', r.inline.atLeast(1).tryParse(x.content), { attr: x.attr }));
|
||||
},
|
||||
jump: r => P.regexp(/<jump>(.+?)<\/jump>/, 1).map(x => createTree('jump', r.inline.atLeast(1).tryParse(x), {})),
|
||||
flip: r => P.regexp(/<flip>(.+?)<\/flip>/, 1).map(x => createTree('flip', r.inline.atLeast(1).tryParse(x), {})),
|
||||
twitch: r => P.regexp(/<twitch>(.+?)<\/twitch>/, 1).map(x => createTree('twitch', r.inline.atLeast(1).tryParse(x), {})),
|
||||
shake: r => P.regexp(/<shake>(.+?)<\/shake>/, 1).map(x => createTree('shake', r.inline.atLeast(1).tryParse(x), {})),
|
||||
center: r => r.startOfLine.then(P.regexp(/<center>([\s\S]+?)<\/center>/, 1).map(x => createTree('center', r.inline.atLeast(1).tryParse(x), {}))),
|
||||
inlineCode: () => P.regexp(/`([^´\n]+?)`/, 1).map(x => createLeaf('inlineCode', { code: x })),
|
||||
mathBlock: r => r.startOfLine.then(P.regexp(/\\\[([\s\S]+?)\\\]/, 1).map(x => createLeaf('mathBlock', { formula: x.trim() }))),
|
||||
@@ -192,5 +157,29 @@ export const mfmLanguage = P.createLanguage({
|
||||
const code = P.regexp(emojiRegex).map(x => createLeaf('emoji', { emoji: x }));
|
||||
return P.alt(name, code);
|
||||
},
|
||||
fn: r => {
|
||||
return P.seqObj(
|
||||
P.string('['), ['fn', P.regexp(/[^\s\n\[\]]+/)] as any, P.string(' '), P.optWhitespace, ['text', P.regexp(/[^\n\[\]]+/)] as any, P.string(']'),
|
||||
).map((x: any) => {
|
||||
let name = x.fn;
|
||||
const args = {};
|
||||
const separator = x.fn.indexOf('.');
|
||||
if (separator > -1) {
|
||||
name = x.fn.substr(0, separator);
|
||||
for (const arg of x.fn.substr(separator + 1).split(',')) {
|
||||
const kv = arg.split('=');
|
||||
if (kv.length === 1) {
|
||||
args[kv[0]] = true;
|
||||
} else {
|
||||
args[kv[0]] = kv[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return createTree('fn', r.inline.atLeast(1).tryParse(x.text), {
|
||||
name,
|
||||
args
|
||||
});
|
||||
});
|
||||
},
|
||||
text: () => P.any.map(x => createLeaf('text', { text: x }))
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user