これもWordpressでSyntaxHighlighterをインストールすると以下のように簡略化して入力できる。
[cpp]
ソース
これを
<pre class="brush:xxx">ソース</pre>
に変換するスクリプト。
調べたら「wordpress/wp-content/plugins/syntax_highlighter.php」で処理しているようだ。
てな訳で、同じ仕様で自作してみることに。
function syntax_highlight_header() {
$syntaxHighlighter = SyntaxHighlighter::getInstance();
$syntaxHighlighter->showHeader();
}
function syntax_highlight_decode($body) {
if ($body) {
$syntaxHighlighter = SyntaxHighlighter::getInstance();
$syntaxHighlighter->convertContent($body);
}
}
class SyntaxHighlighter {
var $types = array(
'as3' => array('brush' =>'AS3'),
'bash' => array('brush' => 'Bash'),
'cpp' => array('brush' => 'Cpp'),
'csharp' => array('brush' => 'CSharp'),
'css' => array('brush' => 'Css'),
'delphi' => array('brush' => 'Delphi'),
'coldfusion' => array('brush' => 'ColdFusion'),
'java' => array('brush' => 'Java'),
'javafx' => array('brush' => 'JavaFX'),
'jscript' => array('brush' => 'JScript'),
'diff' => array('brush' => 'Diff'),
'erlang' => array('brush' => 'Erlang'),
'groovy' => array('brush' => 'Groovy'),
'perl' => array('brush' => 'Perl'),
'php' => array('brush' => 'Php'),
'plain' => array('brush' => 'Plain'),
'powershell' => array('brush' => 'PowerShell'),
'python' => array('brush' => 'Python'),
'ruby' => array('brush' => 'Ruby'),
'shell' => array('brush' => 'Sass'),
'scala' => array('brush' => 'Scala'),
'sql' => array('brush' => 'Sql'),
'vb' => array('brush' => 'vb'),
'xhtml' => array('brush' => 'Xml'),
);
private static $instance = null;
public static function getInstance() {
if (SyntaxHighlighter::$instance == null) {
SyntaxHighlighter::$instance = new SyntaxHighlighter();
}
return SyntaxHighlighter::$instance;
}
public function showHeader() {
$tags[] = $this->javascript_tag('dp.SyntaxHighlighter/src/shCore');
if (is_array($this->types)) {
foreach ($this->types as $key => $value) {
$tags[] = $this->javascript_tag("dp.SyntaxHighlighter/scripts/shBrush{$value['brush']}");
}
}
$tag = implode("\n", $tags);
echo($tag);
}
public function convertContent($body) {
$bodys = explode("\n", $body);
if (is_array($bodys)) {
$isCode = false;
foreach($bodys as $key => $line) {
$start_code = $this->syntaxHighliterCode($line);
if ($start_code) {
$code = $start_code;
$tag.= "&ltpre class=\"brush:{$code}\">\n";
} else {
if ($code) {
if ($this->isSyntaxHighliterEndTag($line, $code)) {
$tag.= "</pre>\n";
$code = null;
} else {
$tag.= "{$line}\n";
}
} else {
$line = html_entity_decode(strip_tags($line), ENT_QUOTES, mb_internal_encoding());
$line = "{$line}\n";
$line = nl2br($line);
$tag.= $line;
}
}
}
}
echo($tag);
}
private function syntaxHighliterCode($value) {
$pattern = '/^\[[a-zA-Z0-9]+\]/';
if (preg_match($pattern, $value, $matchs)) {
$code = substr($matchs[0], 1, strlen($matchs[0]) - 2);
$code = strtolower($code);
if ($this->types[$code]) {
return $code;
}
}
}
private function isSyntaxHighliterEndTag($value, $target) {
$pattern = '/^\[\/[a-zA-Z0-9]+\]/';
if (preg_match($pattern, $value, $matchs)) {
$code = substr($matchs[0], 2, strlen($matchs[0]) - 3);
$code = strtolower($code);
return ($target == $code);
}
}
private function javascript_tag($name) {
if (is_string($name) && !empty($name)) {
return "&ltscript type=\"text/javascript\" src=\"{$GLOBALS['controller']->relative_base}javascripts/{$name}.js\">\n";
}
}
}
htmlヘッダーでsyntax_highlight_header()を呼んで、ブログの本文syntax_highlight_decode($text)で変換してやります。
あとDBに保存するときは、htmlentitiesでエスケープしました。
htmlentities(本文, ENT_QUOTES, mb_internal_encoding());
即席でバグバグだと思うけど、とりあえずコンバートできました。 正規表現でパースする部分が美しくないし、singlton使う意味がないかも・・・