require "hpricot" require "fileutils" module BridgeSupport class Parser def initialize(path_from, path_to) @doc = open(path_from) {|f| Hpricot(f).search('signatures').first} if @doc and @doc.children FileUtils.mkdir_p File.dirname(path_to) o = open(path_to, 'w') o.write(@doc.children.collect do |el| next if el.is_a?(Hpricot::Text) case el.name when 'class' then ClassDef.new(el).write('%s/%s.rb' % [File.dirname(path_to),el.attributes['name']]) when 'function' then FunctionDef.new(el).to_s when 'enum' then ConstantDef.new(el).to_s else BaseDef.new(el).to_s end end.compact.join("\n\n")) o.close end end end class BaseDef def initialize(el) @el = el end def to_s '# ' + @el.to_s.gsub("\n","\n# ") end def attr(key) @el.attributes[key] end def indent(str, n=2) n = ' '*n if n.is_a? Fixnum str = str.join("\n\n") if str.is_a? Array n + str.gsub("\n", "\n"+n) end end class ClassDef < BaseDef def to_s "class %s < NSObject\n%s\n\n%s\nend" % [attr('name'), indent(methods_def), indent(super)] end def methods_def @el.children.collect do |c| if c.name == 'method' BridgeSupport::MethodDef.new(c).to_s end end.compact end def write(path) FileUtils.mkdir_p(File.dirname(path)) open(path,'w') {|f| f.write(to_s)} end end class FunctionDef < BaseDef def retval r = @el.search('retval').first "%s [ %s ]" % [r.attributes['declared_type'], r.attributes['type']] end def to_s "def %s(%s) # => %s\n%s\nend" % [name, args.join(', '), retval, indent(super)] end def name attr('name') end def args @el.children.collect do |c| c.attributes['name'] if c.name == 'arg' end.compact end end class MethodDef < FunctionDef def to_s arg = args.join(', ') "def self.#{name}(#{arg}) end\n%s" % super end def messages attr('selector')[0..-1].split(':') end def name messages.first end def args msg = messages arg = @el.children.collect do |c| c.attributes['name'] if c.name == 'arg' end.compact arg.collect.with_index do |a,i| if i > 0 and msg and msg[i] "%s:%s" % [msg[i], a] else a end end end end class ConstantDef < BaseDef def to_s "%s = %s\n%s" % [attr('name'), attr('value'), super] end end end source_dir = '/Library/RubyMotion/data/5.1/BridgeSupport' destination_dir = '/Users/andrei/DropboxAndrei/Dropbox/Projects/iOS/BridgeSupport' Dir[source_dir + '/*.bridgesupport'].each do |f| p f BridgeSupport::Parser.new(f, destination_dir + '/%s/framework.rb' % File.basename(f,'.bridgesupport')) end