MasatoMakino / qiita-to-md

Markdown generator from qiita.com
MIT License
1 stars 0 forks source link

改段落やリストを含むNote記法が正しく変換されない #33

Open Robot-Inventor opened 1 year ago

Robot-Inventor commented 1 year ago

素晴らしいツールをありがとうございます!

Note記法の中身に改段落やリストなどが含まれていると変換されず、そのまま<p>タグなどで出力されてしまうようです。

MasatoMakino commented 1 year ago

ありがとうございます。

https://github.com/MasatoMakino/qiita-to-md/blob/main/src/plugin/RemarkNotePlugin.ts

Note記法の変換はこちらのプラグインクラスで担当しています。 このクラスでは、Note記法内をプレーンテキストとして決め打ちして出力しています。 Note記法内のタグの再解釈を行っていません。

Note記法内のタグを再解釈するために、もう一段.use(remarkParse)を通せばいいのかもしれません。 調査と検討をしてみます。

Robot-Inventor commented 1 year ago

ありがとうございます!よろしくお願いします

P.S.

最初の投稿で「<p>タグ」と書いていたのですが、文字列ではなくHTMLとして解釈されてしまい、意味が分かりにくくなっていました。すみません

MasatoMakino commented 1 year ago

現状までの調査の結果を記録します。

期待される動作

const md = `
:::note
note
:::
`

const md2 = `
:::note

note

:::
`

をJsonGenerator.convertToHTML()に入力すると、どちらも

<div class="note">note</div>

が出力される。

現状の動作

const md2 = `
:::note

note

:::
`

では

<p>:::note</p><p>note</p><p>:::</p>

が出力される。

原因

RemarkNotePlugin.tsのvisit関数がパラグラフ単位での処理を前提としている。 ディレクティブ構文:::が改行2回で複数のパラグラフに分離した場合、判定ができない。

remark-directiveプラグインでの対応

https://github.com/remarkjs/remark-directive マークダウンのディレクティブ構文プロポーザルを実装したプラグインがある。

  public static async convertToHTML(body: string) {
    const result = await unified()
      .use(remarkParse) // markdown -> mdast の変換
      .use(remarkDirective)// ディレクティブ構文の検出
      .use(myRemarkPlugin as any)// ディレクティブ構文の変換
      .use(RemarkLinkCardPlugin.plugin)
      .use(remarkRehype, {
        handlers: {
          LinkCard: RemarkLinkCardPlugin.rehypeHandler as any,
        },
      }) // mdast -> hast の変換
      .use(rehypeHighlight, { ignoreMissing: true })
      .use(rehypeStringify) // hast -> html の変換
      .process(body); // 実行

以上のような形でプラグインを差し込むと、プロポーザルに準じた変換ができる。

しかし、Qiitaのnote構文は、プロポーザルとは違う形で実装されている。

:::note warn
note
:::

remark-directiveはwarnをclassとして受け取らない。

:::note{.warn}
note
:::

の形でクラスを指定することになっている。

この問題への対応方法

remark-directiveを参考に、remarkプラグインを作成すれば解消できる。