Markdown & MDX コード ブロックの言語タブ


Gatsby に構文強調表示を統合することは、 gatsby-remark-prismjs prism-react-renderer のようなソリューションで解決できます. Markdown でコード ブロックを作成するときは、開始する 3 つのバッククォートの後に目的の言語 (js または css など) を指定します.ここのブログで行っているように、コード ブロック自体にも指定された言語を表示するのはいい感じです.

const harry = spell("lumos")


次の 2 つの簡単なヒントでは、この機能を gatsby-remark-prismjs または prism-react-renderer (それぞれ Markdown または MDX) と統合する方法について説明します.

Markdown & gatsby-remark-prismjs



コードサンドボックス language-tabs-for-gatsby-remark-prismjs を作成しました.ソリューションに直接ジャンプしたい場合は、最終的な作業コードを見ることができます.

Markdown からデータを取得できる Gatsby プロジェクトをセットアップします.たとえば、次のことができます. npm init gatsby を実行し、Markdown オプションを選択します. gatsby-remark-prismjs をインストールし、それに応じて gatsby-config.jsgatsby-browser.js を構成します.マークダウン ファイルの 1 つにダミー コンテンツを追加して、何かが起こることを確認します.

const harry = spell("lumos")


Gatsby 開発サーバーを起動すると、構文が強調表示されたコード ブロックが表示されます.次に、コード ブロックを右クリックし、続いて [Inspect element] をクリックして、開発者ツールでブロックを表示します.次のようなものが表示されます.

<div class="gatsby-highlight" data-language="js">
  <pre
    class="language-js"
  ><code class="language-js">YOUR_CONTENT_HERE</code></pre>
</div>


擬似セレクター .gatsby-highlight を介してラベルを追加するには、 pre クラスと ::before タグをターゲットにする必要があります.

CSS ファイルを作成し、gatsby-browser.js ファイルに含めます. CSS自体は次のとおりです.

.gatsby-highlight {
  position: relative;
  -webkit-overflow-scrolling: touch;
}
.gatsby-highlight pre[class*="language-"] {
  -webkit-overflow-scrolling: touch;
}
.gatsby-highlight pre[class*="language-"]::before {
  background: black;
  border-radius: 0 0 0.25rem 0.25rem;
  color: white;
  font-size: 12px;
  letter-spacing: 0.025rem;
  padding: 0.1rem 0.5rem;
  position: absolute;
  right: 1rem;
  text-align: right;
  text-transform: uppercase;
  top: 0;
}
.gatsby-highlight pre[class="language-js"]::before {
  content: "js";
  background: #f7df1e;
  color: black;
}


ラッピング div には相対位置があるため、タブ自体を絶対に配置できます.また、CSS は attribute selectors を使用して、pre クラスを持つすべての language-* タグをターゲットにします.すべての言語がこれ (デフォルトのスタイリング) の対象となるため、特定の言語ではスタイリングの一部を上書きします.

他の言語用のタブを追加する場合は、既存の language-js バージョンをコピーします (何をターゲットにするかを知る前に、DOM をもう一度調べることができます).

MDX & プリズム反応レンダラー



MDX と gatsby-plugin-mdx を使用する場合、前述の gatsby-remark-prismjs も使用できますが、MDX はより多くの可能性を提供します.ライブエディター用?npm init gatsby で新しいプロジェクトをセットアップし、今回は MDX を選択します. prism-react-renderer もインストールします.最初のクイック ヒントから custom-prism-styles.css をこのプロジェクトにコピーし、 gatsby-browser.js 内にインポートすることもできます.

CSS を custom-prism-styles.css から機能させるには、 div を使用するときに .gatsby-highlightprism-react-renderer に追加することを考える必要があります.

主な部分は、<Code /> コンポーネントを作成し、それを MDX の pre タグにマッピングすることです. language-tabs-mdx コードサンドボックスは完全なセットアップを示しています.コード コンポーネントをスニペットとして次に示します.

import React from "react"
import Highlight, { defaultProps } from "prism-react-renderer"

const Code = () => (
  <Highlight {...defaultProps} code={codeString} language={language}>
    {({ className, style, tokens, getLineProps, getTokenProps }) => (
      <div className="gatsby-highlight" data-language={language}>
        <pre className={className} style={style}>
          {tokens.map((line, i) => (
            <div {...getLineProps({ line, key: i })}>
              {line.map((token, key) => (
                <span {...getTokenProps({ token, key })} />
              ))}
            </div>
          ))}
        </pre>
      </div>
    )}
  </Highlight>
)

export default Code


ここで開発サーバーを起動して HTML を調べると、余分なコンテナーが DOM にあるはずです.上記の CSS で動作するはずですよね?まだ完全ではありませんが、1 つの小さな調整を行う必要があります. DOM でわかるように、pre 要素には 2 つのクラスがあります.

<pre class="prism-code language-js">YOUR_CONTENT</pre>


したがって、以前の pre[class="language-js"] セレクターは、この 1 つのクラスのみを想定しているため、機能しなくなります.これを pre[class~="language-js"] に変更すると、次のようになります: クラス名の 1 つが language-js の場合は、次のようにしてください.