2024-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(ローカルに持たないで公式から直接ロードする)場合
| HTML | highlightjs_hosted.html | GitHub 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
unsigned char buf[8192];
int len;
fprintf(stdout, "---BEGIN DATA CONTENTS---\n");
while (1) {
len = fread(buf, 1, sizeof(buf), stdin);
if (len <= 0) {
break;
}
fwrite(buf, len, 1, stdout);
}
fprintf(stdout, "---END DATA CONTENTS---\n");
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ファイルを読み込み指定すれば、コードも出力結果も全く同じ。
| HTML | highlightjs_local.html | GitHub 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
unsigned char buf[8192];
int len;
fprintf(stdout, "---BEGIN DATA CONTENTS---\n");
while (1) {
len = fread(buf, 1, sizeof(buf), stdin);
if (len <= 0) {
break;
}
fwrite(buf, len, 1, stdout);
}
fprintf(stdout, "---END DATA CONTENTS---\n");
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>
トータルでは以下のように書くことになる。
| HTML | highlightjs_hosted_linenumbers.html | GitHub 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
unsigned char buf[8192];
int len;
fprintf(stdout, "---BEGIN DATA CONTENTS---\n");
while (1) {
len = fread(buf, 1, sizeof(buf), stdin);
if (len <= 0) {
break;
}
fwrite(buf, len, 1, stdout);
}
fprintf(stdout, "---END DATA CONTENTS---\n");
return 0;
}
</code></pre>
</body>
</html>
出力結果はこちら(別ウインドウ)
出力結果のとおり、以下の問題が発生してしまった。
・スペースが除去されてしまう。 を記述したところスペースされたので、スペースはすべてnbspにしなければならない。面倒!!
・ダークテーマだと正常に表示されない(白がつぶれる)。
前者はまだしも後者はどうしようもない。よって行番号を表示したいなら、後述するGoogle Code Prettifyを使うべきだろう。当サイトも結局そうしました。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
Wav2Lipのオープンソース版を改造して外部から呼べるAPI化する
Wav2Lipのオープンソース版で静止画の口元のみを動かして喋らせる
【iOS】アプリアイコン・ロゴ画像の作成・設定方法
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【2】
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【1】
【Xcode】iPhone is not available because it is unpairedの対処法
【Let's Encrypt】Failed authorization procedure 503の対処法
【Debian】古いバージョンでapt updateしたら404 not foundでエラーになる場合
ファイアウォール内部のWindows11 PCにmacOS Sequoiaからリモートデスクトップする
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
進研ゼミチャレンジタッチをAndroid端末化する
VirtualBoxの仮想マシンをWindows起動時に自動起動し終了時に自動サスペンドする
Googleスプレッドシートを編集したら自動で更新日時を入れる
Androidホームで左にスワイプすると出てくるニュース共を一切表示させない方法
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
Windows11のコマンドプロンプトでテキストをコピーする
size_tとssize_tを使い分けてSegmentation Faultを予防する
【C++】staticメンバ変数がundefined referenceとエラーになる場合