middleman-more 3.0.0.beta.2 → 3.0.0.beta.3

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 (33) hide show
  1. data/features/asset_hash.feature +24 -24
  2. data/features/ignore_already_minified.feature +39 -4
  3. data/features/markdown.feature +3 -12
  4. data/features/markdown_redcarpet.feature +37 -0
  5. data/features/minify_css.feature +72 -10
  6. data/features/minify_javascript.feature +108 -10
  7. data/features/slim.feature +15 -1
  8. data/fixtures/markdown-app/config.rb +0 -9
  9. data/lib/middleman-more.rb +1 -74
  10. data/lib/middleman-more/core_extensions/compass.rb +49 -48
  11. data/lib/middleman-more/core_extensions/sprockets.rb +10 -2
  12. data/lib/middleman-more/extensions/asset_hash.rb +9 -23
  13. data/lib/middleman-more/extensions/cache_buster.rb +51 -53
  14. data/lib/middleman-more/extensions/gzip.rb +14 -0
  15. data/lib/middleman-more/extensions/minify_css.rb +60 -70
  16. data/lib/middleman-more/extensions/minify_javascript.rb +70 -77
  17. data/lib/middleman-more/extensions/relative_assets.rb +47 -47
  18. data/lib/middleman-more/register_extensions.rb +82 -0
  19. data/lib/middleman-more/renderers/coffee_script.rb +22 -0
  20. data/lib/middleman-more/renderers/haml.rb +24 -19
  21. data/lib/middleman-more/renderers/liquid.rb +28 -23
  22. data/lib/middleman-more/renderers/markdown.rb +50 -42
  23. data/lib/middleman-more/renderers/sass.rb +70 -63
  24. data/lib/middleman-more/renderers/slim.rb +27 -19
  25. data/middleman-more.gemspec +6 -7
  26. metadata +34 -43
  27. data/fixtures/already-minified-app/config.rb +0 -2
  28. data/fixtures/already-minified-app/source/javascripts/test.min.js +0 -10
  29. data/fixtures/already-minified-app/source/stylesheets/test.min.css +0 -10
  30. data/fixtures/minify-css-app/config.rb +0 -0
  31. data/fixtures/passthrough-app/config.rb +0 -17
  32. data/fixtures/slim-app/config.rb +0 -1
  33. data/fixtures/slim-app/source/slim.html.slim +0 -7
@@ -2,6 +2,20 @@ Feature: Support slim templating language
2
2
  In order to offer an alternative to Haml
3
3
 
4
4
  Scenario: Rendering Slim
5
- Given the Server is running at "slim-app"
5
+ Given an empty app
6
+ And a file named "config.rb" with:
7
+ """
8
+ """
9
+ And a file named "source/slim.html.slim" with:
10
+ """
11
+ doctype 5
12
+ html lang='en'
13
+ head
14
+ meta charset="utf-8"
15
+
16
+ body
17
+ h1 Welcome to Slim
18
+ """
19
+ And the Server is running at "empty_app"
6
20
  When I go to "/slim.html"
7
21
  Then I should see "<h1>Welcome to Slim</h1>"
@@ -1,9 +0,0 @@
1
- set :markdown, :smartypants => true,
2
- :no_intra_emphasis => true,
3
- :tables => true,
4
- :fenced_code_blocks => true,
5
- :autolink => true,
6
- :strikethrough => true,
7
- :lax_html_blocks => true,
8
- :space_after_headers => true,
9
- :superscript => true
@@ -3,77 +3,4 @@ libdir = File.expand_path(File.dirname(__FILE__))
3
3
  $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
4
4
 
5
5
  require "middleman-core"
6
-
7
- # Top-level Middleman object
8
- module Middleman
9
-
10
- # Custom Renderers
11
- module Renderers
12
- autoload :Haml, "middleman-more/renderers/haml"
13
- autoload :Sass, "middleman-more/renderers/sass"
14
- autoload :Markdown, "middleman-more/renderers/markdown"
15
- autoload :Liquid, "middleman-more/renderers/liquid"
16
- autoload :Slim, "middleman-more/renderers/slim"
17
- end
18
-
19
- # Core (automatic) extensions
20
- module CoreExtensions
21
- # Compass framework for Sass
22
- autoload :Compass, "middleman-more/core_extensions/compass"
23
-
24
- # Sprockets 2
25
- autoload :Sprockets, "middleman-more/core_extensions/sprockets"
26
- end
27
-
28
- # User-activatable extensions
29
- module Extensions
30
- # RelativeAssets allow any asset path in dynamic templates to be either
31
- # relative to the root of the project or use an absolute URL.
32
- autoload :RelativeAssets, "middleman-more/extensions/relative_assets"
33
-
34
- # CacheBuster adds a query string to assets in dynamic templates to avoid
35
- # browser caches failing to update to your new content.
36
- autoload :CacheBuster, "middleman-more/extensions/cache_buster"
37
-
38
- # AssetHash appends a hash of the file contents to the assets filename
39
- # to avoid browser caches failing to update to your new content.
40
- autoload :AssetHash, "middleman-more/extensions/asset_hash"
41
-
42
- # MinifyCss uses the YUI compressor to shrink CSS files
43
- autoload :MinifyCss, "middleman-more/extensions/minify_css"
44
-
45
- # MinifyJavascript uses the YUI compressor to shrink JS files
46
- autoload :MinifyJavascript, "middleman-more/extensions/minify_javascript"
47
-
48
- # GZIP assets and pages during build
49
- autoload :Gzip, "middleman-more/extensions/gzip"
50
- end
51
-
52
- # Setup renderers
53
- require "coffee_script"
54
- Application.register Middleman::Renderers::Haml
55
- Application.register Middleman::Renderers::Sass
56
- Application.register Middleman::Renderers::Markdown
57
- Application.register Middleman::Renderers::Liquid
58
- Application.register Middleman::Renderers::Slim
59
-
60
- # Compass framework
61
- Application.register Middleman::CoreExtensions::Compass
62
-
63
- # Sprockets asset handling
64
- Application.register Middleman::CoreExtensions::Sprockets
65
-
66
- # Register the optional extensions
67
- Extensions.register(:cache_buster) {
68
- ::Middleman::Extensions::CacheBuster }
69
- Extensions.register(:minify_css) {
70
- ::Middleman::Extensions::MinifyCss }
71
- Extensions.register(:minify_javascript) {
72
- ::Middleman::Extensions::MinifyJavascript }
73
- Extensions.register(:relative_assets) {
74
- ::Middleman::Extensions::RelativeAssets }
75
- Extensions.register(:gzip) {
76
- ::Middleman::Extensions::Gzip }
77
- Extensions.register(:asset_hash) {
78
- ::Middleman::Extensions::AssetHash }
79
- end
6
+ require "middleman-more/register_extensions"
@@ -1,60 +1,61 @@
1
- # Forward the settings on config.rb and the result of registered extensions
2
- # to Compass
3
- module Middleman::CoreExtensions::Compass
1
+ module Middleman
2
+ module CoreExtensions
3
+
4
+ # Forward the settings on config.rb and the result of registered
5
+ # extensions to Compass
6
+ module Compass
4
7
 
5
- # Extension registered
6
- class << self
8
+ # Extension registered
9
+ class << self
7
10
 
8
- # Once registered
9
- def registered(app)
10
- require "compass"
11
+ # Once registered
12
+ def registered(app)
13
+ # Require the library
14
+ require "compass"
15
+
16
+ # Where to look for fonts
17
+ app.set :fonts_dir, "fonts"
11
18
 
12
- # Where to look for fonts
13
- app.set :fonts_dir, "fonts"
14
- app.define_hook :compass_config
15
- app.define_hook :after_compass_config
19
+ # Hooks to manually update the compass config after we're
20
+ # done with it
21
+ app.define_hook :compass_config
16
22
 
17
- app.after_configuration do
18
- ::Compass.configuration do |config|
19
- config.project_path = source_dir
20
- config.environment = :development
21
- config.cache_path = File.join(root, ".sass-cache")
22
- config.sass_dir = css_dir
23
- config.css_dir = css_dir
24
- config.javascripts_dir = js_dir
25
- config.fonts_dir = fonts_dir
26
- config.images_dir = images_dir
27
- config.http_path = http_prefix
28
-
29
- # Correctly support HTTP paths with generated sprites
30
- # if config.respond_to? :http_generated_images_path
31
- # config.http_generated_images_path = if app.respond_to? :http_generated_images_path
32
- # app.http_generated_images_path
33
- # else
34
- # File.join(app.http_prefix || "/", app.images_dir)
35
- # end
36
- # end
23
+ app.after_configuration do
24
+ ::Compass.configuration do |config|
25
+ config.project_path = source_dir
26
+ config.environment = :development
27
+ config.cache_path = File.join(root, ".sass-cache")
28
+ config.sass_dir = css_dir
29
+ config.css_dir = css_dir
30
+ config.javascripts_dir = js_dir
31
+ config.fonts_dir = fonts_dir
32
+ config.images_dir = images_dir
33
+ config.http_path = http_prefix
37
34
 
38
- config.asset_cache_buster :none
39
- config.relative_assets = false
40
- config.output_style = :nested
35
+ # Disable this initially, the cache_buster extension will
36
+ # re-enable it if requested.
37
+ config.asset_cache_buster :none
38
+
39
+ # Disable this initially, the relative_assets extension will
40
+ # re-enable it if requested.
41
+ config.relative_assets = false
42
+
43
+ # Default output style
44
+ config.output_style = :nested
41
45
 
42
- if respond_to?(:asset_host) && asset_host.is_a?(Proc)
43
- config.asset_host(&asset_host)
46
+ if respond_to?(:asset_host) && asset_host.is_a?(Proc)
47
+ config.asset_host(&asset_host)
48
+ end
49
+ end
50
+
51
+ # Call hook
52
+ run_hook :compass_config, ::Compass.configuration
44
53
  end
45
54
  end
46
-
47
- # if build?
48
- # ::Compass.configuration do |config|
49
- # config.environment = :production
50
- # config.project_path = File.join(root, build_dir)
51
- # end
52
- # end
53
-
54
- run_hook :compass_config, ::Compass.configuration
55
- run_hook :after_compass_config
55
+ alias :included :registered
56
56
  end
57
+
57
58
  end
58
- alias :included :registered
59
+
59
60
  end
60
61
  end
@@ -52,8 +52,6 @@ module Middleman::CoreExtensions::Sprockets
52
52
  @app = app
53
53
  super app.source_dir
54
54
 
55
- digest = Digest::SHA1
56
-
57
55
  # Make the app context available to Sprockets
58
56
  context_class.send(:define_method, :app) { app }
59
57
  context_class.class_eval do
@@ -75,6 +73,16 @@ module Middleman::CoreExtensions::Sprockets
75
73
  append_path app.css_dir
76
74
  end
77
75
 
76
+ # Override Sprockets' default digest function to *not*
77
+ # change depending on the exact Sprockets version. It still takes
78
+ # into account "version" which is a user-suppliable version
79
+ # number that can be used to force assets to have a new
80
+ # hash.
81
+ def digest
82
+ @digest ||= Digest::SHA1.new.update(version.to_s)
83
+ @digest.dup
84
+ end
85
+
78
86
  # During development, don't use the asset cache
79
87
  def find_asset(path, options = {})
80
88
  expire_index! if @app.development?
@@ -3,14 +3,16 @@ module Middleman::Extensions
3
3
  module AssetHash
4
4
  class << self
5
5
  def registered(app, options)
6
- exts = options[:exts] || %w(.ico .manifest .jpg .jpeg .png .gif .js .css)
6
+ exts = options[:exts] || %w(.jpg .jpeg .png .gif .js .css)
7
+
8
+ # Allow specifying regexes to ignore, plus always ignore apple touch icons
9
+ ignore = Array(options[:ignore]) << /^apple-touch-icon/
7
10
 
8
11
  app.ready do
9
12
  sitemap.register_resource_list_manipulator(
10
13
  :asset_hash,
11
- AssetHashManager.new(self, exts)
14
+ AssetHashManager.new(self, exts, ignore)
12
15
  )
13
-
14
16
  use Middleware, :exts => exts, :middleman_app => self
15
17
  end
16
18
  end
@@ -18,16 +20,17 @@ module Middleman::Extensions
18
20
  end
19
21
 
20
22
  class AssetHashManager
21
- def initialize(app, exts)
23
+ def initialize(app, exts, ignore)
22
24
  @app = app
23
25
  @exts = exts
26
+ @ignore = ignore
24
27
  end
25
28
 
26
29
  # Update the main sitemap resource list
27
30
  # @return [void]
28
31
  def manipulate_resource_list(resources)
29
32
  resources.each do |resource|
30
- if @exts.include? resource.ext
33
+ if @exts.include?(resource.ext) && @ignore.none? {|ignore| resource.path =~ ignore }
31
34
  # figure out the path Sprockets would use for this asset
32
35
  if resource.ext == '.js'
33
36
  sprockets_path = resource.path.sub(@app.js_dir,'').sub(/^\//,'')
@@ -69,7 +72,7 @@ module Middleman::Extensions
69
72
  dirpath = Pathname.new(File.dirname(path))
70
73
 
71
74
  if path =~ /(^\/$)|(\.(htm|html|php|css|js)$)/
72
- body = extract_response_text(response)
75
+ body = ::Middleman::Util.extract_response_text(response)
73
76
 
74
77
  if body
75
78
  # TODO: This regex will change some paths in plan HTML (not in a tag) - is that OK?
@@ -94,23 +97,6 @@ module Middleman::Extensions
94
97
  end
95
98
  [status, headers, response]
96
99
  end
97
-
98
- private
99
-
100
- def extract_response_text(response)
101
- case(response)
102
- when String
103
- response
104
- when Array
105
- response.join
106
- when Rack::Response
107
- response.body.join
108
- when Rack::File
109
- File.read(response.path)
110
- else
111
- response.to_s
112
- end
113
- end
114
100
  end
115
101
  end
116
102
 
@@ -1,73 +1,71 @@
1
1
  # Extension namespace
2
- module Middleman::Extensions
2
+ module Middleman
3
+ module Extensions
3
4
 
4
- # The Cache Buster extension
5
- module CacheBuster
5
+ # The Cache Buster extension
6
+ module CacheBuster
6
7
 
7
- # Setup extension
8
- class << self
8
+ # Setup extension
9
+ class << self
9
10
 
10
- # Once registered
11
- def registered(app)
12
- # Add instance methods to context
13
- app.send :include, InstanceMethods
11
+ # Once registered
12
+ def registered(app)
13
+ # Add instance methods to context
14
+ app.send :include, InstanceMethods
14
15
 
15
- # After compass is setup, make it use the registered cache buster
16
- app.compass_config do |config|
17
- config.asset_cache_buster do |path, real_path|
18
- real_path = real_path.path if real_path.is_a? File
19
- real_path = real_path.gsub(File.join(root, build_dir), source)
20
- if File.readable?(real_path)
21
- File.mtime(real_path).strftime("%s")
22
- else
23
- $stderr.puts "WARNING: '#{File.basename(path)}' was not found (or cannot be read) in #{File.dirname(real_path)}"
16
+ # After compass is setup, make it use the registered cache buster
17
+ app.compass_config do |config|
18
+ config.asset_cache_buster do |path, real_path|
19
+ real_path = real_path.path if real_path.is_a? File
20
+ real_path = real_path.gsub(File.join(root, build_dir), source)
21
+ if File.readable?(real_path)
22
+ File.mtime(real_path).strftime("%s")
23
+ else
24
+ $stderr.puts "WARNING: '#{File.basename(path)}' was not found (or cannot be read) in #{File.dirname(real_path)}"
25
+ end
24
26
  end
25
27
  end
26
28
  end
29
+ alias :included :registered
27
30
  end
28
- alias :included :registered
29
- end
30
31
 
31
- # Cache buster instance methods
32
- module InstanceMethods
32
+ # Cache buster instance methods
33
+ module InstanceMethods
33
34
 
34
- # asset_url override if we're using cache busting
35
- # @param [String] path
36
- # @param [String] prefix
37
- def asset_url(path, prefix="")
38
- http_path = super
35
+ # asset_url override if we're using cache busting
36
+ # @param [String] path
37
+ # @param [String] prefix
38
+ def asset_url(path, prefix="")
39
+ http_path = super
39
40
 
40
- if http_path.include?("://") || !%w(.css .png .jpg .jpeg .svg .svgz .js .gif).include?(File.extname(http_path))
41
- http_path
42
- else
43
- begin
44
- prefix = images_dir if prefix == http_images_path
45
- rescue
46
- end
41
+ if http_path.include?("://") || !%w(.css .png .jpg .jpeg .svg .svgz .js .gif).include?(File.extname(http_path))
42
+ http_path
43
+ else
44
+ if respond_to?(:http_images_path) && prefix == http_images_path
45
+ prefix = images_dir
46
+ end
47
47
 
48
- real_path_static = File.join(prefix, path)
48
+ real_path_static = File.join(prefix, path)
49
49
 
50
- if build?
51
- real_path_dynamic = File.join(build_dir, prefix, path)
52
- real_path_dynamic = File.expand_path(real_path_dynamic, root)
53
- http_path << "?" + File.mtime(real_path_dynamic).strftime("%s") if File.readable?(real_path_dynamic)
54
- elsif resource = sitemap.find_resource_by_path(real_path_static)
55
- if !resource.template?
56
- http_path << "?" + File.mtime(resource.source_file).strftime("%s")
57
- else
58
- # It's a template, possible with partials. We can't really know when
59
- # it's updated, so generate fresh cache buster every time durin
60
- # developement
61
- http_path << "?" + Time.now.strftime("%s")
50
+ if build?
51
+ real_path_dynamic = File.join(build_dir, prefix, path)
52
+ real_path_dynamic = File.expand_path(real_path_dynamic, root)
53
+ http_path << "?" + File.mtime(real_path_dynamic).strftime("%s") if File.readable?(real_path_dynamic)
54
+ elsif resource = sitemap.find_resource_by_path(real_path_static)
55
+ if !resource.template?
56
+ http_path << "?" + File.mtime(resource.source_file).strftime("%s")
57
+ else
58
+ # It's a template, possible with partials. We can't really
59
+ # know when it's updated, so generate fresh cache buster every
60
+ # time during developement
61
+ http_path << "?" + Time.now.strftime("%s")
62
+ end
62
63
  end
63
- end
64
64
 
65
- http_path
65
+ http_path
66
+ end
66
67
  end
67
68
  end
68
69
  end
69
70
  end
70
-
71
- # Register the extension
72
- # register :cache_buster, CacheBuster
73
- end
71
+ end
@@ -39,12 +39,26 @@ module Middleman::Extensions
39
39
  def gzip_file(path, builder)
40
40
  input_file = File.open(path, 'r').read
41
41
  output_filename = path + '.gz'
42
+ input_file_time = File.mtime(path)
43
+
44
+ # Check if the right file's already there
45
+ if File.exist?(output_filename) && File.mtime(output_filename) == input_file_time
46
+ return
47
+ end
48
+
42
49
  File.open(output_filename, 'w') do |f|
43
50
  gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION)
51
+ gz.mtime = input_file_time.to_i
44
52
  gz.write input_file
45
53
  gz.close
46
54
  end
47
55
 
56
+ # Make the file times match, both for Nginx's gzip_static extension
57
+ # and so we can ID existing files. Also, so even if the GZ files are
58
+ # wiped out by build --clean and recreated, we won't rsync them over
59
+ # again because they'll end up with the same mtime.
60
+ File.utime(File.atime(output_filename), input_file_time, output_filename)
61
+
48
62
  old_size = File.size(path)
49
63
  new_size = File.size(output_filename)
50
64