DokuWiki時代にお世話になったソースコードをハイライトしてくれるPHPライブラリのGeSHiで遊んでみる。
GeSHi - Generic Syntax Highlighter
"php -s"をGeSHiを使ったスクリプトに置き換えてみたり、Smarty修飾子プラグイン書いてみたり、MTプラグイン作りを狙ってみたりと、うだうだやりつつたどり着いたのがCLI。
~% geshi -l php -f input.php -o output.php ~% echo 'echo "hoge\n";' | geshi -l php
イメージは↑な感じね。
で、ちょこちょこ書いて(一応)動くものは書けた。書けたけど、まあ暇つぶし以外の何者でもない。ので、いい加減。意味無し。
書いた後で、同梱されてんじゃね?とちょっと見てみれば、"contrib/aliased.php"とかいうブラウザ経由のViewerらしきものを発見。そもそも、GeSHiのサイトにあるDemoで事足りるような気もする。
コマンドとして運用するにはライブラリの置き場所に困ったり。言語ファイルもgeshi/にあるものとして書いちゃったし。まあ、いいんです。自分用だし。
そんなわけで、(一応)続きにコード晒し。普通に*nixなコマンドがあればそっち使いたい。。。
#!/usr/bin/env php <?php /** * This command is GeSHi CLI * * @require PHP5 * @require GeSHi <http://qbnz.com/highlighter/> * */ define("VERSION", "0.0.2"); // this module must be under the include_path // <include_path>/geshi.php // <include_path>/geshi/<language>.php if (!is_installed_geshi_lib()) { echo "Not found GeSHi library.\n"; echo " GeSHi library must be under <include_path>. include_path/ geshi.php geshi/ some language files... Download from <http://qbnz.com/highlighter/> "; exit(1); } require_once("geshi.php"); // usage define("USAGE", "Usage: geshi -v geshi -h geshi -e geshi -l <language> -f <input file> [-o <output file>] STDIN | geshi -l <language> [-o <output file>] -v Echo version -h Echo usage and some informations -e Echo elisp -l <language> Set code language -f <file> Set input file -o <file> Set output file Supportted languages: " . implode(", ", get_languages()) . "\n"); // parse options $options = getopt('vhel:f:o:'); // only version echo if (isset($options["v"])) { echo "Version: " . VERSION . "\n"; exit(0); } // only echo help(usage) if (isset($options["h"])) { echo USAGE; exit(0); } // only elisp echo if (isset($options["e"])) { $languageAlist = '("' . implode('") ("', get_languages()) . '")'; echo <<<DOC ;;; ;;; リージョン内のスクリプトをHTML形式でハイライト表示 (defun geshi-region nil "Source code highlight" (interactive) (let ( (geshi-language-alist '( $languageAlist ) ) (completion-ignore-case t)) (setq geshi-language (completing-read "言語: " geshi-language-alist nil t)) (shell-command-on-region (region-beginning) (region-end) (concat "geshi -l " geshi-language)) (switch-to-buffer "*Shell Command Output*")) ) (global-set-key (kbd "C-c g") 'geshi-region) DOC; echo "\n"; exit(0); } // initialization $source = ""; $language = ""; $outputFilePath = ""; // check language if (isset($options["l"])) { if (validLanguage($options["l"])) { $language = $options["l"]; } else { echo "Failed: Not supported such language.\n\n"; echo USAGE; exit(1); } } else { echo "Failed: Input code language.\n\n"; echo USAGE; exit(1); } // check input file if (isset($options["f"])) { $inputFilePath = $options["f"]; // check file if (file_exists($inputFilePath) and is_readable($inputFilePath)) { $source = file_get_contents($inputFilePath); } else { echo "Failed: No such file or permission denied.\n\n"; echo USAGE; exit(1); } } else { // check STDIN if (($source = get_stdin()) == "") { echo "Failed: Cannot get input data from STDIN.\n\n"; echo USAGE; exit(1); } } // source highlight $geshi = new GeSHi($source, $language); $hilighted = $geshi->parse_code(); // check output file path if (isset($options["o"])) { $path = $options["o"]; if (is_make_file($path)) { file_put_contents($path, $hilighted); } else { echo "Failed: Is output file path valid?\n\n"; echo USAGE; exit(1); } } else { echo $hilighted; } /** * Get STDIN data * * @return String */ function get_stdin($timeout = 1) { $stat = fstat(STDIN); $input = ""; if ($stat["size"] > 0) { $input = fread(STDIN, $stat["size"]); } return $input; } /** * Validation language type * * @return Boolean */ function validLanguage($language) { $searchPathList = explode(PATH_SEPARATOR, ini_get("include_path")); foreach ($searchPathList as $dir) { $path = rtrim($dir, DIRECTORY_SEPARATOR) . "/geshi/" . $language . ".php"; if (file_exists($path)) { return true; } } return false; } /** * test make file * * @return Boolean */ function is_make_file($path) { if ((file_exists($path) and is_writable($path)) or (!file_exists($path) and is_writable(dirname($path)))) { return true; } else { return false; } } /** * get supported languages * * @return Array */ function get_languages() { $searchPathList = explode(PATH_SEPARATOR, ini_get("include_path")); $languages = array(); foreach ($searchPathList as $dir) { $path = rtrim($dir, DIRECTORY_SEPARATOR) . "/geshi/"; if (file_exists($path) and is_dir($path)) { $files = scandir($path); foreach ($files as $file) { if (preg_match("/(.+)\.php$/", $file, $matchs)) { $languages[] = $matchs[1]; } } } } return $languages; } /** * check GeSHi installed * * @return Boolean */ function is_installed_geshi_lib() { $searchPathList = explode(PATH_SEPARATOR, ini_get("include_path")); foreach ($searchPathList as $dir) { if (file_exists($dir . "/geshi.php") and is_readable($dir . "/geshi.php") and file_exists($dir . "/geshi/") and is_dir($dir . "/geshi/")) { return true; } } return false; } ?>

