Skip to content
Snippets Groups Projects
Commit 15c2ad5c authored by marihachi's avatar marihachi
Browse files

Merge branch 'develop' into master

parents 16fb2a4e 64d0429b
No related branches found
Tags v0.17.0
No related merge requests found
{
"name": "mfm-js",
"version": "0.16.2",
"version": "0.16.3",
"description": "An MFM parser implementation with PEG.js",
"main": "./built/index.js",
"types": "./built/index.d.ts",
......
......@@ -66,7 +66,7 @@ fullParser
= nodes:(&. n:full { return n; })* { return mergeText(nodes); }
plainParser
= nodes:(&. n:(emojiCode / unicodeEmoji / plainText) { return n; })* { return mergeText(nodes); }
= nodes:(&. n:plain { return n; })* { return mergeText(nodes); }
inlineParser
= nodes:(&. n:inline { return n; })* { return mergeText(nodes); }
......@@ -92,9 +92,9 @@ full
/ mention
/ hashtag
/ url
/// fnVer2
/ fnVer2
/ link
/// fnVer1
/ fnVer1
/ search // block
/ inlineText
......@@ -111,11 +111,32 @@ inline
/ mention
/ hashtag
/ url
/// fnVer2
/ fnVer2
/ link
/// fnVer1
/ fnVer1
/ inlineText
inlineWithoutFn
= emojiCode
/ unicodeEmoji
/ big
/ bold
/ small
/ italic
/ strike
/ inlineCode
/ mathInline
/ mention
/ hashtag
/ url
/ link
/ inlineText
plain
= emojiCode
/ unicodeEmoji
/ plainText
//
// block rules
//
......@@ -336,15 +357,21 @@ hashtag
}
hashtagContent
= (hashtagBracketPair / hashtagChar)+ { return text(); }
hashtagBracketPair
= "(" hashtagContent* ")"
/ "[" hashtagContent* "]"
/ "「" hashtagContent* "」"
= hashtagChar+ { return text(); }
hashtagChar
= ![ \t.,!?'"#:\/\[\]【】()「」] CHAR
= ![ \t.,!?'"#:\/【】] CHAR
// hashtagContent
// = (hashtagBracketPair / hashtagChar)+ { return text(); }
// hashtagBracketPair
// = "(" hashtagContent* ")"
// / "[" hashtagContent* "]"
// / "「" hashtagContent* "」"
// hashtagChar
// = ![ \t.,!?'"#:\/\[\]【】()「」] CHAR
// inline: URL
......@@ -368,28 +395,41 @@ urlContent
= urlContentPart+
urlContentPart
= urlBracketPair
/ [.,] &urlContentPart // last char is neither "." nor ",".
= [.,] &urlContentPart // last char is neither "." nor ",".
/ [a-z0-9_/:%#@$&?!~=+-]i
urlBracketPair
= "(" urlContentPart* ")"
/ "[" urlContentPart* "]"
// urlContentPart
// = urlBracketPair
// / [.,] &urlContentPart // last char is neither "." nor ",".
// / [a-z0-9_/:%#@$&?!~=+-]i
// urlBracketPair
// = "(" urlContentPart* ")"
// / "[" urlContentPart* "]"
// inline: link
link
= silent:"?"? "[" label:linkLabelPart+ "](" url:linkUrl ")"
= silent:"?"? "[" label:linkLabel "](" url:linkUrl ")"
{
return LINK((silent != null), url, mergeText(label));
}
linkLabel
= parts:linkLabelPart+
{
return parts;
//return parts.flat(Infinity);
}
// linkLabelPart
// = url { return text(); /* text node */ }
// / link { return text(); /* text node */ }
// / !"]" n:inline { return n; }
linkLabelPart
= !"]" . { return text(); }
// = "[" linkLabelPart* "]"
= !"]" p:plain { return p; }
linkUrl
= url { return text(); }
......@@ -397,14 +437,14 @@ linkUrl
// inline: fn
fnVer1
= "[" name:$([a-z0-9_]i)+ args:fnArgs? _ content:(!"]" i:inline { return i; })+ "]"
= "[" name:$([a-z0-9_]i)+ args:fnArgs? _ content:fnContentPart+ "]"
{
args = args || {};
return FN(name, args, mergeText(content));
}
fnVer2
= "$[" name:$([a-z0-9_]i)+ args:fnArgs? _ content:(!"]" i:inline { return i; })+ "]"
= "$[" name:$([a-z0-9_]i)+ args:fnArgs? _ content:fnContentPart+ "]"
{
args = args || {};
return FN(name, args, mergeText(content));
......@@ -430,6 +470,9 @@ fnArg
return { k: k, v: true };
}
fnContentPart
= !("]") i:inlineWithoutFn { return i; }
// inline: text
inlineText
......
......@@ -608,17 +608,18 @@ describe('FullParser', () => {
assert.deepStrictEqual(mfm.parse(input), output);
});
it('do not yield link node even if label is recognisable as a link', () => {
const input = 'official instance: [[https://misskey.io/@ai](https://misskey.io/@ai)](https://misskey.io/@ai).';
const output = [
TEXT('official instance: '),
LINK(false, 'https://misskey.io/@ai', [
TEXT('[https://misskey.io/@ai](https://misskey.io/@ai)')
]),
TEXT('.')
];
assert.deepStrictEqual(mfm.parse(input), output);
});
// disabled
// it('do not yield link node even if label is recognisable as a link', () => {
// const input = 'official instance: [[https://misskey.io/@ai](https://misskey.io/@ai)](https://misskey.io/@ai).';
// const output = [
// TEXT('official instance: '),
// LINK(false, 'https://misskey.io/@ai', [
// TEXT('[https://misskey.io/@ai](https://misskey.io/@ai)')
// ]),
// TEXT('.')
// ];
// assert.deepStrictEqual(mfm.parse(input), output);
// });
});
describe('fn v1', () => {
......@@ -642,17 +643,18 @@ describe('FullParser', () => {
assert.deepStrictEqual(mfm.parse(input), output);
});
it('nest', () => {
const input = '[spin.speed=1.1s [shake a]]';
const output = [
FN('spin', { speed: '1.1s' }, [
FN('shake', { }, [
TEXT('a')
])
])
];
assert.deepStrictEqual(mfm.parse(input), output);
});
// fn nest is disabled
// it('nest', () => {
// const input = '[spin.speed=1.1s [shake a]]';
// const output = [
// FN('spin', { speed: '1.1s' }, [
// FN('shake', { }, [
// TEXT('a')
// ])
// ])
// ];
// assert.deepStrictEqual(mfm.parse(input), output);
// });
});
describe('fn v2', () => {
......@@ -676,17 +678,18 @@ describe('FullParser', () => {
assert.deepStrictEqual(mfm.parse(input), output);
});
it('nest', () => {
const input = '$[spin.speed=1.1s $[shake a]]';
const output = [
FN('spin', { speed: '1.1s' }, [
FN('shake', { }, [
TEXT('a')
])
])
];
assert.deepStrictEqual(mfm.parse(input), output);
});
// fn nest is disabled
// it('nest', () => {
// const input = '$[spin.speed=1.1s $[shake a]]';
// const output = [
// FN('spin', { speed: '1.1s' }, [
// FN('shake', { }, [
// TEXT('a')
// ])
// ])
// ];
// assert.deepStrictEqual(mfm.parse(input), output);
// });
});
it('composite', () => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment