ソフトウェア/pukiwiki/tchart.inc.php の履歴(No.4)

更新


公開メモ

pukiwiki でタイミング図を書きたい

デジタル信号処理の記事を書くのに、

&tchart( clock _~_~_~_~_~_~_~_~_~_~_ data =====X=DATA========X===== valid ~~~~~~~~~~_ ready ________[~~]_ );

こういったタイミング図を書きたくて、 プラグインにしてみました。

XSS 対策が必要ですね・・・

現在のコードは XSS 攻撃に対して脆弱なので、気をつけて下さい。

tchart

非常に便利なツールを熊谷正朗さんが公開しておられます。

このツールを使うと、

clock	_~_~_~_~_~_~_~_~_~_~_
data	=====X=DATA========X=====
valid	_____~~~~~~~~~~______
ready	_____________[~~]______

こんな風にテキストで書いたタイミング図を、

&tchart( clock _~_~_~_~_~_~_~_~_~_~_ data =====X=DATA========X===== valid ~~~~~~~~~~_ ready ________[~~]_ );

このように画像化できます。

このツールの出力はポストスクリプトになるため、 そのままだとホームページ上に表示できません。

そこで、svg を出力する tchart のようなものを作成しました。

こちらで紹介しています。ソフトウェア/tchart.rb

pukiwiki.php の変更

標準ではプラグインに渡す引数に改行文字を入れられないので、 tchart プラグインに限って改行入りの引数を渡せるように変更します。

具体的には、改行文字を <br> という文字に変更しておき、 プラグイン側で改行文字に復元します。

LANG:php
//       $body  = get_source($base);

       $lines = get_source($base);
       for($i=0;$i<count($lines);$i++)
           if (preg_match('/\&tchart\(/', $lines[$i]) ) 
               while(!preg_match('/\&tchart\(.*?\)\;/', $lines[$i]) && ($i+1<count($lines)))
                   array_splice($lines, $i, 2, chop($lines[$i]) . '<br>' . $lines[$i+1] );
       $body  = convert_html($lines);

plugin/tchart.inc.php

  • 引数を連結して1つの文字列にする
  • <br> を改行に戻す
    • ソースを tchart.rb へ渡して表示する
LANG:php(linenumber)
<?php

// 画像ファイルのキャッシュ場所
define('TCHART_DIR', 'tchart');

function tchart($source)
{
    $descriptorspec = array(
       0 => array("pipe", "r"),             // stdin
       1 => array("pipe", "w"),             // stdout
       2 => array("file", "/dev/null", "a") // stderr
    );
    $process = proc_open('/usr/local/bin/tchart.rb', $descriptorspec, $pipes);

    if (is_resource($process)) {
        fwrite($pipes[0], $source);
        fclose($pipes[0]);

        $result = stream_get_contents($pipes[1]);
        fclose($pipes[1]);

        proc_close($process);
    }
    return $result;
}

# 結果をキャッシュしたければこちらを呼び出す
function tchart_cached($source)
{
    $result = '';

    $image_base = sha1($source);
    $image_dir = TCHART_DIR . "/{$image_base[0]}/{$image_base[1]}";
    $image_svg = "{$image_dir}/{$image_base}.svg";

    if(!file_exists($image_svg)) {
        $svg = tchart($source);
        
        if (mb_substr($svg[0],0,4)=="<svg") {
            if(!file_exists($image_dir)){
                mkdir($image_dir, 0770, true);
            }
            $fh = fopen($image_svg, "w");
            fwrite($fh, join("", $svg));
            fclose($fh);
        }
    } else {
        $svg = file($image_svg);
    }

    return $svg;
}

function plugin_tchart_inline()
{
    $args = func_get_args();
    $source = join(",", $args);
    $source = preg_replace('/<br>/', "\n", $source);
    return tchart($source);
}

?>

コメント・質問





Counter: 4133 (from 2010/06/03), today: 3, yesterday: 0