アプリケーション開発ポータルサイト
ServerNote.NET
Amazon.co.jpでPC関連商品タイムセール開催中!
カテゴリー【JavaScriptGit/GitHub
ブログに貼り付けたソースコードをハイライトする【highlight.js編】
POSTED BY
2023-04-29

公開するソースコードはすべてGitHubで管理しているので、ブログに貼りつけるにはgist-itを経由して貼るか、単一のファイルならgistで管理して公式機能で貼るかの2択しか選択肢が無いのだが、以下どうにもならない問題に悩まされていた。

1、gist-itまたはgithub経由でコードがロードされ装飾されるため相当重い。
2、正直見栄えが悪い。カスタマイズはほとんどできない。

GitHubのコードをそのまま出せるgist-itは非常に便利なのだが、上記問題が特に顕著であるので、当サイトでは両者の使用をやめ、以下の方法にリニューアルした。

GitHubで全ソースを管理するのには変わりはないが、ブログのあるローカルサーバーにソースをクローンし、ローカルでそのまま読みこみ、HTMLメタ文字をエスケープして出力すれば、巷の高速ハイライトツールが使える。
つまりデータベースのブログ記事本文には$SOURCE=sample/test.c$などと独自のキーワードを埋め込んでおき、表示するときにこのキーワードをローカルにクローンしてあるsample/test.cを読み込んだものと差し替えて出力することにした。

「巷の高速ハイライトツール」には、highlight.jsとgoogle-code-prettifyを両方試したので、以下まずhighlight.jsからメモ。

【highlight.js】

1、CDN Hosted(ローカルに持たないで公式から直接ロードする)場合

HTMLhighlightjs_hosted.htmlGitHub Source
<html lang="ja">
<head>
<meta charset="utf-8">

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/styles/obsidian.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/highlight.min.js"></script>
<!-- and it's easy to individually load additional languages -->
<script charset="UTF-8" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/languages/go.min.js"></script>
<script>
    hljs.configure({tabReplace:'    '});
    hljs.initHighlightingOnLoad();
</script>

<title>ソースコードハイライトサンプル</title>
</head>

<body>
<pre><code class="h++">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

int main(void) {

  unsigned char buf[8192];
  int len;

  fprintf(stdout, &quot;---BEGIN DATA CONTENTS---\n&quot;);

  while (1) {
    len = fread(buf, 1, sizeof(buf), stdin);
    if (len &lt;= 0) {
      break;
    }
    fwrite(buf, len, 1, stdout);
  }

  fprintf(stdout, &quot;---END DATA CONTENTS---\n&quot;);

  return 0;
}
</code></pre>
</body>
</html>

出力結果はこちら(別ウインドウ)

・styles/obsidian.min.cssのところを、好みの見栄えのスタイルを選んで変更する。スタイルのデモは以下にある。

https://highlightjs.org/static/demo/

選んだスタイルのファイル名は、

https://github.com/highlightjs/highlight.js/tree/master/src/styles

にあるので、差し替えればOK。

・デフォルトでサポートされていない言語は別途jsをロードする必要がある。上記例(というより公式サンプルそのまま)ではlanguages/go.min.jsをロードしている。どの言語だと別途jsが必要かは、

https://github.com/highlightjs/highlight.js/blob/master/SUPPORTED_LANGUAGES.md

に書いてあるが、これを見るとほとんどはデフォルトでサポートされており、ロードする必要は無いように見える。

・hljs.configure({tabReplace:' '}); で、コード内のタブをスペースに一応変換している。が、結局自力でlt,quot等HTMLエスケープしなくてはいけないので、そこでまとめてやっておくほうがいい。

・code classで指定するターゲット言語の識別子は、上記SUPPORTED_LANGUAGESにあるので該当のものを指定。

・コード1行目は改行無しでcodeタグ直後に書かないと改行されてしまうトラップあり。

2、ファイル一式をローカルにダウンロードして使う場合

https://highlightjs.org/download/

Custom package

使う言語にチェック。ほとんどはデフォルトCommonのままでよいだろう。

「Download」ボタンを押す highlight.zipがダウンロードされるので解凍し、highlightディレクトリをhtdocsに設置する。

あとはこのローカルに設置したjs,cssファイルを読み込み指定すれば、コードも出力結果も全く同じ。

HTMLhighlightjs_local.htmlGitHub Source
<html lang="ja">
<head>
<meta charset="utf-8">

<link rel="stylesheet" href="./highlight/styles/obsidian.css">
<script src="./highlight/highlight.pack.js"></script>
<script>
    hljs.configure({tabReplace:'    '});
    hljs.initHighlightingOnLoad();
</script>

<title>ソースコードハイライトサンプル</title>
</head>

<body>
<pre><code class="h++">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

int main(void) {

  unsigned char buf[8192];
  int len;

  fprintf(stdout, &quot;---BEGIN DATA CONTENTS---\n&quot;);

  while (1) {
    len = fread(buf, 1, sizeof(buf), stdin);
    if (len &lt;= 0) {
      break;
    }
    fwrite(buf, len, 1, stdout);
  }

  fprintf(stdout, &quot;---END DATA CONTENTS---\n&quot;);

  return 0;
}
</code></pre>
</body>
</html>

3、行番号を表示させる

行番号を表示するにはhighlightjs-line-numbers.jsプラグインを組み込む。

CDN Hostedの場合、highlightjsロード直下に、

<script src="https://cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.7.0/highlightjs-line-numbers.min.js"></script>
<script>
    hljs.initLineNumbersOnLoad();
</script>

と設置する。ローカルダウンロードの場合、

https://github.com/wcoder/highlightjs-line-numbers.js/blob/master/src/highlightjs-line-numbers.js

をダウンロードして、highlight.pack.jsと同じ場所に設置し、

<script src="./highlight/highlightjs-line-numbers.js"></script>
<script>
    hljs.initLineNumbersOnLoad();
</script>

とする。

公式サイトにもあるが、以下のようにしてCSSで見栄えを調整する必要あり。

<style type="text/css">
/* for block of numbers */
td.hljs-ln-numbers {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;

    text-align: center;
    color: #ccc;
    border-right: 1px solid #CCC;
    vertical-align: top;
    padding-right: 5px;

    /* your custom style here */
}

/* for block of code */
td.hljs-ln-code {
    padding-left: 10px !important;
}
</style>

トータルでは以下のように書くことになる。

HTMLhighlightjs_hosted_linenumbers.htmlGitHub Source
<html lang="ja">
<head>
<meta charset="utf-8">

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/highlight.min.js"></script>
<!-- and it's easy to individually load additional languages -->
<script charset="UTF-8" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/languages/go.min.js"></script>
<script>
    hljs.configure({tabReplace:'    '});
    hljs.initHighlightingOnLoad();
</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.7.0/highlightjs-line-numbers.min.js"></script>
<script>
    hljs.initLineNumbersOnLoad();
</script>
<style type="text/css">
/* for block of numbers */
td.hljs-ln-numbers {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;

    text-align: center;
    color: #ccc;
    border-right: 1px solid #CCC;
    vertical-align: top;
    padding-right: 5px;

    /* your custom style here */
}

/* for block of code */
td.hljs-ln-code {
    padding-left: 10px !important;
}
</style>

<title>ソースコードハイライトサンプル</title>
</head>

<body>
<pre><code class="h++">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

int main(void) {

  unsigned char buf[8192];
  int len;

  fprintf(stdout, &quot;---BEGIN DATA CONTENTS---\n&quot;);

  while (1) {
    len = fread(buf, 1, sizeof(buf), stdin);
    if (len &lt;= 0) {
      break;
    }
    fwrite(buf, len, 1, stdout);
  }

  fprintf(stdout, &quot;---END DATA CONTENTS---\n&quot;);

  return 0;
}
</code></pre>
</body>
</html>

出力結果はこちら(別ウインドウ)

出力結果のとおり、以下の問題が発生してしまった。

スペースが除去されてしまう。&nbsp;を記述したところスペースされたので、スペースはすべてnbspにしなければならない。面倒!!

ダークテーマだと正常に表示されない(白がつぶれる)。

前者はまだしも後者はどうしようもない。よって行番号を表示したいなら、後述するGoogle Code Prettifyを使うべきだろう。当サイトも結局そうしました。

※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!
ご連絡は以下アドレスまでお願いします★

☆ServerNote.NETショッピング↓
ShoppingNote / Amazon.co.jp
☆お仲間ブログ↓
一人社長の不動産業務日誌
【キーワード検索】