こんにちは。たまにはアップデート以外の記事も書きたいので。
前々から思っていたのですが、このブログではPHPとかJavaScriptのソースを提示することがままあります。現状、モノクロの味気ないソースコードだったので、PHPマニュアルのユーザーノート にあるようなカラフルな色付けにしたいなと思っていたわけです。この手のことを実現するには大きく2通りのアプローチがあって、サーバー側でハイライト表示の処理をして読み込ませる方法と、もうひとつはクライアント側のJavaScriptに解析させてその場でハイライト表示させる方法です。前者の例だと、PHPライブラリではGeSHi - Generic Syntax Highlighter などがあり、後者だとグーグルのgoogle-code-prettify が有名でしょうか。
でも、この手のやつって、これようのCSSファイルも用意しないといけないし、ファイルサイズはでかいし、設置が面倒そうだなと。なので書いてみました。基本的に、自分用なのでPHPとJavaScriptの一部の関数しかサポートしていませんが、まぁ、要は見栄えを良くすることが目的なので、すべてを網羅する必要はないと考えてます。PHPの組み込み関数なんて山ほどありますし。おかげで随分とサイズが小さいスクリプトになりましたが、それっぽく見えます。
特徴としては、このスクリプト単体で動作可能ということです。他の見栄えのためのCSSファイルとかは必要ないです。記事の中のPREタグを見つけたら、その中身をハイライト表示します。初めは、PREタグに特定のクラス名を付けて、それを認識させようかと思っていましたが、そうすると過去の記事の書き換えをしないといけないし、どうせPREタグに書くのはソースコードぐらいだろうと割り切り、PREタグに絞りました。早速ですが、そのソースコードをこのスクリプトを使って表示してみます。
/*
Lightweight syntax-analyzing script
Copyright: modified BSD license 2008 martin
version: 20080803.204553
*/
function pettieSyntax(){
var cssprops = ['#c03', '#003366', '#636', /((?:[^{;_<]{2,}|[abipq*]))¥s*?¥{(¥s*[^}=_[¥]?<>]+?)¥}/ig];
var etcetera = ['#c33', /( > | < )/g];
var operants = ['green', /(¥/¥/¥-¥->|¥+¥+|¥-¥-|!?===?|<=|>=|=>|¥+=|¥-=|!=|&&|¥|¥|| = )/g];
var variants = ['#669', /(¥$¥w+?¥b|var¥b¥w+¥b|@)/g];
var htmltags = ['navy', /(<¥/¥w+?>|<¥w+|<¥?(?:xml|php)|(?:¥?|¥/)>|>)/g];
var keywords = ['blue', /(¥b(?:alert|[Aa]rray|break|case|catch|class|charset|continue|Date|default|define|delete|do|else|false|FALSE|for|function|global|i[fn]|instanceof|new|null|Object|return|script|src|type|switch|this|throw|document¥S|TRUE|true|echo|try|typeof|var|void|while|window¥S|with|Location|version|encoding)¥b)/g];
var decimals = ['#c69', /([¥s:¥/¥(,[+;."=>])(¥-?¥d+(?:¥.¥d+)?)(%|px|pt|em)?/g];
var equipped = ['#036', /([¥.¥s(@>])([^'"¥(¥n=¥s<>¥/]+?)([¥( ])/g];
var oneliner = ['#906', /('[^'¥r¥n]+?'|"[^"]*?"|<![^¥r¥n]+?¥-¥-.*?>)/g];
var regulars = ['tomato', /([¥s(])(¥/[^¥r¥n]+?¥/)([igmy¥s¥);.])/g];
var enoparts = ['indigo', /(¥b(?:o|oParts)¥b|¥.(?:away|moveTo|sizeTo|dimension|target)¥(¥)|¥.(?:loadScript|evt|metrics|start|css|view|each|sib))/g];
var comments = ['#093', /([^:]|)((?:¥/¥/|#)¥s+[^'¥r¥n]+(?:¥r?¥n?|$)|¥/¥*[¥s¥S]+?¥*¥/)/g];
var omitspan = function(m){ return m.replace(/<span[^>]*?>/ig, '').replace(/<¥/span>/ig, '');}
var targets = document.getElementsByTagName('PRE');
if(targets){
for(var t, i = 0; t = targets[i++];){
var c = t.innerHTML.replace(/<(?:span|code)[^>]*?>([^<]+?)<¥/(?:span|code)>/ig, '$1').replace(/¥t/g, '').replace(/'/g, ''').replace(/"/g, '"');
if(/<(?:a |img )/i.test(c)) continue;
c = c.replace(cssprops[3], function(A, B, C){ return /:/.test(C) ? '<span style=¥tcolor:'+cssprops[0]+'¥t>'+B+'</span>' + A.replace(B, '').replace(/([^:{]+?):([^;]+?);/g, '<span style=¥tcolor:'+cssprops[1]+'¥t>$1</span>:<span style=¥tcolor:'+cssprops[2]+'¥t>$2</span>;') : A;});
c = c.replace(etcetera[1], '<span style=¥tcolor:'+etcetera[0]+'¥t>$1</span>');
c = c.replace(operants[1], '<span style=¥tcolor:'+operants[0]+'¥t>$1</span>');
c = c.replace(variants[1], '<span style=¥tcolor:'+variants[0]+'¥t>$1</span>');
c = c.replace(htmltags[1], '<span style=¥tcolor:'+htmltags[0]+'¥t>$1</span>');
c = c.replace(keywords[1], '<span style=¥tcolor:'+keywords[0]+';font-weight:bold¥t>$1</span>');
c = c.replace(equipped[1], function (A, B, C, D){return B + '<span style=¥tcolor:'+equipped[0]+'¥t>' + C + '</span>' + D;});
c = c.replace(enoparts[1], '<span style=¥tcolor:'+enoparts[0]+';font-weight:bold;¥t>$1</span>');
c = c.replace(decimals[1], '$1<span style=¥tcolor:'+decimals[0]+'¥t>$2$3</span>');
c = c.replace(regulars[1], function (A, B, C, D){return B + '<span style=¥tcolor:'+regulars[0]+'¥t>' + omitspan(C) + '</span>' + D;});
c = c.replace(oneliner[1], function (A, B){return '<span style=¥tcolor:'+oneliner[0]+'¥t>' + omitspan(B) + '</span>';});
c = c.replace(comments[1], function (A, B, C){return B + '<span style="color:'+comments[0]+'">' + omitspan(C) + '</span>';});
c = c.replace(/¥t/g, '"');
if(/*@cc_on!@*/false){
t.outerHTML = '¥n<pre>' + c + '</pre>¥n'; /* IEの改行対策です */
} else t.innerHTML = c;
};
}
};
ファイルサイズは2キロ前後と小さいです。ppBlogで使うのであれば、とりあえずこのファイルをjsディレクトリにアップロードして、後は、lib.jsの最初の方で、このスクリプトを以下のように呼び出します。
oParts.loadScript('js/syntax.js');
次に同じlib.jsの下の方にある、oParts.start関数内で、このpettieSyntax()を呼び出せばOKです。
if(typeof pettieSyntax != UD) pettieSyntax();
コードを見れば分かりますが、ハイライトの色はSPANタグ内でスタイルシート指定してますので、この部分を好きな色に変えれば良いです。あと、強調したいキーワードを追加したいときも、ソース内の該当箇所に追加していけばよいです。
ppBlog使用前提なら、上のような設置になりますが、純粋に単体で動かしたい場合は、外部スクリプトとして、
<script type="text/javascript" src="path/to/syntax.js"></script>
みたく読み込ませて、ページ読み込み完了後にpettieSyntax()を呼べば良いです。
まだろくに動作検証していないのですが、興味がある方はどうぞ。syntax.jsと、あと、ppBlogの設置例としてlib.jsを添付しておきます。
JavaScript
Comments