end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

Simple Tree Menuで表示するツリーデータ(ul,li)を作成

ツリー形式の表示には Simple Tree Menu(※1) を使用していますが、いただいたデータ(※2)をSimple Tree Menuで表示可能なul,liに変換する必要があったので、使用したperl scriptを書き留めておきます。

※1 http://www.dynamicdrive.com/dynamicindex1/navigate1.htm
※2 元データの例

末端 1段目 2段目 3段目
node1_1 node1_2 TOP CATE1
node2_1 node2_2 TOP CATE1 CATE2
node3_1 TOP CATE1 CATE3

原則、タブ区切データで、末端内に複数を定義する場合、空白区切

#!/usr/local/bin/perl
use strict;
use warnings;
use utf8;
use Data::Dumper;

main(@ARGV);

sub main {
    my ($tree_src) = @_;
    my $tree_pl = retrieve_tree_src($tree_src);
    print Dumper($tree_pl);
    print conv_tree_pl2html_ul($tree_pl,0);
}

sub retrieve_tree_src {
    my($tree_src) = @_;

    open my $fh, $tree_src or die "Cannot open file : $tree_src : $!";
    my @lines = <$fh>;
    close($fh) or die "Cannot close file : $tree_src : $!";

    my $tree_pl = {};
    for my $line (@lines){

	$line =~ s/\s+$//o;	#trim

	my ($nodes_str,@paths) = split("\t",$line);
	my @nodes = split(/ /,$nodes_str);

	next if (@nodes < 1 or @paths < 1);

	my $tmp_hash = $tree_pl;
	for my $path ( @paths ){
	    $tmp_hash->{$path} = {} if (not $tmp_hash->{$path});
	    $tmp_hash = $tmp_hash->{$path};
	}

	$tmp_hash->{node} = [];
	for my $node ( @nodes ){
	    push(@{$tmp_hash->{node}},$node);
	}
    }

    return $tree_pl;
}


sub conv_tree_pl2html_ul {
    my($tree_pl,$depth) = @_;

    return "" if ( ref($tree_pl) ne "HASH");

    my $ret_html = "";
    my $indent = " " x $depth;

    if ($depth < 1){
	$ret_html .= "$indent<ul id=\"treemenu\" class=\"treeview\">\n";
    } else {
	$ret_html .= "$indent<ul>\n";
    }

    for my $key (sort keys %$tree_pl){
	if ($key eq "node"){
	    for my $node (@{$tree_pl->{$key}}){
		$ret_html .= "$indent<li>$node<li>\n";
	    }
	} else {
	    $ret_html .= "$indent<li>$key\n";
	    $ret_html .= conv_tree_pl2html_ul($tree_pl->{$key},$depth+1);
	    $ret_html .= "$indent</li>\n";
	}
    }

    $ret_html .= "$indent</ul>\n";
    return $ret_html;
}

実行結果

[endo@colinux tmp]$ ./foo.pl tree.tsv 
$VAR1 = {
          'TOP' => {
                     'CATE1' => {
                                  'CATE2' => {
                                               'node' => [
                                                         'node2_1',
                                                         'node2_2'
                                                       ]
                                             },
                                  'node' => [
                                            'node1_1',
                                            'node1_2'
                                          ],
                                  'CATE3' => {
                                               'node' => [
                                                         'node3_1'
                                                       ]
                                             }
                                }
                   }
        };
<ul id="treemenu" class="treeview">
<li>TOP
 <ul>
 <li>CATE1
  <ul>
  <li>CATE2
   <ul>
   <li>node2_1<li>
   <li>node2_2<li>
   </ul>
  </li>
  <li>CATE3
   <ul>
   <li>node3_1<li>
   </ul>
  </li>
  <li>node1_1<li>
  <li>node1_2<li>
  </ul>
 </li>
 </ul>
</li>
</ul>
[endo@colinux tmp]$ 

これをhtmlにして、表示すると、次のようになります。

<html> <head>
<title></title>
<script type="text/javascript" src="simpletreemenu.js"></script>
<link rel="stylesheet" type="text/css" href="simpletree.css">
</head>
<body>
<ul id="treemenu" class="treeview">
<li>TOP
 <ul>
 <li>CATE1
  <ul>
  <li>CATE2
   <ul>
   <li>node2_1<li>
   <li>node2_2<li>
   </ul>
  </li>
  <li>CATE3
   <ul>
   <li>node3_1<li>
   </ul>
  </li>
  <li>node1_1<li>
  <li>node1_2<li>
  </ul>
 </li>
 </ul>
</li>
</ul>
<script type="text/javascript">
ddtreemenu.createTree("treemenu", true);
</script>
</body>
</html>