ramaze 0.1.4 → 0.2.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.
Files changed (192) hide show
  1. data/Rakefile +26 -6
  2. data/bin/ramaze +8 -1
  3. data/doc/AUTHORS +13 -11
  4. data/doc/CHANGELOG +472 -13
  5. data/doc/LEGAL +22 -0
  6. data/doc/README +1 -4
  7. data/doc/TODO +7 -2
  8. data/doc/changes.txt +472 -13
  9. data/doc/changes.xml +472 -13
  10. data/doc/meta/announcement.txt +21 -23
  11. data/doc/readme_chunks/appendix.txt +0 -3
  12. data/doc/readme_chunks/features.txt +1 -1
  13. data/examples/auth/auth.rb +49 -0
  14. data/examples/auth/template/layout.haml +20 -0
  15. data/examples/auth/template/login.haml +16 -0
  16. data/examples/blog/spec/blog.rb +1 -0
  17. data/examples/caching.rb +5 -6
  18. data/examples/css.rb +37 -0
  19. data/examples/layout.rb +3 -17
  20. data/examples/simple_auth.rb +23 -0
  21. data/examples/sourceview/public/images/file.gif +0 -0
  22. data/examples/sourceview/public/images/folder.gif +0 -0
  23. data/examples/sourceview/public/images/tv-collapsable-last.gif +0 -0
  24. data/examples/sourceview/public/images/tv-collapsable.gif +0 -0
  25. data/examples/sourceview/public/images/tv-expandable-last.gif +0 -0
  26. data/examples/sourceview/public/images/tv-expandable.gif +0 -0
  27. data/examples/sourceview/public/images/tv-item-last.gif +0 -0
  28. data/examples/sourceview/public/images/tv-item.gif +0 -0
  29. data/examples/sourceview/public/jquery.js +11 -0
  30. data/examples/sourceview/public/jquery.treeview.css +47 -0
  31. data/examples/sourceview/public/jquery.treeview.js +223 -0
  32. data/examples/sourceview/public/sourceview.js +16 -0
  33. data/examples/sourceview/sourceview.rb +74 -0
  34. data/examples/sourceview/template/index.haml +43 -0
  35. data/examples/templates/template/external.nag +28 -0
  36. data/examples/templates/template/external.xsl +57 -0
  37. data/examples/templates/template_amrita2.rb +2 -4
  38. data/examples/templates/template_erubis.rb +1 -1
  39. data/examples/templates/template_haml.rb +1 -1
  40. data/examples/templates/template_liquid.rb +2 -4
  41. data/examples/templates/template_markaby.rb +2 -4
  42. data/examples/templates/template_nagoro.rb +53 -0
  43. data/examples/templates/template_remarkably.rb +2 -4
  44. data/examples/templates/template_xslt.rb +52 -0
  45. data/examples/whywiki/spec/whywiki.rb +63 -0
  46. data/examples/whywiki/start.rb +11 -13
  47. data/examples/whywiki/template/edit.xhtml +3 -3
  48. data/examples/whywiki/template/show.xhtml +5 -8
  49. data/examples/wikore/spec/wikore.rb +115 -0
  50. data/examples/wikore/src/controller.rb +81 -0
  51. data/examples/wikore/src/model.rb +51 -0
  52. data/examples/wikore/start.rb +6 -0
  53. data/examples/wikore/template/index.xhtml +8 -0
  54. data/examples/wiktacular/spec/wiktacular.rb +1 -0
  55. data/examples/wiktacular/src/controller.rb +1 -1
  56. data/lib/ramaze.rb +6 -3
  57. data/lib/ramaze/action.rb +2 -13
  58. data/lib/ramaze/action/render.rb +36 -18
  59. data/lib/ramaze/adapter.rb +1 -1
  60. data/lib/ramaze/adapter/cgi.rb +0 -3
  61. data/lib/ramaze/adapter/evented_mongrel.rb +7 -0
  62. data/lib/ramaze/adapter/mongrel.rb +4 -13
  63. data/lib/ramaze/adapter/swiftiplied_mongrel.rb +7 -0
  64. data/lib/ramaze/cache.rb +12 -7
  65. data/lib/ramaze/contrib.rb +22 -0
  66. data/lib/ramaze/contrib/auto_params.rb +128 -0
  67. data/lib/ramaze/contrib/auto_params/get_args.rb +56 -0
  68. data/lib/ramaze/contrib/gzip_filter.rb +57 -0
  69. data/lib/ramaze/contrib/route.rb +40 -0
  70. data/lib/ramaze/contrib/sequel/fill.rb +12 -0
  71. data/lib/ramaze/controller.rb +17 -6
  72. data/lib/ramaze/controller/resolve.rb +51 -14
  73. data/lib/ramaze/dispatcher.rb +15 -13
  74. data/lib/ramaze/dispatcher/action.rb +4 -3
  75. data/lib/ramaze/dispatcher/directory.rb +3 -3
  76. data/lib/ramaze/dispatcher/error.rb +1 -1
  77. data/lib/ramaze/dispatcher/file.rb +17 -6
  78. data/lib/ramaze/error.rb +3 -0
  79. data/lib/ramaze/gestalt.rb +28 -8
  80. data/lib/ramaze/global.rb +26 -6
  81. data/lib/ramaze/global/globalstruct.rb +31 -6
  82. data/lib/ramaze/helper.rb +2 -1
  83. data/lib/ramaze/helper/aspect.rb +2 -2
  84. data/lib/ramaze/helper/auth.rb +6 -9
  85. data/lib/ramaze/helper/cache.rb +89 -9
  86. data/lib/ramaze/helper/cgi.rb +2 -2
  87. data/lib/ramaze/helper/formatting.rb +44 -0
  88. data/lib/ramaze/helper/link.rb +7 -5
  89. data/lib/ramaze/helper/partial.rb +6 -4
  90. data/lib/ramaze/helper/redirect.rb +24 -9
  91. data/lib/ramaze/helper/stack.rb +6 -1
  92. data/lib/ramaze/inform/growl.rb +1 -1
  93. data/lib/ramaze/inform/informer.rb +2 -1
  94. data/lib/ramaze/inform/informing.rb +6 -0
  95. data/lib/ramaze/inform/syslog.rb +1 -0
  96. data/lib/ramaze/snippets/array/put_within.rb +24 -0
  97. data/lib/ramaze/snippets/dictionary.rb +499 -0
  98. data/lib/ramaze/snippets/numeric/filesize_format.rb +19 -0
  99. data/lib/ramaze/snippets/ordered_set.rb +31 -0
  100. data/lib/ramaze/snippets/string/DIVIDE.rb +1 -1
  101. data/lib/ramaze/snippets/string/snake_case.rb +1 -1
  102. data/lib/ramaze/snippets/struct/values_at.rb +5 -1
  103. data/lib/ramaze/snippets/thread/into.rb +25 -0
  104. data/lib/ramaze/sourcereload.rb +39 -19
  105. data/lib/ramaze/spec/helper.rb +4 -1
  106. data/lib/ramaze/spec/helper/{context.rb → browser.rb} +3 -0
  107. data/lib/ramaze/spec/helper/layout.rb +3 -0
  108. data/lib/ramaze/spec/helper/minimal.rb +3 -0
  109. data/lib/ramaze/spec/helper/mock_http.rb +8 -5
  110. data/lib/ramaze/spec/helper/requester.rb +4 -1
  111. data/lib/ramaze/spec/helper/wrap.rb +15 -7
  112. data/lib/ramaze/template.rb +5 -1
  113. data/lib/ramaze/template/ezamar/engine.rb +2 -3
  114. data/lib/ramaze/template/ezamar/morpher.rb +26 -45
  115. data/lib/ramaze/template/nagoro.rb +53 -0
  116. data/lib/ramaze/template/none.rb +14 -0
  117. data/lib/ramaze/template/xslt.rb +96 -0
  118. data/lib/ramaze/tool.rb +0 -1
  119. data/lib/ramaze/tool/localize.rb +7 -2
  120. data/lib/ramaze/trinity/request.rb +1 -0
  121. data/lib/ramaze/trinity/session.rb +3 -3
  122. data/lib/ramaze/version.rb +2 -2
  123. data/rake_tasks/conf.rake +1 -2
  124. data/rake_tasks/{maintaince.rake → maintenance.rake} +25 -17
  125. data/spec/contrib/auto_params.rb +97 -0
  126. data/spec/contrib/route.rb +60 -0
  127. data/spec/contrib/sequel/fill.rb +46 -0
  128. data/spec/examples/caching.rb +1 -2
  129. data/spec/examples/css.rb +12 -0
  130. data/spec/examples/element.rb +0 -1
  131. data/spec/examples/hello.rb +0 -1
  132. data/spec/examples/simple.rb +0 -1
  133. data/spec/helper.rb +3 -2
  134. data/spec/ramaze/action/cache.rb +24 -7
  135. data/spec/ramaze/action/layout.rb +19 -11
  136. data/spec/ramaze/action/template/sub/sub_wrapper.xhtml +1 -0
  137. data/spec/ramaze/controller.rb +11 -0
  138. data/spec/ramaze/controller/template_resolving.rb +28 -27
  139. data/spec/ramaze/dispatcher.rb +32 -0
  140. data/spec/ramaze/dispatcher/directory.rb +2 -1
  141. data/spec/ramaze/element.rb +1 -1
  142. data/spec/ramaze/gestalt.rb +28 -0
  143. data/spec/ramaze/helper/aspect.rb +14 -3
  144. data/spec/ramaze/helper/cache.rb +78 -13
  145. data/spec/ramaze/helper/formatting.rb +20 -0
  146. data/spec/ramaze/helper/link.rb +2 -0
  147. data/spec/ramaze/helper/partial.rb +12 -1
  148. data/spec/ramaze/helper/redirect.rb +44 -8
  149. data/spec/ramaze/helper/stack.rb +3 -3
  150. data/spec/ramaze/helper/template/loop.xhtml +3 -0
  151. data/spec/ramaze/helper/template/num.xhtml +1 -0
  152. data/spec/ramaze/helper/template/recursive.xhtml +8 -0
  153. data/spec/ramaze/morpher.rb +25 -6
  154. data/spec/ramaze/params.rb +6 -2
  155. data/spec/ramaze/request.rb +5 -2
  156. data/spec/ramaze/session.rb +19 -0
  157. data/spec/ramaze/template.rb +2 -2
  158. data/spec/ramaze/template/amrita2.rb +2 -2
  159. data/spec/ramaze/template/erubis.rb +2 -2
  160. data/spec/ramaze/template/ezamar.rb +6 -3
  161. data/spec/ramaze/template/haml.rb +3 -3
  162. data/spec/ramaze/template/liquid.rb +1 -1
  163. data/spec/ramaze/template/markaby.rb +1 -1
  164. data/spec/ramaze/template/nagoro.rb +65 -0
  165. data/spec/ramaze/template/nagoro/another/long/action.nag +1 -0
  166. data/spec/ramaze/template/nagoro/combined.nag +1 -0
  167. data/spec/ramaze/template/nagoro/file_only.nag +1 -0
  168. data/spec/ramaze/template/nagoro/index.nag +1 -0
  169. data/spec/ramaze/template/nagoro/nested.nag +1 -0
  170. data/spec/ramaze/template/nagoro/some__long__action.nag +1 -0
  171. data/spec/ramaze/template/nagoro/sum.nag +1 -0
  172. data/spec/ramaze/template/remarkably.rb +1 -1
  173. data/spec/ramaze/template/sass.rb +1 -1
  174. data/spec/ramaze/template/xslt.rb +93 -0
  175. data/spec/ramaze/template/xslt/concat_words.xsl +16 -0
  176. data/spec/ramaze/template/xslt/index.xsl +14 -0
  177. data/spec/ramaze/template/xslt/products.xsl +32 -0
  178. data/spec/ramaze/template/xslt/ruby_version.xsl +14 -0
  179. data/spec/snippets/array/put_within.rb +32 -0
  180. data/spec/snippets/numeric/filesize_format.rb +12 -0
  181. data/spec/snippets/ordered_set.rb +56 -0
  182. data/spec/snippets/ramaze/caller_lines.rb +6 -3
  183. data/spec/snippets/string/snake_case.rb +3 -0
  184. metadata +118 -22
  185. data/doc/README.html +0 -737
  186. data/examples/fcgi.rb +0 -13
  187. data/lib/ramaze/snippets/numeric/human_readable_filesize_format.rb +0 -33
  188. data/lib/ramaze/tool/tidy.rb +0 -104
  189. data/spec/ramaze/controller/template/edit.xhtml +0 -1
  190. data/spec/ramaze/controller/template/edit/content.xhtml +0 -1
  191. data/spec/ramaze/tidy.rb +0 -12
  192. data/spec/snippets/numeric/human_readable_filesize_format.rb +0 -11
@@ -0,0 +1,19 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ class Numeric
5
+ FILESIZE_FORMAT = [
6
+ ['%.1fT', 1 << 40],
7
+ ['%.1fG', 1 << 30],
8
+ ['%.1fM', 1 << 20],
9
+ ['%.1fK', 1 << 10],
10
+ ]
11
+
12
+ def filesize_format
13
+ FILESIZE_FORMAT.each do |format, size|
14
+ return format % (self.to_f / size) if self >= size
15
+ end
16
+
17
+ self.to_s
18
+ end
19
+ end
@@ -0,0 +1,31 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ class OrderedSet
5
+ instance_methods.each { |m| undef_method m unless m =~ /^__/ }
6
+
7
+ def initialize(*args)
8
+ @set = *args
9
+ @set ||= []
10
+ @set = [@set] unless Array === @set
11
+ @set.uniq!
12
+ end
13
+
14
+ def method_missing(meth, *args, &block)
15
+ case meth.to_s
16
+ when /push|unshift|\<\</
17
+ @set.delete *args
18
+ when '[]='
19
+ @set.map! do |e|
20
+ if Array === args.last
21
+ args.last.include?(e) ? nil : e
22
+ else
23
+ args.last == e ? nil : e
24
+ end
25
+ end
26
+ end
27
+ @set.__send__(meth, *args, &block)
28
+ ensure
29
+ @set.delete nil
30
+ end
31
+ end
@@ -5,7 +5,7 @@
5
5
 
6
6
  class String
7
7
 
8
- # A convinient way to do File.join
8
+ # A convenient way to do File.join
9
9
  #
10
10
  # Example:
11
11
  # 'a' / 'b' # -> 'a/b'
@@ -10,6 +10,6 @@ class String
10
10
  # 'FooBar'.snake_case # => 'foo_bar'
11
11
 
12
12
  def snake_case
13
- gsub(/\B[A-Z]/, '_\&').downcase.gsub(' ', '_')
13
+ gsub(/\B[A-Z][^A-Z]/, '_\&').downcase.gsub(' ', '_')
14
14
  end
15
15
  end
@@ -18,6 +18,10 @@ class Struct
18
18
  # # => [15, 10]
19
19
 
20
20
  def values_at(*keys)
21
- keys.map{|k| self[k.to_sym] }
21
+ if keys.all?{|key| key.respond_to?(:to_int) }
22
+ keys.map{|key| values[key.to_int] }
23
+ else
24
+ keys.map{|k| self[k] }
25
+ end
22
26
  end
23
27
  end
@@ -0,0 +1,25 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ class Thread
5
+ # Copy following:
6
+ # :action, :response, :request, :session,
7
+ # :task, :adapter, :controller, :exception
8
+
9
+ def self.into
10
+ Thread.new(Thread.current) do |thread|
11
+ current = Thread.current
12
+
13
+ vars = Dir["#{Ramaze::BASEDIR}/**/*.rb"].
14
+ map{|f| File.readlines(f).
15
+ map{|l| l[/Thread\.current\[:([^\]]*)\]/, 1] } }
16
+
17
+ vars.flatten.compact.uniq.each do |var|
18
+ var = var.to_sym
19
+ current[var] = thread[var]
20
+ end
21
+
22
+ yield
23
+ end
24
+ end
25
+ end
@@ -11,23 +11,29 @@ module Ramaze
11
11
  # manner.
12
12
 
13
13
  class SourceReload
14
- attr_accessor :thread, :interval, :reload_glob, :map
14
+ attr_accessor :thread, :interval, :map
15
15
 
16
- # Take interval and a regular expression for files that are going to be reloaded.
17
- def initialize interval = 1, reload_glob = %r{(^\./)|#{Dir.pwd}|ramaze}
18
- @interval, @reload_glob = interval, reload_glob
16
+ # Reload everything which falls under this regex
17
+ trait :reload_glob => %r{(^\./)|#{Dir.pwd}|ramaze}
18
+
19
+ # Take interval for files that are going to be reloaded.
20
+
21
+ def initialize(interval = 1)
22
+ @interval = interval
19
23
  @map, @files, @paths = [], [], []
20
24
  @mtimes = {}
21
25
  end
22
26
 
23
27
  # start reloader-thread and assign it to this instance.
28
+
24
29
  def start
25
- Inform.debug("initialize automatic source reload every #{interval} seconds")
30
+ Inform.dev("initialize automatic source reload every #{interval} seconds")
26
31
  @thread = reloader
27
32
  end
28
33
 
29
34
  # Takes value of Global.sourcereload and unless it's false calls #start
30
- def self.startup options = {}
35
+
36
+ def self.startup(options = {})
31
37
  interval = Global.sourcereload
32
38
  instance = new(interval)
33
39
  Thread.main[:sourcereload] = instance
@@ -36,6 +42,7 @@ module Ramaze
36
42
  end
37
43
 
38
44
  # Start reload loop in separate Thread
45
+
39
46
  def reloader
40
47
  Thread.new do
41
48
  loop do
@@ -45,16 +52,17 @@ module Ramaze
45
52
  end
46
53
  end
47
54
 
48
- # One iteration of reload will look for files that changed since the last iteration
49
- # and will try to #safe_load it.
50
- # This method is quite handy if you want direct control over when your code is reloaded
55
+ # One iteration of reload will look for files that changed since the last
56
+ # iteration and will try to #safe_load it.
57
+ # This method is quite handy if you want direct control over when your
58
+ # code is reloaded
51
59
  #
52
60
  # Usage example:
53
61
  #
54
- # trap :HUB do
55
- # Ramaze::Inform.info "reloading source"
56
- # Thread.main[:sourcereload].reload
57
- # end
62
+ # trap :HUP do
63
+ # Ramaze::Inform.info "reloading source"
64
+ # Thread.main[:sourcereload].reload
65
+ # end
58
66
  #
59
67
 
60
68
  def reload
@@ -71,32 +79,38 @@ module Ramaze
71
79
  end
72
80
 
73
81
  # Scans loaded features and paths for file-paths, filters them in the end
74
- # according to the @reload_glob
82
+ # according to the trait[:reload_glob]
83
+
75
84
  def all_reload_files
76
- files, paths = $LOADED_FEATURES, Array['', './', *$LOAD_PATH]
85
+ files = Array[$0, *$LOADED_FEATURES]
86
+ paths = Array['', './', *$LOAD_PATH]
77
87
 
78
88
  unless [@files, @paths] == [files, paths]
79
89
  @files, @paths = files.dup, paths.dup
80
90
 
81
91
  map = files.map do |file|
82
- possible = paths.map{|pa| File.join(pa.to_s, file.to_s) }
83
- possible.find{|po| File.exists?(po) }
92
+ paths.map{|pa|
93
+ File.expand_path(File.join(pa.to_s, file.to_s))
94
+ }.find{|po| File.exists?(po) }
84
95
  end
85
96
 
86
97
  @map = map.compact
87
98
  end
88
99
 
89
- m = @map.grep(@reload_glob)
100
+ m = @map.grep(class_trait[:reload_glob])
90
101
  end
91
102
 
92
103
  # Safe mtime
104
+
93
105
  def mtime(file)
94
106
  File.mtime(file)
95
107
  rescue Errno::ENOENT
96
108
  false
97
109
  end
98
110
 
99
- # A safe Kernel::load, issuing the SourceReloadHooks dependin on the result.
111
+ # A safe Kernel::load, issuing the SourceReloadHooks depending on the
112
+ # result.
113
+
100
114
  def safe_load(file)
101
115
  SourceReloadHooks.before_safe_load(file)
102
116
  load(file)
@@ -134,6 +148,12 @@ module Ramaze
134
148
  def after_safe_load_succeed(file)
135
149
  Cache.compiled.clear
136
150
  Cache.resolved.clear
151
+ SourceReloadHooks.after_safe_load(file)
152
+ end
153
+
154
+ # Overwrite to add custom hook in addition to default Cache cleaning
155
+
156
+ def after_safe_load(file)
137
157
  end
138
158
 
139
159
  # Overwrite to add actions after a file is Kernel::load-ed unsuccessfully,
@@ -5,7 +5,7 @@ require 'ramaze/spec/helper/minimal'
5
5
  require 'ramaze/spec/helper/mock_http'
6
6
  require 'ramaze/spec/helper/simple_http'
7
7
  require 'ramaze/spec/helper/requester'
8
- require 'ramaze/spec/helper/context'
8
+ require 'ramaze/spec/helper/browser'
9
9
 
10
10
  Spec::Runner.configure do |config|
11
11
  config.include MockHTTP
@@ -22,7 +22,10 @@ end
22
22
  # that will be merged with the default-options.
23
23
 
24
24
  def ramaze_start hash = {}
25
+ appdir = File.dirname(caller[0].split(':').first)
25
26
  options = {
27
+ :template_root => appdir/:template,
28
+ :public_root => appdir/:public,
26
29
  :adapter => false,
27
30
  :run_loose => true,
28
31
  :error_page => false,
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
1
4
  class Browser
2
5
  attr_reader :cookie
3
6
 
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
1
4
  require 'ramaze/spec/helper/wrap'
2
5
 
3
6
  class SpecLayout
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
1
4
  require 'timeout'
2
5
 
3
6
  begin
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
1
4
  require 'ramaze'
2
5
  require 'rack/mock'
3
6
 
@@ -40,7 +43,7 @@ module MockHTTP
40
43
  def process_request(path, query)
41
44
  options = {}
42
45
  FISHING.each{|key, value|
43
- options[value] = query.delete(key)}
46
+ options[value] = query.delete(key)} if query.is_a?(Hash)
44
47
  [create_url(path, query), options]
45
48
  end
46
49
 
@@ -52,9 +55,9 @@ module MockHTTP
52
55
  end
53
56
 
54
57
  def make_query query
55
- return query unless query && query.class == Hash
56
- query.inject([]) do |s, (key, value)|
57
- s + [CGI::escape(key) + "=" + CGI::escape(value)]
58
- end.join('&')
58
+ return query unless query and not query.is_a?(String)
59
+ query.map{|key, value|
60
+ "#{CGI::escape(key.to_s)}=#{CGI::escape(value.to_s)}"
61
+ }.join('&')
59
62
  end
60
63
  end
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
1
4
  module Requester
2
5
  def get url = '/', hash = {}
3
6
  request(:get, url, hash)
@@ -10,7 +13,7 @@ module Requester
10
13
  def request method, url, hash = {}
11
14
  http = SimpleHttp.new(url2uri(url))
12
15
  if method == :get and not hash.empty?
13
- http.uri.query = hash.inject([]){|s,(k,v)| s << "#{k}=#{v}"}.join('&')
16
+ http.uri.query = hash.map{|k,v| "#{k}=#{v}"}.join('&')
14
17
  hash = {}
15
18
  end
16
19
 
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
1
4
  require 'pp'
2
5
  require 'set'
3
6
 
@@ -9,7 +12,7 @@ end
9
12
  begin
10
13
  require 'systemu'
11
14
  rescue LoadError
12
- puts "Please install systemu for better-looking results"
15
+ puts "Please install systemu for accurate results"
13
16
 
14
17
  # small drop-in replacement for systemu... far from perfect though, so please
15
18
  # install the library
@@ -65,7 +68,10 @@ class SpecWrap
65
68
  end
66
69
 
67
70
  def run
68
- @specs.sort_by{|s| s.last}.each do |file, name|
71
+ total = @specs.size
72
+ n_width = (total.to_s.size * 2) + 4
73
+ @specs.sort_by{|s| s.last}.each_with_index do |(file, name), idx|
74
+ print "(#{idx+1}/#{total}) ".ljust(n_width)
69
75
  spec = SpecFile.new(file, name, term_width)
70
76
  spec.run
71
77
  spec.short_summary
@@ -118,7 +124,7 @@ class SpecFile
118
124
  end
119
125
 
120
126
  def init
121
- print "Running #@name... ".ljust(@term_width + 20)
127
+ print "#@name ".ljust(@term_width + 10)
122
128
  end
123
129
 
124
130
  def execute
@@ -141,7 +147,8 @@ class SpecFile
141
147
  elsif failed?
142
148
  text = "#{total} specs - #{failed} failed".rjust(width)
143
149
  if @stdout =~ /Usually you should not worry about this failure, just install the/
144
- lib = @stdout.scan(/^no such file to load -- (.*?)$/).flatten.first
150
+ lib = @stdout[/^no such file to load -- (.*?)$/, 1] ||
151
+ @stdout[/RubyGem version error: (.*)$/, 1]
145
152
  text = "needs #{lib}".center(width)
146
153
  @mark_passed = true
147
154
  end
@@ -154,9 +161,10 @@ class SpecFile
154
161
  end
155
162
 
156
163
  def long_summary
157
- puts "[ #@name ]".center(80, '-'), "ExitStatus:".yellow
158
- pp @status
159
- puts "StdOut:".yellow, @stdout, "StdErr:".yellow, @stderr
164
+ puts "[ #@name ]".center(80, '-')
165
+ puts "ExitStatus:".yellow, PP.pp(@status)
166
+ puts "StdOut:".yellow, @stdout
167
+ puts "StdErr:".yellow, PP.pp(@stderr, '')
160
168
  end
161
169
 
162
170
  def parse
@@ -16,7 +16,8 @@ module Ramaze
16
16
 
17
17
  ENGINES = {} unless defined?(ENGINES)
18
18
 
19
- %w[ Amrita2 Erubis Haml Liquid Markaby Remarkably Sass ].each do |const|
19
+ %w[ Amrita2 Erubis Haml Liquid Markaby Nagoro None Remarkably Sass XSLT ].
20
+ each do |const|
20
21
  autoload(const, "ramaze/template/#{const.downcase}")
21
22
  end
22
23
 
@@ -63,7 +64,10 @@ module Ramaze
63
64
 
64
65
  def wrap_compile(action, template = nil)
65
66
  template ||= reaction_or_file(action).to_s
67
+ caching_compile(action, template)
68
+ end
66
69
 
70
+ def caching_compile(action, template)
67
71
  if Global.compile
68
72
  Cache.compiled[action.relaxed_hash] ||= compile(action, template)
69
73
  else
@@ -12,7 +12,6 @@ require 'digest/sha1'
12
12
  module Ezamar
13
13
 
14
14
  require 'ramaze/template/ezamar/element'
15
- require 'ramaze/template/ezamar/morpher'
16
15
 
17
16
  # This class is responsible for initializing and compiling the template.
18
17
 
@@ -56,11 +55,11 @@ module Ezamar
56
55
  start_heredoc, end_heredoc = "\n<<#{start_heredoc}\n", "\n#{start_heredoc}\n"
57
56
  bufadd = "_out_ << "
58
57
 
59
- temp.gsub!(/<%\s+(.*?)\s+%>/m,
58
+ temp.gsub!(/<%(?!=)\s*(.*?)\s*%>/m,
60
59
  "#{end_heredoc} \\1; #{bufadd} #{start_heredoc}")
61
60
  temp.gsub!(/<\?r\s+(.*?)\s+\?>/m,
62
61
  "#{end_heredoc} \\1; #{bufadd} #{start_heredoc}")
63
- temp.gsub!(/<%=\s+(.*?)\s+%>/m,
62
+ temp.gsub!(/<%=\s*(.*?)\s*%>/m,
64
63
  "#{end_heredoc} #{bufadd} (\\1); #{bufadd} #{start_heredoc}")
65
64
 
66
65
  @compiled = "_out_ = ''
@@ -2,6 +2,12 @@
2
2
  # All files in this distribution are subject to the terms of the Ruby license.
3
3
 
4
4
  require 'ramaze/template/ezamar/engine'
5
+ begin
6
+ require 'hpricot'
7
+ rescue LoadError => ex
8
+ Ramaze::Inform.error "Please install hpricot (for example via `gem install hpricot`) to get morphing"
9
+ puts ex
10
+ end
5
11
 
6
12
  # This applies a morphing-replace for the template.
7
13
  #
@@ -20,16 +26,16 @@ require 'ramaze/template/ezamar/engine'
20
26
  # from:
21
27
  # Ramaze::Template::Ezamar::TRANSFORM_PIPELINE
22
28
  # or do:
23
- # Ramaze::Morpher.trait[:morphs] = {}
29
+ # Ramaze::Morpher::MORPHS.clear
24
30
  #
25
31
  # The latter is a tad slower, but i mention the possibility in case you
26
32
  # find good use for it.
27
33
  #
28
- # You can add your own morphers in Ramaze::Morpher.trait[:morphs]
34
+ # You can add your own morphers in Ramaze::Morpher::MORPHS
29
35
  #
30
36
  # For Example:
31
37
  #
32
- # Morpher.trait[:morphs]['if'] = '<?r %morph %expression ?>%content<?r end ?>'
38
+ # Morpher::MORPHS['if'] = '<?r %morph %expression ?>%content<?r end ?>'
33
39
  #
34
40
  # Now, assuming that some tag in your template is '<a if="@foo">x</a>'
35
41
  #
@@ -40,12 +46,12 @@ require 'ramaze/template/ezamar/engine'
40
46
  class Ezamar::Morpher
41
47
 
42
48
  # Use this trait to define your custom morphs.
43
- trait :morphs => {
44
- 'if' => '<?r %morph %expression ?>%content<?r end ?>',
45
- 'unless' => '<?r %morph %expression ?>%content<?r end ?>',
46
- 'for' => '<?r %morph %expression ?>%content<?r end ?>',
47
- 'each' => '<?r %expression.%morph do |_e| ?>%content<?r end ?>',
48
- 'times' => '<?r %expression.%morph do |_t| ?>%content<?r end ?>',
49
+ MORPHS = {
50
+ 'if' => '<?r %morph %expression ?>%content<?r end ?>',
51
+ 'unless' => '<?r %morph %expression ?>%content<?r end ?>',
52
+ 'for' => '<?r %morph %expression ?>%content<?r end ?>',
53
+ 'each' => '<?r %expression.%morph do |_e| ?>%content<?r end ?>',
54
+ 'times' => '<?r %expression.%morph do |_t| ?>%content<?r end ?>',
49
55
  }
50
56
 
51
57
  # Since the functionality is best explained by examples, here they come.
@@ -107,49 +113,24 @@ class Ezamar::Morpher
107
113
  # - Add pure Ruby implementation as a fall-back.
108
114
 
109
115
  def self.transform(template)
110
- morphs =
111
- trait[:morphs].map{|k,v| [k.to_s, v.to_s]}.select do |(k,v)|
112
- template.to_s.include?("#{k}=")
113
- end
114
-
115
- morphs = Hash[*morphs.flatten]
116
-
117
- return template if morphs.empty?
118
-
119
- require 'hpricot'
120
-
116
+ template = template.to_s
121
117
  hp = Hpricot(template)
122
- hp.each_child do |child|
123
- if child.elem?
124
- morphs.each_pair do |morph, replacement|
125
- if expression = child[morph]
126
- old = child.to_html
127
- child.remove_attribute(morph)
128
-
129
- replacement = replacement.dup.
130
- gsub('%morph', morph).
131
- gsub('%expression', expression).
132
- gsub('%content', child.to_html)
133
-
134
- template.gsub!(old, replacement)
135
- end
136
- end
137
- end
138
- end
139
118
 
140
- template
119
+ MORPHS.each do |morph, replacement|
120
+ hp.search("[@#{morph}]") do |elem|
121
+ expr = elem[morph]
141
122
 
142
- rescue LoadError => ex
143
- error "Please install hpricot (for example via `gem install hpricot`) to get morphing"
123
+ elem.remove_attribute(morph)
144
124
 
145
- # replace this method with a stub that only returns the template.
125
+ repl = replacement.
126
+ sub('%morph', morph).
127
+ sub('%expression', expr).
128
+ sub('%content', elem.to_html)
146
129
 
147
- self.class_eval do
148
- def self.transform(template)
149
- template
130
+ elem.swap(repl)
150
131
  end
151
132
  end
152
133
 
153
- template
134
+ hp.to_html
154
135
  end
155
136
  end