Perl 小品集 ─ wread

#!/usr/bin/perl
#
# wread.pl
# MS Word ファイルを wvware と netscape で読む
# wvHtml, netscape 6.21 が必要

### Main

$c_dir = `pwd`;
chomp $c_dir;
$input = $ARGV[0];
chomp $input;
if ($input eq ""){
    &select;
    }
else{
    &start ($input);
    }

### Sub

# ファイルの撰択
sub select{
local ($input, $file, $parts, $file_name);
while(1){
    if ($input eq 'd'){
        &get_dir;
        }
    else{
        &get_info ($c_dir);
        }
    print "Select by number => ";
    $input = <STDIN>;
    chomp $input;
    # 終了
    if ($input eq 'q'){
        exit 0;
        }
    # ファイルの表示
    elsif ($input eq 'f'){
        next;
        }
    # ディレクトリーの表示
    elsif ($input eq 'd'){
        next;
        }
    # 番号による撰択
    elsif ($input =~ /^[\d]+/){
        $file = $data[$input - 1];
        if (-d $file){
            &get_info ($file);
            next;
            }
        @parts = split /\./, $file;
        $file_name = $parts[0];
        &start ("$file_name");
        }
    # ディレクトリーの移動
    else {
        ($input) = &path_find ($input);
        &get_info ($input);
        }
    }
&select;
}

# ディレクトリーの分析
sub path_find{
local ($work_dir);
local ($input) = @_;
$work_dir = $c_dir;
# ひとつ上のディレクトリーに
if ($input =~ /^\.\./){
    $input = "$work_dir/$input";
    while ($input =~ /\.\./){
        $input =~ s/\/[\w]+\/\.\.//;
        }
    }
# ひとつ下のディレクトリーに(ドットがある時)
elsif ($input =~ /^\.\//){
    $input =~ s/^\./$work_dir/;
    }
# ひとつ下のディレクトリーに(ドットがない時)
elsif ($input =~ /^[\w]+/){
    $input =~ s/^/$work_dir\//;
    }
# 指定されたディレクトリーがあった場合
if (-d $input){
    return $input;
    }
# 指定されたディレクトリーが無かった場合
else{
    print "There is no such directory!\n";
    sleep 1;
    return $c_dir;
    }
}

# ファイル情報の取得
sub get_info{
($c_dir) = @_;
$c_dir =~ s/\/$//;
@data = glob ("$c_dir/*.doc");
if (($sum = scalar (@data)) > 0){
    &show_data ("DOCUMENT LIST", $sum);
    }
else{
    &get_dir;
    }
}

sub get_dir{
local ($dir_list, $dir_data, $dir_name, $input);

# ディレクトリー情報の取得
@dir_data = glob("$c_dir/*");
$i = 0;
foreach $dir_name (@dir_data){
    if (-d $dir_name){
        $data[$i] = $dir_name;
        $i++;
        }
    }
&show_data ("DIRECTORY LIST", $i);
}

# データの表示
sub show_data{
local ($line, $i, $last);
local ($title, $sum) = @_;

# 縦二列に表示するため、左側の列の長さを得る
if ($sum % 2 == 0){
    $last = $sum / 2 + 1;
    }else{
    $last = int($sum / 2) + 2;
    }

# 画面をクリヤしてタイトルを表示する
print "\033[2J\033[1;0H";
$title = " $title ($c_dir) ";
# 左側のラインを引く
$line = int((80 - length ($title)) / 2);
$i = 0;
while ($i < $line){
    print '=';
    $i++;
    }
# タイトルを表示
print $title;
# 右側のラインを引く
$i = $i + length ($title);
while ($i < 80){
    print '=';
    $i++;
    }
# 左側のファイル名を表示
&show_column (2, 0, 1, $last);
# 右側のファイル名を表示
&show_column (2, 40, $last, $sum + 1);
if ($sum % 2 == 0){
    print "\n";}else{
    print "\n\n";}
}

# ファイル名をコラムに表示
sub show_column{
local ($row, $col, $start, $end, $file, $file_name) = @_;
while ($start < $end){
    if ($start < 10){
        $number = " [0$start] ";}else{
        $number = " [$start] ";
        }
    $file = $data[$start - 1];
    $file =~ /([^\/]+)$/;
    $file_name = $1;
    # ファイル名が長い場合の処理
    if (length ($file_name) > 30){
        ($file_name) = &to_short ($file_name);
        }
    print "\033[$row;$col\H$number$file_name";
    $row++;
    $start++;
    }
}

# 文字列を 30 文字でカットする
sub to_short{
local ($letter, $short, $i);
local ($long) = @_;
@letter = split //, $long;
$short = "";
$i = 0;
while ($i < 30){
    $short = "$short$letter[$i++]";
    }
return "$short...";
}

# 変換作業
sub start{
local ($file) = @_;
if (-e "$file.doc"){
    system "wvHtml '$file.doc' '$file.html'";
    system "/usr/local/netscape/netscape --edit 'file://$file.html'";
    }
else{
    print "I cannot find the file.\n";
    sleep 1;
    &select;
    }
}


[INDEX]