public
Rubygem
Fork of nex3/haml
Description: HTML Abstraction Markup Language - A Markup Haiku
Homepage: http://haml.hamptoncatlin.com
Clone URL: git://github.com/chriseppstein/haml.git
Search Repo:
:template_location now accepts a map of template locations to css output 
locations in addition to a string.
:css_location is ignored if :template location is a map.
chriseppstein (author)
Thu Jun 19 16:10:50 -0700 2008
commit  c6a29d7372aa99851e602ebd585659dc0c4213a2
tree    6c4bfe3f61acd7cfac72e69fd160399960ab951f
parent  f42e750f65c93c0cf6f0ee87f259b219f2d7491e
...
846
847
848
849
 
 
 
 
850
851
852
 
 
853
854
 
 
855
856
857
...
846
847
848
 
849
850
851
852
853
854
855
856
857
858
 
859
860
861
862
863
0
@@ -846,12 +846,18 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
0
 # Defaults to false in production mode, true otherwise.
0
 # Only has meaning within Ruby on Rails or Merb.
0
 #
0
-# [<tt>:template_location</tt>] The directory where Sass templates should be read from.
0
+# [<tt>:template_location</tt>] A path to the root sass template directory for you application.
0
+# If a hash, :css_location is ignored and this option designates
0
+# both a mapping between input and output directories.
0
+# May also be given a list of 2-element lists, instead of a hash.
0
 # Defaults to <tt>RAILS_ROOT + "/public/stylesheets/sass"</tt>
0
 # or <tt>MERB_ROOT + "/public/stylesheets/sass"</tt>.
0
 # Only has meaning within Ruby on Rails or Merb.
2
+# This will be derived from the :css_location path list if not provided
0
+# by appending a folder of "sass" to each corresponding css location.
0
 #
0
-# [<tt>:css_location</tt>] The directory where CSS output should be written to.
2
+# [<tt>:css_location</tt>] The colon(:) delimited path list where CSS output should be written to.
0
+# This option is ignored when :template_location is a Hash.
0
 # Defaults to <tt>RAILS_ROOT + "/public/stylesheets"</tt>
0
 # or <tt>MERB_ROOT + "/public/stylesheets"</tt>.
0
 # Only has meaning within Ruby on Rails or Merb.
...
7
8
9
10
11
12
13
...
34
35
36
37
38
39
40
41
 
 
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
 
 
 
 
 
 
 
 
74
 
75
76
77
78
79
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
84
85
...
96
97
98
99
100
101
102
 
 
 
 
 
 
 
 
103
104
105
...
121
122
123
124
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
127
128
129
 
 
130
131
132
133
134
135
136
137
 
 
 
 
138
139
140
141
142
 
 
 
143
144
145
...
7
8
9
 
10
11
12
...
33
34
35
 
 
 
 
 
36
37
38
39
40
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
 
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
...
135
136
137
 
 
 
 
138
139
140
141
142
143
144
145
146
147
148
...
164
165
166
 
 
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
 
 
183
184
185
186
187
188
189
190
 
 
191
192
193
194
195
196
 
 
 
197
198
199
200
201
202
0
@@ -7,7 +7,6 @@ module Sass
0
   module Plugin
0
     class << self
0
       @@options = {
0
- :template_location => './public/stylesheets/sass',
0
         :css_location => './public/stylesheets',
0
         :always_update => false,
0
         :always_check => true,
0
@@ -34,52 +33,92 @@ module Sass
0
         @@options.merge!(value)
0
       end
0
 
0
- # Checks each stylesheet in <tt>options[:css_location]</tt>
0
- # to see if it needs updating,
0
- # and updates it using the corresponding template
0
- # from <tt>options[:templates]</tt>
0
- # if it does.
0
+ # Checks each css stylesheet to see if it needs updating,
0
+ # and updates it using the corresponding sass template if it does.
0
       def update_stylesheets
0
         return if options[:never_update]
0
 
0
         @@checked_for_updates = true
0
- Dir.glob(File.join(options[:template_location], "**", "*.sass")).entries.each do |file|
0
-
0
- # Get the relative path to the file with no extension
0
- name = file.sub(options[:template_location] + "/", "")[0...-5]
0
-
0
- if !forbid_update?(name) && (options[:always_update] || stylesheet_needs_update?(name))
0
- css = css_filename(name)
0
- File.delete(css) if File.exists?(css)
0
-
0
- filename = template_filename(name)
0
- l_options = @@options.dup
0
- l_options[:filename] = filename
2
- l_options[:load_paths] = load_paths
0
- engine = Engine.new(File.read(filename), l_options)
0
- result = begin
0
- engine.render
0
- rescue Exception => e
0
- exception_string(e)
0
- end
0
-
0
- # Create any directories that might be necessary
0
- dirs = [l_options[:css_location]]
0
- name.split("/")[0...-1].each { |dir| dirs << "#{dirs[-1]}/#{dir}" }
0
- dirs.each { |dir| Dir.mkdir(dir) unless File.exist?(dir) }
0
-
0
- # Finally, write the file
0
- File.open(css, 'w') do |file|
0
- file.print(result)
0
+ template_location_map.each do |template_location, css_location|
0
+
0
+ Dir.glob(File.join(template_location, "**", "*.sass")).entries.each do |file|
0
+ # Get the relative path to the file with no extension
0
+ name = file.sub(template_location + "/", "")[0...-5]
0
+
0
+ if !forbid_update?(name) && (options[:always_update] || stylesheet_needs_update?(name, template_location, css_location))
0
+ update_stylesheet(name, template_location, css_location)
0
             end
0
+
0
           end
0
         end
0
       end
0
 
2
       private
0
 
0
+ def update_stylesheet(name, template_location, css_location)
0
+ css = css_filename(name, css_location)
0
+ File.delete(css) if File.exists?(css)
0
+
0
+ filename = template_filename(name, template_location)
0
+ l_options = @@options.dup
0
+ l_options[:filename] = filename
0
+ l_options[:load_paths] = load_paths
0
+ engine = Engine.new(File.read(filename), l_options)
0
+ result = begin
0
+ engine.render
0
+ rescue Exception => e
0
+ exception_string(e)
0
+ end
0
+
0
+ # Create any directories that might be necessary
0
+ mkpath(css_location,name)
0
+
0
+ # Finally, write the file
0
+ File.open(css, 'w') do |file|
0
+ file.print(result)
2
+ end
0
+ end
0
+
0
+ # Create any successive directories required to be able to write a file to: File.join(base,name)
0
+ def mkpath(base,name)
0
+ dirs = [base]
0
+ name.split(File::SEPARATOR)[0...-1].each { |dir| dirs << File.join(dirs[-1],dir) }
0
+ dirs.each { |dir| Dir.mkdir(dir) unless File.exist?(dir) }
0
+ end
0
+
0
       def load_paths
2
- (options[:load_paths] || []) + [options[:template_location]]
0
+ (options[:load_paths] || []) + template_locations
0
+ end
0
+
0
+ def template_locations
0
+ case location = (options[:template_location] || default_template_location)
0
+ when String
0
+ [location]
0
+ when Array
0
+ #in case we get passed a list of tuples.
0
+ location.map{ |t| t.first }
0
+ when Hash
0
+ location.keys
0
+ end
2
+ end
0
+
0
+ def css_locations
0
+ case options[:template_location]
0
+ when Hash
0
+ template_locations.map{ |m|options[:template_location][m] }
0
+ when Array
0
+ #in case we get passed a list of tuples.
0
+ options[:template_location].map{ |t| t.last }
0
+ else
2
+ Array(options[:css_location] || default_css_location)
0
+ end
0
+ end
0
+
0
+ # map of template locations to css locations
2
+ def template_location_map
0
+ template_locations.zip(css_locations).inject([]) do |memo, pair|
0
+ memo << [pair.first || memo.first.first, pair.last || memo.first.last]
0
+ end
0
       end
0
 
2
       def exception_string(e)
0
@@ -96,10 +135,14 @@ module Sass
0
                 e_string << "\n\n"
0
 
0
                 min = [e.sass_line - 5, 0].max
0
- File.read(e.sass_filename).rstrip.split("\n")[
0
- min .. e.sass_line + 5
0
- ].each_with_index do |line, i|
0
- e_string << "#{min + i + 1}: #{line}\n"
0
+ begin
0
+ File.read(e.sass_filename).rstrip.split("\n")[
0
+ min .. e.sass_line + 5
0
+ ].each_with_index do |line, i|
0
+ e_string << "#{min + i + 1}: #{line}\n"
0
+ end
2
+ rescue
0
+ e_string << "Couldn't read sass file: #{e.sass_filename}"
0
                 end
0
               end
0
             end
0
@@ -121,25 +164,39 @@ END
0
         end
0
       end
0
 
0
- def template_filename(name)
0
- "#{options[:template_location]}/#{name}.sass"
0
+ def default_css_location
0
+ Array(options[:css_location]).first
0
+ end
0
+
0
+ def default_template_location
0
+ if options[:template_location]
0
+ Array(options[:template_location]).first
0
+ else
2
+ File.join(default_css_location,'sass')
0
+ end
0
+ end
0
+
0
+ def template_filename(name, path = default_template_location)
0
+ "#{path}/#{name}.sass"
0
       end
0
 
0
- def css_filename(name)
0
- "#{options[:css_location]}/#{name}.css"
0
+ def css_filename(name, path = default_css_location)
0
+ "#{path}/#{name}.css"
0
       end
0
 
0
       def forbid_update?(name)
0
         name.sub(/^.*\//, '')[0] == ?_
0
       end
0
 
0
- def stylesheet_needs_update?(name)
0
- if !File.exists?(css_filename(name))
0
+ def stylesheet_needs_update?(name, template_path = default_template_location, css_path = default_css_location)
0
+ css_file = css_filename(name, css_path)
0
+ template_file = template_filename(name, template_path)
0
+ if !File.exists?(css_file)
0
           return true
0
         else
0
- css_mtime = File.mtime(css_filename(name))
0
- File.mtime(template_filename(name)) > css_mtime ||
0
- dependencies(template_filename(name)).any?(&dependency_updated?(css_mtime))
0
+ css_mtime = File.mtime(css_file)
2
+ File.mtime(template_file) > css_mtime ||
0
+ dependencies(template_file).any?(&dependency_updated?(css_mtime))
0
         end
0
       end
0
 
...
15
16
17
 
18
19
20
21
22
23
 
24
25
26
...
69
70
71
 
 
 
 
 
 
 
 
72
73
74
...
105
106
107
108
109
 
 
110
111
112
113
114
115
116
 
 
117
118
119
120
 
 
121
122
123
124
 
 
125
126
127
 
128
129
130
131
132
133
134
 
135
136
137
...
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
115
116
117
 
 
118
119
120
121
122
123
124
 
 
125
126
127
128
 
 
129
130
131
132
 
 
133
134
135
136
 
137
138
139
140
141
142
143
 
144
145
146
147
0
@@ -15,12 +15,14 @@ class SassPluginTest < Test::Unit::TestCase
0
 
0
   def setup
0
     FileUtils.mkdir File.dirname(__FILE__) + '/tmp'
0
+ FileUtils.mkdir File.dirname(__FILE__) + '/more_tmp'
0
     set_plugin_opts
0
     Sass::Plugin.update_stylesheets
0
   end
0
 
0
   def teardown
0
     FileUtils.rm_r File.dirname(__FILE__) + '/tmp'
0
+ FileUtils.rm_r File.dirname(__FILE__) + '/more_tmp'
0
   end
0
 
0
   def test_templates_should_render_correctly
0
@@ -69,6 +71,14 @@ class SassPluginTest < Test::Unit::TestCase
0
 
0
     Sass::Plugin.options[:full_exception] = true
0
   end
0
+
0
+ def test_two_template_directories
2
+ templates = ['templates', 'more_templates'].map{ |t| File.dirname(__FILE__) + "/#{t}" }
0
+ csses = ['tmp', 'more_tmp'].map{ |c| File.dirname(__FILE__) + "/#{c}" }
0
+ set_plugin_opts :template_location => templates.zip(csses)
0
+ Sass::Plugin.update_stylesheets
0
+ ['more1', 'more_import'].each { |name| assert_renders_correctly(name, 'more_') }
0
+ end
0
 
0
   def test_rails_update
0
     File.delete(tempfile_loc('basic'))
0
@@ -105,33 +115,33 @@ class SassPluginTest < Test::Unit::TestCase
0
 
0
  private
0
 
0
- def assert_renders_correctly(name)
0
- File.read(result_loc(name)).split("\n").zip(File.read(tempfile_loc(name)).split("\n")).each_with_index do |pair, line|
0
+ def assert_renders_correctly(name, prefix = nil)
0
+ File.read(result_loc(name,prefix)).split("\n").zip(File.read(tempfile_loc(name,prefix)).split("\n")).each_with_index do |pair, line|
0
       message = "template: #{name}\nline: #{line + 1}"
0
       assert_equal(pair.first, pair.last, message)
0
     end
0
   end
2
 
0
- def template_loc(name)
0
- File.dirname(__FILE__) + "/templates/#{name}.sass"
0
+ def template_loc(name, prefix = nil)
0
+ File.dirname(__FILE__) + "/#{prefix}templates/#{name}.sass"
0
   end
0
 
0
- def tempfile_loc(name)
0
- File.dirname(__FILE__) + "/tmp/#{name}.css"
0
+ def tempfile_loc(name, prefix = nil)
0
+ File.dirname(__FILE__) + "/#{prefix}tmp/#{name}.css"
0
   end
0
 
0
- def result_loc(name)
0
- File.dirname(__FILE__) + "/results/#{name}.css"
0
+ def result_loc(name, prefix = nil)
0
+ File.dirname(__FILE__) + "/#{prefix}results/#{name}.css"
0
   end
0
 
0
- def set_plugin_opts
0
+ def set_plugin_opts(overides = {})
0
     Sass::Plugin.options = {
0
       :template_location => File.dirname(__FILE__) + '/templates',
0
       :css_location => File.dirname(__FILE__) + '/tmp',
0
       :style => :compact,
3
       :load_paths => [File.dirname(__FILE__) + '/results'],
0
       :always_update => true,
0
- }
0
+ }.merge(overides)
0
   end
0
 end
0
 

Comments