Luxeritas のシンタックスハイライターに他の言語を追加する
今回は Luxceritas のシンタックスハイライター機能に、初期状態では選べなかった言語を追加してみます。
というのも、なんか…選べる言語に Go言語 がなかったんですよね…(涙目
Luxceritas のシンタックスハイライターに言語を追加する
早速作業に入ります。
たぶん難易度的には低めだと思うんだけど…、多少面倒くさく、少しややこしい…気がします。
Prism の言語別スクリプトを入手する
まずやることは、新たに追加したい言語用のシンタックスハイライタースクリプトを入手するところから。
Luxeritas はシンタックスハイライトの機能を「Prism」で実現しているようです。通常「Prism」のスクリプト構成だと、様々な言語用のスクリプトが1ファイルにまとまっていますが、Luxeritas では、Prism本体、HTML用、Java用、C用、PHP用…、といった感じでファイル分けされバラバラ。
なので追加したい言語用のスクリプトだけを入手すれば良さげです。
スクリプトの入手場所となる「Prism」の公式サイトはここ。
言語別のスクリプトをダウンロードする
公式サイトを開きダウンロードページに移動する。
追加したい言語のスクリプトをダウンロードする
一旦「Lunguages」のチェックをすべて外す。
必要な言語のチェックを入れる。
依存関係のある言語があれば、それらも自動的にチェックが入る。依存する言語は後の設定で関係してくるので覚えておくこと。
ダウンロードする。
スクリプトの不要な行を削除する
ダウンロードしたスクリプトをエディタ等で開き、追加したい言語用のスクリプトのみを残し他は削除する。
// 1~2行目はコメント
/* PrismJS 1.25.0
https://prismjs.com/download.html#themes=prism&languages=clike+go */
// Prism の本体(かな?)
var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalSco
// clike 用のスクリプト(Go言語のハイライトをする前提になるスクリプト)
Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,look
// ↓ Go言語用のスクリプト、この行だけを残して他は消す
Prism.languages.go=Prism.languages.extend("clike",{string:{pattern:/(["'`])(?:\
不要な行を削除した状態。追加したい言語用のスクリプト1行だけが残る。
ファイル名を次のルールで変更しておく。
ここでつける [言語名] は後の設定で絡んできます。
# ファイル名のルール
[言語名].js
# e.g.
go.js
最初から同梱されていたスクリプトはこいつら。
どのファイルが何の言語なのかはファイル名から察せると思う。あと、言語ごとのスクリプトに加えて prism.js
や prism-options.js
など、Prism の本体(?)も入っている。
Luxeritas は、こんな風にスクリプトをバラバラにしておいて、シンタックスハイライターが表示された時、利用している言語、それと依存関係のある言語のスクリプトのみをロードすることで、高速化を図ってるみたい。
もし追加したい言語に依存する言語用スクリプトがこの中になければ、その言語用スクリプトも同様に配置し、このあとに触るが thk_highlighter_load
ファンクションの中で一緒ロードされるよう条件を加える必要が出てくる。
- apacheconf.js
- aspnet.js
- autohotkey.js
- bash.js
- basic.js
- batch.js
- c.js
- clike.js
- cpp.js
- csharp.js
- css.js
- diff.js
- git.js
- java.js
- javascript.js
- json.js
- markup.js
- nginx.js
- nim.js
- perl.js
- php.js
- plsql.js
- powershell.js
- prism-options.js
- prism.js
- python.js
- r.js
- ruby.js
- rust.js
- sass.js
- sql.js
- vbnet.js
- vim.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言語を追加
^^^^^^^^^^^^^^
"highlight_" + [言語名]
重要なのは key の名前で highlight_
に続く go
(言語名)の部分。
この go
の部分がプログラム内では $lang
として扱われ、先程配置した言語用スクリプトのファイル名("$lang"+".js")だったり、 変更箇所1でも言語を識別するための値として使われてるようです。
ちなみに value に設定する値はラベルとして使われてる様子。(シンタックスハイライター右上だったり、編集画面のシンタックスハイライターブロックで選択できる言語一覧だったり…)
# thk_highlighter_load
-> /[WPRoot]/wp-content/themes/luxeritas/inc/load-inline.php
# thk_syntax_highlighter_list
-> /[WPRoot]/wp-content/themes/luxeritas/inc/wpfunc.php
動作確認をする
編集画面のシンタックスハイライターブロックで、言語一覧から Go が選べるようになったし、ちゃんと色分けされてますね!
package main
import "fmt"
main() {
fmt.Println( "Hello World!" )
}
さいごに
といった感じで長くなりましたが、今回やりたかったことは達成できました。
んが、親テーマのディレクトリにスクリプトぶち込んだり、親テーマからファンクションパクって割り込み定義したりしてるので、親テーマのバージョンアップで動かねぐなるかも知んねぇです。。。
些細なことでリスクを背負い込むより、素直に作者さんに要望出したほうが面倒が少なくていいのかもね?_(:3」∠)_
というわけで、いじょ!٩( 'ω’ )و
ディスカッション
コメント一覧
まだ、コメントがありません