malt 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. data/.ruby +156 -0
  2. data/Assembly +28 -0
  3. data/COPYING.rdoc +33 -0
  4. data/Gemfile +10 -0
  5. data/HISTORY.rdoc +102 -0
  6. data/README.rdoc +16 -10
  7. data/Reapfile +4 -0
  8. data/lib/malt.rb +36 -8
  9. data/lib/malt.yml +156 -0
  10. data/lib/malt/conversions.rb +42 -0
  11. data/lib/malt/core_ext.rb +81 -3
  12. data/lib/malt/engines/abstract.rb +259 -50
  13. data/lib/malt/engines/bluecloth.rb +19 -9
  14. data/lib/malt/engines/builder.rb +93 -32
  15. data/lib/malt/engines/coffee.rb +46 -0
  16. data/lib/malt/engines/creole.rb +60 -0
  17. data/lib/malt/engines/erb.rb +69 -44
  18. data/lib/malt/engines/erector.rb +61 -30
  19. data/lib/malt/engines/erubis.rb +41 -31
  20. data/lib/malt/engines/haml.rb +13 -37
  21. data/lib/malt/engines/kramdown.rb +40 -15
  22. data/lib/malt/engines/less.rb +15 -14
  23. data/lib/malt/engines/liquid.rb +24 -14
  24. data/lib/malt/engines/markaby.rb +44 -22
  25. data/lib/malt/engines/maruku.rb +89 -0
  26. data/lib/malt/engines/mustache.rb +20 -14
  27. data/lib/malt/engines/nokogiri.rb +89 -0
  28. data/lib/malt/engines/radius.rb +72 -34
  29. data/lib/malt/engines/ragtag.rb +26 -18
  30. data/lib/malt/engines/rdiscount.rb +18 -11
  31. data/lib/malt/engines/rdoc.rb +21 -15
  32. data/lib/malt/engines/redcarpet.rb +137 -0
  33. data/lib/malt/engines/redcloth.rb +15 -7
  34. data/lib/malt/engines/ruby.rb +13 -12
  35. data/lib/malt/engines/sass.rb +30 -17
  36. data/lib/malt/engines/string.rb +36 -0
  37. data/lib/malt/engines/tenjin.rb +70 -27
  38. data/lib/malt/engines/wikicloth.rb +48 -0
  39. data/lib/malt/formats/abstract.rb +90 -29
  40. data/lib/malt/formats/abstract_template.rb +10 -8
  41. data/lib/malt/formats/builder.rb +39 -13
  42. data/lib/malt/formats/coffee.rb +54 -0
  43. data/lib/malt/formats/css.rb +3 -3
  44. data/lib/malt/formats/erb.rb +31 -66
  45. data/lib/malt/formats/haml.rb +8 -8
  46. data/lib/malt/formats/html.rb +1 -7
  47. data/lib/malt/formats/javascript.rb +27 -0
  48. data/lib/malt/formats/latex.rb +1 -1
  49. data/lib/malt/formats/less.rb +13 -11
  50. data/lib/malt/formats/liquid.rb +7 -7
  51. data/lib/malt/formats/markdown.rb +43 -44
  52. data/lib/malt/formats/mediawiki.rb +70 -0
  53. data/lib/malt/formats/mustache.rb +5 -5
  54. data/lib/malt/formats/pdf.rb +1 -7
  55. data/lib/malt/formats/radius.rb +5 -4
  56. data/lib/malt/formats/ragtag.rb +14 -13
  57. data/lib/malt/formats/rbhtml.rb +28 -20
  58. data/lib/malt/formats/rdoc.rb +5 -4
  59. data/lib/malt/formats/rhtml.rb +19 -43
  60. data/lib/malt/formats/ruby.rb +11 -45
  61. data/lib/malt/formats/sass.rb +16 -24
  62. data/lib/malt/formats/scss.rb +13 -30
  63. data/lib/malt/formats/string.rb +61 -0
  64. data/lib/malt/formats/tenjin.rb +4 -4
  65. data/lib/malt/formats/text.rb +1 -1
  66. data/lib/malt/formats/textile.rb +7 -19
  67. data/lib/malt/kernel.rb +1 -2
  68. data/lib/malt/machine.rb +83 -13
  69. data/lib/malt/tilted.rb +216 -0
  70. data/lib/malt/version.rb +21 -0
  71. data/test/helper.rb +15 -0
  72. data/test/unit/engines/case_engine_bluecloth.rb +40 -0
  73. data/test/unit/engines/case_engine_builder.rb +30 -0
  74. data/test/unit/engines/case_engine_coffee.rb +30 -0
  75. data/test/unit/engines/case_engine_creole.rb +35 -0
  76. data/test/unit/engines/case_engine_erb.rb +28 -0
  77. data/test/unit/engines/case_engine_erector.rb +36 -0
  78. data/test/unit/engines/case_engine_erubis.rb +28 -0
  79. data/test/unit/engines/case_engine_haml.rb +30 -0
  80. data/test/unit/engines/case_engine_kramdown.rb +30 -0
  81. data/test/unit/engines/case_engine_less.rb +40 -0
  82. data/test/unit/engines/case_engine_liquid.rb +28 -0
  83. data/test/unit/engines/case_engine_markaby.rb +20 -0
  84. data/test/unit/engines/case_engine_maruku.rb +30 -0
  85. data/test/unit/engines/case_engine_mustache.rb +28 -0
  86. data/test/unit/engines/case_engine_nokogiri.rb +30 -0
  87. data/test/unit/engines/case_engine_radius.rb +30 -0
  88. data/test/unit/engines/case_engine_ragtag.rb +40 -0
  89. data/test/unit/engines/case_engine_rdiscount.rb +30 -0
  90. data/test/unit/engines/case_engine_rdoc.rb +31 -0
  91. data/test/unit/engines/case_engine_redcarpet.rb +30 -0
  92. data/test/unit/engines/case_engine_redcloth.rb +31 -0
  93. data/test/unit/engines/case_engine_ruby.rb +28 -0
  94. data/test/unit/engines/case_engine_sass.rb +36 -0
  95. data/test/unit/engines/case_engine_string.rb +28 -0
  96. data/test/unit/engines/case_engine_tenjin.rb +28 -0
  97. data/test/unit/engines/case_engine_wikicloth.rb +25 -0
  98. data/test/unit/machine.rb +27 -0
  99. data/test/unit/malt.rb +12 -0
  100. metadata +364 -266
  101. data/History.rdoc +0 -64
  102. data/License.txt +0 -205
  103. data/Syckfile +0 -80
  104. data/features/consistent_rendering.feature +0 -36
  105. data/features/samples/sample.erb +0 -1
  106. data/features/samples/sample.erubis +0 -1
  107. data/features/samples/sample.liquid +0 -1
  108. data/features/samples/sample.mustache +0 -1
  109. data/features/samples/sample.radius +0 -1
  110. data/features/step_definitions/engine_steps.rb +0 -49
  111. data/features/support/loadpath.rb +0 -1
  112. data/features/support/sample_class.rb +0 -8
  113. data/lib/malt/formats/erector.rb +0 -53
  114. data/lib/malt/formats/markaby.rb +0 -53
  115. data/lib/malt/meta/data.rb +0 -26
  116. data/lib/malt/meta/package +0 -21
  117. data/lib/malt/meta/profile +0 -21
  118. data/meta/data.rb +0 -26
  119. data/meta/package +0 -21
  120. data/meta/profile +0 -21
  121. data/qed/01_overview.rdoc +0 -8
  122. data/qed/02_formats.rdoc +0 -39
  123. data/qed/03_formats/01_overview.rdoc +0 -7
  124. data/qed/03_formats/02_rdoc.rdoc +0 -83
  125. data/qed/03_formats/03_textile.rdoc +0 -48
  126. data/qed/03_formats/04_markdown.rdoc +0 -66
  127. data/qed/03_formats/05_erb.rdoc +0 -65
  128. data/qed/03_formats/06_liquid.rdoc +0 -54
  129. data/qed/03_formats/07_haml.rdoc +0 -44
  130. data/qed/03_formats/08_ragtag.rdoc +0 -19
  131. data/qed/03_formats/09_radius.rdoc +0 -43
  132. data/qed/03_formats/11_tenjin.rdoc +0 -47
  133. data/qed/03_formats/12_rbhtml.rdoc +0 -55
  134. data/qed/03_formats/13_sass.rdoc +0 -55
  135. data/qed/03_formats/14_scss.rdoc +0 -58
  136. data/qed/03_formats/15_less.rdoc +0 -46
  137. data/qed/03_formats/16_ruby.rdoc +0 -48
  138. data/qed/03_formats/17_markaby.rdoc +0 -50
  139. data/qed/03_formats/18_builder.rb +0 -50
  140. data/qed/03_formats/19_erector.rb +0 -50
  141. data/qed/03_formats/20_mustache.rdoc +0 -54
  142. data/qed/05_machine/01_limited_formats.rdoc +0 -29
  143. data/qed/05_machine/02_prioritized_engines.rdoc +0 -34
  144. data/qed/applique/malt.rb +0 -13
  145. data/qed/samples/data.yml +0 -4
  146. data/qed/samples/output-erb.txt +0 -1
  147. data/qed/samples/output-liquid.txt +0 -1
  148. data/qed/samples/output-mustache.txt +0 -1
  149. data/qed/samples/output-radius.txt +0 -1
  150. data/qed/samples/sample.erb +0 -1
  151. data/qed/samples/sample.liquid +0 -1
  152. data/qed/samples/sample.markdown +0 -308
  153. data/qed/samples/sample.mustache +0 -1
  154. data/qed/samples/sample.radius +0 -1
  155. data/qed/samples/sample.rdoc +0 -8
@@ -0,0 +1,156 @@
1
+ ---
2
+ source:
3
+ - var
4
+ authors:
5
+ - name: trans
6
+ email: transfire@gmail.com
7
+ copyrights:
8
+ - holder: Rubyworks
9
+ year: '2010'
10
+ license: BSD-2-Clause
11
+ replacements: []
12
+ alternatives: []
13
+ requirements:
14
+ - name: blankslate
15
+ - name: detroit
16
+ groups:
17
+ - build
18
+ development: true
19
+ - name: qed
20
+ groups:
21
+ - test
22
+ development: true
23
+ - name: test
24
+ groups:
25
+ - test
26
+ development: true
27
+ - name: lemon
28
+ groups:
29
+ - test
30
+ development: true
31
+ - name: ae
32
+ groups:
33
+ - test
34
+ development: true
35
+ - name: rdoc
36
+ version: 3+
37
+ groups:
38
+ - test
39
+ development: true
40
+ - name: RedCloth
41
+ groups:
42
+ - test
43
+ development: true
44
+ - name: bluecloth
45
+ groups:
46
+ - test
47
+ development: true
48
+ - name: kramdown
49
+ groups:
50
+ - test
51
+ development: true
52
+ - name: rdiscount
53
+ groups:
54
+ - test
55
+ development: true
56
+ - name: haml
57
+ groups:
58
+ - test
59
+ development: true
60
+ - name: sass
61
+ groups:
62
+ - test
63
+ development: true
64
+ - name: less
65
+ groups:
66
+ - test
67
+ development: true
68
+ - name: tenjin
69
+ groups:
70
+ - test
71
+ development: true
72
+ - name: rtals
73
+ groups:
74
+ - test
75
+ development: true
76
+ - name: liquid
77
+ groups:
78
+ - test
79
+ development: true
80
+ - name: erubis
81
+ groups:
82
+ - test
83
+ development: true
84
+ - name: mustache
85
+ groups:
86
+ - test
87
+ development: true
88
+ - name: markaby
89
+ groups:
90
+ - test
91
+ development: true
92
+ - name: builder
93
+ groups:
94
+ - test
95
+ development: true
96
+ - name: radius
97
+ groups:
98
+ - test
99
+ development: true
100
+ - name: ragtag
101
+ groups:
102
+ - test
103
+ development: true
104
+ - name: redcarpet
105
+ groups:
106
+ - test
107
+ development: true
108
+ - name: wikicloth
109
+ groups:
110
+ - test
111
+ development: true
112
+ - name: maruku
113
+ groups:
114
+ - test
115
+ development: true
116
+ - name: creole
117
+ groups:
118
+ - test
119
+ development: true
120
+ - name: erector
121
+ groups:
122
+ - test
123
+ development: true
124
+ - name: active_support
125
+ groups:
126
+ - test
127
+ development: true
128
+ - name: coffee-script
129
+ groups:
130
+ - test
131
+ development: true
132
+ dependencies: []
133
+ conflicts: []
134
+ repositories:
135
+ - uri: git@github.com:rubyworks/malt.git
136
+ scm: git
137
+ name: upstream
138
+ resources:
139
+ home: http://rubyworks.github.com/malt
140
+ code: http://github.com/rubyworks/malt
141
+ wiki: http://wiki.github.com/rubyworks/malt
142
+ docs: http://rubyworks.github.com/malt/docs/api
143
+ bugs: http://github.com/rubyworks/malt/issues
144
+ extra: {}
145
+ load_path:
146
+ - lib
147
+ revision: 0
148
+ created: '2010-06-22'
149
+ summary: Multi-template/multi-markup rendering engine
150
+ title: Malt
151
+ version: 0.4.0
152
+ name: malt
153
+ description: Malt provides a factory framework for rendering a variety of template
154
+ and markup document formats.
155
+ organization: rubyworks
156
+ date: '2011-11-26'
@@ -0,0 +1,42 @@
1
+ module Malt
2
+
3
+ module Conversions
4
+
5
+ module Binding
6
+ extend self
7
+
8
+ #
9
+ def to_binding(binding)
10
+ binding
11
+ end
12
+
13
+ #
14
+ def to_hash(binding)
15
+ Hash.new{ |h,k| h[k] = binding.eval(k) }
16
+ end
17
+
18
+ #
19
+ def to_object(binding)
20
+ obj = binding.eval("self")
21
+
22
+ vars = binding.eval("local_variables")
23
+ vals = binding.eval("[#{vars.join(',')}]")
24
+ data = Hash[*vars.zip(vals).flatten]
25
+
26
+ adhoc = (class << obj; self; end)
27
+ data.each do |name,value|
28
+ adhoc.__send__(:define_method, name){ value }
29
+ end
30
+
31
+ obj
32
+ end
33
+
34
+ end
35
+
36
+ module Object
37
+
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -1,8 +1,10 @@
1
1
  require 'ostruct'
2
2
  require 'facets/module/basename'
3
+ require 'facets/to_hash'
4
+ require 'facets/hash/rekey'
3
5
 
6
+ =begin
4
7
  class Hash
5
-
6
8
  #
7
9
  def to_hash
8
10
  dup
@@ -18,14 +20,90 @@ class Hash
18
20
  end
19
21
  h
20
22
  end unless method_defined?(:rekey)
23
+ end
24
+ =end
25
+
26
+
27
+ class Binding
28
+ # Conversion for bindings.
29
+ #
30
+ # @todo Is there any way to integrate the optional data and block?
31
+ def to_binding
32
+ self
33
+ end
34
+
35
+ #
36
+ def itself
37
+ eval('self')
38
+ end
39
+
40
+ # Create a new binding incorporating the current binding and
41
+ # the given local settings hash and yield block.
42
+ #
43
+ # The yield code was neccessary b/c Ruby does not respect the use
44
+ # of yield in a lambda (boo hiss).
45
+ def with(_hash, &_yield)
46
+ _hash = (_hash || {}).to_hash
47
+
48
+ if _yield
49
+ vars = eval('local_variables')
50
+ vals = eval("[#{vars.join(',')}]")
51
+
52
+ vars += _hash.keys
53
+ vals += _hash.values
54
+
55
+ code = <<-END
56
+ def self.___with(#{vars.join(',')})
57
+ binding
58
+ end
59
+ method(:___with)
60
+ END
61
+ eval(code).call(*vals, &_yield)
21
62
 
63
+ #_args = _hash.empty? ? '' : '|' + _hash.keys.join(',') + ',&y|'
64
+ #lamb = eval("lambda{#{_args} binding}")
65
+ #(class << self; self; end).send(:define_method, :__temp__, &lamb)
66
+ #method(:__temp__).call(*_hash.values, &_yield)
67
+ else
68
+ _args = _hash.empty? ? '' : '|' + _hash.keys.join(',') + '|'
69
+ eval("lambda{#{_args} binding}").call(*_hash.values)
70
+ end
71
+ end
72
+ end
73
+
74
+ class Object
75
+ def to_binding
76
+ binding
77
+ end
78
+ end
79
+
80
+ class Struct
81
+ def to_struct
82
+ self
83
+ end
84
+
85
+ def to_h
86
+ Hash[members.zip(values)]
87
+ end unless method_defined?(:to_h)
88
+
89
+ #def to_hash
90
+ # Hash[members.zip(values)]
91
+ #end
22
92
  end
23
93
 
24
94
  class OpenStruct
95
+ def to_struct
96
+ self
97
+ end
25
98
 
26
99
  #
27
- def to_hash
100
+ def to_h #ash
28
101
  @table.dup
29
- end unless method_defined?(:to_hash)
102
+ end unless method_defined?(:to_h)
103
+ end
30
104
 
105
+ unless defined?(::BasicObject)
106
+ require 'blankslate'
107
+ ::BasicObject = ::BlankSlate
31
108
  end
109
+
@@ -58,36 +58,62 @@ module Engine
58
58
  @cache = {}
59
59
  @source = {}
60
60
 
61
- initialize_engine
61
+ require_engine
62
62
  end
63
63
 
64
64
  # Access to the options given to the initializer.
65
65
  attr :settings
66
66
 
67
67
  #
68
- def render(text, options={}) #format, text, file, db, &yld)
69
- if format = options[:format]
70
- raise "unsupported rendering -- #{format}"
68
+ def cache?
69
+ !settings[:nocache]
70
+ end
71
+
72
+ #
73
+ def render(params, &block)
74
+ if into = params[:to]
75
+ raise NotImplementedError, "unsupported rendering -- #{into}"
71
76
  else
72
- raise "unsupported rendering"
77
+ raise NotImplementedError, "unsupported rendering"
73
78
  end
74
79
  end
75
80
 
76
- #
77
- def compile(db, &yld)
78
- raise "not implemented"
81
+ # Prepare engine for rendering.
82
+ def prepare_engine(params={}, &content)
83
+ create_engine(params, &content)
79
84
  end
80
85
 
86
+ # Instantiate engine class with engine options and template text,
87
+ # if possible.
81
88
  #
82
- def cache?
83
- !settings[:nocache]
89
+ # The initialization MUST never include template data and should
90
+ # support caching, if feasible.
91
+ #
92
+ def create_engine(params={})
93
+ raise NotImplementedError, "not implemented"
84
94
  end
85
95
 
86
- private
96
+ # Convert a rendition to Ruby source code. Not all engines support compiling.
97
+ #
98
+ #def compile(*data, &content)
99
+ # raise NotImplementedError, "not implemented"
100
+ #end
101
+
102
+ private
103
+
104
+ # Cached yield reuslt with given key if cache mode is active.
105
+ #
106
+ def cached(*key)
107
+ if cache?
108
+ @cache[key] ||= yield
109
+ else
110
+ yield
111
+ end
112
+ end
87
113
 
88
114
  # Override this to load template engine library and
89
115
  # prepare is for geeral usage.
90
- def initialize_engine
116
+ def require_engine
91
117
  end
92
118
 
93
119
  # Require template library.
@@ -95,63 +121,246 @@ module Engine
95
121
  require(path)
96
122
  end
97
123
 
98
- # Convert a data source into a Binding.
99
- # TODO: handle yld.
100
- def make_binding(db, &yld)
101
- return db if Binding === db # FIXME: no yld
124
+ # - - - D A T A H A N D L I N G - - -
125
+
126
+ # Take `scope` and `locals` data sources are return them as object and
127
+ # locals hash.
128
+ #
129
+ # @param [Object,Binding] scope
130
+ #
131
+ # @param [Hash] locals
132
+ #
133
+ # @return [Array<Object,Hash>] Two element array of scope object and data hash.
134
+ def make_ready(scope, locals=nil, &content)
135
+ locals ||= {}
136
+
137
+ case scope
138
+ when Binding
139
+ vars = scope.eval("local_variables")
140
+ vals = scope.eval("[#{vars.join(',')}]")
141
+ locals = locals.merge(Hash[*vars.zip(vals).flatten])
142
+ scope = scope.eval("self")
143
+ end
144
+
145
+ if scope.respond_to?(:to_struct)
146
+ locals = locals.merge(scope.to_struct.to_h)
147
+ scope = Object.new
148
+ end
102
149
 
103
- if db.respond_to?(:to_binding)
104
- return db.to_binding(&yld)
150
+ if scope.respond_to?(:to_hash)
151
+ locals = locals.merge(scope.to_hash)
152
+ scope = Object.new
105
153
  end
106
154
 
107
- db = make_object(db, &yld)
155
+ scope ||= Object.new
108
156
 
109
- return db.instance_eval{ binding }
157
+ locals[:content] = content.call if content
158
+
159
+ return scope, locals
110
160
  end
111
161
 
112
- # Convert a data source into an Object (aka a "scope").
113
- def make_object(db, &yld)
114
- if db.respond_to?(:to_hash)
115
- hash = db.to_hash
116
- hash[:yield] = yld.call if yld
117
- attrs = hash.keys.map{ |k| k.to_sym }
118
- return Struct.new(*attrs).new(*hash.values)
162
+ # Take scope and locals are return the same reworked for use as externalized
163
+ # template variables.
164
+ #
165
+ # @return [Array<Object,Hash>]
166
+ # Two element array of scope object and data hash.
167
+ def make_external(scope, locals=nil, &content)
168
+ locals ||= {}
169
+
170
+ case scope
171
+ when Binding
172
+ vars = scope.eval("local_variables")
173
+ vals = scope.eval("[#{vars.join(',')}]")
174
+ locals = locals.merge(Hash[*vars.zip(vals).flatten])
175
+ scope = scope.eval("self")
176
+ end
177
+
178
+ if scope.respond_to?(:to_struct)
179
+ locals = locals.merge(scope.to_struct.to_h)
180
+ #scope = Object.new
119
181
  end
120
182
 
121
- if Binding === db
122
- eval('self', binding) # FIXME: no yld
183
+ if scope.respond_to?(:to_hash)
184
+ locals = locals.merge(scope.to_hash)
185
+ scope = Object.new
123
186
  end
124
187
 
125
- return db
188
+ scope ||= Object.new
189
+ scope = make_object(scope || Object.new)
190
+
191
+ locals[:scope] = scope
192
+ locals[:content] = content.call if content
193
+
194
+ return scope, locals
126
195
  end
127
196
 
128
- # Convert a data source into a Hash.
129
- def make_hash(db, &yld)
130
- if Binding === db
131
- db = make_object(db)
197
+ # Convert scope and data into a Binding.
198
+ #
199
+ # @param [Object,Binding,Hash,Array] data
200
+ # The data source used for evaluation.
201
+ #
202
+ # @see #split_data
203
+ #
204
+ # @return [Object] The data and yield block converted to a Binding.
205
+ def make_binding(scope, locals=nil, &content)
206
+ case scope
207
+ when Binding
208
+ locals ||= {}
209
+ locals[:content] = content.call if content
210
+ scope.with(locals)
211
+ else
212
+ scope, locals = make_ready(scope, locals, &content)
213
+ scope.to_binding.with(locals)
132
214
  end
215
+ end
133
216
 
134
- if db.respond_to?(:to_hash)
135
- db = db.to_hash
136
- db[:yield] = yld.call if yld
137
- return db
217
+ # TODO: Simplify the #make_object method.
218
+
219
+ # Convert data into an object.
220
+ #
221
+ # @param [Object,Binding,Hash,Array] data
222
+ # The data source used for evaluation.
223
+ #
224
+ # @return [Object] The data and yield block converted to an Object.
225
+ def make_object(scope, locals=nil)
226
+ locals ||= {}
227
+
228
+ case scope
229
+ when nil
230
+ hash = locals.to_hash.dup
231
+ if hash.empty?
232
+ Object.new
233
+ else
234
+ vars, vals = [], []
235
+ hash.each_pair do |k,v|
236
+ vars << k; vals << v
237
+ end
238
+ Struct.new(*vars).new(*vals)
239
+ end
240
+ when Binding
241
+ Class.new(::BasicObject){
242
+ define_method(:method_missing) do |s, *a|
243
+ if locals.key?(s)
244
+ locals[s]
245
+ elsif locals.key?(s.to_s)
246
+ locals[s.to_s]
247
+ else
248
+ scope.eval(s.to_s)
249
+ end
250
+ end
251
+ }.new
252
+ when Struct
253
+ vars, vals = [], []
254
+ scope.each_pair do |k,v|
255
+ vars << k; vals << v
256
+ end
257
+ locals.each_pair do |k,v|
258
+ vars << k; vals << v
259
+ end
260
+ Struct.new(*vars).new(*vals)
261
+ else
262
+ if scope.respond_to?(:to_hash)
263
+ hash = scope.to_hash.merge(locals.to_hash)
264
+ if hash.empty?
265
+ Object.new
266
+ else
267
+ vars, vals = [], []
268
+ hash.each_pair do |k,v|
269
+ vars << k; vals << v
270
+ end
271
+ Struct.new(*vars).new(*vals)
272
+ end
273
+ else
274
+ Class.new(::BasicObject){
275
+ define_method(:method_missing) do |s, *a, &b|
276
+ if locals.key?(s)
277
+ locals[s]
278
+ elsif locals.key?(s.to_s)
279
+ locals[s.to_s]
280
+ else
281
+ scope.__send__(s.to_s, *a, &b)
282
+ end
283
+ end
284
+ }.new
285
+ end
138
286
  end
287
+ end
139
288
 
140
- if db.respond_to?(:to_h)
141
- db = db.to_h
142
- db[:yield] = yld.call if yld
143
- return db
289
+ # Convert data source into a hash.
290
+ #
291
+ # @param [Object,Binding,Hash,Array] data
292
+ # The data source used for evaluation.
293
+ #
294
+ # @see #scope_vs_hash
295
+ #
296
+ # @return [Hash] The data and yield block converted to a Hash.
297
+ def make_hash(scope, locals=nil, &content)
298
+ case scope
299
+ when nil
300
+ hash = locals || {}
301
+ when Binding
302
+ #hash = Hash.new{ |h,k| p h,k; h[k] = data.key?(k) ? data[k] : scope.eval(k) }
303
+ hash = Hash.new{ |h,k| h[k] = scope.eval(k) }
304
+ else
305
+ if scope.respond_to?(:to_hash)
306
+ hash = scope.to_hash.merge(data)
307
+ else
308
+ #hash = Hash.new{ |h,k| data.key?(k) ? data[k] : h[k] = scope.__send__(k) }
309
+ hash = Hash.new{ |h,k| h[k] = scope.__send__(k) }
310
+ end
144
311
  end
145
312
 
146
- # last resort
147
- db = db.instance_variables.inject({}) do |h, i|
148
- k = i.sub('@','').to_sym
149
- v = instance_variable_get(i)
150
- h[k] = v
151
- h
313
+ hash = hash.merge(locals || {})
314
+
315
+ if content
316
+ hash[:content] = content.call.to_s # rescue nil ?
317
+ end
318
+
319
+ hash
320
+ end
321
+
322
+ #
323
+ #def make_scope_and_data(data, &content)
324
+ # scope, data = scope_vs_data(data)
325
+ # case scope
326
+ # when Binding
327
+ # vars = scope.eval("local_variables")
328
+ # vals = scope.eval("[#{vars.join(',')}]")
329
+ # data = data.merge(Hash[*vars.zip(vals).flatten])
330
+ # scope = scope.eval("self")
331
+ # else
332
+ # scope ||= Object.new
333
+ # end
334
+ # return scope, data
335
+ #end
336
+
337
+ #
338
+ def engine_options(params)
339
+ opts = {}
340
+ engine_option_names.each do |o|
341
+ o = o.to_sym
342
+ v = params[o] || settings[o]
343
+ opts[o] = v if v
344
+ end
345
+ opts
346
+ end
347
+
348
+ # Override this.
349
+ def engine_option_names
350
+ []
351
+ end
352
+
353
+ # Helper method to get paramters.
354
+ def parameters(params, *names)
355
+ pvals = names.map do |name|
356
+ params[name.to_sym] || settings[name.to_sym]
357
+ end
358
+
359
+ if names.size == 1
360
+ return pvals.first
361
+ else
362
+ return *pvals
152
363
  end
153
- db[:yield] = yld.call if yld
154
- return db
155
364
  end
156
365
 
157
366
  end