#!/usr/local/bin/perl #!D:/Perl/bin/perl.exe #--------------------------------------------------------------------------------- # ファイル一覧のhtml作成と文字コードの一括変換用Perlスクリプト # URL:http://sakaguch.com 電子メール:http://sakaguch.com/cgi/postmail/ より送信して下さい。 # ファイル名:html_utf8conv.pl 2004.06.06 作成:鷹の巣 #--------------------------------------------------------------------------------- # 参考URL:なし。ただし、C言語では、下記のURLが再帰呼び出しの参考になります。 # パソコン基礎知識 C 言語編 (その九) 再帰呼び出し処理 - ディレクトリ検索 - SAK Streets # http://homepage2.nifty.com/sak/w_sak3/doc/syspc/c_k09.htm #--------------------------------------------------------------------------------- # 改版記録: # 2002.08.04 Rev.0.000 初版 # 2003.01.19 Rev.0.100 ファイル一覧のhtml作成用に変更。 # 2003.02.21 Rev.1.000 コメントを追加して、公開。 # 2003.03.15 Rev.1.001 ファイル形式検出の誤動作のため、一部コメント行に変更。 # 2004.06.06 Rev.1.100 文字コードの一括変換処理を追加。 $ver = 'html_utf8conv.pl Rev.1.100(作成:鷹の巣)'; #--------------------------------------------------------------------------------- # 1.用途 # #  このPerlスクリプトは、フリーソフトです。詳細は、項4をご一読願います。 # #  このPerlスクリプトは、httpdドキュメントルート以下の全てのディレクトリ内の #  ファイル名を取得し、ファイル一覧のhtmlファイルを作成します。 #  また、大変危険ですが、htmlファイルの文字コードを全て変換して書き換えます。 # #  元々は、指定ディレクトリ以下の全てのディレクトリ内のファイル名を取得する #  再帰呼び出しの練習用スクリプトとして作成しました。 #  しかし、これだけでは何の役にも立たないので、ロボット検索のクローラ用の #  ファイル一覧のhtmlファイルを作成を行なうように変更したものです。 #  Googleでは、リンク先のURLを100未満にする勧告がありますので、ご注意願います。 # #  クライアント機で処理することを前提にしている為、サーバーへの負荷を小さく出来ます。 #  (というか、サーバー機で実行するものではありません。) # #  この機会に是非、クライアント機にPerlをインストールして、 #  このスクリプトを実行して下さい。 #   #--------------------------------------------------------------------------------- # 2.作成されるファイルの表示例と特徴 # #  作成されるhtmlファイルの表示例は、以下のURLのリンク先に設置しています。 #  http://sakaguch.com/AccessUp.html#Crawler # #  ○利点:httpdドキュメントルート以下の全てのディレクトリ内のファイル名から、 #      ロボット検索のクローラ用のhtmlファイルを作成を一気に行なうので、 #      クローラ用のhtmlファイルを作成する手間が多少は、はぶける。 #      取得したファイル名をディスクに書き出すので、メモリを要求しない。 # #      文字コードをUTF-8Nコードにした場合に全角文字の-や~等の文字が #      変換されない。 # #  ○欠点:クライアント機にPerlをインストールしなければならない。 #      スクリプトの読みやすさに重点を置いているので、処理速度が遅い。 #      取得したファイル名をディスクに書き出すので、処理速度が遅い。 # #      ソースのhtmlファイルのバックアップは、最初の一回だけ取って #      ソースのhtmlファイルの文字コードを書き換えていますが、 #      あてにならないので、バックアップは、必ず取っておいて下さい。 # #--------------------------------------------------------------------------------- # 3.ご注意事項 # #  このスクリプトは、Windows 2000 Professional #  Active Perl 5.8.4.810 built for MSWin32-x86-multi-thread #  の環境にて、動作確認を行っております。 #  基本的にPerl5以降でしか、動作しません。 # #  このスクリプトに対するご質問や不具合がございましたら、電子メールで、 #  webmaster@sakaguch.com まで、お寄せ下さい。 #  また、「鷹の巣」の自宅サーバー掲示板 #  http://sakaguch.com/cgi/bbs/ #  にご投稿して頂いても結構です。 # #--------------------------------------------------------------------------------- # 4.著作権 # #  このスクリプトは、鷹の巣が作成しましたが、著作権は放棄しています。 #  スクリプトの再配布や改造は自由ですが、無償として下さい。 #  いかなる目的であっても、このスクリプトに付加価値をつけて、 #  有償配布してはなりません。 # #--------------------------------------------------------------------------------- # 5.起動方法 # #  コマンドラインから、perl html_utf8conv.plを実行します。 # #--------------------------------------------------------------------------------- # 6.その他 # #  サブルーチンでファイルハンドルを局所変数として使用しています。 #  動作確認は行なっていますが、Perlのベテランの方から怒られるかもしれません。 # #  ファイル名の取得だけでしたら、 #  @FILTERの設定と&out_files ( $first_dir_path , $out_file_name ); #  の呼び出しだけで、可能です。 # #  Perlの練習用として作成していますので、特殊なモジュールは使用していません。 # #--------------------------------------------------------------------------------- #--------------------------- #■□■ 基本設定 ■□■ #--------------------------- # HTMLドキュメントルートのディレクトリ(フォルダ)の設定 $document_root = "D:/WWW/public_html-utf8"; # 変換先の文字コード(Shift_JIS と euc-jp と iso-2022-jp と UTF-8 の4種類の内のいずれかを指定) # Windows の場合は、Shift_JIS をPC-UNIX の場合は、euc-jp を設定します。 # $CONV_CODE = "Shift_JIS"; # $CONV_CODE = "euc-jp"; # $CONV_CODE = "iso-2022-jp"; $CONV_CODE = "UTF-8"; # エンコードモジュールの設定 # 非推奨 jcode.pm を追加インストールした           場合は、未使用($FLAG_ENCODE = 0)を選択のこと。 #  推奨 Perl 5.8 以降の Encode モジュール(標準モジュール)の場合は、 使用($FLAG_ENCODE = 1)を選択のこと。 $FLAG_ENCODE = 1; #--------------------------- #■□■ 基本設定の終わり ■□■ #--------------------------- # HTMLドキュメントルートのURLの設定 # URLを表示する場合は、$Rep_URL = "http://www.example.com";と設定。 # ファイル名だけの表示で良い場合は、$Rep_URL = ".";と設定。 #$Rep_URL = "http://www.example.com"; $Rep_URL = "."; # html出力ファイル名の指定 #$html_out_file_name = "$document_root/FileList.html"; $html_out_file_name = "./FileList.html"; ################# ファイル取得関係の設定 ################# # 取得する対象ファイル名の拡張子(末尾一致文字列)の設定 #  指定しない場合の記入例:@FILTER = ( "" ); @FILTER = ( ".html" , ".htm" , ".sht" , ".shtml" , ".css" , ".txt" ); # 開始ディレクトリ(フォルダ)の設定 $first_dir_path = $document_root; # 出力ファイル名の設定(無指定時は、画面(標準出力)に出力します。) $out_file_name = "./file.txt"; # 変換エラー出力ファイル名の設定 $ERROR_FILE_NAME = "./error.txt"; ################# ファイル取得関係の設定おわり ################# #---------------------------- # HTMLのヘッダーデータの設定 #---------------------------- # 作成されたhtmlファイルをそのままご使用になる場合は、 # 以下のデータもご訂正願います。 sub html_header_set { # 作成するHTMLファイルの書式バージョンの設定 #  わからなければ、HTML 4.01 strict用を選択すること。 #$HTMLver = "XHTML 1.1"; # XHTML 1.1用 #$HTMLver = "XHTML 1.0 strict"; # XHTML 1.0 strict用 $HTMLver = "HTML 4.01 strict"; # HTML 4.01 strict用 # 作成するHTMLファイル上部に挿入するリンクやバナー #  先頭付近に必ず、適当な文字というリンクを必ず入れること!!! #  ただし、XHTML 1.1では、とすること。 #  の等の非推奨タグを使用したり、タグを大文字で書くと、 #  Another HTML-lint gatewayの減点対象となりますので、ご注意願います。 #  (あらかじめ、上記のサイトで$banner1部分のタグを試験されることを推奨します。) $banner = <<'BANNER';

目次

BANNER $charset = "Shift_JIS"; $description = "サイト内のファイルの一覧を表\示します。"; $KeyWords = "サイト,ファイル一覧"; $mailaddress = "webmaster\@example.com"; $webmaster = "管理者名"; $prevpage = "./index.html"; $title = "サイト内ファイル一覧"; # $sakusei = "20XX年XX月XX日"; $sakusei = ""; } #--------------------------- # 設定の終わり #--------------------------- # 日本語コード変換モジュールの使用を宣言。 if ( $FLAG_ENCODE ) { # 日本語コード変換 Encode モジュールの使用を宣言する。(Perl 5.8以降は、標準モジュール) eval 'use Encode qw/ encode decode /;'; eval 'use Encode qw/ from_to /;'; eval 'use Encode::Guess qw/ shiftjis euc-jp 7bit-jis /;'; # eval 'use Encode::JP::H2Z;'; } else { # 日本語コード変換jcode.pmモジュールの使用を宣言する。 eval 'use Jcode;'; } &main ( $first_dir_path , $out_file_name , $html_out_file_name ); exit; #---------------- # 主回路 #---------------- sub main { ( $first_dir_path , $out_file_name , $html_out_file_name ) = @_; print "$ver\n"; open( $OUT_HANDLE , "> $html_out_file_name" ) || &error ( $file ); # HTMLのヘッダーデータの設定 &html_header_set; # HTMLのヘッダー作成 &html_header ($OUT_HANDLE, $HTMLver, $charset, $description, $KeyWords, $mailaddress, $webmaster, $prevpage, $title, $banner, $sakusei); # ディレクトリ(フォルダ)階層下の全ファイル名を取得する。 print "ファイル名を取得中です。\n"; &out_files ( $first_dir_path , $out_file_name ); # ファイル名からURLへの変換回路 &rep_url_anker ($OUT_HANDLE, $out_file_name , $html_out_file_name , $HTMLver , $document_root , $Rep_URL ); # HTMLのフッター作成 &html_footer ( $OUT_HANDLE , $HTMLver ); close ( $OUT_HANDLE ); } #---------------------------------- # ファイル名取得とハンドル設定回路 #---------------------------------- sub out_files { # ディレクトリ(フォルダ)階層下の全ファイル名を取得する。 # (出力ファイル名が指定されていない場合は、標準出力に出力します。) # # 入力:$dir_path - 開始ディレクトリ(フォルダ)名 #    $file - 出力ファイル名 # 出力:$file - $fileにファイル名を書き出し。 my ( $dir_path , $file ) = @_; if ( $file eq "") { # 出力ファイル名が指定されていない場合は、 # 取得したファイル名を画面(標準出力)に出力する。 $FILE_NAME_OUT_HANDLE = "STDOUT"; &get_files ( $dir_path ) ; } else { # ファイル$fileに出力する場合は、 # 取得したファイル名をファイルハンドル$OUT_HANDLEに出力する。 open( $FILE_NAME_OUT_HANDLE , "> $file" ) || &error ( $file ); &get_files ( $dir_path ); close ( $FILE_NAME_OUT_HANDLE ); } } #-------------------- # ファイル名取得回路 #-------------------- sub get_files { # ディレクトリ(フォルダ)階層下の全ファイル名を取得する。 # (テキストファイル以外を除外するように指定しています。) # # 入力:       $dir_path - ディレクトリ(フォルダ)名 #    広域変数   @FILTER - ファイル名末尾の文字列の配列 #    呼出し側変数 $FILE_NAME_OUT_HANDLE - 出力ファイルハンドル # # 出力:ファイルハンドル$FILE_NAME_OUT_HANDLEで指定したファイルファイル名を書き出し。 my ($dir_path ) = $_[0]; my ( $IN_HANDLE , $file , @file ); # ディレクトリ(フォルダ)を指定して、ファイル名を取得する。 opendir ( $IN_HANDLE , $dir_path ) || &error ( $dir_path ); @file = readdir ( $IN_HANDLE ); closedir ( $IN_HANDLE ); # 取得したファイル名の検査 foreach $file ( @file ) { # カレントディレクトリと親ディレクトリを除外 if ( ( $file eq "." ) or ( $file eq ".." ) ) { next; } # ファイル名にファイルパスを追加する。 $path_file = "$dir_path/$file"; # バイナリファイルを除外。 # 2003.03.15 誤動作のため、コメント行に変更 if ( -B $path_file ) { next; } if ( -d $path_file ) { # ファイル名がディレクトリ(フォルダ)の場合、 # ディレクトリ(フォルダ)のファイル名を取得する。(再帰呼び出し) &get_files ( $path_file ) ; } else { # ファイル名が通常のファイルの場合、標準出力へ出力する。 # テキストファイル以外を除外。 # 2003.03.15 誤動作のため、コメント行に変更 if ( !( -T $path_file ) ) { next; } # ファイル名末尾の文字列を検査し、標準出力へ出力する。 $flag = 0; foreach $filter ( @FILTER ) { if ( $file =~ /$filter$/ ) { $flag = 1; last; } } if ($flag) { print $FILE_NAME_OUT_HANDLE "$path_file\n"; } } } } #------------------------------- # ファイル名からURLへの変換回路 #------------------------------- sub rep_url_anker { my ( $OUT_HANDLE , $in_file_name , $out_file_name , $HTMLver , $document_root , $Rep_URL ) = @_; my ( $IN_HANDLE ); open ( $IN_HANDLE , "< $in_file_name" ) || &error("Open Error : $in_file_name" ); print "$in_file_nameを処理中です。\n"; $count = 0; if ($HTMLver eq "HTML 4.01 strict") { $br = "
"; } else { $br = "
"; } while ( $_ = <$IN_HANDLE> ) { # 行末の改行コードを取り除く。 chomp( $_ ); &conv ( $_ , $_ , $CONV_CODE , $ERROR_FILE_NAME ); # 2004.06.05 追加 $_ =~ s|^$document_root|$Rep_URL|; print $OUT_HANDLE ""; $_ =~ s|^$Rep_URL/||; print $OUT_HANDLE "$_$br\n"; $count++; } close ( $IN_HANDLE ); print "$countのリンク数がありました。\n"; } #-------------------- # HTMLのヘッダー作成 #-------------------- sub html_header { my ($OUT_HANDLE, $HTMLver, $charset, $description, $KeyWords, $mailaddress, $webmaster, $prevpage, $title, $banner, $sakusei) = @_; if ($HTMLver eq "HTML 4.01 strict") { # HTML 4.01 strict用 print $OUT_HANDLE <<"HTML"; HTML } elsif ($HTMLver eq "XHTML 1.0 strict") { # XHTML 1.0 strict用 print $OUT_HANDLE <<"HTML"; HTML } else { # XHTML 1.1用 print $OUT_HANDLE <<"HTML"; HTML } $sakusei = &get_time ( $sakusei ); $hed = <<"HTML"; $title
$banner
$sakusei 作成:$webmaster
$description

$title

HTML $hed = &TagRep ( $hed , $HTMLver ); print $OUT_HANDLE "$hed\n"; } #-------------------- # HTMLのフッター作成 #-------------------- sub html_footer { my ( $OUT_HANDLE , $HTMLver ) = @_; $foot = <<"HTML";
▲頁先頭

HTML $foot = &TagRep ( $foot , $HTMLver ); print $OUT_HANDLE "$foot\n"; } #------------------ # HTMLタグの置換 #------------------ sub TagRep { my ( $HTMLtag , $HTMLver ) = @_; if ($HTMLver eq "HTML 4.01 strict") { $HTMLtag =~ s|\s/>|>|g; } else { $HTMLtag =~ s|
|
|g; $HTMLtag =~ s|
|
|g; } return $HTMLtag; } #-------------- # 時間の取得 #-------------- sub get_time { my ( $date ) = $_[0]; my ( $day , $mon , $year , $date ); if ( $date eq "") { ( $sec, $min, $hour, $day , $mon , $year ) = localtime ( time() ); $date = "作成日:" . sprintf ( "%04d年%02d月%02d日" , $year+1900 , $mon+1 , $day ); } return $date; } #------------------ # エラー内容表示 #------------------ sub error { # エラーの内容を表示して終了する。 print "$_[0]\n"; die "$_[0] : $!"; } #---------------------- # 日本語文字コード変換 #---------------------- # 2004.06.05 追加 sub conv { # 日本語コード変換を行う。 # # 入力:$in - 入力ファイル名 #    $out_code - 出力する日本語文字コード(UTF-8,Shift_JIS,euc-jp,iso-2022-jp) # # 出力:$out - 出力ファイル名 #    $error - 出力ファイル名 my ( $in , $out , $out_code , $error ) = @_; my ( $dist_code , $line_count , , ) = @_; # 変換先の文字コード$out_codeは、Shift_JIS と euc-jp と iso-2022-jp と UTF-8 の4種類が指定可能。 if ( $FLAG_ENCODE ) { # 日本語コード変換 Encode モジュールの使用を宣言する。(Perl 5.8以降は、標準モジュール) if ($out_code eq "UTF-8") { $dist_code = "utf8"; } elsif ($out_code eq "Shift_JIS") { $dist_code = "shiftjis"; } elsif ($out_code eq "euc-jp") { $dist_code = "euc-jp"; } elsif ($out_code eq "iso-2022-jp") { $dist_code = "7bit-jis"; } } else { # 日本語コード変換jcode.pmモジュールの使用を宣言する。 if ($out_code eq "UTF-8") { $dist_code = "utf8"; } elsif ($out_code eq "Shift_JIS") { $dist_code = "sjis"; } elsif ($out_code eq "euc-jp") { $dist_code = "euc"; } elsif ($out_code eq "iso-2022-jp") { $dist_code = "jis"; } } open(ERROUT,">> $error") || &error("Open Error: $error"); open(IN,"< $in") || &error("Open Error: $in"); @buf = ; close(IN); if (!(-e "$in.bak")) { # バックアップファイルが存在しなければ、 $flag_rename = rename($in, "$in.bak"); } open(OUT,"> $out") || &error("Open Error: $out"); if ( $FLAG_ENCODE ) { # 日本語コード変換 Encode モジュールの使用時 $line_count = 0; foreach (@buf) { $line_count++; # 変換元の文字コードを検査 my $enc = guess_encoding ( $_ ); # 指定文字コードに変換(半角カナを全角カナには、変換しない。) if ( ref $enc ) { from_to ( $_ , $enc->name , $dist_code ); } else { print ERROUT "$out - $line_count\n"; } # 指定文字コードに変更 $_ =~ s/encoding=\"(Shift_JIS|euc-jp|UTF-8)\"/encoding=\"$out_code\"/ig; $_ =~ s/charset=(Shift_JIS|euc-jp|UTF-8)\"/charset=$out_code\"/ig; print OUT $_; } } else { # 日本語コード変換jcode.pmモジュールの使用時 foreach (@buf) { # 文字コードの種類を調べる Jcode::convert( \$_ , $enc ); # 指定文字コードに変換(半角カナを全角カナに変換) Jcode::convert ( \$_ , $dist_code , $enc , "z" ); # 指定文字コードに変換(半角カナを全角カナには、変換しない。) # $_ = jcode ( $_ ) -> $dist_code; # 指定文字コードに変更 $_ =~ s/encoding=\"(Shift_JIS|euc-jp|UTF-8)\"/encoding=\"$out_code\"/ig; $_ =~ s/charset=(Shift_JIS|euc-jp|UTF-8)\"/charset=$out_code"/ig; print OUT $_; } } close(OUT); close(ERROUT); }