SyntaxHighlighterをショートカットで表示

2010/07/22

これも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使う意味がないかも・・・
フォーム有効期限切れで Page Expired をリダイレクト
ログを日付でローテーションやクリアや削除
Homebrew で PHP8.0 から PHP7.4 にダウングレード
Big sur で zsh 移行と Homebrew アップグレード
Mac に minikube をインストール
途中から .gitignore に追加する
Larevel 6.x から Laravel 8.x にバージョンアップ
Composer で Allowed memory size (メモリ不足)エラー
Blade でカスタムクラスを利用する
git push git pull にブランチ指定せずに実行する
git pull や git push できなくなったとき
Docker のコンテナからホストOS に接続
Mac で ローカル IP アドレス(ipv4)のみを表示する
ホストOS から Docker の MySQLコンテナに接続
caching_sha2_password のエラー
node-config で環境設定ファイルを利用する
rootパスワードを初期化(再設定)する
Git から clone したときのエラー対処
Mac に MySQL をインストール
Mac に PostgreSQL をインストール
Laravel 環境構築 - Mac ネイティブ編
Firebase 入門 - Firebase とは
Firebase 入門 - CLI インストールとデータベースの設定
AWS 無料枠(t2.micro)で容量とメモリエラー
Cloud9 を起動する -初心者編-
gcloud で GCEインスタンスを起動してみる
AWS CLI と jq でインスタンス一覧を整形して表示
React と Laravel7 のプロジェクトを作成する
Homebrewインストール-2020年版
3直線で囲まれた範囲塗りつぶし
PuLP で線形最適化問題を解く
カスタムのペジネーションを作る
node-sass を使って sass をコンパイルする
Log ファサードでSQLログを分離して書き出す
いちから始める Docker - 複数のコンテナを使う - (2020年)
いちから始める Docker - docker-compose を使う - (2020年)
AWS ECR を使ってみる
Laravel7 でマルチ認証
Mac に AWS Client を設定する
Laravel7 リリース
v-html でHTML表示する
Laravel で Nuxt.js を使ってみる(Docker環境)
Laravel で Vue コンポーネントを使う
いちから始める Docker -コンテナをビルド- (2020年)
いちから始める Docker -起動してみる- (2020年)
Mac で MySQL(8系)
composer で vendor がインストールできない
Eloquent の日付を Carbon で扱う
webpack 4 入門(npm編)
[Mac]容量を減らす