カテゴリ:プラグイン 自作 追加

shiki.webp

Shikiによる構文ハイライトプラグイン

shiki.inc.php
製作者kanateko
ライセンスGPLv3
バージョン1.0.0
動作確認PukiWiki 1.5.4 - 1.5.4
最終更新2026-02-12

Shiki (https://shiki.style) を使ってコードブロックを読みやすく装飾するプラグイン。

Shiki は VSCode でも使われている TextMate の文法をベースにしており、高いカスタマイズ性や豊富な対応言語・テーマが魅力。

これまでは他の方が作成してくれていた Prism を用いたプラグイン (https://storagebox.xxxxxxxx.jp) を使用していたのだが、細かいところを自分で調整したくなり、せっかくならまだ使われていないライブラリを使って新しく作ろうと思い、 Shiki を選ぶに至った。

プラグインの特徴

  • Shiki による高品質なシンタックスハイライト
  • 言語・テーマの指定に対応
  • 行番号表示 (開始行指定可)
  • コードブロックタイトル表示
  • 追加 CSS クラス指定可能
  • 単一ファイル構成で導入が簡単

動作環境

  • PukiWiki 1.5.4 以降
  • PHP 8.x 推奨
  • JavaScript 有効環境

ダウンロード

最新: https://github.com/kanateko/pukiwiki-shiki

日付バージョン備考
2026-02-121.0.0
  • 初版作成

セットアップ

  1. GitHub の Release から最新のファイルをダウンロードする。
  2. ダウンロードした「shiki.inc.php」を plugin/ ディレクトリに配置する。
  3. pukiwiki.ini.php を編集してマルチラインプラグインを許可する。

プラグイン設定

Shikiクラス
DEFAULT_LANGstring'text'デフォルトの言語指定
DEFAULT_THEMEstring'github-dark'デフォルトのテーマ
DEFAULT_LINENUMBERSstring''デフォルトの開始行番号
DEFAULT_TITLEstring''デフォルトのタイトル
DEFAULT_CLASSstring''デフォルトのクラス名

使用方法

#shiki([オプション]){{
表示したいコード
}}

引数一覧

引数名説明
lang言語指定 (Shiki 対応言語)lang=js
themeテーマ名theme=github-dark
titleコードブロック上部タイトルtitle=sample.js
linenumbers行番号表示 (開始行指定可)linenumbers
linenumbers=12
startlinenumbers の別名start=10
class追加 CSS クラスclass=my-code my-code-2
diff差分ハイライト (+ / - 行)diff

※上記に当てはまらない引数は言語指定として扱う。

使用例

#shiki(php,theme=dark-plus,title=shiki.inc.php,start=60){{
    public function convert(): string
    {
        $code = htmlsc($this->code);
        $lang = ' data-lang="' . $this->lang . '"';
        $hasLinenumbers = $this->linenumbers !== '';
        $theme = ' data-theme="' . $this->theme . '"';
        $class = $this->class !== '' ? $this->class : '';
        $title = $this->title !== '' ? ' data-title="' . $this->title . '"' : '';
        $linenumbers = $hasLinenumbers ? 'data-linenumbers' : '';
        $start = $hasLinenumbers ? '--start-index:' . $this->linenumbers . ';' : '';
        $script = $this->script();

        return <<<EOD
        <div class="plugin-shiki$class" style="visibility:hidden;$start"$lang$theme$title$linenumbers>
            <pre class="shiki-target">$code</pre>
        </div>
        $script
        EOD;
    }
}}

技術的メモ

  • Shiki は CDN (https://esm.run/shiki@3) から ESM として読み込み
  • import { createHighlighter } from 'shiki' を利用し、ブラウザ上でハイライトを実行
  • PHP 側では以下のみを担当
    • コード内容のエスケープ
    • 引数(言語・テーマ・行番号など)の解析
    • 必要な HTML 構造と data 属性の出力
  • 実際のシンタックスハイライト処理はすべてクライアント側 JavaScript で実行
  • ページ内に複数 #shiki があっても JS/CSS は1回のみロード
  • 初期表示時は visibility:hidden → ハイライト完了後に表示

処理フロー概要

  1. PukiWiki が #shiki(...) を解釈し、shiki.inc.php が実行される
  2. PHP 側で以下を生成
    • <pre><code> を含むプレースホルダー HTML
    • 言語・テーマ・行番号などを data-* 属性として付与
  3. JavaScript で <head> にプラグイン用の <style> 要素を挿入
  4. ページ読み込み後、 createHighlighterhighlighterInstance を一度のみ作成
    • この時点では初期テーマのみをロードする
    • この際言語はロードせず、各コードブロックの処理時に必要な言語やテーマをロードする
  5. 各コードブロックごとに highlighterInstance.codeToHtml() を実行し、 ハイライト済み HTML に差し替え
    • data 属性から言語とテーマ、タイトルや行番号指定などを取得
      • 言語やテーマがまだロードされていない場合は、ここでロードする
    • Transformer を使ってコードブロックの上にタイトル、言語ラベル、コピーボタンなどのヘッダー要素を追加
  6. 処理完了後、各コードブロックを表示する

備考

  • Prism から変えたらページの表示速度が下がるかと思ったが、むしろ早くなった。
  • 今回からリポジトリをプラグインごとに分けるようにした。
  • CSS や JS を PHP にまとめて単一ファイルで配布できるようにしつつ、開発中はそれぞれ別のファイルに分けて編集したかったので、 Docker で PHP 8 + PukiWiki 1.5.4 + Node.js という開発環境を構築し、最終的なプラグインファイルをビルドするという形を取った。
    • ビルド用のスクリプトはローカル LLM (Qwen3 Coder 30B) を使って生成してみた。流石にそのままじゃダメだったので手直ししたが、それでも作業時間は短縮してくれたように思う。まぁ最初から Claude やら ChatGPT 頼ればもっと早いじゃんねっていうのはそうなんだけれども。

コメント

Loading comments…