Quantcast
Viewing all articles
Browse latest Browse all 8335

はてなブログを「Shiki | 式」でシンタックスハイライトする - kasu.log

本ブログでも使っている、Syntax Highlighter Shikiはてなブログに導入する方法をここに記します。

Shiki | 式

Shikiとは TypeScript 製の Syntax Highlighter で、対応言語やテーマの数が豊富なことからとても人気があります。(筆者の主観)

markdown-itVitePressなどの Integration が提供されていたり Astroに組み込まれていたりと、触れたことがある人も多いのではないでしょうか。

shiki.style

はてなブログ

さて、はてなブログの Syntax Highlighter を変更するといっても既存のものを止める訳ではありません。

今のところ、HTML のレンダリングに介入することは出来ないので...

置き換える

はてなブログではヘッダに任意の HTML を挿入することができるので、HTML 読み込み時に既存のコードブロック要素を Shikiレンダリングしたものに後から置き換えることにします。

(ここでブラウザをリロードしてみると、コードブロックが置き換わる様子が見えるでしょう)

Installation | Shiki

ドキュメントにあるブラウザ向けの CDNを利用して、はてなブログの HTML 上にあるコードブロックを置き換える処理を実装します。

<scripttype="module">import { codeToHtml } from"https://esm.sh/shiki@1.12.0"constpres=document.querySelectorAll("pre.code")
pres.forEach((pre)=>{const lang = pre.dataset.lang
    const rawCode = pre.textContent
    ;(async()=>{const code =awaitcodeToHtml(rawCode,{theme:"github-dark",lang: lang,})const dummy =document.createElement("div")
        dummy.innerHTML = code
        pre.replaceWith(dummy.firstChild)})()})</script>

あとは、ブログの 設定 > 詳細設定 > head内タグ > <head>要素にメタデータを追加から上記のスクリプトを張り付ければ完成です。

ブログのテーマによっては、CLS(Cumulative Layout Shift)の原因となるので元のコードブロックのフォントサイズなどを揃えておきましょう。

HTML 編集モード

HTML 編集モードでは、はてなブログで生成されるコードブロックの HTML に合わせて <pre>タグに code classと、data-lang attribute に言語を指定してください。

<preclass="code"data-lang="javascript">
console.log("Hello, World!")
</pre>

設定

Themes

Shikiには次のテーマが指定可能です。

Themes | Shiki

prefers-color-scheme

Light/Dark Dual Themes | Shiki

端末のダークモードに追従させることもできます。

-   theme: "github-dark",+  themes: { +    light: 'github-light',+    dark: 'github-dark',+  },

上記のようにテーマを設定した後、以下のスタイルをブログの 設定から <head>要素に追加してください。

<style>@media (prefers-color-scheme: dark) {.shiki,
  .shikispan{color: var(--shiki-dark)!important;
    background-color: var(--shiki-dark-bg)!important;
    /* Optional, if you also want font styles */font-style: var(--shiki-dark-font-style)!important;
    font-weight: var(--shiki-dark-font-weight)!important;
    text-decoration: var(--shiki-dark-text-decoration)!important;
  }}</style>

おまけ

Shikiは v1 から ESM となりました。 つまり、JavaScript モジュールで使う必要があります。

もしも、あなたが過去を生きるユーザーも救いたいということであれば、以下に古いバージョンのコードを用意したのでお使いください。

<scriptdefersrc="https://unpkg.com/shiki@0.14.6"></script><script>window.addEventListener("DOMContentLoaded",function(){const pres =document.querySelectorAll("pre.code")const langs =[]for(const pre of pres){const lang = pre.dataset.lang
        langs.push(lang)}
    shiki.getHighlighter({theme:'github-dark',langs: langs,}).then(highlighter =>{
    pres.forEach(pre =>{const lang = pre.dataset.lang
      const rawCode = pre.textContent
      const code = highlighter.codeToHtml(rawCode,{lang: lang
      })const dummy =document.createElement('div')
      dummy.innerHTML = code
      pre.replaceWith(dummy.firstChild)})})})</script>

inline スクリプトに defer 使いたいナ


Viewing all articles
Browse latest Browse all 8335

Trending Articles