/* Encoding: UTF-8 */

if (typeof _gat != "undefined") {
	var pageTracker = _gat._getTracker("UA-1451311-3");
	pageTracker._trackPageview();
}

if (document.implementation) {
	/* DOMをサポートしているブラウザのみ */
	$(document).ready(function(){
		if (navigator.appName == "Microsoft Internet Explorer") {
			/* IE のみ */
			viewCiteAttrs();
			insertQuotes();
		}
		replaceAddress();
		highlightSourceCode();
	});
}

// 画像になっているメールアドレスをテキストに変換
function replaceAddress() {
	var mail = new Array("m", "o", "c", ".", "l", "i", "a", "m", "g", 
				"@", "w", "o", "l", "f", "x", "u", "l", "f", "e", "r").reverse().join("");
	$("img.address").replaceWith("<a href='mailto:" + mail + "'>" + mail + "</a>");
}


// cite属性値に基づいてblockquote要素に引用元を表示
function viewCiteAttrs() {
	$("blockquote").each(function() {
		if (this.cite) {
			var p = document.createElement("p");
			p.className = "info";
			p.style.textAlign = "right";
			p.appendChild(document.createTextNode(this.cite + " より"));
			this.appendChild(p);
		}
	});
}


// q要素に引用符を追加
function insertQuotes() {
	$("q").each(function() {
		this.insertBefore(document.createTextNode("“"), this.firstChild);
		this.appendChild(document.createTextNode("”"));
	});
}


// ソースコードのハイライト表示
function highlightSourceCode() {
	var javaKeywords = /\/\/[^\r\n]*|\/\*[\S\s]*?\*\/|"([^\\"]|\\.)*"|'([^\\']|\\.)*'|\b(abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|false|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|null|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|transient|true|try|void|volatile|while)\b/m;
	var jsKeywords = /\/\/[^\r\n]*|\/\*[\S\s]*?\*\/|"([^\\"]|\\.)*"|'([^\\']|\\.)*'|\b(abstract|boolean|break|byte|case|catch|char|class|const|continue|debugger|default|delete|do|double|else|enum|export|extends|final|finally|float|for|function|goto|if|implements|import|in|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|super|switch|synchronized|this|throw|throws|transient|try|typeof|var|void|volatile|while|with)\b/m;
	var phpKeywords = /(\/\/|#)[^\r\n]*|\/\*[\S\s]*?\*\/|"([^\\"]|\\.)*"|'([^\\']|\\.)*'|\<\?php|\?\>|\b(__CLASS__|__FILE__|__FUNCTION__|__LINE__|__METHOD__|abstract|and|array|as|break|case|catch|cfunction|class|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|eval|exception|exit|extends|extends|final|for|foreach|function|global|if|implements|include|include_once|interface|isset|list|new|old_function|or|php_user_filter|php_user_filter|print|private|protected|public|require|require_once|return|static|switch|this|throw|try|unset|use|var|while|xor)\b/m;
	var cppKeywords = /\/\/[^\r\n]*|\/\*[\S\s]*?\*\/|#[\s]*[\w]+|"([^\\"]|\\.)*"|'([^\\']|\\.)*'|\b(and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|class|compl|const|const_cast|continue|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|not|not_eq|operator|or|or_eq|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_cast|struct|switch|template|this|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq)\b/m;
	var csKeywords = /\/\/[^\r\n]*|\/\*[\S\s]*?\*\/|#[\s]*[\w]+|"([^\\"]|\\.)*"|'([^\\']|\\.)*'|\b(abstract|as|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|get|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|partial|private|protected|public|readonly|ref|return|sbyte|sealed|set|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|where|while|yield)\b/m;
	var rubyKeywords = /#[^\r\n]*|=begin[\S\s]*?=end|"([^\\"]|\\.)*"|'([^\\']|\\.)*'|\b(alias|and|begin|BEGIN|break|case|class|def|defined\?|do|else|elsif|END|end|ensure|false|for|if|in|module|next|nil|not|or|redo|rescue|retry|return|self|super|then|true|undef|unless|until|when|while|yield)\b/m;
	
	var getKeywordTypeJ = function(keyword) {
		switch(keyword.charAt(0)) {
			case "/":
			case "#": // RubyとPHP
			case "=": // Ruby
				return "comment";
			case "\"": case "'":
				return "string";
			default:
				return "keyword";
		}
	};
	var getKeywordTypeC = function(keyword) {
		switch(keyword.charAt(0)) {
			case "/":
				return "comment";
			case "\"": case "'":
				return "string";
			default:
				return "keyword";
		}
	};
	
	function Language(keywords, getKeywordType) {
		this.keywords = keywords;
		this.getKeywordType = getKeywordType;
	}
	Language.prototype.matches = function(node) {
		return this.keywords.exec(node.nodeValue);
	}
	
	var langList = {
		"java": new Language(javaKeywords, getKeywordTypeJ),
		"javascript": new Language(jsKeywords, getKeywordTypeJ),
		"php": new Language(phpKeywords, getKeywordTypeJ),
		"cpp": new Language(cppKeywords, getKeywordTypeC),
		"cs": new Language(csKeywords, getKeywordTypeC),
		"ruby": new Language(rubyKeywords, getKeywordTypeJ)
	}
	
	var lang = null;
	$("code, code *").each(function() {
		if (this.nodeName.toLowerCase() == "code") {
			lang = langList[this.className];
		}
		if (!lang) return;
		
		$(this).contents().filter(function() { return this.nodeType == 3 }).each(function() {
			var restTextNode = this;
			var match;
			while ((match = lang.matches(restTextNode)) != null) {
				var keywordTextNode = restTextNode.splitText(match.index);
				restTextNode = keywordTextNode.splitText(match[0].length);
				var span = document.createElement("span");
				span.className = lang.getKeywordType(match[0]);
				$(keywordTextNode).wrap(span);
			}
		});
	});
}

