pukiwiki/texthighlight.inc.php の履歴(No.3)
更新pukiwiki 上でソースコードをカラー表示するためのプラグイン†
http://shjs.sourceforge.net/index.html にある SHJS という ライブラリを使って JavaScript で色を付けることができます。
pukiwiki 文法ではソースコードなどを記述するには文頭に空白を 置きます。
たとえば、こんな感じですね。
printf("Hello, world!\n");
このプラグインを入れて、ソースコードブロックの一行目に、" LANG:C++" と書くと、
LANG:C++
printf("Hello, world!\n");
となります。
また、" LANG:C++(linenumber)" とすると、左側に行番号を付ける事もできます。
行番号を付けた場合にも、ソースコード部分のみを選択&コピーできるようになっています。
LANG:C++(linenumber)
printf("Hello, world!\n");
printf("Hello, world!\n");
printf("Hello, world!\n");
下記の php ソースであれば " LANG:php" と書いてあります。
SHJS は C++, php の他にも、下記の多くの言語に対応していて、 この機能を pukiwiki 上でそのまま使う事ができます。
| Bison | Java properties files | PHP |
| C | JavaScript | Prolog |
| C++ | JavaScript with DOM | Python |
| C# | LaTeX | RPM spec files |
| ChangeLog | LDAP files | Ruby |
| CSS | Log files | S-Lang |
| Desktop files | LSM (Linux Software Map) files | Scala |
| Diff | M4 | Shell |
| Flex | Makefile | SQL |
| GLSL | Objective Caml | Standard ML |
| Haxe | Oracle SQL | Tcl |
| HTML | Pascal | XML |
| Java | Perl | Xorg configuration files |
あるいは、文法ファイルを頑張って手で書けば、 その他の言語にも割と簡単に対応させることができます。
役に立ちそうだったらご利用ください。
ソースコード†
LANG:php(linenumber)
<?php
/*
* シンタックスハイライトプラグイン - texthighlight 2.0
*
* プログラムコードなどをシンタックスハイライト (+行番号付け) して
* 表示するプラグイン。内部で shjs というライブラリを使っています。
*
* by Osamu TAKEUCHI <osamu@big.jp> http://dora.bk.tsukuba.ac.jp/~takeuchi/
*
* 利用・配布・改変は自由に行ってください。
* ただし、結果について作者は保証しません。
* 各自の責任で行うようにしてください。
*
*
* 使い方:
*
* インストールはまず pukiwiki の plugin フォルダに texthighlight.inc.php
* を放り込む。
*
* http://shjs.sourceforge.net/index.html から shjs を落としてきて、
* pukiwiki フォルダの直下(plugin フォルダと同じ階層)に shjs という
* 名前のフォルダを掘ってそこに展開する。
*
* このプログラムは実際にはプラグインではなくフィルタのようなものなので、
* plugin フォルダに入れるだけでは動かない。
*
* スキンファイル (skin/pukiwiki.skin.php など) を以下の要領で変更する。
*
* return $body; となっている部分を return texthighlight($body); とする。
* その直前に require_once("plugin/texthighlight.inc.php"); も必要。
*
* ヘッダ部分で shjs ライブラリへのリンクを張る
* <link rel="stylesheet" type="text/css" href="shjs/css/sh_ide-eclipse.css" />
* <script type="text/javascript" src="shjs/sh_main.js"></script>
*
* body onLoad で shjs を呼び出す
* <body onLoad="sh_highlightDocument('shjs/lang/', '.js');">
*
*/
function texthighlight($body)
{
// 本当は以下のように preg_replace_callback 一発で終わらせたいの
// だけれども、これだと $body が長くなるとうまくいかないのでちまちまと
// return preg_replace_callback(
// "#<pre>(?:LANG(?:UAGE)?:".
// "([a-zA-Z0-9\#\+\-]+)(\(([^\)]*)\))?\n)?((\n|.)*?)</pre>#",
// 'do_texthighlight',
// $body);
$newbody= "";
while( trye ){
$pos= stripos( $body, "<pre>LANG" );
if($pos===FALSE)
break;
$newbody.= substr($body, 0, $pos);
$body= substr($body, $pos);
$end= stripos( $body, "</pre>" );
$pre= substr($body, 0, $end);
$body= substr($body, $end+6);
if( preg_match("#<pre>\s*(?:LANG(?:UAGE)?:".
"([a-zA-Z0-9\#\+\-]+)(\(([^\)]*)\))?\s*\n)?#",
$pre, $matches) ) {
$newbody.= do_texthighlight($matches, substr($pre, strlen($matches[0])));
}else{
$newbody.= $pre;
}
}
return $newbody . $body;
}
function do_texthighlight($matches, $source)
{
$language= strtolower($matches[1]);
$args= $matches[3] ? split(",", $matches[3]) : array();
$source= html_entity_decode($source);
// 別名に対応
if($language == "c#") $language= "csharp";
if($language == "c++") $language= "cpp";
if($language == "s-lang") $language= "slang";
if( in_array("linenumber", $args) ){
// 行番号付け
$n= count(split("\n", $source));
$numbers= "";
for($line=1; $line<=$n; $line++)
$numbers .= sprintf("%d:\n", $line);
return '<table class="sh_linenumber"><tr><td><pre class="sh_linenumber">' .
$numbers . '</pre></td><td><pre class="sh_' . $language . '">' .
htmlspecialchars($source) . '</pre></td></tr></table>';
}else
if( $language ){
// 横幅を制限するために table に入れている。
return '<table class="sh_bound"><tr><td><pre class="sh_' . $language . '">' .
htmlspecialchars($source) . '</pre></td></tr></table>';
}else{
// 横幅を制限するために table に入れている。
return '<table class="sh_bound"><tr><td><pre>' .
htmlspecialchars($source) . '</pre></td></tr></table>';
}
}
?>
スタイルシート(pukiwiki.css.php など) の末尾に追加する内容:
LANG:CSS(linenumber)
/* texthighlight.inc.php 関連 */
pre {
background-color:#f0f0ff !important;
border: 1px #66e dashed;
overflow:auto;
margin:0px;
padding:.5em;
}
table.sh_bound {
min-width:40em;
margin:0px;
margin-right:2em;
margin-left:0.5em;
}
pre.sh_console {
background-color:black !important;
color:white;
border: 0px;
}
table.sh_linenumber tr td {
margin:0px;
padding:0px;
border:0px;
background-color:#f0f0ff;
}
table.sh_linenumber tr {
margin:0px;
padding:0px;
border:0px;
}
pre.sh_linenumber {
color:grey;
text-align:right;
}
table.sh_linenumber tr td pre {
border:0px;
margin:0px;
padding:.5em;
}
table.sh_linenumber {
background-color:#f0f0ff;
border: 1px #66e dashed;
margin:0px;
margin-right:2em;
margin-left:0.5em;
}
Verilog 用の言語ファイル†
sh_verilog.js
LANG:javascript
if (! this.sh_languages) {
this.sh_languages = {};
}
sh_languages['verilog'] = [
[
[ /\/\/[ \t]*synthesis[ \t]+attribute[ \t]/gi, 'sh_preproc', 5 ],
[ /^[ \t]*`\w/gi, 'sh_preproc', 5 ],
[ /#(?:\d+|\d*'b[01xXzZ]+|\d*'h[0-9a-fA-FxXzZ]+|\d*'d[\dxXzZ]+)\b/gi, 'sh_preproc', -1 ],
[ /\/\//g, 'sh_comment', 1 ],
[ /\/\*/g, 'sh_comment', 2 ],
[ /\(\*/g, 'sh_preproc', 4 ],
[ /\b(?:\d+|\d*'b[01xXzZ]+|\d*'h[0-9a-fA-FxXzZ]+|\d*'d[\dxXzZ]+)\b/g, 'sh_number', -1],
[ /"/g, 'sh_string', 3 ],
[ /(?:\.|\$)\w+\s*(?=\()/g, 'sh_function', -1 ],
[ /\b(?:shortint|int|longint|byte|bit|logic|reg|integer|time|signed|unsigned|real|shortreal|void|candle|event|string)\b/g, 'sh_type', -1 ],
[ /\b(?:always|end|ifnone|or|rpmos|tranif1|and|endcase|initial|output|rtran|tri|assign|endmodule|inout|parameter|rtr|nif0|tri0|begin|endfunction|input|pmos|rtranif1|tri1|buf|endprimitive|integer|posedge|scalared|triand|bufif0|endspecify|join|primitive|small|trior|bufif1|endtable|large|pull0|specify|trireg|case|endtask|macromodule|pull1|specparam|vectored|casex|event|medium|pullup|strong0|wait|casez|for|module|pulldown|strong1|wand|cmos|force|nand|rcmos|supply0|weak0|deass|gn|forever|negedge|real|supply1|weak1|default|for|nmos|realtime|table|while|defparam|function|nor|reg|task|wire|disable|highz0|not|release|time|wor|edge|highz1|notif0|repeat|tran|xnor|else|if|notif1|rnmos|tranif0|xor)\b/g, 'sh_keyword', -1 ],
[ /\b(?:generate|endgenerate|genvar|typedef|class|enum|union|struct|localparam|export|import|context|fork)\b/g, 'sh_keyword', -1 ],
[ /~|!|%|\^|\*|\(|\)|-|\+|=|\[|\]|\\|:|;|,|\.|\/|\?|&|<|>|\|/g, 'sh_symbol', -1 ],
],
[ // 1
[ /$/g, null, -2 ],
[ /(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,
'sh_url', -1 ],
],
[ // 2
[ /\*\//g, null, -2 ],
[ /(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,
'sh_url', -1 ],
],
[ // 3
[ /\\"|\\\\/g, null, -1 ],
[ /"/g, 'sh_string', -2 ]
],
[ // 4
[ /\*\)/g, 'sh_preproc', -2 ],
],
[ // 5
[ /$/g, 'sh_preproc', -2 ],
],
];
手書きで適当に書いたので不具合もありそうなのですが。
コメント†
Counter: 14502 (from 2010/06/03),
today: 1,
yesterday: 3