dashcode-converter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ out/*
data/README.markdown ADDED
@@ -0,0 +1,18 @@
1
+ # Dashcode Converter #
2
+
3
+ This tool converts Apple Dashcode projects into NIBs for use with the [Coherent Javascript framework](http://github.com/jeffwatkins/coherent/).
4
+
5
+ ## Installation ##
6
+
7
+ Like all Ruby Gems, installation is really simple:
8
+
9
+ $ gem install dashcode-converter
10
+
11
+ ## Usage ##
12
+
13
+ You can pass `dashcode-converter` either the path to a Dashcode project file (ending in .dcproj) or a folder that contains a Dashcode project file. For example:
14
+
15
+ $ dashcode-converter ~/Projects/RssReader.dcproj
16
+
17
+ This will create a Coherent NIB package in the `out` folder with the same name as the project. The NIB package will contain an HTML file, CSS file, copies of any images used by the project's HTML and CSS files, a controller class file, and a NIB definition.
18
+
data/Rakefile ADDED
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "dashcode-converter"
8
+ gem.summary = "Tool to convert Apple Dashcode projects into Coherent NIBs"
9
+ gem.description = ""
10
+ gem.email = "jeff@metrocat.org"
11
+ gem.homepage = "http://github.com/jeffwatkins/dashcode-converter"
12
+ gem.authors = ["Jeff Watkins"]
13
+ gem.add_dependency('json', '>= 1.4.3')
14
+ gem.add_dependency('nokogiri', '>=1.4.3.1')
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ # require 'rake/testtask'
23
+ # Rake::TestTask.new(:test) do |test|
24
+ # test.libs << 'lib' << 'test'
25
+ # test.pattern = 'test/**/test_*.rb'
26
+ # test.verbose = true
27
+ # end
28
+ #
29
+ # begin
30
+ # require 'rcov/rcovtask'
31
+ # Rcov::RcovTask.new do |test|
32
+ # test.libs << 'test'
33
+ # test.pattern = 'test/**/test_*.rb'
34
+ # test.verbose = true
35
+ # end
36
+ # rescue LoadError
37
+ # task :rcov do
38
+ # abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
39
+ # end
40
+ # end
41
+
42
+ task :push => "gemcutter:release"
43
+
44
+ task :test => :check_dependencies
45
+
46
+ task :default => :build
47
+
48
+ require 'rake/rdoctask'
49
+ Rake::RDocTask.new do |rdoc|
50
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "dashcode-converter #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+
4
+ module DashcodeConverter
5
+
6
+ LIB_DIR= File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
7
+ VENDOR_DIR= File.expand_path(File.join(File.dirname(__FILE__), "..", "vendor"))
8
+ APP_NAME= File.basename($0)
9
+
10
+ $:.unshift(LIB_DIR)
11
+
12
+ options= {
13
+ :namespace=>nil,
14
+ :output_folder=>File.expand_path('out')
15
+ }
16
+
17
+ optparser= OptionParser.new do |opts|
18
+ opts.banner= "Usage: #{APP_NAME} [options] PROJECT"
19
+ opts.on('--namespace NAMESPACE', "Define the namespace to contain classes and functions.") do |namespace|
20
+ options[:namespace]= namespace
21
+ end
22
+ opts.on('--dest FOLDER', "Specifies where should the output JSIB folder be located.") do |output_folder|
23
+ options[:output_folder]= output_folder
24
+ end
25
+ end
26
+
27
+ optparser.parse!
28
+
29
+ require 'dashcode-converter'
30
+
31
+ project_files= []
32
+
33
+ ARGV.each { |arg|
34
+ arg= File.expand_path(arg)
35
+ project_files += Dir.glob(File.join(arg, "*.dcproj")) if File.directory?(arg)
36
+ project_files << arg if File.fnmatch("*.dcproj", arg)
37
+ }
38
+
39
+ if project_files.empty?
40
+ puts optparser
41
+ exit 1
42
+ end
43
+
44
+ project_files.each { |project_path|
45
+ project= Project.new(project_path, options[:output_folder])
46
+ project.namespace= options[:namespace]
47
+ project.convert
48
+ }
49
+
50
+ end
51
+
@@ -0,0 +1,122 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>currentDocument</key>
6
+ <string>out/dash2coherent.jsnib/dash2coherent.js</string>
7
+ <key>documents</key>
8
+ <array>
9
+ <dict>
10
+ <key>expanded</key>
11
+ <true/>
12
+ <key>name</key>
13
+ <string>dashcode-converter</string>
14
+ <key>regexFolderFilter</key>
15
+ <string>!.*/(\.[^/]*|CVS|_darcs|_MTN|\{arch\}|blib|.*~\.nib|.*\.(framework|app|pbproj|pbxproj|xcode(proj)?|bundle))$</string>
16
+ <key>sourceDirectory</key>
17
+ <string></string>
18
+ </dict>
19
+ </array>
20
+ <key>fileHierarchyDrawerWidth</key>
21
+ <integer>270</integer>
22
+ <key>metaData</key>
23
+ <dict>
24
+ <key>README.markdown</key>
25
+ <dict>
26
+ <key>caret</key>
27
+ <dict>
28
+ <key>column</key>
29
+ <integer>0</integer>
30
+ <key>line</key>
31
+ <integer>18</integer>
32
+ </dict>
33
+ <key>firstVisibleColumn</key>
34
+ <integer>0</integer>
35
+ <key>firstVisibleLine</key>
36
+ <integer>0</integer>
37
+ </dict>
38
+ <key>lib/dashcode-converter/nib/collection-view.rb</key>
39
+ <dict>
40
+ <key>caret</key>
41
+ <dict>
42
+ <key>column</key>
43
+ <integer>15</integer>
44
+ <key>line</key>
45
+ <integer>31</integer>
46
+ </dict>
47
+ <key>firstVisibleColumn</key>
48
+ <integer>0</integer>
49
+ <key>firstVisibleLine</key>
50
+ <integer>0</integer>
51
+ </dict>
52
+ <key>lib/dashcode-converter/nib/nib-item.rb</key>
53
+ <dict>
54
+ <key>caret</key>
55
+ <dict>
56
+ <key>column</key>
57
+ <integer>0</integer>
58
+ <key>line</key>
59
+ <integer>51</integer>
60
+ </dict>
61
+ <key>firstVisibleColumn</key>
62
+ <integer>0</integer>
63
+ <key>firstVisibleLine</key>
64
+ <integer>23</integer>
65
+ </dict>
66
+ <key>out/dash2coherent.jsnib/Dash2coherentController.js</key>
67
+ <dict>
68
+ <key>caret</key>
69
+ <dict>
70
+ <key>column</key>
71
+ <integer>0</integer>
72
+ <key>line</key>
73
+ <integer>0</integer>
74
+ </dict>
75
+ <key>firstVisibleColumn</key>
76
+ <integer>0</integer>
77
+ <key>firstVisibleLine</key>
78
+ <integer>0</integer>
79
+ </dict>
80
+ <key>out/dash2coherent.jsnib/dash2coherent.css</key>
81
+ <dict>
82
+ <key>caret</key>
83
+ <dict>
84
+ <key>column</key>
85
+ <integer>9</integer>
86
+ <key>line</key>
87
+ <integer>384</integer>
88
+ </dict>
89
+ <key>firstVisibleColumn</key>
90
+ <integer>0</integer>
91
+ <key>firstVisibleLine</key>
92
+ <integer>196</integer>
93
+ </dict>
94
+ <key>out/dash2coherent.jsnib/dash2coherent.js</key>
95
+ <dict>
96
+ <key>caret</key>
97
+ <dict>
98
+ <key>column</key>
99
+ <integer>0</integer>
100
+ <key>line</key>
101
+ <integer>0</integer>
102
+ </dict>
103
+ <key>firstVisibleColumn</key>
104
+ <integer>0</integer>
105
+ <key>firstVisibleLine</key>
106
+ <integer>0</integer>
107
+ </dict>
108
+ </dict>
109
+ <key>openDocuments</key>
110
+ <array>
111
+ <string>out/dash2coherent.jsnib/dash2coherent.js</string>
112
+ <string>out/dash2coherent.jsnib/dash2coherent.css</string>
113
+ <string>out/dash2coherent.jsnib/Dash2coherentController.js</string>
114
+ <string>lib/dashcode-converter/nib/nib-item.rb</string>
115
+ <string>lib/dashcode-converter/nib/collection-view.rb</string>
116
+ </array>
117
+ <key>showFileHierarchyDrawer</key>
118
+ <false/>
119
+ <key>windowFrame</key>
120
+ <string>{{318, 0}, {1122, 878}}</string>
121
+ </dict>
122
+ </plist>
@@ -0,0 +1,45 @@
1
+ require 'json'
2
+ require 'nokogiri'
3
+ require 'erb'
4
+ require 'fileutils'
5
+
6
+ module DashcodeConverter
7
+
8
+ JSON_PARAMS= {
9
+ :indent=> " ",
10
+ :object_nl=> "\n",
11
+ :array_nl=> "\n",
12
+ :space=> " "
13
+ }
14
+
15
+ INDENT= " "
16
+
17
+ end
18
+
19
+ class JavascriptCode < String
20
+ def to_json(*options)
21
+ self
22
+ end
23
+ end
24
+
25
+ module Kernel
26
+ # A convenience factory method
27
+ def JavascriptCode(str)
28
+ JavascriptCode.new(str)
29
+ end
30
+ end
31
+
32
+ class String
33
+ def remove_indent
34
+ match= self.match(/(^\s+)/)
35
+ return self unless match
36
+ self.gsub(/^#{match[1]}/, '').strip
37
+ end
38
+ def indent(str)
39
+ self.gsub(/^/, str)
40
+ end
41
+ end
42
+
43
+ require 'dashcode-converter/controller'
44
+ require 'dashcode-converter/nib'
45
+ require 'dashcode-converter/project'
@@ -0,0 +1,33 @@
1
+ module DashcodeConverter
2
+
3
+ class Controller
4
+
5
+ DECL_TEMPLATE= <<-EOF
6
+ /*import coherent*/
7
+
8
+ <%=namespace%>.<%=name%>= Class.create(coherent.ViewController, {
9
+
10
+ <%=@methods.join(",\n").indent(INDENT)%>
11
+
12
+ });
13
+ EOF
14
+
15
+ attr_reader :name, :namespace
16
+
17
+ def initialize(name, namespace=nil)
18
+ @name= "#{name.capitalize}Controller"
19
+ @namespace= namespace || name
20
+ @methods= []
21
+ end
22
+
23
+ def add_action_method(name)
24
+ @methods << "#{name}: function(sender)\n{\n}"
25
+ end
26
+
27
+ def declaration
28
+ return @declaration if @declaration
29
+ @declaration= ERB.new(DECL_TEMPLATE.remove_indent).result binding
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,93 @@
1
+ module DashcodeConverter
2
+
3
+ module Nib
4
+
5
+ CLASSNAME_LOOKUP= {
6
+ "Text" => "View",
7
+ "PushButton" => "Button",
8
+ "List" => "CollectionView"
9
+ }
10
+
11
+ class Nib
12
+
13
+ DECL_TEMPLATE= <<-EOF
14
+ /*import coherent*/
15
+ NIB('<%=name%>', {
16
+
17
+ <%=items_array.join(",\n\n").indent(INDENT)%>,
18
+
19
+ 'owner': {
20
+ view: REF('<%=name%>')
21
+ }
22
+ });
23
+ EOF
24
+
25
+ attr_reader :name, :items, :views, :owner
26
+
27
+ def initialize(name, owner)
28
+ @name= name
29
+ @owner= owner
30
+ @items= {}
31
+ @views= []
32
+ end
33
+
34
+ def add_view(view)
35
+ items[view.name]= view
36
+ views << view
37
+ end
38
+
39
+ def add_view_from_path(path, name=@name)
40
+ view= View.new(name, parse(path), self)
41
+ add_view(view)
42
+ end
43
+
44
+ def add_datasources_from_path(path)
45
+ datasources= parse(path)
46
+ datasources.each { |name, datasource|
47
+ items[name]= NibItem.new(name, datasource, self)
48
+ }
49
+ end
50
+
51
+ def declaration
52
+ return @declaration if @declaration
53
+
54
+ items_array= items.map { |key, value| value.declaration }
55
+
56
+ @declaration= ERB.new(DECL_TEMPLATE.remove_indent).result binding
57
+ end
58
+
59
+ def parse(path)
60
+ in_json= false
61
+ json= "{\n"
62
+ text= File.read(path)
63
+ text.each { |line|
64
+ if in_json
65
+ json << line
66
+ next
67
+ end
68
+
69
+ next unless (line =~ /dashcodePartSpecs/ || line =~ /dashcodeDataSources/)
70
+ in_json= true
71
+ }
72
+ JSON.parse(json.gsub(/;$/,''))
73
+ end
74
+
75
+ def unique_name(basename)
76
+ index=0
77
+ name= basename
78
+ while items.include?(name)
79
+ index+=1
80
+ name= "#{basename}#{index}"
81
+ end
82
+ name
83
+ end
84
+
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+
91
+ require 'dashcode-converter/nib/nib-item'
92
+ require 'dashcode-converter/nib/view'
93
+ require 'dashcode-converter/nib/collection-view'
@@ -0,0 +1,41 @@
1
+ module DashcodeConverter
2
+
3
+ module Nib
4
+
5
+ class NibItem
6
+
7
+ def adjust_declaration_for_CollectionView(decl)
8
+ if decl.include?("dataArrayBinding")
9
+ decl.delete("dataArray")
10
+ decl["contentBinding"]= decl.delete("dataArrayBinding")
11
+ end
12
+
13
+ decl.delete("useDataSource")
14
+ decl.delete("sampleRows")
15
+ decl.delete("labelElementId")
16
+ decl.delete("listStyle")
17
+ decl["content"]= decl.delete("dataArray") if decl.include?("dataArray")
18
+ decl
19
+ end
20
+
21
+ # Need to fix up the bindings for CollectionViews because Coherent before
22
+ # version 3.0 used a whacky star notation for binding to values in the
23
+ # list view.
24
+ def fixup_html_for_CollectionView(html)
25
+ template= View.new(nib.unique_name("ItemTemplate"), nil, nib)
26
+ template.is_template= true
27
+ nib.add_view(template)
28
+ @spec["viewTemplate"]= JavascriptCode("REF('#{template.name}')")
29
+
30
+ html.css("[id]").each { |node|
31
+ next unless (item= view.items_by_id["##{node["id"]}"])
32
+ view.remove_item(item)
33
+ template.add_item(item)
34
+ }
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,80 @@
1
+ module DashcodeConverter
2
+ module Nib
3
+
4
+ class NibItem
5
+
6
+ attr_reader :name, :nib
7
+ attr_accessor :view
8
+
9
+ def initialize(name, spec, nib)
10
+ @name= name
11
+ @nib= nib
12
+ @view= nil
13
+ @spec= from_spec(spec)
14
+ end
15
+
16
+ def declaration
17
+ return @declaration if @declaration
18
+
19
+ values= @spec.to_json(JSON_PARAMS)
20
+ @declaration= "'#{name}': #{@classname}(#{values})"
21
+ end
22
+
23
+ def fixup_html(html)
24
+ if 'coherent.Button'==@classname
25
+ html.name='button'
26
+ end
27
+ if @spec.include?('text')
28
+ html.content= @spec.delete('text')
29
+ end
30
+
31
+ # allow class specific fixups
32
+ if self.respond_to?("fixup_html_for_#{@fixupname}")
33
+ self.send("fixup_html_for_#{@fixupname}", html)
34
+ end
35
+ end
36
+
37
+ def from_spec(spec)
38
+ nib_item= {}
39
+ spec.each { |key, value|
40
+ next if ["view", "Class", "propertyValues"].include?(key)
41
+
42
+ # translate Dashcode's onclick parameter into a target/action pair
43
+ if "onclick"==key
44
+ key="action"
45
+ nib_item["target"]= "owner"
46
+ nib.owner.add_action_method(value)
47
+ end
48
+
49
+ nib_item[key]= value
50
+ }
51
+ nib_item.merge!(spec['propertyValues']) if spec['propertyValues']
52
+
53
+ nib_item.each { |key, value|
54
+ # rewrite relative bindings to use representedObject which is the
55
+ # way this works in Coherent 3.0.
56
+ if key =~ /Binding$/ && value.include?("keypath")
57
+ value["keypath"]= value["keypath"].gsub(/^\*\./, "representedObject.")
58
+ end
59
+ }
60
+
61
+ parts= (spec['view']||spec['Class']).split(".")
62
+ if 2==parts.length
63
+ parts[0]= "coherent" if parts[0]=="DC"
64
+ parts[1]= CLASSNAME_LOOKUP[parts[1]] if CLASSNAME_LOOKUP.include?(parts[1])
65
+ end
66
+
67
+ @fixupname= parts[-1]
68
+
69
+ if self.respond_to?("adjust_declaration_for_#{@fixupname}")
70
+ nib_item= self.send("adjust_declaration_for_#{@fixupname}", nib_item)
71
+ end
72
+
73
+ @classname= parts.join(".")
74
+ nib_item
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,51 @@
1
+ module DashcodeConverter
2
+ module Nib
3
+
4
+ class View
5
+
6
+ DECL_TEMPLATE= <<-EOF
7
+ '<%=name%>': <%=is_template ? "VIEW_TEMPLATE" : "VIEW"%>({
8
+ <%=views.join(",\n\n").indent(INDENT)%>
9
+ })
10
+ EOF
11
+
12
+ attr_reader :name, :nib, :items, :items_by_id
13
+ attr_accessor :is_template
14
+
15
+ def initialize(name, spec, nib)
16
+ @name= name
17
+ @nib= nib
18
+ @items= []
19
+ @items_by_id= {}
20
+ from_spec(spec) if spec
21
+ end
22
+
23
+ def remove_item(item)
24
+ @items_by_id.delete(item.name)
25
+ @items.delete(item)
26
+ end
27
+
28
+ def add_item(item)
29
+ item.view= self
30
+ @items_by_id[item.name]= item
31
+ @items << item
32
+ end
33
+
34
+ def from_spec(spec)
35
+ spec.each { |id, part_spec|
36
+ item= NibItem.new("##{id}", part_spec, nib)
37
+ add_item(item)
38
+ }
39
+ end
40
+
41
+ def declaration
42
+ return @declaration if @declaration
43
+
44
+ views= items.map { |item| item.declaration }
45
+ @declaration= ERB.new(DECL_TEMPLATE.remove_indent).result binding
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,144 @@
1
+ module DashcodeConverter
2
+
3
+ CSS_IMAGE_URL_REGEX= /url\("?(.*\.(jpg|png|gif))"?\)/
4
+ BUNDLE_EXTENSION= "jsnib"
5
+
6
+ class Project
7
+
8
+ attr_accessor :namespace
9
+
10
+ def initialize(project_bundle, output_folder)
11
+ @project_bundle= File.expand_path(project_bundle)
12
+ @name= File.basename(@project_bundle, ".*")
13
+ @namespace= @name
14
+ @output_folder= File.expand_path(File.join(output_folder, "#{@name}.#{BUNDLE_EXTENSION}"))
15
+ @parts_spec_path= File.join(@project_bundle, "project", "safari", "Parts", "setup.js")
16
+ @datasources_spec_path= File.join(@project_bundle, "project", "Parts", "datasources.js")
17
+ @css_path= File.join(@project_bundle, "project", "safari", "main.css")
18
+ @markup_path= File.join(@project_bundle, "project", "index.html")
19
+ @images_folder= File.join(@output_folder, "images")
20
+ FileUtils.mkdir_p(@output_folder)
21
+ end
22
+
23
+ def path_relative_to_folder(path, folder)
24
+ path= File.expand_path(path)
25
+ outputFolder= File.expand_path(folder).to_s
26
+
27
+ # Remove leading slash and split into parts
28
+ file_parts= path.slice(1..-1).split('/');
29
+ output_parts= outputFolder.slice(1..-1).split('/');
30
+
31
+ common_prefix_length= 0
32
+
33
+ file_parts.each_index { |i|
34
+ common_prefix_length= i
35
+ break if file_parts[i]!=output_parts[i]
36
+ }
37
+
38
+ return '../'*(output_parts.length-common_prefix_length) + file_parts[common_prefix_length..-1].join('/')
39
+ end
40
+
41
+ def relative_path(path)
42
+ path_relative_to_folder(path, @output_folder)
43
+ end
44
+
45
+ def doc
46
+ return @doc if @doc
47
+
48
+ html= File.read(@markup_path)
49
+ @doc= Nokogiri::HTML(html)
50
+ end
51
+
52
+ def controller
53
+ return @controller if @controller
54
+ @controller= Controller.new(@name, @namespace)
55
+ end
56
+
57
+ def nib
58
+ return @nib if @nib
59
+
60
+ @nib= Nib::Nib.new(@name, controller)
61
+ @nib.add_view_from_path(@parts_spec_path)
62
+ @nib.add_datasources_from_path(@datasources_spec_path)
63
+ @nib
64
+ end
65
+
66
+ def css
67
+ text= File.read(@css_path)
68
+ dirname= File.dirname(@css_path)
69
+ text.gsub!(CSS_IMAGE_URL_REGEX) { |match|
70
+ image_file= File.join(dirname, $1)
71
+
72
+ if (!File.exists?(image_file))
73
+ match
74
+ else
75
+ new_image_file= File.join(@images_folder, File.basename(image_file))
76
+ FileUtils.mkdir_p(File.dirname(new_image_file))
77
+ FileUtils.cp image_file, new_image_file
78
+ "url(\"#{relative_path(new_image_file)}\")"
79
+ end
80
+ }
81
+ text
82
+ end
83
+
84
+ def fixup_html
85
+ base= doc.css("base")
86
+ base= base ? base.attribute("href") : nil
87
+
88
+ content= doc.css("body > *:first-child")[0]
89
+ content.traverse { |node|
90
+ next unless node.attributes
91
+ node.attributes.each { |attr, value|
92
+ if 0==attr.index("apple-")
93
+ node.remove_attribute(attr)
94
+ end
95
+ }
96
+ }
97
+
98
+ dirname= File.dirname(@markup_path)
99
+ dirname= File.join(dirname, base) if base
100
+
101
+ content.css("[src]").each { |node|
102
+ image_file= File.join(dirname, node.attribute('src'))
103
+ new_image_file= File.join(@images_folder, File.basename(image_file))
104
+ FileUtils.mkdir_p(File.dirname(new_image_file))
105
+ FileUtils.cp image_file, new_image_file
106
+ node["src"]= relative_path(new_image_file)
107
+ }
108
+
109
+ nib.views.each { |view|
110
+ # Use a copy of the view's items, because the iterator isn't stable if
111
+ # items are removed while iterating.
112
+ items= view.items.clone
113
+ items.each { |item|
114
+ html= doc.css(item.name)[0]
115
+ item.fixup_html(html)
116
+ }
117
+ }
118
+ end
119
+
120
+ def convert
121
+ fixup_html
122
+
123
+ FileUtils.mkdir_p(@output_folder)
124
+ FileUtils.mkdir_p(@images_folder)
125
+
126
+ Dir.chdir(@output_folder) do
127
+ File.open("#{@name.capitalize}Controller.js", "w") { |controller_file|
128
+ controller_file << controller.declaration
129
+ }
130
+ File.open("#{@name}.js", "w") { |nib_file|
131
+ nib_file << nib.declaration
132
+ }
133
+ File.open("#{@name}.css", "w") { |css_file|
134
+ css_file << css
135
+ }
136
+ File.open("#{@name}.html", "w") { |html_file|
137
+ html_file << doc.css("body > *:first-child")[0].serialize
138
+ }
139
+ end
140
+ end
141
+
142
+ end
143
+
144
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dashcode-converter
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Jeff Watkins
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-12 00:00:00 -07:00
19
+ default_executable: dashcode-converter
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: json
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 1
30
+ segments:
31
+ - 1
32
+ - 4
33
+ - 3
34
+ version: 1.4.3
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: nokogiri
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 113
46
+ segments:
47
+ - 1
48
+ - 4
49
+ - 3
50
+ - 1
51
+ version: 1.4.3.1
52
+ type: :runtime
53
+ version_requirements: *id002
54
+ description: ""
55
+ email: jeff@metrocat.org
56
+ executables:
57
+ - dashcode-converter
58
+ extensions: []
59
+
60
+ extra_rdoc_files:
61
+ - README.markdown
62
+ files:
63
+ - .gitignore
64
+ - README.markdown
65
+ - Rakefile
66
+ - VERSION
67
+ - bin/dashcode-converter
68
+ - dashcode-converter.tmproj
69
+ - lib/dashcode-converter.rb
70
+ - lib/dashcode-converter/controller.rb
71
+ - lib/dashcode-converter/nib.rb
72
+ - lib/dashcode-converter/nib/collection-view.rb
73
+ - lib/dashcode-converter/nib/nib-item.rb
74
+ - lib/dashcode-converter/nib/view.rb
75
+ - lib/dashcode-converter/project.rb
76
+ has_rdoc: true
77
+ homepage: http://github.com/jeffwatkins/dashcode-converter
78
+ licenses: []
79
+
80
+ post_install_message:
81
+ rdoc_options:
82
+ - --charset=UTF-8
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ hash: 3
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ requirements: []
104
+
105
+ rubyforge_project:
106
+ rubygems_version: 1.3.7
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: Tool to convert Apple Dashcode projects into Coherent NIBs
110
+ test_files: []
111
+