rake-pipeline-web-filters-fork 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/.gitignore +19 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +11 -0
  4. data/.yardopts +2 -0
  5. data/Gemfile +6 -0
  6. data/README.markdown +58 -0
  7. data/README.yard +25 -0
  8. data/Rakefile +10 -0
  9. data/lib/rake-pipeline-web-filters.rb +31 -0
  10. data/lib/rake-pipeline-web-filters/cache_buster_filter.rb +42 -0
  11. data/lib/rake-pipeline-web-filters/chained_filter.rb +116 -0
  12. data/lib/rake-pipeline-web-filters/coffee_script_filter.rb +41 -0
  13. data/lib/rake-pipeline-web-filters/filter_with_dependencies.rb +27 -0
  14. data/lib/rake-pipeline-web-filters/gzip_filter.rb +59 -0
  15. data/lib/rake-pipeline-web-filters/handlebars_filter.rb +62 -0
  16. data/lib/rake-pipeline-web-filters/helpers.rb +138 -0
  17. data/lib/rake-pipeline-web-filters/iife_filter.rb +38 -0
  18. data/lib/rake-pipeline-web-filters/jade_filter.rb +61 -0
  19. data/lib/rake-pipeline-web-filters/less_filter.rb +55 -0
  20. data/lib/rake-pipeline-web-filters/markdown_filter.rb +70 -0
  21. data/lib/rake-pipeline-web-filters/minispade_filter.rb +63 -0
  22. data/lib/rake-pipeline-web-filters/neuter_filter.rb +110 -0
  23. data/lib/rake-pipeline-web-filters/sass_filter.rb +87 -0
  24. data/lib/rake-pipeline-web-filters/stylus_filter.rb +59 -0
  25. data/lib/rake-pipeline-web-filters/tilt_filter.rb +70 -0
  26. data/lib/rake-pipeline-web-filters/uglify_filter.rb +82 -0
  27. data/lib/rake-pipeline-web-filters/version.rb +9 -0
  28. data/lib/rake-pipeline-web-filters/yui_css_filter.rb +70 -0
  29. data/lib/rake-pipeline-web-filters/yui_javascript_filter.rb +59 -0
  30. data/rake-pipeline-web-filters.gemspec +33 -0
  31. data/spec/cache_buster_filter_spec.rb +108 -0
  32. data/spec/chained_filter_spec.rb +79 -0
  33. data/spec/coffee_script_filter_spec.rb +113 -0
  34. data/spec/gzip_filter_spec.rb +52 -0
  35. data/spec/handlebars_filter_spec.rb +73 -0
  36. data/spec/helpers_spec.rb +146 -0
  37. data/spec/iife_filter_spec.rb +58 -0
  38. data/spec/jade_filter_spec.rb +92 -0
  39. data/spec/less_filter_spec.rb +62 -0
  40. data/spec/markdown_filter_spec.rb +89 -0
  41. data/spec/minispade_filter_spec.rb +82 -0
  42. data/spec/neuter_filter_spec.rb +216 -0
  43. data/spec/sass_filter_spec.rb +152 -0
  44. data/spec/spec_helper.rb +28 -0
  45. data/spec/stylus_filter_spec.rb +72 -0
  46. data/spec/support/spec_helpers/file_utils.rb +33 -0
  47. data/spec/support/spec_helpers/filters.rb +37 -0
  48. data/spec/support/spec_helpers/input_helpers.rb +23 -0
  49. data/spec/support/spec_helpers/memory_file_wrapper.rb +38 -0
  50. data/spec/support/spec_helpers/memory_manifest.rb +19 -0
  51. data/spec/tilt_filter_spec.rb +82 -0
  52. data/spec/uglify_filter_spec.rb +128 -0
  53. data/spec/yui_css_filter_spec.rb +91 -0
  54. data/spec/yui_javascript_filter_spec.rb +71 -0
  55. metadata +308 -0
@@ -0,0 +1,62 @@
1
+ module Rake::Pipeline::Web::Filters
2
+ # A filter that converts handlebars templates to javascript
3
+ # and stores them in a defined variable.
4
+ #
5
+ # @example
6
+ # !!!ruby
7
+ # Rake::Pipeline.build do
8
+ # input "**/*.handlebars"
9
+ # output "public"
10
+ #
11
+ # # Compile each handlebars file to JS
12
+ # handlebars
13
+ # end
14
+ class HandlebarsFilter < Rake::Pipeline::Filter
15
+
16
+ include Rake::Pipeline::Web::Filters::FilterWithDependencies
17
+
18
+ # @return [Hash] a hash of options for generate_output
19
+ attr_reader :options
20
+
21
+ # @param [Hash] options
22
+ # options to pass to the output generator
23
+ # @option options [Array] :target
24
+ # the variable to store templates in
25
+ # @option options [Array] :compile_open
26
+ # the js to wrap template contents in
27
+ # @option options [Array] :compile_close
28
+ # the js to wrap template contents in
29
+ # @param [Proc] block a block to use as the Filter's
30
+ # {#output_name_generator}.
31
+ def initialize(options={},&block)
32
+ # Convert .handlebars file extensions to .js
33
+ block ||= proc { |input| input.sub(/\.handlebars|\.hbs$/, '.js') }
34
+ super(&block)
35
+ @options = {
36
+ :target =>'Ember.TEMPLATES',
37
+ :wrapper_proc => proc { |source| "Ember.Handlebars.compile(#{source});" },
38
+ :key_name_proc => proc { |input| File.basename(input.path, File.extname(input.path)) }
39
+ }.merge(options)
40
+ end
41
+
42
+ def generate_output(inputs, output)
43
+
44
+ inputs.each do |input|
45
+ # The name of the template is the filename, sans extension
46
+ name = options[:key_name_proc].call(input)
47
+
48
+ # Read the file and escape it so it's a valid JS string
49
+ source = input.read.to_json
50
+
51
+ # Write out a JS file, saved to target, wrapped in compiler
52
+ output.write "#{options[:target]}['#{name}']=#{options[:wrapper_proc].call(source)}"
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def external_dependencies
59
+ [ 'json' ]
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,138 @@
1
+ module Rake::Pipeline::Web::Filters
2
+ # Extends the Rake::Pipeline DSL to include shortcuts
3
+ # for adding filters to the pipeline.
4
+ #
5
+ # Instead of:
6
+ # !!!ruby
7
+ # match("*.scss") do
8
+ # filter Rake::Pipeline::Web::Filters::SassFilter, :syntax => :sass
9
+ # end
10
+ #
11
+ # You can do:
12
+ # !!!ruby
13
+ # match("*.scss") do
14
+ # sass :syntax => :sass
15
+ # end
16
+ module PipelineHelpers
17
+ # Add a new {MinispadeFilter} to the pipeline.
18
+ # @see MinispadeFilter#initialize
19
+ def minispade(*args, &block)
20
+ filter(Rake::Pipeline::Web::Filters::MinispadeFilter, *args, &block)
21
+ end
22
+
23
+ # Add a new {NeuterFilter} to the pipeline.
24
+ # @see NeuterFilter#initialize
25
+ def neuter(*args, &block)
26
+ filter(Rake::Pipeline::Web::Filters::NeuterFilter, *args, &block)
27
+ end
28
+
29
+ # Add a new {SassFilter} to the pipeline.
30
+ # @see SassFilter#initialize
31
+ def sass(*args, &block)
32
+ filter(Rake::Pipeline::Web::Filters::SassFilter, *args, &block)
33
+ end
34
+ alias_method :scss, :sass
35
+
36
+ # Add a new {JadeFilter} to the pipeline.
37
+ # @see JadeFilter#initialize
38
+ def jade(*args, &block)
39
+ filter(Rake::Pipeline::Web::Filters::JadeFilter, *args, &block)
40
+ end
41
+
42
+ # Add a new {StylusFilter} to the pipeline.
43
+ # @see StylusFilter#initialize
44
+ def stylus(*args, &block)
45
+ filter(Rake::Pipeline::Web::Filters::StylusFilter, *args, &block)
46
+ end
47
+
48
+ # Add a new {TiltFilter} to the pipeline.
49
+ # @see TiltFilter#initialize
50
+ def tilt(*args, &block)
51
+ filter(Rake::Pipeline::Web::Filters::TiltFilter, *args, &block)
52
+ end
53
+
54
+ # Add a new {MarkdownFilter} to the pipeline.
55
+ # @see MarkdownFilter#initialize
56
+ def markdown(*args, &block)
57
+ filter(Rake::Pipeline::Web::Filters::MarkdownFilter, *args, &block)
58
+ end
59
+
60
+ # Add a new {CacheBusterFilter} to the pipeline.
61
+ # @see CacheBusterFilter#initialize
62
+ def cache_buster(&block)
63
+ filter(Rake::Pipeline::Web::Filters::CacheBusterFilter, &block)
64
+ end
65
+
66
+ # Add a new {CoffeeScriptFilter} to the pipeline.
67
+ # @see CoffeeScriptFilter#initialize
68
+ def coffee_script(*args, &block)
69
+ filter(Rake::Pipeline::Web::Filters::CoffeeScriptFilter, *args, &block)
70
+ end
71
+
72
+ # Add a new {YUIJavaScriptFilter} to the pipeline.
73
+ # @see YUIJavaScriptFilter#initialize
74
+ def yui_javascript(*args, &block)
75
+ filter(Rake::Pipeline::Web::Filters::YUIJavaScriptFilter, *args, &block)
76
+ end
77
+
78
+ # Add a new {YUICssFilter} to the pipeline.
79
+ # @see YUICssFilter#initialize
80
+ def yui_css(*args, &block)
81
+ filter(Rake::Pipeline::Web::Filters::YUICssFilter, *args, &block)
82
+ end
83
+
84
+ # Add a new {GzipFilter} to the pipeline.
85
+ # @see GzipFilter#initialize
86
+ def gzip(&block)
87
+ filter(Rake::Pipeline::Web::Filters::GzipFilter, &block)
88
+ end
89
+
90
+ # Add a new {UglifyFilter} to the pipeline.
91
+ # @see UglifyFilter#initialize
92
+ def uglify(*args, &block)
93
+ filter(Rake::Pipeline::Web::Filters::UglifyFilter, *args, &block)
94
+ end
95
+
96
+ # Add a new {LessFilter} to the pipeline.
97
+ # @see LessFilter#initialize
98
+ def less(*args, &block)
99
+ filter(Rake::Pipeline::Web::Filters::LessFilter, *args, &block)
100
+ end
101
+
102
+ # Add a new {HandlebarsFilter} to the pipeline.
103
+ # @see HandlebarsFilter#initialize
104
+ def handlebars(*args, &block)
105
+ filter(Rake::Pipeline::Web::Filters::HandlebarsFilter, *args, &block)
106
+ end
107
+ #
108
+ # Add a new {IifeFilter} to the pipeline.
109
+ # @see IifeFilter#initialize
110
+ def iife(*args, &block)
111
+ filter(Rake::Pipeline::Web::Filters::IifeFilter, *args, &block)
112
+ end
113
+ end
114
+
115
+ module ProjectHelpers
116
+ # Register a filter class for a particular file extension
117
+ # and add a ChainedFilter as a before filter.
118
+ #
119
+ # If this is the first use of +register+, it will set up
120
+ # the before filter. Subsequent uses will just update the
121
+ # types hash.
122
+ #
123
+ # @see ChainedFilter
124
+ def register(extension, klass)
125
+ if @types_hash
126
+ @types_hash[extension] = klass
127
+ else
128
+ @types_hash = { extension => klass }
129
+ before_filter ChainedFilter, { :types => @types_hash }
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ require "rake-pipeline/dsl"
136
+
137
+ Rake::Pipeline::DSL::PipelineDSL.send(:include, Rake::Pipeline::Web::Filters::PipelineHelpers)
138
+ Rake::Pipeline::DSL::ProjectDSL.send(:include, Rake::Pipeline::Web::Filters::ProjectHelpers)
@@ -0,0 +1,38 @@
1
+ module Rake::Pipeline::Web::Filters
2
+ # A filter that wraps input files in an IIFE (immediately invoked functional expression)
3
+ #
4
+ #
5
+ # @example
6
+ # !!!ruby
7
+ # Rake::Pipeline.build do
8
+ # input "app/assets", "**/*.js"
9
+ # output "public"
10
+ #
11
+ # # Wrap each file in: (function() { ... })();"
12
+ # filter Rake::Pipeline::Web::Filters::IifeFilter
13
+ # end
14
+ class IifeFilter < Rake::Pipeline::Filter
15
+ # @param [Proc] block a block to use as the Filter's
16
+ # {#output_name_generator}.
17
+ def initialize(&block)
18
+ block ||= proc { |input| input }
19
+ super(&block)
20
+ end
21
+
22
+ # Implement the {#generate_output} method required by
23
+ # the {Filter} API. Wraps each input in an IIFE.
24
+ #
25
+ # @param [Array<FileWrapper>] inputs an Array of
26
+ # {FileWrapper} objects representing the inputs to
27
+ # this filter.
28
+ # @param [FileWrapper] output a single {FileWrapper}
29
+ # object representing the output.
30
+ def generate_output(inputs, output)
31
+ inputs.each do |input|
32
+ output.write "(function() {\n"
33
+ output.write input.read
34
+ output.write "})();"
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,61 @@
1
+ require 'rake-pipeline-web-filters/filter_with_dependencies'
2
+
3
+ module Rake::Pipeline::Web::Filters
4
+ # A filter that compiles input files written in Jade
5
+ # to HTML using the Jade compiler
6
+ #
7
+ # Requires node and https://npmjs.org/package/jade by
8
+ # [sudo] npm install jade -g
9
+ #
10
+ # @example
11
+ # !!!ruby
12
+ # Rake::Pipeline.build do
13
+ # input "app/assets", "**/*.jade"
14
+ # output "public"
15
+ #
16
+ # # Compile each Jade file under the app/assets
17
+ # # directory.
18
+ # filter Rake::Pipeline::Web::Filters::JadeFilter
19
+ # end
20
+ # !!!ruby
21
+ # Rake::Pipeline.build do
22
+ # input "app/assets", "**/*.jade"
23
+ # output "public"
24
+ #
25
+ # jade :pretty
26
+ # end
27
+ class JadeFilter < Rake::Pipeline::Filter
28
+ include Rake::Pipeline::Web::Filters::FilterWithDependencies
29
+
30
+ # @return [Hash] a hash of options to pass to Less
31
+ # when compiling.
32
+ # @option option :prettify output
33
+ attr_reader :options
34
+
35
+ def initialize(options={}, &block)
36
+ block ||= proc { |input| input.sub(/\.(jade)$/, '.html') }
37
+ super(&block)
38
+ @options = options
39
+ end
40
+
41
+ def generate_output(inputs, output)
42
+
43
+ inputs.each do |input|
44
+ if options[:pretty]
45
+ `jade < #{input.root}/#{input.path} -P --path #{input.root}/#{input.path} > #{output.root}/#{output.path}`
46
+ else
47
+ `jade < #{input.root}/#{input.path} --path #{input.root}/#{input.path} > #{output.root}/#{output.path}`
48
+ end
49
+ out = output.read
50
+ output.write out
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def external_dependencies
57
+ [ ]
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,55 @@
1
+ require 'rake-pipeline-web-filters/filter_with_dependencies'
2
+
3
+ module Rake::Pipeline::Web::Filters
4
+ # A filter that accepts a series of inputs and translates
5
+ # them using the Tilt template interface, which will attempt
6
+ # to guess which template language to use based on the input
7
+ # file extension.
8
+ #
9
+ # Requires {https://rubygems.org/gems/less-js less-js}
10
+ #
11
+ # @example
12
+ # !!!ruby
13
+ # Rake::Pipeline.build do
14
+ # input "app/assets", "**/*.less"
15
+ # output "public"
16
+ #
17
+ # # Compile each less file with Less.js
18
+ # filter Rake::Pipeline::Web::Filters::LessFilter
19
+ # end
20
+ class LessFilter < Rake::Pipeline::Filter
21
+ include Rake::Pipeline::Web::Filters::FilterWithDependencies
22
+
23
+ # @return [Hash] a hash of options to pass to Less
24
+ # when compiling.
25
+ attr_reader :options
26
+
27
+ # @param [Proc] block a block to use as the Filter's
28
+ # {#output_name_generator}.
29
+ def initialize(options={}, context = nil, &block)
30
+ block ||= proc { |input| input.sub(/\.less$/, '.css') }
31
+ super(&block)
32
+ @options = options
33
+ end
34
+
35
+ # Implement the {#generate_output} method required by
36
+ # the {Filter} API. Attempts to compile each input file
37
+ # with LessJs.
38
+ #
39
+ # @param [Array<FileWrapper>] inputs an Array of
40
+ # {FileWrapper} objects representing the inputs to
41
+ # this filter.
42
+ # @param [FileWrapper] output a single {FileWrapper}
43
+ # object representing the output.
44
+ def generate_output(inputs, output)
45
+ parser = Less::Parser.new options
46
+ inputs.each do |input|
47
+ output.write parser.parse(input.read).to_css
48
+ end
49
+ end
50
+
51
+ def external_dependencies
52
+ [ 'less' ]
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,70 @@
1
+ module Rake::Pipeline::Web::Filters
2
+ # A filter that compiles input files written in Markdown
3
+ # to Markdown using the Redcarpet compiler.
4
+ #
5
+ # @example
6
+ # !!!ruby
7
+ # Rake::Pipeline.build do
8
+ # input "app/assets", "**/*.md"
9
+ # output "public"
10
+ #
11
+ # # Compile each .md file under the app/assets
12
+ # # directory.
13
+ # filter Rake::Pipeline::Web::Filters::MarkdownFilter
14
+ # end
15
+ #
16
+ class MarkdownFilter < Rake::Pipeline::Filter
17
+
18
+ # @param [Hash] options options to pass to the markdown
19
+ # compiler
20
+ # @see http://rubydoc.info/gems/redcarpet/2.0.0/frames for more information
21
+ # about options
22
+ # @option options [#call] :compiler If you wish to use a different
23
+ # Markdown compiler, you can do so by passing anything that responds
24
+ # to `:call`, which will be passed the Markdown text and any
25
+ # options (other than `:compiler`).
26
+ # @option options [Redcarpet::Render::Base] :renderer a
27
+ # Redcarpet renderer. Used only if using the default compiler.
28
+ # @param [Proc] block a block to use as the Filter's
29
+ # {#output_name_generator}.
30
+ def initialize(options={}, &block)
31
+ block ||= proc { |input| input.sub(/\.(md|mdown|mkdown|markdown)$/, '.html') }
32
+ super(&block)
33
+ @compiler = options.delete(:compiler)
34
+ @options = options
35
+ end
36
+
37
+ # Implement the {#generate_output} method required by
38
+ # the {Filter} API. Compiles each input file with Sass.
39
+ #
40
+ # @param [Array<FileWrapper>] inputs an Array of
41
+ # {FileWrapper} objects representing the inputs to
42
+ # this filter.
43
+ # @param [FileWrapper] output a single {FileWrapper}
44
+ # object representing the output.
45
+ def generate_output(inputs, output)
46
+ inputs.each do |input|
47
+ output.write compile(input.read)
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def compile(markdown)
54
+ if @compiler
55
+ @compiler.call(markdown, @options)
56
+ else
57
+ default_compiler.render(markdown)
58
+ end
59
+ end
60
+
61
+ def default_compiler
62
+ @default_renderer ||= begin
63
+ require 'redcarpet'
64
+ renderer = @options.delete(:renderer) || Redcarpet::Render::HTML.new
65
+ Redcarpet::Markdown.new(renderer, @options)
66
+ end
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,63 @@
1
+ module Rake::Pipeline::Web::Filters
2
+ # A filter that wraps JavaScript files in a minispade.register closure
3
+ # for use in minispade.
4
+ #
5
+ # @example
6
+ # !!!ruby
7
+ # Rake::Pipeline.build do
8
+ # input "app/assets", "**/*.js"
9
+ # output "public"
10
+ #
11
+ # # Wrap each JS file in a minispade.register closure.
12
+ # filter Rake::Pipeline::Web::Filters::MinispadeFilter
13
+ # end
14
+ class MinispadeFilter < Rake::Pipeline::Filter
15
+
16
+ # @param [Hash] options
17
+ # @option options [Boolean] :use_strict Whether to add "use strict" to
18
+ # each outputted function; defaults to false.
19
+ # @option options [Proc] :module_id_generator a proc to use to generate
20
+ # the minispade module id.
21
+ # @option options [Boolean] :rewrite_requires If true, change calls to
22
+ # +require+ in the source to +minispade.require+.
23
+ # @option options [Boolean] :string If true, compiles the output as
24
+ # a String instead of a closure. This means that @sourceURL can be
25
+ # appended for good stack traces and debugging.
26
+ def initialize(options = {})
27
+ super()
28
+ @use_strict = options[:use_strict]
29
+ @module_id_generator = options[:module_id_generator] ||
30
+ proc { |input| input.fullpath.sub(Dir.pwd, '') }
31
+ @rewrite_requires = options[:rewrite_requires]
32
+ @string_module = options[:string]
33
+ end
34
+
35
+ # Implement the {#generate_output} method required by
36
+ # the {Filter} API. Wraps each input file in a minispade.register
37
+ # closure.
38
+ #
39
+ # @param [Array<FileWrapper>] inputs an Array of
40
+ # {FileWrapper} objects representing the inputs to
41
+ # this filter.
42
+ # @param [FileWrapper] output a single {FileWrapper}
43
+ # object representing the output.
44
+ def generate_output(inputs, output)
45
+ inputs.each do |input|
46
+ code = input.read
47
+ code.gsub!(%r{^\s*require\s*\(\s*}, 'minispade.require(') if @rewrite_requires
48
+ code.gsub!(%r{^\s*requireAll\s*\(\s*}, 'minispade.requireAll(') if @rewrite_requires
49
+ code = %["use strict";\n] + code if @use_strict
50
+
51
+ module_id = @module_id_generator.call(input)
52
+
53
+ if @string_module
54
+ contents = %{(function() {#{code}\n})();\n/*@if (@_jscript) @else @*/\n//@ sourceURL=#{module_id}\n/*@end@*/}.to_json
55
+ else
56
+ contents = "function() {#{code}\n}"
57
+ end
58
+ ret = "minispade.register('#{module_id}', #{contents});"
59
+ output.write ret
60
+ end
61
+ end
62
+ end
63
+ end