mango 0.1.1 → 0.5.0.beta1

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.
Files changed (74) hide show
  1. data/.gitignore +6 -0
  2. data/.yardopts +6 -0
  3. data/README.mdown +62 -29
  4. data/Rakefile +62 -0
  5. data/VERSION +1 -0
  6. data/bin/mango +5 -0
  7. data/doc/HISTORY.mdown +71 -0
  8. data/doc/ROAD-MAP.mdown +10 -0
  9. data/lib/mango.rb +7 -0
  10. data/lib/mango/application.rb +334 -0
  11. data/lib/mango/content_page.rb +193 -0
  12. data/lib/mango/dependencies.rb +125 -0
  13. data/lib/mango/flavored_markdown.rb +82 -0
  14. data/lib/mango/rack/debugger.rb +22 -0
  15. data/lib/mango/runner.rb +95 -0
  16. data/lib/mango/templates/Gemfile +4 -0
  17. data/lib/mango/templates/README.md +1 -0
  18. data/lib/mango/templates/config.ru +4 -0
  19. data/lib/mango/templates/content/index.md +5 -0
  20. data/lib/mango/templates/themes/default/public/images/particles.gif +0 -0
  21. data/lib/mango/templates/themes/default/public/javascripts/fireworks.js +546 -0
  22. data/lib/mango/templates/themes/default/public/javascripts/timer.js +5 -0
  23. data/lib/mango/templates/themes/default/public/robots.txt +5 -0
  24. data/lib/mango/templates/themes/default/public/styles/fireworks.css +55 -0
  25. data/lib/mango/templates/themes/default/public/styles/reset.css +54 -0
  26. data/lib/mango/templates/themes/default/styles/screen.sass +17 -0
  27. data/lib/mango/templates/themes/default/views/404.haml +21 -0
  28. data/lib/mango/templates/themes/default/views/layout.haml +20 -0
  29. data/lib/mango/templates/themes/default/views/page.haml +3 -0
  30. data/lib/mango/version.rb +6 -0
  31. data/mango.gemspec +35 -0
  32. data/spec/app_root/content/about/index.haml +1 -0
  33. data/spec/app_root/content/about/us.haml +1 -0
  34. data/spec/app_root/content/engines/haml.haml +7 -0
  35. data/spec/app_root/content/engines/markdown.markdown +7 -0
  36. data/spec/app_root/content/engines/md.md +7 -0
  37. data/spec/app_root/content/engines/mdown.mdown +7 -0
  38. data/spec/app_root/content/index.haml +1 -0
  39. data/spec/app_root/content/override.haml +1 -0
  40. data/spec/app_root/content/page_with_missing_view.haml +4 -0
  41. data/spec/app_root/content/turner+hooch.haml +1 -0
  42. data/spec/app_root/security_hole.haml +1 -0
  43. data/spec/app_root/themes/default/public/default.css +3 -0
  44. data/spec/app_root/themes/default/public/images/index.html +10 -0
  45. data/spec/app_root/themes/default/public/images/ripe-mango.jpg +0 -0
  46. data/spec/app_root/themes/default/public/override +10 -0
  47. data/spec/app_root/themes/default/public/robots.txt +2 -0
  48. data/spec/app_root/themes/default/public/styles/override.css +3 -0
  49. data/spec/app_root/themes/default/public/styles/reset.css +27 -0
  50. data/spec/app_root/themes/default/public/styles/subfolder/another.css +3 -0
  51. data/spec/app_root/themes/default/security_hole.sass +1 -0
  52. data/spec/app_root/themes/default/security_hole.txt +1 -0
  53. data/spec/app_root/themes/default/styles/override.sass +2 -0
  54. data/spec/app_root/themes/default/styles/screen.sass +13 -0
  55. data/spec/app_root/themes/default/styles/subfolder/screen.sass +12 -0
  56. data/spec/app_root/themes/default/views/404.haml +7 -0
  57. data/spec/app_root/themes/default/views/layout.haml +7 -0
  58. data/spec/app_root/themes/default/views/page.haml +4 -0
  59. data/spec/mango/application/routing_content_pages_spec.rb +357 -0
  60. data/spec/mango/application/routing_public_files_spec.rb +181 -0
  61. data/spec/mango/application/routing_style_sheets_spec.rb +286 -0
  62. data/spec/mango/application_spec.rb +34 -0
  63. data/spec/mango/content_page/finding_spec.rb +213 -0
  64. data/spec/mango/content_page/initializing_spec.rb +298 -0
  65. data/spec/mango/content_page_spec.rb +44 -0
  66. data/spec/mango/dependencies_spec.rb +189 -0
  67. data/spec/mango/flavored_markdown_spec.rb +52 -0
  68. data/spec/mango/rack/debugger_spec.rb +114 -0
  69. data/spec/mango/version_spec.rb +18 -0
  70. data/spec/quality_spec.rb +32 -0
  71. data/spec/spec.opts +3 -0
  72. data/spec/spec_helper.rb +18 -0
  73. data/spec/support/matchers/malformed_whitespace_matchers.rb +60 -0
  74. metadata +304 -17
@@ -0,0 +1,193 @@
1
+ # encoding: UTF-8
2
+
3
+ require "bluecloth"
4
+ require "haml"
5
+ require "yaml"
6
+
7
+ module Mango
8
+ # `ContentPage` is a **model** class. An instance of `ContentPage` is the representation of a
9
+ # single content file. The primary responsiblity of `ContentPage` is to manage the conversion of
10
+ # user-generated data into HTML. It accomplishes this task by utilizing 3rd-party content
11
+ # engines, which convert easy-to-read, easy-to-write plain text and markup into structurally
12
+ # valid HTML.
13
+ #
14
+ # `ContentPage` instances have two primary components -- **a body** and some **attributes**.
15
+ # Each component is defined within a single content file.
16
+ #
17
+ # ### Example content file
18
+ #
19
+ # # mango_poem.markdown
20
+ # ---
21
+ # title: The Sin of Mango
22
+ # categories:
23
+ # - bad
24
+ # - poetry
25
+ # ---
26
+ # Mango is like a drug.
27
+ # You must have more and more and more of the Mango
28
+ # until there is no Mango left.
29
+ # Not even for Mango!
30
+ #
31
+ # Mangos aside, let's bring attention to a few important facets of this example and content files
32
+ # in general.
33
+ #
34
+ # 1. Content pages are stored as files on disk. Here, the file name is `mango_poem.markdown`.
35
+ # 2. Attributes are defined first, embedded within triple-dashed ("---") dividers.
36
+ # 3. The body comes second, nestled comfortably below the attributes header.
37
+ # 4. Attributes are key-value pairs, defined with [YAML](http://www.yaml.org/) formatting.
38
+ # 5. The body, in this example, is plain-text. Because of the file extension, it's interpretted
39
+ # as Markdown.
40
+ #
41
+ # ### The Body
42
+ #
43
+ # The body of a content file may be written using one of the following human-friendly formats:
44
+ #
45
+ # * [Markdown](http://daringfireball.net/projects/markdown/syntax) extended with
46
+ # `Mango::FlavoredMarkdown`
47
+ # * [Haml](http://haml-lang.com/)
48
+ #
49
+ # The content file's extension determines the body's formatting. For a complete list of content
50
+ # file formats and their extensions, see `Mango::ContentPage::CONTENT_ENGINES`
51
+ #
52
+ # `ContentPage` instances are expected to be passed along into the view template they define.
53
+ # Once in that scope, the instance can convert its body to HTML with the `#to_html` method:
54
+ #
55
+ # @content_page.to_html
56
+ #
57
+ # ### The Attributes
58
+ #
59
+ # Attributes are key-value pairs, defined with [YAML](http://www.yaml.org/) formatting.
60
+ #
61
+ # All `ContentPage` instances have a `view` attribute, even if one is not explicitly declared in
62
+ # the content file. This attribute is essential as it guides the `Mango::Application` to render
63
+ # the correct view template file.
64
+ #
65
+ # When declaring an explicit view template, only the base file name is important. **It's assumed
66
+ # that all view templates are in Haml format.** The default view template file name is defined
67
+ # by `Mango::ContentPage::DEFAULT["attributes"]`.
68
+ #
69
+ # Syntactic sugar has been added for accessing attribtues. For example:
70
+ #
71
+ # @content_page.attributes["title"]
72
+ #
73
+ # can be shortened to
74
+ #
75
+ # @content_page.title
76
+ #
77
+ # Again, `ContentPage` instances are expected to be passed along into the view template they
78
+ # define. With a `@content_page` instance in scope, accessing attributes inside a Haml template
79
+ # works like this:
80
+ #
81
+ # %title
82
+ # = @content_page.title
83
+ #
84
+ # @see Mango::FlavoredMarkdown
85
+ #
86
+ class ContentPage
87
+ class PageNotFound < RuntimeError; end
88
+
89
+ # Known content formats and their associated file extensions
90
+ CONTENT_ENGINES = {
91
+ :markdown => ["md", "mdown", "markdown"],
92
+ :haml => ["haml"]
93
+ }
94
+
95
+ # Default values for various accessors
96
+ DEFAULT = {
97
+ :attributes => { "view" => :page },
98
+ :body => "",
99
+ :content_engine => :markdown
100
+ }
101
+
102
+ # `String`
103
+ attr_reader :data
104
+ # `Hash`
105
+ attr_reader :attributes
106
+ # `String`
107
+ attr_reader :body
108
+ # `Symbol`
109
+ attr_reader :content_engine
110
+
111
+ # Creates a new instance by extracting the body and attributes from raw data. Any extracted
112
+ # components found are merged with their defaults.
113
+ #
114
+ # @param [String] data
115
+ # @param [Hash] options
116
+ # @option options [Symbol] :content_engine See `CONTENT_ENGINES` and `DEFAULT[:content_engine]`
117
+ #
118
+ def initialize(data, options = {})
119
+ @data = data
120
+ @content_engine = options.delete(:content_engine) || DEFAULT[:content_engine]
121
+
122
+ if self.data =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
123
+ @attributes = DEFAULT[:attributes].merge(YAML.load($1) || {})
124
+ @body = self.data[($1.size + $2.size)..-1]
125
+ else
126
+ @attributes = DEFAULT[:attributes]
127
+ @body = self.data || DEFAULT[:body]
128
+ end
129
+ end
130
+
131
+ # Create a new instance by searching for and reading a content file from disk. Content files
132
+ # are searched consecutively until a page with known content extension is found.
133
+ #
134
+ # @param [String] path_without_extension
135
+ # @raise [PageNotFound] Raised when a content page cannot be found
136
+ # @return [ContentPage] A new instance is created and returned when found
137
+ #
138
+ def self.find_by_path(path_without_extension)
139
+ CONTENT_ENGINES.each_pair do |content_engine, extensions|
140
+ extensions.each do |extension|
141
+ path = "#{path_without_extension}.#{extension}"
142
+ return new(File.read(path), :content_engine => content_engine) if File.exist?(path)
143
+ end
144
+ end
145
+
146
+ raise PageNotFound, "Unable to find content page for path -- #{path_without_extension}"
147
+ end
148
+
149
+ # Given a content engine, converts the body to HTML.
150
+ #
151
+ # @raise [RuntimeError] Raised when content engine is unknown
152
+ # @return [String] HTML from the conversion
153
+ #
154
+ def to_html
155
+ case content_engine
156
+ when :markdown
157
+ BlueCloth.new(Mango::FlavoredMarkdown.shake(body)).to_html
158
+ when :haml
159
+ Haml::Engine.new(body).to_html
160
+ else
161
+ raise "Unknown content engine -- #{content_engine}"
162
+ end
163
+ end
164
+
165
+ # Returns just the view template's base file name. It's assumed that all view templates are in
166
+ # Haml format.
167
+ #
168
+ # @example
169
+ # @content_page.attributes["view"] #=> "blog.haml"
170
+ # @content_page.view #=> :blog
171
+ #
172
+ # @return [Symbol] The view template's base file name.
173
+ #
174
+ def view
175
+ File.basename(attributes["view"], '.*').to_sym
176
+ end
177
+
178
+ # Adds syntactic suger for reading attributes.
179
+ #
180
+ # @example
181
+ # @content_page.title == @content_page.attributes["title"]
182
+ #
183
+ # @param [Symbol] method_name
184
+ # @raise [NoMethodError] Raised when there is no method name key in attributes
185
+ # @return [Object] Value of the method name attribute
186
+ #
187
+ def method_missing(method_name)
188
+ key = method_name.to_s
189
+ attributes.has_key?(key) ? attributes[key] : super
190
+ end
191
+
192
+ end
193
+ end
@@ -0,0 +1,125 @@
1
+ # encoding: UTF-8
2
+
3
+ module Mango
4
+ # `Mango::Dependencies` is a class-methods-only **singleton** class that performs both strict
5
+ # parse-time dependency checking and simple, elegant run-time dependency warning.
6
+ #
7
+ # My preferred mental model is to consider software library dependencies as a snapshot in time.
8
+ # I also make the assumption, sometimes incorrectly, that a newer version of a software library
9
+ # is not always a better version.
10
+ #
11
+ # `Mango::Dependencies` automatically enforces a strict parse-time check for the
12
+ # `REQUIRED_RUBY_VERSION` on both application and development processes for the `Mango` library.
13
+ # (i.e. `bin/mango`, `rake`, `spec`, etc) Because of this, I've ensured this file is
14
+ # syntactically compatible with Ruby 1.8.6 or higher.
15
+ #
16
+ # Currently, `Mango` does **not** enforce strict parse-time version checking on `DEVELOPMENT_GEMS`.
17
+ # In the future, I would like to experiment with using RubyGems and the `Kernel#gem` method to
18
+ # this end. For now, each developer is responsible for ensuring the correct versions of their
19
+ # necessary development gems are located in the `$LOAD_PATH` on their system.
20
+ #
21
+ # When a gem is required, but a `LoadError` is raised, and rescued, `Mango::Dependencies` can be
22
+ # incorporated into the process to warn a developer of missing development features. Even with a
23
+ # few methods -- `.create_warning_for` and `.warn_at_exit` -- users are automatically warned, in
24
+ # this case at the moment of termination, about gems that could not found be in the `$LOAD_PATH`.
25
+ # Using `Mango::Dependencies` is **not** a mandatory inclusion for all gem requirements, merely a
26
+ # guide to help developers quickly see obstacles in their path.
27
+ #
28
+ # @example Simple usage with the YARD gem
29
+ # begin
30
+ # require "yard"
31
+ # YARD::Rake::YardocTask.new(:yard)
32
+ # rescue LoadError => e
33
+ # Mango::Dependencies.create_warning_for(e)
34
+ # end
35
+ #
36
+ # @see Mango::Dependencies.create_warning_for
37
+ # @see Mango::Dependencies.warn_at_exit
38
+ class Dependencies
39
+ # For now, starting with Ruby 1.9.1 but I would like to experiment with compatibility with Ruby >= 1.9.1 in the future.
40
+ REQUIRED_RUBY_VERSION = "1.9.1"
41
+
42
+ # bluecloth is a hidden yard dependency for markdown support
43
+ DEVELOPMENT_GEMS = {
44
+ :"rack-test" => "0.5.4",
45
+ :rspec => "1.3.0",
46
+ :yard => "0.5.8",
47
+ :"yard-sinatra" => "0.5.0",
48
+ :bluecloth => "2.0.7"
49
+ }
50
+
51
+ FILE_NAME_TO_GEM_NAME = {
52
+ :"rack/test" => :"rack-test",
53
+ :"spec/rake/spectask" => :rspec,
54
+ :"yard/sinatra" => :"yard-sinatra"
55
+ }
56
+
57
+ # Empties the warnings cache. This method is called when the class is required.
58
+ def self.destroy_warnings
59
+ @@warnings_cache = []
60
+ end
61
+ destroy_warnings
62
+
63
+ # Creates and caches a warning from a `LoadError` exception. Warnings are only created for
64
+ # known development gem dependencies.
65
+ #
66
+ # @param [LoadError] error A rescued exception
67
+ # @raise [RuntimeError] Raised when the `LoadError` argument is an unknown development gem.
68
+ def self.create_warning_for(error)
69
+ pattern = %r{no such file to load -- ([\w\-\\/]*)}
70
+ error.message.match(pattern) do |match_data|
71
+ file_name = match_data[1].to_sym
72
+ gem_name = if DEVELOPMENT_GEMS.has_key?(file_name)
73
+ file_name
74
+ elsif FILE_NAME_TO_GEM_NAME.has_key?(file_name)
75
+ FILE_NAME_TO_GEM_NAME[file_name]
76
+ else
77
+ raise "Cannot create a dependency warning for unknown development gem -- #{file_name}"
78
+ end
79
+
80
+ @@warnings_cache << "#{gem_name} --version '#{DEVELOPMENT_GEMS[gem_name]}'"
81
+ end
82
+ end
83
+
84
+ # Displays a warning message to the user on the standard output channel if there are warnings
85
+ # to render.
86
+ #
87
+ # @example Sample warning message
88
+ # The following development gem dependencies could not be found. Without them, some available development features are missing:
89
+ # jeweler --version "1.4.0"
90
+ # rspec --version "1.3.0"
91
+ # yard --version "0.5.3"
92
+ # bluecloth --version "2.0.7"
93
+ def self.render_warnings
94
+ unless @@warnings_cache.empty?
95
+ message = []
96
+ message << "The following development gem dependencies could not be found. Without them, some available development features are missing:"
97
+ message += @@warnings_cache
98
+ puts "\n" + message.join("\n")
99
+ end
100
+ end
101
+
102
+ # Attaches a call to `render_warnings` to `Kernel#at_exit`
103
+ def self.warn_at_exit
104
+ at_exit { render_warnings }
105
+ end
106
+
107
+ private
108
+
109
+ # Checks that the version of the current Ruby process matches the `REQUIRED_RUBY_VERSION`.
110
+ # This method is automatically invoked at the first time this class is required, ensuring the
111
+ # correct Ruby version at parse-time.
112
+ #
113
+ # @param [String] ruby_version Useful for automated specifications. Defaults to `RUBY_VERSION`.
114
+ # @raise [SystemExit] Raised, with a message, when the process is using an incorrect version of Ruby.
115
+ def self.check_ruby_version(ruby_version = RUBY_VERSION)
116
+ unless ruby_version == REQUIRED_RUBY_VERSION
117
+ abort <<-ERROR
118
+ This library requires Ruby #{REQUIRED_RUBY_VERSION}, but you're using #{ruby_version}.
119
+ Please visit http://www.ruby-lang.org/ for installation instructions.
120
+ ERROR
121
+ end
122
+ end
123
+ check_ruby_version
124
+ end
125
+ end
@@ -0,0 +1,82 @@
1
+ require "digest/md5"
2
+
3
+ module Mango
4
+ # `Mango::FlavoredMarkdown` (MFM) is a subset of GithubFlavoredMarkdown (GFM). MFM adds a touch
5
+ # seasoning to the standard Markdown (SM) syntax.
6
+ #
7
+ # ## Differences from standard Markdown
8
+ #
9
+ # ### Newlines
10
+ #
11
+ # The biggest difference that MFM introduces is in the handling of linebreaks. With SM you can
12
+ # hard wrap paragraphs of text and they will be combined into a single paragraph. I find this to
13
+ # be the cause of a huge number of unintentional formatting errors. MFM treats newlines in
14
+ # paragraph-like content as real line breaks, which is probably what you intended.
15
+ #
16
+ # The next paragraph contains two phrases separated by a single newline character:
17
+ #
18
+ # Roses are red
19
+ # Violets are blue
20
+ #
21
+ # becomes
22
+ #
23
+ # Roses are red
24
+ # Violets are blue
25
+ #
26
+ # ### Multiple underscores in words
27
+ #
28
+ # It is not reasonable to italicize just part of a word, especially when you're dealing with code
29
+ # and names often appear with multiple underscores. Therefore, MFM ignores multiple underscores
30
+ # in words.
31
+ #
32
+ # perform_complicated_task
33
+ # do_this_and_do_that_and_another_thing
34
+ #
35
+ # becomes
36
+ #
37
+ # perform_complicated_task
38
+ # do_this_and_do_that_and_another_thing
39
+ #
40
+ # @see http://github.github.com/github-flavored-markdown/
41
+ # @see http://daringfireball.net/projects/markdown/syntax
42
+ #
43
+ class FlavoredMarkdown
44
+ # For maximum flavor, add one shake of seasoning to markdown text **before** cooking with a
45
+ # Markdown engine.
46
+ #
47
+ # @example Cooking with BlueCloth
48
+ #
49
+ # BlueCloth.new(Mango::FlavoredMarkdown.shake(text)).to_html
50
+ #
51
+ # @param [String] text
52
+ # @return [String] Seasoned text that is ready to cook!
53
+ #
54
+ def self.shake(text)
55
+ # Extract pre blocks
56
+ extractions = {}
57
+ text.gsub!(%r{<pre>.*?</pre>}m) do |match|
58
+ md5 = Digest::MD5.hexdigest(match)
59
+ extractions[md5] = match
60
+ "{gfm-extraction-#{md5}}"
61
+ end
62
+
63
+ # prevent foo_bar_baz from ending up with an italic word in the middle
64
+ text.gsub!(/(^(?! {4}|\t)\w+_\w+_\w[\w_]*)/) do |x|
65
+ x.gsub("_", '\_') if x.split('').sort.join[0..1] == "__"
66
+ end
67
+
68
+ # in very clear cases, let newlines become <br /> tags
69
+ text.gsub!(/^[\w\<][^\n]*\n+/) do |x|
70
+ x =~ /\n{2}/ ? x : (x.strip!; x << " \n")
71
+ end
72
+
73
+ # Insert pre block extractions
74
+ text.gsub!(/\{gfm-extraction-([0-9a-f]{32})\}/) do
75
+ "\n\n" + extractions[$1]
76
+ end
77
+
78
+ text
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+ module Mango
3
+ module Rack
4
+ class Debugger
5
+ def initialize(app, kernel = Kernel, ruby_version = RUBY_VERSION)
6
+ @app = app
7
+ kernel.require "ruby-debug"
8
+ ::Debugger.start
9
+ puts "=> Debugger enabled"
10
+ rescue LoadError
11
+ gem_name = (ruby_version >= "1.9" ? "ruby-debug19" : "ruby-debug")
12
+ puts "=> Debugger not enabled"
13
+ puts "=> The #{gem_name} library is required to run the server in debugging mode."
14
+ puts "=> With RubyGems, use 'gem install #{gem_name}' to install the library."
15
+ end
16
+
17
+ def call(env)
18
+ @app.call(env)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,95 @@
1
+ # encoding: UTF-8
2
+ require "thor"
3
+
4
+ module Mango
5
+ class Runner < Thor
6
+ include Thor::Actions
7
+
8
+ add_runtime_options!
9
+
10
+ source_root File.join(File.dirname(__FILE__), "templates")
11
+
12
+ desc "create /path/to/your/app",
13
+ "Creates a new Mango application with a default directory structure and configuration at the path you specify."
14
+ def create(destination)
15
+ self.destination_root = destination
16
+ copy_file("config.ru", File.join(self.destination_root, "config.ru"))
17
+ copy_file("Gemfile", File.join(self.destination_root, "Gemfile"))
18
+ copy_file("README.md", File.join(self.destination_root, "README.md"))
19
+
20
+ build_content_path
21
+ build_themes_path
22
+ end
23
+
24
+ ###############################################################################################
25
+
26
+ protected
27
+
28
+ def build_content_path
29
+ content_root = File.join(self.destination_root, "content")
30
+ empty_directory(content_root)
31
+ copy_file("content/index.md", File.join(content_root, "index.md"))
32
+ end
33
+
34
+ def build_themes_path
35
+ themes_root = File.join(self.destination_root, "themes")
36
+ empty_directory(themes_root)
37
+
38
+ default_root = File.join(themes_root, "default")
39
+ empty_directory(default_root)
40
+
41
+ build_public_path default_root
42
+ build_styles_path default_root
43
+ build_views_path default_root
44
+ end
45
+
46
+ ###############################################################################################
47
+
48
+ protected
49
+
50
+ def build_public_path(destination)
51
+ public_root = File.join(destination, "public")
52
+ empty_directory(public_root)
53
+ create_file(File.join(public_root, "favicon.ico"))
54
+ copy_file("themes/default/public/robots.txt", File.join(public_root, "robots.txt"))
55
+
56
+ build_public_images_path public_root
57
+ build_public_javascripts_path public_root
58
+ build_public_styles_path public_root
59
+ end
60
+
61
+ def build_public_images_path(destination)
62
+ public_images_root = File.join(destination, "images")
63
+ empty_directory(public_images_root)
64
+ copy_file("themes/default/public/images/particles.gif", File.join(public_images_root, "particles.gif"))
65
+ end
66
+
67
+ def build_public_javascripts_path(destination)
68
+ public_javascripts_root = File.join(destination, "javascripts")
69
+ empty_directory(public_javascripts_root)
70
+ copy_file("themes/default/public/javascripts/fireworks.js", File.join(public_javascripts_root, "fireworks.js"))
71
+ copy_file("themes/default/public/javascripts/timer.js", File.join(public_javascripts_root, "timer.js"))
72
+ end
73
+
74
+ def build_public_styles_path(destination)
75
+ public_styles_root = File.join(destination, "styles")
76
+ empty_directory(public_styles_root)
77
+ copy_file("themes/default/public/styles/fireworks.css", File.join(public_styles_root, "fireworks.css"))
78
+ copy_file("themes/default/public/styles/reset.css", File.join(public_styles_root, "reset.css"))
79
+ end
80
+
81
+ def build_styles_path(destination)
82
+ styles_root = File.join(destination, "styles")
83
+ empty_directory(styles_root)
84
+ copy_file("themes/default/styles/screen.sass", File.join(styles_root, "screen.sass"))
85
+ end
86
+
87
+ def build_views_path(destination)
88
+ views_root = File.join(destination, "views")
89
+ empty_directory(views_root)
90
+ copy_file("themes/default/views/404.haml", File.join(views_root, "404.haml"))
91
+ copy_file("themes/default/views/layout.haml", File.join(views_root, "layout.haml"))
92
+ copy_file("themes/default/views/page.haml", File.join(views_root, "page.haml"))
93
+ end
94
+ end
95
+ end