SSブログ

min.jsなファイルを改行インデントして読みやすくするプログラム。 [プログラミング]

JavaScriptがダウンロードのかさを減らすために、人間が読みやすくするために入れたインデントや改行を除いたバージョンのライブラリファイルとかありますよね。ファイル名が*.min.jsなファイルの事です。それを読みやすいように改行インデントをサクッと終わらせたいと思った。面白い効果だなと思っても、jsファイルはコンパイルされているわけじゃないのに、可読性が著しく低くて悲しい思いをした人も多いでしょう。

今までやろうと思っていたんだけど誰かがやっていそうなのでやらなかった。そんなわけで重い腰を上げてググらずRubyでやってみようと思った。一度はなんとなく最近使っているGolangでやろうと思ったけど、Rubyでやった方がLLっぽくて楽できそうだ。

ふと思ったんだけど、*.min.jsなファイルはどうやって生成しているんだろう。そっちのほうが気になってきた。だって逆やればいいわけでしょ? ハードTabとスペースの文字列以外の空白文字と、改行文字をなくせばいいだけかもしれないけど、何かいい方法があるのだろうか。AWKとかのツールだけで事足りそうな気がしますね。これはどこかで定番コマンドとかありそうなので後で探しておこうかな。


とりあえず、セミコロンが出てきたら改行する。これは簡単だ。
;を;+改行に置換すればいい。そのあとは今までインデントしてきた分だけインデントする。

波かっこが出てきたら、改行してインデントするのも忘れてはいけないね。
考えれば考えるほど、SEDとかAWKで足りそうな気がしてならない。
インテリジェントな方法論でいければいいなぁ。

あとインデントをカウントして頭に空白行をつければいいかも。
{が来たら後ろに改行を入れて、インデントカウンタを+1してインデント。
}が来たら前に改行を入れて、インデントカウンタを-1してインデント。

これだけでもかなり見やすくなりそう。
ただオブジェクトがあるといちいち改行入れないほうがいい場合もあるだろう。
実際やってみて読みにくかったら処理を入れてみる。

それで何とか動くようにして見たコード。もっときれいに実装ができそうなもんだけど、String#indexを使おうとしたらしんどかったので、こんなになっちゃいました。jqueryのmin.jsを通したんだけど、そこそこインデントができていた。ただfor文の中身のセミコロンまで改行しているので、なかなか普通では見られないソースになってしまうところはある。完全に不完全w。

ちなみにRubyのバージョンは2.1.8で動かしました。
改行文字とインデント文字は最初のところで変えておくと大体反映されるはずです。てきと〜
#!/usr/bin/env ruby

indent_num = 0
indent = "  "
line_break = "\n"
write_name = "indented_" + ARGV[0]


open(write_name, "w") do |fi|
  open(ARGV[0]) do |f|
    fLines = f.readlines
    for fLine in fLines
      buf = ""
      cs = fLine.chars.to_a
      for c in cs
        if c == ";"
          buf << ( c + line_break + indent * indent_num )
        elsif c == "{"
          indent_num += 1
          buf << ( c + line_break + indent * indent_num )
        elsif c == "}"
          indent_num -= 1
          buf << ( line_break + indent * indent_num + c + line_break + indent * indent_num )
        else
          buf << c
        end
      end
      fi.write buf
    end
  end
end


まぁこの程度の行数だとそんなに高性能になるわけがないんだよね。そこそこ可読性が高くなる程度でした。改造の余地ありあり。なんか久しぶりにRubyのコードを書いた感じ。簡単な割には結構時間がかかった。使い方はruby hoehoe.rb jquery.min.js みたいな感じでやると、indented_jquery.min.jsと出力されます。

はじめはString#indexあたりを使ってやろうとしていたから、String#charsあたりで横着する方向性には考えが向かなかった。その後もcharsで分断した文字の配列を一つ一つ変更していこうと思ったら、for文のinのそれぞれの文字列に反映されなかった。for文のスコープの問題かな? それともそもそもRubyのfor文がそれを前提としてないとか。なんかすごい基本的なところでハマってるなw。少なくともinの前の変数が後の配列のコピーで参照ではないらしい。細かく調べりゃ済むんだろうけど、なんかしんどくなってきた。


そういやgofmtというツールがgolangにあったから、それを改造すればよかったのかも。gofmtはgoで書かれているのかな。その程度しか知らない。まぁC言語と似たようなもんだから、応用は効かせることはできそうな気はしている。と、調べもしないで囀ってると、また上から目線の揚げ足取りが来そうなのでここで止めておきましょうw。

文字列の扱いはここにあるものでなんとか行けそうだ。
 http://ashitani.jp/golangtips/tips_string.html
GolangはLLよりもC言語に近い部分が多いから、テキストの扱いとかは少々面倒なところが多そうだな。まぁそれも余裕が出来てからにしたいと思う。

タグ:Ruby JavaScript
コメント(0) 
共通テーマ:パソコン・インターネット

コメント 0