Google Code-Prettify

プログラムのコードをキーワードや構文などにより色分けして表示する機能(シンタックスハイライト)を簡単に実装できる Google Code-Prettify の設定方法や基本的な使い方、WordPress でのショートコードの作成方法について。

このサイトでも利用しているシンタックスハイライト Google Code-Prettify は軽量で簡単に導入することができます。多機能ではありませんが、好みのスタイル(テーマ)を選択したり CSS で見栄えを調整することができます。

追記:Google Code-Prettify は Apr 22, 2020 で開発は終了しています。代わりのシンタックスハイライターとしては、Highlight.js や Prism.js が定評があります。以下は関連ページです。

以下は Google Code-Prettify の関連リンクです。

WordPress Code-Prettify でシンタックスハイライトするブロックの作成

作成日:2019年06月15日

Google Code-Prettify の基本的な使い方

code-prettify を使うには <script> タグを記述してオートローダーで関連ファイルを読み込むか、必要なファイルをダウンロードして読み込みます。

オートローダー

オートローダー(Auto-Loader)を利用すると <script> タグを記述するだけで JavaScript と CSS などの必要なライブラリを自動的に読み込んで code-prettify を使える状態にします。

以下の1行を body の閉じタグの直前などに記述するだけです。

<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>

2019年10月には今まで提供されていた RawGit の CDN(cdn.rawgit.com)は終了し、上記の cdn.jsdelivr.net に変更になっています(cdn.jsdelivr.net は2019年3月から使用可能です)。

CDN 変更のお知らせ:Action Required: Google Code Prettify changing CDNs

CGI パラメータ

オートローダーの URL の最後にクエリ文字(CGI parameter)を追加してオプションを指定することができます。

以下のようなオプションを指定することができます。

CGI パラメータ デフォルト 意味
autorun= true ページ読み込み時に自動的に実行するかどうか。autorun=false と指定すると自動的に実行しません。
lang= なし 指定した言語のハンドラー(その言語を表示するためのファイル)を読み込みます。通常はその言語のソースファイルの言語名部分(lang-xxxx.js の xxxx)を指定します。複数指定することができます(例:?lang=css&lang=ml)。言語のリストは「index of language handlers」参照。
skin= なし シンタックスハイライトのテーマ(skin)を指定します。どのようなテーマがあるかは skin gallery を参照。複数指定した場合は、読み込みに最初に成功したテーマが使われます。
callback= なし code-prettify のコールバック関数を指定できます。code-prettify 処理終了時に window.exports["xxxx"] が呼ばれます。

クエリ文字(CGI parameter)は ? から始まり「パラメータ=値」の形式で記述し、複数ある場合は & で繋ぎます。

以下は「?lang=css&skin=desert」と記述して CSS 言語ハンドラーと desert と言うテーマ(skin)を読み込むように指定する例です。

<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js?lang=css&skin=desert"></script>

ダウンロード

オートローダーを使わずに code-prettify の JavaScript と CSS ファイルをダウンロードして、必要なファイルをサーバーにアップロードして使うこともできます。

code-prettify download」をクリックすると以下のような確認画面が表示され「ファイルを保存する」を選択し「OK」をクリックすると prettify-small.zip のダウンロードが開始されます。

code-prettify のダウンロード確認画面のスクリーンショット

ダウンロードした prettify-small.zip を解凍すると以下のようなファイルがあるので、必要なファイルをアップロードしてそれぞれのファイルを読み込みます。使用しないファイルはアップロードは不要です。

prettify-small.zip を解凍したスクリーンショット

ファイルの読み込み

スタイルの CSS ファイルとシンタックス機能の JavaScript ファイルを適当な場所に配置して読み込む必要があります。

デフォルトの場合は「prettify.css」と「prettify.js」を適当な場所に配置して読み込みます。

CSS ファイル

CSS ファイルは head 内で読み込みます。以下はデフォルトの「prettify.css」を読み込む場合の例です。ファイルを読み込むパスは環境に合わせて変更します。

<link rel="stylesheet" href="prettify/prettify.css">

以下はテーマ Desert の「desert.css」を読み込む場合の例です(テーマを使用する場合はデフォルトの prettify.css は読み込む必要はありません)。

<link rel="stylesheet" href="prettify/skins/desert.css"> 

場合によってはファイルの内容をコピーして、使用している CSS ファイルにまとめてしまっても良いかも知れません。

JavaScript ファイル

JavaScript ファイルは body の閉じタグの直前等で読み込みます。

以下は「prettify.js」を読み込む例です。ファイルを読み込むパスは環境に合わせて変更します。

<script src="prettify/prettify.js"></script> 

以下は「prettify.js」と CSS 言語のハンドラー「lang-css.js」を読み込む例です。言語ハンドラーを読み込む場合にも「prettify.js」を読み込む必要があります。

<script src="prettify/prettify.js"></script>
<script src="prettify/lang-css.js"></script>

解凍したフォルダ内の言語のハンドラーのスクリーンショット

PR.prettyPrint()

また、ダウンロードした prettify.js を読み込む場合は PR.prettyPrint() と言う JavaScript の関数を実行する必要があります(または、run_prettify.js を読み込みます)。

以下は window の load イベントを利用して実行する例です。

「prettify.js」の読み込みの後に記述します。

<script src="prettify/prettify.js"></script>
<script src="prettify/lang-css.js"></script>
<script>
  window.addEventListener("load", function() {
    PR.prettyPrint();
  });
</script>

または onload ハンドラーを使って以下のようにして実行することもできます。

<body onload="PR.prettyPrint()">
run_prettify(追記)

前述の例ではダウンロードした prettify.js を読みましたが、prettify.js の代わりにダウンロードした run_prettify.js を読み込むこともできます。

その場合は、PR.prettyPrint() の実行(記述)は不要になります。

<script src="../../prettify/run_prettify.js"></script>    
クエリパラメータ

run_prettify.js を読み込んだ場合は、オートローダー同様、最後にクエリ文字(CGI parameter)を追加してオプションを指定することができます。

以下はスキンに sunburst を指定する場合の例です。

<script src="../../prettify/run_prettify.js?skin=sunburst"></script>

以下はスキンに desert を指定して、コールバック関数も指定する場合の例です。

<script src="../../prettify/run_prettify.js?skin=desert&callback=testing"></script>
<script>
  window.exports = {
    testing: function () {
      alert('hello');
    }
  }
</script>

コードの記述

code-prettify は prettyprint クラスを指定した <pre> や <code> の要素を探してその中のキーワードやコメント、文字列などを <span> 要素で囲んでスタイルを設定します。

言い換えると、シンタックスハイライトで表示したい部分を以下のように prettyprint クラスを指定した <pre> タグで囲みます。

<pre class="prettyprint">
//コードを記述
</pre>

テーマ(skin)を読み込んでないデフォルトの状態で以下を記述すると、

<pre class="prettyprint">$(window).on('load', function() {
  $(".page-loader").delay(500).fadeOut(600);
});

setTimeout('stoploading()', 10000);
function stoploading() {
  $(".page-loader").fadeOut('fast');
}</pre>

以下のようにデフォルトのスタイルで表示されます。

HTML のコードを表示する場合は、タグなどの特殊文字 "&", "<", ">" ,'"', "'" は "&amp;", "&lt;", "&gt;", "&quot;", "&#39;" に変換する必要があります。

例えば、<pre class="prettyprint"> と表示するには &lt;pre class=&quot;prettyprint&quot;&gt; とします。

関連ページ

行番号の表示

行番号を表示するには、prettyprint クラスに加えて linenums クラスを追加します。

<pre class="prettyprint linenums">
 <!-- ソースコードを記述 -->
</pre>

デフォルトでは5行ごとに行番号が表示されるので、1行ごとに行番号を表示するには CSS で以下のように list-style-type に decimal や decimal-leading-zero を指定します。

.prettyprint ol.linenums > li {
  list-style-type: decimal;
  /* または */
  list-style-type: decimal-leading-zero;
}

特定の行番号から表示させるには「linenums:30(30行目から)」のようにクラスを指定します。

<pre class="prettyprint linenums:30">
 <!-- ソースコードを記述 -->
</pre>

言語の指定

code-prettify は記述されている言語を推測してキーワードや構文に対して自動的に色分けをします。

自動色分けは C や HTML 系の言語でうまく機能するようですが、その他の言語やうまく色分けできていない場合には、言語を示唆するクラス(lang-xxxx)を追加することで言語を明示的に指定してより適切に表示することができます。

以下は CSS の言語をシンタックスハイライトする例で、prettyprint クラスを指定した要素に lang-css クラスを追加しています。

/* lang-css クラスを <pre> 要素に追加する例 */
<pre class="prettyprint lang-css">.map_wrapper {
  position: relative;
  width:100%;
  padding-top:56.25%;
  border: 1px solid #CCC;
}</pre>

言語を明示的に指定する場合は、言語によっては言語ハンドラー(その言語を表示するためのファイル 例:lang-css.js)を読み込んでおく必要があります。

オートロードの場合 | ダウンロードの場合

コールバック関数

クエリ文字(CGI parameter)で callback=xxxx を追加することでコールバック関数を指定することができます。

以下は testing と言うコールバック関数を指定して呼び出す例です。

<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js?skin=sunburst&callback=testing"></script>
<script>
  //コールバック関数の定義
  window.exports = {
    testing: function () {
      alert('hello');
    }
  }
</script>

コールバック関数は複数指定することができます。

<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js?skin=sunburst&callback=testing&callback=testing2"></script>
<script>
  //コールバック関数を複数定義
  window.exports = [];
  window.exports["testing"] = function() {
    alert("This is callback #1");
  }
  window.exports["testing2"] = function() {
    alert("This is callback #2");
  }
</script>

ダウンロードした場合は run_prettify.js を使う必要があるようです。

<!-- ダウンロードした run_prettify.js を読み込み callback=xxxx を指定 -->
<script src="../../prettify/run_prettify.js?callback=testing"></script>
<script>
  window.exports = {
    testing: function () {
      alert('hello');
    }
  }
</script>

スタイルの指定

シンタックスハイライトのスタイルはテーマを読み込むか CSS でスタイルを指定することで変更することができます。

テーマ(skin)の利用

簡単にスタイルを適用するには、テーマ(skin)を読み込みます。数は多くありませんが以下のようなテーマを利用することができます。テーマを読み込まない場合は Default のスタイルが適用されます。

code-prettify テーマギャラリーのスクリーンショット

テーマギャラリーのページ code-prettify themes gallery でどのようなテーマがあるかを確認して好みのテーマを選択します。

テーマの名前をクリックすると、それぞれのテーマの詳細ページへリンクされているのでそのテーマの CSS の詳細などを確認することができます。

テーマの CSS をそのまま使用しても良いですし、それを元に独自のスタイルを設定して使用することもできます。

また、テーマギャラリーのページを印刷することで、それぞれのテーマの印刷時の表示を確認することができます。

オートローダー

オートローダーを使用している場合は、URL の読み込みの文字列にクエリ文字(CGI parameter)を追加してテーマを読み込むことができます。

以下は Sunburst と言うテーマを読み込む例です。パラメータに指定する際はテーマ名は全て小文字で指定します。

<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js?skin=sunburst"></script>

ダウンロード

ダウンロードして使用している場合は、ダウンロードした中の「skins」と言うフォルダにテーマのファイルが入っているのでその中から読み込みます。

ダウンロードした中の「skins」と言うフォルダの中身のスクリーンショット

以下は Sunburst と言うテーマを読み込む例です。

テーマの CSS ファイルを読み込む場合はデフォルトの prettify.css は読み込みません(余計なスタイルが適用されてしまいます)。

<link rel="stylesheet" href="prettify/skins/sunburst.css"><!-- Desert の CSS -->

以下は Sunburst と言うテーマを読み込んだ際の表示例です。

CSS でスタイルのカスタマイズ

オートローダーを使用する場合は、独自のスタイルシートを作成してデフォルトやテーマのスタイルを上書きします。その際には元のスタイルの指定を確認して詳細度などを考慮する必要があるかもしれません。独自のスタイルシートはオートローダーの記述の後に読み込みます。

ダウンロードして使用する場合は、独自のスタイルシートを作成してデフォルトやテーマのスタイルの後に読み込み設定を上書きしても良いですし、テーマのスタイルを変更して独自のスタイルとして使用することもできるかと思います。

以下はカスタマイズの例です。以下はあくまで参考例で、使用するテーマやお使いの環境では異なる設定が必要になる可能性があります。

行番号との区切り線

行番頭とコードの間に区切り線を表示するには、li 要素に border-left を指定します。その際に li 要素や ol 要素にパディングを指定して間隔を調整することができます。

.prettyprint ol{
 padding: .2rem 0 .5rem .8rem; /* 間隔の調整(必要であれば) */
}

.prettyprint ol.linenums > li {
  list-style-type: decimal; /* 1行ごとに行番号を表示 */
  border-left:solid 1px #EBB15E; /* 区切り線を表示  */
  padding-left:0.5rem; /* 間隔の調整(必要であれば) */
}

折り返し

pre 要素を使用するので必要に応じて ol 要素に「overflow: auto;」や「 white-space: pre-wrap; 」などで折り返しの指定をすることができます。

.prettyprint ol{
  white-space: pre-wrap; /* 折り返し  */
}

フォントの指定

必要に応じて(好みで)フォントのスタイルを指定することができます。

pre.prettyprint {
  font-family: Monaco, Menlo, Consolas, 'Courier New', Courier, monospace, sans-serif;
} 

テーマ Sunburst を読み込んで以下のようなスタイルで上書きすると(お使いの環境やテーマが異なれば設定する内容や値も変更する必要があります)、

pre.prettyprint {
  font-family: Monaco, Menlo, Consolas, 'Courier New', Courier, monospace, sans-serif;
  background-color: #0E101E;   /* 背景色 */
  border-top-left-radius: 0;  /* テーマの角丸の設定を上書き */
  border-top-right-radius: 0;
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

.prettyprint ol{
  margin: 0 1rem; /* 間隔の調整 */
  white-space: pre-wrap;  /* 折り返し */
}

.prettyprint ol.linenums > li {
  list-style-type: decimal;  /* 行番号を1行ずつ表示 */
  border-left:solid 1px #EBB15E;  /* 行番号との区切り線 */
  padding-left:0.8em; /* 間隔の調整 */
  color: #999; /* 行番号の色 */
}

以下のような表示になります。

このサイトではテーマ Desert を使用して独自のスタイルを適用しています。

WordPress で使う

New [追記:2020年11月2日]

ブロックエディタ Gutenberg で Code-Prettify を使ってシンタックスハイライトするブロックを作成する方法の記事を追加しました。ショートコードで記述するより便利です。また、以下の「既知(?)の問題」も発生しません。

WordPress で使う場合は、ショートコードを利用すると便利です。ショートコードを利用すれば、コードのエスケープ処理も同時に行うことができます。

関連ページ:WordPress ショートコードの作成

このサンプルでは [code] と言うショートコードを作成します。

code-prettify の読み込み

このショートコードをほとんどのページで使用する場合は、以下のように

wp_enqueue_script を使って通常の読み込みをします。

必要に応じて言語のハンドラーやテーマをクエリ文字(CGI parameter)で追加します(例 ?lang=css&skin=sunburst)。

function add_my_styles_and_scripts() {

  ・・・その他のスクリプトやスタイルの読み込み・・・

  //オートローダーを使う例
  wp_enqueue_script(
    'prettify',
    '//cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js',
    array(),
    '28.04.2015', //バージョン(オプション)
    true
  );
}
add_action( 'wp_enqueue_scripts', 'add_my_styles_and_scripts' );

このショートコードをほとんど使わない場合は、has_shortcode() を使ってコンテンツにショートコード [code] が記述されている場合のみ、code-prettify を読み込むこともできます。

但し、この場合はショートコードの作成の最後の部分のコメント(45~46行目)を外す必要があります。また、has_shortcode() はリソースを使うのでコンテンツが大きい場合などは返って読み込みが遅くなる可能性もあるかも知れません。

global $post;
if ( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'code') ) {
  wp_enqueue_script(
    'prettify',
    '//cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js',
    array(),
    '28.04.2015',
    true
  );
}

ダウンロードして使う場合

以下はテーマの を使用する場合の例です。パスやスタイルシートの名前は環境に応じて適宜変更します。

この例では prettify の初期化(以下)は独自の JavaScript base.js に記述してあります。prettify.js の最後に追加することも可能です。

window.addEventListener("load", function() {
  PR.prettyPrint();
});

また必要に応じて言語ハンドラーを読み込むか、内容を prettify.js にコピーします。

function add_my_styles_and_scripts() {

  ・・・その他のスクリプトやスタイルの読み込み・・・

  //スタイルシート style.css の読み込み
  wp_enqueue_style(
    'my-template-style',
    get_stylesheet_uri(),
    //prettify sunburst を依存関係に
    array('prettify-sunburst-style'),
    filemtime( get_theme_file_path( '/style.css' ) )
  );

  //スタイルシート prettify sunburst.css の読み込み
  wp_enqueue_style(
    'prettify-sunburst-style',
    get_theme_file_uri('/sunburst.css'),
    array(),
    filemtime( get_theme_file_path( '/sunburst.css' ) )
  );

  //独自の JavaScript base.js の読み込み(★ prettify の初期化処理を記述)
  wp_enqueue_script(
    'base-script',
    get_theme_file_uri( '/js/base.js' ),
    array( 'jquery', 'bootstrap' ),
    filemtime( get_theme_file_path( '/js/base.js' ) ),
    true
  );

  //JavaScript prettify.j の読み込み
  wp_enqueue_script(
    'prettify',
    get_theme_file_uri( '/js/prettify.js' ),
    array(),
    '28.04.2015',
    true
  );
}
add_action( 'wp_enqueue_scripts', 'add_my_styles_and_scripts' );

ショートコードの作成と登録

以下がショートコードの作成と登録です。functions.php に記述します。

ショートコードの作成の詳細は「ショートコードのサンプル:コードの表示」を参照ください。

function run_shortcode_code( $content ) {
  global $shortcode_tags;
  $original_shortcode_tags = $shortcode_tags;
  remove_all_shortcodes();
  add_shortcode( 'code', 'shortcode_code' );
  $content = do_shortcode( $content );
  $shortcode_tags = $original_shortcode_tags;
  return $content;
}
add_filter( 'the_content', 'run_shortcode_code', 7 );

function shortcode_code( $atts, $content = null ) {
  extract(shortcode_atts(array(
    'class' => 'prettyprint',
    'linenums' => '1', // 開始行番号の指定
    'lang' => '', // 言語ハンドラーの指定
    'esc' => 'true'  //自前でエスケープする場合は 0 を指定
  ), $atts));

  if($linenums ==='1') {
    $class = 'prettyprint linenums';
  } elseif ($linenums){
    $class = 'prettyprint linenums:' . $linenums;
  }else {
    $class = 'prettyprint';
  }

  if($lang) {
    $class .= ' lang-'. $lang;
  }

  if($esc){ //$content をエスケープ処理('true'は文字列だが true になる)
    $content = htmlspecialchars($content, ENT_QUOTES, get_option('blog_charset'));
  }else{
    $content = esc_html($content);
  }

  return sprintf(
  '<pre class="%s"><code>%s</code></pre>'. "\n",
  esc_attr($class),
  $content
  );
}
//has_shortcode() で code-prettify を読み込んでいる場合は以下のコメントを外す
/*global $shortcode_tags;
$shortcode_tags[ 'code' ] = '__return_false';*/

デフォルトでは行番号を1から表示するようにしています。属性の linenums に 0 を指定すると行番号を表示しません。linenums に 0 以外を指定すると、その番号から開始します(20~26行目)。

属性の lang に言語名を指定すると、言語を指定するクラス lang-xxxx を追加します(28~30行目)。

以下は使用例です。

ショートコードの使用例のスクリーンショット

以下は上記の場合の表示例です(テーマ sunburst と独自のスタイルを指定しています)。

ショートコードの使用例のスクリーンショット

行番号を表示しない場合は [code linenums=0] のように記述します。行番号を5行目から開始する場合は [code linenums=5] のようにします。

言語を指定する場合は [code lang=css] のように記述します。但し、必要な言語ハンドラーを読み込んでおく必要があります。

既知(?)の問題

コードの記述の中に以下のように HTML の開始タグと認識される < が閉じられていない場合は期待通りに機能しません。

if ( x > 50 && y < -50 )
//開始タグ < が終了タグ > と対になっていない場合は正常に機能しない 

上記のようなコードを含むショートコードがあるとショートコードの閉じタグ [/code] が正常に認識されず、その後続のコンテンツの表示にも影響がでてしまいます。

ショートコードが正常に認識されない入力例のスクリーンショット

以下のように正常に認識されないショートコードに続く段落と次のショートコードまでが1つのショートコードコンテンツと認識されてしまい、表示がおかしくなってしまいます。

ショートコードが正常に認識されないためおかしい表示のスクリーンショット

このような場合、可能であれば以下のように > と < の位置を変更して書き換えると機能します(実用的ではありませんが)。

if ( y < -50 && x > 50 ) 

または、属性 esc=0 を指定して以下のようにエスケープした値を記述します(面倒ですが)。

[code esc=0]if(x &gt; 50 &amp;&amp; y &lt; -50) [/code] 

または、最後に「>」を含む文字列を追加します。

[code]if ( x > 50 && y < -50 )
<!-- comment only -->[/code]

上記の場合、ショートコードの閉じタグ [/code] が正常に認識されて以下のように表示されます。

ショートコードが正常に認識された表示のスクリーンショット

問題のある記述の後に「>」が追加されれば良いので、以下のような文字列でも問題ありません。

[code]if ( x > 50 && y < -50 )
###-->終了###[/code]

関連ページ:「コードの表示/追記詳細