#!/usr/local/bin/perl
# 
# find2tree: find(1) 形式の入力を木構造へ整形出力
# 
#     [1996/09/18] OSHIRO Naoki.
#     [1996/10/08] OSHIRO Naoki. HTML 形式のみではなく，普通の出力にも対応．
#     [1996/10/08] OSHIRO Naoki. パス名から各ディレクトリへと展開するようにした．
#     [1996/10/29] OSHIRO Naoki. refdate オプションを追加
#     [1996/12/07] OSHIRO Naoki. 
#     ・&search においてリスト最後のタイトル取得を行っていなかった
#       のを修正（したつもり）
#     [1997/01/05] OSHIRO Naoki.
#     ・&search で木構造が余分に茂って表示されていたのを修正した
#       （前回の修正が不十分だったのを補訂）．
#     [1997/06/28] OSHIRO Naoki.
#     ・HTML の BODY を生成するようにした．
#     ・BGCOLOR を -b オプションで指定できるようにした．
#     [1997/07/29] OSHIRO Naoki.
#     ・HTML でのリンクを「ファイル名」からではなく「内容タイトル」から
#       張るようにしてみた．
#     [1997/09/04] OSHIRO Naoki.
#     ・「内容タイトル」からリンクを張るようにすると，それが取得できない
#       場合に不都合が生じるので，その場合にはファイル名を使用するように
#       した．
#     [1997/11/07] OSHIRO Naoki.
#     ・C プログラムソースのヘッダタイトルを取得可能にした．
#     [1998/12/23] OSHIRO Naoki.
#     ・jcode.el による漢字コード変換処理を入れた．（動作未確認）
#
#     $Log:$
#

# Web 検索用に「ツリー構造」という言葉も入れておこう．．．(^^;．

#
# ToDo:
#     ・現在はファイルのみでなく各段階のディレクトリ出力も必要だが，
#       ファイル名を取得した場合に，これを自動で展開するようにしたい．
#     [1996/12/07]
#     ・なぜか一番最後の項目はタイトルの取得が行われないよ？
#       -->一応修正したつもり[1996/12/07 10:51]
#     [1998/09/12]
#     ・ディレクトリ下に１つしかファイルがない場合には，枝は表示せず簡
#       略化して内容だけをすぐに表示するようにしたい．
#

$find2tree_ver="0.2";

require "jcode.pl";
$jcode='euc';

require "getopts.pl";
&Getopts('htrb:'); # h: HTML, t: TITLE, r: REFDATE, b: BGCOLOR

$bgcolor=" BGCOLOR=\"$opt_b\"" if ($opt_b);
$refdate="(??/??)<!-- #REFDATE --> " if ($opt_r);

while (<>) {
    chop;
    $path=$_;
    $path=~m#^([^/]*)#;
    $top{$1}++;
    while ($path ne "") {
	($base, $path)=&basename($path);
	next if ($base{"$path:$base"}++);
	$path{$path}.="$base\x1b";
    }
}
if ($opt_h) {
    print "<HTML>\n<!-- find2tree v.$find2tree_ver output -->\n";
    print "<HEAD>\n<TITLE>find2tree: $ARGV</TITLE>\n</HEAD>\n\n";
    print "<BODY$bgcolor>\n<PRE>\n";
}
foreach $top (sort(keys(%top))) {
    print "   " . &make_filename("$top", "$top") . "\n";
    &search("$top");
}
print "</PRE>\n</BODY>\n</HTML>\n" if ($opt_h);

# sub routines

sub search {
    local($path)=@_;
    local(@subpath, $i);

    $cont[$level]=" |  " if ($cont[$level] eq " +--");
    $level++;
    unless (defined($path{$path})) {
	$level--;
	return;
    }
    @subpath=split("\x1b", $path{$path});
    for ($i=0; $i<=$#subpath; $i++) {
	$subpath=$subpath[$i];
	$cont[$level]=" +--";
	$a="$path/$subpath";
	$title="";
	if ($opt_t) {
	    if ($a=~/\.html$/) {
		$title=&get_title("$a");
	    } elsif ($a=~/\.c$/) { # C program source
		$title=&get_title_cprogram("$a");
	    } else {
		$title=&get_title_shellscript("$a");
	    }
	    $title=~s/<\/?(BR|H\d|B)>/ /ig;
	    $title=~s/<IMG [^>]+>//ig;
	    $title=~s/^.{50,}/$&/;
	    $title=~s/[ \t\n]+/ /g;
	    $title.=":" if ($title);
        }
	print "   " . join('', @cont[0..$level]);
#	    . $title 
	if ($title) {
	    print &make_filename("$a", "$title") . "$subpath";
	} else {
	    print &make_filename("$a", "$subpath");
	}	    
	print "$refdate" . "\n";
	$cont[$level]="    " if ($i==$#subpath);
	&search($a);
    }
    $level--;
    print "   " . join('', @cont[0..$level]) . "\n" if ($cont[$level] eq " |  ");
}

sub make_filename {
    local($file, $desc)=@_;
    if ($opt_h) {
	return "<A HREF=\"$file\">$desc</A>";
    } else {
	return $desc;
    }
}

sub basename {
    local($_)=@_;
    local($path, $base);

    s#/$##;
    ($base, $path)=('', $_);
    if (m#[^/]+$#) {
	$base=$&;
	$path=$`;
    }
    $path=~s#/$##;
    return ($base, $path);
}

sub get_title {
    local($file)=@_;
    local($title);

    open(F, "<$file") || return "";
    while (<F>) {
	chop;
	&jcode'convert(*_, $jcode) if $jcode;
	if (/<TITLE>/i) {
	    $title=$';
	    last;
	}
    }
    if ($title=~s/<\/TITLE>.*//i) {
	close(F);
	return $title;
    }
    while (<F>) {
	chop;
	&jcode'convert(*_, $jcode) if $jcode;
	if (/<\/TITLE>/i) {
	    $title.=$`;
	    last;
	}
	$title.=$_;
    }
    close(F);

    return $title;
}

sub get_title_shellscript {
    local($file)=@_;
    local($title);

    open(F, "<$file") || return "";
    while (<F>) {
	last unless (/^\s*[#;%]+/ || /^\s*$/);
	chop;
	&jcode'convert(*_, $jcode) if $jcode;
	if (/[#;%]+\s*[^:]+:\s*/) {
	      $title=$';
	      last;
	}
    }
    close(F);

    return $title;
}

sub get_title_cprogram {
    local($file)=@_;
    local($title);

    open(F, "<$file") || return "";
    while (<F>) {
	last unless (/^\s*\/?\*/ || /^\s*$/);
	chop;
	&jcode'convert(*_, $jcode) if $jcode;
	if (/\*\s*[^:]+:\s*/) {
	      $title=$';
	      last;
	}
    }
    close(F);

    return $title;
}

