高橋征義です。

遅くなりました。すでにいろいろな方がメールされているので、
今さら書くことはあんまりなさそうですが。

中村文建 <tx6f-nkmr / asahi-net.or.jp> wrote:
> 最終的にやりたい事はWindows上でHTMLの整形をRubyで自動化したいのです。
> (1)現フォルダのファイル全てを変換(上書き変換する)
> (2)タグ:大文字→小文字変換
> (3)文字コード:SJIS→JIS変換
> (4)HTML整形・・etc

まず、(1)をやるのであれば、出力用のフォルダを作って、そちらに
変換後のファイルを生成するようにした方がいいと思います。
ただでさえ古いファイルを消してしまうと困ったことが起きやすい
ところに、プログラムのミスがあったりすると泣くに泣けない事態が
発生したりしかねない(というかよく発生する……)ためです。

この場合、リダイレクトはせずに、個々の入力用・出力用ファイル名を
作って、openすることになります。

> ▲質問:ファイルの上書きはどのようにするのでしょうか?

上記のような場合、大きな流れとしては、↓こんな感じですね。

   orig_filename = 【オリジナルのファイル名】
   out_filename = 【出力先のファイル名】

   File.open(orig_filename){|f|            # 入力用ファイルを開いて
     content = f.read                      # 読み込んで
     new_content = transform(content)      # 変換する
   }
   File.open(out_filename){|f2|            # 出力用ファイルを開いて
     f2.write(new_content)                 # 書き出す
   }

> 以下 ソースを示します================================================
> 
> require 'kconv'
> 
> filename = ARGV[0]             # ファイル読み込み
> io = File.open(ARGV[0], "r+")  # ファイル・オープン
> 
> filename.tojis                 # 文字コード JIS [ISO-2022-JP]で出力

あー、これは、何もやってないことになります。
String#tojis というのは、与えられた文字列をJIS(ISO-2022-JP)に
変換した新しい文字列を返すものです。文字列 filename が置き換わる
ものではないですし、filenameの指すファイルの文字コードを変換する
ものでもありません。

> HTMLRegexp = /(<!--.*?--\s*>)|
> 						(<(?:[^"'>]*|"[^"]*"|'[^']*')+>)|
> 						([^<]*)/xmu
> 
> data = io.read # ファイルから読み込む
> 
> data.scan(HTMLRegexp){|match|
>   comment, tag, tdata = match[0..2]
>   if comment                              # コメントにマッチした場合
>     p [ "Comment", comment ]
>   elsif tag                               # タグにマッチした場合
> 		tag.gsub!(/\w/){|matched| matched.downcase } 
>     p [ "Tag", tag ]
>   elsif tdata                             # テキストデータにマッチした場合
>     tdata.gsub!(/\s+/, " ")               # 空白をまとめる
>     tdata.sub!(/ $/, "")                  # 末尾の空白を削除する
>     p [ "TextData", tdata ] unless tdata.empty?  # 空でなければ出力する
>   end
> 
> }

この辺りは、もうすでに気づいておられるようですが、「どういう
変換が行われるのか」を確認するためのものにはなっているものの、
「実際に変換してファイルに落とす」ものにはなっていません。

というわけで、新井さんのメールも参考にして、ちょっと
書いてみました。


require 'kconv'

ORIGINAL_DIR = "foo/bar"
OUTPUT_DIR = "outdir"
HTMLRegexp = /(<!--.*?--\s*>)|
              (<(?:[^"'>]*|"[^"]*"|'[^']*')+>)|
              ([^<]*)/xm

Dir.glob(ORIGINAL_DIR+"/*.html"){ |filename|  # ファイル読み込み

  File.open(filename, "r"){|f|                # ファイル・オープン
    outfilename = File.basename(filename)

    data = f.read                             # ファイルから読み込む
    buf = ""
    data.scan(HTMLRegexp){|match|
      comment, tag, tdata = match[0..2]
      if comment                              # コメントにマッチした場合
	p [ "Comment", comment ]
	buf << comment
      elsif tag                               # タグにマッチした場合
	tag.gsub!(/\w/){|matched| matched.downcase } 
	p [ "Tag", tag ]
	buf << tag
      elsif tdata                             # テキストデータにマッチした場合
        tdata.gsub!(/[ \t]+/, " ")            # 空白をまとめる
        tdata.gsub!(/ $/, "")                 # 末尾の空白を削除する
        tdata.gsub!(/\n+/, "\n")              # 改行をまとめる
	p [ "TextData", tdata ]
        buf << tdata
      end
    }

    File.open(OUTPUT_DIR+"/"+outfilename, "w"){|f2|
      f2.write(buf.tojis)
    }
  }

}



ご参考まで。

高橋征義 (TAKAHASHI Masayoshi)   E-mail: maki / rubycolor.org
……ばばっと書いたので、どっか間違っているところもあるかも(_o_)