Techioz Blog

マークダウンでブロック引用符にメタデータを割り当てる

概要

マークダウンのブロック引用符を特定のメタ情報 (作成者/ソース、日付、リンク) に関連付ける必要があります。

その情報はデータ属性に含まれ、CSS はそれらの属性の情報を使用してフッターを表示します。

<blockquote data-source="some source" data-date="some date" data-link="some link">some quote...</blockquote>

問題は、これらのデータ属性を設定するためにマークダウン構文をどのようにフォーマットするかです。

私の現在の答えは、通常の blockquote 構文の前に追加の行を追加することです。

> <source={some source} date={some date} link={some link}>
> some quote...
この文字列は、マークダウン ライブラリ Red Carpet (Ruby) のカスタム レンダラーに渡され、ブロック引用符として認識されます。正規表現を使用してメタデータを抽出し、対応する

タグをレンダリングします。

class CustomRenderer < Redcarpet::Render::HTML
  include Rouge::Plugins::Redcarpet

  def block_quote(quote)
    pattern = /&lt;source={(?<source>[^}]+)} date={(?<date>[^}]+)}( link={(?<link>[^}]+)?})?&gt;(<br>)?(\n)?/m
    match = pattern.match(quote)

    if match
      quote.sub!(pattern, '')

      %{<blockquote data-source="#{match[:source]}" data-date="#{match[:date]}" data-link="#{match[:link]}">#{quote}</blockquote>}
    else
      %{<blockquote>#{quote}</blockquote>}
    end
  end
end

このアプローチはうまく機能しますが、見た目は醜いです。具体的に言うと、これはかなり扱いにくい正規表現です。もっと一般的に言えば、もっと簡単な方法があるはずだという気持ちを払拭することはできません。

文字列を解析する前に前処理することを検討しましたが、どのように前処理しても、最終的には block_quote メソッドを呼び出す必要があり、何らかの方法でメタデータをそこで抽出する必要があると思います。

マークダウン文字列全体のメタデータを取得する方法があることも承知しています。ただし、これには出力にメタデータは含まれません。

これを行うより良い方法はありますか?

解決策

その後、Kramdown gem が私が必要とするものを提供してくれることがわかりました。

ブロックレベル要素のカスタム属性をサポートします。彼らの構文を使用すると、おそらく次のようなことができるでしょう。

> A nice blockquote
{: data-source="..." data-date="..." data-link="..."}

そして、それによって次のものが生成されるはずです。

<blockquote data-source="..." data-date="..." data-link="...">
  A nice blockquote
</blockquote>

互換性のない既存のマークダウン構文があるため、この gem は使用できません。また、ユーザーに任意のカスタム属性 (XSS) を設定させるのは危険だと思うので、ホワイトリストが必要になります。しかし、他の人に役立つかもしれないので、ここに残しておきます。