Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use MfmUrl AST in MfmLink AST #126

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
### Bugfixes

-->
## 0.23.4 (unreleased)

### Improvements
- Improve generation of brackets for links (#126)

## 0.23.3
- tweak fn parsing
Expand Down
33 changes: 22 additions & 11 deletions docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,10 @@ __bold__
- 内容には再度InlineParserを適用する。
- 内容を空にすることはできない。

構文1,3のみ:
構文1,3のみ:
- 内容にはすべての文字、改行が使用できる。

構文2のみ:
構文2のみ:
- 内容には`[a-z0-9 \t]i`にマッチする文字が使用できる。

## ノード
Expand Down Expand Up @@ -289,11 +289,11 @@ _italic_
- 内容には再度InlineParserを適用する。
- 内容を空にすることはできない。

構文1のみ:
構文1のみ:
- 内容にはすべての文字、改行が使用できる。

構文2,3のみ:
※1つ目の`*`と`_`を開始記号と呼ぶ。
構文2,3のみ:
※1つ目の`*`と`_`を開始記号と呼ぶ。
- 内容には`[a-z0-9 \t]i`にマッチする文字が使用できる。
- 開始記号の前の文字が`[a-z0-9]i`に一致しない時にイタリック文字として判定される。

Expand Down Expand Up @@ -326,10 +326,10 @@ _italic_
- 内容には再度InlineParserを適用する。
- 内容を空にすることはできない。

構文1のみ:
構文1のみ:
- 内容には`~`、改行以外の文字を使用できる。

構文2のみ:
構文2のみ:
- 内容にはすべての文字、改行が使用できる。

## ノード
Expand Down Expand Up @@ -488,12 +488,12 @@ http://hoge.jp/abc
```

## 詳細
構文1のみ:
構文1のみ:
- 内容には`[.,a-z0-9_/:%#@$&?!~=+-]i`にマッチする文字を使用できる。
- 内容には対になっている括弧を使用できる。対象: `( )` `[ ]`
- `.`や`,`は最後の文字にできない。

構文2のみ:
構文2のみ:
- 内容には改行、スペース以外の文字を使用できる。

## ノード
Expand Down Expand Up @@ -545,6 +545,11 @@ silent=true
?[Misskey.io](https://misskey.io/)
```

Special characters
```
[#藍ちゃファンクラブ](<https://misskey.io/explore/tags/藍ちゃファンクラブ>)
```

## 詳細
- 表示テキストには再度InlineParserを適用する。ただし、表示テキストではURL、リンク、メンションは使用できない。

Expand All @@ -555,7 +560,13 @@ silent=true
type: 'link',
props: {
silent: false,
url: 'https://misskey.io/'
url: {
type: 'url',
props: {
url: 'https://misskey.io/@ai',
brackets: false
}
},
},
children: [
{
Expand Down Expand Up @@ -665,7 +676,7 @@ abc
```js
{
type: 'text',
props:
props:
text: 'abc'
}
}
Expand Down
4 changes: 2 additions & 2 deletions etc/mfm-js.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function inspect(nodes: MfmNode[], action: (node: MfmNode) => void): void
export const ITALIC: (children: MfmInline[]) => NodeType<'italic'>;

// @public (undocumented)
export const LINK: (silent: boolean, url: string, children: MfmInline[]) => NodeType<'link'>;
export const LINK: (silent: boolean, url: MfmUrl, children: MfmInline[]) => NodeType<'link'>;

// @public (undocumented)
export const MATH_BLOCK: (formula: string) => NodeType<'mathBlock'>;
Expand Down Expand Up @@ -128,7 +128,7 @@ export type MfmLink = {
type: 'link';
props: {
silent: boolean;
url: string;
url: MfmUrl;
};
children: MfmInline[];
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mfm-js",
"version": "0.23.3",
"version": "0.23.4",
"description": "An MFM parser implementation with TypeScript",
"main": "./built/index.js",
"types": "./built/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion src/internal/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ export const language = P.createLanguage({
const silent = (result[1] === '?[');
const label = result[2];
const url: M.MfmUrl = result[5];
return M.LINK(silent, url.props.url, mergeText(label));
return M.LINK(silent, url, mergeText(label));
});
},

Expand Down
2 changes: 1 addition & 1 deletion src/internal/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export function stringifyNode(node: MfmNode): string {
}
case 'link': {
const prefix = node.props.silent ? '?' : '';
return `${ prefix }[${ stringifyTree(node.children) }](${ node.props.url })`;
return `${ prefix }[${ stringifyTree(node.children) }](${ stringifyNode(node.props.url) })`;
}
case 'fn': {
const argFields = Object.keys(node.props.args).map(key => {
Expand Down
4 changes: 2 additions & 2 deletions src/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,11 @@ export type MfmLink = {
type: 'link';
props: {
silent: boolean;
url: string;
url: MfmUrl;
};
children: MfmInline[];
};
export const LINK = (silent: boolean, url: string, children: MfmInline[]): NodeType<'link'> => { return { type: 'link', props: { silent, url }, children }; };
export const LINK = (silent: boolean, url: MfmUrl, children: MfmInline[]): NodeType<'link'> => { return { type: 'link', props: { silent, url }, children }; };

export type MfmFn = {
type: 'fn';
Expand Down
7 changes: 6 additions & 1 deletion test/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ after`;
test('quote', () => {
const input = `
> abc
>
>
> 123
`;

Expand Down Expand Up @@ -132,6 +132,11 @@ after`;
assert.strictEqual(mfm.toString(mfm.parse(input)), '[Ai](https://github.com/syuilo/ai)');
});

test('bracket link', () => {
const input = '[#藍ちゃファンクラブ](<https://misskey.io/explore/tags/藍ちゃファンクラブ>)';
assert.strictEqual(mfm.toString(mfm.parse(input)), '[#藍ちゃファンクラブ](<https://misskey.io/explore/tags/藍ちゃファンクラブ>)');
});

test('silent link', () => {
const input = '?[Ai](https://github.com/syuilo/ai)';
assert.strictEqual(mfm.toString(mfm.parse(input)), '?[Ai](https://github.com/syuilo/ai)');
Expand Down
118 changes: 74 additions & 44 deletions test/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1042,9 +1042,11 @@ hoge`;
test('basic', () => {
const input = '[official instance](https://misskey.io/@ai).';
const output = [
LINK(false, 'https://misskey.io/@ai', [
TEXT('official instance')
]),
LINK(
false,
N_URL('https://misskey.io/@ai'),
[TEXT('official instance')]
),
TEXT('.')
];
assert.deepStrictEqual(mfm.parse(input), output);
Expand All @@ -1053,20 +1055,24 @@ hoge`;
test('silent flag', () => {
const input = '?[official instance](https://misskey.io/@ai).';
const output = [
LINK(true, 'https://misskey.io/@ai', [
TEXT('official instance')
]),
LINK(
true,
N_URL('https://misskey.io/@ai'),
[TEXT('official instance')]
),
TEXT('.')
];
assert.deepStrictEqual(mfm.parse(input), output);
});

test('with angle brackets url', () => {
const input = '[official instance](<https://misskey.io/@ai>).';
const input = '[#藍ちゃファンクラブ](<https://misskey.io/explore/tags/藍ちゃファンクラブ>).';
const output = [
LINK(false, 'https://misskey.io/@ai', [
TEXT('official instance')
]),
LINK(
false,
N_URL('https://misskey.io/explore/tags/藍ちゃファンクラブ', true),
[TEXT('#藍ちゃファンクラブ')]
),
TEXT('.')
];
assert.deepStrictEqual(mfm.parse(input), output);
Expand All @@ -1085,9 +1091,11 @@ hoge`;
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'),
]),
LINK(
false,
N_URL('https://misskey.io/@ai'),
[TEXT('https://misskey.io/@ai')]
),
TEXT('.'),
];
assert.deepStrictEqual(mfm.parse(input), output);
Expand All @@ -1096,12 +1104,16 @@ hoge`;
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([
LINK(
false,
N_URL('https://misskey.io/@ai'),
[
TEXT('https://misskey.io/@ai'),
]),
]),
BOLD([
TEXT('https://misskey.io/@ai'),
]),
]
),
TEXT('.'),
];
assert.deepStrictEqual(mfm.parse(input), output);
Expand All @@ -1113,9 +1125,11 @@ hoge`;
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'),
]),
LINK(
false,
N_URL('https://misskey.io/@ai'),
[TEXT('[https://misskey.io/@ai')]
),
TEXT(']('),
N_URL('https://misskey.io/@ai'),
TEXT(').'),
Expand All @@ -1126,11 +1140,15 @@ hoge`;
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)'),
]),
]),
LINK(
false,
N_URL('https://misskey.io/@ai'),
[
BOLD([
TEXT('[https://misskey.io/@ai](https://misskey.io/@ai)'),
]),
]
),
TEXT('.'),
];
});
Expand All @@ -1140,21 +1158,27 @@ hoge`;
test('basic', () => {
const input = '[@example](https://example.com)';
const output = [
LINK(false, 'https://example.com', [
TEXT('@example'),
]),
LINK(
false,
N_URL('https://example.com'),
[TEXT('@example')]
),
];
assert.deepStrictEqual(mfm.parse(input), output);
});
test('nested', () => {
const input = '[@example**@example**](https://example.com)';
const output = [
LINK(false, 'https://example.com', [
TEXT('@example'),
BOLD([
LINK(
false,
N_URL('https://example.com'),
[
TEXT('@example'),
]),
]),
BOLD([
TEXT('@example'),
]),
]
),
];
assert.deepStrictEqual(mfm.parse(input), output);
});
Expand All @@ -1163,9 +1187,11 @@ hoge`;
test('with brackets', () => {
const input = '[foo](https://example.com/foo(bar))';
const output = [
LINK(false, 'https://example.com/foo(bar)', [
TEXT('foo')
]),
LINK(
false,
N_URL('https://example.com/foo(bar)'),
[TEXT('foo')]
),
];
assert.deepStrictEqual(mfm.parse(input), output);
});
Expand All @@ -1174,9 +1200,11 @@ hoge`;
const input = '([foo](https://example.com/foo(bar)))';
const output = [
TEXT('('),
LINK(false, 'https://example.com/foo(bar)', [
TEXT('foo')
]),
LINK(
false,
N_URL('https://example.com/foo(bar)'),
[TEXT('foo')]
),
TEXT(')'),
];
assert.deepStrictEqual(mfm.parse(input), output);
Expand All @@ -1186,9 +1214,11 @@ hoge`;
const input = '[test] foo [bar](https://example.com)';
const output = [
TEXT('[test] foo '),
LINK(false, 'https://example.com', [
TEXT('bar')
]),
LINK(
false,
N_URL('https://example.com'),
[TEXT('bar')]
),
];
assert.deepStrictEqual(mfm.parse(input), output);
});
Expand Down Expand Up @@ -1369,7 +1399,7 @@ hoge`;
];
assert.deepStrictEqual(mfm.parse(input, { nestLimit: 2 }), output);
});

test('tag', () => {
const input = '<b><b><s>abc</s></b></b>';
const output = [
Expand Down