SOTA-JP.COM

書評、WordPress、アフィリエイト、米国株投資

GeSHiでシンタックスハイライトする方法。AMPページにも対応。

投稿日:2018年6月20日 更新日:

GeSHi

ワードプレスサイトで、PHPライブラリのGeSHiを使って、ソースコードをハイライト表示する方法を紹介します。

Javascriptを使わないので、AMPページでもハイライト表示できるのが大きなメリットです。

見た目はこんな感じになります。

#include <stdio.h>

int main(int argc, char *args[])
{
  printf("Hello, world!\n");
  return 0;
}

シンプルですが、結構見やすくて僕は好きです。

GeSHiとは

GeSHiは、Generic Syntax Highlighterの略で、数多くの言語に対応している強調表示用のPHPライブラリです。

このライブラリを利用すれば、整形されたソースコードをサーバー側で作成できます。
javascriptは不要。
HTMLとCSSだけでソースコードを強調表示できます。

あなたがサイト運営者で、「コードの紹介ページもAMP化したい」という場合には、GeSHiを利用するのがおすすめです。

エスケープ処理不要

GeSHiのもうひとつのメリットは、HTMLの特殊文字列を手動でエスケープ処理する必要がないということです。

エスケープ前の特殊文字列をGeSHiに通せば、自動で変換してくれます。

なので、下のようにそのままHTMLタグを書いても、GeSHiが上手いことエスケープしてくれます。

<pre>
<code class="○○">

<html>
<head></head>
<body></body>
</html>

</code>
</pre>

GeSHiの問題点

どうやらGeSHiはシングルクォーテーション「'」をアポストロフィ「‘」に勝手に変換してしまうようです。

なんでだろう。
僕の使い方が悪いだけかもしれませんが、とりあえず対処する必要があります。

ちょっと乱暴ですが、変換後のコードに含まれるアポストロフィをシングルクォーテーションに一括で置換することにします。

もともとのコードにアポストロフィが含まれている場合にはおかしなことになってしまいますが、今後もアポストロフィを使う予定はないので、当面はこの方法でいきます。

GeSHiのインストール

GeSHiのインストールはすごく簡単です。

sourceforge.netからダウンロードしてきて、適当なフォルダに解凍するだけ。

レンタルサーバーでも手軽に導入できます。

ライブラリの読み込みもシンプル。

子テーマディレクトリの「php_library」に解凍した場合は、こうなります。

require_once locate_template('php_library/geshi/geshi.php');

functions.phpなどに記述するコード

GeSHiは公式ページのドキュメントが充実しているので、それを見ながら試行錯誤するのもありだとは思います。

でも、英語だし読むのが面倒くさい場合は、僕のコードで良ければ使ってください。

まず、functions.phpに次のコードを追記します。

function stjp_set_geshi(){
 
  require_once locate_template('php_library/geshi/geshi.php');
 
  global $post;
  $ary_css = array();
 
  $result = preg_replace_callback('/<[p]re>\n?<code( class=["\'])?(.*?)(["\'])?>(.*?)<\/code>\n?<\/pre>/s',
    function ($matches)  use (&$ary_css){
      //コードが空の場合は何もしない
      if(empty($matches[4])){
        return;
      }else{
        $code = $matches[4];
      }
      //先頭と末尾の改行を削除
      $code = preg_replace('/^\n?(.*?)\n?$/s', '$1', $code);
     
      //言語が指定されていない場合はphpと想定してハイライト
      if(empty($matches[2])){
        $language = 'php';
      }else{
        $language = $matches[2];
      }
      $geshi = new GeSHi($code, $language);
     
      $geshi->set_header_type(GESHI_HEADER_DIV);
     
      //独自クラスを適用する
      $geshi->set_overall_class('mycode');
     
      //キーワードの解説ページへのリンクを無効にする
      $geshi->enable_keyword_links(false);
     
      //CSSを指定
      $overall_style = "font-family:Menlo,Consolas,'DejaVu Sans Mono',monospac;";
      $geshi->set_overall_style($overall_style, true);
     
      //CSSベタ打ちをクラス指定に変換
      $geshi->enable_classes();
     
      //言語ごとにCSSを配列に格納
      $ary_css[$language] = $geshi->get_stylesheet(false);
     
      //ハイライトされたコードを作成
      return $geshi->parse_code();
    },
    $post->post_content);
   
  if(empty($result)){
    return;
  }
 
  //アポストロフィをシングルクォーテーションに置換
  $result = str_replace("'","&#39;", $result);
 
  //投稿内容を書き換え
  $post->post_content = $result;
 
  $css = "";

  foreach($ary_css as $val){
    $css .= $val;
  }

  return $css;
}

続いて、header.php。
上で作成した関数を呼び出します。

cssの表示エリアに、例えば次のコードを書きます。

echo stjp_set_geshi();

後は好みでCSSで微調整します。
僕は、こんな感じにしています。

div.mycode,
div.mycode p{
  font-size:14px;
  line-height:20px;
}
div.mycode{
  background-color:floralwhite;
  border:solid 1px gray;
  padding:5px;
  margin:20px 0 20px 0;
}

これで、仕込みは終了です。

後は記事を表示するだけ。

<pre><code class="○○"></code></pre>でソースコードを囲むと、GeSHiが整形して表示してくれます。

ちなみにclass名には言語の名前を指定してください。
phpなら「php」、javascriptなら「javascript」です。

htmlは「html」ではなく「html5」なのでご注意を。

言語名がわからない場合は、ダウンロードしたフォルダ内の「geshi/geshi」を見てください。
ファイルがズラッと並んでおり、そのファイル名が指定する言語名です。

まとめ

AMPページでハイライト表示したい場合にはGeSHi一択だと思います。

導入も難しくないので、いちど試してみてください。