mirror of
https://activitypub.software/TransFem-org/sfm-js
synced 2024-11-22 05:55:13 +00:00
fix bug of link label parsing
This commit is contained in:
parent
e28b2989e4
commit
6aaa34403a
2 changed files with 88 additions and 36 deletions
|
@ -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
|
||||
|
|
104
test/parser.ts
104
test/parser.ts
|
@ -972,40 +972,84 @@ hoge`;
|
|||
assert.deepStrictEqual(mfm.parse(input), output);
|
||||
});
|
||||
|
||||
it('do not yield url node even if label is recognisable as a url', () => {
|
||||
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('.')
|
||||
];
|
||||
assert.deepStrictEqual(mfm.parse(input), output);
|
||||
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('.'),
|
||||
];
|
||||
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', () => {
|
||||
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(']('),
|
||||
N_URL('https://misskey.io/@ai'),
|
||||
TEXT(').'),
|
||||
];
|
||||
assert.deepStrictEqual(mfm.parse(input), output);
|
||||
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(']('),
|
||||
N_URL('https://misskey.io/@ai'),
|
||||
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', [
|
||||
BOLD([
|
||||
TEXT('[https://misskey.io/@ai](https://misskey.io/@ai)'),
|
||||
]),
|
||||
]),
|
||||
TEXT('.'),
|
||||
];
|
||||
});
|
||||
});
|
||||
|
||||
it('do not yield mention', () => {
|
||||
const input = '[@example](https://example.com)';
|
||||
const output = [
|
||||
LINK(false, 'https://example.com', [
|
||||
TEXT('@example')
|
||||
]),
|
||||
];
|
||||
assert.deepStrictEqual(mfm.parse(input), output);
|
||||
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'),
|
||||
]),
|
||||
];
|
||||
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', () => {
|
||||
|
|
Loading…
Reference in a new issue