octopress-ink 1.0.0.alpha.44 → 1.0.0.alpha.45

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -6
  3. data/assets/docs/_plugin-template.markdown +9 -21
  4. data/assets/docs/creating-a-plugin.markdown +90 -12
  5. data/lib/octopress-ink/assets/asset.rb +55 -26
  6. data/lib/octopress-ink/assets/coffeescript.rb +22 -0
  7. data/lib/octopress-ink/assets/config.rb +12 -8
  8. data/lib/octopress-ink/assets/doc_page.rb +21 -18
  9. data/lib/octopress-ink/assets/file.rb +9 -7
  10. data/lib/octopress-ink/assets/javascript.rb +7 -0
  11. data/lib/octopress-ink/assets/layout.rb +3 -1
  12. data/lib/octopress-ink/assets/page.rb +12 -10
  13. data/lib/octopress-ink/assets/sass.rb +24 -17
  14. data/lib/octopress-ink/assets/stylesheet.rb +12 -6
  15. data/lib/octopress-ink/assets.rb +1 -4
  16. data/lib/octopress-ink/commands/helpers.rb +7 -4
  17. data/lib/octopress-ink/commands/init.rb +48 -0
  18. data/lib/octopress-ink/commands/list.rb +1 -1
  19. data/lib/octopress-ink/commands/new.rb +126 -49
  20. data/lib/octopress-ink/commands.rb +2 -0
  21. data/lib/octopress-ink/configuration.rb +18 -10
  22. data/lib/octopress-ink/filters.rb +4 -4
  23. data/lib/octopress-ink/generators/plugin_assets.rb +3 -2
  24. data/lib/octopress-ink/helpers/path.rb +4 -4
  25. data/lib/octopress-ink/jekyll/hooks.rb +123 -7
  26. data/lib/octopress-ink/jekyll/page.rb +3 -1
  27. data/lib/octopress-ink/plugin.rb +198 -165
  28. data/lib/octopress-ink/plugin_asset_pipeline.rb +172 -0
  29. data/lib/octopress-ink/plugins.rb +44 -168
  30. data/lib/octopress-ink/tags/javascript.rb +1 -1
  31. data/lib/octopress-ink/tags/render.rb +4 -2
  32. data/lib/octopress-ink/tags/stylesheet.rb +1 -1
  33. data/lib/octopress-ink/utils.rb +42 -0
  34. data/lib/octopress-ink/version.rb +1 -1
  35. data/lib/octopress-ink.rb +70 -34
  36. data/octopress-ink.gemspec +2 -2
  37. data/test/_combine_false.yml +4 -0
  38. data/test/_config.yml +1 -1
  39. data/test/combine_css/stylesheets/all-e10f647557c9d610df6df40a458bc823.css +15 -0
  40. data/test/{sass_expanded → combine_css}/stylesheets/print-0dc274efb4e3fba0ae71bd22eef6fb38.css +2 -4
  41. data/test/{concat_css_false → combine_css_false}/stylesheets/awesome-sauce/plugin-media-test.css +0 -0
  42. data/test/{concat_css_false → combine_css_false}/stylesheets/awesome-sauce/plugin-test.css +0 -0
  43. data/test/{concat_css_false → combine_css_false}/stylesheets/site.css +0 -0
  44. data/test/{concat_css_false → combine_css_false}/stylesheets/test.css +0 -0
  45. data/test/{concat_css_false → combine_css_false}/stylesheets/theme/theme-media-test.css +0 -0
  46. data/test/{concat_css_false → combine_css_false}/stylesheets/theme/theme-test.css +0 -0
  47. data/test/{concat_css_false → combine_css_false}/stylesheets/theme/theme-test2.css +0 -0
  48. data/test/combine_js/javascripts/all-d41d8cd98f00b204e9800998ecf8427e.js +7 -0
  49. data/test/{concat_js_false → combine_js_false}/javascripts/site.js +0 -0
  50. data/test/combine_js_false/javascripts/test.js +10 -0
  51. data/test/{concat_js_false → combine_js_false}/javascripts/theme/bar.js +0 -0
  52. data/test/{concat_js_false → combine_js_false}/javascripts/theme/foo.js +0 -0
  53. data/test/copy_layouts_pages/_copy/pages/two.md +0 -1
  54. data/test/copy_test/_copy/pages/two.md +0 -1
  55. data/test/copy_test/_copy/stylesheets/main.scss +4 -1
  56. data/test/expected/index.html +2 -2
  57. data/test/plugins/awesome-sauce/pages/b.html +0 -1
  58. data/test/plugins/awesome-sauce/plugin.rb +1 -1
  59. data/test/plugins/test-theme/javascripts/blah.coffee +1 -0
  60. data/test/plugins/test-theme/plugin.rb +1 -1
  61. data/test/plugins/test-theme/stylesheets/main.scss +4 -1
  62. data/test/source/_plugins/awesome-sauce/config.yml +1 -1
  63. data/test/source/_plugins/theme/config.yml +1 -1
  64. data/test/source/_posts/2014-02-01-test-post.md +1 -0
  65. data/test/source/index.md +2 -2
  66. data/test/test.rb +15 -27
  67. metadata +66 -84
  68. data/lib/octopress-ink/assets/local_asset.rb +0 -47
  69. data/lib/octopress-ink/assets/local_javascript.rb +0 -12
  70. data/lib/octopress-ink/assets/local_sass.rb +0 -30
  71. data/lib/octopress-ink/assets/local_stylesheet.rb +0 -33
  72. data/lib/octopress-ink/helpers/titlecase.rb +0 -37
  73. data/lib/octopress-ink/plugins/asset_pipeline.rb +0 -103
  74. data/test/_concat_false.yml +0 -2
  75. data/test/_sass_compact.yml +0 -4
  76. data/test/_sass_expanded.yml +0 -4
  77. data/test/concat_css/stylesheets/all-e10f647557c9d610df6df40a458bc823.css +0 -1
  78. data/test/concat_css/stylesheets/print-0dc274efb4e3fba0ae71bd22eef6fb38.css +0 -1
  79. data/test/concat_js/javascripts/all-d41d8cd98f00b204e9800998ecf8427e.js +0 -3
  80. data/test/sass_compact/stylesheets/all-e10f647557c9d610df6df40a458bc823.css +0 -18
  81. data/test/sass_compact/stylesheets/print-0dc274efb4e3fba0ae71bd22eef6fb38.css +0 -5
  82. data/test/sass_expanded/stylesheets/all-e10f647557c9d610df6df40a458bc823.css +0 -36
  83. data/test/source/_javascripts/site.js +0 -1
  84. data/test/source/_stylesheets/_foo.scss +0 -1
  85. data/test/source/_stylesheets/site.sass +0 -7
  86. data/test/source/_stylesheets/test.css +0 -1
@@ -12,8 +12,10 @@ module Octopress
12
12
  :layouts_dir, :stylesheets_dir, :javascripts_dir, :files_dir, :includes_dir, :images_dir,
13
13
  :layouts, :includes, :images, :fonts, :files, :pages, :docs
14
14
 
15
- def initialize(options={})
16
- DEFAULT_CONFIG.merge(options || configuration).each { |k,v| set_config(k,v) }
15
+ def initialize(options)
16
+ options = Jekyll::Utils.symbolize_hash_keys(options || configuration)
17
+
18
+ DEFAULT_CONFIG.merge(options).each { |k,v| set_config(k,v) }
17
19
 
18
20
  @layouts_dir = 'layouts'
19
21
  @files_dir = 'files'
@@ -28,7 +30,8 @@ module Octopress
28
30
  @layouts = []
29
31
  @includes = []
30
32
  @css = []
31
- @javascripts = []
33
+ @js = []
34
+ @coffee = []
32
35
  @images = []
33
36
  @sass = []
34
37
  @docs = []
@@ -38,17 +41,6 @@ module Octopress
38
41
  @slug ||= @name
39
42
  end
40
43
 
41
- def configuration; {}; end
42
-
43
- def set_config(name,value)
44
- instance_variable_set("@#{name}", value)
45
- instance_eval(<<-EOS, __FILE__, __LINE__ + 1)
46
- def #{name}
47
- @#{name}
48
- end
49
- EOS
50
- end
51
-
52
44
  def register
53
45
  unless @assets_path.nil?
54
46
  disable_assets
@@ -65,43 +57,25 @@ module Octopress
65
57
  end
66
58
  end
67
59
 
68
- def add_assets; end
69
-
70
- def stylesheets
71
- css.clone.concat sass_without_partials
60
+ # Themes should always have the slug "theme"
61
+ #
62
+ def slug
63
+ Filters.sluggify @type == 'theme' ? 'theme' : @slug
72
64
  end
73
65
 
74
- def config
75
- @config ||= Assets::Config.new(self, @config_file).read
76
- end
66
+ # Path where doc pages will be hosted
67
+ #
68
+ # - returns: String, eg: docs/plugins/plugin-slug
69
+ #
70
+ def docs_base_path
77
71
 
78
- def disable_assets
79
- disabled = []
80
- config['disable'] ||= {}
81
- config['disable'].each do |key,val|
82
- next unless can_disable.include? key
83
- if !!val == val
84
- disabled << key if val
85
- elsif val.is_a? Array
86
- val.each { |v| disabled << File.join(key, v) }
87
- elsif val.is_a? String
88
- disabled << File.join(key, val)
89
- end
72
+ if @type == 'theme'
73
+ base = 'theme'
74
+ else
75
+ base = File.join('plugins', slug)
90
76
  end
91
- config['disable'] = disabled
92
- end
93
77
 
94
- def disabled?(dir, file)
95
- config['disable'].include?(dir) || config['disable'].include?(File.join(dir, file))
96
- end
97
-
98
- def slug
99
- Filters.sluggify @type == 'theme' ? @type : @slug
100
- end
101
-
102
- def docs_base_path
103
- type = @type == 'plugin' ? 'plugins' : @type
104
- File.join('docs', type, slug)
78
+ File.join('docs', base)
105
79
  end
106
80
 
107
81
  # Docs pages for easy listing in an index
@@ -126,6 +100,94 @@ module Octopress
126
100
  end
127
101
  end
128
102
 
103
+ # List info about plugin's assets
104
+ #
105
+ # returs: String filled with asset info
106
+ #
107
+ def list(options={})
108
+ if options['minimal']
109
+ minimal_list
110
+ else
111
+ detailed_list(options)
112
+ end
113
+ end
114
+
115
+ # Add asset files which aren't disabled
116
+ #
117
+ def add_asset_files(options)
118
+ select_assets(options).each do |name, assets|
119
+ next if name == 'defaults'
120
+ assets.each {|file| file.add unless file.disabled? }
121
+ end
122
+ end
123
+
124
+ # Copy asset files to plugin override path
125
+ #
126
+ def copy_asset_files(path, options)
127
+ copied = []
128
+
129
+ select_assets(options).each do |name, assets|
130
+ next if name == 'docs'
131
+ assets.each { |a| copied << a.copy(path) }
132
+ end
133
+ copied
134
+ end
135
+
136
+ # stylesheets should include Sass and CSS
137
+ #
138
+ def stylesheets
139
+ css.clone.concat sass_without_partials
140
+ end
141
+
142
+ def javascripts
143
+ js.clone.concat coffee
144
+ end
145
+
146
+ # Plugin configuration
147
+ #
148
+ # returns: Hash of merged user and default config.yml files
149
+ #
150
+ def config
151
+ @config ||= defaults.read
152
+ end
153
+
154
+ # Remove files from Jekyll since they'll be proccessed by Ink instead
155
+ #
156
+ def remove_jekyll_assets(files)
157
+ files.each {|f| f.remove_jekyll_asset }
158
+ end
159
+
160
+ def include(file)
161
+ @includes.find{|i| i.filename == file }.path
162
+ end
163
+
164
+ private
165
+
166
+ def get_paths(files)
167
+ files.dup.map { |f| f.path }.compact
168
+ end
169
+
170
+ def disable_assets
171
+ disabled = []
172
+ config['disable'] ||= {}
173
+ config['disable'].each do |key,val|
174
+ next unless can_disable.include? key
175
+ if !!val == val
176
+ disabled << key if val
177
+ elsif val.is_a? Array
178
+ val.each { |v| disabled << File.join(key, v) }
179
+ elsif val.is_a? String
180
+ disabled << File.join(key, val)
181
+ end
182
+ end
183
+ config['disable'] = disabled
184
+ end
185
+
186
+ def defaults
187
+ @defaults ||= Assets::Config.new(self, @config_file)
188
+ end
189
+
190
+
129
191
  def can_disable
130
192
  [
131
193
  'pages',
@@ -133,6 +195,8 @@ module Octopress
133
195
  'css',
134
196
  'stylesheets',
135
197
  'javascripts',
198
+ 'js',
199
+ 'coffee',
136
200
  'images',
137
201
  'fonts',
138
202
  'files'
@@ -147,22 +211,49 @@ module Octopress
147
211
  'pages' => @pages,
148
212
  'sass' => @sass,
149
213
  'css' => @css,
150
- 'javascripts' => @javascripts,
214
+ 'js' => @js,
215
+ 'coffee' => @coffee,
151
216
  'images' => @images,
152
217
  'fonts' => @fonts,
153
- 'files' => @files
218
+ 'files' => @files,
219
+ 'defaults' => [@defaults]
154
220
  }
155
221
  end
222
+
223
+ # Return information about each asset
224
+ def assets_list(options)
225
+ message = ''
226
+ no_assets = []
156
227
 
157
- def info(options={})
158
- if options['minimal']
159
- minimal_info
160
- else
161
- detailed_info(options)
228
+ select_assets(options).each do |name, assets|
229
+ next if assets.compact.size == 0
230
+
231
+ case name
232
+ when 'docs'
233
+ header = "documentation: /#{docs_base_path}/"
234
+ message += asset_list(assets, header)
235
+ when 'defaults'
236
+ message += asset_list(assets, 'default configuration')
237
+ else
238
+ message += asset_list(assets, name)
239
+ end
240
+
241
+ message += "\n"
162
242
  end
243
+
244
+ message
163
245
  end
164
246
 
165
- def minimal_info
247
+ def asset_list(assets, heading)
248
+ list = " #{heading}:\n"
249
+ assets.each do |asset|
250
+ list += "#{asset.info}\n"
251
+ end
252
+
253
+ list
254
+ end
255
+
256
+ def minimal_list
166
257
  message = " #{@name}"
167
258
  message += " (#{slug})"
168
259
  message += " - v#{@version}" if @version
@@ -172,9 +263,9 @@ module Octopress
172
263
  message += "\n"
173
264
  end
174
265
 
175
- def detailed_info(options)
176
- asset_info = assets_info(options)
177
- return '' if asset_info.empty?
266
+ def detailed_list(options)
267
+ list = assets_list(options)
268
+ return '' if list.empty?
178
269
 
179
270
  name = "Plugin: #{@name}"
180
271
  name += " (theme)" if @type == 'theme'
@@ -195,7 +286,7 @@ module Octopress
195
286
  80.times { lines += '=' }
196
287
 
197
288
  message = "\n#{message}\n#{lines}\n"
198
- message += asset_info
289
+ message += list
199
290
  message += "\n"
200
291
  end
201
292
 
@@ -203,38 +294,6 @@ module Octopress
203
294
  line = "| #{line.ljust(76)} |"
204
295
  end
205
296
 
206
- # Return information about each asset
207
- def assets_info(options)
208
- message = ''
209
- no_assets = []
210
-
211
- if options['stylesheets']
212
- options['css'] = true
213
- options['sass'] = true
214
- options.delete('stylesheets')
215
- end
216
-
217
- select_assets(options).each do |name, assets|
218
- next if assets.size == 0
219
- if name == 'docs'
220
- message += " documentation: /#{docs_base_path}/\n"
221
- if assets.size > 1
222
- assets.each do |asset|
223
- message += " - #{asset.info}\n"
224
- end
225
- end
226
- else
227
- message += " #{name}:\n"
228
- assets.each do |asset|
229
- message += " - #{asset.info}\n"
230
- end
231
- end
232
- message += "\n"
233
- end
234
-
235
- message
236
- end
237
-
238
297
  # Return selected assets
239
298
  #
240
299
  # input: options (an array ['type',...], hash {'type'=>true}
@@ -243,19 +302,43 @@ module Octopress
243
302
  # Output a hash of assets instances {'files' => @files }
244
303
  #
245
304
  def select_assets(asset_types)
246
- # Accept options from the CLI (as a hash of asset: true)
305
+
306
+ # Accept options from the CLI (as a hash of asset_name: true)
247
307
  # Or from Ink modules as an array of asset names
248
308
  #
249
309
  if asset_types.is_a? Hash
310
+
311
+ # Show Sass and CSS when 'stylesheets' is chosen
312
+ if asset_types['stylesheets']
313
+ asset_types['css'] = true
314
+ asset_types['sass'] = true
315
+ asset_types.delete('stylesheets')
316
+ end
317
+
318
+ if asset_types['javascripts']
319
+ asset_types['js'] = true
320
+ asset_types['coffee'] = true
321
+ asset_types.delete('javascripts')
322
+ end
323
+
250
324
  asset_types = asset_types.keys
251
325
  end
252
326
 
253
- asset_types = [asset_types] if asset_types.is_a? String
327
+ # Args should allow a single asset as a string too
328
+ #
329
+ if asset_types.is_a? String
330
+ asset_types = [asset_types]
331
+ end
254
332
 
255
- # Remove options which don't belong
333
+ # Match asset_types against list of assets and
334
+ # remove asset_types which don't belong
256
335
  #
257
336
  asset_types.select!{|asset| assets.include?(asset)}
258
337
 
338
+ # If there are no asset_types, return all assets
339
+ # This will happen if list command is used with
340
+ # no filtering arguments
341
+ #
259
342
  if asset_types.nil? || asset_types.empty?
260
343
  assets
261
344
  else
@@ -298,7 +381,13 @@ module Octopress
298
381
  end
299
382
 
300
383
  def add_javascripts
301
- @javascripts = add_new_assets(@javascripts_dir, Assets::Javascript)
384
+ find_assets(@javascripts_dir).each do |asset|
385
+ if File.extname(asset) =~ /\.js$/
386
+ @js << Assets::Javascript.new(self, @javascripts_dir, asset)
387
+ elsif File.extname(asset) =~ /\.coffee$/
388
+ @coffee << Assets::Coffeescript.new(self, @javascripts_dir, asset)
389
+ end
390
+ end
302
391
  end
303
392
 
304
393
  def add_fonts
@@ -327,95 +416,39 @@ module Octopress
327
416
  Find.find(dir).to_a.reject {|f| File.directory? f }
328
417
  end
329
418
 
330
- #def add_css(file, media=nil)
331
- #@css << Assets::Stylesheet.new(self, @stylesheets_dir, file, media)
332
- #end
333
-
334
- #def add_sass(file, media=nil)
335
- #@sass << Assets::Sass.new(self, @sass_dir, file, media)
336
- #end
337
-
338
- #def add_css_files(files, media=nil)
339
- #files.each { |f| add_css(f, media) }
340
- #end
341
-
342
- #def add_sass_files(files, media=nil)
343
- #files.each { |f| add_sass(f, media) }
344
- #end
345
-
346
- def remove_jekyll_assets(files)
347
- files.each {|f| f.remove_jekyll_asset }
348
- end
349
-
350
- def add_asset_files(options)
351
- select_assets(options).each do |name, assets|
352
- assets.each {|file| file.add unless file.disabled? }
353
- end
354
- end
355
-
356
- def copy_asset_files(path, options)
357
- copied = []
358
-
359
- if options['stylesheets']
360
- options['css'] = true
361
- options['sass'] = true
362
- options.delete('stylesheets')
363
- end
364
-
365
- select_assets(options).each do |name, assets|
366
- next if name == 'docs'
367
- assets.each { |a| copied << a.copy(path) }
368
- end
369
- copied
370
- end
371
-
372
- def stylesheet_paths
373
- get_paths @css.reject{|f| f.disabled? }
374
- end
375
-
376
- def javascript_paths
377
- get_paths @javascripts.reject{|f| f.disabled? }
378
- end
379
-
380
- def stylesheet_tags
381
- get_tags @css.reject{|f| f.disabled? }
382
- end
383
-
384
419
  def css
385
- @css.reject{|f| f.disabled? }
420
+ @css.reject{|f| f.disabled? }.compact
386
421
  end
387
422
 
388
423
  def sass
389
- @sass.reject{|f| f.disabled? }
424
+ @sass.reject{|f| f.disabled? }.compact
390
425
  end
391
426
 
392
427
  def sass_without_partials
393
428
  sass.reject{|f| f.file =~ /^_/ }
394
429
  end
395
430
 
396
- def javascripts
397
- @javascripts.reject{|f| f.disabled? }
431
+ def js
432
+ @js.reject{|f| f.disabled? }.compact
398
433
  end
399
434
 
400
- def sass_tags
401
- get_tags @sass
435
+ def coffee
436
+ @coffee.reject{|f| f.disabled? }.compact
402
437
  end
403
438
 
404
- def javascript_tags
405
- get_tags @javascripts
406
- end
439
+ def configuration; {}; end
407
440
 
408
- def get_paths(files)
409
- files.dup.map { |f| f.path }.compact
441
+ def set_config(name, value)
442
+ instance_variable_set("@#{name}", value)
443
+ instance_eval(<<-EOS, __FILE__, __LINE__ + 1)
444
+ def #{name}
445
+ @#{name}
446
+ end
447
+ EOS
410
448
  end
411
449
 
412
- def get_tags(files)
413
- files.dup.map { |f| f.tag }
414
- end
450
+ def add_assets; end
415
451
 
416
- def include(file)
417
- @includes.find{|i| i.filename == file }.path
418
- end
419
452
  end
420
453
  end
421
454
  end
@@ -0,0 +1,172 @@
1
+ module Octopress
2
+ module Ink
3
+ module PluginAssetPipeline
4
+
5
+ # Compile CSS to take advantage of Sass's compression settings
6
+ #
7
+ def self.compile_css(content)
8
+ configs = sass_converter.sass_configs
9
+ configs[:syntax] = :scss
10
+
11
+ Sass.compile(content, configs)
12
+ end
13
+
14
+ def self.compile_sass(sass)
15
+ Sass.compile(sass.content, sass_configs(sass))
16
+ end
17
+
18
+ # Gets default Sass configuration hash from Jekyll
19
+ #
20
+ def self.sass_configs(sass)
21
+ configs = sass_converter.sass_configs
22
+
23
+ configs[:syntax] = sass.ext.sub(/^\./,'').to_sym
24
+
25
+ if sass.respond_to? :load_paths
26
+ configs[:load_paths] = sass.load_paths
27
+ end
28
+
29
+ configs
30
+ end
31
+
32
+ # Access Jekyll's built in Sass converter
33
+ #
34
+ def self.sass_converter
35
+ if @sass_converter
36
+ @sass_converter
37
+ else
38
+ Ink.site.converters.each do |c|
39
+ @sass_converter = c if c.kind_of?(Jekyll::Converters::Sass)
40
+ end
41
+ @sass_converter
42
+ end
43
+ end
44
+
45
+ # Return a link tag, for all plugins' stylesheets
46
+ #
47
+ def self.combined_stylesheet_tag
48
+ tags = ''
49
+ combine_stylesheets.keys.each do |media|
50
+ tags.concat "<link href='#{Filters.expand_url(combined_stylesheet_path(media))}' media='#{media}' rel='stylesheet' type='text/css'>"
51
+ end
52
+ tags
53
+ end
54
+
55
+ def self.combined_javascript_tag
56
+ unless combine_javascripts == ''
57
+ "<script src='#{Filters.expand_url(combined_javascript_path)}'></script>"
58
+ end
59
+ end
60
+
61
+
62
+ # Combine stylesheets from each plugin
63
+ #
64
+ # Returns a hash of stylesheets grouped by media types
65
+ #
66
+ # output: { 'screen' => 'body { background... }' }
67
+ #
68
+ def self.combine_stylesheets
69
+ if @combined_stylesheets
70
+ @combined_stylesheets
71
+ else
72
+ combined = {}
73
+
74
+ stylesheets.clone.each do |media,files|
75
+ files.each do |file|
76
+ header = "/* #{file.plugin.type.capitalize}: #{file.plugin.name} */"
77
+ combined[media] ||= ''
78
+ combined[media] << "#{header}\n" unless combined[media] =~ /#{file.plugin.name}/
79
+ combined[media] << file.read
80
+ end
81
+ end
82
+
83
+ @combined_stylesheets = combined
84
+ end
85
+ end
86
+
87
+ def self.write_combined_stylesheet
88
+ css = combine_stylesheets
89
+ css.keys.each do |media|
90
+ contents = compile_css(css[media])
91
+ contents = AutoprefixerRails.process(contents)
92
+ write_files(contents, combined_stylesheet_path(media))
93
+ end
94
+ end
95
+
96
+ def self.combined_stylesheet_path(media)
97
+ File.join('stylesheets', "#{media}-#{stylesheet_fingerprint(media)}.css")
98
+ end
99
+
100
+ def self.stylesheet_fingerprint(media)
101
+ @stylesheet_fingerprint ||= {}
102
+ @stylesheet_fingerprint[media] ||=
103
+ fingerprint(stylesheets[media].clone.map {|f| f.path })
104
+ end
105
+
106
+ # Get all plugins stylesheets
107
+ #
108
+ # Returns a hash of assets grouped by media
109
+ #
110
+ # output: { 'screen' => [Octopress::Ink::Assets::Stylesheet, ..]
111
+ #
112
+ def self.stylesheets
113
+ if @stylesheets
114
+ @stylesheets
115
+ else
116
+ files = {}
117
+ Plugins.plugins.clone.each do |plugin|
118
+ plugin.stylesheets.each do |file|
119
+ files[file.media] ||= []
120
+ files[file.media] << file
121
+ end
122
+ end
123
+ @stylesheets = files
124
+ end
125
+ end
126
+
127
+ def self.javascripts
128
+ @javascripts ||=
129
+ Plugins.plugins.clone.map { |p| p.javascripts }.flatten
130
+ end
131
+
132
+ def self.javascript_fingerprint
133
+ @javascript_fingerprint ||=
134
+ fingerprint(javascripts.clone.map {|f| f.path })
135
+ end
136
+
137
+ def self.combine_javascripts
138
+ if @combined_javascript
139
+ @combined_javascript
140
+ else
141
+ js = ""
142
+ javascripts.clone.each do |f|
143
+ unless js =~ /#{f.plugin.name}/
144
+ js += "/* #{f.plugin.type.capitalize}: #{f.plugin.name} */\n"
145
+ end
146
+ js += f.read
147
+ end
148
+ @combined_javascript = js
149
+ end
150
+ end
151
+
152
+ def self.combined_javascript_path
153
+ File.join('javascripts', "all-#{javascript_fingerprint}.js")
154
+ end
155
+
156
+ def self.write_combined_javascript
157
+ js = combine_javascripts
158
+ write_files(js, combined_javascript_path) unless js == ''
159
+ end
160
+
161
+ def self.write_files(source, dest)
162
+ Plugins.static_files << StaticFileContent.new(source, dest)
163
+ end
164
+
165
+ def self.fingerprint(paths)
166
+ paths = [paths] unless paths.is_a? Array
167
+ Digest::MD5.hexdigest(paths.clone.map! { |path| "#{File.mtime(path).to_i}" }.join)
168
+ end
169
+
170
+ end
171
+ end
172
+ end