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を使うべきだろう。当サイトも結局そうしました。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
Intel Macbook2020にBootCampで入れたWindows11 Pro 23H2のBluetoothを復活させる
Windowsのデスクトップ画面をそのまま配信するための下準備
WindowsでGPUの状態を確認するには(ASUS系監視ソフトの自動起動を停止する)
CORESERVER v1プランからさくらインターネットスタンダートプランへ引っ越しメモ
さくらインターネットでPython MecabをCGIから使う
さくらインターネットのPHPでAnalytics-G4 APIを使う
インクルードパスの調べ方
【Git】特定ファイルを除外する.gitignore
【Ubuntu/Debian】NVIDIA関係のドライバを自動アップデートさせない
【Windows10】リモートデスクトップ間のコピー&ペーストができなくなった場合の対処法
Windows版Google Driveが使用中と言われアンインストールできない場合
【Apache】サーバーに同時接続可能なクライアント数を調整する
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
Windows11でMacのキーボードを使うには
cannot guess build type; you must specify oneと言われた場合
Pythonで処理にかかった時間を計測するには
【ひかり電話+VoIPアダプタ】LANしか通ってない環境でアナログ電話とFAXを使う