Markaby 0.6.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 (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