hobo 0.5.3 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/hobo +18 -4
- data/hobo_files/plugin/CHANGES.txt +511 -0
- data/hobo_files/plugin/README +8 -3
- data/hobo_files/plugin/Rakefile +81 -0
- data/hobo_files/plugin/generators/hobo/hobo_generator.rb +4 -4
- data/hobo_files/plugin/generators/hobo/templates/guest.rb +1 -1
- data/hobo_files/plugin/generators/hobo_front_controller/hobo_front_controller_generator.rb +1 -1
- data/hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml +16 -22
- data/hobo_files/plugin/generators/hobo_front_controller/templates/login.dryml +4 -6
- data/hobo_files/plugin/generators/hobo_front_controller/templates/search.dryml +6 -5
- data/hobo_files/plugin/generators/hobo_front_controller/templates/signup.dryml +4 -6
- data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +237 -0
- data/hobo_files/plugin/generators/hobo_migration/templates/migration.rb +9 -0
- data/hobo_files/plugin/generators/hobo_model/USAGE +2 -3
- data/hobo_files/plugin/generators/hobo_model/hobo_model_generator.rb +1 -14
- data/hobo_files/plugin/generators/hobo_model/templates/fixtures.yml +1 -6
- data/hobo_files/plugin/generators/hobo_model/templates/model.rb +10 -4
- data/hobo_files/plugin/generators/hobo_rapid/hobo_rapid_generator.rb +7 -6
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_base.css +68 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_rapid.css +93 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_rapid.js +11 -6
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/plus.png +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/stylesheets/application.css +24 -14
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/views/application.dryml +28 -44
- data/hobo_files/plugin/generators/hobo_user_model/USAGE +2 -12
- data/hobo_files/plugin/generators/hobo_user_model/hobo_user_model_generator.rb +1 -14
- data/hobo_files/plugin/generators/hobo_user_model/templates/fixtures.yml +0 -6
- data/hobo_files/plugin/generators/hobo_user_model/templates/model.rb +8 -1
- data/hobo_files/plugin/init.rb +6 -2
- data/hobo_files/plugin/lib/active_record/has_many_association.rb +23 -12
- data/hobo_files/plugin/lib/extensions.rb +134 -40
- data/hobo_files/plugin/lib/extensions/test_case.rb +0 -1
- data/hobo_files/plugin/lib/hobo.rb +77 -46
- data/hobo_files/plugin/lib/hobo/authenticated_user.rb +24 -2
- data/hobo_files/plugin/lib/hobo/authentication_support.rb +2 -1
- data/hobo_files/plugin/lib/hobo/controller.rb +35 -12
- data/hobo_files/plugin/lib/hobo/define_tags.rb +4 -4
- data/hobo_files/plugin/lib/hobo/dryml.rb +33 -51
- data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +47 -34
- data/hobo_files/plugin/lib/hobo/dryml/scoped_variables.rb +37 -0
- data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +27 -5
- data/hobo_files/plugin/lib/hobo/dryml/template.rb +545 -302
- data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +305 -135
- data/hobo_files/plugin/lib/hobo/email_address.rb +5 -0
- data/hobo_files/plugin/lib/hobo/field_spec.rb +66 -0
- data/hobo_files/plugin/lib/hobo/hobo_helper.rb +325 -0
- data/hobo_files/plugin/lib/hobo/html_string.rb +2 -0
- data/hobo_files/plugin/lib/hobo/lazy_hash.rb +13 -1
- data/hobo_files/plugin/lib/hobo/markdown_string.rb +3 -1
- data/hobo_files/plugin/lib/hobo/model.rb +185 -66
- data/hobo_files/plugin/lib/hobo/model_controller.rb +56 -49
- data/hobo_files/plugin/lib/hobo/password_string.rb +2 -0
- data/hobo_files/plugin/lib/hobo/plugins.rb +75 -0
- data/hobo_files/plugin/lib/hobo/rapid_helper.rb +98 -0
- data/hobo_files/plugin/lib/hobo/static_tags +0 -3
- data/hobo_files/plugin/lib/hobo/textile_string.rb +11 -1
- data/hobo_files/plugin/lib/hobo/undefined.rb +1 -1
- data/hobo_files/plugin/lib/rexml.rb +166 -75
- data/hobo_files/plugin/spec/fixtures/users.yml +9 -0
- data/hobo_files/plugin/spec/spec.opts +6 -0
- data/hobo_files/plugin/spec/spec_helper.rb +28 -0
- data/hobo_files/plugin/spec/unit/hobo/dryml/template_spec.rb +650 -0
- data/hobo_files/plugin/tags/core.dryml +58 -4
- data/hobo_files/plugin/tags/rapid.dryml +289 -135
- data/hobo_files/plugin/tags/rapid_document_tags.dryml +49 -0
- data/hobo_files/plugin/tags/rapid_editing.dryml +92 -69
- data/hobo_files/plugin/tags/rapid_forms.dryml +242 -0
- data/hobo_files/plugin/tags/rapid_navigation.dryml +65 -65
- data/hobo_files/plugin/tags/rapid_pages.dryml +197 -124
- data/hobo_files/plugin/tags/rapid_support.dryml +23 -0
- metadata +29 -22
- data/hobo_files/plugin/generators/hobo_model/templates/migration.rb +0 -13
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/default_mapping.rb +0 -11
- data/hobo_files/plugin/generators/hobo_user_model/templates/migration.rb +0 -15
- data/hobo_files/plugin/lib/hobo/HtmlString +0 -3
- data/hobo_files/plugin/lib/hobo/controller_helpers.rb +0 -135
- data/hobo_files/plugin/lib/hobo/core.rb +0 -475
- data/hobo_files/plugin/lib/hobo/rapid.rb +0 -447
- data/hobo_files/plugin/test/hobo_dryml_template_test.rb +0 -7
- data/hobo_files/plugin/test/hobo_test.rb +0 -7
@@ -6,7 +6,7 @@ module Hobo
|
|
6
6
|
|
7
7
|
class PermissionDeniedError < RuntimeError; end
|
8
8
|
|
9
|
-
VIEWLIB_DIR = "
|
9
|
+
VIEWLIB_DIR = "taglibs"
|
10
10
|
|
11
11
|
GENERIC_PAGE_TAGS = [:index, :show, :new, :edit, :show_collection, :new_in_collection]
|
12
12
|
|
@@ -16,17 +16,13 @@ module Hobo
|
|
16
16
|
base.extend(ClassMethods)
|
17
17
|
base.helper_method(:find_partial, :model, :current_user)
|
18
18
|
|
19
|
-
Hobo::ControllerHelpers.public_instance_methods.each {|m| base.hide_action(m)}
|
20
|
-
|
21
19
|
for collection in base.collections
|
22
20
|
add_collection_actions(base, collection.to_sym)
|
23
21
|
end
|
24
22
|
|
25
23
|
base.before_filter :set_no_cache_headers
|
26
|
-
|
27
|
-
base
|
28
|
-
alias_method_chain :redirect_to, :object_url
|
29
|
-
end
|
24
|
+
|
25
|
+
Hobo::Controller.included_in_class(base)
|
30
26
|
end
|
31
27
|
|
32
28
|
def find_partial(klass, as)
|
@@ -36,7 +32,8 @@ module Hobo
|
|
36
32
|
|
37
33
|
def template_path(dir, name, is_partial)
|
38
34
|
fileRx = is_partial ? /^_#{name}\.[^.]+/ : /^#{name}\.[^.]+/
|
39
|
-
|
35
|
+
full_dir = "#{RAILS_ROOT}/app/views/#{dir}"
|
36
|
+
unless !File.exists?(full_dir) || Dir.entries(full_dir).grep(fileRx).empty?
|
40
37
|
return "#{dir}/#{name}"
|
41
38
|
end
|
42
39
|
end
|
@@ -131,7 +128,7 @@ module Hobo
|
|
131
128
|
def show_action(*names)
|
132
129
|
show_actions.concat(names)
|
133
130
|
for name in names
|
134
|
-
class_eval "def #{name};
|
131
|
+
class_eval "def #{name}; hobo_show; end"
|
135
132
|
end
|
136
133
|
end
|
137
134
|
|
@@ -201,7 +198,7 @@ module Hobo
|
|
201
198
|
def hobo_index(options = {})
|
202
199
|
options = LazyHash.new(options)
|
203
200
|
@model = model
|
204
|
-
@this = options[:collection] || paginated_find
|
201
|
+
@this = options[:collection] || paginated_find(options)
|
205
202
|
|
206
203
|
instance_variable_set("@#{@model.name.pluralize.underscore}", @this)
|
207
204
|
if block_given?
|
@@ -216,15 +213,18 @@ module Hobo
|
|
216
213
|
options = extract_options_from_args!(args)
|
217
214
|
|
218
215
|
total_number = options.delete(:total_number)
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
216
|
+
@association = options.delete(:association) or
|
217
|
+
if args.any?
|
218
|
+
owner, collection_name = args
|
219
|
+
@association = collection_name.to_s.split(".").inject(owner) { |m, name| m.send(name) }
|
220
|
+
end
|
221
|
+
|
222
|
+
if @association
|
223
|
+
total_number ||= @association.count
|
224
|
+
@reflection = @association.proxy_reflection if @association.respond_to?(:proxy_reflection)
|
226
225
|
end
|
227
226
|
|
227
|
+
total_number ||= count_with_data_filter
|
228
228
|
page_size = options.delete(:page_size) || 20
|
229
229
|
page = options.delete(:page) || params[:page]
|
230
230
|
@pages = ::ActionController::Pagination::Paginator.new(self, total_number, page_size, page)
|
@@ -237,7 +237,7 @@ module Hobo
|
|
237
237
|
if @association
|
238
238
|
@association.find(:all, options, &b)
|
239
239
|
else
|
240
|
-
options[:order]
|
240
|
+
options[:order] ||= :default
|
241
241
|
find_with_data_filter(options, &b)
|
242
242
|
end
|
243
243
|
end
|
@@ -262,7 +262,8 @@ module Hobo
|
|
262
262
|
if @this
|
263
263
|
if Hobo.can_view?(current_user, @this)
|
264
264
|
set_named_this!
|
265
|
-
|
265
|
+
yield if block_given?
|
266
|
+
hobo_render unless performed?
|
266
267
|
else
|
267
268
|
permission_denied(options)
|
268
269
|
end
|
@@ -273,40 +274,41 @@ module Hobo
|
|
273
274
|
def hobo_new(options={})
|
274
275
|
options = LazyHash.new(options)
|
275
276
|
@this = options[:this] || model.new
|
276
|
-
@this.
|
277
|
+
@this.set_creator(current_user) unless options.has_key?(:set_creator) && !options[:set_creator]
|
277
278
|
|
278
279
|
if Hobo.can_create?(current_user, @this)
|
279
280
|
set_named_this!
|
280
|
-
|
281
|
+
yield if block_given?
|
282
|
+
hobo_render unless performed?
|
281
283
|
else
|
282
284
|
permission_denied(options)
|
283
285
|
end
|
284
286
|
end
|
285
287
|
|
286
|
-
|
288
|
+
|
287
289
|
def hobo_create(options={})
|
288
290
|
options = LazyHash.new(options)
|
289
291
|
|
290
|
-
@this =
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
292
|
+
if (@this = options[:this])
|
293
|
+
permission_denied(options) and return unless Hobo.can_create?(current_user, @this)
|
294
|
+
else
|
295
|
+
attributes = params[model.name.underscore]
|
296
|
+
type_attr = params['type']
|
297
|
+
create_model = if 'type'.in?(model.column_names) and
|
298
|
+
type_attr and type_attr.in?(model.send(:subclasses).omap{name})
|
299
|
+
type_attr.constantize
|
300
|
+
else
|
301
|
+
model
|
302
|
+
end
|
303
|
+
@this = create_model.new
|
304
|
+
@check_create_permission = [@this]
|
305
|
+
initialize_from_params(@this, attributes)
|
306
|
+
for obj in @check_create_permission
|
307
|
+
permission_denied(options) and return unless Hobo.can_create?(current_user, obj)
|
308
|
+
end
|
309
|
+
@check_create_permission = nil
|
310
|
+
end
|
311
|
+
|
310
312
|
set_named_this!
|
311
313
|
if @this.save
|
312
314
|
if block_given?
|
@@ -375,8 +377,9 @@ module Hobo
|
|
375
377
|
overridable_response(options, :js_response) do
|
376
378
|
if changes.size == 1
|
377
379
|
# Decreasingly hacky support for the scriptaculous in-place-editor
|
378
|
-
new_val = Hobo::Dryml.render_tag(@template, "
|
379
|
-
:
|
380
|
+
new_val = Hobo::Dryml.render_tag(@template, "view",
|
381
|
+
:with => @this, :field => changes.keys.first,
|
382
|
+
:no_wrapper => true)
|
380
383
|
hobo_ajax_response(@this, :new_field_value => new_val)
|
381
384
|
else
|
382
385
|
hobo_ajax_response(@this)
|
@@ -457,8 +460,8 @@ module Hobo
|
|
457
460
|
permission_denied(options) and return unless Hobo.can_view?(current_user, @owner, collection)
|
458
461
|
|
459
462
|
@association = options[:collection] || @owner.send(collection)
|
460
|
-
@this = options[:this] || @association.
|
461
|
-
@this.
|
463
|
+
@this = options[:this] || @association.new
|
464
|
+
@this.set_creator(current_user) unless options.has_key?(:set_creator) && !options[:set_creator]
|
462
465
|
|
463
466
|
permission_denied(options) and return unless Hobo.can_create?(current_user, @this)
|
464
467
|
|
@@ -533,7 +536,7 @@ module Hobo
|
|
533
536
|
true
|
534
537
|
else
|
535
538
|
if page_kind.in? GENERIC_PAGE_TAGS
|
536
|
-
render_tag("#{page_kind}
|
539
|
+
render_tag("#{page_kind.to_s.camelize}Page", :with => @this)
|
537
540
|
true
|
538
541
|
else
|
539
542
|
false
|
@@ -586,7 +589,7 @@ module Hobo
|
|
586
589
|
|
587
590
|
def initialize_from_params(obj, params)
|
588
591
|
update_with_params(obj, params)
|
589
|
-
obj.
|
592
|
+
obj.set_creator(current_user)
|
590
593
|
(@check_create_permission ||= []) << obj
|
591
594
|
obj
|
592
595
|
end
|
@@ -627,7 +630,9 @@ module Hobo
|
|
627
630
|
|
628
631
|
|
629
632
|
def param_to_value(field_type, value)
|
630
|
-
if field_type
|
633
|
+
if field_type.nil?
|
634
|
+
value
|
635
|
+
elsif field_type <= Date
|
631
636
|
if value.is_a? Hash
|
632
637
|
Date.new(*(%w{year month day}.map{|s| value[s].to_i}))
|
633
638
|
elsif value.is_a? String
|
@@ -640,6 +645,8 @@ module Hobo
|
|
640
645
|
elsif value.is_a? String
|
641
646
|
parse_datetime(value)
|
642
647
|
end
|
648
|
+
elsif field_type <= TrueClass
|
649
|
+
(value.is_a?(String) && value.strip.downcase.in?(['0', 'false']) || value.blank?) ? false : true
|
643
650
|
else
|
644
651
|
# primitive field
|
645
652
|
value
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module ::Hobo::Plugins
|
2
|
+
class HoboPlugin
|
3
|
+
|
4
|
+
def initialize(opt=nil)
|
5
|
+
@opt = opt || Hash.new
|
6
|
+
set_up_options(self.class::PLUGIN_DEFAULTS)
|
7
|
+
|
8
|
+
send @opt[:setup_using] || :default
|
9
|
+
end
|
10
|
+
|
11
|
+
def set_up_options(*defaults)
|
12
|
+
@opt = @opt.reverse_merge(*defaults)
|
13
|
+
make_variations(self.class::PLUGIN_SYMBOLS)
|
14
|
+
end
|
15
|
+
|
16
|
+
def make_variations(h)
|
17
|
+
h.each do |name|
|
18
|
+
if @opt[name] && @opt[name] != false
|
19
|
+
# start with :product_category
|
20
|
+
|
21
|
+
# add :product_categories
|
22
|
+
@opt[name.to_s.pluralize.to_sym] = @opt[name].to_s.pluralize.to_sym
|
23
|
+
|
24
|
+
# :ProductCategory
|
25
|
+
@opt[name.to_s.camelize.to_sym] = @opt[name].to_s.camelize.to_sym
|
26
|
+
|
27
|
+
# :ProductCategories
|
28
|
+
@opt[name.to_s.camelize.pluralize.to_sym] = @opt[name].to_s.camelize.pluralize.to_sym
|
29
|
+
|
30
|
+
# :ProductCategoriesController
|
31
|
+
@opt[(name.to_s.camelize.pluralize+'Controller').to_sym] =
|
32
|
+
(@opt[name].to_s.camelize.pluralize+'Controller').to_sym
|
33
|
+
else
|
34
|
+
@opt[name.to_s.pluralize.to_sym] = false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def hobo_model(name, &b)
|
40
|
+
make_class @opt[name], ActiveRecord::Base do
|
41
|
+
hobo_model
|
42
|
+
class_eval &b if b
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def resource_controller(name, &b)
|
47
|
+
make_class @opt[name], ApplicationController do
|
48
|
+
hobo_model_controller
|
49
|
+
|
50
|
+
class_eval &b if b
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def make_class(class_name, base_class, &b)
|
55
|
+
opt = @opt
|
56
|
+
c = Class.new(base_class)
|
57
|
+
silence_warnings { Object.const_set(class_name, c) }
|
58
|
+
c.class_eval do
|
59
|
+
@plugin_opt = opt
|
60
|
+
def self.sym
|
61
|
+
@plugin_opt
|
62
|
+
end
|
63
|
+
def self.has_feature(name)
|
64
|
+
!@plugin_opt[name].nil? && @plugin_opt[name] != false
|
65
|
+
end
|
66
|
+
def sym
|
67
|
+
self.class.sym
|
68
|
+
end
|
69
|
+
end
|
70
|
+
c.class_eval &b if b
|
71
|
+
c
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Hobo::RapidHelper
|
2
|
+
|
3
|
+
def options_for_hobo_ajax(options)
|
4
|
+
js_options = build_callbacks(options)
|
5
|
+
|
6
|
+
js_options['asynchronous'] = false if options[:type] == :synchronous
|
7
|
+
js_options['method'] = method_option_to_s(options[:method]) if options[:method]
|
8
|
+
js_options['evalScripts'] = false if options[:script] == false
|
9
|
+
js_options['form'] = options[:form] if options[:form]
|
10
|
+
js_options['params'] = make_params_js(options[:params]) if options[:params]
|
11
|
+
js_options['resultUpdate'] = js_result_updates(options[:result_update]) if options[:result_update]
|
12
|
+
js_options['resetForm'] = false if options[:reset_form] == false
|
13
|
+
js_options['refocusForm'] = false if options[:refocus_form] == false
|
14
|
+
|
15
|
+
js_options.empty? ? nil : options_for_javascript(js_options)
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def js_updates(updates)
|
20
|
+
return '[]' unless updates
|
21
|
+
updates = [updates] unless updates.is_a? Array
|
22
|
+
'[' + comma_split(updates).map{|u| js_str(u)}.join(', ') + ']'
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def js_result_updates(updates)
|
27
|
+
return '[]' unless updates
|
28
|
+
updates = [updates] unless updates.is_a? Array
|
29
|
+
pairs = comma_split(updates).omap{split(/\s*=\s*/)}
|
30
|
+
'[' + pairs.map{|p| "{id: #{js_str(p[0])}, result: #{js_str(p[1])}}"}.join(", ") + ']'
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def ajax_updater(url_or_form, message, update, options={})
|
35
|
+
options ||= {}
|
36
|
+
options.symbolize_keys!
|
37
|
+
|
38
|
+
target = if url_or_form == :post_form
|
39
|
+
target = "this"
|
40
|
+
else
|
41
|
+
js_str(url_or_form)
|
42
|
+
end
|
43
|
+
js_options = options_for_hobo_ajax(options)
|
44
|
+
args = [target, js_str(message || "..."), js_updates(update), js_options].compact
|
45
|
+
|
46
|
+
confirm = options.delete(:confirm)
|
47
|
+
|
48
|
+
func = "Hobo.ajaxRequest(#{args * ', '})"
|
49
|
+
if confirm
|
50
|
+
"if (confirm(#{js_str(confirm)})) { #{func} }"
|
51
|
+
else
|
52
|
+
func
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def a_or_an(word)
|
58
|
+
if word =~ /^[aeiouh]/
|
59
|
+
"an #{word}"
|
60
|
+
else
|
61
|
+
"a #{word}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def no_break(s)
|
67
|
+
s = new_context { yield } if block_given?
|
68
|
+
s.gsub(' ', ' ')
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
def in_place_editor(behaviour_class, attributes)
|
75
|
+
blank_message = attributes.delete(:blank_message) || "(click to edit)"
|
76
|
+
|
77
|
+
attributes = add_classes(attributes, behaviour_class)
|
78
|
+
attributes.update(:hobo_model_id => this_field_dom_id,
|
79
|
+
:hobo_blank_message => blank_message,
|
80
|
+
:if_blank => blank_message)
|
81
|
+
|
82
|
+
update = attributes.delete(:update)
|
83
|
+
attributes[:hobo_update] = update if update
|
84
|
+
|
85
|
+
view(attributes)
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
AJAX_ATTRS = [:before, :success, :failure, :complete, :type, :method,
|
91
|
+
:script, :form, :params, :confirm,
|
92
|
+
:reset_form, :refocus_form, :result_update]
|
93
|
+
|
94
|
+
|
95
|
+
def editor_class
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
class Hobo::TextileString < String
|
2
2
|
|
3
|
+
COLUMN_TYPE = :text
|
4
|
+
|
3
5
|
def to_html
|
4
|
-
if
|
6
|
+
if blank?
|
5
7
|
""
|
6
8
|
else
|
7
9
|
textilized = RedCloth.new(self, [ :hard_breaks ])
|
@@ -11,3 +13,11 @@ class Hobo::TextileString < String
|
|
11
13
|
end
|
12
14
|
|
13
15
|
end
|
16
|
+
|
17
|
+
class RedCloth
|
18
|
+
# Patch for RedCloth. Fixed in RedCloth r128 but _why hasn't released it yet.
|
19
|
+
# http://code.whytheluckystiff.net/redcloth/changeset/128
|
20
|
+
def hard_break( text )
|
21
|
+
text.gsub!( /(.)\n(?!\n|\Z| *([#*=]+(\s|$)|[{|]))/, "\\1<br />" ) if hard_breaks && RedCloth::VERSION == "3.0.4"
|
22
|
+
end
|
23
|
+
end
|