今回は Luxceritas のシンタックスハイライター機能に、初期状態では選べなかった言語を追加してみます。
というのも、なんか…選べる言語に Go言語 がなかったんですよね…(涙目
Luxceritas のシンタックスハイライターに言語を追加する
早速作業に入ります。
たぶん難易度的には低めだと思うんだけど…、多少面倒くさく、少しややこしい…気がします。
Prism の言語別スクリプトを入手する
まずやることは、新たに追加したい言語用のシンタックスハイライタースクリプトを入手するところから。
Luxeritas はシンタックスハイライトの機能を「Prism」で実現しているようです。通常「Prism」のスクリプト構成だと、様々な言語用のスクリプトが1ファイルにまとまっていますが、Luxeritas では、Prism本体、HTML用、Java用、C用、PHP用…、といった感じでファイル分けされバラバラ。
なので追加したい言語用のスクリプトだけを入手すれば良さげです。
スクリプトの入手場所となる「Prism」の公式サイトはここ。
言語別のスクリプトをダウンロードする
公式サイトを開きダウンロードページに移動する。

追加したい言語のスクリプトをダウンロードする
一旦「Lunguages」のチェックをすべて外す。

必要な言語のチェックを入れる。
依存関係のある言語があれば、それらも自動的にチェックが入る。依存する言語は後の設定で関係してくるので覚えておくこと。

ダウンロードする。

スクリプトの不要な行を削除する
ダウンロードしたJSファイルをエディタで開き、最後の行(Prism.languages.go~と書かれている行)以外を削除する。

不要な行を削除した状態。追加したい言語用のスクリプト1行だけが残る。

ファイル名を次のルールで変更しておく。
ここでつける [言語名] は後の設定で絡んできます。
ファイル名のルール
[言語名].js
例えば、「go.js」となる。
スクリプトを Luxeritas に配置する
先程入手したスクリプトを親テーマの Luxeritas に FTP かなんかで配置します。
スクリプトの配置場所を確認する
配置する場所は Luxeritas 親テーマの次の位置。
/[WordPressRoot]/wp-content/themes/luxeritas/js/prism
ディレクトリ内にはシンタックスハイライターで使用可能となっている言語と紐づくスクリプトが存在するはずです。

スクリプトを配置する
前述のディレクトリにスクリプトを配置します。
今回はGo言語を追加したいので、先程ダウンロードした go.js
(Go言語用のスクリプト)を配置。
配置したらパーミッションも変更しておく。

function.php にコードを追記する
続いては、子テーマの function.php に2つのファンクションを追記します。
このファンクションは、 Luxeritas の親テーマからパクってきたものに、Go言語用スクリプトも読み込ませるように少し変更しました。変更箇所はコメントで分かるようにしています。
// thk_highlighter_load() の割り込み再定義
function thk_highlighter_load( $loads, $list, $active ) {
global $luxe, $post;
foreach( $list as $key => $val ) {
if( strpos( $post->post_content, '<code class="language-' . str_replace( 'highlight_', '', $key ) . '"' ) !== false ) {
$active = true;
break;
}
}
if( $active === true ) {
$jsdir = TPATH . DSEP . 'js' . DSEP . 'prism' . DSEP;
$cssdir = TPATH . DSEP . 'css' . DSEP . 'prism' . DSEP;
if( !isset( $loads[1]['prism'] ) ) {
$loads[0] .= thk_fgc( $jsdir . 'prism.js' );
$loads[1]['prism'] = true;
}
// CSS
if( !isset( $luxe['highlighter_css_loaded'] ) ) {
if( isset( $luxe['highlighter_css'] ) && $luxe['highlighter_css'] !== 'none' ) {
$highlighter_css = trim( thk_fgc( $cssdir . 'prism-' . $luxe['highlighter_css'] . '.min.css' ) );
$highlighter_css .= 'pre[class*="language-"]{margin:20px 0 30px 0}';
if( TPATH !== SPATH ) {
wp_add_inline_style( 'luxech', $highlighter_css );
$luxe['highlighter_css_loaded'] = true;
}
else {
wp_add_inline_style( 'luxe', $highlighter_css );
$luxe['highlighter_css_loaded'] = true;
}
}
}
// Javascript
foreach( $list as $key => $val ) {
if( strpos( $post->post_content, '<code class="language-' . str_replace( 'highlight_', '', $key ) . '"' ) !== false ) {
$lang = str_replace( 'highlight_', '', $key );
if( !isset( $loads[1][$lang] ) ) {
// markup の場合
if( $lang === 'markup' ) {
// 言語ごとの読み込み
$loads[0] .= thk_fgc( $jsdir . $lang . '.js' );
$loads[1][$lang] = true;
}
/*
* 他言語の依存チェック
*/
// markup
if(
!isset( $loads[1]['markup'] ) &&
( $lang === 'php' || $lang === 'aspnet' )
) {
$loads[0] .= thk_fgc( $jsdir . 'markup.js' );
$loads[1]['markup'] = true;
}
// css
if(
!isset( $loads[1]['css'] ) &&
( $lang === 'markup' || $lang === 'php' || $lang === 'aspnet' || $lang === 'sass' )
) {
$loads[0] .= thk_fgc( $jsdir . 'css.js' );
$loads[1]['css'] = true;
}
// clike
if(
!isset( $loads[1]['clike'] ) &&
// 変更箇所1:Go の依存言語として clike も読み込ませる
//( $lang === 'markup' || $lang === 'javascript' || $lang === 'java' || $lang === 'php' || $lang === 'aspnet' || $lang === 'c' || $lang === 'cpp' || $lang === 'csharp' || $lang === 'ruby' || $lang === 'nginx' )
( $lang === 'go' || $lang === 'markup' || $lang === 'javascript' || $lang === 'java' || $lang === 'php' || $lang === 'aspnet' || $lang === 'c' || $lang === 'cpp' || $lang === 'csharp' || $lang === 'ruby' || $lang === 'nginx' )
) {
$loads[0] .= thk_fgc( $jsdir . 'clike.js' );
$loads[1]['clike'] = true;
}
// javascript
if(
!isset( $loads[1]['javascript'] ) &&
( $lang === 'markup' || $lang === 'php' || $lang === 'aspnet' )
) {
$loads[0] .= thk_fgc( $jsdir . 'javascript.js' );
$loads[1]['javascript'] = true;
}
// c
if(
!isset( $loads[1]['c'] ) &&
$lang === 'cpp'
) {
$loads[0] .= thk_fgc( $jsdir . 'c.js' );
$loads[1]['c'] = true;
}
// basic
if(
!isset( $loads[1]['basic'] ) &&
$lang === 'vbnet'
) {
$loads[0] .= thk_fgc( $jsdir . 'basic.js' );
$loads[1]['basic'] = true;
}
// sql
if(
!isset( $loads[1]['sql'] ) &&
$lang === 'plsql'
) {
$loads[0] .= thk_fgc( $jsdir . 'sql.js' );
$loads[1]['sql'] = true;
}
// markup 以外の場合
if( $lang !== 'markup' ) {
// 言語ごとの読み込み
$loads[0] .= thk_fgc( $jsdir . $lang . '.js' );
$loads[1][$lang] = true;
}
}
}
}
if( !isset( $loads[1]['options'] ) ) {
$loads[0] .= thk_fgc( $jsdir . 'prism-options.js' );
$loads[1]['options'] = true;
}
}
return $loads;
}
// thk_syntax_highlighter_list() の割り込み再定義
function thk_syntax_highlighter_list() {
return array(
'highlight_markup' => 'HTML / XHTML',
'highlight_apacheconf' => 'Apache Config',
'highlight_aspnet' => 'ASP.NET',
'highlight_autohotkey' => 'autoHotkey',
'highlight_bash' => 'Bash',
'highlight_basic' => 'Basic',
'highlight_batch' => 'Batch',
'highlight_clike' => 'Clike',
'highlight_c' => 'C',
'highlight_cpp' => 'C++',
'highlight_csharp' => 'C#',
'highlight_css' => 'CSS',
'highlight_diff' => 'Diff',
'highlight_git' => 'Git',
'highlight_java' => 'Java',
'highlight_javascript' => 'Javascript',
'highlight_json' => 'JSON',
'highlight_nginx' => 'nginx',
'highlight_nim' => 'Nim',
'highlight_perl' => 'Perl',
'highlight_php' => 'PHP',
'highlight_plsql' => 'PL/SQL',
'highlight_powershell' => 'PowerShell',
'highlight_python' => 'Python',
'highlight_r' => 'R',
'highlight_ruby' => 'Ruby',
'highlight_rust' => 'Rust',
'highlight_sass' => 'Sass',
'highlight_sql' => 'SQL',
'highlight_vbnet' => 'VB.NET',
'highlight_vim' => 'Vim',
'highlight_go' => 'Go', // 変更箇所2:Go言語を追加
);
}
変更した部分について
変更箇所1について。
依存関係の解決をしている処理ですね。 Go のハイライト実現には Clike 用のスクリプトも必要なので、次の通り clike をロードする条件に go も加えました。ちなみにですが、追加した条件にある言語名 'go'
は、この後出てくる変更箇所2の key 名の言語名部分と同じです。
まぁ、依存関係がなければこの辺の変更は不要みたいですがね。
// clike
if(
!isset( $loads[1]['clike'] ) &&
// 変更箇所1:Go の依存言語として clike も読み込ませる
//( $lang === 'markup' || $lang === 'javascript' || $lang === 'java' || $lang === 'php' || $lang === 'aspnet' || $lang === 'c' || $lang === 'cpp' || $lang === 'csharp' || $lang === 'ruby' || $lang === 'nginx' )
( $lang === 'go' || $lang === 'markup' || $lang === 'javascript' || $lang === 'java' || $lang === 'php' || $lang === 'aspnet' || $lang === 'c' || $lang === 'cpp' || $lang === 'csharp' || $lang === 'ruby' || $lang === 'nginx' )
) {
$loads[0] .= thk_fgc( $jsdir . 'clike.js' );
$loads[1]['clike'] = true;
}
変更箇所2について。
言語リストを返却するファンクションに Go言語 を加えます。
'highlight_go' => 'Go', // 変更箇所2:Go言語を追加
重要なのは key の名前で highlight_
に続く go
(言語名)の部分。
この go
の部分がプログラム内では $lang
として扱われ、先程配置した言語用スクリプトのファイル名(”$lang”+”.js”)だったり、 変更箇所1でも言語を識別するための値として使われてるようです。

ちなみに value に設定する値はラベルとして使われてる様子。(シンタックスハイライター右上だったり、編集画面のシンタックスハイライターブロックで選択できる言語一覧だったり…)
動作確認をする
編集画面のシンタックスハイライターブロックで、言語一覧から Go が選べるようになったし、ちゃんと色分けされてますね!

さいごに
といった感じで長くなりましたが、今回やりたかったことは達成できました。
んが、親テーマのディレクトリにスクリプトぶち込んだり、親テーマからファンクションパクって割り込み定義したりしてるので、親テーマのバージョンアップで動かねぐなるかも知んねぇです。。。
些細なことでリスクを背負い込むより、素直に作者さんに要望出したほうが面倒が少なくていいのかもね?_(:3」∠)_
というわけで、いじょ!٩( ‘ω’ )و
コメント