diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000000000000000000000000000000000000..bad44a54e48d1ac98d9ff079ee6cacb10e32a27b --- /dev/null +++ b/docs/api.md @@ -0,0 +1,55 @@ +## parse API +入力文å—列ã‹ã‚‰ãƒŽãƒ¼ãƒ‰ãƒ„リーを生æˆã—ã¾ã™ã€‚ +å…¨ã¦ã®MFM構文を利用å¯èƒ½ã§ã™ã€‚ + +例: +```ts +const nodes = mfm.parse('hello [tada world]'); +console.log(JSON.stringify(nodes)); +// => "[{"type":"text","props":{"text":"hello "}},{"type":"fn","props":{"name":"tada","args":{}},"children":[{"type":"text","props":{"text":"world"}}]}]" +``` + +## parsePlain API +入力文å—列ã‹ã‚‰ãƒŽãƒ¼ãƒ‰ãƒ„リーを生æˆã—ã¾ã™ã€‚ +絵文å—コードã¨Unicode絵文å—を利用å¯èƒ½ã§ã™ã€‚ + +例: +```ts +const nodes = mfm.parsePlain('Hello :surprised_ai:'); +console.log(JSON.stringify(nodes)); +// => "[{"type":"text","props":{"text":"Hello "}},{"type":"emojiCode","props":{"name":"surprised_ai"}}]" +``` + +## toString API +ノードツリーã‹ã‚‰MFMæ–‡å—列を生æˆã—ã¾ã™ã€‚ + +例: +```ts +const nodes = mfm.parse('hello [tada world]'); +const output = mfm.toString(nodes); +console.log(output); // => "hello [tada world]" +``` +※元ã®æ–‡å—列ã¨toString APIã§å‡ºåŠ›ã•ã‚Œã‚‹æ–‡å—列ã®åŒä¸€æ€§ã¯ä¿éšœã•ã‚Œã¾ã›ã‚“。 + +## inspect API +ノードツリーã®å…¨ãƒŽãƒ¼ãƒ‰ã«æŒ‡å®šã•ã‚ŒãŸé–¢æ•°ã‚’é©ç”¨ã—ã¾ã™ã€‚ + +例: +```ts +mfm.inspect(nodes, node => { + if (node.type == 'text') { + node.props.text = node.props.text.replace(/Good morning/g, 'Hello'); + } +}); +``` + +## extract API +ブール値を返ã™é–¢æ•°ã‚’渡ã—ã¦ãƒŽãƒ¼ãƒ‰ã‚’抽出ã—ã¾ã™ã€‚ +ã“ã®APIã¯ãƒŽãƒ¼ãƒ‰ãƒ„リーをå†å¸°çš„ã«æŽ¢ç´¢ã—ã¾ã™ã€‚ + +例: +```ts +mfm.extract(nodes, (node) => { + return (node.type === 'emojiCode'); +}); +``` diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000000000000000000000000000000000000..84feadc732ca76ddafa72fbd7ccfb81e42b423cf --- /dev/null +++ b/docs/index.md @@ -0,0 +1,7 @@ +## 目次 + +### [API](api) +ライブラリãŒæä¾›ã—ã¦ã„る関数や型定義ãªã©ã«ã¤ã„ã¦ã®èª¬æ˜Žã§ã™ã€‚ + +### [MFM構文ã¨ãƒŽãƒ¼ãƒ‰æ§‹é€ ã®ä»•æ§˜](syntax) +サãƒãƒ¼ãƒˆã—ã¦ã„ã‚‹MFMæ§‹æ–‡ã‚„ãƒŽãƒ¼ãƒ‰æ§‹é€ ã«ã¤ã„ã¦ã®èª¬æ˜Žã§ã™ã€‚ diff --git a/docs/syntax.md b/docs/syntax.md new file mode 100644 index 0000000000000000000000000000000000000000..3523b8c1c190da86c209c182e63eb16e710e860e --- /dev/null +++ b/docs/syntax.md @@ -0,0 +1,616 @@ +<h1>目次</h2> + +ブãƒãƒƒã‚¯æ§‹æ–‡: +- [引用ブãƒãƒƒã‚¯](#quote) +- [検索ブãƒãƒƒã‚¯](#search) +- [コードブãƒãƒƒã‚¯](#code-block) +- [æ•°å¼ãƒ–ãƒãƒƒã‚¯](#math-block) +- [ä¸å¤®å¯„ã›ãƒ–ãƒãƒƒã‚¯](#center) + +インライン構文: +構文 | 改行å¯èƒ½ï¼Ÿ +-------------------------------|----------- +[æºã‚Œã‚‹å—](#big) | ã¯ã„ +[太å—](#bold) | ã¯ã„ +[目立ãŸãªã„å—](#small) | ã¯ã„ +[イタリック](#italic) | ã¯ã„ +[打ã¡æ¶ˆã—ç·š](#strike) | ã„ã„㈠+[インラインコード](#inline-code) | ã„ã„㈠+[インライン数å¼](#math-inline) | ã„ã„㈠+[メンション](#mention) | ã„ã„㈠+[ãƒãƒƒã‚·ãƒ¥ã‚¿ã‚°](#hashtag) | ã„ã„㈠+[URL](#url) | ã„ã„㈠+[リンク](#link) | ã„ã„㈠+[絵文å—コード(カスタム絵文å—)](#emoji-code) | ã„ã„㈠+[MFM関数](#fn) | ã¯ã„ +[Unicode絵文å—](#unicode-emoji) | ã„ã„㈠+[テã‚スト](#text) | ã¯ã„ + + + +<h1 id="quote">引用ブãƒãƒƒã‚¯</h1> + +## å½¢å¼ +``` +> abc +>abc +>>nest +``` + +## ノード +```js +{ + type: 'quote', + children: [ + { type: 'text', props: { text: 'abc' } } + ] +} +``` + +## 詳細 +- ブãƒãƒƒã‚¯æ§‹æ–‡ã§ã™ã€‚ +- 引用ã•ã‚ŒãŸå†…容ã«ã¯å†åº¦FullParserã‚’é©ç”¨ã™ã‚‹ã€‚ +- `>`ã®å¾Œã«ç¶šã0~1æ–‡å—ã®ã‚¹ãƒšãƒ¼ã‚¹ã‚’無視ã™ã‚‹ã€‚ +- 隣接ã™ã‚‹å¼•ç”¨ã®è¡Œã¯ä¸€ã¤ã«ãªã‚‹ã€‚ +- 複数行ã®å¼•ç”¨ã§ã¯ç©ºè¡Œã‚‚å«ã‚ã‚‹ã“ã¨ãŒã§ãる。 + + + +<h1 id="search">検索ブãƒãƒƒã‚¯</h2> + +## å½¢å¼ +``` +MFM 書ãæ–¹ Search +MFM 書ãæ–¹ 検索 +MFM 書ãæ–¹ [Search] +MFM 書ãæ–¹ [検索] +``` + +## ノード +```js +{ + type: 'search', + props: { + query: 'MFM 書ãæ–¹', + content: 'MFM 書ãæ–¹ Search' + } +} +``` + +## 詳細 +- ブãƒãƒƒã‚¯æ§‹æ–‡ã€‚ +- Searchã®å¤§æ–‡å—å°æ–‡å—ã¯åŒºåˆ¥ã•ã‚Œãªã„。 + + + +<h1 id="code-block">コードブãƒãƒƒã‚¯</h2> + +## å½¢å¼ +<pre> +``` +a + +b``` +```c +```` +``` +</pre> + +<pre> +```js +abc +```` +</pre> + +## ノード +```js +{ + type: 'blockCode', + props: { + code: 'abc', + lang: 'js' + } +} +``` + +## 詳細 +- ブãƒãƒƒã‚¯æ§‹æ–‡ã§ã™ã€‚ +- langã¯æŒ‡å®šã•ã‚Œãªã„å ´åˆã¯nullã«ãªã‚‹ã€‚ + + + +<h1 id="math-block">æ•°å¼ãƒ–ãƒãƒƒã‚¯</h2> + +## å½¢å¼ +``` +\[a = 1\] +``` + +``` +\[ +a = 2 +\] +``` + +## ノード +```js +{ + type: 'mathBlock', + props: { + formula: 'a = 1' + } +} +``` + +## 詳細 +- ブãƒãƒƒã‚¯æ§‹æ–‡ã§ã™ã€‚ +- `\[`ã¯è¡Œé ã§ãªã‘ã‚Œã°ãªã‚‰ãªã„。 +- `\]`ã¯è¡Œæœ«ã§ãªã‘ã‚Œã°ãªã‚‰ãªã„。 +- å‰å¾Œã®ã‚¹ãƒšãƒ¼ã‚¹ã¨æ”¹è¡Œã¯ãƒˆãƒªãƒŸãƒ³ã‚°ã•ã‚Œã‚‹ã€‚ + + + +<h1 id="center">ä¸å¤®å¯„ã›ãƒ–ãƒãƒƒã‚¯</h2> + +## å½¢å¼ +``` +<center>abc</center> +``` +``` +<center> +abc +</center> +``` + +## ノード +```js +{ + type: 'center', + children: [ + { type: 'text', props: { text: 'abc' } } + ] +} +``` + +## 詳細 +- ブãƒãƒƒã‚¯æ§‹æ–‡ã€‚ +- `<center>`ã¯è¡Œé ã§ãªã‘ã‚Œã°ãªã‚‰ãªã„。 +- `</center>`ã¯è¡Œæœ«ã§ãªã‘ã‚Œã°ãªã‚‰ãªã„。 +- ä¸èº«ã‚’空ã«ã™ã‚‹ã“ã¨ã¯ã§ããªã„。 +- 内容ã«ã¯å†åº¦InlineParserã‚’é©ç”¨ã™ã‚‹ã€‚ + + + +<h1 id="big">æºã‚Œã‚‹å—</h2> + +**廃æ¢äºˆå®šã®æ§‹æ–‡ã€‚代替ã®æ§‹æ–‡ãŒç”¨æ„ã•ã‚Œã¦ã„ã¾ã™ã€‚** +## å½¢å¼ +``` +***big!*** +``` + +## ノード +```js +{ + type: 'fn', + props: { + name: 'tada', + args: { } + }, + children: [ + { type: 'text', props: { text: 'big!' } } + ] +} +``` + +## 詳細 +- インライン構文 +- 内容ã«ã¯å†åº¦InlineParserã‚’é©ç”¨ã™ã‚‹ã€‚ +- 内容ã«ã¯æ”¹è¡Œã‚‚å«ã‚ã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚ + + + +<h1 id="bold">太å—</h2> + +## å½¢å¼ +``` +**bold** +``` + +## ノード +```js +{ + type: 'bold', + children: [ + { type: 'text', props: { text: 'bold' } } + ] +} +``` + +## 詳細 +- インライン構文。 +- 内容ã«ã¯å†åº¦InlineParserã‚’é©ç”¨ã™ã‚‹ã€‚ +- 内容ã«ã¯æ”¹è¡Œã‚‚å«ã‚ã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚ + + + +<h1 id="small">目立ãŸãªã„å—</h2> + +## å½¢å¼ +``` +<small>small</small> +``` + +## ノード +```js +{ + type: 'small', + children: [ + { type: 'text', props: { text: 'small' } } + ] +} +``` + +## 詳細 +- インライン構文ã§ã™ã€‚ +- 内容ã«ã¯å†åº¦InlineParserã‚’é©ç”¨ã™ã‚‹ã€‚ +- 内容ã«ã¯æ”¹è¡Œã‚‚å«ã‚ã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚ + + + +<h1 id="italic">イタリック</h2> + +## å½¢å¼ +構文1: +``` +<i>italic</i> +``` + +構文2: +``` +*italic* +``` + +構文3: +``` +_italic_ +``` + +## ノード +```js +{ + type: 'italic', + children: [ + { type: 'text', props: { text: 'italic' } } + ] +} +``` + +## 詳細 +- インライン構文。 +- 内容ã«ã¯å†åº¦InlineParserã‚’é©ç”¨ã™ã‚‹ã€‚ + +構文1ã®ã¿: +- 内容ã«ã¯æ”¹è¡Œã‚‚å«ã‚ã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚ + +構文2,3ã®ã¿: +※1ã¤ç›®ã®`*`ã¨`_`を開始記å·ã¨å‘¼ã¶ã€‚ +- 内容ã«ã¯`[a-z0-9 \t]i`ã«ãƒžãƒƒãƒã™ã‚‹æ–‡å—ãŒä½¿ç”¨ã§ãる。 +- 開始記å·ã®å‰ã®æ–‡å—ãŒ(ç„¡ã„ã€æ”¹è¡Œã€åŠè§’スペース)ã®ã„ãšã‚Œã‹ã®æ™‚ã«ã‚¤ã‚¿ãƒªãƒƒã‚¯æ–‡å—ã¨ã—ã¦åˆ¤å®šã•ã‚Œã‚‹ã€‚ + + + +<h1 id="strike">打ã¡æ¶ˆã—ç·š</h2> + +## å½¢å¼ +``` +~~strike~~ +``` + +## ノード +```js +{ + type: 'strike', + children: [ + { type: 'text', props: { text: 'strike' } } + ] +} +``` + +## 詳細 +- インライン構文。 +- 内容ã«ã¯å†åº¦InlineParserã‚’é©ç”¨ã™ã‚‹ã€‚ +- 内容ã«ã¯æ”¹è¡Œã‚’å«ã‚ã‚‹ã“ã¨ãŒã§ããªã„。 +- 内容ã«ã¯`~`ã‚’å«ã‚ã‚‹ã“ã¨ãŒã§ããªã„。 + + + +<h1 id="inline-code">インラインコード</h2> + +## å½¢å¼ +``` +`$abc <- 1` +``` + +## ノード +```js +{ + type: 'inlineCode', + props: { + code: '$abc <- 1' + } +} +``` + +## 詳細 +- インライン構文。 +- 内容ã«ã¯æ”¹è¡Œã‚’å«ã‚ã‚‹ã“ã¨ãŒã§ããªã„。 + + + +<h1 id="math-inline">インライン数å¼</h2> + +## å½¢å¼ +``` +\(y = 2x\) +``` + +## ノード +```js +{ + type: 'mathInline', + props: { + formula: 'y = 2x' + } +} +``` + +## 詳細 +- インライン構文。 +- 内容ã«ã¯æ”¹è¡Œã‚’å«ã‚ã‚‹ã“ã¨ãŒã§ããªã„。 + + + +<h1 id="mention">メンション</h2> + +## å½¢å¼ +``` +@user@misskey.io +``` +``` +@user +``` + +## ノード +```js +{ + type: 'mention', + props: { + username: 'user', + host: 'misskey.io', + acct: '@user@misskey.io' + } +} +``` + +```js +{ + type: 'mention', + props: { + username: 'user', + host: null, + acct: '@user' + } +} +``` + +## 詳細 +- インライン構文。 +- 最åˆã®`@`ã®å‰ã®æ–‡å—ãŒ(改行ã€ã‚¹ãƒšãƒ¼ã‚¹ã€ç„¡ã—)ã®ã„ãšã‚Œã‹ã®å ´åˆã«ãƒ¡ãƒ³ã‚·ãƒ§ãƒ³ã¨ã—ã¦èªè˜ã™ã‚‹ã€‚ + +### ユーザå +- 1æ–‡å—以上。 +- `A`~`Z` `0`~`9` `_` `-`ãŒå«ã‚られる。 +- 1æ–‡å—ç›®ã¨æœ€å¾Œã®æ–‡å—ã¯`-`ã«ã§ããªã„。 + +### ホストå +- 1æ–‡å—以上。 +- `A`~`Z` `0`~`9` `_` `-` `.`ãŒå«ã‚られる。 +- 1æ–‡å—ç›®ã¨æœ€å¾Œã®æ–‡å—ã¯`-` `.`ã«ã§ããªã„。 + + + +<h1 id="hashtag">ãƒãƒƒã‚·ãƒ¥ã‚¿ã‚°</h2> + +## å½¢å¼ +``` +#abc +``` + +## ノード +```js +{ + type: 'hashtag', + props: { + hashtag: 'abc' + } +} +``` + +## 詳細 +- インライン構文。 +- 内容ã«ã¯åŠè§’スペースã€å…¨è§’スペースã€æ”¹è¡Œã€ã‚¿ãƒ–æ–‡å—ã‚’å«ã‚ã‚‹ã“ã¨ãŒã§ããªã„。 +- 内容ã«ã¯`.` `,` `!` `?` `'` `"` `#` `:` `/` `ã€` `】` ã‚’å«ã‚ã‚‹ã“ã¨ãŒã§ããªã„。 +- 括弧ã¯å¯¾ã«ãªã£ã¦ã„る時ã®ã¿å†…容ã«å«ã‚ã‚‹ã“ã¨ãŒã§ãる。対象: `()` `[]` `「ã€` +- `#`ã®å‰ã®æ–‡å—ãŒ(改行ã€ã‚¹ãƒšãƒ¼ã‚¹ã€ç„¡ã—)ã®ã„ãšã‚Œã‹ã®å ´åˆã«ãƒãƒƒã‚·ãƒ¥ã‚¿ã‚°ã¨ã—ã¦èªè˜ã™ã‚‹ã€‚ + + + +<h1 id="url">URL</h2> + +## å½¢å¼ +``` +https://misskey.io/@ai +``` + +``` +http://hoge.jp/abc +``` + +## ノード +```js +{ + type: 'url', + props: { + url: 'https://misskey.io/@ai' + } +} +``` + +## 詳細 +- インライン構文。 +- 内容ã«ã¯`[.,a-z0-9_/:%#@$&?!~=+-]i`ã«ãƒžãƒƒãƒã™ã‚‹æ–‡å—を使用ã§ãる。 +- 内容ã«ã¯å¯¾ã«ãªã£ã¦ã„る括弧を使用ã§ãる。対象: `(` `)` `[` `]` +- `.`ã‚„`,`ã¯æœ€å¾Œã®æ–‡å—ã«ã§ããªã„。 + + + +<h1 id="link">リンク</h2> + +## å½¢å¼ +silent=false +``` +[Misskey.io](https://misskey.io/) +``` + +silent=true +``` +?[Misskey.io](https://misskey.io/) +``` + +## ノード +```js +[ + { + type: 'link', + props: { + silent: false, + url: 'https://misskey.io/' + }, + children: [ + { + type: 'text', + props: { + text: 'Misskey.io' + } + } + ] + } +] +``` + +## 詳細 +- インライン構文。 +- 内容ã«ã¯å†åº¦InlineParserã‚’é©ç”¨ã™ã‚‹ã€‚ +- 内容ã«å«ã¾ã‚Œã‚‹URLã¯ãƒ†ã‚ストã¨ã—ã¦ãƒ‘ースã™ã‚‹ã€‚ + + + +<h1 id="emoji-code">絵文å—コード(カスタム絵文å—)</h2> + +## å½¢å¼ +``` +:thinking_ai: +``` + +## ノード +```js +{ + type: 'emojiCode', + props: { + name: 'thinking_ai' + } +} +``` + +## 詳細 +- インライン構文。 + + + +<h1 id="fn">関数</h2> + +## å½¢å¼ +``` +[shake ðŸ®] +``` + +``` +[spin.alternate ðŸ®] +``` + +``` +[shake.speed=1s ðŸ®] +``` + +``` +[flip.h,v Misskeyã§Fediverseã®ä¸–ç•ŒãŒåºƒãŒã‚Šã¾ã™] +``` + +## ノード +```js +{ + type: 'fn', + props: { + name: 'shake', + args: { } + }, + children: [ + { type: 'unicodeEmoji', props: { emoji: 'ðŸ‘' } } + ] +} +``` + +## 詳細 +- インライン構文 +- 内容ã«ã¯å†åº¦InlineParserã‚’é©ç”¨ã™ã‚‹ã€‚ +- 内容ã«ã¯æ”¹è¡Œã‚‚å«ã‚ã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚ +- 使用ã§ãる関数åやパラメータã¯ãƒ›ã‚¹ãƒˆå´ã§å®šç¾©ã•ã‚Œã€ãƒ‘ーサã¯ãã®ç™»éŒ²çŠ¶æ³ã‚’関知ã—ã¾ã›ã‚“。 + + + +<h1 id="unicode-emoji">Unicode絵文å—</h2> + +## å½¢å¼ +``` +😇 +``` + +## ノード +```js +{ + type: 'unicodeEmoji', + props: { + emoji: '😇' + } +} +``` + + + +<h1 id="text">テã‚スト</h2> + +## å½¢å¼ +``` +abc +``` + +## ノード +```js +{ + type: 'text', + props: + text: 'abc' + } +} +```