fix bug of link label parsing

This commit is contained in:
marihachi 2022-01-09 18:21:57 +09:00
parent e28b2989e4
commit 6aaa34403a
2 changed files with 88 additions and 36 deletions

View file

@ -32,9 +32,17 @@
function applyParser(input, startRule) {
let parseFunc = peg$parse;
return parseFunc(input, startRule ? { startRule } : { });
return parseFunc(input, {
startRule: startRule,
fnNameList: options.fnNameList,
nestLimit: (nestLimit - depth),
});
}
// link
let isLinkLabel = false;
// emoji
const emojiRegex = require('twemoji-parser/dist/lib/regex').default;
@ -355,7 +363,7 @@ mathInline
// inline: mention
mention
= "@" name:mentionName host:("@" @mentionHost)?
= &{ return !isLinkLabel; } "@" name:mentionName host:("@" @mentionHost)?
{
return MENTION(name, host, text());
}
@ -397,11 +405,11 @@ hashPairInner
// inline: URL
url
= "<" url:$("http" "s"? "://" (!(">" / _) CHAR)+) ">"
= &{ return !isLinkLabel; } "<" url:$("http" "s"? "://" (!(">" / _) CHAR)+) ">"
{
return N_URL(url, true);
}
/ "http" "s"? "://" (&([.,]+ urlContentPart) . / urlContentPart)+
/ &{ return !isLinkLabel; } "http" "s"? "://" (&([.,]+ urlContentPart) . / urlContentPart)+
{
// NOTE: last char is neither "." nor ",".
return N_URL(text());
@ -418,13 +426,13 @@ urlPairInner
// inline: link
link
= silent:"?"? "[" label:linkLabel "](" url:url ")"
= &{ return !isLinkLabel; } silent:"?"? "[" label:linkLabel "](" url:url ")"
{
return LINK((silent != null), url.props.url, mergeText(label));
}
linkLabel
= (!"]" @linkLabelPart)+
= &{ isLinkLabel = true; return true; } @(@(!"]" @linkLabelPart)+ &{ isLinkLabel = false; return true; } / &{ isLinkLabel = false; return false; })
linkLabelPart
= emojiCode

View file

@ -972,24 +972,41 @@ hoge`;
assert.deepStrictEqual(mfm.parse(input), output);
});
it('do not yield url node even if label is recognisable as a url', () => {
describe('cannot nest a url in a link label', () => {
it('basic', () => {
const input = 'official instance: [https://misskey.io/@ai](https://misskey.io/@ai).';
const output = [
TEXT('official instance: '),
LINK(false, 'https://misskey.io/@ai', [
TEXT('https://misskey.io/@ai')
TEXT('https://misskey.io/@ai'),
]),
TEXT('.')
TEXT('.'),
];
assert.deepStrictEqual(mfm.parse(input), output);
});
it('nested', () => {
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'),
BOLD([
TEXT('https://misskey.io/@ai'),
]),
]),
TEXT('.'),
];
assert.deepStrictEqual(mfm.parse(input), output);
});
});
it('cannot nest a link in a link label', () => {
describe('cannot nest a link in a link label', () => {
it('basic', () => {
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')
TEXT('[https://misskey.io/@ai'),
]),
TEXT(']('),
N_URL('https://misskey.io/@ai'),
@ -997,16 +1014,43 @@ hoge`;
];
assert.deepStrictEqual(mfm.parse(input), output);
});
it('nested', () => {
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', [
BOLD([
TEXT('[https://misskey.io/@ai](https://misskey.io/@ai)'),
]),
]),
TEXT('.'),
];
});
});
it('do not yield mention', () => {
describe('cannot nest a mention in a link label', () => {
it('basic', () => {
const input = '[@example](https://example.com)';
const output = [
LINK(false, 'https://example.com', [
TEXT('@example')
TEXT('@example'),
]),
];
assert.deepStrictEqual(mfm.parse(input), output);
});
it('nested', () => {
const input = '[@example**@example**](https://example.com)';
const output = [
LINK(false, 'https://example.com', [
TEXT('@example'),
BOLD([
TEXT('@example'),
]),
]),
];
assert.deepStrictEqual(mfm.parse(input), output);
});
});
it('with brackets', () => {
const input = '[foo](https://example.com/foo(bar))';