html_mockup 0.6.5 → 0.7.0

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.
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## Version 0.7.0
4
+ * Replace --quiet with -s in as it's no longer supported in newer GIT versions
5
+ * Add support for ENV passing to the partials
6
+ * Add support for single file processing and env passing in the extractor (release)
7
+ * Refactor path and url resolving
8
+ * Allow `.html` files to be processed by ERB (both in release and serve)
9
+ * Pass "MOCKUP_PROJECT" variable to env (both in release and serve)
10
+
3
11
  ## Version 0.6.5
4
12
  * Allow disabling of URL relativizing in the extractor with `release.extract :url_relativize => false`
5
13
  * Add missing Hpricot dependency to gem
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "html_mockup"
5
- s.version = "0.6.5"
5
+ s.version = "0.7.0"
6
6
 
7
7
  s.authors = ["Flurin Egger", "Edwin van der Graaf"]
8
8
  s.email = ["info@digitpaint.nl", "flurin@digitpaint.nl"]
@@ -1,4 +1,5 @@
1
1
  require 'hpricot'
2
+ require File.dirname(__FILE__) + '/resolver'
2
3
 
3
4
  module HtmlMockup
4
5
  class Extractor
@@ -12,21 +13,27 @@ module HtmlMockup
12
13
 
13
14
  # @option options [Array] :url_attributes The element attributes to parse and relativize
14
15
  # @option options [Array] :url_relativize Wether or not we should relativize
16
+ # @option options [Array] :env ENV variable to pass to template renderer.
15
17
  def initialize(project, target_path, options={})
16
18
  @project = project
17
19
  @target_path = Pathname.new(target_path)
20
+ @resolver = Resolver.new(self.target_path)
21
+
18
22
 
19
23
  @options = {
20
24
  :url_attributes => %w{src href action},
21
- :url_relativize => true
25
+ :url_relativize => true,
26
+ :env => {}
22
27
  }
23
28
 
24
29
  @options.update(options) if options
30
+
31
+ env.update("MOCKUP_PROJECT" => project)
25
32
  end
26
33
 
27
34
  def run!
28
35
  target_path = self.target_path
29
- source_path, partial_path = self.project.html_path, self.project.partial_path
36
+ source_path = self.project.html_path
30
37
 
31
38
 
32
39
  filter = "**/*.html"
@@ -39,86 +46,48 @@ module HtmlMockup
39
46
  cp_r(source_path.children, target_path)
40
47
 
41
48
  Dir.chdir(source_path) do
42
- Dir.glob(filter).each do |file_name|
43
- source = HtmlMockup::Template.open(file_name, :partial_path => partial_path).render
44
-
45
- if @options[:url_relativize]
46
- source = relativize_urls(source, file_name)
47
- end
48
-
49
- File.open(target_path + file_name,"w"){|f| f.write(source) }
49
+ Dir.glob(filter).each do |file_path|
50
+ self.run_on_file!(file_path, @options[:env])
50
51
  end
51
52
  end
52
53
  end
54
+
55
+ def run_on_file!(file_path, env = {})
56
+ source = self.extract_source_from_file(file_path, env)
57
+ File.open(target_path + file_path,"w"){|f| f.write(source) }
58
+ end
59
+
60
+ # Runs the extractor on a single file and return processed source.
61
+ def extract_source_from_file(file_path, env = {})
62
+ source = HtmlMockup::Template.open(file_path, :partial_path => self.project.partial_path).render(env)
63
+
64
+ if @options[:url_relativize]
65
+ source = relativize_urls(source, file_path)
66
+ end
53
67
 
68
+ source
69
+ end
70
+
54
71
 
55
72
  protected
56
73
 
57
- def relativize_urls(source, file_name)
58
- cur_dir = Pathname.new(file_name).dirname
59
- up_to_root = File.join([".."] * (file_name.split("/").size - 1))
60
-
74
+ def relativize_urls(source, file_path)
61
75
  doc = Hpricot(source)
62
76
  @options[:url_attributes].each do |attribute|
63
77
  (doc/"*[@#{attribute}]").each do |tag|
64
- converted_url = convert_relative_url_to_absolute_url(tag[attribute], cur_dir, up_to_root)
78
+ converted_url = @resolver.url_to_relative_url(tag[attribute], file_path)
65
79
 
66
80
  case converted_url
67
81
  when String
68
82
  tag[attribute] = converted_url
69
83
  when nil
70
- puts "Could not resolve link #{tag[attribute]} in #{file_name}"
84
+ puts "Could not resolve link #{tag[attribute]} in #{file_path}"
71
85
  end
72
86
  end
73
87
  end
74
88
 
75
89
  doc.to_original_html
76
90
  end
77
-
78
- # @return [false, nil, String] False if it can't be converted, nil if it can't be resolved and the converted string if it can be resolved.
79
- def convert_relative_url_to_absolute_url(url, cur_dir, up_to_root)
80
- # Skip if the url doesn't start with a / (but not with //)
81
- return false unless url =~ /\A\/[^\/]/
82
-
83
- # Strip off anchors
84
- anchor = nil
85
- url.gsub!(/(#.+)\Z/) do |r|
86
- anchor = r
87
- ""
88
- end
89
-
90
- # Strip off query strings
91
- query = nil
92
- url.gsub!(/(\?.+)\Z/) do |r|
93
- query = r
94
- ""
95
- end
96
-
97
- if true_file = resolve_path(cur_dir + up_to_root + url.sub(/\A\//,""))
98
- url = true_file.relative_path_from(cur_dir).to_s
99
- url += query if query
100
- url += anchor if anchor
101
- url
102
- else
103
- nil
104
- end
105
-
106
- end
107
-
108
- def resolve_path(path)
109
- path = Pathname.new(path) unless path.kind_of?(Pathname)
110
- # Append index.html/index.htm/index.rhtml if it's a diretory
111
- if path.directory?
112
- search_files = %w{.html .htm}.map!{|p| path + "index#{p}" }
113
- # If it ends with a slash or does not contain a . and it's not a directory
114
- # try to add .html/.htm to see if that exists.
115
- elsif (path.to_s =~ /\/$/) || (path.to_s =~ /^[^.]+$/)
116
- search_files = [path.to_s + ".html", path.to_s + ".htm"].map!{|p| Pathname.new(p) }
117
- else
118
- search_files = [path]
119
- end
120
- search_files.find{|p| p.exist? }
121
- end
122
-
91
+
123
92
  end
124
93
  end
@@ -2,42 +2,37 @@ require 'rack/request'
2
2
  require 'rack/response'
3
3
  require 'rack/file'
4
4
 
5
+ require File.dirname(__FILE__) + '/../resolver'
6
+
5
7
  module HtmlMockup
6
8
  module Rack
9
+
7
10
  class HtmlMockup
8
- def initialize(root,partial_path)
11
+
12
+ attr_reader :project
13
+
14
+ def initialize(project)
15
+ @project = project
16
+ root,partial_path = project.html_path, project.partial_path
17
+
9
18
  @docroot = root
10
19
  @partial_path = partial_path
11
20
  @file_server = ::Rack::File.new(@docroot)
12
21
  end
13
22
 
14
23
  def call(env)
15
- path = env["PATH_INFO"]
16
-
17
- # TODO: Combine with Extractor#resolve_path
24
+ url = env["PATH_INFO"]
25
+ env["MOCKUP_PROJECT"] = project
18
26
 
19
- # Append index.html/index.htm if it's a diretory
20
- if File.directory?(File.join(@docroot,path))
21
- search_files = %w{.html .htm}.map!{|p| File.join(@docroot,path,"index#{p}")}
22
- # If it's already a .html/.htm file, render that file
23
- elsif (path =~ /\.html?$/)
24
- search_files = [File.join(@docroot,path)]
25
- # If it ends with a slash or does not contain a . and it's not a directory
26
- # try to add .html/.htm to see if that exists.
27
- elsif (path =~ /\/$/) || (path =~ /^[^.]+$/)
28
- search_files = [path + ".html", path + ".htm"].map!{|p| File.join(@docroot,p) }
29
- # Otherwise don't render anything at all.
30
- else
31
- search_files = []
32
- end
27
+ resolver = Resolver.new(@docroot)
33
28
 
34
- if template_path = search_files.find{|p| File.exist?(p)}
35
- env["rack.errors"].puts "Rendering template #{template_path.inspect} (#{path.inspect})"
29
+ if template_path = resolver.url_to_path(url)
30
+ env["rack.errors"].puts "Rendering template #{template_path.inspect} (#{url.inspect})"
36
31
  begin
37
32
  templ = ::HtmlMockup::Template.open(template_path, :partial_path => @partial_path)
38
33
  resp = ::Rack::Response.new do |res|
39
34
  res.status = 200
40
- res.write templ.render
35
+ res.write templ.render(env)
41
36
  end
42
37
  resp.finish
43
38
  rescue StandardError => e
@@ -49,7 +44,7 @@ module HtmlMockup
49
44
  resp.finish
50
45
  end
51
46
  else
52
- env["rack.errors"].puts "Invoking file handler for #{path.inspect}"
47
+ env["rack.errors"].puts "Invoking file handler for #{url.inspect}"
53
48
  @file_server.call(env)
54
49
  end
55
50
  end
@@ -61,7 +61,7 @@ module HtmlMockup::Release::Scm
61
61
 
62
62
  if $?.to_i > 0
63
63
  # HEAD is not a tagged verison, get the short SHA1 instead
64
- @_version = `git --git-dir=#{git_dir} show #{ref} --format=format:"%h" --quiet 2>&1`
64
+ @_version = `git --git-dir=#{git_dir} show #{ref} --format=format:"%h" -s 2>&1`
65
65
  else
66
66
  # HEAD is a tagged version, if version is prefixed with "v" it will be stripped off
67
67
  @_version.gsub!(/^v/,"")
@@ -69,7 +69,7 @@ module HtmlMockup::Release::Scm
69
69
  @_version.strip!
70
70
 
71
71
  # Get the date in epoch time
72
- date = `git --git-dir=#{git_dir} show #{ref} --format=format:"%ct" --quiet 2>&1`
72
+ date = `git --git-dir=#{git_dir} show #{ref} --format=format:"%ct" -s 2>&1`
73
73
  if date =~ /\d+/
74
74
  @_date = Time.at(date.to_i)
75
75
  else
@@ -0,0 +1,95 @@
1
+ module HtmlMockup
2
+ class Resolver
3
+
4
+ def initialize(path)
5
+ @base = Pathname.new(path)
6
+ end
7
+
8
+ def url_to_path(url, exact_match = false)
9
+ path, qs, anch = strip_query_string_and_anchor(url.to_s)
10
+
11
+ extensions = %w{html htm}
12
+
13
+ # Append index.extension if it's a diretory
14
+ if File.directory?(File.join(@base,path))
15
+ search_files = extensions.map{|p| File.join(@base,path,"index.#{p}")}
16
+ # If it's already a .extension file, return that file
17
+ elsif extensions.detect{|e| path =~ /\.#{e}\Z/ }
18
+ search_files = [File.join(@base,path)]
19
+ # If it ends with a slash or does not contain a . and it's not a directory
20
+ # try to add extenstions to see if that exists.
21
+ elsif (path =~ /\/$/) || (path =~ /^[^.]+$/)
22
+ search_files = extensions.map{|e| File.join(@base,"#{path}.#{e}") }
23
+ # Otherwise don't return anything at all.
24
+ else
25
+ if exact_match
26
+ search_files = [File.join(@base,path)]
27
+ else
28
+ search_files = []
29
+ end
30
+ end
31
+
32
+ if file = search_files.find{|p| File.exist?(p) }
33
+ Pathname.new(file)
34
+ end
35
+ end
36
+
37
+
38
+ # Convert a disk path on file to an url
39
+ def path_to_url(path, relative_to = nil)
40
+
41
+ path = Pathname.new(path).relative_path_from(@base).cleanpath
42
+
43
+ if relative_to
44
+ if relative_to.to_s =~ /\A\//
45
+ relative_to = Pathname.new(File.dirname(relative_to.to_s)).relative_path_from(@base).cleanpath
46
+ else
47
+ relative_to = Pathname.new(File.dirname(relative_to.to_s))
48
+ end
49
+ path = Pathname.new("/" + path.to_s).relative_path_from(Pathname.new("/" + relative_to.to_s))
50
+ path.to_s
51
+ else
52
+ "/" + path.to_s
53
+ end
54
+
55
+ end
56
+
57
+ def url_to_relative_url(url, relative_to_path)
58
+ # Skip if the url doesn't start with a / (but not with //)
59
+ return false unless url =~ /\A\/[^\/]/
60
+
61
+ path, qs, anch = strip_query_string_and_anchor(url)
62
+
63
+ # Get disk path
64
+ if true_path = self.url_to_path(path, true)
65
+ path = self.path_to_url(true_path, relative_to_path)
66
+ path += qs if qs
67
+ path += anch if anch
68
+ path
69
+ else
70
+ false
71
+ end
72
+ end
73
+
74
+ def strip_query_string_and_anchor(url)
75
+ url = url.dup
76
+
77
+ # Strip off anchors
78
+ anchor = nil
79
+ url.gsub!(/(#.+)\Z/) do |r|
80
+ anchor = r
81
+ ""
82
+ end
83
+
84
+ # Strip off query strings
85
+ query = nil
86
+ url.gsub!(/(\?.+)\Z/) do |r|
87
+ query = r
88
+ ""
89
+ end
90
+
91
+ [url, query, anchor]
92
+ end
93
+
94
+ end
95
+ end
@@ -65,7 +65,7 @@ module HtmlMockup
65
65
  return @app if @app
66
66
 
67
67
  @stack.use Rack::HtmlValidator if self.options[:validate]
68
- @stack.run Rack::HtmlMockup.new(self.project.html_path, self.project.partial_path)
68
+ @stack.run Rack::HtmlMockup.new(self.project)
69
69
 
70
70
  @app = @stack
71
71
  end
@@ -2,6 +2,7 @@ require 'pathname'
2
2
  require 'strscan'
3
3
  require 'erb'
4
4
  require 'cgi'
5
+ require 'tilt'
5
6
 
6
7
  module HtmlMockup
7
8
 
@@ -10,7 +11,7 @@ module HtmlMockup
10
11
  class Template
11
12
 
12
13
  class << self
13
- def open(filename,options={})
14
+ def open(filename, options={})
14
15
  raise "Unknown file #{filename}" unless File.exist?(filename)
15
16
  self.new(File.read(filename),options.update(:target_file => filename))
16
17
  end
@@ -39,18 +40,17 @@ module HtmlMockup
39
40
 
40
41
  # Create a new HtmlMockupTemplate
41
42
  #
42
- # ==== Parameters
43
- # template<String>:: The template to parse
44
- # options<Hash>:: See options
43
+ # @param [String] source The template to parse
44
+ # @param [Hash] options See options
45
45
  #
46
- # ==== Options (optional)
47
- # partial_path<String>:: Path where the partials reside (default: $0/../../partials)
48
- #--
49
- def initialize(template, options={})
50
- defaults = {:partial_path => File.dirname(__FILE__) + "/../../partials/"}
51
- @template = template
46
+ # @option options [String] partial_path Path where the partials reside (default: $0/../../partials)
47
+ def initialize(source, options={})
48
+ defaults = {
49
+ :partial_path => File.dirname(__FILE__) + "/../../partials/"
50
+ }
51
+ @source = source
52
+ @template = Tilt::ERBTemplate.new{ @source }
52
53
  @options = defaults.update(options)
53
- @scanner = StringScanner.new(@template)
54
54
  raise "Partial path '#{self.options[:partial_path]}' not found" unless File.exist?(self.options[:partial_path])
55
55
  end
56
56
 
@@ -65,6 +65,7 @@ module HtmlMockup
65
65
  # String:: The rendered template
66
66
  #--
67
67
  def render(env={})
68
+ @scanner = StringScanner.new(@template.render(Object.new, :env => env))
68
69
  out = ""
69
70
  while (partial = self.parse_partial_tag!) do
70
71
  tag,params,scanned = partial
@@ -73,7 +74,7 @@ module HtmlMockup
73
74
 
74
75
  # scan until end of tag
75
76
  current_content = self.scanner.scan_until(/<!-- \[STOP:#{tag}\] -->/)
76
- out << (render_partial(tag, params) || current_content)
77
+ out << (render_partial(tag, params, env) || current_content)
77
78
  end
78
79
  out << scanner.rest
79
80
  end
@@ -115,24 +116,18 @@ module HtmlMockup
115
116
  unless self.available_partials[tag]
116
117
  raise MissingPartial.new("Could not find partial '#{tag}' in partial path '#{@options[:partial_path]}'")
117
118
  end
118
- template = ERB.new(self.available_partials[tag])
119
- context = TemplateContext.new(params, env)
120
- "\n" + template.result(context.get_binding).rstrip + "\n<!-- [STOP:#{tag}] -->"
119
+ template = Tilt::ERBTemplate.new{ self.available_partials[tag] }
120
+ context = TemplateContext.new(params)
121
+ "\n" + template.render(context, :env => env).rstrip + "\n<!-- [STOP:#{tag}] -->"
121
122
  end
122
123
 
123
124
  class TemplateContext
124
125
  # Params will be set as instance variables
125
- def initialize(params, env = {})
126
+ def initialize(params)
126
127
  params.each do |k,v|
127
128
  self.instance_variable_set("@#{k}",v)
128
129
  end
129
-
130
- @_env = env;
131
- end
132
-
133
- def env; @_env; end
134
-
135
- def get_binding; binding(); end
130
+ end
136
131
  end
137
132
 
138
133
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html_mockup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.5
4
+ version: 0.7.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-12-10 00:00:00.000000000 Z
13
+ date: 2013-01-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: thor
17
- requirement: &70323203509020 !ruby/object:Gem::Requirement
17
+ requirement: &70345877984660 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 0.16.0
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70323203509020
25
+ version_requirements: *70345877984660
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rack
28
- requirement: &70323203508540 !ruby/object:Gem::Requirement
28
+ requirement: &70345877984180 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 1.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *70323203508540
36
+ version_requirements: *70345877984180
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: tilt
39
- requirement: &70323202817780 !ruby/object:Gem::Requirement
39
+ requirement: &70345877983700 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *70323202817780
47
+ version_requirements: *70345877983700
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: hpricot
50
- requirement: &70323202816620 !ruby/object:Gem::Requirement
50
+ requirement: &70345877983200 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,7 +55,7 @@ dependencies:
55
55
  version: 0.6.4
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *70323202816620
58
+ version_requirements: *70345877983200
59
59
  description:
60
60
  email:
61
61
  - info@digitpaint.nl
@@ -101,6 +101,7 @@ files:
101
101
  - lib/html_mockup/release/processors/yuicompressor.rb
102
102
  - lib/html_mockup/release/scm.rb
103
103
  - lib/html_mockup/release/scm/git.rb
104
+ - lib/html_mockup/resolver.rb
104
105
  - lib/html_mockup/server.rb
105
106
  - lib/html_mockup/template.rb
106
107
  - lib/html_mockup/w3c_validator.rb