Markaby 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gitignore +4 -0
  2. data/CHANGELOG.rdoc +43 -0
  3. data/Markaby.gemspec +100 -0
  4. data/README.rdoc +262 -0
  5. data/Rakefile +48 -0
  6. data/VERSION +1 -0
  7. data/garlic.rb +29 -0
  8. data/init.rb +6 -0
  9. data/lib/markaby/builder.rb +275 -0
  10. data/lib/markaby/builder_tags.rb +64 -0
  11. data/lib/markaby/cssproxy.rb +55 -0
  12. data/lib/markaby/kernel_method.rb +7 -0
  13. data/lib/markaby/rails/current.rb +41 -0
  14. data/lib/markaby/rails/deprecated.rb +122 -0
  15. data/lib/markaby/rails.rb +68 -0
  16. data/lib/markaby/tags.rb +193 -0
  17. data/lib/markaby/tilt.rb +21 -0
  18. data/lib/markaby.rb +30 -0
  19. data/spec/markaby/builder_spec.rb +40 -0
  20. data/spec/markaby/css_proxy_spec.rb +44 -0
  21. data/spec/markaby/fragment_spec.rb +7 -0
  22. data/spec/markaby/markaby_other_static.mab +1 -0
  23. data/spec/markaby/markaby_spec.rb +207 -0
  24. data/spec/markaby/rails/spec_helper.rb +20 -0
  25. data/spec/markaby/rails/views/markaby/_a_partial.mab +3 -0
  26. data/spec/markaby/rails/views/markaby/_partial_child_with_locals.mab +1 -0
  27. data/spec/markaby/rails/views/markaby/access_to_helpers.mab +1 -0
  28. data/spec/markaby/rails/views/markaby/broken.mab +7 -0
  29. data/spec/markaby/rails/views/markaby/correct_template_values.mab +5 -0
  30. data/spec/markaby/rails/views/markaby/no_values_passed.mab +3 -0
  31. data/spec/markaby/rails/views/markaby/partial_parent.mab +1 -0
  32. data/spec/markaby/rails/views/markaby/partial_parent_with_locals.mab +7 -0
  33. data/spec/markaby/rails/views/markaby/render_erb_without_explicit_render_call.erb +1 -0
  34. data/spec/markaby/rails/views/markaby/render_explicit_but_empty_markaby_layout.mab +0 -0
  35. data/spec/markaby/rails/views/markaby/render_mab_without_explicit_render_call.mab +3 -0
  36. data/spec/markaby/rails/views/markaby/render_with_ivar.mab +3 -0
  37. data/spec/markaby/rails/views/markaby/renders_erb.rhtml +1 -0
  38. data/spec/markaby/rails_spec.rb +190 -0
  39. data/spec/markaby/rails_version_spec.rb +37 -0
  40. data/spec/markaby/tilt/erb.erb +1 -0
  41. data/spec/markaby/tilt/locals.mab +1 -0
  42. data/spec/markaby/tilt/markaby.mab +1 -0
  43. data/spec/markaby/tilt/markaby_other_static.mab +1 -0
  44. data/spec/markaby/tilt/render_twice.mab +1 -0
  45. data/spec/markaby/tilt/scope.mab +1 -0
  46. data/spec/markaby/tilt/yielding.mab +2 -0
  47. data/spec/markaby/tilt_spec.rb +86 -0
  48. data/spec/markaby/xml_markup_spec.rb +9 -0
  49. data/spec/spec.opts +2 -0
  50. data/spec/spec_helper.rb +39 -0
  51. metadata +126 -0
@@ -0,0 +1,275 @@
1
+ require 'markaby/tags'
2
+ require 'markaby/builder_tags'
3
+
4
+ module Markaby
5
+ # The Markaby::Builder class is the central gear in the system. When using
6
+ # from Ruby code, this is the only class you need to instantiate directly.
7
+ #
8
+ # mab = Markaby::Builder.new
9
+ # mab.html do
10
+ # head { title "Boats.com" }
11
+ # body do
12
+ # h1 "Boats.com has great deals"
13
+ # ul do
14
+ # li "$49 for a canoe"
15
+ # li "$39 for a raft"
16
+ # li "$29 for a huge boot that floats and can fit 5 people"
17
+ # end
18
+ # end
19
+ # end
20
+ # puts mab.to_s
21
+ #
22
+ class Builder
23
+ include Markaby::BuilderTags
24
+
25
+ DEFAULT_OPTIONS = {
26
+ :indent => 0,
27
+ :output_helpers => true,
28
+ :output_xml_instruction => true,
29
+ :output_meta_tag => true,
30
+ :auto_validation => true,
31
+ :tagset => Markaby::XHTMLTransitional,
32
+ :root_attributes => {
33
+ :xmlns => 'http://www.w3.org/1999/xhtml',
34
+ :'xml:lang' => 'en',
35
+ :lang => 'en'
36
+ }
37
+ }
38
+
39
+ @@options = DEFAULT_OPTIONS.dup
40
+
41
+ def self.restore_defaults!
42
+ @@options = DEFAULT_OPTIONS.dup
43
+ end
44
+
45
+ def self.set(option, value)
46
+ @@options[option] = value
47
+ end
48
+
49
+ def self.get(option)
50
+ @@options[option]
51
+ end
52
+
53
+ def self.ignored_helpers
54
+ @@ignored_helpers ||= []
55
+ end
56
+
57
+ def self.ignore_helpers(*helpers)
58
+ ignored_helpers.concat helpers
59
+ end
60
+
61
+ attr_accessor :output_helpers, :tagset
62
+
63
+ # Create a Markaby builder object. Pass in a hash of variable assignments to
64
+ # +assigns+ which will be available as instance variables inside tag construction
65
+ # blocks. If an object is passed in to +helper+, its methods will be available
66
+ # from those same blocks.
67
+ #
68
+ # Pass in a +block+ to new and the block will be evaluated.
69
+ #
70
+ # mab = Markaby::Builder.new {
71
+ # html do
72
+ # body do
73
+ # h1 "Matching Mole"
74
+ # end
75
+ # end
76
+ # }
77
+ #
78
+ def initialize(assigns = {}, helper = nil, &block)
79
+ @streams = [[]]
80
+ @assigns = assigns.dup
81
+ @_helper = helper
82
+ @used_ids = {}
83
+
84
+ @@options.each do |k, v|
85
+ instance_variable_set("@#{k}", @assigns.delete(k) || v)
86
+ end
87
+
88
+ @assigns.each do |k, v|
89
+ instance_variable_set("@#{k}", v)
90
+ end
91
+
92
+ @builder = XmlMarkup.new(:indent => @indent, :target => @streams.last)
93
+
94
+ instance_eval(&block) if block
95
+ end
96
+
97
+ def helper=(helper)
98
+ @_helper = helper
99
+ end
100
+
101
+ def metaclass(&block)
102
+ metaclass = class << self; self; end
103
+ metaclass.class_eval(&block)
104
+ end
105
+
106
+ private :metaclass
107
+
108
+ def locals=(locals)
109
+ locals.each do |key, value|
110
+ metaclass do
111
+ define_method key do
112
+ value
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ # Returns a string containing the HTML stream. Internally, the stream is stored as an Array.
119
+ def to_s
120
+ @streams.last.to_s
121
+ end
122
+
123
+ # Write a +string+ to the HTML stream without escaping it.
124
+ def text(string)
125
+ @builder << string.to_s
126
+ nil
127
+ end
128
+ alias_method :<<, :text
129
+ alias_method :concat, :text
130
+
131
+ # Captures the HTML code built inside the +block+. This is done by creating a new
132
+ # stream for the builder object, running the block and passing back its stream as a string.
133
+ #
134
+ # >> Markaby::Builder.new.capture { h1 "TEST"; h2 "CAPTURE ME" }
135
+ # => "<h1>TITLE</h1>\n<h2>CAPTURE ME</h2>\n"
136
+ #
137
+ def capture(&block)
138
+ @streams.push(@builder.target = [])
139
+ @builder.level += 1
140
+ str = instance_eval(&block)
141
+ str = @streams.last.join if @streams.last.any?
142
+ @streams.pop
143
+ @builder.level -= 1
144
+ @builder.target = @streams.last
145
+ str
146
+ end
147
+
148
+ # Create a tag named +tag+. Other than the first argument which is the tag name,
149
+ # the arguments are the same as the tags implemented via method_missing.
150
+ def tag!(tag, *args, &block)
151
+ ele_id = nil
152
+ if @auto_validation && @tagset
153
+ if !@tagset.tagset.has_key?(tag)
154
+ raise InvalidXhtmlError, "no element `#{tag}' for #{tagset.doctype}"
155
+ elsif args.last.respond_to?(:to_hash)
156
+ attrs = args.last.to_hash
157
+
158
+ if @tagset.forms.include?(tag) && attrs[:id]
159
+ attrs[:name] ||= attrs[:id]
160
+ end
161
+
162
+ attrs.each do |k, v|
163
+ atname = k.to_s.downcase.intern
164
+ unless k =~ /:/ or @tagset.tagset[tag].include? atname
165
+ raise InvalidXhtmlError, "no attribute `#{k}' on #{tag} elements"
166
+ end
167
+ if atname == :id
168
+ ele_id = v.to_s
169
+ if @used_ids.has_key? ele_id
170
+ raise InvalidXhtmlError, "id `#{ele_id}' already used (id's must be unique)."
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+
177
+ if block
178
+ str = capture(&block)
179
+ block = proc { text(str) }
180
+ end
181
+
182
+ f = fragment { @builder.method_missing(tag, *args, &block) }
183
+ @used_ids[ele_id] = f if ele_id
184
+ f
185
+ end
186
+
187
+ private
188
+
189
+ # This method is used to intercept calls to helper methods and instance
190
+ # variables. Here is the order of interception:
191
+ #
192
+ # * If +sym+ is a helper method, the helper method is called
193
+ # and output to the stream.
194
+ # * If +sym+ is a Builder::XmlMarkup method, it is passed on to the builder object.
195
+ # * If +sym+ is also the name of an instance variable, the
196
+ # value of the instance variable is returned.
197
+ # * If +sym+ has come this far and no +tagset+ is found, +sym+ and its arguments are passed to tag!
198
+ # * If a tagset is found, though, +NoMethodError+ is raised.
199
+ #
200
+ # method_missing used to be the lynchpin in Markaby, but it's no longer used to handle
201
+ # HTML tags. See html_tag for that.
202
+ def method_missing(sym, *args, &block)
203
+ if @_helper.respond_to?(sym, true) && !self.class.ignored_helpers.include?(sym)
204
+ r = @_helper.send(sym, *args, &block)
205
+ if @output_helpers && r.respond_to?(:to_str)
206
+ fragment { @builder << r }
207
+ else
208
+ r
209
+ end
210
+ elsif @assigns.has_key?(sym)
211
+ @assigns[sym]
212
+ elsif @assigns.has_key?(stringy_key = sym.to_s)
213
+ # Rails' ActionView assigns hash has string keys for
214
+ # instance variables that are defined in the controller.
215
+ @assigns[stringy_key]
216
+ elsif instance_variables.include?(ivar = "@#{sym}")
217
+ instance_variable_get(ivar)
218
+ elsif @_helper && @_helper.instance_variables.include?(ivar)
219
+ @_helper.instance_variable_get(ivar)
220
+ elsif ::Builder::XmlMarkup.instance_methods.include?(sym.to_s)
221
+ @builder.__send__(sym, *args, &block)
222
+ elsif !@tagset
223
+ tag!(sym, *args, &block)
224
+ else
225
+ super
226
+ end
227
+ end
228
+
229
+ def fragment
230
+ stream = @streams.last
231
+ start = stream.length
232
+ yield
233
+ length = stream.length - start
234
+ Fragment.new(stream, start, length)
235
+ end
236
+ end
237
+
238
+ # Every tag method in Markaby returns a Fragment. If any method gets called on the Fragment,
239
+ # the tag is removed from the Markaby stream and given back as a string. Usually the fragment
240
+ # is never used, though, and the stream stays intact.
241
+ #
242
+ # For a more practical explanation, check out the README.
243
+ class Fragment < ::Builder::BlankSlate
244
+ def initialize(*args)
245
+ @stream, @start, @length = args
246
+ @transformed_stream = false
247
+ end
248
+
249
+ private
250
+
251
+ def method_missing(*args, &block)
252
+ transform_stream unless transformed_stream?
253
+ @str.__send__(*args, &block)
254
+ end
255
+
256
+ def transform_stream
257
+ @transformed_stream = true
258
+
259
+ # We can't do @stream.slice!(@start, @length),
260
+ # as it would invalidate the @starts and @lengths of other Fragment instances.
261
+ @str = @stream[@start, @length].to_s
262
+ @stream[@start, @length] = [nil] * @length
263
+ end
264
+
265
+ def transformed_stream?
266
+ @transformed_stream
267
+ end
268
+ end
269
+
270
+ class XmlMarkup < ::Builder::XmlMarkup
271
+ attr_accessor :target, :level
272
+
273
+ private :method_missing
274
+ end
275
+ end
@@ -0,0 +1,64 @@
1
+ module Markaby
2
+ module BuilderTags
3
+ (XHTMLTransitional.tags - [:head]).each do |k|
4
+ class_eval <<-CODE, __FILE__, __LINE__
5
+ def #{k}(*args, &block)
6
+ html_tag(#{k.inspect}, *args, &block)
7
+ end
8
+ CODE
9
+ end
10
+
11
+ # Every HTML tag method goes through an html_tag call. So, calling <tt>div</tt> is equivalent
12
+ # to calling <tt>html_tag(:div)</tt>. All HTML tags in Markaby's list are given generated wrappers
13
+ # for this method.
14
+ #
15
+ # If the @auto_validation setting is on, this method will check for many common mistakes which
16
+ # could lead to invalid XHTML.
17
+ def html_tag(sym, *args, &block)
18
+ if @auto_validation && @tagset.self_closing.include?(sym) && block
19
+ raise InvalidXhtmlError, "the `#{sym}' element is self-closing, please remove the block"
20
+ elsif args.empty? && !block
21
+ CssProxy.new(self, @streams.last, sym)
22
+ else
23
+ tag!(sym, *args, &block)
24
+ end
25
+ end
26
+
27
+ # Builds a head tag. Adds a <tt>meta</tt> tag inside with Content-Type
28
+ # set to <tt>text/html; charset=utf-8</tt>.
29
+ def head(*args, &block)
30
+ tag!(:head, *args) do
31
+ tag!(:meta, "http-equiv" => "Content-Type", "content" => "text/html; charset=utf-8") if @output_meta_tag
32
+ instance_eval(&block)
33
+ end
34
+ end
35
+
36
+ # Builds an html tag. An XML 1.0 instruction and an XHTML 1.0 Transitional doctype
37
+ # are prepended. Also assumes <tt>:xmlns => "http://www.w3.org/1999/xhtml",
38
+ # :lang => "en"</tt>.
39
+ def xhtml_transitional(attrs = {}, &block)
40
+ self.tagset = Markaby::XHTMLTransitional
41
+ xhtml_html(attrs, &block)
42
+ end
43
+
44
+ # Builds an html tag with XHTML 1.0 Strict doctype instead.
45
+ def xhtml_strict(attrs = {}, &block)
46
+ self.tagset = Markaby::XHTMLStrict
47
+ xhtml_html(attrs, &block)
48
+ end
49
+
50
+ # Builds an html tag with XHTML 1.0 Frameset doctype instead.
51
+ def xhtml_frameset(attrs = {}, &block)
52
+ self.tagset = Markaby::XHTMLFrameset
53
+ xhtml_html(attrs, &block)
54
+ end
55
+
56
+ private
57
+
58
+ def xhtml_html(attrs = {}, &block)
59
+ instruct! if @output_xml_instruction
60
+ declare!(:DOCTYPE, :html, :PUBLIC, *tagset.doctype)
61
+ tag!(:html, @root_attributes.merge(attrs), &block)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,55 @@
1
+ module Markaby
2
+ # Class used by Markaby::Builder to store element options. Methods called
3
+ # against the CssProxy object are added as element classes or IDs.
4
+ #
5
+ # See the README for examples.
6
+ class CssProxy
7
+ def initialize(builder, stream, sym)
8
+ @builder = builder
9
+ @stream = stream
10
+ @sym = sym
11
+ @attrs = {}
12
+
13
+ @original_stream_length = @stream.length
14
+
15
+ @builder.tag! sym
16
+ end
17
+
18
+ def respond_to?(sym, include_private = false)
19
+ include_private || !private_methods.include?(sym.to_s) ? true : false
20
+ end
21
+
22
+ private
23
+
24
+ # Adds attributes to an element. Bang methods set the :id attribute.
25
+ # Other methods add to the :class attribute.
26
+ def method_missing(id_or_class, *args, &block)
27
+ if id_or_class.to_s =~ /(.*)!$/
28
+ @attrs[:id] = $1
29
+ else
30
+ id = id_or_class
31
+ @attrs[:class] = @attrs[:class] ? "#{@attrs[:class]} #{id}".strip : id
32
+ end
33
+
34
+ unless args.empty?
35
+ if args.last.respond_to? :to_hash
36
+ @attrs.merge! args.pop.to_hash
37
+ end
38
+ end
39
+
40
+ args.push(@attrs)
41
+
42
+ while @stream.length > @original_stream_length
43
+ @stream.pop
44
+ end
45
+
46
+ if block
47
+ @builder.tag! @sym, *args, &block
48
+ else
49
+ @builder.tag! @sym, *args
50
+ end
51
+
52
+ self
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,7 @@
1
+ # You'll need to <tt>require 'markaby/kernel_method'</tt> for this.
2
+ module Kernel
3
+ # Shortcut for creating a quick block of Markaby.
4
+ def mab(*args, &block)
5
+ Markaby::Builder.new(*args, &block).to_s
6
+ end
7
+ end
@@ -0,0 +1,41 @@
1
+ module Markaby
2
+ module Rails
3
+ class TemplateHandler < ::ActionView::TemplateHandler
4
+ def compile(template, local_assigns={})
5
+ <<-CODE
6
+ handler = Markaby::Rails::TemplateHandler.new
7
+ handler.view = self
8
+ handler.render(lambda { #{template.source} }, local_assigns)
9
+ CODE
10
+ end
11
+
12
+ def render(template, local_assigns = (template.respond_to?(:locals) ? template.locals : {}))
13
+ builder = Markaby::Builder.new(instance_variables.merge(local_assigns), @view)
14
+
15
+ template.is_a?(Proc) ?
16
+ builder.instance_eval(&template) :
17
+ builder.instance_eval(template.source)
18
+
19
+ builder.to_s
20
+ end
21
+
22
+ attr_accessor :view
23
+
24
+ private
25
+
26
+ def instance_variables
27
+ instance_variable_hash(@view)
28
+ end
29
+
30
+ def instance_variable_hash(object)
31
+ returning Hash.new do |hash|
32
+ object.instance_variables.each do |var_name|
33
+ hash[var_name.gsub("@", "")] = object.instance_variable_get(var_name)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ ActionView::Template.register_template_handler(:mab, Markaby::Rails::TemplateHandler)
@@ -0,0 +1,122 @@
1
+ module ActionView # :nodoc:
2
+ class Base # :nodoc:
3
+ def render_template(template_extension, template, file_path = nil, local_assigns = {})
4
+ if handler = @@template_handlers[template_extension]
5
+ template ||= read_template_file(file_path, template_extension)
6
+ handler.new(self).render(template, local_assigns, file_path)
7
+ else
8
+ compile_and_render_template(template_extension, template, file_path, local_assigns)
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ module Markaby
15
+ module Rails
16
+ class Template
17
+
18
+ def self.builder_class=(builder)
19
+ @@builder_class = builder
20
+ end
21
+
22
+ def self.builder_class
23
+ @@builder_class ||= Builder
24
+ end
25
+
26
+ attr_accessor :source, :path
27
+
28
+ def initialize(source)
29
+ @source = source.to_s
30
+ end
31
+
32
+ def render(*args)
33
+ output = self.class.builder_class.new(*args)
34
+
35
+ if path
36
+ output.instance_eval source, path
37
+ else
38
+ output.instance_eval source
39
+ end
40
+
41
+ output.to_s
42
+ end
43
+ end
44
+
45
+ # Markaby helpers for Rails.
46
+ module ActionControllerHelpers
47
+ # Returns a string of HTML built from the attached +block+. Any +options+ are
48
+ # passed into the render method.
49
+ #
50
+ # Use this method in your controllers to output Markaby directly from inside.
51
+ def render_markaby(options = {}, &block)
52
+ render options.merge({ :text => Builder.new(options[:locals], self, &block).to_s })
53
+ end
54
+ end
55
+
56
+ class ActionViewTemplateHandler # :nodoc:
57
+ def initialize(action_view)
58
+ @action_view = action_view
59
+ end
60
+ def render(template, local_assigns, file_path)
61
+ template = Template.new(template)
62
+ template.path = file_path
63
+ template.render(@action_view.assigns.merge(local_assigns), @action_view)
64
+ end
65
+ end
66
+
67
+ class Builder < ::Markaby::Builder # :nodoc:
68
+ def initialize(*args, &block)
69
+ super *args, &block
70
+
71
+ @assigns.each { |k, v| @helpers.instance_variable_set("@#{k}", v) }
72
+ end
73
+
74
+ def flash(*args)
75
+ @helpers.controller.send(:flash, *args)
76
+ end
77
+
78
+ # Emulate ERB to satisfy helpers like <tt>form_for</tt>.
79
+ def _erbout
80
+ @_erbout ||= FauxErbout.new(self)
81
+ end
82
+
83
+ # Content_for will store the given block in an instance variable for later use
84
+ # in another template or in the layout.
85
+ #
86
+ # The name of the instance variable is content_for_<name> to stay consistent
87
+ # with @content_for_layout which is used by ActionView's layouts.
88
+ #
89
+ # Example:
90
+ #
91
+ # content_for("header") do
92
+ # h1 "Half Shark and Half Lion"
93
+ # end
94
+ #
95
+ # If used several times, the variable will contain all the parts concatenated.
96
+ def content_for(name, &block)
97
+ @helpers.assigns["content_for_#{name}"] =
98
+ eval("@content_for_#{name} = (@content_for_#{name} || '') + capture(&block)")
99
+ end
100
+ end
101
+
102
+ Template.builder_class = Builder
103
+
104
+ class FauxErbout < ::Builder::BlankSlate # :nodoc:
105
+ def initialize(builder)
106
+ @builder = builder
107
+ end
108
+ def nil? # see ActionView::Helpers::CaptureHelper#capture
109
+ true
110
+ end
111
+ def method_missing(*args, &block)
112
+ @builder.send *args, &block
113
+ end
114
+ end
115
+ end
116
+
117
+ if defined? ActionView::Template and ActionView::Template.respond_to? :register_template_handler
118
+ ActionView::Template
119
+ else
120
+ ActionView::Base
121
+ end.register_template_handler(:mab, Markaby::Rails::ActionViewTemplateHandler)
122
+ end
@@ -0,0 +1,68 @@
1
+ module Markaby
2
+ module Rails
3
+ DEPRECATED_RAILS_VERSIONS = [
4
+ "1.2.2",
5
+ "1.2.3",
6
+ "1.2.4",
7
+ "1.2.5",
8
+ "1.2.6",
9
+ ]
10
+
11
+ FULLY_SUPPORTED_RAILS_VERSIONS = [
12
+ # "2.0.0",
13
+ # "2.0.1",
14
+ # "2.0.2",
15
+ # "2.0.3",
16
+ # "2.0.4",
17
+ # "2.0.5",
18
+ "2.1.0",
19
+ "2.1.1",
20
+ "2.1.2",
21
+ "2.2.0",
22
+ "2.2.1",
23
+ "2.2.2",
24
+ "2.2.3",
25
+ # "2.3.0",
26
+ "2.3.1",
27
+ "2.3.2",
28
+ "2.3.2.1",
29
+ "2.3.3",
30
+ "2.3.3.1",
31
+ "2.3.4"
32
+ ]
33
+
34
+ SUPPORTED_RAILS_VERSIONS = DEPRECATED_RAILS_VERSIONS + FULLY_SUPPORTED_RAILS_VERSIONS
35
+
36
+ class << self
37
+ def load
38
+ check_rails_version
39
+
40
+ if deprecated_rails_version?
41
+ require File.dirname(__FILE__) + "/rails/deprecated"
42
+ else
43
+ require File.dirname(__FILE__) + "/rails/current"
44
+ end
45
+ end
46
+
47
+ def deprecated_rails_version?
48
+ DEPRECATED_RAILS_VERSIONS.include?(detected_rails_version)
49
+ end
50
+
51
+ def check_rails_version
52
+ unless SUPPORTED_RAILS_VERSIONS.include?(detected_rails_version)
53
+ error_message = "Cannot load markaby under rails version #{detected_rails_version}. "
54
+ error_message << "See Markaby::Rails::SUPPORTED_RAILS_VERSIONS for exactly that, or redefine this constant."
55
+ raise LoadError, error_message
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def detected_rails_version
62
+ if defined?(::Rails)
63
+ ::Rails::VERSION::STRING
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end