iG:Syntax Hiliterでファイル名を出力する

09/05/11修正 - igSynHilite関数の正規表現にA-Z0-9を追加

ご質問頂いたのでついでにネタにしちゃいます。
iG:Syntax Hiliterでファイル名を出力させる方法です。wp-content/plugins/syntax_hilite.phpの四つの関数を跨いでいます。

igSynHilite

まずは、取得部分。204行目でnum=*の取得と同様にname=*を取得します。

// main function that calls the highlighter
function igSynHilite($inData) {
	$inData = preg_replace_callback('/¥[(¥w{1,})((?:¥s+num+=([0-9]{1,})+)*)((?:¥s+name+=([a-zA-Z0-9¥.¥-¥_]{1,})+)*)¥](.+?)¥[¥/¥1¥]/ims', 'igSynHilite_code', $inData);		// call code hiliter
	return $inData;
}
  1. // main function that calls the highlighter
  2. function igSynHilite($inData) {
  3.     $inData = preg_replace_callback('/¥[(¥w{1,})((?:¥s+num+=([0-9]{1,})+)*)((?:¥s+name+=([a-zA-Z0-9¥.¥-¥_]{1,})+)*)¥](.+?)¥[¥/¥1¥]/ims', 'igSynHilite_code', $inData);      // call code hiliter
  4.     return $inData;
  5. }

igSynHilite_code

igSynHiliteのコールバック。187行目でファイル名を配列から抜き出し、197行目でdoHiliteに第四引数として渡す。

//Hilite CODE
function igSynHilite_code($hCode) {
	global $igsh,$tOffAutoFmt;
	$startTag = strtolower(trim($hCode[1]));
	$inTxt = $hCode[6];
	$pVal = (int) $hCode[3];				// get the starting line number
	$filename = $hCode[5];					// get filename
	$hilitedCode = "";
	if(!empty($startTag)) {
		if(strlen($inTxt)>1) {
			$tOffAutoFmt = 1;							// if code is there, disable auto formatting
		}
		$arrSearch = array("< ", "< ", " >", " >", "< ", "< ", " >", " >");
		$arrReplace = array("<", "<", ">", ">", "<", "<", ">", ">");
		$inTxt = str_replace($arrSearch, $arrReplace, $inTxt);
		$pVal = ((empty($pVal)) || ($pVal<1)) ? 1 : $pVal;
		$hilitedCode = $igsh->doHilite($inTxt, $startTag, $pVal, $filename);
	}
	return $hilitedCode;
}
  1. //Hilite CODE
  2. function igSynHilite_code($hCode) {
  3.     global $igsh,$tOffAutoFmt;
  4.     $startTag = strtolower(trim($hCode[1]));
  5.     $inTxt = $hCode[6];
  6.     $pVal = (int) $hCode[3];                // get the starting line number
  7.     $filename = $hCode[5];                  // get filename
  8.     $hilitedCode = "";
  9.     if(!empty($startTag)) {
  10.         if(strlen($inTxt)>1) {
  11.             $tOffAutoFmt = 1;                           // if code is there, disable auto formatting
  12.         }
  13.         $arrSearch = array("< ", "&lt; ", " >", " &gt;", "<&nbsp;", "&lt;&nbsp;", "&nbsp;>", "&nbsp;&gt;");
  14.         $arrReplace = array("<", "&lt;", ">", "&gt;", "<", "&lt;", ">", "&gt;");
  15.         $inTxt = str_replace($arrSearch, $arrReplace, $inTxt);
  16.         $pVal = ((empty($pVal)) || ($pVal<1)) ? 1 : $pVal;
  17.         $hilitedCode = $igsh->doHilite($inTxt, $startTag, $pVal, $filename);
  18.     }
  19.     return $hilitedCode;
  20. }

doHilite

第四引数でファイル名を受け取って、pFixに渡してあげるだけ。

function doHilite($mTxt, $mType='html', $sNum=1, $filename) {
  1. function doHilite($mTxt, $mType='html', $sNum=1, $filename) {

$hCode = $this->pFix($mTypeShow, $filename, $mType.'-'.$cbId).$hCode.$this->sFix();
  1. $hCode = $this->pFix($mTypeShow, $filename, $mType.'-'.$cbId).$hCode.$this->sFix();

pFix

ヘッダのHTMLを整形している関数pFixの第二引数としてファイル名が渡ってくるので、お好みに合わせて出力して下さい。
syntax_hilite.phpを触った当初の目的がヘッダのHTMLをリストで出力することだったので、この例だと全面的に変更してあります。この辺りは好みの問題だと思うんで、デフォルト通りspanに$filenameを出力してもいいかもしれません。

function pFix($hLang='PHP', $filename, $bId, $bCls='syntax_hilite') {
	$bBody = "";
	$bId = strtolower($bId);

	if(IG_PLAIN_TEXT_TYPE=="inbox") {
		$ig_jsPlainTxt = "showPlainTxt";
	} else {
		$ig_jsPlainTxt = "showCodeTxt";
	}
	$bBody .= "¥t
    "; $bBody .= "¥t¥t
  • {$hLang}
  • "; $bBody .= "¥t¥t
  • {$filename}
  • "; $bBody .= "¥t
  • Source
  • "; $bBody .= "
"; $bBody .= "
¥n"; $bBody .= "
¥n"; return $bBody; }
  1. function pFix($hLang='PHP', $filename, $bId, $bCls='syntax_hilite') {
  2.     $bBody = "";
  3.     $bId = strtolower($bId);
  4.  
  5.     if(IG_PLAIN_TEXT_TYPE=="inbox") {
  6.         $ig_jsPlainTxt = "showPlainTxt";
  7.     } else {
  8.         $ig_jsPlainTxt = "showCodeTxt";
  9.     }
  10.     $bBody .= "¥t<ul class=¥"syntax_hilite_header¥">";
  11.     $bBody .= "¥t¥t<li class=¥"language¥">{$hLang}</li>";
  12.     $bBody .= "¥t¥t<li class=¥"filename¥">{$filename}</li>";
  13.     $bBody .= "¥t<li class=¥"source¥"><a href=¥"#¥" onclick=¥"javascript:{$ig_jsPlainTxt}('{$bId}'); return false;¥">Source</a></li>";
  14.     $bBody .= "</ul>";
  15.     $bBody .= "<div class=¥"{$bCls}¥">¥n";
  16.     $bBody .= "<div id=¥"{$bId}¥">¥n";
  17.  
  18.     return $bBody;
  19. }

問題点

igSynHiliteで使った正規表現上、行数とファイル名の両方を出力する場合、[php name=* num=*]の順だと正しく動きません。
[php num=* name=*]の順か、単体の[php name=*][php num=*]でお使い下さい。
こう書けば逆順でも動くよってコードあったら教えて下さい。

syntax_hilite.php.zip


About this entry