CSSテスタ

先日のリアルタイムなHTMLエディタ*1を見て、リアルタイムに更新されるCSSエディタも欲しいよな、と思ってwindows上のrubyででっちあげてみた。かなり手抜き。1からCSSを作るのではなくて、既存のCSSに手を加える用途を想定している。エディタというより、CSSの編集をすぐにIEで確認するためのもの。win32oleとERBを利用している。ERBは、CSSを編集するときに変数さえ使えないのが不満だったので、雛型として採用。

使い方

HTMLファイルとCSSファイルを用意して、HTMLファイル名とCSSファイル名を指定して、スクリプトを走らせると以下のような動作を行う。

  1. HTMLファイルはIEで開かれる。
  2. CSSファイルの雛型(ERB)がtxtに関連付けられたソフトで立ちあがる。
  3. ERBファイルが更新されるのを監視し、更新された場合は雛型からCSSファイルが生成された上、IEが自動的にリロードされる。スクリプトを止めるまで監視は続行される。

注意事項

このスクリプトはかなり気のきかないスクリプトです。以下諸注意。

  • ERBファイルは、デフォルトではCSSファイルをそのままコピーして生成されるので、自分でERB化してください。
  • CSSファイルは自動的に上書きされてしまうので、消したくないCSSファイルのときはあらかじめバックアップとっといてください。

-僕のcygwin環境にあわせて作られているので、cygwin特有のパスの変換コードがはいってる。その他の環境の方は、get_pathあたりをいじる必要があるかもしれません。

  • txtファイルに関連付けられたアプリを起動するために、"cmd /c start ファイル名"という外部命令を使っている。これがどれくらいの環境で動くのか不明。
  • 終了方法が用意されていない。強制終了かけてください。

動かしてみようという奇特な方は、以上をふまえて自己責任でお願いします。

更新履歴

  1. http://jp.rubyist.net/magazine/?0004-Win32OLEを参考にして、絶対パス取得に、Scripting.FileSystemObjectを使うようにした。M君情報提供ありがとう。これでcygwin用のコードがなくなってると思う。たぶん。

以下ソース

require 'win32ole'
require 'erb'
require 'fileutils.rb'

class CSSTester
  def initialize(htmlfile,cssfile,erbfile = nil)
    @ie = WIN32OLE.new('InternetExplorer.Application')
    @htmlfile = htmlfile
    @cssfile = cssfile
    raise "[#{@htmlfile}] not found" unless FileTest.exist?(@htmlfile)
    raise "[#{@cssfile}] not found" unless FileTest.exist?(@cssfile)
    @erbfile = erbfile || make_erb_filename(cssfile)
  end

  def make_erb_filename(cssfile)
    cssname = File.basename(cssfile)
    cssdir = File.dirname(cssfile)
    erbfilename = cssname.gsub(/\./,'_') + ".txt"
    return File.join(cssdir,erbfilename)
  end

  def get_path(filename)
    fso = WIN32OLE.new('Scripting.FileSystemObject')
    return fso.GetAbsolutePathName(filename)
  end

  def edit_start
    FileUtils.cp(@cssfile,@erbfile) unless FileTest.exist?(@erbfile)
    @ie.Navigate(get_path(@htmlfile))
    @ie.Visible = true
    system "cmd /c start #{@erbfile}"

    return CSSTester.watch(@erbfile) do
      erb_eval
      @ie.refresh2
      false
    end
  end

  def erb_eval
    erb = File.read(@erbfile)
    content = ERB.new(erb).result
    open(@cssfile,"w") do |f|
      f.puts content
    end
  end
  
  def self.watch(filename,interval=1)
    return Thread.start do
      oldtime = Time.now
      loop do
        sleep interval
        next if (newt = File.mtime(filename)) <= oldtime
        oldtime = newt
        break if yield oldtime
      end
    end
  end
end

if __FILE__ == $0
  htmlfile = ARGV.shift
  cssfile = ARGV.shift
  erbfile = ARGV.shift
  cssedit = CSSTester.new(htmlfile,cssfile,erbfile)
  cssedit.edit_start.join
end