dashcode-converter 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+