#!/usr/bin/perl -w
use strict;
use warnings;
my %rel;
my %rel_back;
my $to_org = 0;
my $org_level = 1;
sub star{
my $num = shift;
return '*'x$num;
}
sub say{
print @_;
print "\n";
};
sub init_mind {
say '' unless $to_org;
}
sub open_class {
my $center_class = shift;
say "" unless $to_org;
say star($org_level++) . " " . $center_class if $to_org;
}
sub open_left_class {
my $base = shift;
say "" unless $to_org;
say star($org_level) . " " . $base if $to_org;
}
sub open_right_class {
my $base = shift;
say "" unless $to_org;
say star($org_level) . " " . $base if $to_org;
}
sub close_class() {
say "" unless $to_org;
$org_level-- if $to_org;
}
sub add_base_classes {
my $center_class = shift;
return unless exists $rel{$center_class};
my @base_list = split /,/,$rel{$center_class};
for my $base (@base_list) {
&open_left_class($base);
$org_level++ if $to_org;
&add_base_classes($base);
&close_class;
}
}
sub add_child_classes {
my $center_class = shift;
return unless exists $rel_back{$center_class};
my @child_list = split /,/,$rel_back{$center_class};
for my $child (@child_list) {
&open_right_class($child);
$org_level++ if $to_org;
&add_child_classes($child);
&close_class;
}
}
sub main {
#to org mode support
$to_org = 1 if ($ARGV[2] && $ARGV[2] eq "--org");
my $FILE;
open $FILE, "<", $ARGV[0];
my $line;
my @tail_bases;
while ($line=<$FILE>) {
chop $line;
my ($cls, $base) = split /\s+--D\s+/, $line;
next unless $cls && $base;
$cls =~ s/\s//g;
$base =~ s/\s//g;
if (exists $rel{$cls}) {
$rel{$cls} = $rel{$cls} . "," . $base;
} else {
$rel{$cls} = $base;
}
push @tail_bases, $base;
}
for my $base (@tail_bases) {
$rel{$base} = "" unless exists $rel{$base};
}
for my $key (keys %rel) {
my $val = $rel{$key};
my @base_list = split /,/,$val;
for my $base (@base_list) {
if (exists $rel_back{$base}) {
$rel_back{$base} = $rel_back{$base} . "," . $key;
} else {
$rel_back{$base} = $key;
}
}
}
if ($ARGV[1] && exists $rel{$ARGV[1]}) {
my $center_class = $ARGV[1];
&init_mind;
&open_class($center_class);
&add_base_classes($center_class);
&close_class if $to_org;
$org_level = 1 if $to_org;
&open_class($center_class) if $to_org;
&add_child_classes($center_class);
&close_class;
&fini_mind;
}
}
&main;