ソフトウェア/pukiwiki/uml.inc.php

更新


公開メモ

UML を貼るためのプラグインです

このように書くと、

&uml(
[*] -> コマンド待ち
コマンド待ち: rready = 1
コマンド待ち: rvalid = 0
コマンド待ち --> 読み出し: arvalid & \narready
読み出し: rready = 0
読み出し: rvalid = 0
読み出し-right--> 結果送信: 読み出し終了
結果送信: rready = 0
結果送信: rvalid = 1
結果送信 --> コマンド待ち : rready
);

こう表示されます。

コマンド待ちrready = 1rvalid = 0読み出しrready = 0rvalid = 0結果送信rready = 0rvalid = 1arvalid &arready読み出し終了rready

先頭に "skinparam handwritten true" という行を加えると、 手書き風にもできます。

コマンド待ちrready = 1rvalid = 0読み出しrready = 0rvalid = 0結果送信rready = 0rvalid = 1arvalid &arready読み出し終了rready

謝辞

図の作成には PlantUML を利用させていただきました

http://ja.plantuml.com/

/usr/local/bin に plantuml.jar を置いて使っています。

表示には、

ダーツフォント
http://www.p-darts.jp/font/dartsfont/

を使わせていただきました。

cdn.rawgit.com で公開されているようでしたので、そちらを参照するようにしています。

ソースファイル

cache/uml_svg/ というフォルダの下に .svg ファイルをキャッシュします。

plugin/uml.inc.php

LANG:php
<?php

$plugin_uml_initialized = false;

function plantuml($source)
{
    $tmp = tempnam("/tmp", "plantuml");

    if (preg_match('/skinparam\s+handwritten\s+true/', $source)) {
      $source = <<<"EOS"
@startuml
skinparam defaultFontName dartsfont
skinparam defaultFontStyle bold
skinparam monochrome true
skinparam shadowing false
$source
@enduml
EOS;
    } else {
      $source = <<<"EOS"
@startuml
skinparam defaultFontName umldefault
$source
@enduml
EOS;
    }

    $handle = fopen($tmp, "w");
    fwrite($handle, preg_replace("/\\r?\\n/","\r\n",$source));
    fclose($handle);
    system("/usr/bin/java -Dfile.encoding=utf-8 -jar /usr/local/bin/plantuml.jar ".$tmp." -tsvg");
    unlink($tmp);

    $svg = file_get_contents($tmp.".svg");
    unlink($tmp.".svg");

    return preg_replace('/^<\\?xml.*?>/', '', $svg);
}

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

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

    return $svg;
}

function plugin_uml_header()
{
    $style = '';
    global $plugin_uml_initialized;
    if (!$plugin_uml_initialized) {
      $style = <<<'EOS'
<style type="text/css">
@font-face {
  font-family: "dartsfont";
  src: url("http://dora.bk.tsukuba.ac.jp/~takeuchi/skin/font/dartsfont.eot?#iefix") format('eot'),
       url("http://dora.bk.tsukuba.ac.jp/~takeuchi/skin/font/dartsfont.woff") format('woff');
}

svg text[font-family="dartsfont"] {
  font-family: "dartsfont";
}

svg text[font-family="umldefault"] {
  font-family:Arial,Helvetica,'ヒラギノ角ゴ Pro W3','Hiragino Kaku Gothic Pro','メイリオ',Meiryo,'MS Pゴシック',sans-serif;
}
</style>
EOS;
      $plugin_uml_initialized = true;
    }
    return $style;
}

function plugin_uml_inline()
{
    $aryargs = func_get_args();
    $source = join(",", $aryargs);
    $source = rtrim($source, ",");  //remove extra comma at the end.
    $source = str_replace("<br>", "\n",$source);

    $style = plugin_uml_header();
    return $style . plantuml_convert($source);
}

?>

pukiwiki.php の改造

複数行のパラメータを渡せるように、次のように改造しました。

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

        $lines = get_source($base); 

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

        $body  = convert_html($lines);

plantuml のソースコードを簡単に書くには

こちらが参考になりそうです。

Qiita - AtomとPlantUMLで爆速UMLモデリング
http://qiita.com/nakahashi/items/3d88655f055ca6a2617c

  • 右下の言語設定で PlantUML を選びます
  • メニューから [Package]-[plantuml-viewer]-[Toggle] でプレビューウィンドウを表示します

Windows7 64bit 上でリアルタイムに図を確認できました。

atom-plugim-plantuml.png

以下では Sublime 3 でも似たようなことができると書かれているのですが、

http://qiita.com/ogomr/items/0b5c4de7f38fd1482a48

まだうまくいってません。

使用例

http://ja.plantuml.com/ の例をいくつか。

skinparam handwritten true

actor Foo1
boundary Foo2
control Foo3
entity Foo4
database Foo5
Foo1 -> Foo2 : To boundary
Foo1 -> Foo3 : To control
Foo1 -> Foo4 : To entity
Foo1 -> Foo5 : To database

Foo1Foo1Foo2Foo2Foo3Foo3Foo4Foo4Foo5Foo5To boundaryTo controlTo entityTo database

handwritten true が無ければ次のようになります。

Foo1Foo1Foo2Foo2Foo3Foo3Foo4Foo4Foo5Foo5To boundaryTo controlTo entityTo database

skinparam handwritten true

:Main Admin: as Admin
 (Use the application) as (Use)

User -> (Start)
User --> (Use)

Admin ---> (Use)

note right of Admin : This is an example.

note right of (Use)
  A note can also
  be on several lines
end note

note "This note is connected\nto several objects." as N2
(Start) .. N2
N2 .. (Use)

Main AdminUse the applicationUserStartThis is an example.A note can alsobe on several linesThis note is connectedto several objects.

package "Classic Collections" #DDDDDD {
abstract class AbstractList
abstract AbstractCollection
interface List
interface Collection
}

List <|-- AbstractList
Collection <|-- AbstractCollection

Collection <|- List
AbstractCollection <|- AbstractList

AbstractList <|-- ArrayList

class ArrayList {
  Object[] elementData
  size()
}

enum TimeUnit {
  DAYS
  HOURS
  MINUTES
}

annotation SuppressWarnings

Classic CollectionsAbstractListAbstractCollectionListCollectionArrayListObject[] elementDatasize()TimeUnitDAYSHOURSMINUTESSuppressWarnings

start
:ClickServlet.handleRequest() ;
:new page;
if (Page.onSecurityCheck) then (true)
  :Page.onInit() ;
  if (isForward?) then (no)
    :Process controls;
    if (continue processing?) then (no)
      stop
    endif
    
    if (isPost?) then (yes)
      :Page.onPost() ;
    else (no)
      :Page.onGet() ;
    endif
    :Page.onRender() ;
  endif
else (false)
endif

if (do redirect?) then (yes)
  :redirect process;
else
  if (do forward?) then (yes)
    :Forward request;
  else (no)
    :Render page template;
  endif
endif

stop

ClickServlet.handleRequest()new pagePage.onSecurityChecktruefalsePage.onInit()isForward?noProcess controlscontinue processing?noisPost?yesnoPage.onPost()Page.onGet()Page.onRender()do redirect?yesredirect processdo forward?yesnoForward requestRender page template

質問・コメント




usrについて

()

素人質問で申し訳ありません。

/usr/local/bin に plantuml.jar を置いて使っています。
usrフォルダはpluginと同じレベルでよかったですか?ないので新規作成しました。

同様に"/usr/bin/java"がないのですが、どのようにすればいいでしょうか?

  • java はお使いの Linux ディストリビューションに合わせて apt あるいは rpm などでインストールするのが普通です。例えば openjdk jre などのパッケージを入れることになります。/usr/local/bin の /usr はルート直下の usr フォルダという意味です。管理者権限がない場合には /usr の下にインストールすることはできませんので何とか自分でインストールして使うことになりますが、オーナーやパーミッションの設定などいろいろ気を付けなければならなくなるので全く分からないところから動くところまで持っていくのは非常に大変だと思います。 -- 武内(管理人)

pukiwikiの改造について

()

便利に使わせてもらっています。

 lib/pukiwiki.phpですが、こちらの環境では$lines = get_source($base);
を追加したら動くようになりました。(1.5.1)

ご参考まで。

  • ご指摘ありがとうございます。本当ですね、一行抜けていました。本文を修正いたしました。 -- 武内 (管理人)

添付ファイル: fileatom-plugim-plantuml.png 1462件 [詳細]

Counter: 6592 (from 2010/06/03), today: 4, yesterday: 2