class Template2rails::Parser

Attributes

_csses[RW]
_images[RW]
_jses[RW]
asset_root[RW]
document[RW]
source_root[RW]

Public Class Methods

new(path) click to toggle source
# File lib/template2rails.rb, line 30
def initialize(path)
  path = File.expand_path(path)
  File.exists?(path) or raise Exception.new("File #{path} not found.")
  @source_root = File.dirname(path)
  @asset_root = Rails.root.join('vendor','assets')
  f = File.open(path)
  @document = Nokogiri::HTML(f)
  @_csses = @document.css('link[rel=stylesheet]').dup
  @_jses = @document.css('script[src]').dup
  @_images = @document.css('img[src]').dup
  f.close
end

Public Instance Methods

asset_file(file) click to toggle source
# File lib/template2rails.rb, line 102
def asset_file(file)
  case File.extname(file)
    when '.css';
      prefix = 'stylesheets'
    when '.js';
      prefix = 'javascripts'
    when '.ttf', '.eot', '.woff', '.otf';
      prefix = 'fonts'
    when '.jpg', '.jpeg', '.png', '.gif', '.bmp';
      prefix = 'images'
    else;
      prefix = 'miscellaneous'
  end
  
  file = file.gsub(/(\.{0,2}\/)*((assets|resources|fonts)\/)*([^\n]+)/, '\4')
end
asset_path(with_file = true) click to toggle source
# File lib/template2rails.rb, line 140
def asset_path(with_file = true)
  paths = []
  @_csses.each do |css|
    dir = with_file ? css['href'] : File.dirname(css['href']) 
    paths.push(dir) unless paths.include?(dir) 
  end
  @_jses.each do |js|
    dir = with_file ? js['src'] : File.dirname(js['src']) 
    paths.push(dir) unless paths.include?(dir) 
  end
  @_images.each do |img|
    dir = with_file ? img['src'] : File.dirname(img['src']) 
    paths.push(dir) unless paths.include?(dir) 
  end
  paths
end
copy_assets(asset_file) click to toggle source
# File lib/template2rails.rb, line 119
def copy_assets(asset_file)
  asset_file = asset_file.split(/[\?\#]/)[0]
  
  # skip net assets
  if asset_file =~ /(https?\:)?\/\/[^\n]+/
    return 
  end
  
  realpath = File.expand_path("#{@source_root}/#{asset_file}")
  raise Exception.new "Error while parsing #{asset_file}:\n\tFile #{realpath} not found."\
    unless File.exists?(realpath)
  
  realdir  = File.dirname(realpath)
  
  require 'fileutils'
  tgt = "#{@asset_root}/#{asset_file(asset_file)}"
  FileUtils.cp(realpath, tgt) if File.exists?(realpath)
  
  update_asset(tgt, File.dirname(asset_file))
end
prep_dirs() click to toggle source
# File lib/template2rails.rb, line 43
def prep_dirs
  require 'fileutils'
  FileUtils::rm_rf(@asset_root)
  asset_path(false).each do |path|
    # skip net assets
    if path =~ /(https?\:)?\/\/[^\n]+/
      next 
    end
    FileUtils::mkdir_p "#{@asset_root}/#{asset_file(path)}"
  end
end
to_rails() click to toggle source
# File lib/template2rails.rb, line 55
def to_rails
  begin
    # check for head and body tag
    @document.at_xpath("/html/head") or raise Exception.new("Will not convert HTML without HEAD")
    @document.at_xpath("/html/body") or raise Exception.new("Will not convert HTML without BODY")
    # prepare required directories
    prep_dirs
    # start copying assets
    
    asset_path(true).each do |path|
      copy_assets(path)
    end
    
    # convert html to rails
    transform('css')
    transform('js')
    transform('images')
    transform('content', {:menu => ENV['MENU'], :content => ENV['CONTENT']})
    
    apply
  rescue Exception => error
    puts "#{error.backtrace[0]}:\n\t#{error.message}"
  end
end
update_asset(asset, relativeTo) click to toggle source
# File lib/template2rails.rb, line 80
def update_asset(asset, relativeTo)
  asset = asset.split(/[\?\#]/)[0]
  ext = File.extname(asset)
  return unless ext =~ /\.(css)/
  require 'find'
  text = File.read(asset)
  unless text.match(REGEXES[ext][:rgx]).nil?
    tgt = nil
    new_contents = text.gsub(REGEXES[ext][:rgx]) do |link|
      in_url = $1
      file = in_url.split(/[\?\#]/)[0]
      source_file = File.expand_path("#{@source_root}/#{relativeTo}/#{file}")
      dest_file   = File.expand_path("#{@asset_root}/#{asset_file(relativeTo)}/#{file}")
      dest_dir    = File.dirname(dest_file)
      File.directory?(dest_dir) or FileUtils.mkdir_p(dest_dir)
      FileUtils.cp(source_file, dest_file) if File.exists?(source_file)
      "url(#{dest_file.sub(/.+assets\/[^\/]+\/([^\n]+)/, '/assets/\1')})"
    end
    File.open(asset, 'wb') do |file| file.puts new_contents end
  end
end

Private Instance Methods

apply() click to toggle source
# File lib/template2rails.rb, line 242
def apply
  File.open(
    Rails.root.join('app', 'views', 'layouts', 'application.html.erb'), 
    'wb'
  ) do |app_html|
    app_html.write(@document.to_html)
  end
end
csses() click to toggle source
# File lib/template2rails.rb, line 250
def csses
  @document.css('link[rel=stylesheet]')
end
images() click to toggle source
# File lib/template2rails.rb, line 256
def images
  @document.css('img[src]')
end
scripts() click to toggle source
# File lib/template2rails.rb, line 253
def scripts
  @document.css('script[src]')
end
transform(type, args = {}) click to toggle source
# File lib/template2rails.rb, line 158
def transform(type, args = {})
  raise Exception.new("Cannot select nil element") if type.nil?
  case type
    when 'content';
      raise Exception.new("Expecting MENU to be specified as ARGV") \
        if args[:menu].nil?
        
      raise Exception.new("Expecting CONTENT to be specified as ARGV") \
        if args[:content].nil?
          
      require 'fileutils'
          
      # process menu
      menu = @document.at_css(args[:menu])
      FileUtils::mkdir_p Rails.root.join('app', 'views', 'shared') \
        if not File.directory?(Rails.root.join('app', 'views', 'shared'))
      File.open(Rails.root.join('app', 'views', 'shared', '_menu.html.erb'), 'wb') do |f|
        f.write menu.inner_html
      end
      menu.inner_html = @document.create_cdata('<%= render "shared/menu" %>')
          
      # process content
      content = @document.at_css(args[:content])
      FileUtils::mkdir_p Rails.root.join('app', 'views', 'welcome') \
        if not File.directory?(Rails.root.join('app', 'views', 'welcome'))
      File.open(Rails.root.join('app', 'views', 'welcome', 'index.html.erb'), 'wb') do |f|
        f.write content.inner_html
      end
      content.inner_html = @document.create_cdata('<%= yield %>')
    when 'images';
      
      images.each do |link|
        img = link['src']
        next if img =~ /(https?\:)?\/\/[^\n]+/
        img = asset_file(img).split('/')
        img.shift
        img = img.join('/')
        attrs = ""
        link.keys.each do |attr|
          next if attr == 'src'
          attrs << "#{attr}: '#{link[attr]}', "
        end
        link.add_next_sibling(@document.create_cdata("<%= image_tag('#{img}', #{attrs[0..-1]}) %>"))
        link.remove
      end
    when 'css';
      csses.each do |link|
        link.remove
      end
      File.open(Rails.root.join('app', 'assets', 'stylesheets', 'application.css'), 'wb') do |app_css|
        @_csses.each do |link|
          link = link['href']
          next if link =~ /(https?\:)?\/\/[^\n]+/
          link = asset_file(link).split('/')
          link.shift
          link = link.join('/')
          app_css << "/*= require #{link} */\n"
        end
      end
      head = @document.css('head')
      head.children.first.add_next_sibling(
        @document.create_cdata('<%= stylesheet_link_tag "application", media: "all" %>')
      )
    when 'js';
      scripts.each do |link|
        link.remove
      end
      File.open(Rails.root.join('app', 'assets', 'stylesheets', 'post-application.js'), 'wb') do |app_js|
        @_jses.each do |link|
          link = link['src']
          next if link =~ /(https?\:)?\/\/[^\n]+/
          link = asset_file(link).split('/')
          link.shift
          link = link.join('/')
          app_js << "//= require #{link}\n"
        end
      end
      body = @document.css('body')
      bodyscript = @document.at_css("script:not([src])")
      (bodyscript || body.children.last).add_previous_sibling(
        @document.create_cdata('<%= javascript_include_tag "post-application" %>')
      )
  end
end